xtablo-source/apps/main/src/components/ProtectedRoute.tsx
Arthur Belleville c56d5718b8
refactor: remove is_temporary flag across the entire codebase
Drop the is_temporary boolean from the DB schema (new migration), types,
API routers/helpers/middleware, and all frontend components and tests.
Access control now relies solely on is_client.

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-04-30 17:04:11 +02:00

71 lines
2 KiB
TypeScript

import { useEffect, useState } from "react";
import { Navigate, Outlet } from "react-router-dom";
import { match } from "ts-pattern";
import { redirectClientUserToPortal } from "../lib/clientPortal";
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-redirect-client"
| "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 if (user.is_client) {
status = "should-redirect-client";
} else {
status = "should-pass";
}
const fallbackUrl = fallback ?? "/login";
const redirectUrl = shouldRedirectToCurrentPage
? `${fallbackUrl}?redirect=${encodeURIComponent(
`${window.location.pathname}${window.location.search}`
)}`
: fallbackUrl;
return match(status)
.with("loading", () => <LoadingSpinner />)
.with("should-land-user", () => <Navigate to="/landing" replace />)
.with("should-redirect", () => <Navigate to={redirectUrl} replace />)
.with("should-redirect-client", () => <ClientPortalRedirect />)
.with("should-pass", () => <Outlet />)
.exhaustive();
};
const ClientPortalRedirect = () => {
useEffect(() => {
redirectClientUserToPortal("/");
}, []);
return <LoadingSpinner />;
};