defmodule DaProductAppWeb.AlertsLive do use DaProductAppWeb, :live_view alias DaProductApp.TerminalManagement @impl true def mount(_params, _session, socket) do # Subscribe to real-time alerts if connected?(socket) do TerminalManagement.subscribe_to_device_updates() # Check for alerts every 60 seconds Process.send_after(self(), :check_alerts, 60_000) end socket = socket |> assign(:page_title, "Alert & Notification Management") |> assign(:current_tab, "dashboard") |> assign(:loading, true) |> assign(:current_page, "alerts") |> load_alert_data() {:ok, socket} end @impl true def handle_params(params, _url, socket) do tab = params["tab"] || "dashboard" socket = socket |> assign(:current_tab, tab) |> load_alert_data() {:noreply, socket} end @impl true def handle_event("change_tab", %{"tab" => tab}, socket) do {:noreply, push_patch(socket, to: ~p"/alerts?tab=#{tab}")} end @impl true def handle_event("acknowledge_alert", %{"alert_id" => alert_id}, socket) do user_id = socket.assigns[:current_user][:id] || "system" case TerminalManagement.acknowledge_alert(String.to_integer(alert_id), user_id, "Acknowledged via dashboard") do {:ok, _updated_alert} -> socket = socket |> put_flash(:info, "Alert acknowledged successfully") |> load_alert_data() {:noreply, socket} {:error, reason} -> socket = put_flash(socket, :error, "Failed to acknowledge alert: #{reason}") {:noreply, socket} end end @impl true def handle_event("resolve_alert", %{"alert_id" => alert_id}, socket) do user_id = socket.assigns[:current_user][:id] || "system" case TerminalManagement.resolve_alert(String.to_integer(alert_id), user_id, "Resolved via dashboard") do {:ok, _updated_alert} -> socket = socket |> put_flash(:info, "Alert resolved successfully") |> load_alert_data() {:noreply, socket} {:error, reason} -> socket = put_flash(socket, :error, "Failed to resolve alert: #{reason}") {:noreply, socket} end end @impl true def handle_event("create_alert_rule", params, socket) do rule_config = %{ name: params["name"], description: params["description"], alert_type: params["alert_type"], severity: params["severity"], conditions: %{}, notification_channels: String.split(params["notification_channels"], ","), enabled: params["enabled"] == "true" } case TerminalManagement.create_alert_rule(rule_config) do {:ok, _rule} -> socket = socket |> put_flash(:info, "Alert rule created successfully") |> load_alert_data() {:noreply, socket} {:error, reason} -> socket = put_flash(socket, :error, "Failed to create alert rule: #{reason}") {:noreply, socket} end end @impl true def handle_event("test_notification", %{"channel" => channel}, socket) do test_alert = %{ id: "test", type: "test", severity: "medium", title: "Test Notification", message: "This is a test notification from the alert system", created_at: DateTime.utc_now() } case TerminalManagement.send_notification(test_alert, [channel]) do %{successful: 1} -> socket = put_flash(socket, :info, "Test notification sent successfully via #{channel}") {:noreply, socket} _ -> socket = put_flash(socket, :error, "Failed to send test notification via #{channel}") {:noreply, socket} end end @impl true def handle_event("refresh_alerts", _params, socket) do socket = socket |> assign(:loading, true) |> load_alert_data() {:noreply, socket} end @impl true def handle_info(:check_alerts, socket) do # Process real-time alerts alert_results = TerminalManagement.process_realtime_alerts() # Broadcast new alerts if any if alert_results.new_alerts > 0 do send(self(), {:new_alerts, alert_results.new_alerts}) end # Schedule next check Process.send_after(self(), :check_alerts, 60_000) socket = load_alert_data(socket) {:noreply, socket} end @impl true def handle_info({:new_alerts, count}, socket) do socket = put_flash(socket, :info, "#{count} new alerts detected") {:noreply, socket} end @impl true def handle_info({:device_update, _device_data}, socket) do # Refresh alerts when device data changes socket = load_alert_data(socket) {:noreply, socket} end @impl true def handle_info({:monitoring_update, _monitoring_data}, socket) do # Refresh alerts when monitoring data changes socket = load_alert_data(socket) {:noreply, socket} end defp load_alert_data(socket) do # Load alert dashboard data alert_stats = TerminalManagement.get_alert_dashboard_stats() alert_config = TerminalManagement.get_alert_configuration() current_alerts = TerminalManagement.process_realtime_alerts() socket |> assign(:alert_stats, alert_stats) |> assign(:alert_config, alert_config) |> assign(:current_alerts, current_alerts) |> assign(:loading, false) end @impl true def render(assigns) do ~H"""

🔔 Alert & Notification Management

Real-time alerts, notifications, and escalation management

Last Check: <%= Calendar.strftime(DateTime.utc_now(), "%H:%M:%S") %>
<%= if @loading do %>
Loading alert data...
<% end %>
<%= case @current_tab do %> <% "dashboard" -> %> <%= render_dashboard_tab(assigns) %> <% "active_alerts" -> %> <%= render_active_alerts_tab(assigns) %> <% "rules" -> %> <%= render_rules_tab(assigns) %> <% "notifications" -> %> <%= render_notifications_tab(assigns) %> <% "escalation" -> %> <%= render_escalation_tab(assigns) %> <% _ -> %> <%= render_dashboard_tab(assigns) %> <% end %>
""" end defp render_dashboard_tab(assigns) do ~H"""

