import React, { useState, useEffect, useRef } from 'react'; import { Link, NavLink, useNavigate, useLocation } from 'react-router-dom'; import { useAuth } from './AuthContext'; export const Layout = ({ children }) => { const { user, logout } = useAuth(); const navigate = useNavigate(); const location = useLocation(); const searchParams = new URLSearchParams(location.search); const urlQuery = searchParams.get('q') || ''; const [globalSearchQuery, setGlobalSearchQuery] = useState(urlQuery); useEffect(() => { setGlobalSearchQuery(urlQuery); }, [urlQuery]); const [isDemoMode, setIsDemoMode] = useState(false); const [isProfileOpen, setIsProfileOpen] = useState(false); const [isNotificationsOpen, setIsNotificationsOpen] = useState(false); const [notifications, setNotifications] = useState([]); const [loadingNotifications, setLoadingNotifications] = useState(false); const [hasUnreadNotifications, setHasUnreadNotifications] = useState(false); const notificationsRef = useRef(null); const profileRef = useRef(null); useEffect(() => { const handleClickOutside = (event) => { if (notificationsRef.current && !notificationsRef.current.contains(event.target)) { setIsNotificationsOpen(false); } if (profileRef.current && !profileRef.current.contains(event.target)) { setIsProfileOpen(false); } }; document.addEventListener("mousedown", handleClickOutside); return () => { document.removeEventListener("mousedown", handleClickOutside); }; }, []); const fetchNotifications = async () => { if (!user) return; setLoadingNotifications(true); try { const token = localStorage.getItem('wss_token') || sessionStorage.getItem('wss_token'); const res = await fetch('/api/auth/notifications', { headers: { 'Authorization': `Bearer ${token}` } }); if (res.ok) { const data = await res.json(); const fetched = data.notifications || []; const lastSeenId = localStorage.getItem('last_seen_notification_id'); if (fetched.length > 0 && String(fetched[0].id) !== lastSeenId) { setHasUnreadNotifications(true); } setNotifications(fetched); } } catch (err) { console.error("Failed to fetch notifications:", err); } finally { setLoadingNotifications(false); } }; useEffect(() => { if (user) { fetchNotifications(); const interval = setInterval(fetchNotifications, 60000); // refresh every minute return () => clearInterval(interval); } }, [user]); useEffect(() => { setIsDemoMode(!!window.WSS_DEMO_MODE); const checkInterval = setInterval(() => { setIsDemoMode(!!window.WSS_DEMO_MODE); }, 1000); return () => clearInterval(checkInterval); }, []); // Force removal of dark theme and clear localStorage keys useEffect(() => { document.documentElement.classList.remove('dark'); localStorage.removeItem('color-theme'); }, []); const [impersonationToken, setImpersonationToken] = useState(null); const [organizations, setOrganizations] = useState([]); useEffect(() => { setImpersonationToken(localStorage.getItem('original_admin_token')); }, [location.pathname]); useEffect(() => { const fetchOrgs = async () => { const adminToken = localStorage.getItem('original_admin_token') || localStorage.getItem('wss_token') || sessionStorage.getItem('wss_token'); // Only attempt if they might be an admin if (!adminToken) return; try { const res = await fetch('/api/auth/organizations', { headers: { 'Authorization': `Bearer ${adminToken}` } }); if (res.ok) { const data = await res.json(); setOrganizations(data.organizations || []); } } catch (err) { console.error("Failed to fetch organizations for dropdown", err); } }; const isSuperAdmin = user?.role === 'super_admin' || user?.role === 'admin' || localStorage.getItem('original_admin_token'); if (isSuperAdmin) { fetchOrgs(); } }, [user]); const handleReturnToAdmin = () => { const orig = localStorage.getItem('original_admin_token'); if (orig) { localStorage.removeItem('original_admin_token'); localStorage.setItem('wss_token', orig); window.location.href = location.pathname; } }; const handleLogout = () => { const isSuperAdmin = user?.role === 'super_admin' || sessionStorage.getItem('superAdminAuth') === 'true'; logout(); sessionStorage.removeItem('superAdminAuth'); localStorage.removeItem('original_admin_token'); navigate(isSuperAdmin ? '/' : '/login'); }; let navItems = []; if (user?.role === 'executive_user') { navItems = [ { to: '/scans/history', label: 'Organization Reports', icon: 'analytics' }, { to: '/settings', label: 'Settings', icon: 'settings' }, ]; } else { navItems = [ { to: '/dashboard', label: 'Dashboard', icon: 'dashboard' }, { to: '/scans/new', label: 'New Scan', icon: 'security' }, { to: '/scans/history', label: 'Reports', icon: 'analytics' }, { to: '/scans/results', label: 'Vulnerabilities', icon: 'bug_report' }, { to: '/settings', label: 'Settings', icon: 'settings' }, ]; } if (user?.role === 'super_admin') { navItems.push({ to: '/super-admin', label: 'Global Management', icon: 'admin_panel_settings' }); } return (
{user.email}
{(user.role || 'User').replace(/_/g, ' ')}