@@ -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.
+ 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 @@
+
+
\ 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.
-
+ )
+ )}
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={
- {showDescription && (
-
+ {showAdvanced && (
+ <>
+
+
+ >
)}
@@ -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.
*