'use client'; import { useEffect, useState } from 'react'; import { useRouter } from 'next/navigation'; import { zodResolver } from '@hookform/resolvers/zod'; import { Loader } from 'lucide-react'; import { useForm } from 'react-hook-form'; import { DO_NOT_INVALIDATE_QUERY_ON_MUTATION } from '@documenso/lib/constants/trpc'; import type { Field, Recipient } from '@documenso/prisma/client'; import { DocumentStatus } from '@documenso/prisma/client'; import type { DocumentWithData } from '@documenso/prisma/types/document-with-data'; import { trpc } from '@documenso/trpc/react'; import { DocumentSendEmailMessageHelper } from '@documenso/ui/components/document/document-send-email-message-helper'; import { useToast } from '@documenso/ui/primitives/use-toast'; import { Button } from '../button'; import { FormErrorMessage } from '../form/form-error-message'; import { Input } from '../input'; import { Label } from '../label'; import { useStep } from '../stepper'; import { Textarea } from '../textarea'; import { type TAddSubjectFormSchema, ZAddSubjectFormSchema } from './add-subject.types'; import { DocumentFlowFormContainerActions, DocumentFlowFormContainerContent, DocumentFlowFormContainerFooter, DocumentFlowFormContainerHeader, DocumentFlowFormContainerStep, } from './document-flow-root'; import { ShowFieldItem } from './show-field-item'; import type { DocumentFlowStep } from './types'; export type AddSubjectFormProps = { documentFlow: DocumentFlowStep; recipients: Recipient[]; fields: Field[]; document: DocumentWithData; onSubmit: (_data: TAddSubjectFormSchema) => void; isDocumentPdfLoaded: boolean; }; export const AddSubjectFormPartial = ({ documentFlow, recipients: recipients, fields: fields, document, onSubmit, isDocumentPdfLoaded, }: AddSubjectFormProps) => { const { register, handleSubmit, setValue, formState: { errors, isSubmitting }, } = useForm({ defaultValues: { meta: { subject: document.documentMeta?.subject ?? '', message: document.documentMeta?.message ?? '', }, }, resolver: zodResolver(ZAddSubjectFormSchema), }); const [oldEmailData, setOldEmailData] = useState<{ subject: string; message: string } | null>( document.documentMeta ? { subject: document.documentMeta.subject ?? '', message: document.documentMeta.message ?? '', } : null, ); const [changedFields, setChangedFields] = useState<{ subject: boolean; message: boolean }>({ subject: false, message: false, }); const { toast } = useToast(); const router = useRouter(); const utils = trpc.useUtils(); const { mutateAsync: setEmailSettingsForDocument } = trpc.document.setDocumentEmailSettings.useMutation({ ...DO_NOT_INVALIDATE_QUERY_ON_MUTATION, onSuccess: () => { const data = utils.document.getDocumentWithDetailsById.getData({ id: document.id, }); setOldEmailData({ subject: data?.documentMeta?.subject ?? '', message: data?.documentMeta?.message ?? '', }); }, }); const handleOnBlur = async (field: 'subject' | 'message', value: string) => { if (value == oldEmailData?.[field]) return; try { await setEmailSettingsForDocument({ documentId: document.id, [field]: value, }); setChangedFields((prev) => ({ ...prev, [field]: true })); router.refresh(); toast({ title: 'Email settings updated', description: 'The email settings for the document have been updated.', duration: 5000, }); } catch (e) { console.error(e); toast({ title: 'Error', description: 'An error occurred while updating the email settings.', duration: 5000, }); } }; const handleUndoButton = async (field: 'subject' | 'message') => { if (!oldEmailData) return; try { await setEmailSettingsForDocument({ documentId: document.id, [field]: oldEmailData[field], }); setValue(`meta.${field}`, oldEmailData[field]); setOldEmailData((prev) => (prev ? { ...prev, [field]: undefined } : null)); setChangedFields((prev) => ({ ...prev, [field]: false })); router.refresh(); toast({ title: 'Change reverted', description: `The latest change to the ${field} has been reverted.`, duration: 5000, }); if (oldEmailData.subject === undefined && oldEmailData.message === undefined) { setOldEmailData(null); } } catch (e) { console.error(e); toast({ title: 'Error', description: 'An error occurred while undoing the latest change', duration: 5000, }); } }; useEffect(() => { const timeout = setTimeout(() => { setChangedFields({ subject: false, message: false }); }, 5000); return () => { clearTimeout(timeout); }; }, [oldEmailData]); const onFormSubmit = handleSubmit(onSubmit); const { currentStep, totalSteps, previousStep } = useStep(); return ( <>
{isDocumentPdfLoaded && fields.map((field, index) => ( ))}
{ void handleOnBlur('subject', event.target.value); }, })} /> {changedFields.subject && oldEmailData && (
)}