From 8be1f90f2d7228aa7d80dd31d83598676ae6b5d0 Mon Sep 17 00:00:00 2001 From: jamey Date: Sun, 8 Feb 2026 12:10:08 +0000 Subject: [PATCH] refactor: extract shop_layout component to eliminate template boilerplate Co-Authored-By: Claude Opus 4.6 --- .../components/page_templates/cart.html.heex | 47 ++++---------- .../page_templates/checkout_success.html.heex | 48 ++++---------- .../page_templates/collection.html.heex | 48 ++++---------- .../page_templates/contact.html.heex | 48 ++++---------- .../page_templates/content.html.heex | 48 ++++---------- .../components/page_templates/error.html.heex | 45 ++++--------- .../components/page_templates/home.html.heex | 48 ++++---------- .../components/page_templates/pdp.html.heex | 47 ++++---------- .../components/shop_components.ex | 64 +++++++++++++++++++ .../live/shop_live/collection.ex | 50 ++++----------- 10 files changed, 173 insertions(+), 320 deletions(-) diff --git a/lib/simpleshop_theme_web/components/page_templates/cart.html.heex b/lib/simpleshop_theme_web/components/page_templates/cart.html.heex index caa02d5..670b588 100644 --- a/lib/simpleshop_theme_web/components/page_templates/cart.html.heex +++ b/lib/simpleshop_theme_web/components/page_templates/cart.html.heex @@ -1,24 +1,15 @@ -
- <.skip_link /> - - <%= if @theme_settings.announcement_bar do %> - <.announcement_bar theme_settings={@theme_settings} /> - <% end %> - - <.shop_header - theme_settings={@theme_settings} - logo_image={@logo_image} - header_image={@header_image} - active_page="cart" - mode={@mode} - cart_count={@cart_count} - /> -
<.page_title text="Your basket" /> @@ -49,18 +40,4 @@
<% end %> - - <.shop_footer theme_settings={@theme_settings} mode={@mode} /> - - <.cart_drawer - cart_items={@cart_items} - subtotal={@cart_subtotal} - cart_count={@cart_count} - mode={@mode} - open={assigns[:cart_drawer_open] || false} - cart_status={assigns[:cart_status]} - /> - <.search_modal hint_text={~s(Try a search – e.g. "mountain" or "notebook")} /> - - <.mobile_bottom_nav active_page="cart" mode={@mode} /> - + diff --git a/lib/simpleshop_theme_web/components/page_templates/checkout_success.html.heex b/lib/simpleshop_theme_web/components/page_templates/checkout_success.html.heex index 0e08646..125f108 100644 --- a/lib/simpleshop_theme_web/components/page_templates/checkout_success.html.heex +++ b/lib/simpleshop_theme_web/components/page_templates/checkout_success.html.heex @@ -1,24 +1,15 @@ -
- <.skip_link /> - - <%= if @theme_settings.announcement_bar do %> - <.announcement_bar theme_settings={@theme_settings} /> - <% end %> - - <.shop_header - theme_settings={@theme_settings} - logo_image={@logo_image} - header_image={@header_image} - active_page="checkout" - mode={@mode} - cart_count={@cart_count} - /> -
<%= if @order && @order.payment_status == "paid" do %>
@@ -171,19 +162,4 @@
<% end %>
- - <.shop_footer theme_settings={@theme_settings} mode={@mode} /> - - <.cart_drawer - cart_items={@cart_items} - subtotal={@cart_subtotal} - cart_count={@cart_count} - mode={@mode} - open={assigns[:cart_drawer_open] || false} - cart_status={assigns[:cart_status]} - /> - - <.search_modal hint_text={~s(Try a search – e.g. "mountain" or "notebook")} /> - - <.mobile_bottom_nav active_page="checkout" mode={@mode} /> -
+ diff --git a/lib/simpleshop_theme_web/components/page_templates/collection.html.heex b/lib/simpleshop_theme_web/components/page_templates/collection.html.heex index 34f5ae4..bf971ea 100644 --- a/lib/simpleshop_theme_web/components/page_templates/collection.html.heex +++ b/lib/simpleshop_theme_web/components/page_templates/collection.html.heex @@ -1,24 +1,15 @@ -
- <.skip_link /> - - <%= if @theme_settings.announcement_bar do %> - <.announcement_bar theme_settings={@theme_settings} /> - <% end %> - - <.shop_header - theme_settings={@theme_settings} - logo_image={@logo_image} - header_image={@header_image} - active_page="collection" - mode={@mode} - cart_count={@cart_count} - /> -
<.collection_header title="All Products" product_count={length(@preview_data.products)} /> @@ -38,19 +29,4 @@
- - <.shop_footer theme_settings={@theme_settings} mode={@mode} /> - - <.cart_drawer - cart_items={@cart_items} - subtotal={@cart_subtotal} - cart_count={@cart_count} - mode={@mode} - open={assigns[:cart_drawer_open] || false} - cart_status={assigns[:cart_status]} - /> - - <.search_modal hint_text={~s(Try a search – e.g. "mountain" or "notebook")} /> - - <.mobile_bottom_nav active_page="collection" mode={@mode} /> - + diff --git a/lib/simpleshop_theme_web/components/page_templates/contact.html.heex b/lib/simpleshop_theme_web/components/page_templates/contact.html.heex index 8144d90..bb80eda 100644 --- a/lib/simpleshop_theme_web/components/page_templates/contact.html.heex +++ b/lib/simpleshop_theme_web/components/page_templates/contact.html.heex @@ -1,24 +1,15 @@ -
- <.skip_link /> - - <%= if @theme_settings.announcement_bar do %> - <.announcement_bar theme_settings={@theme_settings} /> - <% end %> - - <.shop_header - theme_settings={@theme_settings} - logo_image={@logo_image} - header_image={@header_image} - active_page="contact" - mode={@mode} - cart_count={@cart_count} - /> -
<.hero_section variant={:page} @@ -53,19 +44,4 @@
- - <.shop_footer theme_settings={@theme_settings} mode={@mode} /> - - <.cart_drawer - cart_items={@cart_items} - subtotal={@cart_subtotal} - cart_count={@cart_count} - mode={@mode} - open={assigns[:cart_drawer_open] || false} - cart_status={assigns[:cart_status]} - /> - - <.search_modal hint_text={~s(Try a search – e.g. "mountain" or "notebook")} /> - - <.mobile_bottom_nav active_page="contact" mode={@mode} /> - + diff --git a/lib/simpleshop_theme_web/components/page_templates/content.html.heex b/lib/simpleshop_theme_web/components/page_templates/content.html.heex index 41c0af2..7ff3ab2 100644 --- a/lib/simpleshop_theme_web/components/page_templates/content.html.heex +++ b/lib/simpleshop_theme_web/components/page_templates/content.html.heex @@ -1,24 +1,15 @@ -
- <.skip_link /> - - <%= if @theme_settings.announcement_bar do %> - <.announcement_bar theme_settings={@theme_settings} /> - <% end %> - - <.shop_header - theme_settings={@theme_settings} - logo_image={@logo_image} - header_image={@header_image} - active_page={@active_page} - mode={@mode} - cart_count={@cart_count} - /> -
<%= if assigns[:hero_background] do %> <.hero_section @@ -53,19 +44,4 @@ <.rich_text blocks={@content_blocks} />
- - <.shop_footer theme_settings={@theme_settings} mode={@mode} /> - - <.cart_drawer - cart_items={@cart_items} - subtotal={@cart_subtotal} - cart_count={@cart_count} - mode={@mode} - open={assigns[:cart_drawer_open] || false} - cart_status={assigns[:cart_status]} - /> - - <.search_modal hint_text={~s(Try a search – e.g. "mountain" or "notebook")} /> - - <.mobile_bottom_nav active_page={@active_page} mode={@mode} /> - + diff --git a/lib/simpleshop_theme_web/components/page_templates/error.html.heex b/lib/simpleshop_theme_web/components/page_templates/error.html.heex index c5ab739..b301fee 100644 --- a/lib/simpleshop_theme_web/components/page_templates/error.html.heex +++ b/lib/simpleshop_theme_web/components/page_templates/error.html.heex @@ -1,22 +1,16 @@ -
- <.skip_link /> - - <%= if @theme_settings.announcement_bar do %> - <.announcement_bar theme_settings={@theme_settings} /> - <% end %> - - <.shop_header - theme_settings={@theme_settings} - logo_image={@logo_image} - header_image={@header_image} - active_page="error" - mode={@mode} - cart_count={@cart_count} - /> -
- - <.shop_footer theme_settings={@theme_settings} mode={@mode} /> - - <.cart_drawer - cart_items={@cart_items} - subtotal={@cart_subtotal} - cart_count={@cart_count} - mode={@mode} - open={assigns[:cart_drawer_open] || false} - cart_status={assigns[:cart_status]} - /> - - <.search_modal hint_text={~s(Try a search – e.g. "mountain" or "notebook")} /> - + diff --git a/lib/simpleshop_theme_web/components/page_templates/home.html.heex b/lib/simpleshop_theme_web/components/page_templates/home.html.heex index a5a664e..0e870d2 100644 --- a/lib/simpleshop_theme_web/components/page_templates/home.html.heex +++ b/lib/simpleshop_theme_web/components/page_templates/home.html.heex @@ -1,24 +1,15 @@ -
- <.skip_link /> - - <%= if @theme_settings.announcement_bar do %> - <.announcement_bar theme_settings={@theme_settings} /> - <% end %> - - <.shop_header - theme_settings={@theme_settings} - logo_image={@logo_image} - header_image={@header_image} - active_page="home" - mode={@mode} - cart_count={@cart_count} - /> -
<.hero_section title="Original designs, printed on demand" @@ -46,19 +37,4 @@ mode={@mode} />
- - <.shop_footer theme_settings={@theme_settings} mode={@mode} /> - - <.cart_drawer - cart_items={@cart_items} - subtotal={@cart_subtotal} - cart_count={@cart_count} - mode={@mode} - open={assigns[:cart_drawer_open] || false} - cart_status={assigns[:cart_status]} - /> - - <.search_modal hint_text={~s(Try a search – e.g. "mountain" or "notebook")} /> - - <.mobile_bottom_nav active_page="home" mode={@mode} /> -
+ diff --git a/lib/simpleshop_theme_web/components/page_templates/pdp.html.heex b/lib/simpleshop_theme_web/components/page_templates/pdp.html.heex index e63fef3..643c142 100644 --- a/lib/simpleshop_theme_web/components/page_templates/pdp.html.heex +++ b/lib/simpleshop_theme_web/components/page_templates/pdp.html.heex @@ -1,24 +1,15 @@ -
- <.skip_link /> - - <%= if @theme_settings.announcement_bar do %> - <.announcement_bar theme_settings={@theme_settings} /> - <% end %> - - <.shop_header - theme_settings={@theme_settings} - logo_image={@logo_image} - header_image={@header_image} - active_page="pdp" - mode={@mode} - cart_count={@cart_count} - /> -
<.breadcrumb items={ @@ -88,18 +79,4 @@ mode={@mode} />
- - <.shop_footer theme_settings={@theme_settings} mode={@mode} /> - - <.cart_drawer - cart_items={@cart_items} - subtotal={@cart_subtotal} - cart_count={@cart_count} - mode={@mode} - open={assigns[:cart_drawer_open] || false} - cart_status={assigns[:cart_status]} - /> - <.search_modal hint_text={~s(Try a search – e.g. "mountain" or "notebook")} /> - - <.mobile_bottom_nav active_page="pdp" mode={@mode} /> -
+ diff --git a/lib/simpleshop_theme_web/components/shop_components.ex b/lib/simpleshop_theme_web/components/shop_components.ex index a543712..16735a1 100644 --- a/lib/simpleshop_theme_web/components/shop_components.ex +++ b/lib/simpleshop_theme_web/components/shop_components.ex @@ -53,6 +53,70 @@ defmodule SimpleshopThemeWeb.ShopComponents do """ end + @doc """ + Wraps page content in the standard shop shell: container, header, footer, + cart drawer, search modal, and mobile bottom nav. + + Templates pass their unique `
` content as the inner block. + The `error_page` flag disables the CartPersist hook and mobile bottom nav. + """ + attr :theme_settings, :map, required: true + attr :logo_image, :any, required: true + attr :header_image, :any, required: true + attr :mode, :atom, required: true + attr :cart_items, :list, required: true + attr :cart_count, :integer, required: true + attr :cart_subtotal, :string, required: true + attr :cart_drawer_open, :boolean, default: false + attr :cart_status, :string, default: nil + attr :active_page, :string, required: true + attr :error_page, :boolean, default: false + + slot :inner_block, required: true + + def shop_layout(assigns) do + ~H""" +
+ <.skip_link /> + + <%= if @theme_settings.announcement_bar do %> + <.announcement_bar theme_settings={@theme_settings} /> + <% end %> + + <.shop_header + theme_settings={@theme_settings} + logo_image={@logo_image} + header_image={@header_image} + active_page={@active_page} + mode={@mode} + cart_count={@cart_count} + /> + + {render_slot(@inner_block)} + + <.shop_footer theme_settings={@theme_settings} mode={@mode} /> + + <.cart_drawer + cart_items={@cart_items} + subtotal={@cart_subtotal} + cart_count={@cart_count} + mode={@mode} + open={@cart_drawer_open} + cart_status={@cart_status} + /> + + <.search_modal hint_text={~s(Try a search – e.g. "mountain" or "notebook")} /> + + <.mobile_bottom_nav :if={!@error_page} active_page={@active_page} mode={@mode} /> +
+ """ + end + # ============================================================================= # Themed Form Components # ============================================================================= diff --git a/lib/simpleshop_theme_web/live/shop_live/collection.ex b/lib/simpleshop_theme_web/live/shop_live/collection.ex index 26567c0..9ff5af9 100644 --- a/lib/simpleshop_theme_web/live/shop_live/collection.ex +++ b/lib/simpleshop_theme_web/live/shop_live/collection.ex @@ -78,27 +78,18 @@ defmodule SimpleshopThemeWeb.ShopLive.Collection do @impl true def render(assigns) do ~H""" -
- - - <%= if @theme_settings.announcement_bar do %> - - <% end %> - - -
- - - - - - - - - + """ end