infoalloggi-monorepo/apps/infoalloggi/src/providers/SessionProvider.tsx

92 lines
2.2 KiB
TypeScript
Raw Normal View History

2025-08-04 17:45:44 +02:00
import { useRouter } from "next/router";
import {
createContext,
useContext,
useEffect,
type FC,
type ReactNode,
} from "react";
import type { Session, ValidSession } from "~/server/api/trpc";
2025-08-04 17:45:44 +02:00
import { api } from "~/utils/api";
type SessionStatus = "pending" | "success" | "error";
export type SessionContextType = {
user: Session | null;
status: SessionStatus;
};
const SessionContext = createContext<SessionContextType>({
user: null,
status: "pending",
});
export const SessionProvider: FC<{ children: ReactNode }> = ({ children }) => {
const router = useRouter();
const utils = api.useUtils();
const {
data: user,
status,
isLoading,
2025-08-28 13:46:51 +02:00
isError,
error,
2025-08-04 17:45:44 +02:00
} = api.auth.getSession.useQuery(undefined, {
refetchOnWindowFocus: true,
refetchOnReconnect: true,
refetchOnMount: true,
staleTime: 0,
refetchInterval: 30000,
2025-08-04 17:45:44 +02:00
});
2025-08-28 13:46:51 +02:00
if (isError && error) {
console.error("Session fetch error: ", error);
}
2025-08-04 17:45:44 +02:00
// Invalidate session on route change
useEffect(() => {
const handleRouteChange = () => {
if (isLoading) return;
utils.auth.getSession.invalidate().catch((error: Error) => {
console.error("Error invalidating session on route change:", error);
});
};
router.events.on("routeChangeComplete", handleRouteChange);
return () => {
router.events.off("routeChangeComplete", handleRouteChange);
};
}, [router, utils]);
// Invalidate session if user is null
useEffect(() => {
if (!user) {
utils.auth.getSession.invalidate().catch((error: Error) => {
console.error("Error during session invalidation:", error);
});
}
}, [user]);
return (
<SessionContext.Provider value={{ user: user || null, status }}>
{children}
</SessionContext.Provider>
);
};
export const useSession = () => useContext(SessionContext);
export const EnforcedSessionContext = createContext<ValidSession | undefined>(
undefined,
);
/**
* AreaRiservata specific session context. It ensures that the session is valid.
*/
export const useEnforcedSession = () => {
const session = useContext(EnforcedSessionContext);
if (!session) {
throw new Error(
"useValidSession must be used within a ValidSessionProvider",
);
}
return session;
};