import { type FC, useCallback } from 'react'; import { useIntl } from 'react-intl'; import type { Nullable } from '../../../../types'; import { type FormSubmitHandler, useForm, type FormSubmitStatus, type FormSubmitMessages, } from '../../../../utils/hooks'; import { Button, Form, type FormProps, Input, Label, Spinner, TextArea, Notice, } from '../../../atoms'; import { LabelledField } from '../../../molecules'; import styles from './contact-form.module.scss'; export type ContactFormData = { email: string; message: string; name: string; object: string; }; export type ContactFormSubmit = FormSubmitHandler; export type ContactFormProps = Omit & { /** * A callback function to handle form submit. */ onSubmit?: ContactFormSubmit; }; /** * ContactForm component * * Render a contact form. */ export const ContactForm: FC = ({ className = '', onSubmit, ...props }) => { const formClass = `${styles.form} ${className}`; const intl = useIntl(); const { messages, submit, submitStatus, update, values } = useForm({ initialValues: /* The order matter: it will be reused to generate the fields in the right * order. */ { name: '', email: '', object: '', message: '', }, submitHandler: onSubmit, }); const btnLabel = intl.formatMessage({ defaultMessage: 'Send', description: 'ContactForm: send button', id: 'VkAnvv', }); const loadingMsg = intl.formatMessage({ defaultMessage: 'Sending mail...', description: 'ContactForm: spinner message on submit', id: 'xaqaYQ', }); const renderFields = useCallback(() => { const entries = Object.entries(values) as [ keyof ContactFormData, ContactFormData[keyof ContactFormData], ][]; const labels = { email: intl.formatMessage({ defaultMessage: 'Email:', description: 'ContactForm: email label', id: 'w4B5PA', }), message: intl.formatMessage({ defaultMessage: 'Message:', description: 'ContactForm: message label', id: 'yN5P+m', }), name: intl.formatMessage({ defaultMessage: 'Name:', description: 'ContactForm: name label', id: '1dCuCx', }), object: intl.formatMessage({ defaultMessage: 'Object:', description: 'ContactForm: object label', id: 's8/tyz', }), }; return entries.map(([field, value]) => { const isRequired = field !== 'object'; const inputType = field === 'email' ? 'email' : 'text'; return ( ) : ( ) } key={field} label={ } /> ); }); }, [values, intl, update]); const renderNotice = useCallback( ( currentStatus: FormSubmitStatus, msg: Nullable> ) => { switch (currentStatus) { case 'FAILED': return msg?.error ? ( {msg.error} ) : null; case 'PENDING': return ( {loadingMsg} ); case 'SUCCEEDED': return msg?.success ? ( {msg.success} ) : null; default: return null; } }, [loadingMsg] ); return (
{renderFields()} {renderNotice(submitStatus, messages)}
); };