Skip to content

Commit 6425c9f

Browse files
PROD-3245 #comment This commit removes the customer- and member-specific top nav. It also adds IDs to the routes so we can ID them separately from the title and the titles don't need to be unique. Finally, it sets the self-service tool to use the same tool name for all its pages. #time 2h
1 parent c3d60e2 commit 6425c9f

File tree

21 files changed

+78
-106
lines changed

21 files changed

+78
-106
lines changed

src-ts/config/constants.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,9 @@ export enum ToolTitle {
22
dev = 'Dev Center',
33
game = 'Gamification Admin',
44
settings = 'Account Settings',
5+
support = 'Support',
56
tca = 'Topcoder Academy',
6-
work = 'Self-Service',
7+
work = 'Self-Service Challenges',
78
}
89

910
export const PageSubheaderPortalId: string = 'page-subheader-portal-el'

src-ts/lib/functions/authentication-functions/authentication.functions.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ export function getRegistrationSource(
2626
activeTool: PlatformRoute | undefined,
2727
): AuthenticationRegistrationSource | undefined {
2828

29-
switch (activeTool?.title) {
29+
switch (activeTool?.id) {
3030

3131
// currently, there is no reg source for members
3232
case ToolTitle.tca:

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

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,10 @@ export interface PlatformRoute {
22
alternativePaths?: Array<string>
33
authRequired?: boolean
44
children?: Array<PlatformRoute>
5-
customerOnly?: boolean
65
disabled?: boolean
76
element: JSX.Element
87
hidden?: boolean
9-
memberOnly?: boolean
8+
id?: string
109
rolesRequired?: Array<string>
1110
route: string
1211
title?: string

src-ts/lib/route-provider/route-context-data.model.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ export interface RouteContextData {
88
allRoutes: Array<PlatformRoute>
99
getChildren: (parent: string) => Array<PlatformRoute>
1010
getChildRoutes: (parent: string) => Array<ReactElement>
11-
getPath: (routeTitle: string) => string
1211
getPathFromRoute: (route: PlatformRoute) => string
1312
getRouteElement: (route: PlatformRoute) => JSX.Element
1413
getSignupUrl: (currentLocation: string, toolRoutes: Array<PlatformRoute>, returnUrl?: string) => string
@@ -17,6 +16,5 @@ export interface RouteContextData {
1716
rootLoggedInRoute: string
1817
rootLoggedOutFC: FC<{}>
1918
toolsRoutes: Array<PlatformRoute>
20-
toolsRoutesForNav: Array<PlatformRoute>
2119
utilsRoutes: Array<PlatformRoute>
2220
}
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
export {
2+
getActive as routeGetActive,
23
getSignupUrl as routeGetSignupUrl,
3-
isActiveTool as routeIsActiveTool,
44
} from './route.functions'

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

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +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 {
9+
return toolRoutes.find(tool => isActiveTool(currentLocation, tool))
10+
}
11+
812
// NOTE: this function ties together routes and auth,
913
// so one could make an argument that it should be
1014
// part of the auth functions and be provided by the
@@ -18,14 +22,14 @@ export function getSignupUrl(
1822
): string {
1923

2024
// figure out the current tool so we can assign the correct reg source
21-
const activeTool: PlatformRoute | undefined = toolRoutes.find(tool => isActiveTool(currentLocation, tool))
25+
const activeTool: PlatformRoute | undefined = getActive(currentLocation, toolRoutes)
2226
const regSource: AuthenticationRegistrationSource | undefined
2327
= authGetRegistrationSource(activeTool)
2428

2529
return authUrlSignup(returnUrl, regSource)
2630
}
2731

28-
export function isActiveTool(activePath: string, toolRoute: PlatformRoute): boolean {
32+
function isActiveTool(activePath: string, toolRoute: PlatformRoute): boolean {
2933
return !!activePath.startsWith(toolRoute.route)
3034
|| !!toolRoute.alternativePaths?.some(path => activePath.startsWith(path))
3135
}

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

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,8 @@ import { RouteContextData } from './route-context-data.model'
44

55
export const defaultRouteContextData: RouteContextData = {
66
allRoutes: [],
7-
getChildRoutes: () => [],
87
getChildren: () => [],
9-
getPath: () => '',
8+
getChildRoutes: () => [],
109
getPathFromRoute: () => '',
1110
getRouteElement: () => <></>,
1211
getSignupUrl: () => '',
@@ -15,7 +14,6 @@ export const defaultRouteContextData: RouteContextData = {
1514
rootLoggedInRoute: '',
1615
rootLoggedOutFC: () => <></>,
1716
toolsRoutes: [],
18-
toolsRoutesForNav: [],
1917
utilsRoutes: [],
2018
}
2119

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

Lines changed: 6 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ import { profileContext, ProfileContextData } from '../profile-provider'
1818
import { PlatformRoute } from './platform-route.model'
1919
import { RequireAuthProvider } from './require-auth-provider'
2020
import { RouteContextData } from './route-context-data.model'
21-
import { routeGetSignupUrl, routeIsActiveTool } from './route-functions'
21+
import { routeGetActive, routeGetSignupUrl } from './route-functions'
2222
import { default as routeContext, defaultRouteContextData } from './route.context'
2323

2424
interface RouteProviderProps {
@@ -47,39 +47,14 @@ export const RouteProvider: FC<RouteProviderProps> = (props: RouteProviderProps)
4747
// TODO: try to make these prop names configurable instead of hard-codded
4848
const toolsRoutes: Array<PlatformRoute> = props.toolsRoutes.filter(route => !route.disabled)
4949

50-
// display a tool in the nav if the following conditions are met:
51-
// 1. the tool has a title
52-
// 2. the tool isn't hidden (if the tool is hidden, it should never appear in the nav)
53-
// AND
54-
// 3. the tool is one of the following:
55-
// a. for customers and the user is a customer
56-
// b. for members and the user is a member
57-
// c. the active tool in the app (in case someone deep-links to it)
58-
let activeRoute: PlatformRoute | undefined
59-
const toolsRoutesForNav: Array<PlatformRoute> = toolsRoutes
60-
.filter(route => {
61-
62-
const isActive: boolean = routeIsActiveTool(location.pathname, route)
63-
if (isActive) {
64-
activeRoute = route
65-
}
66-
67-
return !!route.title
68-
&& !route.hidden
69-
&& (
70-
(
71-
(!route.customerOnly || !!profile?.isCustomer)
72-
&& (!route.memberOnly || !!profile?.isMember)
73-
)
74-
|| isActive
75-
)
76-
})
77-
7850
const utilsRoutes: Array<PlatformRoute> = props.utilsRoutes.filter(route => !route.disabled)
7951
allRoutes = [
8052
...toolsRoutes,
8153
...utilsRoutes,
8254
]
55+
56+
const activeRoute: PlatformRoute | undefined = routeGetActive(location.pathname, allRoutes)
57+
8358
// TODO: support additional roles and landing pages
8459
const loggedInRoot: string = !profile
8560
? ''
@@ -88,12 +63,11 @@ export const RouteProvider: FC<RouteProviderProps> = (props: RouteProviderProps)
8863
: props.rootMember
8964

9065
const contextData: RouteContextData = {
91-
activeToolName: activeRoute?.title,
66+
activeToolName: activeRoute?.title || activeRoute?.id,
9267
activeToolRoute: !!activeRoute ? `https://${window.location.hostname}${activeRoute.route}` : undefined,
9368
allRoutes,
9469
getChildren,
9570
getChildRoutes,
96-
getPath,
9771
getPathFromRoute,
9872
getRouteElement,
9973
getSignupUrl: routeGetSignupUrl,
@@ -102,15 +76,14 @@ export const RouteProvider: FC<RouteProviderProps> = (props: RouteProviderProps)
10276
rootLoggedInRoute: loggedInRoot,
10377
rootLoggedOutFC: props.rootLoggedOutFC,
10478
toolsRoutes,
105-
toolsRoutesForNav,
10679
utilsRoutes,
10780
}
10881
setRouteContextData(contextData)
10982
}
11083

11184
function getChildren(parent: string): Array<PlatformRoute> {
11285
return allRoutes
113-
.find(route => route.title === parent)
86+
.find(route => route.id === parent)
11487
?.children
11588
|| []
11689
}
@@ -120,12 +93,6 @@ export const RouteProvider: FC<RouteProviderProps> = (props: RouteProviderProps)
12093
.map(route => getRouteElement(route))
12194
}
12295

123-
function getPath(routeTitle: string): string {
124-
const platformRoute: PlatformRoute = allRoutes.find(route => route.title === routeTitle) as PlatformRoute
125-
// if the path has a trailing asterisk, remove it
126-
return getPathFromRoute(platformRoute)
127-
}
128-
12996
function getPathFromRoute(route: PlatformRoute): string {
13097
return route.route.replace('/*', '')
13198
}

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

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ const DevCenter: LazyLoadedComponent = lazyLoad(() => import('./DevCenter'))
1111

1212
export const toolTitle: string = ToolTitle.dev
1313

14-
export const devCenterRoutes: Array<PlatformRoute> = [
14+
export const devCenterRoutes: ReadonlyArray<PlatformRoute> = [
1515
{
1616
children: [
1717
{
@@ -24,8 +24,7 @@ export const devCenterRoutes: Array<PlatformRoute> = [
2424
},
2525
],
2626
element: <DevCenter />,
27-
memberOnly: true,
27+
id: toolTitle,
2828
route: '/dev-center',
29-
title: toolTitle,
3029
},
3130
]

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ export function badgeDetailPath(badgeId: string, view?: 'edit' | 'award'): strin
1818

1919
export const createBadgeRoute: string = `${basePath}${createBadgePath}`
2020

21-
export const gamificationAdminRoutes: Array<PlatformRoute> = [
21+
export const gamificationAdminRoutes: ReadonlyArray<PlatformRoute> = [
2222
{
2323
authRequired: true,
2424
children: [
@@ -37,10 +37,10 @@ export const gamificationAdminRoutes: Array<PlatformRoute> = [
3737
],
3838
element: <GamificationAdmin />,
3939
hidden: true,
40+
id: toolTitle,
4041
rolesRequired: [
4142
UserRole.gamificationAdmin,
4243
],
4344
route: basePath,
44-
title: toolTitle,
4545
},
4646
]

src-ts/tools/learn/learn.routes.tsx

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -82,55 +82,54 @@ export function getViewStyleParamKey(): string {
8282
return Object.keys(LearnConfig.CERT_ALT_PARAMS)[0]
8383
}
8484

85-
export const learnRoutes: Array<PlatformRoute> = [
85+
export const learnRoutes: ReadonlyArray<PlatformRoute> = [
8686
{
8787
children: [
8888
{
8989
children: [],
9090
element: <WelcomePage />,
91+
id: 'Welcome to Topcoder Academy',
9192
route: '',
92-
title: 'Welcome to Topcoder Academy',
9393
},
9494
{
9595
children: [],
9696
element: <CourseDetailsPage />,
97+
id: 'Course Details',
9798
route: ':provider/:certification',
98-
title: 'Course Details',
9999
},
100100
{
101101
children: [],
102102
element: <CourseCompletedPage />,
103+
id: 'Course Completed',
103104
route: ':provider/:certification/completed',
104-
title: 'Course Completed',
105105
},
106106
{
107107
children: [],
108108
element: <MyCertificate />,
109+
id: 'My Certificate',
109110
route: ':provider/:certification/certificate',
110-
title: 'My Certificate',
111111
},
112112
{
113113
children: [],
114114
element: <UserCertificate />,
115+
id: 'User Certificate',
115116
route: ':provider/:certification/:memberHandle/certificate',
116-
title: 'User Certificate',
117117
},
118118
{
119119
children: [],
120120
element: <FreeCodeCamp />,
121+
id: 'FxreeCodeCamp',
121122
route: ':provider/:certification/:module/:lesson',
122-
title: 'FreeCodeCamp',
123123
},
124124
{
125125
children: [],
126126
element: <MyLearning />,
127+
id: 'My Learning',
127128
route: 'my-learning',
128-
title: 'My Learning',
129129
},
130130
],
131131
element: <LandingLearn />,
132-
memberOnly: true,
132+
id: toolTitle,
133133
route: rootRoute,
134-
title: toolTitle,
135134
},
136135
]

src-ts/tools/tools.routes.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,10 @@ import { gamificationAdminRoutes } from './gamification-admin'
55
import { learnRoutes } from './learn'
66
import { workRoutes } from './work'
77

8-
const toolRoutes: Array<PlatformRoute> = [
9-
// NOTE: these will be displayed in the order they are defined in this array
10-
// TODO: support ordering
8+
const toolRoutes: ReadonlyArray<PlatformRoute> = [
9+
// NOTE: Order matters here bc the active tool
10+
// is determined by finding the first route
11+
// that matches the current path
1112
...workRoutes,
1213
...devCenterRoutes,
1314
...learnRoutes,

src-ts/tools/work/Work.tsx

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
1-
import { Dispatch, FC, useContext } from 'react'
1+
import { Dispatch, FC, useCallback, useContext } from 'react'
22
import { useDispatch } from 'react-redux'
33
import { Navigate, NavigateFunction, Outlet, Routes, useNavigate } from 'react-router-dom'
4+
import { AnyAction } from 'redux'
45

56
// TODO: move this from the legacy to the nextgen app
67
import { resetIntakeForm } from '../../../src/actions/form'
@@ -23,15 +24,26 @@ import { WorkProvider } from './work-lib'
2324
import { selfServiceRootRoute, selfServiceStartRoute } from './work.routes'
2425

2526
export const toolTitle: string = ToolTitle.work
26-
export const dashboardTitle: string = `${toolTitle} Dashboard`
27+
export const dashboardRouteId: string = `${toolTitle} Dashboard`
28+
export const intakeFormsRouteId: string = `${toolTitle} Intake Forms`
2729

2830
const Work: FC<{}> = () => {
2931

3032
const { getChildRoutes }: RouteContextData = useContext(routeContext)
3133
const { profile, initialized }: ProfileContextData = useContext(profileContext)
32-
const dispatch: Dispatch<any> = useDispatch()
34+
const dispatch: Dispatch<AnyAction> = useDispatch()
3335
const navigate: NavigateFunction = useNavigate()
3436

37+
const startWork: () => void = useCallback(() => {
38+
clearCachedChallengeId()
39+
clearAutoSavedForm()
40+
dispatch(resetIntakeForm(true))
41+
navigate(selfServiceStartRoute)
42+
}, [
43+
dispatch,
44+
navigate,
45+
])
46+
3547
// if a user arrives here who is not logged in, don't let them get to the page
3648
if (!profile) {
3749

@@ -44,13 +56,6 @@ const Work: FC<{}> = () => {
4456
return <Navigate to={selfServiceRootRoute} />
4557
}
4658

47-
function startWork(): void {
48-
clearCachedChallengeId()
49-
clearAutoSavedForm()
50-
dispatch(resetIntakeForm(true))
51-
navigate(selfServiceStartRoute)
52-
}
53-
5459
const buttonConfig: ButtonProps = {
5560
label: 'Start work',
5661
onClick: startWork,
@@ -64,7 +69,7 @@ const Work: FC<{}> = () => {
6469
<WorkProvider>
6570
<Outlet />
6671
<Routes>
67-
{getChildRoutes(dashboardTitle)}
72+
{getChildRoutes(dashboardRouteId)}
6873
</Routes>
6974
</WorkProvider>
7075
</ContentLayout>

src-ts/tools/work/work-self-service/intake-forms/IntakeForms.tsx

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,7 @@ import {
66
routeContext,
77
RouteContextData,
88
} from '../../../../lib'
9-
10-
export const intakeFormsTitle: string = 'Work Intake Forms'
9+
import { intakeFormsRouteId } from '../../Work'
1110

1211
const IntakeForms: FC<{}> = () => {
1312

@@ -17,7 +16,7 @@ const IntakeForms: FC<{}> = () => {
1716
<ContentLayout>
1817
<Outlet />
1918
<Routes>
20-
{getChildRoutes(intakeFormsTitle)}
19+
{getChildRoutes(intakeFormsRouteId)}
2120
</Routes>
2221
</ContentLayout>
2322
)

0 commit comments

Comments
 (0)