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
|
- [ ] Real product variants need testing and refinement with live data
|
||||||
|
|
||||||
### Cart
|
### 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
|
- [ ] Cart drawer button → "view basket" feels redundant — streamline the flow
|
||||||
|
|
||||||
### Navigation & links
|
### Navigation & links
|
||||||
|
|||||||
@ -8,10 +8,11 @@ defmodule SimpleshopThemeWeb.CartHook do
|
|||||||
Handles these events so individual LiveViews don't have to:
|
Handles these events so individual LiveViews don't have to:
|
||||||
- `open_cart_drawer` / `close_cart_drawer` - toggle drawer visibility
|
- `open_cart_drawer` / `close_cart_drawer` - toggle drawer visibility
|
||||||
- `remove_item` - remove item from cart
|
- `remove_item` - remove item from cart
|
||||||
|
- `increment` / `decrement` - change item quantity
|
||||||
- `{:cart_updated, cart}` info - cross-tab cart sync via PubSub
|
- `{:cart_updated, cart}` info - cross-tab cart sync via PubSub
|
||||||
|
|
||||||
LiveViews with custom cart logic (add_to_cart, increment, decrement)
|
LiveViews with custom cart logic (e.g. add_to_cart) can call
|
||||||
can call `update_cart_assigns/2` and `broadcast_and_update/2` directly.
|
`update_cart_assigns/2` and `broadcast_and_update/2` directly.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import Phoenix.Component, only: [assign: 3]
|
import Phoenix.Component, only: [assign: 3]
|
||||||
@ -64,6 +65,31 @@ defmodule SimpleshopThemeWeb.CartHook do
|
|||||||
{:halt, socket}
|
{:halt, socket}
|
||||||
end
|
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}
|
defp handle_cart_event(_event, _params, socket), do: {:cont, socket}
|
||||||
|
|
||||||
# Shared info handlers
|
# 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;">
|
<ul role="list" aria-label="Cart items" style="list-style: none; margin: 0; padding: 0;">
|
||||||
<%= for item <- @cart_items do %>
|
<%= for item <- @cart_items do %>
|
||||||
<li style="border-bottom: 1px solid var(--t-border-default);">
|
<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>
|
</li>
|
||||||
<% end %>
|
<% end %>
|
||||||
</ul>
|
</ul>
|
||||||
|
|||||||
@ -8,33 +8,6 @@ defmodule SimpleshopThemeWeb.ShopLive.Cart do
|
|||||||
{:ok, assign(socket, :page_title, "Cart")}
|
{:ok, assign(socket, :page_title, "Cart")}
|
||||||
end
|
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
|
@impl true
|
||||||
def render(assigns) do
|
def render(assigns) do
|
||||||
assigns = assign(assigns, :cart_page_subtotal, Cart.calculate_subtotal(assigns.cart_items))
|
assigns = assign(assigns, :cart_page_subtotal, Cart.calculate_subtotal(assigns.cart_items))
|
||||||
|
|||||||
@ -68,7 +68,7 @@ defmodule SimpleshopThemeWeb.ShopLive.CartTest do
|
|||||||
|
|
||||||
html =
|
html =
|
||||||
view
|
view
|
||||||
|> element("button[aria-label='Increase quantity of #{product.title}']")
|
|> element("#main-content button[aria-label='Increase quantity of #{product.title}']")
|
||||||
|> render_click()
|
|> render_click()
|
||||||
|
|
||||||
assert html =~ "Quantity updated to 2"
|
assert html =~ "Quantity updated to 2"
|
||||||
@ -83,7 +83,7 @@ defmodule SimpleshopThemeWeb.ShopLive.CartTest do
|
|||||||
|
|
||||||
html =
|
html =
|
||||||
view
|
view
|
||||||
|> element("button[aria-label='Decrease quantity of #{product.title}']")
|
|> element("#main-content button[aria-label='Decrease quantity of #{product.title}']")
|
||||||
|> render_click()
|
|> render_click()
|
||||||
|
|
||||||
assert html =~ "Your basket is empty"
|
assert html =~ "Your basket is empty"
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user