diff --git a/src/components/LoadingIndicator/index.jsx b/src/components/LoadingIndicator/index.jsx index a5f70dd1..96faef90 100644 --- a/src/components/LoadingIndicator/index.jsx +++ b/src/components/LoadingIndicator/index.jsx @@ -4,17 +4,20 @@ * Optionally shows error. */ import React from "react"; +import _ from "lodash"; import PT from "prop-types"; import "./styles.module.scss"; const LoadingIndicator = ({ error }) => { return ( -
{!error ? "Loading..." : error}
+
+ {!error ? "Loading..." : _.get(error, "response.data.message") || error} +
); }; LoadingIndicator.propTypes = { - error: PT.string, + error: PT.object, }; export default LoadingIndicator; diff --git a/src/hoc/withAuthentication.js b/src/hoc/withAuthentication.js new file mode 100644 index 00000000..0385666b --- /dev/null +++ b/src/hoc/withAuthentication.js @@ -0,0 +1,42 @@ +/** + * Authentication + * + * wrap component for authentication + */ +import React, { useCallback, useState, useEffect } from "react"; +import { getAuthUserTokens, login } from "@topcoder/micro-frontends-navbar-app"; +import LoadingIndicator from "../components/LoadingIndicator"; + +export default function withAuthentication(Component) { + const AuthenticatedComponent = (props) => { + let [isLoggedIn, setIsLoggedIn] = useState(null); + let [authError, setAuthError] = useState(false); + + useEffect(() => { + if (props.auth) { + getAuthUserTokens() + .then(({ tokenV3 }) => { + if (!!tokenV3) { + setIsLoggedIn(!!tokenV3); + } else { + login(); + } + }) + .catch((err) => { + setAuthError(err); + }); + } + }, [props.auth]); + + return ( + <> + {authError && } + {!props.auth || (props.auth && isLoggedIn === true) ? ( + + ) : null} + + ); + }; + + return AuthenticatedComponent; +} diff --git a/src/root.component.jsx b/src/root.component.jsx index dd6bd948..6ae1658e 100644 --- a/src/root.component.jsx +++ b/src/root.component.jsx @@ -4,19 +4,22 @@ import { Router } from "@reach/router"; import MyTeamsList from "./routes/MyTeamsList"; import MyTeamsDetails from "./routes/MyTeamsDetails"; import PositionDetails from "./routes/PositionDetails"; -import ReduxToastr from 'react-redux-toastr' +import ReduxToastr from "react-redux-toastr"; import store from "./store"; import "./styles/main.vendor.scss"; import styles from "./styles/main.module.scss"; export default function Root() { return ( -
+
- - - + + + {/* Global config for Toastr popups */} diff --git a/src/routes/MyTeamsDetails/index.jsx b/src/routes/MyTeamsDetails/index.jsx index 2f0d5c75..c8e258d1 100644 --- a/src/routes/MyTeamsDetails/index.jsx +++ b/src/routes/MyTeamsDetails/index.jsx @@ -14,6 +14,7 @@ import LoadingIndicator from "components/LoadingIndicator"; import TeamSummary from "./components/TeamSummary"; import TeamMembers from "./components/TeamMembers"; import TeamPositions from "./components/TeamPositions"; +import withAuthentication from "../../hoc/withAuthentication"; import { useAsync } from "react-use"; const MyTeamsDetails = ({ teamId }) => { @@ -22,7 +23,7 @@ const MyTeamsDetails = ({ teamId }) => { return ( {!team ? ( - + ) : ( <> @@ -39,4 +40,4 @@ MyTeamsDetails.propTypes = { teamId: PT.string, }; -export default MyTeamsDetails; +export default withAuthentication(MyTeamsDetails); diff --git a/src/routes/MyTeamsList/index.jsx b/src/routes/MyTeamsList/index.jsx index 8db13129..afc92e73 100644 --- a/src/routes/MyTeamsList/index.jsx +++ b/src/routes/MyTeamsList/index.jsx @@ -13,6 +13,7 @@ import { getMyTeams } from "../../services/teams"; import TeamCard from "./components/TeamCard"; import TeamCardGrid from "./components/TeamCardGrid"; import LoadingIndicator from "../../components/LoadingIndicator"; +import withAuthentication from "../../hoc/withAuthentication"; import { useDebounce } from "react-use"; import { TEAMS_PER_PAGE } from "constants"; import "./styles.module.scss"; @@ -74,7 +75,7 @@ const MyTeamsList = () => {
No teams found
)} {!myTeams ? ( - + ) : ( <> @@ -98,4 +99,4 @@ const MyTeamsList = () => { ); }; -export default MyTeamsList; +export default withAuthentication(MyTeamsList); diff --git a/src/routes/PositionDetails/index.jsx b/src/routes/PositionDetails/index.jsx index 4c30df09..cb9d3ae6 100644 --- a/src/routes/PositionDetails/index.jsx +++ b/src/routes/PositionDetails/index.jsx @@ -9,6 +9,7 @@ import LayoutContainer from "components/LayoutContainer"; import LoadingIndicator from "components/LoadingIndicator"; import PageHeader from "components/PageHeader"; import { CANDIDATE_STATUS } from "constants"; +import withAuthentication from "../../hoc/withAuthentication"; import PositionCandidates from "./components/PositionCandidates"; import CandidatesStatusFilter from "./components/CandidatesStatusFilter"; import { useTeamPositionsState } from "./hooks/useTeamPositionsState"; @@ -61,4 +62,4 @@ PositionDetails.propTypes = { positionId: PT.string, }; -export default PositionDetails; +export default withAuthentication(PositionDetails);