diff --git a/web/app/dashboard/page.tsx b/web/app/dashboard/page.tsx new file mode 100644 index 0000000..af9f8ac --- /dev/null +++ b/web/app/dashboard/page.tsx @@ -0,0 +1,137 @@ +'use client'; + +import { useEffect, useState } from 'react'; +import { useRouter } from 'next/navigation'; +import { api } from '@/lib/api'; +import { Incident, ActiveOrg } from '@/types'; + +export default function DashboardPage() { + const router = useRouter(); + const [incidents, setIncidents] = useState([]); + const [activeOrg, setActiveOrg] = useState(null); + const [loading, setLoading] = useState(true); + const [error, setError] = useState(''); + + useEffect(() => { + const token = localStorage.getItem('accessToken'); + if (!token) { + router.push('/login'); + return; + } + + api.setAccessToken(token); + const org = localStorage.getItem('activeOrg'); + if (org) { + setActiveOrg(JSON.parse(org)); + } + + loadIncidents(); + }, [router]); + + const loadIncidents = async () => { + try { + const response = await api.getIncidents(); + setIncidents(response.items); + } catch (err) { + setError(err instanceof Error ? err.message : 'Failed to load incidents'); + } finally { + setLoading(false); + } + }; + + const handleLogout = async () => { + const refreshToken = localStorage.getItem('refreshToken'); + if (refreshToken) { + try { + await api.logout(refreshToken); + } catch { + // Ignore logout errors + } + } + localStorage.removeItem('accessToken'); + localStorage.removeItem('refreshToken'); + localStorage.removeItem('activeOrg'); + api.setAccessToken(null); + router.push('/login'); + }; + + const getStatusColor = (status: string) => { + switch (status) { + case 'triggered': return 'var(--error)'; + case 'acknowledged': return 'var(--warning)'; + case 'mitigated': return 'var(--primary)'; + case 'resolved': return 'var(--success)'; + default: return 'inherit'; + } + }; + + if (loading) { + return ( +
+

Loading...

+
+ ); + } + + return ( +
+
+
+

IncidentOps

+ {activeOrg && ( +

+ {activeOrg.name} ({activeOrg.role}) +

+ )} +
+ +
+ +
+
+

Incidents

+ +
+ + {error &&

{error}

} + + {incidents.length === 0 ? ( +

No incidents found.

+ ) : ( + + + + + + + + + + + {incidents.map((incident) => ( + router.push(`/incidents/${incident.id}`)} + > + + + + + + ))} + +
TitleServiceStatusCreated
{incident.title}{incident.serviceName} + {incident.status} + + {new Date(incident.createdAt).toLocaleString()} +
+ )} +
+
+ ); +}