diff --git a/src/assets/images/icon-role-fallback-old.svg b/src/assets/images/icon-role-fallback-old.svg new file mode 100644 index 00000000..9e0f1123 --- /dev/null +++ b/src/assets/images/icon-role-fallback-old.svg @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/assets/images/icon-role-fallback.svg b/src/assets/images/icon-role-fallback.svg index 9e0f1123..d285b7e6 100644 --- a/src/assets/images/icon-role-fallback.svg +++ b/src/assets/images/icon-role-fallback.svg @@ -1,17 +1,23 @@ - - - - - - - - - - - - - - - + + + + Layer 1 + + + + + + + + + + + + + + - \ No newline at end of file + + + + diff --git a/src/routes/CreateNewTeam/actions/index.js b/src/routes/CreateNewTeam/actions/index.js index 99106fc4..bb78565f 100644 --- a/src/routes/CreateNewTeam/actions/index.js +++ b/src/routes/CreateNewTeam/actions/index.js @@ -1,15 +1,23 @@ import { ACTION_TYPE } from "constants"; -export const clearSearchedRoles = () => ({ +const updateLocalStorage = (state) => { + try { + localStorage.setItem("rolesState", JSON.stringify(state)); + } catch { + console.error("Unable to set localStorage"); + } +}; + +const clearRoles = () => ({ type: ACTION_TYPE.CLEAR_SEARCHED_ROLES, }); -export const addSearchedRole = (searchedRole) => ({ +const addRole = (searchedRole) => ({ type: ACTION_TYPE.ADD_SEARCHED_ROLE, payload: searchedRole, }); -export const addRoleSearchId = (id) => ({ +const addPreviousSearchId = (id) => ({ type: ACTION_TYPE.ADD_ROLE_SEARCH_ID, payload: id, }); @@ -18,3 +26,18 @@ export const replaceSearchedRoles = (roles) => ({ type: ACTION_TYPE.REPLACE_SEARCHED_ROLES, payload: { roles, lastRoleId: roles[roles.length - 1].searchId }, }); + +export const clearSearchedRoles = () => (dispatch, getState) => { + dispatch(clearRoles()); + updateLocalStorage(getState().searchedRoles); +}; + +export const addSearchedRole = (searchedRole) => (dispatch, getState) => { + dispatch(addRole(searchedRole)); + updateLocalStorage(getState().searchedRoles); +}; + +export const addRoleSearchId = (id) => (dispatch, getState) => { + dispatch(addPreviousSearchId(id)); + updateLocalStorage(getState().searchedRoles); +}; diff --git a/src/routes/CreateNewTeam/components/NoMatchingProfilesResultCard/index.jsx b/src/routes/CreateNewTeam/components/NoMatchingProfilesResultCard/index.jsx index 18940725..2b1fd779 100644 --- a/src/routes/CreateNewTeam/components/NoMatchingProfilesResultCard/index.jsx +++ b/src/routes/CreateNewTeam/components/NoMatchingProfilesResultCard/index.jsx @@ -28,7 +28,7 @@ function NoMatchingProfilesResultCard() {

$1,200

/Week

- + diff --git a/src/routes/CreateNewTeam/components/SearchAndSubmit/index.jsx b/src/routes/CreateNewTeam/components/SearchAndSubmit/index.jsx index 9f27e3ba..b801e2d1 100644 --- a/src/routes/CreateNewTeam/components/SearchAndSubmit/index.jsx +++ b/src/routes/CreateNewTeam/components/SearchAndSubmit/index.jsx @@ -1,13 +1,23 @@ import { Router } from "@reach/router"; import React from "react"; +import { useSelector } from "react-redux"; import SearchContainer from "../SearchContainer"; import SubmitContainer from "../SubmitContainer"; function SearchAndSubmit(props) { + const { addedRoles, previousSearchId } = useSelector( + (state) => state.searchedRoles + ); + return ( - - + + ); } diff --git a/src/routes/CreateNewTeam/components/SearchContainer/index.jsx b/src/routes/CreateNewTeam/components/SearchContainer/index.jsx index 4cf96c6f..8e91bc3b 100644 --- a/src/routes/CreateNewTeam/components/SearchContainer/index.jsx +++ b/src/routes/CreateNewTeam/components/SearchContainer/index.jsx @@ -8,7 +8,7 @@ import React, { useCallback, useState } from "react"; import PT from "prop-types"; import _ from "lodash"; -import { useDispatch, useSelector } from "react-redux"; +import { useDispatch } from "react-redux"; import AddedRolesAccordion from "../AddedRolesAccordion"; import Completeness from "../Completeness"; import SearchCard from "../SearchCard"; @@ -19,25 +19,6 @@ import { setCurrentStage } from "utils/helpers"; import { addRoleSearchId, addSearchedRole } from "../../actions"; import "./styles.module.scss"; -/** - * Converts an array of role search objects to two data - * lists which can be set as sessionStorage items - * - * @param {object[]} arrayOfObjects array of role objects - */ -const storeStrings = (arrayOfObjects) => { - const objectOfArrays = arrayOfObjects.reduce( - (acc, curr) => ({ - searchId: [...acc.searchId, curr.searchId], - name: [...acc.name, curr.name], - }), - { searchId: [], name: [] } - ); - - sessionStorage.setItem("searchIds", objectOfArrays.searchId.join(",")); - sessionStorage.setItem("roleNames", objectOfArrays.name.join(",")); -}; - function SearchContainer({ stages, setStages, @@ -45,24 +26,18 @@ function SearchContainer({ toRender, searchObject, completenessStyle, - reloadRolesPage, navigate, + addedRoles, + previousSearchId, }) { - const { addedRoles, previousSearchId } = useSelector( - (state) => state.searchedRoles - ); - const [searchState, setSearchState] = useState(null); const [matchingRole, setMatchingRole] = useState(null); - const [addAnotherModalOpen, setAddAnotherModalOpen] = useState(false); - const [submitDone, setSubmitDone] = useState(true); const dispatch = useDispatch(); const onSubmit = useCallback(() => { - storeStrings(addedRoles); navigate("result", { state: { matchingRole } }); - }, [addedRoles, navigate, matchingRole]); + }, [navigate, matchingRole]); const search = () => { setCurrentStage(1, stages, setStages); @@ -135,8 +110,9 @@ SearchContainer.propTypes = { searchObject: PT.object, toRender: PT.node, completenessStyle: PT.string, - reloadRolesPage: PT.func, navigate: PT.func, + addedRoles: PT.array, + previousSearchId: PT.string, }; export default SearchContainer; diff --git a/src/routes/CreateNewTeam/components/SubmitContainer/index.jsx b/src/routes/CreateNewTeam/components/SubmitContainer/index.jsx index a8223a29..55c493bb 100644 --- a/src/routes/CreateNewTeam/components/SubmitContainer/index.jsx +++ b/src/routes/CreateNewTeam/components/SubmitContainer/index.jsx @@ -4,9 +4,14 @@ * Requires authentication to complete submission process * and contains a series of popups to lead user through the flow. */ -import React, { useCallback, useEffect, useState } from "react"; +import React, { + useCallback, + useEffect, + useLayoutEffect, + useState, +} from "react"; import PT from "prop-types"; -import { useDispatch, useSelector } from "react-redux"; +import { useDispatch } from "react-redux"; import _ from "lodash"; import { toastr } from "react-redux-toastr"; import { navigate } from "@reach/router"; @@ -19,46 +24,19 @@ import ConfirmationModal from "../ConfirmationModal"; import withAuthentication from "../../../../hoc/withAuthentication"; import "./styles.module.scss"; import { setCurrentStage } from "utils/helpers"; -import { clearSearchedRoles, replaceSearchedRoles } from "../../actions"; +import { clearSearchedRoles } from "../../actions"; import { postTeamRequest } from "services/teams"; import SuccessCard from "../SuccessCard"; -const retrieveRoles = () => { - const searchIdString = sessionStorage.getItem("searchIds"); - const nameString = sessionStorage.getItem("roleNames"); - - if (!searchIdString || !nameString) return []; - const searchIds = searchIdString.split(","); - const names = nameString.split(","); - if (searchIds.length !== names.length) return []; - - const roles = []; - for (let i = 0; i < searchIds.length; i++) { - roles.push({ - searchId: searchIds[i], - name: names[i], - }); - } - - return roles; -}; - -const clearSessionKeys = () => { - sessionStorage.removeItem("searchIds"); - sessionStorage.removeItem("roleNames"); -}; - function SubmitContainer({ stages, setStages, completenessStyle, - reloadRolesPage, location, + addedRoles, }) { const matchingRole = location?.state?.matchingRole; - const { addedRoles } = useSelector((state) => state.searchedRoles); - const [addAnotherOpen, setAddAnotherOpen] = useState(true); const [teamDetailsOpen, setTeamDetailsOpen] = useState(false); const [teamObject, setTeamObject] = useState(null); @@ -68,11 +46,17 @@ function SubmitContainer({ useEffect(() => { setCurrentStage(2, stages, setStages); - const storedRoles = retrieveRoles(); - if (storedRoles) { - if (!addedRoles || storedRoles.length > addedRoles.length) { - dispatch(replaceSearchedRoles(storedRoles)); - } + if (!addedRoles || addedRoles.length === 0) { + navigate("/taas/myteams/createnewteam"); + } + // eslint-disable-next-line react-hooks/exhaustive-deps + }, []); + + // redirects user if they enter the page URL directly + // without adding any roles. + useLayoutEffect(() => { + if (!addedRoles || addedRoles.length === 0) { + navigate("/taas/myteams/createnewteam"); } // eslint-disable-next-line react-hooks/exhaustive-deps }, []); @@ -83,11 +67,7 @@ function SubmitContainer({ }; const addAnother = () => { - if (reloadRolesPage) { - setCurrentStage(0, stages, setStages); - reloadRolesPage(); - } - navigate("/taas/myteams/createnewteam/role"); + navigate("/taas/myteams/createnewteam"); }; const assembleTeam = (formData) => { @@ -121,7 +101,6 @@ function SubmitContainer({ postTeamRequest(teamObject) .then((res) => { const projectId = _.get(res, ["data", "projectId"]); - clearSessionKeys(); dispatch(clearSearchedRoles()); navigate(`/taas/myteams/${projectId}`); }) @@ -171,8 +150,8 @@ SubmitContainer.propTypes = { stages: PT.array, setStages: PT.func, completenessStyle: PT.string, - reloadRolesPage: PT.bool, location: PT.object, + addedRoles: PT.array, }; export default withAuthentication(SubmitContainer); diff --git a/src/routes/CreateNewTeam/components/SuccessCard/index.jsx b/src/routes/CreateNewTeam/components/SuccessCard/index.jsx index 1aa05fa8..ff2ee0da 100644 --- a/src/routes/CreateNewTeam/components/SuccessCard/index.jsx +++ b/src/routes/CreateNewTeam/components/SuccessCard/index.jsx @@ -30,7 +30,7 @@ function SuccessCard() { Please use the button to the right to submit your request, or the button below to search for additional roles.

- + diff --git a/src/routes/CreateNewTeam/index.jsx b/src/routes/CreateNewTeam/index.jsx index 4158b2f8..efd722e5 100644 --- a/src/routes/CreateNewTeam/index.jsx +++ b/src/routes/CreateNewTeam/index.jsx @@ -1,9 +1,6 @@ /** * Create New Team * - * Gets location state from router to pass - * along to search pages - * * Landing page for creating new teams * by selecting a role, inputting skills, * or inputting a job description @@ -11,25 +8,14 @@ import React, { useEffect } from "react"; import { navigate } from "@reach/router"; import _ from "lodash"; -import PT from "prop-types"; -import { useDispatch } from "react-redux"; import Page from "components/Page"; import PageHeader from "components/PageHeader"; import LandingBox from "./components/LandingBox"; import IconMultipleActionsCheck from "../../assets/images/icon-multiple-actions-check-2.svg"; import IconListQuill from "../../assets/images/icon-list-quill.svg"; import IconOfficeFileText from "../../assets/images/icon-office-file-text.svg"; -import { clearSearchedRoles } from "./actions"; - -function CreateNewTeam({ location: { state: locationState } }) { - const dispatch = useDispatch(); - - useEffect(() => { - if (!locationState || !locationState.keepAddedRoles) { - dispatch(clearSearchedRoles()); - } - }); +function CreateNewTeam() { const goToRoute = (path) => { navigate(path); }; @@ -65,8 +51,4 @@ function CreateNewTeam({ location: { state: locationState } }) { ); } -CreateNewTeam.propTypes = { - locationState: PT.object, -}; - export default CreateNewTeam; diff --git a/src/routes/CreateNewTeam/pages/InputSkills/components/SkillItem/index.jsx b/src/routes/CreateNewTeam/pages/InputSkills/components/SkillItem/index.jsx index ec94cea5..66a819e7 100644 --- a/src/routes/CreateNewTeam/pages/InputSkills/components/SkillItem/index.jsx +++ b/src/routes/CreateNewTeam/pages/InputSkills/components/SkillItem/index.jsx @@ -5,7 +5,7 @@ */ import React from "react"; import PT from "prop-types"; -import IconQuestionCircle from "../../../../../../assets/images/icon-question-circle.svg"; +import IconSkill from "../../../../../../assets/images/icon-skill.svg"; import "./styles.module.scss"; import cn from "classnames"; @@ -28,7 +28,7 @@ function SkillItem({ id, name, onClick, isSelected }) { styleName="image" /> ) : ( - + )}

{name}

diff --git a/src/routes/CreateNewTeam/pages/SelectRole/index.jsx b/src/routes/CreateNewTeam/pages/SelectRole/index.jsx index 5488b60b..7486b59e 100644 --- a/src/routes/CreateNewTeam/pages/SelectRole/index.jsx +++ b/src/routes/CreateNewTeam/pages/SelectRole/index.jsx @@ -33,12 +33,6 @@ function SelectRole() { setRoleDetailsModalOpen(true); }, []); - const resetState = () => { - setSelectedRoleId(null); - setRoleDetailsModalOpen(false); - setRoleDetailsModalId(null); - }; - if (!roles) { return ; } @@ -50,7 +44,6 @@ function SelectRole() { isCompletenessDisabled={!selectedRoleId} searchObject={{ roleId: selectedRoleId }} completenessStyle="role-selection" - reloadRolesPage={resetState} toRender={ <> { + const defaultState = { + previousSearchId: undefined, + addedRoles: [], + }; + try { + const state = localStorage.getItem("rolesState"); + if (state === null) { + return defaultState; + } + return JSON.parse(state); + } catch { + return defaultState; + } }; +const initialState = loadState(); + const reducer = (state = initialState, action) => { switch (action.type) { case ACTION_TYPE.CLEAR_SEARCHED_ROLES: