Skip to content

Commit 6f44c77

Browse files
removed ai upload
1 parent 111b68d commit 6f44c77

File tree

1 file changed

+180
-50
lines changed

1 file changed

+180
-50
lines changed

src/app/upload/page.tsx

Lines changed: 180 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
"use client";
2+
23
import React, { useState } from "react";
34
import axios from "axios";
45
import toast from "react-hot-toast";
@@ -7,46 +8,26 @@ import { Button } from "@/components/ui/button";
78
import Navbar from "@/components/Navbar";
89
import Footer from "@/components/Footer";
910
import { type PostPDFToCloudinary } from "@/interface";
11+
import { slots, years, campuses, semesters, exams } from "@/components/select_options";
12+
import SearchBar from "@/components/searchbarSubjectList";
1013
import Dropzone from "react-dropzone";
11-
12-
import { createCanvas } from "canvas";
13-
import { getDocument, GlobalWorkerOptions } from "pdfjs-dist";
14-
import { PDFDocument } from "pdf-lib";
15-
async function pdfToImage(file: File) {
16-
GlobalWorkerOptions.workerSrc =
17-
"https://unpkg.com/[email protected]/build/pdf.worker.min.js";
18-
19-
const pdfDoc = await PDFDocument.load(await file.arrayBuffer());
20-
21-
// Get the first page
22-
const page = pdfDoc.getPages()[0];
23-
if (!page) {
24-
throw "First page not found";
25-
}
26-
// Create a canvas to render the image
27-
const canvas = createCanvas(page.getWidth(), page.getHeight());
28-
const context = canvas.getContext("2d");
29-
30-
// Use pdfjs-dist to render the page
31-
const pdfjsDoc = await getDocument({ data: await file.arrayBuffer() })
32-
.promise;
33-
const pdfPage = await pdfjsDoc.getPage(1);
34-
35-
// Render page to canvas
36-
const viewport = pdfPage.getViewport({ scale: 1 });
37-
await pdfPage.render({ canvasContext: context, viewport }).promise;
38-
39-
// Convert the canvas to the desired output (Buffer, base64, etc.)
40-
return canvas.toDataURL(); // Returns a Base64 string
41-
}
14+
import {
15+
Select,
16+
SelectContent,
17+
SelectGroup,
18+
SelectItem,
19+
SelectLabel,
20+
SelectTrigger,
21+
SelectValue,
22+
} from "@/components/ui/select";
4223

