From 51b7222186696ef11dfc9d4e47f8d8052c90f2e5 Mon Sep 17 00:00:00 2001 From: Kiril Kartunov Date: Fri, 28 Jun 2019 11:54:51 +0300 Subject: [PATCH 1/8] New navi integration to Contentful --- package-lock.json | 578 ++++++++++++++++-- package.json | 1 + src/assets/images/tc-logo.svg | 17 + src/shared/actions/contentful.js | 106 ++++ .../components/Contentful/Menu/index.jsx | 20 +- .../Contentful/MenuLoader/index.jsx | 123 ++++ src/shared/reducers/index.js | 2 + src/shared/reducers/menuNavigation.js | 52 ++ src/shared/utils/contentful.js | 21 + 9 files changed, 871 insertions(+), 49 deletions(-) create mode 100644 src/assets/images/tc-logo.svg create mode 100644 src/shared/containers/Contentful/MenuLoader/index.jsx create mode 100644 src/shared/reducers/menuNavigation.js diff --git a/package-lock.json b/package-lock.json index cfaa80f8f4..31b863ff85 100644 --- a/package-lock.json +++ b/package-lock.json @@ -501,6 +501,110 @@ "integrity": "sha512-tXZCqWtlOOP4wgCp6RjRvLmfuhnqTLy9VHwRochJBCP2nDm27JnnuFEnXFASVyQNHk36jD1tAammsCEEqgscIQ==", "dev": true }, + "@babel/register": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@babel/register/-/register-7.4.4.tgz", + "integrity": "sha512-sn51H88GRa00+ZoMqCVgOphmswG4b7mhf9VOB0LUBAieykq2GnRFerlN+JQkO/ntT7wz4jaHNSRPg9IdMPEUkA==", + "requires": { + "core-js": "3.1.4", + "find-cache-dir": "2.1.0", + "lodash": "4.17.11", + "mkdirp": "0.5.1", + "pirates": "4.0.1", + "source-map-support": "0.5.12" + }, + "dependencies": { + "core-js": { + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.1.4.tgz", + "integrity": "sha512-YNZN8lt82XIMLnLirj9MhKDFZHalwzzrL9YLt6eb0T5D0EDl4IQ90IGkua8mHbnxNrkj1d8hbdizMc0Qmg1WnQ==" + }, + "find-cache-dir": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-2.1.0.tgz", + "integrity": "sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ==", + "requires": { + "commondir": "1.0.1", + "make-dir": "2.1.0", + "pkg-dir": "3.0.0" + } + }, + "find-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", + "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "requires": { + "locate-path": "3.0.0" + } + }, + "locate-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", + "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "requires": { + "p-locate": "3.0.0", + "path-exists": "3.0.0" + } + }, + "make-dir": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", + "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", + "requires": { + "pify": "4.0.1", + "semver": "5.6.0" + } + }, + "p-limit": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.0.tgz", + "integrity": "sha512-pZbTJpoUsCzV48Mc9Nh51VbwO0X9cuPFE8gYwx9BTCt9SF8/b7Zljd2fVgOxhIF/HDTKgpVzs+GPhyKfjLLFRQ==", + "requires": { + "p-try": "2.2.0" + } + }, + "p-locate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", + "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "requires": { + "p-limit": "2.2.0" + } + }, + "p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==" + }, + "pify": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", + "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==" + }, + "pkg-dir": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-3.0.0.tgz", + "integrity": "sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw==", + "requires": { + "find-up": "3.0.0" + } + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" + }, + "source-map-support": { + "version": "0.5.12", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.12.tgz", + "integrity": "sha512-4h2Pbvyy15EE02G+JOZpUCmqWJuqrs+sEkzewTm++BPi7Hvn/HwcqLAcNxYAyI0x13CpPPn+kMjl+hplXMHITQ==", + "requires": { + "buffer-from": "1.1.1", + "source-map": "0.6.1" + } + } + } + }, "@babel/runtime": { "version": "7.3.4", "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.3.4.tgz", @@ -3145,8 +3249,7 @@ "buffer-from": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", - "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==", - "dev": true + "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==" }, "buffer-xor": { "version": "1.0.3", @@ -3968,8 +4071,7 @@ "commondir": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", - "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=", - "dev": true + "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=" }, "commoner": { "version": "0.10.8", @@ -4343,7 +4445,6 @@ "version": "5.2.0", "resolved": "https://registry.npmjs.org/cross-env/-/cross-env-5.2.0.tgz", "integrity": "sha512-jtdNFfFW1hB7sMhr/H6rW1Z45LFqyI431m3qU6bFXcQ3Eh7LtBuG3h74o7ohHZ3crrRkkqHlo4jYHFPcjroANg==", - "dev": true, "requires": { "cross-spawn": "6.0.5", "is-windows": "1.0.2" @@ -4353,7 +4454,6 @@ "version": "6.0.5", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", - "dev": true, "requires": { "nice-try": "1.0.5", "path-key": "2.0.1", @@ -7425,6 +7525,7 @@ "version": "1.2.7", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.7.tgz", "integrity": "sha512-Pxm6sI2MeBD7RdD12RYsqaP0nMiwx8eZBXCa6z2L+mRHm2DYrOYwihmhjpkdjUHwQhslWQjRpEgNq4XvBmaAuw==", + "optional": true, "requires": { "nan": "2.12.1", "node-pre-gyp": "0.10.3" @@ -7432,19 +7533,26 @@ "dependencies": { "abbrev": { "version": "1.1.1", - "bundled": true + "bundled": true, + "dev": true, + "optional": true }, "ansi-regex": { "version": "2.1.1", - "bundled": true + "bundled": true, + "dev": true }, "aproba": { "version": "1.2.0", - "bundled": true + "bundled": true, + "dev": true, + "optional": true }, "are-we-there-yet": { "version": "1.1.5", "bundled": true, + "dev": true, + "optional": true, "requires": { "delegates": "1.0.0", "readable-stream": "2.3.6" @@ -7452,11 +7560,13 @@ }, "balanced-match": { "version": "1.0.0", - "bundled": true + "bundled": true, + "dev": true }, "brace-expansion": { "version": "1.1.11", "bundled": true, + "dev": true, "requires": { "balanced-match": "1.0.0", "concat-map": "0.0.1" @@ -7464,57 +7574,78 @@ }, "chownr": { "version": "1.1.1", - "bundled": true + "bundled": true, + "dev": true, + "optional": true }, "code-point-at": { "version": "1.1.0", - "bundled": true + "bundled": true, + "dev": true }, "concat-map": { "version": "0.0.1", - "bundled": true + "bundled": true, + "dev": true }, "console-control-strings": { "version": "1.1.0", - "bundled": true + "bundled": true, + "dev": true }, "core-util-is": { "version": "1.0.2", - "bundled": true + "bundled": true, + "dev": true, + "optional": true }, "debug": { "version": "2.6.9", "bundled": true, + "dev": true, + "optional": true, "requires": { "ms": "2.0.0" } }, "deep-extend": { "version": "0.6.0", - "bundled": true + "bundled": true, + "dev": true, + "optional": true }, "delegates": { "version": "1.0.0", - "bundled": true + "bundled": true, + "dev": true, + "optional": true }, "detect-libc": { "version": "1.0.3", - "bundled": true + "bundled": true, + "dev": true, + "optional": true }, "fs-minipass": { "version": "1.2.5", "bundled": true, + "dev": true, + "optional": true, "requires": { "minipass": "2.3.5" } }, "fs.realpath": { "version": "1.0.0", - "bundled": true + "bundled": true, + "dev": true, + "optional": true }, "gauge": { "version": "2.7.4", "bundled": true, + "dev": true, + "optional": true, "requires": { "aproba": "1.2.0", "console-control-strings": "1.1.0", @@ -7529,6 +7660,8 @@ "glob": { "version": "7.1.3", "bundled": true, + "dev": true, + "optional": true, "requires": { "fs.realpath": "1.0.0", "inflight": "1.0.6", @@ -7540,11 +7673,15 @@ }, "has-unicode": { "version": "2.0.1", - "bundled": true + "bundled": true, + "dev": true, + "optional": true }, "iconv-lite": { "version": "0.4.24", "bundled": true, + "dev": true, + "optional": true, "requires": { "safer-buffer": "2.1.2" } @@ -7552,6 +7689,8 @@ "ignore-walk": { "version": "3.0.1", "bundled": true, + "dev": true, + "optional": true, "requires": { "minimatch": "3.0.4" } @@ -7559,6 +7698,8 @@ "inflight": { "version": "1.0.6", "bundled": true, + "dev": true, + "optional": true, "requires": { "once": "1.4.0", "wrappy": "1.0.2" @@ -7566,37 +7707,46 @@ }, "inherits": { "version": "2.0.3", - "bundled": true + "bundled": true, + "dev": true }, "ini": { "version": "1.3.5", - "bundled": true + "bundled": true, + "dev": true, + "optional": true }, "is-fullwidth-code-point": { "version": "1.0.0", "bundled": true, + "dev": true, "requires": { "number-is-nan": "1.0.1" } }, "isarray": { "version": "1.0.0", - "bundled": true + "bundled": true, + "dev": true, + "optional": true }, "minimatch": { "version": "3.0.4", "bundled": true, + "dev": true, "requires": { "brace-expansion": "1.1.11" } }, "minimist": { "version": "0.0.8", - "bundled": true + "bundled": true, + "dev": true }, "minipass": { "version": "2.3.5", "bundled": true, + "dev": true, "requires": { "safe-buffer": "5.1.2", "yallist": "3.0.3" @@ -7605,6 +7755,8 @@ "minizlib": { "version": "1.2.1", "bundled": true, + "dev": true, + "optional": true, "requires": { "minipass": "2.3.5" } @@ -7612,17 +7764,22 @@ "mkdirp": { "version": "0.5.1", "bundled": true, + "dev": true, "requires": { "minimist": "0.0.8" } }, "ms": { "version": "2.0.0", - "bundled": true + "bundled": true, + "dev": true, + "optional": true }, "needle": { "version": "2.2.4", "bundled": true, + "dev": true, + "optional": true, "requires": { "debug": "2.6.9", "iconv-lite": "0.4.24", @@ -7632,6 +7789,8 @@ "node-pre-gyp": { "version": "0.10.3", "bundled": true, + "dev": true, + "optional": true, "requires": { "detect-libc": "1.0.3", "mkdirp": "0.5.1", @@ -7648,6 +7807,8 @@ "nopt": { "version": "4.0.1", "bundled": true, + "dev": true, + "optional": true, "requires": { "abbrev": "1.1.1", "osenv": "0.1.5" @@ -7655,11 +7816,15 @@ }, "npm-bundled": { "version": "1.0.5", - "bundled": true + "bundled": true, + "dev": true, + "optional": true }, "npm-packlist": { "version": "1.2.0", "bundled": true, + "dev": true, + "optional": true, "requires": { "ignore-walk": "3.0.1", "npm-bundled": "1.0.5" @@ -7668,6 +7833,8 @@ "npmlog": { "version": "4.1.2", "bundled": true, + "dev": true, + "optional": true, "requires": { "are-we-there-yet": "1.1.5", "console-control-strings": "1.1.0", @@ -7677,30 +7844,40 @@ }, "number-is-nan": { "version": "1.0.1", - "bundled": true + "bundled": true, + "dev": true }, "object-assign": { "version": "4.1.1", - "bundled": true + "bundled": true, + "dev": true, + "optional": true }, "once": { "version": "1.4.0", "bundled": true, + "dev": true, "requires": { "wrappy": "1.0.2" } }, "os-homedir": { "version": "1.0.2", - "bundled": true + "bundled": true, + "dev": true, + "optional": true }, "os-tmpdir": { "version": "1.0.2", - "bundled": true + "bundled": true, + "dev": true, + "optional": true }, "osenv": { "version": "0.1.5", "bundled": true, + "dev": true, + "optional": true, "requires": { "os-homedir": "1.0.2", "os-tmpdir": "1.0.2" @@ -7708,15 +7885,21 @@ }, "path-is-absolute": { "version": "1.0.1", - "bundled": true + "bundled": true, + "dev": true, + "optional": true }, "process-nextick-args": { "version": "2.0.0", - "bundled": true + "bundled": true, + "dev": true, + "optional": true }, "rc": { "version": "1.2.8", "bundled": true, + "dev": true, + "optional": true, "requires": { "deep-extend": "0.6.0", "ini": "1.3.5", @@ -7726,13 +7909,17 @@ "dependencies": { "minimist": { "version": "1.2.0", - "bundled": true + "bundled": true, + "dev": true, + "optional": true } } }, "readable-stream": { "version": "2.3.6", "bundled": true, + "dev": true, + "optional": true, "requires": { "core-util-is": "1.0.2", "inherits": "2.0.3", @@ -7746,37 +7933,51 @@ "rimraf": { "version": "2.6.3", "bundled": true, + "dev": true, + "optional": true, "requires": { "glob": "7.1.3" } }, "safe-buffer": { "version": "5.1.2", - "bundled": true + "bundled": true, + "dev": true }, "safer-buffer": { "version": "2.1.2", - "bundled": true + "bundled": true, + "dev": true, + "optional": true }, "sax": { "version": "1.2.4", - "bundled": true + "bundled": true, + "dev": true, + "optional": true }, "semver": { "version": "5.6.0", - "bundled": true + "bundled": true, + "dev": true, + "optional": true }, "set-blocking": { "version": "2.0.0", - "bundled": true + "bundled": true, + "dev": true, + "optional": true }, "signal-exit": { "version": "3.0.2", - "bundled": true + "bundled": true, + "dev": true, + "optional": true }, "string-width": { "version": "1.0.2", "bundled": true, + "dev": true, "requires": { "code-point-at": "1.1.0", "is-fullwidth-code-point": "1.0.0", @@ -7786,6 +7987,8 @@ "string_decoder": { "version": "1.1.1", "bundled": true, + "dev": true, + "optional": true, "requires": { "safe-buffer": "5.1.2" } @@ -7793,17 +7996,22 @@ "strip-ansi": { "version": "3.0.1", "bundled": true, + "dev": true, "requires": { "ansi-regex": "2.1.1" } }, "strip-json-comments": { "version": "2.0.1", - "bundled": true + "bundled": true, + "dev": true, + "optional": true }, "tar": { "version": "4.4.8", "bundled": true, + "dev": true, + "optional": true, "requires": { "chownr": "1.1.1", "fs-minipass": "1.2.5", @@ -7816,22 +8024,28 @@ }, "util-deprecate": { "version": "1.0.2", - "bundled": true + "bundled": true, + "dev": true, + "optional": true }, "wide-align": { "version": "1.1.3", "bundled": true, + "dev": true, + "optional": true, "requires": { "string-width": "1.0.2" } }, "wrappy": { "version": "1.0.2", - "bundled": true + "bundled": true, + "dev": true }, "yallist": { "version": "3.0.3", - "bundled": true + "bundled": true, + "dev": true } } }, @@ -8147,6 +8361,11 @@ "integrity": "sha1-8QdIy+dq+WS3yWyTxrzCivEgwIE=", "dev": true }, + "gud": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/gud/-/gud-1.0.0.tgz", + "integrity": "sha512-zGEOVKFM5sVPPrYs7J5/hYEw2Pof8KCyOwyhG8sAF26mCAeUFAcYPu1mwB7hhpIP29zOIBaDqwuHdLp0jvZXjw==" + }, "handlebars": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.1.0.tgz", @@ -9280,8 +9499,7 @@ "is-windows": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", - "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", - "dev": true + "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==" }, "is-word-character": { "version": "1.0.2", @@ -11713,6 +11931,31 @@ "dom-walk": "0.1.1" } }, + "mini-create-react-context": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/mini-create-react-context/-/mini-create-react-context-0.3.2.tgz", + "integrity": "sha512-2v+OeetEyliMt5VHMXsBhABoJ0/M4RCe7fatd/fBy6SMiKazUSEt3gxxypfnk2SHMkdBYvorHRoQxuGoiwbzAw==", + "requires": { + "@babel/runtime": "7.4.5", + "gud": "1.0.0", + "tiny-warning": "1.0.2" + }, + "dependencies": { + "@babel/runtime": { + "version": "7.4.5", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.4.5.tgz", + "integrity": "sha512-TuI4qpWZP6lGOGIuGWtp9sPluqYICmbk8T/1vpSysqJxRPkudh/ofFWyqdcMsDf2s7KvDL4/YHgKyvcS3g9CJQ==", + "requires": { + "regenerator-runtime": "0.13.2" + } + }, + "regenerator-runtime": { + "version": "0.13.2", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.2.tgz", + "integrity": "sha512-S/TQAZJO+D3m9xeN1WTI8dLKBBiRgXBlTJvbWjCThHWZj9EvHK70Ff50/tYj2J/fvBY6JtFVwRuazHN2E7M9BA==" + } + } + }, "mini-css-extract-plugin": { "version": "0.4.5", "resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-0.4.5.tgz", @@ -12009,6 +12252,203 @@ "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", "dev": true }, + "navigation-component": { + "version": "git+https://github.com/topcoder-platform/navigation-component.git#69604750b855d16d70c6871c3760ef20f137172d", + "requires": { + "classnames": "2.2.6", + "lodash": "4.17.11", + "moment": "2.24.0", + "prop-types": "15.7.2", + "react-resize-detector": "4.2.0", + "react-router-dom": "5.0.1", + "topcoder-react-utils": "0.7.9" + }, + "dependencies": { + "config": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/config/-/config-3.1.0.tgz", + "integrity": "sha512-t6oDeNQbsIWa+D/KF4959TANzjSHLv1BA/hvL8tHEA3OUSWgBXELKaONSI6nr9oanbKs0DXonjOWLcrtZ3yTAA==", + "requires": { + "json5": "1.0.1" + } + }, + "history": { + "version": "4.9.0", + "resolved": "https://registry.npmjs.org/history/-/history-4.9.0.tgz", + "integrity": "sha512-H2DkjCjXf0Op9OAr6nJ56fcRkTSNrUiv41vNJ6IswJjif6wlpZK0BTfFbi7qK9dXLSYZxkq5lBsj3vUjlYBYZA==", + "requires": { + "@babel/runtime": "7.3.4", + "loose-envify": "1.4.0", + "resolve-pathname": "2.2.0", + "tiny-invariant": "1.0.4", + "tiny-warning": "1.0.2", + "value-equal": "0.4.0" + } + }, + "hoist-non-react-statics": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.0.tgz", + "integrity": "sha512-0XsbTXxgiaCDYDIWFcwkmerZPSwywfUqYmwT4jzewKTQSWoE6FCMoUVOeBJWK3E/CrWbxRG3m5GzY4lnIwGRBA==", + "requires": { + "react-is": "16.8.4" + } + }, + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=" + }, + "json5": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", + "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "requires": { + "minimist": "1.2.0" + } + }, + "minimist": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=" + }, + "path-to-regexp": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.7.0.tgz", + "integrity": "sha1-Wf3g9DW62suhA6hOnTvGTpa5k30=", + "requires": { + "isarray": "0.0.1" + } + }, + "react-redux": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/react-redux/-/react-redux-6.0.1.tgz", + "integrity": "sha512-T52I52Kxhbqy/6TEfBv85rQSDz6+Y28V/pf52vDWs1YRXG19mcFOGfHnY2HsNFHyhP+ST34Aih98fvt6tqwVcQ==", + "requires": { + "@babel/runtime": "7.3.4", + "hoist-non-react-statics": "3.3.0", + "invariant": "2.2.4", + "loose-envify": "1.4.0", + "prop-types": "15.7.2", + "react-is": "16.8.4" + } + }, + "react-router": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/react-router/-/react-router-5.0.1.tgz", + "integrity": "sha512-EM7suCPNKb1NxcTZ2LEOWFtQBQRQXecLxVpdsP4DW4PbbqYWeRiLyV/Tt1SdCrvT2jcyXAXmVTmzvSzrPR63Bg==", + "requires": { + "@babel/runtime": "7.3.4", + "history": "4.9.0", + "hoist-non-react-statics": "3.3.0", + "loose-envify": "1.4.0", + "mini-create-react-context": "0.3.2", + "path-to-regexp": "1.7.0", + "prop-types": "15.7.2", + "react-is": "16.8.4", + "tiny-invariant": "1.0.4", + "tiny-warning": "1.0.2" + } + }, + "react-router-dom": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-5.0.1.tgz", + "integrity": "sha512-zaVHSy7NN0G91/Bz9GD4owex5+eop+KvgbxXsP/O+iW1/Ln+BrJ8QiIR5a6xNPtrdTvLkxqlDClx13QO1uB8CA==", + "requires": { + "@babel/runtime": "7.3.4", + "history": "4.9.0", + "loose-envify": "1.4.0", + "prop-types": "15.7.2", + "react-router": "5.0.1", + "tiny-invariant": "1.0.4", + "tiny-warning": "1.0.2" + } + }, + "redux": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/redux/-/redux-4.0.1.tgz", + "integrity": "sha512-R7bAtSkk7nY6O/OYMVR9RiBI+XghjF9rlbl5806HJbQph0LJVHZrU5oaO4q70eUKiqMRqm4y07KLTlMZ2BlVmg==", + "requires": { + "loose-envify": "1.4.0", + "symbol-observable": "1.2.0" + } + }, + "topcoder-react-utils": { + "version": "0.7.9", + "resolved": "https://registry.npmjs.org/topcoder-react-utils/-/topcoder-react-utils-0.7.9.tgz", + "integrity": "sha512-bH5t7lVTezl3rh2S1pguMWhUlJb39gOLLkCG9jwLCsMKTzri+LsOvpRJ6dOvYZPzA7GdmCgQNeGAoctiqAGb4g==", + "requires": { + "@babel/register": "7.4.4", + "@babel/runtime": "7.3.4", + "body-parser": "1.18.3", + "command-line-args": "5.0.2", + "command-line-usage": "5.0.5", + "compression": "1.7.3", + "config": "3.1.0", + "cookie-parser": "1.4.4", + "cross-env": "5.2.0", + "express": "4.16.4", + "helmet": "3.16.0", + "lodash": "4.17.11", + "moment": "2.24.0", + "morgan": "1.9.1", + "node-forge": "0.7.6", + "prop-types": "15.7.2", + "raf": "3.4.1", + "react": "16.8.4", + "react-css-super-themr": "2.2.0", + "react-dom": "16.8.4", + "react-helmet": "5.2.0", + "react-redux": "6.0.1", + "react-router-dom": "4.3.1", + "redux": "4.0.1", + "redux-actions": "2.6.5", + "redux-devtools": "3.5.0", + "redux-devtools-dock-monitor": "1.1.3", + "redux-devtools-log-monitor": "1.4.0", + "redux-promise": "0.6.0", + "request-ip": "2.1.3", + "serialize-javascript": "1.6.1", + "serve-favicon": "2.5.0", + "shortid": "2.2.14", + "url-parse": "1.4.4" + }, + "dependencies": { + "hoist-non-react-statics": { + "version": "2.5.5", + "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-2.5.5.tgz", + "integrity": "sha512-rqcy4pJo55FTTLWt+bU8ukscqHeE/e9KWvsOW2b/a3afxQZhwkQdT1rPPCJ0rYXdj4vNcasY8zHTH+jF/qStxw==" + }, + "react-router": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/react-router/-/react-router-4.3.1.tgz", + "integrity": "sha512-yrvL8AogDh2X42Dt9iknk4wF4V8bWREPirFfS9gLU1huk6qK41sg7Z/1S81jjTrGHxa3B8R3J6xIkDAA6CVarg==", + "requires": { + "history": "4.9.0", + "hoist-non-react-statics": "2.5.5", + "invariant": "2.2.4", + "loose-envify": "1.4.0", + "path-to-regexp": "1.7.0", + "prop-types": "15.7.2", + "warning": "4.0.3" + } + }, + "react-router-dom": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-4.3.1.tgz", + "integrity": "sha512-c/MlywfxDdCp7EnB7YfPMOfMD3tOtIjrQlj/CKfNMBxdmpJP8xcz5P/UAFn3JbnQCNUxsHyVVqllF9LhgVyFCA==", + "requires": { + "history": "4.9.0", + "invariant": "2.2.4", + "loose-envify": "1.4.0", + "prop-types": "15.7.2", + "react-router": "4.3.1", + "warning": "4.0.3" + } + } + } + } + } + }, "ncname": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/ncname/-/ncname-1.0.0.tgz", @@ -12052,8 +12492,7 @@ "nice-try": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", - "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", - "dev": true + "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==" }, "nocache": { "version": "2.0.0", @@ -12203,6 +12642,11 @@ } } }, + "node-modules-regexp": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/node-modules-regexp/-/node-modules-regexp-1.0.0.tgz", + "integrity": "sha1-jZ2+KJZKSsVxLpExZCEHxx6Q7EA=" + }, "node-notifier": { "version": "5.4.0", "resolved": "https://registry.npmjs.org/node-notifier/-/node-notifier-5.4.0.tgz", @@ -13002,6 +13446,14 @@ "pinkie": "2.0.4" } }, + "pirates": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.1.tgz", + "integrity": "sha512-WuNqLTbMI3tmfef2TKxlQmAiLHKtFhlsCZnPIpuv2Ow0RDVO8lfy1Opf4NUzlMXLjPl+Men7AuVdX6TA+s+uGA==", + "requires": { + "node-modules-regexp": "1.0.0" + } + }, "pixelmatch": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/pixelmatch/-/pixelmatch-4.0.2.tgz", @@ -14945,6 +15397,11 @@ "performance-now": "2.1.0" } }, + "raf-schd": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/raf-schd/-/raf-schd-4.0.1.tgz", + "integrity": "sha512-/QTXV4+Tf81CmJgTZac47N63ZzKmaVe+1cQX/grCFeLrs4Mcc6oq+KJfbF3tFjeS1NF91lmTvgmwYjk02UTo9A==" + }, "railroad-diagrams": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/railroad-diagrams/-/railroad-diagrams-1.0.0.tgz", @@ -15472,6 +15929,18 @@ "eventemitter3": "3.1.0" } }, + "react-resize-detector": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/react-resize-detector/-/react-resize-detector-4.2.0.tgz", + "integrity": "sha512-AtOaNIxs0ydua7tEoglXR3902/EdlIj9PXDu1Zj0ug2VAUnkSQjguLGzaG/N6CXLOhJSccTsUCZxjLayQ1mE9Q==", + "requires": { + "lodash": "4.17.11", + "lodash-es": "4.17.11", + "prop-types": "15.7.2", + "raf-schd": "4.0.1", + "resize-observer-polyfill": "1.5.1" + } + }, "react-router": { "version": "4.3.1", "resolved": "https://registry.npmjs.org/react-router/-/react-router-4.3.1.tgz", @@ -16657,6 +17126,11 @@ "integrity": "sha1-79qpjqdFEyTQkrKyFjpqHXqaIUc=", "dev": true }, + "resize-observer-polyfill": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/resize-observer-polyfill/-/resize-observer-polyfill-1.5.1.tgz", + "integrity": "sha512-LwZrotdHOo12nQuZlHEmtuXdqGoOD0OhaxopaNFxWzInpEgaLWoVuAMbTzixuosCx2nEG58ngzW3vxdWoxIgdg==" + }, "resolve": { "version": "1.10.0", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.10.0.tgz", @@ -28016,6 +28490,16 @@ "setimmediate": "1.0.5" } }, + "tiny-invariant": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/tiny-invariant/-/tiny-invariant-1.0.4.tgz", + "integrity": "sha512-lMhRd/djQJ3MoaHEBrw8e2/uM4rs9YMNk0iOr8rHQ0QdbM7D4l0gFl3szKdeixrlyfm9Zqi4dxHCM2qVG8ND5g==" + }, + "tiny-warning": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/tiny-warning/-/tiny-warning-1.0.2.tgz", + "integrity": "sha512-rru86D9CpQRLvsFG5XFdy0KdLAvjdQDyZCsRcuu60WtzFylDM3eAWSxEVz5kzL2Gp544XiUvPbVKtOA/txLi9Q==" + }, "tinycolor2": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/tinycolor2/-/tinycolor2-1.4.1.tgz", diff --git a/package.json b/package.json index cda3f3a074..7de502ca32 100644 --- a/package.json +++ b/package.json @@ -65,6 +65,7 @@ "moment-timezone": "^0.5.21", "money": "^0.2.0", "morgan": "^1.9.0", + "navigation-component": "git+https://github.com/topcoder-platform/navigation-component.git#develop", "node-forge": "^0.7.5", "nuka-carousel": "^4.5.3", "postcss": "^6.0.23", diff --git a/src/assets/images/tc-logo.svg b/src/assets/images/tc-logo.svg new file mode 100644 index 0000000000..88d9bc860f --- /dev/null +++ b/src/assets/images/tc-logo.svg @@ -0,0 +1,17 @@ + + + + Group 3 + Created with Sketch. + + + + + + + + + + + + \ No newline at end of file diff --git a/src/shared/actions/contentful.js b/src/shared/actions/contentful.js index 76b53ffa2a..4c963a00c5 100644 --- a/src/shared/actions/contentful.js +++ b/src/shared/actions/contentful.js @@ -1,5 +1,8 @@ +import _ from 'lodash'; import { getService } from 'services/contentful'; import { redux } from 'topcoder-react-utils'; +import { removeTrailingSlash } from 'utils/url'; +import { menuItemBuilder, target as urlTarget } from 'utils/contentful'; const ERRMSG_UNKNOWN_TARGET = 'Unknown action target'; @@ -125,6 +128,107 @@ async function queryContentDone(operationId, queryId, target, }; } +/** + * Prepare menu fetching + * @param {Object} menuProps The navi menu data from Contentful + */ +function getMenuInit(menuProps) { + return { + ...menuProps, + }; +} + +/** + * Fetches recursively complete navi menu data from Contentful + * @param {Object} menuProps The navi menu data from Contentful + */ +async function getMenuDone(menuProps) { + const { + preview, spaceName, environment, fields, + } = menuProps; + let { baseUrl } = fields; + let menu = []; // will store results here + const service = getService({ preview, spaceName, environment }); + // remove trail slash from baseUrl + baseUrl = baseUrl ? removeTrailingSlash(baseUrl) : baseUrl; + // different menu strucures depending on title + // if title is set new navi supports only 2 levels of menus + // otherwise 3 when directly loaded + if (fields.title) { + menu.push({ + id: menuProps.id, + title: fields.title, + subMenu: [], + }); + } + // Prepare menu loading + const l1P = _.map( + fields.items, + item => service.getEntry(item.sys.id).then(async (L1Item) => { + const mI = menuItemBuilder(baseUrl, L1Item); + const { childRoutes, submenu } = L1Item.fields; + if (childRoutes) { + mI.subMenu = await Promise.all(_.map( + childRoutes, + cR => service.getEntry(cR.sys.id).then( + async (cR2) => { + const url2 = urlTarget(baseUrl, L1Item); + const sI2 = menuItemBuilder(url2, cR2); + // no title => 3 level menu supported + if (!fields.title && cR2.fields.childRoutes) { + sI2.subMenu = await Promise.all(_.map( + cR2.fields.childRoutes, + cR3 => service.getEntry(cR3.sys.id).then( + c3 => menuItemBuilder(urlTarget(url2, cR2), c3), + ), + )); + } + return sI2; + }, + ), + )); + } + if (submenu) { + const submenuNavi = await service.getEntry(submenu.sys.id); + mI.subMenu = await Promise.all(_.map( + submenuNavi.fields.items, + subI => service.getEntry(subI.sys.id).then( + async (sub2) => { + const url2 = urlTarget(baseUrl, L1Item); + const sI2 = menuItemBuilder(url2, sub2); + // no title => 3 level menu supported + if (!fields.title && sub2.fields.submenu) { + const submenuNavi2 = await service.getEntry(sub2.fields.submenu.sys.id); + sI2.subMenu = await Promise.all(_.map( + submenuNavi2.fields.items, + cR3 => service.getEntry(cR3.sys.id).then( + s3 => menuItemBuilder(urlTarget(url2, sub2), s3), + ), + )); + } + return sI2; + }, + ), + )); + } + return mI; + }), + ); + // Load and wait for all menu data + const menuData = await Promise.all(l1P); + // merge and return menu + if (fields.title) { + menu[0].subMenu = menuData; + } else { + menu = menuData; + } + + return { + id: menuProps.id, + menu, + }; +} + export default redux.createActions({ CONTENTFUL: { BOOK_CONTENT: bookContent, @@ -136,5 +240,7 @@ export default redux.createActions({ GET_CONTENT_DONE: getContentDone, QUERY_CONTENT_INIT: queryContentInit, QUERY_CONTENT_DONE: queryContentDone, + GET_MENU_INIT: getMenuInit, + GET_MENU_DONE: getMenuDone, }, }); diff --git a/src/shared/components/Contentful/Menu/index.jsx b/src/shared/components/Contentful/Menu/index.jsx index 620c668314..18f40112ff 100644 --- a/src/shared/components/Contentful/Menu/index.jsx +++ b/src/shared/components/Contentful/Menu/index.jsx @@ -4,6 +4,7 @@ /* global window */ import _ from 'lodash'; import ContentfulLoader from 'containers/ContentfulLoader'; +import ContentfulMenuLoader from 'containers/Contentful/MenuLoader'; import LoadingIndicator from 'components/LoadingIndicator'; import PT from 'prop-types'; import React from 'react'; @@ -168,9 +169,24 @@ export default function ContentfulMenu(props) { preview={preview} spaceName={spaceName} environment={environment} - render={(data) => { - const { fields } = Object.values(data.entries.items)[0]; + render={(menuData) => { + const { fields } = Object.values(menuData.entries.items)[0]; if (!fields) return null; + if (fields.theme === 'General') { + // New navi style menu + // we deligate to special custom component and lib + return ( + + ); + } + // legacy navi themes + // those are still supported... return ( ; + } + if (isomorphy.isClientSide()) { + // eslint-disable-next-line global-require + const { TopNav } = require('navigation-component'); + return ( +
+ } + loggedIn={!_.isEmpty(auth)} + currentLevel1Id={activeLevel1Id} + onChangeLevel1Id={this.handleChangeLevel1Id} + path={path} + openMore={openMore} + setOpenMore={this.handleChangeOpenMore} + /> +
+ ); + } + // no SSR for navi component yet + // TODO when ready + return null; + } +} + +MenuLoaderContainer.defaultProps = { + preview: false, + spaceName: null, + environment: null, + menu: [], +}; + +MenuLoaderContainer.propTypes = { + id: PT.string.isRequired, + preview: PT.bool, + spaceName: PT.string, + environment: PT.string, + fields: PT.shape().isRequired, + auth: PT.shape().isRequired, + loadMenuData: PT.func.isRequired, + menu: PT.arrayOf(PT.shape()), + loading: PT.bool.isRequired, +}; + +function mapStateToProps(state, ownProps) { + return { + auth: state.auth || {}, + menu: state.menuNavigation[ownProps.id] ? state.menuNavigation[ownProps.id].menu : [], + loading: state.menuNavigation[ownProps.id] ? state.menuNavigation[ownProps.id].loading : true, + }; +} + +function mapDispatchToProps(dispatch) { + const a = actions.contentful; + return { + loadMenuData: (ownProps) => { + dispatch(a.getMenuInit(ownProps)); + dispatch(a.getMenuDone(ownProps)); + }, + }; +} + +export default connect(mapStateToProps, mapDispatchToProps)(MenuLoaderContainer); diff --git a/src/shared/reducers/index.js b/src/shared/reducers/index.js index 071be6b883..5207527fbd 100644 --- a/src/shared/reducers/index.js +++ b/src/shared/reducers/index.js @@ -25,6 +25,7 @@ import contentful from './contentful'; import topcoderHeader from './topcoder_header'; import rss from './rss'; import newsletterArchive from './newsletterArchive'; +import menuNavigation from './menuNavigation'; import { factory as challengeListingFactory } from './challenge-listing'; import { factory as examplesFactory } from './examples'; import { factory as pageFactory } from './page'; @@ -132,6 +133,7 @@ export function factory(req) { rss, toastr: toastrReducer, newsletterArchive, + menuNavigation, })); } diff --git a/src/shared/reducers/menuNavigation.js b/src/shared/reducers/menuNavigation.js new file mode 100644 index 0000000000..a0aa9b999f --- /dev/null +++ b/src/shared/reducers/menuNavigation.js @@ -0,0 +1,52 @@ +/** + * Reducer for state.menuNavigation + */ + +import actions from 'actions/contentful'; +import { handleActions } from 'redux-actions'; + +/** + * Handles menuNavigation.getMenuInit action. + * @param {Object} state Previous state. + * @param {Object} action The action. + */ +function onGetMenuInit(state, action) { + return { + ...state, + [action.payload.id]: { + loading: true, + menu: [], + }, + }; +} + +/** + * Handles menuNavigation.getMenuDone action. + * @param {Object} state Previous state. + * @param {Object} action The action. + */ +function onGetMenuDone(state, action) { + return { + ...state, + [action.payload.id]: { + loading: false, + menu: action.payload.menu, + }, + }; +} + +/** + * Creates newsletterArchive 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.getMenuInit]: onGetMenuInit, + [actions.contentful.getMenuDone]: onGetMenuDone, + }, state); +} + +/* Reducer with the default initial state. */ +export default create(); diff --git a/src/shared/utils/contentful.js b/src/shared/utils/contentful.js index afa8a2a7fd..93ce7cf368 100644 --- a/src/shared/utils/contentful.js +++ b/src/shared/utils/contentful.js @@ -83,4 +83,25 @@ export function linkText(item) { || item.fields.linkText /* NavigationMenuItem-only */ || item.fields.name; } +/** + * Builds navi menu items + * @param {String} baseUrl + * @param {Object} item + */ +export function menuItemBuilder(baseUrl, item) { + switch (item.sys.contentType.sys.id) { + case 'route': + return { + title: item.fields.naviMenuLinkText || item.fields.name, + href: target(baseUrl, item), + }; + case 'navigationMenuItem': + return { + title: item.fields.linkText || item.fields.name, + href: target(baseUrl, item), + }; + default: return {}; + } +} + export default undefined; From 2472171b1835cf54e944f19261decf18e722598e Mon Sep 17 00:00:00 2001 From: Kiril Kartunov Date: Mon, 1 Jul 2019 17:53:48 +0300 Subject: [PATCH 2/8] Challenges Component base #2367 --- src/shared/actions/contentful.js | 49 ++++++++ .../components/ChallengesBlock/index.jsx | 47 -------- .../ChallengesBlock/Card/index.jsx | 3 - .../ChallengesBlock/Card/style.scss | 0 .../Contentful/ChallengesBlock/index.jsx | 80 +++++++++++++ .../ChallengesBlock/style.scss | 13 +++ .../components/Contentful/Viewport/index.jsx | 2 +- src/shared/containers/ChallengesBlock.jsx | 106 ------------------ .../containers/Contentful/ChallengesBlock.jsx | 90 +++++++++++++++ .../reducers/contentful/challengesBlock.js | 54 +++++++++ .../{ => contentful}/menuNavigation.js | 2 +- src/shared/reducers/index.js | 4 +- 12 files changed, 291 insertions(+), 159 deletions(-) delete mode 100644 src/shared/components/ChallengesBlock/index.jsx rename src/shared/components/{ => Contentful}/ChallengesBlock/Card/index.jsx (93%) rename src/shared/components/{ => Contentful}/ChallengesBlock/Card/style.scss (100%) create mode 100644 src/shared/components/Contentful/ChallengesBlock/index.jsx rename src/shared/components/{ => Contentful}/ChallengesBlock/style.scss (66%) delete mode 100644 src/shared/containers/ChallengesBlock.jsx create mode 100644 src/shared/containers/Contentful/ChallengesBlock.jsx create mode 100644 src/shared/reducers/contentful/challengesBlock.js rename src/shared/reducers/{ => contentful}/menuNavigation.js (93%) diff --git a/src/shared/actions/contentful.js b/src/shared/actions/contentful.js index 4c963a00c5..c3d06f3e5c 100644 --- a/src/shared/actions/contentful.js +++ b/src/shared/actions/contentful.js @@ -3,6 +3,7 @@ import { getService } from 'services/contentful'; import { redux } from 'topcoder-react-utils'; import { removeTrailingSlash } from 'utils/url'; import { menuItemBuilder, target as urlTarget } from 'utils/contentful'; +import { services } from 'topcoder-react-lib'; const ERRMSG_UNKNOWN_TARGET = 'Unknown action target'; @@ -229,6 +230,52 @@ async function getMenuDone(menuProps) { }; } +/** + * Prepare challenges block fetching + * @param {Object} blockProps + */ +function getChallengesBlockInit(blockProps) { + return { + ...blockProps, + }; +} + +/** + * Fetchs challenges block needed data + * @param {Object} blockProps + */ +async function getChallengesBlockDone(blockProps) { + const { + id, preview, spaceName, environment, + } = blockProps; + // get the Contentful data + const service = getService({ preview, spaceName, environment }); + const block = await service.getEntry(id); + // prepare for getting the challenges + const challengesService = services.challenge.getService(); + const filter = {}; + if (!block.fields.completedChallenges) { + filter.status = 'ACTIVE'; + } + if (block.fields.challengeTitleContains) { + filter.name = block.fields.challengeTitleContains; + } + if (block.fields.challengeType) { + filter.subTrack = block.fields.challengeType.join(','); + } + if (block.fields.technologies) { + filter.technologies = block.fields.technologies.join(','); + } + const challenges = await challengesService.getChallenges(filter); + // console.log('getChallengesBlockDone', block, challenges); + + return { + id, + challenges: challenges.challenges, + fields: block.fields, + }; +} + export default redux.createActions({ CONTENTFUL: { BOOK_CONTENT: bookContent, @@ -242,5 +289,7 @@ export default redux.createActions({ QUERY_CONTENT_DONE: queryContentDone, GET_MENU_INIT: getMenuInit, GET_MENU_DONE: getMenuDone, + GET_CHALLENGES_BLOCK_INIT: getChallengesBlockInit, + GET_CHALLENGES_BLOCK_DONE: getChallengesBlockDone, }, }); diff --git a/src/shared/components/ChallengesBlock/index.jsx b/src/shared/components/ChallengesBlock/index.jsx deleted file mode 100644 index 598638900e..0000000000 --- a/src/shared/components/ChallengesBlock/index.jsx +++ /dev/null @@ -1,47 +0,0 @@ -/** - * Displays a few challenge cards and the link to challenge listing. - */ - -import PT from 'prop-types'; -import React from 'react'; -import { PrimaryButton } from 'topcoder-react-ui-kit'; - -import Card from './Card'; - -import './style.scss'; - -export default function ChallengesBlock({ - baseUrl, - challenges, - setChallengeListingFilter, -}) { - return ( -
-

- Active Challenges -

-
- { - challenges.slice(0, 3).map(challenge => ( - - )) - } -
- -Browse all challenges - -
- ); -} - -ChallengesBlock.propTypes = { - baseUrl: PT.string.isRequired, - challenges: PT.arrayOf(PT.object).isRequired, - setChallengeListingFilter: PT.func.isRequired, -}; diff --git a/src/shared/components/ChallengesBlock/Card/index.jsx b/src/shared/components/Contentful/ChallengesBlock/Card/index.jsx similarity index 93% rename from src/shared/components/ChallengesBlock/Card/index.jsx rename to src/shared/components/Contentful/ChallengesBlock/Card/index.jsx index b2364f7465..bf4722c621 100644 --- a/src/shared/components/ChallengesBlock/Card/index.jsx +++ b/src/shared/components/Contentful/ChallengesBlock/Card/index.jsx @@ -20,7 +20,6 @@ const FORMAT = 'MMM D, HH:mm'; export default function Card({ baseUrl, challenge, - setChallengeListingFilter, }) { const { subTrack, @@ -55,7 +54,6 @@ export default function Card({ return (
setImmediate(() => setChallengeListingFilter({ subtracks: [subTrack] }))} to={`${baseUrl}/challenges?filter[subtracks][0]=${ encodeURIComponent(subTrack)}`} > @@ -100,5 +98,4 @@ Card.propTypes = { submissionEndDate: PT.string.isRequired, track: PT.string.isRequired, }).isRequired, - setChallengeListingFilter: PT.func.isRequired, }; diff --git a/src/shared/components/ChallengesBlock/Card/style.scss b/src/shared/components/Contentful/ChallengesBlock/Card/style.scss similarity index 100% rename from src/shared/components/ChallengesBlock/Card/style.scss rename to src/shared/components/Contentful/ChallengesBlock/Card/style.scss diff --git a/src/shared/components/Contentful/ChallengesBlock/index.jsx b/src/shared/components/Contentful/ChallengesBlock/index.jsx new file mode 100644 index 0000000000..6df10d59b3 --- /dev/null +++ b/src/shared/components/Contentful/ChallengesBlock/index.jsx @@ -0,0 +1,80 @@ +/** + * Displays a few challenge cards and the link to challenge listing. + */ + +import PT from 'prop-types'; +import React from 'react'; +import { PrimaryButton } from 'topcoder-react-ui-kit'; +import Carousel from 'nuka-carousel'; +import ArrowNext from 'assets/images/arrow_right.svg'; +import ArrowPrev from 'assets/images/arrow-left.svg'; + +import Card from './Card'; + +import './style.scss'; + +export default function ChallengesBlock({ + baseUrl, + challenges, + fields, +}) { + return ( +
+

{fields.title}

+
+ ( + + + + )} + renderCenterRightControls={({ nextSlide }) => ( + + + + )} + > + { + challenges.slice(0, fields.limit || 10).map(challenge => ( + + )) + } + +
+ { + fields.buttonText && fields.buttonUrl ? ( + + {fields.buttonText} + + ) : null + } +
+ ); +} + +ChallengesBlock.propTypes = { + baseUrl: PT.string.isRequired, + challenges: PT.arrayOf(PT.object).isRequired, + fields: PT.shape().isRequired, +}; diff --git a/src/shared/components/ChallengesBlock/style.scss b/src/shared/components/Contentful/ChallengesBlock/style.scss similarity index 66% rename from src/shared/components/ChallengesBlock/style.scss rename to src/shared/components/Contentful/ChallengesBlock/style.scss index 7d4bd4af93..c7a63db4eb 100644 --- a/src/shared/components/ChallengesBlock/style.scss +++ b/src/shared/components/Contentful/ChallengesBlock/style.scss @@ -22,3 +22,16 @@ margin-bottom: 40px; } + +.control { + border: 0; + background: rgba(0, 0, 0, 0.4); + color: white; + padding: 10px; + cursor: pointer; + display: flex; +} + +.multiContent { + width: 100%; +} diff --git a/src/shared/components/Contentful/Viewport/index.jsx b/src/shared/components/Contentful/Viewport/index.jsx index 20eb4af7fa..acf70c16ea 100644 --- a/src/shared/components/Contentful/Viewport/index.jsx +++ b/src/shared/components/Contentful/Viewport/index.jsx @@ -5,7 +5,7 @@ import _ from 'lodash'; import Accordion from 'components/Contentful/Accordion'; import Banner from 'components/Contentful/Banner'; -import ChallengesBlock from 'containers/ChallengesBlock'; +import ChallengesBlock from 'containers/Contentful/ChallengesBlock'; import ContentBlock from 'components/Contentful/ContentBlock'; import BlogPost from 'components/Contentful/BlogPost'; import ContentfulLoader from 'containers/ContentfulLoader'; diff --git a/src/shared/containers/ChallengesBlock.jsx b/src/shared/containers/ChallengesBlock.jsx deleted file mode 100644 index dc15b997ad..0000000000 --- a/src/shared/containers/ChallengesBlock.jsx +++ /dev/null @@ -1,106 +0,0 @@ -/** - * A block that fetches (if necessary) and renders a few cards with active - * challenges. It originates from Veterans community's Home page. Spawned - * to a separate component, to expose it to Contentful. Should be further - * enhanced for usability in other places. - */ - -import challengeListingActions from 'actions/challenge-listing'; -import challengeListingSidebarActions from 'actions/challenge-listing/sidebar'; -import ChallengesBlock from 'components/ChallengesBlock'; -import LoadingIndicator from 'components/LoadingIndicator'; -import moment from 'moment'; -import PT from 'prop-types'; -import React from 'react'; -import shortId from 'shortid'; -import { connect } from 'react-redux'; -import { BUCKETS } from 'utils/challenge-listing/buckets'; - -/* Holds cache time [ms] for the data demanded by this container. */ -const MAXAGE = 30 * 60 * 1000; - -class ChallengesBlockContiner extends React.Component { - componentDidMount() { - const { - getAllActiveChallenges, - lastUpdateOfActiveChallenges, - loadingActiveChallenges, - tokenV3, - } = this.props; - if (Date.now() - lastUpdateOfActiveChallenges > MAXAGE - && !loadingActiveChallenges) getAllActiveChallenges(tokenV3); - } - - render() { - const { - baseUrl, - challenges, - loadingActiveChallenges, - setChallengeListingFilter, - } = this.props; - - const activeChallenges = challenges.filter(x => x.status === 'ACTIVE') - .sort((a, b) => moment(b.registrationStartDate).diff(a.registrationStartDate)); - - if (loadingActiveChallenges && ( - !activeChallenges || !activeChallenges.length - )) { - return ; - } - - return ( - - ); - } -} - -ChallengesBlockContiner.defaultProps = { - tokenV3: null, -}; - -ChallengesBlockContiner.propTypes = { - baseUrl: PT.string.isRequired, - challenges: PT.arrayOf(PT.object).isRequired, - getAllActiveChallenges: PT.func.isRequired, - lastUpdateOfActiveChallenges: PT.number.isRequired, - loadingActiveChallenges: PT.bool.isRequired, - setChallengeListingFilter: PT.func.isRequired, - tokenV3: PT.string, -}; - -function mapStateToProps(state) { - return { - challenges: state.challengeListing.challenges, - lastUpdateOfActiveChallenges: - state.challengeListing.lastUpdateOfActiveChallenges, - loadingActiveChallenges: - Boolean(state.challengeListing.loadingActiveChallengesUUID), - tokenV3: state.auth.tokenV3, - }; -} - -function mapDispatchToActions(dispatch) { - const cla = challengeListingActions.challengeListing; - const clsa = challengeListingSidebarActions.challengeListing.sidebar; - return { - getAllActiveChallenges: (tokenV3) => { - const uuid = shortId(); - dispatch(cla.getAllActiveChallengesInit(uuid)); - dispatch(cla.getAllActiveChallengesDone(uuid, tokenV3)); - }, - setChallengeListingFilter: (filter) => { - dispatch(cla.setFilter(filter)); - dispatch(clsa.selectBucket(BUCKETS.ALL)); - }, - }; -} - -export default connect( - mapStateToProps, - mapDispatchToActions, -)(ChallengesBlockContiner); diff --git a/src/shared/containers/Contentful/ChallengesBlock.jsx b/src/shared/containers/Contentful/ChallengesBlock.jsx new file mode 100644 index 0000000000..0748868e3e --- /dev/null +++ b/src/shared/containers/Contentful/ChallengesBlock.jsx @@ -0,0 +1,90 @@ +/** + * A block that fetches and renders a few cards with active challenges. + */ + +import actions from 'actions/contentful'; +import ChallengesBlock from 'components/Contentful/ChallengesBlock'; +import LoadingIndicator from 'components/LoadingIndicator'; +import PT from 'prop-types'; +import React from 'react'; +import { connect } from 'react-redux'; + +class ChallengesBlockContiner extends React.Component { + componentDidMount() { + const { + getChallenges, + id, + preview, + spaceName, + environment, + } = this.props; + + getChallenges({ + id, + preview, + spaceName, + environment, + }); + } + + render() { + const { + loading, challenges, baseUrl, fields, + } = this.props; + + if (loading) { + return ; + } + + return ( + + ); + } +} + +ChallengesBlockContiner.defaultProps = { + id: null, + preview: false, + spaceName: null, + environment: null, +}; + +ChallengesBlockContiner.propTypes = { + fields: PT.shape().isRequired, + baseUrl: PT.string.isRequired, + challenges: PT.arrayOf(PT.object).isRequired, + getChallenges: PT.func.isRequired, + loading: PT.bool.isRequired, + id: PT.string, + preview: PT.bool, + spaceName: PT.string, + environment: PT.string, +}; + +function mapStateToProps(state, ownProps) { + const data = state.challengesBlock[ownProps.id]; + return { + fields: data ? data.fields : {}, + challenges: data ? data.challenges : [], + loading: data ? data.loading : true, + }; +} + +function mapDispatchToActions(dispatch) { + const a = actions.contentful; + return { + getChallenges: (ownProps) => { + dispatch(a.getChallengesBlockInit(ownProps)); + dispatch(a.getChallengesBlockDone(ownProps)); + }, + }; +} + +export default connect( + mapStateToProps, + mapDispatchToActions, +)(ChallengesBlockContiner); diff --git a/src/shared/reducers/contentful/challengesBlock.js b/src/shared/reducers/contentful/challengesBlock.js new file mode 100644 index 0000000000..f86eb39138 --- /dev/null +++ b/src/shared/reducers/contentful/challengesBlock.js @@ -0,0 +1,54 @@ +/** + * Reducer for state.challengesBlock + */ + +import actions from 'actions/contentful'; +import { handleActions } from 'redux-actions'; + +/** + * Handles challengesBlock.getChallengesBlockInit action. + * @param {Object} state Previous state. + * @param {Object} action The action. + */ +function onGetChallengesBlockInit(state, action) { + return { + ...state, + [action.payload.id]: { + loading: true, + challenges: [], + fields: {}, + }, + }; +} + +/** + * Handles challengesBlock.getChallengesBlockDone action. + * @param {Object} state Previous state. + * @param {Object} action The action. + */ +function onGetChallengesBlockDone(state, action) { + return { + ...state, + [action.payload.id]: { + loading: false, + challenges: action.payload.challenges, + fields: action.payload.fields, + }, + }; +} + +/** + * 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.getChallengesBlockInit]: onGetChallengesBlockInit, + [actions.contentful.getChallengesBlockDone]: onGetChallengesBlockDone, + }, state); +} + +/* Reducer with the default initial state. */ +export default create(); diff --git a/src/shared/reducers/menuNavigation.js b/src/shared/reducers/contentful/menuNavigation.js similarity index 93% rename from src/shared/reducers/menuNavigation.js rename to src/shared/reducers/contentful/menuNavigation.js index a0aa9b999f..7915e44991 100644 --- a/src/shared/reducers/menuNavigation.js +++ b/src/shared/reducers/contentful/menuNavigation.js @@ -36,7 +36,7 @@ function onGetMenuDone(state, action) { } /** - * Creates newsletterArchive reducer with the specified initial state. + * Creates challengesBlock reducer with the specified initial state. * @param {Object} state Optional. If not given, the default one is * generated automatically. * @return {Function} Reducer. diff --git a/src/shared/reducers/index.js b/src/shared/reducers/index.js index 5207527fbd..6b759c0c7c 100644 --- a/src/shared/reducers/index.js +++ b/src/shared/reducers/index.js @@ -25,7 +25,8 @@ import contentful from './contentful'; import topcoderHeader from './topcoder_header'; import rss from './rss'; import newsletterArchive from './newsletterArchive'; -import menuNavigation from './menuNavigation'; +import menuNavigation from './contentful/menuNavigation'; +import challengesBlock from './contentful/challengesBlock'; import { factory as challengeListingFactory } from './challenge-listing'; import { factory as examplesFactory } from './examples'; import { factory as pageFactory } from './page'; @@ -134,6 +135,7 @@ export function factory(req) { toastr: toastrReducer, newsletterArchive, menuNavigation, + challengesBlock, })); } From c98c3c650eb8574ed9e00554c38dd6752df79fa0 Mon Sep 17 00:00:00 2001 From: Kiril Kartunov Date: Tue, 2 Jul 2019 15:02:35 +0300 Subject: [PATCH 3/8] Final fixes #2367 --- src/shared/actions/contentful.js | 1 - .../ChallengesBlock/Card/style.scss | 1 + .../Contentful/ChallengesBlock/index.jsx | 89 +++++++++++-------- .../Contentful/ChallengesBlock/style.scss | 1 - 4 files changed, 54 insertions(+), 38 deletions(-) diff --git a/src/shared/actions/contentful.js b/src/shared/actions/contentful.js index c3d06f3e5c..8746dcd5e8 100644 --- a/src/shared/actions/contentful.js +++ b/src/shared/actions/contentful.js @@ -267,7 +267,6 @@ async function getChallengesBlockDone(blockProps) { filter.technologies = block.fields.technologies.join(','); } const challenges = await challengesService.getChallenges(filter); - // console.log('getChallengesBlockDone', block, challenges); return { id, diff --git a/src/shared/components/Contentful/ChallengesBlock/Card/style.scss b/src/shared/components/Contentful/ChallengesBlock/Card/style.scss index 1486690a43..4a610ca8d0 100644 --- a/src/shared/components/Contentful/ChallengesBlock/Card/style.scss +++ b/src/shared/components/Contentful/ChallengesBlock/Card/style.scss @@ -11,6 +11,7 @@ margin: 10px; padding: 30px; text-align: left; + min-height: 350px; } .prizes { diff --git a/src/shared/components/Contentful/ChallengesBlock/index.jsx b/src/shared/components/Contentful/ChallengesBlock/index.jsx index 6df10d59b3..e42a1f7c23 100644 --- a/src/shared/components/Contentful/ChallengesBlock/index.jsx +++ b/src/shared/components/Contentful/ChallengesBlock/index.jsx @@ -18,47 +18,64 @@ export default function ChallengesBlock({ challenges, fields, }) { + const challengesToRender = challenges.slice(0, fields.limit || 10); return (

{fields.title}

- ( - - - - )} - renderCenterRightControls={({ nextSlide }) => ( - - - - )} - > - { - challenges.slice(0, fields.limit || 10).map(challenge => ( - - )) + { + challengesToRender.length > 2 ? ( + ( + + + + )} + renderCenterRightControls={({ nextSlide }) => ( + + + + )} + > + { + challengesToRender.map(challenge => ( + + )) + } + + ) : ( + challengesToRender.map(challenge => ( + + )) + ) } -
{ fields.buttonText && fields.buttonUrl ? ( diff --git a/src/shared/components/Contentful/ChallengesBlock/style.scss b/src/shared/components/Contentful/ChallengesBlock/style.scss index c7a63db4eb..614c11e3be 100644 --- a/src/shared/components/Contentful/ChallengesBlock/style.scss +++ b/src/shared/components/Contentful/ChallengesBlock/style.scss @@ -10,7 +10,6 @@ display: flex; flex-wrap: wrap; justify-content: space-between; - margin-bottom: 40px; @include xs-to-sm { flex-direction: column; From 3caa4c6a81783f1059d53b283c95c0ff6b5769d3 Mon Sep 17 00:00:00 2001 From: Kiril Kartunov Date: Tue, 2 Jul 2019 16:39:40 +0300 Subject: [PATCH 4/8] new navi final fixes #2400 --- config/default.js | 27 ++++++++++++ src/shared/actions/contentful.js | 6 +++ .../Contentful/MenuLoader/index.jsx | 42 ++++++++++++++++--- .../reducers/contentful/menuNavigation.js | 2 + 4 files changed, 71 insertions(+), 6 deletions(-) diff --git a/config/default.js b/config/default.js index 42e7064993..a0bcae4d7f 100644 --- a/config/default.js +++ b/config/default.js @@ -211,4 +211,31 @@ module.exports = { GRANT_TYPE: '', }, }, + HEADER_AUTH_URLS: { + href: 'https://accounts.topcoder-dev.com/member/registration?utm_source=community-app-main', + location: 'https://accounts.topcoder-dev.com/member?retUrl=%S&utm_source=community-app-main', + }, + ACCOUNT_MENU: [ + { + title: 'Settings', + href: '/settings/profile', + }, + { separator: true }, + { + title: 'Help', + href: 'https://help.topcoder-dev.com/', + }, + { + title: 'About Topcoder', + href: 'https://www.topcoder.com/about/', + }, + { + title: 'Log Out', + href: 'https://www.topcoder-dev.com/logout', + }, + ], + ACCOUNT_MENU_SWITCH_TEXT: { + title: 'Switch to BUSINESS', + href: 'https://connect.topcoder-dev.com', + }, }; diff --git a/src/shared/actions/contentful.js b/src/shared/actions/contentful.js index 8746dcd5e8..30167f4c65 100644 --- a/src/shared/actions/contentful.js +++ b/src/shared/actions/contentful.js @@ -217,6 +217,11 @@ async function getMenuDone(menuProps) { ); // Load and wait for all menu data const menuData = await Promise.all(l1P); + // Load logo if set + let menuLogo; + if (fields.logo) { + menuLogo = await service.getAsset(fields.logo.sys.id); + } // merge and return menu if (fields.title) { menu[0].subMenu = menuData; @@ -227,6 +232,7 @@ async function getMenuDone(menuProps) { return { id: menuProps.id, menu, + menuLogo, }; } diff --git a/src/shared/containers/Contentful/MenuLoader/index.jsx b/src/shared/containers/Contentful/MenuLoader/index.jsx index f247523d22..ccdf863f22 100644 --- a/src/shared/containers/Contentful/MenuLoader/index.jsx +++ b/src/shared/containers/Contentful/MenuLoader/index.jsx @@ -9,10 +9,11 @@ import LoadingIndicator from 'components/LoadingIndicator'; import PT from 'prop-types'; import React from 'react'; import { connect } from 'react-redux'; -// import Logo from 'assets/images/tc-logo.svg'; -import { isomorphy } from 'topcoder-react-utils'; +import Logo from 'assets/images/tc-logo.svg'; +import { isomorphy, config } from 'topcoder-react-utils'; import actions from 'actions/contentful'; + class MenuLoaderContainer extends React.Component { constructor(props) { super(props); @@ -24,6 +25,8 @@ class MenuLoaderContainer extends React.Component { // bind this.handleChangeOpenMore = this.handleChangeOpenMore.bind(this); this.handleChangeLevel1Id = this.handleChangeLevel1Id.bind(this); + this.handleCloseOpenMore = this.handleCloseOpenMore.bind(this); + this.handleSwitchMenu = this.handleSwitchMenu.bind(this); } componentDidMount() { @@ -53,26 +56,51 @@ class MenuLoaderContainer extends React.Component { this.setState({ openMore: changedOpenMore }); } + handleSwitchMenu() { + this.setState({ activeLevel1Id: null }); + } + + handleCloseOpenMore() { + this.setState({ openMore: false }); + } + render() { - const { menu, auth, loading } = this.props; + const { + menu, auth, loading, menuLogo, + } = this.props; const { openMore, path, activeLevel1Id } = this.state; if (loading) { return ; } if (isomorphy.isClientSide()) { // eslint-disable-next-line global-require - const { TopNav } = require('navigation-component'); + const { TopNav, LoginNav } = require('navigation-component'); + const logoToUse = !_.isEmpty(menuLogo) ? menu logo : ; return (
} - loggedIn={!_.isEmpty(auth)} + logo={logoToUse} currentLevel1Id={activeLevel1Id} onChangeLevel1Id={this.handleChangeLevel1Id} path={path} openMore={openMore} setOpenMore={this.handleChangeOpenMore} + loggedIn={!_.isEmpty(auth.profile)} + rightMenu={( + + )} />
); @@ -100,6 +128,7 @@ MenuLoaderContainer.propTypes = { loadMenuData: PT.func.isRequired, menu: PT.arrayOf(PT.shape()), loading: PT.bool.isRequired, + menuLogo: PT.shape().isRequired, }; function mapStateToProps(state, ownProps) { @@ -107,6 +136,7 @@ function mapStateToProps(state, ownProps) { auth: state.auth || {}, menu: state.menuNavigation[ownProps.id] ? state.menuNavigation[ownProps.id].menu : [], loading: state.menuNavigation[ownProps.id] ? state.menuNavigation[ownProps.id].loading : true, + menuLogo: state.menuNavigation[ownProps.id] ? state.menuNavigation[ownProps.id].menuLogo : {}, }; } diff --git a/src/shared/reducers/contentful/menuNavigation.js b/src/shared/reducers/contentful/menuNavigation.js index 7915e44991..0cefd4af88 100644 --- a/src/shared/reducers/contentful/menuNavigation.js +++ b/src/shared/reducers/contentful/menuNavigation.js @@ -16,6 +16,7 @@ function onGetMenuInit(state, action) { [action.payload.id]: { loading: true, menu: [], + menuLogo: {}, }, }; } @@ -31,6 +32,7 @@ function onGetMenuDone(state, action) { [action.payload.id]: { loading: false, menu: action.payload.menu, + menuLogo: action.payload.menuLogo || {}, }, }; } From 10bbbedeeff4e6ce7ec9daa18c5d38fffc742b80 Mon Sep 17 00:00:00 2001 From: Kiril Kartunov Date: Wed, 3 Jul 2019 14:45:54 +0300 Subject: [PATCH 5/8] Fix #2659 --- .../components/Contentful/Accordion/AccordionItem/style.scss | 1 - 1 file changed, 1 deletion(-) diff --git a/src/shared/components/Contentful/Accordion/AccordionItem/style.scss b/src/shared/components/Contentful/Accordion/AccordionItem/style.scss index cc3d049cb8..a68e973394 100644 --- a/src/shared/components/Contentful/Accordion/AccordionItem/style.scss +++ b/src/shared/components/Contentful/Accordion/AccordionItem/style.scss @@ -54,7 +54,6 @@ .content { display: none; padding-bottom: 25px; - padding-top: 25px; p { color: #394146; From 1984e4c3e6e7aac94a923314895d52c5cafa2742 Mon Sep 17 00:00:00 2001 From: Kiril Kartunov Date: Wed, 3 Jul 2019 14:47:19 +0300 Subject: [PATCH 6/8] Fix #2665 --- src/shared/components/Contentful/Banner/themes/general.scss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/shared/components/Contentful/Banner/themes/general.scss b/src/shared/components/Contentful/Banner/themes/general.scss index d7d152fa8c..d6efa0a93a 100644 --- a/src/shared/components/Contentful/Banner/themes/general.scss +++ b/src/shared/components/Contentful/Banner/themes/general.scss @@ -17,7 +17,7 @@ $contentWrapperPadding: 0; position: static; transform: none; padding: 120px $contentWrapperPadding; - min-height: 600px; + min-height: 400px; display: flex; align-items: center; justify-content: center; From b7cfcc8259a84c8da8622d99ae831db562b72562 Mon Sep 17 00:00:00 2001 From: Kiril Kartunov Date: Wed, 3 Jul 2019 23:19:36 +0300 Subject: [PATCH 7/8] Align top challenges block card items --- .../components/Contentful/ChallengesBlock/Card/style.scss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/shared/components/Contentful/ChallengesBlock/Card/style.scss b/src/shared/components/Contentful/ChallengesBlock/Card/style.scss index 4a610ca8d0..018bf8d0ad 100644 --- a/src/shared/components/Contentful/ChallengesBlock/Card/style.scss +++ b/src/shared/components/Contentful/ChallengesBlock/Card/style.scss @@ -7,7 +7,7 @@ display: flex; flex: 1; flex-direction: column; - justify-content: space-between; + justify-content: flex-start; margin: 10px; padding: 30px; text-align: left; From 096bf1695d57d78802ebe6328170a4e2647ae606 Mon Sep 17 00:00:00 2001 From: Kiril Kartunov Date: Thu, 4 Jul 2019 12:07:08 +0300 Subject: [PATCH 8/8] refactor menu links build --- config/default.js | 38 ++++++++++++------- config/production.js | 37 ++++++++++++++++++ src/shared/actions/contentful.js | 5 ++- .../Contentful/MenuLoader/index.jsx | 31 +++++++++++++-- 4 files changed, 93 insertions(+), 18 deletions(-) diff --git a/config/default.js b/config/default.js index a0bcae4d7f..d41c64e863 100644 --- a/config/default.js +++ b/config/default.js @@ -211,27 +211,37 @@ module.exports = { GRANT_TYPE: '', }, }, - HEADER_AUTH_URLS: { - href: 'https://accounts.topcoder-dev.com/member/registration?utm_source=community-app-main', - location: 'https://accounts.topcoder-dev.com/member?retUrl=%S&utm_source=community-app-main', - }, - ACCOUNT_MENU: [ + SECONDARY_MENU_FOR_LOGGED_USER: [ + { + title: 'Dashboard', + href: '/my-dashboard', + }, + { + id: 'myprofile', + title: 'My Profile', + href: '/members/', + }, + { + title: 'Payments', + href: 'https://community.topcoder-dev.com/PactsMemberServlet?module=PaymentHistory&full_list=false', + }, + ], + SECONDARY_MENU_FOR_GUEST: [ { - title: 'Settings', - href: '/settings/profile', + title: 'Overview', + href: 'https://www.topcoder-dev.com/about', }, - { separator: true }, { - title: 'Help', - href: 'https://help.topcoder-dev.com/', + title: 'How It Works', + href: 'https://www.topcoder-dev.com/how-it-works/faqs/', }, { - title: 'About Topcoder', - href: 'https://www.topcoder.com/about/', + title: 'Tracks', + href: '/community/learn', }, { - title: 'Log Out', - href: 'https://www.topcoder-dev.com/logout', + title: 'Why Join', + href: 'https://www.topcoder-dev.com/about/why-crowdsourcing/', }, ], ACCOUNT_MENU_SWITCH_TEXT: { diff --git a/config/production.js b/config/production.js index 7a020b9394..483bcceee6 100644 --- a/config/production.js +++ b/config/production.js @@ -56,4 +56,41 @@ module.exports = { FILESTACK: { SUBMISSION_CONTAINER: 'topcoder-submissions-dmz', }, + SECONDARY_MENU_FOR_LOGGED_USER: [ + { + title: 'Dashboard', + href: '/my-dashboard', + }, + { + id: 'myprofile', + title: 'My Profile', + href: '/members/', + }, + { + title: 'Payments', + href: 'https://community.topcoder.com/PactsMemberServlet?module=PaymentHistory&full_list=false', + }, + ], + SECONDARY_MENU_FOR_GUEST: [ + { + title: 'Overview', + href: 'https://www.topcoder.com/about', + }, + { + title: 'How It Works', + href: 'https://www.topcoder.com/how-it-works/faqs/', + }, + { + title: 'Tracks', + href: '/community/learn', + }, + { + title: 'Why Join', + href: 'https://www.topcoder.com/about/why-crowdsourcing/', + }, + ], + ACCOUNT_MENU_SWITCH_TEXT: { + title: 'Switch to BUSINESS', + href: 'https://connect.topcoder.com', + }, }; diff --git a/src/shared/actions/contentful.js b/src/shared/actions/contentful.js index 30167f4c65..4391e85b36 100644 --- a/src/shared/actions/contentful.js +++ b/src/shared/actions/contentful.js @@ -1,6 +1,6 @@ import _ from 'lodash'; import { getService } from 'services/contentful'; -import { redux } from 'topcoder-react-utils'; +import { redux, config } from 'topcoder-react-utils'; import { removeTrailingSlash } from 'utils/url'; import { menuItemBuilder, target as urlTarget } from 'utils/contentful'; import { services } from 'topcoder-react-lib'; @@ -228,6 +228,9 @@ async function getMenuDone(menuProps) { } else { menu = menuData; } + // add the preconfigured secondary menus + menu[0].secondaryMenuForLoggedInUser = config.SECONDARY_MENU_FOR_LOGGED_USER; + menu[0].secondaryMenuForGuest = config.SECONDARY_MENU_FOR_GUEST; return { id: menuProps.id, diff --git a/src/shared/containers/Contentful/MenuLoader/index.jsx b/src/shared/containers/Contentful/MenuLoader/index.jsx index ccdf863f22..b894e430bb 100644 --- a/src/shared/containers/Contentful/MenuLoader/index.jsx +++ b/src/shared/containers/Contentful/MenuLoader/index.jsx @@ -87,18 +87,43 @@ class MenuLoaderContainer extends React.Component { openMore={openMore} setOpenMore={this.handleChangeOpenMore} loggedIn={!_.isEmpty(auth.profile)} + // profileHandle={auth.profile ? auth.profile.handle : ''} rightMenu={( )} />