defmodule BerrypodWeb.Shop.Pages.Collection do @moduledoc """ Collection page handler for the unified Shop.Page LiveView. """ import Phoenix.Component, only: [assign: 3] import Phoenix.LiveView, only: [push_patch: 2, push_navigate: 2, put_flash: 3] alias Berrypod.{Pages, Pagination, Products} @sort_options [ {"featured", "Featured"}, {"newest", "Newest"}, {"price_asc", "Price: Low to High"}, {"price_desc", "Price: High to Low"}, {"name_asc", "Name: A-Z"}, {"name_desc", "Name: Z-A"} ] def init(socket, _params, _uri) do page = Pages.get_page("collection") socket = socket |> assign(:page, page) |> assign(:sort_options, @sort_options) |> assign(:current_sort, "featured") {:noreply, socket} end def handle_params(%{"slug" => slug} = params, _uri, socket) do sort = params["sort"] || "featured" page_num = Pagination.parse_page(params) case load_collection(slug, sort, page_num) do {:ok, title, category, pagination} -> socket = 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(:pagination, pagination) |> assign(:products, pagination.items) {:noreply, socket} :not_found -> socket = socket |> put_flash(:error, "Collection not found") |> push_navigate(to: "/collections/all") {:noreply, socket} end end def handle_event("sort_changed", %{"sort" => sort}, socket) do slug = case socket.assigns.current_category do nil -> "all" :sale -> "sale" category -> category.slug end {:noreply, push_patch(socket, to: "/collections/#{slug}?sort=#{sort}")} end def handle_event(_event, _params, _socket), do: :cont 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, 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, page) do case Enum.find(Products.list_categories(), &(&1.slug == slug)) do nil -> :not_found category -> pagination = Products.list_visible_products_paginated( category: category.name, sort: sort, page: page ) {:ok, category.name, category, pagination} end end defp collection_description("All Products"), do: "Browse our full range of products." defp collection_description("Sale"), do: "Browse our current sale items." defp collection_description(title), do: "Browse our #{String.downcase(title)} collection." end