/* eslint-disable max-statements */ import { type ChangeEvent, type FC, type FormEvent, type ReactNode, useCallback, useMemo, useState, useId, } from 'react'; import { useIntl } from 'react-intl'; import { Button, Form, type FormProps, Heading, type HeadingLevel, Spinner, Input, TextArea, Label, } from '../../../atoms'; import { LabelledField } from '../../../molecules'; import styles from './comment-form.module.scss'; export type CommentFormData = { author: string; comment: string; email: string; parentId?: number; website?: string; }; export type CommentFormProps = Pick & { /** * Pass a component to print a success/error message. */ Notice?: ReactNode; /** * The comment parent id. */ parentId?: number; /** * A callback function to save comment. It takes a function as parameter to * reset the form. */ saveComment: (data: CommentFormData, reset: () => void) => Promise; /** * The form title. */ title?: string; /** * The title level. Default: 2. */ titleLevel?: HeadingLevel; }; export const CommentForm: FC = ({ className = '', Notice, parentId, saveComment, title, titleLevel = 2, ...props }) => { const formClass = `${styles.form} ${className}`; const intl = useIntl(); const emptyForm: CommentFormData = useMemo(() => { return { author: '', comment: '', email: '', parentId, website: '', }; }, [parentId]); const [data, setData] = useState(emptyForm); const [isSubmitting, setIsSubmitting] = useState(false); /** * Reset all the form fields. */ const resetForm = useCallback(() => { setData(emptyForm); setIsSubmitting(false); }, [emptyForm]); const nameLabel = intl.formatMessage({ defaultMessage: 'Name:', description: 'CommentForm: name label', id: 'ZIrTee', }); const emailLabel = intl.formatMessage({ defaultMessage: 'Email:', description: 'CommentForm: email label', id: 'Bh7z5v', }); const websiteLabel = intl.formatMessage({ defaultMessage: 'Website:', description: 'CommentForm: website label', id: 'u41qSk', }); const commentLabel = intl.formatMessage({ defaultMessage: 'Comment:', description: 'CommentForm: comment label', id: 'A8hGaK', }); const formTitle = intl.formatMessage({ defaultMessage: 'Comment form', description: 'CommentForm: aria label', id: 'dz2kDV', }); const loadingMsg = intl.formatMessage({ defaultMessage: 'Submitting...', description: 'CommentForm: spinner message on submit', id: 'IY5ew6', }); const formAriaLabel = title ? undefined : formTitle; const formId = useId(); const formLabelledBy = title ? formId : undefined; const updateForm = useCallback( (e: ChangeEvent) => { switch (e.target.name) { case 'author': setData((prevData) => { return { ...prevData, author: e.target.value }; }); break; case 'comment': setData((prevData) => { return { ...prevData, comment: e.target.value }; }); break; case 'email': setData((prevData) => { return { ...prevData, email: e.target.value }; }); break; case 'website': setData((prevData) => { return { ...prevData, website: e.target.value }; }); break; default: break; } }, [] ); const sendForm = useCallback( (e: FormEvent) => { e.preventDefault(); setIsSubmitting(true); saveComment(data, resetForm).then(() => setIsSubmitting(false)); }, [data, resetForm, saveComment] ); return (
{title ? ( {title} ) : null} } label={ } /> } label={ } /> } label={} /> } label={ } /> {isSubmitting ? {loadingMsg} : null} {Notice} ); };