From cb4698bec851c826aaa86d47c4ca003a92f735cc Mon Sep 17 00:00:00 2001 From: jamey Date: Sun, 8 Feb 2026 12:24:39 +0000 Subject: [PATCH] refactor: extract Cart.build_state/1 as single source of truth for cart state Co-Authored-By: Claude Opus 4.6 --- lib/simpleshop_theme/cart.ex | 17 +++++++++++++++++ lib/simpleshop_theme_web/cart_hook.ex | 14 +++++--------- 2 files changed, 22 insertions(+), 9 deletions(-) diff --git a/lib/simpleshop_theme/cart.ex b/lib/simpleshop_theme/cart.ex index 19b5f86..a288520 100644 --- a/lib/simpleshop_theme/cart.ex +++ b/lib/simpleshop_theme/cart.ex @@ -166,6 +166,23 @@ defmodule SimpleshopTheme.Cart do # Helpers # ============================================================================= + @doc """ + Builds the full display state for a cart. + + Takes raw cart items (list of {variant_id, quantity} tuples) and returns + a map with hydrated items, count, and formatted subtotal. Single source + of truth for cart state computation — used by CartHook. + """ + def build_state(raw_cart) do + hydrated = hydrate(raw_cart) + + %{ + items: hydrated, + count: item_count(raw_cart), + subtotal: format_subtotal(hydrated) + } + end + @doc """ Returns the total item count in the cart. """ diff --git a/lib/simpleshop_theme_web/cart_hook.ex b/lib/simpleshop_theme_web/cart_hook.ex index a17ac10..895a8b9 100644 --- a/lib/simpleshop_theme_web/cart_hook.ex +++ b/lib/simpleshop_theme_web/cart_hook.ex @@ -21,14 +21,10 @@ defmodule SimpleshopThemeWeb.CartHook do def on_mount(:mount_cart, _params, session, socket) do cart_items = Cart.get_from_session(session) - hydrated = Cart.hydrate(cart_items) socket = socket - |> assign(:raw_cart, cart_items) - |> assign(:cart_items, hydrated) - |> assign(:cart_count, Cart.item_count(cart_items)) - |> assign(:cart_subtotal, Cart.format_subtotal(hydrated)) + |> update_cart_assigns(cart_items) |> assign(:cart_drawer_open, false) |> assign(:cart_status, nil) |> attach_hook(:cart_events, :handle_event, &handle_cart_event/3) @@ -84,13 +80,13 @@ defmodule SimpleshopThemeWeb.CartHook do Updates all cart-related assigns from raw cart data. """ def update_cart_assigns(socket, cart) do - hydrated = Cart.hydrate(cart) + %{items: items, count: count, subtotal: subtotal} = Cart.build_state(cart) socket |> assign(:raw_cart, cart) - |> assign(:cart_items, hydrated) - |> assign(:cart_count, Cart.item_count(cart)) - |> assign(:cart_subtotal, Cart.format_subtotal(hydrated)) + |> assign(:cart_items, items) + |> assign(:cart_count, count) + |> assign(:cart_subtotal, subtotal) end @doc """