import { lazy, useEffect, useMemo } from 'react'; import type { MessageDescriptor } from '@lingui/core'; import { msg } from '@lingui/core/macro'; import { Trans, useLingui } from '@lingui/react/macro'; import { FieldType, RecipientRole } from '@prisma/client'; import { FileTextIcon } from 'lucide-react'; import { Link } from 'react-router'; import { isDeepEqual } from 'remeda'; import { match } from 'ts-pattern'; import { useCurrentEnvelopeEditor } from '@documenso/lib/client-only/providers/envelope-editor-provider'; import { useCurrentEnvelopeRender } from '@documenso/lib/client-only/providers/envelope-render-provider'; import type { TCheckboxFieldMeta, TDateFieldMeta, TDropdownFieldMeta, TEmailFieldMeta, TFieldMetaSchema, TInitialsFieldMeta, TNameFieldMeta, TNumberFieldMeta, TRadioFieldMeta, TSignatureFieldMeta, TTextFieldMeta, } from '@documenso/lib/types/field-meta'; import { canRecipientFieldsBeModified } from '@documenso/lib/utils/recipients'; import { AnimateGenericFadeInOut } from '@documenso/ui/components/animate/animate-generic-fade-in-out'; import PDFViewerKonvaLazy from '@documenso/ui/components/pdf-viewer/pdf-viewer-konva-lazy'; import { Alert, AlertDescription, AlertTitle } from '@documenso/ui/primitives/alert'; import { Button } from '@documenso/ui/primitives/button'; import { RecipientSelector } from '@documenso/ui/primitives/recipient-selector'; import { Separator } from '@documenso/ui/primitives/separator'; import { EditorFieldCheckboxForm } from '~/components/forms/editor/editor-field-checkbox-form'; import { EditorFieldDateForm } from '~/components/forms/editor/editor-field-date-form'; import { EditorFieldDropdownForm } from '~/components/forms/editor/editor-field-dropdown-form'; import { EditorFieldEmailForm } from '~/components/forms/editor/editor-field-email-form'; import { EditorFieldInitialsForm } from '~/components/forms/editor/editor-field-initials-form'; import { EditorFieldNameForm } from '~/components/forms/editor/editor-field-name-form'; import { EditorFieldNumberForm } from '~/components/forms/editor/editor-field-number-form'; import { EditorFieldRadioForm } from '~/components/forms/editor/editor-field-radio-form'; import { EditorFieldSignatureForm } from '~/components/forms/editor/editor-field-signature-form'; import { EditorFieldTextForm } from '~/components/forms/editor/editor-field-text-form'; import { EnvelopeEditorFieldDragDrop } from './envelope-editor-fields-drag-drop'; import { EnvelopeRendererFileSelector } from './envelope-file-selector'; const EnvelopeEditorFieldsPageRenderer = lazy( async () => import('./envelope-editor-fields-page-renderer'), ); const FieldSettingsTypeTranslations: Record = { [FieldType.SIGNATURE]: msg`Signature Settings`, [FieldType.FREE_SIGNATURE]: msg`Free Signature Settings`, [FieldType.TEXT]: msg`Text Settings`, [FieldType.DATE]: msg`Date Settings`, [FieldType.EMAIL]: msg`Email Settings`, [FieldType.NAME]: msg`Name Settings`, [FieldType.INITIALS]: msg`Initials Settings`, [FieldType.NUMBER]: msg`Number Settings`, [FieldType.RADIO]: msg`Radio Settings`, [FieldType.CHECKBOX]: msg`Checkbox Settings`, [FieldType.DROPDOWN]: msg`Dropdown Settings`, }; export const EnvelopeEditorFieldsPage = () => { const { envelope, editorFields, relativePath } = useCurrentEnvelopeEditor(); const { currentEnvelopeItem } = useCurrentEnvelopeRender(); const { t } = useLingui(); const selectedField = useMemo( () => structuredClone(editorFields.selectedField), [editorFields.selectedField], ); const updateSelectedFieldMeta = (fieldMeta: TFieldMetaSchema) => { if (!selectedField) { return; } const isMetaSame = isDeepEqual(selectedField.fieldMeta, fieldMeta); // Todo: Envelopes - Clean up console logs. if (!isMetaSame) { console.log('TRIGGER UPDATE'); editorFields.updateFieldByFormId(selectedField.formId, { fieldMeta, }); } else { console.log('DATA IS SAME, NO UPDATE'); } }; /** * Set the selected recipient to the first recipient in the envelope. */ useEffect(() => { const firstSelectableRecipient = envelope.recipients.find( (recipient) => recipient.role === RecipientRole.SIGNER || recipient.role === RecipientRole.APPROVER, ); editorFields.setSelectedRecipient(firstSelectableRecipient?.id ?? null); }, []); return (
{/* Horizontal envelope item selector */} {/* Document View */}
{envelope.recipients.length === 0 && (
Missing Recipients You need at least one recipient to add fields
)} {currentEnvelopeItem !== null ? ( ) : (

No documents found

Please upload a document to continue

)}
{/* Right Section - Form Fields Panel */} {currentEnvelopeItem && envelope.recipients.length > 0 && (
{/* Recipient selector section. */}

Selected Recipient

editorFields.setSelectedRecipient(recipient.id) } recipients={envelope.recipients} className="w-full" align="end" /> {editorFields.selectedRecipient && !canRecipientFieldsBeModified(editorFields.selectedRecipient, envelope.fields) && ( This recipient can no longer be modified as they have signed a field, or completed the document. )}
{/* Add fields section. */}

Add Fields

{/* Field details section. */} {selectedField && (

{t(FieldSettingsTypeTranslations[selectedField.type])}

{match(selectedField.type) .with(FieldType.SIGNATURE, () => ( updateSelectedFieldMeta(value)} /> )) .with(FieldType.CHECKBOX, () => ( updateSelectedFieldMeta(value)} /> )) .with(FieldType.DATE, () => ( updateSelectedFieldMeta(value)} /> )) .with(FieldType.DROPDOWN, () => ( updateSelectedFieldMeta(value)} /> )) .with(FieldType.EMAIL, () => ( updateSelectedFieldMeta(value)} /> )) .with(FieldType.INITIALS, () => ( updateSelectedFieldMeta(value)} /> )) .with(FieldType.NAME, () => ( updateSelectedFieldMeta(value)} /> )) .with(FieldType.NUMBER, () => ( updateSelectedFieldMeta(value)} /> )) .with(FieldType.RADIO, () => ( updateSelectedFieldMeta(value)} /> )) .with(FieldType.TEXT, () => ( updateSelectedFieldMeta(value)} /> )) .otherwise(() => null)}
)}
)}
); };