import React, { useEffect, useState } from 'react'; import axios from 'axios'; import { formatLocalTime } from './utils/timeUtils'; import './Status.css'; function Status() { const [resources, setResources] = useState([]); const [incidents, setIncidents] = useState([]); const [maintenanceWindows, setMaintenanceWindows] = useState([]); const [loading, setLoading] = useState(true); const [autoRefresh, setAutoRefresh] = useState(true); const [lastUpdated, setLastUpdated] = useState(new Date()); useEffect(() => { loadStatusData(); if (!autoRefresh) return; const interval = setInterval(loadStatusData, 15000); return () => clearInterval(interval); }, [autoRefresh]); const loadStatusData = async () => { try { const statusRes = await axios.get('/api/status-page'); setResources(statusRes.data.resources || []); setIncidents(statusRes.data.incidents || []); setMaintenanceWindows(statusRes.data.maintenanceWindows || []); setLastUpdated(new Date()); } catch (error) { // Status load error handled } finally { setLoading(false); } }; const formatDuration = (ms) => { const seconds = Math.floor(ms / 1000); const minutes = Math.floor(seconds / 60); const hours = Math.floor(minutes / 60); const days = Math.floor(hours / 24); if (days > 0) return `${days}d ${hours % 24}h`; if (hours > 0) return `${hours}h ${minutes % 60}m`; if (minutes > 0) return `${minutes}m`; return `${seconds}s`; }; const getResourceStatus = (resourceId) => { const activeIncident = incidents.find( (inc) => inc.resource_id === resourceId && !inc.resolved_at ); return activeIncident ? 'down' : 'up'; }; const upCount = resources.filter((r) => getResourceStatus(r.id) === 'up').length; const downCount = resources.filter((r) => getResourceStatus(r.id) === 'down').length; if (loading) { return

Loading status...

; } return (

System Status

Real-time monitoring status

Last updated: {formatLocalTime(lastUpdated)}

{upCount}
Services Up
{downCount}
Services Down
{maintenanceWindows.filter((m) => { const now = new Date(); const start = new Date(m.start_time); const end = new Date(m.end_time); return now >= start && now <= end; }).length}
Maintenance

Service Status

{resources.map((resource) => { const status = getResourceStatus(resource.id); const activeIncident = incidents.find( (inc) => inc.resource_id === resource.id && !inc.resolved_at ); const inMaintenance = maintenanceWindows.some((m) => { const now = new Date(); const start = new Date(m.start_time); const end = new Date(m.end_time); return m.resource_id === resource.id && now >= start && now <= end; }); const daily = resource.dailyUptime || []; const last90Days = (() => { const days = []; for (let i = 89; i >= 0; i--) { const d = new Date(); d.setDate(d.getDate() - i); const key = d.toISOString().slice(0, 10); const entry = daily.find(e => e.day === key); days.push({ day: key, uptime: entry ? entry.uptime : null }); } return days; })(); return (

{resource.name}

{inMaintenance ? 'Maintenance' : status === 'up' ? 'Operational' : 'Incident'}
{resource.url && (

{resource.url}

)}
{last90Days.map((d) => { const color = d.uptime === null ? '#334155' : d.uptime >= 99 ? '#14b8a6' : d.uptime >= 95 ? '#f59e0b' : '#ef4444'; return (
); })}
90 days ago {daily.length > 0 ? `${daily[daily.length - 1]?.uptime ?? '—'}% today` : ''} Today
{activeIncident && (

Active Incident

Started: {formatLocalTime(activeIncident.started_at)}

{activeIncident.description && (

{activeIncident.description}

)}

Duration: {formatDuration(new Date() - new Date(activeIncident.started_at))}

)} {inMaintenance && (

Scheduled Maintenance

{formatLocalTime( maintenanceWindows.find( (m) => m.resource_id === resource.id && new Date() >= new Date(m.start_time) && new Date() <= new Date(m.end_time) )?.start_time )}

)} {status === 'up' && !inMaintenance && (

✓ All systems operational

)}
); })}
{maintenanceWindows.length > 0 && (

Scheduled Maintenance

{maintenanceWindows.map((maint) => ( ))}
Service Start Time End Time Reason
{resources.find((r) => r.id === maint.resource_id)?.name || 'Unknown'} {formatLocalTime(maint.start_time)} {formatLocalTime(maint.end_time)} {maint.reason || '-'}
)} {incidents.filter((inc) => !inc.resolved_at).length > 0 && (

Active Incidents

{incidents .filter((inc) => !inc.resolved_at) .map((incident) => ( ))}
Service Started Duration Description
{resources.find((r) => r.id === incident.resource_id)?.name || 'Unknown'} {formatLocalTime(incident.started_at)} {formatDuration(new Date() - new Date(incident.started_at))} {incident.description || '-'}
)}
); } export default Status;