All files / apps/web/src/backoffice/components AdminLayout.jsx

0% Statements 0/23
0% Branches 0/18
0% Functions 0/10
0% Lines 0/17

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                                                                                                                                                                                               
import { Outlet, Link, useLocation } from 'react-router-dom'
import { Users, Building2, Play } from 'lucide-react'
import { useState, useEffect, useRef } from 'react'
import AppHeader from '../../components/AppHeader'
 
const DESKTOP_QUERY = '(min-width: 1024px)'
 
function AdminLayout() {
  // Sidebar ouverte par défaut sur desktop, fermée sur mobile (drawer).
  const [menuOpen, setMenuOpen] = useState(
    () => typeof window !== 'undefined' && window.matchMedia(DESKTOP_QUERY).matches,
  )
  const isDesktopRef = useRef(typeof window !== 'undefined' && window.matchMedia(DESKTOP_QUERY).matches)
  const location = useLocation()
 
  useEffect(() => {
    const mql = window.matchMedia(DESKTOP_QUERY)
    const onChange = (e) => { isDesktopRef.current = e.matches }
    mql.addEventListener('change', onChange)
    return () => mql.removeEventListener('change', onChange)
  }, [])
 
  useEffect(() => {
    if (!isDesktopRef.current) setMenuOpen(false) // ferme le drawer mobile à la navigation
  }, [location.pathname])
 
  const closeOnMobile = () => { if (!isDesktopRef.current) setMenuOpen(false) }
 
  const nav = (
    <div className="p-2 overflow-y-auto flex-1 space-y-1">
      <Link
        to="/admin/users"
        onClick={closeOnMobile}
        className={`flex items-center px-4 py-2 rounded-lg transition-all text-sm ${
          location.pathname === '/admin/users'
            ? 'bg-indigo-600 text-white border-l-4 border-indigo-500'
            : 'text-slate-300 hover:bg-slate-800 hover:text-white border-l-4 border-transparent'
        }`}
      >
        <Users className="w-5 h-5 flex-shrink-0" />
        <span className="ml-3 font-medium">Utilisateurs</span>
      </Link>
      <Link
        to="/admin/organizations"
        onClick={closeOnMobile}
        className={`flex items-center px-4 py-2 rounded-lg transition-all text-sm ${
          location.pathname === '/admin/organizations'
            ? 'bg-indigo-600 text-white border-l-4 border-indigo-500'
            : 'text-slate-300 hover:bg-slate-800 hover:text-white border-l-4 border-transparent'
        }`}
      >
        <Building2 className="w-5 h-5 flex-shrink-0" />
        <span className="ml-3 font-medium">Organisations</span>
      </Link>
      <Link
        to="/"
        onClick={closeOnMobile}
        className="flex items-center px-4 py-2 rounded-lg transition-all text-sm text-slate-300 hover:bg-slate-800 hover:text-white border-l-4 border-transparent"
      >
        <Play className="w-5 h-5 flex-shrink-0" />
        <span className="ml-3 font-medium">Retour à l'interface</span>
      </Link>
    </div>
  )
 
  return (
    <div className="min-h-screen bg-gray-100">
      {/* Backdrop — mobile uniquement */}
      {menuOpen && (
        <div className="fixed inset-0 z-[35] bg-gray-900/50 lg:hidden" onClick={() => setMenuOpen(false)} />
      )}
 
      {/* Sidebar : persistante (ouvrable/fermable) sur desktop, drawer sur mobile */}
      <aside
        className={`fixed top-16 bottom-0 left-0 z-[36] w-72 bg-slate-900 text-white overflow-y-auto flex flex-col transition-transform duration-200 ${
          menuOpen ? 'translate-x-0' : '-translate-x-full'
        }`}
      >
        {nav}
      </aside>
 
      <div className="min-h-screen flex flex-col">
        <AppHeader mode="admin" dark onOpenSidebar={() => setMenuOpen((v) => !v)} />
 
        <main className={`flex-1 transition-all duration-200 ${menuOpen ? 'lg:pl-72' : 'lg:pl-0'}`}>
          <div className="p-3 sm:p-4 lg:p-8">
            <Outlet context={{ navOpen: menuOpen }} />
          </div>
        </main>
      </div>
    </div>
  )
}
 
export default AdminLayout