From 0343b4452319123b9dd6211ca988b29163ba37d8 Mon Sep 17 00:00:00 2001 From: DesmondL-dev <161560016+DesmondL-dev@users.noreply.github.com> Date: Wed, 11 Mar 2026 22:21:14 -0400 Subject: [PATCH] feat(dashboard): decouple AODA telemetry and inject meltdown beacon Implement isolated AODA onboarding toast and persistent visual CTA for the 5-min session teardown feature to enhance non-technical recruiter evaluation. --- .../dashboard/components/DashboardLayout.tsx | 26 +++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/src/features/dashboard/components/DashboardLayout.tsx b/src/features/dashboard/components/DashboardLayout.tsx index 8bddc4b..85cb3ac 100644 --- a/src/features/dashboard/components/DashboardLayout.tsx +++ b/src/features/dashboard/components/DashboardLayout.tsx @@ -2,11 +2,13 @@ import { useEffect, useState } from 'react'; import { useNavigate } from 'react-router-dom'; import { DashboardView } from './DashboardView'; import { AodaTelemetryHUD } from './AodaTelemetryHUD'; -import { LogOut, Shield } from 'lucide-react'; +import { LogOut, Shield, Keyboard, X } from 'lucide-react'; import { useAuthStore } from '../../auth/store/useAuthStore'; import { SessionTimeoutModal } from '../../auth/components/SessionTimeoutModal'; import { useIdleTimeout } from '../hooks/useIdleTimeout'; import { useAodaTelemetry } from '../store/useAodaTelemetry'; +import { useDemoMode } from '../../../core/hooks/useDemoMode'; +import { DemoBeacon } from '../../../core/components/DemoBeacon'; // Protected zone shell — rendered exclusively after the ProtectedRoute // perimeter has validated the authentication predicate. @@ -22,11 +24,19 @@ export const DashboardLayout = () => { const navigate = useNavigate(); const { isIdle, resetIdleTimer, forceTimeout } = useIdleTimeout(); const [isModalOpen, setIsModalOpen] = useState(false); + const { isDemoMode } = useDemoMode(); + const [showAodaToast, setShowAodaToast] = useState(false); useEffect(() => { if (isIdle) setIsModalOpen(true); }, [isIdle]); + useEffect(() => { + if (!isDemoMode) return; + const t = setTimeout(() => setShowAodaToast(true), 2000); + return () => clearTimeout(t); + }, [isDemoMode]); + // Session teardown pipeline: wipe in-memory state machine first, // then redirect — guarantees no stale auth payload persists during // the navigation transition (OWASP A07). @@ -55,10 +65,11 @@ export const DashboardLayout = () => { {/* Dead Man's Switch trigger — intentionally low-contrast to remain invisible during normal operation; surfaces only to a trained eye during live demos. Bypasses the IDLE_MS wall clock via forceTimeout escape hatch. */} + + + )} ); };