xtablo-source/apps/main/src/components/ProtectedRoute.tsx
Arthur Belleville 33d16e71ec
Fix tests
2025-10-23 23:04:56 +02:00

49 lines
1.5 KiB
TypeScript

import { useEffect, useState } from "react";
import { Navigate, Outlet } from "react-router-dom";
import { match } from "ts-pattern";
import { useMaybeUser } from "../providers/UserStoreProvider";
import { LoadingSpinner } from "./LoadingSpinner";
interface ProtectedRouteProps {
fallback?: string;
shouldRedirectToCurrentPage?: boolean;
}
export const ProtectedRoute = ({ fallback, shouldRedirectToCurrentPage }: ProtectedRouteProps) => {
const user = useMaybeUser();
const [isLoading, setIsLoading] = useState(true);
useEffect(() => {
const timer = setTimeout(() => {
setIsLoading(false);
}, 500);
return () => clearTimeout(timer);
}, [user, fallback]);
let status: "loading" | "should-land-user" | "should-redirect" | "should-pass" = "loading";
const isFirstTimeUser = localStorage.getItem("xtablo-has-seen-landing-page") === null;
if (isLoading) {
status = "loading";
} else if (!user && isFirstTimeUser) {
status = "should-land-user";
} else if (!user) {
status = "should-redirect";
} else {
status = "should-pass";
}
const redirectUrl = shouldRedirectToCurrentPage
? `${fallback ?? "/login"}?redirect=${encodeURIComponent(
`${window.location.pathname}${window.location.search}`
)}`
: (fallback ?? "/login");
return match(status)
.with("loading", () => <LoadingSpinner />)
.with("should-land-user", () => <Navigate to="/landing" replace />)
.with("should-redirect", () => <Navigate to={redirectUrl} replace />)
.with("should-pass", () => <Outlet />)
.exhaustive();
};