diff --git a/.circleci/config.yml b/.circleci/config.yml
index ea2e339f75..62b48152fc 100644
--- a/.circleci/config.yml
+++ b/.circleci/config.yml
@@ -356,7 +356,7 @@ workflows:
filters:
branches:
only:
- - debug-CMS-error
+ - tco23
# This is alternate dev env for parallel testing
- "build-qa":
context : org-global
diff --git a/__tests__/shared/components/__snapshots__/Content.jsx.snap b/__tests__/shared/components/__snapshots__/Content.jsx.snap
index f9d9c7553a..a4e05fa565 100644
--- a/__tests__/shared/components/__snapshots__/Content.jsx.snap
+++ b/__tests__/shared/components/__snapshots__/Content.jsx.snap
@@ -491,7 +491,7 @@ exports[`Matches shallow shapshot 1`] = `
TopGear (Wipro) community
diff --git a/src/server/index.js b/src/server/index.js
index 9996ce180f..70590aa8b8 100644
--- a/src/server/index.js
+++ b/src/server/index.js
@@ -185,6 +185,7 @@ async function onExpressJsSetup(server) {
+ ` ${config.CDN.PUBLIC}`
+ ' https://d1of0acg2orgco.cloudfront.net'
+ ' https://d24oibycet9bsb.cloudfront.net'
+ + ' https://d1mwkvp2xbqfs9.cloudfront.net'
+ ' https://43d132d5dbff47c59d9d53ad448f93c2.js.ubembed.com;'
+ " frame-src 'self'"
+ ` ${config.URL.AUTH}`
diff --git a/src/server/services/communities.js b/src/server/services/communities.js
index 54c797eee3..90a02b68fb 100644
--- a/src/server/services/communities.js
+++ b/src/server/services/communities.js
@@ -116,6 +116,17 @@ export async function getMetadata(communityId) {
if (metadata.groupIds) {
metadata.groupIds = await extendByChildGroups(metadata.groupIds);
}
+
+ // FIXME: This is a tempory patch to resolve "Backstage Error" that's showing up on Topgear
+ // app due to missing "Wipro All" authorized group
+ // Roll this back as soon as the root cause is fixed
+ // which is likely either in topcoder-react-lib that handles merging groups (https://github.com/topcoder-platform/topcoder-react-lib/blob/c637525211550bea283390e52490fce7f6dd44a8/src/services/groups.js#L107)
+ // or Groups Api
+ if (communityId === 'wipro') {
+ logger.info('Getting metadata for Topgear. Existing Authorized Groups', JSON.stringify(metadata.authorizedGroupIds));
+ metadata.authorizedGroupIds = _.uniq(metadata.authorizedGroupIds.concat('b7f7c0f8-8ee8-409e-9e5c-33404983b635'));
+ logger.info('After adding "Wipro All" group', JSON.stringify(metadata.authorizedGroupIds));
+ }
getMetadata.cache[communityId] = { data: metadata, timestamp: now };
return _.cloneDeep(metadata);
}
diff --git a/src/server/tc-communities/tco23/metadata.json b/src/server/tc-communities/tco23/metadata.json
new file mode 100644
index 0000000000..04b88da612
--- /dev/null
+++ b/src/server/tc-communities/tco23/metadata.json
@@ -0,0 +1,20 @@
+{
+ "challengeFilter": {
+ "events": ["tco23"]
+ },
+ "communityId": "tco23",
+ "communityName": "TCO23",
+ "groupIds": [],
+ "hideSearch": true,
+ "logos": [{
+ "img": "/community-app-assets/themes/tco/TCO23.svg",
+ "url": "https://tco23.topcoder.com"
+ }],
+ "menuItems": [{
+ "navigationMenu": "6SsceF3R5YuKxsf8XnCM5I"
+ }],
+ "newsFeed": "http://www.topcoder.com/feed",
+ "subdomains": ["tco23"],
+ "description": "2023 Topcoder Open. The Ultimate Programming & Design Tournament",
+ "image": "tco23.jpg"
+}
diff --git a/src/shared/components/Content/index.jsx b/src/shared/components/Content/index.jsx
index 293cb35600..a1c9139df2 100644
--- a/src/shared/components/Content/index.jsx
+++ b/src/shared/components/Content/index.jsx
@@ -413,7 +413,7 @@ export default function Content() {
-
+
TopGear (Wipro) community
diff --git a/src/shared/components/Contentful/ContentBlock/index.jsx b/src/shared/components/Contentful/ContentBlock/index.jsx
index 2aea7d2b78..d567a69c35 100644
--- a/src/shared/components/Contentful/ContentBlock/index.jsx
+++ b/src/shared/components/Contentful/ContentBlock/index.jsx
@@ -19,6 +19,7 @@ import generalTheme from './themes/general.scss';
import blobCard from './themes/blobCard.scss';
import TCO20Theme from './themes/TCO20.scss';
import largeCard from './themes/largeCard.scss';
+import bracketsTheme from './themes/brackets.scss';
const THEMES = {
Default: defaultTheme,
@@ -31,6 +32,7 @@ const THEMES = {
'Blob Card': blobCard,
TCO20: TCO20Theme,
'Large Card': largeCard,
+ Brackets: bracketsTheme,
};
/* Loads content block background asset. */
diff --git a/src/shared/components/Contentful/ContentBlock/themes/brackets.scss b/src/shared/components/Contentful/ContentBlock/themes/brackets.scss
new file mode 100644
index 0000000000..5475fff209
--- /dev/null
+++ b/src/shared/components/Contentful/ContentBlock/themes/brackets.scss
@@ -0,0 +1,64 @@
+@import "~styles/mixins";
+@import "~components/Contentful/brackets";
+
+.contentWrapper {
+ display: flex;
+ margin: 0 auto;
+ max-width: $screen-lg;
+ padding: 15px 0;
+ color: $tc-black;
+
+ @include xs-to-sm {
+ flex-direction: column;
+ }
+}
+
+.container {
+ align-content: center;
+ background: white;
+ padding: 10px 0;
+
+ &:nth-child(even) .contentWrapper {
+ flex-direction: row-reverse;
+
+ @include xs-to-sm {
+ flex-direction: column;
+ }
+ }
+}
+
+strong a {
+ font-weight: 600 !important;
+}
+
+.content {
+ flex: 1;
+ padding: 0;
+
+ @include xs-to-md {
+ padding: 15px;
+ }
+
+ @include roboto-regular;
+
+ h1,
+ h2,
+ h3,
+ h4,
+ h5,
+ h6 {
+ color: $tco-black;
+ }
+
+ @include brackets-headers;
+ @include brackets-content;
+}
+
+.image {
+ flex: 1;
+ margin: 15px;
+
+ img {
+ width: 100%;
+ }
+}
diff --git a/src/shared/components/Contentful/Tabs/Tabs.jsx b/src/shared/components/Contentful/Tabs/Tabs.jsx
index 85280aa4bd..4eb0541cdf 100644
--- a/src/shared/components/Contentful/Tabs/Tabs.jsx
+++ b/src/shared/components/Contentful/Tabs/Tabs.jsx
@@ -27,6 +27,7 @@ import underlineDarkTheme from './themes/underline-dark.scss';
import verticalTheme from './themes/vertical.scss';
import pillsTheme from './themes/pills.scss';
import underlineBoxTheme from './themes/underline-box.scss';
+import bracketsTheme from './themes/brackets.scss';
export const TAB_THEMES = {
Default: defaultTheme,
@@ -38,6 +39,7 @@ export const TAB_THEMES = {
Vertical: verticalTheme,
Pills: pillsTheme,
'Underline box': underlineBoxTheme,
+ Brackets: bracketsTheme,
};
export default class TabsItemsLoader extends Component {
diff --git a/src/shared/components/Contentful/Tabs/themes/brackets.scss b/src/shared/components/Contentful/Tabs/themes/brackets.scss
new file mode 100644
index 0000000000..589de02776
--- /dev/null
+++ b/src/shared/components/Contentful/Tabs/themes/brackets.scss
@@ -0,0 +1,168 @@
+@import "~styles/mixins";
+
+$container-background-gray: #ebebeb;
+$text-color-black: #262628;
+$text-color-gray: #888894;
+$text-color-pannel: #4a4a4a;
+
+.container {
+ margin: auto;
+
+ @include xs-to-sm {
+ margin-top: 65px;
+ }
+}
+
+.tabListWrap {
+ display: flex;
+ justify-content: center;
+ position: relative;
+
+ .tablist {
+ @include roboto-regular;
+
+ display: flex;
+ flex-direction: row;
+ justify-content: center;
+ list-style-type: none;
+ box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.06);
+ margin: auto;
+ min-height: 60px;
+ border-radius: 30px;
+ align-items: center;
+ background-color: white;
+ padding: 0 25px;
+ border: 1px solid #e4e4e4;
+
+ @include xs-to-sm {
+ white-space: nowrap;
+ flex-direction: column;
+ padding: 28px 15px 0;
+ align-items: flex-start;
+ border-radius: 8px;
+ min-width: 85vw;
+ overflow: visible;
+ position: absolute;
+ z-index: 999;
+ display: none; // by default
+
+ &.visible {
+ display: flex;
+ }
+ }
+ }
+
+ .tabListMobileTrigger {
+ display: none;
+ justify-content: center;
+ align-items: center;
+ background-color: white;
+ position: absolute;
+ top: -65px;
+ width: 85vw;
+ left: calc(50% - 42.5vw);
+ outline: none;
+ border: navajowhite;
+ min-height: 60px;
+ font-family: Barlow, sans-serif;
+ font-size: 16px;
+ font-weight: 600;
+ text-transform: uppercase;
+ border-radius: 30px;
+ box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.06);
+ color: #2a2a2a;
+
+ @media (max-width: 768px) {
+ display: flex;
+ }
+
+ .tabListMobileTriggerSVG,
+ .tabListMobileTriggerSVGOpen {
+ margin-left: 9px;
+ }
+
+ .tabListMobileTriggerSVGOpen {
+ transform: scaleY(-1);
+ }
+ }
+}
+
+.tab {
+ text-align: center;
+ margin: 0 25px;
+ color: #555;
+ font-family: Barlow, sans-serif;
+ font-size: 16px;
+ font-weight: 600;
+ line-height: 20px;
+ padding-bottom: 5px;
+ cursor: pointer;
+ margin-bottom: -5px;
+ position: relative;
+
+ @include xs-to-sm {
+ margin: 0;
+ margin-bottom: 23px;
+ padding: 0;
+ padding-left: 5px;
+
+ &::after {
+ display: none;
+ }
+
+ &:hover,
+ &.selected {
+ border-left: 3px solid #43d7b0;
+ margin-left: -3px;
+ }
+ }
+
+ &:hover,
+ &.selected {
+ color: #2a2a2a;
+
+ &::after {
+ content: '';
+ border-radius: 1000vw;
+ background: #43d7b0;
+ height: 3px;
+ width: 15px;
+ position: absolute;
+ bottom: 0;
+ left: calc(50% - 7px);
+ border-left: 1px solid #fff;
+ border-right: 1px solid #fff;
+
+ @include xs-to-sm {
+ width: calc(100% - 36px);
+ bottom: -5px;
+ }
+ }
+ }
+
+ p {
+ small {
+ color: #888894;
+ font-size: 13px;
+ font-weight: 400;
+ line-height: 25px;
+ text-align: left;
+ }
+
+ strong {
+ font-weight: bold;
+ }
+ }
+}
+
+.tabpannel {
+ display: none;
+}
+
+.selectedTabPanel {
+ display: block;
+
+ @include xs-to-sm {
+ padding: 0 15px;
+ }
+}
diff --git a/src/shared/components/Contentful/_brackets.scss b/src/shared/components/Contentful/_brackets.scss
new file mode 100644
index 0000000000..db13a3a911
--- /dev/null
+++ b/src/shared/components/Contentful/_brackets.scss
@@ -0,0 +1,281 @@
+@import "~styles/mixins";
+
+@mixin default-headers {
+ h1,
+ h2,
+ h3,
+ h4,
+ h5,
+ h6 {
+ margin: 10px 0;
+ }
+
+ h1 {
+ font-size: 42px;
+ line-height: 50px;
+
+ @include roboto-light;
+ }
+
+ h2 {
+ font-size: 36px;
+ line-height: 45px;
+
+ @include roboto-light;
+ }
+
+ h3 {
+ font-size: 28px;
+ line-height: 35px;
+
+ @include roboto-regular;
+ }
+
+ h4 {
+ font-size: 20px;
+ line-height: 35px;
+
+ @include roboto-regular;
+ }
+
+ h5 {
+ font-size: 15px;
+ line-height: 25px;
+
+ @include roboto-bold;
+ }
+
+ h6 {
+ font-size: 13px;
+ line-height: 25px;
+
+ @include roboto-bold;
+ }
+}
+
+@mixin brackets-headers {
+ h1 {
+ @include barlow-condensed-semi-bold;
+
+ font-size: 80px;
+ line-height: 72px;
+ text-transform: uppercase;
+ margin-top: 80px;
+ margin-bottom: 20px;
+
+ @include xs-to-sm {
+ font-size: 42px !important;
+ font-weight: 600 !important;
+ line-height: 40px !important;
+ margin-top: 42px;
+ margin-bottom: 10px;
+ }
+ }
+
+ h2 {
+ @include barlow-condensed-semi-bold;
+
+ font-size: 54px;
+ line-height: 52px;
+ text-transform: uppercase;
+ margin-top: 54px;
+ margin-bottom: 20px;
+
+ @include xs-to-sm {
+ font-size: 32px !important;
+ font-weight: 500 !important;
+ margin-top: 32px;
+ margin-bottom: 10px;
+ line-height: 32px !important;
+ }
+ }
+
+ h3 {
+ @include barlow-condensed-semi-bold;
+
+ font-size: 44px;
+ line-height: 44px;
+ text-transform: uppercase;
+ margin-top: 44px;
+ margin-bottom: 20px;
+
+ @include xs-to-sm {
+ font-size: 27px !important;
+ font-weight: 500 !important;
+ line-height: 28px !important;
+ margin-top: 27px;
+ margin-bottom: 10px;
+ }
+ }
+
+ h4 {
+ @include barlow-condensed-semi-bold;
+
+ font-size: 32px;
+ line-height: 34px;
+ text-transform: uppercase;
+ margin-top: 32px;
+ margin-bottom: 10px;
+
+ @include xs-to-sm {
+ font-size: 22px !important;
+ font-weight: 500 !important;
+ line-height: 24px !important;
+ margin-top: 22px;
+ }
+ }
+
+ h5,
+ h6 {
+ @include barlow-condensed-semi-bold;
+
+ font-size: 26px;
+ line-height: 28px;
+ font-weight: 600;
+ text-transform: uppercase;
+ margin-top: 26px;
+ margin-bottom: 10px;
+
+ @include xs-to-sm {
+ font-size: 16px !important;
+ font-weight: 600 !important;
+ line-height: 18px !important;
+ margin-top: 16px;
+ }
+ }
+}
+
+@mixin brackets-content {
+ a {
+ @include roboto-regular;
+
+ font-size: 16px;
+ line-height: 24px;
+ color: #0d61bf;
+ text-decoration: none;
+
+ &:hover {
+ text-decoration: none;
+ color: #0d61bf;
+ }
+
+ &:visited {
+ color: #8231a9;
+ }
+ }
+
+ p {
+ @include tc-body-md;
+
+ color: $tco-black;
+ font-size: 16px;
+ line-height: 24px;
+ margin-bottom: 20px;
+ margin-top: 0;
+
+ strong {
+ @include roboto-medium;
+
+ line-height: 24px;
+ text-align: left;
+ font-weight: 600;
+ }
+ }
+
+ table {
+ margin-bottom: 20px;
+
+ th {
+ @include barlow-bold;
+
+ color: #2a2a2a;
+ font-size: 11px;
+ line-height: 14px;
+ text-align: left;
+ text-transform: uppercase;
+ padding: 18px 10px 14px 0;
+
+ @include md-to-xl {
+ white-space: nowrap;
+ }
+
+ &:first-child {
+ padding-left: 10px;
+ }
+ }
+
+ td {
+ @include roboto-regular;
+
+ font-size: 16px;
+ line-height: 26px;
+ text-align: left;
+ color: #2a2a2a;
+ border-top: 1px solid #d4d4d4;
+ border-bottom: 1px solid #d4d4d4;
+ padding: 18px 50px 18px 0;
+ max-height: 63px;
+
+ &:first-child {
+ padding-left: 10px;
+ }
+
+ &:last-child {
+ padding-right: 10px;
+ }
+ }
+ }
+
+ ul,
+ ol {
+ @include tc-body-md;
+
+ padding-left: 20px;
+ margin-bottom: 20px;
+
+ @include roboto-regular;
+
+ color: $tc-black;
+
+ li p {
+ margin-bottom: 0;
+ }
+ }
+
+ ul {
+ list-style-type: disc;
+ }
+
+ ol {
+ list-style-type: decimal;
+ }
+
+ img {
+ max-width: 100%;
+ border-radius: 6px;
+ }
+
+ code {
+ @include roboto-mono-regular;
+
+ color: #2a2a2a;
+ line-height: 1.5;
+ white-space: pre;
+ }
+
+ sub,
+ sup {
+ font-size: 75%;
+ line-height: 0;
+ position: relative;
+ vertical-align: baseline;
+ }
+
+ sup {
+ top: -0.5em;
+ }
+
+ sub {
+ bottom: -0.25em;
+ }
+}
diff --git a/src/shared/components/buttons/themed/brackets.scss b/src/shared/components/buttons/themed/brackets.scss
new file mode 100644
index 0000000000..799353c58e
--- /dev/null
+++ b/src/shared/components/buttons/themed/brackets.scss
@@ -0,0 +1,303 @@
+@import "~styles/mixins";
+
+@mixin primary {
+ @include roboto-bold;
+
+ font-weight: 700 !important;
+ text-decoration: none !important;
+ text-transform: uppercase !important;
+ margin: 0 !important;
+ white-space: nowrap !important;
+ letter-spacing: 0.8px;
+}
+
+@mixin primary-master {
+ @include primary;
+
+ background-color: #e6cff1 !important;
+ background-image: none !important;
+ color: #8231a9 !important;
+ border: none !important;
+ box-shadow: none !important;
+
+ &:hover {
+ background-color: #e6cff1 !important;
+ }
+
+ &:active {
+ background-color: #e6cff1 !important;
+ }
+
+ &:disabled {
+ color: #8231a9;
+ border: none !important;
+ background: none !important;
+ }
+}
+
+@mixin primary-green {
+ @include primary;
+
+ background-color: #137d60 !important;
+ background-image: none !important;
+ color: #fff !important;
+ border: none !important;
+ box-shadow: none !important;
+
+ &:hover {
+ background-color: #219174 !important;
+ }
+
+ &:active {
+ background-color: #0d664e !important;
+ }
+
+ &:disabled {
+ color: #767676;
+ border: none !important;
+ background: none !important;
+ }
+}
+
+@mixin primary-white {
+ @include primary;
+
+ background-color: #fff !important;
+ background-image: none !important;
+ color: #137d60 !important;
+ border: 2px solid #137d60 !important;
+ box-shadow: none !important;
+
+ &:hover {
+ color: #219174;
+ border: 2px solid #219174 !important;
+ }
+
+ &:active {
+ color: #0d664e !important;
+ border: 2px solid #0d664e !important;
+ }
+
+ &:disabled {
+ color: #767676;
+ border: none !important;
+ }
+}
+
+@mixin primary-tertiary {
+ @include primary;
+
+ background-color: #fff !important;
+ background-image: none !important;
+ color: #137d60 !important;
+ border: none !important;
+ box-shadow: none !important;
+
+ &:hover,
+ &:active {
+ color: #0d664e;
+ }
+
+ &:disabled {
+ color: #767676;
+ }
+}
+
+@mixin sm {
+ font-size: 12px !important;
+ line-height: 24px !important;
+ border-radius: 24px !important;
+ min-height: auto !important;
+ max-height: 24px !important;
+ padding: 0 16px !important;
+}
+
+@mixin md {
+ font-size: 13px !important;
+ line-height: 24px !important;
+ border-radius: 24px !important;
+ min-height: auto !important;
+ max-height: 32px !important;
+ padding: 4px 20px !important;
+}
+
+@mixin lg {
+ font-size: 14px !important;
+ line-height: 24px !important;
+ border-radius: 24px !important;
+ min-height: auto !important;
+ max-height: 40px !important;
+ padding: 8px 24px !important;
+}
+
+@mixin xl {
+ font-size: 16px !important;
+ line-height: 24px !important;
+ border-radius: 50px !important;
+ min-height: auto !important;
+ max-height: 48px !important;
+ padding: 12px 24px !important;
+}
+
+.primary {
+ &-master {
+ &-sm {
+ @include primary-master;
+ @include sm;
+
+ &:hover {
+ @include primary-master;
+ }
+ }
+
+ &-md {
+ @include primary-master;
+ @include md;
+
+ &:hover {
+ @include primary-master;
+ }
+ }
+
+ &-lg {
+ @include primary-master;
+ @include lg;
+
+ &:hover {
+ @include primary-master;
+ }
+ }
+
+ &-xl {
+ @include primary-master;
+ @include xl;
+
+ &:hover {
+ @include primary-master;
+ }
+ }
+ }
+
+ &-green {
+ &-sm {
+ @include primary-green;
+ @include sm;
+
+ &:hover {
+ @include primary-green;
+ }
+ }
+
+ &-md {
+ @include primary-green;
+ @include md;
+
+ &:hover {
+ @include primary-green;
+ }
+ }
+
+ &-lg {
+ @include primary-green;
+ @include lg;
+
+ &:hover {
+ @include primary-green;
+ }
+ }
+
+ &-xl {
+ @include primary-green;
+ @include xl;
+
+ &:hover {
+ @include primary-green;
+ }
+ }
+ }
+
+ &-white {
+ &-sm {
+ @include primary-white;
+ @include sm;
+
+ &:hover {
+ @include primary-white;
+ }
+ }
+
+ &-md {
+ @include primary-white;
+ @include md;
+
+ line-height: 38px !important;
+
+ &:hover {
+ @include primary-white;
+ }
+ }
+
+ &-lg {
+ @include primary-white;
+ @include lg;
+
+ &:hover {
+ @include primary-white;
+ }
+ }
+
+ &-xl {
+ @include primary-white;
+ @include xl;
+
+ &:hover {
+ @include primary-white;
+ }
+ }
+ }
+
+ &-tertiary {
+ &-sm {
+ @include primary-tertiary;
+ @include sm;
+
+ &:hover {
+ @include primary-tertiary;
+ }
+ }
+
+ &-md {
+ @include primary-tertiary;
+ @include md;
+
+ &:hover {
+ @include primary-tertiary;
+ }
+ }
+
+ &-lg {
+ @include primary-tertiary;
+ @include lg;
+
+ &:hover {
+ @include primary-tertiary;
+ }
+ }
+
+ &-xl {
+ @include primary-tertiary;
+ @include xl;
+
+ &:hover {
+ @include primary-tertiary;
+ }
+ }
+ }
+}
+
+.themedButtonDisabled {
+ background-color: #e9e9e9 !important;
+ border: none !important;
+ text-decoration: none !important;
+ color: #fafafb !important;
+}
diff --git a/src/shared/routes/Communities/Routes.jsx b/src/shared/routes/Communities/Routes.jsx
index 920791339e..ddee9a97f0 100644
--- a/src/shared/routes/Communities/Routes.jsx
+++ b/src/shared/routes/Communities/Routes.jsx
@@ -39,6 +39,7 @@ import tco19 from './TCO19';
import tco20 from './TCO20';
import tco21 from './TCO21';
import tco22 from './TCO22';
+import tco23 from './TCO23';
import Mobile from './Mobile';
import Zurich from './Zurich';
import Comcast from './Comcast';
@@ -66,6 +67,7 @@ const TCOs = {
tco20,
tco21,
tco22,
+ tco23,
};
export default function Communities({
diff --git a/src/shared/routes/Communities/TCO23/Routes.jsx b/src/shared/routes/Communities/TCO23/Routes.jsx
new file mode 100644
index 0000000000..126febfe6a
--- /dev/null
+++ b/src/shared/routes/Communities/TCO23/Routes.jsx
@@ -0,0 +1,60 @@
+/**
+ * Routing of TCO23 Community.
+ */
+
+import Error404 from 'components/Error404';
+import PT from 'prop-types';
+import React from 'react';
+import { Route, Switch } from 'react-router-dom';
+import ContentfulRoute from 'components/Contentful/Route';
+import ContentfulMenu from 'components/Contentful/Menu';
+import Profile from 'routes/Profile';
+import ProfileStats from 'routes/ProfileStats';
+import Settings from 'routes/Settings';
+
+export default function TCO23({ base, meta }) {
+ return (
+
+ {
+ meta.menuItems ? (
+
+ ) : null
+ }
+
+ }
+ exact
+ path={`${base}/members/:handle([\\w\\-\\[\\].{}]{2,15})`}
+ />
+ }
+ exact
+ path={`${base}/members/:handle([\\w\\-\\[\\].{}]{2,15})/details`}
+ />
+ }
+ path={`${base}/settings`}
+ />
+ }
+ id="6sV6osYXXLq9Jai5nPt3xI"
+ />
+
+
+ );
+}
+
+TCO23.defaultProps = {
+ base: '',
+};
+
+TCO23.propTypes = {
+ base: PT.string,
+ meta: PT.shape().isRequired,
+};
diff --git a/src/shared/routes/Communities/TCO23/index.jsx b/src/shared/routes/Communities/TCO23/index.jsx
new file mode 100644
index 0000000000..6cdf98cc20
--- /dev/null
+++ b/src/shared/routes/Communities/TCO23/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: "tco23-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/utils/markdown.js b/src/shared/utils/markdown.js
index a7cdb5cd8c..5e0883bf04 100644
--- a/src/shared/utils/markdown.js
+++ b/src/shared/utils/markdown.js
@@ -41,6 +41,7 @@ import tco10 from 'components/buttons/outline/tco/tco10.scss';
import tco09 from 'components/buttons/outline/tco/tco09.scss';
import tco07 from 'components/buttons/outline/tco/tco07.scss';
import tc from 'components/buttons/themed/tc.scss';
+import bs from 'components/buttons/themed/brackets.scss';
import Highlighter from './highlighter';
@@ -73,6 +74,7 @@ const tcoButtonThemes = {
*/
const buttonThemes = {
tc,
+ bs,
};
/**