From 608445f6ab4d969597cc9cb28ada6fdb298d0718 Mon Sep 17 00:00:00 2001 From: sirakinb Date: Wed, 27 May 2026 10:59:18 -0400 Subject: [PATCH] fix: validate linked protection duration fields --- .../application/application_form.tsx | 65 +++++++++++++++---- 1 file changed, 52 insertions(+), 13 deletions(-) diff --git a/src/components/application/application_form.tsx b/src/components/application/application_form.tsx index dcf3d90d..d217c9a1 100644 --- a/src/components/application/application_form.tsx +++ b/src/components/application/application_form.tsx @@ -80,7 +80,7 @@ export default function ApplicationForm(props: ApplicationFormProperties) { const [ coverageUntilMin, setCoverageUntilMin ] = useState(dayjs().add(props.applicationApi.coverageDurationDaysMin, 'days')); const [ coverageUntilMax, setCoverageUntilMax ] = useState(dayjs().add(props.applicationApi.coverageDurationDaysMax, 'days')); - const { handleSubmit, control, formState, getValues, setValue, watch } = useForm({ + const { handleSubmit, control, formState, getFieldState, getValues, setValue, trigger, watch } = useForm({ mode: "onChange", reValidateMode: "onChange", defaultValues: { @@ -102,14 +102,15 @@ export default function ApplicationForm(props: ApplicationFormProperties) { const errors = useMemo(() => formState.errors, [formState]); - const validateFormState = useCallback(() => { + const validateFormState = useCallback(async () => { // console.log("validateFormState"); - if (formState.touchedFields.protectedAmount === undefined) { + if (!getFieldState("protectedAmount").isTouched) { console.log("amount not touched, not calculating premium..."); return false; } - if (errors.coverageDuration !== undefined || errors.insuredWallet !== undefined || errors.protectedAmount !== undefined) { + const formFieldsAreValid = await trigger(["protectedAmount", "coverageDuration", "coverageEndDate"]); + if (!formFieldsAreValid) { console.log("Form is invalid, not calculating premium..."); return false; } @@ -119,7 +120,7 @@ export default function ApplicationForm(props: ApplicationFormProperties) { return false; } return true; - }, [errors, formState.touchedFields.protectedAmount, bundles.length]); + }, [bundles.length, getFieldState, trigger]); const getPremiumParameters = useCallback(() => { // console.log("getPremiumParameters"); @@ -132,7 +133,7 @@ export default function ApplicationForm(props: ApplicationFormProperties) { const calculatePremium = useCallback(async () => { // console.log("calculatePremium"); - if ( ! validateFormState()) { + if ( ! await validateFormState()) { console.log("form not valid, not calculating premium"); dispatch(setApplicableBundleIds(undefined)); dispatch(clearPremium()); @@ -212,13 +213,16 @@ export default function ApplicationForm(props: ApplicationFormProperties) { setCoverageDaysMin(minCoverageDays); setCoverageDaysMax(maxCoverageDays); const coverageDays = maxCoverageDays < 30 ? maxCoverageDays : 30; - setValue("coverageDuration", coverageDays.toString()); - setValue("coverageEndDate", dayjs().add(coverageDays, 'days')); + setValue("coverageDuration", coverageDays.toString(), { shouldValidate: true }); + setValue("coverageEndDate", dayjs().add(coverageDays, 'days'), { shouldValidate: true }); setCoverageUntilMin(dayjs().add(minCoverageDays, 'days')); setCoverageUntilMax(dayjs().add(maxCoverageDays, 'days')); + if (getFieldState("protectedAmount").isTouched) { + void calculatePremium(); + } } - }, [bundles, props.usd1Decimals, setValue]); + }, [bundles, calculatePremium, getFieldState, props.usd1Decimals, setValue]); const switchBundle = useCallback(async (bundle: BundleData) => { const { insuredWallet, protectedAmount, coverageSeconds } = getPremiumParameters(); @@ -251,6 +255,19 @@ export default function ApplicationForm(props: ApplicationFormProperties) { const loadingBar = applicationInProgress ? : null; const walletUsd1BalanceBN = BigNumber.from(walletUsd1Balance.amount); + function coverageEndDateErrorText(): string { + if (errors.coverageEndDate === undefined) { + return ""; + } + if (errors.coverageEndDate.type === "minDate") { + return t("error.field.min", { ns: "common", minValue: coverageUntilMin.format("DD.MM.YYYY") }); + } + if (errors.coverageEndDate.type === "maxDate") { + return t("error.field.max", { ns: "common", maxValue: coverageUntilMax.format("DD.MM.YYYY") }); + } + return t(`error.field.${errors.coverageEndDate.type}`, { ns: "common" }); + } + return (<>
{ field.onBlur(); - setValue("coverageEndDate", dayjs().startOf('day').add(parseInt(e.target.value), 'days')); + const durationDays = parseInt(e.target.value, 10); + if (!Number.isNaN(durationDays)) { + setValue( + "coverageEndDate", + dayjs().startOf('day').add(durationDays, 'days'), + { shouldDirty: true, shouldTouch: true, shouldValidate: true } + ); + } await calculatePremium(); }} InputProps={{ @@ -361,7 +385,13 @@ export default function ApplicationForm(props: ApplicationFormProperties) { value === null || !value.startOf('day').isBefore(coverageUntilMin.startOf('day')), + maxDate: (value) => value === null || !value.startOf('day').isAfter(coverageUntilMax.startOf('day')), + } + }} render={({ field }) => { - setValue("coverageDuration", dayjs(date).startOf('day').diff(dayjs().startOf('day'), 'days').toString()); + setValue( + "coverageDuration", + dayjs(date).startOf('day').diff(dayjs().startOf('day'), 'days').toString(), + { shouldDirty: true, shouldTouch: true, shouldValidate: true } + ); await calculatePremium(); }} disablePast={true}