"use client"; import { useState, useEffect } from "react"; import { DashboardLayout } from "@/components/layouts/DashboardLayout"; import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/layout/Card"; import { Button } from "@/components/ui/forms/Button"; import { Badge } from "@/components/ui/layout/Badge"; import { Activity, CheckCircle, XCircle, Clock, AlertTriangle, Play, Pause, Settings, TrendingUp, TrendingDown, Zap, Loader2, } from "lucide-react"; import { useAuth } from "@/contexts/AuthContext"; import { supabase } from "@/lib/supabase"; import { logError, getUserFriendlyErrorMessage, extractSupabaseErrorInfo } from "@/utils/errorUtils"; interface MonitoringStatus { id: string; website_name: string; website_url: string; is_monitoring: boolean; last_check: string; status: "up" | "down" | "warning"; response_time: number; uptime_percentage: number; incidents_count: number; created_at: string; } interface UptimeMetric { website_id: string; timestamp: string; status: "up" | "down" | "warning"; response_time: number; error_message?: string; } export default function MonitoringPage() { const { userDetails } = useAuth(); const [websites, setWebsites] = useState([]); const [recentChecks, setRecentChecks] = useState([]); const [loading, setLoading] = useState(true); const [updating, setUpdating] = useState(null); useEffect(() => { if (userDetails?.organization_id) { loadMonitoringData(); // Set up real-time updates const interval = setInterval(loadMonitoringData, 30000); // Update every 30 seconds return () => clearInterval(interval); } }, [userDetails]); const loadMonitoringData = async () => { if (!userDetails?.organization_id) return; try { setLoading(true); // Fetch websites with monitoring status const { data: websitesData, error: websitesError } = await supabase .from("websites") .select(` id, name, base_url, is_active, created_at, uptime_checks ( id, status, response_time, checked_at, error_message ) `) .eq("organization_id", userDetails.organization_id) .eq("is_active", true) .order("created_at", { ascending: false }); if (websitesError) throw websitesError; // Process monitoring data const monitoringData: MonitoringStatus[] = websitesData?.map((website: any) => { const checks = website.uptime_checks || []; const recentChecks = checks .filter((check: any) => { const checkDate = new Date(check.checked_at); const dayAgo = new Date(Date.now() - 24 * 60 * 60 * 1000); return checkDate >= dayAgo; }) .sort((a: any, b: any) => new Date(b.checked_at).getTime() - new Date(a.checked_at).getTime()); const latestCheck = recentChecks[0]; const upChecks = recentChecks.filter((check: any) => check.status === "up").length; const totalChecks = recentChecks.length; const uptimePercentage = totalChecks > 0 ? Math.round((upChecks / totalChecks) * 100) : 0; const incidents = recentChecks.filter((check: any) => check.status === "down").length; return { id: website.id, website_name: website.name, website_url: website.base_url, is_monitoring: true, // Assume monitoring is enabled for active websites last_check: latestCheck?.checked_at || website.created_at, status: latestCheck?.status || "warning", response_time: latestCheck?.response_time || 0, uptime_percentage: uptimePercentage, incidents_count: incidents, created_at: website.created_at, }; }) || []; setWebsites(monitoringData); // Get recent checks for the timeline const allChecks: UptimeMetric[] = []; websitesData?.forEach((website: any) => { const checks = website.uptime_checks || []; checks.slice(0, 10).forEach((check: any) => { allChecks.push({ website_id: website.id, timestamp: check.checked_at, status: check.status, response_time: check.response_time, error_message: check.error_message, }); }); }); allChecks.sort((a, b) => new Date(b.timestamp).getTime() - new Date(a.timestamp).getTime()); setRecentChecks(allChecks.slice(0, 20)); } catch (error) { const errorInfo = extractSupabaseErrorInfo(error); logError("Error loading monitoring data", error, { organizationId: userDetails.organization_id, function: "loadMonitoringData", supabaseError: errorInfo }); } finally { setLoading(false); } }; const toggleMonitoring = async (websiteId: string, currentStatus: boolean) => { try { setUpdating(websiteId); // In a real implementation, you would update monitoring settings // For now, we'll just simulate the action await new Promise(resolve => setTimeout(resolve, 1000)); // Update local state setWebsites(prev => prev.map(website => website.id === websiteId ? { ...website, is_monitoring: !currentStatus } : website )); } catch (error) { console.error("Error toggling monitoring:", error); } finally { setUpdating(null); } }; const getStatusIcon = (status: string) => { switch (status) { case "up": return ; case "down": return ; case "warning": return ; default: return ; } }; const getStatusColor = (status: string) => { switch (status) { case "up": return "bg-green-100 text-green-800"; case "down": return "bg-red-100 text-red-800"; case "warning": return "bg-yellow-100 text-yellow-800"; default: return "bg-gray-100 text-gray-800"; } }; const getUptimeColor = (percentage: number) => { if (percentage >= 99) return "text-green-600"; if (percentage >= 95) return "text-yellow-600"; return "text-red-600"; }; if (loading) { return (
); } const totalWebsites = websites.length; const activeMonitoring = websites.filter(w => w.is_monitoring).length; const upWebsites = websites.filter(w => w.status === "up").length; const downWebsites = websites.filter(w => w.status === "down").length; const avgUptime = websites.length > 0 ? Math.round(websites.reduce((sum, w) => sum + w.uptime_percentage, 0) / websites.length) : 0; return (
{/* Header */}

Website Monitoring

Real-time uptime monitoring for your websites

{/* Summary Cards */}

Total Websites

{totalWebsites}

Monitoring Active

{activeMonitoring}

Websites Up

{upWebsites}

Average Uptime

{avgUptime}%

{/* Monitoring Status */}

Website Status

{websites.length > 0 ? (
{websites.map((website) => (
{getStatusIcon(website.status)}

{website.website_name}

{website.website_url}

{website.status.toUpperCase()}

Last check: {new Date(website.last_check).toLocaleTimeString()}

{website.response_time > 0 ? `${website.response_time}ms` : "—"}

Response time

{website.uptime_percentage}%

24h uptime

{website.incidents_count}

Incidents

))}
) : (

No websites being monitored

Add websites and enable monitoring to see uptime status here

)}
{/* Recent Activity */} {recentChecks.length > 0 && ( Recent Activity
{recentChecks.slice(0, 10).map((check, index) => { const website = websites.find(w => w.id === check.website_id); return (
{getStatusIcon(check.status)}

{website?.website_name || "Unknown"}

{new Date(check.timestamp).toLocaleString()}

{check.response_time}ms

{check.error_message && (

{check.error_message}

)}
); })}
)}
); }