forked from RiseUP/riseup_squad_03
modified: src/App.jsx
modified: src/components/AppShell.jsx new file: src/config/permissions.js new file: src/hooks/useAuth.js new file: src/pages/UsersPage.jsx new file: src/repositories/userRepository.js
This commit is contained in:
81
src/App.jsx
81
src/App.jsx
@@ -1,9 +1,9 @@
|
||||
import { useCallback, useEffect, useMemo, useState } from 'react'
|
||||
|
||||
import { authRepository } from './repositories/authRepository.js'
|
||||
|
||||
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'
|
||||
@@ -16,11 +16,13 @@ import { ProfilePage } from './pages/ProfilePage.jsx'
|
||||
import { ReportsPage } from './pages/ReportsPage.jsx'
|
||||
import { SettingsPage } from './pages/SettingsPage.jsx'
|
||||
import { TeamPage } from './pages/TeamPage.jsx'
|
||||
import { UsersPage } from './pages/UsersPage.jsx'
|
||||
import { VisitsPage } from './pages/VisitsPage.jsx'
|
||||
import { patientRepository } from './repositories/patientRepository.js'
|
||||
|
||||
function App() {
|
||||
const [location, setLocation] = useState(() => readLocation())
|
||||
const { isAuthenticated, role, loading: authLoading } = useAuth()
|
||||
|
||||
const navigate = useCallback((to, options = {}) => {
|
||||
if (options.replace) {
|
||||
@@ -49,25 +51,47 @@ function App() {
|
||||
return () => window.removeEventListener('popstate', handlePopState)
|
||||
}, [])
|
||||
|
||||
const route = useMemo(() => resolveRoute(location.pathname, navigate), [location.pathname, navigate])
|
||||
const isAuthenticated = authRepository.isAuthenticated()
|
||||
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 (
|
||||
<div className="flex min-h-screen items-center justify-center bg-[#0a0a0a]">
|
||||
<p className="text-sm text-[#a3a3a3]">Carregando...</p>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
// Rotas públicas (sem shell)
|
||||
if (!route.withShell) {
|
||||
return route.element
|
||||
}
|
||||
|
||||
// Usuário não autenticado
|
||||
if (!isAuthenticated) {
|
||||
return <LoginPage navigate={navigate} />
|
||||
}
|
||||
|
||||
// Usuário autenticado mas sem permissão para a rota
|
||||
if (role && !canAccess(role, location.pathname)) {
|
||||
return (
|
||||
<AppShell currentPath={location.pathname} navigate={navigate} role={role} routeTitle="Sem acesso">
|
||||
<UnauthorizedPage navigate={navigate} />
|
||||
</AppShell>
|
||||
)
|
||||
}
|
||||
|
||||
return (
|
||||
<AppShell currentPath={location.pathname} navigate={navigate} routeTitle={route.title}>
|
||||
<AppShell currentPath={location.pathname} navigate={navigate} role={role} routeTitle={route.title}>
|
||||
{route.element}
|
||||
</AppShell>
|
||||
)
|
||||
}
|
||||
|
||||
function resolveRoute(pathname, navigate) {
|
||||
function resolveRoute(pathname, navigate, role) {
|
||||
if (pathname === '/' || pathname === '/login') {
|
||||
return {
|
||||
element: <LoginPage navigate={navigate} />,
|
||||
@@ -102,7 +126,7 @@ function resolveRoute(pathname, navigate) {
|
||||
|
||||
if (pathname === '/agenda') {
|
||||
return {
|
||||
element: <AgendaPage navigate={navigate} />,
|
||||
element: <AgendaPage navigate={navigate} role={role} />,
|
||||
title: 'Agenda',
|
||||
withShell: true,
|
||||
}
|
||||
@@ -110,7 +134,7 @@ function resolveRoute(pathname, navigate) {
|
||||
|
||||
if (pathname === '/pacientes') {
|
||||
return {
|
||||
element: <PatientsPage navigate={navigate} />,
|
||||
element: <PatientsPage navigate={navigate} role={role} />,
|
||||
title: 'Pacientes',
|
||||
withShell: true,
|
||||
}
|
||||
@@ -126,7 +150,6 @@ function resolveRoute(pathname, navigate) {
|
||||
|
||||
if (pathname.startsWith('/pacientes/')) {
|
||||
const patientId = pathname.split('/')[2]
|
||||
|
||||
return {
|
||||
element: <PatientDetailRoute navigate={navigate} patientId={patientId} />,
|
||||
title: 'Paciente',
|
||||
@@ -145,7 +168,7 @@ function resolveRoute(pathname, navigate) {
|
||||
if (pathname === '/laudos') {
|
||||
return {
|
||||
element: <ReportsPage navigate={navigate} />,
|
||||
title: 'Relatorios medicos',
|
||||
title: 'Relatórios médicos',
|
||||
withShell: true,
|
||||
}
|
||||
}
|
||||
@@ -174,6 +197,14 @@ function resolveRoute(pathname, navigate) {
|
||||
}
|
||||
}
|
||||
|
||||
if (pathname === '/usuarios') {
|
||||
return {
|
||||
element: <UsersPage role={role} />,
|
||||
title: 'Usuários',
|
||||
withShell: true,
|
||||
}
|
||||
}
|
||||
|
||||
if (pathname === '/perfil') {
|
||||
return {
|
||||
element: <ProfilePage navigate={navigate} />,
|
||||
@@ -192,7 +223,7 @@ function resolveRoute(pathname, navigate) {
|
||||
|
||||
return {
|
||||
element: <NotFoundPage navigate={navigate} />,
|
||||
title: 'Tela nao encontrada',
|
||||
title: 'Página não encontrada',
|
||||
withShell: true,
|
||||
}
|
||||
}
|
||||
@@ -204,7 +235,8 @@ function PatientDetailRoute({ navigate, patientId }) {
|
||||
useEffect(() => {
|
||||
let active = true
|
||||
|
||||
patientRepository.getById(patientId)
|
||||
patientRepository
|
||||
.getById(patientId)
|
||||
.then((data) => {
|
||||
if (active) setPatient(data)
|
||||
})
|
||||
@@ -221,7 +253,30 @@ function PatientDetailRoute({ navigate, patientId }) {
|
||||
return <div className="pt-10 text-sm text-[#a3a3a3]">Carregando paciente...</div>
|
||||
}
|
||||
|
||||
return patient ? <PatientDetailPage navigate={navigate} patient={patient} /> : <NotFoundPage navigate={navigate} />
|
||||
return patient ? (
|
||||
<PatientDetailPage navigate={navigate} patient={patient} />
|
||||
) : (
|
||||
<NotFoundPage navigate={navigate} />
|
||||
)
|
||||
}
|
||||
|
||||
function UnauthorizedPage({ navigate }) {
|
||||
return (
|
||||
<div className="flex flex-col items-center justify-center py-20 text-center">
|
||||
<p className="text-5xl">🔒</p>
|
||||
<h1 className="mt-4 text-2xl font-bold text-[#e5e5e5]">Acesso não permitido</h1>
|
||||
<p className="mt-2 text-sm text-[#a3a3a3]">
|
||||
Você não tem permissão para acessar esta página.
|
||||
</p>
|
||||
<button
|
||||
className="mt-6 rounded-lg bg-[#3b82f6] px-5 py-2.5 text-sm font-medium text-white transition hover:bg-[#2563eb]"
|
||||
onClick={() => navigate('/inicio')}
|
||||
type="button"
|
||||
>
|
||||
Voltar ao painel
|
||||
</button>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
function readLocation() {
|
||||
|
||||
Reference in New Issue
Block a user