prop/lib/microwaveprop_web/live/beacon_live/form.ex
Graham McIntire 67e095bd47 Label beacon TX power as EIRP
The power_mw field represents the beacon's effective radiated power,
not just transmitter output. Relabel it as "TX power (EIRP)" on the
form and detail list, "EIRP (mW)" in the index, and drop the now-
meaningless tx_gain_dbi constant in RangeEstimate since the stored
value already includes antenna gain.
2026-04-08 13:32:32 -05:00

125 lines
3.8 KiB
Elixir

defmodule MicrowavepropWeb.BeaconLive.Form do
@moduledoc false
use MicrowavepropWeb, :live_view
alias Microwaveprop.Beacons
alias Microwaveprop.Beacons.Beacon
@impl true
def render(assigns) do
~H"""
<Layouts.app flash={@flash} current_scope={@current_scope}>
<.header>
{@page_title}
<:subtitle>
Enter either a grid or lat/lon — whichever you leave blank is filled in
from the other.
</:subtitle>
</.header>
<.form for={@form} id="beacon-form" phx-change="validate" phx-submit="save">
<.input
field={@form[:frequency_mhz]}
type="number"
label="Frequency (MHz)"
step="any"
required
/>
<.input field={@form[:callsign]} type="text" label="Call" required />
<.input field={@form[:grid]} type="text" label="Grid" />
<.input field={@form[:lat]} type="number" label="Latitude" step="any" />
<.input field={@form[:lon]} type="number" label="Longitude" step="any" />
<.input
field={@form[:power_mw]}
type="number"
label="TX power (EIRP) (mW)"
step="any"
required
/>
<.input
field={@form[:height_ft]}
type="number"
label="Height above ground (ft)"
step="any"
required
/>
<.input field={@form[:on_the_air]} type="checkbox" label="On the air" />
<footer>
<.button phx-disable-with="Saving..." variant="primary">Save Beacon</.button>
<.button navigate={return_path(@return_to, @beacon)}>Cancel</.button>
</footer>
</.form>
</Layouts.app>
"""
end
@impl true
def mount(params, _session, socket) do
{:ok,
socket
|> assign(:return_to, return_to(params["return_to"]))
|> apply_action(socket.assigns.live_action, params)}
end
defp return_to("show"), do: "show"
defp return_to(_), do: "index"
defp apply_action(socket, :edit, %{"id" => id}) do
beacon = Beacons.get_beacon!(id)
socket
|> assign(:page_title, "Edit beacon")
|> assign(:beacon, beacon)
|> assign(:form, to_form(Beacons.change_beacon(beacon)))
end
defp apply_action(socket, :new, _params) do
beacon = %Beacon{}
socket
|> assign(:page_title, "New beacon")
|> assign(:beacon, beacon)
|> assign(:form, to_form(Beacons.change_beacon(beacon)))
end
@impl true
def handle_event("validate", %{"beacon" => beacon_params}, socket) do
changeset = Beacons.change_beacon(socket.assigns.beacon, beacon_params)
{:noreply, assign(socket, form: to_form(changeset, action: :validate))}
end
def handle_event("save", %{"beacon" => beacon_params}, socket) do
save_beacon(socket, socket.assigns.live_action, beacon_params)
end
defp save_beacon(socket, :edit, beacon_params) do
case Beacons.update_beacon(socket.assigns.beacon, beacon_params) do
{:ok, beacon} ->
{:noreply,
socket
|> put_flash(:info, "Beacon updated")
|> push_navigate(to: return_path(socket.assigns.return_to, beacon))}
{:error, %Ecto.Changeset{} = changeset} ->
{:noreply, assign(socket, form: to_form(changeset))}
end
end
defp save_beacon(socket, :new, beacon_params) do
user = socket.assigns.current_scope.user
case Beacons.create_beacon(user, beacon_params) do
{:ok, beacon} ->
{:noreply,
socket
|> put_flash(:info, "Beacon created")
|> push_navigate(to: return_path(socket.assigns.return_to, beacon))}
{:error, %Ecto.Changeset{} = changeset} ->
{:noreply, assign(socket, form: to_form(changeset))}
end
end
defp return_path("index", _beacon), do: ~p"/beacons"
defp return_path("show", beacon), do: ~p"/beacons/#{beacon}"
end