Skip to content

Commit e9cbe4f

Browse files
committed
added no upcoming papers text and fixed responsiveness
1 parent e50f5ce commit e9cbe4f

3 files changed

Lines changed: 160 additions & 65 deletions

File tree

src/components/CatalogueContent.tsx

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -316,16 +316,21 @@ const CatalogueContentInner = ({ subject }: { subject: string | null }) => {
316316
</div>
317317

318318
{/* Select/Deselect/Download All Buttons */}
319-
<div className="mb-8 flex w-full items-center justify-end gap-4">
319+
<div className="mb-6 mt-5 flex w-full flex-wrap items-center justify-start gap-3 sm:gap-4 md:mt-4 md:justify-end">
320320
<SortComponent
321321
onSortChange={setSortOption}
322322
currentSort={sortOption}
323323
/>
324-
<SidebarButton onClick={handleSelectAll}>Select All</SidebarButton>
325-
<SidebarButton onClick={handleDeselectAll}>
324+
325+
<SidebarButton onClick={handleSelectAll} className="order-2">
326+
Select All
327+
</SidebarButton>
328+
329+
<SidebarButton onClick={handleDeselectAll} className="order-2">
326330
Deselect All
327331
</SidebarButton>
328-
<SidebarButton onClick={handleDownloadSelected}>
332+
333+
<SidebarButton onClick={handleDownloadSelected} className="order-2">
329334
Download Selected
330335
</SidebarButton>
331336
</div>

src/components/PapersCarousel.tsx

Lines changed: 80 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,9 @@ function PapersCarousel() {
2323

2424
useEffect(() => {
2525
const handleResize = () => {
26-
if(window.innerWidth <= 540){
26+
if (window.innerWidth <= 540) {
2727
setChunkSize(2);
28-
}
29-
else if (window.innerWidth <= 920) {
28+
} else if (window.innerWidth <= 920) {
3029
setChunkSize(4);
3130
} else {
3231
setChunkSize(8);
@@ -42,7 +41,9 @@ function PapersCarousel() {
4241
const fetchPapers = async () => {
4342
try {
4443
setIsLoading(true);
45-
const response = await axios.get<IUpcomingPaper[]>("/api/upcoming-papers");
44+
const response = await axios.get<IUpcomingPaper[]>(
45+
"/api/upcoming-papers",
46+
);
4647
setDisplayPapers(response.data);
4748
} catch (error) {
4849
console.error("Failed to fetch papers:", error);
@@ -62,70 +63,90 @@ function PapersCarousel() {
6263
const chunkedPapers = chunkArray(displayPapers, chunkSize);
6364
const plugins = [Autoplay({ delay: 8000, stopOnInteraction: true })];
6465

65-
return (
66+
if (chunkedPapers.length === 0)
67+
return (
6668
<div className="mt-3 px-4">
6769
<p className="my-8 text-center font-play text-lg font-semibold md:block">
6870
Upcoming Exams
6971
</p>
72+
<p className="my-8 text-center font-play text-lg font-semibold md:block">
73+
<i>No more upcoming papers, Enjoy your break!</i>
74+
</p>
75+
</div>
76+
);
7077

71-
<Carousel
72-
opts={{ align: "start", loop: true }}
73-
plugins={plugins}
74-
className="w-full"
75-
>
76-
{/* Only show arrows when there are multiple chunks to scroll through */}
77-
{chunkedPapers.length > 1 && displayPapers.length > chunkSize && (
78-
<div className="relative mt-4 flex justify-end gap-4">
79-
<CarouselPrevious className="relative" />
80-
<CarouselNext className="relative" />
81-
</div>
82-
)}
78+
return (
79+
<div className="mt-3 px-4">
80+
<p className="my-8 text-center font-play text-lg font-semibold md:block">
81+
Upcoming Exams
82+
</p>
8383

84-
<CarouselContent>
85-
{isLoading ? (
84+
<Carousel
85+
opts={{ align: "start", loop: true }}
86+
plugins={plugins}
87+
className="w-full"
88+
>
89+
{/* Only show arrows when there are multiple chunks to scroll through */}
90+
{chunkedPapers.length > 1 && displayPapers.length > chunkSize && (
91+
<div className="relative mt-4 flex justify-end gap-4">
92+
<CarouselPrevious className="relative" />
93+
<CarouselNext className="relative" />
94+
</div>
95+
)}
96+
97+
<CarouselContent>
98+
{isLoading ? (
99+
<CarouselItem
100+
className={`grid ${
101+
chunkSize === 2
102+
? "grid-cols-1 grid-rows-2"
103+
: chunkSize === 4
104+
? "grid-cols-2 grid-rows-2"
105+
: "grid-cols-4"
106+
} gap-4 lg:auto-rows-fr`}
107+
>
108+
<SkeletonPaperCard length={chunkSize} />
109+
</CarouselItem>
110+
) : (
111+
chunkedPapers.map((paperGroup, index) => {
112+
const placeholdersNeeded = chunkSize - paperGroup.length;
113+
114+
return (
86115
<CarouselItem
87-
className={`grid ${
88-
chunkSize === 2 ? "grid-cols-1 grid-rows-2" : chunkSize === 4 ? "grid-cols-2 grid-rows-2" : "grid-cols-4"
89-
} gap-4 lg:auto-rows-fr`}
116+
key={`carousel-item-${index}`}
117+
className={`grid ${
118+
chunkSize === 2
119+
? "grid-cols-1 grid-rows-2"
120+
: chunkSize === 4
121+
? "grid-cols-2 grid-rows-2"
122+
: "grid-cols-4"
123+
} gap-4 lg:auto-rows-fr`}
90124
>
91-
<SkeletonPaperCard length={chunkSize} />
92-
</CarouselItem>
93-
) : (
94-
chunkedPapers.map((paperGroup, index) => {
95-
const placeholdersNeeded = chunkSize - paperGroup.length;
96-
97-
return (
98-
<CarouselItem
99-
key={`carousel-item-${index}`}
100-
className={`grid ${
101-
chunkSize === 2 ? "grid-cols-1 grid-rows-2" : chunkSize === 4 ? "grid-cols-2 grid-rows-2" : "grid-cols-4"
102-
} gap-4 lg:auto-rows-fr`}
103-
>
104-
{paperGroup.map((paper, subIndex) => (
105-
<div key={subIndex} className="h-full">
106-
<UpcomingPaper
107-
subject={paper.subject}
108-
slots={paper.slots}
109-
/>
110-
</div>
111-
))}
125+
{paperGroup.map((paper, subIndex) => (
126+
<div key={subIndex} className="h-full">
127+
<UpcomingPaper
128+
subject={paper.subject}
129+
slots={paper.slots}
130+
/>
131+
</div>
132+
))}
112133

113-
{Array.from({ length: placeholdersNeeded }).map(
114-
(_, placeholderIndex) => (
115-
<div
116-
key={`placeholder-${placeholderIndex}`}
117-
className="invisible h-full"
118-
></div>
119-
),
120-
)}
121-
</CarouselItem>
122-
);
123-
})
124-
)}
125-
</CarouselContent>
126-
</Carousel>
127-
</div>
134+
{Array.from({ length: placeholdersNeeded }).map(
135+
(_, placeholderIndex) => (
136+
<div
137+
key={`placeholder-${placeholderIndex}`}
138+
className="invisible h-full"
139+
></div>
140+
),
141+
)}
142+
</CarouselItem>
143+
);
144+
})
145+
)}
146+
</CarouselContent>
147+
</Carousel>
148+
</div>
128149
);
129150
}
130151

131-
export default PapersCarousel;
152+
export default PapersCarousel;

src/components/pdfViewer.tsx

Lines changed: 71 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -200,7 +200,75 @@ export default function PdfViewer({ url, name }: PdfViewerProps) {
200200
}, []);
201201

202202
return (
203-
<div className="flex w-full justify-center gap-6 p-3 md:p-0">
203+
<div className="w-full flex-row justify-center gap-6 p-3 md:flex md:p-0">
204+
{!isFullscreen && (
205+
<div className="mx-auto mb-6 mt-2 flex w-full max-w-[480px] flex-col items-center gap-3 rounded-xl bg-[#F3F5FF] p-3 shadow dark:bg-[#262635] sm:flex-row md:hidden">
206+
<div className="flex items-center gap-2">
207+
<Button
208+
onClick={goToPreviousPage}
209+
disabled={pageNumber <= 1}
210+
className="h-9 w-9 rounded p-0 text-white transition hover:bg-[#6536c1] disabled:bg-[#706b7a] disabled:opacity-50"
211+
>
212+
<FaLessThan />
213+
</Button>
214+
215+
<input
216+
type="text"
217+
value={inputValue}
218+
onChange={(e) => setInputValue(e.target.value)}
219+
onKeyDown={(e) => handlePageChange(e)}
220+
onFocus={() => setInputValue("")}
221+
className="h-9 w-14 rounded border bg-[#e7e9ff] p-1 text-center text-sm [appearance:textfield] dark:bg-[#1f1f2a] [&::-webkit-inner-spin-button]:appearance-none [&::-webkit-outer-spin-button]:appearance-none"
222+
/>
223+
224+
<span className="text-sm font-medium">of {numPages ?? 1}</span>
225+
226+
<Button
227+
onClick={goToNextPage}
228+
disabled={pageNumber >= (numPages ?? 1)}
229+
className="h-9 w-9 rounded p-0 text-white transition hover:bg-[#6536c1] disabled:bg-[#706b7a] disabled:opacity-50"
230+
>
231+
<FaGreaterThan />
232+
</Button>
233+
</div>
234+
235+
<div className="flex items-center gap-2">
236+
<Button
237+
onClick={zoomOut}
238+
disabled={scale <= 0.25}
239+
className="h-9 w-9 rounded p-0 text-white transition hover:bg-[#6536c1] disabled:bg-gray-300"
240+
>
241+
<ZoomOut />
242+
</Button>
243+
244+
<span className="w-10 text-center text-sm font-medium">
245+
{(scale * 100).toFixed(0)}%
246+
</span>
247+
248+
<Button
249+
onClick={zoomIn}
250+
disabled={scale >= 3}
251+
className="h-9 w-9 rounded p-0 text-white transition hover:bg-[#6536c1] disabled:bg-gray-300"
252+
>
253+
<ZoomIn />
254+
</Button>
255+
256+
<ShareButton />
257+
258+
<Button onClick={downloadPDF} className="h-9 w-9 rounded p-0">
259+
<Download />
260+
</Button>
261+
262+
<Button
263+
onClick={toggleFullscreen}
264+
className="h-9 w-9 rounded p-0 text-white transition hover:bg-[#6536c1]"
265+
>
266+
{isFullscreen ? <Minimize2 /> : <Maximize2 />}
267+
</Button>
268+
</div>
269+
</div>
270+
)}
271+
204272
<div
205273
ref={containerRef}
206274
className="max-h-[70vh] overflow-auto rounded-lg bg-[#F3F5FF] px-4 shadow-lg dark:bg-[#070114]"
@@ -242,6 +310,7 @@ export default function PdfViewer({ url, name }: PdfViewerProps) {
242310
</div>
243311
))}
244312
</Document>
313+
245314
{isFullscreen && (
246315
<div className="fixed bottom-4 left-1/2 z-50 mt-4 flex -translate-x-1/2 flex-col items-center gap-4 rounded-lg bg-[#F3F5FF] p-4 shadow dark:bg-[#262635] sm:flex-row">
247316
<div className="flex items-center gap-2">
@@ -305,7 +374,7 @@ export default function PdfViewer({ url, name }: PdfViewerProps) {
305374
</div>
306375

307376
{!isFullscreen && (
308-
<div className="flex h-fit flex-col items-center gap-4 rounded-lg bg-[#F3F5FF] p-4 shadow dark:bg-[#262635]">
377+
<div className="hidden h-fit flex-col items-center gap-4 rounded-lg bg-[#F3F5FF] p-4 shadow dark:bg-[#262635] md:flex">
309378
<div className="flex flex-col items-center gap-3">
310379
<Button
311380
onClick={toggleFullscreen}

0 commit comments

Comments
 (0)