diff --git a/lib/towerops_web/live/dashboard_live.html.heex b/lib/towerops_web/live/dashboard_live.html.heex index c5f7a809..134f9356 100644 --- a/lib/towerops_web/live/dashboard_live.html.heex +++ b/lib/towerops_web/live/dashboard_live.html.heex @@ -113,18 +113,20 @@ <%= if assigns[:summary] && @device_count > 0 do %> <%!-- ═══════════════════════════════════════════════ - STAT CARDS — max 4 per row, generous sizing + STAT CARDS — compact row ═══════════════════════════════════════════════ --%> -
{@summary.health_score}
+ <%!-- Uptime --%> +
{if @uptime_percentage == 100.0, do: "100", - else: :erlang.float_to_binary(@uptime_percentage, decimals: 1)}% + else: :erlang.float_to_binary(@uptime_percentage, decimals: 1)}%
-- {@device_up} of {@device_count} devices up +
+ {@device_up}/{@device_count} up
+ + Devices + +
{@device_count}
-0, do: "text-red-600 dark:text-red-400", - else: "text-gray-900 dark:text-white" + else: "text-green-600 dark:text-green-400" ) ]}> - {@total_alert_count} + {if @total_alert_count == 0, do: "✓", else: @total_alert_count}
-- <%= if @total_alert_count == 0 do %> - All clear - <% else %> - View details → - <% end %> +
+ {if @total_alert_count == 0, do: "All clear", else: "View details →"}
- {format_number(@summary.subscribers.total)} -
-- {format_mrr(@summary.subscribers.total_mrr)}/mo MRR -
-+ {format_number(@summary.subscribers.total)} +
++ {format_mrr(@summary.subscribers.total_mrr)}/mo +
+- {format_mrr(@impact_summary.mrr_at_risk)} -
-0} - class="mt-1 text-sm text-red-600 dark:text-red-400" - > - {format_number(@impact_summary.subscribers_affected)} subscribers affected -
-+ {format_mrr(@impact_summary.mrr_at_risk)} +
+0} + class="text-xs text-red-600 dark:text-red-400" + > + {format_number(@impact_summary.subscribers_affected)} affected +
++ {@sites_count} +
+ + <% end %> - <%= if @current_scope.organization.use_sites do %> <.link - navigate={~p"/sites"} - class="rounded-xl border border-gray-200 bg-white p-5 transition hover:shadow-md dark:border-white/10 dark:bg-gray-800/50" + navigate={~p"/insights"} + class="rounded-lg border border-gray-200 bg-white px-4 py-3 transition hover:shadow-sm dark:border-white/10 dark:bg-gray-800/50" > -- {@sites_count} + + Insights + +
+ {@summary.insights.critical + @summary.insights.warning + @summary.insights.info}
+- {@summary.insights.critical + @summary.insights.warning + @summary.insights.info} -
-- No active alerts — all systems operational -
-| + Device + | ++ Message + | ++ Impact + | ++ When + | ++ |
|---|---|---|---|---|
|
+ <.link
+ navigate={~p"/devices/#{alert.device.id}"}
+ class="text-sm font-medium text-gray-900 hover:text-blue-600 dark:text-white dark:hover:text-blue-400"
+ >
+ {alert.device.name}
+
+ + {alert.device.site.name} + + |
+ + {alert.message} + | ++ <%= if alert.gaiia_impact && alert.gaiia_impact["total_subscribers"] && alert.gaiia_impact["total_subscribers"] > 0 do %> + + {alert.gaiia_impact["total_subscribers"]} subs + + <% end %> + | ++ <.timestamp datetime={alert.triggered_at} /> + | ++ <%= if is_nil(alert.acknowledged_at) && is_nil(alert.resolved_at) do %> + + <% else %> + Ack'd + <% end %> + | +
- {if change.device, do: change.device.name, else: "Unknown Device"} -
-- {Calendar.strftime(change.changed_at, "%b %d %H:%M")} · {change.change_size} lines · {Enum.join( - Enum.take(change.sections_changed, 2), - ", " - )} -
-- {activity.summary} -
-- {Calendar.strftime(activity.timestamp, "%b %d %H:%M")} - <%= if Map.get(activity, :actor_name) do %> - by {activity.actor_name} - <% end %> -
-+ <.link + navigate={~p"/insights?source=#{insight.source}"} + class="hover:text-blue-600 dark:hover:text-blue-400" + > + {insight.title} + +
++ {insight.description} +
+No active insights
-- {insight.description} -
- <% end %> -+ {activity.summary} +
+ + {Calendar.strftime(activity.timestamp, "%b %d %H:%M")} + +