Skip to content

Commit c12c790

Browse files
committed
MP-216 address form
1 parent 484e7a6 commit c12c790

File tree

4 files changed

+149
-6
lines changed

4 files changed

+149
-6
lines changed

src/apps/accounts/src/settings/tabs/account/address/MemberAddress.module.scss

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,5 +15,13 @@
1515
>p {
1616
max-width: 380px;
1717
}
18+
19+
.form {
20+
.formCTAs {
21+
margin-top: $sp-4;
22+
padding-top: $sp-4;
23+
border-top: 2px solid $black-10;
24+
}
25+
}
1826
}
1927
}

src/apps/accounts/src/settings/tabs/account/address/MemberAddress.tsx

Lines changed: 130 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,15 @@
1-
import { Dispatch, FC, useCallback, useEffect, useMemo, useState } from 'react'
1+
import { Dispatch, FC, SetStateAction, useCallback, useEffect, useMemo, useState } from 'react'
22
import { toast } from 'react-toastify'
3+
import { bind, trim } from 'lodash'
4+
import classNames from 'classnames'
35

46
import {
5-
Collapsible,
7+
Button,
8+
Collapsible, InputSelect, InputText,
69
} from '~/libs/ui'
710
import {
11+
CountryLookup,
12+
useCountryLookup,
813
UserProfile,
914
} from '~/libs/core'
1015

@@ -15,12 +20,50 @@ interface MemberAddressProps {
1520
}
1621

1722
const MemberAddress: FC<MemberAddressProps> = (props: MemberAddressProps) => {
23+
const countryLookup: CountryLookup[] | undefined
24+
= useCountryLookup()
25+
1826
const [formValues, setFormValues]: [any, Dispatch<any>] = useState({
1927
country: props.profile.homeCountryCode || props.profile.competitionCountryCode,
2028
...props.profile.addresses ? props.profile.addresses[0] : {},
2129
})
2230

23-
console.log('formValues', formValues)
31+
const [formErrors, setFormErrors]: [
32+
{ [key: string]: string },
33+
Dispatch<SetStateAction<{ [key: string]: string }>>
34+
]
35+
= useState<{ [key: string]: string }>({})
36+
37+
const [isSaving, setIsSaving]: [boolean, Dispatch<SetStateAction<boolean>>]
38+
= useState<boolean>(false)
39+
40+
const [isFormChanged, setIsFormChanged]: [boolean, Dispatch<SetStateAction<boolean>>]
41+
= useState<boolean>(false)
42+
43+
function handleFormValueChange(key: string, event: React.ChangeEvent<HTMLInputElement>): void {
44+
const oldFormValues = { ...formValues }
45+
46+
setFormValues({
47+
...oldFormValues,
48+
[key]: event.target.value,
49+
})
50+
setIsFormChanged(true)
51+
}
52+
53+
function handleFormAction(): void {
54+
if (!trim(formValues.city)) {
55+
setFormErrors({ city: 'Please select a city' })
56+
return
57+
}
58+
59+
if (!formValues.country) {
60+
setFormErrors({ country: 'Please select a country' })
61+
return
62+
}
63+
64+
setIsSaving(true)
65+
66+
}
2467

2568
return (
2669
<Collapsible
@@ -33,9 +76,90 @@ const MemberAddress: FC<MemberAddressProps> = (props: MemberAddressProps) => {
3376
Sharing your contact details will never result in robocalls about health insurance plans or junk mail.
3477
</p>
3578

36-
<div className={styles.formWrap}>
37-
38-
</div>
79+
<form
80+
className={classNames(styles.formWrap)}
81+
>
82+
<div className={styles.form}>
83+
<InputText
84+
name='address'
85+
label='Address'
86+
error={formErrors.streetAddr1}
87+
placeholder='Your address'
88+
dirty
89+
tabIndex={0}
90+
type='text'
91+
onChange={bind(handleFormValueChange, this, 'address')}
92+
value={formValues.streetAddr1}
93+
/>
94+
<InputText
95+
name='address2'
96+
label='Address 2'
97+
error={formErrors.streetAddr2}
98+
placeholder='Your address continued'
99+
dirty
100+
tabIndex={0}
101+
type='text'
102+
onChange={bind(handleFormValueChange, this, 'address2')}
103+
value={formValues.streetAddr2}
104+
/>
105+
<InputText
106+
name='city'
107+
label='City *'
108+
error={formErrors.city}
109+
placeholder='Which city do you live in?'
110+
dirty
111+
tabIndex={0}
112+
type='text'
113+
onChange={bind(handleFormValueChange, this, 'city')}
114+
value={formValues.city}
115+
/>
116+
<InputText
117+
name='state'
118+
label='State'
119+
error={formErrors.state}
120+
placeholder='State'
121+
dirty
122+
tabIndex={0}
123+
type='text'
124+
onChange={bind(handleFormValueChange, this, 'state')}
125+
value={formValues.state}
126+
/>
127+
<InputText
128+
name='zip'
129+
label='Zip/Postal Code'
130+
error={formErrors.zip}
131+
placeholder='Your Zip or Postal Code'
132+
dirty
133+
tabIndex={0}
134+
type='text'
135+
onChange={bind(handleFormValueChange, this, 'zip')}
136+
value={formValues.zip}
137+
/>
138+
<InputSelect
139+
options={(countryLookup || []).map((cl: CountryLookup) => ({
140+
label: cl.country,
141+
value: cl.countryCode,
142+
}))}
143+
value={formValues.country}
144+
onChange={bind(handleFormValueChange, this, 'country')}
145+
name='country'
146+
label='Country *'
147+
error={formErrors.country}
148+
placeholder='Select a Country'
149+
dirty
150+
/>
151+
152+
<div className={styles.formCTAs}>
153+
<Button
154+
secondary
155+
size='lg'
156+
label='Save Changes'
157+
onClick={handleFormAction}
158+
disabled={isSaving || !isFormChanged}
159+
/>
160+
</div>
161+
</div>
162+
</form>
39163
</Collapsible>
40164
)
41165
}

src/libs/core/lib/profile/data-providers/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,3 +10,4 @@ export * from './useMemberMFAStatus'
1010
export * from './useDiceIdConnection'
1111
export * from './useMemberTraits'
1212
export * from './useMemberDevicesLookup'
13+
export * from './useCountryLookup'
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import { SWRResponse } from 'swr'
2+
import useSWRImmutable from 'swr/immutable'
3+
4+
import { CountryLookup, countryLookupURL } from '~/libs/core'
5+
6+
export function useCountryLookup(): CountryLookup[] | undefined {
7+
const { data }: SWRResponse = useSWRImmutable(countryLookupURL)
8+
9+
return data ? data.result?.content : undefined
10+
}

0 commit comments

Comments
 (0)