- Replace gray->cool-steel, blue/indigo->cerulean, red->sweet-salmon, yellow/amber->wheat - Dark sidebar: sidebar/footer use cool-steel-800 bg, text lightened for contrast - ~11,600 color replacements across ~99 files - Update tests for new color class names
172 lines
7.4 KiB
Text
172 lines
7.4 KiB
Text
<%= if @not_found do %>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="utf-8" />
|
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
<title>Status Page Not Found</title>
|
|
</head>
|
|
<body class="bg-cool-steel-50 flex items-center justify-center min-h-screen">
|
|
<div class="text-center">
|
|
<h1 class="text-2xl font-bold text-cool-steel-900">Status Page Not Found</h1>
|
|
<p class="mt-2 text-cool-steel-600">
|
|
The requested status page does not exist or is not enabled.
|
|
</p>
|
|
</div>
|
|
</body>
|
|
</html>
|
|
<% else %>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="utf-8" />
|
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
<title>{@page_title}</title>
|
|
<link phx-track-static rel="stylesheet" href={~p"/assets/app.css"} />
|
|
<script defer phx-track-static src={~p"/assets/app.js"}>
|
|
</script>
|
|
<%= if @config.custom_css do %>
|
|
<style>
|
|
{@config.custom_css}
|
|
</style>
|
|
<% end %>
|
|
</head>
|
|
<body class="bg-cool-steel-50 dark:bg-cool-steel-950 min-h-screen">
|
|
<div class="max-w-3xl mx-auto px-4 py-8">
|
|
<%!-- Header --%>
|
|
<header class="text-center mb-8">
|
|
<%= if @config.logo_url do %>
|
|
<img src={@config.logo_url} alt={@config.company_name} class="h-10 mx-auto mb-4" />
|
|
<% end %>
|
|
<h1 class="text-2xl font-bold text-cool-steel-900 dark:text-white">
|
|
{@config.company_name || "System Status"}
|
|
</h1>
|
|
</header>
|
|
|
|
<%!-- Overall Status Banner --%>
|
|
<div class={"rounded-lg p-4 mb-8 text-white text-center #{overall_color(@overall_status)}"}>
|
|
<p class="text-lg font-semibold">{overall_text(@overall_status)}</p>
|
|
<p class="text-sm opacity-90 mt-1">
|
|
Last updated: {Calendar.strftime(DateTime.utc_now(), "%B %d, %Y at %H:%M UTC")}
|
|
</p>
|
|
</div>
|
|
|
|
<%!-- Active Incidents --%>
|
|
<%= if @active_incidents != [] do %>
|
|
<div class="mb-8">
|
|
<h2 class="text-lg font-semibold text-cool-steel-900 dark:text-white mb-4">
|
|
Active Incidents
|
|
</h2>
|
|
<div class="space-y-4">
|
|
<%= for incident <- @active_incidents do %>
|
|
<div class="bg-white dark:bg-cool-steel-800 rounded-lg border border-cool-steel-200 dark:border-cool-steel-700 p-4">
|
|
<div class="flex items-start justify-between">
|
|
<div>
|
|
<h3 class={"font-semibold #{severity_color(incident.severity)}"}>
|
|
{incident.title}
|
|
</h3>
|
|
<%= if incident.body do %>
|
|
<p class="mt-1 text-sm text-cool-steel-600 dark:text-cool-steel-400">
|
|
{incident.body}
|
|
</p>
|
|
<% end %>
|
|
</div>
|
|
<span class="inline-flex items-center px-2 py-0.5 rounded text-xs font-medium bg-wheat-100 text-wheat-800 dark:bg-wheat-900/50 dark:text-wheat-300">
|
|
{incident_status_label(incident.status)}
|
|
</span>
|
|
</div>
|
|
<p class="mt-2 text-xs text-cool-steel-500">
|
|
Started: {Calendar.strftime(incident.started_at, "%b %d, %H:%M UTC")}
|
|
</p>
|
|
</div>
|
|
<% end %>
|
|
</div>
|
|
</div>
|
|
<% end %>
|
|
|
|
<%!-- Components --%>
|
|
<div class="mb-8">
|
|
<h2 class="text-lg font-semibold text-cool-steel-900 dark:text-white mb-4">
|
|
Components
|
|
</h2>
|
|
<div class="bg-white dark:bg-cool-steel-800 rounded-lg border border-cool-steel-200 dark:border-cool-steel-700 divide-y divide-cool-steel-200 dark:divide-cool-steel-700">
|
|
<%= if @components == [] do %>
|
|
<div class="p-4 text-center text-cool-steel-500 dark:text-cool-steel-400">
|
|
No components configured
|
|
</div>
|
|
<% else %>
|
|
<%= for component <- @components do %>
|
|
<div class="px-4 py-3 flex items-center justify-between">
|
|
<div>
|
|
<span class="font-medium text-cool-steel-900 dark:text-white">
|
|
{component.name}
|
|
</span>
|
|
<%= if component.description do %>
|
|
<p class="text-xs text-cool-steel-500 dark:text-cool-steel-400">
|
|
{component.description}
|
|
</p>
|
|
<% end %>
|
|
</div>
|
|
<div class="flex items-center gap-2">
|
|
<div class={"w-2.5 h-2.5 rounded-full #{component_color(component.status)}"}>
|
|
</div>
|
|
<span class="text-sm text-cool-steel-600 dark:text-cool-steel-400">
|
|
{component_label(component.status)}
|
|
</span>
|
|
</div>
|
|
</div>
|
|
<% end %>
|
|
<% end %>
|
|
</div>
|
|
</div>
|
|
|
|
<%!-- Recent Incidents --%>
|
|
<div class="mb-8">
|
|
<h2 class="text-lg font-semibold text-cool-steel-900 dark:text-white mb-4">
|
|
Recent Incidents
|
|
</h2>
|
|
<%= if @recent_incidents == [] do %>
|
|
<p class="text-sm text-cool-steel-500 dark:text-cool-steel-400 bg-white dark:bg-cool-steel-800 rounded-lg border border-cool-steel-200 dark:border-cool-steel-700 p-4 text-center">
|
|
No recent incidents — looking good!
|
|
</p>
|
|
<% else %>
|
|
<div class="space-y-3">
|
|
<%= for incident <- @recent_incidents do %>
|
|
<div class="bg-white dark:bg-cool-steel-800 rounded-lg border border-cool-steel-200 dark:border-cool-steel-700 p-4">
|
|
<div class="flex items-center justify-between">
|
|
<h3 class="text-sm font-medium text-cool-steel-900 dark:text-white">
|
|
{incident.title}
|
|
</h3>
|
|
<span class={"text-xs px-2 py-0.5 rounded font-medium " <> if(incident.status == "resolved", do: "bg-green-100 text-green-700 dark:bg-green-900/50 dark:text-green-300", else: "bg-wheat-100 text-wheat-700 dark:bg-wheat-900/50 dark:text-wheat-300")}>
|
|
{incident_status_label(incident.status)}
|
|
</span>
|
|
</div>
|
|
<p class="mt-1 text-xs text-cool-steel-500">
|
|
{Calendar.strftime(incident.started_at, "%b %d, %Y")}
|
|
<%= if incident.resolved_at do %>
|
|
— Resolved {Calendar.strftime(incident.resolved_at, "%b %d, %H:%M UTC")}
|
|
<% end %>
|
|
</p>
|
|
</div>
|
|
<% end %>
|
|
</div>
|
|
<% end %>
|
|
</div>
|
|
|
|
<%!-- Footer --%>
|
|
<footer class="text-center text-xs text-cool-steel-400 dark:text-cool-steel-600 mt-12">
|
|
<%= if @config.support_email do %>
|
|
<p>
|
|
Need help? Contact
|
|
<a
|
|
href={"mailto:#{@config.support_email}"}
|
|
class="underline hover:text-cool-steel-600 dark:hover:text-cool-steel-400"
|
|
>
|
|
{@config.support_email}
|
|
</a>
|
|
</p>
|
|
<% end %>
|
|
<p class="mt-1">Powered by Towerops</p>
|
|
</footer>
|
|
</div>
|
|
</body>
|
|
</html>
|
|
<% end %>
|