Skip to content

Commit 60c935c

Browse files
Merge remote-tracking branch 'refs/remotes/origin/staging' into staging
2 parents 9ad004a + e9f4fa9 commit 60c935c

File tree

7 files changed

+151
-105
lines changed

7 files changed

+151
-105
lines changed

public/papers.png

-656 KB
Loading

src/app/actions/get-papers-by-id.ts

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,23 @@
11
// "use server";
2-
import { ErrorResponse, PaperResponse } from "@/interface";
3-
import axios, { AxiosResponse } from "axios";
2+
import { ErrorResponse, type PaperResponse } from "@/interface";
3+
import axios, { type AxiosResponse } from "axios";
4+
5+
export const fetchPaperID = async (id: string): Promise<PaperResponse> => {
6+
const serverUrl = process.env.SERVER_URL ?? "https://papers.codechefvit.com";
47

5-
export const fetchPaperID = async (
6-
id: string,
7-
) => {
88
try {
9-
if(!process.env.SERVER_URL)
10-
{
11-
throw "error env not set (server url)"
12-
}
139
const response: AxiosResponse<PaperResponse> = await axios.get(
14-
`${process.env.SERVER_URL}/api/paper-by-id/${id}`,
10+
`${serverUrl}/api/paper-by-id/${id}`
1511
);
1612
return response.data;
1713
} catch (err: unknown) {
18-
throw err;
19-
14+
if (axios.isAxiosError(err)) {
15+
console.error("Axios error:", err.response?.data || err.message);
16+
const errorMessage = (err.response?.data as { message?: string })?.message ?? "Failed to fetch paper";
17+
throw new Error(errorMessage);
18+
} else {
19+
console.error("Unexpected error:", err);
20+
throw new Error("An unexpected error occurred");
21+
}
2022
}
2123
};

src/app/layout.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ export const metadata: Metadata = {
3030
keywords: [
3131
"CodeChef",
3232
"VIT",
33+
"VIT Papers",
3334
"Vellore Institute of Technology",
3435
"CodeChef-VIT",
3536
"Papers",

src/app/paper/[id]/page.tsx

Lines changed: 82 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,9 @@ import Footer from "@/components/Footer";
33
import Navbar from "@/components/Navbar";
44
import PdfViewer from "@/components/pdfViewer";
55
import Loader from "@/components/ui/loader";
6-
import { ErrorResponse, PaperResponse } from "@/interface";
7-
import axios, { AxiosResponse } from "axios";
8-
import { Metadata } from "next";
6+
import { type ErrorResponse, type PaperResponse } from "@/interface";
7+
import axios, { type AxiosResponse } from "axios";
8+
import { type Metadata } from "next";
99
import { redirect } from "next/navigation"; // Import redirect
1010

1111
export async function generateMetadata({
@@ -18,35 +18,100 @@ export async function generateMetadata({
1818
if (paper) {
1919
return {
2020
metadataBase: new URL("https://papers.codechefvit.com/"),
21-
title: `Papers| ${paper.subject}| ${paper.exam} |${paper.slot}`,
22-
description:
23-
`Discover ${paper.subject}'s question paper created by CodeChef-VIT at Vellore Institute of Technology. Made with ♡ to help students excel.`,
21+
title: `Papers | ${paper.subject} | ${paper.exam} | ${paper.slot}`,
22+
description: `Discover ${paper.subject}'s question paper created by CodeChef-VIT at Vellore Institute of Technology. Made with ♡ to help students excel.`,
2423
icons: [{ rel: "icon", url: "/codechef_logo.svg" }],
2524
openGraph: {
26-
title: `Papers| ${paper.subject}| ${paper.exam} |${paper.slot}`,
25+
title: `Papers | ${paper.subject} | ${paper.exam} | ${paper.slot}`,
2726
images: [{ url: "/papers.png" }],
2827
url: "https://papers.codechefvit.com/",
2928
type: "website",
30-
description:
31-
`Discover ${paper.subject}'s question paper created by CodeChef-VIT at Vellore Institute of Technology. Made with ♡ to help students excel.`,
29+
description: `Discover ${paper.subject}'s question paper created by CodeChef-VIT at Vellore Institute of Technology. Made with ♡ to help students excel.`,
3230
siteName: "Papers by CodeChef-VIT",
3331
},
3432
twitter: {
3533
card: "summary_large_image",
36-
title: `Papers| ${paper.subject}| ${paper.exam} |${paper.slot}`,
37-
description:
38-
`Discover ${paper.subject}'s question paper created by CodeChef-VIT at Vellore Institute of Technology. Made with ♡ to help students excel.`,
34+
title: `Papers | ${paper.subject} | ${paper.exam} | ${paper.slot}`,
35+
description: `Discover ${paper.subject}'s question paper created by CodeChef-VIT at Vellore Institute of Technology. Made with ♡ to help students excel.`,
3936
images: [{ url: "/papers.png" }],
4037
},
4138
applicationName: "Papers by CodeChef-VIT",
4239
keywords: [
43-
paper.subject,
44-
paper.exam,
45-
paper.slot,
46-
paper.year
40+
"CodeChef",
41+
"VIT",
42+
"Vellore Institute of Technology",
43+
"CodeChef-VIT",
44+
"Papers",
45+
"Exam solutions",
46+
"Student resources",
47+
"VIT exam papers",
48+
"Exam preparation",
49+
"Previous year papers VIT",
50+
"VITCAT1",
51+
"VITCAT2",
52+
"VITFAT",
53+
"VIT CAT1 papers",
54+
"VIT CAT2 papers",
55+
"VIT FAT papers",
56+
"VIT exam question papers",
57+
"VIT question bank",
58+
"VIT previous year question papers",
59+
"VIT academic resources",
60+
"VIT exam pattern",
61+
"VIT preparation tips",
62+
"VIT question solutions",
63+
"VIT model papers",
64+
"VIT solved papers",
65+
"VIT test papers",
66+
"VIT sample papers",
67+
"VIT question papers with solutions",
68+
"VIT exam guide",
69+
"VIT CAT1 preparation",
70+
"VIT CAT2 preparation",
71+
"VIT FAT preparation",
72+
"VIT previous year CAT1 papers",
73+
"VIT previous year CAT2 papers",
74+
"VIT previous year FAT papers",
75+
"VIT exam resources",
76+
"VIT academic help",
77+
"VIT syllabus",
78+
"VIT question paper pattern",
79+
"VIT 2023 papers",
80+
"VIT 2024 papers",
81+
"VIT exam practice",
82+
"VIT question paper archives",
83+
"VIT study materials",
84+
"VIT engineering papers",
85+
"VIT exam strategy",
86+
"VIT online exam resources",
87+
"VIT question paper download",
88+
"VIT important questions",
89+
"VIT question paper solutions",
90+
`${paper.subject} question paper`,
91+
`${paper.exam} question paper`,
92+
`${paper.slot} question paper`,
93+
`${paper.year} question paper`,
94+
`${paper.subject} question paper`,
95+
`${paper.exam} question paper`,
96+
`${paper.slot} question paper`,
97+
`${paper.year} question paper`,
98+
`${paper.subject} ${paper.exam} question paper`,
99+
`${paper.subject} ${paper.slot} question paper`,
100+
`${paper.subject} ${paper.year} question paper`,
101+
`${paper.exam} ${paper.slot} question paper`,
102+
`${paper.exam} ${paper.year} question paper`,
103+
`${paper.subject} ${paper.exam} ${paper.year} question paper`,
104+
`${paper.subject} ${paper.exam} ${paper.slot} question paper`,
105+
`${paper.subject} ${paper.year} ${paper.slot} question paper`,
106+
`${paper.exam} ${paper.year} ${paper.slot} question paper`,
107+
`${paper.subject} ${paper.exam} ${paper.year} ${paper.slot} question paper`,
108+
`${paper.year} ${paper.subject} ${paper.slot} question paper`,
109+
`${paper.year} ${paper.exam} ${paper.subject} question paper`,
110+
`${paper.exam} ${paper.subject} ${paper.year} question paper`,
111+
`${paper.slot} ${paper.subject} ${paper.year} question paper`,
112+
`${paper.slot} ${paper.exam} ${paper.year} question paper`,
47113
],
48114
robots: "index, follow",
49-
50115
};
51116
}
52117

src/app/upload/page.tsx

Lines changed: 38 additions & 66 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;
@@ -76,15 +69,17 @@ const Page = () => {
7669
toast.error("More than 5 files selected");
7770
return;
7871
}
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`);
72+
73+
if (!Array.from(files).every((file) => file.type === files[0]?.type)) {
74+
toast.error(`All files MUST be of the same type`);
75+
return;
76+
}
77+
8278
for (const file of files) {
8379
if (file.size > maxFileSize) {
8480
toast.error(`File ${file.name} is more than 5MB`);
8581
return;
8682
}
87-
8883
if (!allowedFileTypes.includes(file.type)) {
8984
toast.error(
9085
`File type of ${file.name} is not allowed. Only PDFs and images are accepted.`,
@@ -97,53 +92,57 @@ const Page = () => {
9792
if (files[0]?.type === "application/pdf") {
9893
isPdf = true;
9994
if (files.length > 1) {
100-
toast.error(`PDFs should be uploaded seperately`);
95+
toast.error(`PDFs should be uploaded separately`);
10196
return;
10297
}
10398
}
99+
104100
const Arrfiles = Array.from(files);
105101
const formData = new FormData();
106102
Arrfiles.forEach((file) => {
107103
formData.append("files", file);
108104
});
109-
110-
// const body = {
111-
// subject: subject,
112-
// slot: slot,
113-
// year: year,
114-
// exam: exam,
115-
// isPdf: isPdf,
116-
// };
117105
formData.append("subject", subject);
118106
formData.append("slot", slot);
119107
formData.append("year", year);
120108
formData.append("exam", exam);
121109
formData.append("isPdf", String(isPdf));
110+
111+
setIsUploading(true);
112+
122113
void toast.promise(
123114
(async () => {
124115
try {
125116
const response = await axios.post<PostPDFToCloudinary>(
126117
"/api/upload",
127118
formData,
128119
);
129-
} catch (error: unknown) {
130-
throw handleAPIError(error);
120+
121+
setSlot("");
122+
setSubject("");
123+
setExam("");
124+
setYear("");
125+
setFiles([]);
126+
if (fileInputRef.current) {
127+
fileInputRef.current.value = "";
128+
}
129+
130+
setResetSearch(true);
131+
setTimeout(() => setResetSearch(false), 100);
132+
} catch (error) {
133+
handleAPIError(error);
134+
} finally {
135+
setIsUploading(false);
131136
}
132137
})(),
133138
{
134139
loading: "Uploading papers...",
135-
success: "papers uploaded",
136-
error: (err: ApiError) => err.message,
140+
success: "Papers uploaded",
141+
error: (err:ApiError) => err.message,
137142
},
138143
);
139144
};
140145

141-
const handleSubjectSelect = (value: string) => {
142-
setSubject(value);
143-
setInputValue(value);
144-
setIsSubjectCommandOpen(false);
145-
};
146-
147146
return (
148147
<div className="flex h-screen flex-col justify-between">
149148
<div>
@@ -195,31 +194,7 @@ const Page = () => {
195194
{/* Subject Selection */}
196195
<div>
197196
<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> */}
197+
<SearchBar setSubject={setSubject} resetSearch={resetSearch} />
223198
</div>
224199

225200
{/* Year Selection */}
@@ -232,14 +207,11 @@ const Page = () => {
232207
<SelectContent>
233208
<SelectGroup>
234209
<SelectLabel>Years</SelectLabel>
235-
{years.map((year)=>
236-
{
237-
return (<SelectItem key={year} value={String(year)}>
210+
{years.map((year) => (
211+
<SelectItem key={year} value={String(year)}>
238212
{year}
239-
</SelectItem>)
240-
241-
}
242-
)}
213+
</SelectItem>
214+
))}
243215
</SelectGroup>
244216
</SelectContent>
245217
</Select>
@@ -283,7 +255,7 @@ const Page = () => {
283255
{isUploading ? "Uploading..." : "Upload Papers"}
284256
</Button>
285257
</div>
286-
<div className="">
258+
<div>
287259
<Footer />
288260
</div>
289261
</div>

0 commit comments

Comments
 (0)