'use client'; import React, { useId, useMemo, useState } from 'react'; import { zodResolver } from '@hookform/resolvers/zod'; import { motion } from 'framer-motion'; import { InfoIcon, Plus, Trash } from 'lucide-react'; import { useFieldArray, useForm } from 'react-hook-form'; import { useLimits } from '@documenso/ee/server-only/limits/provider/client'; import { DOCUMENT_AUTH_TYPES } from '@documenso/lib/constants/document-auth'; import { RecipientActionAuth, ZRecipientAuthOptionsSchema, } from '@documenso/lib/types/document-auth'; import { nanoid } from '@documenso/lib/universal/id'; import type { Field, Recipient } from '@documenso/prisma/client'; import { RecipientRole, SendStatus } from '@documenso/prisma/client'; import { AnimateGenericFadeInOut } from '@documenso/ui/components/animate/animate-generic-fade-in-out'; import { cn } from '@documenso/ui/lib/utils'; import { Button } from '../button'; import { Checkbox } from '../checkbox'; import { Form, FormControl, FormField, FormItem, FormLabel, FormMessage } from '../form/form'; import { FormErrorMessage } from '../form/form-error-message'; import { Input } from '../input'; import { ROLE_ICONS } from '../recipient-role-icons'; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '../select'; import { useStep } from '../stepper'; import { Tooltip, TooltipContent, TooltipTrigger } from '../tooltip'; import { useToast } from '../use-toast'; import type { TAddSignersFormSchema } from './add-signers.types'; import { ZAddSignersFormSchema } from './add-signers.types'; import { DocumentFlowFormContainerActions, DocumentFlowFormContainerContent, DocumentFlowFormContainerFooter, DocumentFlowFormContainerHeader, DocumentFlowFormContainerStep, } from './document-flow-root'; import { ShowFieldItem } from './show-field-item'; import type { DocumentFlowStep } from './types'; export type AddSignersFormProps = { documentFlow: DocumentFlowStep; recipients: Recipient[]; fields: Field[]; isDocumentEnterprise: boolean; onSubmit: (_data: TAddSignersFormSchema) => void; isDocumentPdfLoaded: boolean; }; export const AddSignersFormPartial = ({ documentFlow, recipients, fields, isDocumentEnterprise, onSubmit, isDocumentPdfLoaded, }: AddSignersFormProps) => { const { toast } = useToast(); const { remaining } = useLimits(); const initialId = useId(); const { currentStep, totalSteps, previousStep } = useStep(); const form = useForm({ resolver: zodResolver(ZAddSignersFormSchema), defaultValues: { signers: recipients.length > 0 ? recipients.map((recipient) => ({ nativeId: recipient.id, formId: String(recipient.id), name: recipient.name, email: recipient.email, role: recipient.role, actionAuth: ZRecipientAuthOptionsSchema.parse(recipient.authOptions)?.actionAuth ?? undefined, })) : [ { formId: initialId, name: '', email: '', role: RecipientRole.SIGNER, actionAuth: undefined, }, ], }, }); // Always show advanced settings if any recipient has auth options. const alwaysShowAdvancedSettings = useMemo(() => { const recipientHasAuthOptions = recipients.find((recipient) => { const recipientAuthOptions = ZRecipientAuthOptionsSchema.parse(recipient.authOptions); return recipientAuthOptions?.accessAuth || recipientAuthOptions?.actionAuth; }); const formHasActionAuth = form.getValues('signers').find((signer) => signer.actionAuth); return recipientHasAuthOptions !== undefined || formHasActionAuth !== undefined; }, [recipients, form]); const [showAdvancedSettings, setShowAdvancedSettings] = useState(alwaysShowAdvancedSettings); const { formState: { errors, isSubmitting }, control, } = form; const onFormSubmit = form.handleSubmit(onSubmit); const { append: appendSigner, fields: signers, remove: removeSigner, } = useFieldArray({ control, name: 'signers', }); const hasBeenSentToRecipientId = (id?: number) => { if (!id) { return false; } return recipients.some( (recipient) => recipient.id === id && recipient.sendStatus === SendStatus.SENT && recipient.role !== RecipientRole.CC, ); }; const onAddSigner = () => { appendSigner({ formId: nanoid(12), name: '', email: '', role: RecipientRole.SIGNER, actionAuth: undefined, }); }; const onRemoveSigner = (index: number) => { const signer = signers[index]; if (hasBeenSentToRecipientId(signer.nativeId)) { toast({ title: 'Cannot remove signer', description: 'This signer has already received the document.', variant: 'destructive', }); return; } removeSigner(index); }; const onKeyDown = (event: React.KeyboardEvent) => { if (event.key === 'Enter' && event.target instanceof HTMLInputElement) { onAddSigner(); } }; return ( <> {isDocumentPdfLoaded && fields.map((field, index) => ( ))}
{signers.map((signer, index) => ( ( {!showAdvancedSettings && index === 0 && ( Email )} )} /> ( {!showAdvancedSettings && index === 0 && ( Name )} )} /> {showAdvancedSettings && isDocumentEnterprise && ( ( )} /> )} ( )} /> ))}
{!alwaysShowAdvancedSettings && isDocumentEnterprise && (
setShowAdvancedSettings(Boolean(value))} />
)}
void onFormSubmit()} /> ); };