Skip to content

Commit

Permalink
change date picker to year input in renew ITA flow
Browse files Browse the repository at this point in the history
  • Loading branch information
Fbasham committed Oct 15, 2024
1 parent f901de0 commit b3f1631
Show file tree
Hide file tree
Showing 8 changed files with 31 additions and 93 deletions.
2 changes: 1 addition & 1 deletion frontend/app/.server/domain/dtos/benefit-renewal.dto.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ export type BenefitRenewalRequestDto = Readonly<{
}>;
partnerInformation?: Readonly<{
confirm: boolean;
dateOfBirth: string;
yearOfBirth: string;
socialInsuranceNumber: string;
}>;
maritalStatus: string;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -291,13 +291,13 @@ function toRelatedPersons({ partnerInformation }: ToRelatedPersonArgs) {

interface ToRelatedPersonSpouseArgs {
confirm: boolean;
dateOfBirth: string;
yearOfBirth: string;
socialInsuranceNumber: string;
}

function toRelatedPersonSpouse({ confirm, dateOfBirth, socialInsuranceNumber }: ToRelatedPersonSpouseArgs) {
function toRelatedPersonSpouse({ confirm, yearOfBirth, socialInsuranceNumber }: ToRelatedPersonSpouseArgs) {
return {
PersonBirthDate: toDate(dateOfBirth),
PersonBirthDate: { date: yearOfBirth },
PersonRelationshipCode: {
ReferenceDataName: 'Spouse' as const,
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -268,13 +268,13 @@ function toRelatedPersons({ partnerInformation }: ToRelatedPersonArgs) {

interface ToRelatedPersonSpouseArgs {
confirm: boolean;
dateOfBirth: string;
yearOfBirth: string;
socialInsuranceNumber: string;
}

function toRelatedPersonSpouse({ confirm, dateOfBirth, socialInsuranceNumber }: ToRelatedPersonSpouseArgs) {
function toRelatedPersonSpouse({ confirm, yearOfBirth, socialInsuranceNumber }: ToRelatedPersonSpouseArgs) {
return {
PersonBirthDate: toDate(dateOfBirth),
PersonBirthDate: { date: yearOfBirth },
PersonRelationshipCode: {
ReferenceDataName: 'Spouse' as const,
},
Expand Down
2 changes: 1 addition & 1 deletion frontend/app/route-helpers/renew-route-helpers.server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ export interface RenewState {
};
readonly partnerInformation?: {
confirm: boolean;
dateOfBirth: string;
yearOfBirth: string;
socialInsuranceNumber: string;
};
readonly maritalStatus?: string;
Expand Down
4 changes: 2 additions & 2 deletions frontend/app/routes/public/renew/$id/ita/confirmation.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ export async function loader({ context: { configProvider, serviceProvider, sessi

const spouseInfo = {
confirm: state.partnerInformation.confirm,
birthday: toLocaleDateString(parseDateString(state.partnerInformation.dateOfBirth), locale),
yearOfBirth: state.partnerInformation.yearOfBirth,
sin: state.partnerInformation.socialInsuranceNumber,
};

Expand Down Expand Up @@ -209,7 +209,7 @@ export default function RenewFlowConfirm() {
<DescriptionListItem term={t('confirm.sin')}>
<span className="text-nowrap">{formatSin(spouseInfo.sin)}</span>
</DescriptionListItem>
<DescriptionListItem term={t('confirm.dob')}>{spouseInfo.birthday}</DescriptionListItem>
<DescriptionListItem term={t('confirm.year-of-birth')}>{spouseInfo.yearOfBirth}</DescriptionListItem>
<DescriptionListItem term={t('confirm.consent')}>{t('confirm.consent-answer')}</DescriptionListItem>
</dl>
</section>
Expand Down
87 changes: 15 additions & 72 deletions frontend/app/routes/public/renew/$id/ita/marital-status.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ import { z } from 'zod';

import pageIds from '../../../../page-ids.json';
import { Button, ButtonLink } from '~/components/buttons';
import { DatePickerField } from '~/components/date-picker-field';
import { useErrorSummary } from '~/components/error-summary';
import { InputCheckbox } from '~/components/input-checkbox';
import { InputPatternField } from '~/components/input-pattern-field';
Expand All @@ -22,7 +21,6 @@ import { Progress } from '~/components/progress';
import { loadRenewItaState } from '~/route-helpers/renew-ita-route-helpers.server';
import type { PartnerInformationState } from '~/route-helpers/renew-route-helpers.server';
import { renewStateHasPartner, saveRenewState } from '~/route-helpers/renew-route-helpers.server';
import { extractDateParts, getAgeFromDateString, isPastDateString, isValidDateString } from '~/utils/date-utils';
import { getEnv } from '~/utils/env-utils.server';
import { getTypedI18nNamespaces } from '~/utils/locale-utils';
import { getFixedT, getLocale } from '~/utils/locale-utils.server';
Expand Down Expand Up @@ -86,59 +84,23 @@ export async function action({ context: { session }, params, request }: ActionFu
.min(1, t('renew-ita:marital-status.error-message.marital-status-required')),
});

const partnerInformationSchema = z
.object({
confirm: z.boolean().refine((val) => val === true, t('renew-ita:marital-status.error-message.confirm-required')),
dateOfBirthYear: z.number({
required_error: t('renew-ita:marital-status.error-message.date-of-birth-year-required'),
invalid_type_error: t('renew-ita:marital-status.error-message.date-of-birth-year-number'),
}),
dateOfBirthMonth: z.number({
required_error: t('renew-ita:marital-status.error-message.date-of-birth-month-required'),
}),
dateOfBirthDay: z.number({
required_error: t('renew-ita:marital-status.error-message.date-of-birth-day-required'),
invalid_type_error: t('renew-ita:marital-status.error-message.date-of-birth-day-number'),
}),
dateOfBirth: z.string(),
socialInsuranceNumber: z
.string()
.trim()
.min(1, t('renew-ita:marital-status.error-message.sin-required'))
.refine(isValidSin, t('renew-ita:marital-status.error-message.sin-valid'))
.refine((sin) => isValidSin(sin) && formatSin(sin, '') !== state.partnerInformation?.socialInsuranceNumber, t('renew-ita:marital-status.error-message.sin-unique')),
})
.superRefine((val, ctx) => {
// At this point the year, month and day should have been validated as positive integer
const dateOfBirthParts = extractDateParts(`${val.dateOfBirthYear}-${val.dateOfBirthMonth}-${val.dateOfBirthDay}`);
const dateOfBirth = `${dateOfBirthParts.year}-${dateOfBirthParts.month}-${dateOfBirthParts.day}`;

if (!isValidDateString(dateOfBirth)) {
ctx.addIssue({ code: z.ZodIssueCode.custom, message: t('renew-ita:marital-status.error-message.date-of-birth-valid'), path: ['dateOfBirth'] });
} else if (!isPastDateString(dateOfBirth)) {
ctx.addIssue({ code: z.ZodIssueCode.custom, message: t('renew-ita:marital-status.error-message.date-of-birth-is-past'), path: ['dateOfBirth'] });
} else if (getAgeFromDateString(dateOfBirth) > 150) {
ctx.addIssue({ code: z.ZodIssueCode.custom, message: t('renew-ita:marital-status.error-message.date-of-birth-is-past-valid'), path: ['dateOfBirth'] });
}
})
.transform((val) => {
// At this point the year, month and day should have been validated as positive integer
const dateOfBirthParts = extractDateParts(`${val.dateOfBirthYear}-${val.dateOfBirthMonth}-${val.dateOfBirthDay}`);
return {
...val,
dateOfBirth: `${dateOfBirthParts.year}-${dateOfBirthParts.month}-${dateOfBirthParts.day}`,
};
}) satisfies z.ZodType<PartnerInformationState>;
const partnerInformationSchema = z.object({
confirm: z.boolean().refine((val) => val === true, t('renew-ita:marital-status.error-message.confirm-required')),
yearOfBirth: z.string().trim().min(1, t('renew-ita:marital-status.error-message.date-of-birth-year-required')),
socialInsuranceNumber: z
.string()
.trim()
.min(1, t('renew-ita:marital-status.error-message.sin-required'))
.refine(isValidSin, t('renew-ita:marital-status.error-message.sin-valid'))
.refine((sin) => isValidSin(sin) && formatSin(sin, '') !== state.partnerInformation?.socialInsuranceNumber, t('renew-ita:marital-status.error-message.sin-unique')),
}) satisfies z.ZodType<PartnerInformationState>;

const maritalStatusData = {
maritalStatus: formData.get('maritalStatus') ? String(formData.get('maritalStatus')) : undefined,
};
const partnerInformationData = {
confirm: formData.get('confirm') === 'yes',
dateOfBirthYear: formData.get('dateOfBirthYear') ? Number(formData.get('dateOfBirthYear')) : undefined,
dateOfBirthMonth: formData.get('dateOfBirthMonth') ? Number(formData.get('dateOfBirthMonth')) : undefined,
dateOfBirthDay: formData.get('dateOfBirthDay') ? Number(formData.get('dateOfBirthDay')) : undefined,
dateOfBirth: '',
yearOfBirth: String(formData.get('yearOfBirth') ?? ''),
socialInsuranceNumber: String(formData.get('socialInsuranceNumber') ?? ''),
};

Expand All @@ -149,7 +111,7 @@ export async function action({ context: { session }, params, request }: ActionFu
return json({
errors: {
...(parsedMaritalStatus.error ? transformFlattenedError(parsedMaritalStatus.error.flatten()) : {}),
...(parsedPartnerInformation.error ? transformFlattenedError(parsedPartnerInformation.error.flatten()) : {}),
...(parsedMaritalStatus.success && renewStateHasPartner(parsedMaritalStatus.data.maritalStatus) && parsedPartnerInformation.error ? transformFlattenedError(parsedPartnerInformation.error.flatten()) : {}),
},
});
}
Expand All @@ -164,7 +126,7 @@ export async function action({ context: { session }, params, request }: ActionFu
}

export default function RenewItaMaritalStatus() {
const { i18n, t } = useTranslation(handle.i18nNamespaces);
const { t } = useTranslation(handle.i18nNamespaces);
const { csrfToken, defaultState, editMode, maritalStatuses, MARITAL_STATUS_CODE_COMMONLAW, MARITAL_STATUS_CODE_MARRIED } = useLoaderData<typeof loader>();
const params = useParams();
const fetcher = useFetcher<typeof action>();
Expand All @@ -175,10 +137,7 @@ export default function RenewItaMaritalStatus() {
const errors = fetcher.data?.errors;
const errorSummary = useErrorSummary(errors, {
maritalStatus: 'input-radio-marital-status-option-0',
...(i18n.language === 'fr'
? { dateOfBirth: 'date-picker-date-of-birth-day', dateOfBirthDay: 'date-picker-date-of-birth-day', dateOfBirthMonth: 'date-picker-date-of-birth-month' }
: { dateOfBirth: 'date-picker-date-of-birth-month', dateOfBirthMonth: 'date-picker-date-of-birth-month', dateOfBirthDay: 'date-picker-date-of-birth-day' }),
dateOfBirthYear: 'date-picker-date-of-birth-year',
yearOfBirth: 'year-of-birth',
socialInsuranceNumber: 'social-insurance-number',
confirm: 'input-checkbox-confirm',
});
Expand Down Expand Up @@ -209,23 +168,7 @@ export default function RenewItaMaritalStatus() {
<h2 className="mb-6 font-lato text-2xl font-bold">{t('renew-ita:marital-status.spouse-or-commonlaw')}</h2>
<p className="mb-4">{t('renew-ita:marital-status.provide-sin')}</p>
<p className="mb-6">{t('renew-ita:marital-status.required-information')}</p>
<DatePickerField
id="date-of-birth"
names={{
day: 'dateOfBirthDay',
month: 'dateOfBirthMonth',
year: 'dateOfBirthYear',
}}
defaultValue={defaultState.dateOfBirth ?? ''}
legend={t('renew-ita:marital-status.date-of-birth')}
errorMessages={{
all: errors?.dateOfBirth,
year: errors?.dateOfBirthYear,
month: errors?.dateOfBirthMonth,
day: errors?.dateOfBirthDay,
}}
required
/>
<InputPatternField id="year-of-birth" name="yearOfBirth" inputMode="numeric" format="####" defaultValue={defaultState.yearOfBirth ?? ''} label={t('renew-ita:marital-status.year-of-birth')} errorMessage={errors?.yearOfBirth} required />
<InputPatternField
id="social-insurance-number"
name="socialInsuranceNumber"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ export async function loader({ context: { configProvider, serviceProvider, sessi
};

const spouseInfo = state.partnerInformation && {
birthday: toLocaleDateString(parseDateString(state.partnerInformation.dateOfBirth), locale),
yearOfBirth: state.partnerInformation.yearOfBirth,
sin: state.partnerInformation.socialInsuranceNumber,
consent: state.partnerInformation.confirm,
};
Expand Down Expand Up @@ -272,8 +272,8 @@ export default function RenewItaReviewInformation() {
</InlineLink>
</div>
</DescriptionListItem>
<DescriptionListItem term={t('renew-ita:review-information.dob-title')}>
<p>{spouseInfo.birthday}</p>
<DescriptionListItem term={t('renew-ita:review-information.year-of-birth')}>
<p>{spouseInfo.yearOfBirth}</p>
<div className="mt-4">
<InlineLink id="change-spouse-date-of-birth" routeId="public/renew/$id/ita/marital-status" params={params}>
{t('renew-ita:review-information.dob-change')}
Expand Down
11 changes: 3 additions & 8 deletions frontend/public/locales/en/renew-ita.json
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@
"cancel-btn": "Cancel",
"save-btn": "Save",
"sin": "Social Insurance Number (SIN)",
"date-of-birth": "Date of birth",
"year-of-birth": "Year of birth",
"single-legal-name": "If your spouse or common-law partner has a single legal name",
"name-instructions": "If using a single legal name, please enter that name in BOTH the first name and last name fields.",
"confirm-checkbox": "I confirm that my spouse or common-law partner is aware and has agreed to share their personal information.",
Expand All @@ -46,13 +46,6 @@
"marital-status-required": "Select marital status",
"marital-status-no-partner-information": "If you are married or in a common-law relationship you must enter their information on the next page. Select your marital status and press 'Save'.",
"confirm-required": "Checkbox must be selected",
"date-of-birth-day-number": "Day must be a number",
"date-of-birth-day-required": "Date of birth must include a day",
"date-of-birth-is-past": "Date of birth must be in the past",
"date-of-birth-is-past-valid": "Date of birth too far in the past",
"date-of-birth-month-required": "Date of birth must include a month",
"date-of-birth-valid": "Day must be valid for the given month and year",
"date-of-birth-year-number": "Year must be a number, for example 1950",
"date-of-birth-year-required": "Date of birth must include a year",
"sin-required": "Enter 9-digit SIN, for example 123 456 789",
"sin-valid": "Must be a valid SIN",
Expand Down Expand Up @@ -213,6 +206,7 @@
"full-name-change": "Change full name",
"marital-title": "Marital status",
"marital-change": "Change marital status",
"year-of-birth": "Year of birth",
"spouse-title": "Spouse or common-law partner information",
"spouse-consent": {
"label": "Consent",
Expand Down Expand Up @@ -267,6 +261,7 @@
"applicant-summary": "Summary of updates",
"applicant-title": "Applicant",
"member-info": "Member information",
"year-of-birth": "Year of birth",
"spouse-info": "Spouse or common-law partner information",
"contact-info": "Contact information",
"dental-insurance": "Access to dental insurance",
Expand Down

0 comments on commit b3f1631

Please sign in to comment.