'use client'; import { useEffect, useState, useTransition } from 'react'; import { useRouter } from 'next/navigation'; import { Loader } from 'lucide-react'; import { DO_NOT_INVALIDATE_QUERY_ON_MUTATION } from '@documenso/lib/constants/trpc'; import { AppError, AppErrorCode } from '@documenso/lib/errors/app-error'; import type { TRecipientActionAuth } from '@documenso/lib/types/document-auth'; import type { Recipient } from '@documenso/prisma/client'; import type { FieldWithSignature } from '@documenso/prisma/types/field-with-signature'; import { trpc } from '@documenso/trpc/react'; import { Button } from '@documenso/ui/primitives/button'; import { Dialog, DialogContent, DialogFooter, DialogTitle } from '@documenso/ui/primitives/dialog'; import { Input } from '@documenso/ui/primitives/input'; import { Label } from '@documenso/ui/primitives/label'; import { useToast } from '@documenso/ui/primitives/use-toast'; import { useRequiredDocumentAuthContext } from './document-auth-provider'; import { SigningFieldContainer } from './signing-field-container'; export type TextFieldProps = { field: FieldWithSignature; recipient: Recipient; }; export const TextField = ({ field, recipient }: TextFieldProps) => { const router = useRouter(); const { toast } = useToast(); const { executeActionAuthProcedure } = useRequiredDocumentAuthContext(); const [isPending, startTransition] = useTransition(); const { mutateAsync: signFieldWithToken, isLoading: isSignFieldWithTokenLoading } = trpc.field.signFieldWithToken.useMutation(DO_NOT_INVALIDATE_QUERY_ON_MUTATION); const { mutateAsync: removeSignedFieldWithToken, isLoading: isRemoveSignedFieldWithTokenLoading, } = trpc.field.removeSignedFieldWithToken.useMutation(DO_NOT_INVALIDATE_QUERY_ON_MUTATION); const isLoading = isSignFieldWithTokenLoading || isRemoveSignedFieldWithTokenLoading || isPending; const [showCustomTextModal, setShowCustomTextModal] = useState(false); const [localText, setLocalCustomText] = useState(''); useEffect(() => { if (!showCustomTextModal) { setLocalCustomText(''); } }, [showCustomTextModal]); /** * When the user clicks the sign button in the dialog where they enter the text field. */ const onDialogSignClick = () => { setShowCustomTextModal(false); void executeActionAuthProcedure({ onReauthFormSubmit: async (authOptions) => await onSign(authOptions), actionTarget: field.type, }); }; const onPreSign = () => { if (!localText) { setShowCustomTextModal(true); return false; } return true; }; const onSign = async (authOptions?: TRecipientActionAuth) => { try { if (!localText) { return; } await signFieldWithToken({ token: recipient.token, fieldId: field.id, value: localText, isBase64: true, authOptions, }); setLocalCustomText(''); startTransition(() => router.refresh()); } catch (err) { const error = AppError.parseError(err); if (error.code === AppErrorCode.UNAUTHORIZED) { throw error; } console.error(err); toast({ title: 'Error', description: 'An error occurred while signing the document.', variant: 'destructive', }); } }; const onRemove = async () => { try { await removeSignedFieldWithToken({ token: recipient.token, fieldId: field.id, }); startTransition(() => router.refresh()); } catch (err) { console.error(err); toast({ title: 'Error', description: 'An error occurred while removing the text.', variant: 'destructive', }); } }; return ( {isLoading && (
)} {!field.inserted && (

Text

)} {field.inserted &&

{field.customText}

} Enter your Text ({recipient.email})
setLocalCustomText(e.target.value)} />
); };