import { useCallback, useEffect, useMemo, useState } from 'react' import './App.css' import { AppShell } from './components/AppShell.jsx' import { canAccess } from './config/permissions.js' import { useAuth } from './hooks/useAuth.js' import { AgendaPage } from './pages/AgendaPage.jsx' import { AnalyticsPage } from './pages/AnalyticsPage.jsx' import { ForgotPasswordPage, LoginPage, RegisterPage } from './pages/AuthPages.jsx' import { HomePage } from './pages/HomePage.jsx' import { MedicalRecordsPage } from './pages/MedicalRecordsPage.jsx' import { MessagesPage } from './pages/MessagesPage.jsx' import { NotFoundPage } from './pages/NotFoundPage.jsx' import { PatientDetailPage, PatientsPage } from './pages/PatientsPage.jsx' import { ProfilePage } from './pages/ProfilePage.jsx' import { ReportsPage } from './pages/ReportsPage.jsx' import { SettingsPage } from './pages/SettingsPage.jsx' import { UsersPage } from './pages/UsersPage.jsx' import { VisitsPage } from './pages/VisitsPage.jsx' import { patientRepository } from './repositories/patientRepository.js' const PANEL_PATHS = ['/inicio', '/home', '/dashboard'] const ROLE_HOME_PATHS = { medico: '/agenda', secretaria: '/agenda', } function App() { const [location, setLocation] = useState(() => readLocation()) const { isAuthenticated, role, loading: authLoading } = useAuth() const navigate = useCallback((to, options = {}) => { if (options.replace) { window.history.replaceState({}, '', to) } else { window.history.pushState({}, '', to) } setLocation(readLocation()) const hash = to.split('#')[1] window.requestAnimationFrame(() => { if (hash) { document.getElementById(hash)?.scrollIntoView({ block: 'start' }) } else { window.scrollTo({ left: 0, top: 0 }) } }) }, []) useEffect(() => { function handlePopState() { setLocation(readLocation()) } window.addEventListener('popstate', handlePopState) return () => window.removeEventListener('popstate', handlePopState) }, []) const route = useMemo( () => resolveRoute(location.pathname, navigate, role), [location.pathname, navigate, role], ) // Tela de carregamento enquanto busca o role do usuário if (authLoading) { return (

Carregando...

) } // Rotas públicas (sem shell) if (!route.withShell) { return route.element } // Usuário não autenticado if (!isAuthenticated) { return } // Usuário autenticado mas sem permissão para a rota if (!role || !canAccess(role, location.pathname)) { const roleHomePath = ROLE_HOME_PATHS[role] if (roleHomePath && PANEL_PATHS.includes(location.pathname)) { navigate(roleHomePath, { replace: true }) return null } return ( ) } return ( {route.element} ) } function resolveRoute(pathname, navigate, role) { if (pathname === '/' || pathname === '/login') { return { element: , title: 'Login', withShell: false, } } if (pathname === '/cadastro') { return { element: , title: 'Cadastro', withShell: false, } } if (pathname === '/recuperar-senha') { return { element: , title: 'Recuperar senha', withShell: false, } } if (pathname === '/inicio' || pathname === '/home' || pathname === '/dashboard') { return { element: , title: 'Painel', withShell: true, } } if (pathname === '/agenda') { return { element: , title: 'Agenda', withShell: true, } } if (pathname === '/pacientes') { return { element: , title: 'Pacientes', withShell: true, } } if (pathname === '/prontuario') { return { element: , title: 'Prontuário', withShell: true, } } if (pathname.startsWith('/pacientes/')) { const patientId = pathname.split('/')[2] return { element: , title: 'Paciente', withShell: true, } } if (pathname === '/consultas') { return { element: , title: 'Consultas', withShell: true, } } if (pathname === '/laudos') { return { element: , title: 'Relatórios', withShell: true, } } if (pathname === '/relatorios') { return { element: , title: 'Analytics', withShell: true, } } if (pathname === '/camunicacao') { navigate('/comunicacao', { replace: true }) return { element: , title: 'Comunicação', withShell: true, } } if (pathname === '/comunicacao' || pathname === '/mensagens') { return { element: , title: 'Comunicação', withShell: true, } } if (pathname === '/usuarios') { return { element: , title: 'Usuários', withShell: true, } } if (pathname === '/perfil') { return { element: , title: 'Perfil', withShell: true, } } if (pathname === '/configuracoes' || pathname === '/config') { return { element: , title: 'Configurações', withShell: true, } } return { element: , title: 'Página não encontrada', withShell: true, } } function PatientDetailRoute({ navigate, patientId, role }) { const [patient, setPatient] = useState(null) const [loading, setLoading] = useState(true) useEffect(() => { let active = true patientRepository .getById(patientId) .then((data) => { if (active) setPatient(data) }) .finally(() => { if (active) setLoading(false) }) return () => { active = false } }, [patientId]) if (loading) { return
Carregando paciente...
} return patient ? ( ) : ( ) } function UnauthorizedPage({ navigate }) { return (

🔒

Acesso não permitido

Você não tem permissão para acessar esta página.

) } function readLocation() { return { pathname: normalizePath(window.location.pathname), search: window.location.search, } } function normalizePath(pathname) { if (!pathname || pathname === '/') { return '/' } return pathname.replace(/\/+$/, '') } export default App