All files / src/components/Navbar Navbar.tsx

100% Statements 10/10
100% Branches 2/2
100% Functions 4/4
100% Lines 7/7

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118                                    1x               6x 6x 6x     6x 6x   6x                                                                                                                                                                      
import React, { Suspense } from 'react';
import AppBar           from '@mui/material/AppBar';
import Toolbar          from '@mui/material/Toolbar';
import IconButton       from '@mui/material/IconButton';
import Box              from '@mui/material/Box';
import Drawer           from '@mui/material/Drawer';
import useMediaQuery    from '@mui/material/useMediaQuery';
import CircularProgress from '@mui/material/CircularProgress';
import MenuIcon         from '@mui/icons-material/Menu';
import { useTheme } from '@mui/material/styles';
import { useTranslation } from 'react-i18next';
import { NavLinkList } from './NavLinkList';
import logoSrc from '../../assets/logos/logo_arcs.png';
import logoParis from '../../assets/logos/logo_paris.png';
import LanguageSwitcher from '../LanguageSwitcher';
import ThemeToggle from '../ThemeToggle';
import AuthMenu from '../AuthMenu/AuthMenu';
 
const CartPreview = React.lazy(() => import('../CartPreview/CartPreview'));
 
interface NavbarProps {
  mode: 'light' | 'dark';
  toggleMode: () => void;
}
 
function Navbar({ mode, toggleMode }: NavbarProps) {
  const { t } = useTranslation();
  const theme = useTheme();
  const isMobile = useMediaQuery(theme.breakpoints.down('sm'));
 
  // ─── État du drawer mobile ───────────────────────────────────────────────
  const [open, setOpen] = React.useState(false);
  const toggleDrawer = () => setOpen(o => !o);
 
  return (
    <>
      <AppBar position="fixed" color="inherit" elevation={0}
        sx={{ borderBottom: '1px solid', borderColor: 'divider' }}>
        <Toolbar variant="dense" sx={{ justifyContent: 'space-between' }}>
 
          {isMobile ? (
            // ────────── BARRE MOBILE ──────────
            <>
              {/* menu burger */}
              <IconButton edge="start" onClick={toggleDrawer} aria-label={t('navbar.menu')}>
                <MenuIcon />
              </IconButton>
          
              {/* logos centrés */}
              <Box sx={{ display: 'flex', alignItems: 'center', gap: 1 }}>
                <Box component="img" src={logoSrc} alt={t('navbar.logoJO')} sx={{ height: 32 }} />
                <Box component="img" src={logoParis} alt={t('navbar.logoParis')} sx={{ height: 32 }} />
              </Box>
 
              <Suspense fallback={<CircularProgress size={24} />}>
                <CartPreview />
              </Suspense>
            </>
          ) : (
            // ────────── BARRE DESKTOP ──────────
            <>
              {/* logos + nav principale */}
              <Box sx={{ display: 'flex', alignItems: 'center', gap: 2 }}>
                <Box sx={{ display: 'flex', alignItems: 'center', gap: 1, mr: 1 }}>
                  <Box component="img" src={logoSrc} alt={t('navbar.logoJO')} sx={{ height: 32 }} />
                  <Box component="img" src={logoParis} alt={t('navbar.logoParis')} sx={{ height: 32 }} />
                </Box>
                <NavLinkList isMobile={false} />
              </Box>
 
              {/* utilitaires */}
              <Box sx={{ display: 'flex', alignItems: 'center', gap: 2 }}>
                <ThemeToggle
                  mode={mode}
                  toggleMode={toggleMode}
                  aria-label={t('navbar.toggleTheme')}
                />
                <LanguageSwitcher />
                <AuthMenu />
                <Suspense fallback={<CircularProgress size={24} />}>
                  <CartPreview />
                </Suspense>
              </Box>
            </>
          )}
        </Toolbar>
      </AppBar>
 
      {/* ────────── DRAWER MOBILE ────────── */}
      <Drawer anchor="left" open={open} onClose={toggleDrawer}>
        <Box sx={{ width: 250, height: '100%', display: 'flex', flexDirection: 'column' }}>
 
          {/* En-tête logos centré */}
          <Box sx={{ display: 'flex', justifyContent: 'center', alignItems: 'center', gap: 1, p: 2 }}>
            <Box component="img" src={logoSrc} alt={t('navbar.logoJO')} sx={{ height: 32 }} />
            <Box component="img" src={logoParis} alt={t('navbar.logoParis')} sx={{ height: 32 }} />
          </Box>
 
          {/* Liens principaux */}
          <NavLinkList isMobile toggleDrawer={toggleDrawer} />
 
          {/* Pied de drawer : langue + thème */}
          <Box sx={{ mt: 'auto', p: 2, display: 'flex', alignItems: 'center', justifyContent: 'space-between' }}>
            <LanguageSwitcher />
              <ThemeToggle
                mode={mode}
                toggleMode={toggleMode}
                aria-label={t('navbar.toggleTheme')}
              />
          </Box>
        </Box>
      </Drawer>
    </>
  );
}
 
export default Navbar;