defmodule AmmopricesWeb.HomeLive do @moduledoc false use AmmopricesWeb, :live_view import AmmopricesWeb.PriceComponents alias Ammoprices.Catalog alias Ammoprices.Prices @categories [ %{id: "handgun", label: "Handgun"}, %{id: "rifle", label: "Rifle"}, %{id: "rimfire", label: "Rimfire"}, %{id: "shotgun", label: "Shotgun"} ] @impl true def mount(_params, _session, socket) do if connected?(socket) do Phoenix.PubSub.subscribe(Ammoprices.PubSub, "prices:updated") end calibers = Catalog.list_calibers() grouped = calibers |> Enum.group_by(& &1.category) |> Map.new(fn {cat, cals} -> {cat, Enum.sort_by(cals, & &1.name)} end) {:ok, socket |> assign( page_title: "AmmoCPR", categories: @categories, calibers_by_category: grouped ) |> assign_cheapest_map()} end @impl true def handle_info({:prices_updated, _caliber_ids}, socket) do {:noreply, assign_cheapest_map(socket)} end defp assign_cheapest_map(socket) do cheapest_map = Map.new(Prices.cheapest_per_caliber(), fn r -> {r.caliber_id, r.min_ppr} end) assign(socket, :cheapest_map, cheapest_map) end @impl true def render(assigns) do ~H"""
<%!-- Hero --%>

AmmoCPR

Real-time ammunition prices from top retailers. Find the cheapest rounds, track price history.

<%!-- Category grid --%>

{cat.label}

<.link :for={cal <- Map.get(@calibers_by_category, cat.id, [])} navigate={~p"/calibers/#{cal.slug}"} id={"caliber-#{cal.slug}"} class="group flex items-center justify-between gap-2 px-3 py-2.5 rounded-lg border border-base-300 bg-base-100 hover:border-primary/40 hover:bg-primary/5 transition-all duration-150" > {cal.name} <.price_per_round cents={@cheapest_map[cal.id]} />
""" end end