Files
documenso/apps/remix/app/components/general/envelope-signing/envelope-signer-form.tsx
2025-11-07 14:17:52 +11:00

134 lines
4.5 KiB
TypeScript

import { useMemo } from 'react';
import { Plural, Trans } from '@lingui/react/macro';
import { FieldType, RecipientRole } from '@prisma/client';
import { Input } from '@documenso/ui/primitives/input';
import { Label } from '@documenso/ui/primitives/label';
import { RadioGroup, RadioGroupItem } from '@documenso/ui/primitives/radio-group';
import { SignaturePadDialog } from '@documenso/ui/primitives/signature-pad/signature-pad-dialog';
import { useEmbedSigningContext } from '~/components/embed/embed-signing-context';
import { useRequiredEnvelopeSigningContext } from '../document-signing/envelope-signing-provider';
export default function EnvelopeSignerForm() {
const {
fullName,
signature,
setFullName,
setSignature,
envelope,
recipientFields,
recipient,
assistantFields,
assistantRecipients,
selectedAssistantRecipient,
setSelectedAssistantRecipientId,
} = useRequiredEnvelopeSigningContext();
const { isNameLocked, isEmailLocked } = useEmbedSigningContext() || {};
const hasSignatureField = useMemo(() => {
return recipientFields.some((field) => field.type === FieldType.SIGNATURE);
}, [recipientFields]);
const isSubmitting = false;
if (recipient.role === RecipientRole.VIEWER) {
return null;
}
if (recipient.role === RecipientRole.ASSISTANT) {
return (
<fieldset className="embed--DocumentWidgetForm dark:bg-background border-border rounded-2xl sm:border sm:p-3">
<RadioGroup
className="gap-0 space-y-2 shadow-none sm:space-y-3"
value={selectedAssistantRecipient?.id?.toString()}
onValueChange={(value) => {
setSelectedAssistantRecipientId(Number(value));
}}
>
{assistantRecipients
.filter((r) => r.fields.length > 0)
.map((r) => (
<div
key={r.id}
className="bg-widget border-border relative flex flex-col gap-4 rounded-lg border p-4"
>
<div className="flex items-center justify-between">
<div className="flex items-center gap-3">
<RadioGroupItem
id={r.id.toString()}
value={r.id.toString()}
className="after:absolute after:inset-0"
/>
<div className="grid grow gap-1">
<Label className="inline-flex items-start" htmlFor={r.id.toString()}>
{r.name}
{r.id === recipient.id && (
<span className="text-muted-foreground ml-2">
<Trans>(You)</Trans>
</span>
)}
</Label>
<p className="text-muted-foreground text-xs">{r.email}</p>
</div>
</div>
<div className="text-muted-foreground text-xs leading-[inherit]">
<Plural
value={assistantFields.filter((field) => field.recipientId === r.id).length}
one="# field"
other="# fields"
/>
</div>
</div>
</div>
))}
</RadioGroup>
</fieldset>
);
}
return (
<fieldset disabled={isSubmitting} className="flex flex-1 flex-col gap-4">
<div className="flex flex-1 flex-col gap-y-4">
<div>
<Label htmlFor="full-name">
<Trans>Full Name</Trans>
</Label>
<Input
type="text"
id="full-name"
className="bg-background mt-2"
value={fullName}
disabled={isNameLocked}
onChange={(e) => !isNameLocked && setFullName(e.target.value.trimStart())}
/>
</div>
{hasSignatureField && (
<div>
<Label htmlFor="Signature">
<Trans>Signature</Trans>
</Label>
<SignaturePadDialog
className="mt-2"
disabled={isSubmitting}
value={signature ?? ''}
onChange={(v) => setSignature(v ?? '')}
typedSignatureEnabled={envelope.documentMeta.typedSignatureEnabled}
uploadSignatureEnabled={envelope.documentMeta.uploadSignatureEnabled}
drawSignatureEnabled={envelope.documentMeta.drawSignatureEnabled}
/>
</div>
)}
</div>
</fieldset>
);
}