import React from 'react'; import { Trans } from '@lingui/react/macro'; import { FieldType } from '@prisma/client'; import { X } from 'lucide-react'; import { type TRecipientActionAuth } from '@documenso/lib/types/document-auth'; import { ZFieldMetaSchema } from '@documenso/lib/types/field-meta'; import type { FieldWithSignature } from '@documenso/prisma/types/field-with-signature'; import { FieldRootContainer } from '@documenso/ui/components/field/field'; import { cn } from '@documenso/ui/lib/utils'; import { Tooltip, TooltipContent, TooltipTrigger } from '@documenso/ui/primitives/tooltip'; import { useRequiredDocumentSigningAuthContext } from './document-signing-auth-provider'; export type DocumentSigningFieldContainerProps = { field: FieldWithSignature; loading?: boolean; children: React.ReactNode; /** * A function that is called before the field requires to be signed, or reauthed. * * Example, you may want to show a dialog prior to signing where they can enter a value. * * Once that action is complete, you will need to call `executeActionAuthProcedure` to proceed * regardless if it requires reauth or not. * * If the function returns true, we will proceed with the signing process. Otherwise if * false is returned we will not proceed. */ onPreSign?: () => Promise | boolean; /** * The function required to be executed to insert the field. * * The auth values will be passed in if available. */ onSign?: (documentAuthValue?: TRecipientActionAuth) => Promise | void; onRemove?: (fieldType?: string) => Promise | void; type?: | 'Date' | 'Initials' | 'Email' | 'Name' | 'Signature' | 'Radio' | 'Dropdown' | 'Number' | 'Checkbox'; tooltipText?: string | null; }; export const DocumentSigningFieldContainer = ({ field, loading, onPreSign, onSign, onRemove, children, type, tooltipText, }: DocumentSigningFieldContainerProps) => { const { executeActionAuthProcedure, isAuthRedirectRequired } = useRequiredDocumentSigningAuthContext(); const parsedFieldMeta = field.fieldMeta ? ZFieldMetaSchema.parse(field.fieldMeta) : undefined; const readOnlyField = parsedFieldMeta?.readOnly || false; const handleInsertField = async () => { if (field.inserted || !onSign) { return; } // Bypass reauth for non signature fields. if (field.type !== FieldType.SIGNATURE) { const presignResult = await onPreSign?.(); if (presignResult === false) { return; } await onSign(); return; } if (isAuthRedirectRequired) { await executeActionAuthProcedure({ onReauthFormSubmit: () => { // Do nothing since the user should be redirected. }, actionTarget: field.type, }); return; } // Handle any presign requirements, and halt if required. if (onPreSign) { const preSignResult = await onPreSign(); if (preSignResult === false) { return; } } await executeActionAuthProcedure({ onReauthFormSubmit: onSign, actionTarget: field.type, }); }; const onRemoveSignedFieldClick = async () => { if (!field.inserted) { return; } await onRemove?.(); }; const onClearCheckBoxValues = async (fieldType?: string) => { if (!field.inserted) { return; } await onRemove?.(fieldType); }; return (
{!field.inserted && !loading && !readOnlyField && ( )} {type === 'Date' && field.inserted && !loading && !readOnlyField && ( {tooltipText && {tooltipText}} )} {type === 'Checkbox' && field.inserted && !loading && !readOnlyField && ( )} {type !== 'Date' && type !== 'Checkbox' && field.inserted && !loading && !readOnlyField && ( )} {children}
); };