From 39a44a339211a49dbdb4c01c2b961d0ea860e66e Mon Sep 17 00:00:00 2001 From: maxceem Date: Tue, 12 Jan 2021 23:54:31 +0200 Subject: [PATCH 01/90] feat: track page analytics and page titles --- src/components/LayoutContainer/index.jsx | 18 ---------- src/components/Page/index.jsx | 33 +++++++++++++++++++ .../styles.module.scss | 2 +- src/routes/MyTeamsDetails/index.jsx | 6 ++-- src/routes/MyTeamsList/index.jsx | 6 ++-- src/routes/PositionDetails/index.jsx | 6 ++-- src/utils/format.js | 14 ++++++++ 7 files changed, 57 insertions(+), 28 deletions(-) delete mode 100644 src/components/LayoutContainer/index.jsx create mode 100644 src/components/Page/index.jsx rename src/components/{LayoutContainer => Page}/styles.module.scss (66%) diff --git a/src/components/LayoutContainer/index.jsx b/src/components/LayoutContainer/index.jsx deleted file mode 100644 index 6f7046af..00000000 --- a/src/components/LayoutContainer/index.jsx +++ /dev/null @@ -1,18 +0,0 @@ -/** - * LayoutContainer - * - * Common container for pages. - */ -import React from "react"; -import PT from "prop-types"; -import "./styles.module.scss"; - -const LayoutContainer = ({ children }) => { - return
{children}
; -}; - -LayoutContainer.propTypes = { - children: PT.node, -}; - -export default LayoutContainer; diff --git a/src/components/Page/index.jsx b/src/components/Page/index.jsx new file mode 100644 index 00000000..3b06b3aa --- /dev/null +++ b/src/components/Page/index.jsx @@ -0,0 +1,33 @@ +/** + * Page + * + * Handles common stuff for pages. + * Should wrap each page. + */ +import React, { useEffect } from "react"; +import PT from "prop-types"; +import "./styles.module.scss"; +import { formatPageTitle } from "utils/format"; + +const Page = ({ children, title }) => { + // set page title and triggering analytics + useEffect(() => { + // we set title manually like this instead of using `react-helmet` because of the issue: + // https://github.com/nfl/react-helmet/issues/189 + document.title = formatPageTitle(title); + + // call analytics if the parent Frame app initialized it + if (window.analytics && typeof window.analytics.page === "function") { + window.analytics.page(); + } + }, [title]); + + return
{children}
; +}; + +Page.propTypes = { + children: PT.node, + title: PT.string, +}; + +export default Page; diff --git a/src/components/LayoutContainer/styles.module.scss b/src/components/Page/styles.module.scss similarity index 66% rename from src/components/LayoutContainer/styles.module.scss rename to src/components/Page/styles.module.scss index 671a3abd..88860a5b 100644 --- a/src/components/LayoutContainer/styles.module.scss +++ b/src/components/Page/styles.module.scss @@ -1,3 +1,3 @@ -.container { +.page { padding: 0 35px 32px; } diff --git a/src/routes/MyTeamsDetails/index.jsx b/src/routes/MyTeamsDetails/index.jsx index c8e258d1..588cc109 100644 --- a/src/routes/MyTeamsDetails/index.jsx +++ b/src/routes/MyTeamsDetails/index.jsx @@ -6,7 +6,7 @@ */ import React from "react"; import PT from "prop-types"; -import LayoutContainer from "components/LayoutContainer"; +import Page from "components/Page"; import PageHeader from "components/PageHeader"; import { useData } from "hooks/useData"; import { getTeamById } from "services/teams"; @@ -21,7 +21,7 @@ const MyTeamsDetails = ({ teamId }) => { const [team, loadingError] = useData(getTeamById, teamId); return ( - + {!team ? ( ) : ( @@ -32,7 +32,7 @@ const MyTeamsDetails = ({ teamId }) => { )} - + ); }; diff --git a/src/routes/MyTeamsList/index.jsx b/src/routes/MyTeamsList/index.jsx index afc92e73..cb35ab06 100644 --- a/src/routes/MyTeamsList/index.jsx +++ b/src/routes/MyTeamsList/index.jsx @@ -5,7 +5,7 @@ */ import React, { useCallback, useState, useEffect } from "react"; import _ from "lodash"; -import LayoutContainer from "components/LayoutContainer"; +import Page from "components/Page"; import PageHeader from "components/PageHeader"; import Input from "components/Input"; import Pagination from "components/Pagination"; @@ -60,7 +60,7 @@ const MyTeamsList = () => { ); return ( - + { )} )} - + ); }; diff --git a/src/routes/PositionDetails/index.jsx b/src/routes/PositionDetails/index.jsx index cb9d3ae6..cd916f24 100644 --- a/src/routes/PositionDetails/index.jsx +++ b/src/routes/PositionDetails/index.jsx @@ -5,7 +5,7 @@ */ import React, { useCallback, useState } from "react"; import PT from "prop-types"; -import LayoutContainer from "components/LayoutContainer"; +import Page from "components/Page"; import LoadingIndicator from "components/LoadingIndicator"; import PageHeader from "components/PageHeader"; import { CANDIDATE_STATUS } from "constants"; @@ -30,7 +30,7 @@ const PositionDetails = ({ teamId, positionId }) => { ); return ( - + {!position ? ( ) : ( @@ -53,7 +53,7 @@ const PositionDetails = ({ teamId, positionId }) => { /> )} - + ); }; diff --git a/src/utils/format.js b/src/utils/format.js index edf98638..f36180dd 100644 --- a/src/utils/format.js +++ b/src/utils/format.js @@ -149,3 +149,17 @@ export const formatDateRange = (startDate, endDate) => { return `${startDateStr} - ${endDateStr}`; }; + +/** + * Format page title to show in the browser header. + * + * @param {string} pageTitle page title + */ +export const formatPageTitle = (pageTitle) => { + let formattedPageTitle = "TaaS | Topcoder"; + if (pageTitle) { + formattedPageTitle = pageTitle + " | " + formattedPageTitle; + } + + return formattedPageTitle; +}; From 7512a1c8f1a5fcf9f02fd54cec4a2012fd2b067d Mon Sep 17 00:00:00 2001 From: maxceem Date: Wed, 27 Jan 2021 10:47:50 +0200 Subject: [PATCH 02/90] chore: deploy branch "dev-1_5" --- .circleci/config.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.circleci/config.yml b/.circleci/config.yml index ed03863f..89b6efa1 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -77,6 +77,7 @@ workflows: branches: only: - dev + - dev-1_5 # Production builds are exectuted only on tagged commits to the # master branch. From f219e3fd0956bee38d76ce1126cba8472e9d1679 Mon Sep 17 00:00:00 2001 From: maxceem Date: Wed, 27 Jan 2021 18:38:44 +0200 Subject: [PATCH 03/90] Revert "Merge branch 'master' into dev" This reverts commit 9102ccc3ca5d4fe93be15f64ec1329d976d30641, reversing changes made to c0de69d15ce98048d04f670842bbd501bdba5d8d. --- .vscode/settings.json | 5 ++ README.md | 2 +- babel.config.js | 59 ++++++++++++++++++++ babel.config.json | 51 ----------------- config/{development.js => dev.js} | 0 config/index.js | 6 +- config/{production.js => prod.js} | 0 src/components/Pagination/styles.module.scss | 7 ++- src/components/SkillsList/index.jsx | 1 + src/components/SkillsList/styles.module.scss | 4 +- src/utils/format.js | 4 ++ webpack.config.js | 11 +++- 12 files changed, 92 insertions(+), 58 deletions(-) create mode 100644 .vscode/settings.json create mode 100644 babel.config.js delete mode 100644 babel.config.json rename config/{development.js => dev.js} (100%) rename config/{production.js => prod.js} (100%) diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 00000000..ea4cddfc --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,5 @@ +{ + "javascript.preferences.quoteStyle": "double", + "typescript.preferences.quoteStyle": "double", + "prettier.jsxSingleQuote": false +} diff --git a/README.md b/README.md index aa44f185..4a827f43 100644 --- a/README.md +++ b/README.md @@ -20,7 +20,7 @@ This is a [single-spa](https://single-spa.js.org/) example React microapp. ## Config -For available variables config which depend on the running environment (`development` or `production`), please refer to `config/development.js` and `config/production.js`. +For available variables config which depend on the running environment (`APPENV=dev` or `APPENV=prod`), please refer to `config/dev.js` and `config/prod.js`. For application constants which don't depend on the running environment use `src/constants/index.js`. diff --git a/babel.config.js b/babel.config.js new file mode 100644 index 00000000..07815e13 --- /dev/null +++ b/babel.config.js @@ -0,0 +1,59 @@ +module.exports = function (api) { + const isProd = process.env.APPMODE === "production"; + api.cache(!isProd); + + const generateScopedName = isProd + ? "[hash:base64:6]" + : "teams_[path][name]___[local]___[hash:base64:6]"; + return { + presets: ["@babel/preset-env", "@babel/preset-react"], + plugins: [ + [ + "@babel/plugin-transform-runtime", + { + useESModules: true, + regenerator: false, + }, + ], + [ + "react-css-modules", + { + filetypes: { + ".scss": { + syntax: "postcss-scss", + }, + }, + generateScopedName, + }, + ], + "inline-react-svg", + ], + env: { + test: { + presets: [ + [ + "@babel/preset-env", + { + targets: "current node", + }, + ], + ], + plugins: [ + [ + "module-resolver", + { + alias: { + styles: "./src/styles", + components: "./src/components", + hooks: "./src/hooks", + utils: "./src/utils", + constants: "./src/constants", + services: "./src/services", + }, + }, + ], + ], + }, + }, + }; +}; diff --git a/babel.config.json b/babel.config.json deleted file mode 100644 index 00432fb5..00000000 --- a/babel.config.json +++ /dev/null @@ -1,51 +0,0 @@ -{ - "presets": [ - "@babel/preset-env", - "@babel/preset-react" - ], - "plugins": [ - [ - "@babel/plugin-transform-runtime", - { - "useESModules": true, - "regenerator": false - } - ], - [ - "react-css-modules", - { - "filetypes": { - ".scss": { - "syntax": "postcss-scss" - } - }, - "generateScopedName": "teams_[path][name]___[local]___[hash:base64:6]" - } - ], - "inline-react-svg" - ], - "env": { - "test": { - "presets": [ - [ - "@babel/preset-env", - { - "targets": "current node" - } - ] - ], - "plugins": [ - ["module-resolver", { - "alias": { - "styles": "./src/styles", - "components": "./src/components", - "hooks": "./src/hooks", - "utils": "./src/utils", - "constants": "./src/constants", - "services": "./src/services" - } - }] - ] - } - } -} diff --git a/config/development.js b/config/dev.js similarity index 100% rename from config/development.js rename to config/dev.js diff --git a/config/index.js b/config/index.js index d89d9220..0de81581 100644 --- a/config/index.js +++ b/config/index.js @@ -1,11 +1,11 @@ /* global process */ module.exports = (() => { - const env = process.env.NODE_ENV || "development"; + const env = process.env.APPENV || "dev"; // for security reason don't let to require any arbitrary file defined in process.env - if (["production", "development"].indexOf(env) < 0) { - return require("./development"); + if (["prod", "dev"].indexOf(env) < 0) { + return require("./dev"); } return require("./" + env); diff --git a/config/production.js b/config/prod.js similarity index 100% rename from config/production.js rename to config/prod.js diff --git a/src/components/Pagination/styles.module.scss b/src/components/Pagination/styles.module.scss index 9f0ce714..5c918ff5 100644 --- a/src/components/Pagination/styles.module.scss +++ b/src/components/Pagination/styles.module.scss @@ -2,11 +2,14 @@ .pagination { display: flex; + flex-wrap: wrap; + margin-bottom: -10px; .page { padding: 0 10px; - margin: 0 5px; + margin: 0 5px 10px; min-width: 30px; + } .current { @@ -17,6 +20,7 @@ .next { margin-left: 5px; + margin-bottom: 10px; > svg { transform: rotate(-90deg); @@ -29,6 +33,7 @@ .prev { margin-right: 5px; + margin-bottom: 10px; > svg { margin-right: 3px; diff --git a/src/components/SkillsList/index.jsx b/src/components/SkillsList/index.jsx index edc64219..c4cc1ae4 100644 --- a/src/components/SkillsList/index.jsx +++ b/src/components/SkillsList/index.jsx @@ -101,6 +101,7 @@ const SkillsList = ({ requiredSkills, skills, limit = 3 }) => {
Required Job Skills
    + {!requiredSkills.length &&
  • None
  • } {requiredSkills.map((skill) => (
  • {_.find(skills, { id: skill.id }) ? ( diff --git a/src/components/SkillsList/styles.module.scss b/src/components/SkillsList/styles.module.scss index 637d0967..2b15c443 100644 --- a/src/components/SkillsList/styles.module.scss +++ b/src/components/SkillsList/styles.module.scss @@ -22,10 +22,12 @@ .popover-content { display: flex; - padding: 24px; + flex-wrap: wrap; + padding: 4px 24px 24px; } .skills-section { + margin-top: 20px; padding-right: 32px; } diff --git a/src/utils/format.js b/src/utils/format.js index 54de66f9..47435e12 100644 --- a/src/utils/format.js +++ b/src/utils/format.js @@ -161,5 +161,9 @@ export const formatDateRange = (startDate, endDate) => { const startDateStr = startDate ? moment(startDate).format(DAY_FORMAT) : ""; const endDateStr = endDate ? moment(endDate).format(DAY_FORMAT) : ""; + if (!startDateStr && !endDateStr) { + return "TBD"; + } + return `${startDateStr} - ${endDateStr}`; }; diff --git a/webpack.config.js b/webpack.config.js index 53bce9e0..64dbbbfe 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -1,10 +1,14 @@ /* global __dirname */ +const webpack = require("webpack"); const webpackMerge = require("webpack-merge"); const singleSpaDefaults = require("webpack-config-single-spa-react"); const path = require("path"); const autoprefixer = require("autoprefixer"); -const cssLocalIdent = "teams_[path][name]___[local]___[hash:base64:6]"; + +const cssLocalIdent = process.env.APPMODE === "production" + ? "[hash:base64:6]" + : "teams_[path][name]___[local]___[hash:base64:6]"; module.exports = (webpackConfigEnv) => { const defaultConfig = singleSpaDefaults({ @@ -65,5 +69,10 @@ module.exports = (webpackConfigEnv) => { services: path.resolve(__dirname, "src/services"), }, }, + plugins: [ + // ignore moment locales to reduce bundle size by 64kb gzipped + // see solution details https://stackoverflow.com/questions/25384360/how-to-prevent-moment-js-from-loading-locales-with-webpack/25426019#25426019 + new webpack.IgnorePlugin(/^\.\/locale$/, /moment$/), + ], }); }; From 9e4bba0221bd6d08dc701c381a608e95923f206f Mon Sep 17 00:00:00 2001 From: maxceem Date: Thu, 28 Jan 2021 00:49:31 +0200 Subject: [PATCH 04/90] fix: path during local setup --- webpack.config.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/webpack.config.js b/webpack.config.js index 64dbbbfe..222fa8a4 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -6,7 +6,7 @@ const path = require("path"); const autoprefixer = require("autoprefixer"); -const cssLocalIdent = process.env.APPMODE === "production" +const cssLocalIdent = process.env.APPMODE === "production" ? "[hash:base64:6]" : "teams_[path][name]___[local]___[hash:base64:6]"; @@ -18,6 +18,10 @@ module.exports = (webpackConfigEnv) => { }); return webpackMerge.smart(defaultConfig, { + output: { + // path: path.resolve(__dirname, 'dist'), + publicPath: 'taas-app', + }, // modify the webpack config however you'd like to by adding to this object module: { rules: [ From 3cbcdc5a79bd66de433b722a4da378d44e12792c Mon Sep 17 00:00:00 2001 From: Nowshad Date: Thu, 4 Feb 2021 23:35:57 +0600 Subject: [PATCH 05/90] Jobs and Booking Resource Management Submission. --- package.json | 4 + server.js | 9 +- src/assets/images/icon-bag.svg | 14 ++ src/assets/images/icon-computer.svg | 20 ++ src/assets/images/icon-description.svg | 22 ++ src/assets/images/icon-money.svg | 8 +- src/assets/images/icon-openings.svg | 25 +++ src/assets/images/icon-skill.svg | 16 ++ src/components/ActionsMenu/styles.module.scss | 2 +- src/components/AvatarGroup/styles.module.scss | 4 +- src/components/Button/index.jsx | 3 + src/components/Button/styles.module.scss | 26 +-- src/components/DataItem/styles.module.scss | 10 +- src/components/DateInput/index.jsx | 30 +++ src/components/DateInput/styles.module.scss | 11 + src/components/FormField/index.jsx | 113 ++++++++++ src/components/FormField/styles.module.scss | 49 +++++ src/components/Input/styles.module.scss | 8 +- src/components/PageHeader/styles.module.scss | 2 +- src/components/Pagination/styles.module.scss | 9 +- .../PercentageBar/styles.module.scss | 4 +- src/components/ReactSelect/index.jsx | 77 +++++++ src/components/ReactSelect/styles.module.scss | 12 ++ src/components/Select/styles.module.scss | 9 +- src/components/SkillsList/styles.module.scss | 2 +- .../SkillsSummary/styles.module.scss | 4 +- src/components/TCForm/index.jsx | 143 +++++++++++++ src/components/TCForm/styles.module.scss | 52 +++++ src/components/TCForm/utils.js | 105 ++++++++++ src/components/TextArea/index.jsx | 36 ++++ src/components/TextArea/styles.module.scss | 9 + src/components/TextInput/index.jsx | 56 +++++ src/components/TextInput/styles.module.scss | 26 +++ .../ThreeDotsMenu/styles.module.scss | 2 +- src/components/User/index.jsx | 10 +- src/constants/index.js | 61 ++++++ src/root.component.jsx | 11 +- src/routes/JobDetails/index.jsx | 105 ++++++++++ src/routes/JobDetails/styles.module.scss | 36 ++++ src/routes/JobForm/index.jsx | 135 ++++++++++++ src/routes/JobForm/styles.module.scss | 10 + src/routes/JobForm/utils.js | 193 ++++++++++++++++++ .../components/TeamMembers/index.jsx | 1 + .../components/TeamPositions/index.jsx | 23 ++- .../TeamPositions/styles.module.scss | 18 ++ src/routes/MyTeamsList/styles.module.scss | 8 +- .../components/PositionCandidates/index.jsx | 10 +- src/routes/PositionDetails/index.jsx | 1 + .../ResourceDetails/index.jsx | 83 ++++++++ .../ResourceDetails/styles.module.scss | 24 +++ .../ResourceSummary/index.jsx | 36 ++++ .../ResourceSummary/styles.module.scss | 16 ++ src/routes/ResourceBookingDetails/index.jsx | 78 +++++++ .../ResourceBookingDetails/styles.module.scss | 27 +++ src/routes/ResourceBookingForm/index.jsx | 111 ++++++++++ .../ResourceBookingForm/styles.module.scss | 10 + src/routes/ResourceBookingForm/utils.js | 67 ++++++ src/services/jobs.js | 54 +++++ src/services/requestInterceptor.js | 12 ++ src/services/resourceBookings.js | 28 +++ src/services/skills.js | 59 ++++++ src/styles/_mixins.scss | 1 - src/utils/format.js | 23 ++- webpack.config.js | 10 +- 64 files changed, 2116 insertions(+), 67 deletions(-) create mode 100644 src/assets/images/icon-bag.svg create mode 100644 src/assets/images/icon-computer.svg create mode 100644 src/assets/images/icon-description.svg create mode 100644 src/assets/images/icon-openings.svg create mode 100644 src/assets/images/icon-skill.svg create mode 100644 src/components/DateInput/index.jsx create mode 100644 src/components/DateInput/styles.module.scss create mode 100644 src/components/FormField/index.jsx create mode 100644 src/components/FormField/styles.module.scss create mode 100644 src/components/ReactSelect/index.jsx create mode 100644 src/components/ReactSelect/styles.module.scss create mode 100644 src/components/TCForm/index.jsx create mode 100644 src/components/TCForm/styles.module.scss create mode 100644 src/components/TCForm/utils.js create mode 100644 src/components/TextArea/index.jsx create mode 100644 src/components/TextArea/styles.module.scss create mode 100644 src/components/TextInput/index.jsx create mode 100644 src/components/TextInput/styles.module.scss create mode 100644 src/routes/JobDetails/index.jsx create mode 100644 src/routes/JobDetails/styles.module.scss create mode 100644 src/routes/JobForm/index.jsx create mode 100644 src/routes/JobForm/styles.module.scss create mode 100644 src/routes/JobForm/utils.js create mode 100644 src/routes/ResourceBookingDetails/ResourceDetails/index.jsx create mode 100644 src/routes/ResourceBookingDetails/ResourceDetails/styles.module.scss create mode 100644 src/routes/ResourceBookingDetails/ResourceSummary/index.jsx create mode 100644 src/routes/ResourceBookingDetails/ResourceSummary/styles.module.scss create mode 100644 src/routes/ResourceBookingDetails/index.jsx create mode 100644 src/routes/ResourceBookingDetails/styles.module.scss create mode 100644 src/routes/ResourceBookingForm/index.jsx create mode 100644 src/routes/ResourceBookingForm/styles.module.scss create mode 100644 src/routes/ResourceBookingForm/utils.js create mode 100644 src/services/jobs.js create mode 100644 src/services/resourceBookings.js create mode 100644 src/services/skills.js diff --git a/package.json b/package.json index 3a16e2cc..a53574fb 100644 --- a/package.json +++ b/package.json @@ -59,17 +59,21 @@ "axios": "^0.21.0", "classnames": "^2.2.6", "express": "^4.17.1", + "final-form": "^4.20.1", "immutability-helper": "^3.1.1", "lodash": "^4.17.20", "moment": "^2.29.1", "prop-types": "^15.7.2", "react": "^16.12.0", "react-avatar": "^3.9.7", + "react-datepicker": "^3.4.1", "react-dom": "^16.12.0", + "react-final-form": "^6.5.2", "react-outside-click-handler": "^1.3.0", "react-popper": "^2.2.3", "react-redux": "^7.2.2", "react-redux-toastr": "^7.6.5", + "react-select": "^4.0.2", "react-use": "^15.3.4", "redux": "^4.0.5", "redux-logger": "^3.0.6", diff --git a/server.js b/server.js index 81f5c040..0753bddd 100644 --- a/server.js +++ b/server.js @@ -4,7 +4,8 @@ const express = require("express"); const app = express(); -app.use('/taas-app', +app.use( + "/taas-app", express.static("./dist", { setHeaders: function setHeaders(res) { res.header("Access-Control-Allow-Origin", "*"); @@ -17,9 +18,9 @@ app.use('/taas-app', }) ); -app.get('/', function (req, res) { - res.send('alive') -}) +app.get("/", function (req, res) { + res.send("alive"); +}); const PORT = process.env.PORT || 8501; app.listen(PORT); diff --git a/src/assets/images/icon-bag.svg b/src/assets/images/icon-bag.svg new file mode 100644 index 00000000..b15a9ec3 --- /dev/null +++ b/src/assets/images/icon-bag.svg @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/assets/images/icon-computer.svg b/src/assets/images/icon-computer.svg new file mode 100644 index 00000000..2ac66471 --- /dev/null +++ b/src/assets/images/icon-computer.svg @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/assets/images/icon-description.svg b/src/assets/images/icon-description.svg new file mode 100644 index 00000000..185971e0 --- /dev/null +++ b/src/assets/images/icon-description.svg @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/assets/images/icon-money.svg b/src/assets/images/icon-money.svg index 198a0932..8e1fa9b5 100644 --- a/src/assets/images/icon-money.svg +++ b/src/assets/images/icon-money.svg @@ -1,9 +1,9 @@ - - - + + + @@ -12,4 +12,4 @@ - + \ No newline at end of file diff --git a/src/assets/images/icon-openings.svg b/src/assets/images/icon-openings.svg new file mode 100644 index 00000000..f713e013 --- /dev/null +++ b/src/assets/images/icon-openings.svg @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/assets/images/icon-skill.svg b/src/assets/images/icon-skill.svg new file mode 100644 index 00000000..9b79ee65 --- /dev/null +++ b/src/assets/images/icon-skill.svg @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/components/ActionsMenu/styles.module.scss b/src/components/ActionsMenu/styles.module.scss index e0024961..c9556de7 100644 --- a/src/components/ActionsMenu/styles.module.scss +++ b/src/components/ActionsMenu/styles.module.scss @@ -39,7 +39,7 @@ } .option { - color: #0D61BF; + color: #0d61bf; cursor: pointer; font-size: 14px; line-height: 20px; diff --git a/src/components/AvatarGroup/styles.module.scss b/src/components/AvatarGroup/styles.module.scss index d9d5aa2e..54d41108 100644 --- a/src/components/AvatarGroup/styles.module.scss +++ b/src/components/AvatarGroup/styles.module.scss @@ -14,10 +14,10 @@ .rest-count { align-items: center; - border: 1px solid #0D61BF; + border: 1px solid #0d61bf; border-radius: 100%; box-sizing: border-box; - color: #0D61BF; + color: #0d61bf; display: flex; font-size: 14px; height: 40px; diff --git a/src/components/Button/index.jsx b/src/components/Button/index.jsx index 7264af96..77edd3e7 100644 --- a/src/components/Button/index.jsx +++ b/src/components/Button/index.jsx @@ -27,6 +27,7 @@ const Button = ({ routeTo, href, target, + isSubmit, }) => { if (href) { return ( @@ -49,6 +50,7 @@ const Button = ({ className={className} ref={innerRef} disabled={disabled} + type={isSubmit ? "submit" : "button"} > {children} @@ -68,6 +70,7 @@ Button.propTypes = { disabled: PT.bool, routeTo: PT.string, href: PT.string, + isSubmit: PT.bool, }; export default Button; diff --git a/src/components/Button/styles.module.scss b/src/components/Button/styles.module.scss index 91dc4bb7..7302f649 100644 --- a/src/components/Button/styles.module.scss +++ b/src/components/Button/styles.module.scss @@ -42,51 +42,51 @@ } .type-primary { - border: 1px solid #137D60; - background-color: #137D60; + border: 1px solid #137d60; + background-color: #137d60; color: #fff; } .type-warning { - border: 1px solid #EF476F; - background-color: #EF476F; + border: 1px solid #ef476f; + background-color: #ef476f; color: #fff; } .type-secondary { background-color: #fff; - border: 1px solid #137D60; + border: 1px solid #137d60; color: #229174; } .type-secondary[disabled] { - border-color: #E9E9E9; - color: #E9E9E9; + border-color: #e9e9e9; + color: #e9e9e9; } .type-segment { background-color: transparent; border: 1px solid transparent; - color: #2A2A2A; + color: #2a2a2a; font-size: 12px; font-weight: normal; } .type-segment-selected { - border: 1px solid #7F7F7F; - background-color: #7F7F7F; + border: 1px solid #7f7f7f; + background-color: #7f7f7f; color: #fff; font-size: 12px; font-weight: normal; } .type-segment[disabled] { - color: #E9E9E9; + color: #e9e9e9; } .type-primary[disabled], .type-warning[disabled], .type-segment-selected[disabled] { - background-color: #E9E9E9; - border-color: #E9E9E9; + background-color: #e9e9e9; + border-color: #e9e9e9; } diff --git a/src/components/DataItem/styles.module.scss b/src/components/DataItem/styles.module.scss index 78b71dc9..6c69f358 100644 --- a/src/components/DataItem/styles.module.scss +++ b/src/components/DataItem/styles.module.scss @@ -1,13 +1,19 @@ @import "styles/include"; .data-item { - align-items: center; + align-items: flex-start; display: flex; flex-direction: row; + svg { + margin-top: 4px; + } } .data { margin-left: 16px; + display: flex; + flex-direction: column; + flex-basis: 90%; } .title { @@ -16,7 +22,6 @@ letter-spacing: 0.5px; line-height: 16px; text-align: left; - white-space: nowrap; } .value { @@ -25,5 +30,4 @@ font-weight: 500; margin-top: 2px; text-align: left; - white-space: nowrap; } diff --git a/src/components/DateInput/index.jsx b/src/components/DateInput/index.jsx new file mode 100644 index 00000000..93484e84 --- /dev/null +++ b/src/components/DateInput/index.jsx @@ -0,0 +1,30 @@ +/** + * DateInput + * + * Date Input control. + */ +import React from "react"; +import PT from "prop-types"; +import DatePicker from "react-datepicker"; +import "./styles.module.scss"; + +const DateInput = ({ value, onChange, placeholder }) => { + return ( +
    + +
    + ); +}; + +DateInput.propTypes = { + value: PT.string, + onChange: PT.func.isRequired, + placeholder: PT.string, +}; + +export default DateInput; diff --git a/src/components/DateInput/styles.module.scss b/src/components/DateInput/styles.module.scss new file mode 100644 index 00000000..6d2904a4 --- /dev/null +++ b/src/components/DateInput/styles.module.scss @@ -0,0 +1,11 @@ +@import "styles/include"; + +.datepicker-wrapper { + & > div { + width: 100%; + } +} + +.datepicker-wrapper > div:nth-child(2) > div:nth-child(2) { + z-index: 100; +} diff --git a/src/components/FormField/index.jsx b/src/components/FormField/index.jsx new file mode 100644 index 00000000..1e89a552 --- /dev/null +++ b/src/components/FormField/index.jsx @@ -0,0 +1,113 @@ +/** + * FormField + * + * FormField Component. + */ +import React from "react"; +import PT from "prop-types"; +import { Field } from "react-final-form"; +import { FORM_FIELD_TYPE } from "../../constants"; +import TextInput from "../../components/TextInput"; +import TextArea from "../../components/TextArea"; +import ReactSelect from "../../components/ReactSelect"; +import DateInput from "../../components/DateInput"; +import "./styles.module.scss"; + +const FormField = ({ field, isGroupField }) => { + return ( + + {({ input, meta }) => ( +
    + + {field.type === FORM_FIELD_TYPE.TEXT && ( + { + input.onChange(v); + }} + className={meta.error ? "error" : ""} + readonly={field.readonly} + /> + )} + {field.type === FORM_FIELD_TYPE.NUMBER && ( + + )} + {field.type === FORM_FIELD_TYPE.TEXTAREA && ( +