Resumen de lo entregado
Some checks failed
/ Deploy to Cloudflare Pages (push) Has been cancelled

This commit is contained in:
2026-07-07 09:47:31 -03:00
parent 2922d4c2f3
commit bc9f70419c
26 changed files with 4102 additions and 23 deletions

View File

@@ -6,6 +6,11 @@ import { LibraryPage } from '@/features/library/LibraryPage'
import { SettingsPage } from '@/features/settings/SettingsPage'
import { ResourceCatalogPage } from '@/features/resources/ResourceCatalogPage'
import { LoginPage } from '@/features/login/LoginPage'
import { ResetPasswordPage } from '@/features/auth/ResetPasswordPage'
import { AdminLayout } from '@/features/admin/AdminLayout'
import { OrganizationsPage } from '@/features/admin/OrganizationsPage'
import { OrganizationDetailPage } from '@/features/admin/OrganizationDetailPage'
import { UsersPage } from '@/features/admin/UsersPage'
import { useAuth } from '@/auth/AuthContext'
import { Loader2 } from 'lucide-react'
@@ -26,19 +31,26 @@ function ReportPageWithSuspense() {
)
}
const PUBLIC_PATHS = ['/login', '/reset-password']
function RootComponent() {
const { user, loading } = useAuth()
const { user, loading, pendingPasswordReset } = useAuth()
const navigate = useNavigate()
const pathname = useRouterState({ select: (s) => s.location.pathname })
useEffect(() => {
if (loading) return
if (!user && pathname !== '/login') {
// Usuario con PASSWORD_RECOVERY activo → forzar /reset-password
if (user && pendingPasswordReset && pathname !== '/reset-password') {
void navigate({ to: '/reset-password' })
return
}
if (!user && !PUBLIC_PATHS.includes(pathname)) {
void navigate({ to: '/login' })
} else if (user && pathname === '/login') {
} else if (user && !pendingPasswordReset && pathname === '/login') {
void navigate({ to: '/' })
}
}, [user, loading, pathname, navigate])
}, [user, loading, pathname, navigate, pendingPasswordReset])
if (loading) {
return (
@@ -48,7 +60,7 @@ function RootComponent() {
)
}
if (!user && pathname !== '/login') return (
if (!user && !PUBLIC_PATHS.includes(pathname)) return (
<div className="min-h-screen flex items-center justify-center">
<Loader2 className="h-8 w-8 animate-spin" style={{ color: '#F59845' }} />
</div>
@@ -57,6 +69,13 @@ function RootComponent() {
return <Outlet />
}
// Redirect /admin → /admin/organizations
function AdminIndexRedirect() {
const navigate = useNavigate()
useEffect(() => { void navigate({ to: '/admin/organizations' }) }, [navigate])
return null
}
const rootRoute = createRootRoute({ component: RootComponent })
const loginRoute = createRoute({
@@ -65,6 +84,12 @@ const loginRoute = createRoute({
component: LoginPage,
})
const resetPasswordRoute = createRoute({
getParentRoute: () => rootRoute,
path: '/reset-password',
component: ResetPasswordPage,
})
const indexRoute = createRoute({
getParentRoute: () => rootRoute,
path: '/',
@@ -101,14 +126,53 @@ const resourcesRoute = createRoute({
component: ResourceCatalogPage,
})
// ─── Admin routes (guard de platform_admin en AdminLayout) ────────────────────
const adminLayoutRoute = createRoute({
getParentRoute: () => rootRoute,
path: '/admin',
component: AdminLayout,
})
const adminIndexRoute = createRoute({
getParentRoute: () => adminLayoutRoute,
path: '/',
component: AdminIndexRedirect,
})
const adminOrgsRoute = createRoute({
getParentRoute: () => adminLayoutRoute,
path: '/organizations',
component: OrganizationsPage,
})
const adminOrgDetailRoute = createRoute({
getParentRoute: () => adminLayoutRoute,
path: '/organizations/$orgId',
component: OrganizationDetailPage,
})
const adminUsersRoute = createRoute({
getParentRoute: () => adminLayoutRoute,
path: '/users',
component: UsersPage,
})
const routeTree = rootRoute.addChildren([
loginRoute,
resetPasswordRoute,
indexRoute,
importRoute,
workspaceRoute,
reportRoute,
settingsRoute,
resourcesRoute,
adminLayoutRoute.addChildren([
adminIndexRoute,
adminOrgsRoute,
adminOrgDetailRoute,
adminUsersRoute,
]),
])
export const router = createRouter({ routeTree })