defmodule SimpleshopThemeWeb.Shop.Collection do use SimpleshopThemeWeb, :live_view alias SimpleshopTheme.Theme.PreviewData @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"} ] @impl true def mount(_params, _session, socket) do socket = socket |> assign(:categories, PreviewData.categories()) |> assign(:sort_options, @sort_options) |> assign(:current_sort, "featured") {:ok, socket} end @impl true def handle_params(%{"slug" => slug} = params, _uri, socket) do sort = params["sort"] || "featured" case load_collection(slug) do {:ok, title, category, products} -> {:noreply, socket |> assign(:page_title, title) |> assign(:collection_title, title) |> assign(:current_category, category) |> assign(:current_sort, sort) |> assign(:products, sort_products(products, sort))} :not_found -> {:noreply, socket |> put_flash(:error, "Collection not found") |> push_navigate(to: ~p"/collections/all")} end end defp load_collection("all") do {:ok, "All Products", nil, PreviewData.products()} end defp load_collection("sale") do sale_products = Enum.filter(PreviewData.products(), & &1.on_sale) {:ok, "Sale", :sale, sale_products} end defp load_collection(slug) do case PreviewData.category_by_slug(slug) do nil -> :not_found category -> {:ok, category.name, category, PreviewData.products_by_category(slug)} end end @impl true 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: ~p"/collections/#{slug}?sort=#{sort}")} end defp sort_products(products, "featured"), do: products defp sort_products(products, "newest"), do: Enum.reverse(products) defp sort_products(products, "price_asc"), do: Enum.sort_by(products, & &1.cheapest_price) defp sort_products(products, "price_desc"), do: Enum.sort_by(products, & &1.cheapest_price, :desc) defp sort_products(products, "name_asc"), do: Enum.sort_by(products, & &1.title) defp sort_products(products, "name_desc"), do: Enum.sort_by(products, & &1.title, :desc) defp sort_products(products, _), do: products defp collection_path(slug, "featured"), do: ~p"/collections/#{slug}" defp collection_path(slug, sort), do: ~p"/collections/#{slug}?sort=#{sort}" @impl true def render(assigns) do ~H""" <.shop_layout theme_settings={@theme_settings} logo_image={@logo_image} header_image={@header_image} mode={@mode} cart_items={@cart_items} cart_count={@cart_count} cart_subtotal={@cart_subtotal} cart_drawer_open={@cart_drawer_open} cart_status={assigns[:cart_status]} active_page="collection" >
<.collection_header title={@collection_title} product_count={length(@products)} />
<.collection_filter_bar categories={@categories} current_slug={ case @current_category do :sale -> "sale" nil -> nil cat -> cat.slug end } sort_options={@sort_options} current_sort={@current_sort} /> <.product_grid theme_settings={@theme_settings}> <%= for product <- @products do %> <.product_card product={product} theme_settings={@theme_settings} mode={@mode} variant={:default} show_category={@current_category in [nil, :sale]} /> <% end %> <%= if @products == [] do %>

No products found in this collection.

<.link navigate={~p"/collections/all"} class="mt-4 inline-block underline" style="color: var(--t-text-accent);" > View all products
<% end %>
""" end defp collection_filter_bar(assigns) do ~H"""
<.shop_select name="sort" options={@sort_options} selected={@current_sort} class="px-3 py-1.5 sm:px-4 sm:py-2 text-xs sm:text-sm" aria-label="Sort products" />
""" end end