add pagination across all admin and shop views
All checks were successful
deploy / deploy (push) Successful in 1m38s

URL-based offset pagination with ?page=N for bookmarkable pages.
Admin views use push_patch, shop collection uses navigate links.
Responsive on mobile with horizontal-scroll tables and stacking
pagination controls. Includes dev seed script for testing.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
jamey
2026-03-01 09:42:34 +00:00
parent 7f6fd012a5
commit 3480b326a9
21 changed files with 1485 additions and 211 deletions

View File

@@ -1,7 +1,7 @@
defmodule BerrypodWeb.Shop.Collection do
use BerrypodWeb, :live_view
alias Berrypod.{Pages, Products}
alias Berrypod.{Pages, Pagination, Products}
@sort_options [
{"featured", "Featured"},
@@ -28,18 +28,21 @@ defmodule BerrypodWeb.Shop.Collection do
@impl true
def handle_params(%{"slug" => slug} = params, _uri, socket) do
sort = params["sort"] || "featured"
page_num = Pagination.parse_page(params)
case load_collection(slug, sort) do
{:ok, title, category, products} ->
case load_collection(slug, sort, page_num) do
{:ok, title, category, pagination} ->
{:noreply,
socket
|> assign(:page_title, title)
|> assign(:page_description, collection_description(title))
|> assign(:og_url, BerrypodWeb.Endpoint.url() <> "/collections/#{slug}")
|> assign(:collection_title, title)
|> assign(:collection_slug, slug)
|> assign(:current_category, category)
|> assign(:current_sort, sort)
|> assign(:products, products)}
|> assign(:pagination, pagination)
|> assign(:products, pagination.items)}
:not_found ->
{:noreply,
@@ -49,22 +52,30 @@ defmodule BerrypodWeb.Shop.Collection do
end
end
defp load_collection("all", sort) do
{:ok, "All Products", nil, Products.list_visible_products(sort: sort)}
defp load_collection("all", sort, page) do
pagination = Products.list_visible_products_paginated(sort: sort, page: page)
{:ok, "All Products", nil, pagination}
end
defp load_collection("sale", sort) do
{:ok, "Sale", :sale, Products.list_visible_products(on_sale: true, sort: sort)}
defp load_collection("sale", sort, page) do
pagination = Products.list_visible_products_paginated(on_sale: true, sort: sort, page: page)
{:ok, "Sale", :sale, pagination}
end
defp load_collection(slug, sort) do
defp load_collection(slug, sort, page) do
case Enum.find(Products.list_categories(), &(&1.slug == slug)) do
nil ->
:not_found
category ->
products = Products.list_visible_products(category: category.name, sort: sort)
{:ok, category.name, category, products}
pagination =
Products.list_visible_products_paginated(
category: category.name,
sort: sort,
page: page
)
{:ok, category.name, category, pagination}
end
end