Skip to content

Commit 1436faf

Browse files
committed
fix : FIxed the upload page issue
1 parent 568e48c commit 1436faf

File tree

2 files changed

+55
-96
lines changed

2 files changed

+55
-96
lines changed

src/app/upload/page.tsx

Lines changed: 43 additions & 88 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
"use client";
2+
23
import React, { useRef, useState } from "react";
34
import axios from "axios";
45
import toast, { Toaster } from "react-hot-toast";
@@ -17,19 +18,12 @@ import {
1718
SelectLabel,
1819
SelectItem,
1920
} from "@/components/ui/select";
20-
import {
21-
Command,
22-
CommandInput,
23-
CommandList,
24-
CommandItem,
25-
CommandEmpty,
26-
CommandGroup,
27-
} from "@/components/ui/command";
2821
import Navbar from "@/components/Navbar";
2922
import Footer from "@/components/Footer";
3023
import { PostPDFToCloudinary } from "@/interface";
3124
import { courses, slots, years } from "@/components/select_options";
3225
import SearchBar from "@/components/searchbarSubjectList";
26+
3327
const Page = () => {
3428
const router = useRouter();
3529
const fileInputRef = useRef<HTMLInputElement>(null);
@@ -39,9 +33,8 @@ const Page = () => {
3933
const [exam, setExam] = useState("");
4034
const [year, setYear] = useState("");
4135
const [files, setFiles] = useState<File[]>([]);
42-
const [inputValue, setInputValue] = useState("");
43-
const [isSubjectCommandOpen, setIsSubjectCommandOpen] = useState(false);
4436
const [isUploading, setIsUploading] = useState(false);
37+
const [resetSearch, setResetSearch] = useState(false);
4538

4639
const handlePrint = async () => {
4740
const maxFileSize = 5 * 1024 * 1024;
@@ -53,38 +46,26 @@ const Page = () => {
5346
];
5447
const files = fileInputRef.current?.files as FileList | null;
5548

56-
if (!slot) {
57-
toast.error("Slot is required");
58-
return;
59-
}
60-
if (!subject) {
61-
toast.error("Subject is required");
62-
return;
63-
}
64-
if (!exam) {
65-
toast.error("Exam is required");
49+
if (!slot || !subject || !exam || !year || !files || files.length === 0) {
50+
toast.error("All fields are required.");
6651
return;
6752
}
68-
if (!year) {
69-
toast.error("Year is required");
53+
54+
if (files.length > 5) {
55+
toast.error("More than 5 files selected");
7056
return;
7157
}
72-
if (!files || files.length === 0) {
73-
toast.error("No files selected");
74-
return;
75-
} else if (files.length > 5) {
76-
toast.error("More than 5 files selected");
58+
59+
if (!Array.from(files).every((file) => file.type === files[0]?.type)) {
60+
toast.error(`All files MUST be of the same type`);
7761
return;
7862
}
79-
//file have same extension
80-
if (!Array.from(files).every((file) => file.type == files[0]?.type))
81-
toast.error(`All files MUST be of same type`);
63+
8264
for (const file of files) {
8365
if (file.size > maxFileSize) {
8466
toast.error(`File ${file.name} is more than 5MB`);
8567
return;
8668
}
87-
8869
if (!allowedFileTypes.includes(file.type)) {
8970
toast.error(
9071
`File type of ${file.name} is not allowed. Only PDFs and images are accepted.`,
@@ -97,53 +78,54 @@ const Page = () => {
9778
if (files[0]?.type === "application/pdf") {
9879
isPdf = true;
9980
if (files.length > 1) {
100-
toast.error(`PDFs should be uploaded seperately`);
81+
toast.error(`PDFs should be uploaded separately`);
10182
return;
10283
}
10384
}
85+
10486
const Arrfiles = Array.from(files);
10587
const formData = new FormData();
10688
Arrfiles.forEach((file) => {
10789
formData.append("files", file);
10890
});
109-
110-
// const body = {
111-
// subject: subject,
112-
// slot: slot,
113-
// year: year,
114-
// exam: exam,
115-
// isPdf: isPdf,
116-
// };
11791
formData.append("subject", subject);
11892
formData.append("slot", slot);
11993
formData.append("year", year);
12094
formData.append("exam", exam);
12195
formData.append("isPdf", String(isPdf));
96+
97+
setIsUploading(true);
98+
12299
void toast.promise(
123100
(async () => {
124101
try {
125-
const response = await axios.post<PostPDFToCloudinary>(
126-
"/api/upload",
127-
formData,
128-
);
129-
} catch (error: unknown) {
130-
throw handleAPIError(error);
102+
await axios.post("/api/upload", formData);
103+
104+
setSlot("");
105+
setSubject("");
106+
setExam("");
107+
setYear("");
108+
setFiles([]);
109+
if (fileInputRef.current) {
110+
fileInputRef.current.value = "";
111+
}
112+
113+
setResetSearch(true);
114+
setTimeout(() => setResetSearch(false), 100);
115+
} catch (error) {
116+
handleAPIError(error);
117+
} finally {
118+
setIsUploading(false);
131119
}
132120
})(),
133121
{
134122
loading: "Uploading papers...",
135-
success: "papers uploaded",
136-
error: (err: ApiError) => err.message,
123+
success: "Papers uploaded",
124+
error: (err:ApiError) => err.message,
137125
},
138126
);
139127
};
140128

141-
const handleSubjectSelect = (value: string) => {
142-
setSubject(value);
143-
setInputValue(value);
144-
setIsSubjectCommandOpen(false);
145-
};
146-
147129
return (
148130
<div className="flex h-screen flex-col justify-between">
149131
<div>
@@ -195,31 +177,7 @@ const Page = () => {
195177
{/* Subject Selection */}
196178
<div>
197179
<label>Subject:</label>
198-
{/* setSubject */}
199-
<SearchBar setSubject={setSubject}></SearchBar>
200-
{/* <Command className="rounded-lg border shadow-md md:min-w-[450px]">
201-
<CommandInput
202-
value={inputValue}
203-
onChangeCapture={(e) =>
204-
setInputValue((e.target as HTMLInputElement).value)
205-
}
206-
placeholder="Type a subject or search..."
207-
/> */}
208-
{/* <CommandList className="h-[100px]">
209-
<CommandEmpty>No results found.</CommandEmpty>
210-
211-
<CommandGroup heading="Subjects">
212-
{courses.map((course) => (
213-
<CommandItem
214-
key={course}
215-
onSelect={() => handleSubjectSelect(course)}
216-
>
217-
<span>{course}</span>
218-
</CommandItem>
219-
))}
220-
</CommandGroup>
221-
</CommandList>
222-
</Command> */}
180+
<SearchBar setSubject={setSubject} resetSearch={resetSearch} />
223181
</div>
224182

225183
{/* Year Selection */}
@@ -232,14 +190,11 @@ const Page = () => {
232190
<SelectContent>
233191
<SelectGroup>
234192
<SelectLabel>Years</SelectLabel>
235-
{years.map((year)=>
236-
{
237-
return (<SelectItem key={year} value={String(year)}>
193+
{years.map((year) => (
194+
<SelectItem key={year} value={String(year)}>
238195
{year}
239-
</SelectItem>)
240-
241-
}
242-
)}
196+
</SelectItem>
197+
))}
243198
</SelectGroup>
244199
</SelectContent>
245200
</Select>
@@ -283,11 +238,11 @@ const Page = () => {
283238
{isUploading ? "Uploading..." : "Upload Papers"}
284239
</Button>
285240
</div>
286-
<div className="">
241+
<div>
287242
<Footer />
288243
</div>
289244
</div>
290245
);
291246
};
292247

293-
export default Page;
248+
export default Page;

src/components/searchbarSubjectList.tsx

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
"use client";
2-
31
import { useState, useCallback, useRef, useEffect } from "react";
42
import { Search } from "lucide-react";
53
import debounce from "debounce";
@@ -8,8 +6,10 @@ import { courses } from "./select_options";
86

97
function SearchbarSubjectList({
108
setSubject,
9+
resetSearch,
1110
}: {
1211
setSubject: React.Dispatch<React.SetStateAction<string>>;
12+
resetSearch: boolean;
1313
}) {
1414
const [searchText, setSearchText] = useState("");
1515
const [suggestions, setSuggestions] = useState<string[]>([]);
@@ -30,11 +30,11 @@ function SearchbarSubjectList({
3030

3131
if (filteredSubjects.length === 0) {
3232
setError("Subject not found");
33+
setSuggestions([]);
3334
return;
3435
}
3536
setSuggestions(filteredSubjects);
3637
setError(null);
37-
3838
setLoading(false);
3939
} else {
4040
setSuggestions([]);
@@ -52,11 +52,10 @@ function SearchbarSubjectList({
5252
void debouncedSearch(text);
5353
};
5454

55-
const handleSelectSuggestion = async (suggestion: string) => {
55+
const handleSelectSuggestion = (suggestion: string) => {
5656
setSearchText(suggestion);
5757
setSuggestions([]);
5858
setSubject(suggestion);
59-
// router.push(`/catalogue?subject=${encodeURIComponent(suggestion)}`);
6059
};
6160

6261
const handleClickOutside = (event: MouseEvent) => {
@@ -75,6 +74,13 @@ function SearchbarSubjectList({
7574
};
7675
}, []);
7776

77+
useEffect(() => {
78+
if (resetSearch) {
79+
setSearchText("");
80+
setSuggestions([]);
81+
}
82+
}, [resetSearch]);
83+
7884
return (
7985
<div className="mx-4 md:mx-0">
8086
<form className=" my-2 ml-2 w-full max-w-xl">
@@ -84,14 +90,12 @@ function SearchbarSubjectList({
8490
value={searchText}
8591
onChange={handleSearchChange}
8692
placeholder="Search for subject..."
87-
// className={`text-md w-fuyll rounded-full border bg-[#434dba] px-4 py-6 pr-10 font-sans tracking-wider text-white shadow-sm placeholder:text-white focus:outline-none focus:ring-2 ${loading ? "opacity-70" : ""}`}
8893
/>
8994
<button
9095
type="submit"
9196
className="absolute inset-y-0 right-0 flex items-center pr-3"
9297
disabled
9398
>
94-
{" "}
9599
<Search className="h-5 w-5 text-white " />
96100
</button>
97101
{loading && (
@@ -131,4 +135,4 @@ function SearchbarSubjectList({
131135
);
132136
}
133137

134-
export default SearchbarSubjectList;
138+
export default SearchbarSubjectList;

0 commit comments

Comments
 (0)