defmodule SimpleshopTheme.Settings.ThemeSettings do use Ecto.Schema import Ecto.Changeset @derive Jason.Encoder @primary_key false embedded_schema do # Core theme tokens field :mood, :string, default: "neutral" field :typography, :string, default: "clean" field :shape, :string, default: "soft" field :density, :string, default: "balanced" field :grid_columns, :string, default: "4" field :header_layout, :string, default: "standard" field :accent_color, :string, default: "#f97316" # Branding field :site_name, :string, default: "Store Name" field :site_description, :string, default: "Discover unique products and original designs." field :logo_mode, :string, default: "text-only" field :logo_image_id, :binary_id field :logo_size, :integer, default: 36 field :logo_recolor, :boolean, default: false field :logo_color, :string, default: "#171717" # Header Background field :header_background_enabled, :boolean, default: false field :header_image_id, :binary_id field :header_zoom, :integer, default: 100 field :header_position_x, :integer, default: 50 field :header_position_y, :integer, default: 50 # Advanced customization field :secondary_accent_color, :string, default: "#ea580c" field :sale_color, :string, default: "#dc2626" field :font_size, :string, default: "medium" field :heading_weight, :string, default: "bold" field :layout_width, :string, default: "wide" field :button_style, :string, default: "filled" field :card_shadow, :string, default: "none" field :product_text_align, :string, default: "left" field :image_aspect_ratio, :string, default: "square" # Feature toggles field :announcement_bar, :boolean, default: true field :sticky_header, :boolean, default: false field :hover_image, :boolean, default: true field :show_prices, :boolean, default: true field :pdp_trust_badges, :boolean, default: true field :pdp_reviews, :boolean, default: true field :pdp_related_products, :boolean, default: true end @doc false def changeset(settings, attrs) do settings |> cast(attrs, [ :mood, :typography, :shape, :density, :grid_columns, :header_layout, :accent_color, :site_name, :site_description, :logo_mode, :logo_image_id, :logo_size, :logo_recolor, :logo_color, :header_background_enabled, :header_image_id, :header_zoom, :header_position_x, :header_position_y, :secondary_accent_color, :sale_color, :font_size, :heading_weight, :layout_width, :button_style, :card_shadow, :product_text_align, :image_aspect_ratio, :announcement_bar, :sticky_header, :hover_image, :show_prices, :pdp_trust_badges, :pdp_reviews, :pdp_related_products ]) |> validate_required([:mood, :typography, :shape, :density]) |> validate_inclusion(:mood, ~w(neutral warm cool dark)) |> validate_inclusion( :typography, ~w(clean editorial modern classic friendly minimal impulse) ) |> validate_inclusion(:shape, ~w(sharp soft round pill)) |> validate_inclusion(:density, ~w(spacious balanced compact)) |> validate_inclusion(:grid_columns, ~w(2 3 4)) |> validate_inclusion(:header_layout, ~w(standard centered left)) |> validate_inclusion(:logo_mode, ~w(text-only logo-text logo-only)) |> validate_number(:logo_size, greater_than_or_equal_to: 24, less_than_or_equal_to: 120) |> validate_number(:header_zoom, greater_than_or_equal_to: 100, less_than_or_equal_to: 200) |> validate_number(:header_position_x, greater_than_or_equal_to: 0, less_than_or_equal_to: 100 ) |> validate_number(:header_position_y, greater_than_or_equal_to: 0, less_than_or_equal_to: 100 ) |> validate_inclusion(:layout_width, ~w(contained wide full)) |> validate_inclusion(:card_shadow, ~w(none sm md lg)) |> validate_inclusion(:font_size, ~w(small medium large)) |> validate_inclusion(:heading_weight, ~w(regular medium bold)) |> validate_inclusion(:button_style, ~w(filled outline soft)) |> validate_inclusion(:product_text_align, ~w(left center)) |> validate_inclusion(:image_aspect_ratio, ~w(square portrait landscape)) end end