import clsx from "clsx"; import { FormEvent, forwardRef, ReactNode, Ref, useEffect, useImperativeHandle, useRef, useState } from "react"; import {ButtonSecondary} from "../buttons/ButtonSecondary"; import {LoadingButton} from "../buttons/LoadingButton"; import ConfirmModal, { RefConfirmModal } from "../modals/ConfirmModal"; import ErrorModal, { RefErrorModal } from "../modals/ErrorModal"; import InfoBanner from "../banners/InfoBanner"; import {ErrorBanner} from "../banners/ErrorBanner"; import { useRouter } from "next/navigation"; import { useApp } from "../../../hooks"; export interface RefFormGroup { submitForm: () => void; } interface Props { id?: string | undefined; onCancel?: () => void; children: ReactNode; className?: string; classNameFooter?: string; editing?: boolean; canUpdate?: boolean; canDelete?: boolean; canSubmit?: boolean; onSubmit?: (e: FormData) => void | undefined; onDelete?: () => void; onCreatedRedirect?: string; confirmationPrompt?: { title: string; yesTitle?: string; noTitle?: string; description?: string; }; deleteRedirect?: string; actionNames?: { create?: string; update?: string; delete?: string; }; state?: { loading?: boolean; submitting?: boolean }; message?: { success?: string; error?: string; }; labels?: { create?: string; }; withErrorModal?: boolean; submitDisabled?: boolean; } const FormGroup = ( { id, onCancel, children, className, classNameFooter, editing, canUpdate = true, canDelete = true, canSubmit = true, confirmationPrompt, onSubmit, onCreatedRedirect, deleteRedirect, onDelete, actionNames, state, message, labels, withErrorModal = true, submitDisabled, }: Props, ref: Ref ) => { const { t } = useApp(); const formRef = useRef(null); useImperativeHandle(ref, () => ({ submitForm, })); function submitForm() { const formData = new FormData(formRef.current!); /* submit(formData, { method: "post", }); */ } const actionData: any = {}; /* useActionData<{ error?: string; }>(); */ const navigation = useRouter(); const loading = false;// navigation.state === "submitting" || state?.submitting; //const submit = useSubmit(); const confirmRemove = useRef(null); const confirmSubmit = useRef(null); const errorModal = useRef(null); const [error, setError] = useState(); const [formData, setFormData] = useState(); useEffect(() => { setError(actionData?.error); // eslint-disable-next-line react-hooks/exhaustive-deps }, [actionData]); useEffect(() => { setError(undefined); if (error) { errorModal.current?.show(t("shared.error"), error); } // eslint-disable-next-line react-hooks/exhaustive-deps }, [error]); function remove() { confirmRemove.current?.show(t("shared.confirmDelete"), t("shared.delete"), t("shared.cancel"), t("shared.warningCannotUndo")); } function yesRemove() { if (onDelete) { onDelete(); } else { const form = new FormData(); form.set("action", actionNames?.delete ?? "delete"); form.set("id", id ?? ""); form.set("redirect", deleteRedirect ?? ""); /* submit(form, { method: "post", }); */ } } function handleSubmit(e: FormEvent) { e.stopPropagation(); e.preventDefault(); const formData = new FormData(e.currentTarget); if (confirmationPrompt) { setFormData(formData); confirmSubmit.current?.show(confirmationPrompt.title, confirmationPrompt.yesTitle, confirmationPrompt.noTitle, confirmationPrompt.description); } else { if (onSubmit !== undefined) { onSubmit(formData); } else { /* submit(formData, { method: "post", }); */ } } } function yesSubmit() { if (formData) { if (onSubmit !== undefined) { onSubmit(formData); } else { /* submit(formData, { method: "post", }); */ } } } return (
{children} {(!id || editing) && canSubmit && (
{id && canDelete && (
{t("shared.delete")}
)}
{onCancel && (
{t("shared.cancel")}
)} {id === undefined && onCreatedRedirect === "addAnother" ? (
{t("shared.saveAndAdd")}
) : ( {labels?.create ?? t("shared.save")} )}
{message && (
{} {}
)}
)}
{withErrorModal && canSubmit && } ); }; export default forwardRef(FormGroup);