From 9c63cc2984ba38e1e978387aece5cdb4b2bf703d Mon Sep 17 00:00:00 2001 From: Michael Baghel Date: Wed, 14 Jul 2021 11:36:48 +0400 Subject: [PATCH 1/4] Label updates and simple UI style fixes Resolves: #363, #366, #367, #368, #369, #371, #372 --- .../NoMatchingProfilesResultCard/index.jsx | 9 ++-- .../styles.module.scss | 2 +- .../components/ResultCard/index.jsx | 15 +----- .../components/SearchContainer/index.jsx | 2 +- .../components/SubmitContainer/index.jsx | 2 +- src/routes/CreateNewTeam/index.jsx | 8 +-- .../components/SkillListPopup/index.jsx | 10 ++-- .../SkillListPopup/styles.module.scss | 51 +++---------------- .../pages/InputJobDescription/index.jsx | 7 +++ .../InputJobDescription/styles.module.scss | 7 +++ .../SelectRole/components/RoleItem/index.jsx | 2 +- 11 files changed, 40 insertions(+), 75 deletions(-) diff --git a/src/routes/CreateNewTeam/components/NoMatchingProfilesResultCard/index.jsx b/src/routes/CreateNewTeam/components/NoMatchingProfilesResultCard/index.jsx index 2085ab7c..7606b4b8 100644 --- a/src/routes/CreateNewTeam/components/NoMatchingProfilesResultCard/index.jsx +++ b/src/routes/CreateNewTeam/components/NoMatchingProfilesResultCard/index.jsx @@ -42,7 +42,7 @@ function NoMatchingProfilesResultCard({ role }) {
-

No Matching Profiles

+

Additional Evaluation Needed

@@ -53,8 +53,11 @@ function NoMatchingProfilesResultCard({ role }) { : "Custom Role"}

- We will be looking internally for members matching your requirements - and be back at them in about 2 weeks. + We did not get a perfect match to your requirements on the first pass, + but we are confident they are out there. We'd like to dig a little + deeper into our community to find someone who can fit your needs. This + may take up to two weeks. Please continue to submit your request, and + a Topcoder representative will reach out to you soon with next steps.

