-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
5 changed files
with
267 additions
and
97 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,112 +1,73 @@ | ||
import { required, useForm } from '@modular-forms/preact' | ||
import { useSignalEffect } from '@preact/signals' | ||
|
||
import { Porting } from '../types' | ||
import { sanitizeSubmitData } from './sanitizeSubmitData' | ||
import { StepAddressForm, StepAddressFormData } from './StepAddressForm' | ||
import { | ||
StepCarrierDetailsForm, | ||
StepCarrierDetailsFormData, | ||
} from './StepCarrierDetailsForm' | ||
import { | ||
StepDonorApprovalForm, | ||
StepDonorApprovalFormData, | ||
} from './StepDonorApproval' | ||
import { | ||
StepHolderDetailsForm, | ||
StepHolderDetailsFormData, | ||
} from './StepHolderDetailsForm' | ||
import { wizardStep } from './wizardStep' | ||
|
||
type Props = { | ||
porting: Porting | ||
onValidationChange?: (event: { isValid: boolean }) => unknown | ||
onSubmit: (data: Partial<PortingForm>) => unknown | ||
onSubmit: (data: Partial<PortingFormData>) => unknown | ||
} | ||
|
||
type PortingForm = { | ||
accountPin: string | ||
accountNumber: string | ||
birthday: string | ||
firstName: string | ||
lastName: string | ||
} | ||
type PortingFormData = | ||
| StepCarrierDetailsFormData | ||
| StepHolderDetailsFormData | ||
| { address?: StepAddressFormData } | ||
| StepDonorApprovalFormData | ||
|
||
export function PortingForm({ porting, onValidationChange, onSubmit }: Props) { | ||
const [portingForm, { Form, Field }] = useForm<PortingForm>({ | ||
initialValues: { | ||
accountNumber: porting.accountNumber || '', | ||
accountPin: '', | ||
birthday: porting.birthday || '', | ||
firstName: porting.firstName || '', | ||
lastName: porting.lastName || '', | ||
}, | ||
validateOn: 'blur', | ||
}) | ||
|
||
useSignalEffect(() => { | ||
const isValid = !portingForm.invalid.value | ||
onValidationChange?.({ isValid }) | ||
}) | ||
const step = wizardStep(porting) | ||
|
||
return ( | ||
<Form | ||
id="gigsPortingEmbedForm" // TODO: make customizable | ||
role="form" | ||
shouldDirty // only include changed fields in the onSubmit handler | ||
onSubmit={(data) => { | ||
const sanitizedData = sanitizeSubmitData(data) | ||
return onSubmit(sanitizedData) | ||
}} | ||
> | ||
<Field name="accountNumber" validate={[required('Please enter')]}> | ||
{(field, props) => ( | ||
<div> | ||
<label for="accountNumber">Account Number</label> | ||
<input | ||
id="accountNumber" | ||
type="text" | ||
value={field.value} | ||
{...props} | ||
/> | ||
{field.error && <div>{field.error}</div>} | ||
</div> | ||
)} | ||
</Field> | ||
if (step === 'carrierDetails') { | ||
return ( | ||
<StepCarrierDetailsForm | ||
porting={porting} | ||
onValidationChange={onValidationChange} | ||
onSubmit={(data) => onSubmit(data)} | ||
/> | ||
) | ||
} | ||
|
||
<Field | ||
name="accountPin" | ||
validate={porting.accountPinExists ? [] : [required('Please enter')]} | ||
> | ||
{(field, props) => ( | ||
<div> | ||
<label for="accountPin">Account PIN</label> | ||
<input | ||
id="accountPin" | ||
type="text" | ||
placeholder={porting.accountPinExists ? '••••' : undefined} | ||
{...props} | ||
/> | ||
{field.error && <div>{field.error}</div>} | ||
</div> | ||
)} | ||
</Field> | ||
if (step === 'holderDetails') { | ||
return ( | ||
<StepHolderDetailsForm | ||
porting={porting} | ||
onValidationChange={onValidationChange} | ||
onSubmit={(data) => onSubmit(data)} | ||
/> | ||
) | ||
} | ||
|
||
<Field name="birthday" validate={[required('Please enter')]}> | ||
{(field, props) => ( | ||
<div> | ||
<label for="birthday">Birthday</label> | ||
<input id="birthday" type="text" value={field.value} {...props} /> | ||
{field.error && <div>{field.error}</div>} | ||
</div> | ||
)} | ||
</Field> | ||
if (step === 'address') { | ||
return ( | ||
<StepAddressForm | ||
porting={porting} | ||
onValidationChange={onValidationChange} | ||
onSubmit={(data) => onSubmit({ address: data })} | ||
/> | ||
) | ||
} | ||
|
||
<Field name="firstName" validate={[required('Please enter')]}> | ||
{(field, props) => ( | ||
<div> | ||
<label for="firstName">First Name</label> | ||
<input id="firstName" type="text" value={field.value} {...props} /> | ||
{field.error && <div>{field.error}</div>} | ||
</div> | ||
)} | ||
</Field> | ||
if (step === 'donorApproval') { | ||
return ( | ||
<StepDonorApprovalForm | ||
porting={porting} | ||
onValidationChange={onValidationChange} | ||
onSubmit={(data) => onSubmit(data)} | ||
/> | ||
) | ||
} | ||
|
||
<Field name="lastName" validate={[required('Please enter')]}> | ||
{(field, props) => ( | ||
<div> | ||
<label for="lastName">Last Name</label> | ||
<input id="lastName" type="text" value={field.value} {...props} /> | ||
{field.error && <div>{field.error}</div>} | ||
</div> | ||
)} | ||
</Field> | ||
</Form> | ||
) | ||
return null | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
import { useForm } from '@modular-forms/preact' | ||
import { useSignalEffect } from '@preact/signals' | ||
|
||
import { Porting } from '../types' | ||
|
||
export type StepAddressFormData = { | ||
city: string | ||
country: string | ||
line1: string | ||
line2: string | null | ||
postalCode: string | ||
state: string | null | ||
} | ||
|
||
type Props = { | ||
porting: Porting | ||
onValidationChange?: (event: { isValid: boolean }) => unknown | ||
onSubmit: (data: StepAddressFormData) => unknown | ||
} | ||
|
||
export function StepAddressForm({ | ||
porting, | ||
onValidationChange, | ||
onSubmit, | ||
}: Props) { | ||
const [portingForm, { Form, Field }] = useForm<StepAddressFormData>({ | ||
Check failure on line 26 in lib/PortingEmbed/StepAddressForm.tsx GitHub Actions / build
|
||
initialValues: { | ||
city: porting.address?.city ?? '', | ||
country: porting.address?.country ?? '', | ||
line1: porting.address?.line1 ?? '', | ||
line2: porting.address?.line2 ?? '', | ||
postalCode: porting.address?.postalCode ?? '', | ||
state: porting.address?.state ?? '', | ||
}, | ||
validateOn: 'blur', | ||
}) | ||
|
||
useSignalEffect(() => { | ||
const isValid = !portingForm.invalid.value | ||
onValidationChange?.({ isValid }) | ||
}) | ||
|
||
return ( | ||
<Form | ||
id="gigsPortingEmbedForm" // TODO: make customizable | ||
role="form" | ||
onSubmit={(data) => { | ||
// The address form is always submitted as a whole, never partially. | ||
// line2 and state are optional and must be converted to null if empty. | ||
const sanitizedData = { | ||
...data, | ||
line2: data.line2 || null, | ||
state: data.state || null, | ||
} | ||
|
||
return onSubmit(sanitizedData) | ||
}} | ||
> | ||
{porting.id} | ||
</Form> | ||
) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
import { useForm } from '@modular-forms/preact' | ||
import { useSignalEffect } from '@preact/signals' | ||
|
||
import { Porting } from '../types' | ||
import { sanitizeSubmitData } from './sanitizeSubmitData' | ||
|
||
export type StepCarrierDetailsFormData = { | ||
accountNumber?: string | ||
accountPin?: string | ||
} | ||
|
||
type Props = { | ||
porting: Porting | ||
onValidationChange?: (event: { isValid: boolean }) => unknown | ||
onSubmit: (data: Partial<StepCarrierDetailsFormData>) => unknown | ||
} | ||
|
||
export function StepCarrierDetailsForm({ | ||
porting, | ||
onValidationChange, | ||
onSubmit, | ||
}: Props) { | ||
const [portingForm, { Form, Field }] = useForm<StepCarrierDetailsFormData>({ | ||
Check failure on line 23 in lib/PortingEmbed/StepCarrierDetailsForm.tsx GitHub Actions / build
|
||
initialValues: { | ||
accountNumber: porting.accountNumber ?? '', | ||
accountPin: '', | ||
}, | ||
validateOn: 'blur', | ||
}) | ||
|
||
useSignalEffect(() => { | ||
const isValid = !portingForm.invalid.value | ||
onValidationChange?.({ isValid }) | ||
}) | ||
|
||
return ( | ||
<Form | ||
id="gigsPortingEmbedForm" // TODO: make customizable | ||
role="form" | ||
shouldDirty // only include changed fields in the onSubmit handler | ||
onSubmit={(data) => { | ||
const sanitizedData = sanitizeSubmitData(data) | ||
return onSubmit(sanitizedData) | ||
}} | ||
> | ||
{porting.id} | ||
</Form> | ||
) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
import { useForm } from '@modular-forms/preact' | ||
import { useSignalEffect } from '@preact/signals' | ||
|
||
import { Porting } from '../types' | ||
import { sanitizeSubmitData } from './sanitizeSubmitData' | ||
|
||
export type StepDonorApprovalFormData = { | ||
donorProviderApproval?: boolean | ||
} | ||
|
||
type Props = { | ||
porting: Porting | ||
onValidationChange?: (event: { isValid: boolean }) => unknown | ||
onSubmit: (data: Partial<StepDonorApprovalFormData>) => unknown | ||
} | ||
|
||
export function StepDonorApprovalForm({ | ||
porting, | ||
onValidationChange, | ||
onSubmit, | ||
}: Props) { | ||
const [portingForm, { Form, Field }] = useForm<StepDonorApprovalFormData>({ | ||
Check failure on line 22 in lib/PortingEmbed/StepDonorApproval.tsx GitHub Actions / build
|
||
initialValues: { | ||
donorProviderApproval: porting.donorProviderApproval ?? false, | ||
}, | ||
validateOn: 'blur', | ||
}) | ||
|
||
useSignalEffect(() => { | ||
const isValid = !portingForm.invalid.value | ||
onValidationChange?.({ isValid }) | ||
}) | ||
|
||
return ( | ||
<Form | ||
id="gigsPortingEmbedForm" // TODO: make customizable | ||
role="form" | ||
shouldDirty // only include changed fields in the onSubmit handler | ||
onSubmit={(data) => { | ||
const sanitizedData = sanitizeSubmitData(data) | ||
return onSubmit(sanitizedData) | ||
}} | ||
> | ||
{porting.id} | ||
</Form> | ||
) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
import { useForm } from '@modular-forms/preact' | ||
import { useSignalEffect } from '@preact/signals' | ||
|
||
import { Porting } from '../types' | ||
import { sanitizeSubmitData } from './sanitizeSubmitData' | ||
|
||
export type StepHolderDetailsFormData = { | ||
firstName?: string | ||
lastName?: string | ||
birthday?: string | ||
} | ||
|
||
type Props = { | ||
porting: Porting | ||
onValidationChange?: (event: { isValid: boolean }) => unknown | ||
onSubmit: (data: Partial<StepHolderDetailsFormData>) => unknown | ||
} | ||
|
||
export function StepHolderDetailsForm({ | ||
porting, | ||
onValidationChange, | ||
onSubmit, | ||
}: Props) { | ||
const [portingForm, { Form, Field }] = useForm<StepHolderDetailsFormData>({ | ||
Check failure on line 24 in lib/PortingEmbed/StepHolderDetailsForm.tsx GitHub Actions / build
|
||
initialValues: { | ||
firstName: porting.firstName ?? '', | ||
lastName: porting.lastName ?? '', | ||
birthday: porting.birthday ?? '', | ||
}, | ||
validateOn: 'blur', | ||
}) | ||
|
||
useSignalEffect(() => { | ||
const isValid = !portingForm.invalid.value | ||
onValidationChange?.({ isValid }) | ||
}) | ||
|
||
return ( | ||
<Form | ||
id="gigsPortingEmbedForm" // TODO: make customizable | ||
role="form" | ||
shouldDirty // only include changed fields in the onSubmit handler | ||
onSubmit={(data) => { | ||
const sanitizedData = sanitizeSubmitData(data) | ||
return onSubmit(sanitizedData) | ||
}} | ||
> | ||
{porting.id} | ||
</Form> | ||
) | ||
} |