diff --git a/apps/remix/app/components/dialogs/template-create-dialog.tsx b/apps/remix/app/components/dialogs/template-create-dialog.tsx deleted file mode 100644 index 676537e4c..000000000 --- a/apps/remix/app/components/dialogs/template-create-dialog.tsx +++ /dev/null @@ -1,136 +0,0 @@ -import { useState } from 'react'; - -import { msg } from '@lingui/core/macro'; -import { useLingui } from '@lingui/react'; -import { Trans } from '@lingui/react/macro'; -import { FilePlus, Loader } from 'lucide-react'; -import { useNavigate } from 'react-router'; - -import { useSession } from '@documenso/lib/client-only/providers/session'; -import { formatTemplatesPath } from '@documenso/lib/utils/teams'; -import { trpc } from '@documenso/trpc/react'; -import type { TCreateTemplatePayloadSchema } from '@documenso/trpc/server/template-router/schema'; -import { Button } from '@documenso/ui/primitives/button'; -import { - Dialog, - DialogClose, - DialogContent, - DialogDescription, - DialogFooter, - DialogHeader, - DialogTitle, - DialogTrigger, -} from '@documenso/ui/primitives/dialog'; -import { DocumentDropzone } from '@documenso/ui/primitives/document-dropzone'; -import { useToast } from '@documenso/ui/primitives/use-toast'; - -import { useCurrentTeam } from '~/providers/team'; - -type TemplateCreateDialogProps = { - folderId?: string; -}; - -export const TemplateCreateDialog = ({ folderId }: TemplateCreateDialogProps) => { - const navigate = useNavigate(); - - const { user } = useSession(); - const { toast } = useToast(); - const { _ } = useLingui(); - - const team = useCurrentTeam(); - - const { mutateAsync: createTemplate } = trpc.template.createTemplate.useMutation(); - - const [showTemplateCreateDialog, setShowTemplateCreateDialog] = useState(false); - const [isUploadingFile, setIsUploadingFile] = useState(false); - - const onFileDrop = async (files: File[]) => { - const file = files[0]; - - if (isUploadingFile) { - return; - } - - setIsUploadingFile(true); - - try { - const payload = { - title: file.name, - folderId: folderId, - } satisfies TCreateTemplatePayloadSchema; - - const formData = new FormData(); - - formData.append('payload', JSON.stringify(payload)); - formData.append('file', file); - - const { envelopeId: id } = await createTemplate(formData); - - toast({ - title: _(msg`Template document uploaded`), - description: _( - msg`Your document has been uploaded successfully. You will be redirected to the template page.`, - ), - duration: 5000, - }); - - setShowTemplateCreateDialog(false); - - await navigate(`${formatTemplatesPath(team.url)}/${id}/edit`); - } catch { - toast({ - title: _(msg`Something went wrong`), - description: _(msg`Please try again later.`), - variant: 'destructive', - }); - - setIsUploadingFile(false); - } - }; - - return ( - - ); -}; diff --git a/apps/remix/app/components/general/document/document-upload-button-legacy.tsx b/apps/remix/app/components/general/document/document-upload-button-legacy.tsx index f4f13aaf0..03f4f5068 100644 --- a/apps/remix/app/components/general/document/document-upload-button-legacy.tsx +++ b/apps/remix/app/components/general/document/document-upload-button-legacy.tsx @@ -14,9 +14,10 @@ import { useSession } from '@documenso/lib/client-only/providers/session'; import { APP_DOCUMENT_UPLOAD_SIZE_LIMIT } from '@documenso/lib/constants/app'; import { DEFAULT_DOCUMENT_TIME_ZONE, TIME_ZONES } from '@documenso/lib/constants/time-zones'; import { AppError, AppErrorCode } from '@documenso/lib/errors/app-error'; -import { formatDocumentsPath } from '@documenso/lib/utils/teams'; +import { formatDocumentsPath, formatTemplatesPath } from '@documenso/lib/utils/teams'; import { trpc } from '@documenso/trpc/react'; import type { TCreateDocumentPayloadSchema } from '@documenso/trpc/server/document-router/create-document.types'; +import type { TCreateTemplatePayloadSchema } from '@documenso/trpc/server/template-router/schema'; import { cn } from '@documenso/ui/lib/utils'; import { DocumentUploadButton as DocumentUploadButtonPrimitive } from '@documenso/ui/primitives/document-upload-button'; import { @@ -31,9 +32,13 @@ import { useCurrentTeam } from '~/providers/team'; export type DocumentUploadButtonLegacyProps = { className?: string; + type: EnvelopeType; }; -export const DocumentUploadButtonLegacy = ({ className }: DocumentUploadButtonLegacyProps) => { +export const DocumentUploadButtonLegacy = ({ + className, + type, +}: DocumentUploadButtonLegacyProps) => { const { _ } = useLingui(); const { toast } = useToast(); const { user } = useSession(); @@ -54,8 +59,18 @@ export const DocumentUploadButtonLegacy = ({ className }: DocumentUploadButtonLe const [isLoading, setIsLoading] = useState(false); const { mutateAsync: createDocument } = trpc.document.create.useMutation(); + const { mutateAsync: createTemplate } = trpc.template.createTemplate.useMutation(); const disabledMessage = useMemo(() => { + if (!user.emailVerified) { + return msg`Verify your email to upload documents.`; + } + + // No errors for templates. + if (type === EnvelopeType.TEMPLATE) { + return; + } + if (organisation.subscription && remaining.documents === 0) { return msg`Document upload disabled due to unpaid invoices`; } @@ -64,11 +79,8 @@ export const DocumentUploadButtonLegacy = ({ className }: DocumentUploadButtonLe return msg`You have reached your document limit.`; } - if (!user.emailVerified) { - return msg`Verify your email to upload documents.`; - } // eslint-disable-next-line react-hooks/exhaustive-deps - }, [remaining.documents, user.emailVerified, team]); + }, [remaining.documents, user.emailVerified, team, type]); const onFileDrop = async (file: File) => { try { @@ -80,30 +92,48 @@ export const DocumentUploadButtonLegacy = ({ className }: DocumentUploadButtonLe meta: { timezone: userTimezone, }, - } satisfies TCreateDocumentPayloadSchema; + } satisfies TCreateDocumentPayloadSchema | TCreateTemplatePayloadSchema; const formData = new FormData(); formData.append('payload', JSON.stringify(payload)); formData.append('file', file); - const { envelopeId: id } = await createDocument(formData); + // Handle legacy document creation. + if (type === EnvelopeType.DOCUMENT) { + const { envelopeId: id } = await createDocument(formData); - void refreshLimits(); + void refreshLimits(); - await navigate(`${formatDocumentsPath(team.url)}/${id}/edit`); + await navigate(`${formatDocumentsPath(team.url)}/${id}/edit`); - toast({ - title: _(msg`Document uploaded`), - description: _(msg`Your document has been uploaded successfully.`), - duration: 5000, - }); + toast({ + title: _(msg`Document uploaded`), + description: _(msg`Your document has been uploaded successfully.`), + duration: 5000, + }); - analytics.capture('App: Document Uploaded', { - userId: user.id, - documentId: id, - timestamp: new Date().toISOString(), - }); + analytics.capture('App: Document Uploaded', { + userId: user.id, + documentId: id, + timestamp: new Date().toISOString(), + }); + } + + // Handle legacy template creation. + if (type === EnvelopeType.TEMPLATE) { + const { envelopeId: id } = await createTemplate(formData); + + await navigate(`${formatTemplatesPath(team.url)}/${id}/edit`); + + toast({ + title: _(msg`Template document uploaded`), + description: _( + msg`Your document has been uploaded successfully. You will be redirected to the template page.`, + ), + duration: 5000, + }); + } } catch (err) { const error = AppError.parseError(err); @@ -149,17 +179,18 @@ export const DocumentUploadButtonLegacy = ({ className }: DocumentUploadButtonLe