import { MaintenanceConfig, MonitorTarget } from '@/types/config' import { Center, Container, Title, Collapse, Button, Box } from '@mantine/core' import { IconCircleCheck, IconAlertCircle, IconPlus, IconMinus } from '@tabler/icons-react' import { useEffect, useState } from 'react' import MaintenanceAlert from './MaintenanceAlert' import { pageConfig } from '@/uptime.config' function useWindowVisibility() { const [isVisible, setIsVisible] = useState(true) useEffect(() => { const handleVisibilityChange = () => setIsVisible(document.visibilityState === 'visible') document.addEventListener('visibilitychange', handleVisibilityChange) return () => document.removeEventListener('visibilitychange', handleVisibilityChange) }, []) return isVisible } export default function OverallStatus({ state, maintenances, monitors, }: { state: { overallUp: number; overallDown: number; lastUpdate: number } maintenances: MaintenanceConfig[] monitors: MonitorTarget[] }) { let group = pageConfig.group let groupedMonitor = (group && Object.keys(group).length > 0) || false let statusString = '' let icon = if (state.overallUp === 0 && state.overallDown === 0) { statusString = 'No data yet' } else if (state.overallUp === 0) { statusString = 'All systems not operational' } else if (state.overallDown === 0) { statusString = 'All systems operational' icon = } else { statusString = `Some systems not operational (${state.overallDown} out of ${ state.overallUp + state.overallDown })` } const [openTime] = useState(Math.round(Date.now() / 1000)) const [currentTime, setCurrentTime] = useState(Math.round(Date.now() / 1000)) const isWindowVisible = useWindowVisibility() const [expandUpcoming, setExpandUpcoming] = useState(false) useEffect(() => { const interval = setInterval(() => { if (!isWindowVisible) return if (currentTime - state.lastUpdate > 300 && currentTime - openTime > 30) { window.location.reload() } setCurrentTime(Math.round(Date.now() / 1000)) }, 1000) return () => clearInterval(interval) }) const now = new Date() const activeMaintenances: (Omit & { monitors?: MonitorTarget[] })[] = maintenances .filter((m) => now >= new Date(m.start) && (!m.end || now <= new Date(m.end))) .map((maintenance) => ({ ...maintenance, monitors: maintenance.monitors?.map( (monitorId) => monitors.find((mon) => monitorId === mon.id)! ), })) const upcomingMaintenances: (Omit & { monitors?: (MonitorTarget | undefined)[] })[] = maintenances .filter((m) => now < new Date(m.start)) .map((maintenance) => ({ ...maintenance, monitors: maintenance.monitors?.map( (monitorId) => monitors.find((mon) => monitorId === mon.id)! ), })) return (
{icon}
{statusString} Last updated on:{' '} {`${new Date(state.lastUpdate * 1000).toLocaleString()} (${ currentTime - state.lastUpdate } sec ago)`} {/* Upcoming Maintenance */} {upcomingMaintenances.length > 0 && ( <> {`${upcomingMaintenances.length} upcoming ${ upcomingMaintenances.length === 1 ? 'maintenance' : 'maintenances' }`}{' '} <span style={{ textDecoration: 'underline', cursor: 'pointer' }} onClick={() => setExpandUpcoming(!expandUpcoming)} > {expandUpcoming ? '[Hide]' : '[Show]'} </span> {upcomingMaintenances.map((maintenance, idx) => ( ))} )} {/* Active Maintenance */} {activeMaintenances.map((maintenance, idx) => ( ))}
) }