···
4
4
import './LoginCallback.css'; // Optional: Add styles if needed
5
5
6
6
const LoginCallback = () => {
7
7
-
const { client } = useAuth(); // Get the client instance from context
7
7
+
// Get loading and authentication status from AuthContext
8
8
+
const { loading, isAuthenticated, error: authError } = useAuth();
8
9
const navigate = useNavigate();
9
9
-
const [status, setStatus] = useState('Processing login...');
10
10
-
const [error, setError] = useState(null);
10
10
+
const [localError, setLocalError] = useState(null);
11
11
12
12
useEffect(() => {
13
13
-
const handleCallback = async () => {
14
14
-
// Client might not be initialized immediately on page load
15
15
-
if (!client) {
16
16
-
setStatus('Waiting for authentication client...');
17
17
-
// Optionally add a small delay and retry or rely on AuthContext re-render
18
18
-
const timeoutId = setTimeout(() => {
19
19
-
if (!client) { // Check again after delay
20
20
-
console.error('OAuth client not available after delay.');
21
21
-
setError('Authentication client failed to load. Please try logging in again.');
22
22
-
setStatus(''); // Clear status message
23
23
-
}
24
24
-
// If client became available, the effect will re-run anyway
25
25
-
}, 2000); // Wait 2 seconds
26
26
-
return () => clearTimeout(timeoutId);
27
27
-
}
13
13
+
// Don't do anything until the AuthProvider is done loading
14
14
+
if (loading) {
15
15
+
return;
16
16
+
}
28
17
29
29
-
try {
30
30
-
console.log('(LoginCallback) Client available, attempting to handle callback...');
31
31
-
// The client.init() in AuthContext likely already handled the callback.
32
32
-
// We might not need client.callback() here if init handles it.
33
33
-
// However, keeping client.callback() as a fallback or direct handler can be robust.
34
34
-
// Check if init() already processed it by seeing if session exists
35
35
-
// This check might be complex depending on AuthContext's exact init timing.
36
36
-
37
37
-
// Let's assume AuthContext's init() handles the primary callback logic.
38
38
-
// This component might just need to redirect based on the resulting session state.
39
39
-
40
40
-
// Check AuthContext state directly (may require exposing session explicitly)
41
41
-
// Or simply redirect - AuthContext should have set the session if successful
42
42
-
43
43
-
setStatus('Login successful! Redirecting...');
44
44
-
45
45
-
// Attempt to retrieve the original intended URL from state if passed during login
46
46
-
// Note: client.init() doesn't directly return state here. We might need
47
47
-
// AuthContext to store the state temporarily or parse it from the URL hash/query.
48
48
-
// For simplicity, we'll redirect to home. Implement state parsing if needed.
49
49
-
50
50
-
// Retrieve returnUrl from state saved during login (requires state handling)
51
51
-
// const stateParam = new URLSearchParams(window.location.hash.substring(1)).get('state') || new URLSearchParams(window.location.search).get('state');
52
52
-
let returnUrl = '/';
53
53
-
// if (stateParam) {
54
54
-
// try {
55
55
-
// const decodedState = JSON.parse(atob(stateParam)); // Adjust decoding if needed
56
56
-
// returnUrl = decodedState.returnUrl || '/';
57
57
-
// } catch (e) {
58
58
-
// console.error("Error parsing state parameter:", e);
59
59
-
// }
60
60
-
// }
61
61
-
62
62
-
// Redirect after a short delay to show the success message
63
63
-
setTimeout(() => {
64
64
-
navigate(returnUrl);
65
65
-
}, 1500);
18
18
+
// Once loading is complete, check the authentication status
19
19
+
if (isAuthenticated) {
20
20
+
console.log('(LoginCallback) Authentication successful, redirecting...');
21
21
+
// TODO: Implement state parsing for returnUrl if needed
22
22
+
const returnUrl = '/'; // Default redirect
23
23
+
navigate(returnUrl);
24
24
+
} else {
25
25
+
// If not authenticated after loading, something went wrong
26
26
+
console.error('(LoginCallback) Authentication failed after loading.');
27
27
+
setLocalError(authError || 'Authentication failed. Please try logging in again.');
28
28
+
}
66
29
67
67
-
} catch (err) {
68
68
-
console.error('(LoginCallback) Error processing callback:', err);
69
69
-
setError(`Login failed: ${err.message || 'Unknown error'}`);
70
70
-
setStatus('');
71
71
-
}
72
72
-
};
30
30
+
}, [loading, isAuthenticated, navigate, authError]); // Depend on loading and auth state
73
31
74
74
-
handleCallback();
32
32
+
// Display loading message
33
33
+
if (loading) {
34
34
+
return (
35
35
+
<div className="login-callback-container">
36
36
+
<h2>Processing Login</h2>
37
37
+
<p className="status-message">Verifying authentication...</p>
38
38
+
{/* Optionally add a spinner here */}
39
39
+
</div>
40
40
+
);
41
41
+
}
75
42
76
76
-
}, [client, navigate]); // Depend on client availability
43
43
+
// Display error message if authentication failed
44
44
+
if (localError) {
45
45
+
return (
46
46
+
<div className="login-callback-container">
47
47
+
<h2>Authentication Failed</h2>
48
48
+
<p className="error-message">{localError}</p>
49
49
+
<button onClick={() => navigate('/login')} className="home-button">Try Login Again</button>
50
50
+
<button onClick={() => navigate('/')} className="home-button" style={{marginLeft: '10px'}}>Go to Homepage</button>
51
51
+
</div>
52
52
+
);
53
53
+
}
77
54
55
55
+
// Render nothing while redirecting (or a minimal redirecting message)
56
56
+
// This state should be brief as the effect triggers redirection quickly
78
57
return (
79
79
-
<div className="login-callback-container">
80
80
-
<h2>Authentication Callback</h2>
81
81
-
{status && <p className="status-message">{status}</p>}
82
82
-
{error && <p className="error-message">{error}</p>}
83
83
-
{!status && !error && <p>Verifying authentication...</p>}
84
84
-
{/* Add a button to retry or go home if stuck */}
85
85
-
{(error || (!client && !status && !error)) && (
86
86
-
<button onClick={() => navigate('/')} className="home-button">Go to Homepage</button>
87
87
-
)}
88
88
-
</div>
58
58
+
<div className="login-callback-container">
59
59
+
<h2>Redirecting...</h2>
60
60
+
</div>
89
61
);
90
62
};
91
63