import { useCurrentEnvelopeEditor } from '@documenso/lib/client-only/providers/envelope-editor-provider'; import { EnvelopeRenderProvider, useCurrentEnvelopeRender, } from '@documenso/lib/client-only/providers/envelope-render-provider'; import { PDF_VIEWER_ERROR_MESSAGES } from '@documenso/lib/constants/pdf-viewer-i18n'; import { ZFieldAndMetaSchema } from '@documenso/lib/types/field-meta'; import { extractFieldInsertionValues } from '@documenso/lib/utils/envelope-signing'; import { toCheckboxCustomText } from '@documenso/lib/utils/fields'; import { extractInitials } from '@documenso/lib/utils/recipient-formatter'; import { AnimateGenericFadeInOut } from '@documenso/ui/components/animate/animate-generic-fade-in-out'; import { Alert, AlertDescription, AlertTitle } from '@documenso/ui/primitives/alert'; import { RecipientSelector } from '@documenso/ui/primitives/recipient-selector'; import { Separator } from '@documenso/ui/primitives/separator'; import type { Faker } from '@faker-js/faker'; import { Trans } from '@lingui/react/macro'; import { FieldType, SigningStatus } from '@prisma/client'; import { FileTextIcon } from 'lucide-react'; import { useEffect, useMemo, useRef, useState } from 'react'; import { match } from 'ts-pattern'; import { EnvelopeGenericPageRenderer } from '~/components/general/envelope-editor/envelope-generic-page-renderer'; import { EnvelopePdfViewer } from '~/components/general/pdf-viewer/envelope-pdf-viewer'; import { EnvelopeRendererFileSelector } from './envelope-file-selector'; export const EnvelopeEditorPreviewPage = () => { const { envelope, editorFields, editorConfig } = useCurrentEnvelopeEditor(); const { currentEnvelopeItem, fields } = useCurrentEnvelopeRender(); const scrollableContainerRef = useRef(null); const [selectedPreviewMode, setSelectedPreviewMode] = useState<'recipient' | 'signed'>('recipient'); const [fakerInstance, setFakerInstance] = useState(null); useEffect(() => { void import('@faker-js/faker/locale/en').then((mod) => { setFakerInstance(mod.faker); }); }, []); const fieldsWithPlaceholders = useMemo(() => { if (!fakerInstance) { return []; } const faker = fakerInstance; return fields.map((field) => { const fieldMeta = ZFieldAndMetaSchema.parse(field); const recipient = envelope.recipients.find((recipient) => recipient.id === field.recipientId); if (!recipient) { throw new Error('Recipient not found'); } faker.seed(recipient.id); const recipientName = recipient.name || faker.person.fullName(); const recipientEmail = recipient.email || faker.internet.email(); faker.seed(recipient.id + field.id); return { ...field, inserted: true, ...match(fieldMeta) .with({ type: FieldType.TEXT }, ({ fieldMeta }) => { let text = fieldMeta?.text || faker.lorem.words(5); if (fieldMeta?.characterLimit) { text = text.slice(0, fieldMeta?.characterLimit); } return { customText: text, }; }) .with({ type: FieldType.NUMBER }, ({ fieldMeta }) => { let number = fieldMeta?.value ?? ''; if (number === '') { number = faker.number .int({ min: fieldMeta?.minValue ?? 0, max: fieldMeta?.maxValue ?? 1000, }) .toString(); } return { customText: number, }; }) .with({ type: FieldType.DATE }, () => { const date = extractFieldInsertionValues({ fieldValue: { type: FieldType.DATE, value: true, }, field, documentMeta: envelope.documentMeta, }); return { customText: date.customText, }; }) .with({ type: FieldType.EMAIL }, () => { return { customText: recipientEmail, }; }) .with({ type: FieldType.NAME }, () => { return { customText: recipientName, }; }) .with({ type: FieldType.INITIALS }, () => { return { customText: extractInitials(recipientName), }; }) .with({ type: FieldType.RADIO }, ({ fieldMeta }) => { const values = fieldMeta?.values ?? []; if (values.length === 0) { return ''; } let customText = ''; const preselectedValue = values.findIndex((value) => value.checked); if (preselectedValue !== -1) { customText = preselectedValue.toString(); } else { const randomIndex = faker.number.int({ min: 0, max: values.length - 1 }); customText = randomIndex.toString(); } return { customText, }; }) .with({ type: FieldType.CHECKBOX }, ({ fieldMeta }) => { let checkedValues: number[] = []; const values = fieldMeta?.values ?? []; values.forEach((value, index) => { if (value.checked) { checkedValues.push(index); } }); if (checkedValues.length === 0 && values.length > 0) { const numberOfValues = fieldMeta?.validationLength || 1; checkedValues = Array.from({ length: numberOfValues }, (_, index) => index); } return { customText: toCheckboxCustomText(checkedValues), }; }) .with({ type: FieldType.DROPDOWN }, ({ fieldMeta }) => { const values = fieldMeta?.values ?? []; let customText = fieldMeta?.defaultValue || ''; if (!customText && values.length > 0) { const randomIndex = faker.number.int({ min: 0, max: values.length - 1 }); customText = values[randomIndex].value; } return { customText, }; }) .with({ type: FieldType.SIGNATURE }, () => { return { customText: '', signature: { signatureImageAsBase64: '', typedSignature: recipientName, }, }; }) .with({ type: FieldType.FREE_SIGNATURE }, () => { return { customText: '', }; }) .exhaustive(), }; }); }, [fields, envelope, envelope.recipients, envelope.documentMeta, fakerInstance]); /** * Set the selected recipient to the first recipient in the envelope. */ useEffect(() => { editorFields.setSelectedRecipient(envelope.recipients[0]?.id ?? null); }, []); // Override the parent renderer provider so we can inject custom fields. return ( ({ ...recipient, signingStatus: SigningStatus.SIGNED, }))} presignToken={editorConfig?.embedded?.presignToken} overrideSettings={{ mode: 'export', }} >
{/* Horizontal envelope item selector */} Preview Mode Preview what the signed document will look like with placeholder data {/* Document View */}
{currentEnvelopeItem !== null ? ( ) : (

No documents found

Please upload a document to continue

)}
{/* Right Section - Form Fields Panel */} {currentEnvelopeItem && false && (
{/* Add fields section. */}
{/*

Preivew Mode

*/} Preview Mode Preview what the signed document will look like with placeholder data {/* setSelectedPreviewMode(value as 'recipient' | 'signed')} >
Preview what a recipient will see
Preview the signed document
*/}
{false && ( {selectedPreviewMode === 'recipient' && ( <> {/* Recipient selector section. */}

Selected Recipient

editorFields.setSelectedRecipient(recipient.id)} recipients={envelope.recipients} className="w-full" align="end" />
)}
)}
)}
); };