Files
esign/packages/ui/components/document/document-email-checkboxes.tsx
zeekayandHanzo Dev 04b66be987 fix(forms): type the document and template flows by the form's input
@hookform/resolvers 5 types a zod resolver as input in, output out: the
form holds z.input of its schema, and only handleSubmit sees z.output. The
flows spelled their forms as the output and dropped the input on the floor,
where a default or a transform makes the two differ: signers' actionAuth and
distributionMethod have defaults, and field meta takes `{}` and makes it
undefined.

Each flow's schema now exports its input beside its output, and whatever
holds or passes on the form's values uses it: the clipboard and last-active
field, the field item, its content and tooltip (which re-parse the meta
anyway), the email checkboxes, and every autosave. Autosave reads
getValues(), which is what the user typed, not what the schema made of it,
so it is typed as that all the way to the mutation, whose request type is
now z.input of the request schema — what the server parses.

Three reads of form state now apply the schema's own default where the
value may be unset: `actionAuth ?? []` in both signer steps and
`distributionMethod ?? EMAIL` in the subject step. Every writer in those
forms sets the value, so nothing reachable changes. Two `value &&
onChange(value)` statements become ifs, which typescript-eslint 8 asks for.

Co-authored-by: Hanzo Dev <[email protected]>
2026-09-19 04:20:14 -07:00

335 lines
10 KiB
TypeScript

