fix issues

This commit is contained in:
2026-01-01 16:32:06 +01:00
parent aee182b09e
commit 17d715f259
19 changed files with 1014 additions and 344 deletions

View File

@@ -62,7 +62,9 @@ export class AuthGateway {
return {
canAccess: this.canAccess(),
reason: this.blocker.getBlockMessage(),
isLoading: reason === 'loading',
// Only show loading if auth context is still loading
// If auth context is done but session is null, that's unauthenticated (not loading)
isLoading: this.authContext.loading,
isAuthenticated: this.authContext.session?.isAuthenticated ?? false,
};
}
@@ -137,4 +139,11 @@ export class AuthGateway {
getBlockReason(): string {
return this.blocker.getReason();
}
/**
* Get user-friendly block message
*/
getBlockMessage(): string {
return this.blocker.getBlockMessage();
}
}

View File

@@ -10,7 +10,7 @@
'use client';
import { ReactNode, useEffect, useState } from 'react';
import { ReactNode, useEffect, useState, useMemo } from 'react';
import { useRouter } from 'next/navigation';
import { useAuth } from '@/lib/auth/AuthContext';
import { AuthGateway, AuthGatewayConfig } from './AuthGateway';
@@ -51,41 +51,50 @@ export function RouteGuard({
const router = useRouter();
const authContext = useAuth();
const [gateway] = useState(() => new AuthGateway(authContext, config));
const [accessState, setAccessState] = useState(gateway.getAccessState());
const [isChecking, setIsChecking] = useState(true);
// Update gateway when auth context changes
useEffect(() => {
// Calculate access state
const accessState = useMemo(() => {
gateway.refresh();
setAccessState(gateway.getAccessState());
return {
canAccess: gateway.canAccess(),
reason: gateway.getBlockMessage(),
redirectPath: gateway.getUnauthorizedRedirectPath(),
};
}, [authContext.session, authContext.loading, gateway]);
// Handle redirects
// Handle the loading state and redirects
useEffect(() => {
if (!accessState.canAccess && !accessState.isLoading) {
if (config.redirectOnUnauthorized !== false) {
const redirectPath = gateway.getUnauthorizedRedirectPath();
// Use a small delay to show unauthorized message briefly
const timer = setTimeout(() => {
router.push(redirectPath);
}, 500);
return () => clearTimeout(timer);
}
// If we're loading, stay in checking state
if (authContext.loading) {
setIsChecking(true);
return;
}
}, [accessState, gateway, router, config.redirectOnUnauthorized]);
// Done loading, can exit checking state
setIsChecking(false);
// If we can't access and should redirect, do it
if (!accessState.canAccess && config.redirectOnUnauthorized !== false) {
const timer = setTimeout(() => {
router.push(accessState.redirectPath);
}, 500);
return () => clearTimeout(timer);
}
}, [authContext.loading, accessState.canAccess, accessState.redirectPath, config.redirectOnUnauthorized, router]);
// Show loading state
if (accessState.isLoading) {
if (isChecking || authContext.loading) {
return loadingComponent || (
<div className="flex items-center justify-center min-h-screen">
<LoadingState message="Loading..." className="min-h-screen" />
<LoadingState message="Verifying authentication..." className="min-h-screen" />
</div>
);
}
// Show unauthorized state
if (!accessState.canAccess) {
// Show unauthorized state (only if not redirecting)
if (!accessState.canAccess && config.redirectOnUnauthorized === false) {
return unauthorizedComponent || (
<div className="flex items-center justify-center min-h-screen">
<div className="bg-iron-gray p-8 rounded-lg border border-charcoal-outline max-w-md text-center">
@@ -102,6 +111,15 @@ export function RouteGuard({
);
}
// Show redirecting state
if (!accessState.canAccess && config.redirectOnUnauthorized !== false) {
return (
<div className="flex items-center justify-center min-h-screen">
<LoadingState message="Redirecting to login..." className="min-h-screen" />
</div>
);
}
// Render protected content
return <>{children}</>;
}