diff --git a/client/package.json b/client/package.json
index 6485f4584..de8c9b498 100644
--- a/client/package.json
+++ b/client/package.json
@@ -26,9 +26,15 @@
"react-image-file-resizer": "^0.2.1",
"react-moment": "^0.9.7",
"react-number-format": "^4.3.1",
+ "react-redux": "^7.1.3",
"react-router-dom": "^5.1.2",
"react-scripts": "3.2.0",
"react-trello": "^2.2.3",
+ "redux": "^4.0.5",
+ "redux-logger": "^3.0.6",
+ "redux-persist": "^6.0.0",
+ "redux-saga": "^1.1.3",
+ "reselect": "^4.0.0",
"styled-components": "^4.4.1",
"subscriptions-transport-ws": "^0.9.16"
},
diff --git a/client/src/App/App.container.jsx b/client/src/App/App.container.jsx
index fa2168fce..27db52240 100644
--- a/client/src/App/App.container.jsx
+++ b/client/src/App/App.container.jsx
@@ -1,23 +1,20 @@
-import React, { Component } from "react";
-
-import App from "./App";
-import Spin from "../components/loading-spinner/loading-spinner.component";
-
+import { ApolloLink } from "apollo-boost";
+import { InMemoryCache } from "apollo-cache-inmemory";
import ApolloClient from "apollo-client";
import { split } from "apollo-link";
+import { setContext } from "apollo-link-context";
import { HttpLink } from "apollo-link-http";
+import apolloLogger from "apollo-link-logger";
import { WebSocketLink } from "apollo-link-ws";
import { getMainDefinition } from "apollo-utilities";
-import { InMemoryCache } from "apollo-cache-inmemory";
-import { setContext } from "apollo-link-context";
-import { resolvers, typeDefs } from "../graphql/resolvers";
-import apolloLogger from "apollo-link-logger";
-import { ApolloLink } from "apollo-boost";
+import React, { Component } from "react";
import { ApolloProvider } from "react-apollo";
-import { persistCache } from "apollo-cache-persist";
-import initialState from "../graphql/initial-state";
+import SpinnerComponent from "../components/loading-spinner/loading-spinner.component";
//import { shouldRefreshToken, refreshToken } from "../graphql/middleware";
import errorLink from "../graphql/apollo-error-handling";
+import App from "./App";
+
+
class AppContainer extends Component {
state = {
@@ -69,14 +66,8 @@ class AppContainer extends Component {
);
const authLink = setContext((_, { headers }) => {
- // get the authentication token from local storage if it exists
const token = localStorage.getItem("token");
- // return the headers to the context so httpLink can read them
if (token) {
- // if (shouldRefreshToken) {
- // refreshToken();
- // }
-
return {
headers: {
...headers,
@@ -99,31 +90,13 @@ class AppContainer extends Component {
const client = new ApolloClient({
link: ApolloLink.from(middlewares),
cache,
- typeDefs,
- resolvers,
connectToDevTools: true
});
- client.writeData({
- data: initialState
- });
-
- try {
- await persistCache({
- cache,
- storage: window.sessionStorage,
- debug: true
- });
- } catch (error) {
- console.error("Error restoring Apollo cache", error);
- }
-
this.setState({
client,
loaded: true
});
-
- //Init local state.
}
componentWillUnmount() {}
@@ -132,7 +105,7 @@ class AppContainer extends Component {
const { client, loaded } = this.state;
if (!loaded) {
- return ;
+ return ;
}
return (
diff --git a/client/src/App/App.js b/client/src/App/App.js
index 5ff998489..ac2111752 100644
--- a/client/src/App/App.js
+++ b/client/src/App/App.js
@@ -1,22 +1,20 @@
-import React, { useEffect, Suspense, lazy, useState } from "react";
-import { useApolloClient, useQuery } from "@apollo/react-hooks";
-import { Switch, Route, Redirect } from "react-router-dom";
-import firebase from "../firebase/firebase.utils";
+import { useApolloClient } from "@apollo/react-hooks";
import i18next from "i18next";
-
-import "./App.css";
-
+import React, { lazy, Suspense, useEffect, useState } from "react";
+import { Route, Switch } from "react-router-dom";
+import ErrorBoundary from "../components/error-boundary/error-boundary.component";
//Component Imports
import LoadingSpinner from "../components/loading-spinner/loading-spinner.component";
-import AlertComponent from "../components/alert/alert.component";
-import ErrorBoundary from "../components/error-boundary/error-boundary.component";
-
import { auth } from "../firebase/firebase.utils";
import { UPSERT_USER } from "../graphql/user.queries";
-import { GET_CURRENT_USER, GET_LANGUAGE } from "../graphql/local.queries";
-// import { QUERY_BODYSHOP } from "../graphql/bodyshop.queries";
+import { connect } from "react-redux";
+import { createStructuredSelector } from "reselect";
+// 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"));
@@ -25,110 +23,85 @@ const Unauthorized = lazy(() =>
import("../pages/unauthorized/unauthorized.component")
);
-export default () => {
- const apolloClient = useApolloClient();
- const [loaded, setloaded] = useState(false);
+const mapStateToProps = createStructuredSelector({
+ currentUser: selectCurrentUser
+});
+
+const mapDispatchToProps = dispatch => ({
+ checkUserSession: () => dispatch(checkUserSession())
+});
+
+export default connect(
+ mapStateToProps,
+ mapDispatchToProps
+)(({ checkUserSession, currentUser }) => {
useEffect(() => {
- //Run the auth code only on the first render.
- const unsubscribeFromAuth = auth.onAuthStateChanged(async user => {
- console.log("Auth State Changed.");
- setloaded(true);
- if (user) {
- let token;
- token = await user.getIdToken();
- const idTokenResult = await user.getIdTokenResult();
- const hasuraClaim =
- idTokenResult.claims["https://hasura.io/jwt/claims"];
- if (!hasuraClaim) {
- // Check if refresh is required.
- const metadataRef = firebase
- .database()
- .ref("metadata/" + user.uid + "/refreshTime");
+ checkUserSession();
+ return () => {};
+ }, [checkUserSession]);
- metadataRef.on("value", async () => {
- // Force refresh to pick up the latest custom claims changes.
- token = await user.getIdToken(true);
- });
- }
+ // 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);
- // window.sessionStorage.setItem("user", user);
+ // //add the bearer token to the headers.
+ // localStorage.setItem("token", token);
+ // const now = new Date();
+ // window.sessionStorage.setItem(`lastTokenRefreshTime`, now);
- apolloClient
- .mutate({
- mutation: UPSERT_USER,
- variables: { authEmail: user.email, authToken: user.uid }
- })
- .then()
- .catch(error => {
- console.log("User login upsert error.", error);
- });
+ // //token = await user.getIdToken(true); //how to refresh the token.
- apolloClient.writeData({
- data: {
- currentUser: {
- email: user.email,
- displayName: user.displayName,
- token,
- uid: user.uid,
- photoUrl: user.photoURL,
- __typename: "currentUser"
- }
- }
- });
- } else {
- apolloClient.writeData({ data: { currentUser: null } });
- localStorage.removeItem("token");
- }
- });
+ // apolloClient
+ // .mutate({
+ // mutation: UPSERT_USER,
+ // variables: { authEmail: user.email, authToken: user.uid }
+ // })
+ // .then()
+ // .catch(error => {
+ // console.log("User login upsert error.", error);
+ // });
- return function cleanup() {
- unsubscribeFromAuth();
- };
- }, [apolloClient]);
- const HookCurrentUser = useQuery(GET_CURRENT_USER);
- const HookLanguage = useQuery(GET_LANGUAGE);
+ // } else {
+ // localStorage.removeItem("token");
+ // }
+ // setloaded(true);
+ // });
- if (!loaded) return ;
- if (HookCurrentUser.loading || HookLanguage.loading)
- return ;
- if (HookCurrentUser.error || HookLanguage.error)
- return (
-
- );
+ // return function cleanup() {
+ // unsubscribeFromAuth();
+ // };
+ // }, [apolloClient]);
- if (HookLanguage.data.language)
- i18next.changeLanguage(HookLanguage.data.language, (err, t) => {
+ if (false)
+ i18next.changeLanguage("en_US", (err, t) => {
if (err)
return console.log("Error encountered when changing languages.", err);
});
+ console.log("currentUser", currentUser);
+ if (currentUser.authorized === null) {
+ //TODO: Translate this.
+ return ;
+ }
+
return (
}>
-
-
-
- HookCurrentUser.data.currentUser ? (
-
- ) : (
-
- )
- }
- />
+
+
+
+
+
@@ -136,4 +109,4 @@ export default () => {
);
-};
+});
diff --git a/client/src/components/chat-window/chat-window.container.jsx b/client/src/components/chat-window/chat-window.container.jsx
index cd70e1060..940e7b416 100644
--- a/client/src/components/chat-window/chat-window.container.jsx
+++ b/client/src/components/chat-window/chat-window.container.jsx
@@ -1,8 +1,22 @@
import React, { useState } from "react";
import ChatWindowComponent from "./chat-window.component";
import { Button } from "antd";
+import { connect } from "react-redux";
+import { createStructuredSelector } from "reselect";
+import { selectCurrentUser } from "../../redux/user/user.selectors";
-export default function ChatWindowContainer() {
+const mapStateToProps = createStructuredSelector({
+ currentUser: selectCurrentUser
+});
+
+const mapDispatchToProps = dispatch => ({
+ // signOutStart: () => dispatch(signOutStart())
+});
+
+export default connect(
+ mapStateToProps,
+ mapDispatchToProps
+)(function ChatWindowContainer({ currentUser }) {
const [visible, setVisible] = useState(false);
return (
@@ -10,9 +24,10 @@ export default function ChatWindowContainer() {
);
-}
+});
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 5f23bca64..f7735f5d0 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,17 +1,29 @@
-import { useApolloClient, useQuery } from "@apollo/react-hooks";
+import { useApolloClient } from "@apollo/react-hooks";
import { Avatar, Col, Dropdown, Icon, Menu, Row } from "antd";
import i18next from "i18next";
import React from "react";
import { useTranslation } from "react-i18next";
+import { connect } from "react-redux";
import { Link } from "react-router-dom";
+import { createStructuredSelector } from "reselect";
import UserImage from "../../assets/User.svg";
-import { GET_CURRENT_USER } from "../../graphql/local.queries";
-import AlertComponent from "../alert/alert.component";
+import { selectCurrentUser } from "../../redux/user/user.selectors";
import SignOut from "../sign-out/sign-out.component";
-export default function CurrentUserDropdown() {
+const mapStateToProps = createStructuredSelector({
+ currentUser: selectCurrentUser
+});
+
+const mapDispatchToProps = dispatch => ({
+ // signOutStart: () => dispatch(signOutStart())
+});
+
+export default connect(
+ mapStateToProps,
+ mapDispatchToProps
+)(function CurrentUserDropdown({ currentUser }) {
const { t } = useTranslation();
- const { loading, error, data } = useQuery(GET_CURRENT_USER);
+
const client = useApolloClient();
const handleMenuClick = e => {
@@ -24,43 +36,39 @@ export default function CurrentUserDropdown() {
}
};
const menu = (
-