'use client'; import { Activity, RefreshCcw, AlertCircle } from 'lucide-react'; import { useState, useEffect } from 'react'; interface ServiceStatus { name: string; url: string; status: 'up' | 'down'; latency: number; } export function UptimeCard() { const [services, setServices] = useState([]); const [loading, setLoading] = useState(true); const [error, setError] = useState(false); const fetchStatus = async () => { setLoading(true); try { const res = await fetch('/api/status'); if (!res.ok) throw new Error('Failed to fetch'); const data = await res.json(); setServices(data); setError(false); } catch (e) { console.error(e); setError(true); } finally { setLoading(false); } }; useEffect(() => { fetchStatus(); // Poll every 30 seconds const interval = setInterval(fetchStatus, 30000); return () => clearInterval(interval); }, []); // Calculate overall health const upCount = services.filter(s => s.status === 'up').length; const healthPercentage = services.length > 0 ? Math.round((upCount / services.length) * 100) : 0; return (
Uptime Monitor {loading && }
{!loading && !error && ( {healthPercentage}% )}
{error ? (
Failed to load status
) : (
{services.length === 0 && loading ? ( // Skeleton loader [1, 2, 3].map(i => (
)) ) : ( services.map((service) => (
{service.name}
{service.status === 'up' ? `${service.latency}ms` : 'DOWN'}
)) )}
)}
); }