-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
created custom google login component
- Loading branch information
Showing
5 changed files
with
150 additions
and
167 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
import { CredentialResponse } from '@react-oauth/google'; | ||
import { useEffect, useState } from 'react'; | ||
import { useNavigate } from 'react-router-dom'; | ||
import ROUTES from 'router/RouteConfig'; | ||
import { CmButton2 } from 'shared/components'; | ||
import { useLogin } from '../hooks'; | ||
|
||
function GoogleLogin({ navigateAfterLogin, text }: { navigateAfterLogin: () => void; text?: string }) { | ||
const GOOGLE_CLIENT_ID = process.env.REACT_APP_GOOGLE_CLIENT_ID; | ||
const [isLoading, setIsLoading] = useState(false); | ||
const navigate = useNavigate(); | ||
|
||
const { loginGoogleUser } = useLogin(); | ||
|
||
const handleGoogleSuccess = async (credentialResponse: CredentialResponse) => { | ||
setIsLoading(true); | ||
try { | ||
const isSuccessful = await loginGoogleUser(credentialResponse); | ||
if (isSuccessful) { | ||
navigateAfterLogin(); | ||
} else if (!isSuccessful) { | ||
navigate(ROUTES.PRE_QUIZ_PAGE); | ||
} | ||
} catch (error) { | ||
console.error('Error in loginGoogleUser:', error); | ||
} | ||
setIsLoading(false); | ||
}; | ||
|
||
useEffect(() => { | ||
/* Initialize Google API client */ | ||
(window as any).google.accounts.id.initialize({ | ||
client_id: GOOGLE_CLIENT_ID, | ||
callback: handleCredentialResponse, | ||
}); | ||
}, []); | ||
|
||
const handleCredentialResponse = (response: any) => { | ||
const credential = response.credential; | ||
// Pass the credential to your login function | ||
handleGoogleSuccess(credential); | ||
}; | ||
|
||
const handleGoogleLogin = () => { | ||
(window as any).google.accounts.id.prompt(); // Triggers the Google sign-in prompt | ||
}; | ||
return ( | ||
<CmButton2 | ||
text={text} | ||
isLoading={isLoading} | ||
onClick={handleGoogleLogin} | ||
startIcon={<img src="https://cdn.jsdelivr.net/gh/devicons/devicon@latest/icons/google/google-original.svg" style={{ width: 24, height: 24 }} />} | ||
style={{ background: 'white', boxShadow: '0px 2px 3px 0px #0000002B, 0px 0px 3px 0px #00000015', border: 'none' }} | ||
/> | ||
); | ||
} | ||
|
||
export default GoogleLogin; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,31 +1,21 @@ | ||
import { useState } from 'react'; | ||
import { useLocation, useNavigate } from 'react-router-dom'; | ||
import { CredentialResponse, GoogleLogin, GoogleOAuthProvider } from '@react-oauth/google'; | ||
|
||
import ROUTES from 'router/RouteConfig'; | ||
import { CmButton2, CmTextInput } from 'shared/components'; | ||
import { useLogin } from '../hooks'; | ||
|
||
const GOOGLE_CLIENT_ID = process.env.REACT_APP_GOOGLE_CLIENT_ID; | ||
import GoogleLogin from './GoogleLogin'; | ||
|
||
interface Props { | ||
isLoading: boolean; | ||
onSignUp: (firstname: string, lastname: string, email: string, password: string) => void; | ||
} | ||
|
||
function SignUpForm({ isLoading, onSignUp }: Props) { | ||
// For testing | ||
const devMode = localStorage.getItem('devMode') === 'true'; | ||
|
||
const navigate = useNavigate(); | ||
const location = useLocation(); | ||
|
||
const [firstname, setFirstname] = useState({ value: '', touched: false }); | ||
const [lastname, setLastname] = useState({ value: '', touched: false }); | ||
const [email, setEmail] = useState({ value: '', touched: false }); | ||
const [password, setPassword] = useState({ value: '', touched: false }); | ||
const [confirmPassword, setConfirmPassword] = useState({ value: '', touched: false }); | ||
const { loginGoogleUser } = useLogin(); | ||
|
||
function handleSubmit(e?: React.FormEvent) { | ||
e?.preventDefault(); | ||
|
@@ -34,111 +24,80 @@ function SignUpForm({ isLoading, onSignUp }: Props) { | |
onSignUp(firstname.value, lastname.value, email.value, password.value); | ||
} | ||
|
||
function navigateAfterLogin() { | ||
if (location.state && 'from' in location.state) { | ||
navigate(location.state.from); | ||
} else { | ||
navigate(ROUTES.CLIMATE_FEED_PAGE); | ||
} | ||
} | ||
|
||
const handleGoogleSuccess = async (credentialResponse: CredentialResponse) => { | ||
// setIsLoading(true); | ||
try { | ||
const isSuccessful = await loginGoogleUser(credentialResponse); | ||
|
||
if (isSuccessful) { | ||
navigateAfterLogin(); | ||
} else if (!isSuccessful) { | ||
navigate(ROUTES.PRE_QUIZ_PAGE); | ||
} | ||
} catch (error) { | ||
console.error('Error in loginGoogleUser:', error); | ||
} | ||
// setIsLoading(false); | ||
}; | ||
|
||
const handleGoogleError = (error: any) => { | ||
console.error('Google Login Failed:', error); | ||
}; | ||
|
||
const emailValid = /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/.test(email.value); | ||
const passwordValid = /^(?=.*[a-zA-Z])(?=.*[\d!"#$£%&'()*+,-.:;<=>?@[\]^_`{|}~]).{8,128}$/.test(password.value); | ||
const passwordsMatch = password.value === confirmPassword.value; | ||
const formIsValid = emailValid && passwordValid && passwordsMatch && firstname.value !== '' && lastname.value !== ''; | ||
|
||
return ( | ||
<GoogleOAuthProvider clientId={GOOGLE_CLIENT_ID!}> | ||
<form onSubmit={handleSubmit} style={styles.form}> | ||
<CmTextInput | ||
id="firstname" | ||
label="First Name" | ||
value={firstname.value} | ||
onChange={(e) => setFirstname({ value: e.target.value, touched: firstname.touched })} | ||
onBlur={() => setFirstname({ value: firstname.value, touched: true })} | ||
error={firstname.touched && !firstname.value} | ||
helperText={firstname.touched && !firstname.value && 'First name is required'} | ||
placeholder="John" | ||
style={styles.textInput} | ||
/> | ||
|
||
<CmTextInput | ||
id="lastname" | ||
label="Last Name" | ||
value={lastname.value} | ||
onChange={(e) => setLastname({ value: e.target.value, touched: lastname.touched })} | ||
onBlur={() => setLastname({ value: lastname.value, touched: true })} | ||
error={lastname.touched && !lastname.value} | ||
helperText={lastname.touched && !lastname.value && 'Last name is required'} | ||
placeholder="Smith" | ||
style={styles.textInput} | ||
/> | ||
|
||
<CmTextInput | ||
id="email" | ||
label="Email" | ||
value={email.value} | ||
onChange={(e) => setEmail({ value: e.target.value, touched: email.touched })} | ||
onBlur={() => setEmail({ value: email.value, touched: true })} | ||
error={email.touched && !email.value} | ||
helperText={email.touched && !emailValid && 'Invalid email address'} | ||
placeholder="[email protected]" | ||
type="email" | ||
style={styles.textInput} | ||
/> | ||
|
||
<CmTextInput | ||
id="password" | ||
label="Password" | ||
value={password.value} | ||
onChange={(e) => setPassword({ value: e.target.value, touched: password.touched })} | ||
onBlur={() => setPassword({ value: password.value, touched: true })} | ||
error={password.touched && !passwordValid} | ||
helperText={password.touched && !passwordValid && 'Invalid Password. Password must be at least 8 characters and contain one number or one special character'} | ||
placeholder="Super Secret Password" | ||
type="password" | ||
style={styles.textInput} | ||
/> | ||
|
||
<CmTextInput | ||
id="confirmPassword" | ||
label="Confirm Password" | ||
value={confirmPassword.value} | ||
onChange={(e) => setConfirmPassword({ value: e.target.value, touched: confirmPassword.touched })} | ||
onBlur={() => setConfirmPassword({ value: confirmPassword.value, touched: true })} | ||
error={confirmPassword.touched && !passwordsMatch} | ||
helperText={confirmPassword.touched && !passwordsMatch && 'Passwords do not match'} | ||
placeholder="Confirm Password" | ||
type="password" | ||
style={styles.textInput} | ||
/> | ||
|
||
<div style={{ display: 'flex', flexDirection: 'column', justifyContent: 'center', alignItems: 'center', marginTop: 40 }}> | ||
<CmButton2 text="Create Account" isLoading={isLoading} disabled={!formIsValid} onClick={handleSubmit} /> | ||
{devMode && <GoogleLogin onSuccess={handleGoogleSuccess} onError={() => handleGoogleError} text="continue_with" shape="pill" logo_alignment="left" theme="outline" />} | ||
</div> | ||
</form> | ||
</GoogleOAuthProvider> | ||
<form onSubmit={handleSubmit} style={styles.form}> | ||
<CmTextInput | ||
id="firstname" | ||
label="First Name" | ||
value={firstname.value} | ||
onChange={(e) => setFirstname({ value: e.target.value, touched: firstname.touched })} | ||
onBlur={() => setFirstname({ value: firstname.value, touched: true })} | ||
error={firstname.touched && !firstname.value} | ||
helperText={firstname.touched && !firstname.value && 'First name is required'} | ||
placeholder="John" | ||
style={styles.textInput} | ||
/> | ||
|
||
<CmTextInput | ||
id="lastname" | ||
label="Last Name" | ||
value={lastname.value} | ||
onChange={(e) => setLastname({ value: e.target.value, touched: lastname.touched })} | ||
onBlur={() => setLastname({ value: lastname.value, touched: true })} | ||
error={lastname.touched && !lastname.value} | ||
helperText={lastname.touched && !lastname.value && 'Last name is required'} | ||
placeholder="Smith" | ||
style={styles.textInput} | ||
/> | ||
|
||
<CmTextInput | ||
id="email" | ||
label="Email" | ||
value={email.value} | ||
onChange={(e) => setEmail({ value: e.target.value, touched: email.touched })} | ||
onBlur={() => setEmail({ value: email.value, touched: true })} | ||
error={email.touched && !email.value} | ||
helperText={email.touched && !emailValid && 'Invalid email address'} | ||
placeholder="[email protected]" | ||
type="email" | ||
style={styles.textInput} | ||
/> | ||
|
||
<CmTextInput | ||
id="password" | ||
label="Password" | ||
value={password.value} | ||
onChange={(e) => setPassword({ value: e.target.value, touched: password.touched })} | ||
onBlur={() => setPassword({ value: password.value, touched: true })} | ||
error={password.touched && !passwordValid} | ||
helperText={password.touched && !passwordValid && 'Invalid Password. Password must be at least 8 characters and contain one number or one special character'} | ||
placeholder="Super Secret Password" | ||
type="password" | ||
style={styles.textInput} | ||
/> | ||
|
||
<CmTextInput | ||
id="confirmPassword" | ||
label="Confirm Password" | ||
value={confirmPassword.value} | ||
onChange={(e) => setConfirmPassword({ value: e.target.value, touched: confirmPassword.touched })} | ||
onBlur={() => setConfirmPassword({ value: confirmPassword.value, touched: true })} | ||
error={confirmPassword.touched && !passwordsMatch} | ||
helperText={confirmPassword.touched && !passwordsMatch && 'Passwords do not match'} | ||
placeholder="Confirm Password" | ||
type="password" | ||
style={styles.textInput} | ||
/> | ||
|
||
<div style={{ display: 'flex', flexDirection: 'column', justifyContent: 'center', alignItems: 'center', marginTop: 40 }}> | ||
<CmButton2 text="Create Account" isLoading={isLoading} disabled={!formIsValid} onClick={handleSubmit} /> | ||
</div> | ||
</form> | ||
); | ||
} | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.