From 6505a400675304148f3e3053e1bd9a98e9d1c656 Mon Sep 17 00:00:00 2001 From: Catalin Pit <25515812+catalinpit@users.noreply.github.com> Date: Tue, 13 Aug 2024 16:03:35 +0300 Subject: [PATCH] feat: rework the name field --- .../d/[token]/sign-direct-template.tsx | 1 - .../app/(signing)/sign/[token]/name-field.tsx | 134 ++++++++++++++++-- .../sign/[token]/signing-field-container.tsx | 20 ++- 3 files changed, 134 insertions(+), 21 deletions(-) diff --git a/apps/web/src/app/(recipient)/d/[token]/sign-direct-template.tsx b/apps/web/src/app/(recipient)/d/[token]/sign-direct-template.tsx index 5fccddaba..e1f35773e 100644 --- a/apps/web/src/app/(recipient)/d/[token]/sign-direct-template.tsx +++ b/apps/web/src/app/(recipient)/d/[token]/sign-direct-template.tsx @@ -79,7 +79,6 @@ export const SignDirectTemplateForm = ({ const { currentStep, totalSteps, previousStep } = useStep(); const onSignField = (value: TSignFieldWithTokenMutationSchema) => { - console.log('onSignField value:', value.value); setLocalFields( localFields.map((field) => { if (field.id !== value.fieldId) { diff --git a/apps/web/src/app/(signing)/sign/[token]/name-field.tsx b/apps/web/src/app/(signing)/sign/[token]/name-field.tsx index 06a3dfc5e..a79c9f4f3 100644 --- a/apps/web/src/app/(signing)/sign/[token]/name-field.tsx +++ b/apps/web/src/app/(signing)/sign/[token]/name-field.tsx @@ -1,6 +1,6 @@ 'use client'; -import { useEffect, useTransition } from 'react'; +import { useEffect, useState, useTransition } from 'react'; import { useRouter } from 'next/navigation'; @@ -12,7 +12,14 @@ 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 type { TSignFieldWithTokenMutationSchema } from '@documenso/trpc/server/field-router/schema'; +import type { + TRemovedSignedFieldWithTokenMutationSchema, + TSignFieldWithTokenMutationSchema, +} from '@documenso/trpc/server/field-router/schema'; +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'; @@ -23,14 +30,16 @@ export type NameFieldProps = { field: FieldWithSignature; recipient: Recipient; onSignField?: (value: TSignFieldWithTokenMutationSchema) => Promise | void; + onUnsignField?: (value: TRemovedSignedFieldWithTokenMutationSchema) => Promise | void; }; -export const NameField = ({ field, recipient, onSignField }: NameFieldProps) => { +export const NameField = ({ field, recipient, onSignField, onUnsignField }: NameFieldProps) => { const router = useRouter(); const { toast } = useToast(); - const { fullName: providedFullName } = useRequiredSigningContext(); + const { fullName: providedFullName, setFullName: setProvidedFullName } = + useRequiredSigningContext(); const { executeActionAuthProcedure } = useRequiredDocumentAuthContext(); @@ -39,15 +48,47 @@ export const NameField = ({ field, recipient, onSignField }: NameFieldProps) => const { mutateAsync: signFieldWithToken, isLoading: isSignFieldWithTokenLoading } = trpc.field.signFieldWithToken.useMutation(DO_NOT_INVALIDATE_QUERY_ON_MUTATION); - const { isLoading: isRemoveSignedFieldWithTokenLoading } = - trpc.field.removeSignedFieldWithToken.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 [showFullNameModal, setShowFullNameModal] = useState(false); + const [localFullName, setLocalFullName] = useState(''); + + const onPreSign = () => { + if (!providedFullName) { + setShowFullNameModal(true); + return false; + } + + return true; + }; + + /** + * When the user clicks the sign button in the dialog where they enter their full name. + */ + const onDialogSignClick = () => { + setShowFullNameModal(false); + setProvidedFullName(localFullName); + + void executeActionAuthProcedure({ + onReauthFormSubmit: async (authOptions) => await onSign(authOptions, localFullName), + actionTarget: field.type, + }); + }; + const onSign = async (authOptions?: TRecipientActionAuth, name?: string) => { try { const value = name || providedFullName; + if (!value) { + setShowFullNameModal(true); + return; + } + const payload: TSignFieldWithTokenMutationSchema = { token: recipient.token, fieldId: field.id, @@ -81,8 +122,34 @@ export const NameField = ({ field, recipient, onSignField }: NameFieldProps) => } }; + const onRemove = async () => { + try { + const payload: TRemovedSignedFieldWithTokenMutationSchema = { + token: recipient.token, + fieldId: field.id, + }; + + if (onUnsignField) { + await onUnsignField(payload); + return; + } + + await removeSignedFieldWithToken(payload); + + startTransition(() => router.refresh()); + } catch (err) { + console.error(err); + + toast({ + title: 'Error', + description: 'An error occurred while removing the signature.', + variant: 'destructive', + }); + } + }; + useEffect(() => { - if (!field.inserted) { + if (!field.inserted && providedFullName) { void executeActionAuthProcedure({ onReauthFormSubmit: async (authOptions) => await onSign(authOptions), actionTarget: field.type, @@ -91,7 +158,13 @@ export const NameField = ({ field, recipient, onSignField }: NameFieldProps) => }, [field]); return ( - + {isLoading && (
@@ -109,6 +182,51 @@ export const NameField = ({ field, recipient, onSignField }: NameFieldProps) => {field.customText}

)} + + + + + Sign as {recipient.name}{' '} +
({recipient.email})
+
+ +
+ + + setLocalFullName(e.target.value.trimStart())} + /> +
+ + +
+ + + +
+
+
+
); }; diff --git a/apps/web/src/app/(signing)/sign/[token]/signing-field-container.tsx b/apps/web/src/app/(signing)/sign/[token]/signing-field-container.tsx index 43f4c26b4..abcf78d84 100644 --- a/apps/web/src/app/(signing)/sign/[token]/signing-field-container.tsx +++ b/apps/web/src/app/(signing)/sign/[token]/signing-field-container.tsx @@ -173,18 +173,14 @@ export const SigningFieldContainer = ({ )} - {type !== 'Checkbox' && - !automatedFields && - field.inserted && - !loading && - !readOnlyField && ( - - )} + {type !== 'Checkbox' && field.inserted && !loading && !readOnlyField && ( + + )} {children}