Skip to content

Commit b47d169

Browse files
committed
feat: upcoming paper grid
1 parent bbda444 commit b47d169

File tree

8 files changed

+396
-21
lines changed

8 files changed

+396
-21
lines changed

package.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,9 +32,12 @@
3232
"clsx": "^2.1.1",
3333
"cmdk": "1.0.0",
3434
"debounce": "^2.2.0",
35+
"embla-carousel-autoplay": "^8.6.0",
36+
"embla-carousel-react": "^8.6.0",
3537
"fuse.js": "^7.1.0",
3638
"geist": "^1.3.1",
3739
"jose": "^5.10.0",
40+
"lodash": "^4.17.21",
3841
"lucide-react": "^0.395.0",
3942
"mongoose": "^8.13.2",
4043
"next": "^14.2.28",

pnpm-lock.yaml

Lines changed: 43 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/app/api/upcoming-papers/route.ts

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -22,11 +22,9 @@ export async function GET() {
2222
const correspondingSlots = [slot + "1", slot + "2"];
2323
const selectedSubjects = await UpcomingSubject.find({
2424
slots: { $in: correspondingSlots }, // Match any slot in the array
25-
}).limit(8);
26-
const subbbb = await UpcomingSubject.find({
27-
28-
}).limit(8);
29-
console.log(correspondingSlots, subbbb)
25+
});
26+
const subbbb = await UpcomingSubject.find({});
27+
console.log(correspondingSlots, subbbb);
3028
if (selectedSubjects.length === 0) {
3129
return NextResponse.json(
3230
{

src/components/Navbar.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ function Navbar() {
1010
const pathname = usePathname();
1111

1212
return (
13-
<div className="sticky top-0 z-10 flex h-[85px] w-full items-center justify-between gap-x-3 overflow-hidden bg-[#B2B8FF] px-2 py-6 dark:bg-[#1d162d] md:px-12">
13+
<div className="sticky top-0 z-10 flex h-[85px] w-full items-center justify-between gap-x-3 overflow-hidden bg-[#B2B8FF] px-2 py-6 dark:bg-[#130E1F] md:px-12">
1414
<div className="flex items-center gap-x-2 md:w-auto">
1515
<a href="https://www.codechefvit.com/" className="inline-block">
1616
<Image

src/components/StoredPapers.tsx

Lines changed: 71 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,47 +1,107 @@
11
"use client";
2-
import papers from "ongoing-papers";
32
import { useEffect, useState } from "react";
43
import axios from "axios";
54
import { type IUpcomingPaper } from "@/interface";
65
import Loader from "./ui/loader";
76
import UpcomingPaper from "./UpcomingPaper";
7+
import {
8+
Carousel,
9+
CarouselContent,
10+
CarouselItem,
11+
CarouselNext,
12+
CarouselPrevious,
13+
} from "@/components/ui/carousel";
14+
import Autoplay from "embla-carousel-autoplay";
15+
import { chunkArray } from "@/util/utils";
816

917
function StoredPapers() {
1018
const [displayPapers, setDisplayPapers] = useState<IUpcomingPaper[]>([]);
19+
const [isLoading, setIsLoading] = useState(true);
20+
const [chunkSize, setChunkSize] = useState<number>(4);
21+
22+
useEffect(() => {
23+
const handleResize = () => {
24+
if (window.innerWidth < 640) {
25+
setChunkSize(4);
26+
} else {
27+
setChunkSize(8);
28+
}
29+
};
30+
31+
handleResize();
32+
window.addEventListener("resize", handleResize);
33+
34+
return () => {
35+
window.removeEventListener("resize", handleResize);
36+
};
37+
}, []);
38+
39+
const chunkedPapers = chunkArray(displayPapers, chunkSize);
1140

1241
useEffect(() => {
1342
async function fetchPapers() {
1443
try {
44+
setIsLoading(true);
1545
const response = await axios.get<IUpcomingPaper[]>(
1646
"/api/upcoming-papers",
1747
);
1848
setDisplayPapers(response.data);
1949
} catch (error) {
2050
console.error("Failed to fetch papers:", error);
51+
} finally {
52+
setIsLoading(false);
2153
}
2254
}
2355

2456
void fetchPapers();
2557
}, []);
2658

27-
if (displayPapers.length === 0) {
59+
if (isLoading) {
2860
return <Loader prop="m-10" />;
2961
}
3062

63+
const plugins = [Autoplay({ delay: 3000, stopOnInteraction: true })];
64+
3165
return (
32-
<div className="h-min">
66+
<div className="px-4">
3367
<p className="play my-8 text-center text-lg font-semibold">
3468
Upcoming Papers
3569
</p>
3670

37-
<div className="grid grid-cols-1 justify-center gap-6 sm:grid-cols-2 md:grid-cols-2 lg:grid-cols-4 px-6">
38-
{displayPapers.map((paper: IUpcomingPaper) => (
39-
<UpcomingPaper
40-
key={paper.subject}
41-
subject={paper.subject}
42-
slots={paper.slots}
43-
/>
44-
))}
71+
<div className="">
72+
<Carousel
73+
opts={{
74+
align: "start",
75+
loop: true,
76+
}}
77+
plugins={plugins}
78+
className="w-full"
79+
>
80+
<div className="relative mt-4 flex justify-end gap-4">
81+
<CarouselPrevious className="relative" />
82+
<CarouselNext className="relative" />
83+
</div>
84+
<CarouselContent>
85+
{chunkedPapers.map((paperGroup, index) => {
86+
console.log(8 - paperGroup.length);
87+
return (
88+
<CarouselItem
89+
key={`carousel-item-${index}`}
90+
className="grid grid-cols-2 grid-rows-2 gap-4 md:grid-cols-4 lg:auto-rows-fr"
91+
>
92+
{paperGroup.map((paper, subIndex) => (
93+
<div key={subIndex} className="h-full">
94+
<UpcomingPaper
95+
subject={paper.subject}
96+
slots={paper.slots}
97+
/>
98+
</div>
99+
))}
100+
</CarouselItem>
101+
);
102+
})}
103+
</CarouselContent>
104+
</Carousel>
45105
</div>
46106
</div>
47107
);

src/components/UpcomingPaper.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,18 +33,18 @@ export default function PaperCard({ subject, slots }: PaperCardProps) {
3333

3434
router.push(`/catalogue?${queryParams.toString()}`);
3535
}}
36-
className="cursor-pointer rounded-sm border-2 border-[#734DFF] bg-[#FFFFFF] text-black shadow-lg transition duration-150 ease-in-out hover:bg-[#EFEAFF] dark:border-[#36266D] dark:bg-[#171720] dark:text-white hover:dark:bg-[#262635]"
36+
className="h-full cursor-pointer rounded-sm border-2 border-[#734DFF] bg-[#FFFFFF] text-black shadow-lg transition duration-150 ease-in-out hover:bg-[#EFEAFF] dark:border-[#36266D] dark:bg-[#171720] dark:text-white hover:dark:bg-[#262635]"
3737
>
3838
{/* Course Code */}
3939
<div className="border-b-2 border-[#453D60] p-2">
40-
<h3 className="vipnabd inline-block rounded-t-lg px-2 py-1 text-lg tracking-widest">
40+
<h3 className="vipnabd inline-block rounded-t-lg px-2 py-1 text-base md:text-lg md:tracking-widest">
4141
{courseCode} {/* Replace with dynamic code if needed */}
4242
</h3>
4343
</div>
4444

4545
{/* Subject Name */}
4646
<div className="flex flex-col justify-between p-4">
47-
<h2 className="mt-2 text-xl font-bold">{courseName}</h2>
47+
<h2 className="mt-2 text-base font-bold md:text-xl">{courseName}</h2>
4848
{/* Slot Buttons */}
4949
<div className="mt-4 flex gap-2">
5050
{slots?.map((slotValue, index) => capsule(slotValue))}

0 commit comments

Comments
 (0)