import { useEffect } from 'react'; import { zodResolver } from '@hookform/resolvers/zod'; import { msg } from '@lingui/core/macro'; import { useLingui } from '@lingui/react'; import { Trans } from '@lingui/react/macro'; import type { Field, Recipient } from '@prisma/client'; import { DocumentDistributionMethod, DocumentStatus, RecipientRole } from '@prisma/client'; import { AnimatePresence, motion } from 'framer-motion'; import { InfoIcon } from 'lucide-react'; import { useForm } from 'react-hook-form'; import { useAutoSave } from '@documenso/lib/client-only/hooks/use-autosave'; import { useCurrentOrganisation } from '@documenso/lib/client-only/providers/organisation'; import { RECIPIENT_ROLES_DESCRIPTION } from '@documenso/lib/constants/recipient-roles'; import type { TDocument } from '@documenso/lib/types/document'; import { ZDocumentEmailSettingsSchema } from '@documenso/lib/types/document-email'; import { formatSigningLink } from '@documenso/lib/utils/recipients'; import { trpc } from '@documenso/trpc/react'; import { DocumentSendEmailMessageHelper } from '@documenso/ui/components/document/document-send-email-message-helper'; import { Form, FormControl, FormField, FormItem, FormLabel, FormMessage, } from '@documenso/ui/primitives/form/form'; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue, } from '@documenso/ui/primitives/select'; import { Tabs, TabsList, TabsTrigger } from '@documenso/ui/primitives/tabs'; import { CopyTextButton } from '../../components/common/copy-text-button'; import { DocumentEmailCheckboxes } from '../../components/document/document-email-checkboxes'; import { DocumentReadOnlyFields, mapFieldsWithRecipients, } from '../../components/document/document-read-only-fields'; import { AvatarWithText } from '../avatar'; import { Input } from '../input'; import { useStep } from '../stepper'; import { Textarea } from '../textarea'; import { Tooltip, TooltipContent, TooltipTrigger } from '../tooltip'; import { toast } from '../use-toast'; import { type TAddSubjectFormSchema, ZAddSubjectFormSchema } from './add-subject.types'; import { DocumentFlowFormContainerActions, DocumentFlowFormContainerContent, DocumentFlowFormContainerFooter, DocumentFlowFormContainerHeader, DocumentFlowFormContainerStep, } from './document-flow-root'; import type { DocumentFlowStep } from './types'; export type AddSubjectFormProps = { documentFlow: DocumentFlowStep; recipients: Recipient[]; fields: Field[]; document: TDocument; onSubmit: (_data: TAddSubjectFormSchema) => void; onAutoSave: (_data: TAddSubjectFormSchema) => Promise; isDocumentPdfLoaded: boolean; }; export const AddSubjectFormPartial = ({ documentFlow, recipients: recipients, fields: fields, document, onSubmit, onAutoSave, isDocumentPdfLoaded, }: AddSubjectFormProps) => { const { _ } = useLingui(); const organisation = useCurrentOrganisation(); const form = useForm({ defaultValues: { meta: { emailId: document.documentMeta?.emailId ?? null, emailReplyTo: document.documentMeta?.emailReplyTo || undefined, // emailReplyName: document.documentMeta?.emailReplyName || undefined, subject: document.documentMeta?.subject ?? '', message: document.documentMeta?.message ?? '', distributionMethod: document.documentMeta?.distributionMethod || DocumentDistributionMethod.EMAIL, emailSettings: ZDocumentEmailSettingsSchema.parse(document?.documentMeta?.emailSettings), }, }, resolver: zodResolver(ZAddSubjectFormSchema), }); const { handleSubmit, setValue, watch, trigger, getValues, formState: { isSubmitting }, } = form; const { data: emailData, isLoading: isLoadingEmails } = trpc.enterprise.organisation.email.find.useQuery({ organisationId: organisation.id, perPage: 100, }); const emails = emailData?.data || []; const GoNextLabel = { [DocumentDistributionMethod.EMAIL]: { [DocumentStatus.DRAFT]: msg`Send`, [DocumentStatus.PENDING]: recipients.some((recipient) => recipient.sendStatus === 'SENT') ? msg`Resend` : msg`Send`, [DocumentStatus.COMPLETED]: msg`Update`, [DocumentStatus.REJECTED]: msg`Update`, }, [DocumentDistributionMethod.NONE]: { [DocumentStatus.DRAFT]: msg`Generate Links`, [DocumentStatus.PENDING]: msg`View Document`, [DocumentStatus.COMPLETED]: msg`View Document`, [DocumentStatus.REJECTED]: msg`View Document`, }, }; const distributionMethod = watch('meta.distributionMethod'); const emailSettings = watch('meta.emailSettings'); const onFormSubmit = handleSubmit(onSubmit); const { currentStep, totalSteps, previousStep } = useStep(); const { scheduleSave } = useAutoSave(onAutoSave); const handleAutoSave = async () => { const isFormValid = await trigger(); if (!isFormValid) { return; } const formData = getValues(); scheduleSave(formData); }; useEffect(() => { const container = window.document.getElementById('document-flow-form-container'); const handleBlur = () => { void handleAutoSave(); }; if (container) { container.addEventListener('blur', handleBlur, true); return () => { container.removeEventListener('blur', handleBlur, true); }; } }, []); return ( <>
{isDocumentPdfLoaded && ( recipient.id)} fields={mapFieldsWithRecipients(fields, recipients)} /> )} // eslint-disable-next-line @typescript-eslint/consistent-type-assertions setValue('meta.distributionMethod', value as DocumentDistributionMethod) } value={distributionMethod} className="mb-2" > Email None {distributionMethod === DocumentDistributionMethod.EMAIL && (
{organisation.organisationClaim.flags.emailDomains && ( ( Email Sender )} /> )} ( Reply To Email{' '} (Optional) )} /> {/* ( Reply To Name{' '} (Optional) )} /> */} ( Subject{' '} (Optional) )} /> ( Message{' '} (Optional)