Skip to content

Commit

Permalink
VKT(Frontend): PublicEnrollmentContactStepper show error dialog if us…
Browse files Browse the repository at this point in the history
…er tries to proceed with invalid fields
  • Loading branch information
pkoivisto committed Dec 18, 2024
1 parent ac7ddda commit f610d26
Show file tree
Hide file tree
Showing 3 changed files with 110 additions and 11 deletions.
18 changes: 18 additions & 0 deletions frontend/packages/vkt/public/i18n/fi-FI/public.json
Original file line number Diff line number Diff line change
Expand Up @@ -320,6 +320,24 @@
}
},
"publicEnrollmentContact": {
"controlButtons": {
"submit": "Lähetä"
},
"errors": {
"fields": {
"email": "Sähköpostiosoite",
"emailConfirmation": "Sähköpostiosoitteen vahvistus",
"firstName": "Etunimi",
"hasPreviousEnrollment": "Oletko osallistunut aiemmin hyvän ja tyydyttävän taidon tutkintoon?",
"isFullExam": "Haluatko suorittaa sekä suullisen että kirjallisen taidon tutkinnon?",
"message": "Viesti",
"lastName": "Sukunimi",
"partialExamSelection": "Kerro, minkä osakokeen / mitkä osakokeet haluat suorittaa",
"phoneNumber": "Puhelinnumero"
},
"fixErrors": "Korjaa puuttuvat tai virheelliset tiedot:",
"title": "Tiedoissa on korjattavaa!"
},
"examinerDetails": {
"byRequest": "Sovittavissa",
"examDate": "Tutkintopäivä",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,27 @@ import {
} from '@mui/icons-material';
import { useEffect, useState } from 'react';
import { useNavigate } from 'react-router';
import { CustomButton, LoadingProgressIndicator } from 'shared/components';
import { APIResponseStatus, Color, Variant } from 'shared/enums';
import {
CustomButton,
LoadingProgressIndicator,
Text,
} from 'shared/components';
import { APIResponseStatus, Color, Severity, Variant } from 'shared/enums';
import { useDialog } from 'shared/hooks';
import { getErrors, StringUtils } from 'shared/utils';

import {
contactDetailsStepEmailsMatch,
contactDetailsStepFields,
} from 'components/publicEnrollmentContact/steps/FillContactDetails';
import { useCommonTranslation, usePublicTranslation } from 'configs/i18n';
import { useAppDispatch, useAppSelector } from 'configs/redux';
import { AppRoutes } from 'enums/app';
import { PublicEnrollmentContactFormStep } from 'enums/publicEnrollment';
import { PublicEnrollmentContact } from 'interfaces/publicEnrollment';
import {
PublicEnrollmentContact,
PublicEnrollmentContactRequestDetails,
} from 'interfaces/publicEnrollment';
import {
loadPublicEnrollmentSave,
resetPublicEnrollmentContact,
Expand All @@ -35,7 +48,7 @@ export const PublicEnrollmentContactControlButtons = ({
examinerId: number;
}) => {
const { t } = usePublicTranslation({
keyPrefix: 'vkt.component.publicEnrollment.controlButtons',
keyPrefix: 'vkt.component.publicEnrollmentContact',
});
const translateCommon = useCommonTranslation();
const [isSubmitLoading, setIsSubmitLoading] = useState(false);
Expand All @@ -50,6 +63,8 @@ export const PublicEnrollmentContactControlButtons = ({
navigate(AppRoutes.PublicGoodAndSatisfactoryLevelLanding);
};

const { showDialog } = useDialog();

useEffect(() => {
if (submitStatus === APIResponseStatus.Success) {
navigate(
Expand All @@ -73,6 +88,37 @@ export const PublicEnrollmentContactControlButtons = ({
navigate(RouteUtils.contactStepToRoute(nextStep, examinerId));
} else {
setShowValidation(true);
const errors = getErrors<PublicEnrollmentContactRequestDetails>({
fields: contactDetailsStepFields,
values: enrollment,
t,
extraValidation: (errors, values, dirtyFields) =>
contactDetailsStepEmailsMatch(t, errors, values, dirtyFields),
});

const dialogContent = (
<div>
<Text>{t('errors.fixErrors')}</Text>
<ul>
{Object.entries(errors)
.filter(([_, val]) => val)
.map(([field, _]) => (
<Text key={field}>
<li>{t(`errors.fields.${field}`)}</li>
</Text>
))}
</ul>
</div>
);

showDialog({
title: t('errors.title'),
severity: Severity.Error,
content: dialogContent,
actions: [
{ title: translateCommon('back'), variant: Variant.Contained },
],
});
}
};

Expand All @@ -83,6 +129,39 @@ export const PublicEnrollmentContactControlButtons = ({
dispatch(loadPublicEnrollmentSave({ enrollment, examinerId }));
} else {
setShowValidation(true);
const errors = {
isFullExam: enrollment.isFullExam === undefined,
partialExamSelection:
enrollment.isFullExam === false &&
(enrollment.partialExamSelection === undefined ||
StringUtils.isBlankString(enrollment.partialExamSelection)),
hasPreviousEnrollment: enrollment.hasPreviousEnrollment === undefined,
message: StringUtils.isBlankString(enrollment.message),
};

const dialogContent = (
<div>
<Text>{t('errors.fixErrors')}</Text>
<ul>
{Object.entries(errors)
.filter(([_, val]) => val)
.map(([field, _]) => (
<Text key={field}>
<li>{t(`errors.fields.${field}`)}</li>
</Text>
))}
</ul>
</div>
);

showDialog({
title: t('errors.title'),
severity: Severity.Error,
content: dialogContent,
actions: [
{ title: translateCommon('back'), variant: Variant.Contained },
],
});
}
};

Expand Down Expand Up @@ -141,7 +220,7 @@ export const PublicEnrollmentContactControlButtons = ({
data-testid="public-enrollment__controlButtons__submit"
disabled={isSubmitLoading}
>
{t('submit')}
{t('controlButtons.submit')}
</CustomButton>
</LoadingProgressIndicator>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,9 @@ import {
PublicEnrollmentContactRequestDetails,
} from 'interfaces/publicEnrollment';

const fields: Array<TextField<PublicEnrollmentContactRequestDetails>> = [
export const contactDetailsStepFields: Array<
TextField<PublicEnrollmentContactRequestDetails>
> = [
{
name: 'firstName',
required: true,
Expand Down Expand Up @@ -46,7 +48,7 @@ const fields: Array<TextField<PublicEnrollmentContactRequestDetails>> = [
},
];

const emailsMatch = (
export const contactDetailsStepEmailsMatch = (
t: (key: string) => string,
errors: FieldErrors<PublicEnrollmentContactRequestDetails>,
values: PublicEnrollmentContactRequestDetails,
Expand Down Expand Up @@ -92,22 +94,22 @@ export const FillContactDetails = ({

const dirty = showValidation ? undefined : dirtyFields;
const errors = getErrors<PublicEnrollmentContactRequestDetails>({
fields,
fields: contactDetailsStepFields,
values: enrollment,
t: translateCommon,
dirtyFields: dirty,
extraValidation: emailsMatch.bind(this, t),
extraValidation: contactDetailsStepEmailsMatch.bind(this, t),
});

const dispatch = useAppDispatch();

useEffect(() => {
setIsStepValid(
!hasErrors<PublicEnrollmentContactRequestDetails>({
fields,
fields: contactDetailsStepFields,
values: enrollment,
t: translateCommon,
extraValidation: emailsMatch.bind(this, t),
extraValidation: contactDetailsStepEmailsMatch.bind(this, t),
}),
);
}, [setIsStepValid, enrollment, t, translateCommon]);
Expand Down

0 comments on commit f610d26

Please sign in to comment.