add no-JS progressive enhancement for all shop flows
All checks were successful
deploy / deploy (push) Successful in 1m23s

Every key shop flow now works via plain HTML forms when JS is
unavailable. LiveView progressively enhances when JS connects.

- PDP: form wraps variant/qty/add-to-cart with action="/cart/add"
- Cart page: qty +/- and remove use form POST fallbacks
- Cart/search header icons are now links with phx-click enhancement
- Collection sort form has GET action + noscript submit button
- New /search page with form-based search for no-JS users
- CartController gains add/remove/update_item POST actions
- CartHook gains update_quantity_form and remove_item_form handlers
- Fix flaky analytics tests caused by event table pollution

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
jamey
2026-02-24 22:56:19 +00:00
parent f788108665
commit 0b0adba0fe
16 changed files with 461 additions and 67 deletions

View File

@@ -213,11 +213,18 @@ defmodule BerrypodWeb.ShopComponents.Cart do
<div class="cart-item-actions">
<%= if @show_quantity_controls do %>
<div class="cart-qty-group">
<form
action="/cart/update"
method="post"
phx-submit="update_quantity_form"
class="cart-qty-group"
>
<input type="hidden" name="_csrf_token" value={Phoenix.Controller.get_csrf_token()} />
<input type="hidden" name="variant_id" value={@item.variant_id} />
<button
type="button"
phx-click="decrement"
phx-value-id={@item.variant_id}
type="submit"
name="quantity"
value={@item.quantity - 1}
class="cart-qty-btn"
aria-label={"Decrease quantity of #{@item.name}"}
>
@@ -227,15 +234,15 @@ defmodule BerrypodWeb.ShopComponents.Cart do
{@item.quantity}
</span>
<button
type="button"
phx-click="increment"
phx-value-id={@item.variant_id}
type="submit"
name="quantity"
value={@item.quantity + 1}
class="cart-qty-btn"
aria-label={"Increase quantity of #{@item.name}"}
>
+
</button>
</div>
</form>
<% else %>
<span class="cart-qty-text">
Qty: {@item.quantity}
@@ -306,15 +313,17 @@ defmodule BerrypodWeb.ShopComponents.Cart do
def cart_remove_button(assigns) do
~H"""
<button
type="button"
phx-click="remove_item"
phx-value-id={@variant_id}
class="cart-remove-btn"
aria-label={"Remove #{@item_name} from cart"}
>
Remove
</button>
<form action="/cart/remove" method="post" phx-submit="remove_item_form" class="cart-remove-form">
<input type="hidden" name="_csrf_token" value={Phoenix.Controller.get_csrf_token()} />
<input type="hidden" name="variant_id" value={@variant_id} />
<button
type="submit"
class="cart-remove-btn"
aria-label={"Remove #{@item_name} from cart"}
>
Remove
</button>
</form>
"""
end