diff --git a/lib/simpleshop_theme_web/live/shop_live/collection.ex b/lib/simpleshop_theme_web/live/shop_live/collection.ex index a30a6fa..8e940c9 100644 --- a/lib/simpleshop_theme_web/live/shop_live/collection.ex +++ b/lib/simpleshop_theme_web/live/shop_live/collection.ex @@ -5,6 +5,15 @@ defmodule SimpleshopThemeWeb.ShopLive.Collection do alias SimpleshopTheme.Media alias SimpleshopTheme.Theme.{CSSCache, CSSGenerator, 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 theme_settings = Settings.get_theme_settings() @@ -32,40 +41,62 @@ defmodule SimpleshopThemeWeb.ShopLive.Collection do |> assign(:cart_count, 0) |> assign(:cart_subtotal, "£0.00") |> assign(:categories, PreviewData.categories()) + |> assign(:sort_options, @sort_options) + |> assign(:current_sort, "featured") {:ok, socket} end @impl true - def handle_params(%{"slug" => "all"}, _uri, socket) do - {:noreply, - socket - |> assign(:page_title, "All Products") - |> assign(:collection_title, "All Products") - |> assign(:current_category, nil) - |> assign(:products, PreviewData.products())} - end + def handle_params(%{"slug" => slug} = params, _uri, socket) do + sort = params["sort"] || "featured" - def handle_params(%{"slug" => slug}, _uri, socket) do - case PreviewData.category_by_slug(slug) do - nil -> + 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")} - - category -> - products = PreviewData.products_by_category(slug) - - {:noreply, - socket - |> assign(:page_title, category.name) - |> assign(:collection_title, category.name) - |> assign(:current_category, category) - |> assign(:products, products)} end end + defp load_collection("all") do + {:ok, "All Products", nil, PreviewData.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 = if socket.assigns.current_category, do: socket.assigns.current_category.slug, else: "all" + {: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.price) + defp sort_products(products, "price_desc"), do: Enum.sort_by(products, & &1.price, :desc) + defp sort_products(products, "name_asc"), do: Enum.sort_by(products, & &1.name) + defp sort_products(products, "name_desc"), do: Enum.sort_by(products, & &1.name, :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""" @@ -92,7 +123,12 @@ defmodule SimpleshopThemeWeb.ShopLive.Collection do />