import { NavLink } from 'react-router-dom';
import { LayoutDashboard, Settings, Shield, X, Palette, Globe, CalendarDays, FileText, Lock } from 'lucide-react';
import BrandLogo from './BrandLogo';
import { useAuth } from '../contexts/AuthContext';
import { useLanguage } from '../contexts/LanguageContext';
import { useBranding } from '../contexts/BrandingContext';
import ThemeSelector from './ThemeSelector';
import { useState, useEffect } from 'react';
import api from '../services/api';
export default function Sidebar({ open, onClose }) {
const { user } = useAuth();
const { t } = useLanguage();
const { imprintUrl, privacyUrl } = useBranding();
const [themeOpen, setThemeOpen] = useState(false);
const [federationCount, setFederationCount] = useState(0);
// On mobile the sidebar is an off-canvas drawer: while closed it must be
// inert so its links aren't reachable via Tab or screen readers. On
// desktop (lg+) it is always visible and never inert.
const [isDesktop, setIsDesktop] = useState(
() => window.matchMedia('(min-width: 1024px)').matches
);
useEffect(() => {
const mq = window.matchMedia('(min-width: 1024px)');
const handleChange = (e) => setIsDesktop(e.matches);
mq.addEventListener('change', handleChange);
return () => mq.removeEventListener('change', handleChange);
}, []);
// Fetch pending federation invitation count
useEffect(() => {
const fetchCount = async () => {
try {
const res = await api.get('/federation/invitations/pending-count');
setFederationCount(res.data.count || 0);
} catch {
// Ignore — federation may not be enabled
}
};
fetchCount();
const interval = setInterval(fetchCount, 30000);
return () => clearInterval(interval);
}, []);
const navItems = [
{ to: '/dashboard', icon: LayoutDashboard, label: t('nav.dashboard') },
{ to: '/calendar', icon: CalendarDays, label: t('nav.calendar') },
{ to: '/federation/inbox', icon: Globe, label: t('nav.federation'), badge: federationCount },
{ to: '/settings', icon: Settings, label: t('nav.settings') },
];
if (user?.role === 'admin') {
navItems.push({ to: '/admin', icon: Shield, label: t('nav.admin') });
}
const linkClasses = ({ isActive }) =>
`flex items-center gap-3 px-3 py-2.5 rounded-lg text-sm font-medium transition-all duration-200 ${isActive
? 'bg-th-accent text-th-accent-t shadow-xs'
: 'text-th-text-s hover:text-th-text hover:bg-th-hover'
}`;
return (
<>
{/* Theme Selector Modal */}
{themeOpen && setThemeOpen(false)} />}
>
);
}