add quantity controls to cart drawer via shared CartHook
Move increment/decrement handlers from Cart LiveView into CartHook so they work from any page's drawer. Enable show_quantity_controls on the drawer's cart_item_row. Scope cart tests to #main-content to avoid duplicate button matches. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
3c73b98d2b
commit
b3d1019cd4
@ -48,7 +48,7 @@ Issues found during hands-on testing of the deployed prod site on mobile and des
|
||||
- [ ] Real product variants need testing and refinement with live data
|
||||
|
||||
### Cart
|
||||
- [ ] Should be able to change quantity in the cart drawer (currently only on cart page?)
|
||||
- [x] Should be able to change quantity in the cart drawer (currently only on cart page?)
|
||||
- [ ] Cart drawer button → "view basket" feels redundant — streamline the flow
|
||||
|
||||
### Navigation & links
|
||||
|
||||
@ -8,10 +8,11 @@ defmodule SimpleshopThemeWeb.CartHook do
|
||||
Handles these events so individual LiveViews don't have to:
|
||||
- `open_cart_drawer` / `close_cart_drawer` - toggle drawer visibility
|
||||
- `remove_item` - remove item from cart
|
||||
- `increment` / `decrement` - change item quantity
|
||||
- `{:cart_updated, cart}` info - cross-tab cart sync via PubSub
|
||||
|
||||
LiveViews with custom cart logic (add_to_cart, increment, decrement)
|
||||
can call `update_cart_assigns/2` and `broadcast_and_update/2` directly.
|
||||
LiveViews with custom cart logic (e.g. add_to_cart) can call
|
||||
`update_cart_assigns/2` and `broadcast_and_update/2` directly.
|
||||
"""
|
||||
|
||||
import Phoenix.Component, only: [assign: 3]
|
||||
@ -64,6 +65,31 @@ defmodule SimpleshopThemeWeb.CartHook do
|
||||
{:halt, socket}
|
||||
end
|
||||
|
||||
defp handle_cart_event("increment", %{"id" => variant_id}, socket) do
|
||||
cart = Cart.add_item(socket.assigns.raw_cart, variant_id, 1)
|
||||
new_qty = Cart.get_quantity(cart, variant_id)
|
||||
|
||||
socket =
|
||||
socket
|
||||
|> broadcast_and_update(cart)
|
||||
|> assign(:cart_status, "Quantity updated to #{new_qty}")
|
||||
|
||||
{:halt, socket}
|
||||
end
|
||||
|
||||
defp handle_cart_event("decrement", %{"id" => variant_id}, socket) do
|
||||
current = Cart.get_quantity(socket.assigns.raw_cart, variant_id)
|
||||
cart = Cart.update_quantity(socket.assigns.raw_cart, variant_id, current - 1)
|
||||
new_qty = Cart.get_quantity(cart, variant_id)
|
||||
|
||||
socket =
|
||||
socket
|
||||
|> broadcast_and_update(cart)
|
||||
|> assign(:cart_status, "Quantity updated to #{new_qty}")
|
||||
|
||||
{:halt, socket}
|
||||
end
|
||||
|
||||
defp handle_cart_event(_event, _params, socket), do: {:cont, socket}
|
||||
|
||||
# Shared info handlers
|
||||
|
||||
@ -105,7 +105,7 @@ defmodule SimpleshopThemeWeb.ShopComponents.Cart do
|
||||
<ul role="list" aria-label="Cart items" style="list-style: none; margin: 0; padding: 0;">
|
||||
<%= for item <- @cart_items do %>
|
||||
<li style="border-bottom: 1px solid var(--t-border-default);">
|
||||
<.cart_item_row item={item} size={:compact} mode={@mode} />
|
||||
<.cart_item_row item={item} size={:compact} show_quantity_controls mode={@mode} />
|
||||
</li>
|
||||
<% end %>
|
||||
</ul>
|
||||
|
||||
@ -8,33 +8,6 @@ defmodule SimpleshopThemeWeb.ShopLive.Cart do
|
||||
{:ok, assign(socket, :page_title, "Cart")}
|
||||
end
|
||||
|
||||
@impl true
|
||||
def handle_event("increment", %{"id" => variant_id}, socket) do
|
||||
cart = Cart.add_item(socket.assigns.raw_cart, variant_id, 1)
|
||||
new_qty = Cart.get_quantity(cart, variant_id)
|
||||
|
||||
socket =
|
||||
socket
|
||||
|> SimpleshopThemeWeb.CartHook.broadcast_and_update(cart)
|
||||
|> assign(:cart_status, "Quantity updated to #{new_qty}")
|
||||
|
||||
{:noreply, socket}
|
||||
end
|
||||
|
||||
@impl true
|
||||
def handle_event("decrement", %{"id" => variant_id}, socket) do
|
||||
current = Cart.get_quantity(socket.assigns.raw_cart, variant_id)
|
||||
cart = Cart.update_quantity(socket.assigns.raw_cart, variant_id, current - 1)
|
||||
new_qty = Cart.get_quantity(cart, variant_id)
|
||||
|
||||
socket =
|
||||
socket
|
||||
|> SimpleshopThemeWeb.CartHook.broadcast_and_update(cart)
|
||||
|> assign(:cart_status, "Quantity updated to #{new_qty}")
|
||||
|
||||
{:noreply, socket}
|
||||
end
|
||||
|
||||
@impl true
|
||||
def render(assigns) do
|
||||
assigns = assign(assigns, :cart_page_subtotal, Cart.calculate_subtotal(assigns.cart_items))
|
||||
|
||||
@ -68,7 +68,7 @@ defmodule SimpleshopThemeWeb.ShopLive.CartTest do
|
||||
|
||||
html =
|
||||
view
|
||||
|> element("button[aria-label='Increase quantity of #{product.title}']")
|
||||
|> element("#main-content button[aria-label='Increase quantity of #{product.title}']")
|
||||
|> render_click()
|
||||
|
||||
assert html =~ "Quantity updated to 2"
|
||||
@ -83,7 +83,7 @@ defmodule SimpleshopThemeWeb.ShopLive.CartTest do
|
||||
|
||||
html =
|
||||
view
|
||||
|> element("button[aria-label='Decrease quantity of #{product.title}']")
|
||||
|> element("#main-content button[aria-label='Decrease quantity of #{product.title}']")
|
||||
|> render_click()
|
||||
|
||||
assert html =~ "Your basket is empty"
|
||||
|
||||
Loading…
Reference in New Issue
Block a user