2025-09-14 23:23:15 +00:00
|
|
|
import {
|
|
|
|
|
createFileRoute,
|
|
|
|
|
Navigate,
|
|
|
|
|
Outlet,
|
|
|
|
|
useLocation,
|
|
|
|
|
} from "@tanstack/react-router"
|
|
|
|
|
import {
|
|
|
|
|
Authenticated,
|
|
|
|
|
AuthLoading,
|
|
|
|
|
Unauthenticated,
|
|
|
|
|
useConvexAuth,
|
|
|
|
|
} from "convex/react"
|
|
|
|
|
import { useEffect, useState } from "react"
|
2025-10-05 20:21:45 +00:00
|
|
|
import { authClient } from "@/auth-client"
|
2025-09-14 23:23:15 +00:00
|
|
|
import { LoadingSpinner } from "@/components/ui/loading-spinner"
|
2025-09-14 21:46:38 +00:00
|
|
|
|
|
|
|
|
export const Route = createFileRoute("/_authenticated")({
|
|
|
|
|
component: AuthenticatedLayout,
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
function AuthenticatedLayout() {
|
2025-09-14 23:23:15 +00:00
|
|
|
const { search } = useLocation()
|
|
|
|
|
const { isLoading } = useConvexAuth()
|
2025-10-05 20:21:45 +00:00
|
|
|
const { isPending: sessionLoading } = authClient.useSession()
|
2025-09-14 23:23:15 +00:00
|
|
|
const [hasProcessedAuth, setHasProcessedAuth] = useState(false)
|
|
|
|
|
|
|
|
|
|
// Check if we're in the middle of processing an auth code
|
|
|
|
|
const hasAuthCode = search && typeof search === "object" && "code" in search
|
|
|
|
|
|
|
|
|
|
// Track when auth processing is complete
|
|
|
|
|
useEffect(() => {
|
2025-10-05 20:21:45 +00:00
|
|
|
if (!sessionLoading && !isLoading) {
|
2025-09-14 23:23:15 +00:00
|
|
|
// Delay to ensure auth state is fully synchronized
|
|
|
|
|
const timer = setTimeout(() => {
|
|
|
|
|
setHasProcessedAuth(true)
|
|
|
|
|
}, 500)
|
|
|
|
|
return () => clearTimeout(timer)
|
|
|
|
|
}
|
2025-10-05 20:21:45 +00:00
|
|
|
}, [sessionLoading, isLoading])
|
2025-09-14 23:23:15 +00:00
|
|
|
|
|
|
|
|
// Show loading during auth code processing or while auth state is syncing
|
2025-10-05 20:21:45 +00:00
|
|
|
if (hasAuthCode || sessionLoading || isLoading || !hasProcessedAuth) {
|
2025-09-14 23:23:15 +00:00
|
|
|
return (
|
|
|
|
|
<div className="flex h-screen w-full items-center justify-center">
|
|
|
|
|
<LoadingSpinner className="size-10" />
|
|
|
|
|
</div>
|
|
|
|
|
)
|
|
|
|
|
}
|
|
|
|
|
|
2025-09-14 21:46:38 +00:00
|
|
|
return (
|
|
|
|
|
<>
|
|
|
|
|
<Authenticated>
|
|
|
|
|
<Outlet />
|
|
|
|
|
</Authenticated>
|
|
|
|
|
<Unauthenticated>
|
2025-09-14 23:23:15 +00:00
|
|
|
<Navigate replace to="/login" />
|
2025-09-14 21:46:38 +00:00
|
|
|
</Unauthenticated>
|
2025-09-14 23:23:15 +00:00
|
|
|
<AuthLoading>
|
|
|
|
|
<div className="flex h-screen w-full items-center justify-center">
|
|
|
|
|
<LoadingSpinner className="size-10" />
|
|
|
|
|
</div>
|
|
|
|
|
</AuthLoading>
|
2025-09-14 21:46:38 +00:00
|
|
|
</>
|
|
|
|
|
)
|
|
|
|
|
}
|