add SettingsField struct and repeater field type for block settings
All checks were successful
deploy / deploy (push) Successful in 1m23s
All checks were successful
deploy / deploy (push) Successful in 1m23s
Introduces typed settings schema with SettingsField struct, replaces the read-only JSON textarea with a full repeater UI for info_card items. Supports add, remove, reorder and inline editing of repeater items. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -7,6 +7,7 @@ defmodule Berrypod.Pages.BlockTypes do
|
||||
is present on a page.
|
||||
"""
|
||||
|
||||
alias Berrypod.Pages.SettingsField
|
||||
alias Berrypod.Products
|
||||
alias Berrypod.Theme.PreviewData
|
||||
|
||||
@@ -18,13 +19,23 @@ defmodule Berrypod.Pages.BlockTypes do
|
||||
icon: "hero-megaphone",
|
||||
allowed_on: :all,
|
||||
settings_schema: [
|
||||
%{key: "title", label: "Title", type: :text, default: ""},
|
||||
%{key: "description", label: "Description", type: :textarea, default: ""},
|
||||
%{key: "cta_text", label: "Button text", type: :text, default: ""},
|
||||
%{key: "cta_href", label: "Button link", type: :text, default: ""},
|
||||
%{key: "secondary_cta_text", label: "Secondary button text", type: :text, default: ""},
|
||||
%{key: "secondary_cta_href", label: "Secondary button link", type: :text, default: ""},
|
||||
%{
|
||||
%SettingsField{key: "title", label: "Title", type: :text, default: ""},
|
||||
%SettingsField{key: "description", label: "Description", type: :textarea, default: ""},
|
||||
%SettingsField{key: "cta_text", label: "Button text", type: :text, default: ""},
|
||||
%SettingsField{key: "cta_href", label: "Button link", type: :text, default: ""},
|
||||
%SettingsField{
|
||||
key: "secondary_cta_text",
|
||||
label: "Secondary button text",
|
||||
type: :text,
|
||||
default: ""
|
||||
},
|
||||
%SettingsField{
|
||||
key: "secondary_cta_href",
|
||||
label: "Secondary button link",
|
||||
type: :text,
|
||||
default: ""
|
||||
},
|
||||
%SettingsField{
|
||||
key: "variant",
|
||||
label: "Style",
|
||||
type: :select,
|
||||
@@ -38,23 +49,33 @@ defmodule Berrypod.Pages.BlockTypes do
|
||||
icon: "hero-star",
|
||||
allowed_on: :all,
|
||||
settings_schema: [
|
||||
%{key: "title", label: "Title", type: :text, default: "Featured products"},
|
||||
%{key: "product_count", label: "Number of products", type: :number, default: 8},
|
||||
%{
|
||||
%SettingsField{
|
||||
key: "title",
|
||||
label: "Title",
|
||||
type: :text,
|
||||
default: "Featured products"
|
||||
},
|
||||
%SettingsField{
|
||||
key: "product_count",
|
||||
label: "Number of products",
|
||||
type: :number,
|
||||
default: 8
|
||||
},
|
||||
%SettingsField{
|
||||
key: "layout",
|
||||
label: "Layout",
|
||||
type: :select,
|
||||
options: ~w(section grid),
|
||||
default: "section"
|
||||
},
|
||||
%{
|
||||
%SettingsField{
|
||||
key: "card_variant",
|
||||
label: "Card style",
|
||||
type: :select,
|
||||
options: ~w(featured default minimal compact),
|
||||
default: "featured"
|
||||
},
|
||||
%{
|
||||
%SettingsField{
|
||||
key: "columns",
|
||||
label: "Columns",
|
||||
type: :select,
|
||||
@@ -69,11 +90,11 @@ defmodule Berrypod.Pages.BlockTypes do
|
||||
icon: "hero-photo",
|
||||
allowed_on: :all,
|
||||
settings_schema: [
|
||||
%{key: "title", label: "Title", type: :text, default: ""},
|
||||
%{key: "description", label: "Description", type: :textarea, default: ""},
|
||||
%{key: "image_url", label: "Image URL", type: :text, default: ""},
|
||||
%{key: "link_text", label: "Link text", type: :text, default: ""},
|
||||
%{key: "link_href", label: "Link URL", type: :text, default: ""}
|
||||
%SettingsField{key: "title", label: "Title", type: :text, default: ""},
|
||||
%SettingsField{key: "description", label: "Description", type: :textarea, default: ""},
|
||||
%SettingsField{key: "image_url", label: "Image URL", type: :text, default: ""},
|
||||
%SettingsField{key: "link_text", label: "Link text", type: :text, default: ""},
|
||||
%SettingsField{key: "link_href", label: "Link URL", type: :text, default: ""}
|
||||
]
|
||||
},
|
||||
"category_nav" => %{
|
||||
@@ -99,8 +120,17 @@ defmodule Berrypod.Pages.BlockTypes do
|
||||
icon: "hero-information-circle",
|
||||
allowed_on: :all,
|
||||
settings_schema: [
|
||||
%{key: "title", label: "Title", type: :text, default: ""},
|
||||
%{key: "items", label: "Items", type: :json, default: []}
|
||||
%SettingsField{key: "title", label: "Title", type: :text, default: ""},
|
||||
%SettingsField{
|
||||
key: "items",
|
||||
label: "Items",
|
||||
type: :repeater,
|
||||
default: [],
|
||||
item_schema: [
|
||||
%SettingsField{key: "label", label: "Label", type: :text, default: ""},
|
||||
%SettingsField{key: "value", label: "Value", type: :text, default: ""}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"trust_badges" => %{
|
||||
@@ -188,7 +218,7 @@ defmodule Berrypod.Pages.BlockTypes do
|
||||
icon: "hero-envelope",
|
||||
allowed_on: ["contact"],
|
||||
settings_schema: [
|
||||
%{key: "email", label: "Email", type: :text, default: "hello@example.com"}
|
||||
%SettingsField{key: "email", label: "Email", type: :text, default: "hello@example.com"}
|
||||
]
|
||||
},
|
||||
"order_tracking_card" => %{
|
||||
@@ -205,8 +235,8 @@ defmodule Berrypod.Pages.BlockTypes do
|
||||
icon: "hero-document-text",
|
||||
allowed_on: ["about", "delivery", "privacy", "terms"],
|
||||
settings_schema: [
|
||||
%{key: "image_src", label: "Image", type: :text, default: ""},
|
||||
%{key: "image_alt", label: "Image alt text", type: :text, default: ""}
|
||||
%SettingsField{key: "image_src", label: "Image", type: :text, default: ""},
|
||||
%SettingsField{key: "image_alt", label: "Image alt text", type: :text, default: ""}
|
||||
]
|
||||
},
|
||||
|
||||
|
||||
16
lib/berrypod/pages/settings_field.ex
Normal file
16
lib/berrypod/pages/settings_field.ex
Normal file
@@ -0,0 +1,16 @@
|
||||
defmodule Berrypod.Pages.SettingsField do
|
||||
@moduledoc "Defines a single field in a block's settings schema."
|
||||
|
||||
@type field_type :: :text | :textarea | :number | :select | :repeater
|
||||
@type t :: %__MODULE__{
|
||||
key: String.t(),
|
||||
label: String.t(),
|
||||
type: field_type(),
|
||||
default: term(),
|
||||
options: [String.t()] | nil,
|
||||
item_schema: [t()] | nil
|
||||
}
|
||||
|
||||
@enforce_keys [:key, :label, :type]
|
||||
defstruct [:key, :label, :type, default: nil, options: nil, item_schema: nil]
|
||||
end
|
||||
Reference in New Issue
Block a user