Files
juwan-frontend/app/providers.tsx
T
zetaloop ff03532da4 feat: restore auth state from backend session on app load
Call GET /api/v1/users/me on startup to rehydrate Zustand auth store
from the existing JToken cookie, so login survives page refresh.
2026-04-24 05:07:44 +08:00

61 lines
1.7 KiB
TypeScript

"use client"
import { GlobalLoginDialog } from "@/components/global-login-dialog"
import { ThemeSyncEffect } from "@/components/theme-sync"
import { TooltipProvider } from "@/components/ui/tooltip"
import { getCurrentUserForLogin } from "@/lib/api"
import { useAuthStore } from "@/store/auth"
import { QueryClient, QueryClientProvider } from "@tanstack/react-query"
import { ThemeProvider } from "next-themes"
import { useEffect, useRef, useState } from "react"
import { Toaster } from "sonner"
function AuthBootstrap() {
const login = useAuthStore((s) => s.login)
const isAuthenticated = useAuthStore((s) => s.isAuthenticated)
const tried = useRef(false)
useEffect(() => {
if (tried.current || isAuthenticated) return
tried.current = true
getCurrentUserForLogin()
.then((user) => {
login(user, user.verifiedRoles ?? ["consumer"])
})
.catch(() => {
// no valid session — stay logged out
})
}, [login, isAuthenticated])
return null
}
export function Providers({ children }: { children: React.ReactNode }) {
const [queryClient] = useState(
() =>
new QueryClient({
defaultOptions: {
queries: {
staleTime: 60 * 1000,
refetchOnWindowFocus: false,
},
},
}),
)
return (
<QueryClientProvider client={queryClient}>
<ThemeProvider attribute="class" defaultTheme="system" enableSystem disableTransitionOnChange>
<TooltipProvider>
<ThemeSyncEffect />
<AuthBootstrap />
{children}
<Toaster richColors position="top-center" />
<GlobalLoginDialog />
</TooltipProvider>
</ThemeProvider>
</QueryClientProvider>
)
}