3
3
import { useEffect , useState } from "react" ;
4
4
import axios from "axios" ;
5
5
import { type IUpcomingPaper } from "@/interface" ;
6
- import Loader from "./ui/loader" ;
7
6
import UpcomingPaper from "./UpcomingPaper" ;
8
7
import {
9
8
Carousel ,
@@ -14,15 +13,12 @@ import {
14
13
} from "@/components/ui/carousel" ;
15
14
import Autoplay from "embla-carousel-autoplay" ;
16
15
import { chunkArray } from "@/util/utils" ;
16
+ import { Skeleton } from "@/components/ui/skeleton" ;
17
17
18
- function PapersCarousel ( {
19
- carouselType,
20
- } : {
21
- carouselType : "users" | "default" ;
22
- } ) {
18
+ function PapersCarousel ( ) {
23
19
const [ displayPapers , setDisplayPapers ] = useState < IUpcomingPaper [ ] > ( [ ] ) ;
24
20
const [ isLoading , setIsLoading ] = useState ( true ) ;
25
- const [ chunkSize , setChunkSize ] = useState < number > ( 4 ) ;
21
+ const [ chunkSize , setChunkSize ] = useState < number > ( 4 ) ; // dynamic chunk size
26
22
27
23
useEffect ( ( ) => {
28
24
const handleResize = ( ) => {
@@ -33,6 +29,7 @@ function PapersCarousel({
33
29
}
34
30
} ;
35
31
32
+ // preload sample subjects
36
33
localStorage . setItem (
37
34
"userSubjects" ,
38
35
JSON . stringify ( [
@@ -41,35 +38,20 @@ function PapersCarousel({
41
38
"Design and Analysis of Algorithms [MCSE502L]" ,
42
39
"Complex Variables and Linear Algebra [BMAT201L]" ,
43
40
"Differential Equations and Transforms [BMAT102L]" ,
44
- ] ) ,
41
+ ] )
45
42
) ;
46
43
47
- handleResize ( ) ;
44
+ handleResize ( ) ; // initialize
48
45
window . addEventListener ( "resize" , handleResize ) ;
49
-
50
- return ( ) => {
51
- window . removeEventListener ( "resize" , handleResize ) ;
52
- } ;
46
+ return ( ) => window . removeEventListener ( "resize" , handleResize ) ;
53
47
} , [ ] ) ;
54
48
55
- const chunkedPapers = chunkArray ( displayPapers , chunkSize ) ;
56
-
57
49
useEffect ( ( ) => {
58
50
async function fetchPapers ( ) {
59
51
try {
60
52
setIsLoading ( true ) ;
61
- if ( carouselType === "users" ) {
62
- const storedSubjects = JSON . parse (
63
- localStorage . getItem ( "userSubjects" ) ?? "[]"
64
- ) as string [ ] ;
65
- const response = await axios . post < IUpcomingPaper [ ] > ( "/api/user-papers" , storedSubjects ) ;
66
- setDisplayPapers ( response . data ) ;
67
- } else {
68
- const response = await axios . get < IUpcomingPaper [ ] > (
69
- "/api/upcoming-papers" ,
70
- ) ;
71
- setDisplayPapers ( response . data ) ;
72
- }
53
+ const response = await axios . get < IUpcomingPaper [ ] > ( "/api/upcoming-papers" ) ;
54
+ setDisplayPapers ( response . data ) ;
73
55
} catch ( error ) {
74
56
console . error ( "Failed to fetch papers:" , error ) ;
75
57
} finally {
@@ -80,52 +62,75 @@ function PapersCarousel({
80
62
void fetchPapers ( ) ;
81
63
} , [ ] ) ;
82
64
83
- if ( isLoading ) {
84
- return < Loader prop = "m-10" /> ;
85
- }
86
-
65
+ const chunkedPapers = chunkArray ( displayPapers , chunkSize ) ;
87
66
const plugins = [ Autoplay ( { delay : 8000 , stopOnInteraction : true } ) ] ;
88
67
89
68
return (
90
69
< div className = "px-4" >
91
70
< p className = "my-8 text-center font-play text-lg font-semibold" >
92
- { carouselType === "users" ? "Your Papers" : " Upcoming Papers" }
71
+ Upcoming Papers
93
72
</ p >
94
73
95
- < div className = "" >
96
- < Carousel
97
- opts = { {
98
- align : "start" ,
99
- loop : true ,
100
- } }
101
- plugins = { plugins }
102
- className = "w-full"
103
- >
104
- < div className = "relative mt-4 flex justify-end gap-4" >
105
- < CarouselPrevious className = "relative" />
106
- < CarouselNext className = "relative" />
107
- </ div >
108
- < CarouselContent >
109
- { chunkedPapers . map ( ( paperGroup , index ) => {
110
- return (
111
- < CarouselItem
112
- key = { `carousel-item-${ index } ` }
113
- className = "grid grid-cols-2 grid-rows-2 gap-4 md:grid-cols-4 lg:auto-rows-fr"
74
+ < Carousel
75
+ opts = { { align : "start" , loop : true } }
76
+ plugins = { plugins }
77
+ className = "w-full"
78
+ >
79
+ < div className = "relative mt-4 flex justify-end gap-4" >
80
+ < CarouselPrevious className = "relative" />
81
+ < CarouselNext className = "relative" />
82
+ </ div >
83
+
84
+ < CarouselContent >
85
+ { isLoading ? (
86
+ < CarouselItem
87
+ className = { `grid ${
88
+ chunkSize === 4
89
+ ? "grid-cols-2 grid-rows-2"
90
+ : "grid-cols-4"
91
+ } gap-4 lg:auto-rows-fr`}
92
+ >
93
+ { Array . from ( { length : chunkSize } ) . map ( ( _ , idx ) => (
94
+ < div
95
+ key = { idx }
96
+ 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]"
114
97
>
115
- { paperGroup . map ( ( paper , subIndex ) => (
116
- < div key = { subIndex } className = "h-full" >
117
- < UpcomingPaper
118
- subject = { paper . subject }
119
- slots = { paper . slots }
120
- />
98
+ < div className = "border-b-2 border-[#453D60] p-2" >
99
+ < Skeleton className = "h-6 w-24 rounded-md" />
100
+ </ div >
101
+ < div className = "flex flex-col justify-between p-4" >
102
+ < Skeleton className = "mb-4 h-6 w-32 rounded-md" />
103
+ < div className = "flex gap-2" >
104
+ < Skeleton className = "h-7 w-16 rounded-full" />
105
+ < Skeleton className = "h-7 w-16 rounded-full" />
121
106
</ div >
122
- ) ) }
123
- </ CarouselItem >
124
- ) ;
125
- } ) }
126
- </ CarouselContent >
127
- </ Carousel >
128
- </ div >
107
+ </ div >
108
+ </ div >
109
+ ) ) }
110
+ </ CarouselItem >
111
+ ) : (
112
+ chunkedPapers . map ( ( paperGroup , index ) => (
113
+ < CarouselItem
114
+ key = { `carousel-item-${ index } ` }
115
+ className = { `grid ${
116
+ chunkSize === 4
117
+ ? "grid-cols-2 grid-rows-2"
118
+ : "grid-cols-4"
119
+ } gap-4 lg:auto-rows-fr`}
120
+ >
121
+ { paperGroup . map ( ( paper , subIndex ) => (
122
+ < div key = { subIndex } className = "h-full" >
123
+ < UpcomingPaper
124
+ subject = { paper . subject }
125
+ slots = { paper . slots }
126
+ />
127
+ </ div >
128
+ ) ) }
129
+ </ CarouselItem >
130
+ ) )
131
+ ) }
132
+ </ CarouselContent >
133
+ </ Carousel >
129
134
</ div >
130
135
) ;
131
136
}
0 commit comments