defmodule BerrypodWeb.Admin.Pages.Index do use BerrypodWeb, :live_view alias Berrypod.Pages @page_groups [ {"Marketing", ~w(home about contact)}, {"Legal", ~w(delivery privacy terms)}, {"Shop", ~w(collection pdp cart search)}, {"Orders", ~w(checkout_success orders order_detail)}, {"System", ~w(error)} ] @impl true def mount(_params, _session, socket) do pages = Pages.list_pages() |> Map.new(&{&1.slug, &1}) custom_pages = Pages.list_custom_pages() {:ok, socket |> assign(:page_title, "Pages") |> assign(:pages, pages) |> assign(:custom_pages, custom_pages) |> assign(:page_groups, @page_groups)} end @impl true def handle_event("delete_custom_page", %{"slug" => slug}, socket) do case Pages.get_page_struct(slug) do %{type: "custom"} = page -> {:ok, _} = Pages.delete_custom_page(page) {:noreply, socket |> assign(:custom_pages, Pages.list_custom_pages()) |> put_flash(:info, "Page deleted")} _ -> {:noreply, put_flash(socket, :error, "Page not found")} end end @impl true def handle_event("duplicate_custom_page", %{"slug" => slug}, socket) do case Pages.get_page_struct(slug) do %{type: "custom"} = page -> case Pages.duplicate_custom_page(page) do {:ok, copy} -> {:noreply, socket |> assign(:custom_pages, Pages.list_custom_pages()) |> put_flash(:info, "\"#{copy.title}\" created as draft")} {:error, _} -> {:noreply, put_flash(socket, :error, "Failed to duplicate page")} end _ -> {:noreply, put_flash(socket, :error, "Page not found")} end end @impl true def render(assigns) do ~H""" <.header> Pages <:subtitle>Customise the layout and content of every page on your shop. <:actions> <.link navigate={~p"/admin/pages/new"} class="admin-btn admin-btn-sm admin-btn-primary"> <.icon name="hero-plus" class="size-4" /> New page

{group_name}

<.link :for={slug <- slugs} navigate={~p"/admin/pages/#{slug}"} class="page-card" > <.icon name={page_icon(slug)} class="size-5" /> {@pages[slug].title} {length(@pages[slug].blocks)} {if length(@pages[slug].blocks) == 1, do: "block", else: "blocks"} <.icon name="hero-chevron-right-mini" class="size-4 page-card-arrow" />

Custom pages

<.link navigate={~p"/admin/pages/#{page.slug}"} class="page-card-link"> <.icon name="hero-document" class="size-5" /> {page.title} Draft /{page.slug} ยท {length(page.blocks)} {if length(page.blocks) == 1, do: "block", else: "blocks"} <.icon name="hero-chevron-right-mini" class="size-4 page-card-arrow" />
""" end defp page_icon("home"), do: "hero-home" defp page_icon("about"), do: "hero-user" defp page_icon("contact"), do: "hero-envelope" defp page_icon("delivery"), do: "hero-truck" defp page_icon("privacy"), do: "hero-shield-check" defp page_icon("terms"), do: "hero-document-text" defp page_icon("collection"), do: "hero-tag" defp page_icon("pdp"), do: "hero-cube" defp page_icon("cart"), do: "hero-shopping-cart" defp page_icon("search"), do: "hero-magnifying-glass" defp page_icon("checkout_success"), do: "hero-check-circle" defp page_icon("orders"), do: "hero-clipboard-document-list" defp page_icon("order_detail"), do: "hero-clipboard-document" defp page_icon("error"), do: "hero-exclamation-triangle" end