<.header> Alerts Experimental <:subtitle>Triage alerts by site impact — fix the biggest problems first <%!-- Filter Tabs --%>
<.link patch={~p"/alerts?filter=unresolved&sort=#{@sort_by}"} class={["tab", @filter == "unresolved" && "tab-active"]} > Unresolved {@counts.unresolved} <.link patch={~p"/alerts?filter=critical&sort=#{@sort_by}"} class={["tab", @filter == "critical" && "tab-active"]} > Critical {@counts.critical} <.link patch={~p"/alerts?filter=all&sort=#{@sort_by}"} class={["tab", @filter == "all" && "tab-active"]} > All {@counts.all} <.link patch={~p"/alerts?filter=resolved&sort=#{@sort_by}"} class={["tab", @filter == "resolved" && "tab-active"]} > Resolved {@counts.resolved}
<%!-- Sort Controls --%>
Sort: <.link patch={~p"/alerts?filter=#{@filter}&sort=severity"} class={["btn btn-xs", (@sort_by == "severity" && "btn-primary") || "btn-ghost"]} > Severity <.link patch={~p"/alerts?filter=#{@filter}&sort=age"} class={["btn btn-xs", (@sort_by == "age" && "btn-primary") || "btn-ghost"]} > Oldest First <.link patch={~p"/alerts?filter=#{@filter}&sort=impact"} class={["btn btn-xs", (@sort_by == "impact" && "btn-primary") || "btn-ghost"]} > Subscriber Impact
<%= if Enum.empty?(@alerts) do %>
<.icon name="hero-check-circle-solid" class="h-12 w-12 text-green-500 dark:text-green-400" />

All Clear!

<%= case @filter do %> <% "unresolved" -> %> No active alerts. Your network is looking good! <% "critical" -> %> No critical alerts. Nice work keeping things healthy! <% "resolved" -> %> No resolved alerts yet. <% _ -> %> No active alerts. Your network is looking good! <% end %>

<% else %> <%!-- Grouped by Site --%>
<%= for group <- @grouped_alerts do %>
0 && "border-red-300 dark:border-red-800 bg-red-50/50 dark:bg-red-950/30", group.critical_count == 0 && "border-base-300 bg-base-100" ]}> 0 } phx-click="toggle_site" phx-value-site-id={group.site_id || "none"} /> <%!-- Site Header --%>
<.icon name={ if group.critical_count > 0, do: "hero-exclamation-triangle", else: "hero-signal" } class={[ "h-5 w-5", group.critical_count > 0 && "text-red-500", group.critical_count == 0 && "text-gray-400" ]} /> <%= if group.site_id do %> <.link navigate={~p"/sites/#{group.site_id}"} class="hover:text-blue-600 dark:hover:text-blue-400" > {group.site_name} <% else %> {group.site_name} <% end %> <%!-- Alert count badge --%> 0 && "badge-error", group.critical_count == 0 && "badge-ghost" ]}> {group.total_count} alert{if group.total_count != 1, do: "s"} <%= if group.critical_count > 0 do %> {group.critical_count} down <% end %>
<%!-- Subscriber impact for site --%>
<%= if group.subscriber_info && group.total_subscribers > 0 do %> <.icon name="hero-users" class="h-3.5 w-3.5" /> {format_number(group.total_subscribers)} subscribers <%= if group.subscriber_info.total_mrr do %> <.icon name="hero-currency-dollar" class="h-3.5 w-3.5" /> {format_mrr(group.subscriber_info.total_mrr)}/mo <% end %> <% end %>
<%!-- Alerts within site --%>
<%= for alert <- group.alerts do %> <% color = severity_color(alert) %>
<%!-- Alert type badge --%> <%= case alert.alert_type do %> <% :device_down -> %> <.icon name="hero-exclamation-triangle" class="h-3.5 w-3.5" /> Down <% :device_up -> %> <.icon name="hero-check-circle" class="h-3.5 w-3.5" /> Recovered <% end %> <%!-- Age badge --%> {age_text(alert)} <%!-- Status badges --%> <%= if alert.resolved_at do %> Resolved <% end %> <%= if alert.acknowledged_at && is_nil(alert.resolved_at) do %> Ack'd <% end %> <%!-- Per-alert subscriber impact --%> <%= if alert.gaiia_impact && alert.gaiia_impact["total_subscribers"] && alert.gaiia_impact["total_subscribers"] > 0 do %> <.icon name="hero-users" class="h-3 w-3" /> {alert.gaiia_impact["total_subscribers"]} affected <%= if alert.gaiia_impact["total_mrr"] && alert.gaiia_impact["total_mrr"] != "0" do %> ${alert.gaiia_impact["total_mrr"]}/mo <% end %> <% end %>
<%!-- Device name + message --%>
<.link navigate={~p"/devices/#{alert.device.id}"} class="font-semibold text-blue-600 hover:text-blue-700 dark:text-blue-400 dark:hover:text-blue-300" > {alert.device.name} {alert.device.ip_address}
<%= if alert.message do %>

{alert.message}

<% end %> <%!-- Timestamps --%>
Triggered: {ToweropsWeb.TimeHelpers.format_iso8601( alert.triggered_at, @timezone )} <%= if alert.acknowledged_at do %> Ack'd: {ToweropsWeb.TimeHelpers.format_iso8601( alert.acknowledged_at, @timezone )} <%= if alert.acknowledged_by do %> by {alert.acknowledged_by.email} <% end %> <% end %> <%= if alert.resolved_at do %> Resolved: {ToweropsWeb.TimeHelpers.format_iso8601( alert.resolved_at, @timezone )} <% end %>
<%!-- Action Buttons --%>
<%= 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" /> Ack <% end %> <%= if is_nil(alert.resolved_at) do %> <.button phx-click="resolve" phx-value-id={alert.id} data-confirm="Resolve this alert?" > <.icon name="hero-check-circle" class="h-4 w-4" /> Resolve <% end %>
<% end %>
<% end %>
<% end %>