diff --git a/.circleci/config.yml b/.circleci/config.yml
index e751e36073..080146f76e 100644
--- a/.circleci/config.yml
+++ b/.circleci/config.yml
@@ -180,10 +180,8 @@ workflows:
context : org-global
filters:
branches:
- only:
- - hot-fixes
- - legacy-tco
- - general-features
+ only:
+ - legacy-tco
# This is beta env for production soft releases
- "build-prod-beta":
context : org-global
diff --git a/README.md b/README.md
index c1706ba0ea..cf28314b2e 100644
--- a/README.md
+++ b/README.md
@@ -1,5 +1,8 @@


+[](https://sonarcloud.io/dashboard?id=topcoder-platform_community-app)
+[](https://sonarcloud.io/dashboard?id=topcoder-platform_community-app)
+[](https://sonarcloud.io/dashboard?id=topcoder-platform_community-app)
# Topcoder Community App
New version of Topcoder Community website.
diff --git a/src/assets/themes/tco18-01/TCO01.svg b/src/assets/themes/tco18-01/TCO01.svg
new file mode 100644
index 0000000000..1d398a46c5
--- /dev/null
+++ b/src/assets/themes/tco18-01/TCO01.svg
@@ -0,0 +1,45 @@
+
+
+
diff --git a/src/assets/themes/tco18-01/TCO02.png b/src/assets/themes/tco18-01/TCO02.png
new file mode 100644
index 0000000000..40b9c39a92
Binary files /dev/null and b/src/assets/themes/tco18-01/TCO02.png differ
diff --git a/src/assets/themes/tco18-01/TCO03.png b/src/assets/themes/tco18-01/TCO03.png
new file mode 100644
index 0000000000..0966377755
Binary files /dev/null and b/src/assets/themes/tco18-01/TCO03.png differ
diff --git a/src/assets/themes/tco18-01/TCO04.png b/src/assets/themes/tco18-01/TCO04.png
new file mode 100644
index 0000000000..89f37fdfda
Binary files /dev/null and b/src/assets/themes/tco18-01/TCO04.png differ
diff --git a/src/assets/themes/tco18-01/TCO05.png b/src/assets/themes/tco18-01/TCO05.png
new file mode 100644
index 0000000000..82a79d9bde
Binary files /dev/null and b/src/assets/themes/tco18-01/TCO05.png differ
diff --git a/src/assets/themes/tco18-01/TCO06.png b/src/assets/themes/tco18-01/TCO06.png
new file mode 100644
index 0000000000..1de8303d7c
Binary files /dev/null and b/src/assets/themes/tco18-01/TCO06.png differ
diff --git a/src/assets/themes/tco18-01/TCO07.png b/src/assets/themes/tco18-01/TCO07.png
new file mode 100644
index 0000000000..20bc154cc4
Binary files /dev/null and b/src/assets/themes/tco18-01/TCO07.png differ
diff --git a/src/assets/themes/tco18-01/TCO08.png b/src/assets/themes/tco18-01/TCO08.png
new file mode 100644
index 0000000000..9236de62d7
Binary files /dev/null and b/src/assets/themes/tco18-01/TCO08.png differ
diff --git a/src/assets/themes/tco18-01/TCO09.png b/src/assets/themes/tco18-01/TCO09.png
new file mode 100644
index 0000000000..38cc88a5c3
Binary files /dev/null and b/src/assets/themes/tco18-01/TCO09.png differ
diff --git a/src/assets/themes/tco18-01/TCO10.png b/src/assets/themes/tco18-01/TCO10.png
new file mode 100644
index 0000000000..93315a78b0
Binary files /dev/null and b/src/assets/themes/tco18-01/TCO10.png differ
diff --git a/src/assets/themes/tco18-01/TCO11.png b/src/assets/themes/tco18-01/TCO11.png
new file mode 100644
index 0000000000..d3eddfc629
Binary files /dev/null and b/src/assets/themes/tco18-01/TCO11.png differ
diff --git a/src/assets/themes/tco18-01/TCO12.svg b/src/assets/themes/tco18-01/TCO12.svg
new file mode 100644
index 0000000000..c04ace2d77
--- /dev/null
+++ b/src/assets/themes/tco18-01/TCO12.svg
@@ -0,0 +1,44 @@
+
+
+
diff --git a/src/assets/themes/tco18-01/TCO13.svg b/src/assets/themes/tco18-01/TCO13.svg
new file mode 100644
index 0000000000..71acd34eab
--- /dev/null
+++ b/src/assets/themes/tco18-01/TCO13.svg
@@ -0,0 +1,49 @@
+
+
+
diff --git a/src/assets/themes/tco18-01/TCO14.svg b/src/assets/themes/tco18-01/TCO14.svg
new file mode 100644
index 0000000000..8b56609a0d
--- /dev/null
+++ b/src/assets/themes/tco18-01/TCO14.svg
@@ -0,0 +1,48 @@
+
+
+
diff --git a/src/assets/themes/tco18-01/TCO15.svg b/src/assets/themes/tco18-01/TCO15.svg
new file mode 100644
index 0000000000..eb6c6287d7
--- /dev/null
+++ b/src/assets/themes/tco18-01/TCO15.svg
@@ -0,0 +1,46 @@
+
+
+
diff --git a/src/assets/themes/tco18-01/TCO16.svg b/src/assets/themes/tco18-01/TCO16.svg
new file mode 100644
index 0000000000..8fd81e127f
--- /dev/null
+++ b/src/assets/themes/tco18-01/TCO16.svg
@@ -0,0 +1,41 @@
+
+
+
diff --git a/src/assets/themes/tco17/TCO17.svg b/src/assets/themes/tco18-01/TCO17.svg
similarity index 100%
rename from src/assets/themes/tco17/TCO17.svg
rename to src/assets/themes/tco18-01/TCO17.svg
diff --git a/src/assets/themes/tco18/TCO18.svg b/src/assets/themes/tco18-01/TCO18.svg
similarity index 100%
rename from src/assets/themes/tco18/TCO18.svg
rename to src/assets/themes/tco18-01/TCO18.svg
diff --git a/src/server/tc-communities/tco01/metadata.json b/src/server/tc-communities/tco01/metadata.json
new file mode 100644
index 0000000000..4d06b51b57
--- /dev/null
+++ b/src/server/tc-communities/tco01/metadata.json
@@ -0,0 +1,14 @@
+{
+ "communityId": "tco01",
+ "hidden": true,
+ "communityName": "TCO01",
+ "groupIds": [],
+ "hideSearch": true,
+ "logos": [{
+ "img": "/community-app-assets/themes/tco18-01/TCO01.svg",
+ "url": "https://tco01.topcoder.com"
+ }],
+ "newsFeed": "http://www.topcoder.com/feed",
+ "subdomains": ["tco01"],
+ "description": "2001 Topcoder Open. The Ultimate Programming & Design Tournament"
+}
diff --git a/src/server/tc-communities/tco02/metadata.json b/src/server/tc-communities/tco02/metadata.json
new file mode 100644
index 0000000000..2e3f4fe263
--- /dev/null
+++ b/src/server/tc-communities/tco02/metadata.json
@@ -0,0 +1,14 @@
+{
+ "communityId": "tco02",
+ "hidden": true,
+ "communityName": "TCO02",
+ "groupIds": [],
+ "hideSearch": true,
+ "logos": [{
+ "img": "/community-app-assets/themes/tco18-01/TCO02.png",
+ "url": "https://tco02.topcoder.com"
+ }],
+ "newsFeed": "http://www.topcoder.com/feed",
+ "subdomains": ["tco02"],
+ "description": "2002 Topcoder Open. The Ultimate Programming & Design Tournament"
+}
diff --git a/src/server/tc-communities/tco03/metadata.json b/src/server/tc-communities/tco03/metadata.json
new file mode 100644
index 0000000000..a7ed9c0287
--- /dev/null
+++ b/src/server/tc-communities/tco03/metadata.json
@@ -0,0 +1,17 @@
+{
+ "communityId": "tco03",
+ "hidden": true,
+ "communityName": "TCO03",
+ "groupIds": [],
+ "hideSearch": true,
+ "logos": [{
+ "img": "/community-app-assets/themes/tco18-01/TCO03.png",
+ "url": "https://tco03.topcoder.com"
+ }],
+ "menuItems": [{
+ "navigationMenu": "1NTh1Tcgf31hGo5OSUXSTA"
+ }],
+ "newsFeed": "http://www.topcoder.com/feed",
+ "subdomains": ["tco03"],
+ "description": "2003 Topcoder Open. The Ultimate Programming & Design Tournament"
+}
diff --git a/src/server/tc-communities/tco04/metadata.json b/src/server/tc-communities/tco04/metadata.json
new file mode 100644
index 0000000000..5c81ed7c9a
--- /dev/null
+++ b/src/server/tc-communities/tco04/metadata.json
@@ -0,0 +1,17 @@
+{
+ "communityId": "tco04",
+ "hidden": true,
+ "communityName": "TCO04",
+ "groupIds": [],
+ "hideSearch": true,
+ "logos": [{
+ "img": "/community-app-assets/themes/tco18-01/TCO04.png",
+ "url": "https://tco04.topcoder.com"
+ }],
+ "menuItems": [{
+ "navigationMenu": "7FFCD13ZeWgLUhgC2FS86M"
+ }],
+ "newsFeed": "http://www.topcoder.com/feed",
+ "subdomains": ["tco04"],
+ "description": "2004 Topcoder Open. The Ultimate Programming & Design Tournament"
+}
diff --git a/src/server/tc-communities/tco05/metadata.json b/src/server/tc-communities/tco05/metadata.json
new file mode 100644
index 0000000000..cdbc4cad14
--- /dev/null
+++ b/src/server/tc-communities/tco05/metadata.json
@@ -0,0 +1,17 @@
+{
+ "communityId": "tco05",
+ "hidden": true,
+ "communityName": "TCO05",
+ "groupIds": [],
+ "hideSearch": true,
+ "logos": [{
+ "img": "/community-app-assets/themes/tco18-01/TCO05.png",
+ "url": "https://tco05.topcoder.com"
+ }],
+ "menuItems": [{
+ "navigationMenu": "5ckaJfIYOf7juZczKSwjyB"
+ }],
+ "newsFeed": "http://www.topcoder.com/feed",
+ "subdomains": ["tco05"],
+ "description": "2005 Topcoder Open. The Ultimate Programming & Design Tournament"
+}
diff --git a/src/server/tc-communities/tco06/metadata.json b/src/server/tc-communities/tco06/metadata.json
new file mode 100644
index 0000000000..212c1414f9
--- /dev/null
+++ b/src/server/tc-communities/tco06/metadata.json
@@ -0,0 +1,17 @@
+{
+ "communityId": "tco06",
+ "hidden": true,
+ "communityName": "TCO06",
+ "groupIds": [],
+ "hideSearch": true,
+ "logos": [{
+ "img": "/community-app-assets/themes/tco18-01/TCO06.png",
+ "url": "https://tco06.topcoder.com"
+ }],
+ "menuItems": [{
+ "navigationMenu": "TTGuQGYZ7Q5TFm3m6hyua"
+ }],
+ "newsFeed": "http://www.topcoder.com/feed",
+ "subdomains": ["tco06"],
+ "description": "2006 Topcoder Open. The Ultimate Programming & Design Tournament"
+}
diff --git a/src/server/tc-communities/tco07/metadata.json b/src/server/tc-communities/tco07/metadata.json
new file mode 100644
index 0000000000..2045a22acc
--- /dev/null
+++ b/src/server/tc-communities/tco07/metadata.json
@@ -0,0 +1,17 @@
+{
+ "communityId": "tco07",
+ "hidden": true,
+ "communityName": "TCO07",
+ "groupIds": [],
+ "hideSearch": true,
+ "logos": [{
+ "img": "/community-app-assets/themes/tco18-01/TCO07.png",
+ "url": "https://tco07.topcoder.com"
+ }],
+ "menuItems": [{
+ "navigationMenu": "3fVSY5EbFPFAykNujEsvv8"
+ }],
+ "newsFeed": "http://www.topcoder.com/feed",
+ "subdomains": ["tco07"],
+ "description": "2007 Topcoder Open. The Ultimate Programming & Design Tournament"
+}
diff --git a/src/server/tc-communities/tco08/metadata.json b/src/server/tc-communities/tco08/metadata.json
new file mode 100644
index 0000000000..2240217b85
--- /dev/null
+++ b/src/server/tc-communities/tco08/metadata.json
@@ -0,0 +1,17 @@
+{
+ "communityId": "tco08",
+ "hidden": true,
+ "communityName": "TCO08",
+ "groupIds": [],
+ "hideSearch": true,
+ "logos": [{
+ "img": "/community-app-assets/themes/tco18-01/TCO08.png",
+ "url": "https://tco08.topcoder.com"
+ }],
+ "menuItems": [{
+ "navigationMenu": "4rYnxNIsLi0zVAvDsTK9JK"
+ }],
+ "newsFeed": "http://www.topcoder.com/feed",
+ "subdomains": ["tco08"],
+ "description": "2008 Topcoder Open. The Ultimate Programming & Design Tournament"
+}
diff --git a/src/server/tc-communities/tco09/metadata.json b/src/server/tc-communities/tco09/metadata.json
new file mode 100644
index 0000000000..76ae2f6822
--- /dev/null
+++ b/src/server/tc-communities/tco09/metadata.json
@@ -0,0 +1,17 @@
+{
+ "communityId": "tco09",
+ "hidden": true,
+ "communityName": "TCO09",
+ "groupIds": [],
+ "hideSearch": true,
+ "logos": [{
+ "img": "/community-app-assets/themes/tco18-01/TCO09.png",
+ "url": "https://tco09.topcoder.com"
+ }],
+ "menuItems": [{
+ "navigationMenu": "4NcwpDu5Fzx1BE36PRoySk"
+ }],
+ "newsFeed": "http://www.topcoder.com/feed",
+ "subdomains": ["tco09"],
+ "description": "2009 Topcoder Open. The Ultimate Programming & Design Tournament"
+}
diff --git a/src/server/tc-communities/tco10/metadata.json b/src/server/tc-communities/tco10/metadata.json
new file mode 100644
index 0000000000..0aea6f74b8
--- /dev/null
+++ b/src/server/tc-communities/tco10/metadata.json
@@ -0,0 +1,17 @@
+{
+ "communityId": "tco10",
+ "hidden": true,
+ "communityName": "TCO10",
+ "groupIds": [],
+ "hideSearch": true,
+ "logos": [{
+ "img": "/community-app-assets/themes/tco18-01/TCO10.png",
+ "url": "https://tco10.topcoder.com"
+ }],
+ "menuItems": [{
+ "navigationMenu": "NEG4INIrZGWnVQXbsxzbq"
+ }],
+ "newsFeed": "http://www.topcoder.com/feed",
+ "subdomains": ["tco10"],
+ "description": "2010 Topcoder Open. The Ultimate Programming & Design Tournament"
+}
diff --git a/src/server/tc-communities/tco11/metadata.json b/src/server/tc-communities/tco11/metadata.json
new file mode 100644
index 0000000000..1fe51ed2eb
--- /dev/null
+++ b/src/server/tc-communities/tco11/metadata.json
@@ -0,0 +1,17 @@
+{
+ "communityId": "tco11",
+ "hidden": true,
+ "communityName": "TCO11",
+ "groupIds": [],
+ "hideSearch": true,
+ "logos": [{
+ "img": "/community-app-assets/themes/tco18-01/TCO11.png",
+ "url": "https://tco11.topcoder.com"
+ }],
+ "menuItems": [{
+ "navigationMenu": "7tudOHlGLUOTzsPVPrV7gm"
+ }],
+ "newsFeed": "http://www.topcoder.com/feed",
+ "subdomains": ["tco11"],
+ "description": "2011 Topcoder Open. The Ultimate Programming & Design Tournament"
+}
diff --git a/src/server/tc-communities/tco12/metadata.json b/src/server/tc-communities/tco12/metadata.json
new file mode 100644
index 0000000000..0115bee5c7
--- /dev/null
+++ b/src/server/tc-communities/tco12/metadata.json
@@ -0,0 +1,17 @@
+{
+ "communityId": "tco12",
+ "hidden": true,
+ "communityName": "TCO12",
+ "groupIds": [],
+ "hideSearch": true,
+ "logos": [{
+ "img": "/community-app-assets/themes/tco18-01/TCO12.svg",
+ "url": "https://tco12.topcoder.com"
+ }],
+ "menuItems": [{
+ "navigationMenu": "1EOuUA49hvEfR12P1h6o4J"
+ }],
+ "newsFeed": "http://www.topcoder.com/feed",
+ "subdomains": ["tco12"],
+ "description": "2012 Topcoder Open. The Ultimate Programming & Design Tournament"
+}
diff --git a/src/server/tc-communities/tco13/metadata.json b/src/server/tc-communities/tco13/metadata.json
new file mode 100644
index 0000000000..baab2f6b92
--- /dev/null
+++ b/src/server/tc-communities/tco13/metadata.json
@@ -0,0 +1,17 @@
+{
+ "communityId": "tco13",
+ "hidden": true,
+ "communityName": "TCO13",
+ "groupIds": [],
+ "hideSearch": true,
+ "logos": [{
+ "img": "/community-app-assets/themes/tco18-01/TCO13.svg",
+ "url": "https://tco13.topcoder.com"
+ }],
+ "menuItems": [{
+ "navigationMenu": "4kGaSRZWN8Hb9kqWrfqexL"
+ }],
+ "newsFeed": "http://www.topcoder.com/feed",
+ "subdomains": ["tco13"],
+ "description": "2013 Topcoder Open. The Ultimate Programming & Design Tournament"
+}
diff --git a/src/server/tc-communities/tco14/metadata.json b/src/server/tc-communities/tco14/metadata.json
new file mode 100644
index 0000000000..1ce4036127
--- /dev/null
+++ b/src/server/tc-communities/tco14/metadata.json
@@ -0,0 +1,17 @@
+{
+ "communityId": "tco14",
+ "hidden": true,
+ "communityName": "TCO14",
+ "groupIds": [],
+ "hideSearch": true,
+ "logos": [{
+ "img": "/community-app-assets/themes/tco18-01/TCO14.svg",
+ "url": "https://tco14.topcoder.com"
+ }],
+ "menuItems": [{
+ "navigationMenu": "6rXdWUciLO5dathvpOmPRc"
+ }],
+ "newsFeed": "http://www.topcoder.com/feed",
+ "subdomains": ["tco14"],
+ "description": "2014 Topcoder Open. The Ultimate Programming & Design Tournament"
+}
diff --git a/src/server/tc-communities/tco15/metadata.json b/src/server/tc-communities/tco15/metadata.json
new file mode 100644
index 0000000000..a0d1a5057e
--- /dev/null
+++ b/src/server/tc-communities/tco15/metadata.json
@@ -0,0 +1,17 @@
+{
+ "communityId": "tco15",
+ "hidden": true,
+ "communityName": "TCO15",
+ "groupIds": [],
+ "hideSearch": true,
+ "logos": [{
+ "img": "/community-app-assets/themes/tco18-01/TCO15.svg",
+ "url": "https://tco15.topcoder.com"
+ }],
+ "menuItems": [{
+ "navigationMenu": "2YbWIaEZGghDDiFtb0pYGz"
+ }],
+ "newsFeed": "http://www.topcoder.com/feed",
+ "subdomains": ["tco15"],
+ "description": "2015 Topcoder Open. The Ultimate Programming & Design Tournament"
+}
diff --git a/src/server/tc-communities/tco16/metadata.json b/src/server/tc-communities/tco16/metadata.json
new file mode 100644
index 0000000000..f89055db0c
--- /dev/null
+++ b/src/server/tc-communities/tco16/metadata.json
@@ -0,0 +1,17 @@
+{
+ "communityId": "tco16",
+ "hidden": true,
+ "communityName": "TCO16",
+ "groupIds": [],
+ "hideSearch": true,
+ "logos": [{
+ "img": "/community-app-assets/themes/tco18-01/TCO16.svg",
+ "url": "https://tco16.topcoder.com"
+ }],
+ "menuItems": [{
+ "navigationMenu": "2CnO5xaWYA4XoB3musqcku"
+ }],
+ "newsFeed": "http://www.topcoder.com/feed",
+ "subdomains": ["tco16"],
+ "description": "2016 Topcoder Open. The Ultimate Programming & Design Tournament"
+}
diff --git a/src/server/tc-communities/tco17/metadata.json b/src/server/tc-communities/tco17/metadata.json
index 14f7f07d93..f08876d8e9 100644
--- a/src/server/tc-communities/tco17/metadata.json
+++ b/src/server/tc-communities/tco17/metadata.json
@@ -5,7 +5,7 @@
"groupIds": [],
"hideSearch": true,
"logos": [{
- "img": "/community-app-assets/themes/tco17/TCO17.svg",
+ "img": "/community-app-assets/themes/tco18-01/TCO17.svg",
"url": "https://tco17.topcoder.com"
}],
"menuItems": [{
diff --git a/src/server/tc-communities/tco18/metadata.json b/src/server/tc-communities/tco18/metadata.json
index 80382d76fc..2f66559f70 100644
--- a/src/server/tc-communities/tco18/metadata.json
+++ b/src/server/tc-communities/tco18/metadata.json
@@ -5,7 +5,7 @@
"groupIds": [],
"hideSearch": true,
"logos": [{
- "img": "/community-app-assets/themes/tco18/TCO18.svg",
+ "img": "/community-app-assets/themes/tco18-01/TCO18.svg",
"url": "https://tco18.topcoder.com"
}],
"menuItems": [{
diff --git a/src/server/tc-communities/tco19/metadata.json b/src/server/tc-communities/tco19/metadata.json
index c39622d0c9..ed501a0c34 100644
--- a/src/server/tc-communities/tco19/metadata.json
+++ b/src/server/tc-communities/tco19/metadata.json
@@ -14,7 +14,7 @@
"url": "https://tco19.topcoder.com"
}],
"menuItems": [{
- "navigationMenu": "2Q7PFVzaoEGK0SciSceoew"
+ "navigationMenu": "3QcKcut8TFtBwXk0Dkk0AZ"
}],
"newsFeed": "http://www.topcoder.com/feed",
"subdomains": ["tco19"],
diff --git a/src/shared/components/Contentful/Menu/Menu.jsx b/src/shared/components/Contentful/Menu/Menu.jsx
index 0f8c8b524e..86a249aff5 100644
--- a/src/shared/components/Contentful/Menu/Menu.jsx
+++ b/src/shared/components/Contentful/Menu/Menu.jsx
@@ -3,21 +3,27 @@
*
*/
/* global window */
+import _ from 'lodash';
import React from 'react';
import PT from 'prop-types';
-import { isomorphy } from 'topcoder-react-utils';
-import { removeTrailingSlash } from 'utils/url';
import Dropdown from 'components/tc-communities/Dropdown';
+import { isomorphy } from 'topcoder-react-utils';
+import { isActive, linkText, target } from 'utils/contentful';
import MenuItem from './MenuItem';
export default function Menu(props) {
const {
- menuItems, theme, baseUrl, parentItems, activeParentItem,
+ menuItems, theme, baseUrl, parentBaseUrl, parentItems, activeParentItem,
} = props;
- let pathname = '';
+
if (isomorphy.isClientSide()) {
- pathname = removeTrailingSlash(window.location.pathname);
+ if (baseUrl && baseUrl === parentBaseUrl && baseUrl !== _.trimEnd(window.location.pathname, '/')) {
+ return null;
+ }
+ } else {
+ // TODO: should probably get the current URL from the web framework
+ // and apply the check ot current location path
}
return (
@@ -27,11 +33,11 @@ export default function Menu(props) {
({
- label: pI.fields.linkText,
- value: pI.fields.slug,
- url: `${baseUrl}/../${pI.fields.slug}`,
+ label: linkText(pI),
+ value: pI.sys.id,
+ url: target(parentBaseUrl, pI),
}))}
- value={activeParentItem.fields.slug}
+ value={activeParentItem.sys.id}
onChange={(option) => { window.location.href = option.url; }}
/>
@@ -43,10 +49,7 @@ export default function Menu(props) {
@@ -72,6 +75,7 @@ Menu.propTypes = {
}),
menuItems: PT.arrayOf(PT.shape()),
baseUrl: PT.string.isRequired,
+ parentBaseUrl: PT.string.isRequired,
parentItems: PT.arrayOf(PT.shape()).isRequired,
activeParentItem: PT.shape().isRequired,
};
diff --git a/src/shared/components/Contentful/Menu/MenuItem.jsx b/src/shared/components/Contentful/Menu/MenuItem.jsx
index 794723b077..b5c8e3f221 100644
--- a/src/shared/components/Contentful/Menu/MenuItem.jsx
+++ b/src/shared/components/Contentful/Menu/MenuItem.jsx
@@ -4,26 +4,14 @@
import React from 'react';
import PT from 'prop-types';
import { NavLink } from 'topcoder-react-utils';
+import { linkText, target } from 'utils/contentful';
export default function MenuItem(props) {
const {
item, theme, isActive, baseUrl,
} = props;
- // use/prefer url if available
- let to = '';
- if (item.fields.url) {
- to = item.fields.url.startsWith('http') ? item.fields.url : `${baseUrl}${item.fields.url}`;
- } else if (item.fields.viewport) {
- // for viewports use
- // menu item slug to build the url
- to = `${baseUrl}/${item.fields.slug}`;
- } else {
- // case when nor url either viewport
- // of item are specified. Bad link!?
- to = '#';
- }
- return (
+ return item.fields.excludeFromNavigationMenus !== true ? (
isActive}
- to={to}
+ to={target(baseUrl, item)}
openNewTab={item.fields.inNewTab}
>
- {item.fields.linkText || item.fields.name}
+ {linkText(item)}
- );
+ ) : null;
}
diff --git a/src/shared/components/Contentful/Menu/index.jsx b/src/shared/components/Contentful/Menu/index.jsx
index f2184ec7b5..620c668314 100644
--- a/src/shared/components/Contentful/Menu/index.jsx
+++ b/src/shared/components/Contentful/Menu/index.jsx
@@ -4,10 +4,11 @@
/* global window */
import _ from 'lodash';
import ContentfulLoader from 'containers/ContentfulLoader';
+import LoadingIndicator from 'components/LoadingIndicator';
import PT from 'prop-types';
import React from 'react';
-import { isomorphy } from 'topcoder-react-utils';
import { removeTrailingSlash } from 'utils/url';
+import { isActive, target } from 'utils/contentful';
import NavMenu from './Menu';
@@ -27,34 +28,53 @@ function MenuItemsLoader(props) {
title,
themeName,
theme,
+ parentBaseUrl,
parentItems,
activeParentItem,
level,
+ spaceName,
+ environment,
} = props;
const themeToUse = theme || THEMES[themeName];
let { baseUrl } = props;
- let pathname = '';
// remove trail slash from baseUrl
baseUrl = removeTrailingSlash(baseUrl);
- // check current path
- if (isomorphy.isClientSide()) {
- pathname = removeTrailingSlash(window.location.pathname);
- }
+
return (
{
const submenu = _.compact(_.values(data.entries.items).map((menuItem) => {
- if (menuItem.fields.submenu
- && (pathname.indexOf(menuItem.fields.slug) !== -1 || (pathname === baseUrl && menuItem.fields.url === '/'))) {
+ if (menuItem.fields.submenu && isActive(baseUrl, menuItem, 'submenu')) {
return (
+
+ );
+ }
+ if (menuItem.fields.childRoutes && menuItem.fields.excludeFromNavigationMenus !== true && isActive(baseUrl, menuItem, 'childRoutes')) {
+ return (
+
+
@@ -87,6 +108,7 @@ function MenuItemsLoader(props) {
key={menuId}
theme={themeToUse}
baseUrl={baseUrl}
+ parentBaseUrl={parentBaseUrl}
parentItems={parentItems}
activeParentItem={activeParentItem}
/>
@@ -98,6 +120,7 @@ function MenuItemsLoader(props) {
);
}}
+ renderPlaceholder={LoadingIndicator}
/>
);
}
@@ -105,16 +128,21 @@ function MenuItemsLoader(props) {
MenuItemsLoader.defaultProps = {
title: '',
theme: null,
+ spaceName: null,
+ environment: null,
};
MenuItemsLoader.propTypes = {
menuId: PT.string.isRequired,
ids: PT.arrayOf(PT.string).isRequired,
preview: PT.bool.isRequired,
+ spaceName: PT.string,
+ environment: PT.string,
title: PT.string,
themeName: PT.string.isRequired,
baseUrl: PT.string.isRequired,
theme: PT.shape(),
+ parentBaseUrl: PT.string.isRequired,
parentItems: PT.arrayOf(PT.shape()).isRequired,
activeParentItem: PT.shape().isRequired,
level: PT.number.isRequired,
@@ -126,15 +154,20 @@ export default function ContentfulMenu(props) {
preview,
baseUrl,
theme,
+ parentBaseUrl,
parentItems,
activeParentItem,
level,
+ spaceName,
+ environment,
} = props;
return (
{
const { fields } = Object.values(data.entries.items)[0];
if (!fields) return null;
@@ -143,24 +176,31 @@ export default function ContentfulMenu(props) {
menuId={id}
ids={_.map(fields.items, 'sys.id')}
preview={preview}
+ spaceName={spaceName}
+ environment={environment}
themeName={fields.theme}
theme={theme}
title={fields.title}
baseUrl={fields.baseUrl || baseUrl}
+ parentBaseUrl={parentBaseUrl}
parentItems={parentItems}
activeParentItem={activeParentItem}
level={level}
/>
);
}}
+ renderPlaceholder={LoadingIndicator}
/>
);
}
ContentfulMenu.defaultProps = {
preview: false,
+ spaceName: null,
+ environment: null,
baseUrl: '',
theme: null,
+ parentBaseUrl: '',
parentItems: [],
activeParentItem: {},
level: 0,
@@ -171,7 +211,10 @@ ContentfulMenu.propTypes = {
preview: PT.bool,
baseUrl: PT.string,
theme: PT.shape(),
+ parentBaseUrl: PT.string,
parentItems: PT.arrayOf(PT.shape()),
activeParentItem: PT.shape(),
level: PT.number,
+ spaceName: PT.string,
+ environment: PT.string,
};
diff --git a/src/shared/components/Contentful/Menu/themes/default.scss b/src/shared/components/Contentful/Menu/themes/default.scss
index 9b7535fc99..17d71a3b58 100644
--- a/src/shared/components/Contentful/Menu/themes/default.scss
+++ b/src/shared/components/Contentful/Menu/themes/default.scss
@@ -48,10 +48,10 @@
line-height: 30px;
a {
- color: #aaaaab;
+ color: #aaaaab !important;
&:hover {
- color: darken($color: #aaaaab, $amount: 10);
+ color: darken($color: #aaaaab, $amount: 10) !important;
}
}
@@ -59,7 +59,7 @@
color: #404041;
&:hover {
- color: darken($color: #404041, $amount: 20);
+ color: darken($color: #404041, $amount: 20) !important;
}
}
@@ -107,11 +107,11 @@
.menuItemLevel {
a {
- color: #a3a3ad;
+ color: #a3a3ad !important;
font-weight: 400;
&:hover {
- color: $tc-white;
+ color: $tc-white !important;
}
}
@@ -120,7 +120,7 @@
}
.menuItemLinkActive::after {
- background-color: $tc-white;
+ background-color: $tc-white !important;
}
}
@@ -167,7 +167,7 @@
font-size: 13px;
font-weight: 700;
line-height: 25px;
- color: $tc-white;
+ color: $tc-white !important;
text-transform: uppercase;
:global {
@@ -184,7 +184,7 @@
font-weight: 400;
line-height: 30px;
text-transform: uppercase;
- color: #47474f;
+ color: #47474f !important;
padding-left: 10px;
padding-right: 20px;
diff --git a/src/shared/components/Contentful/Route.jsx b/src/shared/components/Contentful/Route.jsx
index d18c502586..204a44064c 100644
--- a/src/shared/components/Contentful/Route.jsx
+++ b/src/shared/components/Contentful/Route.jsx
@@ -58,6 +58,7 @@ function ChildRoutesLoader(props) {
preview={preview}
spaceName={spaceName}
environment={environment}
+ baseUrl={url}
/>
) :
}
diff --git a/src/shared/components/tc-communities/communities/tco19/Home/index.jsx b/src/shared/components/tc-communities/communities/tco19/Home/index.jsx
deleted file mode 100644
index 9fb4d0d109..0000000000
--- a/src/shared/components/tc-communities/communities/tco19/Home/index.jsx
+++ /dev/null
@@ -1,10 +0,0 @@
-import React from 'react';
-import Viewport from 'components/Contentful/Viewport';
-
-export default function Home() {
- return (
-
- );
-}
diff --git a/src/shared/components/tc-communities/communities/tco19/Home/style.scss b/src/shared/components/tc-communities/communities/tco19/Home/style.scss
deleted file mode 100644
index e4bd7a5666..0000000000
--- a/src/shared/components/tc-communities/communities/tco19/Home/style.scss
+++ /dev/null
@@ -1,57 +0,0 @@
-@import '~styles/mixins';
-
-.statsContainer {
- padding: 0;
-}
-
-.statsContent {
- border-bottom: 1px solid #ddd;
- padding: 43px 38px 50px;
-
- @include xs-to-sm {
- display: flex;
- justify-content: space-around;
- padding: 30px 12px 32px;
- }
-}
-
-.resourcesContainer {
- background-color: #fafafa;
- padding: 70px 0;
-
- @include xs-to-sm {
- padding: 40px 0;
- }
-}
-
-.linksContainer {
- padding: 24px 0 60px;
-
- @include xs-to-sm {
- padding: 0;
- }
-}
-
-.introContainer {
- background: $tc-gray-neutral-light;
- color: #787d81;
- padding-bottom: 48px;
- margin-bottom: 24px;
-
- @include xs-to-sm {
- padding-left: 24px;
- padding-right: 24px;
- }
-
- h1 {
- color: #394146;
- font: 600 36px 'Open Sans', sans-serif;
- margin-bottom: 12px;
- }
-
- p {
- color: #787d81;
- font: 15px/22px 'Open Sans', sans-serif;
- padding: 6px 0;
- }
-}
diff --git a/src/shared/containers/tc-communities/tco19/Home.jsx b/src/shared/containers/tc-communities/tco19/Home.jsx
deleted file mode 100644
index 4973462ce3..0000000000
--- a/src/shared/containers/tc-communities/tco19/Home.jsx
+++ /dev/null
@@ -1,11 +0,0 @@
-import _ from 'lodash';
-import Home from 'components/tc-communities/communities/tco19/Home';
-import { connect } from 'react-redux';
-
-function mapStateToProps(state) {
- return {
- userGroups: _.get(state.auth.profile, 'groups'),
- };
-}
-
-export default connect(mapStateToProps)(Home);
diff --git a/src/shared/routes/Communities/Routes.jsx b/src/shared/routes/Communities/Routes.jsx
index 8fda8c85b2..2c3e3dfddd 100644
--- a/src/shared/routes/Communities/Routes.jsx
+++ b/src/shared/routes/Communities/Routes.jsx
@@ -17,18 +17,55 @@ import Veterans from './Veterans';
import Wipro from './Wipro';
import Cognitive from './Cognitive';
import IoT from './iot';
-import TCO17 from './TCO17';
-import TCO18 from './TCO18';
-import TCO19 from './TCO19';
+import tco01 from './TCO01';
+import tco02 from './TCO02';
+import tco03 from './TCO03';
+import tco04 from './TCO04';
+import tco05 from './TCO05';
+import tco06 from './TCO06';
+import tco07 from './TCO07';
+import tco08 from './TCO08';
+import tco09 from './TCO09';
+import tco10 from './TCO10';
+import tco11 from './TCO11';
+import tco12 from './TCO12';
+import tco13 from './TCO13';
+import tco14 from './TCO14';
+import tco15 from './TCO15';
+import tco16 from './TCO16';
+import tco17 from './TCO17';
+import tco18 from './TCO18';
+import tco19 from './TCO19';
import Mobile from './Mobile';
import Zurich from './Zurich';
+const TCOs = {
+ tco01,
+ tco02,
+ tco03,
+ tco04,
+ tco05,
+ tco06,
+ tco07,
+ tco08,
+ tco09,
+ tco10,
+ tco11,
+ tco12,
+ tco13,
+ tco14,
+ tco15,
+ tco16,
+ tco17,
+ tco18,
+ tco19,
+};
+
export default function Communities({
base, communityId, member, meta,
}) {
switch (communityId) {
- case 'blockchain':
- return ;
+ case 'blockchain': return ;
case 'community-2': return ;
case 'cs': return ;
case 'zurich': return ;
@@ -37,16 +74,18 @@ export default function Communities({
case 'srmx': return ;
case 'taskforce': return ;
case 'tc-prod-dev': return ;
- case 'veterans':
- return ;
+ case 'veterans': return ;
case 'wipro': return ;
case 'cognitive': return ;
case 'iot': return ;
- case 'tco17': return ;
- case 'tco18': return ;
- case 'tco19': return ;
case 'mobile': return ;
- default: throw new Error('Unknown community ID!');
+ default:
+ // to avoid listing all TCOs we use defaut switch with a check
+ if (TCOs[communityId]) {
+ const TCOCommunity = TCOs[communityId];
+ return ;
+ }
+ throw new Error('Unknown community ID!');
}
}
diff --git a/src/shared/routes/Communities/TCO01/Routes.jsx b/src/shared/routes/Communities/TCO01/Routes.jsx
new file mode 100644
index 0000000000..31b00fba55
--- /dev/null
+++ b/src/shared/routes/Communities/TCO01/Routes.jsx
@@ -0,0 +1,48 @@
+/**
+ * Routing of TCO01 Community.
+ */
+
+import ContentfulRoute from 'components/Contentful/Route';
+import Error404 from 'components/Error404';
+import Header from 'containers/tc-communities/Header';
+import PT from 'prop-types';
+import React from 'react';
+import { Route, Switch } from 'react-router-dom';
+
+import headerTheme from 'components/tc-communities/communities/tco/themes/header.scss';
+
+export default function TCO01({ base }) {
+ return (
+ (
+
+
+
+ }
+ id="1fX3oi25s40qzhFlzeWaoc"
+ />
+
+
+
+ )}
+ path={`${base}/:pageId?`}
+ />
+ );
+}
+
+TCO01.defaultProps = {
+ base: '',
+};
+
+TCO01.propTypes = {
+ base: PT.string,
+};
diff --git a/src/shared/routes/Communities/TCO01/index.jsx b/src/shared/routes/Communities/TCO01/index.jsx
new file mode 100644
index 0000000000..ca7c6cfbf2
--- /dev/null
+++ b/src/shared/routes/Communities/TCO01/index.jsx
@@ -0,0 +1,32 @@
+/**
+ * Loader for the community's code chunks.
+ */
+
+import LoadingIndicator from 'components/LoadingIndicator';
+import path from 'path';
+import PT from 'prop-types';
+import React from 'react';
+import { AppChunk, webpack } from 'topcoder-react-utils';
+
+export default function ChunkLoader({ base, meta }) {
+ return (
+ import(/* webpackChunkName: "tco01-community/chunk" */ './Routes')
+ .then(({ default: Routes }) => (
+
+ ))
+ }
+ renderPlaceholder={() => }
+ renderServer={() => {
+ const Routes = webpack.requireWeak(path.resolve(__dirname, './Routes'));
+ return ;
+ }}
+ />
+ );
+}
+
+ChunkLoader.propTypes = {
+ base: PT.string.isRequired,
+ meta: PT.shape().isRequired,
+};
diff --git a/src/shared/routes/Communities/TCO02/Routes.jsx b/src/shared/routes/Communities/TCO02/Routes.jsx
new file mode 100644
index 0000000000..53a3e5aa05
--- /dev/null
+++ b/src/shared/routes/Communities/TCO02/Routes.jsx
@@ -0,0 +1,48 @@
+/**
+ * Routing of TCO02 Community.
+ */
+
+import ContentfulRoute from 'components/Contentful/Route';
+import Error404 from 'components/Error404';
+import Header from 'containers/tc-communities/Header';
+import PT from 'prop-types';
+import React from 'react';
+import { Route, Switch } from 'react-router-dom';
+
+import headerTheme from 'components/tc-communities/communities/tco/themes/header.scss';
+
+export default function TCO02({ base }) {
+ return (
+ (
+
+
+
+ }
+ id="2FYBo8o2bOOCbqSWuYcX1u"
+ />
+
+
+
+ )}
+ path={`${base}/:pageId?`}
+ />
+ );
+}
+
+TCO02.defaultProps = {
+ base: '',
+};
+
+TCO02.propTypes = {
+ base: PT.string,
+};
diff --git a/src/shared/routes/Communities/TCO02/index.jsx b/src/shared/routes/Communities/TCO02/index.jsx
new file mode 100644
index 0000000000..76141a292a
--- /dev/null
+++ b/src/shared/routes/Communities/TCO02/index.jsx
@@ -0,0 +1,32 @@
+/**
+ * Loader for the community's code chunks.
+ */
+
+import LoadingIndicator from 'components/LoadingIndicator';
+import path from 'path';
+import PT from 'prop-types';
+import React from 'react';
+import { AppChunk, webpack } from 'topcoder-react-utils';
+
+export default function ChunkLoader({ base, meta }) {
+ return (
+ import(/* webpackChunkName: "tco02-community/chunk" */ './Routes')
+ .then(({ default: Routes }) => (
+
+ ))
+ }
+ renderPlaceholder={() => }
+ renderServer={() => {
+ const Routes = webpack.requireWeak(path.resolve(__dirname, './Routes'));
+ return ;
+ }}
+ />
+ );
+}
+
+ChunkLoader.propTypes = {
+ base: PT.string.isRequired,
+ meta: PT.shape().isRequired,
+};
diff --git a/src/shared/routes/Communities/TCO03/Routes.jsx b/src/shared/routes/Communities/TCO03/Routes.jsx
new file mode 100644
index 0000000000..c31dc5b5d7
--- /dev/null
+++ b/src/shared/routes/Communities/TCO03/Routes.jsx
@@ -0,0 +1,48 @@
+/**
+ * Routing of TCO03 Community.
+ */
+
+import ContentfulRoute from 'components/Contentful/Route';
+import Error404 from 'components/Error404';
+import Header from 'containers/tc-communities/Header';
+import PT from 'prop-types';
+import React from 'react';
+import { Route, Switch } from 'react-router-dom';
+
+import headerTheme from 'components/tc-communities/communities/tco/themes/header.scss';
+
+export default function TCO03({ base }) {
+ return (
+ (
+
+
+
+ }
+ id="4mKZxfgAi6Us6dRS4Hy2Ab"
+ />
+
+
+
+ )}
+ path={`${base}/:pageId?`}
+ />
+ );
+}
+
+TCO03.defaultProps = {
+ base: '',
+};
+
+TCO03.propTypes = {
+ base: PT.string,
+};
diff --git a/src/shared/routes/Communities/TCO03/index.jsx b/src/shared/routes/Communities/TCO03/index.jsx
new file mode 100644
index 0000000000..67757632d6
--- /dev/null
+++ b/src/shared/routes/Communities/TCO03/index.jsx
@@ -0,0 +1,32 @@
+/**
+ * Loader for the community's code chunks.
+ */
+
+import LoadingIndicator from 'components/LoadingIndicator';
+import path from 'path';
+import PT from 'prop-types';
+import React from 'react';
+import { AppChunk, webpack } from 'topcoder-react-utils';
+
+export default function ChunkLoader({ base, meta }) {
+ return (
+ import(/* webpackChunkName: "tco03-community/chunk" */ './Routes')
+ .then(({ default: Routes }) => (
+
+ ))
+ }
+ renderPlaceholder={() => }
+ renderServer={() => {
+ const Routes = webpack.requireWeak(path.resolve(__dirname, './Routes'));
+ return ;
+ }}
+ />
+ );
+}
+
+ChunkLoader.propTypes = {
+ base: PT.string.isRequired,
+ meta: PT.shape().isRequired,
+};
diff --git a/src/shared/routes/Communities/TCO04/Routes.jsx b/src/shared/routes/Communities/TCO04/Routes.jsx
new file mode 100644
index 0000000000..304c885a62
--- /dev/null
+++ b/src/shared/routes/Communities/TCO04/Routes.jsx
@@ -0,0 +1,48 @@
+/**
+ * Routing of TCO04 Community.
+ */
+
+import ContentfulRoute from 'components/Contentful/Route';
+import Error404 from 'components/Error404';
+import Header from 'containers/tc-communities/Header';
+import PT from 'prop-types';
+import React from 'react';
+import { Route, Switch } from 'react-router-dom';
+
+import headerTheme from 'components/tc-communities/communities/tco/themes/header.scss';
+
+export default function TCO04({ base }) {
+ return (
+ (
+
+
+
+ }
+ id="3Qua3zCM6DjLVmwlH8LSMA"
+ />
+
+
+
+ )}
+ path={`${base}/:pageId?`}
+ />
+ );
+}
+
+TCO04.defaultProps = {
+ base: '',
+};
+
+TCO04.propTypes = {
+ base: PT.string,
+};
diff --git a/src/shared/routes/Communities/TCO04/index.jsx b/src/shared/routes/Communities/TCO04/index.jsx
new file mode 100644
index 0000000000..73d386667c
--- /dev/null
+++ b/src/shared/routes/Communities/TCO04/index.jsx
@@ -0,0 +1,32 @@
+/**
+ * Loader for the community's code chunks.
+ */
+
+import LoadingIndicator from 'components/LoadingIndicator';
+import path from 'path';
+import PT from 'prop-types';
+import React from 'react';
+import { AppChunk, webpack } from 'topcoder-react-utils';
+
+export default function ChunkLoader({ base, meta }) {
+ return (
+ import(/* webpackChunkName: "tco04-community/chunk" */ './Routes')
+ .then(({ default: Routes }) => (
+
+ ))
+ }
+ renderPlaceholder={() => }
+ renderServer={() => {
+ const Routes = webpack.requireWeak(path.resolve(__dirname, './Routes'));
+ return ;
+ }}
+ />
+ );
+}
+
+ChunkLoader.propTypes = {
+ base: PT.string.isRequired,
+ meta: PT.shape().isRequired,
+};
diff --git a/src/shared/routes/Communities/TCO05/Routes.jsx b/src/shared/routes/Communities/TCO05/Routes.jsx
new file mode 100644
index 0000000000..c4ff510be5
--- /dev/null
+++ b/src/shared/routes/Communities/TCO05/Routes.jsx
@@ -0,0 +1,48 @@
+/**
+ * Routing of TCO05 Community.
+ */
+
+import ContentfulRoute from 'components/Contentful/Route';
+import Error404 from 'components/Error404';
+import Header from 'containers/tc-communities/Header';
+import PT from 'prop-types';
+import React from 'react';
+import { Route, Switch } from 'react-router-dom';
+
+import headerTheme from 'components/tc-communities/communities/tco/themes/header.scss';
+
+export default function TCO05({ base }) {
+ return (
+ (
+
+
+
+ }
+ id="kvig81sweT2PYI4iIwP7B"
+ />
+
+
+
+ )}
+ path={`${base}/:pageId?`}
+ />
+ );
+}
+
+TCO05.defaultProps = {
+ base: '',
+};
+
+TCO05.propTypes = {
+ base: PT.string,
+};
diff --git a/src/shared/routes/Communities/TCO05/index.jsx b/src/shared/routes/Communities/TCO05/index.jsx
new file mode 100644
index 0000000000..318d7d8788
--- /dev/null
+++ b/src/shared/routes/Communities/TCO05/index.jsx
@@ -0,0 +1,32 @@
+/**
+ * Loader for the community's code chunks.
+ */
+
+import LoadingIndicator from 'components/LoadingIndicator';
+import path from 'path';
+import PT from 'prop-types';
+import React from 'react';
+import { AppChunk, webpack } from 'topcoder-react-utils';
+
+export default function ChunkLoader({ base, meta }) {
+ return (
+ import(/* webpackChunkName: "tco05-community/chunk" */ './Routes')
+ .then(({ default: Routes }) => (
+
+ ))
+ }
+ renderPlaceholder={() => }
+ renderServer={() => {
+ const Routes = webpack.requireWeak(path.resolve(__dirname, './Routes'));
+ return ;
+ }}
+ />
+ );
+}
+
+ChunkLoader.propTypes = {
+ base: PT.string.isRequired,
+ meta: PT.shape().isRequired,
+};
diff --git a/src/shared/routes/Communities/TCO06/Routes.jsx b/src/shared/routes/Communities/TCO06/Routes.jsx
new file mode 100644
index 0000000000..528f49e61c
--- /dev/null
+++ b/src/shared/routes/Communities/TCO06/Routes.jsx
@@ -0,0 +1,48 @@
+/**
+ * Routing of TCO06 Community.
+ */
+
+import ContentfulRoute from 'components/Contentful/Route';
+import Error404 from 'components/Error404';
+import Header from 'containers/tc-communities/Header';
+import PT from 'prop-types';
+import React from 'react';
+import { Route, Switch } from 'react-router-dom';
+
+import headerTheme from 'components/tc-communities/communities/tco/themes/header.scss';
+
+export default function TCO06({ base }) {
+ return (
+ (
+
+
+
+ }
+ id="4VDa1nH6C3aNAlhqXI6tBe"
+ />
+
+
+
+ )}
+ path={`${base}/:pageId?`}
+ />
+ );
+}
+
+TCO06.defaultProps = {
+ base: '',
+};
+
+TCO06.propTypes = {
+ base: PT.string,
+};
diff --git a/src/shared/routes/Communities/TCO06/index.jsx b/src/shared/routes/Communities/TCO06/index.jsx
new file mode 100644
index 0000000000..0fc5164e76
--- /dev/null
+++ b/src/shared/routes/Communities/TCO06/index.jsx
@@ -0,0 +1,32 @@
+/**
+ * Loader for the community's code chunks.
+ */
+
+import LoadingIndicator from 'components/LoadingIndicator';
+import path from 'path';
+import PT from 'prop-types';
+import React from 'react';
+import { AppChunk, webpack } from 'topcoder-react-utils';
+
+export default function ChunkLoader({ base, meta }) {
+ return (
+ import(/* webpackChunkName: "tco06-community/chunk" */ './Routes')
+ .then(({ default: Routes }) => (
+
+ ))
+ }
+ renderPlaceholder={() => }
+ renderServer={() => {
+ const Routes = webpack.requireWeak(path.resolve(__dirname, './Routes'));
+ return ;
+ }}
+ />
+ );
+}
+
+ChunkLoader.propTypes = {
+ base: PT.string.isRequired,
+ meta: PT.shape().isRequired,
+};
diff --git a/src/shared/routes/Communities/TCO07/Routes.jsx b/src/shared/routes/Communities/TCO07/Routes.jsx
new file mode 100644
index 0000000000..6636d64233
--- /dev/null
+++ b/src/shared/routes/Communities/TCO07/Routes.jsx
@@ -0,0 +1,48 @@
+/**
+ * Routing of TCO07 Community.
+ */
+
+import ContentfulRoute from 'components/Contentful/Route';
+import Error404 from 'components/Error404';
+import Header from 'containers/tc-communities/Header';
+import PT from 'prop-types';
+import React from 'react';
+import { Route, Switch } from 'react-router-dom';
+
+import headerTheme from 'components/tc-communities/communities/tco/themes/header.scss';
+
+export default function TCO07({ base }) {
+ return (
+ (
+
+
+
+ }
+ id="2XWcxVALvInOlAOfROErKS"
+ />
+
+
+
+ )}
+ path={`${base}/:pageId?`}
+ />
+ );
+}
+
+TCO07.defaultProps = {
+ base: '',
+};
+
+TCO07.propTypes = {
+ base: PT.string,
+};
diff --git a/src/shared/routes/Communities/TCO07/index.jsx b/src/shared/routes/Communities/TCO07/index.jsx
new file mode 100644
index 0000000000..403fe9c8fb
--- /dev/null
+++ b/src/shared/routes/Communities/TCO07/index.jsx
@@ -0,0 +1,32 @@
+/**
+ * Loader for the community's code chunks.
+ */
+
+import LoadingIndicator from 'components/LoadingIndicator';
+import path from 'path';
+import PT from 'prop-types';
+import React from 'react';
+import { AppChunk, webpack } from 'topcoder-react-utils';
+
+export default function ChunkLoader({ base, meta }) {
+ return (
+ import(/* webpackChunkName: "tco07-community/chunk" */ './Routes')
+ .then(({ default: Routes }) => (
+
+ ))
+ }
+ renderPlaceholder={() => }
+ renderServer={() => {
+ const Routes = webpack.requireWeak(path.resolve(__dirname, './Routes'));
+ return ;
+ }}
+ />
+ );
+}
+
+ChunkLoader.propTypes = {
+ base: PT.string.isRequired,
+ meta: PT.shape().isRequired,
+};
diff --git a/src/shared/routes/Communities/TCO08/Routes.jsx b/src/shared/routes/Communities/TCO08/Routes.jsx
new file mode 100644
index 0000000000..4571266274
--- /dev/null
+++ b/src/shared/routes/Communities/TCO08/Routes.jsx
@@ -0,0 +1,48 @@
+/**
+ * Routing of TCO08 Community.
+ */
+
+import ContentfulRoute from 'components/Contentful/Route';
+import Error404 from 'components/Error404';
+import Header from 'containers/tc-communities/Header';
+import PT from 'prop-types';
+import React from 'react';
+import { Route, Switch } from 'react-router-dom';
+
+import headerTheme from 'components/tc-communities/communities/tco/themes/header.scss';
+
+export default function TCO08({ base }) {
+ return (
+ (
+
+
+
+ }
+ id="6e1kgev8X8GSHEcDDiKrVD"
+ />
+
+
+
+ )}
+ path={`${base}/:pageId?`}
+ />
+ );
+}
+
+TCO08.defaultProps = {
+ base: '',
+};
+
+TCO08.propTypes = {
+ base: PT.string,
+};
diff --git a/src/shared/routes/Communities/TCO08/index.jsx b/src/shared/routes/Communities/TCO08/index.jsx
new file mode 100644
index 0000000000..783d779240
--- /dev/null
+++ b/src/shared/routes/Communities/TCO08/index.jsx
@@ -0,0 +1,32 @@
+/**
+ * Loader for the community's code chunks.
+ */
+
+import LoadingIndicator from 'components/LoadingIndicator';
+import path from 'path';
+import PT from 'prop-types';
+import React from 'react';
+import { AppChunk, webpack } from 'topcoder-react-utils';
+
+export default function ChunkLoader({ base, meta }) {
+ return (
+ import(/* webpackChunkName: "tco08-community/chunk" */ './Routes')
+ .then(({ default: Routes }) => (
+
+ ))
+ }
+ renderPlaceholder={() => }
+ renderServer={() => {
+ const Routes = webpack.requireWeak(path.resolve(__dirname, './Routes'));
+ return ;
+ }}
+ />
+ );
+}
+
+ChunkLoader.propTypes = {
+ base: PT.string.isRequired,
+ meta: PT.shape().isRequired,
+};
diff --git a/src/shared/routes/Communities/TCO09/Routes.jsx b/src/shared/routes/Communities/TCO09/Routes.jsx
new file mode 100644
index 0000000000..c4b9392a2c
--- /dev/null
+++ b/src/shared/routes/Communities/TCO09/Routes.jsx
@@ -0,0 +1,48 @@
+/**
+ * Routing of TCO09 Community.
+ */
+
+import ContentfulRoute from 'components/Contentful/Route';
+import Error404 from 'components/Error404';
+import Header from 'containers/tc-communities/Header';
+import PT from 'prop-types';
+import React from 'react';
+import { Route, Switch } from 'react-router-dom';
+
+import headerTheme from 'components/tc-communities/communities/tco/themes/header.scss';
+
+export default function TCO09({ base }) {
+ return (
+ (
+
+
+
+ }
+ id="1w99R7k46hAh3SwkRuFQiI"
+ />
+
+
+
+ )}
+ path={`${base}/:pageId?`}
+ />
+ );
+}
+
+TCO09.defaultProps = {
+ base: '',
+};
+
+TCO09.propTypes = {
+ base: PT.string,
+};
diff --git a/src/shared/routes/Communities/TCO09/index.jsx b/src/shared/routes/Communities/TCO09/index.jsx
new file mode 100644
index 0000000000..767a64c576
--- /dev/null
+++ b/src/shared/routes/Communities/TCO09/index.jsx
@@ -0,0 +1,32 @@
+/**
+ * Loader for the community's code chunks.
+ */
+
+import LoadingIndicator from 'components/LoadingIndicator';
+import path from 'path';
+import PT from 'prop-types';
+import React from 'react';
+import { AppChunk, webpack } from 'topcoder-react-utils';
+
+export default function ChunkLoader({ base, meta }) {
+ return (
+ import(/* webpackChunkName: "tco09-community/chunk" */ './Routes')
+ .then(({ default: Routes }) => (
+
+ ))
+ }
+ renderPlaceholder={() => }
+ renderServer={() => {
+ const Routes = webpack.requireWeak(path.resolve(__dirname, './Routes'));
+ return ;
+ }}
+ />
+ );
+}
+
+ChunkLoader.propTypes = {
+ base: PT.string.isRequired,
+ meta: PT.shape().isRequired,
+};
diff --git a/src/shared/routes/Communities/TCO10/Routes.jsx b/src/shared/routes/Communities/TCO10/Routes.jsx
new file mode 100644
index 0000000000..d339b8e989
--- /dev/null
+++ b/src/shared/routes/Communities/TCO10/Routes.jsx
@@ -0,0 +1,48 @@
+/**
+ * Routing of TCO10 Community.
+ */
+
+import ContentfulRoute from 'components/Contentful/Route';
+import Error404 from 'components/Error404';
+import Header from 'containers/tc-communities/Header';
+import PT from 'prop-types';
+import React from 'react';
+import { Route, Switch } from 'react-router-dom';
+
+import headerTheme from 'components/tc-communities/communities/tco/themes/header.scss';
+
+export default function TCO10({ base }) {
+ return (
+ (
+
+
+
+ }
+ id="2br5Pgqe2mPx5HG2DwmKhJ"
+ />
+
+
+
+ )}
+ path={`${base}/:pageId?`}
+ />
+ );
+}
+
+TCO10.defaultProps = {
+ base: '',
+};
+
+TCO10.propTypes = {
+ base: PT.string,
+};
diff --git a/src/shared/routes/Communities/TCO10/index.jsx b/src/shared/routes/Communities/TCO10/index.jsx
new file mode 100644
index 0000000000..73001685d9
--- /dev/null
+++ b/src/shared/routes/Communities/TCO10/index.jsx
@@ -0,0 +1,32 @@
+/**
+ * Loader for the community's code chunks.
+ */
+
+import LoadingIndicator from 'components/LoadingIndicator';
+import path from 'path';
+import PT from 'prop-types';
+import React from 'react';
+import { AppChunk, webpack } from 'topcoder-react-utils';
+
+export default function ChunkLoader({ base, meta }) {
+ return (
+ import(/* webpackChunkName: "tco10-community/chunk" */ './Routes')
+ .then(({ default: Routes }) => (
+
+ ))
+ }
+ renderPlaceholder={() => }
+ renderServer={() => {
+ const Routes = webpack.requireWeak(path.resolve(__dirname, './Routes'));
+ return ;
+ }}
+ />
+ );
+}
+
+ChunkLoader.propTypes = {
+ base: PT.string.isRequired,
+ meta: PT.shape().isRequired,
+};
diff --git a/src/shared/routes/Communities/TCO11/Routes.jsx b/src/shared/routes/Communities/TCO11/Routes.jsx
new file mode 100644
index 0000000000..67d36218a9
--- /dev/null
+++ b/src/shared/routes/Communities/TCO11/Routes.jsx
@@ -0,0 +1,48 @@
+/**
+ * Routing of TCO11 Community.
+ */
+
+import ContentfulRoute from 'components/Contentful/Route';
+import Error404 from 'components/Error404';
+import Header from 'containers/tc-communities/Header';
+import PT from 'prop-types';
+import React from 'react';
+import { Route, Switch } from 'react-router-dom';
+
+import headerTheme from 'components/tc-communities/communities/tco/themes/header.scss';
+
+export default function TCO11({ base }) {
+ return (
+ (
+
+
+
+ }
+ id="3Inhu3CrJhVNnzNHsmevps"
+ />
+
+
+
+ )}
+ path={`${base}/:pageId?`}
+ />
+ );
+}
+
+TCO11.defaultProps = {
+ base: '',
+};
+
+TCO11.propTypes = {
+ base: PT.string,
+};
diff --git a/src/shared/routes/Communities/TCO11/index.jsx b/src/shared/routes/Communities/TCO11/index.jsx
new file mode 100644
index 0000000000..cd102bd1b5
--- /dev/null
+++ b/src/shared/routes/Communities/TCO11/index.jsx
@@ -0,0 +1,32 @@
+/**
+ * Loader for the community's code chunks.
+ */
+
+import LoadingIndicator from 'components/LoadingIndicator';
+import path from 'path';
+import PT from 'prop-types';
+import React from 'react';
+import { AppChunk, webpack } from 'topcoder-react-utils';
+
+export default function ChunkLoader({ base, meta }) {
+ return (
+ import(/* webpackChunkName: "tco11-community/chunk" */ './Routes')
+ .then(({ default: Routes }) => (
+
+ ))
+ }
+ renderPlaceholder={() => }
+ renderServer={() => {
+ const Routes = webpack.requireWeak(path.resolve(__dirname, './Routes'));
+ return ;
+ }}
+ />
+ );
+}
+
+ChunkLoader.propTypes = {
+ base: PT.string.isRequired,
+ meta: PT.shape().isRequired,
+};
diff --git a/src/shared/routes/Communities/TCO12/Routes.jsx b/src/shared/routes/Communities/TCO12/Routes.jsx
new file mode 100644
index 0000000000..7f676a8569
--- /dev/null
+++ b/src/shared/routes/Communities/TCO12/Routes.jsx
@@ -0,0 +1,48 @@
+/**
+ * Routing of TCO12 Community.
+ */
+
+import ContentfulRoute from 'components/Contentful/Route';
+import Error404 from 'components/Error404';
+import Header from 'containers/tc-communities/Header';
+import PT from 'prop-types';
+import React from 'react';
+import { Route, Switch } from 'react-router-dom';
+
+import headerTheme from 'components/tc-communities/communities/tco/themes/header.scss';
+
+export default function TCO12({ base }) {
+ return (
+ (
+
+
+
+ }
+ id="ajoVqIOPhPSSXfCA7kt3N"
+ />
+
+
+
+ )}
+ path={`${base}/:pageId?`}
+ />
+ );
+}
+
+TCO12.defaultProps = {
+ base: '',
+};
+
+TCO12.propTypes = {
+ base: PT.string,
+};
diff --git a/src/shared/routes/Communities/TCO12/index.jsx b/src/shared/routes/Communities/TCO12/index.jsx
new file mode 100644
index 0000000000..83dfed1509
--- /dev/null
+++ b/src/shared/routes/Communities/TCO12/index.jsx
@@ -0,0 +1,32 @@
+/**
+ * Loader for the community's code chunks.
+ */
+
+import LoadingIndicator from 'components/LoadingIndicator';
+import path from 'path';
+import PT from 'prop-types';
+import React from 'react';
+import { AppChunk, webpack } from 'topcoder-react-utils';
+
+export default function ChunkLoader({ base, meta }) {
+ return (
+ import(/* webpackChunkName: "tco12-community/chunk" */ './Routes')
+ .then(({ default: Routes }) => (
+
+ ))
+ }
+ renderPlaceholder={() => }
+ renderServer={() => {
+ const Routes = webpack.requireWeak(path.resolve(__dirname, './Routes'));
+ return ;
+ }}
+ />
+ );
+}
+
+ChunkLoader.propTypes = {
+ base: PT.string.isRequired,
+ meta: PT.shape().isRequired,
+};
diff --git a/src/shared/routes/Communities/TCO13/Routes.jsx b/src/shared/routes/Communities/TCO13/Routes.jsx
new file mode 100644
index 0000000000..ee13fbd710
--- /dev/null
+++ b/src/shared/routes/Communities/TCO13/Routes.jsx
@@ -0,0 +1,48 @@
+/**
+ * Routing of TCO13 Community.
+ */
+
+import ContentfulRoute from 'components/Contentful/Route';
+import Error404 from 'components/Error404';
+import Header from 'containers/tc-communities/Header';
+import PT from 'prop-types';
+import React from 'react';
+import { Route, Switch } from 'react-router-dom';
+
+import headerTheme from 'components/tc-communities/communities/tco/themes/header.scss';
+
+export default function TCO13({ base }) {
+ return (
+ (
+
+
+
+ }
+ id="2O131soNK7FqORBFRMfcqu"
+ />
+
+
+
+ )}
+ path={`${base}/:pageId?`}
+ />
+ );
+}
+
+TCO13.defaultProps = {
+ base: '',
+};
+
+TCO13.propTypes = {
+ base: PT.string,
+};
diff --git a/src/shared/routes/Communities/TCO13/index.jsx b/src/shared/routes/Communities/TCO13/index.jsx
new file mode 100644
index 0000000000..f8d1d5cea8
--- /dev/null
+++ b/src/shared/routes/Communities/TCO13/index.jsx
@@ -0,0 +1,32 @@
+/**
+ * Loader for the community's code chunks.
+ */
+
+import LoadingIndicator from 'components/LoadingIndicator';
+import path from 'path';
+import PT from 'prop-types';
+import React from 'react';
+import { AppChunk, webpack } from 'topcoder-react-utils';
+
+export default function ChunkLoader({ base, meta }) {
+ return (
+ import(/* webpackChunkName: "tco13-community/chunk" */ './Routes')
+ .then(({ default: Routes }) => (
+
+ ))
+ }
+ renderPlaceholder={() => }
+ renderServer={() => {
+ const Routes = webpack.requireWeak(path.resolve(__dirname, './Routes'));
+ return ;
+ }}
+ />
+ );
+}
+
+ChunkLoader.propTypes = {
+ base: PT.string.isRequired,
+ meta: PT.shape().isRequired,
+};
diff --git a/src/shared/routes/Communities/TCO14/Routes.jsx b/src/shared/routes/Communities/TCO14/Routes.jsx
new file mode 100644
index 0000000000..b55721221e
--- /dev/null
+++ b/src/shared/routes/Communities/TCO14/Routes.jsx
@@ -0,0 +1,48 @@
+/**
+ * Routing of TCO14 Community.
+ */
+
+import ContentfulRoute from 'components/Contentful/Route';
+import Error404 from 'components/Error404';
+import Header from 'containers/tc-communities/Header';
+import PT from 'prop-types';
+import React from 'react';
+import { Route, Switch } from 'react-router-dom';
+
+import headerTheme from 'components/tc-communities/communities/tco/themes/header.scss';
+
+export default function TCO14({ base }) {
+ return (
+ (
+
+
+
+ }
+ id="4H8E3xUu9egGuEWAp0mj7Q"
+ />
+
+
+
+ )}
+ path={`${base}/:pageId?`}
+ />
+ );
+}
+
+TCO14.defaultProps = {
+ base: '',
+};
+
+TCO14.propTypes = {
+ base: PT.string,
+};
diff --git a/src/shared/routes/Communities/TCO14/index.jsx b/src/shared/routes/Communities/TCO14/index.jsx
new file mode 100644
index 0000000000..5270617e6d
--- /dev/null
+++ b/src/shared/routes/Communities/TCO14/index.jsx
@@ -0,0 +1,32 @@
+/**
+ * Loader for the community's code chunks.
+ */
+
+import LoadingIndicator from 'components/LoadingIndicator';
+import path from 'path';
+import PT from 'prop-types';
+import React from 'react';
+import { AppChunk, webpack } from 'topcoder-react-utils';
+
+export default function ChunkLoader({ base, meta }) {
+ return (
+ import(/* webpackChunkName: "tco14-community/chunk" */ './Routes')
+ .then(({ default: Routes }) => (
+
+ ))
+ }
+ renderPlaceholder={() => }
+ renderServer={() => {
+ const Routes = webpack.requireWeak(path.resolve(__dirname, './Routes'));
+ return ;
+ }}
+ />
+ );
+}
+
+ChunkLoader.propTypes = {
+ base: PT.string.isRequired,
+ meta: PT.shape().isRequired,
+};
diff --git a/src/shared/routes/Communities/TCO15/Routes.jsx b/src/shared/routes/Communities/TCO15/Routes.jsx
new file mode 100644
index 0000000000..7ec8acc9d0
--- /dev/null
+++ b/src/shared/routes/Communities/TCO15/Routes.jsx
@@ -0,0 +1,48 @@
+/**
+ * Routing of TCO15 Community.
+ */
+
+import ContentfulRoute from 'components/Contentful/Route';
+import Error404 from 'components/Error404';
+import Header from 'containers/tc-communities/Header';
+import PT from 'prop-types';
+import React from 'react';
+import { Route, Switch } from 'react-router-dom';
+
+import headerTheme from 'components/tc-communities/communities/tco/themes/header.scss';
+
+export default function TCO15({ base }) {
+ return (
+ (
+
+
+
+ }
+ id="1wjcHvy0CC9B4N4KeLsDJ0"
+ />
+
+
+
+ )}
+ path={`${base}/:pageId?`}
+ />
+ );
+}
+
+TCO15.defaultProps = {
+ base: '',
+};
+
+TCO15.propTypes = {
+ base: PT.string,
+};
diff --git a/src/shared/routes/Communities/TCO15/index.jsx b/src/shared/routes/Communities/TCO15/index.jsx
new file mode 100644
index 0000000000..ad4e04191e
--- /dev/null
+++ b/src/shared/routes/Communities/TCO15/index.jsx
@@ -0,0 +1,32 @@
+/**
+ * Loader for the community's code chunks.
+ */
+
+import LoadingIndicator from 'components/LoadingIndicator';
+import path from 'path';
+import PT from 'prop-types';
+import React from 'react';
+import { AppChunk, webpack } from 'topcoder-react-utils';
+
+export default function ChunkLoader({ base, meta }) {
+ return (
+ import(/* webpackChunkName: "tco15-community/chunk" */ './Routes')
+ .then(({ default: Routes }) => (
+
+ ))
+ }
+ renderPlaceholder={() => }
+ renderServer={() => {
+ const Routes = webpack.requireWeak(path.resolve(__dirname, './Routes'));
+ return ;
+ }}
+ />
+ );
+}
+
+ChunkLoader.propTypes = {
+ base: PT.string.isRequired,
+ meta: PT.shape().isRequired,
+};
diff --git a/src/shared/routes/Communities/TCO16/Routes.jsx b/src/shared/routes/Communities/TCO16/Routes.jsx
new file mode 100644
index 0000000000..039fbbea06
--- /dev/null
+++ b/src/shared/routes/Communities/TCO16/Routes.jsx
@@ -0,0 +1,48 @@
+/**
+ * Routing of TCO16 Community.
+ */
+
+import ContentfulRoute from 'components/Contentful/Route';
+import Error404 from 'components/Error404';
+import Header from 'containers/tc-communities/Header';
+import PT from 'prop-types';
+import React from 'react';
+import { Route, Switch } from 'react-router-dom';
+
+import headerTheme from 'components/tc-communities/communities/tco/themes/header.scss';
+
+export default function TCO16({ base }) {
+ return (
+ (
+
+
+
+ }
+ id="6jQnnCtlJUr7p6lOzaHwNg"
+ />
+
+
+
+ )}
+ path={`${base}/:pageId?`}
+ />
+ );
+}
+
+TCO16.defaultProps = {
+ base: '',
+};
+
+TCO16.propTypes = {
+ base: PT.string,
+};
diff --git a/src/shared/routes/Communities/TCO16/index.jsx b/src/shared/routes/Communities/TCO16/index.jsx
new file mode 100644
index 0000000000..edb8b59591
--- /dev/null
+++ b/src/shared/routes/Communities/TCO16/index.jsx
@@ -0,0 +1,32 @@
+/**
+ * Loader for the community's code chunks.
+ */
+
+import LoadingIndicator from 'components/LoadingIndicator';
+import path from 'path';
+import PT from 'prop-types';
+import React from 'react';
+import { AppChunk, webpack } from 'topcoder-react-utils';
+
+export default function ChunkLoader({ base, meta }) {
+ return (
+ import(/* webpackChunkName: "tco16-community/chunk" */ './Routes')
+ .then(({ default: Routes }) => (
+
+ ))
+ }
+ renderPlaceholder={() => }
+ renderServer={() => {
+ const Routes = webpack.requireWeak(path.resolve(__dirname, './Routes'));
+ return ;
+ }}
+ />
+ );
+}
+
+ChunkLoader.propTypes = {
+ base: PT.string.isRequired,
+ meta: PT.shape().isRequired,
+};
diff --git a/src/shared/routes/Communities/TCO19/Routes.jsx b/src/shared/routes/Communities/TCO19/Routes.jsx
index 70acff60f6..df59b48930 100644
--- a/src/shared/routes/Communities/TCO19/Routes.jsx
+++ b/src/shared/routes/Communities/TCO19/Routes.jsx
@@ -5,7 +5,6 @@
import _ from 'lodash';
import Error404 from 'components/Error404';
import Header from 'containers/tc-communities/Header';
-import Home from 'containers/tc-communities/tco19/Home';
import PT from 'prop-types';
import React from 'react';
import { Route, Switch } from 'react-router-dom';
@@ -13,6 +12,7 @@ import Viewport from 'components/Contentful/Viewport';
import ContentfulLoader from 'containers/ContentfulLoader';
import Blog from 'components/Contentful/Blog';
import { HeroImageLoader } from 'components/Contentful/BlogPost';
+import ContentfulRoute from 'components/Contentful/Route';
import headerTheme from 'components/tc-communities/communities/tco19/themes/header.scss';
@@ -67,38 +67,10 @@ export default function TCO19({ base }) {
);
}}
/>
- {
- const mId = p.match.params.menuItems.split('/');
- const query = {
- content_type: 'navigationMenuItem',
- 'fields.slug': mId[mId.length - 1],
- };
- return (
- {
- const menuItem = _.values(data.entries.items)[0];
- if (!menuItem) return Error404();
-
- return (
-
- );
- }}
- />
- );
- }}
- path={`${base}/:menuItems+`}
- />
- }
- exact
- path={`${base}`}
- />
- }
- exact
- path={`${base}/home`}
+ }
+ id="6kF6iiWGmhM6EHH8j7Kee7"
/>
_.camelCase(key)) : undefined;
}
+// Concatenates a base and segment and handles optional trailing slashes
+const buildUrl = (base, segment) => `${_.trimEnd(base, '/')}/${_.trim(segment, '/')}`;
+
+/**
+ * Checks if URL is absolute
+ * @param {String} url
+ */
+function isAbsolute(url) {
+ return url.startsWith('http:') || url.startsWith('https:');
+}
+
+/**
+ * Builds target url for menu link
+ * @param {String} baseUrl
+ * @param {String} item
+ */
+export function target(baseUrl, item) {
+ // use/prefer url if available
+ let to = '';
+ if (item.fields.url) {
+ // for Routes or NavigationMenuItem entries with a non-empty url field
+ to = isAbsolute(item.fields.url) ? item.fields.url : buildUrl(baseUrl, item.fields.url);
+ } else if (item.fields.slug) {
+ // for NavigationMenuItem entries without an URL field
+ // menu item slug to build the url
+ to = buildUrl(baseUrl, item.fields.slug);
+ } else {
+ // for Routes with no url
+ to = baseUrl;
+ }
+ return to;
+}
+
+/**
+ * Checks if menu link is active
+ * @param {String} baseUrl
+ * @param {String} item
+ */
+export function isActive(baseUrl, item, caller) {
+ let to = removeTrailingSlash(target(baseUrl, item));
+ to = to ? to.toLowerCase() : to;
+
+ let location;
+ if (isomorphy.isClientSide()) {
+ location = isAbsolute(to) ? buildUrl(window.location.origin, window.location.pathname)
+ : window.location.pathname;
+ location = location.toLowerCase();
+ } else {
+ // TODO: should probably get the current URL from the web framework
+ return false;
+ }
+
+ // handles the special case when url === `/`
+ if (caller === 'menuItem'
+ && to === baseUrl
+ && (location !== to && location !== `${to}/`)) {
+ return false;
+ }
+
+ // check if the current location is the link target or a subdirectory
+ return location && (location === to || location.startsWith(`${to}/`));
+}
+
+/**
+ * Picks the text for menu links
+ * @param {Object} item
+ */
+export function linkText(item) {
+ return item.fields.naviMenuLinkText /* Route-only */
+ || item.fields.linkText /* NavigationMenuItem-only */ || item.fields.name;
+}
+
export default undefined;