diff --git a/src/routes/InputSkills/components/AddAnotherModal/index.jsx b/src/components/AddAnotherModal/index.jsx
similarity index 92%
rename from src/routes/InputSkills/components/AddAnotherModal/index.jsx
rename to src/components/AddAnotherModal/index.jsx
index e031669a..14d2bdb1 100644
--- a/src/routes/InputSkills/components/AddAnotherModal/index.jsx
+++ b/src/components/AddAnotherModal/index.jsx
@@ -8,8 +8,8 @@ import React from "react";
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 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";
diff --git a/src/routes/InputSkills/components/AddAnotherModal/styles.module.scss b/src/components/AddAnotherModal/styles.module.scss
similarity index 100%
rename from src/routes/InputSkills/components/AddAnotherModal/styles.module.scss
rename to src/components/AddAnotherModal/styles.module.scss
diff --git a/src/routes/InputSkills/components/CompleteProgress/index.jsx b/src/components/CompleteProgress/index.jsx
similarity index 100%
rename from src/routes/InputSkills/components/CompleteProgress/index.jsx
rename to src/components/CompleteProgress/index.jsx
diff --git a/src/routes/InputSkills/components/CompleteProgress/styles.module.scss b/src/components/CompleteProgress/styles.module.scss
similarity index 100%
rename from src/routes/InputSkills/components/CompleteProgress/styles.module.scss
rename to src/components/CompleteProgress/styles.module.scss
diff --git a/src/routes/InputSkills/components/Completeness/index.jsx b/src/components/Completeness/index.jsx
similarity index 77%
rename from src/routes/InputSkills/components/Completeness/index.jsx
rename to src/components/Completeness/index.jsx
index 4bc91ac9..bf6a9cfa 100644
--- a/src/routes/InputSkills/components/Completeness/index.jsx
+++ b/src/components/Completeness/index.jsx
@@ -10,11 +10,15 @@ import cn from "classnames";
import PT from "prop-types";
import CompleteProgress from "../CompleteProgress";
import "./styles.module.scss";
-import IconListQuill from "../../../../assets/images/icon-list-quill.svg";
+import IconListQuill from "../../assets/images/icon-list-quill.svg";
-function Completeness({ isDisabled, onClick, buttonLabel, stage }) {
+function Completeness({ title, backgroundIcon, isDisabled, backgroundImage, onClick, buttonLabel, stage }) {
return (
-
+
@@ -26,7 +30,7 @@ function Completeness({ isDisabled, onClick, buttonLabel, stage }) {
{ done: stage > 1 }
)}
>
- Input Skills
+ Input {title}
{buttonLabel}
-
+ {backgroundIcon}
);
}
@@ -59,6 +63,9 @@ Completeness.propTypes = {
onClick: PT.func,
buttonLabel: PT.string,
stage: PT.number,
+ title: PT.string,
+ backgroundImage: PT.string,
+ backgroundIcon: PT.string
};
export default Completeness;
diff --git a/src/routes/InputSkills/components/Completeness/styles.module.scss b/src/components/Completeness/styles.module.scss
similarity index 78%
rename from src/routes/InputSkills/components/Completeness/styles.module.scss
rename to src/components/Completeness/styles.module.scss
index 5c44deb9..3320d5ef 100644
--- a/src/routes/InputSkills/components/Completeness/styles.module.scss
+++ b/src/components/Completeness/styles.module.scss
@@ -4,9 +4,17 @@
@include rounded-card;
padding: 12px;
position: relative;
- background-image: linear-gradient(221.5deg, #2c95d7 0%, #9d41c9 100%);
width: 250px;
color: #fff;
+
+ > svg {
+ position: absolute;
+ right: -50px;
+ top: 85px;
+ opacity: 10%;
+ width: 144px;
+ height: 144px;
+ }
}
.list {
@@ -47,12 +55,3 @@
}
}
}
-
-.transparent-icon {
- position: absolute;
- right: -50px;
- top: 85px;
- opacity: 10%;
- width: 144px;
- height: 144px;
-}
diff --git a/src/routes/InputSkills/components/ResultCard/index.jsx b/src/components/ResultCard/index.jsx
similarity index 90%
rename from src/routes/InputSkills/components/ResultCard/index.jsx
rename to src/components/ResultCard/index.jsx
index 01a98935..a99446ad 100644
--- a/src/routes/InputSkills/components/ResultCard/index.jsx
+++ b/src/components/ResultCard/index.jsx
@@ -6,11 +6,11 @@
*/
import React, { useState } from "react";
import "./styles.module.scss";
-import IconEarthCheck from "../../../../assets/images/icon-earth-check.svg";
-import IconMultipleUsers from "../../../../assets/images/icon-multiple-users.svg";
-import IconMultipleActionsCheck from "../../../../assets/images/icon-multiple-actions-check-2.svg";
-import IconTeamMeetingChat from "../../../../assets/images/icon-team-meeting-chat.svg";
-import Curve from "../../../../assets/images/curve.svg";
+import IconEarthCheck from "../../assets/images/icon-earth-check.svg";
+import IconMultipleUsers from "../../assets/images/icon-multiple-users.svg";
+import IconMultipleActionsCheck from "../../assets/images/icon-multiple-actions-check-2.svg";
+import IconTeamMeetingChat from "../../assets/images/icon-team-meeting-chat.svg";
+import Curve from "../../assets/images/curve.svg";
import Button from "components/Button";
function ResultCard() {
diff --git a/src/routes/InputSkills/components/ResultCard/styles.module.scss b/src/components/ResultCard/styles.module.scss
similarity index 100%
rename from src/routes/InputSkills/components/ResultCard/styles.module.scss
rename to src/components/ResultCard/styles.module.scss
diff --git a/src/routes/InputSkills/components/SearchCard/index.jsx b/src/components/SearchCard/index.jsx
similarity index 77%
rename from src/routes/InputSkills/components/SearchCard/index.jsx
rename to src/components/SearchCard/index.jsx
index dbdebd5a..0edb34f5 100644
--- a/src/routes/InputSkills/components/SearchCard/index.jsx
+++ b/src/components/SearchCard/index.jsx
@@ -5,10 +5,10 @@
*/
import React, { useEffect, useState } from "react";
import "./styles.module.scss";
-import IconEarthSearch from "../../../../assets/images/icon-earth-search.svg";
-import WorldMapDotted from "../../../../assets/images/world-map-dotted.svg";
-import WorldMapSearch1 from "../../../../assets/images/world-map-search1.svg";
-import WorldMapSearch2 from "../../../../assets/images/world-map-search2.svg";
+import IconEarthSearch from "../../assets/images/icon-earth-search.svg";
+import WorldMapDotted from "../../assets/images/world-map-dotted.svg";
+import WorldMapSearch1 from "../../assets/images/world-map-search1.svg";
+import WorldMapSearch2 from "../../assets/images/world-map-search2.svg";
function SearchCard() {
const [searchState, setSearchState] = useState(null);
diff --git a/src/routes/InputSkills/components/SearchCard/styles.module.scss b/src/components/SearchCard/styles.module.scss
similarity index 100%
rename from src/routes/InputSkills/components/SearchCard/styles.module.scss
rename to src/components/SearchCard/styles.module.scss
diff --git a/src/root.component.jsx b/src/root.component.jsx
index a50a3023..268ae29a 100644
--- a/src/root.component.jsx
+++ b/src/root.component.jsx
@@ -11,6 +11,7 @@ import JobForm from "./routes/JobForm";
import TeamAccess from "./routes/TeamAccess";
import CreateNewTeam from "./routes/CreateNewTeam";
import InputSkills from "./routes/InputSkills";
+import InputJobDescription from "./routes/InputJobDescription";
import ReduxToastr from "react-redux-toastr";
import store from "./store";
import "./styles/main.vendor.scss";
@@ -33,6 +34,7 @@ export default function Root() {
+
diff --git a/src/routes/CreateNewTeam/index.jsx b/src/routes/CreateNewTeam/index.jsx
index 08701d91..3f4a5d91 100644
--- a/src/routes/CreateNewTeam/index.jsx
+++ b/src/routes/CreateNewTeam/index.jsx
@@ -30,6 +30,10 @@ function CreateNewTeam() {
});
};
+ const goToJobDescription = ()=> {
+ navigate(`/taas/myteams/createnewteam/jd`);
+ }
+
return (
@@ -55,7 +59,7 @@ function CreateNewTeam() {
description="You would like to use a description to explain what you need."
icon={}
backgroundImage="linear-gradient(135deg, #2984BD 0%, #0AB88A 100%)"
- isDisabled
+ onClick={goToJobDescription}
/>
);
diff --git a/src/routes/InputJobDescription/components/Popup/index.jsx b/src/routes/InputJobDescription/components/Popup/index.jsx
new file mode 100644
index 00000000..38aaae61
--- /dev/null
+++ b/src/routes/InputJobDescription/components/Popup/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 Popup({ open, skills, onClose, isLoading, onContinueClick }) {
+ return (
+
+ }
+ styles={{
+ modal: modalStyle,
+ modalContainer: containerStyle,
+ }}
+ >
+
+ {isLoading ? (
+ <>
+
+
loading skills
+ >
+ ) : (
+ <>
+
+
skills
+ {_.map(skills, (s) => {
+ return
{s.tag}
;
+ })}
+ >
+ )}
+
+
+
+
+
+ );
+}
+
+Popup.propTypes = {
+ open: PT.bool,
+ onClose: PT.func,
+ isLoading: PT.bool,
+ onContinueClick: PT.func,
+ skills: PT.arrayOf(PT.shape()),
+};
+
+export default Popup;
diff --git a/src/routes/InputJobDescription/components/Popup/styles.module.scss b/src/routes/InputJobDescription/components/Popup/styles.module.scss
new file mode 100644
index 00000000..b0270326
--- /dev/null
+++ b/src/routes/InputJobDescription/components/Popup/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/InputJobDescription/index.jsx b/src/routes/InputJobDescription/index.jsx
new file mode 100644
index 00000000..15581565
--- /dev/null
+++ b/src/routes/InputJobDescription/index.jsx
@@ -0,0 +1,145 @@
+/**
+ * Input Job Description page
+ *
+ */
+import React, { useCallback, useEffect, useState } from "react";
+import { useData } from "hooks/useData";
+import { navigate } from "@reach/router";
+import { toastr } from "react-redux-toastr";
+import MarkdownEditor from "../../components/MarkdownEditor";
+import { getSkillsByJobDescription } from "../../services/teams";
+import Page from "components/Page";
+import PageHeader from "components/PageHeader";
+import PT from "prop-types";
+import Completeness from "components/Completeness";
+import { getSkills } from "services/skills";
+import LoadingIndicator from "components/LoadingIndicator";
+import SearchCard from "components/SearchCard";
+import ResultCard from "components/ResultCard";
+import AddAnotherModal from "components/AddAnotherModal";
+import SkillListPopup from "./components/Popup";
+import "./styles.module.scss";
+import withAuthentication from "../../hoc/withAuthentication";
+import IconOfficeFileText from "../../assets/images/icon-office-file-text.svg";
+
+function InputJobDescription() {
+ 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");
+ setTimeout(() => {
+ 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 ? (
+
+
+
}
+ onClick={onSearch}
+ buttonLabel="Search"
+ stage={1}
+ />
+
setSkillModalOpen(false)}
+ isLoading={isLoadingSkills}
+ onContinueClick={onConfirationClick}
+ />
+
+ ) : searchState === "searching" ? (
+
+
+ }
+ isDisabled
+ buttonLabel="Submit Request"
+ stage={2}
+ />
+
+ ) : (
+
+
+
}
+ buttonLabel="Submit Request"
+ stage={3}
+ onClick={submitJob}
+ />
+
setModalOpen(false)}
+ submitDone={submitDone}
+ addAnother={addAnother}
+ />
+
+ )}
+
+ );
+}
+
+InputJobDescription.propTypes = {
+ projectId: PT.string,
+};
+
+export default withAuthentication(InputJobDescription);
diff --git a/src/routes/InputJobDescription/styles.module.scss b/src/routes/InputJobDescription/styles.module.scss
new file mode 100644
index 00000000..31e3ca4b
--- /dev/null
+++ b/src/routes/InputJobDescription/styles.module.scss
@@ -0,0 +1,17 @@
+.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;
+ }
+}
diff --git a/src/routes/InputSkills/index.jsx b/src/routes/InputSkills/index.jsx
index a69d6e95..be4d89d9 100644
--- a/src/routes/InputSkills/index.jsx
+++ b/src/routes/InputSkills/index.jsx
@@ -12,16 +12,17 @@ import { useData } from "hooks/useData";
import { navigate } from "@reach/router";
import { toastr } from "react-redux-toastr";
import PT from "prop-types";
-import SkillsList from "./components/SkillsList";
-import Completeness from "./components/Completeness";
+import Completeness from "components/Completeness";
import "./styles.module.scss";
import { getSkills } from "services/skills";
import LoadingIndicator from "components/LoadingIndicator";
-import SearchCard from "./components/SearchCard";
-import ResultCard from "./components/ResultCard";
+import SearchCard from "components/SearchCard";
+import ResultCard from "components/ResultCard";
import { createJob } from "services/jobs";
-import AddAnotherModal from "./components/AddAnotherModal";
+import AddAnotherModal from "components/AddAnotherModal";
+import SkillsList from "./components/SkillsList";
import withAuthentication from "../../hoc/withAuthentication";
+import IconListQuill from "../../assets/images/icon-list-quill.svg";
function InputSkills({ projectId }) {
const [selectedSkills, setSelectedSkills] = useState([]);
@@ -91,6 +92,9 @@ function InputSkills({ projectId }) {
toggleSkill={toggleSkill}
/>
}
isDisabled={selectedSkills.length < 1}
onClick={search}
buttonLabel="Search"
@@ -100,12 +104,21 @@ function InputSkills({ projectId }) {
) : searchState === "searching" ? (
-
+ }
+ isDisabled
+ buttonLabel="Submit Request"
+ stage={2} />
) : (
}
buttonLabel="Submit Request"
stage={3}
onClick={submitJob}
diff --git a/src/services/teams.js b/src/services/teams.js
index 0d4aa79f..f220a1d6 100644
--- a/src/services/teams.js
+++ b/src/services/teams.js
@@ -31,6 +31,17 @@ export const getV5UserProfile = () => {
return axios.get(`${config.API.V5}/taas-teams/me`);
};
+/**
+ * Get skills by job description
+ * @param {string} description
+ * @returns {Promise<{}>} skills list
+ */
+export const getSkillsByJobDescription = (description) => {
+ return axios.post(`${config.API.V5}/taas-teams/getSkillsByJobDescription`, {
+ description,
+ });
+};
+
/**
* Get team by id.
*