phase 2: register, login, logout, verify, session, forgat password, delete and cofirm, refresh session all simplified
This commit is contained in:
@@ -1,4 +1,14 @@
|
||||
import { useQuery, type UseQueryOptions } from "@tanstack/react-query";
|
||||
import {
|
||||
createElement,
|
||||
createContext,
|
||||
useContext,
|
||||
type ReactNode,
|
||||
} from "react";
|
||||
import {
|
||||
useQuery,
|
||||
type UseQueryOptions,
|
||||
type UseQueryResult,
|
||||
} from "@tanstack/react-query";
|
||||
import { http } from "../api/http";
|
||||
|
||||
type SessionResponse = {
|
||||
@@ -16,12 +26,31 @@ type SessionResponse = {
|
||||
|
||||
type Options = Omit<UseQueryOptions<SessionResponse, Error>, "queryKey" | "queryFn">;
|
||||
|
||||
export function useAuthSession(options?: Options) {
|
||||
function useAuthSessionQuery(options?: Options) {
|
||||
return useQuery<SessionResponse, Error>({
|
||||
queryKey: ["auth", "session"],
|
||||
queryFn: async () =>
|
||||
http<SessionResponse>("/auth/session", { skipAuthRedirect: true }),
|
||||
// Keep session warm across route transitions to avoid duplicate auth calls.
|
||||
staleTime: 60_000,
|
||||
refetchOnMount: false,
|
||||
refetchOnReconnect: false,
|
||||
retry: false,
|
||||
...options,
|
||||
});
|
||||
}
|
||||
|
||||
const AuthSessionContext = createContext<UseQueryResult<SessionResponse, Error> | null>(null);
|
||||
|
||||
export function AuthSessionProvider({ children }: { children: ReactNode }) {
|
||||
const session = useAuthSessionQuery();
|
||||
return createElement(AuthSessionContext.Provider, { value: session }, children);
|
||||
}
|
||||
|
||||
export function useAuthSession(options?: Options) {
|
||||
const contextSession = useContext(AuthSessionContext);
|
||||
if (contextSession) {
|
||||
return contextSession;
|
||||
}
|
||||
return useAuthSessionQuery(options);
|
||||
}
|
||||
|
||||
@@ -11,6 +11,7 @@ import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
|
||||
import { ToastProvider } from "./components/Toast";
|
||||
import { RequireAuth } from "./components/RequireAuth";
|
||||
import { BetaGate } from "./components/BetaGate";
|
||||
import { AuthSessionProvider } from "./hooks/useAuthSession";
|
||||
import App from "./App";
|
||||
import "./styles.css";
|
||||
|
||||
@@ -196,9 +197,11 @@ const router = createBrowserRouter(
|
||||
ReactDOM.createRoot(document.getElementById("root")!).render(
|
||||
<React.StrictMode>
|
||||
<QueryClientProvider client={client}>
|
||||
<ToastProvider>
|
||||
<RouterProvider router={router} />
|
||||
</ToastProvider>
|
||||
<AuthSessionProvider>
|
||||
<ToastProvider>
|
||||
<RouterProvider router={router} />
|
||||
</ToastProvider>
|
||||
</AuthSessionProvider>
|
||||
</QueryClientProvider>
|
||||
</React.StrictMode>
|
||||
);
|
||||
|
||||
@@ -57,7 +57,8 @@ export default function LoginPage() {
|
||||
body: { email, password },
|
||||
skipAuthRedirect: true,
|
||||
});
|
||||
qc.clear();
|
||||
await qc.invalidateQueries({ queryKey: ["auth", "session"] });
|
||||
await session.refetch();
|
||||
navigate(next || "/", { replace: true });
|
||||
} catch (err) {
|
||||
const status = (err as { status?: number; code?: string })?.status;
|
||||
|
||||
@@ -78,12 +78,13 @@ export default function RegisterPage() {
|
||||
skipAuthRedirect: true,
|
||||
}
|
||||
);
|
||||
qc.clear();
|
||||
if (result.needsVerification) {
|
||||
navigate(`/verify?email=${encodeURIComponent(email)}&next=${encodeURIComponent(next || "/")}`, {
|
||||
replace: true,
|
||||
});
|
||||
} else {
|
||||
await qc.invalidateQueries({ queryKey: ["auth", "session"] });
|
||||
await session.refetch();
|
||||
navigate(next || "/", { replace: true });
|
||||
}
|
||||
} catch (err) {
|
||||
|
||||
Reference in New Issue
Block a user