{role.rates && role.name ? (
diff --git a/src/routes/CreateNewTeam/components/NoMatchingProfilesResultCard/styles.module.scss b/src/routes/CreateNewTeam/components/NoMatchingProfilesResultCard/styles.module.scss index b39ab76b..d60db1e5 100644 --- a/src/routes/CreateNewTeam/components/NoMatchingProfilesResultCard/styles.module.scss +++ b/src/routes/CreateNewTeam/components/NoMatchingProfilesResultCard/styles.module.scss @@ -56,7 +56,7 @@ @include font-roboto; font-size: 14px; line-height: 22px; - width: 357px; + width: 80%; text-align: center; } .niche-rate-box { diff --git a/src/routes/CreateNewTeam/components/ResultCard/index.jsx b/src/routes/CreateNewTeam/components/ResultCard/index.jsx index 07f21c13..87b8e469 100644 --- a/src/routes/CreateNewTeam/components/ResultCard/index.jsx +++ b/src/routes/CreateNewTeam/components/ResultCard/index.jsx @@ -245,20 +245,7 @@ function ResultCard({ role }) {

Members matched

-
-

- 60% of members are available 20 hours / week (part - time) -

-

- 20% of members are available 30 hours / week (part - time) -

-

- 10% of members are available 40 hours / week (full - time) -

-
+
)} diff --git a/src/routes/CreateNewTeam/components/SearchContainer/index.jsx b/src/routes/CreateNewTeam/components/SearchContainer/index.jsx index 33f1a580..2a02501d 100644 --- a/src/routes/CreateNewTeam/components/SearchContainer/index.jsx +++ b/src/routes/CreateNewTeam/components/SearchContainer/index.jsx @@ -59,7 +59,7 @@ function SearchContainer({ } onClick={() => setAddAnotherOpen(true)} extraStyleName={completenessStyle} - buttonLabel="Submit Request" + buttonLabel="Continue" stages={stages} percentage={getPercentage()} /> diff --git a/src/routes/CreateNewTeam/components/SubmitContainer/index.jsx b/src/routes/CreateNewTeam/components/SubmitContainer/index.jsx index b7bfdc40..96e52738 100644 --- a/src/routes/CreateNewTeam/components/SubmitContainer/index.jsx +++ b/src/routes/CreateNewTeam/components/SubmitContainer/index.jsx @@ -119,7 +119,7 @@ function SubmitContainer({ setAddAnotherOpen(true)} extraStyleName={completenessStyle} - buttonLabel="Submit Request" + buttonLabel="Continue" stages={stages} percentage="98" /> diff --git a/src/routes/CreateNewTeam/index.jsx b/src/routes/CreateNewTeam/index.jsx index 7140a739..570bd41a 100644 --- a/src/routes/CreateNewTeam/index.jsx +++ b/src/routes/CreateNewTeam/index.jsx @@ -32,22 +32,22 @@ function CreateNewTeam() { Please select how you want to find members that match your requirements.

} backgroundImage="linear-gradient(101.95deg, #8B41B0 0%, #EF476F 100%)" onClick={() => goToRoute("/taas/createnewteam/role")} /> } backgroundImage="linear-gradient(221.5deg, #2C95D7 0%, #9D41C9 100%)" onClick={() => goToRoute("/taas/createnewteam/skills")} /> } backgroundImage="linear-gradient(135deg, #2984BD 0%, #0AB88A 100%)" onClick={() => goToRoute("/taas/createnewteam/jd")} diff --git a/src/routes/CreateNewTeam/pages/InputJobDescription/components/SkillListPopup/index.jsx b/src/routes/CreateNewTeam/pages/InputJobDescription/components/SkillListPopup/index.jsx index 6d095ca5..0597ba98 100644 --- a/src/routes/CreateNewTeam/pages/InputJobDescription/components/SkillListPopup/index.jsx +++ b/src/routes/CreateNewTeam/pages/InputJobDescription/components/SkillListPopup/index.jsx @@ -32,10 +32,10 @@ function SkillListPopup({ open, skills, isLoading, onClose, onContinueClick }) { open={open} onClose={onClose} headerIcon={} - title="Skills" + title="Identified Skills" subtitle={ skills.length - ? "These skills are found in your Job Description" + ? "Topcoder has identified the following skills referenced in your Job Description." : "No skills are found in your Job Description" } isLoading={isLoading} @@ -43,11 +43,11 @@ function SkillListPopup({ open, skills, isLoading, onClose, onContinueClick }) { maxWidth="460px" buttons={Buttons} > -
+
    {_.map(skills, (s) => { - return
    {s.tag}
    ; + return
  • {s.tag}
  • ; })} -
+ ); } diff --git a/src/routes/CreateNewTeam/pages/InputJobDescription/components/SkillListPopup/styles.module.scss b/src/routes/CreateNewTeam/pages/InputJobDescription/components/SkillListPopup/styles.module.scss index b0270326..ee0c59e2 100644 --- a/src/routes/CreateNewTeam/pages/InputJobDescription/components/SkillListPopup/styles.module.scss +++ b/src/routes/CreateNewTeam/pages/InputJobDescription/components/SkillListPopup/styles.module.scss @@ -1,48 +1,9 @@ @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; +.list { + @include font-roboto; + font-size: 18px; + line-height: normal; + color: #2a2a2a; 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; - } -} +} \ No newline at end of file diff --git a/src/routes/CreateNewTeam/pages/InputJobDescription/index.jsx b/src/routes/CreateNewTeam/pages/InputJobDescription/index.jsx index 10e1809b..1fbfee71 100644 --- a/src/routes/CreateNewTeam/pages/InputJobDescription/index.jsx +++ b/src/routes/CreateNewTeam/pages/InputJobDescription/index.jsx @@ -67,6 +67,13 @@ function InputJobDescription() { title={
Input Job Description
} backTo="/taas/createnewteam" /> +

+ Input a Job Description for your opening and the Topcoder Platform + will identify the skills required to perform the job duties and find + the best matching freelancers for your job opening. After inputting + the Job Description click on the "Search" button to see the skills + identified. +

- Description + View Description & Skills
); From 81ab3ee6ddfb952290a492ff39cd9c128ae615c1 Mon Sep 17 00:00:00 2001 From: Michael Baghel Date: Wed, 14 Jul 2021 13:47:12 +0400 Subject: [PATCH 2/4] feat: Integrate Customer Scroll - Add Customer Scroll to all pages under createnewteam route - Refactor Create New Team Landing Page to its own component - Change createnewteam routes to nested routes to facilitate code sharing - Change height on ItemList and Job Description input components to avoid overlapping with Customer Scroll Resolves: #355 --- src/assets/images/customer-logos.svg | 139 ++++++++++++++++++ src/components/CustomerScroll/index.jsx | 13 ++ .../CustomerScroll/styles.module.scss | 45 ++++++ src/root.component.jsx | 11 +- .../components/ItemList/styles.module.scss | 2 +- src/routes/CreateNewTeam/index.jsx | 62 ++------ .../pages/CreateTeamLanding/index.jsx | 58 ++++++++ .../CreateTeamLanding/styles.module.scss | 3 + .../pages/InputJobDescription/index.jsx | 2 +- src/routes/CreateNewTeam/styles.module.scss | 20 ++- 10 files changed, 296 insertions(+), 59 deletions(-) create mode 100644 src/assets/images/customer-logos.svg create mode 100644 src/components/CustomerScroll/index.jsx create mode 100644 src/components/CustomerScroll/styles.module.scss create mode 100644 src/routes/CreateNewTeam/pages/CreateTeamLanding/index.jsx create mode 100644 src/routes/CreateNewTeam/pages/CreateTeamLanding/styles.module.scss diff --git a/src/assets/images/customer-logos.svg b/src/assets/images/customer-logos.svg new file mode 100644 index 00000000..0719e61e --- /dev/null +++ b/src/assets/images/customer-logos.svg @@ -0,0 +1,139 @@ + + + Homepage-Logos + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/components/CustomerScroll/index.jsx b/src/components/CustomerScroll/index.jsx new file mode 100644 index 00000000..bc89cecf --- /dev/null +++ b/src/components/CustomerScroll/index.jsx @@ -0,0 +1,13 @@ +import React from "react"; +import "./styles.module.scss"; + +function CustomerScroll() { + return ( +
+
Trusted By
+
+
+ ); +} + +export default CustomerScroll; diff --git a/src/components/CustomerScroll/styles.module.scss b/src/components/CustomerScroll/styles.module.scss new file mode 100644 index 00000000..35c004fb --- /dev/null +++ b/src/components/CustomerScroll/styles.module.scss @@ -0,0 +1,45 @@ +@import "styles/include"; + +.title { + @include font-barlow; + font-weight: 600; + font-size: 22px; + color: #7f7f7f; + text-align: center; + text-transform: uppercase; + margin-bottom: 30px; +} + +@keyframes scroll { + from {background-position: 0 0;} + to {background-position: -7701px 0;} +} + +.scrolling-logos { + background-image: url("../../assets/images/customer-logos.svg"); + height: 60px; + width: 100%; + animation: scroll 300s linear infinite; + position: relative; + + &:before { + background: linear-gradient(to right, #F4F5F6 0%, rgba(255, 255, 255, 0) 100%); + content: ''; + height: 60px; + left: 0; + position: absolute; + top: 0; + width: 60px; + z-index: 2; + } + &:after { + background: linear-gradient(to right, rgba(255, 255, 255, 0) 0%, #F4F5F6 100%); + content: ''; + height: 60px; + position: absolute; + right: 0; + top: 0; + width: 60px; + z-index: 2; + } +} \ No newline at end of file diff --git a/src/root.component.jsx b/src/root.component.jsx index bdd3b79b..4392f546 100644 --- a/src/root.component.jsx +++ b/src/root.component.jsx @@ -10,6 +10,7 @@ import JobDetails from "./routes/JobDetails"; import JobForm from "./routes/JobForm"; import TeamAccess from "./routes/TeamAccess"; import CreateNewTeam from "./routes/CreateNewTeam"; +import CreateTeamLanding from "./routes/CreateNewTeam/pages/CreateTeamLanding"; import InputSkills from "./routes/CreateNewTeam/pages/InputSkills"; import InputJobDescription from "./routes/CreateNewTeam/pages/InputJobDescription"; import SelectRole from "./routes/CreateNewTeam/pages/SelectRole"; @@ -25,7 +26,6 @@ export default function Root() { - @@ -34,9 +34,12 @@ export default function Root() { - - - + + + + + + {/* Global config for Toastr popups */} diff --git a/src/routes/CreateNewTeam/components/ItemList/styles.module.scss b/src/routes/CreateNewTeam/components/ItemList/styles.module.scss index cf201197..3ee04ddc 100644 --- a/src/routes/CreateNewTeam/components/ItemList/styles.module.scss +++ b/src/routes/CreateNewTeam/components/ItemList/styles.module.scss @@ -6,7 +6,7 @@ width: 100%; margin-right: 20px; position: relative; - height: 80vh; + height: 70vh; overflow-y: auto; .title { diff --git a/src/routes/CreateNewTeam/index.jsx b/src/routes/CreateNewTeam/index.jsx index 570bd41a..44c07e6c 100644 --- a/src/routes/CreateNewTeam/index.jsx +++ b/src/routes/CreateNewTeam/index.jsx @@ -1,59 +1,19 @@ /** * Create New Team * - * Landing page for creating new teams - * by selecting a role, inputting skills, - * or inputting a job description + * Container for Create New Team subroutes */ -import React, { useEffect } from "react"; -import { useDispatch } from "react-redux"; -import { navigate } from "@reach/router"; -import _ from "lodash"; -import Page from "components/Page"; -import PageHeader from "components/PageHeader"; -import LandingBox from "./components/LandingBox"; -import { clearMatchingRole } from "./actions"; -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 React from "react"; +import CustomerScroll from "components/CustomerScroll"; import "./styles.module.scss"; -function CreateNewTeam() { - const dispatch = useDispatch(); - const goToRoute = (path) => { - dispatch(clearMatchingRole()); - navigate(path); - }; - - return ( - - Create New Team
} /> -

