Skip to content

Commit 2a22680

Browse files
authored
Merge pull request #383 from topcoder-platform/PROD-2614_Self-service_payment
PROD-2799 PROD-2708 PROD-2707 PROD-2675 PROD-2672 PROD-2648 PROD-2641 PROD-2636 PROD-2622 PROD-2616 -> Fix issues in bug hunt self-service -> dev
2 parents bf6dd98 + 5d5fbdb commit 2a22680

File tree

35 files changed

+649
-317
lines changed

35 files changed

+649
-317
lines changed

src-ts/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,3 +23,4 @@ export {
2323
} from './lib'
2424
export * from './tools'
2525
export * from './utils'
26+
export * from './lib/svgs'

src-ts/lib/button/Button.tsx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ export interface ButtonProps {
1616
readonly elementType?: keyof JSX.IntrinsicElements
1717
readonly hidden?: boolean
1818
readonly icon?: FC<SVGProps<SVGSVGElement>>
19+
readonly id?: string
1920
readonly label?: string
2021
readonly name?: string
2122
readonly onClick?: (event?: any) => void
@@ -79,6 +80,8 @@ const Button: FC<ButtonProps> = (props: ButtonProps) => {
7980
tabIndex={props.tabIndex}
8081
title={props.title}
8182
type={props.type || 'button'}
83+
id={props.id}
84+
value={props.id}
8285
>
8386
{content}
8487
</button>

src-ts/lib/contact-support-form/ContactSupportForm.tsx

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
1-
import { FC, useContext } from 'react'
1+
import { Dispatch, FC, SetStateAction, useContext, useEffect, useState } from 'react'
22

33
import { Form, FormDefinition, formGetInputModel, FormInputModel } from '../form'
4+
import { LoadingSpinner } from '../loading-spinner'
45
import { profileContext, ProfileContextData } from '../profile-provider'
56

67
import { ContactSupportFormField } from './contact-support-form.config'
@@ -18,6 +19,15 @@ const ContactSupportForm: FC<ContactSupportFormProps> = (props: ContactSupportFo
1819

1920
const { profile }: ProfileContextData = useContext(profileContext)
2021

22+
const [loading, setLoading]: [boolean, Dispatch<SetStateAction<boolean>>] = useState<boolean>(false)
23+
const [saveOnSuccess, setSaveOnSuccess]: [boolean, Dispatch<SetStateAction<boolean>>] = useState<boolean>(false)
24+
25+
useEffect(() => {
26+
if (!loading && saveOnSuccess) {
27+
props.onSave()
28+
}
29+
}, [loading, saveOnSuccess])
30+
2131
function generateRequest(inputs: ReadonlyArray<FormInputModel>): ContactSupportRequest {
2232
const firstName: string = formGetInputModel(inputs, ContactSupportFormField.first).value as string
2333
const lastName: string = formGetInputModel(inputs, ContactSupportFormField.last).value as string
@@ -34,10 +44,11 @@ const ContactSupportForm: FC<ContactSupportFormProps> = (props: ContactSupportFo
3444
}
3545

3646
async function saveAsync(request: ContactSupportRequest): Promise<void> {
47+
setLoading(true)
3748
return contactSupportSubmitRequestAsync(request)
3849
.then(() => {
39-
props.onSave()
40-
})
50+
setSaveOnSuccess(true)
51+
}).finally(() => setLoading(false))
4152
}
4253

4354
const emailElement: JSX.Element | undefined = !!profile?.email
@@ -50,6 +61,7 @@ const ContactSupportForm: FC<ContactSupportFormProps> = (props: ContactSupportFo
5061

5162
return (
5263
<>
64+
<LoadingSpinner hide={!loading} type='Overlay' />
5365
<div className={styles['contact-support-intro']}>
5466
<p>
5567
Hi {profile?.firstName || 'there'}, we're here to help.

src-ts/lib/form/Form.tsx

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ interface FormProps<ValueType, RequestType> {
3838
readonly resetFormAfterSave?: boolean
3939
readonly resetFormOnUnmount?: boolean
4040
readonly save: (value: RequestType) => Promise<void>
41+
readonly shouldDisableButton?: (isPrimaryGroup: boolean, index: number) => boolean
4142
}
4243

4344
const Form: <ValueType extends any, RequestType extends any>(props: FormProps<ValueType, RequestType>) => JSX.Element
@@ -146,21 +147,29 @@ const Form: <ValueType extends any, RequestType extends any>(props: FormProps<Va
146147

147148
formInitializeValues(inputs, props.formValues)
148149

150+
const setOnClickOnReset: (button: FormButton) => FormButton = (button) => {
151+
// if this is a reset button, set its onclick to reset
152+
if (!!button.isReset) {
153+
button = {
154+
...button,
155+
onClick: onReset,
156+
}
157+
}
158+
159+
return button
160+
}
161+
149162
const createButtonGroup: (groups: ReadonlyArray<FormButton>, isPrimaryGroup: boolean) => Array<JSX.Element> = (groups, isPrimaryGroup) => {
150163
return groups.map((button, index) => {
151-
// if this is a reset button, set its onclick to reset
152-
if (!!button.isReset) {
153-
button = {
154-
...button,
155-
onClick: onReset,
156-
}
157-
}
164+
button = setOnClickOnReset(button)
165+
166+
const disabled: boolean = (button.isSubmit && isFormInvalid) || !!props.shouldDisableButton?.(isPrimaryGroup, index)
158167

159168
return (
160169
<Button
161170
{...button}
162171
key={button.label || `button-${index}`}
163-
disable={button.isSubmit && isFormInvalid}
172+
disable={disabled}
164173
tabIndex={button.notTabble ? -1 : index + (inputs ? inputs.length : 0) + (formDef.tabIndexStart || 0)}
165174
/>
166175
)

src-ts/lib/form/form-button.model.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,10 @@ import { ButtonSize, ButtonStyle, ButtonType } from '../button'
55
export interface FormButton {
66
readonly buttonStyle?: ButtonStyle
77
hidden?: boolean,
8-
readonly icon?: FC<SVGProps<SVGSVGElement>>
8+
icon?: FC<SVGProps<SVGSVGElement>>
99
readonly isReset?: boolean
1010
readonly isSubmit?: boolean
11-
readonly label?: string
11+
label?: string
1212
readonly notTabble?: boolean
1313
onClick?: (event?: any) => void
1414
readonly route?: string

src-ts/lib/form/form-functions/form.functions.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ export async function onSubmitAsync<T>(
7979

8080
// get the dirty fields before we validate b/c validation marks them dirty on submit
8181
const dirty: FormInputModel | undefined = inputs?.find(fieldDef => !!fieldDef.dirty)
82+
8283
// if there are any validation errors, display a message and stop submitting
8384
// NOTE: need to check this before we check if the form is dirty bc you
8485
// could have a form that's not dirty but has errors and you wouldn't

src-ts/lib/form/form-groups/form-card-set/FormCardSet.module.scss

Lines changed: 135 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -16,25 +16,36 @@
1616
.card {
1717
flex: 1 1 0;
1818
margin-right: $space-xl;
19-
border: solid 1px $black-80;
2019
border-radius: $space-xs;
21-
padding: $space-lg;
22-
cursor: pointer;
20+
padding: $space-lg 0;
21+
background-color: $black-5;
22+
position: relative;
2323

24-
&.selected {
25-
background-color: $turq-160;
26-
border: 1px solid $turq-160;
24+
.popular-card {
25+
display: flex;
26+
flex-direction: row;
27+
justify-content: center;
28+
align-items: center;
29+
padding: $space-sm;
30+
31+
width: 100%;
32+
height: $space-xxxxl;
33+
background: $tc-grad19;
34+
border-radius: $space-sm $space-sm 0px 0px;
2735
color: $tc-white;
28-
svg {
29-
path {
30-
color: $tc-white;
31-
}
32-
}
36+
position: absolute;
37+
left: 0;
38+
top: -$space-xxl;
39+
}
40+
41+
&.mobile-popular {
42+
margin-top: $space-xxxl;
3343
}
3444

3545
@include ltemd {
3646
margin-right: 0;
3747
margin-bottom: $space-lg;
48+
padding-top: $space-xxl;
3849
&:last-child {
3950
margin-bottom: 0;
4051
}
@@ -45,22 +56,134 @@
4556

4657
.card-header {
4758
text-align: center;
59+
display: flex;
60+
flex-direction: column;
61+
align-items: center;
62+
63+
h3 {
64+
margin: $space-lg;
65+
font-weight: 500;
66+
font-size: $space-mx;
67+
line-height: $space-mx;
68+
margin-top: $space-xxl;
69+
}
70+
71+
&.feature {
72+
visibility: hidden;
73+
74+
h3 {
75+
margin: $space-lg;
76+
margin-top: $space-xxl;
77+
font-size: $space-xxxxl;
78+
}
79+
}
80+
81+
&.mobile {
82+
h3 {
83+
font-size: $space-xxxxl;
84+
line-height: $space-xxxxl;
85+
margin-top: $space-md;
86+
margin-bottom: $space-xxl;
87+
}
88+
}
89+
}
90+
91+
.card-header-features {
92+
visibility: hidden;
93+
94+
h3 {
95+
margin: $space-lg;
96+
}
4897
}
4998

5099
.card-section {
51100
margin: $space-lg 0;
52101

102+
.row {
103+
height: auto;
104+
}
105+
106+
.row-divider {
107+
height: $border-xs;
108+
border-bottom: $border solid $black-10;
109+
width: auto;
110+
margin: 0;
111+
}
112+
53113
.card-row {
54114
display: flex;
115+
padding: $space-md;
116+
align-items: center;
117+
min-height: calc($space-lg + $space-mx);
118+
position: relative;
55119

56120
.card-row-col {
57121
align-content: center;
58122
align-items: center;
59-
width: 50%;
60123
flex-wrap: wrap;
61124
flex-grow: 1;
125+
126+
&.mobile {
127+
display: flex;
128+
justify-content: flex-start;
129+
}
130+
131+
&.info-col {
132+
display: flex;
133+
}
134+
135+
svg {
136+
display: inline;
137+
margin-left: $space-xs;
138+
}
139+
140+
&.center {
141+
text-align: center;
142+
}
143+
144+
.label {
145+
@include ltemd {
146+
font-size: 10px;
147+
}
148+
}
149+
150+
.info-icon {
151+
margin-left: $space-sm;
152+
color: $turq-160;
153+
cursor: pointer;
154+
outline: none;
155+
}
62156
}
63157
}
158+
&.mobile {
159+
.feature-name {
160+
width: 100%;
161+
}
162+
.center {
163+
width: 40%;
164+
}
165+
}
166+
&.feature {
167+
margin: calc($space-lg - 0.2px) 0;
168+
}
169+
}
170+
171+
&.feature {
172+
background-color: $tc-white;
173+
margin-right: 0;
174+
175+
.card-row-col:nth-child(2) {
176+
display: none;
177+
}
178+
179+
.row-divider {
180+
width: 100%;
181+
margin-left: 6%;
182+
}
183+
184+
&.mobile {
185+
display: none;
186+
}
64187
}
65188
}
66189

0 commit comments

Comments
 (0)