'use client'; import React, { useState } from 'react'; import { OperationsNavId, OperatorSession, OperationsHealth, SafeAuditEvent, } from './types'; import { OperationsTopBar } from './operations-top-bar'; import { OperationsSidebar } from './operations-sidebar'; import { OperationsOverview } from './operations-overview'; import { OperationsAudit } from './operations-audit'; import { OperationsOperators } from './operations-operators'; import { OperationsSessionView } from './operations-session'; import { OperationsIncidentsList } from './operations-incidents-list'; import { OperationsCreateIncident } from './operations-create-incident'; import { OperationsIncidentDetail } from './operations-incident-detail'; interface OperationsShellProps { initialSession: OperatorSession; initialHealth: OperationsHealth; initialAudit?: { events: SafeAuditEvent[]; next_cursor?: string | null; total?: number; }; initialNav?: OperationsNavId; initialCaseRef?: string | null; } export function OperationsShell({ initialSession, initialHealth, initialAudit, initialNav = 'overview', initialCaseRef = null, }: OperationsShellProps) { const [session, setSession] = useState(initialSession); const [activeNav, setActiveNav] = useState(initialNav); const [mobileSidebarOpen, setMobileSidebarOpen] = useState(false); // Incidents navigation sub-state const [incidentView, setIncidentView] = useState<'list' | 'create' | 'detail'>( initialCaseRef ? 'detail' : 'list' ); const [selectedCaseRef, setSelectedCaseRef] = useState(initialCaseRef); // Health state const [health, setHealth] = useState(initialHealth); const [isRefreshingHealth, setIsRefreshingHealth] = useState(false); // Audit state const [auditEvents, setAuditEvents] = useState( initialAudit?.events ?? [] ); const [nextCursor, setNextCursor] = useState( initialAudit?.next_cursor ?? null ); const [auditTotal, setAuditTotal] = useState( initialAudit?.total ); const [isLoadingAudit, setIsLoadingAudit] = useState(false); const [isLoadingMoreAudit, setIsLoadingMoreAudit] = useState(false); // Sign out state const [signingOut, setSigningOut] = useState(false); // Manual Health Refresh (Zero automatic polling) async function handleRefreshHealth() { if (isRefreshingHealth) return; setIsRefreshingHealth(true); try { const response = await fetch('/api/ops/health', { method: 'GET', headers: { accept: 'application/json' }, cache: 'no-store', }); if (response.ok) { const data = (await response.json()) as OperationsHealth; setHealth(data); } else { setHealth((prev: OperationsHealth) => ({ ...prev, status: 'unavailable', checked_at: new Date().toISOString(), })); } } catch { setHealth((prev: OperationsHealth) => ({ ...prev, status: 'unavailable', checked_at: new Date().toISOString(), })); } finally { setIsRefreshingHealth(false); } } // Next Page of Audit Events (Owner only, server cursor) async function handleLoadNextAuditPage() { if (!nextCursor || isLoadingMoreAudit) return; setIsLoadingMoreAudit(true); try { const response = await fetch( `/api/ops/audit-events?cursor=${encodeURIComponent(nextCursor)}`, { method: 'GET', headers: { accept: 'application/json' }, cache: 'no-store', } ); if (response.ok) { const data = await response.json(); setAuditEvents((prev) => [...prev, ...(data.events ?? [])]); setNextCursor(data.next_cursor ?? null); if (typeof data.total === 'number') { setAuditTotal(data.total); } } } catch { // Retain current events on failure } finally { setIsLoadingMoreAudit(false); } } // Sign Out Handler async function handleSignOut() { if (signingOut) return; setSigningOut(true); try { await fetch('/api/ops/auth/logout', { method: 'POST', headers: { origin: window.location.origin, }, }); } catch { // Continue client cleanup regardless of network error } finally { window.location.href = '/login'; } } return (
{/* Sidebar (Desktop persistent + Mobile off-canvas drawer) */} setActiveNav(nav)} isOpenOnMobile={mobileSidebarOpen} onCloseMobile={() => setMobileSidebarOpen(false)} role={session.role} /> {/* Main Workspace Area */}
{/* Top App Bar */} setMobileSidebarOpen(!mobileSidebarOpen)} signingOut={signingOut} /> {/* Content Body Container */}
{activeNav === 'overview' && ( )} {activeNav === 'incidents' && ( <> {incidentView === 'list' && ( { setSelectedCaseRef(caseRef); setIncidentView('detail'); }} onCreateIncident={() => setIncidentView('create')} /> )} {incidentView === 'create' && ( { setSelectedCaseRef(caseRef); setIncidentView('detail'); }} onCancel={() => setIncidentView('list')} /> )} {incidentView === 'detail' && selectedCaseRef && ( { setSelectedCaseRef(null); setIncidentView('list'); }} /> )} )} {activeNav === 'audit' && ( )} {activeNav === 'operators' && } {activeNav === 'session' && ( )}
); }