defmodule MicrowavepropWeb.QsoLive.Index do @moduledoc false use MicrowavepropWeb, :live_view alias Microwaveprop.Radio @sortable_fields ~w(station1 station2 band mode distance_km qso_timestamp inserted_at) @default_sort_by "qso_timestamp" @default_sort_order "desc" @impl true def mount(_params, _session, socket) do {:ok, socket} end @impl true def handle_params(params, _uri, socket) do page = params |> Map.get("page", "1") |> String.to_integer() |> max(1) sort_by = validate_sort_field(Map.get(params, "sort_by", @default_sort_by)) sort_order = validate_sort_order(Map.get(params, "sort_order", @default_sort_order)) result = Radio.list_qsos( page: page, sort_by: String.to_existing_atom(sort_by), sort_order: String.to_existing_atom(sort_order) ) {:noreply, assign(socket, page_title: "QSOs", page: result.page, total_pages: result.total_pages, total_entries: result.total_entries, qsos: result.entries, sort_by: sort_by, sort_order: sort_order )} end @impl true def handle_event("sort", %{"field" => field}, socket) do field = validate_sort_field(field) new_order = if socket.assigns.sort_by == field && socket.assigns.sort_order == "asc", do: "desc", else: "asc" {:noreply, push_patch(socket, to: ~p"/qsos?sort_by=#{field}&sort_order=#{new_order}")} end defp validate_sort_field(field) when field in @sortable_fields, do: field defp validate_sort_field(_), do: @default_sort_by defp validate_sort_order(order) when order in ~w(asc desc), do: order defp validate_sort_order(_), do: @default_sort_order @impl true def render(assigns) do ~H""" <.header> QSOs <:subtitle>{@total_entries} contacts <:actions> <.link navigate={~p"/submit"} class="btn btn-primary"> <.icon name="hero-plus" class="w-5 h-5" /> Submit QSO <.table id="qsos" rows={@qsos} row_id={fn qso -> "qso-#{qso.id}" end} row_click={fn qso -> JS.navigate(~p"/qsos/#{qso.id}") end} sort_by={@sort_by} sort_order={@sort_order} > <:col :let={qso} label="Station 1" sort_field="station1">{qso.station1} <:col :let={qso} label="Grid 1">{qso.grid1 || "—"} <:col :let={qso} label="Station 2" sort_field="station2">{qso.station2} <:col :let={qso} label="Grid 2">{qso.grid2 || "—"} <:col :let={qso} label="Band" sort_field="band">{qso.band} <:col :let={qso} label="Mode" sort_field="mode">{qso.mode} <:col :let={qso} label="Distance (km)" sort_field="distance_km">{qso.distance_km} <:col :let={qso} label="Timestamp" sort_field="qso_timestamp"> {Calendar.strftime(qso.qso_timestamp, "%Y-%m-%d %H:%M")} <:col :let={qso} label="Committed" sort_field="inserted_at"> {Calendar.strftime(qso.inserted_at, "%Y-%m-%d %H:%M")}
<.link :if={@page > 1} patch={~p"/qsos?page=#{@page - 1}&sort_by=#{@sort_by}&sort_order=#{@sort_order}"} class="btn btn-sm btn-outline" > <.icon name="hero-chevron-left" class="w-4 h-4" /> Previous Page {@page} of {@total_pages} <.link :if={@page < @total_pages} patch={~p"/qsos?page=#{@page + 1}&sort_by=#{@sort_by}&sort_order=#{@sort_order}"} class="btn btn-sm btn-outline" > Next <.icon name="hero-chevron-right" class="w-4 h-4" /> = @total_pages} />
""" end end