From db57744649db2641ba9ba3a3c37c64c94af67053 Mon Sep 17 00:00:00 2001 From: Anwar Sadath Date: Thu, 3 Nov 2022 19:27:27 +0530 Subject: [PATCH 01/10] PROD-3109 #comment Fix text in the 'What will I receive?' section does not match the provided text --- .../work-functions/work-store/work-type.config.ts | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src-ts/tools/work/work-lib/work-provider/work-functions/work-store/work-type.config.ts b/src-ts/tools/work/work-lib/work-provider/work-functions/work-store/work-type.config.ts index 2e4fdb495..6cefd83d8 100644 --- a/src-ts/tools/work/work-lib/work-provider/work-functions/work-store/work-type.config.ts +++ b/src-ts/tools/work/work-lib/work-provider/work-functions/work-store/work-type.config.ts @@ -12,9 +12,7 @@ export const WorkTypeConfigs: { [workType: string]: WorkTypeConfig } = { [WorkType.bugHunt]: { about: `Expert QA testers will verify that all of the pages on your website are working correctly from the end-user perspective. The testing will stress functional issues, but also includes security issues, user interface issues, usability issues and more. Test on desktop, tablet, and mobile, to uncover bugs before your customers encounter them.`, bgImage: bugHuntTileImg, - deliverablesDescription: `You will receive thorough testing of your website, and at the conclusion will be provided - a detailed report of bugs which have steps to reproduce, screenshots / videos if applicable, - details of the bug, and severity of the issue.`, + deliverablesDescription: 'You will receive thorough testing of your website by QA experts, and an actionable report extremely quickly. Our experts will deliver a detailed list of bugs found, with steps to reproduce, including screenshots, videos, and the information you need to fix them.', description: 'Execute thorough bug hunts exceptionally fast. Receive a detailed list of bugs and instructions on exactly how to fix them.', duration: { 'advanced': 6, From b011ce91556121c0ca907d347ab36c695c0b9862 Mon Sep 17 00:00:00 2001 From: Anwar Sadath Date: Tue, 8 Nov 2022 23:47:29 +0530 Subject: [PATCH 02/10] PROD-3106 #comment Fix Bug hunt package details are not displayed in the WM challenge specification and challenge details page --- .../WorkDetailDetailsPane.tsx | 16 ++-------------- .../work-functions/work-factory/work.factory.ts | 3 ++- src-ts/utils/bug-hunt/index.ts | 16 ++++++++++++++++ 3 files changed, 20 insertions(+), 15 deletions(-) create mode 100644 src-ts/utils/bug-hunt/index.ts diff --git a/src-ts/tools/work/work-detail-details/work-detail-details-pane/WorkDetailDetailsPane.tsx b/src-ts/tools/work/work-detail-details/work-detail-details-pane/WorkDetailDetailsPane.tsx index a336d891e..5e9edfcc5 100644 --- a/src-ts/tools/work/work-detail-details/work-detail-details-pane/WorkDetailDetailsPane.tsx +++ b/src-ts/tools/work/work-detail-details/work-detail-details-pane/WorkDetailDetailsPane.tsx @@ -3,10 +3,9 @@ import _ from 'lodash' import { Dispatch, FC, SetStateAction, useEffect, useState } from 'react' import { Link } from 'react-router-dom' -import { currencyFormat } from '../../../../../src/utils' -import { ArrowIcon, FormCard, LoadingSpinner } from '../../../../lib' +import { ArrowIcon, LoadingSpinner } from '../../../../lib' +import getSelectedPackageFormatted from '../../../../utils/bug-hunt' import { ChallengeMetadataName, workFactoryMapFormData } from '../../work-lib' -import BugHuntPricingConfig from '../../work-self-service/intake-forms/bug-hunt/bug-hunt.form.pricing-config' import styles from './WorkDetailDetailsPane.module.scss' @@ -108,15 +107,4 @@ function checkIsEmpty(detail: Array | {} | string): boolean { .filter((val) => val?.trim().length > 0).length === 0) } -const getSelectedPackageFormatted: (packageId: string) => string = (packageId) => { - const currentPackage: FormCard | undefined = BugHuntPricingConfig.find((pricingConfig) => pricingConfig.id === packageId) - if (currentPackage) { - const deviceType: string = currentPackage.sections?.[0]?.rows?.[3]?.text || '' - const noOfTesters: string = `${currentPackage.sections?.[0]?.rows?.[2]?.text || 0} testers` - return `${currentPackage.title} - ${currencyFormat(currentPackage.price)} - ${deviceType} - ${noOfTesters}` - } - - return packageId -} - export default WorkDetailDetailsPane diff --git a/src-ts/tools/work/work-lib/work-provider/work-functions/work-factory/work.factory.ts b/src-ts/tools/work/work-lib/work-provider/work-functions/work-factory/work.factory.ts index 5eb4d4556..99a3bce24 100644 --- a/src-ts/tools/work/work-lib/work-provider/work-functions/work-factory/work.factory.ts +++ b/src-ts/tools/work/work-lib/work-provider/work-functions/work-factory/work.factory.ts @@ -1,4 +1,5 @@ import moment from 'moment' +import getSelectedPackageFormatted from '../../../../../../utils/bug-hunt' import { WorkConfigConstants, WorkStrings } from '../../../work-constants' import { @@ -302,7 +303,7 @@ function buildFormDataBugHunt(formData: any): ReadonlyArray { { key: ChallengeMetadataName.packageType, title: ChallengeMetadataTitle.bugHuntPackage, - value: formData.packageType, + value: getSelectedPackageFormatted(formData.packageType), }, ] } diff --git a/src-ts/utils/bug-hunt/index.ts b/src-ts/utils/bug-hunt/index.ts new file mode 100644 index 000000000..7e3c33917 --- /dev/null +++ b/src-ts/utils/bug-hunt/index.ts @@ -0,0 +1,16 @@ +import { currencyFormat } from "../../../src/utils" +import { FormCard } from "../../lib" +import BugHuntPricingConfig from "../../tools/work/work-self-service/intake-forms/bug-hunt/bug-hunt.form.pricing-config" + +function getSelectedPackageFormatted(packageId: string): string { + const currentPackage: FormCard | undefined = BugHuntPricingConfig.find((pricingConfig) => pricingConfig.id === packageId) + if (currentPackage) { + const deviceType: string = currentPackage.sections?.[0]?.rows?.[3]?.text || '' + const noOfTesters: string = `${currentPackage.sections?.[0]?.rows?.[2]?.text || 0} testers` + return `${currentPackage.title} - ${currencyFormat(currentPackage.price)} - ${deviceType} - ${noOfTesters}` + } + + return packageId +} + +export default getSelectedPackageFormatted From c8219df41e6a465ee3da0c0f8ee712692d87a3e0 Mon Sep 17 00:00:00 2001 From: Anwar Sadath Date: Mon, 14 Nov 2022 19:09:37 +0530 Subject: [PATCH 03/10] PROD-2708 #comment Improve readability of the bug hunt package --- .../form-card-set/FormCardSet.module.scss | 56 +++++++++++++++---- .../form-groups/form-card-set/FormCardSet.tsx | 5 +- 2 files changed, 47 insertions(+), 14 deletions(-) diff --git a/src-ts/lib/form/form-groups/form-card-set/FormCardSet.module.scss b/src-ts/lib/form/form-groups/form-card-set/FormCardSet.module.scss index f9cf29bd2..211cce2b0 100644 --- a/src-ts/lib/form/form-groups/form-card-set/FormCardSet.module.scss +++ b/src-ts/lib/form/form-groups/form-card-set/FormCardSet.module.scss @@ -17,9 +17,10 @@ flex: 1 1 0; margin-right: $space-xl; border-radius: $space-xs; - padding: $space-lg 0; + padding: $space-xxl 0px 0px; background-color: $black-5; position: relative; + height: calc($space-xl * 30); .popular-card { display: flex; @@ -61,19 +62,25 @@ align-items: center; h3 { - margin: $space-lg; + margin: $space-xxl $space-lg; font-weight: 500; - font-size: $space-mx; + font-size: calc($space-mx + $space-xs); line-height: $space-mx; - margin-top: $space-xxl; + } + + .body-medium-bold { + font-weight: 700; + font-size: $space-xxl; + font-family: "Roboto"; + padding: 0; + line-height: calc($space-xxl - 2px); } &.feature { visibility: hidden; h3 { - margin: $space-lg; - margin-top: $space-xxl; + margin: $space-xxl $space-lg; font-size: $space-xxxxl; } } @@ -82,9 +89,15 @@ h3 { font-size: $space-xxxxl; line-height: $space-xxxxl; - margin-top: $space-md; + margin-top: $space-sm; margin-bottom: $space-xxl; } + + .body-medium-bold { + font-size: $space-xl; + line-height: $space-xxxxl; + font-style: normal; + } } } @@ -97,10 +110,18 @@ } .card-section { - margin: $space-lg 0; + margin: $space-mx 0; .row { height: auto; + + &:last-child { + .row-divider { + &:last-child { + display: block; + } + } + } } .row-divider { @@ -108,13 +129,17 @@ border-bottom: $border solid $black-10; width: auto; margin: 0; + + &:last-child { + display: none; + } } .card-row { display: flex; padding: $space-md; align-items: center; - min-height: calc($space-lg + $space-mx); + min-height: calc($space-lg + $space-mx - 2px); position: relative; .card-row-col { @@ -156,6 +181,7 @@ } } &.mobile { + margin-bottom: 0; .feature-name { width: 100%; } @@ -164,13 +190,14 @@ } } &.feature { - margin: calc($space-lg - 0.2px) 0; + margin-top: $space-mx; } } &.feature { background-color: $tc-white; margin-right: 0; + flex-grow: 0.9; .card-row-col:nth-child(2) { display: none; @@ -188,9 +215,14 @@ } svg.card-row-icon { - height: 14px; - width: 14px; + height: 24px; + width: 24px; display: inline; margin-right: 6px; + + @include ltemd { + height: 16px; + width: 16px; + } } } diff --git a/src-ts/lib/form/form-groups/form-card-set/FormCardSet.tsx b/src-ts/lib/form/form-groups/form-card-set/FormCardSet.tsx index 1629be9b7..6983ba8ca 100644 --- a/src-ts/lib/form/form-groups/form-card-set/FormCardSet.tsx +++ b/src-ts/lib/form/form-groups/form-card-set/FormCardSet.tsx @@ -49,7 +49,7 @@ const FormCardSet: React.FC = ({ name, cards, onChange, value
{ card.mostPopular &&
MOST POPULAR
}
-
{card.title}
+
{card.title}

