Backup: 2025-06-07 19:48 - Script test
[Restore from backup: vip-coordinator-backup-2025-06-07-19-48-script-test]
This commit is contained in:
104
frontend/src/components/GoogleLogin.tsx
Normal file
104
frontend/src/components/GoogleLogin.tsx
Normal file
@@ -0,0 +1,104 @@
|
||||
import { useEffect, useRef } from 'react';
|
||||
|
||||
interface GoogleLoginProps {
|
||||
onSuccess: (user: any, token: string) => void;
|
||||
onError: (error: string) => void;
|
||||
}
|
||||
|
||||
// Helper to decode JWT token
|
||||
function parseJwt(token: string) {
|
||||
try {
|
||||
const base64Url = token.split('.')[1];
|
||||
const base64 = base64Url.replace(/-/g, '+').replace(/_/g, '/');
|
||||
const jsonPayload = decodeURIComponent(atob(base64).split('').map(function(c) {
|
||||
return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2);
|
||||
}).join(''));
|
||||
return JSON.parse(jsonPayload);
|
||||
} catch (e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
declare global {
|
||||
interface Window {
|
||||
google: any;
|
||||
}
|
||||
}
|
||||
|
||||
const GoogleLogin: React.FC<GoogleLoginProps> = ({ onSuccess, onError }) => {
|
||||
const buttonRef = useRef<HTMLDivElement>(null);
|
||||
|
||||
useEffect(() => {
|
||||
// Initialize Google Sign-In
|
||||
const initializeGoogleSignIn = () => {
|
||||
if (!window.google) {
|
||||
setTimeout(initializeGoogleSignIn, 100);
|
||||
return;
|
||||
}
|
||||
|
||||
window.google.accounts.id.initialize({
|
||||
client_id: '308004695553-6k34bbq22frc4e76kejnkgq8mncepbbg.apps.googleusercontent.com',
|
||||
callback: handleCredentialResponse,
|
||||
auto_select: false,
|
||||
cancel_on_tap_outside: true,
|
||||
});
|
||||
|
||||
// Render the button
|
||||
if (buttonRef.current) {
|
||||
window.google.accounts.id.renderButton(
|
||||
buttonRef.current,
|
||||
{
|
||||
theme: 'outline',
|
||||
size: 'large',
|
||||
text: 'signin_with',
|
||||
shape: 'rectangular',
|
||||
logo_alignment: 'center',
|
||||
width: 300,
|
||||
}
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
const handleCredentialResponse = async (response: any) => {
|
||||
try {
|
||||
// Send the Google credential to our backend
|
||||
const res = await fetch('/auth/google/verify', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify({ credential: response.credential }),
|
||||
});
|
||||
|
||||
const data = await res.json();
|
||||
|
||||
if (!res.ok) {
|
||||
if (data.error === 'pending_approval') {
|
||||
// User created but needs approval - still successful login
|
||||
onSuccess(data.user, data.token);
|
||||
} else {
|
||||
throw new Error(data.error || 'Authentication failed');
|
||||
}
|
||||
} else {
|
||||
onSuccess(data.user, data.token);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error during authentication:', error);
|
||||
onError(error instanceof Error ? error.message : 'Failed to process authentication');
|
||||
}
|
||||
};
|
||||
|
||||
initializeGoogleSignIn();
|
||||
}, [onSuccess, onError]);
|
||||
|
||||
return (
|
||||
<div className="flex flex-col items-center">
|
||||
<div ref={buttonRef} className="google-signin-button"></div>
|
||||
<p className="mt-4 text-sm text-gray-600">
|
||||
Sign in with your Google account to continue
|
||||
</p>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default GoogleLogin;
|
||||
Reference in New Issue
Block a user