- Please select how you want to find members that match your requirements. -

- } - backgroundImage="linear-gradient(101.95deg, #8B41B0 0%, #EF476F 100%)" - onClick={() => goToRoute("/taas/createnewteam/role")} - /> - } - backgroundImage="linear-gradient(221.5deg, #2C95D7 0%, #9D41C9 100%)" - onClick={() => goToRoute("/taas/createnewteam/skills")} - /> - } - backgroundImage="linear-gradient(135deg, #2984BD 0%, #0AB88A 100%)" - onClick={() => goToRoute("/taas/createnewteam/jd")} - /> - - ); -} +const CreateNewTeam = (props) => ( +
+ {props.children} +
+ +
+
+); export default CreateNewTeam; diff --git a/src/routes/CreateNewTeam/pages/CreateTeamLanding/index.jsx b/src/routes/CreateNewTeam/pages/CreateTeamLanding/index.jsx new file mode 100644 index 00000000..cae9e49a --- /dev/null +++ b/src/routes/CreateNewTeam/pages/CreateTeamLanding/index.jsx @@ -0,0 +1,58 @@ +/** + * Create Team Landing + * + * Landing page for creating new teams + * by selecting a role, inputting skills, + * or inputting a job description + */ +import React from "react"; +import { useDispatch } from "react-redux"; +import { navigate } from "@reach/router"; +import Page from "components/Page"; +import PageHeader from "components/PageHeader"; +import LandingBox from "../../components/LandingBox"; +import { clearMatchingRole } from "../../actions"; +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 "./styles.module.scss"; + +function CreateNewTeam() { + const dispatch = useDispatch(); + const goToRoute = (path) => { + dispatch(clearMatchingRole()); + navigate(path); + }; + + return ( + + Create New Team} /> +

+ Please select how you want to find members that match your requirements. +

+ } + backgroundImage="linear-gradient(101.95deg, #8B41B0 0%, #EF476F 100%)" + onClick={() => goToRoute("/taas/createnewteam/role")} + /> + } + backgroundImage="linear-gradient(221.5deg, #2C95D7 0%, #9D41C9 100%)" + onClick={() => goToRoute("/taas/createnewteam/skills")} + /> + } + backgroundImage="linear-gradient(135deg, #2984BD 0%, #0AB88A 100%)" + onClick={() => goToRoute("/taas/createnewteam/jd")} + /> +
+ ); +} + +export default CreateNewTeam; diff --git a/src/routes/CreateNewTeam/pages/CreateTeamLanding/styles.module.scss b/src/routes/CreateNewTeam/pages/CreateTeamLanding/styles.module.scss new file mode 100644 index 00000000..e1903c90 --- /dev/null +++ b/src/routes/CreateNewTeam/pages/CreateTeamLanding/styles.module.scss @@ -0,0 +1,3 @@ +.title { + font-weight: 500; +} \ No newline at end of file diff --git a/src/routes/CreateNewTeam/pages/InputJobDescription/index.jsx b/src/routes/CreateNewTeam/pages/InputJobDescription/index.jsx index 1fbfee71..1216aaa1 100644 --- a/src/routes/CreateNewTeam/pages/InputJobDescription/index.jsx +++ b/src/routes/CreateNewTeam/pages/InputJobDescription/index.jsx @@ -84,7 +84,7 @@ function InputJobDescription() { /> Date: Thu, 15 Jul 2021 13:44:12 +0400 Subject: [PATCH 3/4] fix: Increase job description length, Change minimum job duration - Validate job descriptions are no longer than 100,000 characters - Validate duration is 4 or greater in Team Details Modal - Change width of Customer scroll Resolves: #362, #374 --- .../components/TeamDetailsModal/index.jsx | 194 +++++++++--------- .../TeamDetailsModal/utils/validator.js | 11 +- .../pages/InputJobDescription/index.jsx | 6 +- src/routes/CreateNewTeam/styles.module.scss | 5 +- 4 files changed, 116 insertions(+), 100 deletions(-) diff --git a/src/routes/CreateNewTeam/components/TeamDetailsModal/index.jsx b/src/routes/CreateNewTeam/components/TeamDetailsModal/index.jsx index 0f8743a1..7f717007 100644 --- a/src/routes/CreateNewTeam/components/TeamDetailsModal/index.jsx +++ b/src/routes/CreateNewTeam/components/TeamDetailsModal/index.jsx @@ -133,100 +133,108 @@ function TeamDetailsModal({ open, onClose, submitForm, addedRoles }) { Start month - {addedRoles.map(({ searchId: id, name, numberOfResources, durationWeeks, startMonth }) => ( - - {name} - - - {({ input, meta }) => ( - + {addedRoles.map( + ({ + searchId: id, + name, + numberOfResources, + durationWeeks, + startMonth, + }) => ( + + {name} + + + {({ input, meta }) => ( + + )} + + + + + + {({ input, meta }) => ( + + )} + + + + + {startMonth || startMonthVisible[id] ? ( + <> + + {(props) => ( + + )} + + + + ) : ( +
+ + +
)} -
- - - - - {({ input, meta }) => ( - - )} - - - - - {startMonth || startMonthVisible[id] ? ( - <> - - {(props) => ( - - )} - - - - ) : ( -
- - -
- )} - - - - - - ))} + + + + + + ) + )} diff --git a/src/routes/CreateNewTeam/components/TeamDetailsModal/utils/validator.js b/src/routes/CreateNewTeam/components/TeamDetailsModal/utils/validator.js index 9e1a9caf..e10139cb 100644 --- a/src/routes/CreateNewTeam/components/TeamDetailsModal/utils/validator.js +++ b/src/routes/CreateNewTeam/components/TeamDetailsModal/utils/validator.js @@ -18,6 +18,15 @@ const validateNumber = (number) => { return undefined; }; +const validateGreaterThan = (number, min) => { + const isInvalidNum = validateNumber(number); + if (isInvalidNum) return isInvalidNum; + + return number < min + ? "Talent as a Service engagements have a 4 week minimum commitment." + : undefined; +}; + const validateMonth = (monthString) => { const then = new Date(monthString); const now = new Date(); @@ -35,7 +44,7 @@ const validateMonth = (monthString) => { const validateRole = (role) => { const roleErrors = {}; roleErrors.numberOfResources = validateNumber(role.numberOfResources); - roleErrors.durationWeeks = validateNumber(role.durationWeeks); + roleErrors.durationWeeks = validateGreaterThan(role.durationWeeks, 4); if (role.startMonth) { roleErrors.startMonth = validateMonth(role.startMonth); } diff --git a/src/routes/CreateNewTeam/pages/InputJobDescription/index.jsx b/src/routes/CreateNewTeam/pages/InputJobDescription/index.jsx index 1216aaa1..c212a93f 100644 --- a/src/routes/CreateNewTeam/pages/InputJobDescription/index.jsx +++ b/src/routes/CreateNewTeam/pages/InputJobDescription/index.jsx @@ -56,7 +56,7 @@ function InputJobDescription() { 2000} + isCompletenessDisabled={jdString.length < 10 || jdString.length > 100000} completenessStyle="input-job-description" searchObject={searchObject} page="jd" @@ -88,8 +88,8 @@ function InputJobDescription() { placeholder="input job description" onChange={onEditChange} errorMessage={ - jdString.length > 2000 - ? "Maximum of 2000 characters. Please reduce job description length." + jdString.length > 100000 + ? "Maximum of 100,000 characters. Please reduce job description length." : "" } /> diff --git a/src/routes/CreateNewTeam/styles.module.scss b/src/routes/CreateNewTeam/styles.module.scss index c24b9708..045668bd 100644 --- a/src/routes/CreateNewTeam/styles.module.scss +++ b/src/routes/CreateNewTeam/styles.module.scss @@ -1,14 +1,13 @@ .logos { position: fixed; bottom: 15px; - width: calc(100vw - 340px); - margin-left: 35px; + width: calc(100vw - 270px); z-index: -1; } @media only screen and (max-width: 1023px) { .logos { - width: calc(100vw - 70px) + width: 100vw; } } From 0cbe16ed68a298637021f89de6ac97b6c711f0e4 Mon Sep 17 00:00:00 2001 From: Michael Baghel <31278895+mbaghel@users.noreply.github.com> Date: Thu, 15 Jul 2021 15:10:46 +0400 Subject: [PATCH 4/4] feat: Update Team Details Labels & add additional options under "Advanced" Resolves: #365 --- package-lock.json | 29 ++++++++-- package.json | 3 +- .../components/SubmitContainer/index.jsx | 10 +++- .../components/TeamDetailsModal/index.jsx | 55 ++++++++++++------- .../TeamDetailsModal/styles.module.scss | 2 +- .../TeamDetailsModal/utils/validator.js | 4 +- src/utils/helpers.js | 9 +++ 7 files changed, 81 insertions(+), 31 deletions(-) diff --git a/package-lock.json b/package-lock.json index da18caae..b524184a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -14995,6 +14995,12 @@ "psl": "^1.1.28", "punycode": "^2.1.1" } + }, + "uuid": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", + "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", + "dev": true } } }, @@ -15873,6 +15879,14 @@ "faye-websocket": "^0.10.0", "uuid": "^3.4.0", "websocket-driver": "0.6.5" + }, + "dependencies": { + "uuid": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", + "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", + "dev": true + } } }, "sockjs-client": { @@ -17104,10 +17118,9 @@ "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=" }, "uuid": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", - "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", - "dev": true + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==" }, "v8-compile-cache": { "version": "2.1.1", @@ -17755,6 +17768,14 @@ "requires": { "ansi-colors": "^3.0.0", "uuid": "^3.3.2" + }, + "dependencies": { + "uuid": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", + "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", + "dev": true + } } }, "webpack-merge": { diff --git a/package.json b/package.json index 61cd6967..a95fce45 100644 --- a/package.json +++ b/package.json @@ -87,7 +87,8 @@ "redux-logger": "^3.0.6", "redux-promise-middleware": "^6.1.2", "redux-thunk": "^2.3.0", - "tc-auth-lib": "topcoder-platform/tc-auth-lib#1.0.4" + "tc-auth-lib": "topcoder-platform/tc-auth-lib#1.0.4", + "uuid": "^8.3.2" }, "browserslist": [ "last 1 version", diff --git a/src/routes/CreateNewTeam/components/SubmitContainer/index.jsx b/src/routes/CreateNewTeam/components/SubmitContainer/index.jsx index 96e52738..56d1f1b1 100644 --- a/src/routes/CreateNewTeam/components/SubmitContainer/index.jsx +++ b/src/routes/CreateNewTeam/components/SubmitContainer/index.jsx @@ -23,7 +23,7 @@ import TeamDetailsModal from "../TeamDetailsModal"; import ConfirmationModal from "../ConfirmationModal"; import withAuthentication from "../../../../hoc/withAuthentication"; import "./styles.module.scss"; -import { isCustomRole, setCurrentStage } from "utils/helpers"; +import { isCustomRole, isUuid, setCurrentStage } from "utils/helpers"; import { clearSearchedRoles } from "../../actions"; import { postTeamRequest } from "services/teams"; import NoMatchingProfilesResultCard from "../NoMatchingProfilesResultCard"; @@ -65,11 +65,15 @@ function SubmitContainer({ }; const assembleTeam = (formData) => { - const teamObject = _.pick(formData, ["teamName", "teamDescription"]); + const teamObject = _.pick(formData, [ + "teamName", + "teamDescription", + "refCode", + ]); const positions = []; for (let key of Object.keys(formData)) { - if (key === "teamName" || key === "teamDescription") { + if (!isUuid(key)) { continue; } const position = _.mapValues(formData[key], (val, key) => diff --git a/src/routes/CreateNewTeam/components/TeamDetailsModal/index.jsx b/src/routes/CreateNewTeam/components/TeamDetailsModal/index.jsx index 7f717007..fde71b11 100644 --- a/src/routes/CreateNewTeam/components/TeamDetailsModal/index.jsx +++ b/src/routes/CreateNewTeam/components/TeamDetailsModal/index.jsx @@ -11,6 +11,7 @@ import FormField from "components/FormField"; import BaseCreateModal from "../BaseCreateModal"; import { FORM_FIELD_TYPE } from "constants/"; import { formatPlural } from "utils/format"; +import { isUuid } from "utils/helpers"; import Button from "components/Button"; import MonthPicker from "components/MonthPicker"; import InformationTooltip from "components/InformationTooltip"; @@ -28,7 +29,7 @@ const Error = ({ name }) => { }; function TeamDetailsModal({ open, onClose, submitForm, addedRoles }) { - const [showDescription, setShowDescription] = useState(false); + const [showAdvanced, setShowAdvanced] = useState(false); const [startMonthVisible, setStartMonthVisible] = useState({}); // Ensure role is removed from form state when it is removed from redux store @@ -37,7 +38,7 @@ function TeamDetailsModal({ open, onClose, submitForm, addedRoles }) { useEffect(() => { const values = getFormState().values; for (let fieldName of Object.keys(values)) { - if (fieldName === "teamName" || fieldName === "teamDescription") { + if (!isUuid(fieldName)) { continue; } if (addedRoles.findIndex((role) => role.searchId === fieldName) === -1) { @@ -49,8 +50,8 @@ function TeamDetailsModal({ open, onClose, submitForm, addedRoles }) { const dispatch = useDispatch(); - const toggleDescription = () => { - setShowDescription((prevState) => !prevState); + const toggleAdvanced = () => { + setShowAdvanced((prevState) => !prevState); }; return ( @@ -78,7 +79,7 @@ function TeamDetailsModal({ open, onClose, submitForm, addedRoles }) { open={open} onClose={onClose} title="Team Details" - subtitle="Please provide your team details before submitting a request." + subtitle="Please provide a name for your Team. This could be the name of the project they will work on, the name of the team they are joining, or whatever else will make this talent request meaningful for you." buttons={ @@ -147,7 +160,7 @@ function TeamDetailsModal({ open, onClose, submitForm, addedRoles }) { {({ input, meta }) => ( {({ input, meta }) => ( span { font-size: 18px; diff --git a/src/routes/CreateNewTeam/components/TeamDetailsModal/utils/validator.js b/src/routes/CreateNewTeam/components/TeamDetailsModal/utils/validator.js index e10139cb..d5290486 100644 --- a/src/routes/CreateNewTeam/components/TeamDetailsModal/utils/validator.js +++ b/src/routes/CreateNewTeam/components/TeamDetailsModal/utils/validator.js @@ -1,3 +1,5 @@ +import { isUuid } from "utils/helpers"; + const validateName = (name) => { if (!name || name.trim().length === 0) { return "Please enter a team name."; @@ -58,7 +60,7 @@ const validator = (values) => { errors.teamName = validateName(values.teamName); for (const key of Object.keys(values)) { - if (key === "teamDescription" || key === "teamName") continue; + if (!isUuid(key)) continue; errors[key] = validateRole(values[key]); } diff --git a/src/utils/helpers.js b/src/utils/helpers.js index c54cbe5f..60eea1d5 100644 --- a/src/utils/helpers.js +++ b/src/utils/helpers.js @@ -5,8 +5,17 @@ * If there are multiple methods which could be grouped into a separate file by their meaning they should be extracted from here to not make this file too big. */ import _ from "lodash"; +import { validate } from "uuid"; + import { CUSTOM_ROLE_NAMES } from "constants/"; +/** + * @param {String} string a possible uuid + * + * @returns {Boolean} true if uuid, false if not + */ +export const isUuid = validate; + /** * Delay code for some milliseconds using promise. *