{formattedPrice}

{getButton(card, selected)}
@@ -77,12 +77,13 @@ const FormCardSet: React.FC = ({ name, cards, onChange, value {( { row.valueIcon ? - : + : {row.text} } )}
+
))} From cd567ed3c0114d729ac471eca0aae0881ed9b20b Mon Sep 17 00:00:00 2001 From: Anwar Sadath Date: Mon, 14 Nov 2022 19:18:55 +0530 Subject: [PATCH 04/10] PROD-2640 #comment Fix package type not selected when users comes back from the initial draft --- .../intake-forms/bug-hunt/BugHuntIntakeForm.tsx | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src-ts/tools/work/work-self-service/intake-forms/bug-hunt/BugHuntIntakeForm.tsx b/src-ts/tools/work/work-self-service/intake-forms/bug-hunt/BugHuntIntakeForm.tsx index 9403b4396..125952baf 100644 --- a/src-ts/tools/work/work-self-service/intake-forms/bug-hunt/BugHuntIntakeForm.tsx +++ b/src-ts/tools/work/work-self-service/intake-forms/bug-hunt/BugHuntIntakeForm.tsx @@ -49,6 +49,8 @@ const BugHuntIntakeForm: React.FC = () => { const [loading, setLoading]: [boolean, Dispatch>] = useState(false) const [saveSuccess, setSaveSuccess]: [boolean, Dispatch>] = useState(false) + const defaultPackage: PricePackageName = 'standard' + BugHuntFormConfig.buttons.primaryGroup[0].onClick = () => { setAction('save') } BugHuntFormConfig.buttons.primaryGroup[0].hidden = !isLoggedIn BugHuntFormConfig.buttons.primaryGroup[1].onClick = () => { setAction('submit') } @@ -72,7 +74,7 @@ const BugHuntIntakeForm: React.FC = () => { const [formValues, setFormValues]: [any, Dispatch] = useState({ currentStep: 'basicInfo', - [ChallengeMetadataName.packageType]: 'standard', + [ChallengeMetadataName.packageType]: defaultPackage, }) const [selectedPackage, setSelectedPackage]: [PricePackageName, Dispatch>] @@ -111,6 +113,11 @@ const BugHuntIntakeForm: React.FC = () => { if (formData?.packageType) { setSelectedPackage(formData.packageType) + } else { + setFormValues({ + ...formValues, + [ChallengeMetadataName.packageType]: defaultPackage, + }) } } From b7a7c5557a1d35919cc1bfbb65c607f081671e35 Mon Sep 17 00:00:00 2001 From: Anwar Sadath Date: Mon, 14 Nov 2022 19:19:43 +0530 Subject: [PATCH 05/10] Fix lint errors --- .../work-functions/work-factory/work.factory.ts | 2 +- src-ts/utils/bug-hunt/index.ts | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src-ts/tools/work/work-lib/work-provider/work-functions/work-factory/work.factory.ts b/src-ts/tools/work/work-lib/work-provider/work-functions/work-factory/work.factory.ts index 99a3bce24..ee35783c0 100644 --- a/src-ts/tools/work/work-lib/work-provider/work-functions/work-factory/work.factory.ts +++ b/src-ts/tools/work/work-lib/work-provider/work-functions/work-factory/work.factory.ts @@ -1,6 +1,6 @@ import moment from 'moment' -import getSelectedPackageFormatted from '../../../../../../utils/bug-hunt' +import getSelectedPackageFormatted from '../../../../../../utils/bug-hunt' import { WorkConfigConstants, WorkStrings } from '../../../work-constants' import { ActivateWorkRequest, diff --git a/src-ts/utils/bug-hunt/index.ts b/src-ts/utils/bug-hunt/index.ts index 7e3c33917..f8a160dc5 100644 --- a/src-ts/utils/bug-hunt/index.ts +++ b/src-ts/utils/bug-hunt/index.ts @@ -1,6 +1,6 @@ -import { currencyFormat } from "../../../src/utils" -import { FormCard } from "../../lib" -import BugHuntPricingConfig from "../../tools/work/work-self-service/intake-forms/bug-hunt/bug-hunt.form.pricing-config" +import { currencyFormat } from '../../../src/utils' +import { FormCard } from '../../lib' +import BugHuntPricingConfig from '../../tools/work/work-self-service/intake-forms/bug-hunt/bug-hunt.form.pricing-config' function getSelectedPackageFormatted(packageId: string): string { const currentPackage: FormCard | undefined = BugHuntPricingConfig.find((pricingConfig) => pricingConfig.id === packageId) From 8eaf66364808f2bbd9c773faceeed41cf1a703a3 Mon Sep 17 00:00:00 2001 From: Anwar Sadath Date: Tue, 15 Nov 2022 23:27:05 +0530 Subject: [PATCH 06/10] Fix as per review comments --- .../form-card-set/FormCardSet.module.scss | 28 +++++++------------ .../form-groups/form-card-set/FormCardSet.tsx | 4 +-- .../WorkDetailDetailsPane.tsx | 2 +- .../work-factory/work.factory.ts | 2 +- .../work-functions/work.functions.ts | 14 +++++++++- src-ts/utils/bug-hunt/index.ts | 16 ----------- 6 files changed, 27 insertions(+), 39 deletions(-) delete mode 100644 src-ts/utils/bug-hunt/index.ts diff --git a/src-ts/lib/form/form-groups/form-card-set/FormCardSet.module.scss b/src-ts/lib/form/form-groups/form-card-set/FormCardSet.module.scss index 211cce2b0..b92510b04 100644 --- a/src-ts/lib/form/form-groups/form-card-set/FormCardSet.module.scss +++ b/src-ts/lib/form/form-groups/form-card-set/FormCardSet.module.scss @@ -68,14 +68,6 @@ line-height: $space-mx; } - .body-medium-bold { - font-weight: 700; - font-size: $space-xxl; - font-family: "Roboto"; - padding: 0; - line-height: calc($space-xxl - 2px); - } - &.feature { visibility: hidden; @@ -92,12 +84,6 @@ margin-top: $space-sm; margin-bottom: $space-xxl; } - - .body-medium-bold { - font-size: $space-xl; - line-height: $space-xxxxl; - font-style: normal; - } } } @@ -178,10 +164,18 @@ cursor: pointer; outline: none; } + + .check-icon { + @include icon-xxl; + @include ltemd { + @include icon-lg; + } + } } } &.mobile { margin-bottom: 0; + margin-top: $space-xxl; .feature-name { width: 100%; } @@ -215,14 +209,12 @@ } svg.card-row-icon { - height: 24px; - width: 24px; + @include icon-xxl; display: inline; margin-right: 6px; @include ltemd { - height: 16px; - width: 16px; + @include icon-lg; } } } diff --git a/src-ts/lib/form/form-groups/form-card-set/FormCardSet.tsx b/src-ts/lib/form/form-groups/form-card-set/FormCardSet.tsx index 6983ba8ca..50501e282 100644 --- a/src-ts/lib/form/form-groups/form-card-set/FormCardSet.tsx +++ b/src-ts/lib/form/form-groups/form-card-set/FormCardSet.tsx @@ -49,7 +49,7 @@ const FormCardSet: React.FC = ({ name, cards, onChange, value
{ card.mostPopular &&
MOST POPULAR
}
-
{card.title}
+
{card.title}

