Fix loading page hanging

This commit is contained in:
Arthur Belleville 2025-10-16 17:45:35 +02:00
parent b042e770c3
commit 1197a8cb06
No known key found for this signature in database
3 changed files with 39 additions and 42 deletions

View file

@ -3,6 +3,7 @@ import { ProtectedRoute } from "@ui/components/ProtectedRoute";
import { SessionTestProvider } from "@ui/contexts/SessionContext";
import { renderWithRouter } from "@ui/utils/testHelpers";
import { Route, Routes } from "react-router-dom";
import { TestUserStoreProvider } from "src/providers/UserStoreProvider";
describe("ProtectedRoute", () => {
beforeEach(() => {
@ -30,14 +31,16 @@ describe("ProtectedRoute", () => {
it("redirects to login when user is not authenticated", async () => {
renderWithRouter(
<SessionTestProvider>
<Routes>
<Route element={<ProtectedRoute />}>
<Route path="/" element={<div>Protected Content</div>} />
</Route>
<Route path="/login" element={<div>Login Page</div>} />
</Routes>
</SessionTestProvider>,
<TestUserStoreProvider user={null}>
<SessionTestProvider>
<Routes>
<Route element={<ProtectedRoute />}>
<Route path="/" element={<div>Protected Content</div>} />
</Route>
<Route path="/login" element={<div>Login Page</div>} />
</Routes>
</SessionTestProvider>
</TestUserStoreProvider>,
{ route: "/" }
);
@ -71,31 +74,24 @@ describe("ProtectedRoute", () => {
it("renders protected content when user is authenticated", async () => {
renderWithRouter(
<SessionTestProvider
testUser={{
<TestUserStoreProvider
user={{
id: "123",
app_metadata: {},
user_metadata: {
full_name: "Test User",
email: "test@example.com",
email_verified: true,
first_name: "Test",
last_name: "User",
business_name: "Test Business",
},
aud: "authenticated",
created_at: new Date().toISOString(),
name: "Test User",
email: "test@example.com",
role: "authenticated",
updated_at: new Date().toISOString(),
avatar_url: "https://example.com/avatar.jpg",
streamToken: null,
short_user_id: "123",
}}
>
<Routes>
<Route element={<ProtectedRoute />}>
<Route path="/" element={<div>Protected Content</div>} />
</Route>
</Routes>
</SessionTestProvider>,
<SessionTestProvider>
<Routes>
<Route element={<ProtectedRoute />}>
<Route path="/" element={<div>Protected Content</div>} />
</Route>
</Routes>
</SessionTestProvider>
</TestUserStoreProvider>,
{ route: "/" }
);

View file

@ -3,6 +3,7 @@ import { useEffect, useState } from "react";
import { Navigate, Outlet } from "react-router-dom";
import { match } from "ts-pattern";
import { LoadingSpinner } from "./LoadingSpinner";
import { useMaybeUser } from "src/providers/UserStoreProvider";
interface ProtectedRouteProps {
fallback?: string;
@ -22,13 +23,14 @@ export const ProtectedRoute = ({ fallback, shouldRedirectToCurrentPage }: Protec
let status: "loading" | "should-land-user" | "should-redirect" | "should-pass" = "loading";
const user = useMaybeUser();
const isFirstTimeUser = localStorage.getItem("xtablo-has-seen-landing-page") === null;
if (isLoading) {
status = "loading";
} else if (!session?.user && isFirstTimeUser) {
} else if (!user && isFirstTimeUser) {
status = "should-land-user";
} else if (!session?.user) {
} else if (!user) {
status = "should-redirect";
} else {
status = "should-pass";
@ -40,14 +42,10 @@ export const ProtectedRoute = ({ fallback, shouldRedirectToCurrentPage }: Protec
)}`
: (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()}
</>
);
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();
};

View file

@ -72,8 +72,11 @@ export const TestUserStoreProvider = ({
user,
}: {
children: React.ReactNode;
user: User;
user: User | null;
}) => {
if (!user) {
return children;
}
const store = createStore<User>()(() => user);
return (