towerops/lib/towerops_web/live/alert_live/index.html.heex
Graham McIntire d81b025282
Make Active Alerts the first and default tab in alerts page
Changed the default filter from 'all' to 'active' and reordered tabs
so Active Alerts appears first (leftmost) in the tab bar
2026-01-17 17:16:35 -06:00

155 lines
6.2 KiB
Text

<Layouts.authenticated
flash={@flash}
current_scope={@current_scope}
current_organization={@current_organization}
active_page="alerts"
>
<.header>
Alerts
<:subtitle>Monitor and acknowledge system alerts</:subtitle>
</.header>
<div class="mb-6">
<div class="inline-flex rounded-lg border border-zinc-200 dark:border-zinc-800">
<.link
patch={~p"/orgs/#{@current_organization.slug}/alerts"}
class={[
"px-4 py-2 text-sm font-medium rounded-l-lg",
@filter == "active" &&
"bg-blue-600 text-white dark:bg-blue-500",
@filter != "active" &&
"bg-white text-zinc-700 hover:bg-zinc-50 dark:bg-zinc-900 dark:text-zinc-300 dark:hover:bg-zinc-800"
]}
>
Active Alerts
</.link>
<.link
patch={~p"/orgs/#{@current_organization.slug}/alerts?filter=all"}
class={[
"px-4 py-2 text-sm font-medium rounded-r-lg border-l border-zinc-200 dark:border-zinc-800",
@filter == "all" &&
"bg-blue-600 text-white dark:bg-blue-500",
@filter != "all" &&
"bg-white text-zinc-700 hover:bg-zinc-50 dark:bg-zinc-900 dark:text-zinc-300 dark:hover:bg-zinc-800"
]}
>
All Alerts
</.link>
</div>
</div>
<%= if Enum.empty?(@alerts) do %>
<div class="text-center py-16">
<.icon name="hero-bell-slash" class="mx-auto h-12 w-12 text-zinc-400 dark:text-zinc-600" />
<h3 class="mt-4 text-lg font-semibold text-zinc-900 dark:text-zinc-100">No alerts</h3>
<p class="mt-2 text-sm text-zinc-600 dark:text-zinc-400">
<%= if @filter == "active" do %>
There are no active alerts for this organization.
<% else %>
No alerts have been triggered yet.
<% end %>
</p>
</div>
<% else %>
<div class="space-y-4">
<%= for alert <- @alerts do %>
<div class={[
"rounded-lg border p-6 shadow-sm",
alert.resolved_at && "opacity-60",
alert.alert_type == :device_down && is_nil(alert.resolved_at) &&
"border-l-4 border-red-500 bg-red-50 dark:bg-red-950 dark:border-red-700",
(alert.alert_type != :device_down || alert.resolved_at) &&
"border-zinc-200 bg-white dark:border-zinc-800 dark:bg-zinc-900"
]}>
<div class="flex items-start justify-between">
<div class="flex-1">
<div class="flex items-center gap-3 flex-wrap">
<span class={[
"inline-flex items-center gap-1.5 rounded-full px-3 py-1 text-sm font-medium",
alert.alert_type == :device_down &&
"bg-red-100 text-red-800 dark:bg-red-900 dark:text-red-200",
alert.alert_type == :device_up &&
"bg-green-100 text-green-800 dark:bg-green-900 dark:text-green-200"
]}>
<%= case alert.alert_type do %>
<% :device_down -> %>
<.icon name="hero-exclamation-triangle" class="h-4 w-4" /> Device Down
<% :device_up -> %>
<.icon name="hero-check-circle" class="h-4 w-4" /> Device Recovered
<% end %>
</span>
<%= if alert.resolved_at do %>
<span class="inline-flex items-center rounded-full bg-zinc-100 px-2.5 py-0.5 text-xs font-medium text-zinc-800 dark:bg-zinc-800 dark:text-zinc-200">
Resolved
</span>
<% end %>
<%= if alert.acknowledged_at do %>
<span class="inline-flex items-center rounded-full bg-blue-100 px-2.5 py-0.5 text-xs font-medium text-blue-800 dark:bg-blue-900 dark:text-blue-200">
Acknowledged
</span>
<% end %>
</div>
<h3 class="mt-3 font-semibold text-zinc-900 dark:text-zinc-100">
<.link
navigate={~p"/orgs/#{@current_organization.slug}/devices/#{alert.device.id}"}
class="text-blue-600 hover:text-blue-700 dark:text-blue-400 dark:hover:text-blue-300"
>
{alert.device.name}
</.link>
</h3>
<p class="mt-1 text-sm text-zinc-700 dark:text-zinc-300">{alert.message}</p>
<div class="mt-3 space-y-1 text-xs text-zinc-600 dark:text-zinc-400">
<div>
<strong class="font-medium">Triggered:</strong>
{Calendar.strftime(alert.triggered_at, "%Y-%m-%d %H:%M:%S UTC")}
</div>
<%= if alert.acknowledged_at do %>
<div>
<strong class="font-medium">Acknowledged:</strong>
{Calendar.strftime(alert.acknowledged_at, "%Y-%m-%d %H:%M:%S UTC")}
<%= if alert.acknowledged_by do %>
by {alert.acknowledged_by.email}
<% end %>
</div>
<% end %>
<%= if alert.resolved_at do %>
<div>
<strong class="font-medium">Resolved:</strong>
{Calendar.strftime(alert.resolved_at, "%Y-%m-%d %H:%M:%S UTC")}
</div>
<% end %>
<div>
<strong class="font-medium">Site:</strong>
<.link
navigate={
~p"/orgs/#{@current_organization.slug}/sites/#{alert.device.site.id}"
}
class="text-blue-600 hover:text-blue-700 dark:text-blue-400 dark:hover:text-blue-300"
>
{alert.device.site.name}
</.link>
</div>
</div>
</div>
<div class="ml-4">
<%= if alert.alert_type == :device_down && is_nil(alert.acknowledged_at) && is_nil(alert.resolved_at) do %>
<.button phx-click="acknowledge" phx-value-id={alert.id} variant="primary">
<.icon name="hero-check" class="h-4 w-4" /> Acknowledge
</.button>
<% end %>
</div>
</div>
</div>
<% end %>
</div>
<% end %>
</Layouts.authenticated>