diff --git a/config/dev.js b/config/dev.js
index 2daf4829..dfe168fd 100644
--- a/config/dev.js
+++ b/config/dev.js
@@ -13,7 +13,4 @@ module.exports = {
V5: "https://api.topcoder-dev.com/v5", //"http://localhost:3030/api/v5"
V3: "https://api.topcoder-dev.com/v3",
},
-
- // matching rate for search role result page
- MATCHING_RATE: process.env.MATCHING_RATE || 80,
};
diff --git a/config/prod.js b/config/prod.js
index 5416e540..21cdc373 100644
--- a/config/prod.js
+++ b/config/prod.js
@@ -13,7 +13,4 @@ module.exports = {
V5: "https://api.topcoder.com/v5",
V3: "https://api.topcoder.com/v3",
},
-
- // matching rate for search role result page
- MATCHING_RATE: process.env.MATCHING_RATE || 80,
};
diff --git a/src/root.component.jsx b/src/root.component.jsx
index 97b8bdcb..797270ff 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/components/Completeness/styles.module.scss b/src/routes/CreateNewTeam/components/Completeness/styles.module.scss
index 8e488b15..3227642c 100644
--- a/src/routes/CreateNewTeam/components/Completeness/styles.module.scss
+++ b/src/routes/CreateNewTeam/components/Completeness/styles.module.scss
@@ -6,7 +6,6 @@
position: relative;
width: 250px;
color: #fff;
- overflow: hidden;
button {
border: none;
}
diff --git a/src/routes/CreateNewTeam/components/NoMatchingProfilesResultCard/index.jsx b/src/routes/CreateNewTeam/components/NoMatchingProfilesResultCard/index.jsx
index 2938cccf..0bde6659 100644
--- a/src/routes/CreateNewTeam/components/NoMatchingProfilesResultCard/index.jsx
+++ b/src/routes/CreateNewTeam/components/NoMatchingProfilesResultCard/index.jsx
@@ -3,17 +3,13 @@
* Card that appears when there are no matching profiles after searching.
*/
import React from "react";
-import PT from "prop-types";
import { navigate } from "@reach/router";
-import {
- formatMoney,
-} from "utils/format";
import "./styles.module.scss";
import IconEarthX from "../../../../assets/images/icon-earth-x.svg";
import Curve from "../../../../assets/images/curve.svg";
import Button from "components/Button";
-function NoMatchingProfilesResultCard({rates = [{global: 0}], onSearch}) {
+function NoMatchingProfilesResultCard() {
return (
@@ -29,11 +25,11 @@ function NoMatchingProfilesResultCard({rates = [{global: 0}], onSearch}) {
Niche Rate
-
{formatMoney(rates[0].global)}
+
$1,200
/Week
)}
- {showRates && isExternalMember && (
+ {showRates && !showSpecialRates && (
@@ -166,7 +159,7 @@ function ResultCard({
(40h / week)
-
{formatMoney(rates[0].global)}
+
$1,800
/Week
@@ -176,7 +169,7 @@ function ResultCard({
(30h / week)
-
{formatMoney(rates[0].inCountry)}
+
$1,250
/Week
@@ -186,7 +179,7 @@ function ResultCard({
(20h / week)
-
{formatMoney(rates[0].offShore)}
+
$800
/Week
@@ -197,14 +190,14 @@ function ResultCard({
Qualified candidates within
-
{timeToCandidate}h
+
24h
Interviews can start within
-
{timeToInterview}h
+
48h
@@ -216,11 +209,11 @@ function ResultCard({
- {config.MATCHING_RATE}%
+ 80%
Matching rate
}
@@ -229,7 +222,7 @@ function ResultCard({
-
{numberOfMembersAvailable}+
+
300+
Members matched
@@ -253,12 +246,4 @@ function ResultCard({
);
}
-ResultCard.propTypes = {
- numberOfMembersAvailable:PT.number,
- numberOfMembers: PT.string,
- timeToCandidate: PT.number,
- timeToInterview: PT.number,
- isExternalMember: PT.bool,
- rates: PT.array,
-};
export default ResultCard;
diff --git a/src/routes/CreateNewTeam/components/ResultCard/styles.module.scss b/src/routes/CreateNewTeam/components/ResultCard/styles.module.scss
index cba4f0a9..1b4e7347 100644
--- a/src/routes/CreateNewTeam/components/ResultCard/styles.module.scss
+++ b/src/routes/CreateNewTeam/components/ResultCard/styles.module.scss
@@ -3,7 +3,6 @@
.result-card {
@include rounded-card;
max-width: 746px;
- overflow: hidden;
width: 50vw;
margin-right: 30px;
}
@@ -24,6 +23,7 @@
position: relative;
text-align: center;
border-radius: 8px 8px 0 0;
+ cursor: pointer;
svg {
margin-bottom: 8px;
@@ -72,12 +72,9 @@
margin: 0 40px;
}
.progressbar-child {
+ margin-top: 5px;
width: 90px;
height: 90px;
- overflow: hidden;
- > h4 {
- margin-top: 10px;
- }
}
}
@@ -157,9 +154,6 @@
&:not(:first-child) {
margin-left: 40px;
}
- &:not(:last-child) {
- border-right: 1px solid #E9E9E9;
- }
.rate-heading {
display: flex;
diff --git a/src/routes/CreateNewTeam/components/RoleDetailsModal/index.jsx b/src/routes/CreateNewTeam/components/RoleDetailsModal/index.jsx
index 179619c3..17039e66 100644
--- a/src/routes/CreateNewTeam/components/RoleDetailsModal/index.jsx
+++ b/src/routes/CreateNewTeam/components/RoleDetailsModal/index.jsx
@@ -6,18 +6,17 @@ import React, { useState, useEffect } from "react";
import PT from "prop-types";
import Modal from "react-responsive-modal";
import Button from "components/Button";
-import MarkdownEditorViewer from "../../../../components/MarkdownEditorViewer";
import IconCrossLight from "../../../../assets/images/icon-cross-light.svg";
import FallbackIcon from "../../../../assets/images/icon-role-fallback.svg";
import "./styles.module.scss";
import CenteredSpinner from "components/CenteredSpinner";
import { getRoleById } from "services/roles";
+
const modalStyle = {
- borderRadius: "10px",
- padding: "70px 80px 60px",
- maxWidth: "680px",
+ borderRadius: "8px",
+ padding: "32px 32px 22px 32px",
+ maxWidth: "460px",
width: "100%",
- height: "650px",
margin: 0,
"overflow-x": "hidden",
};
@@ -45,7 +44,9 @@ function RoleDetailsModal({ roleId, open, onClose }) {
open={open}
center
onClose={onClose}
- showCloseIcon={false}
+ closeIcon={
+
+ }
styles={{
modal: modalStyle,
modalContainer: containerStyle,
@@ -55,7 +56,7 @@ function RoleDetailsModal({ roleId, open, onClose }) {
{isLoading ? (
<>
- Loading...
+ Loading...
>
) : (
<>
@@ -69,7 +70,6 @@ function RoleDetailsModal({ roleId, open, onClose }) {
) : (
)}
- {role?.name}
- {!showSkills &&
}
- {showSkills && {_.map(role?.listOfSkills, (s)=>
- {s}
- )}
}
+ {role?.name}
+ {role?.description}
>
)}
diff --git a/src/routes/CreateNewTeam/components/RoleDetailsModal/styles.module.scss b/src/routes/CreateNewTeam/components/RoleDetailsModal/styles.module.scss
index 3f964c9a..81daa623 100644
--- a/src/routes/CreateNewTeam/components/RoleDetailsModal/styles.module.scss
+++ b/src/routes/CreateNewTeam/components/RoleDetailsModal/styles.module.scss
@@ -1,39 +1,5 @@
@import "styles/include";
-
-.loading {
- margin-bottom: 100px;
- margin-top: 200px;
-}
-
-.skill-tag-list {
- display: flex;
- height: 260px;
- flex-wrap: wrap;
-}
-
-.desc-container {
- width: 100%;
- height: 260px;
- overflow: scroll;
-}
-
-.skill-tag {
- @include font-roboto;
-
- background-color: #E9E9E9;
- border-radius: 5px;
- padding: 6px 10px;
- margin-right: 6px;
- margin-bottom: 10px;
- color: #2A2A2A;
- font-size: 12px;
- letter-spacing: 0.25px;
- line-height: 16px;
- height: 26px;
- display: inline-block;
-}
-
.button-group {
display: flex;
flex-direction: row;
@@ -49,8 +15,7 @@
flex-direction: row;
align-items: center;
justify-content: center;
- margin-top: 14px;
- margin-bottom: 30px;
+ margin-bottom: 42px;
}
.modal-body {
@@ -58,19 +23,18 @@
flex-direction: column;
justify-content: flex-start;
align-items: center;
- // text-align: center;
- margin-bottom: 40px;
+ text-align: center;
+ margin-bottom: 80px;
.role-icon {
width: 42px;
height: 42px;
- margin-bottom: 18px;
}
h5 {
@include font-barlow-condensed;
font-size: 34px;
- color: #000;
+ color: #1e94a3;
text-transform: uppercase;
font-weight: 500;
margin-bottom: 10px;
diff --git a/src/routes/CreateNewTeam/components/SearchableList/index.jsx b/src/routes/CreateNewTeam/components/SearchableList/index.jsx
deleted file mode 100644
index 88ab6624..00000000
--- a/src/routes/CreateNewTeam/components/SearchableList/index.jsx
+++ /dev/null
@@ -1,88 +0,0 @@
-/**
- * SearchableList
- * wrap roles list and skills list
- * Allows selecting and filtering by name.
- */
-import React, { useEffect, useState } from "react";
-import { useDebounce } from "react-use";
-import PT from "prop-types";
-import Input from "components/Input";
-import PageHeader from "components/PageHeader";
-import "./styles.module.scss";
-import { INPUT_DEBOUNCE_DELAY } from "constants/";
-
-function SearchableList({title, inputPlaceholder, itemList, selectedRoleId, onDescriptionClick, toggleRole, renderItem, countElement}) {
- const [filteredItems, setFilteredItems] = useState(itemList);
- const [filter, setFilter] = useState("");
- const [debouncedFilter, setDebouncedFilter] = useState("");
-
- const onFilterChange = (e) => {
- setFilter(e.target.value);
- };
-
- useDebounce(
- () => {
- setDebouncedFilter(filter);
- },
- INPUT_DEBOUNCE_DELAY,
- [filter]
- );
-
- useEffect(() => {
- if (debouncedFilter.length > 0) {
- const filterText = debouncedFilter.toLowerCase();
- setFilteredItems(
- itemList.filter((item) => item.name.toLowerCase().includes(filterText))
- );
- } else {
- setFilteredItems(itemList);
- }
- }, [debouncedFilter, itemList]);
-
- return (
-
- }
- />
- {countElement}
-
- {filteredItems.map((item) => (
- renderItem(item)
- ))}
-
-
- );
-}
-
-SearchableList.propTypes = {
- itemList: PT.array,
- title: PT.string,
- inputPlaceholder: PT.string,
- renderItem: PT.func,
- countElement: PT.element,
- toggleRole: PT.func,
-};
-
-export default SearchableList;
diff --git a/src/routes/CreateNewTeam/components/SearchableList/styles.module.scss b/src/routes/CreateNewTeam/components/SearchableList/styles.module.scss
deleted file mode 100644
index e17803f5..00000000
--- a/src/routes/CreateNewTeam/components/SearchableList/styles.module.scss
+++ /dev/null
@@ -1,73 +0,0 @@
-@import "styles/include";
-
-
-.input-container {
- position: relative;
-}
-
-.searchable-list {
- @include rounded-card;
- max-width: 746px;
- margin-right: 20px;
- position: relative;
- flex: 1;
-
- > header {
- padding: 16px 24px;
- }
-}
-
-.role-count {
- position: absolute;
- font-size: 12px;
- top: 72px;
- left: 73px;
-}
-
-// 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;
- border-radius: 6px;
- box-sizing: border-box;
- color: #2a2a2a;
- font-size: 14px;
- height: 40px;
- line-height: 38px;
- 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;
- }
-}
-
-.clear-input-button {
- position: absolute;
- right: 15px;
- font-size: 14px;
- font-weight: 700;
- line-height: 38px;
- cursor: pointer;
- &:hover {
- color: rgb(216, 24, 24);
- }
-}
-
-.searchable-container {
- display: flex;
- flex-direction: row;
- justify-content: flex-start;
- flex-wrap: wrap;
- margin-right: 24px;
-}
diff --git a/src/routes/CreateNewTeam/index.jsx b/src/routes/CreateNewTeam/index.jsx
index 763791cf..62fd1826 100644
--- a/src/routes/CreateNewTeam/index.jsx
+++ b/src/routes/CreateNewTeam/index.jsx
@@ -14,10 +14,24 @@ 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 onSearchClick = (page) => {
- navigate(`/taas/myteams/createnewteam/${page}`);
+ 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);
+ });
+ };
+
+ const goToJobDescription = () => {
+ navigate(`/taas/myteams/createnewteam/jd`);
};
return (
@@ -31,24 +45,24 @@ 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={() => onSearchClick("role")}
+ onClick={() => createProjectAndNavigate("role")}
/>
}
backgroundImage="linear-gradient(221.5deg, #2C95D7 0%, #9D41C9 100%)"
- onClick={() => onSearchClick("skills")}
+ onClick={() => createProjectAndNavigate("skills")}
/>
}
backgroundImage="linear-gradient(135deg, #2984BD 0%, #0AB88A 100%)"
- onClick={() => onSearchClick("jd")}
+ onClick={goToJobDescription}
/>
);
}
-export default CreateNewTeam;
+export default withAuthentication(CreateNewTeam);
diff --git a/src/routes/CreateNewTeam/pages/InputJobDescription/components/SkillListPopup/index.jsx b/src/routes/CreateNewTeam/pages/InputJobDescription/components/SkillListPopup/index.jsx
new file mode 100644
index 00000000..60317253
--- /dev/null
+++ b/src/routes/CreateNewTeam/pages/InputJobDescription/components/SkillListPopup/index.jsx
@@ -0,0 +1,80 @@
+/**
+ * Temporary Popup for skill list
+ * show skill list
+ */
+import React from "react";
+import _ from "lodash";
+import PT from "prop-types";
+import Modal from "react-responsive-modal";
+import Button from "components/Button";
+import IconCrossLight from "../../../../../../assets/images/icon-cross-light.svg";
+import IconSingleManAdd from "../../../../../../assets/images/icon-single-man-add.svg";
+import "./styles.module.scss";
+import CenteredSpinner from "components/CenteredSpinner";
+
+const modalStyle = {
+ borderRadius: "8px",
+ padding: "32px 32px 22px 32px",
+ maxWidth: "460px",
+ width: "100%",
+ margin: 0,
+ "overflow-x": "hidden",
+};
+
+const containerStyle = {
+ padding: "10px",
+};
+
+function SkillListPopup({ open, skills, onClose, isLoading, onContinueClick }) {
+ return (
+
+ }
+ styles={{
+ modal: modalStyle,
+ modalContainer: containerStyle,
+ }}
+ >
+
+ {isLoading ? (
+ <>
+
+
loading skills
+ >
+ ) : (
+ <>
+
+
skills
+ {_.map(skills, (s) => {
+ return
{s.tag}
;
+ })}
+ >
+ )}
+
+
+
+
+
+ );
+}
+
+SkillListPopup.propTypes = {
+ open: PT.bool,
+ onClose: PT.func,
+ isLoading: PT.bool,
+ onContinueClick: PT.func,
+ skills: PT.arrayOf(PT.shape()),
+};
+
+export default SkillListPopup;
diff --git a/src/routes/CreateNewTeam/pages/InputJobDescription/components/SkillListPopup/styles.module.scss b/src/routes/CreateNewTeam/pages/InputJobDescription/components/SkillListPopup/styles.module.scss
new file mode 100644
index 00000000..b0270326
--- /dev/null
+++ b/src/routes/CreateNewTeam/pages/InputJobDescription/components/SkillListPopup/styles.module.scss
@@ -0,0 +1,48 @@
+@import "styles/include";
+
+.button-group {
+ display: flex;
+ flex-direction: row;
+ justify-content: center;
+ align-items: flex-end;
+ :first-child {
+ margin-right: 8px;
+ }
+}
+
+.modal-body {
+ display: flex;
+ flex-direction: column;
+ justify-content: flex-start;
+ align-items: center;
+ text-align: center;
+ margin-bottom: 80px;
+
+ svg {
+ width: 48px;
+ height: 48px;
+ margin-bottom: 16px;
+ }
+
+ h5 {
+ @include font-barlow-condensed;
+ font-size: 34px;
+ color: #1e94a3;
+ text-transform: uppercase;
+ font-weight: 500;
+ margin-bottom: 10px;
+ }
+
+ p {
+ @include font-roboto;
+ font-size: 16px;
+ color: #555555;
+ line-height: 26px;
+ }
+}
+
+.cross {
+ g {
+ stroke: #000;
+ }
+}
diff --git a/src/routes/CreateNewTeam/pages/InputJobDescription/index.jsx b/src/routes/CreateNewTeam/pages/InputJobDescription/index.jsx
index 8020ce43..f6bbc2de 100644
--- a/src/routes/CreateNewTeam/pages/InputJobDescription/index.jsx
+++ b/src/routes/CreateNewTeam/pages/InputJobDescription/index.jsx
@@ -15,13 +15,12 @@ import MarkdownEditor from "../../../../components/MarkdownEditor";
import { getSkillsByJobDescription } from "../../../../services/teams";
import Completeness from "../../components/Completeness";
import { getSkills } from "services/skills";
-import { sendRoleSearchRequest } from "services/teams";
import SearchCard from "../../components/SearchCard";
import ResultCard from "../../components/ResultCard";
-import NoMatchingProfilesResultCard from "../../components/NoMatchingProfilesResultCard";
import AddAnotherModal from "../../components/AddAnotherModal";
+import SkillListPopup from "./components/SkillListPopup";
import "./styles.module.scss";
-import AddedRolesAccordion from "../../components/AddedRolesAccordion";
+import withAuthentication from "../../../../hoc/withAuthentication";
import IconOfficeFileText from "../../../../assets/images/icon-office-file-text.svg";
function InputJobDescription() {
@@ -30,18 +29,39 @@ function InputJobDescription() {
{ name: "Search Member" },
{ name: "Overview of the Results" },
]);
- const [roleSearchResult, setRoleSearchResult] = useState(null);
- const [addedRoles, setAddedRoles] = useState([]);
- const [
- previousRoleSearchRequestId,
- setPreviousRoleSearchRequestId,
- ] = useState(null);
const [jdString, setJdString] = useState("");
- const [matchingProfiles, setMatchingProfiles] = useState(null);
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`);
@@ -55,36 +75,6 @@ function InputJobDescription() {
}, 3000);
};
- const search = useCallback(() => {
- setCurrentStage(1, stages, setStages);
- setSearchState("searching");
- sendRoleSearchRequest({
- jobDescription: jdString,
- previousRoleSearchRequestId,
- })
- .then(({ data }) => {
- setRoleSearchResult(data);
- setPreviousRoleSearchRequestId(data.roleSearchRequestId);
- setCurrentStage(2, stages, setStages);
- setMatchingProfiles(null); // display no matching profiles screen for a while
- if (data.name && data.name.toLowerCase() !== "niche") {
- setMatchingProfiles(true);
- setAddedRoles((addedRoles) => [
- ...addedRoles,
- { id: data.id, name: data.name },
- ]);
- } else {
- setMatchingProfiles(false);
- }
- setSearchState("done");
- })
- .catch((e) => {
- setCurrentStage(2, stages, setStages);
- setMatchingProfiles(false); // display no matching profiles screen for a while
- setSearchState("done");
- });
- }, [jdString]);
-
const onEditChange = useCallback((value) => {
setJdString(value);
}, []);
@@ -104,20 +94,21 @@ function InputJobDescription() {
onChange={onEditChange}
/>
-
-
- {addedRoles.length > 0 && (
-
- )}
-
+ setSkillModalOpen(false)}
+ isLoading={isLoadingSkills}
+ onContinueClick={onConfirationClick}
+ />
) : searchState === "searching" ? (
@@ -132,19 +123,7 @@ function InputJobDescription() {
) : (
- {matchingProfiles ? (
-
- ) : (
-
- )}
-
-
- {addedRoles.length > 0 && (
-
- )}
+
-
)}
);
@@ -169,4 +147,4 @@ InputJobDescription.propTypes = {
projectId: PT.string,
};
-export default InputJobDescription;
+export default withAuthentication(InputJobDescription);
diff --git a/src/routes/CreateNewTeam/pages/InputJobDescription/styles.module.scss b/src/routes/CreateNewTeam/pages/InputJobDescription/styles.module.scss
index a1b3188b..31e3ca4b 100644
--- a/src/routes/CreateNewTeam/pages/InputJobDescription/styles.module.scss
+++ b/src/routes/CreateNewTeam/pages/InputJobDescription/styles.module.scss
@@ -14,11 +14,4 @@
padding: 0 30px 30px;
flex: 1;
}
- .right-side {
- display: flex;
- flex-direction: column;
- & > div:not(:first-child) {
- margin-top: 16px;
- }
- }
}
diff --git a/src/routes/CreateNewTeam/pages/InputSkills/index.jsx b/src/routes/CreateNewTeam/pages/InputSkills/index.jsx
index e513ac5c..9341e86b 100644
--- a/src/routes/CreateNewTeam/pages/InputSkills/index.jsx
+++ b/src/routes/CreateNewTeam/pages/InputSkills/index.jsx
@@ -12,20 +12,17 @@ import { useData } from "hooks/useData";
import { navigate } from "@reach/router";
import { toastr } from "react-redux-toastr";
import PT from "prop-types";
-import SearchableList from "../../components/SearchableList";
-import SkillItem from "./components/SkillItem";
+import SkillsList from "./components/SkillsList";
import Completeness from "../../components/Completeness";
import "./styles.module.scss";
import { getSkills } from "services/skills";
-import { sendRoleSearchRequest } from "services/teams";
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 AddedRolesAccordion from "../../components/AddedRolesAccordion";
+import withAuthentication from "../../../../hoc/withAuthentication";
function InputSkills({ projectId }) {
const [stages, setStages] = useState([
@@ -33,17 +30,10 @@ function InputSkills({ projectId }) {
{ name: "Search Member" },
{ name: "Overview of the Results" },
]);
- const [
- previousRoleSearchRequestId,
- setPreviousRoleSearchRequestId,
- ] = useState(null);
- const [roleSearchResult, setRoleSearchResult] = useState(null);
const [selectedSkills, setSelectedSkills] = useState([]);
- const [matchingProfiles, setMatchingProfiles] = useState(null);
const [searchState, setSearchState] = useState(null);
const [modalOpen, setModalOpen] = useState(false);
const [submitDone, setSubmitDone] = useState(false);
- const [addedRoles, setAddedRoles] = useState([]);
const [skills, loadingError] = useData(getSkills);
@@ -76,7 +66,6 @@ function InputSkills({ projectId }) {
const toggleSkill = useCallback(
(id) => {
- setPreviousRoleSearchRequestId(null);
if (selectedSkills.includes(id)) {
setSelectedSkills(selectedSkills.filter((skill) => skill !== id));
} else {
@@ -88,64 +77,27 @@ function InputSkills({ projectId }) {
[selectedSkills]
);
- const search = useCallback(() => {
- setCurrentStage(1, stages, setStages);
+ // mocked search for users with given skills
+ const search = () => {
setSearchState("searching");
- sendRoleSearchRequest({
- skills: selectedSkills,
- previousRoleSearchRequestId,
- })
- .then(({ data }) => {
- setRoleSearchResult(data);
- setPreviousRoleSearchRequestId(data.roleSearchRequestId);
- setCurrentStage(2, stages, setStages);
- setMatchingProfiles(null); // display no matching profiles screen for a while
- if (data.name && data.name.toLowerCase() !== "niche") {
- setAddedRoles((addedRoles) => [
- ...addedRoles,
- { id: data.id, name: data.name },
- ]);
- setMatchingProfiles(true);
- } else {
- setMatchingProfiles(false);
- }
- setSearchState("done");
- })
- .catch((e) => {
- setCurrentStage(2, stages, setStages);
- setMatchingProfiles(false); // display no matching profiles screen for a while
- setSearchState("done");
- });
- }, [selectedSkills]);
+ setCurrentStage(1, stages, setStages);
+ searchTimer = setTimeout(() => {
+ setSearchState("done");
+ setCurrentStage(2, stages, setStages);
+ }, 3000);
+ };
+
+ useEffect(() => clearTimeout(searchTimer));
return !skills ? (
) : !searchState ? (
-
0 && (
-
- {selectedSkills.length} skills selected
-
- )
- }
- renderItem={({ id, name }) => {
- return (
-
- );
- }}
+
- {addedRoles.length > 0 && }
) : (
- {matchingProfiles ? (
-
- ) : (
-
- )}
-
- {addedRoles.length > 0 && (
-
- )}
+
-
);
}
@@ -199,4 +142,4 @@ InputSkills.propTypes = {
projectId: PT.string,
};
-export default InputSkills;
+export default withAuthentication(InputSkills);
diff --git a/src/routes/CreateNewTeam/pages/InputSkills/styles.module.scss b/src/routes/CreateNewTeam/pages/InputSkills/styles.module.scss
index a6c5fff9..b47da072 100644
--- a/src/routes/CreateNewTeam/pages/InputSkills/styles.module.scss
+++ b/src/routes/CreateNewTeam/pages/InputSkills/styles.module.scss
@@ -4,20 +4,4 @@
justify-content: center;
align-items: flex-start;
margin: 42px 35px;
-
- .right-side {
- display: flex;
- flex-direction: column;
- & > div:not(:first-child) {
- margin-top: 16px;
- }
- }
-}
-
-
-.skill-count {
- position: absolute;
- font-size: 12px;
- top: 72px;
- left: 73px;
}
diff --git a/src/routes/CreateNewTeam/components/AddedRolesAccordion/index.jsx b/src/routes/CreateNewTeam/pages/SelectRole/components/AddedRolesAccordion/index.jsx
similarity index 100%
rename from src/routes/CreateNewTeam/components/AddedRolesAccordion/index.jsx
rename to src/routes/CreateNewTeam/pages/SelectRole/components/AddedRolesAccordion/index.jsx
diff --git a/src/routes/CreateNewTeam/components/AddedRolesAccordion/styles.module.scss b/src/routes/CreateNewTeam/pages/SelectRole/components/AddedRolesAccordion/styles.module.scss
similarity index 100%
rename from src/routes/CreateNewTeam/components/AddedRolesAccordion/styles.module.scss
rename to src/routes/CreateNewTeam/pages/SelectRole/components/AddedRolesAccordion/styles.module.scss
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 a1d5560d..3f5b7652 100644
--- a/src/routes/CreateNewTeam/pages/SelectRole/components/RoleItem/styles.module.scss
+++ b/src/routes/CreateNewTeam/pages/SelectRole/components/RoleItem/styles.module.scss
@@ -33,7 +33,6 @@
}
.button {
- width: 75px;
font-size: 14px;
line-height: 22px;
padding: 0;
diff --git a/src/routes/CreateNewTeam/pages/SelectRole/index.jsx b/src/routes/CreateNewTeam/pages/SelectRole/index.jsx
index 9e15b3b7..a8137e94 100644
--- a/src/routes/CreateNewTeam/pages/SelectRole/index.jsx
+++ b/src/routes/CreateNewTeam/pages/SelectRole/index.jsx
@@ -11,8 +11,7 @@ import { useData } from "hooks/useData";
import { navigate } from "@reach/router";
import { toastr } from "react-redux-toastr";
import PT from "prop-types";
-import RoleItem from "./components/RoleItem";
-import SearchableList from '../../components/SearchableList'
+import RolesList from "./components/RolesList";
import Completeness from "../../components/Completeness";
import "./styles.module.scss";
import { getRoles } from "services/roles";
@@ -22,11 +21,10 @@ import SearchCard from "../../components/SearchCard";
import ResultCard from "../../components/ResultCard";
import NoMatchingProfilesResultCard from "../../components/NoMatchingProfilesResultCard";
import { createJob } from "services/jobs";
-import { sendRoleSearchRequest } from "services/teams";
import AddAnotherModal from "../../components/AddAnotherModal";
import RoleDetailsModal from "../../components/RoleDetailsModal";
-import AddedRolesAccordion from "../../components/AddedRolesAccordion";
-
+import withAuthentication from "../../../../hoc/withAuthentication";
+import AddedRolesAccordion from "./components/AddedRolesAccordion";
function SelectRole({ projectId }) {
const [stages, setStages] = useState([
@@ -34,8 +32,6 @@ function SelectRole({ projectId }) {
{ name: "Search Member" },
{ name: "Overview of the Results" },
]);
- const [roleSearchResult, setRoleSearchResult] = useState(null);
- const [previousRoleSearchRequestId, setPreviousRoleSearchRequestId] = useState(null);
const [addedRoles, setAddedRoles] = useState([]);
const [selectedRoleId, setSelectedRoleId] = useState(null);
const [searchState, setSearchState] = useState(null);
@@ -80,7 +76,6 @@ function SelectRole({ projectId }) {
const toggleRole = useCallback(
(id) => {
- setPreviousRoleSearchRequestId(null)
setSelectedRoleId((selectedRoleId) =>
id === selectedRoleId ? null : id
);
@@ -93,27 +88,22 @@ function SelectRole({ projectId }) {
setRoleDetailsModalOpen(true);
}, []);
- const search = useCallback(() => {
+ // mocked search for users with given roles
+ const search = () => {
setCurrentStage(1, stages, setStages);
setSearchState("searching");
- sendRoleSearchRequest({roleId: selectedRoleId, previousRoleSearchRequestId}).then(({data})=> {
- setRoleSearchResult(data)
- setCurrentStage(2, stages, setStages);
- setMatchingProfiles(null); // display no matching profiles screen for a while
- setPreviousRoleSearchRequestId(data.roleSearchRequestId)
- if (data.name && data.name.toLowerCase() !== 'niche' ) {
- setAddedRoles((addedRoles) => [...addedRoles, { id: data.id, name: data.name }]);
- setMatchingProfiles(true)
- } else {
- setMatchingProfiles(false)
- }
- setSearchState("done");
- }).catch(e=> {
- setCurrentStage(2, stages, setStages);
- setMatchingProfiles(false); // display no matching profiles screen for a while
- setSearchState("done");
- })
- }, [selectedRoleId, previousRoleSearchRequestId]);
+ 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);
+ };
+
+ useEffect(() => clearTimeout(searchTimer));
if (!roles) {
return ;
@@ -122,23 +112,11 @@ function SelectRole({ projectId }) {
if (roles && !searchState) {
return (
-
{
- return (
-
- )
- }}
+
{addedRoles.length > 0 && (
@@ -152,15 +130,11 @@ function SelectRole({ projectId }) {
stages={stages}
percentage="26"
/>
- {
- roleDetailsModalOpen && (
- setRoleDetailsModalOpen(false)}
- />
- )
- }
+ setRoleDetailsModalOpen(false)}
+ />
);
@@ -184,7 +158,7 @@ function SelectRole({ projectId }) {
if (searchState === "done") {
return (
- {matchingProfiles ?
:
}
+ {matchingProfiles ? : }
{matchingProfiles &&
}
{
return axios.get(`${config.API.V5}/taas-teams?${query}`);
};
-/**
- * search role detail.
- *
- * @param {object} data search param, roleId | jobDescription | skills
- * @returns {Promise<{}>} role detail
- */
-export const sendRoleSearchRequest = (data) => {
- // mock data
- delete data.previousRoleSearchRequestId
- return axios.post(`${config.API.V5}/taas-teams/sendRoleSearchRequest`, data);
-};
-
/**
* Get v5 user profile.
*
@@ -202,3 +190,19 @@ export const postMembers = (teamId, handles, emails) => {
return axios.post(url, bodyObj);
};
+
+/**
+ * Post new project
+ *
+ * @returns {Promise