google sign in with oauth 2.0. no more console errors or warnings

This commit is contained in:
jackiettran
2025-10-08 12:46:25 -04:00
parent 299522b3a6
commit 052781a0e6
8 changed files with 186 additions and 93 deletions

View File

@@ -0,0 +1,98 @@
import React, { useEffect, useState, useRef } from 'react';
import { useNavigate, useSearchParams } from 'react-router-dom';
import { useAuth } from '../contexts/AuthContext';
import { fetchCSRFToken } from '../services/api';
const GoogleCallback: React.FC = () => {
const [searchParams] = useSearchParams();
const navigate = useNavigate();
const { googleLogin } = useAuth();
const [error, setError] = useState<string>('');
const [processing, setProcessing] = useState(true);
const hasProcessed = useRef(false);
useEffect(() => {
const handleCallback = async () => {
// Prevent double execution in React StrictMode
if (hasProcessed.current) {
return;
}
hasProcessed.current = true;
try {
const code = searchParams.get('code');
const errorParam = searchParams.get('error');
if (errorParam) {
setError('Google Sign-In was cancelled or failed. Please try again.');
setProcessing(false);
return;
}
if (!code) {
setError('No authorization code received from Google.');
setProcessing(false);
return;
}
// Fetch CSRF token before making auth request
const csrfToken = await fetchCSRFToken();
if (!csrfToken) {
console.error('Failed to fetch CSRF token');
setError('Failed to initialize security token. Please try again.');
setProcessing(false);
return;
}
// Exchange code for user session
await googleLogin(code);
// Redirect to home page on success
navigate('/', { replace: true });
} catch (err: any) {
console.error('Google OAuth callback error:', err);
setError(err.response?.data?.error || 'Failed to sign in with Google. Please try again.');
setProcessing(false);
}
};
handleCallback();
}, [searchParams, googleLogin, navigate]);
return (
<div className="container">
<div className="row justify-content-center mt-5">
<div className="col-md-6">
<div className="card">
<div className="card-body text-center py-5">
{processing ? (
<>
<div className="spinner-border text-primary mb-3" role="status">
<span className="visually-hidden">Loading...</span>
</div>
<h5>Completing Google Sign-In...</h5>
<p className="text-muted">Please wait while we log you in.</p>
</>
) : error ? (
<>
<i className="bi bi-exclamation-circle text-danger" style={{ fontSize: '3rem' }}></i>
<h5 className="mt-3">Sign-In Failed</h5>
<p className="text-danger">{error}</p>
<button
className="btn btn-primary mt-3"
onClick={() => navigate('/')}
>
Return to Home
</button>
</>
) : null}
</div>
</div>
</div>
</div>
</div>
);
};
export default GoogleCallback;