feat: add dynamic variant selector with color swatches

- Fix Printify options parsing (Color/Size were swapped)
- Add extract_option_types/1 for frontend display with hex colors
- Filter option types to only published variants (not full catalog)
- Track selected variant in LiveView with price updates
- Color swatches for color-type options, text buttons for size
- Disable unavailable combinations
- Add startup recovery for stale sync status

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
jamey
2026-02-03 22:17:48 +00:00
parent 1b49b470f2
commit 880e7a2888
8 changed files with 572 additions and 40 deletions

View File

@@ -336,12 +336,35 @@ defmodule SimpleshopThemeWeb.ThemeLive.Index do
defp preview_page(%{page: :pdp} = assigns) do
product = List.first(assigns.preview_data.products)
option_types = product[:option_types] || []
variants = product[:variants] || []
# Select first variant by default for preview
{selected_options, selected_variant} =
case variants do
[first | _] -> {first.options, first}
[] -> {%{}, nil}
end
# All options available in preview mode (show all values)
available_options =
Enum.reduce(option_types, %{}, fn opt, acc ->
values = Enum.map(opt.values, & &1.title)
Map.put(acc, opt.name, values)
end)
display_price =
if selected_variant, do: selected_variant.price, else: product.price
assigns =
assigns
|> assign(:product, product)
|> assign(:gallery_images, build_gallery_images(product))
|> assign(:related_products, Enum.slice(assigns.preview_data.products, 1, 4))
|> assign(:option_types, option_types)
|> assign(:selected_options, selected_options)
|> assign(:available_options, available_options)
|> assign(:display_price, display_price)
~H"""
<SimpleshopThemeWeb.PageTemplates.pdp
@@ -356,6 +379,10 @@ defmodule SimpleshopThemeWeb.ThemeLive.Index do
cart_items={PreviewData.cart_drawer_items()}
cart_count={2}
cart_subtotal="£72.00"
option_types={@option_types}
selected_options={@selected_options}
available_options={@available_options}
display_price={@display_price}
/>
"""
end