{formattedPrice}

{getButton(card, selected)}
@@ -77,7 +77,7 @@ const FormCardSet: React.FC = ({ name, cards, onChange, value {( { row.valueIcon ? - : + : {row.text} } diff --git a/src-ts/tools/work/work-detail-details/work-detail-details-pane/WorkDetailDetailsPane.tsx b/src-ts/tools/work/work-detail-details/work-detail-details-pane/WorkDetailDetailsPane.tsx index 5e9edfcc5..7369018c7 100644 --- a/src-ts/tools/work/work-detail-details/work-detail-details-pane/WorkDetailDetailsPane.tsx +++ b/src-ts/tools/work/work-detail-details/work-detail-details-pane/WorkDetailDetailsPane.tsx @@ -4,8 +4,8 @@ import { Dispatch, FC, SetStateAction, useEffect, useState } from 'react' import { Link } from 'react-router-dom' import { ArrowIcon, LoadingSpinner } from '../../../../lib' -import getSelectedPackageFormatted from '../../../../utils/bug-hunt' import { ChallengeMetadataName, workFactoryMapFormData } from '../../work-lib' +import { getSelectedPackageFormatted } from '../../work-lib/work-provider/work-functions/work.functions' import styles from './WorkDetailDetailsPane.module.scss' diff --git a/src-ts/tools/work/work-lib/work-provider/work-functions/work-factory/work.factory.ts b/src-ts/tools/work/work-lib/work-provider/work-functions/work-factory/work.factory.ts index ee35783c0..82ee6a8f7 100644 --- a/src-ts/tools/work/work-lib/work-provider/work-functions/work-factory/work.factory.ts +++ b/src-ts/tools/work/work-lib/work-provider/work-functions/work-factory/work.factory.ts @@ -1,6 +1,5 @@ import moment from 'moment' -import getSelectedPackageFormatted from '../../../../../../utils/bug-hunt' import { WorkConfigConstants, WorkStrings } from '../../../work-constants' import { ActivateWorkRequest, @@ -26,6 +25,7 @@ import { WorkTypeCategory, WorkTypeConfig, } from '../work-store' +import { getSelectedPackageFormatted } from '../work.functions' export interface FormDetail { key: string, diff --git a/src-ts/tools/work/work-lib/work-provider/work-functions/work.functions.ts b/src-ts/tools/work/work-lib/work-provider/work-functions/work.functions.ts index ddf6a24f3..c1cabda93 100644 --- a/src-ts/tools/work/work-lib/work-provider/work-functions/work.functions.ts +++ b/src-ts/tools/work/work-lib/work-provider/work-functions/work.functions.ts @@ -1,6 +1,7 @@ import { PaymentMethodResult, Stripe, StripeCardNumberElement } from '@stripe/stripe-js' -import { Page, UserProfile } from '../../../../../lib' +import { FormCard, Page, textFormatMoneyLocaleString, UserProfile } from '../../../../../lib' +import BugHuntPricingConfig from '../../../work-self-service/intake-forms/bug-hunt/bug-hunt.form.pricing-config' import { WorkByStatus } from './work-by-status.model' import { @@ -171,3 +172,14 @@ async function getPageAsync(handle: string, page: Page): Promise> { .map(challenge => workFactoryCreate(challenge, workGetPricesConfig())) .filter(work => work.status !== WorkStatus.deleted && work.type !== WorkType.unknown) } + +export function getSelectedPackageFormatted(packageId: string): string { + const currentPackage: FormCard | undefined = BugHuntPricingConfig.find((pricingConfig) => pricingConfig.id === packageId) + if (currentPackage) { + const deviceType: string = currentPackage.sections?.[0]?.rows?.[3]?.text || '' + const noOfTesters: string = `${currentPackage.sections?.[0]?.rows?.[2]?.text || 0} testers` + return `${currentPackage.title} - ${textFormatMoneyLocaleString(currentPackage.price)} - ${deviceType} - ${noOfTesters}` + } + + return packageId +} diff --git a/src-ts/utils/bug-hunt/index.ts b/src-ts/utils/bug-hunt/index.ts deleted file mode 100644 index f8a160dc5..000000000 --- a/src-ts/utils/bug-hunt/index.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { currencyFormat } from '../../../src/utils' -import { FormCard } from '../../lib' -import BugHuntPricingConfig from '../../tools/work/work-self-service/intake-forms/bug-hunt/bug-hunt.form.pricing-config' - -function getSelectedPackageFormatted(packageId: string): string { - const currentPackage: FormCard | undefined = BugHuntPricingConfig.find((pricingConfig) => pricingConfig.id === packageId) - if (currentPackage) { - const deviceType: string = currentPackage.sections?.[0]?.rows?.[3]?.text || '' - const noOfTesters: string = `${currentPackage.sections?.[0]?.rows?.[2]?.text || 0} testers` - return `${currentPackage.title} - ${currencyFormat(currentPackage.price)} - ${deviceType} - ${noOfTesters}` - } - - return packageId -} - -export default getSelectedPackageFormatted From 51e0a968f789ed058ff00094ada1ffc920d1314a Mon Sep 17 00:00:00 2001 From: Brooke Date: Tue, 15 Nov 2022 10:09:24 -0800 Subject: [PATCH 07/10] PROD-2614 #comment This commit cleans up some imports #time 15m --- .../WorkDetailDetailsPane.tsx | 11 +++++++---- .../work-lib/work-provider/work-functions/index.ts | 1 + .../work-provider/work-functions/work.functions.ts | 2 +- .../work-self-service/intake-forms/bug-hunt/index.tsx | 1 + 4 files changed, 10 insertions(+), 5 deletions(-) diff --git a/src-ts/tools/work/work-detail-details/work-detail-details-pane/WorkDetailDetailsPane.tsx b/src-ts/tools/work/work-detail-details/work-detail-details-pane/WorkDetailDetailsPane.tsx index 7369018c7..c9c3dd878 100644 --- a/src-ts/tools/work/work-detail-details/work-detail-details-pane/WorkDetailDetailsPane.tsx +++ b/src-ts/tools/work/work-detail-details/work-detail-details-pane/WorkDetailDetailsPane.tsx @@ -4,8 +4,11 @@ import { Dispatch, FC, SetStateAction, useEffect, useState } from 'react' import { Link } from 'react-router-dom' import { ArrowIcon, LoadingSpinner } from '../../../../lib' -import { ChallengeMetadataName, workFactoryMapFormData } from '../../work-lib' -import { getSelectedPackageFormatted } from '../../work-lib/work-provider/work-functions/work.functions' +import { + ChallengeMetadataName, + workFactoryMapFormData, + workGetSelectedPackageFormatted, +} from '../../work-lib' import styles from './WorkDetailDetailsPane.module.scss' @@ -68,9 +71,9 @@ const WorkDetailDetailsPane: FC = ({ collapsible, de

{detail.title}

{detail.key === ChallengeMetadataName.packageType ? ( -

{getSelectedPackageFormatted(detail.value)}

+

{workGetSelectedPackageFormatted(detail.value)}

) : ( -

{formatOption(detail.value)}

+

{formatOption(detail.value)}

)}
) diff --git a/src-ts/tools/work/work-lib/work-provider/work-functions/index.ts b/src-ts/tools/work/work-lib/work-provider/work-functions/index.ts index 1a474fd7e..2831d36a6 100644 --- a/src-ts/tools/work/work-lib/work-provider/work-functions/index.ts +++ b/src-ts/tools/work/work-lib/work-provider/work-functions/index.ts @@ -32,6 +32,7 @@ export { getByWorkIdAsync as workGetByWorkIdAsync, getGroupedByStatus as workGetGroupedByStatus, getPricesConfig as workGetPricesConfig, + getSelectedPackageFormatted as workGetSelectedPackageFormatted, getStatusFilter as workGetStatusFilter, updateAsync as workUpdateAsync, } from './work.functions' diff --git a/src-ts/tools/work/work-lib/work-provider/work-functions/work.functions.ts b/src-ts/tools/work/work-lib/work-provider/work-functions/work.functions.ts index c1cabda93..717192f6b 100644 --- a/src-ts/tools/work/work-lib/work-provider/work-functions/work.functions.ts +++ b/src-ts/tools/work/work-lib/work-provider/work-functions/work.functions.ts @@ -1,7 +1,7 @@ import { PaymentMethodResult, Stripe, StripeCardNumberElement } from '@stripe/stripe-js' import { FormCard, Page, textFormatMoneyLocaleString, UserProfile } from '../../../../../lib' -import BugHuntPricingConfig from '../../../work-self-service/intake-forms/bug-hunt/bug-hunt.form.pricing-config' +import { BugHuntPricingConfig } from '../../../work-self-service' import { WorkByStatus } from './work-by-status.model' import { diff --git a/src-ts/tools/work/work-self-service/intake-forms/bug-hunt/index.tsx b/src-ts/tools/work/work-self-service/intake-forms/bug-hunt/index.tsx index 5d269208e..fa139e46e 100644 --- a/src-ts/tools/work/work-self-service/intake-forms/bug-hunt/index.tsx +++ b/src-ts/tools/work/work-self-service/intake-forms/bug-hunt/index.tsx @@ -1,3 +1,4 @@ +export { default as BugHuntPricingConfig } from './bug-hunt.form.pricing-config' export * from './BugHuntIntakeForm' export { default as BugHuntIntakeForm } from './BugHuntIntakeForm' export * from './deliverables-info-card' From 9bedb3cf3e9b241d5b22437caadd7938d6c921af Mon Sep 17 00:00:00 2001 From: Brooke Date: Wed, 16 Nov 2022 11:21:01 -0800 Subject: [PATCH 08/10] PROD-2614 Lint fixes #time 30m --- src-ts/lib/form/Form.tsx | 2 +- .../work-factory/work.factory.ts | 35 ++++-- .../work-store/work-type.config.ts | 1 + .../work-functions/work.functions.ts | 2 +- .../bug-hunt/BugHuntIntakeForm.tsx | 113 ++++++++++-------- 5 files changed, 91 insertions(+), 62 deletions(-) diff --git a/src-ts/lib/form/Form.tsx b/src-ts/lib/form/Form.tsx index 07de469e4..c5b954062 100644 --- a/src-ts/lib/form/Form.tsx +++ b/src-ts/lib/form/Form.tsx @@ -95,7 +95,7 @@ const Form: (props: }, []) function checkIfFormIsValid(formInputFields: Array): void { - setFormInvalid(formInputFields.filter(item => !!item.error).length > 0) + setFormInvalid(formInputFields.some(item => !!item.error)) } function onBlur(event: FocusEvent): void { diff --git a/src-ts/tools/work/work-lib/work-provider/work-functions/work-factory/work.factory.ts b/src-ts/tools/work/work-lib/work-provider/work-functions/work-factory/work.factory.ts index 220b57269..b16fdf4cc 100644 --- a/src-ts/tools/work/work-lib/work-provider/work-functions/work-factory/work.factory.ts +++ b/src-ts/tools/work/work-lib/work-provider/work-functions/work-factory/work.factory.ts @@ -1,3 +1,4 @@ +/* eslint-disable @typescript-eslint/no-explicit-any */ import moment from 'moment' import { WorkConfigConstants, WorkStrings } from '../../../work-constants' @@ -130,12 +131,17 @@ export function buildCustomerPaymentRequest( } } -export function buildUpdateRequest(workTypeConfig: WorkTypeConfig, challenge: Challenge, formData: any): UpdateWorkRequest { +export function buildUpdateRequest( + workTypeConfig: WorkTypeConfig, + challenge: Challenge, + formData: any, +): UpdateWorkRequest { const type: WorkType = workTypeConfig.type const priceConfig: WorkPrice = workTypeConfig.priceConfig - const intakeForm: ChallengeMetadata | undefined = findMetadata(challenge, ChallengeMetadataName.intakeForm) || undefined + const intakeForm: ChallengeMetadata | undefined + = findMetadata(challenge, ChallengeMetadataName.intakeForm) || undefined const form: IntakeForm = !!intakeForm?.value ? JSON.parse(intakeForm.value)?.form : {} form.basicInfo = formData @@ -182,7 +188,8 @@ export function buildUpdateRequest(workTypeConfig: WorkTypeConfig, challenge: Ch // then update the duration for that phase to the correct value const timeline: Array = workTypeConfig.timeline.map(phase => { if (workTypeConfig.submissionPhaseDuration && phase.phaseId === WorkConfigConstants.PHASE_ID_SUBMISSION) { - phase.duration = workTypeConfig.submissionPhaseDuration[formData[ChallengeMetadataName.packageType] as PricePackageName] || 0 + const packageName: PricePackageName = formData[ChallengeMetadataName.packageType] as PricePackageName + phase.duration = workTypeConfig.submissionPhaseDuration[packageName] || 0 } return phase @@ -238,9 +245,11 @@ export function getStatus(challenge: Challenge): WorkStatus { case ChallengeStatus.draft: return WorkStatus.active - case ChallengeStatus.completed: - const customerFeedback: ChallengeMetadata | undefined = findMetadata(challenge, ChallengeMetadataName.feedback) + case ChallengeStatus.completed: { + const customerFeedback: ChallengeMetadata | undefined + = findMetadata(challenge, ChallengeMetadataName.feedback) return !customerFeedback ? WorkStatus.ready : WorkStatus.done + } case ChallengeStatus.cancelled: case ChallengeStatus.cancelledPaymentFailed: @@ -450,8 +459,9 @@ function findOpenPhase(challenge: Challenge): ChallengePhase | undefined { // sort the phases descending by start date const sortedPhases: Array = challenge.phases .sort((a, b) => new Date(b.actualStartDate) - .getTime() - new Date(a.actualStartDate) - .getTime()) + .getTime() + - new Date(a.actualStartDate) + .getTime()) const now: Date = new Date() // if we have an open phase, just use that @@ -519,7 +529,8 @@ function getCost(challenge: Challenge, priceConfig: WorkPrice, type: WorkType): case WorkType.bugHunt: { // get the selected package from the intake form - const intakeFormBH: ChallengeMetadata | undefined = findMetadata(challenge, ChallengeMetadataName.intakeForm) + const intakeFormBH: ChallengeMetadata | undefined + = findMetadata(challenge, ChallengeMetadataName.intakeForm) const formBH: IntakeForm = !!intakeFormBH?.value ? JSON.parse(intakeFormBH.value)?.form : undefined return priceConfig.getPrice(priceConfig, formBH?.basicInfo?.packageType) } @@ -539,6 +550,9 @@ function getDescription(challenge: Challenge, type: WorkType): string | undefine case WorkType.design: case WorkType.designLegacy: return findMetadata(challenge, ChallengeMetadataName.description)?.value + + default: + return undefined } } @@ -597,7 +611,7 @@ function getProgressStepActive(challenge: Challenge, workStatus: WorkStatus): nu switch (challenge.status) { case ChallengeStatus.active: - case ChallengeStatus.approved: + case ChallengeStatus.approved: { const openPhase: ChallengePhase | undefined = findOpenPhase(challenge) // if we don't have an open phase, just return submitted @@ -613,6 +627,7 @@ function getProgressStepActive(challenge: Challenge, workStatus: WorkStatus): nu default: return 2 } + } case ChallengeStatus.completed: return workStatus === WorkStatus.ready ? 3 : 4 @@ -699,7 +714,7 @@ function getType(challenge: Challenge): WorkType { // parse the form const form: { form: IntakeForm } = JSON.parse(intakeForm.value) const workTypeKey: (keyof typeof WorkType) | undefined = Object.entries(WorkType) - .find(([key, value]) => value === form.form?.workType?.selectedWorkType) + .find(([, value]) => value === form.form?.workType?.selectedWorkType) ?.[0] as keyof typeof WorkType const output: WorkType = !!workTypeKey ? WorkType[workTypeKey] : WorkType.unknown diff --git a/src-ts/tools/work/work-lib/work-provider/work-functions/work-store/work-type.config.ts b/src-ts/tools/work/work-lib/work-provider/work-functions/work-store/work-type.config.ts index dbad709a6..dbd1cb510 100644 --- a/src-ts/tools/work/work-lib/work-provider/work-functions/work-store/work-type.config.ts +++ b/src-ts/tools/work/work-lib/work-provider/work-functions/work-store/work-type.config.ts @@ -1,3 +1,4 @@ +/* eslint-disable max-len */ import { bugHuntTileImg } from '../../../work-images' import { ChallengeTag } from './challenge-tag.enum' diff --git a/src-ts/tools/work/work-lib/work-provider/work-functions/work.functions.ts b/src-ts/tools/work/work-lib/work-provider/work-functions/work.functions.ts index fecf498e2..dc0667cb2 100644 --- a/src-ts/tools/work/work-lib/work-provider/work-functions/work.functions.ts +++ b/src-ts/tools/work/work-lib/work-provider/work-functions/work.functions.ts @@ -1,7 +1,7 @@ import { PaymentMethodResult, Stripe, StripeCardNumberElement } from '@stripe/stripe-js' import { FormCard, GenericDataObject, Page, textFormatMoneyLocaleString, UserProfile } from '../../../../../lib' -import { BugHuntPricingConfig } from '../../../work-self-service' +import BugHuntPricingConfig from '../../../work-self-service/intake-forms/bug-hunt/bug-hunt.form.pricing-config' import { WorkByStatus } from './work-by-status.model' import { diff --git a/src-ts/tools/work/work-self-service/intake-forms/bug-hunt/BugHuntIntakeForm.tsx b/src-ts/tools/work/work-self-service/intake-forms/bug-hunt/BugHuntIntakeForm.tsx index 165c08b69..50759068e 100644 --- a/src-ts/tools/work/work-self-service/intake-forms/bug-hunt/BugHuntIntakeForm.tsx +++ b/src-ts/tools/work/work-self-service/intake-forms/bug-hunt/BugHuntIntakeForm.tsx @@ -1,5 +1,6 @@ +/* eslint-disable @typescript-eslint/no-explicit-any */ import { NavigateFunction, useNavigate, useParams } from 'react-router-dom' -import React, { Dispatch, SetStateAction, useContext, useEffect, useState } from 'react' +import React, { Dispatch, SetStateAction, useCallback, useContext, useEffect, useState } from 'react' import { Form, @@ -68,7 +69,8 @@ const BugHuntIntakeForm: React.FC = () => { BugHuntFormConfig.buttons.primaryGroup[1].label = 'Complete and pay' } - const [challenge, setChallenge]: [Challenge | undefined, Dispatch>] = useState() + const [challenge, setChallenge]: [Challenge | undefined, Dispatch>] + = useState() const [formDef]: [FormDefinition, Dispatch>] = useState({ ...BugHuntFormConfig }) @@ -80,7 +82,8 @@ const BugHuntIntakeForm: React.FC = () => { const [selectedPackage, setSelectedPackage]: [PricePackageName, Dispatch>] = useState(formValues?.packageType) - const [disableSaveForLater, setDisableSaveForLater]: [boolean, Dispatch>] = useState(true) + const [disableSaveForLater, setDisableSaveForLater]: [boolean, Dispatch>] + = useState(true) useEffect(() => { @@ -124,38 +127,53 @@ const BugHuntIntakeForm: React.FC = () => { setLoading(true) getAndSetWork() .finally(() => setLoading(false)) + // eslint-disable-next-line react-hooks/exhaustive-deps }, [ isLoggedIn, workId, ]) + const handleSaveSuccess: () => void = () => { + if (action === 'save') { + navigate(`${dashboardRoute}/draft`) + } else if (action === 'submit') { + const nextUrl: string = `${WorkIntakeFormRoutes[WorkType.bugHunt].review}/${workId || challenge?.id}` + navigate(nextUrl) + } + } + useEffect(() => { if (!loading && saveSuccess) { handleSaveSuccess() } + // eslint-disable-next-line react-hooks/exhaustive-deps }, [loading, saveSuccess]) - const requestGenerator: (inputs: ReadonlyArray) => void = inputs => { - const projectTitle: string = formGetInputModel(inputs, ChallengeMetadataName.projectTitle).value as string - const featuresToTest: string = formGetInputModel(inputs, ChallengeMetadataName.featuresToTest).value as string - const deliveryType: string = formGetInputModel(inputs, ChallengeMetadataName.deliveryType).value as string - const repositoryLink: string = formGetInputModel(inputs, ChallengeMetadataName.repositoryLink).value as string - const websiteURL: string = formGetInputModel(inputs, ChallengeMetadataName.websiteURL).value as string - const goals: string = formGetInputModel(inputs, ChallengeMetadataName.goals).value as string - const packageType: string = formGetInputModel(inputs, ChallengeMetadataName.packageType).value as string - return { - deliveryType, - featuresToTest, - goals, - packageType, - projectTitle, - repositoryLink, - websiteURL, - } - } + const requestGenerator: (inputs: ReadonlyArray) => any + = useCallback((inputs: ReadonlyArray) => { + const projectTitle: string = formGetInputModel(inputs, ChallengeMetadataName.projectTitle).value as string + const featuresToTest: string + = formGetInputModel(inputs, ChallengeMetadataName.featuresToTest).value as string + const deliveryType: string = formGetInputModel(inputs, ChallengeMetadataName.deliveryType).value as string + const repositoryLink: string + = formGetInputModel(inputs, ChallengeMetadataName.repositoryLink).value as string + const websiteURL: string = formGetInputModel(inputs, ChallengeMetadataName.websiteURL).value as string + const goals: string = formGetInputModel(inputs, ChallengeMetadataName.goals).value as string + const packageType: string = formGetInputModel(inputs, ChallengeMetadataName.packageType).value as string + return { + deliveryType, + featuresToTest, + goals, + packageType, + projectTitle, + repositoryLink, + websiteURL, + } + }, []) const onChange: (inputs: ReadonlyArray) => void = inputs => { - const packageType: PricePackageName = formGetInputModel(inputs, ChallengeMetadataName.packageType).value as PricePackageName + const packageType: PricePackageName + = formGetInputModel(inputs, ChallengeMetadataName.packageType).value as PricePackageName if (packageType !== selectedPackage) { setSelectedPackage(packageType) @@ -166,6 +184,18 @@ const BugHuntIntakeForm: React.FC = () => { setDisableSaveForLater(!title?.trim()) } + const goToLoginStep: (formData: any) => void = (formData: any) => { + if (localStorage) { + localStorage.setItem('challengeInProgress', JSON.stringify(formData)) + localStorage.setItem('challengeInProgressType', WorkType.bugHunt) + } + + const returnUrl: string + = encodeURIComponent(`${window.location.origin}${WorkIntakeFormRoutes[WorkType.bugHunt].saveAfterLogin}`) + const loginPromptUrl: string = `${WorkIntakeFormRoutes[WorkType.bugHunt].loginPrompt}/${returnUrl}` + navigate(loginPromptUrl) + } + const onSave: (val: any) => Promise = val => { if (!isLoggedIn) { goToLoginStep(val) @@ -185,45 +215,28 @@ const BugHuntIntakeForm: React.FC = () => { .finally(() => setLoading(false)) } - const handleSaveSuccess: () => void = () => { - if (action === 'save') { - navigate(`${dashboardRoute}/draft`) - } else if (action === 'submit') { - const nextUrl: string = `${WorkIntakeFormRoutes[WorkType.bugHunt].review}/${workId || challenge?.id}` - navigate(nextUrl) - } - } - const onSaveSuccess: () => void = () => { setSaveSuccess(true) } - const goToLoginStep: (formData: any) => void = (formData: any) => { - if (localStorage) { - localStorage.setItem('challengeInProgress', JSON.stringify(formData)) - localStorage.setItem('challengeInProgressType', WorkType.bugHunt) - } - - const returnUrl: string = encodeURIComponent(`${window.location.origin}${WorkIntakeFormRoutes[WorkType.bugHunt].saveAfterLogin}`) - const loginPromptUrl: string = `${WorkIntakeFormRoutes[WorkType.bugHunt].loginPrompt}/${returnUrl}` - navigate(loginPromptUrl) - } - /** * This function is used to decide whether SAVE FOR LATER button should be enabled or not * @param isPrimaryGroup whether its a primary group or not * @param index the index of the button * @returns true or false depending on whether its SAVE FOR LATER */ - function shouldDisableButton(isPrimaryGroup: boolean, index: number): boolean { - // SAVE FOR LATER belongs to primary group and its index is 0, we are interested only for that particular case - // else return false which means not disabled from this function - if (isPrimaryGroup && index === 0) { - return disableSaveForLater - } + const shouldDisableButton: (isPrimaryGroup: boolean, index: number) => boolean + = useCallback((isPrimaryGroup: boolean, index: number) => { + + // SAVE FOR LATER belongs to primary group and its index is 0, + // we are interested only for that particular case + // else return false which means not disabled from this function + if (isPrimaryGroup && index === 0) { + return disableSaveForLater + } - return false - } + return false + }, [disableSaveForLater]) return ( <> From 6b451488837074d2bce9aac0ef489caa07367d19 Mon Sep 17 00:00:00 2001 From: Brooke Date: Wed, 16 Nov 2022 11:26:58 -0800 Subject: [PATCH 09/10] PROD-2614 clean up --- .../work-provider/work-functions/work-factory/work.factory.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src-ts/tools/work/work-lib/work-provider/work-functions/work-factory/work.factory.ts b/src-ts/tools/work/work-lib/work-provider/work-functions/work-factory/work.factory.ts index b16fdf4cc..ff0b2128e 100644 --- a/src-ts/tools/work/work-lib/work-provider/work-functions/work-factory/work.factory.ts +++ b/src-ts/tools/work/work-lib/work-provider/work-functions/work-factory/work.factory.ts @@ -1,6 +1,7 @@ /* eslint-disable @typescript-eslint/no-explicit-any */ import moment from 'moment' +import { workGetSelectedPackageFormatted } from '..' import { WorkConfigConstants, WorkStrings } from '../../../work-constants' import { ActivateWorkRequest, @@ -26,7 +27,6 @@ import { WorkTypeCategory, WorkTypeConfig, } from '../work-store' -import { getSelectedPackageFormatted } from '../work.functions' export interface FormDetail { key: string, @@ -314,7 +314,7 @@ function buildFormDataBugHunt(formData: any): ReadonlyArray { { key: ChallengeMetadataName.packageType, title: ChallengeMetadataTitle.bugHuntPackage, - value: getSelectedPackageFormatted(formData.packageType), + value: workGetSelectedPackageFormatted(formData.packageType), }, ] } From 38e064e5d575dd62fb13c1ab5761979fbb74939c Mon Sep 17 00:00:00 2001 From: Brooke Date: Wed, 16 Nov 2022 11:34:09 -0800 Subject: [PATCH 10/10] PROD-2614 clean up --- .../work-lib/work-provider/work-functions/work.functions.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src-ts/tools/work/work-lib/work-provider/work-functions/work.functions.ts b/src-ts/tools/work/work-lib/work-provider/work-functions/work.functions.ts index dc0667cb2..5111589cd 100644 --- a/src-ts/tools/work/work-lib/work-provider/work-functions/work.functions.ts +++ b/src-ts/tools/work/work-lib/work-provider/work-functions/work.functions.ts @@ -1,6 +1,9 @@ import { PaymentMethodResult, Stripe, StripeCardNumberElement } from '@stripe/stripe-js' import { FormCard, GenericDataObject, Page, textFormatMoneyLocaleString, UserProfile } from '../../../../../lib' +// this has to be imported directly from the file bc the order of operations +// that items are loaded in the barrel file this config is empty and throws an error +// eslint-disable-next-line ordered-imports/ordered-imports import BugHuntPricingConfig from '../../../work-self-service/intake-forms/bug-hunt/bug-hunt.form.pricing-config' import { WorkByStatus } from './work-by-status.model'