diff --git a/client/src/App/App.js b/client/src/App/App.js index ac2111752..d6159b39b 100644 --- a/client/src/App/App.js +++ b/client/src/App/App.js @@ -1,20 +1,16 @@ -import { useApolloClient } from "@apollo/react-hooks"; import i18next from "i18next"; -import React, { lazy, Suspense, useEffect, useState } from "react"; +import React, { lazy, Suspense, useEffect } from "react"; +import { connect } from "react-redux"; import { Route, Switch } from "react-router-dom"; +import { createStructuredSelector } from "reselect"; import ErrorBoundary from "../components/error-boundary/error-boundary.component"; //Component Imports import LoadingSpinner from "../components/loading-spinner/loading-spinner.component"; -import { auth } from "../firebase/firebase.utils"; -import { UPSERT_USER } from "../graphql/user.queries"; -import { connect } from "react-redux"; -import { createStructuredSelector } from "reselect"; - +import { checkUserSession } from "../redux/user/user.actions"; +import { selectCurrentUser } from "../redux/user/user.selectors"; // import { QUERY_BODYSHOP } from "../graphql/bodyshop.queries"; import PrivateRoute from "../utils/private-route"; import "./App.css"; -import { checkUserSession } from "../redux/user/user.actions"; -import { selectCurrentUser } from "../redux/user/user.selectors"; const LandingPage = lazy(() => import("../pages/landing/landing.page")); const ManagePage = lazy(() => import("../pages/manage/manage.page")); @@ -26,11 +22,9 @@ const Unauthorized = lazy(() => const mapStateToProps = createStructuredSelector({ currentUser: selectCurrentUser }); - const mapDispatchToProps = dispatch => ({ checkUserSession: () => dispatch(checkUserSession()) }); - export default connect( mapStateToProps, mapDispatchToProps @@ -40,42 +34,6 @@ export default connect( return () => {}; }, [checkUserSession]); - // useEffect(() => { - // //Run the auth code only on the first render. - // const unsubscribeFromAuth = auth.onAuthStateChanged(async user => { - // console.log("onAuthStateChanged: User:", user); - // if (user) { - // let token; - // token = await user.getIdToken(); - - // //add the bearer token to the headers. - // localStorage.setItem("token", token); - // const now = new Date(); - // window.sessionStorage.setItem(`lastTokenRefreshTime`, now); - - // //token = await user.getIdToken(true); //how to refresh the token. - - // apolloClient - // .mutate({ - // mutation: UPSERT_USER, - // variables: { authEmail: user.email, authToken: user.uid } - // }) - // .then() - // .catch(error => { - // console.log("User login upsert error.", error); - // }); - - // } else { - // localStorage.removeItem("token"); - // } - // setloaded(true); - // }); - - // return function cleanup() { - // unsubscribeFromAuth(); - // }; - // }, [apolloClient]); - if (false) i18next.changeLanguage("en_US", (err, t) => { if (err) diff --git a/client/src/components/current-user-dropdown/current-user-dropdown.component.jsx b/client/src/components/current-user-dropdown/current-user-dropdown.component.jsx index f7735f5d0..dbf6b6a45 100644 --- a/client/src/components/current-user-dropdown/current-user-dropdown.component.jsx +++ b/client/src/components/current-user-dropdown/current-user-dropdown.component.jsx @@ -1,4 +1,3 @@ -import { useApolloClient } from "@apollo/react-hooks"; import { Avatar, Col, Dropdown, Icon, Menu, Row } from "antd"; import i18next from "i18next"; import React from "react"; @@ -7,6 +6,7 @@ import { connect } from "react-redux"; import { Link } from "react-router-dom"; import { createStructuredSelector } from "reselect"; import UserImage from "../../assets/User.svg"; +import { setUserLanguage, signOutStart } from "../../redux/user/user.actions"; import { selectCurrentUser } from "../../redux/user/user.selectors"; import SignOut from "../sign-out/sign-out.component"; @@ -15,30 +15,30 @@ const mapStateToProps = createStructuredSelector({ }); const mapDispatchToProps = dispatch => ({ - // signOutStart: () => dispatch(signOutStart()) + signOutStart: () => dispatch(signOutStart()), + setUserLanguage: language => dispatch(setUserLanguage(language)) }); export default connect( mapStateToProps, mapDispatchToProps -)(function CurrentUserDropdown({ currentUser }) { +)(function CurrentUserDropdown({ currentUser, signOutStart, setUserLanguage }) { const { t } = useTranslation(); - const client = useApolloClient(); - const handleMenuClick = e => { if (e.item.props.actiontype === "lang-select") { i18next.changeLanguage(e.key, (err, t) => { if (err) return console.log("Error encountered when changing languages.", err); - client.writeData({ data: { language: e.key } }); + setUserLanguage(e.key); + console.log("clicking"); }); } }; const menu = ( - + {t("menus.currentuser.profile")} diff --git a/client/src/components/header/header.component.jsx b/client/src/components/header/header.component.jsx index 0067db0d6..e1ec729b3 100644 --- a/client/src/components/header/header.component.jsx +++ b/client/src/components/header/header.component.jsx @@ -1,4 +1,3 @@ -import { useApolloClient } from "@apollo/react-hooks"; import { Col, Icon, Menu, Row } from "antd"; import React from "react"; import { useTranslation } from "react-i18next"; @@ -7,21 +6,15 @@ import CurrentUserDropdown from "../current-user-dropdown/current-user-dropdown. import GlobalSearch from "../global-search/global-search.component"; import ManageSignInButton from "../manage-sign-in-button/manage-sign-in-button.component"; -export default ({ landingHeader, navItems, selectedNavItem }) => { - const apolloClient = useApolloClient(); +export default ({ landingHeader, selectedNavItem }) => { const { t } = useTranslation(); - const handleClick = e => { - apolloClient.writeData({ data: { selectedNavItem: e.key } }); - }; - return ( diff --git a/client/src/components/jobs-documents/jobs-documents.container.jsx b/client/src/components/jobs-documents/jobs-documents.container.jsx index 32aedb3f5..dd48114dc 100644 --- a/client/src/components/jobs-documents/jobs-documents.container.jsx +++ b/client/src/components/jobs-documents/jobs-documents.container.jsx @@ -1,13 +1,22 @@ import React from "react"; import { useQuery } from "react-apollo"; +import { connect } from "react-redux"; +import { createStructuredSelector } from "reselect"; import { QUERY_SHOP_ID } from "../../graphql/bodyshop.queries"; import { GET_DOCUMENTS_BY_JOB } from "../../graphql/documents.queries"; +import { selectCurrentUser } from "../../redux/user/user.selectors"; import AlertComponent from "../alert/alert.component"; import LoadingSpinner from "../loading-spinner/loading-spinner.component"; import JobDocuments from "./jobs-documents.component"; -import { GET_CURRENT_USER } from "../../graphql/local.queries"; -export default function JobsDocumentsContainer({ jobId }) { +const mapStateToProps = createStructuredSelector({ + currentUser: selectCurrentUser +}); + +export default connect( + mapStateToProps, + null +)(function JobsDocumentsContainer({ jobId, currentUser }) { const { loading, error, data } = useQuery(GET_DOCUMENTS_BY_JOB, { variables: { jobId: jobId }, fetchPolicy: "network-only" @@ -17,14 +26,12 @@ export default function JobsDocumentsContainer({ jobId }) { fetchPolicy: "network-only" }); - const user = useQuery(GET_CURRENT_USER); - - if (loading || shopData.loading || user.loading) return ; - if (error || shopData.error || user.error) + if (loading || shopData.loading) return ; + if (error || shopData.error) return ( ); @@ -32,7 +39,7 @@ export default function JobsDocumentsContainer({ jobId }) { ); -} +}); diff --git a/client/src/components/manage-sign-in-button/manage-sign-in-button.component.jsx b/client/src/components/manage-sign-in-button/manage-sign-in-button.component.jsx index 85a87a58c..55ffe1281 100644 --- a/client/src/components/manage-sign-in-button/manage-sign-in-button.component.jsx +++ b/client/src/components/manage-sign-in-button/manage-sign-in-button.component.jsx @@ -1,10 +1,7 @@ -import React from "react"; -import { useQuery } from "react-apollo"; -import { Link } from "react-router-dom"; -import { GET_CURRENT_USER } from "../../graphql/local.queries"; import { Icon } from "antd"; -import LoadingSpinner from "../loading-spinner/loading-spinner.component"; +import React from "react"; import { connect } from "react-redux"; +import { Link } from "react-router-dom"; import { createStructuredSelector } from "reselect"; import { selectCurrentUser } from "../../redux/user/user.selectors"; @@ -12,28 +9,19 @@ const mapStateToProps = createStructuredSelector({ currentUser: selectCurrentUser }); -const mapDispatchToProps = dispatch => ({ - // signOutStart: () => dispatch(signOutStart()) -}); - export default connect( mapStateToProps, - mapDispatchToProps + null )(function ManageSignInButton({ currentUser }) { - return currentUser.isAuthorized ? ( -
- {" "} - - - Manage - -
+ return currentUser.authorized ? ( + + + Manage + ) : ( -
- - - Sign In - -
+ + + Sign In + ); }); diff --git a/client/src/components/sign-in-form/sign-in-form.component.jsx b/client/src/components/sign-in-form/sign-in-form.component.jsx index e41aeff39..1a93c9a77 100644 --- a/client/src/components/sign-in-form/sign-in-form.component.jsx +++ b/client/src/components/sign-in-form/sign-in-form.component.jsx @@ -1,14 +1,13 @@ import { Button, Form, Icon, Input } from "antd"; import React from "react"; +import { useApolloClient } from "react-apollo"; import { connect } from "react-redux"; +import { Redirect } from "react-router-dom"; import { createStructuredSelector } from "reselect"; import Logo from "../../assets/logo240.png"; +import { UPSERT_USER } from "../../graphql/user.queries"; import { emailSignInStart } from "../../redux/user/user.actions"; -import { - selectCurrentUser, - selectSignInError -} from "../../redux/user/user.selectors"; -import { Redirect } from "react-router-dom"; +import { selectCurrentUser, selectSignInError } from "../../redux/user/user.selectors"; const mapStateToProps = createStructuredSelector({ currentUser: selectCurrentUser, @@ -30,6 +29,8 @@ export default connect( currentUser, signInError }) { + const apolloClient = useApolloClient(); + const handleSubmit = e => { e.preventDefault(); form.validateFields(async (err, values) => { @@ -41,7 +42,21 @@ export default connect( }); }; - console.log("currentUser", currentUser); + if (currentUser.authorized === true) { + apolloClient + .mutate({ + mutation: UPSERT_USER, + variables: { + authEmail: currentUser.email, + authToken: currentUser.uid + } + }) + .then() + .catch(error => { + console.log("User login upsert error.", error); + }); + } + const { getFieldDecorator } = form; return (
diff --git a/client/src/components/sign-out/sign-out.component.jsx b/client/src/components/sign-out/sign-out.component.jsx index 9e995d819..4dfc90ece 100644 --- a/client/src/components/sign-out/sign-out.component.jsx +++ b/client/src/components/sign-out/sign-out.component.jsx @@ -1,20 +1,8 @@ import React from "react"; import { useTranslation } from "react-i18next"; -import firebase from "../../firebase/firebase.utils"; - -export default function SignoutComponent() { - const signOut = async () => { - try { - await firebase.auth().signOut(); - // this.setState({ - // redirect: true - // }); - } catch (error) { - console.log(error); - } - }; +export default function SignoutComponent({ signOutStart }) { const { t } = useTranslation(); - return
{t("user.actions.signout")}
; + return
{t("user.actions.signout")}
; } diff --git a/client/src/graphql/local.queries.js b/client/src/graphql/local.queries.js deleted file mode 100644 index 7611dfd32..000000000 --- a/client/src/graphql/local.queries.js +++ /dev/null @@ -1,25 +0,0 @@ -import { gql } from "apollo-boost"; - -export const GET_CURRENT_USER = gql` - query GET_CURRENT_USER { - currentUser @client { - email - displayName - token - uid - photoUrl - } - } -`; - -export const GET_CURRENT_SELECTED_NAV_ITEM = gql` - query GET_CURRENT_SELECTED_NAV_ITEM { - selectedNavItem @client - } -`; - -export const GET_LANGUAGE = gql` - query GET_USER_LANGUAGE { - language @client - } -`; diff --git a/client/src/redux/user/user.actions.js b/client/src/redux/user/user.actions.js index 334ad2d8a..90cd48c41 100644 --- a/client/src/redux/user/user.actions.js +++ b/client/src/redux/user/user.actions.js @@ -33,3 +33,8 @@ export const signOutFailure = error => ({ export const unauthorizedUser = () => ({ type: UserActionTypes.UNAUTHORIZED_USER }); + +export const setUserLanguage = language => ({ + type: UserActionTypes.SET_USER_LANGUAGE, + payload: language +}); diff --git a/client/src/redux/user/user.reducer.js b/client/src/redux/user/user.reducer.js index fa9535d9e..89a6eb41c 100644 --- a/client/src/redux/user/user.reducer.js +++ b/client/src/redux/user/user.reducer.js @@ -2,7 +2,8 @@ import UserActionTypes from "./user.types"; const INITIAL_STATE = { currentUser: { - authorized: null + authorized: null, + language: "en_US" }, error: null }; @@ -27,9 +28,15 @@ const userReducer = (state = INITIAL_STATE, action) => { error: null, currentUser: { authorized: false } }; + case UserActionTypes.SET_USER_LANGUAGE: + return { + ...state, + language: action.payload + }; case UserActionTypes.SIGN_IN_FAILURE: case UserActionTypes.SIGN_OUT_FAILURE: case UserActionTypes.EMAIL_SIGN_UP_FAILURE: + console.log("Reduced getting called."); return { ...state, error: action.payload diff --git a/client/src/redux/user/user.sagas.js b/client/src/redux/user/user.sagas.js index f67356042..9a7db1526 100644 --- a/client/src/redux/user/user.sagas.js +++ b/client/src/redux/user/user.sagas.js @@ -1,12 +1,6 @@ import { all, call, put, takeLatest } from "redux-saga/effects"; import { auth, getCurrentUser } from "../../firebase/firebase.utils"; -import { - signInFailure, - signInSuccess, - signOutFailure, - signOutSuccess, - unauthorizedUser -} from "./user.actions"; +import { signInFailure, signInSuccess, signOutFailure, signOutSuccess, unauthorizedUser } from "./user.actions"; import UserActionTypes from "./user.types"; // export function* getSnapshotFromUserAuth(userAuth) { @@ -23,7 +17,7 @@ export function* signInWithEmail({ payload: { email, password } }) { const { user } = yield auth.signInWithEmailAndPassword(email, password); yield put( signInSuccess({ - id: user.uid, + uid: user.uid, email: user.email, displayName: user.displayName, authorized: true @@ -45,9 +39,13 @@ export function* isUserAuthenticated() { yield put(unauthorizedUser()); return; } + let token = yield user.getIdToken(); + localStorage.setItem("token", token); + window.sessionStorage.setItem(`lastTokenRefreshTime`, new Date()); + yield put( signInSuccess({ - id: user.uid, + uid: user.uid, email: user.email, displayName: user.displayName, authorized: true @@ -66,6 +64,7 @@ export function* signOutStart() { try { yield auth.signOut(); yield put(signOutSuccess()); + localStorage.removeItem("token"); } catch (error) { yield put(signOutFailure(error.message)); } @@ -75,12 +74,13 @@ export function* onSignOutStart() { yield takeLatest(UserActionTypes.SIGN_OUT_START, signOutStart); } + export function* userSagas() { yield all([ // call(onGoogleSignInStart), call(onEmailSignInStart), call(onCheckUserSession), - call(onSignOutStart) + call(onSignOutStart), // call(onEmailSignUpStart), // call(onEmailSignUpSuccess) ]); diff --git a/client/src/redux/user/user.types.js b/client/src/redux/user/user.types.js index 07a32eb3b..d4d2c2919 100644 --- a/client/src/redux/user/user.types.js +++ b/client/src/redux/user/user.types.js @@ -1,17 +1,17 @@ const UserActionTypes = { - SET_CURRENT_USER: "SET_CURRENT_USER", - GOOGLE_SIGN_IN_START: "GOOGLE_SIGN_IN_START", - SIGN_IN_SUCCESS: "SIGN_IN_SUCCESS", - SIGN_IN_FAILURE: "SIGN_IN_FAILURE", - EMAIL_SIGN_IN_START: "EMAIL_SIGN_IN_START", - CHECK_USER_SESSION: "CHECK_USER_SESSION", - SIGN_OUT_START: "SIGN_OUT_START", - SIGN_OUT_SUCCESS: "SIGN_OUT_SUCCESS", - SIGN_OUT_FAILURE: "SIGN_OUT_FAILURE", - EMAIL_SIGN_UP_START: "EMAIL_SIGN_UP_START", - EMAIL_SIGN_UP_SUCCESS: "EMAIL_SIGN_UP_SUCCESS", - EMAIL_SIGN_UP_FAILURE: "EMAIL_SIGN_UP_FAILURE", - UNAUTHORIZED_USER: "UNAUTHORIZED_USER" - }; - export default UserActionTypes; - \ No newline at end of file + SET_CURRENT_USER: "SET_CURRENT_USER", + GOOGLE_SIGN_IN_START: "GOOGLE_SIGN_IN_START", + SIGN_IN_SUCCESS: "SIGN_IN_SUCCESS", + SIGN_IN_FAILURE: "SIGN_IN_FAILURE", + EMAIL_SIGN_IN_START: "EMAIL_SIGN_IN_START", + CHECK_USER_SESSION: "CHECK_USER_SESSION", + SIGN_OUT_START: "SIGN_OUT_START", + SIGN_OUT_SUCCESS: "SIGN_OUT_SUCCESS", + SIGN_OUT_FAILURE: "SIGN_OUT_FAILURE", + EMAIL_SIGN_UP_START: "EMAIL_SIGN_UP_START", + EMAIL_SIGN_UP_SUCCESS: "EMAIL_SIGN_UP_SUCCESS", + EMAIL_SIGN_UP_FAILURE: "EMAIL_SIGN_UP_FAILURE", + UNAUTHORIZED_USER: "UNAUTHORIZED_USER", + SET_USER_LANGUAGE: "SET_USER_LANGUAGE" +}; +export default UserActionTypes;