Skip to content

Commit dadc26c

Browse files
committed
add AddressForm
1 parent a63e142 commit dadc26c

File tree

1 file changed

+199
-0
lines changed

1 file changed

+199
-0
lines changed
Lines changed: 199 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,199 @@
1+
import { component$, useSignal, useStore, useTask$ } from '@builder.io/qwik';
2+
import { Form } from '@builder.io/qwik-city';
3+
import {
4+
SfButton,
5+
SfCheckbox,
6+
SfInput,
7+
SfLoaderCircular,
8+
SfSelect,
9+
} from 'qwik-storefront-ui';
10+
import { useAddressForm } from '~/routes/layout';
11+
import { FormHelperText } from '../Form/FormHelperText';
12+
import { FormLabel } from '../Form/FormLabel';
13+
14+
type AddressFields =
15+
| 'firstName'
16+
| 'lastName'
17+
| 'phone'
18+
| 'country'
19+
| 'streetName'
20+
| 'streetNumber'
21+
| 'city'
22+
| 'state'
23+
| 'postalCode';
24+
25+
export type AddressFormFields = Record<AddressFields, string>;
26+
27+
export type AddressFormProps = {
28+
type: 'billingAddress' | 'shippingAddress';
29+
savedAddress?: AddressFormFields | undefined;
30+
};
31+
32+
export const AddressForm = component$<AddressFormProps>(
33+
({ type, savedAddress }) => {
34+
const addressFormAction = useAddressForm();
35+
const formRefSig = useSignal<HTMLFormElement>();
36+
useStore<{ value: AddressFormFields }>({
37+
value: {
38+
firstName: savedAddress?.firstName || '',
39+
lastName: savedAddress?.lastName || '',
40+
phone: savedAddress?.phone || '',
41+
country: savedAddress?.country || '',
42+
streetName: savedAddress?.streetName || '',
43+
streetNumber: savedAddress?.streetNumber || '',
44+
city: savedAddress?.city || '',
45+
state: savedAddress?.state || '',
46+
postalCode: savedAddress?.postalCode || '',
47+
},
48+
});
49+
const countries = ['US'];
50+
const states = ['California'];
51+
52+
useTask$(({ track }) => {
53+
const success = track(() => addressFormAction.value?.success);
54+
if (success) {
55+
if (formRefSig.value) {
56+
formRefSig.value.reset();
57+
}
58+
}
59+
});
60+
61+
return (
62+
<Form
63+
class='grid grid-cols-1 md:grid-cols-[50%_1fr_120px] gap-4'
64+
data-testid='address-form'
65+
action={addressFormAction}
66+
ref={formRefSig}
67+
>
68+
<label>
69+
<FormLabel>{$localize`form.firstNameLabel`}</FormLabel>
70+
<SfInput
71+
name='firstName'
72+
autoComplete='given-name'
73+
// defaultValue={addressStore.firstName} <-- fix lib <-- fix lib
74+
required
75+
/>
76+
</label>
77+
<label class='md:col-span-2'>
78+
<FormLabel>{$localize`form.lastNameLabel`}</FormLabel>
79+
<SfInput
80+
name='lastName'
81+
autoComplete='family-name'
82+
// defaultValue={addressStore.lastName} <-- fix lib
83+
required
84+
/>
85+
</label>
86+
<label class='md:col-span-3'>
87+
<FormLabel>{$localize`form.phoneLabel`}</FormLabel>
88+
<SfInput
89+
name='phone'
90+
type='tel'
91+
autoComplete='tel'
92+
// defaultValue={addressStore.phone} <-- fix lib
93+
required
94+
/>
95+
</label>
96+
<label class='md:col-span-3'>
97+
<FormLabel>{$localize`form.countryLabel`}</FormLabel>
98+
<SfSelect
99+
name='country'
100+
placeholder={$localize`form.selectPlaceholder`}
101+
autoComplete='country-name'
102+
// defaultValue={addressStore.country} <-- fix lib
103+
required
104+
>
105+
{countries.map((country) => (
106+
<option key={country}>{country}</option>
107+
))}
108+
</SfSelect>
109+
</label>
110+
<label class='md:col-span-2'>
111+
<FormLabel>{$localize`form.streetNameLabel`}</FormLabel>
112+
<SfInput
113+
name='streetName'
114+
autoComplete='address-line1'
115+
// defaultValue={// addressStore.streetName} <-- fix lib
116+
required
117+
/>
118+
<FormHelperText>{$localize`form.streetNameHelp`}</FormHelperText>
119+
</label>
120+
<label>
121+
<FormLabel>{$localize`form.streetNumberLabel`}</FormLabel>
122+
<SfInput
123+
name='streetNumber'
124+
// defaultValue={// addressStore.streetNumber} <-- fix lib
125+
/>
126+
<FormHelperText>{$localize`form.streetNumberHelp`}</FormHelperText>
127+
</label>
128+
<label class='md:col-span-3'>
129+
<FormLabel>{$localize`form.cityLabel`}</FormLabel>
130+
<SfInput
131+
name='city'
132+
autoComplete='address-level2'
133+
// defaultValue={// addressStore.city} <-- fix lib
134+
required
135+
/>
136+
</label>
137+
<label class='md:col-span-2'>
138+
<FormLabel>{$localize`form.stateLabel`}</FormLabel>
139+
<SfSelect
140+
name='state'
141+
autoComplete='address-level1'
142+
// defaultValue={// addressStore.state} <-- fix lib
143+
placeholder={$localize`form.selectPlaceholder`}
144+
required
145+
>
146+
{states.map((state) => (
147+
<option key={state}>{state}</option>
148+
))}
149+
</SfSelect>
150+
</label>
151+
<label>
152+
<FormLabel>{$localize`form.postalCodeLabel`}</FormLabel>
153+
<SfInput
154+
name='postalCode'
155+
autoComplete='postal-code'
156+
// defaultValue={// addressStore.postalCode} <-- fix lib
157+
required
158+
/>
159+
</label>
160+
161+
{type === 'billingAddress' && (
162+
<label class='md:col-span-3 flex items-center gap-2'>
163+
<SfCheckbox name='useAsShipping' />
164+
{$localize`form.useAsShippingLabel`}
165+
</label>
166+
)}
167+
168+
<div class='md:col-span-3 flex justify-end gap-4'>
169+
<SfButton
170+
type='reset'
171+
onClick$={() => {
172+
if (formRefSig.value) {
173+
formRefSig.value.reset();
174+
}
175+
}}
176+
class='max-md:w-1/2'
177+
variant='secondary'
178+
>
179+
{$localize`checkout:contactInfo.clearAll`}
180+
</SfButton>
181+
<SfButton
182+
type='submit'
183+
class='w-1/2 md:w-1/6'
184+
disabled={addressFormAction.isRunning}
185+
>
186+
{addressFormAction.isRunning ? (
187+
<SfLoaderCircular
188+
class='flex justify-center items-center'
189+
size='sm'
190+
/>
191+
) : (
192+
$localize`checkout:contactInfo.save`
193+
)}
194+
</SfButton>
195+
</div>
196+
</Form>
197+
);
198+
}
199+
);

0 commit comments

Comments
 (0)