feat(04-02): wire AlertBanner and AdminMonitoringDashboard into Dashboard

- Add AlertBanner import and render above nav (admin + active alerts only)
- Add AdminMonitoringDashboard import replacing UploadMonitoringDashboard in monitoring tab
- Add activeAlerts state (AlertEvent[]) with isAdmin-gated useEffect fetch
- Add handleAcknowledge with optimistic update and re-fetch on failure
- Remove UploadMonitoringDashboard import (replaced by AdminMonitoringDashboard)
This commit is contained in:
admin
2026-02-24 16:38:52 -05:00
parent 6ab8af3cde
commit 6c345a6cdb

View File

@@ -7,10 +7,11 @@ import DocumentUpload from './components/DocumentUpload';
import DocumentList from './components/DocumentList'; import DocumentList from './components/DocumentList';
import DocumentViewer from './components/DocumentViewer'; import DocumentViewer from './components/DocumentViewer';
import Analytics from './components/Analytics'; import Analytics from './components/Analytics';
import UploadMonitoringDashboard from './components/UploadMonitoringDashboard'; import AlertBanner from './components/AlertBanner';
import AdminMonitoringDashboard from './components/AdminMonitoringDashboard';
import LogoutButton from './components/LogoutButton'; import LogoutButton from './components/LogoutButton';
import { documentService, GCSErrorHandler, GCSError } from './services/documentService'; import { documentService, GCSErrorHandler, GCSError } from './services/documentService';
import { adminService } from './services/adminService'; import { adminService, AlertEvent } from './services/adminService';
// import { debugAuth, testAPIAuth } from './utils/authDebug'; // import { debugAuth, testAPIAuth } from './utils/authDebug';
import { import {
@@ -38,6 +39,24 @@ const Dashboard: React.FC = () => {
// Check if user is admin // Check if user is admin
const isAdmin = adminService.isAdmin(user?.email); const isAdmin = adminService.isAdmin(user?.email);
const [activeAlerts, setActiveAlerts] = useState<AlertEvent[]>([]);
useEffect(() => {
if (isAdmin) {
adminService.getAlerts().then(setActiveAlerts).catch(() => {});
}
}, [isAdmin]);
const handleAcknowledge = async (id: string) => {
setActiveAlerts(prev => prev.filter(a => a.id !== id));
try {
await adminService.acknowledgeAlert(id);
} catch {
// On failure, re-fetch to restore correct state
adminService.getAlerts().then(setActiveAlerts).catch(() => {});
}
};
// Map backend status to frontend status // Map backend status to frontend status
const mapBackendStatus = (backendStatus: string): string => { const mapBackendStatus = (backendStatus: string): string => {
switch (backendStatus) { switch (backendStatus) {
@@ -400,6 +419,9 @@ const Dashboard: React.FC = () => {
return ( return (
<div className="min-h-screen bg-gray-50"> <div className="min-h-screen bg-gray-50">
{isAdmin && activeAlerts.length > 0 && (
<AlertBanner alerts={activeAlerts} onAcknowledge={handleAcknowledge} />
)}
{/* Navigation */} {/* Navigation */}
<nav className="bg-primary-600 shadow-soft border-b border-primary-700"> <nav className="bg-primary-600 shadow-soft border-b border-primary-700">
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8"> <div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
@@ -688,7 +710,7 @@ const Dashboard: React.FC = () => {
)} )}
{activeTab === 'monitoring' && isAdmin && ( {activeTab === 'monitoring' && isAdmin && (
<UploadMonitoringDashboard /> <AdminMonitoringDashboard />
)} )}
{/* Redirect non-admin users away from admin tabs */} {/* Redirect non-admin users away from admin tabs */}