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
|
use SimpleshopThemeWeb, :live_view
|
||||||
|
|
||||||
alias SimpleshopTheme.Cart
|
alias SimpleshopTheme.Cart
|
||||||
alias SimpleshopTheme.Settings
|
|
||||||
alias SimpleshopTheme.Media
|
|
||||||
alias SimpleshopTheme.Theme.{CSSCache, CSSGenerator}
|
|
||||||
|
|
||||||
@impl true
|
@impl true
|
||||||
def mount(_params, _session, socket) do
|
def mount(_params, _session, socket) do
|
||||||
theme_settings = Settings.get_theme_settings()
|
{:ok, assign(socket, :page_title, "Cart")}
|
||||||
|
|
||||||
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}
|
|
||||||
end
|
end
|
||||||
|
|
||||||
@impl true
|
@impl true
|
||||||
|
|||||||
@ -1,27 +1,10 @@
|
|||||||
defmodule SimpleshopThemeWeb.ShopLive.CheckoutSuccess do
|
defmodule SimpleshopThemeWeb.ShopLive.CheckoutSuccess do
|
||||||
use SimpleshopThemeWeb, :live_view
|
use SimpleshopThemeWeb, :live_view
|
||||||
|
|
||||||
alias SimpleshopTheme.{Orders, Settings, Media}
|
alias SimpleshopTheme.Orders
|
||||||
alias SimpleshopTheme.Theme.{CSSCache, CSSGenerator}
|
|
||||||
|
|
||||||
@impl true
|
@impl true
|
||||||
def mount(%{"session_id" => session_id}, _session, socket) do
|
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)
|
order = Orders.get_order_by_stripe_session(session_id)
|
||||||
|
|
||||||
# Subscribe to order status updates (webhook may arrive after redirect)
|
# 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
|
# Clear the cart after successful checkout
|
||||||
socket =
|
socket =
|
||||||
if order && connected?(socket) do
|
if order && connected?(socket) do
|
||||||
empty_cart = []
|
SimpleshopThemeWeb.CartHook.broadcast_and_update(socket, [])
|
||||||
|
|
||||||
socket
|
|
||||||
|> SimpleshopThemeWeb.CartHook.broadcast_and_update(empty_cart)
|
|
||||||
else
|
else
|
||||||
socket
|
socket
|
||||||
end
|
end
|
||||||
@ -43,11 +23,6 @@ defmodule SimpleshopThemeWeb.ShopLive.CheckoutSuccess do
|
|||||||
socket =
|
socket =
|
||||||
socket
|
socket
|
||||||
|> assign(:page_title, "Order confirmed")
|
|> 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)
|
|> assign(:order, order)
|
||||||
|
|
||||||
{:ok, socket}
|
{:ok, socket}
|
||||||
|
|||||||
@ -1,9 +1,7 @@
|
|||||||
defmodule SimpleshopThemeWeb.ShopLive.Collection do
|
defmodule SimpleshopThemeWeb.ShopLive.Collection do
|
||||||
use SimpleshopThemeWeb, :live_view
|
use SimpleshopThemeWeb, :live_view
|
||||||
|
|
||||||
alias SimpleshopTheme.Settings
|
alias SimpleshopTheme.Theme.PreviewData
|
||||||
alias SimpleshopTheme.Media
|
|
||||||
alias SimpleshopTheme.Theme.{CSSCache, CSSGenerator, PreviewData}
|
|
||||||
|
|
||||||
@sort_options [
|
@sort_options [
|
||||||
{"featured", "Featured"},
|
{"featured", "Featured"},
|
||||||
@ -16,29 +14,8 @@ defmodule SimpleshopThemeWeb.ShopLive.Collection do
|
|||||||
|
|
||||||
@impl true
|
@impl true
|
||||||
def mount(_params, _session, socket) do
|
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 =
|
||||||
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(:categories, PreviewData.categories())
|
||||||
|> assign(:sort_options, @sort_options)
|
|> assign(:sort_options, @sort_options)
|
||||||
|> assign(:current_sort, "featured")
|
|> assign(:current_sort, "featured")
|
||||||
|
|||||||
@ -1,38 +1,9 @@
|
|||||||
defmodule SimpleshopThemeWeb.ShopLive.Contact do
|
defmodule SimpleshopThemeWeb.ShopLive.Contact do
|
||||||
use SimpleshopThemeWeb, :live_view
|
use SimpleshopThemeWeb, :live_view
|
||||||
|
|
||||||
alias SimpleshopTheme.Settings
|
|
||||||
alias SimpleshopTheme.Media
|
|
||||||
alias SimpleshopTheme.Theme.{CSSCache, CSSGenerator}
|
|
||||||
|
|
||||||
@impl true
|
@impl true
|
||||||
def mount(_params, _session, socket) do
|
def mount(_params, _session, socket) do
|
||||||
theme_settings = Settings.get_theme_settings()
|
{:ok, assign(socket, :page_title, "Contact")}
|
||||||
|
|
||||||
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}
|
|
||||||
end
|
end
|
||||||
|
|
||||||
@impl true
|
@impl true
|
||||||
|
|||||||
@ -1,32 +1,10 @@
|
|||||||
defmodule SimpleshopThemeWeb.ShopLive.Content do
|
defmodule SimpleshopThemeWeb.ShopLive.Content do
|
||||||
use SimpleshopThemeWeb, :live_view
|
use SimpleshopThemeWeb, :live_view
|
||||||
|
|
||||||
alias SimpleshopTheme.{Settings, Media}
|
alias SimpleshopTheme.Theme.PreviewData
|
||||||
alias SimpleshopTheme.Theme.{CSSCache, CSSGenerator, PreviewData}
|
|
||||||
|
|
||||||
@impl true
|
@impl true
|
||||||
def mount(_params, _session, socket) do
|
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}
|
{:ok, socket}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@ -1,28 +1,10 @@
|
|||||||
defmodule SimpleshopThemeWeb.ShopLive.Home do
|
defmodule SimpleshopThemeWeb.ShopLive.Home do
|
||||||
use SimpleshopThemeWeb, :live_view
|
use SimpleshopThemeWeb, :live_view
|
||||||
|
|
||||||
alias SimpleshopTheme.Settings
|
alias SimpleshopTheme.Theme.PreviewData
|
||||||
alias SimpleshopTheme.Media
|
|
||||||
alias SimpleshopTheme.Theme.{CSSCache, CSSGenerator, PreviewData}
|
|
||||||
|
|
||||||
@impl true
|
@impl true
|
||||||
def mount(_params, _session, socket) do
|
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 = %{
|
preview_data = %{
|
||||||
products: PreviewData.products(),
|
products: PreviewData.products(),
|
||||||
categories: PreviewData.categories()
|
categories: PreviewData.categories()
|
||||||
@ -31,12 +13,7 @@ defmodule SimpleshopThemeWeb.ShopLive.Home do
|
|||||||
socket =
|
socket =
|
||||||
socket
|
socket
|
||||||
|> assign(:page_title, "Home")
|
|> 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(:preview_data, preview_data)
|
||||||
|> assign(:mode, :shop)
|
|
||||||
|
|
||||||
{:ok, socket}
|
{:ok, socket}
|
||||||
end
|
end
|
||||||
|
|||||||
@ -2,28 +2,10 @@ defmodule SimpleshopThemeWeb.ShopLive.ProductShow do
|
|||||||
use SimpleshopThemeWeb, :live_view
|
use SimpleshopThemeWeb, :live_view
|
||||||
|
|
||||||
alias SimpleshopTheme.Cart
|
alias SimpleshopTheme.Cart
|
||||||
alias SimpleshopTheme.Settings
|
alias SimpleshopTheme.Theme.PreviewData
|
||||||
alias SimpleshopTheme.Media
|
|
||||||
alias SimpleshopTheme.Theme.{CSSCache, CSSGenerator, PreviewData}
|
|
||||||
|
|
||||||
@impl true
|
@impl true
|
||||||
def mount(%{"id" => id}, _session, socket) do
|
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()
|
products = PreviewData.products()
|
||||||
|
|
||||||
# Find product by slug or ID (real products use slugs, mock data uses string IDs)
|
# 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 =
|
||||||
socket
|
socket
|
||||||
|> assign(:page_title, product.name)
|
|> 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(:product, product)
|
||||||
|> assign(:gallery_images, gallery_images)
|
|> assign(:gallery_images, gallery_images)
|
||||||
|> assign(:related_products, related_products)
|
|> assign(:related_products, related_products)
|
||||||
|> assign(:quantity, 1)
|
|> assign(:quantity, 1)
|
||||||
|> assign(:mode, :shop)
|
|
||||||
|> assign(:option_types, option_types)
|
|> assign(:option_types, option_types)
|
||||||
|> assign(:variants, variants)
|
|> assign(:variants, variants)
|
||||||
|> assign(:selected_options, selected_options)
|
|> assign(:selected_options, selected_options)
|
||||||
|
|||||||
@ -32,7 +32,10 @@ defmodule SimpleshopThemeWeb.Router do
|
|||||||
|
|
||||||
live_session :public_shop,
|
live_session :public_shop,
|
||||||
layout: {SimpleshopThemeWeb.Layouts, :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 "/", ShopLive.Home, :index
|
||||||
live "/about", ShopLive.Content, :about
|
live "/about", ShopLive.Content, :about
|
||||||
live "/delivery", ShopLive.Content, :delivery
|
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