diff --git a/apps/web/src/app/(dashboard)/templates/use-template-dialog.tsx b/apps/web/src/app/(dashboard)/templates/use-template-dialog.tsx
index 544cf4d72..811a39e55 100644
--- a/apps/web/src/app/(dashboard)/templates/use-template-dialog.tsx
+++ b/apps/web/src/app/(dashboard)/templates/use-template-dialog.tsx
@@ -7,15 +7,17 @@ import { useRouter } from 'next/navigation';
import { zodResolver } from '@hookform/resolvers/zod';
import { Trans, msg } from '@lingui/macro';
import { useLingui } from '@lingui/react';
-import { InfoIcon, Plus } from 'lucide-react';
+import { InfoIcon, Plus, Upload, X } from 'lucide-react';
import { useFieldArray, useForm } from 'react-hook-form';
import * as z from 'zod';
+import { APP_DOCUMENT_UPLOAD_SIZE_LIMIT } from '@documenso/lib/constants/app';
import {
TEMPLATE_RECIPIENT_EMAIL_PLACEHOLDER_REGEX,
TEMPLATE_RECIPIENT_NAME_PLACEHOLDER_REGEX,
} from '@documenso/lib/constants/template';
import { AppError } from '@documenso/lib/errors/app-error';
+import { putPdfFile } from '@documenso/lib/universal/upload/put-file';
import type { Recipient } from '@documenso/prisma/client';
import { DocumentDistributionMethod, DocumentSigningOrder } from '@documenso/prisma/client';
import { trpc } from '@documenso/trpc/react';
@@ -50,6 +52,11 @@ import { useOptionalCurrentTeam } from '~/providers/team';
const ZAddRecipientsForNewDocumentSchema = z
.object({
distributeDocument: z.boolean(),
+ useCustomDocument: z.boolean().default(false),
+ customDocumentData: z
+ .any()
+ .refine((data) => data instanceof File || data === undefined)
+ .optional(),
recipients: z.array(
z.object({
id: z.number(),
@@ -119,6 +126,8 @@ export function UseTemplateDialog({
resolver: zodResolver(ZAddRecipientsForNewDocumentSchema),
defaultValues: {
distributeDocument: false,
+ useCustomDocument: false,
+ customDocumentData: undefined,
recipients: recipients
.sort((a, b) => (a.signingOrder || 0) - (b.signingOrder || 0))
.map((recipient) => {
@@ -145,11 +154,19 @@ export function UseTemplateDialog({
const onSubmit = async (data: TAddRecipientsForNewDocumentSchema) => {
try {
+ let customDocumentDataId: string | undefined = undefined;
+
+ if (data.useCustomDocument && data.customDocumentData) {
+ const customDocumentData = await putPdfFile(data.customDocumentData);
+ customDocumentDataId = customDocumentData.id;
+ }
+
const { id } = await createDocumentFromTemplate({
templateId,
teamId: team?.id,
recipients: data.recipients,
distributeDocument: data.distributeDocument,
+ customDocumentDataId,
});
toast({
@@ -300,89 +317,245 @@ export function UseTemplateDialog({
/>
))}
+
+ {recipients.length > 0 && (
+
+
(
+
+
+
+
+ {documentDistributionMethod === DocumentDistributionMethod.EMAIL && (
+
+ )}
+
+ {documentDistributionMethod === DocumentDistributionMethod.NONE && (
+
+ )}
+
+
+ )}
+ />
+
+ )}
+
+ (
+
+
+
{
+ field.onChange(checked);
+ if (!checked) {
+ form.setValue('customDocumentData', undefined);
+ }
+ }}
+ />
+
+
+
+ )}
+ />
+
+ {form.watch('useCustomDocument') && (
+
+
(
+
+
+
+
+
+
+
+
+ )}
+ />
+
+ )}
- {recipients.length > 0 && (
-
-
(
-
-
-
-
- {documentDistributionMethod === DocumentDistributionMethod.EMAIL && (
-
- )}
-
- {documentDistributionMethod === DocumentDistributionMethod.NONE && (
-
- )}
-
-
- )}
- />
-
- )}
-
-
+