feat: implement AppLayoutGuard for onboarding redirection
This commit is contained in:
34
apps/web/src/components/layout/AppLayoutGuard.tsx
Normal file
34
apps/web/src/components/layout/AppLayoutGuard.tsx
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
import { useEffect } from 'react'
|
||||||
|
import { useQuery } from '@tanstack/react-query'
|
||||||
|
import { useNavigate } from '@tanstack/react-router'
|
||||||
|
import { Loader2 } from 'lucide-react'
|
||||||
|
import { useAuth } from '../../context/AuthProvider'
|
||||||
|
import { getOnboardingStatus } from '../../lib/api'
|
||||||
|
import { RootLayout } from './RootLayout'
|
||||||
|
|
||||||
|
export function AppLayoutGuard() {
|
||||||
|
const { user, isPending } = useAuth()
|
||||||
|
const navigate = useNavigate()
|
||||||
|
|
||||||
|
const statusQuery = useQuery({
|
||||||
|
queryKey: ['onboarding', 'status'],
|
||||||
|
queryFn: getOnboardingStatus,
|
||||||
|
enabled: !!user,
|
||||||
|
staleTime: 5 * 60 * 1000,
|
||||||
|
})
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (!user || !statusQuery.data || statusQuery.data.completed) return
|
||||||
|
void navigate({ to: '/onboarding', replace: true })
|
||||||
|
}, [user, statusQuery.data, navigate])
|
||||||
|
|
||||||
|
if (isPending || (user && statusQuery.isPending)) {
|
||||||
|
return (
|
||||||
|
<div className="flex min-h-dvh items-center justify-center">
|
||||||
|
<Loader2 className="size-6 animate-spin text-foreground/40" />
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
return <RootLayout />
|
||||||
|
}
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
import { createRootRoute, createRoute, createRouter, Outlet } from '@tanstack/react-router'
|
import { createRootRoute, createRoute, createRouter, Outlet } from '@tanstack/react-router'
|
||||||
import { RootLayout } from './components/layout'
|
import { AppLayoutGuard } from './components/layout/AppLayoutGuard'
|
||||||
import { HomeView } from './routes/home'
|
import { HomeView } from './routes/home'
|
||||||
import { GroupsView } from './routes/groups'
|
import { GroupsView } from './routes/groups'
|
||||||
import { PaymentsView } from './routes/payments'
|
import { PaymentsView } from './routes/payments'
|
||||||
@@ -41,10 +41,11 @@ const onboardingRoute = createRoute({
|
|||||||
})
|
})
|
||||||
|
|
||||||
// Capa con la navegación de la app autenticada (Sidebar + BottomNav).
|
// Capa con la navegación de la app autenticada (Sidebar + BottomNav).
|
||||||
|
// El guard redirige a /onboarding a quien no completó el onboarding.
|
||||||
const appLayoutRoute = createRoute({
|
const appLayoutRoute = createRoute({
|
||||||
getParentRoute: () => rootRoute,
|
getParentRoute: () => rootRoute,
|
||||||
id: 'app',
|
id: 'app',
|
||||||
component: RootLayout,
|
component: AppLayoutGuard,
|
||||||
})
|
})
|
||||||
|
|
||||||
const indexRoute = createRoute({
|
const indexRoute = createRoute({
|
||||||
|
|||||||
Reference in New Issue
Block a user