Critical Alerts

<%= @alert_stats.active_alerts.critical %>

High Priority

<%= @alert_stats.active_alerts.high %>

Medium Priority

<%= @alert_stats.active_alerts.medium %>

Low Priority

<%= @alert_stats.active_alerts.low %>

Total Active

<%= @alert_stats.active_alerts.total %>

📈 Alert Trends

Last 24 Hours <%= @alert_stats.alert_trends.last_24h %>
Last 7 Days <%= @alert_stats.alert_trends.last_7d %>
Growth Rate +<%= @alert_stats.alert_trends.growth_rate %>%

⚡ Response Metrics

Avg Acknowledgment Time <%= @alert_stats.response_metrics.avg_acknowledgment_time %>
Avg Resolution Time <%= @alert_stats.response_metrics.avg_resolution_time %>
Escalation Rate <%= @alert_stats.response_metrics.escalation_rate %>%

🎯 Top Alert Sources

<%= for source <- @alert_stats.top_alert_sources do %>
<%= source.source %> <%= source.count %>
<% end %>

📤 Notification Statistics

📧 Email Sent (Via Aritic) <%= @alert_stats.notification_stats.email_sent %>
📱 SMS Sent (Via Aritic) <%= @alert_stats.notification_stats.sms_sent %>
🔗 Webhook Calls <%= @alert_stats.notification_stats.webhook_calls %>
🔔 Push Notifications (Via Aritic) <%= @alert_stats.notification_stats.push_notifications %>
Delivery Rate <%= @alert_stats.notification_stats.delivery_rate %>%
""" end defp render_active_alerts_tab(assigns) do ~H"""

🚨 Current Alert Status

Real-time alert monitoring and management

<%= @current_alerts.new_alerts %>
New
<%= @current_alerts.acknowledged_alerts %>
Acknowledged
<%= @current_alerts.resolved_alerts %>
Resolved
<%= @current_alerts.total_alerts %>
Total

Active Alerts

<%= if length(@current_alerts.alerts) > 0 do %> <%= for alert <- @current_alerts.alerts do %>
case alert.severity do "critical" -> "bg-red-100 text-red-800" "high" -> "bg-orange-100 text-orange-800" "medium" -> "bg-yellow-100 text-yellow-800" "low" -> "bg-blue-100 text-blue-800" _ -> "bg-gray-100 text-gray-800" end}> <%= String.upcase(alert.severity) %> case alert.status do "new" -> "bg-red-100 text-red-800" "acknowledged" -> "bg-yellow-100 text-yellow-800" "resolved" -> "bg-green-100 text-green-800" _ -> "bg-gray-100 text-gray-800" end}> <%= String.upcase(alert.status) %>

<%= alert.title %>

<%= alert.message %>

ID: #<%= alert.id %> Type: <%= alert.type %> Created: <%= Calendar.strftime(alert.created_at, "%Y-%m-%d %H:%M") %>
<%= if alert.status == "new" do %> <% end %> <%= if alert.status in ["new", "acknowledged"] do %> <% end %>
<% end %> <% else %>

No Active Alerts

All systems are operating normally

<% end %>
""" end defp render_rules_tab(assigns) do ~H"""

➕ Create New Alert Rule

Configured Alert Rules

<%= for rule <- @alert_config.alert_rules do %>

<%= rule.name %>

case rule.severity do "critical" -> "bg-red-100 text-red-800" "high" -> "bg-orange-100 text-orange-800" "medium" -> "bg-yellow-100 text-yellow-800" "low" -> "bg-blue-100 text-blue-800" end}> <%= String.upcase(rule.severity) %> if(rule.enabled, do: "bg-green-100 text-green-800", else: "bg-gray-100 text-gray-800")}> <%= if rule.enabled, do: "ENABLED", else: "DISABLED" %>
Type: <%= rule.type %> ID: #<%= rule.id %>
<% end %>
""" end defp render_notifications_tab(assigns) do ~H"""
<%= for channel <- @alert_config.notification_channels do %>

<%= channel.name %>

if(channel.enabled, do: "bg-green-100 text-green-800", else: "bg-red-100 text-red-800")}> <%= if channel.enabled, do: "ENABLED", else: "DISABLED" %>
<% end %>

📝 Notification Templates

Email Template

Subject: Alert: {{alert.title}}
Alert: {{alert.title}}
Severity: {{alert.severity}}
Time: {{alert.created_at}}

Description: {{alert.message}}

Please investigate and acknowledge this alert.

SMS Template

ALERT: {{alert.title}}. {{alert.message}}. Check dashboard for details.

📤 Recent Notifications

<%= for i <- 1..5 do %>
EMAIL <%= Calendar.strftime(DateTime.add(DateTime.utc_now(), -i * 15, :minute), "%H:%M") %>

Device Offline Alert

Sent to admin@company.com

DELIVERED
<% end %>
""" end defp render_escalation_tab(assigns) do ~H"""

📈 Escalation Policies

<%= for policy <- @alert_config.escalation_policies do %>

<%= policy.name %>

Policy #<%= policy.id %>
<%= for step <- policy.steps do %>
<%= step.level %> After <%= step.delay_minutes %> minutes → <%= Enum.join(step.channels, ", ") %>
<% end %>
<% end %>

➕ Create Escalation Policy

Escalation Steps

🔄 Active Escalations

No Active Escalations

All alerts are being handled within normal response times

""" end end