function App() { const [route, setRoute] = React.useState(''); const [user, setUser] = React.useState(API.getUser()); // Hash router const navigate = (hash) => { window.location.hash = hash; }; React.useEffect(() => { const handleHash = () => { const hash = window.location.hash.slice(1) || '/'; setRoute(hash); // Auth guard if (!API.isLoggedIn() && hash !== '/login') { navigate('#/login'); return; } if (API.isLoggedIn() && hash === '/login') { navigate('#/projects'); return; } }; window.addEventListener('hashchange', handleHash); handleHash(); return () => window.removeEventListener('hashchange', handleHash); }, []); const handleLogin = (userData) => { setUser(userData); navigate('#/projects'); }; const handleLogout = () => { API.logout(); setUser(null); }; // Route matching const projectMatch = route.match(/^\/project\/(\d+)$/); const projectId = projectMatch ? parseInt(projectMatch[1]) : null; // Login page (no header) if (route === '/login' || !API.isLoggedIn()) { return React.createElement(LoginPage, { onLogin: handleLogin }); } // Build breadcrumb let breadcrumb = null; if (projectId) { breadcrumb = React.createElement('div', { className: 'header-breadcrumb' }, React.createElement('a', { href: '#/projects' }, 'Projets'), React.createElement('span', { className: 'sep' }, '/'), React.createElement('span', { className: 'current' }, 'Projet') ); } else if (route === '/admin') { breadcrumb = React.createElement('div', { className: 'header-breadcrumb' }, React.createElement('a', { href: '#/projects' }, 'Projets'), React.createElement('span', { className: 'sep' }, '/'), React.createElement('span', { className: 'current' }, 'Administration') ); } const isAdmin = user && user.role === 'admin'; const initials = user ? (user.display_name || user.username || '?').substring(0, 2).toUpperCase() : '?'; return React.createElement('div', { className: 'app-shell' }, // Header React.createElement('div', { className: 'app-header' }, React.createElement('div', { className: 'header-left' }, React.createElement('span', { className: 'header-brand', onClick: () => navigate('#/projects') }, 'APROGSYS'), breadcrumb ), React.createElement('div', { className: 'header-right' }, isAdmin && React.createElement('button', { className: 'btn btn-ghost btn-sm', onClick: () => navigate('#/admin'), style: route === '/admin' ? { borderColor: 'var(--accent)', color: 'var(--accent)' } : {} }, '\u2699 Admin'), React.createElement('div', { className: 'header-user' }, React.createElement('span', { className: 'avatar' }, initials), React.createElement('span', null, user ? (user.display_name || user.username) : ''), ), React.createElement('button', { className: 'btn btn-ghost btn-sm', onClick: handleLogout, title: 'Déconnexion' }, '\u23FB') ) ), // Content projectId ? React.createElement(ProjectView, { key: projectId, projectId, onBack: () => navigate('#/projects'), user }) : route === '/admin' && isAdmin ? React.createElement(AdminPanel, { user }) : React.createElement(ProjectList, { onSelectProject: (id) => navigate(`#/project/${id}`), user }) ); } // Mount ReactDOM.createRoot(document.getElementById('root')).render(React.createElement(App));