rename project from SimpleshopTheme to Berrypod
All modules, configs, paths, and references updated. 836 tests pass, zero warnings. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
38
lib/berrypod/settings/setting.ex
Normal file
38
lib/berrypod/settings/setting.ex
Normal file
@@ -0,0 +1,38 @@
|
||||
defmodule Berrypod.Settings.Setting do
|
||||
use Ecto.Schema
|
||||
import Ecto.Changeset
|
||||
|
||||
@primary_key {:id, :binary_id, autogenerate: true}
|
||||
@foreign_key_type :binary_id
|
||||
|
||||
schema "settings" do
|
||||
field :key, :string
|
||||
field :value, :string
|
||||
field :value_type, :string, default: "string"
|
||||
field :encrypted_value, :binary
|
||||
|
||||
timestamps(type: :utc_datetime)
|
||||
end
|
||||
|
||||
@doc false
|
||||
def changeset(setting, attrs) do
|
||||
setting
|
||||
|> cast(attrs, [:key, :value, :value_type, :encrypted_value])
|
||||
|> validate_required([:key, :value_type])
|
||||
|> validate_inclusion(:value_type, ~w(string json integer boolean encrypted))
|
||||
|> validate_has_value()
|
||||
|> unique_constraint(:key)
|
||||
end
|
||||
|
||||
# Encrypted settings store data in encrypted_value, not value.
|
||||
# All other types require value.
|
||||
defp validate_has_value(changeset) do
|
||||
case get_field(changeset, :value_type) do
|
||||
"encrypted" ->
|
||||
validate_required(changeset, [:encrypted_value])
|
||||
|
||||
_ ->
|
||||
validate_required(changeset, [:value])
|
||||
end
|
||||
end
|
||||
end
|
||||
123
lib/berrypod/settings/theme_settings.ex
Normal file
123
lib/berrypod/settings/theme_settings.ex
Normal file
@@ -0,0 +1,123 @@
|
||||
defmodule Berrypod.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
|
||||
Reference in New Issue
Block a user