From f2086c2c1a4b30391b787b4e8dd0cf3631cd0014 Mon Sep 17 00:00:00 2001 From: Sam Rizvi Date: Sun, 28 Jan 2024 04:58:43 -0800 Subject: [PATCH] feat: add system status #351 = created custom component for status - added to footer - h/t instatus Closes #351 --- apps/ai/src/components/layout/site-footer.tsx | 3 + .../src/components/layout/system-status.tsx | 117 ++++++++++++++++++ 2 files changed, 120 insertions(+) create mode 100644 apps/ai/src/components/layout/system-status.tsx diff --git a/apps/ai/src/components/layout/site-footer.tsx b/apps/ai/src/components/layout/site-footer.tsx index 1bceca8c..e7507e6b 100644 --- a/apps/ai/src/components/layout/site-footer.tsx +++ b/apps/ai/src/components/layout/site-footer.tsx @@ -7,6 +7,8 @@ import { siteConfig } from '#/config/site'; import { ModeToggle } from '#/components/layout/mode-toggle'; +import SystemStatusWidget from './system-status'; + interface FooterLinkData { href: string; label: string; @@ -82,6 +84,7 @@ export function SiteFooter({ className }: React.HTMLAttributes) { {links.map((link) => ( ))} + diff --git a/apps/ai/src/components/layout/system-status.tsx b/apps/ai/src/components/layout/system-status.tsx new file mode 100644 index 00000000..037d5a52 --- /dev/null +++ b/apps/ai/src/components/layout/system-status.tsx @@ -0,0 +1,117 @@ +'use client'; + +import React, { useEffect, useState } from 'react'; + +type PageStatus = 'UP' | 'HASISSUES' | 'UNDERMAINTENANCE'; +type IncidentStatus = + | 'INVESTIGATING' + | 'IDENTIFIED' + | 'MONITORING' + | 'RESOLVED'; +type MaintenanceStatus = 'NOTSTARTEDYET' | 'INPROGRESS' | 'COMPLETED'; + +interface Incident { + name: string; + started: string; + status: IncidentStatus; + impact: string; + url: string; +} + +interface Maintenance { + name: string; + start: string; + status: MaintenanceStatus; + duration: string; + url: string; +} + +interface StatusData { + page: { + name: string; + url: string; + status: PageStatus; + }; + activeIncidents: Incident[]; + activeMaintenances: Maintenance[]; +} + +type GeneralStatus = PageStatus | IncidentStatus | MaintenanceStatus; + +interface StatusIndicatorProps { + status: GeneralStatus; +} + +const getStatusProperties = (status: GeneralStatus) => { + switch (status) { + case 'UP': + case 'RESOLVED': + return { + color: 'bg-green-600 dark:bg-green-500', + text: 'Running smooth', + }; + case 'HASISSUES': + case 'INVESTIGATING': + case 'IDENTIFIED': + case 'MONITORING': + return { + color: 'bg-yellow-600 dark:bg-yellow-500', + text: "Something's up", + }; + case 'UNDERMAINTENANCE': + case 'NOTSTARTEDYET': + case 'INPROGRESS': + return { color: 'bg-red-600 dark:bg-red-500', text: "We're on it" }; + default: + return { color: 'bg-gray-400 dark:bg-gray-300', text: 'Status Unknown' }; + } +}; + +const StatusIndicator = ({ status }: StatusIndicatorProps) => { + const { color, text } = getStatusProperties(status); + return ( +
+
+ + {text} + +
+ ); +}; + +const SystemStatusWidget = () => { + const [statusData, setStatusData] = useState(null); + + useEffect(() => { + fetch('https://andvoila.instatus.com/summary.json') + .then((response) => response.json()) + .then((data) => setStatusData(data as StatusData)) + // eslint-disable-next-line no-console + .catch((error) => console.error('Error fetching status data:', error)); + }, []); + + return ( + +
+ {statusData && ( +
+ + {statusData.activeIncidents?.map((incident, index) => ( + + ))} + {statusData.activeMaintenances?.map((maintenance, index) => ( + + ))} +
+ )} +
+
+ ); +}; + +export default SystemStatusWidget;