···9292 color: #3B9AF8; /* Change color on hover */
9393}
94949595+/* Add rule for dark mode nav links */
9696+.dark-mode .navbar-links ul li a {
9797+ color: #3b9af8;
9898+}
9999+95100/* Right Section: Actions */
96101.navbar-actions {
97102 display: flex;
···329334 box-shadow: 0 4px 8px rgba(0, 0, 0, 0.3);
330335}
331336337337+/* Add rule for base color of dropdown links in dark mode */
338338+.dark-mode .dropdown-menu li a {
339339+ color: #e0e0e0; /* Light grey for readability */
340340+}
341341+332342.dark-mode .dropdown-menu li a:hover {
333343 background-color: rgba(59, 154, 248, 0.2);
334334- color: #66b2ff;
344344+ /* Update hover color to match main links */
345345+ color: #3b9af8;
335346}
336347337348/* ---------------------------------- */
+7-60
src/components/ProtectedRoute.js
···11-import React, { useEffect, useRef, useState } from 'react';
11+import React, { useEffect, useState } from 'react';
22import { Navigate, useLocation } from 'react-router-dom';
33import { useAuth } from '../contexts/AuthContext';
44import { isAccountAllowed } from '../config/allowlist';
···6677// Component to protect routes that require authentication
88const ProtectedRoute = ({ children }) => {
99- const { isAuthenticated, loading, session, checkAuthStatus } = useAuth();
99+ const { isAuthenticated, loading, session } = useAuth();
1010 const location = useLocation();
1111- const [redirecting, setRedirecting] = useState(false);
1212- const [checkingStatus, setCheckingStatus] = useState(false);
1313- const checkCount = useRef(0);
1414- const maxChecks = 3; // Maximum number of checks to prevent infinite loops
1515-1616- // Perform an immediate auth check when the component mounts
1717- useEffect(() => {
1818- const checkAuth = async () => {
1919- if (checkCount.current >= maxChecks) {
2020- console.error("Maximum auth check attempts reached. Stopping to prevent infinite loop.");
2121- return;
2222- }
2323-2424- // Only proceed if not already checking, not already redirecting, and not loading
2525- if (!isAuthenticated && !checkingStatus && !redirecting && !loading) {
2626- try {
2727- console.log("ProtectedRoute: Checking authentication status");
2828- setCheckingStatus(true);
2929- checkCount.current += 1;
3030- await checkAuthStatus();
3131- } catch (error) {
3232- console.error("ProtectedRoute: Auth check failed:", error);
3333- } finally {
3434- setCheckingStatus(false);
3535- }
3636- }
3737- };
3838-3939- // Call immediately on mount or when dependency values change
4040- checkAuth();
4141-4242- // Set up interval for periodic checks only if authenticated
4343- let interval;
4444- if (isAuthenticated && session) {
4545- console.log("ProtectedRoute: Setting up periodic auth checks");
4646- interval = setInterval(() => {
4747- checkAuthStatus().catch(err => {
4848- console.error("Error in periodic auth check:", err);
4949- });
5050- }, 30000); // Check every 30 seconds
5151- }
5252-5353- return () => {
5454- if (interval) {
5555- console.log("ProtectedRoute: Clearing periodic auth checks");
5656- clearInterval(interval);
5757- }
5858- };
5959- }, [isAuthenticated, checkAuthStatus, redirecting, loading, checkingStatus, session]);
60116161- // Show loading state while authentication is being checked
6262- if (loading || checkingStatus) {
1212+ // Show loading state while authentication context is initializing
1313+ if (loading) {
6314 return <Loading message="Checking authentication..." />;
6415 }
65166666- // If not authenticated, redirect to login with return URL
6767- if (!isAuthenticated && !redirecting) {
1717+ // If not authenticated after loading, redirect to login
1818+ if (!isAuthenticated) {
6819 console.log("ProtectedRoute: Not authenticated, redirecting to login");
6969- setRedirecting(true); // Prevent multiple redirects
7070- const returnUrl = encodeURIComponent(location.pathname);
2020+ const returnUrl = encodeURIComponent(location.pathname + location.search); // Include search params
7121 return <Navigate to={`/login?returnUrl=${returnUrl}`} replace />;
7222 }
7323···7727 return <Navigate to="/supporter" replace />;
7828 }
79298080- // Reset counter when rendering the protected content
8181- checkCount.current = 0;
8282-8330 // Render children if authenticated and allowed
8431 console.log("ProtectedRoute: Authentication successful, rendering protected content");
8532 return children;
-20
src/components/Verifier/Verifier.js
···569569 if (isAuthLoading) return <p>Loading authentication...</p>;
570570 if (authError) return <p>Authentication Error: {authError}. <a href="/login">Please login</a>.</p>;
571571572572- // Direct redirect for unauthenticated users as a backup
573573- if (!isAuthenticated) {
574574- console.log('Verifier: Detected unauthenticated user, forcing redirect');
575575-576576- // Force redirect as an additional failsafe
577577- setTimeout(() => {
578578- const redirectUrl = `/login?returnUrl=${encodeURIComponent(window.location.pathname)}`;
579579- window.location.replace(redirectUrl);
580580- }, 100);
581581-582582- return <p>Authentication required. Redirecting to login...</p>;
583583- }
584584-585585- // Verify we have a valid session
586586- if (!session || !session.did) {
587587- console.log('Verifier: Session invalid, forcing redirect');
588588- window.location.replace('/login');
589589- return <p>Session invalid. Redirecting to login...</p>;
590590- }
591591-592572 const isAnyOperationInProgress = isVerifying || isRevoking || isLoadingVerifications || isLoadingNetwork || isCheckingValidity;
593573594574 return (
+3
src/contexts/AuthContext.js
···143143144144 // Force a page refresh if session state changes and we're on a protected path
145145 // This ensures the latest auth state is always used for route protection
146146+ // REMOVED: This can cause unwanted flashing/reloads
147147+ /*
146148 if (!loading && window.location.pathname === '/verifier' && !session) {
147149 console.log('(AuthProvider) No session on protected page, forcing refresh');
148150 window.location.reload();
149151 }
152152+ */
150153 }, [session, loading, error]);
151154152155 return (