defmodule MicrowavepropWeb.ContactLive.Index do @moduledoc false use MicrowavepropWeb, :live_view use LiveTable.LiveResource, schema: Microwaveprop.Radio.Contact def table_options do %{sorting: %{default_sort: [inserted_at: :desc]}} end def fields do [ id: %{label: "ID", hidden: true}, station1: %{label: "Station 1", sortable: true, searchable: true}, grid1: %{label: "Grid 1", sortable: true, searchable: true}, station2: %{label: "Station 2", sortable: true, searchable: true}, grid2: %{label: "Grid 2", sortable: true, searchable: true}, band: %{label: "Band", sortable: true, renderer: &band_cell/1}, mode: %{label: "Mode", sortable: true, searchable: true}, distance_km: %{label: "Distance (km)", sortable: true}, hrrr_status: %{label: "Enriched", renderer: &enrichment_cell/2}, flagged_invalid: %{label: "Flag", renderer: &flag_cell/1}, qso_timestamp: %{label: "QSO (UTC)", sortable: true, renderer: &format_ts/1}, inserted_at: %{label: "Added (UTC)", sortable: true, renderer: &format_ts/1} ] end def filters, do: [] def actions do [ view: fn %{record: contact} -> assigns = %{contact: contact} ~H""" <.link navigate={~p"/contacts/#{@contact.id}"} class="btn btn-xs btn-ghost"> View """ end ] end @impl true def mount(_params, _session, socket) do {:ok, assign(socket, :page_title, "Contacts")} end @enrichment_fields [ {:hrrr_status, "HRRR"}, {:weather_status, "Weather"}, {:terrain_status, "Terrain"}, {:iemre_status, "IEMRE"} ] @done_statuses [:complete, :unavailable] defp enrichment_cell(_value, contact) do details = Enum.map(@enrichment_fields, fn {field, name} -> {name, Map.get(contact, field)} end) done = Enum.count(details, fn {_, s} -> s in @done_statuses end) failed = Enum.count(details, fn {_, s} -> s == :failed end) {label, class} = cond do done == 4 -> {"Complete", "badge-success"} failed > 0 -> {"Failed", "badge-error"} done > 0 -> {"Partial", "badge-warning"} true -> {"Pending", "badge-ghost"} end tooltip = Enum.map_join(details, ", ", fn {name, status} -> "#{name}: #{status}" end) assigns = %{label: label, class: class, tooltip: tooltip} ~H""" {@label} """ end defp band_cell(nil), do: "" defp band_cell(%Decimal{} = d), do: Decimal.to_string(d, :normal) defp band_cell(other), do: to_string(other) defp flag_cell(true) do assigns = %{} ~H""" ! """ end defp flag_cell(_), do: "" defp format_ts(nil), do: "" defp format_ts(%DateTime{} = dt), do: Calendar.strftime(dt, "%Y-%m-%d %H:%M") defp format_ts(%NaiveDateTime{} = dt), do: Calendar.strftime(dt, "%Y-%m-%d %H:%M") defp format_ts(other), do: to_string(other) @impl true def render(assigns) do ~H""" <.header> Contacts <:subtitle>Sort or search by callsign, grid, or mode. <:actions> <.link navigate={~p"/submit"} class="btn btn-primary"> <.icon name="hero-plus" class="w-5 h-5" /> Submit Contact <.live_table fields={fields()} filters={filters()} options={@options} streams={@streams} actions={actions()} /> """ end end