feat: enhance nationality and national ID prefill logic in LicenseApplicationPage

This commit is contained in:
estifanos
2026-08-10 12:14:27 +00:00
parent 50aeaf4fa3
commit 47884831b2

View File

@@ -47,6 +47,7 @@ import {
useResubmitApplicationMutation,
useSubmitApplicationMutation,
type FieldErrors,
type FormFieldConfig,
type ValidationIssue,
} from '@ema-platform/api';
import { getCountryCode, ModalFooter } from '@ema-platform/ui';
@@ -114,30 +115,53 @@ export function LicenseApplicationPage() {
if (detail?.application?.formData) setDraft(detail.application.formData);
}, [detail?.application?.id, detail?.application?.adjustmentRound]);
// Nationality is already on file from the profile's Address tab — carry it
// into whichever section the form config puts a `nationality` field in,
// rather than asking again. Only fills a blank; a value already on the
// draft (the applicant's own edit, or one the server saved) is left alone.
// Nationality and National ID (Fayda) number are already on file from the
// profile's Address tab — carry them into whichever section the form
// config puts those fields in, rather than asking again. Only fills a
// blank; a value already on the draft (the applicant's own edit, or one
// the server saved) is left alone.
useEffect(() => {
const nationality = profile?.address?.nationality;
if (!nationality || !config) return;
const section = config.licenseType.formSchema.sections.find((s) =>
s.fields.some((f) => f.key === 'nationality'),
);
const field = section?.fields.find((f) => f.key === 'nationality');
if (!section || !field) return;
// Profile stores the full country name; a SELECT field's options follow the
// CountrySelect convention of alpha-2 codes, so translate for that case.
const value = field.type === 'SELECT' ? (getCountryCode(nationality) ?? nationality) : nationality;
setDraft((prev) =>
prev[section.key]?.nationality
? prev
: { ...prev, [section.key]: { ...prev[section.key], nationality: value } },
);
const address = profile?.address;
if (!address || !config) return;
setDraft((prev) => {
let next = prev;
const fill = (
matchField: (label: string, key: string) => boolean,
toFieldValue: (field: FormFieldConfig) => unknown,
) => {
for (const section of config.licenseType.formSchema.sections) {
const field = section.fields.find((f) => matchField(localized(f.label).toLowerCase(), f.key));
if (!field) continue;
if (next[section.key]?.[field.key]) return; // already set — leave it
next = { ...next, [section.key]: { ...next[section.key], [field.key]: toFieldValue(field) } };
return;
}
};
if (address.nationality) {
// Profile stores the full country name; a SELECT field's options
// follow the CountrySelect convention of alpha-2 codes.
fill(
(label, key) => key === 'nationality' || label.includes('nationality'),
(field) =>
field.type === 'SELECT' ? (getCountryCode(address.nationality) ?? address.nationality) : address.nationality,
);
}
if (address.idType === 'NID' && address.idNumber) {
fill(
(label, key) =>
key === 'idNumber' || key === 'nationalId' || key === 'faydaNumber' ||
label.includes('fayda') || label.includes('national id'),
() => address.idNumber,
);
}
return next;
});
// Also re-run after the server seed effect (above) replaces `draft`
// wholesale — that effect can resolve after this one, wiping the
// prefill back out since the server's own draft has no nationality yet.
}, [profile?.address?.nationality, config, detail?.application?.id, detail?.application?.formData]);
// prefill back out since the server's own draft has none of this yet.
}, [profile?.address, config, detail?.application?.id, detail?.application?.formData]);
const application = detail?.application;
const isAdjusting = application?.status === 'RESUBMIT_REQUIRED';