Skip to content

Commit f7d8efc

Browse files
authored
Merge pull request #123 from topcoder-platform/PROD-2321_bh-carousel
BH Config & Carousel -> PROD-2321
2 parents c4d9c4e + cfafb93 commit f7d8efc

19 files changed

+13022
-12431
lines changed

src-ts/tools/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,4 +24,5 @@ export {
2424
WorkTypeCategoryDataIcon,
2525
WorkTypeCategoryDesignIcon,
2626
WorkTypeCategoryUnknownIcon,
27+
WorkTypeConfigs,
2728
} from './work'
Loading

src-ts/tools/work/work-lib/work-provider/work-context-data.model.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
import { Challenge, Work, WorkStatus } from './work-functions'
1+
import { Challenge, Work, WorkPricesType, WorkStatus } from './work-functions'
22

33
export interface WorkContextData {
4-
createFromChallenge: (challenge: Challenge) => Work
4+
createFromChallenge: (challenge: Challenge, workPrices: WorkPricesType) => Work
55
deleteWorkAsync: (id: string) => Promise<void>
66
error?: string
77
getStatusFromChallenge: (challenge: Challenge) => WorkStatus

src-ts/tools/work/work-lib/work-provider/work-functions/index.ts

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,6 @@ export {
33
workFactoryCreate,
44
workFactoryGetStatus,
55
workFactoryMapFormData,
6-
workPriceData,
7-
workPriceDesign,
8-
workPriceDesignLegacy,
9-
workPriceFindData,
10-
workPriceProblem,
116
type WorkProgress,
127
type WorkProgressStep,
138
type WorkSolution,
@@ -18,8 +13,17 @@ export {
1813
export {
1914
type Challenge,
2015
ChallengeMetadataName,
16+
workBugHuntConfig,
17+
workPriceData,
18+
workPriceDesign,
19+
workPriceDesignLegacy,
20+
workPriceFindData,
21+
workPriceProblem,
22+
WorkPrices,
2123
WorkStatusFilter,
24+
WorkTypeConfigs,
2225
} from './work-store'
26+
export type { WorkPricesType } from './work-store'
2327
export * from './work-by-status.model'
2428
export {
2529
deleteAsync as workDeleteAsync,

src-ts/tools/work/work-lib/work-provider/work-functions/work-factory/index.ts

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,3 @@
1-
export {
2-
data as workPriceData,
3-
design as workPriceDesign,
4-
designLegacy as workPriceDesignLegacy,
5-
findData as workPriceFindData,
6-
problem as workPriceProblem,
7-
} from './work-prices.config'
81
export * from './work-progress.model'
92
export * from './work-progress-step.model'
103
export * from './work-status.enum'

src-ts/tools/work/work-lib/work-provider/work-functions/work-factory/work-price.model.ts

Lines changed: 0 additions & 7 deletions
This file was deleted.

src-ts/tools/work/work-lib/work-provider/work-functions/work-factory/work-type.enum.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
export enum WorkType {
2+
bugHunt = 'Website Bug Hunt',
23
data = 'Data Exploration',
34
design = 'Website Design',
45
designLegacy = 'Website Design Legacy',

src-ts/tools/work/work-lib/work-provider/work-functions/work-factory/work.factory.ts

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,11 @@ import {
66
ChallengeMetadataName,
77
ChallengePhase,
88
ChallengePhaseName,
9+
WorkPrice,
10+
WorkPricesType,
911
} from '../work-store'
1012

1113
import { ChallengeStatus } from './challenge-status.enum'
12-
import { WorkPrice } from './work-price.model'
13-
import { WorkPrices } from './work-prices.config'
1414
import { WorkProgressStep } from './work-progress-step.model'
1515
import { WorkProgress } from './work-progress.model'
1616
import { WorkStatus } from './work-status.enum'
@@ -38,14 +38,15 @@ interface IntakeForm {
3838
}
3939
}
4040

41-
export function create(challenge: Challenge): Work {
41+
export function create(challenge: Challenge, workPrices: WorkPricesType): Work {
4242

4343
const status: WorkStatus = getStatus(challenge)
4444
const submittedDate: Date | undefined = getSubmittedDate(challenge)
4545
const type: WorkType = getType(challenge)
46+
const priceConfig: WorkPrice = workPrices[type]
4647

4748
return {
48-
cost: getCost(challenge, type),
49+
cost: getCost(challenge, priceConfig, type),
4950
created: submittedDate,
5051
description: getDescription(challenge, type),
5152
id: challenge.id,
@@ -254,15 +255,8 @@ function findPhase(challenge: Challenge, phases: Array<string>): ChallengePhase
254255
return phase
255256
}
256257

257-
// the switch statement shouldn't count against cyclomatic complexity
258-
// tslint:disable-next-line: cyclomatic-complexity
259-
function getCost(challenge: Challenge, type: WorkType): number | undefined {
258+
function getCost(challenge: Challenge, priceConfig: WorkPrice, type: WorkType): number | undefined {
260259

261-
function getCountFromString(raw: string | undefined): number {
262-
return Number(raw?.split(' ')?.[0] || '0')
263-
}
264-
265-
const priceConfig: WorkPrice = WorkPrices[type]
266260
switch (type) {
267261

268262
case WorkType.designLegacy:

src-ts/tools/work/work-lib/work-provider/work-functions/work-store/index.ts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,25 @@ export * from './challenge-metadata.model'
33
export * from './challenge-phase'
44
export * from './challenge-phase-name.enum'
55
export * from './challenge.model'
6+
export * from './work-price.model'
7+
export {
8+
bugHunt as workPriceBugHunt,
9+
data as workPriceData,
10+
design as workPriceDesign,
11+
designLegacy as workPriceDesignLegacy,
12+
findData as workPriceFindData,
13+
problem as workPriceProblem,
14+
WorkPrices
15+
} from './work-prices.config'
16+
export type { WorkPricesType } from './work-prices.config'
617
export * from './work-status-filter.enum'
718
export {
819
deleteAsync as workStoreDeleteAsync,
920
getAsync as workStoreGetAsync,
1021
getFilteredByStatus as workStoreGetFilteredByStatus,
1122
} from './work-store.functions'
23+
export {
24+
bugHuntConfig as workBugHuntConfig,
25+
WorkTypeConfigs
26+
} from './work-type.config'
27+
export * from './work-type.model'
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import { WorkType } from '../work-factory'
2+
3+
export const WorkIntakeFormRoutes: { [workType: string]: ReadonlyArray<string> } = {
4+
// TODO: determine URL for Bug Hunt and if the following "/self-service" routes
5+
// can be deleted. Not sure if they correspond to the currentStep
6+
[WorkType.bugHunt]: [
7+
'/self-service/wizard',
8+
'/self-service/work/new/bug-hunt/basic-info',
9+
'/self-service',
10+
'/self-service',
11+
'/self-service/work/new/bug-hunt/login-prompt',
12+
'/self-service',
13+
'/self-service/work/new/bug-hunt/review',
14+
'/self-service/work/new/bug-hunt/thank-you',
15+
],
16+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
export interface WorkPrice {
2+
base: number,
3+
getPrice: (price: WorkPrice, pageCount?: number, deviceCount?: number) => number,
4+
payments?: {
5+
base?: {
6+
prizes: ReadonlyArray<number>,
7+
reviewers: ReadonlyArray<number>,
8+
},
9+
promo?: {
10+
prizes: ReadonlyArray<number>,
11+
reviewers: ReadonlyArray<number>,
12+
},
13+
},
14+
perPage?: number,
15+
promo?: number,
16+
usePromo?: boolean,
17+
}

src-ts/tools/work/work-lib/work-provider/work-functions/work-factory/work-prices.config.ts renamed to src-ts/tools/work/work-lib/work-provider/work-functions/work-store/work-prices.config.ts

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,25 @@
1+
import { WorkType } from '../work-factory'
2+
13
import { WorkPrice } from './work-price.model'
2-
import { WorkType } from './work-type.enum'
34

45
export const WorkPrices: { [workType: string]: WorkPrice } = {
6+
// TODO: modify payments specific to bug hunt
7+
[WorkType.bugHunt]: {
8+
base: 2,
9+
getPrice: getPriceDefault,
10+
payments: {
11+
base: {
12+
prizes: [0.2609, 0.2174, 0.1304],
13+
reviewers: [0.0435, 0.0435],
14+
},
15+
promo: {
16+
prizes: [0.348, 0.29, 0.174],
17+
reviewers: [0.058, 0.058],
18+
},
19+
},
20+
promo: 1,
21+
usePromo: true,
22+
},
523
[WorkType.data]: {
624
base: 799,
725
getPrice: getPriceDefault,
@@ -41,6 +59,9 @@ export const WorkPrices: { [workType: string]: WorkPrice } = {
4159
},
4260
}
4361

62+
export type WorkPricesType = typeof WorkPrices
63+
64+
export const bugHunt: WorkPrice = WorkPrices[WorkType.bugHunt]
4465
export const data: WorkPrice = WorkPrices[WorkType.data]
4566
export const design: WorkPrice = WorkPrices[WorkType.design]
4667
export const designLegacy: WorkPrice = WorkPrices[WorkType.designLegacy]
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
export interface WorkTimeline {
2+
duration: number,
3+
phaseId: string,
4+
}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
import { WorkType } from '../work-factory'
2+
3+
import { WorkTimeline } from './work-timeline.model'
4+
5+
export const WorkTimelines: { [workType: string]: ReadonlyArray<WorkTimeline> } = {
6+
// TODO: Determine actual timeline for Bug Hunt
7+
[WorkType.bugHunt]: [
8+
{
9+
// Registration
10+
duration: 259200, // 3 days
11+
phaseId: 'a93544bc-c165-4af4-b55e-18f3593b457a',
12+
},
13+
{
14+
// Submission
15+
duration: 259200, // 3 days
16+
phaseId: '6950164f-3c5e-4bdc-abc8-22aaf5a1bd49',
17+
},
18+
{
19+
// Review
20+
duration: 86400, // 1 day
21+
phaseId: 'aa5a3f78-79e0-4bf7-93ff-b11e8f5b398b',
22+
},
23+
{
24+
// Appeals
25+
duration: 86400, // 1 day
26+
phaseId: '1c24cfb3-5b0a-4dbd-b6bd-4b0dff5349c6',
27+
},
28+
{
29+
// Appeals response
30+
duration: 259200, // 3 days
31+
phaseId: '797a6af7-cd3f-4436-9fca-9679f773bee9',
32+
},
33+
],
34+
}
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
import imgBugHunt from '../../../work-images/bug-hunt-main.jpeg'
2+
import { WorkType } from '../work-factory'
3+
4+
import { WorkIntakeFormRoutes } from './work-intake-form-routes.config'
5+
import { bugHunt as workPriceBugHunt } from './work-prices.config'
6+
import { WorkTimelines } from './work-timelines.config'
7+
import { WorkTypeConfig } from './work-type.model'
8+
9+
export const WorkTypeConfigs: { [workType: string]: WorkTypeConfig } = {
10+
// TODO: Verify timelineTemplateId, trackId, typeId
11+
[WorkType.bugHunt]: {
12+
about: `Our Website Bug Hunt services remove the burden of testing from you and your teams and provide detailed results quickly.
13+
Topcoder has conducted hundreds bug hunts for customers like you. For each bug hunt, we average between 25 and 150 bug hunters,
14+
and we typically find a significant number bugs which helps improve quality of your site. The Bug Hunt will start with a
15+
registration period, where experienced quality assurance engineers signup to register for the bug hunt. After the registration
16+
period completes, we will run the bug hunt for the time which meets the option you choose below.`,
17+
bgImage: imgBugHunt,
18+
description: 'This is Bug Hunt description',
19+
// TODO: The duration will be based on the package the user selects
20+
duration: 2,
21+
featured: true,
22+
intakeFormRoutes: WorkIntakeFormRoutes[WorkType.bugHunt],
23+
results: `You will receive thorough testing of your website, and at the conclusion will be provided
24+
a detailed report of bugs which have steps to reproduce, screenshots / videos if applicable,
25+
details of the bug, and severity of the issue.`,
26+
shortDescription: 'Find bugs quickly and vigorously',
27+
startRoute: WorkIntakeFormRoutes[WorkType.bugHunt][1],
28+
subtitle: `Conduct a time based testing bug hunt where Topcoder experts scramble to find bugs or issues in the system`,
29+
timeline: WorkTimelines[WorkType.bugHunt],
30+
timelineTemplateId: '7ebf1c69-f62f-4d3a-bdfb-fe9ddb56861c', // Default Challenge
31+
title: WorkType.bugHunt,
32+
trackId: '36e6a8d0-7e1e-4608-a673-64279d99c115', // QA
33+
type: WorkType.bugHunt,
34+
typeId: '927abff4-7af9-4145-8ba1-577c16e64e2e', // Challenge
35+
...workPriceBugHunt,
36+
// TODO: do we need to include breadcrumbs here?
37+
},
38+
}
39+
40+
export const bugHuntConfig: WorkTypeConfig = WorkTypeConfigs[WorkType.bugHunt]
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import { WorkType } from '../work-factory'
2+
3+
import { WorkPrice } from './work-price.model'
4+
import { WorkTimeline } from './work-timeline.model'
5+
6+
export interface WorkTypeConfig extends WorkPrice {
7+
about: string,
8+
bgImage: string,
9+
description: string,
10+
duration: number,
11+
featured: boolean,
12+
intakeFormRoutes: ReadonlyArray<string>
13+
results: string,
14+
shortDescription: string,
15+
startRoute: string,
16+
subtitle: string,
17+
timeline: ReadonlyArray<WorkTimeline>
18+
timelineTemplateId: string,
19+
title: string,
20+
trackId: string,
21+
type: WorkType,
22+
typeId: string,
23+
}

src-ts/tools/work/work-lib/work-provider/work-functions/work.functions.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { Page } from '../../../../../lib'
33

44
import { WorkByStatus } from './work-by-status.model'
55
import { Work, workFactoryCreate, WorkStatus, WorkType } from './work-factory'
6-
import { Challenge, WorkStatusFilter, workStoreDeleteAsync, workStoreGetAsync, workStoreGetFilteredByStatus } from './work-store'
6+
import { Challenge, WorkPrices, WorkStatusFilter, workStoreDeleteAsync, workStoreGetAsync, workStoreGetFilteredByStatus } from './work-store'
77

88
export async function deleteAsync(workId: string): Promise<void> {
99
return workStoreDeleteAsync(workId)
@@ -16,7 +16,7 @@ export async function getAsync(handle: string, page: Page): Promise<Array<Work>>
1616

1717
// run it through the factory and filter out deleted and non-self-service
1818
const workItems: Array<Work> = challenges
19-
.map(challenge => workFactoryCreate(challenge))
19+
.map(challenge => workFactoryCreate(challenge, WorkPrices))
2020
.filter(work => work.status !== WorkStatus.deleted && work.type !== WorkType.unknown)
2121

2222
return workItems

src/routes/SelectWorkType/index.jsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ import PageContent from "../../components/PageContent";
1313
import PageDivider from "../../components/PageDivider";
1414
import PageH2 from "../../components/PageElements/PageH2";
1515
import Slider from "../../components/Slider";
16-
import { Breadcrumb, ContactSupportModal } from "../../../src-ts";
16+
import { Breadcrumb, ContactSupportModal, WorkTypeConfigs } from "../../../src-ts";
1717
import {
1818
BUTTON_SIZE,
1919
projectAndProfessionalWork,
@@ -127,7 +127,7 @@ const SelectWorkType = ({
127127
const challenge = useSelector((state) => state.challenge);
128128
const navigate = useNavigate()
129129

130-
const allWorkTypes = [...workTypes, ...webWorkTypes];
130+
const allWorkTypes = [...workTypes, ...webWorkTypes, ...Object.values(WorkTypeConfigs)];
131131
const featuredWorkTypes = allWorkTypes.filter((wt) => wt.featured);
132132

133133
useEffect(() => {

0 commit comments

Comments
 (0)