'use client' import { useState } from 'react' import { useQuery } from '@tanstack/react-query' import { monitorAPI } from '@/lib/api' import { DashboardLayout } from '@/components/layout/dashboard-layout' import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card' import { Badge } from '@/components/ui/badge' import { Button } from '@/components/ui/button' import { useRouter } from 'next/navigation' type FilterType = 'all' | 'errors' | 'changes' interface Incident { id: string monitorId: string monitorName: string monitorUrl: string type: 'error' | 'change' timestamp: Date details?: string } export default function IncidentsPage() { const router = useRouter() const [filter, setFilter] = useState('all') const [resolvedIds, setResolvedIds] = useState>(new Set()) const [showResolved, setShowResolved] = useState(false) const { data, isLoading } = useQuery({ queryKey: ['monitors'], queryFn: async () => { const response = await monitorAPI.list() return response.monitors }, }) if (isLoading) { return (

Loading...

) } const monitors = data || [] // Build incidents list from monitors const incidents: Incident[] = monitors.flatMap((m: any) => { const result: Incident[] = [] if (m.status === 'error') { result.push({ id: `error-${m.id}`, monitorId: m.id, monitorName: m.name || m.url, monitorUrl: m.url, type: 'error', timestamp: new Date(m.updated_at || m.created_at), details: m.last_error || 'Connection failed' }) } if (m.last_change_at) { result.push({ id: `change-${m.id}`, monitorId: m.id, monitorName: m.name || m.url, monitorUrl: m.url, type: 'change', timestamp: new Date(m.last_change_at), details: 'Content changed' }) } return result }).sort((a: Incident, b: Incident) => b.timestamp.getTime() - a.timestamp.getTime()) // Apply filters const filteredIncidents = incidents.filter(incident => { if (!showResolved && resolvedIds.has(incident.id)) return false if (filter === 'errors') return incident.type === 'error' if (filter === 'changes') return incident.type === 'change' return true }) const errorCount = incidents.filter(i => i.type === 'error').length const changeCount = incidents.filter(i => i.type === 'change').length const toggleResolved = (id: string) => { setResolvedIds(prev => { const next = new Set(prev) if (next.has(id)) { next.delete(id) } else { next.add(id) } return next }) } const formatTimeAgo = (date: Date) => { const seconds = Math.floor((Date.now() - date.getTime()) / 1000) if (seconds < 60) return 'just now' const minutes = Math.floor(seconds / 60) if (minutes < 60) return `${minutes}m ago` const hours = Math.floor(minutes / 60) if (hours < 24) return `${hours}h ago` const days = Math.floor(hours / 24) return `${days}d ago` } return ( {/* Filter Tabs */}
{filteredIncidents.length === 0 ? (

All Clear!

{filter === 'all' ? 'No incidents or changes detected' : filter === 'errors' ? 'No errors to show' : 'No changes to show' }

) : (
{filteredIncidents.map((incident) => (
{incident.type === 'error' ? ( ) : ( )}

{incident.monitorName}

{incident.type === 'error' ? 'Error' : 'Changed'} {resolvedIds.has(incident.id) && ( ✓ Resolved )}

{incident.monitorUrl}

{incident.details && (

{incident.details}

)}

{formatTimeAgo(incident.timestamp)}

))}
)} {/* Summary Stats */} {incidents.length > 0 && ( Summary

{incidents.length}

Total Incidents

{errorCount}

Errors

{changeCount}

Changes

)}
) }