wire collection, PDP, cart, and search pages to page renderer
Stage 4 of the page builder: all shop pages now render via PageRenderer instead of inline templates or PageTemplates. - Collection: full filter bar moved to renderer (category pills, sort dropdown, CollectionFilters hook, empty state) - PDP: related_products and reviews loaded via block data loaders instead of manual queries - Cart: page definition loaded in mount, subtotal computed in render - Search: page definition loaded in mount, handle_params unchanged - Added Phoenix.VerifiedRoutes to PageRenderer for ~p sigil - Net -55 lines (128 added, 183 removed) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -10,6 +10,11 @@ defmodule BerrypodWeb.PageRenderer do
|
||||
use Phoenix.Component
|
||||
use BerrypodWeb.ShopComponents
|
||||
|
||||
use Phoenix.VerifiedRoutes,
|
||||
endpoint: BerrypodWeb.Endpoint,
|
||||
router: BerrypodWeb.Router,
|
||||
statics: BerrypodWeb.static_paths()
|
||||
|
||||
alias Berrypod.Cart
|
||||
|
||||
# ── Public API ──────────────────────────────────────────────────
|
||||
@@ -263,14 +268,85 @@ defmodule BerrypodWeb.PageRenderer do
|
||||
end
|
||||
|
||||
defp render_block(%{block: %{"type" => "filter_bar"}} = assigns) do
|
||||
current_slug =
|
||||
case assigns[:current_category] do
|
||||
:sale -> "sale"
|
||||
nil -> nil
|
||||
cat -> cat.slug
|
||||
end
|
||||
|
||||
assigns =
|
||||
assigns
|
||||
|> assign(:current_slug, current_slug)
|
||||
|> assign(:current_sort, assigns[:current_sort] || "featured")
|
||||
|> assign(:sort_options, assigns[:sort_options] || [])
|
||||
|
||||
~H"""
|
||||
<div class="page-container">
|
||||
<.filter_bar categories={assigns[:categories] || []} />
|
||||
<div class="filter-bar">
|
||||
<nav
|
||||
aria-label="Collection filters"
|
||||
id="collection-filters"
|
||||
phx-hook="CollectionFilters"
|
||||
class="collection-filters"
|
||||
>
|
||||
<ul class="collection-filter-pills">
|
||||
<li>
|
||||
<.link
|
||||
navigate={collection_path("all", @current_sort)}
|
||||
aria-current={@current_slug == nil && "page"}
|
||||
class={["collection-filter-pill", @current_slug == nil && "active"]}
|
||||
>
|
||||
All
|
||||
</.link>
|
||||
</li>
|
||||
<li>
|
||||
<.link
|
||||
navigate={collection_path("sale", @current_sort)}
|
||||
aria-current={@current_slug == "sale" && "page"}
|
||||
class={["collection-filter-pill", @current_slug == "sale" && "active"]}
|
||||
>
|
||||
Sale
|
||||
</.link>
|
||||
</li>
|
||||
<%= for category <- assigns[:categories] || [] do %>
|
||||
<li>
|
||||
<.link
|
||||
navigate={collection_path(category.slug, @current_sort)}
|
||||
aria-current={@current_slug == category.slug && "page"}
|
||||
class={["collection-filter-pill", @current_slug == category.slug && "active"]}
|
||||
>
|
||||
{category.name}
|
||||
</.link>
|
||||
</li>
|
||||
<% end %>
|
||||
</ul>
|
||||
</nav>
|
||||
|
||||
<form
|
||||
action={~p"/collections/#{@current_slug || "all"}"}
|
||||
method="get"
|
||||
phx-change="sort_changed"
|
||||
>
|
||||
<.shop_select
|
||||
name="sort"
|
||||
options={@sort_options}
|
||||
selected={@current_sort}
|
||||
aria-label="Sort products"
|
||||
/>
|
||||
<noscript>
|
||||
<button type="submit" class="themed-button collection-sort-submit">Sort</button>
|
||||
</noscript>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
"""
|
||||
end
|
||||
|
||||
defp render_block(%{block: %{"type" => "product_grid"}} = assigns) do
|
||||
show_category = assigns[:current_category] in [nil, :sale]
|
||||
assigns = assign(assigns, :show_category, show_category)
|
||||
|
||||
~H"""
|
||||
<div class="page-container">
|
||||
<.product_grid theme_settings={@theme_settings}>
|
||||
@@ -280,10 +356,19 @@ defmodule BerrypodWeb.PageRenderer do
|
||||
theme_settings={@theme_settings}
|
||||
mode={@mode}
|
||||
variant={:default}
|
||||
show_category={true}
|
||||
show_category={@show_category}
|
||||
/>
|
||||
<% end %>
|
||||
</.product_grid>
|
||||
|
||||
<%= if (assigns[:products] || []) == [] do %>
|
||||
<div class="collection-empty">
|
||||
<p>No products found in this collection.</p>
|
||||
<.link navigate={~p"/collections/all"} class="collection-empty-link">
|
||||
View all products
|
||||
</.link>
|
||||
</div>
|
||||
<% end %>
|
||||
</div>
|
||||
"""
|
||||
end
|
||||
@@ -722,6 +807,7 @@ defmodule BerrypodWeb.PageRenderer do
|
||||
def page_main_class("orders"), do: "page-container orders-main"
|
||||
def page_main_class("order_detail"), do: "page-container order-detail-main"
|
||||
def page_main_class("error"), do: "error-main"
|
||||
def page_main_class("collection"), do: nil
|
||||
def page_main_class("pdp"), do: "page-container"
|
||||
def page_main_class("search"), do: "page-container"
|
||||
def page_main_class("about"), do: "content-page"
|
||||
@@ -767,6 +853,9 @@ defmodule BerrypodWeb.PageRenderer do
|
||||
|
||||
defp breadcrumb_items(_), do: []
|
||||
|
||||
defp collection_path(slug, "featured"), do: ~p"/collections/#{slug}"
|
||||
defp collection_path(slug, sort), do: ~p"/collections/#{slug}?sort=#{sort}"
|
||||
|
||||
# Reuse from PageTemplates
|
||||
def format_order_status("unfulfilled"), do: "Being prepared"
|
||||
def format_order_status("submitted"), do: "Sent to printer"
|
||||
|
||||
Reference in New Issue
Block a user