diff --git a/.circleci/config.yml b/.circleci/config.yml index 539c227375..e3e323f801 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -245,8 +245,7 @@ workflows: filters: branches: only: - - milestone-20200917 - - develop + - gig-application # This is beta env for production soft releases - "build-prod-beta": context : org-global diff --git a/__tests__/shared/components/GUIKit/Checkbox/__snapshots__/index.jsx.snap b/__tests__/shared/components/GUIKit/Checkbox/__snapshots__/index.jsx.snap index 94a5da518a..2ca9d09aa5 100644 --- a/__tests__/shared/components/GUIKit/Checkbox/__snapshots__/index.jsx.snap +++ b/__tests__/shared/components/GUIKit/Checkbox/__snapshots__/index.jsx.snap @@ -12,13 +12,10 @@ exports[`Default render 1`] = `
-
diff --git a/__tests__/shared/components/GUIKit/Datepicker/__snapshots__/index.jsx.snap b/__tests__/shared/components/GUIKit/Datepicker/__snapshots__/index.jsx.snap index 6bf8ad76cf..8ec048cd49 100644 --- a/__tests__/shared/components/GUIKit/Datepicker/__snapshots__/index.jsx.snap +++ b/__tests__/shared/components/GUIKit/Datepicker/__snapshots__/index.jsx.snap @@ -2,7 +2,7 @@ exports[`Default render 1`] = `
} date={null} - daySize={53} + daySize={47} disableScroll={false} disabled={false} displayFormat="MMM DD, YYYY" diff --git a/__tests__/shared/components/GUIKit/RadioButton/__snapshots__/index.jsx.snap b/__tests__/shared/components/GUIKit/RadioButton/__snapshots__/index.jsx.snap index 29192cd7c7..f7455f2db2 100644 --- a/__tests__/shared/components/GUIKit/RadioButton/__snapshots__/index.jsx.snap +++ b/__tests__/shared/components/GUIKit/RadioButton/__snapshots__/index.jsx.snap @@ -1,29 +1,31 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`Default render 1`] = ` -
+
- - - radio - + className="src-shared-components-GUIKit-RadioButton-___style__label___MCxnk" + > + radio + +
-
+ `; diff --git a/__tests__/shared/components/Settings/Preferences/Email/__snapshots__/index.jsx.snap b/__tests__/shared/components/Settings/Preferences/Email/__snapshots__/index.jsx.snap index cde7b4e722..ab117b50c9 100644 --- a/__tests__/shared/components/Settings/Preferences/Email/__snapshots__/index.jsx.snap +++ b/__tests__/shared/components/Settings/Preferences/Email/__snapshots__/index.jsx.snap @@ -65,6 +65,14 @@ exports[`renders email preferences setting page correctly 1`] = ` secondaryText="For all the latest updates surrounding the Topcoder Open you should definitely be subscribing to this one. Expect an update in your mailbox every Tuesday!" value="TCO Tuesdays" /> + `; diff --git a/package-lock.json b/package-lock.json index 9835410199..3c35321344 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1934,6 +1934,11 @@ "lodash.throttle": "^4.0.1" } }, + "append-field": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/append-field/-/append-field-1.0.0.tgz", + "integrity": "sha1-HjRA6RXwsSA9I3SOeO3XubW0PlY=" + }, "append-transform": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/append-transform/-/append-transform-0.4.0.tgz", @@ -2235,12 +2240,9 @@ "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==" }, "attr-accept": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/attr-accept/-/attr-accept-1.1.3.tgz", - "integrity": "sha512-iT40nudw8zmCweivz6j58g+RT33I4KbaIvRUhjNmDwO2WmsQUxFEZZYZ5w3vXe5x5MX9D7mfvA/XaLOZYFR9EQ==", - "requires": { - "core-js": "^2.5.0" - } + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/attr-accept/-/attr-accept-2.2.2.tgz", + "integrity": "sha512-7prDjvt9HmqiZ0cl5CRjtS84sEyhsHP2coDkaZKRKVfCDo9s7iw7ChVmar78Gu9pC4SoR/28wFu/G5JJhTnqEg==" }, "auth0-js": { "version": "9.13.2", @@ -3911,6 +3913,38 @@ "safe-json-stringify": "~1" } }, + "busboy": { + "version": "0.2.14", + "resolved": "https://registry.npmjs.org/busboy/-/busboy-0.2.14.tgz", + "integrity": "sha1-bCpiLvz0fFe7vh4qnDetNseSVFM=", + "requires": { + "dicer": "0.2.5", + "readable-stream": "1.1.x" + }, + "dependencies": { + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=" + }, + "readable-stream": { + "version": "1.1.14", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", + "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=", + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + } + }, + "string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=" + } + } + }, "bytes": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz", @@ -4750,7 +4784,6 @@ "version": "1.6.2", "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", - "dev": true, "requires": { "buffer-from": "^1.0.0", "inherits": "^2.0.3", @@ -6716,6 +6749,38 @@ "defined": "^1.0.0" } }, + "dicer": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/dicer/-/dicer-0.2.5.tgz", + "integrity": "sha1-WZbAhrszIYyBLAkL3cCc0S+stw8=", + "requires": { + "readable-stream": "1.1.x", + "streamsearch": "0.1.2" + }, + "dependencies": { + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=" + }, + "readable-stream": { + "version": "1.1.14", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", + "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=", + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + } + }, + "string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=" + } + } + }, "diff": { "version": "3.5.0", "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", @@ -8312,6 +8377,11 @@ "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=" }, + "fast-safe-stringify": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/fast-safe-stringify/-/fast-safe-stringify-2.0.7.tgz", + "integrity": "sha512-Utm6CdzT+6xsDk2m8S6uL8VHxNwI6Jub+e9NYTcAms28T84pTa25GJQV9j0CY0N1rM8hK4x6grpF2BQf+2qwVA==" + }, "fastparse": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/fastparse/-/fastparse-1.1.2.tgz", @@ -8396,6 +8466,21 @@ "schema-utils": "^0.4.5" } }, + "file-selector": { + "version": "0.1.13", + "resolved": "https://registry.npmjs.org/file-selector/-/file-selector-0.1.13.tgz", + "integrity": "sha512-T2efCBY6Ps+jLIWdNQsmzt/UnAjKOEAlsZVdnQztg/BtAZGNL4uX1Jet9cMM8gify/x4CSudreji2HssGBNVIQ==", + "requires": { + "tslib": "^2.0.1" + }, + "dependencies": { + "tslib": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.0.1.tgz", + "integrity": "sha512-SgIkNheinmEBgx1IUNirK0TUD4X9yjjBRTqqjggWCU3pUEqIk3/Uwl3yRixYKT6WjQuGiwDv4NomL3wqRCj+CQ==" + } + } + }, "file-set": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/file-set/-/file-set-2.0.1.tgz", @@ -8999,12 +9084,12 @@ "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=" }, "form-data": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.5.1.tgz", - "integrity": "sha512-m21N3WOmEEURgk6B9GLOE4RuWOFf28Lhh9qGYeNlGq4VDXUlJy2th2slBNU8Gp8EzloYZOibZJ7t5ecIrFSjVA==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.0.tgz", + "integrity": "sha512-CKMFDglpbMi6PyN+brwB9Q/GOw0eAnsrEZDgcsH5Krhz5Od/haKHAX0NmQfha2zPPz0JpWzA7GJHGSnvCRLWsg==", "requires": { "asynckit": "^0.4.0", - "combined-stream": "^1.0.6", + "combined-stream": "^1.0.8", "mime-types": "^2.1.12" } }, @@ -14482,6 +14567,21 @@ "isarray": "^1.0.0" } }, + "multer": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/multer/-/multer-1.4.2.tgz", + "integrity": "sha512-xY8pX7V+ybyUpbYMxtjM9KAiD9ixtg5/JkeKUTD6xilfDv0vzzOFcCp4Ljb1UU3tSOM3VTZtKo63OmzOrGi3Cg==", + "requires": { + "append-field": "^1.0.0", + "busboy": "^0.2.11", + "concat-stream": "^1.5.2", + "mkdirp": "^0.5.1", + "object-assign": "^4.1.1", + "on-finished": "^2.3.0", + "type-is": "^1.6.4", + "xtend": "^4.0.0" + } + }, "mute-stream": { "version": "0.0.7", "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz", @@ -18088,12 +18188,13 @@ } }, "react-dropzone": { - "version": "3.13.4", - "resolved": "https://registry.npmjs.org/react-dropzone/-/react-dropzone-3.13.4.tgz", - "integrity": "sha1-hNomgVxAM5aRxJtFRMLvehaRLMw=", + "version": "11.2.0", + "resolved": "https://registry.npmjs.org/react-dropzone/-/react-dropzone-11.2.0.tgz", + "integrity": "sha512-S/qaXQHCCg7MVlcrhqd05MLC6DupITLUB0CFn3iCLs6OTjzxdGDF1WTktTe5Jyq8jZdxYfMHNUZOHL0mg+K0Dw==", "requires": { - "attr-accept": "^1.0.3", - "prop-types": "^15.5.7" + "attr-accept": "^2.0.0", + "file-selector": "^0.1.12", + "prop-types": "^15.7.2" } }, "react-fast-compare": { @@ -20392,7 +20493,8 @@ "semver-compare": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/semver-compare/-/semver-compare-1.0.0.tgz", - "integrity": "sha1-De4hahyUGrN+nvsXiPavxf9VN/w=" + "integrity": "sha1-De4hahyUGrN+nvsXiPavxf9VN/w=", + "dev": true }, "semver-regex": { "version": "2.0.0", @@ -21145,6 +21247,11 @@ "integrity": "sha512-DBp0lSvX5G9KGRDTkR/R+a29H+Wk2xItOF+MpZLLNDWbEV9tGPnqLPxHEYjmiz8xGtJHRIqmI+hCjmNzqoA4nQ==", "dev": true }, + "streamsearch": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-0.1.2.tgz", + "integrity": "sha1-gIudDlb8Jz2Am6VzOOkpkZoanxo=" + }, "strict-uri-encode": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-2.0.0.tgz", @@ -22099,6 +22206,16 @@ "ms": "^2.1.1" } }, + "form-data": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.5.1.tgz", + "integrity": "sha512-m21N3WOmEEURgk6B9GLOE4RuWOFf28Lhh9qGYeNlGq4VDXUlJy2th2slBNU8Gp8EzloYZOibZJ7t5ecIrFSjVA==", + "requires": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.6", + "mime-types": "^2.1.12" + } + }, "ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", @@ -22896,12 +23013,10 @@ "filestack-js": "^1.13.2", "formsy-react": "^0.19.5", "isomorphic-fetch": "^2.2.1", - "libphonenumber-js": "1.4.6", "lodash": "^4.0.0", "material-ui": "^0.20.2", "moment": "^2.11.2", "prop-types": "^15.7.2", - "rc-slider": "8.6.4", "react": "^15.3.1", "react-addons-pure-render-mixin": "^15.3.1", "react-addons-update": "^15.3.1", @@ -22918,7 +23033,6 @@ "react-textarea-autosize": "^5.2.1", "react-transition-group": "^2.2.1", "redux-thunk": "^2.1.0", - "tc-ui": "git+https://github.com/appirio-tech/tc-ui.git#feature/connectv2", "uncontrollable": "^4.0.1" }, "dependencies": { @@ -22965,16 +23079,6 @@ "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-1.2.0.tgz", "integrity": "sha1-qkSM8JhtVcxAdzsXF0t90GbLfPs=" }, - "libphonenumber-js": { - "version": "1.4.6", - "resolved": "https://registry.npmjs.org/libphonenumber-js/-/libphonenumber-js-1.4.6.tgz", - "integrity": "sha512-TD1DyhPjVfNNiIxhwsooCO5j9L6JB60Qd+rlIEItgw8RKEqezu8Tva3V/4wrBiYMnBOHkp3uyzAe/PT9omyUdw==", - "requires": { - "minimist": "^1.2.0", - "semver-compare": "^1.0.0", - "xml2js": "^0.4.17" - } - }, "loose-envify": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", @@ -22983,11 +23087,6 @@ "js-tokens": "^3.0.0 || ^4.0.0" } }, - "minimist": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==" - }, "moment": { "version": "2.24.0", "resolved": "https://registry.npmjs.org/moment/-/moment-2.24.0.tgz", @@ -23016,20 +23115,6 @@ "strict-uri-encode": "^1.0.0" } }, - "rc-slider": { - "version": "8.6.4", - "resolved": "https://registry.npmjs.org/rc-slider/-/rc-slider-8.6.4.tgz", - "integrity": "sha512-CV2i2Ww6ib0EjFuBKvgjw3PgT6QwvWKC93iEpqPtrztZrx5wO9Iw//AUri4KHRqptW13AuBvFdEHovqLi6XFTw==", - "requires": { - "babel-runtime": "6.x", - "classnames": "^2.2.5", - "prop-types": "^15.5.4", - "rc-tooltip": "^3.7.0", - "rc-util": "^4.0.4", - "shallowequal": "^1.0.1", - "warning": "^3.0.0" - } - }, "react-router": { "version": "2.8.1", "resolved": "https://registry.npmjs.org/react-router/-/react-router-2.8.1.tgz", @@ -23042,6 +23127,40 @@ "warning": "^3.0.0" } }, + "tc-ui": { + "version": "git+https://github.com/appirio-tech/tc-ui.git#e577a0e704136f1e9ecce92ce4c0626aab932691", + "from": "git+https://github.com/appirio-tech/tc-ui.git#e577a0e704136f1e9ecce92ce4c0626aab932691", + "requires": { + "classnames": "^2.2.3", + "lodash": "^4.0.0", + "moment": "^2.11.2", + "node-neat": "~1.7.1-beta1", + "react": "^0.14.7", + "react-datetime": "^2.0.2", + "react-dom": "^0.14.7", + "react-dropzone": "^3.3.2", + "react-redux": "^4.2.1", + "react-router": "^2.0.0-rc6", + "react-select": "^0.9.1", + "redux": "^3.3.1" + }, + "dependencies": { + "react": { + "version": "0.14.9", + "resolved": "https://registry.npmjs.org/react/-/react-0.14.9.tgz", + "integrity": "sha1-kRCmSXxJ1EuhwO3TF67CnC4NkdE=", + "requires": { + "envify": "^3.0.0", + "fbjs": "^0.6.1" + } + }, + "react-dom": { + "version": "0.14.9", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-0.14.9.tgz", + "integrity": "sha1-BQZKPc8PsYgKOyv8nVjFXY2fYpM=" + } + } + }, "warning": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/warning/-/warning-3.0.0.tgz", @@ -23049,20 +23168,6 @@ "requires": { "loose-envify": "^1.0.0" } - }, - "xml2js": { - "version": "0.4.23", - "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.4.23.tgz", - "integrity": "sha512-ySPiMjM0+pLDftHgXY4By0uswI3SPKLDw/i3UXbnO8M/p28zqexCUoPmQFrYD+/1BzhGJSs2i1ERWKJAtiLrug==", - "requires": { - "sax": ">=0.6.0", - "xmlbuilder": "~11.0.0" - } - }, - "xmlbuilder": { - "version": "11.0.1", - "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-11.0.1.tgz", - "integrity": "sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==" } } }, @@ -31603,111 +31708,6 @@ "inherits": "2" } }, - "tc-ui": { - "version": "git+https://github.com/appirio-tech/tc-ui.git#e577a0e704136f1e9ecce92ce4c0626aab932691", - "from": "git+https://github.com/appirio-tech/tc-ui.git#feature/connectv2", - "requires": { - "classnames": "^2.2.3", - "lodash": "^4.0.0", - "moment": "^2.11.2", - "node-neat": "~1.7.1-beta1", - "react": "^0.14.7", - "react-datetime": "^2.0.2", - "react-dom": "^0.14.7", - "react-dropzone": "^3.3.2", - "react-redux": "^4.2.1", - "react-router": "^2.0.0-rc6", - "react-select": "^0.9.1", - "redux": "^3.3.1" - }, - "dependencies": { - "fbjs": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/fbjs/-/fbjs-0.6.1.tgz", - "integrity": "sha1-lja3cF9bqWhNRLcveDISVK/IYPc=", - "requires": { - "core-js": "^1.0.0", - "loose-envify": "^1.0.0", - "promise": "^7.0.3", - "ua-parser-js": "^0.7.9", - "whatwg-fetch": "^0.9.0" - } - }, - "history": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/history/-/history-2.1.2.tgz", - "integrity": "sha1-SqLeiXoOSGfkU5hDvm7Nsphr/ew=", - "requires": { - "deep-equal": "^1.0.0", - "invariant": "^2.0.0", - "query-string": "^3.0.0", - "warning": "^2.0.0" - }, - "dependencies": { - "warning": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/warning/-/warning-2.1.0.tgz", - "integrity": "sha1-ISINnGOvx3qMkhEeARr3Bc4MaQE=", - "requires": { - "loose-envify": "^1.0.0" - } - } - } - }, - "hoist-non-react-statics": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-1.2.0.tgz", - "integrity": "sha1-qkSM8JhtVcxAdzsXF0t90GbLfPs=" - }, - "moment": { - "version": "2.27.0", - "resolved": "https://registry.npmjs.org/moment/-/moment-2.27.0.tgz", - "integrity": "sha512-al0MUK7cpIcglMv3YF13qSgdAIqxHTO7brRtaz3DlSULbqfazqkc5kEjNrLDOM7fsjshoFIihnU8snrP7zUvhQ==" - }, - "query-string": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/query-string/-/query-string-3.0.3.tgz", - "integrity": "sha1-ri4UtNBQcdTpuetIc8NbDc1C5jg=", - "requires": { - "strict-uri-encode": "^1.0.0" - } - }, - "react": { - "version": "0.14.9", - "resolved": "https://registry.npmjs.org/react/-/react-0.14.9.tgz", - "integrity": "sha1-kRCmSXxJ1EuhwO3TF67CnC4NkdE=", - "requires": { - "envify": "^3.0.0", - "fbjs": "^0.6.1" - } - }, - "react-dom": { - "version": "0.14.9", - "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-0.14.9.tgz", - "integrity": "sha1-BQZKPc8PsYgKOyv8nVjFXY2fYpM=" - }, - "react-router": { - "version": "2.8.1", - "resolved": "https://registry.npmjs.org/react-router/-/react-router-2.8.1.tgz", - "integrity": "sha1-c+lJH2zrMW0Pd5gpCBhj43juTtc=", - "requires": { - "history": "^2.1.2", - "hoist-non-react-statics": "^1.2.0", - "invariant": "^2.2.1", - "loose-envify": "^1.2.0", - "warning": "^3.0.0" - } - }, - "warning": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/warning/-/warning-3.0.0.tgz", - "integrity": "sha1-MuU3fLVy3kqwR1O9+IIcAe1gW3w=", - "requires": { - "loose-envify": "^1.0.0" - } - } - } - }, "tcomb": { "version": "3.2.29", "resolved": "https://registry.npmjs.org/tcomb/-/tcomb-3.2.29.tgz", @@ -32553,6 +32553,21 @@ "redux": "^3.3.1" }, "dependencies": { + "attr-accept": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/attr-accept/-/attr-accept-1.1.3.tgz", + "integrity": "sha512-iT40nudw8zmCweivz6j58g+RT33I4KbaIvRUhjNmDwO2WmsQUxFEZZYZ5w3vXe5x5MX9D7mfvA/XaLOZYFR9EQ==", + "requires": { + "core-js": "^2.5.0" + }, + "dependencies": { + "core-js": { + "version": "2.6.11", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.11.tgz", + "integrity": "sha512-5wjnpaT/3dV+XB4borEsnAYQchn00XSgTAWKDkEqv+K8KevjbzmofK6hfJ9TZIlpj2N0xQpazy7PiRQiWHqzWg==" + } + } + }, "core-js": { "version": "1.2.7", "resolved": "https://registry.npmjs.org/core-js/-/core-js-1.2.7.tgz", @@ -32621,6 +32636,15 @@ "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-0.14.9.tgz", "integrity": "sha1-BQZKPc8PsYgKOyv8nVjFXY2fYpM=" }, + "react-dropzone": { + "version": "3.13.4", + "resolved": "https://registry.npmjs.org/react-dropzone/-/react-dropzone-3.13.4.tgz", + "integrity": "sha1-hNomgVxAM5aRxJtFRMLvehaRLMw=", + "requires": { + "attr-accept": "^1.0.3", + "prop-types": "^15.5.7" + } + }, "react-input-autosize": { "version": "0.6.13", "resolved": "https://registry.npmjs.org/react-input-autosize/-/react-input-autosize-0.6.13.tgz", @@ -33204,9 +33228,9 @@ "integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==" }, "topcoder-react-lib": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/topcoder-react-lib/-/topcoder-react-lib-1.0.3.tgz", - "integrity": "sha512-cb4QLW2m3CqzJHWkfbx5TM/rV1bpJXk3FqetNIyKETipebkXtbL83mxtkaV3IEDYrpeKmfzDwjmbxwBh8Gopkw==", + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/topcoder-react-lib/-/topcoder-react-lib-1.0.5.tgz", + "integrity": "sha512-vit+BVaU5SbjwTzLDAqFxE2P539+huV6QspsV3Ud5fL12HQqu3cpJg8iZLmEcCPSXonocVyhtvqdrSgqF1oB4Q==", "requires": { "auth0-js": "^6.8.4", "config": "^3.2.0", @@ -33265,6 +33289,14 @@ "json5": "^2.1.1" } }, + "debug": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.2.0.tgz", + "integrity": "sha512-IX2ncY78vDTjZMFUdmsvIRFY2Cf4FnD0wRs+nQwJU8Lu99/tPFdb0VybiiMTPe3I6rQmwsqQqRBvxU+bZ/I8sg==", + "requires": { + "ms": "2.1.2" + } + }, "follow-redirects": { "version": "0.0.7", "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-0.0.7.tgz", @@ -33272,6 +33304,31 @@ "requires": { "debug": "^2.2.0", "stream-consume": "^0.1.0" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + } + } + }, + "form-data": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.0.tgz", + "integrity": "sha512-CKMFDglpbMi6PyN+brwB9Q/GOw0eAnsrEZDgcsH5Krhz5Od/haKHAX0NmQfha2zPPz0JpWzA7GJHGSnvCRLWsg==", + "requires": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" } }, "hoist-non-react-statics": { @@ -33290,6 +33347,16 @@ "minimist": "^1.2.5" } }, + "mime": { + "version": "2.4.6", + "resolved": "https://registry.npmjs.org/mime/-/mime-2.4.6.tgz", + "integrity": "sha512-RZKhC3EmpBchfTGBVb8fb+RL2cWyw/32lshnsETttkBAyAUXSGHxbEJWWRXc751DrIxG1q04b8QwMbAwkRPpUA==" + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, "object-keys": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-0.4.0.tgz", @@ -33308,11 +33375,44 @@ "react-is": "^16.8.2" } }, + "readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + }, + "semver": { + "version": "7.3.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", + "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==" + }, "serialize-javascript": { "version": "1.9.1", "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-1.9.1.tgz", "integrity": "sha512-0Vb/54WJ6k5v8sSWN09S0ora+Hnr+cX40r9F170nT+mSkaxltoE/7R3OrIdBSUv1OoiobH1QoWQbCnAO+e8J1A==" }, + "superagent": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/superagent/-/superagent-5.3.1.tgz", + "integrity": "sha512-wjJ/MoTid2/RuGCOFtlacyGNxN9QLMgcpYLDQlWFIhhdJ93kNscFonGvrpAHSCVjRVj++DGCglocF7Aej1KHvQ==", + "requires": { + "component-emitter": "^1.3.0", + "cookiejar": "^2.1.2", + "debug": "^4.1.1", + "fast-safe-stringify": "^2.0.7", + "form-data": "^3.0.0", + "formidable": "^1.2.2", + "methods": "^1.1.2", + "mime": "^2.4.6", + "qs": "^6.9.4", + "readable-stream": "^3.6.0", + "semver": "^7.3.2" + } + }, "tc-core-library-js": { "version": "github:appirio-tech/tc-core-library-js#d16413db30b1eed21c0cf426e185bedb2329ddab", "from": "github:appirio-tech/tc-core-library-js#v2.6", @@ -33329,15 +33429,15 @@ }, "dependencies": { "auth0-js": { - "version": "9.13.4", - "resolved": "https://registry.npmjs.org/auth0-js/-/auth0-js-9.13.4.tgz", - "integrity": "sha512-G7wXTtEUe8OG5UMdcFPoS47odorEZ3WerNyWLLhoGlLqYcPgv0t+B0ECHv/rVLULbpctbSBrRFFYa43/bJV4+Q==", + "version": "9.14.0", + "resolved": "https://registry.npmjs.org/auth0-js/-/auth0-js-9.14.0.tgz", + "integrity": "sha512-40gIBUejmYAYse06ck6sxdNO0KU0pX+KDIQsWAkcyFtI0HU6dY5aeHxZfVYkYjtbArKr5s13LuZFdKrUiGyCqQ==", "requires": { "base64-js": "^1.3.0", "idtoken-verifier": "^2.0.3", "js-cookie": "^2.2.0", "qs": "^6.7.0", - "superagent": "^3.8.3", + "superagent": "^5.3.1", "url-join": "^4.0.1", "winchan": "^0.2.2" } @@ -33436,9 +33536,9 @@ } }, "topcoder-react-ui-kit": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/topcoder-react-ui-kit/-/topcoder-react-ui-kit-2.0.0.tgz", - "integrity": "sha512-9Ph8fRzRjVVB0VH13s8/N4+/ZWPLflrnW7D0fmS+oeDwnQe6k5wMknyFcBCI/pqWHr/11nhclXX7np3LdyWSwA==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/topcoder-react-ui-kit/-/topcoder-react-ui-kit-2.0.1.tgz", + "integrity": "sha512-pl8tysSZYHDSbWn8srLZxV+8lK9f32ya8N+yt5C2XF2PKak30Qnqb3PCDhBO1fKmFF90p4ohJRsCi0IxLRyH/A==", "requires": { "prop-types": "^15.6.2", "react": "^16.4.1", @@ -33624,8 +33724,7 @@ "typedarray": { "version": "0.0.6", "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", - "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", - "dev": true + "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=" }, "typical": { "version": "4.0.0", diff --git a/package.json b/package.json index e9dbff8f52..adf6e8f71c 100644 --- a/package.json +++ b/package.json @@ -62,6 +62,7 @@ "filestack-react": "^2.0.0", "flag-icon-css": "^3.3.0", "focus-trap-react": "^6.0.0", + "form-data": "^3.0.0", "helmet": "^3.12.1", "highlight.js": "^9.18.1", "html-to-text": "^5.1.1", @@ -81,6 +82,7 @@ "moment-timezone": "^0.5.21", "money": "^0.2.0", "morgan": "^1.9.0", + "multer": "^1.4.2", "navigation-component": "topcoder-platform/navigation-component#develop", "node-forge": "^0.7.5", "nuka-carousel": "^4.5.3", @@ -99,6 +101,7 @@ "react-dates": "^18.2.2", "react-dom": "^16.4.1", "react-dotdotdot": "^1.3.1", + "react-dropzone": "^11.2.0", "react-ga": "^2.7.0", "react-helmet": "^5.2.0", "react-html-parser": "^2.0.2", @@ -137,7 +140,7 @@ "tc-accounts": "git+https://github.com/appirio-tech/accounts-app.git#dev", "tc-core-library-js": "github:appirio-tech/tc-core-library-js#v2.6.3", "tc-ui": "^1.0.12", - "topcoder-react-lib": "1.0.6", + "topcoder-react-lib": "1.0.7", "topcoder-react-ui-kit": "2.0.1", "topcoder-react-utils": "0.7.8", "turndown": "^4.0.2", diff --git a/src/assets/images/back-arrow-gig-apply.svg b/src/assets/images/back-arrow-gig-apply.svg new file mode 100644 index 0000000000..ab3b9f0bbb --- /dev/null +++ b/src/assets/images/back-arrow-gig-apply.svg @@ -0,0 +1,17 @@ + + + + +BD4BD0F4-C75C-4897-A58C-B092051E2535 +Created with sketchtool. + + + + + + + + diff --git a/src/assets/images/big-checkmark.png b/src/assets/images/big-checkmark.png new file mode 100644 index 0000000000..8bd83bc41e Binary files /dev/null and b/src/assets/images/big-checkmark.png differ diff --git a/src/assets/images/sad-face-icon.svg b/src/assets/images/sad-face-icon.svg new file mode 100644 index 0000000000..b9b685c036 --- /dev/null +++ b/src/assets/images/sad-face-icon.svg @@ -0,0 +1,20 @@ + + + + 838C3DF4-2CF1-42A3-BC49-21142AF2003C@2x + Created with sketchtool. + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/server/routes/recruitCRM.js b/src/server/routes/recruitCRM.js index 5047dcdb0d..34c1831539 100644 --- a/src/server/routes/recruitCRM.js +++ b/src/server/routes/recruitCRM.js @@ -6,7 +6,15 @@ import express from 'express'; import RecruitCRMService from '../services/recruitCRM'; const cors = require('cors'); - +const multer = require('multer'); + +const storage = multer.memoryStorage(); +const upload = multer({ + storage, + limits: { + fileSize: 8000000, + }, +}); const routes = express.Router(); // Enables CORS on those routes according config above @@ -15,9 +23,9 @@ routes.use(cors()); routes.options('*', cors()); routes.get('/jobs', (req, res, next) => new RecruitCRMService().getAllJobs(req, res, next)); - routes.get('/jobs/search', (req, res, next) => new RecruitCRMService().getJobs(req, res, next)); - routes.get('/jobs/:id', (req, res, next) => new RecruitCRMService().getJob(req, res, next)); +routes.post('/jobs/:id/apply', upload.single('resume'), (req, res, next) => new RecruitCRMService().applyForJob(req, res, next)); +routes.get('/candidates/search', (req, res, next) => new RecruitCRMService().searchCandidates(req, res, next)); export default routes; diff --git a/src/server/services/recruitCRM.js b/src/server/services/recruitCRM.js index b8659ae824..f5375cae5b 100644 --- a/src/server/services/recruitCRM.js +++ b/src/server/services/recruitCRM.js @@ -6,6 +6,8 @@ import config from 'config'; import qs from 'qs'; import _ from 'lodash'; +const FormData = require('form-data'); + /** * Auxiliary class that handles communication with recruitCRM */ @@ -141,4 +143,155 @@ export default class RecruitCRMService { return next(err); } } + + /** + * Search for candidate by email endpoint. + * @return {Promise} + * @param {Object} the request. + */ + async searchCandidates(req, res, next) { + try { + const response = await fetch(`${this.private.baseUrl}/v1/candidates/search?${qs.stringify(req.query)}`, { + method: 'GET', + headers: { + 'Content-Type': req.headers['content-type'], + Authorization: this.private.authorization, + }, + }); + if (response.status === 429) { + await new Promise(resolve => setTimeout(resolve, 30000)); // wait 30sec + return this.searchCandidates(req, res, next); + } + if (response.status >= 400) { + return res.send({ + error: true, + status: response.status, + url: `${this.private.baseUrl}/v1/candidates/search?${qs.stringify(req.query)}`, + }); + } + const data = await response.json(); + return res.send(data); + } catch (err) { + return next(err); + } + } + + /** + * Apply for candidate for job endpoint. + * @return {Promise} + * @param {Object} the request. + */ + async applyForJob(req, res, next) { + const { id } = req.params; + const { body, file } = req; + const form = JSON.parse(body.form); + const fileData = new FormData(); + fileData.append('resume', file.buffer, file.originalname); + let candidateSlug; + try { + // Check if candidate exsits in the system? + const candidateResponse = await fetch(`${this.private.baseUrl}/v1/candidates/search?email=${form.email}`, { + method: 'GET', + headers: { + 'Content-Type': req.headers['content-type'], + Authorization: this.private.authorization, + }, + }); + if (candidateResponse.status >= 400) { + return res.send({ + error: true, + status: candidateResponse.status, + url: `${this.private.baseUrl}/v1/candidates/search?email=${form.email}`, + errObj: await candidateResponse.json(), + }); + } + let candidateData = await candidateResponse.json(); + if (candidateData.data) { + // Candidate exists we will update profile fields + // otherwise we create it + candidateSlug = candidateData.data[0].slug; + const fieldIndexProfile = _.findIndex( + candidateData.data[0].custom_fields, { field_id: 14 }, + ); + const fieldIndexForm = _.findIndex(form.custom_fields, { field_id: 14 }); + if (fieldIndexProfile !== -1 && fieldIndexForm !== -1) { + form.custom_fields[fieldIndexForm].value += `;${candidateData.data[0].custom_fields[fieldIndexProfile].value}`; + if (form.custom_fields[fieldIndexForm].value.length > 2000) { + form.custom_fields[fieldIndexForm].value = form.custom_fields[ + fieldIndexForm].value.slice(0, 2000); + } + } + } + // Create/update candidate profile + const workCandidateResponse = await fetch(`${this.private.baseUrl}/v1/candidates${candidateSlug ? `/${candidateSlug}` : ''}`, { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + Authorization: this.private.authorization, + }, + body: JSON.stringify(form), + }); + if (workCandidateResponse.status >= 400) { + return res.send({ + error: true, + status: workCandidateResponse.status, + url: `${this.private.baseUrl}/v1/candidates${candidateSlug ? `/${candidateSlug}` : ''}`, + form, + errObj: await workCandidateResponse.json(), + }); + } + candidateData = await workCandidateResponse.json(); + // Attach resume to candidate + const formHeaders = fileData.getHeaders(); + const fileCandidateResponse = await fetch(`${this.private.baseUrl}/v1/candidates/${candidateData.slug}`, { + method: 'POST', + headers: { + Authorization: this.private.authorization, + ...formHeaders, + }, + body: fileData, + }); + if (fileCandidateResponse.status >= 400) { + return res.send({ + error: true, + status: fileCandidateResponse.status, + url: `${this.private.baseUrl}/v1/candidates/${candidateData.slug}`, + form, + fileData, + file, + formHeaders, + errObj: await fileCandidateResponse.json(), + }); + } + candidateData = await fileCandidateResponse.json(); + // Candidate ready to apply for job + const applyResponse = await fetch(`${this.private.baseUrl}/v1/candidates/${candidateData.slug}/assign?job_slug=${id}`, { + method: 'POST', + headers: { + 'Content-Type': req.headers['content-type'], + Authorization: this.private.authorization, + }, + }); + if (applyResponse.status >= 400) { + const errObj = await applyResponse.json(); + if (errObj.errorCode === 422 && errObj.errorMessage === 'Candidate is already assigned to this job') { + return res.send({ + success: true, + }); + } + return res.send({ + error: true, + status: applyResponse.status, + url: `${this.private.baseUrl}/v1/candidates/${candidateData.slug}/assign?job_slug=${id}`, + form, + candidateData, + errObj, + }); + } + const data = await applyResponse.json(); + return res.send(data); + } catch (err) { + return next(err); + } + } } diff --git a/src/shared/actions/recruitCRM.js b/src/shared/actions/recruitCRM.js index 670b71878a..544f9deb76 100644 --- a/src/shared/actions/recruitCRM.js +++ b/src/shared/actions/recruitCRM.js @@ -1,5 +1,6 @@ import { redux } from 'topcoder-react-utils'; import Service from 'services/recruitCRM'; +import _ from 'lodash'; /** * Jobs page fetch init @@ -40,11 +41,96 @@ async function getJobDone(id) { }; } +/** + * Apply for Job init + */ +function applyForJobInit(job, payload) { + return { id: job.slug, payload }; +} + +/** + * Helper utitlity + * @param {object} joib The job object + * @param {object} payload The apply form payload + */ +function normalizeRecruitPayload(job, payload) { + const perJob = [ + `${job.name} ->`, + `Pay Expectation: ${payload.payExpectation}`, + `Date Available: ${new Date(payload.availFrom).toDateString()}`, + `Heard About Gig: ${payload.reffereal}`, + `Why fit: ${payload.whyFit}`, + `Availability Per Week: ${payload.timeAvailability.filter(s => s.checked).map(s => s.label).join(',')}`, + `Able to work during timezone? ${payload.timezoneConfirm.filter(s => s.value).map(s => s.label).join(',')}`, + `Am I ok to work the duration? ${payload.durationConfirm.filter(s => s.value).map(s => s.label).join(',')}`, + `Notes: ${payload.notes}`, + ]; + return { + last_name: payload.lname, + first_name: payload.fname, + email: payload.email, + contact_number: payload.phone, + city: payload.city, + locality: _.find(payload.country, { selected: true }).label, + available_from: payload.availFrom, + salary_expectation: payload.payExpectation, + skill: payload.skills.filter(s => s.selected).map(s => s.label).join(','), + custom_fields: [ + { + field_id: 13, + value: payload.reffereal || '', + }, + { + field_id: 1, + value: payload.tcProfileLink || (payload.handle ? `topcoder.com/members/${payload.handle}` : ''), + }, + { + field_id: 2, + value: payload.handle || '', + }, + { + field_id: 3, + value: payload.whyFit || '', + }, + { + field_id: 14, + value: perJob.join(','), + }, + ], + resume: payload.fileCV, + }; +} + +/** + * Apply for Job done + */ +async function applyForJobDone(job, payload) { + const ss = new Service(); + try { + const res = await ss.applyForJob(job.slug, normalizeRecruitPayload(job, payload)); + + return { + id: job.slug, + data: res, + }; + } catch (error) { + return { + id: job.slug, + data: { + error: true, + errorObj: error, + }, + }; + } +} + export default redux.createActions({ RECRUIT: { GET_JOBS_INIT: getJobsInit, GET_JOBS_DONE: getJobsDone, GET_JOB_INIT: getJobInit, GET_JOB_DONE: getJobDone, + APPLY_FOR_JOB_INIT: applyForJobInit, + APPLY_FOR_JOB_DONE: applyForJobDone, }, }); diff --git a/src/shared/components/ChallengeTile/index.jsx b/src/shared/components/ChallengeTile/index.jsx index 87f935e7fe..3e90be664f 100644 --- a/src/shared/components/ChallengeTile/index.jsx +++ b/src/shared/components/ChallengeTile/index.jsx @@ -108,7 +108,7 @@ class ChallengeTile extends React.Component { {underscoreReplace(type)}

- {formatDate(challenge.submissionEndDate)} + {challenge.submissionEndDate && formatDate(challenge.submissionEndDate)}

{ challenge.wonFirst && !challenge.isPrivate && ( diff --git a/src/shared/components/Contentful/Modal/index.jsx b/src/shared/components/Contentful/Modal/index.jsx index 196dc72074..55fcd996c2 100644 --- a/src/shared/components/Contentful/Modal/index.jsx +++ b/src/shared/components/Contentful/Modal/index.jsx @@ -9,12 +9,14 @@ import LoadingIndicator from 'components/LoadingIndicator'; import Banner from 'components/Contentful/Banner'; import ContentBlock from 'components/Contentful/ContentBlock'; import Viewport from 'components/Contentful/Viewport'; -import { Modal } from 'topcoder-react-ui-kit'; +import { Modal, PrimaryButton } from 'topcoder-react-ui-kit'; import { errors } from 'topcoder-react-lib'; import { themr } from 'react-css-super-themr'; import classnames from 'classnames'; +import tc from 'components/buttons/themed/tc.scss'; +import { fixStyle } from 'utils/contentful'; -import defaultModalTheme from 'components/Leaderboard/ChallengeHistoryModal/styles.scss'; +import defaultModalTheme from './modal-styles.scss'; import defaultStyle from './style.scss'; const { fireErrorMessage } = errors; @@ -89,6 +91,9 @@ class ContentfulModal extends React.Component { renderPlaceholder={LoadingIndicator} render={(data) => { const contentId = _.get(data, `entries.items.${id}.fields.content.sys.id`); + const hideDismissIcon = _.get(data, `entries.items.${id}.fields.hideDismissIcon`); + const hideCloseButton = _.get(data, `entries.items.${id}.fields.hideCloseButton`); + const extraStylesForContainer = _.get(data, `entries.items.${id}.fields.extraStylesForContainer`); if (!contentId) return null; return ( @@ -107,16 +112,20 @@ class ContentfulModal extends React.Component { onCancel={this.onCloseModal} theme={defaultModalTheme} > -
{ this.dismissButtonRef = node; }} - > - × -
+ { + !hideDismissIcon && ( +
{ this.dismissButtonRef = node; }} + > + × +
+ ) + } + { + !hideCloseButton && ( +
+ + CLOSE + +
+ ) + } )}
@@ -160,6 +185,7 @@ ContentfulModal.propTypes = { theme: PT.shape({ modalTrigger: PT.string, dismissButton: PT.any, + closeButton: PT.any, }), preview: PT.bool, spaceName: PT.string, diff --git a/src/shared/components/Contentful/Modal/modal-styles.scss b/src/shared/components/Contentful/Modal/modal-styles.scss new file mode 100644 index 0000000000..8e3bf60873 --- /dev/null +++ b/src/shared/components/Contentful/Modal/modal-styles.scss @@ -0,0 +1,188 @@ +@import "~styles/mixins"; + +$light-gray: #d4d4d4; + +.container { + @include roboto-regular; + + color: $tc-gray-50; + background: $tc-white; + border-radius: 10px; + top: 50%; + width: auto; + max-height: 90%; + overflow-y: auto; + + @media (max-width: 768px) { + width: 80%; + } + + h3 { + color: #1e94a3; + font-family: BarlowCondensed, sans-serif; + font-size: 34px; + font-weight: 500; + line-height: 38px; + text-align: center; + margin-bottom: 60px; + text-transform: uppercase; + + @media (max-width: 768px) { + font-size: 31px !important; + font-weight: 500 !important; + line-height: 33px !important; + margin-bottom: 30px; + } + } +} + +.overlay { + background-color: #2a2a2a; + opacity: 0.95; + border: none; + height: 100%; + left: 0; + outline: none; + position: fixed; + top: 0; + width: 100%; + z-index: 998; +} + +.podium-spot-wrapper { + text-align: center; + display: flex; + justify-content: center; + margin-bottom: 50px; + + > div > span { + height: 128px; + width: 128px; + + img, + svg { + border-radius: 50%; + border-style: solid; + border-width: 3px; + height: 100%; + width: 100%; + } + } +} + +.history-table { + width: 100%; + margin-bottom: 62px; + + thead { + th { + color: #2a2a2a; + font-family: Roboto, sans-serif; + font-size: 14px; + font-weight: 500; + letter-spacing: 0.5px; + line-height: 18px; + text-align: left; + text-transform: uppercase; + border-bottom: 1px solid #d4d4d4; + padding-bottom: 15px; + } + } + + .row { + border-bottom: 1px solid #d4d4d4; + + .name { + .link { + color: #0d61bf; + font-size: 14px; + font-weight: 400; + line-height: 51px; + text-decoration: underline; + + &:hover { + text-decoration: none; + } + } + } + + .placement { + color: #2a2a2a; + font-size: 14px; + font-weight: 500; + line-height: 51px; + } + + .points { + color: #2a2a2a; + font-size: 14px; + font-weight: 400; + line-height: 51px; + } + } +} + +.buttons { + margin-top: 10px; + display: flex; + flex-direction: row; + justify-content: center; + + .close-btn { + color: #fafafb; + font-family: Roboto, sans-serif; + font-size: 14px; + font-weight: 700; + letter-spacing: 0.8px; + line-height: 40px; + background-color: #137d60; + border-radius: 20px; + border: none; + text-transform: uppercase; + padding: 0 20px; + + &:hover { + background-color: #0ab88a !important; + box-shadow: 0 1px 5px 0 rgba(0, 0, 0, 0.2); + } + } +} + +.header-table-content { + display: flex; + align-items: center; +} + +.sort-container { + display: flex; + flex-direction: column; + margin-left: 5px; + padding: 0; + border: none; + outline: none; + background: transparent; +} + +.sort-container > div { + width: 0; + height: 0; + border-left: 4px solid transparent; + border-right: 4px solid transparent; +} + +.sort-up { + border-bottom: 4px solid $light-gray; + margin-bottom: 2px; + + &.active { + border-bottom: 4px solid $tc-black; + } +} + +.sort-down { + border-top: 4px solid $light-gray; + + &.active { + border-top: 4px solid $tc-black; + } +} diff --git a/src/shared/components/Contentful/Modal/style.scss b/src/shared/components/Contentful/Modal/style.scss index c94207a613..4e5dea9b8b 100644 --- a/src/shared/components/Contentful/Modal/style.scss +++ b/src/shared/components/Contentful/Modal/style.scss @@ -25,3 +25,9 @@ opacity: 1; } } + +.closeButton { + display: flex; + justify-content: center; + margin: 40px 0 80px 0; +} diff --git a/src/shared/components/Dashboard/CurrentActivity/Header/index.jsx b/src/shared/components/Dashboard/CurrentActivity/Header/index.jsx index e0615cfead..3b42ee67a5 100644 --- a/src/shared/components/Dashboard/CurrentActivity/Header/index.jsx +++ b/src/shared/components/Dashboard/CurrentActivity/Header/index.jsx @@ -9,13 +9,18 @@ import Option from './Option'; import './style.scss'; export default function Header({ - numChallenges, + // numChallenges, numCommunities, switchTab, tab, }) { + /** + * Temporary hide My Active Challenges - community-app#5004 + */ + /* let myChallengesTitle = 'My Active Challenges'; if (numChallenges) myChallengesTitle += ` (${numChallenges})`; + */ let myCommunitiesTitle = 'My Communities'; if (numCommunities) myCommunitiesTitle += ` (${numCommunities})`; @@ -25,11 +30,13 @@ export default function Header({ + {/* {/* Temporary hide My Active Challenges - community-app#5004