'use client' import { useState, useEffect } from 'react' import { motion } from 'framer-motion' import { Activity, RefreshCw, CheckCircle, XCircle, AlertCircle, Clock, Zap, ExternalLink, ArrowLeft, } from 'lucide-react' import Link from 'next/link' import Header from '@/components/Header' import Footer from '@/components/Footer' interface HealthResult { id: string name: string url: string status: 'online' | 'offline' | 'error' | 'slow' responseTime: number llmsTxtFound: boolean llmsFullTxtFound: boolean foundAt?: string error?: string } interface HealthReport { timestamp: string totalSites: number online: number offline: number errors: number slow: number averageResponseTime: number results: HealthResult[] cached?: boolean cacheAge?: number } const STATUS_CONFIG = { online: { icon: CheckCircle, color: 'text-green-400', bgColor: 'bg-green-500/10', borderColor: 'border-green-500/20', label: 'Online', }, offline: { icon: XCircle, color: 'text-red-400', bgColor: 'bg-red-500/10', borderColor: 'border-red-500/20', label: 'Offline', }, error: { icon: AlertCircle, color: 'text-yellow-400', bgColor: 'bg-yellow-500/10', borderColor: 'border-yellow-500/20', label: 'Error', }, slow: { icon: Clock, color: 'text-orange-400', bgColor: 'bg-orange-500/10', borderColor: 'border-orange-500/20', label: 'Slow', }, } export default function HealthDashboard() { const [report, setReport] = useState(null) const [isLoading, setIsLoading] = useState(true) const [error, setError] = useState(null) const [filter, setFilter] = useState<'all' | 'online' | 'offline' | 'error' | 'slow'>('all') const fetchHealth = async (refresh = false) => { setIsLoading(true) setError(null) try { const params = new URLSearchParams() if (refresh) params.set('refresh', 'true') const response = await fetch(`/api/sites/health?${params}`) if (!response.ok) throw new Error('Failed to fetch health report') const data: HealthReport = await response.json() setReport(data) } catch (err) { setError(err instanceof Error ? err.message : 'Unknown error') } finally { setIsLoading(false) } } useEffect(() => { fetchHealth() }, []) const filteredResults = report?.results.filter(r => { if (filter === 'all') return true return r.status === filter }) || [] const formatTime = (ms: number) => { if (ms < 1000) return `${ms}ms` return `${(ms / 1000).toFixed(1)}s` } return (
{/* Back link */} Back to Directory {/* Page header */}

Health Dashboard

Real-time status of all llms.txt endpoints

{error && ( {error} )} {report && ( <> {/* Summary cards */}
Total Sites
{report.totalSites}
Online
{report.online}
Offline
{report.offline}
Errors
{report.errors}
Avg Response
{formatTime(report.averageResponseTime)}
{/* Cache info */} {report.cached && (
Showing cached results from {report.cacheAge}s ago
)} {/* Filter tabs */}
{(['all', 'online', 'offline', 'error', 'slow'] as const).map((f) => ( ))}
{/* Results table */}
{filteredResults.map((result) => { const config = STATUS_CONFIG[result.status] const StatusIcon = config.icon return ( ) })}
Site Status Files Found Response Time Actions
{result.name}
{new URL(result.url).hostname}
{config.label}
{result.llmsTxtFound && ( llms.txt )} {result.llmsFullTxtFound && ( llms-full.txt )} {!result.llmsTxtFound && !result.llmsFullTxtFound && ( None )}
3000 ? 'text-orange-400' : 'text-neutral-400'}`}> {formatTime(result.responseTime)}
{/* Last updated */}
Last checked: {new Date(report.timestamp).toLocaleString()}
)}
) }