defmodule MicrowavepropWeb.BeaconLive.Index do @moduledoc false use MicrowavepropWeb, :live_view alias Microwaveprop.Beacons alias Microwaveprop.Beacons.Beacon @impl true def render(assigns) do ~H""" <.header> Beacons <:subtitle>Microwave beacons tracked by NTMS. <:actions> <.button variant="primary" navigate={~p"/beacons/new"}> <.icon name="hero-plus" /> Submit Beacon <.table id="beacons" rows={@streams.beacons} row_click={fn {_id, beacon} -> JS.navigate(~p"/beacons/#{beacon}") end} > <:col :let={{_id, beacon}} label="Frequency (MHz)"> {Beacon.format_freq(beacon.frequency_mhz)} <:col :let={{_id, beacon}} label="Call">{beacon.callsign} <:col :let={{_id, beacon}} label="Grid">{beacon.grid} <:col :let={{_id, beacon}} label="Lat">{format_coord(beacon.lat)} <:col :let={{_id, beacon}} label="Lon">{format_coord(beacon.lon)} <:col :let={{_id, beacon}} label="EIRP (mW)">{Beacon.format_mw(beacon.power_mw)} <:col :let={{_id, beacon}} label="Height AGL (ft)">{beacon.height_ft} <:col :let={{_id, beacon}} label="Keying">{Beacon.keying_label(beacon.keying)} <:col :let={{_id, beacon}} label="On air"> {if beacon.on_the_air, do: "Yes", else: "No"} <:action :let={{_id, beacon}}>
<.link navigate={~p"/beacons/#{beacon}"}>Show
<.link :if={admin?(@current_scope)} navigate={~p"/beacons/#{beacon}/edit"}>Edit <:action :let={{id, beacon}}> <.link :if={admin?(@current_scope)} phx-click={JS.push("delete", value: %{id: beacon.id}) |> hide("##{id}")} data-confirm="Delete this beacon?" > Delete
<.header> Pending approval <:subtitle>Submitted beacons waiting for admin review. <.table id="pending-beacons" rows={@streams.pending} row_click={fn {_id, beacon} -> JS.navigate(~p"/beacons/#{beacon}") end} > <:col :let={{_id, beacon}} label="Frequency (MHz)"> {Beacon.format_freq(beacon.frequency_mhz)} <:col :let={{_id, beacon}} label="Call">{beacon.callsign} <:col :let={{_id, beacon}} label="Grid">{beacon.grid} <:col :let={{_id, beacon}} label="EIRP (mW)">{Beacon.format_mw(beacon.power_mw)} <:col :let={{_id, beacon}} label="Height AGL (ft)">{beacon.height_ft} <:col :let={{_id, beacon}} label="Submitted"> {Calendar.strftime(beacon.inserted_at, "%Y-%m-%d %H:%M UTC")} <:action :let={{_id, beacon}}> <.link phx-click={JS.push("approve", value: %{id: beacon.id})} data-confirm="Approve this beacon?" > Approve <:action :let={{id, beacon}}> <.link phx-click={JS.push("delete", value: %{id: beacon.id}) |> hide("##{id}")} data-confirm="Delete this beacon?" > Delete
""" end @impl true def mount(_params, _session, socket) do if connected?(socket), do: Beacons.subscribe_beacons() pending = if admin?(socket.assigns.current_scope) do Beacons.list_pending_beacons() else [] end {:ok, socket |> assign(:page_title, "Beacons") |> assign(:pending, pending) |> stream(:beacons, Beacons.list_beacons()) |> stream(:pending, pending)} end @impl true def handle_event("delete", %{"id" => id}, socket) do if admin?(socket.assigns.current_scope) do beacon = Beacons.get_beacon!(id) {:ok, _} = Beacons.delete_beacon(beacon) {:noreply, socket |> stream_delete(:beacons, beacon) |> stream_delete(:pending, beacon)} else {:noreply, put_flash(socket, :error, "Admins only.")} end end def handle_event("approve", %{"id" => id}, socket) do if admin?(socket.assigns.current_scope) do beacon = Beacons.get_beacon!(id) {:ok, approved} = Beacons.approve_beacon(beacon) {:noreply, socket |> put_flash(:info, "Approved #{approved.callsign}.") |> stream_delete(:pending, beacon) |> stream_insert(:beacons, approved)} else {:noreply, put_flash(socket, :error, "Admins only.")} end end @impl true def handle_info({type, %Beacon{}}, socket) when type in [:created, :updated, :deleted] do pending = if admin?(socket.assigns.current_scope) do Beacons.list_pending_beacons() else [] end {:noreply, socket |> assign(:pending, pending) |> stream(:beacons, Beacons.list_beacons(), reset: true) |> stream(:pending, pending, reset: true)} end defp admin?(%{user: %{is_admin: true}}), do: true defp admin?(_), do: false defp format_coord(value) when is_float(value), do: :erlang.float_to_binary(value, decimals: 6) defp format_coord(value), do: to_string(value) end