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 %>
<% 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"""
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
🔄 Active Escalations
No Active Escalations
All alerts are being handled within normal response times
"""
end
end