prop/lib/microwaveprop_web/controllers/user_settings_html/edit.html.heex
Graham McIntire 355bed178d Add beacon monitor registration and fix prod SMTP
Users can now register beacon monitors on the settings page. Each
monitor gets a unique random token the remote program will use to
authenticate its reports. Name is the only user-supplied field for
now; more will be added as the monitor protocol is defined.

Also adds :gen_smtp to deps. Swoosh's SMTP adapter depends on
:mimemail which lives in that package, and production was 500'ing
when trying to send confirmation emails without it.
2026-04-08 11:30:28 -05:00

125 lines
3.5 KiB
Text

<Layouts.app flash={@flash} current_scope={@current_scope}>
<div class="text-center">
<.header>
Account Settings
<:subtitle>Manage your account email address and password settings</:subtitle>
</.header>
</div>
<.form :let={f} for={@email_changeset} action={~p"/users/settings"} id="update_email">
<input type="hidden" name="action" value="update_email" />
<.input
field={f[:email]}
type="email"
label="Email"
autocomplete="username"
spellcheck="false"
required
/>
<.button variant="primary" phx-disable-with="Changing...">Change Email</.button>
</.form>
<div class="divider" />
<.form :let={f} for={@password_changeset} action={~p"/users/settings"} id="update_password">
<input type="hidden" name="action" value="update_password" />
<.input
field={f[:password]}
type="password"
label="New password"
autocomplete="new-password"
spellcheck="false"
required
/>
<.input
field={f[:password_confirmation]}
type="password"
label="Confirm new password"
autocomplete="new-password"
spellcheck="false"
required
/>
<.button variant="primary" phx-disable-with="Changing...">
Save Password
</.button>
</.form>
<div class="divider" />
<section id="beacon-monitors" class="space-y-4">
<.header>
Beacon monitors
<:subtitle>
Register remote monitor stations. Each monitor gets a unique token the
monitor program uses to authenticate its reports.
</:subtitle>
</.header>
<.form
:let={f}
for={@beacon_monitor_changeset}
as={:beacon_monitor}
action={~p"/users/beacon-monitors"}
id="create_beacon_monitor"
class="flex items-end gap-2"
>
<div class="flex-1">
<.input
field={f[:name]}
type="text"
label="Monitor name"
placeholder="e.g. Shack Pi"
required
/>
</div>
<.button variant="primary" phx-disable-with="Adding...">Add monitor</.button>
</.form>
<%= if @beacon_monitors == [] do %>
<p class="text-sm opacity-70">No monitors registered yet.</p>
<% else %>
<div class="overflow-x-auto">
<table class="table table-sm">
<thead>
<tr>
<th>Name</th>
<th>Token</th>
<th>Last seen</th>
<th class="w-1"></th>
</tr>
</thead>
<tbody>
<%= for monitor <- @beacon_monitors do %>
<tr>
<td class="font-semibold">{monitor.name}</td>
<td>
<code class="text-xs break-all select-all">{monitor.token}</code>
</td>
<td class="text-sm opacity-70">
<%= if monitor.last_seen_at do %>
{Calendar.strftime(monitor.last_seen_at, "%Y-%m-%d %H:%M UTC")}
<% else %>
never
<% end %>
</td>
<td>
<.link
href={~p"/users/beacon-monitors/#{monitor.id}"}
method="delete"
class="btn btn-ghost btn-xs text-error"
data-confirm={"Delete monitor '#{monitor.name}'? Its token will stop working immediately."}
>
Delete
</.link>
</td>
</tr>
<% end %>
</tbody>
</table>
</div>
<% end %>
</section>
</Layouts.app>