fix PDP quantity selector and trust badge consistency

Wire up +/− buttons with phx-click events and handle_event handlers,
clamp to 1–99, reset to 1 after add-to-cart. Trust badges now use a
single hero-check-circle icon and sentence case text.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
jamey
2026-02-10 23:15:09 +00:00
parent 8775c2eeef
commit 3c73b98d2b
5 changed files with 109 additions and 62 deletions

View File

@@ -701,25 +701,24 @@ defmodule SimpleshopThemeWeb.ShopComponents.Content do
end
@doc """
Renders trust badges (e.g., Free Delivery, Easy Returns).
Renders trust badges (e.g., free delivery, easy returns).
## Attributes
* `items` - Optional. List of badge items. Each item is a map with:
- `icon` - Icon type: `:check` or `:shield`
- `title` - Badge title
- `title` - Badge title (sentence case)
- `description` - Badge description
Defaults to Free Delivery and Easy Returns badges.
Defaults to "Made to order" and "Quality materials" badges.
## Examples
<.trust_badges />
<.trust_badges items={[%{icon: :check, title: "Custom", description: "Badge text"}]} />
<.trust_badges items={[%{title: "Custom", description: "Badge text"}]} />
"""
attr :items, :list,
default: [
%{icon: :check, title: "Made to Order", description: "Printed just for you"},
%{icon: :shield, title: "Quality Materials", description: "Premium inks and substrates"}
%{title: "Made to order", description: "Printed just for you"},
%{title: "Quality materials", description: "Premium inks and substrates"}
]
def trust_badges(assigns) do
@@ -730,7 +729,12 @@ defmodule SimpleshopThemeWeb.ShopComponents.Content do
>
<%= for item <- @items do %>
<div class="flex items-start gap-3">
<.trust_badge_icon icon={item.icon} />
<span style="color: hsl(var(--t-accent-h) var(--t-accent-s) var(--t-accent-l));">
<SimpleshopThemeWeb.CoreComponents.icon
name="hero-check-circle"
class="size-5 mt-0.5 shrink-0"
/>
</span>
<div>
<p class="font-semibold" style="color: var(--t-text-primary);">{item.title}</p>
<p class="text-sm" style="color: var(--t-text-secondary);">{item.description}</p>
@@ -741,55 +745,6 @@ defmodule SimpleshopThemeWeb.ShopComponents.Content do
"""
end
attr :icon, :atom, required: true
defp trust_badge_icon(%{icon: :check} = assigns) do
~H"""
<svg
class="w-5 h-5 mt-0.5"
fill="none"
stroke="currentColor"
viewBox="0 0 24 24"
style="color: hsl(var(--t-accent-h) var(--t-accent-s) var(--t-accent-l));"
>
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7" />
</svg>
"""
end
defp trust_badge_icon(%{icon: :shield} = assigns) do
~H"""
<svg
class="w-5 h-5 mt-0.5"
fill="none"
stroke="currentColor"
viewBox="0 0 24 24"
style="color: hsl(var(--t-accent-h) var(--t-accent-s) var(--t-accent-l));"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z"
/>
</svg>
"""
end
defp trust_badge_icon(assigns) do
~H"""
<svg
class="w-5 h-5 mt-0.5"
fill="none"
stroke="currentColor"
viewBox="0 0 24 24"
style="color: hsl(var(--t-accent-h) var(--t-accent-s) var(--t-accent-l));"
>
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7" />
</svg>
"""
end
@doc """
Renders a customer reviews section with collapsible header and review cards.

View File

@@ -1556,14 +1556,32 @@ defmodule SimpleshopThemeWeb.ShopComponents.Product do
class="flex items-center"
style="border: 2px solid var(--t-border-default); border-radius: var(--t-radius-input);"
>
<button type="button" class="px-4 py-2" style="color: var(--t-text-primary);"></button>
<button
type="button"
phx-click="decrement_quantity"
disabled={@quantity <= @min}
aria-label="Decrease quantity"
class="px-4 py-2 disabled:opacity-30"
style="color: var(--t-text-primary);"
>
</button>
<span
class="px-4 py-2 border-x-2"
class="px-4 py-2 border-x-2 min-w-12 text-center tabular-nums"
style="border-color: var(--t-border-default); color: var(--t-text-primary);"
>
{@quantity}
</span>
<button type="button" class="px-4 py-2" style="color: var(--t-text-primary);">+</button>
<button
type="button"
phx-click="increment_quantity"
disabled={@quantity >= @max}
aria-label="Increase quantity"
class="px-4 py-2 disabled:opacity-30"
style="color: var(--t-text-primary);"
>
+
</button>
</div>
<%= if @in_stock do %>
<span class="text-sm" style="color: var(--t-text-tertiary);">In stock</span>