import { Trans } from '@lingui/react/macro';
import { InfoIcon } from 'lucide-react';
import type { TDocumentEmailSettingsInput } from '@hanzo/esign-lib/types/document-email';
import { DocumentEmailEvents } from '@hanzo/esign-lib/types/document-email';
import { Tooltip, TooltipContent, TooltipTrigger } from '@hanzo/esign-ui/primitives/tooltip';
import { cn } from '../../lib/utils';
import { Checkbox } from '../../primitives/checkbox';
type Value = TDocumentEmailSettingsInput;
type DocumentEmailCheckboxesProps = {
value: Value;
onChange: (value: Value) => void;
className?: string;
};
export const DocumentEmailCheckboxes = ({
value,
onChange,
className,
}: DocumentEmailCheckboxesProps) => {
return (
<div className={cn('space-y-3', className)}>
<div className="flex flex-row items-center">
<Checkbox
id={DocumentEmailEvents.RecipientSigned}
className="h-5 w-5"
checked={value.recipientSigned}
onCheckedChange={(checked) =>
onChange({ ...value, [DocumentEmailEvents.RecipientSigned]: Boolean(checked) })
}
/>
<label
className="text-muted-foreground ml-2 flex flex-row items-center text-sm"
htmlFor={DocumentEmailEvents.RecipientSigned}
>
<Trans>Email the owner when a recipient signs</Trans>
<Tooltip>
<TooltipTrigger>
<InfoIcon className="mx-2 h-4 w-4" />
</TooltipTrigger>
<TooltipContent className="text-foreground max-w-md space-y-2 p-4">
<h2>
<strong>
<Trans>Recipient signed email</Trans>
</strong>
</h2>
<p>
<Trans>
This email is sent to the document owner when a recipient has signed the document.
</Trans>
</p>
</TooltipContent>
</Tooltip>
</label>
</div>
<div className="flex flex-row items-center">
<Checkbox
id={DocumentEmailEvents.RecipientSigningRequest}
className="h-5 w-5"
checked={value.recipientSigningRequest}
onCheckedChange={(checked) =>
onChange({ ...value, [DocumentEmailEvents.RecipientSigningRequest]: Boolean(checked) })
}
/>
<label
className="text-muted-foreground ml-2 flex flex-row items-center text-sm"
htmlFor={DocumentEmailEvents.RecipientSigningRequest}
>
<Trans>Email recipients with a signing request</Trans>
<Tooltip>
<TooltipTrigger>
<InfoIcon className="mx-2 h-4 w-4" />
</TooltipTrigger>
<TooltipContent className="text-foreground max-w-md space-y-2 p-4">
<h2>
<strong>
<Trans>Recipient signing request email</Trans>
</strong>
</h2>
<p>
<Trans>
This email is sent to the recipient requesting them to sign the document.
</Trans>
</p>
</TooltipContent>
</Tooltip>
</label>
</div>
<div className="flex flex-row items-center">
<Checkbox
id={DocumentEmailEvents.RecipientRemoved}
className="h-5 w-5"
checked={value.recipientRemoved}
onCheckedChange={(checked) =>
onChange({ ...value, [DocumentEmailEvents.RecipientRemoved]: Boolean(checked) })
}
/>
<label
className="text-muted-foreground ml-2 flex flex-row items-center text-sm"
htmlFor={DocumentEmailEvents.RecipientRemoved}
>
<Trans>Email recipients when they're removed from a pending document</Trans>
<Tooltip>
<TooltipTrigger>
<InfoIcon className="mx-2 h-4 w-4" />
</TooltipTrigger>
<TooltipContent className="text-foreground max-w-md space-y-2 p-4">
<h2>
<strong>
<Trans>Recipient removed email</Trans>
</strong>
</h2>
<p>
<Trans>
This email is sent to the recipient if they are removed from a pending document.
</Trans>
</p>
</TooltipContent>
</Tooltip>
</label>
</div>
<div className="flex flex-row items-center">
<Checkbox
id={DocumentEmailEvents.DocumentPending}
className="h-5 w-5"
checked={value.documentPending}
onCheckedChange={(checked) =>
onChange({ ...value, [DocumentEmailEvents.DocumentPending]: Boolean(checked) })
}
/>
<label
className="text-muted-foreground ml-2 flex flex-row items-center text-sm"
htmlFor={DocumentEmailEvents.DocumentPending}
>
<Trans>Email the signer if the document is still pending</Trans>
<Tooltip>
<TooltipTrigger>
<InfoIcon className="mx-2 h-4 w-4" />
</TooltipTrigger>
<TooltipContent className="text-foreground max-w-md space-y-2 p-4">
<h2>
<strong>
<Trans>Document pending email</Trans>
</strong>
</h2>
<p>
<Trans>
This email will be sent to the recipient who has just signed the document, if
there are still other recipients who have not signed yet.
</Trans>
</p>
</TooltipContent>
</Tooltip>
</label>
</div>
<div className="flex flex-row items-center">
<Checkbox
id={DocumentEmailEvents.DocumentCompleted}
className="h-5 w-5"
checked={value.documentCompleted}
onCheckedChange={(checked) =>
onChange({ ...value, [DocumentEmailEvents.DocumentCompleted]: Boolean(checked) })
}
/>
<label
className="text-muted-foreground ml-2 flex flex-row items-center text-sm"
htmlFor={DocumentEmailEvents.DocumentCompleted}
>
<Trans>Email recipients when the document is completed</Trans>
<Tooltip>
<TooltipTrigger>
<InfoIcon className="mx-2 h-4 w-4" />
</TooltipTrigger>
<TooltipContent className="text-foreground max-w-md space-y-2 p-4">
<h2>
<strong>
<Trans>Document completed email</Trans>
</strong>
</h2>
<p>
<Trans>
This will be sent to all recipients once the document has been fully completed.
</Trans>
</p>
</TooltipContent>
</Tooltip>
</label>
</div>
<div className="flex flex-row items-center">
<Checkbox
id={DocumentEmailEvents.DocumentDeleted}
className="h-5 w-5"
checked={value.documentDeleted}
onCheckedChange={(checked) =>
onChange({ ...value, [DocumentEmailEvents.DocumentDeleted]: Boolean(checked) })
}
/>
<label
className="text-muted-foreground ml-2 flex flex-row items-center text-sm"
htmlFor={DocumentEmailEvents.DocumentDeleted}
>
<Trans>Email recipients when a pending document is deleted</Trans>
<Tooltip>
<TooltipTrigger>
<InfoIcon className="mx-2 h-4 w-4" />
</TooltipTrigger>
<TooltipContent className="text-foreground max-w-md space-y-2 p-4">
<h2>
<strong>
<Trans>Document deleted email</Trans>
</strong>
</h2>
<p>
<Trans>
This will be sent to all recipients if a pending document has been deleted.
</Trans>
</p>
</TooltipContent>
</Tooltip>
</label>
</div>
<div className="flex flex-row items-center">
<Checkbox
id={DocumentEmailEvents.OwnerDocumentCompleted}
className="h-5 w-5"
checked={value.ownerDocumentCompleted}
onCheckedChange={(checked) =>
onChange({ ...value, [DocumentEmailEvents.OwnerDocumentCompleted]: Boolean(checked) })
}
/>
<label
className="text-muted-foreground ml-2 flex flex-row items-center text-sm"
htmlFor={DocumentEmailEvents.OwnerDocumentCompleted}
>
<Trans>Email the owner when the document is completed</Trans>
<Tooltip>
<TooltipTrigger>
<InfoIcon className="mx-2 h-4 w-4" />
</TooltipTrigger>
<TooltipContent className="text-foreground max-w-md space-y-2 p-4">
<h2>
<strong>
<Trans>Document completed email</Trans>
</strong>
</h2>
<p>
<Trans>
This will be sent to the document owner once the document has been fully
completed.
</Trans>
</p>
</TooltipContent>
</Tooltip>
</label>
</div>
<div className="flex flex-row items-center">
<Checkbox
id={DocumentEmailEvents.OwnerRecipientExpired}
className="h-5 w-5"
checked={value.ownerRecipientExpired}
onCheckedChange={(checked) =>
onChange({ ...value, [DocumentEmailEvents.OwnerRecipientExpired]: Boolean(checked) })
}
/>
<label
className="text-muted-foreground ml-2 flex flex-row items-center text-sm"
htmlFor={DocumentEmailEvents.OwnerRecipientExpired}
>
<Trans>Send recipient expired email to the owner</Trans>
<Tooltip>
<TooltipTrigger>
<InfoIcon className="mx-2 h-4 w-4" />
</TooltipTrigger>
<TooltipContent className="text-foreground max-w-md space-y-2 p-4">
<h2>
<strong>
<Trans>Recipient expired email</Trans>
</strong>
</h2>
<p>
<Trans>
This will be sent to the document owner when a recipient's signing window has
expired.
</Trans>
</p>
</TooltipContent>
</Tooltip>
</label>
</div>
</div>
);
};