4324
const Page = () => {
25+
const [slot, setSlot] = useState("");
26+
const [subject, setSubject] = useState("");
27+
const [exam, setExam] = useState("");
28+
const [year, setYear] = useState("");
4429
const [campus, setCampus] = useState("Vellore");
45-
46-
const [files, setFiles] = useState<File[]>([]);
47-
48-
const [isUploading, setIsUploading] = useState(false);
49-
const [, setResetSearch] = useState(false);
30+
const [semester, setSemester] = useState("");
5031
function fileCheckAndSelect<T extends File>(acceptedFiles: T[]) {
5132
const maxFileSize = 5 * 1024 * 1024;
5233
const allowedFileTypes = [
@@ -105,23 +86,82 @@ const Page = () => {
10586
id: toastId,
10687
});
10788
}
89+
const [files, setFiles] = useState<File[]>([]);
90+
const [isUploading, setIsUploading] = useState(false);
91+
const [resetSearch, setResetSearch] = useState(false);
92+
10893
const handlePrint = async () => {
94+
const maxFileSize = 5 * 1024 * 1024;
95+
const allowedFileTypes = [
96+
"application/pdf",
97+
"image/jpeg",
98+
"image/png",
99+
"image/gif",
100+
];
101+
102+
if (!slot) {
103+
toast.error("Slot is required");
104+
return;
105+
}
106+
if (!subject) {
107+
toast.error("Subject is required");
108+
return;
109+
}
110+
if (!exam) {
111+
toast.error("Exam is required");
112+
return;
113+
}
114+
if (!year) {
115+
toast.error("Year is required");
116+
return;
117+
}
109118
if (!campus) {
110119
setCampus("Vellore");
111120
}
112121

122+
if (!semester) {
123+
toast.error("Semester is required");
124+
return;
125+
}
126+
if (!files || files.length === 0) {
127+
toast.error("No files selected");
128+
return;
129+
}
130+
131+
if (files.length > 5) {
132+
toast.error("More than 5 files selected");
133+
return;
134+
}
135+
136+
// File validations
137+
const invalidFiles = files.filter(
138+
(file) =>
139+
file.size > maxFileSize || !allowedFileTypes.includes(file.type),
140+
);
141+
142+
if (invalidFiles.length > 0) {
143+
toast.error(
144+
`Some files are invalid. Ensure each file is below 5MB and of an allowed type (PDF, JPEG, PNG, GIF).`,
145+
);
146+
return;
147+
}
148+
113149
const isPdf = files.length === 1 && files[0]?.type === "application/pdf";
150+
if (isPdf && files.length > 1) {
151+
toast.error("PDFs must be uploaded separately");
152+
return;
153+
}
114154

115155
// Prepare FormData
116156
const formData = new FormData();
117157
files.forEach((file) => {
118158
formData.append("files", file);
119159
});
120-
121-
if (isPdf && files[0]) {
122-
formData.append("image", await pdfToImage(files[0]));
123-
}
124-
// formData.append("exam", exam);
160+
formData.append("subject", subject);
161+
formData.append("slot", slot);
162+
formData.append("year", year);
163+
formData.append("exam", exam);
164+
formData.append("semester", semester);
125165
formData.append("campus", campus);
126166

127167
formData.append("isPdf", String(isPdf));
@@ -130,18 +170,18 @@ const Page = () => {
130170

131171
try {
132172
await toast.promise(
133-
axios.post<PostPDFToCloudinary>("/api/ai-upload", formData),
173+
axios.post<PostPDFToCloudinary>("/api/upload", formData),
134174
{
135175
loading: "Uploading papers...",
136176
success: "Papers uploaded successfully!",
137177
error: "Failed to upload papers. Please try again.",
138178
},
139179
);
140180

141-
// setSlot("");
142-
// setSubject("");
143-
// setExam("");
144-
// setYear("");
181+
setSlot("");
182+
setSubject("");
183+
setExam("");
184+
setYear("");
145185
setFiles([]);
146186
setResetSearch(true);
147187
setTimeout(() => setResetSearch(false), 100);
@@ -159,14 +199,104 @@ const Page = () => {
159199
</div>
160200
<div className="2xl:my-15 flex flex-col items-center">
161201
<fieldset className="mb-4 w-[350px] rounded-lg border-2 border-gray-300 p-4 pr-8">
162-
{/* <legend className="text-lg font-bold">Upload papers</legend> */}
202+
<legend className="text-lg font-bold">Select paper parameters</legend>
163203

164204
<div className="flex w-full flex-col 2xl:gap-y-4">
205+
{/* Slot Selection */}
206+
<div>
207+
<label>Slot:</label>
208+
<Select value={slot} onValueChange={setSlot}>
209+
<SelectTrigger className="m-2 rounded-md border p-2">
210+
<SelectValue placeholder="Select slot" />
211+
</SelectTrigger>
212+
<SelectContent>
213+
<SelectGroup>
214+
<SelectLabel>Slots</SelectLabel>
215+
{slots.map((slot) => (
216+
<SelectItem key={slot} value={slot}>
217+
{slot}
218+
</SelectItem>
219+
))}
220+
</SelectGroup>
221+
</SelectContent>
222+
</Select>
223+
</div>
224+
225+
{/* Exam Selection */}
226+
<div>
227+
<label>Exam:</label>
228+
<Select value={exam} onValueChange={setExam}>
229+
<SelectTrigger className="m-2 rounded-md border p-2">
230+
<SelectValue placeholder="Select exam" />
231+
</SelectTrigger>
232+
<SelectContent>
233+
<SelectGroup>
234+
<SelectLabel>Exams</SelectLabel>
235+
{exams.map((exam) => (
236+
<SelectItem key={exam} value={String(exam)}>
237+
{exam}
238+
</SelectItem>
239+
))}{" "}
240+
</SelectGroup>
241+
</SelectContent>
242+
</Select>
243+
</div>
244+
245+
{/* Subject Selection */}
246+
<div>
247+
<label>Subject:</label>
248+
<SearchBar setSubject={setSubject} resetSearch={resetSearch} />
249+
</div>
250+
251+
{/* Year Selection */}
252+
<div>
253+
<label>Year:</label>
254+
<Select value={year} onValueChange={setYear}>
255+
<SelectTrigger className="m-2 rounded-md border p-2">
256+
<SelectValue placeholder="Select year" />
257+
</SelectTrigger>
258+
<SelectContent>
259+
<SelectGroup>
260+
<SelectLabel>Years</SelectLabel>
261+
{years.map((year) => (
262+
<SelectItem key={year} value={String(year)}>
263+
{year}
264+
</SelectItem>
265+
))}
266+
</SelectGroup>
267+
</SelectContent>
268+
</Select>
269+
</div>
270+
271+
{/* Year Selection */}
272+
273+
<div>
274+
<label>Semester Selection:</label>
275+
<Select value={semester} onValueChange={setSemester}>
276+
<SelectTrigger className="m-2 rounded-md border p-2">
277+
<SelectValue placeholder="Select semester" />
278+
</SelectTrigger>
279+
<SelectContent>
280+
<SelectGroup>
281+
<SelectLabel>Semester</SelectLabel>
282+
{semesters.map((semester) => (
283+
<SelectItem key={semester} value={String(semester)}>
284+
{semester}
285+
</SelectItem>
286+
))}
287+
</SelectGroup>
288+
</SelectContent>
289+
</Select>
290+
</div>
291+
165292
{/* File Dropzone */}
166293
<div>
167-
<Dropzone onDrop={fileCheckAndSelect}>
294+
<Dropzone
295+
onDrop={(acceptedFiles) => setFiles(acceptedFiles)}
296+
accept={{ "image/*": [], "application/pdf": [] }}
297+
>
168298
{({ getRootProps, getInputProps }) => (
169-
<section className="my-2 -mr-2 cursor-pointer rounded-2xl border-2 border-dashed p-8 text-center">
299+
<section className="my-2 -mr-2 rounded-2xl border-2 border-dashed p-8 text-center">
170300
<div {...getRootProps()}>
171301
<input {...getInputProps()} />
172302
<p>
@@ -207,4 +337,4 @@ const Page = () => {
207337
);
208338
};
209339

210-
export default Page;
340+
export default Page;

0 commit comments

Comments
 (0)