🐛(frontend) fix mail domain creation form
- allow to submit form by pressing "Enter" key - force focus on form when form is submited but is invalid - add error 500 handling - update related e2e tests
This commit is contained in:
committed by
Sebastien Nobour
parent
237d64b4c5
commit
b5d8e92d1e
@@ -2,10 +2,16 @@ import { zodResolver } from '@hookform/resolvers/zod';
|
||||
import { Button, Input, Loader, ModalSize } from '@openfun/cunningham-react';
|
||||
import { useRouter } from 'next/navigation';
|
||||
import React from 'react';
|
||||
import { Controller, FormProvider, useForm } from 'react-hook-form';
|
||||
import {
|
||||
Controller,
|
||||
FormProvider,
|
||||
UseFormReturn,
|
||||
useForm,
|
||||
} from 'react-hook-form';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { z } from 'zod';
|
||||
|
||||
import { APIError } from '@/api';
|
||||
import { Box, Text, TextErrors } from '@/components';
|
||||
import { Modal } from '@/components/Modal';
|
||||
import { useCreateMailDomain } from '@/features/mail-domains';
|
||||
@@ -14,7 +20,68 @@ import { default as MailDomainsLogo } from '../assets/mail-domains-logo.svg';
|
||||
|
||||
const FORM_ID = 'form-add-mail-domain';
|
||||
|
||||
export const ModalCreateMailDomain = () => {
|
||||
const useAddMailDomainApiError = ({
|
||||
error,
|
||||
methods,
|
||||
}: {
|
||||
error: APIError | null;
|
||||
methods: UseFormReturn<{ name: string }> | null;
|
||||
}): string[] | undefined => {
|
||||
const [errorCauses, setErrorCauses] = React.useState<undefined | string[]>(
|
||||
undefined,
|
||||
);
|
||||
const { t } = useTranslation();
|
||||
|
||||
React.useEffect(() => {
|
||||
if (methods && t && error) {
|
||||
let causes = undefined;
|
||||
|
||||
if (error.cause?.length) {
|
||||
const parseCauses = (causes: string[]) =>
|
||||
causes.reduce((arrayCauses, cause) => {
|
||||
switch (cause) {
|
||||
case 'Mail domain with this name already exists.':
|
||||
case 'Mail domain with this Slug already exists.':
|
||||
methods.setError('name', {
|
||||
type: 'manual',
|
||||
message: t(
|
||||
'This mail domain is already used. Please, choose another one.',
|
||||
),
|
||||
});
|
||||
break;
|
||||
default:
|
||||
arrayCauses.push(cause);
|
||||
}
|
||||
|
||||
return arrayCauses;
|
||||
}, [] as string[]);
|
||||
|
||||
causes = parseCauses(error.cause);
|
||||
}
|
||||
|
||||
if (error.status === 500 || !error.cause) {
|
||||
causes = [
|
||||
t(
|
||||
'Your request cannot be processed because the server is experiencing an error. If the problem ' +
|
||||
'persists, please contact our support to resolve the issue: suiteterritoriale@anct.gouv.fr.',
|
||||
),
|
||||
];
|
||||
}
|
||||
|
||||
setErrorCauses(causes);
|
||||
}
|
||||
}, [methods, t, error]);
|
||||
|
||||
React.useEffect(() => {
|
||||
if (errorCauses && methods) {
|
||||
methods.setFocus('name');
|
||||
}
|
||||
}, [methods, errorCauses]);
|
||||
|
||||
return errorCauses;
|
||||
};
|
||||
|
||||
export const ModalAddMailDomain = () => {
|
||||
const { t } = useTranslation();
|
||||
const router = useRouter();
|
||||
|
||||
@@ -42,28 +109,16 @@ export const ModalCreateMailDomain = () => {
|
||||
},
|
||||
});
|
||||
|
||||
const onSubmitCallback = () => {
|
||||
void methods.handleSubmit(({ name }, event) => {
|
||||
event?.preventDefault();
|
||||
const errorCauses = useAddMailDomainApiError({ error, methods });
|
||||
|
||||
const onSubmitCallback = (event: React.FormEvent) => {
|
||||
event.preventDefault();
|
||||
|
||||
void methods.handleSubmit(({ name }) => {
|
||||
void createMailDomain(name);
|
||||
})();
|
||||
};
|
||||
|
||||
const causes = error?.cause?.filter((cause) => {
|
||||
const isFound = cause === 'Mail domain with this name already exists.';
|
||||
|
||||
if (isFound) {
|
||||
methods.setError('name', {
|
||||
type: 'manual',
|
||||
message: t(
|
||||
'This mail domain is already used. Please, choose another one.',
|
||||
),
|
||||
});
|
||||
}
|
||||
|
||||
return !isFound;
|
||||
});
|
||||
|
||||
if (!methods) {
|
||||
return null;
|
||||
}
|
||||
@@ -82,7 +137,8 @@ export const ModalCreateMailDomain = () => {
|
||||
onClose={() => router.push('/mail-domains/')}
|
||||
rightActions={
|
||||
<Button
|
||||
onClick={onSubmitCallback}
|
||||
type="submit"
|
||||
form={FORM_ID}
|
||||
disabled={!methods.watch('name') || isPending}
|
||||
>
|
||||
{t('Add the domain')}
|
||||
@@ -98,8 +154,16 @@ export const ModalCreateMailDomain = () => {
|
||||
</>
|
||||
}
|
||||
>
|
||||
{!!errorCauses?.length ? (
|
||||
<TextErrors
|
||||
$margin={{ bottom: 'small' }}
|
||||
$textAlign="left"
|
||||
causes={errorCauses}
|
||||
/>
|
||||
) : null}
|
||||
|
||||
<FormProvider {...methods}>
|
||||
<form action="" id={FORM_ID}>
|
||||
<form id={FORM_ID} onSubmit={onSubmitCallback}>
|
||||
<Controller
|
||||
control={methods.control}
|
||||
name="name"
|
||||
@@ -123,7 +187,6 @@ export const ModalCreateMailDomain = () => {
|
||||
)}
|
||||
/>
|
||||
</form>
|
||||
{!!causes?.length ? <TextErrors causes={causes} /> : null}
|
||||
|
||||
{isPending && (
|
||||
<Box $align="center">
|
||||
|
||||
Reference in New Issue
Block a user