diff --git a/apps/remix/app/components/general/document/document-drop-zone-wrapper.tsx b/apps/remix/app/components/general/document/document-drop-zone-wrapper.tsx
index e5fe18636..84b1dfc4a 100644
--- a/apps/remix/app/components/general/document/document-drop-zone-wrapper.tsx
+++ b/apps/remix/app/components/general/document/document-drop-zone-wrapper.tsx
@@ -4,7 +4,7 @@ import { msg } from '@lingui/core/macro';
import { useLingui } from '@lingui/react';
import { Trans } from '@lingui/react/macro';
import { Loader } from 'lucide-react';
-import { useDropzone } from 'react-dropzone';
+import { ErrorCode, type FileRejection, useDropzone } from 'react-dropzone';
import { Link, useNavigate, useParams } from 'react-router';
import { match } from 'ts-pattern';
@@ -108,15 +108,51 @@ export const DocumentDropZoneWrapper = ({ children, className }: DocumentDropZon
}
};
- const onFileDropRejected = () => {
+ const onFileDropRejected = (fileRejections: FileRejection[]) => {
+ if (!fileRejections.length) {
+ return;
+ }
+
+ // Since users can only upload only one file (no multi-upload), we only handle the first file rejection
+ const { file, errors } = fileRejections[0];
+
+ if (!errors.length) {
+ return;
+ }
+
+ const errorNodes = errors.map((error, index) => (
+
+ {match(error.code)
+ .with(ErrorCode.FileTooLarge, () => (
+ File is larger than {APP_DOCUMENT_UPLOAD_SIZE_LIMIT}MB
+ ))
+ .with(ErrorCode.FileInvalidType, () => Only PDF files are allowed)
+ .with(ErrorCode.FileTooSmall, () => File is too small)
+ .with(ErrorCode.TooManyFiles, () => (
+ Only one file can be uploaded at a time
+ ))
+ .otherwise(() => (
+ Unknown error
+ ))}
+
+ ));
+
+ const description = (
+ <>
+
+ {file.name} couldn't be uploaded:
+
+ {errorNodes}
+ >
+ );
+
toast({
- title: _(msg`Your document failed to upload.`),
- description: _(msg`File cannot be larger than ${APP_DOCUMENT_UPLOAD_SIZE_LIMIT}MB`),
+ title: _(msg`Upload failed`),
+ description,
duration: 5000,
variant: 'destructive',
});
};
-
const { getRootProps, getInputProps, isDragActive } = useDropzone({
accept: {
'application/pdf': ['.pdf'],
@@ -129,8 +165,8 @@ export const DocumentDropZoneWrapper = ({ children, className }: DocumentDropZon
void onFileDrop(acceptedFile);
}
},
- onDropRejected: () => {
- void onFileDropRejected();
+ onDropRejected: (fileRejections) => {
+ onFileDropRejected(fileRejections);
},
noClick: true,
noDragEventsBubbling: true,
diff --git a/apps/remix/app/components/general/template/template-drop-zone-wrapper.tsx b/apps/remix/app/components/general/template/template-drop-zone-wrapper.tsx
index 0d9c3fc9e..dbca5a8ea 100644
--- a/apps/remix/app/components/general/template/template-drop-zone-wrapper.tsx
+++ b/apps/remix/app/components/general/template/template-drop-zone-wrapper.tsx
@@ -4,8 +4,9 @@ import { msg } from '@lingui/core/macro';
import { useLingui } from '@lingui/react';
import { Trans } from '@lingui/react/macro';
import { Loader } from 'lucide-react';
-import { useDropzone } from 'react-dropzone';
+import { ErrorCode, type FileRejection, useDropzone } from 'react-dropzone';
import { useNavigate, useParams } from 'react-router';
+import { match } from 'ts-pattern';
import { APP_DOCUMENT_UPLOAD_SIZE_LIMIT } from '@documenso/lib/constants/app';
import { megabytesToBytes } from '@documenso/lib/universal/unit-convertions';
@@ -67,10 +68,47 @@ export const TemplateDropZoneWrapper = ({ children, className }: TemplateDropZon
}
};
- const onFileDropRejected = () => {
+ const onFileDropRejected = (fileRejections: FileRejection[]) => {
+ if (!fileRejections.length) {
+ return;
+ }
+
+ // Since users can only upload only one file (no multi-upload), we only handle the first file rejection
+ const { file, errors } = fileRejections[0];
+
+ if (!errors.length) {
+ return;
+ }
+
+ const errorNodes = errors.map((error, index) => (
+
+ {match(error.code)
+ .with(ErrorCode.FileTooLarge, () => (
+ File is larger than {APP_DOCUMENT_UPLOAD_SIZE_LIMIT}MB
+ ))
+ .with(ErrorCode.FileInvalidType, () => Only PDF files are allowed)
+ .with(ErrorCode.FileTooSmall, () => File is too small)
+ .with(ErrorCode.TooManyFiles, () => (
+ Only one file can be uploaded at a time
+ ))
+ .otherwise(() => (
+ Unknown error
+ ))}
+
+ ));
+
+ const description = (
+ <>
+
+ {file.name} couldn't be uploaded:
+
+ {errorNodes}
+ >
+ );
+
toast({
- title: _(msg`Your template failed to upload.`),
- description: _(msg`File cannot be larger than ${APP_DOCUMENT_UPLOAD_SIZE_LIMIT}MB`),
+ title: _(msg`Upload failed`),
+ description,
duration: 5000,
variant: 'destructive',
});
@@ -88,8 +126,8 @@ export const TemplateDropZoneWrapper = ({ children, className }: TemplateDropZon
void onFileDrop(acceptedFile);
}
},
- onDropRejected: () => {
- void onFileDropRejected();
+ onDropRejected: (fileRejections) => {
+ onFileDropRejected(fileRejections);
},
noClick: true,
noDragEventsBubbling: true,