diff --git a/src/constants/index.js b/src/constants/index.js
index 34fd9c69..6eee3717 100644
--- a/src/constants/index.js
+++ b/src/constants/index.js
@@ -109,8 +109,8 @@ export const CANDIDATE_STATUS = {
REJECTED_OTHER: "rejected - other",
INTERVIEW: "interview",
TOPCODER_REJECTED: "topcoder-rejected",
- JOB_CLOSED:"job-closed",
- OFFERED:"offered"
+ JOB_CLOSED: "job-closed",
+ OFFERED: "offered",
};
/**
@@ -146,7 +146,7 @@ export const CANDIDATE_STATUS_FILTERS = [
buttonText: "Selected",
title: "Selected",
noCandidateMessage: "No Selected Candidates",
- statuses: [CANDIDATE_STATUS.SELECTED,CANDIDATE_STATUS.OFFERED],
+ statuses: [CANDIDATE_STATUS.SELECTED, CANDIDATE_STATUS.OFFERED],
},
{
key: CANDIDATE_STATUS_FILTER_KEY.NOT_INTERESTED,
@@ -347,3 +347,8 @@ export const INTERVIEW_POPUP_MEDIA_URL =
"http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4";
export const MAX_ALLOWED_INTERVIEWS = 3;
+
+/**
+ * Matching rate to show in CreateNewTeam ResultCard
+ */
+export const MATCHING_RATE = "80";
diff --git a/src/root.component.jsx b/src/root.component.jsx
index 797270ff..97b8bdcb 100644
--- a/src/root.component.jsx
+++ b/src/root.component.jsx
@@ -35,8 +35,8 @@ export default function Root() {
-
-
+
+
{/* Global config for Toastr popups */}
diff --git a/src/routes/CreateNewTeam/pages/SelectRole/components/AddedRolesAccordion/index.jsx b/src/routes/CreateNewTeam/components/AddedRolesAccordion/index.jsx
similarity index 96%
rename from src/routes/CreateNewTeam/pages/SelectRole/components/AddedRolesAccordion/index.jsx
rename to src/routes/CreateNewTeam/components/AddedRolesAccordion/index.jsx
index e09a64e3..2c1d9a6e 100644
--- a/src/routes/CreateNewTeam/pages/SelectRole/components/AddedRolesAccordion/index.jsx
+++ b/src/routes/CreateNewTeam/components/AddedRolesAccordion/index.jsx
@@ -13,7 +13,7 @@ import "./styles.module.scss";
function AddedRolesAccordion({ addedRoles }) {
const [isOpen, setIsOpen] = useState(false);
- return (
+ return addedRoles.length ? (
- {isLoading ? (
- <>
-
-
Loading...
- >
+
+
+ setShowSkills(false)}
+ >
+ Job Description
+
+ setShowSkills(true)}
+ >
+ Skills
+
+
+ {showSkills ? (
+
+ {skills.map((skill, i) => (
+
+ {skill}
+
+ ))}
+
) : (
- <>
- {role && role.imageUrl && !imgError ? (
-
setImgError(true)}
- alt={role.name}
- styleName="role-icon"
- />
- ) : (
-
- )}
-
- setShowSkills(false)}
- >
- Job Description
-
- setShowSkills(true)}
- >
- Skills
-
-
-
{role?.name}
-
{role?.description}
- >
+
+
+
)}
-
-
- Close
-
-
-
+
);
}
diff --git a/src/routes/CreateNewTeam/components/RoleDetailsModal/styles.module.scss b/src/routes/CreateNewTeam/components/RoleDetailsModal/styles.module.scss
index 81daa623..e7470ce5 100644
--- a/src/routes/CreateNewTeam/components/RoleDetailsModal/styles.module.scss
+++ b/src/routes/CreateNewTeam/components/RoleDetailsModal/styles.module.scss
@@ -1,55 +1,49 @@
@import "styles/include";
.button-group {
- display: flex;
- flex-direction: row;
- justify-content: center;
- align-items: flex-end;
- :first-child {
- margin-right: 8px;
- }
-}
-
-.tab-button-group {
display: flex;
flex-direction: row;
align-items: center;
justify-content: center;
- margin-bottom: 42px;
+ margin-bottom: 30px;
}
-.modal-body {
- display: flex;
- flex-direction: column;
- justify-content: flex-start;
- align-items: center;
- text-align: center;
- margin-bottom: 80px;
-
- .role-icon {
- width: 42px;
- height: 42px;
- }
-
- h5 {
- @include font-barlow-condensed;
- font-size: 34px;
- color: #1e94a3;
- text-transform: uppercase;
- font-weight: 500;
- margin-bottom: 10px;
- }
+.body {
+ @include font-roboto;
+ color: #2a2a2a;
+}
- p {
+.markdown-container {
+ // not adds specificity to override style
+ p:not(table) {
@include font-roboto;
+ color: #2a2a2a;
font-size: 16px;
- color: #555555;
line-height: 26px;
}
}
-.cross {
- g {
- stroke: #000;
- }
+.description-item {
+ font-size: 16px;
+ line-height: 26px;
+ margin-bottom: 10px;
+ list-style-type: disc;
+}
+
+.skill-list {
+ margin: 0 30px;
+ display: flex;
+ flex-direction: row;
+ align-items: flex-start;
+ justify-content: flex-start;
+ flex-wrap: wrap;
+}
+
+.skill-item {
+ background-color: #e9e9e9;
+ border-radius: 5px;
+ padding: 6px 9px;
+ margin-right: 6px;
+ margin-bottom: 10px;
+ font-size: 12px;
}
diff --git a/src/routes/CreateNewTeam/components/SearchContainer/index.jsx b/src/routes/CreateNewTeam/components/SearchContainer/index.jsx
new file mode 100644
index 00000000..7e8c2bb4
--- /dev/null
+++ b/src/routes/CreateNewTeam/components/SearchContainer/index.jsx
@@ -0,0 +1,176 @@
+/**
+ * SearchContainer
+ *
+ * A container component for the different
+ * search pages. Contains logic and supporting
+ * components for searching for roles.
+ */
+import React, { useCallback, useState } from "react";
+import PT from "prop-types";
+import { toastr } from "react-redux-toastr";
+import { navigate } from "@reach/router";
+import _ from "lodash";
+import AddedRolesAccordion from "../AddedRolesAccordion";
+import Completeness from "../Completeness";
+import SearchCard from "../SearchCard";
+import ResultCard from "../ResultCard";
+import NoMatchingProfilesResultCard from "../NoMatchingProfilesResultCard";
+import { createJob } from "services/jobs";
+import { postProject, searchRoles } from "services/teams";
+import { setCurrentStage } from "utils/helpers";
+import AddAnotherModal from "../AddAnotherModal";
+import "./styles.module.scss";
+
+function SearchContainer({
+ stages,
+ setStages,
+ isCompletenessDisabled,
+ children,
+ searchObject,
+ completenessStyle,
+ locationState,
+ reloadRolesPage,
+}) {
+ const [addedRoles, setAddedRoles] = useState(
+ locationState?.addedRoles ? locationState.addedRoles : []
+ );
+ const [searchState, setSearchState] = useState(null);
+ const [matchingRole, setMatchingRole] = useState(null);
+ const [addAnotherModalOpen, setAddAnotherModalOpen] = useState(false);
+ const [submitDone, setSubmitDone] = useState(true);
+ const [prevSearchId, setPrevSearchId] = useState(locationState?.prevSearchId);
+
+ const submitJob = () => {
+ setSubmitDone(false);
+ postProject()
+ .then((res) => {
+ const projectId = _.get(res, "data.id");
+
+ createJob({
+ projectId,
+ title: `job-${Date()}`,
+ skills: [],
+ roleIds: addedRoles.map((r) => r.id),
+ numPositions: 1,
+ })
+ .then(() => {
+ toastr.success("Job Submitted");
+ })
+ .catch((err) => {
+ console.error(err);
+ toastr.warning("Error Submitting Job");
+ });
+ })
+ .catch((err) => {
+ console.error(err);
+ toastr.warning("Error Creating Project");
+ })
+ .finally(() => {
+ setSubmitDone(true);
+ navigate("/taas/myteams");
+ });
+ };
+
+ const addAnother = () => {
+ if (!reloadRolesPage) {
+ navigate("/taas/myteams/createnewteam/role", {
+ state: { addedRoles, prevSearchId },
+ });
+ return;
+ }
+ setCurrentStage(0, stages, setStages);
+ setSearchState(null);
+ setMatchingRole(null);
+ setAddAnotherModalOpen(false);
+ reloadRolesPage();
+ };
+
+ const search = () => {
+ setCurrentStage(1, stages, setStages);
+ setSearchState("searching");
+ setMatchingRole(null);
+ const searchObjectCopy = { ...searchObject };
+ if (prevSearchId) {
+ searchObjectCopy.previousRoleSearchRequestId = prevSearchId;
+ }
+ searchRoles(searchObjectCopy)
+ .then((res) => {
+ const id = _.get(res, "data.id");
+ const name = _.get(res, "data.name");
+ setPrevSearchId(_.get(res, "data.roleSearchRequestId"));
+ if (name && !name.toLowerCase().includes("niche")) {
+ setMatchingRole(res.data);
+ setAddedRoles((addedRoles) => [...addedRoles, { id, name }]);
+ }
+ })
+ .catch((err) => {
+ console.error(err);
+ })
+ .finally(() => {
+ setCurrentStage(2, stages, setStages);
+ setSearchState("done");
+ });
+ };
+
+ const renderLeftSide = () => {
+ if (!searchState) return children;
+ if (searchState === "searching") return
;
+ if (matchingRole) return
;
+ return (
+
+ );
+ };
+
+ const getPercentage = useCallback(() => {
+ if (!searchState) return "26";
+ if (searchState === "searching") return "52";
+ if (matchingRole) return "98";
+ return "88";
+ }, [searchState, matchingRole]);
+
+ return (
+
+ {renderLeftSide()}
+
+
+
setAddAnotherModalOpen(true) : search}
+ extraStyleName={completenessStyle}
+ buttonLabel={searchState ? "Submit Request" : "Search"}
+ stages={stages}
+ percentage={getPercentage()}
+ />
+
+ {searchState === "done" && matchingRole && (
+
setAddAnotherModalOpen(false)}
+ submitDone={submitDone}
+ onContinueClick={submitJob}
+ addAnother={addAnother}
+ />
+ )}
+
+ );
+}
+
+SearchContainer.propTypes = {
+ stages: PT.array,
+ setStages: PT.func,
+ isCompletenessDisabled: PT.bool,
+ searchObject: PT.object,
+ children: PT.node,
+ completenessStyle: PT.string,
+ locationState: PT.object,
+ reloadRolesPage: PT.func,
+};
+
+export default SearchContainer;
diff --git a/src/routes/CreateNewTeam/pages/SelectRole/styles.module.scss b/src/routes/CreateNewTeam/components/SearchContainer/styles.module.scss
similarity index 99%
rename from src/routes/CreateNewTeam/pages/SelectRole/styles.module.scss
rename to src/routes/CreateNewTeam/components/SearchContainer/styles.module.scss
index 7bacc294..99cec905 100644
--- a/src/routes/CreateNewTeam/pages/SelectRole/styles.module.scss
+++ b/src/routes/CreateNewTeam/components/SearchContainer/styles.module.scss
@@ -11,4 +11,4 @@
margin-top: 16px;
}
}
-}
+}
\ No newline at end of file
diff --git a/src/routes/CreateNewTeam/index.jsx b/src/routes/CreateNewTeam/index.jsx
index 62fd1826..34eab93e 100644
--- a/src/routes/CreateNewTeam/index.jsx
+++ b/src/routes/CreateNewTeam/index.jsx
@@ -1,5 +1,9 @@
/**
* 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
@@ -7,31 +11,20 @@
import React from "react";
import { navigate } from "@reach/router";
import _ from "lodash";
-import { toastr } from "react-redux-toastr";
+import PT from "prop-types";
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 { postProject } from "services/teams";
-import withAuthentication from "../../hoc/withAuthentication";
-function CreateNewTeam() {
- const createProjectAndNavigate = async (navigateTo) => {
- postProject()
- .then((res) => {
- const id = _.get(res, "data.id");
- navigate(`/taas/myteams/createnewteam/${id}/${navigateTo}`);
- })
- .catch((err) => {
- toastr.warning("Error", "Failed to create a new team.");
- console.error(err);
- });
- };
+function CreateNewTeam({ location: { state: locationState } }) {
+ const prevSearchId = locationState?.prevSearchId;
+ const addedRoles = locationState?.addedRoles;
- const goToJobDescription = () => {
- navigate(`/taas/myteams/createnewteam/jd`);
+ const goToRoute = (path) => {
+ navigate(path, { state: { prevSearchId, addedRoles } });
};
return (
@@ -45,24 +38,28 @@ function CreateNewTeam() {
description="You know you want a front end developer, or a full stack developer, mobile one or others."
icon={
}
backgroundImage="linear-gradient(101.95deg, #8B41B0 0%, #EF476F 100%)"
- onClick={() => createProjectAndNavigate("role")}
+ onClick={() => goToRoute("/taas/myteams/createnewteam/role")}
/>
}
backgroundImage="linear-gradient(221.5deg, #2C95D7 0%, #9D41C9 100%)"
- onClick={() => createProjectAndNavigate("skills")}
+ onClick={() => goToRoute("/taas/myteams/createnewteam/skills")}
/>
}
backgroundImage="linear-gradient(135deg, #2984BD 0%, #0AB88A 100%)"
- onClick={goToJobDescription}
+ onClick={() => goToRoute("/taas/myteams/createnewteam/jd")}
/>
);
}
-export default withAuthentication(CreateNewTeam);
+CreateNewTeam.propTypes = {
+ locationState: PT.object,
+};
+
+export default CreateNewTeam;
diff --git a/src/routes/CreateNewTeam/pages/InputJobDescription/index.jsx b/src/routes/CreateNewTeam/pages/InputJobDescription/index.jsx
index f6bbc2de..6182c9a7 100644
--- a/src/routes/CreateNewTeam/pages/InputJobDescription/index.jsx
+++ b/src/routes/CreateNewTeam/pages/InputJobDescription/index.jsx
@@ -1,150 +1,56 @@
/**
* Input Job Description page
*
+ * Gets location state from router
+ *
+ * Allows user to search for roles by
+ * job description
*/
-import React, { useCallback, useEffect, useState } from "react";
-import { useData } from "hooks/useData";
-import { navigate } from "@reach/router";
-import { toastr } from "react-redux-toastr";
-import { setCurrentStage } from "utils/helpers";
-import Page from "components/Page";
+import React, { useCallback, useState } from "react";
import PT from "prop-types";
import PageHeader from "components/PageHeader";
-import LoadingIndicator from "components/LoadingIndicator";
import MarkdownEditor from "../../../../components/MarkdownEditor";
-import { getSkillsByJobDescription } from "../../../../services/teams";
-import Completeness from "../../components/Completeness";
-import { getSkills } from "services/skills";
-import SearchCard from "../../components/SearchCard";
-import ResultCard from "../../components/ResultCard";
-import AddAnotherModal from "../../components/AddAnotherModal";
-import SkillListPopup from "./components/SkillListPopup";
import "./styles.module.scss";
-import withAuthentication from "../../../../hoc/withAuthentication";
-import IconOfficeFileText from "../../../../assets/images/icon-office-file-text.svg";
+import SearchContainer from "../../components/SearchContainer";
-function InputJobDescription() {
+function InputJobDescription({ location: { state: locationState } }) {
const [stages, setStages] = useState([
- { name: "Input Job Desccription", isCurrent: true },
+ { name: "Input Job Description", isCurrent: true },
{ name: "Search Member" },
{ name: "Overview of the Results" },
]);
const [jdString, setJdString] = useState("");
- const [searchState, setSearchState] = useState(null);
- const [modalOpen, setModalOpen] = useState(false);
- const [skillModalOpen, setSkillModalOpen] = useState(false);
- const [submitDone, setSubmitDone] = useState(false);
- const [skills, setSkills] = useState([]);
- const [isLoadingSkills, setIsLoadingSkills] = useState(false);
-
- const onSearch = useCallback(
- (value) => {
- setSkillModalOpen(true);
- setIsLoadingSkills(true);
- getSkillsByJobDescription(jdString)
- .then((response) => {
- setSkills(response.data);
- setIsLoadingSkills(false);
- setSkillModalOpen(true);
- })
- .catch(() => {
- setIsLoadingSkills(false);
- });
- },
- [jdString]
- );
-
- const onConfirationClick = useCallback(() => {
- setSearchState("searching");
- setCurrentStage(1, stages, setStages);
- setTimeout(() => {
- setCurrentStage(2, stages, setStages);
- setSearchState("done");
- }, 3000);
- }, []);
-
- const addAnother = useCallback(() => {
- // navigate(`/taas/myteams/createnewteam/${projectId}/role`);
- }, []);
-
- const submitJob = () => {
- setSubmitDone(false);
- setModalOpen(true);
- setTimeout(() => {
- setSubmitDone(true);
- }, 3000);
- };
const onEditChange = useCallback((value) => {
setJdString(value);
}, []);
return (
-
- {!searchState ? (
-
-
-
-
setSkillModalOpen(false)}
- isLoading={isLoadingSkills}
- onContinueClick={onConfirationClick}
- />
-
- ) : searchState === "searching" ? (
-
-
-
-
- ) : (
-
-
-
-
setModalOpen(false)}
- submitDone={submitDone}
- addAnother={addAnother}
- />
-
- )}
-
+
+
+
);
}
InputJobDescription.propTypes = {
- projectId: PT.string,
+ locationState: PT.object,
};
-export default withAuthentication(InputJobDescription);
+export default InputJobDescription;
diff --git a/src/routes/CreateNewTeam/pages/InputJobDescription/styles.module.scss b/src/routes/CreateNewTeam/pages/InputJobDescription/styles.module.scss
index 31e3ca4b..9fe69610 100644
--- a/src/routes/CreateNewTeam/pages/InputJobDescription/styles.module.scss
+++ b/src/routes/CreateNewTeam/pages/InputJobDescription/styles.module.scss
@@ -1,17 +1,9 @@
-.page {
- display: flex;
- flex-direction: row;
- justify-content: center;
- align-items: flex-start;
- margin: 42px 35px;
-
- .edit-container {
- background-color: #ffffff;
- border-radius: 8px;
- max-width: 746px;
- position: relative;
- margin-right: 30px;
- padding: 0 30px 30px;
- flex: 1;
- }
+.edit-container {
+ background-color: #ffffff;
+ border-radius: 8px;
+ max-width: 746px;
+ position: relative;
+ margin-right: 30px;
+ padding: 0 30px 30px;
+ flex: 1;
}
diff --git a/src/routes/CreateNewTeam/pages/InputSkills/components/SkillItem/styles.module.scss b/src/routes/CreateNewTeam/pages/InputSkills/components/SkillItem/styles.module.scss
index ecc6b566..8d3c180a 100644
--- a/src/routes/CreateNewTeam/pages/InputSkills/components/SkillItem/styles.module.scss
+++ b/src/routes/CreateNewTeam/pages/InputSkills/components/SkillItem/styles.module.scss
@@ -9,11 +9,14 @@
align-items: center;
margin: 0 0 24px 24px;
cursor: pointer;
+ color: #555;
+ font-weight: 500;
&.selected {
border-color: #0ab88a;
background-color: #e0faf3;
font-weight: 500;
+ color: #2a2a2a;
}
}
diff --git a/src/routes/CreateNewTeam/pages/InputSkills/components/SkillsList/styles.module.scss b/src/routes/CreateNewTeam/pages/InputSkills/components/SkillsList/styles.module.scss
index 15b6fbce..452f06f1 100644
--- a/src/routes/CreateNewTeam/pages/InputSkills/components/SkillsList/styles.module.scss
+++ b/src/routes/CreateNewTeam/pages/InputSkills/components/SkillsList/styles.module.scss
@@ -22,6 +22,8 @@
// adding "input:not([type="checkbox"])" to make sure that we override reset styles
input:not([type="checkbox"]).filter-input {
+ display: inline-block;
+ position: relative;
width: 300px;
background-color: #ffffff;
border: 1px solid #aaaaaa;
@@ -34,6 +36,13 @@ input:not([type="checkbox"]).filter-input {
outline: none;
padding: 0 15px;
+ &:not(:focus) {
+ background-image: url("../../../../../../assets/images/icon-search.svg");
+ background-repeat: no-repeat;
+ background-position: 10px center;
+ text-indent: 20px;
+ }
+
&::placeholder {
color: #aaaaaa;
}
diff --git a/src/routes/CreateNewTeam/pages/InputSkills/index.jsx b/src/routes/CreateNewTeam/pages/InputSkills/index.jsx
index 9341e86b..f105df60 100644
--- a/src/routes/CreateNewTeam/pages/InputSkills/index.jsx
+++ b/src/routes/CreateNewTeam/pages/InputSkills/index.jsx
@@ -2,68 +2,29 @@
* Input Skills page
* Page that user reaches after choosing to input job skills.
*
- * Gets a project id from the router.
+ * Gets location state from the router.
*
* Allows selecting a number of skills, searching for users
* with those skills, and submitting a job requiring the skills.
*/
-import React, { useCallback, useEffect, useState } from "react";
-import { useData } from "hooks/useData";
-import { navigate } from "@reach/router";
-import { toastr } from "react-redux-toastr";
+import React, { useCallback, useState } from "react";
import PT from "prop-types";
+import { useData } from "hooks/useData";
import SkillsList from "./components/SkillsList";
-import Completeness from "../../components/Completeness";
-import "./styles.module.scss";
import { getSkills } from "services/skills";
-import { setCurrentStage } from "utils/helpers";
import LoadingIndicator from "components/LoadingIndicator";
-import SearchCard from "../../components/SearchCard";
-import ResultCard from "../../components/ResultCard";
-import { createJob } from "services/jobs";
-import AddAnotherModal from "../../components/AddAnotherModal";
-import withAuthentication from "../../../../hoc/withAuthentication";
+import SearchContainer from "../../components/SearchContainer";
-function InputSkills({ projectId }) {
+function InputSkills({ location: { state: locationState } }) {
const [stages, setStages] = useState([
{ name: "Input Skills", isCurrent: true },
{ name: "Search Member" },
{ name: "Overview of the Results" },
]);
const [selectedSkills, setSelectedSkills] = useState([]);
- const [searchState, setSearchState] = useState(null);
- const [modalOpen, setModalOpen] = useState(false);
- const [submitDone, setSubmitDone] = useState(false);
const [skills, loadingError] = useData(getSkills);
- let searchTimer;
-
- const submitJob = () => {
- setSubmitDone(false);
- setModalOpen(true);
- createJob({
- projectId,
- title: `job-${Date()}`,
- skills: selectedSkills,
- numPositions: 1,
- })
- .then(() => {
- toastr.success("Job Submitted");
- })
- .catch((err) => {
- console.error(err);
- toastr.warning("Error Submitting Job");
- })
- .finally(() => {
- setSubmitDone(true);
- });
- };
-
- const addAnother = useCallback(() => {
- navigate(`/taas/myteams/createnewteam/${projectId}/roles`);
- }, [projectId]);
-
const toggleSkill = useCallback(
(id) => {
if (selectedSkills.includes(id)) {
@@ -77,69 +38,34 @@ function InputSkills({ projectId }) {
[selectedSkills]
);
- // mocked search for users with given skills
- const search = () => {
- setSearchState("searching");
- setCurrentStage(1, stages, setStages);
- searchTimer = setTimeout(() => {
- setSearchState("done");
- setCurrentStage(2, stages, setStages);
- }, 3000);
- };
+ if (!Array.isArray(skills)) {
+ return
;
+ }
- useEffect(() => clearTimeout(searchTimer));
+ if (skills.length === 0) {
+ return
Failed to load skills
;
+ }
- return !skills ? (
-
- ) : !searchState ? (
-
+ return (
+
-
-
- ) : searchState === "searching" ? (
-
-
-
-
- ) : (
-
-
-
-
setModalOpen(false)}
- submitDone={submitDone}
- addAnother={addAnother}
- />
-
+
);
}
InputSkills.propTypes = {
- projectId: PT.string,
+ locationState: PT.object,
};
-export default withAuthentication(InputSkills);
+export default InputSkills;
diff --git a/src/routes/CreateNewTeam/pages/InputSkills/styles.module.scss b/src/routes/CreateNewTeam/pages/InputSkills/styles.module.scss
deleted file mode 100644
index b47da072..00000000
--- a/src/routes/CreateNewTeam/pages/InputSkills/styles.module.scss
+++ /dev/null
@@ -1,7 +0,0 @@
-.page {
- display: flex;
- flex-direction: row;
- justify-content: center;
- align-items: flex-start;
- margin: 42px 35px;
-}
diff --git a/src/routes/CreateNewTeam/pages/SelectRole/components/RoleItem/styles.module.scss b/src/routes/CreateNewTeam/pages/SelectRole/components/RoleItem/styles.module.scss
index 3f5b7652..361d40e8 100644
--- a/src/routes/CreateNewTeam/pages/SelectRole/components/RoleItem/styles.module.scss
+++ b/src/routes/CreateNewTeam/pages/SelectRole/components/RoleItem/styles.module.scss
@@ -4,12 +4,13 @@
border: 1px solid #d4d4d4;
border-radius: 5px;
padding: 12px 16px;
- width: 213px;
+ width: 212px;
height: 136px;
display: flex;
flex-direction: column;
justify-content: space-evenly;
- margin: 0 0 24px 24px;
+ align-items: flex-start;
+ margin: 0 0 23px 23px;
cursor: pointer;
&.selected {
@@ -22,6 +23,7 @@
width: 42px;
height: 42px;
margin-left: 8px;
+ object-fit: cover;
}
.item-text {
@@ -38,7 +40,7 @@
padding: 0;
outline: none;
background: none;
- color: #0D61BF;
+ color: #0d61bf;
border: none;
text-align: left;
diff --git a/src/routes/CreateNewTeam/pages/SelectRole/components/RolesList/styles.module.scss b/src/routes/CreateNewTeam/pages/SelectRole/components/RolesList/styles.module.scss
index bc9e544e..5cd71f66 100644
--- a/src/routes/CreateNewTeam/pages/SelectRole/components/RolesList/styles.module.scss
+++ b/src/routes/CreateNewTeam/pages/SelectRole/components/RolesList/styles.module.scss
@@ -5,6 +5,8 @@
max-width: 746px;
margin-right: 20px;
position: relative;
+ height: 80vh;
+ overflow-y: scroll;
> header {
padding: 16px 24px;
diff --git a/src/routes/CreateNewTeam/pages/SelectRole/index.jsx b/src/routes/CreateNewTeam/pages/SelectRole/index.jsx
index a8137e94..d2dda3fe 100644
--- a/src/routes/CreateNewTeam/pages/SelectRole/index.jsx
+++ b/src/routes/CreateNewTeam/pages/SelectRole/index.jsx
@@ -1,191 +1,78 @@
/**
* Select Role Page
*
- * Gets project id from the router.
+ * Gets locationState from the router.
*
* Allows selecting a role, searching for users
* with that role, and submitting a job requiring the roles.
*/
-import React, { useCallback, useEffect, useState } from "react";
-import { useData } from "hooks/useData";
-import { navigate } from "@reach/router";
-import { toastr } from "react-redux-toastr";
+import React, { useCallback, useState } from "react";
import PT from "prop-types";
+import { useData } from "hooks/useData";
import RolesList from "./components/RolesList";
-import Completeness from "../../components/Completeness";
-import "./styles.module.scss";
import { getRoles } from "services/roles";
-import { setCurrentStage } from "utils/helpers";
import LoadingIndicator from "components/LoadingIndicator";
-import SearchCard from "../../components/SearchCard";
-import ResultCard from "../../components/ResultCard";
-import NoMatchingProfilesResultCard from "../../components/NoMatchingProfilesResultCard";
-import { createJob } from "services/jobs";
-import AddAnotherModal from "../../components/AddAnotherModal";
import RoleDetailsModal from "../../components/RoleDetailsModal";
-import withAuthentication from "../../../../hoc/withAuthentication";
-import AddedRolesAccordion from "./components/AddedRolesAccordion";
+import SearchContainer from "../../components/SearchContainer";
-function SelectRole({ projectId }) {
+function SelectRole({ location: { state: locationState } }) {
const [stages, setStages] = useState([
{ name: "Select a Role", isCurrent: true },
{ name: "Search Member" },
{ name: "Overview of the Results" },
]);
- const [addedRoles, setAddedRoles] = useState([]);
const [selectedRoleId, setSelectedRoleId] = useState(null);
- const [searchState, setSearchState] = useState(null);
- const [matchingProfiles, setMatchingProfiles] = useState(null);
- const [addAnotherModalOpen, setAddAnotherModalOpen] = useState(false);
const [roleDetailsModalOpen, setRoleDetailsModalOpen] = useState(false);
const [roleDetailsModalId, setRoleDetailsModalId] = useState(null);
- const [submitDone, setSubmitDone] = useState(true);
const [roles, loadingError] = useData(getRoles);
- let searchTimer;
-
- const submitJob = () => {
- setSubmitDone(false);
- createJob({
- projectId,
- title: `job-${Date()}`,
- skills: [],
- roleIds: addedRoles.map((r) => r.id),
- numPositions: 1,
- })
- .then(() => {
- toastr.success("Job Submitted");
- })
- .catch((err) => {
- console.error(err);
- toastr.warning("Error Submitting Job");
- })
- .finally(() => {
- setSubmitDone(true);
- navigate("/taas/myteams");
- });
- };
-
- const addAnother = useCallback(() => {
- setSelectedRoleId(null);
- setCurrentStage(0, stages, setStages);
- setAddAnotherModalOpen(false);
- setSearchState(null);
- }, [stages]);
-
- const toggleRole = useCallback(
- (id) => {
- setSelectedRoleId((selectedRoleId) =>
- id === selectedRoleId ? null : id
- );
- },
- [setSelectedRoleId]
- );
+ const toggleRole = useCallback((id) => {
+ setSelectedRoleId((selectedRoleId) => (id === selectedRoleId ? null : id));
+ }, []);
const onDescriptionClick = useCallback((roleId) => {
setRoleDetailsModalId(roleId);
setRoleDetailsModalOpen(true);
}, []);
- // mocked search for users with given roles
- const search = () => {
- setCurrentStage(1, stages, setStages);
- setSearchState("searching");
- searchTimer = setTimeout(() => {
- setCurrentStage(2, stages, setStages);
- setMatchingProfiles(null); // display no matching profiles screen for a while
- setSearchState("done");
- setTimeout(() => setMatchingProfiles(true), 2000);
- // add selected role
- const { id, name } = roles.find((r) => r.id === selectedRoleId);
- setAddedRoles((addedRoles) => [...addedRoles, { id, name }]);
- }, 3000);
+ const resetState = () => {
+ setSelectedRoleId(null);
+ setRoleDetailsModalId(false);
+ setRoleDetailsModalId(null);
};
- useEffect(() => clearTimeout(searchTimer));
-
if (!roles) {
return
;
}
- if (roles && !searchState) {
- return (
-
-
-
- {addedRoles.length > 0 && (
-
- )}
-
-
setRoleDetailsModalOpen(false)}
- />
-
-
- );
- }
-
- if (searchState === "searching") {
- return (
-
-
-
-
- );
- }
-
- if (searchState === "done") {
- return (
-
- {matchingProfiles ?
:
}
-
- {matchingProfiles &&
}
-
setAddAnotherModalOpen(true)}
- />
-
- {matchingProfiles && (
-
setAddAnotherModalOpen(false)}
- submitDone={submitDone}
- onContinueClick={submitJob}
- addAnother={addAnother}
- />
- )}
-
- );
- }
+ return (
+
+
+ setRoleDetailsModalOpen(false)}
+ />
+
+ );
}
SelectRole.propTypes = {
- projectId: PT.string,
+ locationState: PT.object,
};
-export default withAuthentication(SelectRole);
+export default SelectRole;
diff --git a/src/services/skills.js b/src/services/skills.js
index d2a91299..36a91af8 100644
--- a/src/services/skills.js
+++ b/src/services/skills.js
@@ -16,7 +16,7 @@ export function getSkills() {
getAllSkills().catch((ex) => {
console.error("Error loading skills", ex);
cachedSkillsAsPromise = null;
- return [];
+ return { data: [] };
});
return cachedSkillsAsPromise;
diff --git a/src/services/teams.js b/src/services/teams.js
index f220a1d6..658f98f8 100644
--- a/src/services/teams.js
+++ b/src/services/teams.js
@@ -206,3 +206,21 @@ export const postProject = () => {
return axios.post(url, bodyObj);
};
+
+/**
+ * Search for roles matching a role id, job description
+ * or list of skills
+ *
+ * @param {Object} searchObject object containing data for search
+ * @param {string} searchObject.roleId a role id to search for
+ * @param {string} searchObject.jobDescription job description used for search
+ * @param {string[]} searchObject.skills array of skill ids used for role search
+ * @param {string} searchObject.previousRoleSearchRequestId id of the last search made
+ * @returns
+ */
+export const searchRoles = (searchObject) => {
+ const newObject = { ...searchObject };
+ delete newObject.previousRoleSearchRequestId;
+ const url = `${config.API.V5}/taas-teams/sendRoleSearchRequest`;
+ return axios.post(url, newObject);
+};