diff --git a/package-lock.json b/package-lock.json index ecc537e..9131ee7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -31,6 +31,7 @@ "web-vitals": "^1.1.2" }, "devDependencies": { + "axios": "^1.3.3", "cypress": "^9.5.0", "eslint": "^8.26.0", "eslint-plugin-react": "^7.31.10", @@ -6644,6 +6645,37 @@ "node": ">=4" } }, + "node_modules/axios": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.3.3.tgz", + "integrity": "sha512-eYq77dYIFS77AQlhzEL937yUBSepBfPIe8FcgEDN35vMNZKMrs81pgnyrQpwfy4NF4b4XWX1Zgx7yX+25w8QJA==", + "dev": true, + "dependencies": { + "follow-redirects": "^1.15.0", + "form-data": "^4.0.0", + "proxy-from-env": "^1.1.0" + } + }, + "node_modules/axios/node_modules/form-data": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", + "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", + "dev": true, + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/axios/node_modules/proxy-from-env": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", + "dev": true + }, "node_modules/axobject-query": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-2.2.0.tgz", @@ -16172,6 +16204,11 @@ "node": ">=4.0" } }, + "node_modules/jwt-decode": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/jwt-decode/-/jwt-decode-3.1.2.tgz", + "integrity": "sha512-UfpWE/VZn0iP50d8cz9NrZLM9lSWhcJ+0Gt/nm4by88UL+J1SiKN8/5dkjMmbEzwL2CAe+67GsegCbIKtbp75A==" + }, "node_modules/kind-of": { "version": "6.0.3", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", @@ -31045,6 +31082,36 @@ "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.5.0.tgz", "integrity": "sha512-4+rr8eQ7+XXS5nZrKcMO/AikHL0hVqy+lHWAnE3xdHl+aguag8SOQ6eEqLexwLNWgXIMfunGuD3ON1/6Kyet0A==" }, + "axios": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.3.3.tgz", + "integrity": "sha512-eYq77dYIFS77AQlhzEL937yUBSepBfPIe8FcgEDN35vMNZKMrs81pgnyrQpwfy4NF4b4XWX1Zgx7yX+25w8QJA==", + "dev": true, + "requires": { + "follow-redirects": "^1.15.0", + "form-data": "^4.0.0", + "proxy-from-env": "^1.1.0" + }, + "dependencies": { + "form-data": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", + "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", + "dev": true, + "requires": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + } + }, + "proxy-from-env": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", + "dev": true + } + } + }, "axobject-query": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-2.2.0.tgz", @@ -38059,6 +38126,11 @@ "object.assign": "^4.1.3" } }, + "jwt-decode": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/jwt-decode/-/jwt-decode-3.1.2.tgz", + "integrity": "sha512-UfpWE/VZn0iP50d8cz9NrZLM9lSWhcJ+0Gt/nm4by88UL+J1SiKN8/5dkjMmbEzwL2CAe+67GsegCbIKtbp75A==" + }, "kind-of": { "version": "6.0.3", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", diff --git a/package.json b/package.json index 19d2d0b..2aa9c66 100644 --- a/package.json +++ b/package.json @@ -13,7 +13,6 @@ "@testing-library/react": "^11.2.7", "@testing-library/user-event": "^12.8.3", "framer-motion": "^7.6.1", - "gapi-script": "^1.2.0", "node-sass": "^7.0.3", "react": "^18.2.0", "react-dom": "^18.2.0", @@ -34,6 +33,7 @@ "eject": "react-scripts eject" }, "devDependencies": { + "axios": "^1.3.3", "cypress": "^9.5.0", "eslint": "^8.26.0", "eslint-plugin-react": "^7.31.10", diff --git a/public/index.html b/public/index.html index a7fb0b9..cb0a1cf 100644 --- a/public/index.html +++ b/public/index.html @@ -37,6 +37,7 @@ +
diff --git a/src/components/AddEventButton/AddEventButton.jsx b/src/components/AddEventButton/AddEventButton.jsx index fdd22c2..7ff5939 100644 --- a/src/components/AddEventButton/AddEventButton.jsx +++ b/src/components/AddEventButton/AddEventButton.jsx @@ -6,7 +6,7 @@ import Snackbar from '@mui/material/Snackbar'; import IconButton from '@mui/material/IconButton'; import CloseIcon from '@mui/icons-material/Close'; -import { gapi } from 'gapi-script'; +const { gapi } = window; import Alert from '../Alert/Alert'; diff --git a/src/components/LoginButton/LoginButton.jsx b/src/components/LoginButton/LoginButton.jsx index e449051..a0f523b 100644 --- a/src/components/LoginButton/LoginButton.jsx +++ b/src/components/LoginButton/LoginButton.jsx @@ -1,44 +1,54 @@ import React, { useContext } from 'react'; +import { MyContext } from '../../context/Provider'; import { Button } from '@mui/material'; - import { FcGoogle } from 'react-icons/fc'; import { ImExit } from 'react-icons/im'; -import { gapi } from 'gapi-script'; - import { useNavigate } from 'react-router-dom'; - -import { MyContext } from '../../context/Provider'; +import { useGoogleLogin, googleLogout } from '@react-oauth/google'; +import axios from 'axios'; import './LoginButton.scss'; const blankImage = 'https://i.imgur.com/qEgz28w.png'; +const SCOPES = 'https://www.googleapis.com/auth/calendar https://www.googleapis.com/auth/userinfo.profile'; export default function LoginButton() { - const { isSignedIn, setUserImage, changeSignedInState } = useContext(MyContext); + const { isSignedIn, setUserImage, setUserName, setUserEmail, changeSignedInState } = useContext(MyContext); const navigate = useNavigate(); - const handleAuthClick = async () => { - // Faz o Login - await gapi.auth2.getAuthInstance().signIn(); + const login = useGoogleLogin({ + scope: SCOPES, + onSuccess: (response) => signInWorkflow(response), + onError: (error) => console.error(error), + }); - // Depois verifica se o usuário está logado, e seta esse valor em isSignedIn - await gapi.auth2.getAuthInstance().isSignedIn.listen(changeSignedInState); - await changeSignedInState(gapi.auth2.getAuthInstance().isSignedIn.get()); - - // Agora pega a imagem do usuário e seta em userImage - const profileImage = gapi.auth2.getAuthInstance().currentUser.get() - .getBasicProfile().getImageUrl(); + const signInWorkflow = async (response) => { + changeSignedInState(true); + const userInfo = await requestUserInfo(response); + updateUserInfo(userInfo.data); + navigate('/scheduler'); + }; - setUserImage(profileImage); + const updateUserInfo = (userInfo) => { + const { picture, name, email } = userInfo; + setUserImage(picture); + setUserName(name); + setUserEmail(email); + }; - // Finalmente navega para a página de schedule - navigate('/scheduler'); + const requestUserInfo = async (response) => { + const gettingUserInfo = await axios.get('https://www.googleapis.com/oauth2/v3/userinfo', { + headers: { + Authorization: `Bearer ${response.access_token}` + } + }); + return gettingUserInfo; }; const handleSignoutClick = () => { - gapi.auth2.getAuthInstance().signOut(); + googleLogout(); setUserImage(blankImage); navigate('/'); }; @@ -46,7 +56,7 @@ export default function LoginButton() { const connectButton = (