diff --git a/src/app/api/course-list/route.ts b/src/app/api/course-list/route.ts index 09d171ae..31ef5c0a 100644 --- a/src/app/api/course-list/route.ts +++ b/src/app/api/course-list/route.ts @@ -1,5 +1,5 @@ import { NextResponse } from "next/server"; -import { connectToDatabase } from "@/lib/mongoose"; +import { connectToDatabase } from "@/lib/database/mongoose"; import { Course } from "@/db/course"; export const dynamic = "force-dynamic"; diff --git a/src/app/api/paper-by-id/[id]/route.ts b/src/app/api/paper-by-id/[id]/route.ts index 09a0ebbb..aced225c 100644 --- a/src/app/api/paper-by-id/[id]/route.ts +++ b/src/app/api/paper-by-id/[id]/route.ts @@ -1,5 +1,5 @@ import { NextResponse } from "next/server"; -import { connectToDatabase } from "@/lib/mongoose"; +import { connectToDatabase } from "@/lib/database/mongoose"; import Paper from "@/db/papers"; import { Types } from "mongoose"; diff --git a/src/app/api/papers/count/route.ts b/src/app/api/papers/count/route.ts index 2849c825..2225ff3a 100644 --- a/src/app/api/papers/count/route.ts +++ b/src/app/api/papers/count/route.ts @@ -1,5 +1,5 @@ import { NextResponse } from "next/server"; -import { connectToDatabase } from "@/lib/mongoose"; +import { connectToDatabase } from "@/lib/database/mongoose"; import CourseCount from "@/db/course"; export const dynamic = "force-dynamic"; diff --git a/src/app/api/papers/route.ts b/src/app/api/papers/route.ts index fc4aa808..5b2ae2fc 100644 --- a/src/app/api/papers/route.ts +++ b/src/app/api/papers/route.ts @@ -1,7 +1,9 @@ import { NextResponse, type NextRequest } from "next/server"; -import { connectToDatabase } from "@/lib/mongoose"; +import { connectToDatabase } from "@/lib/database/mongoose"; import Paper from "@/db/papers"; import { type IPaper } from "@/interface"; +import { escapeRegExp } from "@/lib/utils/regex"; +import { extractUniqueValues } from "@/lib/utils/paper-aggregation"; export const dynamic = "force-dynamic"; @@ -10,10 +12,6 @@ export async function GET(req: NextRequest) { await connectToDatabase(); const url = req.nextUrl.searchParams; const subject = url.get("subject"); - const escapeRegExp = (text: string) => { - return text.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); - }; - const escapedSubject = escapeRegExp(subject ?? ""); if (!subject) { return NextResponse.json( @@ -22,42 +20,17 @@ export async function GET(req: NextRequest) { ); } + const escapedSubject = escapeRegExp(subject); const papers: IPaper[] = await Paper.find({ subject: { $regex: new RegExp(`${escapedSubject}`, "i") }, }); - if (papers.length === 0) { - return NextResponse.json( - { - papers, - unique_years: [], - unique_slots: [], - unique_exams: [], - unique_campuses: [], - unique_semesters: [], - }, - { status: 200 }, - ); - } - - const unique_years = Array.from(new Set(papers.map((paper) => paper.year))); - const unique_slots = Array.from(new Set(papers.map((paper) => paper.slot))); - const unique_exams = Array.from(new Set(papers.map((paper) => paper.exam))); - const unique_campuses = Array.from( - new Set(papers.map((paper) => paper.campus)), - ); - const unique_semesters = Array.from( - new Set(papers.map((paper) => paper.semester)), - ); + const uniqueValues = extractUniqueValues(papers); return NextResponse.json( { papers, - unique_years, - unique_slots, - unique_exams, - unique_campuses, - unique_semesters, + ...uniqueValues, }, { status: 200 }, ); @@ -67,4 +40,4 @@ export async function GET(req: NextRequest) { { status: 500 }, ); } -} +} \ No newline at end of file diff --git a/src/app/api/related-subject/route.ts b/src/app/api/related-subject/route.ts index 1640f9ec..77800cbf 100644 --- a/src/app/api/related-subject/route.ts +++ b/src/app/api/related-subject/route.ts @@ -1,7 +1,8 @@ import { NextResponse, type NextRequest } from "next/server"; -import { connectToDatabase } from "@/lib/mongoose"; +import { connectToDatabase } from "@/lib/database/mongoose"; import { IRelatedSubject } from "@/interface"; import RelatedSubject from "@/db/relatedSubjects"; +import { escapeRegExp } from "@/lib/utils/regex"; export const dynamic = "force-dynamic"; @@ -10,10 +11,6 @@ export async function GET(req: NextRequest) { await connectToDatabase(); const url = req.nextUrl.searchParams; const subject = url.get("subject"); - const escapeRegExp = (text: string) => { - return text.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); - }; - const escapedSubject = escapeRegExp(subject ?? ""); if (!subject) { return NextResponse.json( @@ -21,9 +18,12 @@ export async function GET(req: NextRequest) { { status: 400 }, ); } + + const escapedSubject = escapeRegExp(subject); const subjects: IRelatedSubject[] = await RelatedSubject.find({ subject: { $regex: new RegExp(`${escapedSubject}`, "i") }, }); + console.log("realted", subjects); return NextResponse.json( @@ -38,4 +38,4 @@ export async function GET(req: NextRequest) { { status: 500 }, ); } -} +} \ No newline at end of file diff --git a/src/app/api/request/route.ts b/src/app/api/request/route.ts index 3c5920d5..48c93022 100644 --- a/src/app/api/request/route.ts +++ b/src/app/api/request/route.ts @@ -1,5 +1,5 @@ import { NextResponse } from "next/server"; -import { connectToDatabase } from "@/lib/mongoose"; +import { connectToDatabase } from "@/lib/database/mongoose"; import PaperRequest from "@/db/paperRequest"; export async function POST(req: Request) { diff --git a/src/app/api/selected-papers/route.ts b/src/app/api/selected-papers/route.ts index fd972d25..5c822f6b 100644 --- a/src/app/api/selected-papers/route.ts +++ b/src/app/api/selected-papers/route.ts @@ -1,5 +1,5 @@ import { NextResponse } from "next/server"; -import { connectToDatabase } from "@/lib/mongoose"; +import { connectToDatabase } from "@/lib/database/mongoose"; import Paper from "@/db/papers"; export const dynamic = "force-dynamic"; diff --git a/src/app/api/subscribe/route.ts b/src/app/api/subscribe/route.ts index cc08c95e..2848b59f 100644 --- a/src/app/api/subscribe/route.ts +++ b/src/app/api/subscribe/route.ts @@ -1,34 +1,5 @@ import { NextResponse } from "next/server"; -import { google, sheets_v4 } from "googleapis"; -import { JWT } from "google-auth-library"; - -const SCOPES = ["https://www.googleapis.com/auth/spreadsheets"]; -const SHEET_ID = process.env.SHEET_ID; - -async function getAuth(): Promise { - return new google.auth.JWT({ - email: process.env.GOOGLE_CLIENT_EMAIL, - key: process.env.GOOGLE_PRIVATE_KEY?.replace(/\\n/g, "\n"), - scopes: SCOPES, - }); -} - -async function appendEmailToSheet(email: string) { - const authClient = await getAuth(); - const sheets: sheets_v4.Sheets = google.sheets({ - version: "v4", - auth: authClient, - }); - - await sheets.spreadsheets.values.append({ - spreadsheetId: SHEET_ID, - range: "Sheet1!A:A", - valueInputOption: "RAW", - requestBody: { - values: [[email]], - }, - }); -} +import { appendEmailToSheet } from "@/lib/services/google-sheets"; export async function POST(req: Request) { try { @@ -44,4 +15,4 @@ export async function POST(req: Request) { console.error("Error adding email:", error); return NextResponse.json({ error: "Failed to add email" }, { status: 500 }); } -} +} \ No newline at end of file diff --git a/src/app/api/upcoming-papers/route.ts b/src/app/api/upcoming-papers/route.ts index 8b426fab..72d52e9a 100644 --- a/src/app/api/upcoming-papers/route.ts +++ b/src/app/api/upcoming-papers/route.ts @@ -1,7 +1,8 @@ import { NextResponse } from "next/server"; -import { connectToDatabase } from "@/lib/mongoose"; +import { connectToDatabase } from "@/lib/database/mongoose"; import UpcomingSlot from "@/db/upcoming-slot"; import UpcomingSubject from "@/db/upcoming-paper"; +import { calculateCorrespondingSlots } from "@/lib/utils/slot-calculation"; export const dynamic = "force-dynamic"; @@ -10,6 +11,7 @@ export async function GET() { await connectToDatabase(); const upcomingSlot = await UpcomingSlot.find(); const slot = upcomingSlot[0]?.slot; + if (!slot) { return NextResponse.json( { @@ -18,16 +20,12 @@ export async function GET() { { status: 404 }, ); } - const nextSlot = String.fromCharCode(slot.charCodeAt(0) + 1); - const correspondingSlots = [ - slot + "1", - slot + "2", - nextSlot + "1", - nextSlot + "2", - ]; + + const correspondingSlots = calculateCorrespondingSlots(slot); const selectedSubjects = await UpcomingSubject.find({ slots: { $in: correspondingSlots }, }); + if (selectedSubjects.length === 0) { return NextResponse.json( { @@ -49,4 +47,4 @@ export async function GET() { { status: 500 }, ); } -} +} \ No newline at end of file diff --git a/src/app/api/upload/route.ts b/src/app/api/upload/route.ts index 4164ebe4..2fad98e7 100644 --- a/src/app/api/upload/route.ts +++ b/src/app/api/upload/route.ts @@ -1,8 +1,8 @@ import { NextResponse } from "next/server"; -import { connectToDatabase } from "@/lib/mongoose"; +import { connectToDatabase } from "@/lib/database/mongoose"; import { PaperAdmin } from "@/db/papers"; -import { createPDFfromImages } from "@/lib/pdf"; -import { uploadPDF, uploadThumbnail } from "@/lib/storage"; +import { createPDFfromImages } from "@/lib/storage/pdf"; +import { uploadPDF, uploadThumbnail } from "@/lib/storage/gcp"; export const runtime = "nodejs"; diff --git a/src/app/api/user-papers/route.ts b/src/app/api/user-papers/route.ts index 9f1ba6b3..f3a9c674 100644 --- a/src/app/api/user-papers/route.ts +++ b/src/app/api/user-papers/route.ts @@ -1,11 +1,11 @@ import { NextResponse } from "next/server"; -import { connectToDatabase } from "@/lib/mongoose"; +import { connectToDatabase } from "@/lib/database/mongoose"; import Paper from "@/db/papers"; -import { StoredSubjects, TransformedPaper } from "@/interface"; +import { StoredSubjects } from "@/interface"; +import { transformPapersToSubjectSlots } from "@/lib/services/paper-transform"; export const dynamic = "force-dynamic"; - export async function POST(req: Request) { try { await connectToDatabase(); @@ -17,22 +17,7 @@ export async function POST(req: Request) { console.log("Fetched user papers:", usersPapers); - const transformedPapers = usersPapers.reduce( - (acc, paper) => { - const existing = acc.find((item) => item.subject === paper.subject); - - if (existing) { - if (!existing.slots.includes(paper.slot)) { - existing.slots.push(paper.slot); - } - } else { - acc.push({ subject: paper.subject, slots: [paper.slot] }); - } - - return acc; - }, - [], - ); + const transformedPapers = transformPapersToSubjectSlots(usersPapers); return NextResponse.json(transformedPapers, { status: 200, @@ -46,4 +31,4 @@ export async function POST(req: Request) { { status: 500 }, ); } -} +} \ No newline at end of file diff --git a/src/app/paper/[id]/page.tsx b/src/app/paper/[id]/page.tsx index 8161ccf2..fb720f77 100644 --- a/src/app/paper/[id]/page.tsx +++ b/src/app/paper/[id]/page.tsx @@ -3,7 +3,7 @@ import PdfViewer from "@/components/pdfViewer"; import RelatedPapers from "@/components/RelatedPaper"; import Loader from "@/components/ui/loader"; import { type ErrorResponse, type PaperResponse } from "@/interface"; -import { extractBracketContent } from "@/util/utils"; +import { extractBracketContent } from "@/lib/utils/string"; import axios, { type AxiosResponse } from "axios"; import { type Metadata } from "next"; import { redirect } from "next/navigation"; diff --git a/src/app/upload/page.tsx b/src/app/upload/page.tsx index 1260f84f..d5cf150a 100644 --- a/src/app/upload/page.tsx +++ b/src/app/upload/page.tsx @@ -26,7 +26,7 @@ import Dropzone from "react-dropzone"; import { Upload, XIcon } from "lucide-react"; import { getDocument, GlobalWorkerOptions } from "pdfjs-dist"; -GlobalWorkerOptions.workerSrc = +GlobalWorkerOptions.workerSrc = "https://cdnjs.cloudflare.com/ajax/libs/pdf.js/4.8.69/pdf.worker.min.mjs"; interface APIResponse { @@ -288,7 +288,7 @@ export default function Page() { setIsUploading(false); } }; - + return (
diff --git a/src/components/Card.tsx b/src/components/Card.tsx index 6a64f276..c32c1f99 100644 --- a/src/components/Card.tsx +++ b/src/components/Card.tsx @@ -5,15 +5,15 @@ import { type IPaper } from "@/interface"; import Image from "next/image"; import { Eye, Download, Check } from "lucide-react"; import { - capsule, extractBracketContent, extractWithoutBracketContent, -} from "@/util/utils"; +} from "@/lib/utils/string"; import { getSecureUrl, generateFileName, downloadFile, -} from "@/util/download_paper"; +} from "@/lib/utils/download"; +import { Capsule } from "@/components/ui/capsule"; import Link from "next/link"; import { cn } from "@/lib/utils"; @@ -88,10 +88,10 @@ const Card = ({ paper, onSelect, isSelected }: CardProps) => { {extractWithoutBracketContent(paper.subject)}
- {capsule(paper.exam)} - {capsule(paper.slot)} - {capsule(paper.year)} - {capsule(paper.semester)} + {paper.exam} + {paper.slot} + {paper.year} + {paper.semester}
diff --git a/src/components/CatalogueContent.tsx b/src/components/CatalogueContent.tsx index 327be364..90250139 100644 --- a/src/components/CatalogueContent.tsx +++ b/src/components/CatalogueContent.tsx @@ -20,7 +20,7 @@ import { getSecureUrl, generateFileName, downloadFile, -} from "@/util/download_paper"; +} from "@/lib/utils/download"; import type { ICourses } from "@/interface"; import JSZip from "jszip"; import { toast } from "react-hot-toast"; diff --git a/src/components/Navbar.tsx b/src/components/Navbar.tsx index 3b4d2fd3..9a9ac763 100644 --- a/src/components/Navbar.tsx +++ b/src/components/Navbar.tsx @@ -48,13 +48,13 @@ function Navbar() {
- +
- +
@@ -95,7 +95,7 @@ function Navbar() {