import { useEffect, useState } from 'react'; import './App.css'; import LoginRegisterPage from './pages/LoginRegisterPage'; import Dashboard from './pages/Dashboard'; import { logout } from './api'; import { BACKEND_URL } from './config'; function App() { const [hasToken, setHasToken] = useState(!!localStorage.getItem('token')); const [processingCallback, setProcessingCallback] = useState(false); useEffect(() => { const path = window.location.pathname; // Minimal handling for provider callbacks: /auth|/oauth/:provider/callback?code=...&state=... const parts = path.split('/').filter(Boolean); const isCallback = parts.length === 3 && (parts[0] === 'auth') && parts[2] === 'callback'; if (isCallback) { // Guard against double invocation in React 18 StrictMode/dev const w = window as any; if (w.__oauthCallbackHandled) { return; } w.__oauthCallbackHandled = true; setProcessingCallback(true); const provider = parts[1]; const qs = window.location.search || ''; const base = BACKEND_URL.replace(/\/$/, ''); const url = `${base}/auth/${encodeURIComponent(provider)}/callback${qs}`; (async () => { try { const token = localStorage.getItem('token'); const res = await fetch(url, { method: 'GET', credentials: 'include', headers: token ? { Authorization: `Bearer ${token}` } : undefined, }); let data: any = null; try { data = await res.json(); } catch {} if (provider !== 'csas' && res.ok && data?.access_token) { localStorage.setItem('token', data?.access_token); setHasToken(true); } } catch {} // Clean URL and go home regardless of result setProcessingCallback(false); window.history.replaceState({}, '', '/'); })(); } const onStorage = (e: StorageEvent) => { if (e.key === 'token') setHasToken(!!e.newValue); }; window.addEventListener('storage', onStorage); return () => window.removeEventListener('storage', onStorage); }, []); if (processingCallback) { return (
Finishing sign-in…
Please wait
); } if (!hasToken) { return setHasToken(true)} />; } return ( { logout(); setHasToken(false); }} /> ); } export default App;