Add comprehensive layout and styling controls including header layout options (standard, centered, left), content width settings (contained, wide, full), and card shadow levels. Update all theme presets with these new settings. Replace placeholder images with real Unsplash product and category images for more realistic previews. Add announcement bar and sticky header toggle options for enhanced header customization. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
110 lines
3.9 KiB
Elixir
110 lines
3.9 KiB
Elixir
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 :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 :quick_add, :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,
|
|
: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,
|
|
:quick_add,
|
|
: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))
|
|
end
|
|
end
|