From 0de42d3feec6f8c6ea5e1772604a4b5d3c97cc53 Mon Sep 17 00:00:00 2001 From: Patrick Fic Date: Fri, 6 Dec 2019 16:51:43 -0800 Subject: [PATCH] Fixed all firebase login issues. Added private routes. Reconfigured components and reorganized project. --- client/src/App/App.container.jsx | 26 ++----- client/src/App/App.js | 24 ++++--- .../header-app-bar.component.jsx | 67 ------------------- .../header-app-bar.container.jsx | 44 ------------ .../components/header/header.component.jsx | 36 ++++++++++ .../components/header/header.container.jsx | 43 ++++++++++++ .../src/components/header/header.styles.scss | 4 ++ .../job-list/job-list.container.jsx | 5 +- .../sign-in/sign-in.component.jsx | 2 +- .../loading-spinner.component.jsx | 7 ++ .../loading-spinner.styles.scss | 3 + .../manage-shop/manage-shop.component.jsx | 10 +++ .../manage-shop/manage-shop.container.jsx | 27 ++++++++ .../sign-out/sign-out.component.jsx | 11 +++ client/src/graphql/initial-state.js | 2 + client/src/graphql/metadata.queries.js | 22 ++++++ .../src/pages/landing/landing.component.jsx | 15 +++++ client/src/pages/manage/manage.component.jsx | 16 +++++ client/src/utils/private-route.js | 14 ++++ 19 files changed, 232 insertions(+), 146 deletions(-) delete mode 100644 client/src/components/header-app-bar/header-app-bar.component.jsx delete mode 100644 client/src/components/header-app-bar/header-app-bar.container.jsx create mode 100644 client/src/components/header/header.component.jsx create mode 100644 client/src/components/header/header.container.jsx create mode 100644 client/src/components/header/header.styles.scss rename client/src/components/{ => landing-components}/sign-in/sign-in.component.jsx (97%) create mode 100644 client/src/components/loading-spinner/loading-spinner.component.jsx create mode 100644 client/src/components/loading-spinner/loading-spinner.styles.scss create mode 100644 client/src/components/manage-shop/manage-shop.component.jsx create mode 100644 client/src/components/manage-shop/manage-shop.container.jsx create mode 100644 client/src/components/sign-out/sign-out.component.jsx create mode 100644 client/src/graphql/metadata.queries.js create mode 100644 client/src/pages/landing/landing.component.jsx create mode 100644 client/src/pages/manage/manage.component.jsx create mode 100644 client/src/utils/private-route.js diff --git a/client/src/App/App.container.jsx b/client/src/App/App.container.jsx index 0fb4a4c72..d800afd0f 100644 --- a/client/src/App/App.container.jsx +++ b/client/src/App/App.container.jsx @@ -3,16 +3,13 @@ import React, { useState, useEffect } from "react"; import firebase from "../firebase/firebase.utils"; import App from "./App"; -import { Spin } from "antd"; + import { gql } from "apollo-boost"; -import { useMutation } from "@apollo/react-hooks"; import { HttpLink } from "apollo-link-http"; import ApolloClient from "apollo-client"; import { InMemoryCache } from "apollo-cache-inmemory"; -//import gql from "graphql-tag"; - -// on_conflict: { constraint: users_pkey, update_columns: [authid] } +import Spin from '../components/loading-spinner/loading-spinner.component' const UPSERT_USER = gql` mutation upsert_user($authEmail: String!, $authToken: String!) { @@ -36,9 +33,6 @@ const client = new ApolloClient({ export default function Auth() { const [authState, setAuthState] = useState({ status: "loading" }); - // const [upsertUser] = useMutation(UPSERT_USER, { - // client - // }); useEffect(() => { return firebase.auth().onAuthStateChanged(async user => { @@ -57,7 +51,6 @@ export default function Auth() { const idTokenResult = await user.getIdTokenResult(); const hasuraClaim = idTokenResult.claims["https://hasura.io/jwt/claims"]; - console.log("idTokenResult", idTokenResult); if (hasuraClaim) { setAuthState({ status: "in", user, token }); } else { @@ -89,25 +82,14 @@ export default function Auth() { let content; if (authState.status === "loading") { - content = ; + content = ; } else { content = ( <> -
- {authState.status === "in" ? ( -
-

Welcome, {authState.user.displayName}

- -
- ) : ( -
Sign in
- )} -
- ); } - return
{content}
; + return
{content}
; } diff --git a/client/src/App/App.js b/client/src/App/App.js index 19f0a32bb..d4f645759 100644 --- a/client/src/App/App.js +++ b/client/src/App/App.js @@ -1,19 +1,21 @@ import React from "react"; +import { Switch, Route } from "react-router"; import { ApolloProvider } from "react-apollo"; import { HttpLink } from "apollo-link-http"; import ApolloClient from "apollo-client"; import { InMemoryCache } from "apollo-cache-inmemory"; import { resolvers, typeDefs } from "../graphql/resolvers"; - +import initialState from "../graphql/initial-state"; //Styling imports import "./App.css"; -import HeaderAppBarContainer from "../components/header-app-bar/header-app-bar.container"; -import SignIn from "../components/sign-in/sign-in.component"; -import initialState from "../graphql/initial-state"; -import JobListContainer from "../components/job-list/job-list.container"; +//Component Imports +import SignIn from "../components/landing-components/sign-in/sign-in.component"; +import LandingPage from "../pages/landing/landing.component"; +import Manage from "../pages/manage/manage.component"; + +import PrivateRoute from "../utils/private-route"; -//Todo: Issue with this line. Not sure why. const graphqlEndpoint = process.env.REACT_APP_GRAPHQL_ENDPOINT; export default function App({ authState }) { @@ -30,14 +32,16 @@ export default function App({ authState }) { typeDefs }); client.writeData({ - data: initialState + data: { ...initialState, authState } }); return ( - - {isIn ? null : } - + + + + + ); } diff --git a/client/src/components/header-app-bar/header-app-bar.component.jsx b/client/src/components/header-app-bar/header-app-bar.component.jsx deleted file mode 100644 index e344ae284..000000000 --- a/client/src/components/header-app-bar/header-app-bar.component.jsx +++ /dev/null @@ -1,67 +0,0 @@ -import React, { Component } from "react"; -import { Menu, Icon } from "antd"; - -const { SubMenu } = Menu; -class HeaderAppBar extends Component { - handleClick = e => { - console.log("click ", e); - this.setState({ - current: e.key - }); - }; - - render() { - const { selectedNavItem, navItems } = this.props; - return ( - - { - navItems.map(navItem => ( - {navItem.title} - )) - } - - - // - // - // Navigation One - // - // - // - // Navigation Two - // - // - // - // Navigation Three - Submenu - // - // } - // > - // - // Option 1 - // Option 2 - // - // - // Option 3 - // Option 4 - // - // - // - // - // Navigation Four - Link - // - // - // - ); - } -} - -export default HeaderAppBar; diff --git a/client/src/components/header-app-bar/header-app-bar.container.jsx b/client/src/components/header-app-bar/header-app-bar.container.jsx deleted file mode 100644 index 20e2eac0d..000000000 --- a/client/src/components/header-app-bar/header-app-bar.container.jsx +++ /dev/null @@ -1,44 +0,0 @@ -import React from "react"; -import { Query } from "react-apollo"; -import { gql } from "apollo-boost"; - -import { Spin, Alert } from "antd"; -import HeaderAppBar from "./header-app-bar.component"; - -const GET_NAV_ITEMS = gql` - query nav_items { - masterdata_by_pk(key: "NAV_ITEMS") { - value - } - } -`; - -const GET_SELECTED_NAV_ITEM = gql` - query selected_nav_item { - selectedNavItem @client - } -`; - -const HeaderAppBarContainer = () => ( - - {({ loading, error, data: { selectedNavItem } }) => { - return ( - - {({ loading, error, data }) => { - if (loading) return ; - if (error) return ; - const parsedNavItems = JSON.parse(data.masterdata_by_pk.value) - return ( - - ); - }} - - ); - }} - -); - -export default HeaderAppBarContainer; diff --git a/client/src/components/header/header.component.jsx b/client/src/components/header/header.component.jsx new file mode 100644 index 000000000..f5d6f2639 --- /dev/null +++ b/client/src/components/header/header.component.jsx @@ -0,0 +1,36 @@ +import React, { Component } from "react"; +import { Link } from "react-router-dom"; +import { Menu, Icon } from "antd"; +import "./header.styles.scss"; + +class Header extends Component { + handleClick = e => { + console.log("click ", e); + this.setState({ + current: e.key + }); + }; + + render() { + const { selectedNavItem, navItems } = this.props; + return ( + + {navItems.map(navItem => ( + + + + {navItem.title} + + + ))} + + ); + } +} + +export default Header; diff --git a/client/src/components/header/header.container.jsx b/client/src/components/header/header.container.jsx new file mode 100644 index 000000000..15ea85aa1 --- /dev/null +++ b/client/src/components/header/header.container.jsx @@ -0,0 +1,43 @@ +import React from "react"; +import { Query } from "react-apollo"; + +import { Alert } from "antd"; +import Header from "./header.component"; + +import Spin from "../loading-spinner/loading-spinner.component"; + +import { + GET_SELECTED_NAV_ITEM, + GET_LANDING_NAV_ITEMS, + GET_NAV_ITEMS +} from "../../graphql/metadata.queries"; + +const HeaderContainer = ({ landingHeader }) => { + let GET_METADATA; + if (landingHeader) GET_METADATA = GET_LANDING_NAV_ITEMS; + else GET_METADATA = GET_NAV_ITEMS; + + return ( + + {({ loading, error, data: { selectedNavItem } }) => { + return ( + + {({ loading, error, data }) => { + if (loading) return ; + if (error) return ; + const parsedNavItems = JSON.parse(data.masterdata_by_pk.value); + return ( +
+ ); + }} + + ); + }} + + ); +}; + +export default HeaderContainer; diff --git a/client/src/components/header/header.styles.scss b/client/src/components/header/header.styles.scss new file mode 100644 index 000000000..3766e1b90 --- /dev/null +++ b/client/src/components/header/header.styles.scss @@ -0,0 +1,4 @@ +.header{ + text-align: center; + width: 100%; +} \ No newline at end of file diff --git a/client/src/components/job-list/job-list.container.jsx b/client/src/components/job-list/job-list.container.jsx index 2381db3eb..d934e2e70 100644 --- a/client/src/components/job-list/job-list.container.jsx +++ b/client/src/components/job-list/job-list.container.jsx @@ -2,8 +2,9 @@ import React from "react"; import { Query } from "react-apollo"; import { gql } from "apollo-boost"; -import { Spin, Alert } from "antd"; +import { Alert } from "antd"; +import Spin from '../loading-spinner/loading-spinner.component' import JobList from "./job-list.component"; const GET_JOBS = gql` @@ -17,7 +18,7 @@ const GET_JOBS = gql` const JobListContainer = () => ( {({ loading, error, data }) => { - if (loading) return ; + if (loading) return ; if (error) return ; console.log("JobListContainer Data:", data); diff --git a/client/src/components/sign-in/sign-in.component.jsx b/client/src/components/landing-components/sign-in/sign-in.component.jsx similarity index 97% rename from client/src/components/sign-in/sign-in.component.jsx rename to client/src/components/landing-components/sign-in/sign-in.component.jsx index 4f7fde558..9269fadac 100644 --- a/client/src/components/sign-in/sign-in.component.jsx +++ b/client/src/components/landing-components/sign-in/sign-in.component.jsx @@ -1,5 +1,5 @@ import React from "react"; -import { auth } from "../../firebase/firebase.utils"; +import { auth } from "../../../firebase/firebase.utils"; import { Form, Icon, Input, Button, Alert } from "antd"; class SignIn extends React.Component { diff --git a/client/src/components/loading-spinner/loading-spinner.component.jsx b/client/src/components/loading-spinner/loading-spinner.component.jsx new file mode 100644 index 000000000..03b0b89ee --- /dev/null +++ b/client/src/components/loading-spinner/loading-spinner.component.jsx @@ -0,0 +1,7 @@ +import React from "react"; +import { Spin } from "antd"; +import "./loading-spinner.styles.scss"; + +export default function LoadingSpinner() { + return ; +} diff --git a/client/src/components/loading-spinner/loading-spinner.styles.scss b/client/src/components/loading-spinner/loading-spinner.styles.scss new file mode 100644 index 000000000..220a92cc1 --- /dev/null +++ b/client/src/components/loading-spinner/loading-spinner.styles.scss @@ -0,0 +1,3 @@ +.spinner { + text-align: center; +} diff --git a/client/src/components/manage-shop/manage-shop.component.jsx b/client/src/components/manage-shop/manage-shop.component.jsx new file mode 100644 index 000000000..a4a488f9f --- /dev/null +++ b/client/src/components/manage-shop/manage-shop.component.jsx @@ -0,0 +1,10 @@ +import React from "react"; + +export default function ManageShop() { + return ( +
+ + This is the manage shop component. +
+ ); +} diff --git a/client/src/components/manage-shop/manage-shop.container.jsx b/client/src/components/manage-shop/manage-shop.container.jsx new file mode 100644 index 000000000..879b4ded1 --- /dev/null +++ b/client/src/components/manage-shop/manage-shop.container.jsx @@ -0,0 +1,27 @@ +import React from "react"; +import { Query } from "react-apollo"; +import { gql } from "apollo-boost"; + +import { Alert } from "antd"; +import Spin from '../loading-spinner/loading-spinner.component' +import ManageShop from "./manage-shop.component"; + +const GET_NAV_ITEMS = gql` + query nav_items { + masterdata_by_pk(key: "NAV_ITEMS") { + value + } + } +`; + +const ManageShopContainer = () => ( + + {({ loading, error, data }) => { + if (loading) return ; + if (error) return ; + return ; + }} + +); + +export default ManageShopContainer; diff --git a/client/src/components/sign-out/sign-out.component.jsx b/client/src/components/sign-out/sign-out.component.jsx new file mode 100644 index 000000000..55e239762 --- /dev/null +++ b/client/src/components/sign-out/sign-out.component.jsx @@ -0,0 +1,11 @@ +import React, { useState } from 'react' + +export default function SignOut() { + + + return ( +
+ Sign Out +
+ ) +} diff --git a/client/src/graphql/initial-state.js b/client/src/graphql/initial-state.js index 3048f3ca2..23b6fb4d8 100644 --- a/client/src/graphql/initial-state.js +++ b/client/src/graphql/initial-state.js @@ -1,3 +1,5 @@ export default { + authState: null, selectedNavItem: "Home", + recentItems: [] }; diff --git a/client/src/graphql/metadata.queries.js b/client/src/graphql/metadata.queries.js new file mode 100644 index 000000000..940210b5b --- /dev/null +++ b/client/src/graphql/metadata.queries.js @@ -0,0 +1,22 @@ +import { gql } from "apollo-boost"; + +export const GET_LANDING_NAV_ITEMS = gql` + query nav_items { + masterdata_by_pk(key: "LANDING_NAV_ITEMS") { + value + } + } +`; +export const GET_NAV_ITEMS = gql` + query nav_items { + masterdata_by_pk(key: "NAV_ITEMS") { + value + } + } +`; + +export const GET_SELECTED_NAV_ITEM = gql` + query selected_nav_item { + selectedNavItem @client + } +`; diff --git a/client/src/pages/landing/landing.component.jsx b/client/src/pages/landing/landing.component.jsx new file mode 100644 index 000000000..957d31277 --- /dev/null +++ b/client/src/pages/landing/landing.component.jsx @@ -0,0 +1,15 @@ +import React from "react"; +import { Typography } from "antd"; + +import HeaderContainer from "../../components/header/header.container"; + +export default function LandingPage() { + return ( +
+ + + Welcome to bodyshop.app. + +
+ ); +} diff --git a/client/src/pages/manage/manage.component.jsx b/client/src/pages/manage/manage.component.jsx new file mode 100644 index 000000000..f94a4ee73 --- /dev/null +++ b/client/src/pages/manage/manage.component.jsx @@ -0,0 +1,16 @@ +import React from 'react' +import { Route } from "react-router"; + +//Component Imports +import ManageShopContainer from '../../components/manage-shop/manage-shop.container'; + + +//This page will handle all routing for the entire application. +export default function Manage({match}) { + console.log('Manage: match ', match) + return ( +
+ +
+ ) +} diff --git a/client/src/utils/private-route.js b/client/src/utils/private-route.js new file mode 100644 index 000000000..2ee406d81 --- /dev/null +++ b/client/src/utils/private-route.js @@ -0,0 +1,14 @@ +import React from "react"; +import { Route, Redirect } from "react-router-dom"; +export default ({ component: Component, isAuthorized, ...rest }) => ( + + isAuthorized === true ? ( + + ) : ( + + ) + } + /> +);