import React from 'react';
import { Link } from 'react-router-dom';
import { useTranslation } from 'react-i18next';
import {
X,
Home,
Zap,
Trophy,
Shield,
Sparkles,
Gamepad2,
Search,
Compass,
Users,
UserPlus,
FlaskConical,
BrainCircuit,
Eye,
LogIn,
Microscope,
Database,
Share2,
Download,
BookOpen,
type LucideIcon,
} from 'lucide-react';
import { AdSlot } from '../../features/billing/components/AdSlot';
import { User } from '../../types';
const SIDEBAR_AD_SLOT = import.meta.env.VITE_ADSENSE_SLOT_SIDEBAR as string | undefined;
interface SidebarDrawerProps {
isSidebarOpen: boolean;
isAuthenticated: boolean;
user: User | null;
pathname: string;
toggleSidebar: (forceClose?: boolean) => void;
}
interface NavDef {
to: string;
icon: LucideIcon;
label: string;
color: string;
}
const SectionLabel: React.FC<{ children: React.ReactNode }> = ({ children }) => (
{children}
);
const NavItem: React.FC<{ item: NavDef; active: boolean; onClick: () => void }> = ({
item,
active,
onClick,
}) => {
const { icon: Icon, to, label, color } = item;
return (
{active && (
)}
{label}
);
};
const SidebarDrawer: React.FC = ({
isSidebarOpen,
isAuthenticated,
user,
pathname,
toggleSidebar,
}) => {
const { t } = useTranslation();
const close = () => toggleSidebar(true);
const mainLinks: NavDef[] = [
{
to: '/',
icon: Home,
label: t('nav.home', 'Accueil'),
color: 'text-gray-500 dark:text-gray-400',
},
{
to: '/daily-challenge/',
icon: Zap,
label: t('nav.daily', 'Défi Quotidien'),
color: 'text-yellow-400',
},
{ to: '/games/hub/', icon: Gamepad2, label: t('nav.games', 'Jeux'), color: 'text-violet-400' },
];
const exploreLinks: NavDef[] = [
{ to: '/search/', icon: Search, label: t('nav.search', 'Recherche'), color: 'text-cyan-400' },
{
to: '/explore/',
icon: Compass,
label: t('nav.explore', 'Explorer'),
color: 'text-emerald-400',
},
{
to: '/media/manga/library/',
icon: BookOpen,
label: t('nav.library', 'Ma Bibliothèque'),
color: 'text-pink-400',
},
{
to: '/media/manga/offline/',
icon: Download,
label: t('nav.offline_manga', 'Manga Hors-ligne'),
color: 'text-orange-400',
},
];
const communityLinks: NavDef[] = [
{
to: '/social/dashboard/',
icon: Users,
label: t('nav.community', 'Communauté'),
color: 'text-orange-400',
},
...(isAuthenticated
? [
{
to: '/social/friends/',
icon: UserPlus,
label: t('nav.friends', 'Amis'),
color: 'text-pink-400',
},
{
to: '/social/sync/',
icon: Database,
label: t('nav.offline_sync', 'Sync Hors-ligne'),
color: 'text-yellow-400',
},
]
: []),
{
to: '/leaderboard/',
icon: Trophy,
label: t('nav.leaderboard', 'Classement'),
color: 'text-yellow-500',
},
];
// Labs is a hub (/lab/) that links to every experimental tool, so a single entry is enough.
const creationLinks: NavDef[] = [
{
to: '/lab/forge-hub/',
icon: Sparkles,
label: t('nav.forge', 'Forge Créative'),
color: 'text-purple-400',
},
{ to: '/lab/', icon: FlaskConical, label: t('nav.labs_hub', 'Labs'), color: 'text-green-400' },
{
to: '/research/papers/',
icon: Microscope,
label: t('nav.research', 'Recherche IA'),
color: 'text-cyan-500',
},
];
const systemLinks: NavDef[] = [
{
to: '/social/nexus/',
icon: BrainCircuit,
label: t('nav.nexus', 'Nexus Pro'),
color: 'text-fuchsia-400',
},
{
to: '/social/transparency/',
icon: Eye,
label: t('navbar.transparency', 'Transparence'),
color: 'text-slate-400',
},
{
to: '/social/open-data/',
icon: Share2,
label: t('nav.open_data', 'Portail Open Data'),
color: 'text-teal-400',
},
];
const xp = user?.xp ?? 0;
const level = Math.max(1, Math.floor(xp / 500));
const xpProgress = ((xp % 500) / 500) * 100;
return (
);
};
export default React.memo(SidebarDrawer);