Skip to content

Commit

Permalink
Merge pull request #29 from 001elijah/something
Browse files Browse the repository at this point in the history
Google
  • Loading branch information
001elijah authored Jun 26, 2023
2 parents 1ec87cd + 814dc26 commit 9c7ae91
Show file tree
Hide file tree
Showing 11 changed files with 245 additions and 8 deletions.
11 changes: 11 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
"axios": "^1.4.0",
"clsx": "^1.2.1",
"formik": "^2.4.2",
"gapi-script": "^1.2.0",
"modern-normalize": "^2.0.0",
"moment": "^2.29.4",
"notiflix": "^3.2.6",
Expand Down
1 change: 1 addition & 0 deletions public/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -79,4 +79,5 @@
AOS.init();
</script>
</body>
<script src="https://apis.google.com/js/api.js" async defer></script>
</html>
8 changes: 8 additions & 0 deletions src/assets/icons/sprite.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
66 changes: 66 additions & 0 deletions src/components/AuthForm/Login/Login.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import { useFormik } from 'formik';
import { useState } from 'react';
import { useDispatch } from 'react-redux';

import { ButtonAuth } from '../ButtonAuth/ButtonAuth';
import { validationSchemaLogin } from '../schemaValidation';
import { loginUser } from 'redux/Auth/authOperations';
import { LoginWithGoogle } from '../../AuthWithGoogle/AuthWithGoogle';

import icons from '../../../assets/icons/sprite.svg';
import y from './Login.module.scss';

export const Login = () => {
const dispatch = useDispatch();
const [showPassword, setShowPassword] = useState(false);

const toggleShowPassword = () => setShowPassword(!showPassword);

const formik = useFormik({
initialValues: {
email: '',
password: '',
},
validationSchema: validationSchemaLogin,
onSubmit: values => {
dispatch(loginUser(values));
},
});
return (
<form onSubmit={formik.handleSubmit}>
<label htmlFor="email">
<input
id="email"
name="email"
type="email"
onChange={formik.handleChange}
value={formik.values.email}
placeholder="Enter your email"
/>
{formik.touched.email && formik.errors.email && (
<p className={y.error}>{formik.errors.email}</p>
)}
</label>
<label htmlFor="password">
<input
id="password"
name="password"
type={showPassword ? 'text' : 'password'}
onChange={formik.handleChange}
value={formik.values.password}
placeholder="Confirm a password"
/>
<svg className={y.eye} onClick={toggleShowPassword}>
<use
href={showPassword ? `${icons}#icon-eye` : `${icons}#icon-antiEye`}
></use>
</svg>
{formik.touched.password && formik.errors.password && (
<p className={y.error}>{formik.errors.password}</p>
)}
</label>
<ButtonAuth title="Log In Now" />
<LoginWithGoogle></LoginWithGoogle>
</form>
);
};
25 changes: 25 additions & 0 deletions src/components/AuthWithGoogle/AuthWithGoogle.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import React from 'react';
import { useDispatch } from 'react-redux';
import { authWithGoogleOperation } from '../../redux/Auth/authGoogleOperations';
import svg from '../../assets/icons/sprite.svg';
import s from './AuthWithGoogle.module.scss';

export const AuthWithGoogle = () => {
const dispatch = useDispatch();

const handleGoogleLogin = () => {
const googleClientId = `128986061205-1q4bl09jae2cqs2qljamh3tvboatcrin.apps.googleusercontent.com`;
dispatch(authWithGoogleOperation(googleClientId));
};

return (
<div>
<button type="button" className={s.button} onClick={handleGoogleLogin}>
<span className={s.title}>Continue with</span>
<svg className={s.google}>
<use xlinkHref={`${svg}#icon-google`} />
</svg>
</button>
</div>
);
};
41 changes: 41 additions & 0 deletions src/components/AuthWithGoogle/AuthWithGoogle.module.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
@import '../../assets/styles/vars';
@import '../../assets/styles/mixins';

.button {
width: 100%;
height: 49px;
margin-top: 24px;

background-color: $accent-color;
display: flex;
align-items: center;
justify-content: center;
border: none;
border-radius: 8px;

cursor: pointer;

&.colorful {
background-color: $accent-bright-color;
color: $white-text-color;
}

@include mobile {
min-width: 288px;
}

@include tablet {
min-width: 344px;
}
}
.title {
color: $black-text-color;
font-weight: 500;
font-size: 14px;
line-height: 1.5;
text-align: end;
}
.google {
height: 50px;
width: 72px;
}
2 changes: 2 additions & 0 deletions src/components/LoginForm/Login.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { useDispatch } from 'react-redux';
import { ButtonAuth } from '../ButtonAuth/ButtonAuth';
import { validationSchemaLogin } from '../SchemaValidation/schemaValidation';
import { loginUser } from 'redux/Auth/authOperations';
import { AuthWithGoogle } from '../AuthWithGoogle/AuthWithGoogle';

import icons from '../../assets/icons/sprite.svg';
import y from './Login.module.scss';
Expand Down Expand Up @@ -59,6 +60,7 @@ export const Login = () => {
)}
</label>
<ButtonAuth title="Log In Now" />
<AuthWithGoogle></AuthWithGoogle>
</form>
);
};
2 changes: 2 additions & 0 deletions src/components/RegisterForm/Register.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { useDispatch } from 'react-redux';
import { ButtonAuth } from '../ButtonAuth/ButtonAuth';
import { validationSchemaRegister } from '../SchemaValidation/schemaValidation';
import { registerUser } from 'redux/Auth/authOperations';
import { AuthWithGoogle } from 'components/AuthWithGoogle/AuthWithGoogle';

import icons from '../../assets/icons/sprite.svg';
import y from '../LoginForm/Login.module.scss';
Expand Down Expand Up @@ -74,6 +75,7 @@ export const Register = () => {
)}
</label>
<ButtonAuth title="Register Now" />
<AuthWithGoogle></AuthWithGoogle>
</form>
);
};
67 changes: 67 additions & 0 deletions src/redux/Auth/authGoogleOperations.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
import { gapi } from 'gapi-script';
import { authWithGoogleApi } from '../../services/backendAPI';
import { logOut } from './authSlice';
import { Notify } from 'notiflix';

export const authWithGoogleOperation = googleClientId => {
return async dispatch => {
try {
const authResult = await authenticateWithGoogle(googleClientId);
if (authResult.error) {
throw new Error(authResult.error);
}

const { credential } = authResult;
const data = await authWithGoogleApi({ credential });
const { token, userName, email, theme, avatarUrl } = data;

dispatch({
type: 'auth/register/fulfilled',
payload: {
token,
userName,
email,
theme,
avatarUrl,
},
});
Notify.success('Welcome');
} catch (error) {
console.log(error);
dispatch(logOut());
if (error.status === 400) {
Notify.failure('Error');
} else if (error.status === 500) {
Notify.failure('Server error');
}
}
};
};

const authenticateWithGoogle = googleClientId => {
return new Promise((resolve, reject) => {
// Initialize the Google Sign-In API
gapi.load('auth2', () => {
gapi.auth2.init({
client_id: googleClientId,
});

// Trigger Google Sign-In flow
gapi.auth2
.getAuthInstance()
.signIn({ prompt: 'select_account' })
.then(googleUser => {
const idToken = googleUser.getAuthResponse().id_token;

// Resolve with the credential containing the Google ID token
resolve({ credential: { idToken } });
})
.catch(error => {
// Reject with the error message
reject(
new Error(`Failed to authenticate with Google: ${error.error}`),
);
});
});
});
};
29 changes: 21 additions & 8 deletions src/services/backendAPI.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import axios from 'axios';

axios.defaults.baseURL = 'https://taskpro.onrender.com/';
axios.defaults.baseURL = 'https://taskpro.onrender.com';

//axios.defaults.baseURL = 'http://localhost:3000';

const token = {
set(token) {
Expand All @@ -12,36 +14,36 @@ const token = {
};

export const registerUserApi = async userData => {
const { data } = await axios.post('user/register', userData);
const { data } = await axios.post('/user/register', userData);
token.set(data.token);
return { ...data.user, token: data.token };
};

export const loginUserApi = async userData => {
const { data } = await axios.post('user/login', userData);
const { data } = await axios.post('/user/login', userData);
const user = await currentUserApi(data.token);
return { ...user, token: data.token };
};

export const currentUserApi = async userToken => {
token.set(userToken);
const { data } = await axios.get('user/current');
const { data } = await axios.get('/user/current');
return data;
};

export const logoutUserApi = async userToken => {
await axios.post('user/logout', userToken);
await axios.post('/user/logout', userToken);
token.unset();
return null;
};

export const themeChangeUserApi = async theme => {
const { data } = await axios.patch('user/', theme);
const { data } = await axios.patch('/user/', theme);
return data;
};

export const updateUserApi = async userData => {
const { data } = await axios.patch('user/updateUserInfo', userData);
const { data } = await axios.patch('/user/updateUserInfo', userData);
return data.user;
};
//---------------------------------------------BOARDS---------------------//
Expand All @@ -55,7 +57,7 @@ export const getListOfBoardsApi = async userToken => {
//---------------------------------------------EMAIL---------------------//

export const sendEmailApi = async userEmail => {
const { data } = await axios.post('user/sendEmail', userEmail);
const { data } = await axios.post('/user/sendEmail', userEmail);
return data.message;
};

Expand Down Expand Up @@ -94,3 +96,14 @@ export const removeCardApi = async id => {
await axios.delete(`/card/${id}`);
return;
};

export const authWithGoogleApi = async data => {
const { credential } = data;
const { idToken } = credential;
const response = await axios.post('/user/auth/google', {
credential,
idToken,
});
token.set(response.data.token);
return { ...response.data.user, token: response.data.token };
};

0 comments on commit 9c7ae91

Please sign in to comment.