Skip to content

Commit 090674f

Browse files
committed
fix: upload
1 parent 240c6fc commit 090674f

File tree

1 file changed

+56
-82
lines changed

1 file changed

+56
-82
lines changed

src/app/upload/page.tsx

Lines changed: 56 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -1,40 +1,32 @@
11
"use client";
22

3-
import React, { useRef, useState } from "react";
3+
import React, { useState } from "react";
44
import axios from "axios";
5-
import toast, { Toaster } from "react-hot-toast";
5+
import toast from "react-hot-toast";
66
import { handleAPIError } from "../../util/error";
7-
import { useRouter } from "next/navigation";
8-
import { type ApiError } from "next/dist/server/api-utils";
97
import { Button } from "@/components/ui/button";
10-
import { CldUploadWidget } from "next-cloudinary";
11-
import { Input } from "@/components/ui/input";
8+
import Navbar from "@/components/Navbar";
9+
import Footer from "@/components/Footer";
10+
import { type PostPDFToCloudinary } from "@/interface";
11+
import { slots, years } from "@/components/select_options";
12+
import SearchBar from "@/components/searchbarSubjectList";
13+
import Dropzone from "react-dropzone";
1214
import {
1315
Select,
14-
SelectTrigger,
15-
SelectValue,
1616
SelectContent,
1717
SelectGroup,
18-
SelectLabel,
1918
SelectItem,
19+
SelectLabel,
20+
SelectTrigger,
21+
SelectValue,
2022
} from "@/components/ui/select";
21-
import Navbar from "@/components/Navbar";
22-
import Footer from "@/components/Footer";
23-
import { PostPDFToCloudinary } from "@/interface";
24-
import { courses, slots, years } from "@/components/select_options";
25-
import SearchBar from "@/components/searchbarSubjectList";
26-
import Dropzone from "react-dropzone";
2723

2824
const Page = () => {
29-
const fileInputRef = useRef<HTMLInputElement>(null);
30-
3125
const [slot, setSlot] = useState("");
3226
const [subject, setSubject] = useState("");
3327
const [exam, setExam] = useState("");
3428
const [year, setYear] = useState("");
3529
const [files, setFiles] = useState<File[]>([]);
36-
const [inputValue, setInputValue] = useState("");
37-
const [isSubjectCommandOpen, setIsSubjectCommandOpen] = useState(false);
3830
const [isUploading, setIsUploading] = useState(false);
3931
const [resetSearch, setResetSearch] = useState(false);
4032

@@ -47,8 +39,6 @@ const Page = () => {
4739
"image/gif",
4840
];
4941

50-
const files = fileInputRef.current?.files as FileList | null;
51-
5242
if (!slot) {
5343
toast.error("Slot is required");
5444
return;
@@ -65,44 +55,39 @@ const Page = () => {
6555
toast.error("Year is required");
6656
return;
6757
}
58+
6859
if (!files || files.length === 0) {
6960
toast.error("No files selected");
7061
return;
71-
} else if (files.length > 5) {
72-
toast.error("More than 5 files selected");
73-
return;
7462
}
7563

76-
if (!Array.from(files).every((file) => file.type === files[0]?.type)) {
77-
toast.error(`All files MUST be of the same type`);
64+
if (files.length > 5) {
65+
toast.error("More than 5 files selected");
7866
return;
7967
}
8068

81-
for (const file of files) {
82-
if (file.size > maxFileSize) {
83-
toast.error(`File ${file.name} is more than 5MB`);
84-
return;
85-
}
86-
if (!allowedFileTypes.includes(file.type)) {
87-
toast.error(
88-
`File type of ${file.name} is not allowed. Only PDFs and images are accepted.`,
89-
);
90-
return;
91-
}
69+
// File validations
70+
const invalidFiles = files.filter(
71+
(file) =>
72+
file.size > maxFileSize || !allowedFileTypes.includes(file.type),
73+
);
74+
75+
if (invalidFiles.length > 0) {
76+
toast.error(
77+
`Some files are invalid. Ensure each file is below 5MB and of an allowed type (PDF, JPEG, PNG, GIF).`,
78+
);
79+
return;
9280
}
9381

94-
let isPdf = false;
95-
if (files[0]?.type === "application/pdf") {
96-
isPdf = true;
97-
if (files.length > 1) {
98-
toast.error(`PDFs should be uploaded separately`);
99-
return;
100-
}
82+
const isPdf = files.length === 1 && files[0]?.type === "application/pdf";
83+
if (isPdf && files.length > 1) {
84+
toast.error("PDFs must be uploaded separately");
85+
return;
10186
}
10287

103-
const Arrfiles = Array.from(files);
88+
// Prepare FormData
10489
const formData = new FormData();
105-
Arrfiles.forEach((file) => {
90+
files.forEach((file) => {
10691
formData.append("files", file);
10792
});
10893
formData.append("subject", subject);
@@ -113,37 +98,28 @@ const Page = () => {
11398

11499
setIsUploading(true);
115100

116-
void toast.promise(
117-
(async () => {
118-
try {
119-
const response = await axios.post<PostPDFToCloudinary>(
120-
"/api/upload",
121-
formData,
122-
);
123-
124-
setSlot("");
125-
setSubject("");
126-
setExam("");
127-
setYear("");
128-
setFiles([]);
129-
if (fileInputRef.current) {
130-
fileInputRef.current.value = "";
131-
}
132-
133-
setResetSearch(true);
134-
setTimeout(() => setResetSearch(false), 100);
135-
} catch (error) {
136-
handleAPIError(error);
137-
} finally {
138-
setIsUploading(false);
139-
}
140-
})(),
141-
{
142-
loading: "Uploading papers...",
143-
success: "Papers uploaded",
144-
error: (err: ApiError) => err.message,
145-
},
146-
);
101+
try {
102+
await toast.promise(
103+
axios.post<PostPDFToCloudinary>("/api/upload", formData),
104+
{
105+
loading: "Uploading papers...",
106+
success: "Papers uploaded successfully!",
107+
error: "Failed to upload papers. Please try again.",
108+
},
109+
);
110+
111+
setSlot("");
112+
setSubject("");
113+
setExam("");
114+
setYear("");
115+
setFiles([]);
116+
setResetSearch(true);
117+
setTimeout(() => setResetSearch(false), 100);
118+
} catch (error) {
119+
handleAPIError(error);
120+
} finally {
121+
setIsUploading(false);
122+
}
147123
};
148124

149125
return (
@@ -220,16 +196,14 @@ const Page = () => {
220196
</Select>
221197
</div>
222198

199+
{/* File Dropzone */}
223200
<div>
224201
<Dropzone
225-
onDrop={(acceptedFiles) => {
226-
console.log(acceptedFiles);
227-
setFiles(acceptedFiles);
228-
}}
202+
onDrop={(acceptedFiles) => setFiles(acceptedFiles)}
229203
accept={{ "image/*": [], "application/pdf": [] }}
230204
>
231205
{({ getRootProps, getInputProps }) => (
232-
<section className=" my-2 -mr-2 rounded-2xl border-2 border-dashed p-8 text-center">
206+
<section className="my-2 -mr-2 rounded-2xl border-2 border-dashed p-8 text-center">
233207
<div {...getRootProps()}>
234208
<input {...getInputProps()} />
235209
<p>

0 commit comments

Comments
 (0)