Skip to content

Commit 4152a3b

Browse files
authored
Merge pull request #621 from topcoder-platform/dev
v3.2 May Release
2 parents 901729d + 37dd8c9 commit 4152a3b

File tree

71 files changed

+649
-401
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

71 files changed

+649
-401
lines changed

config/dev.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
11
module.exports = {
2+
TC_DOMAIN: 'topcoder-dev.com',
23
/**
34
* URL of Topcoder Community Website
45
*/
56
TOPCODER_COMMUNITY_WEBSITE_URL: "https://topcoder-dev.com",
67
TERMS_URL:
78
"https://www.topcoder-dev.com/challenges/terms/detail/317cd8f9-d66c-4f2a-8774-63c612d99cd4",
89
PRIVACY_POLICY_URL: "https://www.topcoder-dev.com/policy",
9-
SIGN_IN_URL: `https://accounts-auth0.topcoder-dev.com/?retUrl=https%3A%2F%2Fplatform-ui.topcoder-dev.com%2Fself-service%2Fwizard&regSource=selfService`,
10-
SIGN_UP_URL: `https://accounts-auth0.topcoder-dev.com/?retUrl=https%3A%2F%2Fplatform-ui.topcoder-dev.com%2Fself-service%2Fwizard&regSource=selfService&mode=signUp`,
10+
SIGN_IN_URL: `https://accounts-auth0.topcoder-dev.com/?retUrl=https%3A%2F%2Fwork.topcoder-dev.com%2Fself-service%2Fwizard&regSource=selfService`,
11+
SIGN_UP_URL: `https://accounts-auth0.topcoder-dev.com/?retUrl=https%3A%2F%2Fwork.topcoder-dev.com%2Fself-service%2Fwizard&regSource=selfService&mode=signUp`,
1112
/**
1213
* URL of Topcoder Connect Website
1314
*/

config/prod.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
11
module.exports = {
2+
TC_DOMAIN: 'topcoder.com',
23
/**
34
* URL of Topcoder Community Website
45
*/
56
TOPCODER_COMMUNITY_WEBSITE_URL: "https://topcoder.com",
67
TERMS_URL:
78
"https://www.topcoder.com/challenges/terms/detail/564a981e-6840-4a5c-894e-d5ad22e9cd6f",
89
PRIVACY_POLICY_URL: "https://www.topcoder.com/policy",
9-
SIGN_IN_URL: `https://accounts-auth0.topcoder.com/?retUrl=https%3A%2F%2Fplatform-ui.topcoder.com%2Fself-service%2Fwizard&regSource=selfService`,
10-
SIGN_UP_URL: `https://accounts-auth0.topcoder.com/?retUrl=https%3A%2F%2Fplatform-ui.topcoder.com%2Fself-service%2Fwizard&regSource=selfService&mode=signUp`,
10+
SIGN_IN_URL: `https://accounts-auth0.topcoder.com/?retUrl=https%3A%2F%2Fwork.topcoder.com%2Fself-service%2Fwizard&regSource=selfService`,
11+
SIGN_UP_URL: `https://accounts-auth0.topcoder.com/?retUrl=https%3A%2F%2Fwork.topcoder.com%2Fself-service%2Fwizard&regSource=selfService&mode=signUp`,
1112

1213
/**
1314
* URL of Topcoder Connect Website

src-ts/config/constants.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,10 @@
1+
export enum AppSubdomain {
2+
dev = 'devcenter',
3+
game = 'gamification-admin',
4+
tca = 'academy',
5+
work = 'work',
6+
}
7+
18
export enum ToolTitle {
29
dev = 'Dev Center',
310
game = 'Gamification Admin',

src-ts/config/environments/environment-config.model.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,6 @@ import { AppHostEnvironmentType } from './app-host-environment.type'
55
export interface EnvironmentConfigModel extends GlobalConfig {
66
// override the ENV var to require that it's defined in the type
77
ENV: AppHostEnvironmentType,
8+
9+
SUBDOMAIN: string,
810
}

src-ts/config/environments/environment.default.config.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ export const EnvironmentConfigDefault: EnvironmentConfigModel = {
2525
SERVICE: 'platform-ui',
2626
},
2727
MEMBER_VERIFY_LOOKER: 3322,
28+
REACT_APP_ENABLE_EMSI_SKILLS: process.env.REACT_APP_ENABLE_EMSI_SKILLS as unknown as boolean || false,
2829
REACT_APP_ENABLE_TCA_CERT_MONETIZATION: process.env.REACT_APP_ENABLE_TCA_CERT_MONETIZATION as unknown as boolean || false,
2930
REAUTH_OFFSET: 55,
3031
SPRIG: {
@@ -39,6 +40,7 @@ export const EnvironmentConfigDefault: EnvironmentConfigModel = {
3940
CUSTOMER_TOKEN:
4041
'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJyb2xlcyI6WyJUb3Bjb2RlciBVc2VyIl0sImlzcyI6Imh0dHBzOi8vYXBpLnRvcGNvZGVyLWRldi5jb20iLCJoYW5kbGUiOiJ0ZXN0MSIsImV4cCI6MjU2MzA3NjY4OSwidXNlcklkIjoiNDAwNTEzMzMiLCJpYXQiOjE0NjMwNzYwODksImVtYWlsIjoidGVzdEB0b3Bjb2Rlci5jb20iLCJqdGkiOiJiMzNiNzdjZC1iNTJlLTQwZmUtODM3ZS1iZWI4ZTBhZTZhNGEifQ.jl6Lp_friVNwEP8nfsfmL-vrQFzOFp2IfM_HC7AwGcg',
4142
},
43+
SUBDOMAIN: window.location.hostname.split('.')[0],
4244
TOPCODER_URLS: {
4345
ACCOUNT_PROFILE: `${COMMUNITY_WEBSITE}/settings/profile`,
4446
ACCOUNT_SETTINGS: `${COMMUNITY_WEBSITE}/settings/account`,

src-ts/lib/breadcrumb/breadcrumb-item/BreadcrumbItem.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ const BreadcrumbItem: FC<BreadcrumbItemProps> = (props: BreadcrumbItemProps) =>
2626
<Link
2727
className={classNames(props.item.isElipsis && styles.elipsis)}
2828
to={props.item.url}
29+
state={props.item.state}
2930
>
3031
{props.item.name}
3132
</Link>

src-ts/lib/breadcrumb/breadcrumb-item/breadcrumb-item.model.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,5 @@ export interface BreadcrumbItemModel {
33
name: string
44
onClick?: (item: BreadcrumbItemModel) => void
55
url: string
6+
state?: any
67
}

src-ts/lib/global-config.model.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,4 +46,5 @@ export interface GlobalConfig {
4646
}
4747
MEMBER_VERIFY_LOOKER: number,
4848
REACT_APP_ENABLE_TCA_CERT_MONETIZATION: boolean
49+
REACT_APP_ENABLE_EMSI_SKILLS: boolean
4950
}

src-ts/lib/route-provider/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,4 @@ export * from './route-context-data.model'
44
export { default as routeContext } from './route.context'
55
export * from './route.provider'
66
export * from './router.utils'
7+
export * from './rewrite'

src-ts/lib/route-provider/platform-route.model.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
export interface PlatformRoute {
2+
domain?: string
23
alternativePaths?: Array<string>
34
authRequired?: boolean
45
children?: Array<PlatformRoute>

src-ts/lib/route-provider/rewrite.tsx

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import { get } from 'lodash'
2+
import { FC } from 'react'
3+
import { Navigate, Params, useParams } from 'react-router-dom'
4+
5+
export interface RewriteProps {
6+
to: string
7+
}
8+
9+
/**
10+
* Extends react-router-dom Navigate component to support rewriting of urls
11+
* Eg. or rewrite rules:
12+
* - /learn/* -> /* (redirects all learn pages to root)
13+
*/
14+
export const Rewrite: FC<RewriteProps> = props => {
15+
const params: Params = useParams()
16+
const rewriteTo: string = props.to.replace(
17+
/(:[a-z0-9*]+)|\*/ig,
18+
(match: string) => get(params, match.replace(':', ''), ''),
19+
)
20+
21+
return (
22+
<Navigate to={`${rewriteTo}${window.location.search}`} />
23+
)
24+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
export {
22
getActive as routeGetActive,
33
getSignupUrl as routeGetSignupUrl,
4+
matchAppRouter as routeMatchAppRouter,
45
} from './route.functions'

src-ts/lib/route-provider/route-functions/route.functions.ts

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,10 @@ import {
55
} from '../../functions'
66
import { PlatformRoute } from '../platform-route.model'
77

8-
export function getActive(currentLocation: string, toolRoutes: Array<PlatformRoute>): PlatformRoute | undefined {
8+
export function getActive(
9+
currentLocation: string,
10+
toolRoutes: Array<PlatformRoute>,
11+
): PlatformRoute | undefined {
912
return toolRoutes.find(tool => isActiveTool(currentLocation, tool))
1013
}
1114

@@ -33,3 +36,10 @@ function isActiveTool(activePath: string, toolRoute: PlatformRoute): boolean {
3336
return !!activePath.startsWith(toolRoute.route)
3437
|| !!toolRoute.alternativePaths?.some(path => activePath.startsWith(path))
3538
}
39+
40+
export function matchAppRouter(
41+
activeDomain: string | undefined,
42+
toolsRoutes: Array<PlatformRoute>,
43+
): PlatformRoute | undefined {
44+
return !activeDomain ? undefined : toolsRoutes.find(toolRoutes => activeDomain === toolRoutes.domain)
45+
}

src-ts/lib/route-provider/route.provider.tsx

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,12 @@ import { Location, Route, useLocation } from 'react-router-dom'
1414
import { authUrlLogin } from '../functions'
1515
import { LoadingSpinner } from '../loading-spinner'
1616
import { profileContext, ProfileContextData } from '../profile-provider'
17+
import { EnvironmentConfig } from '../../config'
1718

1819
import { PlatformRoute } from './platform-route.model'
1920
import { RequireAuthProvider } from './require-auth-provider'
2021
import { RouteContextData } from './route-context-data.model'
21-
import { routeGetActive, routeGetSignupUrl } from './route-functions'
22+
import { routeGetActive, routeGetSignupUrl, routeMatchAppRouter } from './route-functions'
2223
import { default as routeContext, defaultRouteContextData } from './route.context'
2324

2425
interface RouteProviderProps {
@@ -53,7 +54,13 @@ export const RouteProvider: FC<RouteProviderProps> = (props: RouteProviderProps)
5354
...utilsRoutes,
5455
]
5556

56-
const activeRoute: PlatformRoute | undefined = routeGetActive(location.pathname, allRoutes)
57+
let activeRoute: PlatformRoute | undefined = routeGetActive(location.pathname, allRoutes)
58+
const matchedAppRouter: PlatformRoute | undefined = routeMatchAppRouter(EnvironmentConfig.SUBDOMAIN, allRoutes)
59+
60+
if (matchedAppRouter) {
61+
allRoutes = [matchedAppRouter]
62+
activeRoute = matchedAppRouter
63+
}
5764

5865
// TODO: support additional roles and landing pages
5966
const loggedInRoot: string = !profile

src-ts/tools/dev-center/dev-center-pages/community-app/getting-started/GettingStartedGuide.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import * as React from 'react'
22

33
import { Breadcrumb, BreadcrumbItemModel, ContentLayout } from '../../../../../lib'
4-
import { toolTitle } from '../../../dev-center.routes'
4+
import { rootRoute, toolTitle } from '../../../dev-center.routes'
55
import { LayoutDocHeader, MarkdownDoc } from '../../../dev-center-lib/MarkdownDoc'
66
import useMarkdown from '../../../dev-center-lib/hooks/useMarkdown'
77

@@ -11,7 +11,7 @@ import styles from './GettingStartedGuide.module.scss'
1111
export const GettingStartedGuide: React.FC = () => {
1212
const { doc, toc, title }: ReturnType<typeof useMarkdown> = useMarkdown({ uri: gettingStartedGuide })
1313
const breadcrumb: Array<BreadcrumbItemModel> = React.useMemo(() => [
14-
{ name: toolTitle, url: '/dev-center' },
14+
{ name: toolTitle, url: rootRoute || '/' },
1515
{ name: title, url: '#' },
1616
], [title])
1717

src-ts/tools/dev-center/dev-center-pages/community-app/landing-page/dev-center-get-started/GetStartedCardsContainer/GetStartedCardsContainer.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { FC } from 'react'
33
import { Button } from '../../../../../../../lib'
44
import { ApiCornerIcon, ApiIcon, CommunityAppCornerIcon, CommunityAppIcon } from '../../../../../assets/i'
55
import { DevCenterCard } from '../../dev-center-card'
6+
import { rootRoute } from '../../../../../dev-center.routes'
67

78
import styles from './GetStartedCardsContainer.module.scss'
89

@@ -14,7 +15,7 @@ const GetStartedCardsContainer: FC = () => (
1415
title='Community App'
1516
titleClass={styles.communityTitle}
1617
description='Learn about Topcoder Community App and run started code.'
17-
button={<Button route='/dev-center/getting-started' label='get started' className={styles.button} />}
18+
button={<Button route={`${rootRoute}/getting-started`} label='get started' className={styles.button} />}
1819
/>
1920
<DevCenterCard
2021
cornerIcon={<ApiCornerIcon />}

src-ts/tools/dev-center/dev-center.routes.tsx

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { ToolTitle } from '../../config'
1+
import { AppSubdomain, EnvironmentConfig, ToolTitle } from '../../config'
22
import { lazyLoad, LazyLoadedComponent, PlatformRoute } from '../../lib'
33

44
const GettingStartedGuide: LazyLoadedComponent
@@ -9,6 +9,7 @@ const DevCenterLandingPage: LazyLoadedComponent
99

1010
const DevCenter: LazyLoadedComponent = lazyLoad(() => import('./DevCenter'))
1111

12+
export const rootRoute: string = EnvironmentConfig.SUBDOMAIN === AppSubdomain.dev ? '' : `/${AppSubdomain.dev}`
1213
export const toolTitle: string = ToolTitle.dev
1314

1415
export const devCenterRoutes: ReadonlyArray<PlatformRoute> = [
@@ -23,8 +24,9 @@ export const devCenterRoutes: ReadonlyArray<PlatformRoute> = [
2324
route: '/',
2425
},
2526
],
27+
domain: 'devcenter',
2628
element: <DevCenter />,
2729
id: toolTitle,
28-
route: '/dev-center',
30+
route: rootRoute,
2931
},
3032
]

src-ts/tools/gamification-admin/game-lib/hooks/use-gamification-breadcrumb.hook.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
import { BreadcrumbItemModel } from '../../../../lib'
2-
import { basePath } from '../../gamification-admin.routes'
32
import { toolTitle } from '../../GamificationAdmin'
3+
import { rootRoute } from '../../gamification-admin.routes'
44

55
export function useGamificationBreadcrumb(items: Array<BreadcrumbItemModel>): Array<BreadcrumbItemModel> {
66

77
const breadcrumb: Array<BreadcrumbItemModel> = [
88
{
99
name: toolTitle,
10-
url: basePath,
10+
url: rootRoute || '/',
1111
},
1212
...items,
1313
]

src-ts/tools/gamification-admin/gamification-admin.routes.tsx

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { AppSubdomain, EnvironmentConfig } from '../../config'
12
import { lazyLoad, LazyLoadedComponent, PlatformRoute, UserRole } from '../../lib'
23

34
import { toolTitle } from './GamificationAdmin'
@@ -7,16 +8,15 @@ const BadgeDetailPage: LazyLoadedComponent = lazyLoad(() => import('./pages/badg
78
const BadgeListingPage: LazyLoadedComponent = lazyLoad(() => import('./pages/badge-listing/BadgeListingPage'))
89
const CreateBadgePage: LazyLoadedComponent = lazyLoad(() => import('./pages/create-badge/CreateBadgePage'))
910

11+
export const rootRoute: string = EnvironmentConfig.SUBDOMAIN === AppSubdomain.game ? '' : `/${AppSubdomain.game}`
1012
export const baseDetailPath: string = '/badge-detail'
1113
export const createBadgePath: string = '/create-badge'
1214

13-
export const basePath: string = '/gamification-admin'
14-
1515
export function badgeDetailPath(badgeId: string, view?: 'edit' | 'award'): string {
16-
return `${basePath}${baseDetailPath}/${badgeId}${!!view ? `#${view}` : ''}`
16+
return `${rootRoute}${baseDetailPath}/${badgeId}${!!view ? `#${view}` : ''}`
1717
}
1818

19-
export const createBadgeRoute: string = `${basePath}${createBadgePath}`
19+
export const createBadgeRoute: string = `${rootRoute}${createBadgePath}`
2020

2121
export const gamificationAdminRoutes: ReadonlyArray<PlatformRoute> = [
2222
{
@@ -35,12 +35,13 @@ export const gamificationAdminRoutes: ReadonlyArray<PlatformRoute> = [
3535
route: `${baseDetailPath}/:id`,
3636
},
3737
],
38+
domain: AppSubdomain.game,
3839
element: <GamificationAdmin />,
3940
hidden: true,
4041
id: toolTitle,
4142
rolesRequired: [
4243
UserRole.gamificationAdmin,
4344
],
44-
route: basePath,
45+
route: rootRoute,
4546
},
4647
]

src-ts/tools/gamification-admin/pages/create-badge/create-badge-form/create-badge-form.config.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { noop } from 'lodash'
22

33
import { FormDefinition, IconOutline, validatorRequired } from '../../../../../lib'
44
import { GamificationConfig } from '../../../game-config'
5+
import { rootRoute } from '../../../gamification-admin.routes'
56

67
export enum CreateBadgeFormField {
78
badgeActive = 'badgeActive',
@@ -26,7 +27,7 @@ export const createBadgeFormDef: FormDefinition = {
2627
{
2728
buttonStyle: 'icon-bordered',
2829
icon: IconOutline.ChevronLeftIcon,
29-
route: '/gamification-admin',
30+
route: rootRoute || '/',
3031
size: 'lg',
3132
},
3233
],

src-ts/tools/learn/certification-details/certification-curriculum/curriculum-cards/course-card/CourseCard.tsx

Lines changed: 14 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { FC, ReactNode } from 'react'
22

3-
import { Button, IconSolid, ProgressBar } from '../../../../../../lib'
3+
import { BreadcrumbItemModel, Button, IconSolid, ProgressBar } from '../../../../../../lib'
44
import {
55
clearFCCCertificationTitle,
66
CompletionTimeRange,
@@ -20,6 +20,7 @@ import {
2020
getCertificatePath,
2121
getCoursePath,
2222
getLessonPathFromCurrentLesson,
23+
getTCACertificationPath,
2324
} from '../../../../learn.routes'
2425
import CurriculumCard from '../CurriculumCard'
2526

@@ -36,7 +37,16 @@ interface CourseCardProps {
3637
}
3738

3839
const CourseCard: FC<CourseCardProps> = (props: CourseCardProps) => {
40+
3941
function renderCta(): ReactNode {
42+
43+
const routeState: { tcaCertInfo: BreadcrumbItemModel } = {
44+
tcaCertInfo: {
45+
name: props.tcaCertification.title,
46+
url: getTCACertificationPath(props.tcaCertification.dashedName),
47+
},
48+
}
49+
4050
switch (props.progress?.status) {
4151
case UserCertificationProgressStatus.completed:
4252
return (
@@ -49,12 +59,7 @@ const CourseCard: FC<CourseCardProps> = (props: CourseCardProps) => {
4959
props.provider,
5060
props.certification.certification,
5161
)}
52-
routeState={{
53-
tcaCertInfo: {
54-
dashedName: props.tcaCertification.dashedName,
55-
title: props.tcaCertification.title,
56-
},
57-
}}
62+
routeState={routeState}
5863
/>
5964
<Button
6065
buttonStyle='primary'
@@ -78,12 +83,7 @@ const CourseCard: FC<CourseCardProps> = (props: CourseCardProps) => {
7883
props.certification.certification,
7984
props.progress?.currentLesson,
8085
)}
81-
routeState={{
82-
tcaCertInfo: {
83-
dashedName: props.tcaCertification.dashedName,
84-
title: props.tcaCertification.title,
85-
},
86-
}}
86+
routeState={routeState}
8787
/>
8888
)
8989
default:
@@ -96,12 +96,7 @@ const CourseCard: FC<CourseCardProps> = (props: CourseCardProps) => {
9696
props.provider,
9797
props.certification.certification,
9898
)}
99-
routeState={{
100-
tcaCertInfo: {
101-
dashedName: props.tcaCertification.dashedName,
102-
title: props.tcaCertification.title,
103-
},
104-
}}
99+
routeState={routeState}
105100
/>
106101
)
107102
}

0 commit comments

Comments
 (0)