diff --git a/.circleci/config.yml b/.circleci/config.yml index c70179ce1b..f73a20e51d 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -231,7 +231,6 @@ workflows: branches: only: - develop - - topgear-to-contentful # This is alternate dev env for parallel testing - "build-test": context : org-global diff --git a/.eslintrc b/.eslintrc index ddc5f09737..0636c3dfd6 100644 --- a/.eslintrc +++ b/.eslintrc @@ -2,7 +2,8 @@ "extends": "./node_modules/topcoder-react-utils/config/eslint/default.json", "rules": { "jsx-a11y/anchor-is-valid": false, - "import/no-cycle": [2, { "maxDepth": 1 }] + "import/no-cycle": [2, { "maxDepth": 1 }], + "react/forbid-prop-types": false }, "env": { "browser": true diff --git a/__tests__/shared/components/__snapshots__/TopcoderFooter.jsx.snap b/__tests__/shared/components/__snapshots__/TopcoderFooter.jsx.snap index adf5d611f5..e34a17d9e8 100644 --- a/__tests__/shared/components/__snapshots__/TopcoderFooter.jsx.snap +++ b/__tests__/shared/components/__snapshots__/TopcoderFooter.jsx.snap @@ -348,15 +348,6 @@ exports[`Matches shallow shapshot 1`] = ` Talk to Sales -
  • - - Terms - -
  • Policies diff --git a/__tests__/shared/containers/__snapshots__/TopcoderHeader.jsx.snap b/__tests__/shared/containers/__snapshots__/TopcoderHeader.jsx.snap index 54b150a474..a68a045aea 100644 --- a/__tests__/shared/containers/__snapshots__/TopcoderHeader.jsx.snap +++ b/__tests__/shared/containers/__snapshots__/TopcoderHeader.jsx.snap @@ -11,6 +11,7 @@ exports[`Matches shallow snapshot 1`] = ` closeMobileMenu={[Function]} closeSearch={[Function]} dismissChallengeNotifications={[Function]} + headerMenu={null} loadNotifications={[Function]} markAllNotificationAsRead={[Function]} markAllNotificationAsSeen={[Function]} diff --git a/config/default.js b/config/default.js index 8b7a9d178b..483681f0dd 100644 --- a/config/default.js +++ b/config/default.js @@ -160,7 +160,6 @@ module.exports = { COMMUNITY_API: 'http://localhost:8000', COMMUNITY_APP_GITHUB_ISSUES: 'https://github.com/topcoder-platform/community-app/issues', EMAIL_VERIFY_URL: 'http://www.topcoder-dev.com/settings/account/changeEmail', - THRIVE_POLL_FEED: 'https://www.topcoder.com/feed', }, /* Information about Topcoder user groups can be cached in various places. @@ -406,4 +405,5 @@ module.exports = { TC_EDU_ARTICLES_PATH: '/articles', TC_EDU_SEARCH_PATH: '/search', TC_EDU_SEARCH_BAR_MAX_RESULTS_EACH_GROUP: 3, + POLICY_PAGES_PATH: '/policy', }; diff --git a/package-lock.json b/package-lock.json index 596c83c1c1..e74e82a77f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2034,6 +2034,21 @@ "resolved": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.1.tgz", "integrity": "sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU=" }, + "angular-animate": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/angular-animate/-/angular-animate-1.8.0.tgz", + "integrity": "sha512-ROFK3UIn1MSVpqAlay15ZxjPmVbvwaO3Zn/2vhmQdYeqxSbUVuOckcvtDLBpHPGPtOAreu35qfV7NQ7u2EgDcA==" + }, + "angular-aria": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/angular-aria/-/angular-aria-1.8.0.tgz", + "integrity": "sha512-eCQI6EwgY6bYHdzIUfDABHnZjoZ3bNYpCsnceQF4bLfbq1QtZ7raRPNca45sj6C9Pfjde6PNcEDvuLozFPYnrQ==" + }, + "angular-material": { + "version": "1.1.24", + "resolved": "https://registry.npmjs.org/angular-material/-/angular-material-1.1.24.tgz", + "integrity": "sha512-WlepLr+04g9g+Pd26t0G7vNRvF6XVCgRo7VZA1d/XGwpt5O0KafKujcaurFkYvgF5qaGGQXGPokX8sj6KaxDsw==" + }, "ansi-colors": { "version": "3.2.4", "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-3.2.4.tgz", @@ -3760,6 +3775,16 @@ "integrity": "sha1-aN/1++YMUes3cl6p4+0xDcwed24=", "dev": true }, + "bourbon": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/bourbon/-/bourbon-4.3.4.tgz", + "integrity": "sha1-TaOAAp6SwMj5dkx3lFGhNLEefMM=" + }, + "bourbon-neat": { + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/bourbon-neat/-/bourbon-neat-1.7.2.tgz", + "integrity": "sha1-oiixJ0R53iR20yszFTEHylBTzz0=" + }, "bowser": { "version": "2.9.0", "resolved": "https://registry.npmjs.org/bowser/-/bowser-2.9.0.tgz", @@ -5693,6 +5718,11 @@ } } }, + "css-mediaquery": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/css-mediaquery/-/css-mediaquery-0.1.2.tgz", + "integrity": "sha1-aiw3NEkoYYYxxUvTPO3TAdoYvqA=" + }, "css-modules-loader-core": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/css-modules-loader-core/-/css-modules-loader-core-1.1.0.tgz", @@ -10500,6 +10530,11 @@ } } }, + "hyphenate-style-name": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/hyphenate-style-name/-/hyphenate-style-name-1.0.4.tgz", + "integrity": "sha512-ygGZLjmXfPHj+ZWh6LwbC37l43MhfztxetbFCoYTM2VjkIUpeHgSNn7QIyVFj7YQ1Wl9Cbw5sholVJPzWvC2MQ==" + }, "i18n-iso-countries": { "version": "3.7.8", "resolved": "https://registry.npmjs.org/i18n-iso-countries/-/i18n-iso-countries-3.7.8.tgz", @@ -13674,6 +13709,14 @@ "integrity": "sha512-ea2eGWOqNxPcXv8dyERdSr/6FmzvWwzjMxpfGB/sbMccXoct+xY+YukPD+QTUZwyvK7BZwcr4m21WBOW41pAkg==", "dev": true }, + "matchmediaquery": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/matchmediaquery/-/matchmediaquery-0.3.1.tgz", + "integrity": "sha512-Hlk20WQHRIm9EE9luN1kjRjYXAQToHOIAHPJn9buxBwuhfTHoKUcX+lXBbxc85DVQfXYbEQ4HcwQdd128E3qHQ==", + "requires": { + "css-mediaquery": "^0.1.2" + } + }, "material-colors": { "version": "1.2.6", "resolved": "https://registry.npmjs.org/material-colors/-/material-colors-1.2.6.tgz", @@ -14241,7 +14284,7 @@ "dev": true }, "navigation-component": { - "version": "github:topcoder-platform/navigation-component#24bd50897313b8236a2f0193de0ab5b7a26ab31b", + "version": "github:topcoder-platform/navigation-component#4938269d5610f3f8bff65f23459a37d01121e6f6", "from": "github:topcoder-platform/navigation-component#develop", "requires": { "classnames": "^2.2.6", @@ -14394,6 +14437,14 @@ "semver": "^5.4.1" } }, + "node-bourbon": { + "version": "4.2.8", + "resolved": "https://registry.npmjs.org/node-bourbon/-/node-bourbon-4.2.8.tgz", + "integrity": "sha1-5ETx8JQ0q3ZQ6jGMKOLhA9P5Qs0=", + "requires": { + "bourbon": "^4.2.6" + } + }, "node-dir": { "version": "0.1.17", "resolved": "https://registry.npmjs.org/node-dir/-/node-dir-0.1.17.tgz", @@ -14532,6 +14583,15 @@ "resolved": "https://registry.npmjs.org/node-modules-regexp/-/node-modules-regexp-1.0.0.tgz", "integrity": "sha1-jZ2+KJZKSsVxLpExZCEHxx6Q7EA=" }, + "node-neat": { + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/node-neat/-/node-neat-1.7.2.tgz", + "integrity": "sha1-OEcpELgV4mG4sbmbpRmZRGWhXCE=", + "requires": { + "bourbon-neat": "1.7.2", + "node-bourbon": "^4.2.3" + } + }, "node-notifier": { "version": "5.4.3", "resolved": "https://registry.npmjs.org/node-notifier/-/node-notifier-5.4.3.tgz", @@ -17968,6 +18028,17 @@ "resize-observer-polyfill": "^1.5.1" } }, + "react-responsive": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/react-responsive/-/react-responsive-8.1.0.tgz", + "integrity": "sha512-U8Nv2/ZWACIw/fAE9XNPbc2Xo33X5q1bcCASc2SufvJ9ifB+o/rokfogfznSVcvS22hN1rafGi0uZD6GiVFEHw==", + "requires": { + "hyphenate-style-name": "^1.0.0", + "matchmediaquery": "^0.3.0", + "prop-types": "^15.6.1", + "shallow-equal": "^1.1.0" + } + }, "react-router": { "version": "4.3.1", "resolved": "https://registry.npmjs.org/react-router/-/react-router-4.3.1.tgz", @@ -20012,8 +20083,7 @@ "semver-compare": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/semver-compare/-/semver-compare-1.0.0.tgz", - "integrity": "sha1-De4hahyUGrN+nvsXiPavxf9VN/w=", - "dev": true + "integrity": "sha1-De4hahyUGrN+nvsXiPavxf9VN/w=" }, "semver-regex": { "version": "2.0.0", @@ -20159,6 +20229,11 @@ } } }, + "shallow-equal": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/shallow-equal/-/shallow-equal-1.2.1.tgz", + "integrity": "sha512-S4vJDjHHMBaiZuT9NPb616CSmLf618jawtv3sufLl6ivK8WocjAo58cXwbRV1cgqxH0Qbv+iUt6m05eqEa2IRA==" + }, "shallowequal": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/shallowequal/-/shallowequal-1.1.0.tgz", @@ -21989,14 +22064,17 @@ } }, "tc-accounts": { - "version": "git+https://github.com/appirio-tech/accounts-app.git#9d0daa189dbf5127ad6ca470ed1683eeb2495ac7", + "version": "git+https://github.com/appirio-tech/accounts-app.git#33f4aeb29d07dbe4e6d8206d718830fd54943f47", "from": "git+https://github.com/appirio-tech/accounts-app.git#dev", "requires": { "@uirouter/angularjs": "^1.0.0", "angucomplete-alt": "^2.1.0", "angular": "^1.4.8", + "angular-animate": "^1.7.9", + "angular-aria": "^1.7.9", "angular-auth0": "^3.0.0", "angular-cookies": "^1.5.1", + "angular-material": "^1.1.21", "angular-messages": "^1.5.2", "appirio-tech-ng-iso-constants": "github:appirio-tech/ng-iso-constants#v1.0.7", "appirio-tech-ng-ui-components": "^2.2.4", @@ -22495,6 +22573,7 @@ "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", @@ -22511,6 +22590,7 @@ "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": { @@ -22519,44 +22599,16 @@ "resolved": "https://registry.npmjs.org/coffeescript/-/coffeescript-1.12.7.tgz", "integrity": "sha512-pLXHFxQMPklVoEekowk8b3erNynC+DVJzChxS/LCBBgR6/8AJkHivkm//zbowcfc7BTCAjryuhx6gPqPRfsFoA==" }, - "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=", + "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": { - "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" - } - } + "minimist": "^1.2.0", + "semver-compare": "^1.0.0", + "xml2js": "^0.4.17" } }, - "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=" - }, "loose-envify": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", @@ -22565,6 +22617,11 @@ "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", @@ -22585,60 +22642,20 @@ "react-is": "^16.8.1" } }, - "query-string": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/query-string/-/query-string-3.0.3.tgz", - "integrity": "sha1-ri4UtNBQcdTpuetIc8NbDc1C5jg=", + "rc-slider": { + "version": "8.6.4", + "resolved": "https://registry.npmjs.org/rc-slider/-/rc-slider-8.6.4.tgz", + "integrity": "sha512-CV2i2Ww6ib0EjFuBKvgjw3PgT6QwvWKC93iEpqPtrztZrx5wO9Iw//AUri4KHRqptW13AuBvFdEHovqLi6XFTw==", "requires": { - "strict-uri-encode": "^1.0.0" - } - }, - "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", + "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" } }, - "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", @@ -22646,6 +22663,20 @@ "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==" } } }, @@ -23865,16 +23896,6 @@ "hoek": "2.x.x" } }, - "bourbon": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/bourbon/-/bourbon-4.3.4.tgz", - "integrity": "sha1-TaOAAp6SwMj5dkx3lFGhNLEefMM=" - }, - "bourbon-neat": { - "version": "1.7.2", - "resolved": "https://registry.npmjs.org/bourbon-neat/-/bourbon-neat-1.7.2.tgz", - "integrity": "sha1-oiixJ0R53iR20yszFTEHylBTzz0=" - }, "bowser": { "version": "1.9.4", "resolved": "https://registry.npmjs.org/bowser/-/bowser-1.9.4.tgz", @@ -28059,14 +28080,6 @@ "lower-case": "^1.1.1" } }, - "node-bourbon": { - "version": "4.2.8", - "resolved": "https://registry.npmjs.org/node-bourbon/-/node-bourbon-4.2.8.tgz", - "integrity": "sha1-5ETx8JQ0q3ZQ6jGMKOLhA9P5Qs0=", - "requires": { - "bourbon": "^4.2.6" - } - }, "node-fetch": { "version": "1.7.3", "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-1.7.3.tgz", @@ -28204,15 +28217,6 @@ } } }, - "node-neat": { - "version": "1.7.2", - "resolved": "https://registry.npmjs.org/node-neat/-/node-neat-1.7.2.tgz", - "integrity": "sha1-OEcpELgV4mG4sbmbpRmZRGWhXCE=", - "requires": { - "bourbon-neat": "1.7.2", - "node-bourbon": "^4.2.3" - } - }, "node-sass": { "version": "3.13.1", "resolved": "https://registry.npmjs.org/node-sass/-/node-sass-3.13.1.tgz", @@ -31186,6 +31190,111 @@ "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", @@ -32656,9 +32765,9 @@ "integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==" }, "topcoder-react-lib": { - "version": "1000.13.6", - "resolved": "https://registry.npmjs.org/topcoder-react-lib/-/topcoder-react-lib-1000.13.6.tgz", - "integrity": "sha512-bVr5yz0tIRO1uRrGx1W+pgoM+eZLrFqli9xlyeZ/PYqypHpcFzqOrxJvPSKyHhCwjJkP9K5wFgosK9Jkzofgbg==", + "version": "0.17.2", + "resolved": "https://registry.npmjs.org/topcoder-react-lib/-/topcoder-react-lib-0.17.2.tgz", + "integrity": "sha512-jYuxoSAIKtGB0ql8O5w7xh1tfYnXTBoU0Fq/j/BBbQA+XOhFZcgtseRyOb8JH/3jiyZpKFMTTh0ZTEFOhhi2TQ==", "requires": { "auth0-js": "^6.8.4", "config": "^3.2.0", @@ -32671,7 +32780,6 @@ "qs": "^6.5.2", "react": "^16.4.1", "react-dom": "^16.4.1", - "react-ga": "^2.7.0", "react-redux": "^6.0.1", "redux": "^3.7.2", "redux-actions": "^2.4.0", @@ -32782,12 +32890,12 @@ }, "dependencies": { "auth0-js": { - "version": "9.13.2", - "resolved": "https://registry.npmjs.org/auth0-js/-/auth0-js-9.13.2.tgz", - "integrity": "sha512-gWlf+X3XhCT9JboYpGviflv0pHcaHFPGtkLXiebyJohHDKddiu2rZkezp9kZHEoXqxhtNqgWuuaXkcla5JtnXg==", + "version": "9.13.4", + "resolved": "https://registry.npmjs.org/auth0-js/-/auth0-js-9.13.4.tgz", + "integrity": "sha512-G7wXTtEUe8OG5UMdcFPoS47odorEZ3WerNyWLLhoGlLqYcPgv0t+B0ECHv/rVLULbpctbSBrRFFYa43/bJV4+Q==", "requires": { "base64-js": "^1.3.0", - "idtoken-verifier": "^2.0.2", + "idtoken-verifier": "^2.0.3", "js-cookie": "^2.2.0", "qs": "^6.7.0", "superagent": "^3.8.3", diff --git a/package.json b/package.json index 66d90fd976..68988aba5b 100644 --- a/package.json +++ b/package.json @@ -62,7 +62,6 @@ "filestack-react": "^2.0.0", "flag-icon-css": "^3.3.0", "focus-trap-react": "^6.0.0", - "react-ga": "^2.7.0", "helmet": "^3.12.1", "highlight.js": "^9.18.1", "html-to-text": "^5.1.1", @@ -100,6 +99,7 @@ "react-dates": "^18.2.2", "react-dom": "^16.4.1", "react-dotdotdot": "^1.3.1", + "react-ga": "^2.7.0", "react-helmet": "^5.2.0", "react-html-parser": "^2.0.2", "react-image-fallback": "^7.1.0", @@ -109,6 +109,7 @@ "react-player": "^0.24.1", "react-redux": "^5.0.7", "react-redux-toastr": "^7.2.6", + "react-responsive": "^8.1.0", "react-router": "^4.3.1", "react-router-dom": "^4.3.1", "react-select": "^1.2.0", @@ -134,7 +135,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": "0.17.2", + "topcoder-react-lib": "0.17.2", "topcoder-react-ui-kit": "^1.0.11", "topcoder-react-utils": "0.7.8", "turndown": "^4.0.2", diff --git a/src/shared/actions/contentful.js b/src/shared/actions/contentful.js index dd17409407..8f5b4d556d 100644 --- a/src/shared/actions/contentful.js +++ b/src/shared/actions/contentful.js @@ -297,6 +297,32 @@ async function getChallengesBlockDone(blockProps) { }; } +/** + * Policy pages fetch init + */ +function getPolicyPagesInit() { + return {}; +} + +/** + * Policy pages fetch done + */ +async function getPolicyPagesDone() { + const service = getService({ + preview: false, + spaceName: 'default', + environment: 'master', + }); + + const res = await service.queryEntries({ + content_type: 'policyPage', + }); + + return { + data: [...res.items], + }; +} + export default redux.createActions({ CONTENTFUL: { BOOK_CONTENT: bookContent, @@ -312,5 +338,7 @@ export default redux.createActions({ GET_MENU_DONE: getMenuDone, GET_CHALLENGES_BLOCK_INIT: getChallengesBlockInit, GET_CHALLENGES_BLOCK_DONE: getChallengesBlockDone, + GET_POLICY_PAGES_INIT: getPolicyPagesInit, + GET_POLICY_PAGES_DONE: getPolicyPagesDone, }, }); diff --git a/src/shared/components/Header/index.jsx b/src/shared/components/Header/index.jsx index 28f85b0051..356f268e3a 100644 --- a/src/shared/components/Header/index.jsx +++ b/src/shared/components/Header/index.jsx @@ -19,7 +19,7 @@ try { const Header = ({ profile, auth, notifications, loadNotifications, markNotificationAsRead, - markAllNotificationAsRead, markAllNotificationAsSeen, dismissChallengeNotifications, + markAllNotificationAsRead, markAllNotificationAsSeen, dismissChallengeNotifications, headerMenu, }) => { const [activeLevel1Id, setActiveLevel1Id] = useState(); const [path, setPath] = useState(); @@ -71,7 +71,7 @@ const Header = ({ return (
    _.map(policyDataMenu, item => ( +
  • + {item.menuLinkText} +
  • +)); + +function PolicyPages({ + match, + policyData, +}) { + const [mNavi, setMNavi] = useState({ policies: false, legal: false }); + + function handeSectionClick() { + setMNavi({ + policies: this === 'policies', legal: this === 'legal', + }); + } + // auto scroll to anchors + useEffect(() => { + if (isomorphy.isClientSide()) { + const { hash } = window.location; + setTimeout(() => { + const anchor = document.getElementById(hash ? hash.slice(1) : null); + if (anchor) { + anchor.scrollIntoView({ behavior: 'smooth', block: 'start', inline: 'nearest' }); + } + }, 2000); + } + }); + + let { slug } = match.params; + const pages = policyData.Policies.concat(policyData.Legal); + if (!slug) { + // eslint-disable-next-line prefer-destructuring + slug = pages[0].slug; + } + const policyPage = _.find(pages, { slug }); + return ( +
    + + +
    +

    Policies

    +
      {menuItems(policyData.Policies, slug)}
    +

    Legal

    +
      {menuItems(policyData.Legal, slug)}
    +
    +
    +
    + +
    +
    + Policies +
    +
      + {menuItems(policyData.Policies, slug)} +
    +
    + Legal +
    +
      + {menuItems(policyData.Legal, slug)} +
    +
    +
    +
    + { + slug && !policyPage ? ( + + ) : ( + + ) + } +
    +
    + ); +} + +PolicyPages.propTypes = { + match: PT.shape().isRequired, + policyData: PT.shape().isRequired, +}; + +export default PolicyPages; diff --git a/src/shared/components/PolicyPages/styles.scss b/src/shared/components/PolicyPages/styles.scss new file mode 100644 index 0000000000..afca09b5cf --- /dev/null +++ b/src/shared/components/PolicyPages/styles.scss @@ -0,0 +1,147 @@ +@import '~styles/mixins'; + +.policy-pages-container { + position: relative; + max-width: $screen-md; + margin: 130px auto 200px auto; + display: grid; + grid-template-columns: 300px 1fr; + + @include xs-to-md { + display: flex; + flex-direction: column; + margin-top: 0; + } + + .navi { + display: flex; + flex-direction: column; + width: 200px; + margin-right: 85px; + padding-left: 15px; + padding-top: 15px; + + @include xs-to-md { + width: 100%; + background: white; + border-bottom: 1px solid #e0e0e0; + } + + .navi-section-title, + .navi-section-title2 { + text-transform: uppercase; + color: #2a2a2a; + font-family: Barlow, sans-serif; + font-size: 20px; + font-weight: 600; + line-height: 24px; + margin-bottom: 15px; + + @include xs-to-md { + margin-bottom: 5px; + } + } + + .navi-section-title2 { + margin-top: 42px; + + @include xs-to-md { + margin-top: 12px; + } + } + + .navi-section { + list-style: none; + + li { + a { + color: #2a2a2a; + font-family: Roboto, sans-serif; + font-size: 16px; + font-weight: 400; + line-height: 38px; + + &:hover { + font-weight: 700; + } + } + + &.active { + a { + font-weight: 700; + } + } + } + } + } + + .mobile-navi { + margin-bottom: 30px; + + .mobile-navi-section-title { + color: #2a2a2a; + font-family: Barlow, sans-serif; + font-size: 18px; + line-height: 24px; + text-transform: uppercase; + font-weight: 600; + padding: 15px; + border-bottom: 1px solid #e0e0e0; + outline: none; + + &::before { + display: inline-block; + content: ''; + height: 13px; + width: 13px; + margin-right: 11px; + border-bottom: 3px solid #aaa; + border-right: 3px solid #aaa; + transform: rotate(-45deg); + } + + &.active { + &::before { + transform: rotate(45deg); + } + } + } + + .mobile-navi-section { + list-style: none; + display: none; + padding-top: 17px; + + &.active { + display: block; + border-bottom: 1px solid #e0e0e0; + } + + li { + padding-left: 40px; + font-family: Roboto, sans-serif; + margin-bottom: 24px; + + &:last-child { + margin-bottom: 15px; + } + + &.active { + border-left: 3px solid #43d7b0; + border-radius: 1.5px; + padding-left: 37px; + + a { + font-weight: 700; + line-height: 26px; + } + } + } + } + } + + .page-content { + min-height: 100vh; + flex: 1; + } +} diff --git a/src/shared/components/TopcoderFooter/index.jsx b/src/shared/components/TopcoderFooter/index.jsx index 34d774af68..b402f76603 100644 --- a/src/shared/components/TopcoderFooter/index.jsx +++ b/src/shared/components/TopcoderFooter/index.jsx @@ -94,7 +94,6 @@ export default function TopcoderFooter() { About Community Changelog Talk to Sales - Terms
    @@ -133,7 +132,7 @@ export default function TopcoderFooter() {
    {`© ${currentYear} Topcoder`} - Policies + Policies
    diff --git a/src/shared/components/challenge-detail/Specification/SideBar/index.jsx b/src/shared/components/challenge-detail/Specification/SideBar/index.jsx index 2603e86f02..bd75aa544e 100644 --- a/src/shared/components/challenge-detail/Specification/SideBar/index.jsx +++ b/src/shared/components/challenge-detail/Specification/SideBar/index.jsx @@ -121,7 +121,7 @@ export default function SideBar({ {reviewTypeTitle} -
    +
    ?
    @@ -132,7 +132,7 @@ export default function SideBar({ User Sign-Off -
    +
    ?
    @@ -184,7 +184,7 @@ export default function SideBar({ Review Scorecard -
    +
    ?
    diff --git a/src/shared/containers/PolicyPages.jsx b/src/shared/containers/PolicyPages.jsx new file mode 100644 index 0000000000..3f2336cc49 --- /dev/null +++ b/src/shared/containers/PolicyPages.jsx @@ -0,0 +1,86 @@ +/** + * Connects the Redux store to the PolicyPages component. + */ +import _ from 'lodash'; +import React from 'react'; +import { connect } from 'react-redux'; +import PT from 'prop-types'; +import actions from 'actions/contentful'; +import PolicyPages from 'components/PolicyPages'; +import LoadingIndicator from 'components/LoadingIndicator'; +import Header from 'containers/TopcoderHeader'; +import Footer from 'components/TopcoderFooter'; + +const HEADE_MENU = [ + { + id: 'business', + title: 'BUSINESS', + href: 'https://www.topcoder.com', + }, + { + id: 'community-123', + title: 'COMMUNITY', + href: '/community/learn', + }, +]; + +class PolicyPagesContainer extends React.Component { + componentDidMount() { + const { loadingPolicyPages, policyData, getPolicyPages } = this.props; + if (!loadingPolicyPages && !policyData) { + getPolicyPages(); + } + } + + render() { + const { + loadingPolicyPages, policyData, + } = this.props; + if (loadingPolicyPages || !policyData) return ; + if (_.isEmpty(policyData)) { + return ( +

    Please, publish Policy Pages in Contentful space to see this page.

    + ); + } + return ( +
    +
    + +
    +
    + ); + } +} + +PolicyPagesContainer.defaultProps = { + loadingPolicyPages: false, + policyData: null, +}; + +PolicyPagesContainer.propTypes = { + loadingPolicyPages: PT.bool, + match: PT.shape().isRequired, + policyData: PT.shape(), + getPolicyPages: PT.func.isRequired, +}; + +function mapStateToProps(state, ownProps) { + return { + p: ownProps.p, + policyData: state.policyPages.policyData, + }; +} + +function mapDispatchToProps(dispatch) { + return { + getPolicyPages: () => { + dispatch(actions.contentful.getPolicyPagesInit()); + dispatch(actions.contentful.getPolicyPagesDone()); + }, + }; +} + +export default connect( + mapStateToProps, + mapDispatchToProps, +)(PolicyPagesContainer); diff --git a/src/shared/containers/TopcoderHeader.js b/src/shared/containers/TopcoderHeader.js index 537372ed51..8303cf3c9b 100644 --- a/src/shared/containers/TopcoderHeader.js +++ b/src/shared/containers/TopcoderHeader.js @@ -38,7 +38,7 @@ function mapDispatchToProps(dispatch) { }; } -function mapStateToProps(state) { +function mapStateToProps(state, ownProps) { return { ...state.topcoderHeader, profile: { @@ -51,6 +51,7 @@ function mapStateToProps(state) { auth: { ...state.auth, }, + headerMenu: ownProps.headerMenu, }; } diff --git a/src/shared/reducers/contentful/policyPages.jsx b/src/shared/reducers/contentful/policyPages.jsx new file mode 100644 index 0000000000..663c9418ab --- /dev/null +++ b/src/shared/reducers/contentful/policyPages.jsx @@ -0,0 +1,38 @@ +/** + * Reducer for state.policyPages + */ +import _ from 'lodash'; +import actions from 'actions/contentful'; +import { handleActions } from 'redux-actions'; + +function onGetPolicyPagesInit(state) { + return { + ...state, + loadingPolicyPages: true, + }; +} + +function onGetPolicyPagesDone(state, action) { + const policyData = _.groupBy(action.payload.data.map(pp => pp.fields), 'menuSection'); + return { + ...state, + loadingPolicyPages: false, + policyData, + }; +} + +/** + * Creates challengesBlock reducer with the specified initial state. + * @param {Object} state Optional. If not given, the default one is + * generated automatically. + * @return {Function} Reducer. + */ +function create(state = {}) { + return handleActions({ + [actions.contentful.getPolicyPagesInit]: onGetPolicyPagesInit, + [actions.contentful.getPolicyPagesDone]: onGetPolicyPagesDone, + }, state); +} + +/* Reducer with the default initial state. */ +export default create(); diff --git a/src/shared/reducers/index.js b/src/shared/reducers/index.js index 8e417d6602..e457d88e62 100644 --- a/src/shared/reducers/index.js +++ b/src/shared/reducers/index.js @@ -27,6 +27,7 @@ import rss from './rss'; import newsletterArchive from './newsletterArchive'; import menuNavigation from './contentful/menuNavigation'; import challengesBlock from './contentful/challengesBlock'; +import policyPages from './contentful/policyPages'; import { factory as challengeListingFactory } from './challenge-listing'; import { factory as examplesFactory } from './examples'; import { factory as pageFactory } from './page'; @@ -137,6 +138,7 @@ export function factory(req) { newsletterArchive, menuNavigation, challengesBlock, + policyPages, newsletterPreferences, })); } diff --git a/src/shared/routes/PolicyPages.jsx b/src/shared/routes/PolicyPages.jsx new file mode 100644 index 0000000000..f03fec58f2 --- /dev/null +++ b/src/shared/routes/PolicyPages.jsx @@ -0,0 +1,21 @@ +/** + * The loader of Policy page webpack chunks. + */ +import React from 'react'; + +import LoadingPagePlaceholder from 'components/LoadingPagePlaceholder'; +import { AppChunk } from 'topcoder-react-utils'; + +export default function PolicyPagesRoute(props) { + return ( + import(/* webpackChunkName: "policyPages/chunk" */ 'containers/PolicyPages') + .then(({ default: PolicyPagesContainer }) => ( + + )) + } + renderPlaceholder={() => } + /> + ); +} diff --git a/src/shared/routes/index.jsx b/src/shared/routes/index.jsx index d8bd5d338d..04f1f6d25f 100644 --- a/src/shared/routes/index.jsx +++ b/src/shared/routes/index.jsx @@ -9,7 +9,7 @@ import React from 'react'; import { Switch, Route, withRouter, Redirect, } from 'react-router-dom'; -import { MetaTags } from 'topcoder-react-utils'; +import { MetaTags, config } from 'topcoder-react-utils'; import PT from 'prop-types'; @@ -22,6 +22,7 @@ import Examples from './Examples'; import Sandbox from './Sandbox'; import Topcoder from './Topcoder'; import TrackHomePages from './TrackHomePages'; +import PolicyPages from './PolicyPages'; function Routes({ communityId }) { const metaTags = ( @@ -54,7 +55,7 @@ function Routes({ communityId }) { {metaTags} - { Examples() } + {Examples()} ( } path="/community/(competitive-programming|data-science|design|development|qa)/how-to-compete" /> +