refactor: extract ThemeHook to eliminate mount duplication
on_mount hook assigns theme_settings, generated_css, logo_image, header_image, and mode for all public shop LiveViews. Removes ~70 lines of identical boilerplate and 18 unused aliases across 7 LiveViews. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
dd19281f4f
commit
e6d4fce656
@ -2,38 +2,10 @@ defmodule SimpleshopThemeWeb.ShopLive.Cart do
|
||||
use SimpleshopThemeWeb, :live_view
|
||||
|
||||
alias SimpleshopTheme.Cart
|
||||
alias SimpleshopTheme.Settings
|
||||
alias SimpleshopTheme.Media
|
||||
alias SimpleshopTheme.Theme.{CSSCache, CSSGenerator}
|
||||
|
||||
@impl true
|
||||
def mount(_params, _session, socket) do
|
||||
theme_settings = Settings.get_theme_settings()
|
||||
|
||||
generated_css =
|
||||
case CSSCache.get() do
|
||||
{:ok, css} ->
|
||||
css
|
||||
|
||||
:miss ->
|
||||
css = CSSGenerator.generate(theme_settings)
|
||||
CSSCache.put(css)
|
||||
css
|
||||
end
|
||||
|
||||
logo_image = Media.get_logo()
|
||||
header_image = Media.get_header()
|
||||
|
||||
socket =
|
||||
socket
|
||||
|> assign(:page_title, "Cart")
|
||||
|> assign(:theme_settings, theme_settings)
|
||||
|> assign(:generated_css, generated_css)
|
||||
|> assign(:logo_image, logo_image)
|
||||
|> assign(:header_image, header_image)
|
||||
|> assign(:mode, :shop)
|
||||
|
||||
{:ok, socket}
|
||||
{:ok, assign(socket, :page_title, "Cart")}
|
||||
end
|
||||
|
||||
@impl true
|
||||
|
||||
@ -1,27 +1,10 @@
|
||||
defmodule SimpleshopThemeWeb.ShopLive.CheckoutSuccess do
|
||||
use SimpleshopThemeWeb, :live_view
|
||||
|
||||
alias SimpleshopTheme.{Orders, Settings, Media}
|
||||
alias SimpleshopTheme.Theme.{CSSCache, CSSGenerator}
|
||||
alias SimpleshopTheme.Orders
|
||||
|
||||
@impl true
|
||||
def mount(%{"session_id" => session_id}, _session, socket) do
|
||||
theme_settings = Settings.get_theme_settings()
|
||||
|
||||
generated_css =
|
||||
case CSSCache.get() do
|
||||
{:ok, css} ->
|
||||
css
|
||||
|
||||
:miss ->
|
||||
css = CSSGenerator.generate(theme_settings)
|
||||
CSSCache.put(css)
|
||||
css
|
||||
end
|
||||
|
||||
logo_image = Media.get_logo()
|
||||
header_image = Media.get_header()
|
||||
|
||||
order = Orders.get_order_by_stripe_session(session_id)
|
||||
|
||||
# Subscribe to order status updates (webhook may arrive after redirect)
|
||||
@ -32,10 +15,7 @@ defmodule SimpleshopThemeWeb.ShopLive.CheckoutSuccess do
|
||||
# Clear the cart after successful checkout
|
||||
socket =
|
||||
if order && connected?(socket) do
|
||||
empty_cart = []
|
||||
|
||||
socket
|
||||
|> SimpleshopThemeWeb.CartHook.broadcast_and_update(empty_cart)
|
||||
SimpleshopThemeWeb.CartHook.broadcast_and_update(socket, [])
|
||||
else
|
||||
socket
|
||||
end
|
||||
@ -43,11 +23,6 @@ defmodule SimpleshopThemeWeb.ShopLive.CheckoutSuccess do
|
||||
socket =
|
||||
socket
|
||||
|> assign(:page_title, "Order confirmed")
|
||||
|> assign(:theme_settings, theme_settings)
|
||||
|> assign(:generated_css, generated_css)
|
||||
|> assign(:logo_image, logo_image)
|
||||
|> assign(:header_image, header_image)
|
||||
|> assign(:mode, :shop)
|
||||
|> assign(:order, order)
|
||||
|
||||
{:ok, socket}
|
||||
|
||||
@ -1,9 +1,7 @@
|
||||
defmodule SimpleshopThemeWeb.ShopLive.Collection do
|
||||
use SimpleshopThemeWeb, :live_view
|
||||
|
||||
alias SimpleshopTheme.Settings
|
||||
alias SimpleshopTheme.Media
|
||||
alias SimpleshopTheme.Theme.{CSSCache, CSSGenerator, PreviewData}
|
||||
alias SimpleshopTheme.Theme.PreviewData
|
||||
|
||||
@sort_options [
|
||||
{"featured", "Featured"},
|
||||
@ -16,29 +14,8 @@ defmodule SimpleshopThemeWeb.ShopLive.Collection do
|
||||
|
||||
@impl true
|
||||
def mount(_params, _session, socket) do
|
||||
theme_settings = Settings.get_theme_settings()
|
||||
|
||||
generated_css =
|
||||
case CSSCache.get() do
|
||||
{:ok, css} ->
|
||||
css
|
||||
|
||||
:miss ->
|
||||
css = CSSGenerator.generate(theme_settings)
|
||||
CSSCache.put(css)
|
||||
css
|
||||
end
|
||||
|
||||
logo_image = Media.get_logo()
|
||||
header_image = Media.get_header()
|
||||
|
||||
socket =
|
||||
socket
|
||||
|> assign(:theme_settings, theme_settings)
|
||||
|> assign(:generated_css, generated_css)
|
||||
|> assign(:logo_image, logo_image)
|
||||
|> assign(:header_image, header_image)
|
||||
|> assign(:mode, :shop)
|
||||
|> assign(:categories, PreviewData.categories())
|
||||
|> assign(:sort_options, @sort_options)
|
||||
|> assign(:current_sort, "featured")
|
||||
|
||||
@ -1,38 +1,9 @@
|
||||
defmodule SimpleshopThemeWeb.ShopLive.Contact do
|
||||
use SimpleshopThemeWeb, :live_view
|
||||
|
||||
alias SimpleshopTheme.Settings
|
||||
alias SimpleshopTheme.Media
|
||||
alias SimpleshopTheme.Theme.{CSSCache, CSSGenerator}
|
||||
|
||||
@impl true
|
||||
def mount(_params, _session, socket) do
|
||||
theme_settings = Settings.get_theme_settings()
|
||||
|
||||
generated_css =
|
||||
case CSSCache.get() do
|
||||
{:ok, css} ->
|
||||
css
|
||||
|
||||
:miss ->
|
||||
css = CSSGenerator.generate(theme_settings)
|
||||
CSSCache.put(css)
|
||||
css
|
||||
end
|
||||
|
||||
logo_image = Media.get_logo()
|
||||
header_image = Media.get_header()
|
||||
|
||||
socket =
|
||||
socket
|
||||
|> assign(:page_title, "Contact")
|
||||
|> assign(:theme_settings, theme_settings)
|
||||
|> assign(:generated_css, generated_css)
|
||||
|> assign(:logo_image, logo_image)
|
||||
|> assign(:header_image, header_image)
|
||||
|> assign(:mode, :shop)
|
||||
|
||||
{:ok, socket}
|
||||
{:ok, assign(socket, :page_title, "Contact")}
|
||||
end
|
||||
|
||||
@impl true
|
||||
|
||||
@ -1,32 +1,10 @@
|
||||
defmodule SimpleshopThemeWeb.ShopLive.Content do
|
||||
use SimpleshopThemeWeb, :live_view
|
||||
|
||||
alias SimpleshopTheme.{Settings, Media}
|
||||
alias SimpleshopTheme.Theme.{CSSCache, CSSGenerator, PreviewData}
|
||||
alias SimpleshopTheme.Theme.PreviewData
|
||||
|
||||
@impl true
|
||||
def mount(_params, _session, socket) do
|
||||
theme_settings = Settings.get_theme_settings()
|
||||
|
||||
generated_css =
|
||||
case CSSCache.get() do
|
||||
{:ok, css} ->
|
||||
css
|
||||
|
||||
:miss ->
|
||||
css = CSSGenerator.generate(theme_settings)
|
||||
CSSCache.put(css)
|
||||
css
|
||||
end
|
||||
|
||||
socket =
|
||||
socket
|
||||
|> assign(:theme_settings, theme_settings)
|
||||
|> assign(:generated_css, generated_css)
|
||||
|> assign(:logo_image, Media.get_logo())
|
||||
|> assign(:header_image, Media.get_header())
|
||||
|> assign(:mode, :shop)
|
||||
|
||||
{:ok, socket}
|
||||
end
|
||||
|
||||
|
||||
@ -1,28 +1,10 @@
|
||||
defmodule SimpleshopThemeWeb.ShopLive.Home do
|
||||
use SimpleshopThemeWeb, :live_view
|
||||
|
||||
alias SimpleshopTheme.Settings
|
||||
alias SimpleshopTheme.Media
|
||||
alias SimpleshopTheme.Theme.{CSSCache, CSSGenerator, PreviewData}
|
||||
alias SimpleshopTheme.Theme.PreviewData
|
||||
|
||||
@impl true
|
||||
def mount(_params, _session, socket) do
|
||||
theme_settings = Settings.get_theme_settings()
|
||||
|
||||
generated_css =
|
||||
case CSSCache.get() do
|
||||
{:ok, css} ->
|
||||
css
|
||||
|
||||
:miss ->
|
||||
css = CSSGenerator.generate(theme_settings)
|
||||
CSSCache.put(css)
|
||||
css
|
||||
end
|
||||
|
||||
logo_image = Media.get_logo()
|
||||
header_image = Media.get_header()
|
||||
|
||||
preview_data = %{
|
||||
products: PreviewData.products(),
|
||||
categories: PreviewData.categories()
|
||||
@ -31,12 +13,7 @@ defmodule SimpleshopThemeWeb.ShopLive.Home do
|
||||
socket =
|
||||
socket
|
||||
|> assign(:page_title, "Home")
|
||||
|> assign(:theme_settings, theme_settings)
|
||||
|> assign(:generated_css, generated_css)
|
||||
|> assign(:logo_image, logo_image)
|
||||
|> assign(:header_image, header_image)
|
||||
|> assign(:preview_data, preview_data)
|
||||
|> assign(:mode, :shop)
|
||||
|
||||
{:ok, socket}
|
||||
end
|
||||
|
||||
@ -2,28 +2,10 @@ defmodule SimpleshopThemeWeb.ShopLive.ProductShow do
|
||||
use SimpleshopThemeWeb, :live_view
|
||||
|
||||
alias SimpleshopTheme.Cart
|
||||
alias SimpleshopTheme.Settings
|
||||
alias SimpleshopTheme.Media
|
||||
alias SimpleshopTheme.Theme.{CSSCache, CSSGenerator, PreviewData}
|
||||
alias SimpleshopTheme.Theme.PreviewData
|
||||
|
||||
@impl true
|
||||
def mount(%{"id" => id}, _session, socket) do
|
||||
theme_settings = Settings.get_theme_settings()
|
||||
|
||||
generated_css =
|
||||
case CSSCache.get() do
|
||||
{:ok, css} ->
|
||||
css
|
||||
|
||||
:miss ->
|
||||
css = CSSGenerator.generate(theme_settings)
|
||||
CSSCache.put(css)
|
||||
css
|
||||
end
|
||||
|
||||
logo_image = Media.get_logo()
|
||||
header_image = Media.get_header()
|
||||
|
||||
products = PreviewData.products()
|
||||
|
||||
# Find product by slug or ID (real products use slugs, mock data uses string IDs)
|
||||
@ -53,15 +35,10 @@ defmodule SimpleshopThemeWeb.ShopLive.ProductShow do
|
||||
socket =
|
||||
socket
|
||||
|> assign(:page_title, product.name)
|
||||
|> assign(:theme_settings, theme_settings)
|
||||
|> assign(:generated_css, generated_css)
|
||||
|> assign(:logo_image, logo_image)
|
||||
|> assign(:header_image, header_image)
|
||||
|> assign(:product, product)
|
||||
|> assign(:gallery_images, gallery_images)
|
||||
|> assign(:related_products, related_products)
|
||||
|> assign(:quantity, 1)
|
||||
|> assign(:mode, :shop)
|
||||
|> assign(:option_types, option_types)
|
||||
|> assign(:variants, variants)
|
||||
|> assign(:selected_options, selected_options)
|
||||
|
||||
@ -32,7 +32,10 @@ defmodule SimpleshopThemeWeb.Router do
|
||||
|
||||
live_session :public_shop,
|
||||
layout: {SimpleshopThemeWeb.Layouts, :shop},
|
||||
on_mount: [{SimpleshopThemeWeb.CartHook, :mount_cart}] do
|
||||
on_mount: [
|
||||
{SimpleshopThemeWeb.ThemeHook, :mount_theme},
|
||||
{SimpleshopThemeWeb.CartHook, :mount_cart}
|
||||
] do
|
||||
live "/", ShopLive.Home, :index
|
||||
live "/about", ShopLive.Content, :about
|
||||
live "/delivery", ShopLive.Content, :delivery
|
||||
|
||||
38
lib/simpleshop_theme_web/theme_hook.ex
Normal file
38
lib/simpleshop_theme_web/theme_hook.ex
Normal file
@ -0,0 +1,38 @@
|
||||
defmodule SimpleshopThemeWeb.ThemeHook do
|
||||
@moduledoc """
|
||||
LiveView on_mount hook for theme settings, CSS, and media assigns.
|
||||
|
||||
Mounted in the public_shop live_session alongside CartHook.
|
||||
Eliminates the identical theme-loading boilerplate from every shop LiveView.
|
||||
"""
|
||||
|
||||
import Phoenix.Component, only: [assign: 3]
|
||||
|
||||
alias SimpleshopTheme.{Settings, Media}
|
||||
alias SimpleshopTheme.Theme.{CSSCache, CSSGenerator}
|
||||
|
||||
def on_mount(:mount_theme, _params, _session, socket) do
|
||||
theme_settings = Settings.get_theme_settings()
|
||||
|
||||
generated_css =
|
||||
case CSSCache.get() do
|
||||
{:ok, css} ->
|
||||
css
|
||||
|
||||
:miss ->
|
||||
css = CSSGenerator.generate(theme_settings)
|
||||
CSSCache.put(css)
|
||||
css
|
||||
end
|
||||
|
||||
socket =
|
||||
socket
|
||||
|> assign(:theme_settings, theme_settings)
|
||||
|> assign(:generated_css, generated_css)
|
||||
|> assign(:logo_image, Media.get_logo())
|
||||
|> assign(:header_image, Media.get_header())
|
||||
|> assign(:mode, :shop)
|
||||
|
||||
{:cont, socket}
|
||||
end
|
||||
end
|
||||
Loading…
Reference in New Issue
Block a user