11"use client" ;
22
3+ import React from "react" ;
34import { type IPaper } from "@/interface" ;
45import Image from "next/image" ;
56import { Eye , Download , Check } from "lucide-react" ;
@@ -23,6 +24,8 @@ interface CardProps {
2324}
2425
2526const Card = ( { paper, onSelect, isSelected } : CardProps ) => {
27+ const [ previewOpen , setPreviewOpen ] = React . useState ( false ) ;
28+
2629 const handleDownload = async ( paper : IPaper ) => {
2730 await downloadFile ( getSecureUrl ( paper . file_url ) , generateFileName ( paper ) ) ;
2831 } ;
@@ -34,77 +37,109 @@ const Card = ({ paper, onSelect, isSelected }: CardProps) => {
3437 const paperLink = `/paper/${ paper . _id } ` ;
3538
3639 return (
37- < div
38- className = { cn (
39- "overflow-hidden rounded-sm border-2 border-[#734DFF] bg-[#FFFFFF] font-play transition-all duration-150 hover:bg-[#EFEAFF] dark:border-[#36266D] dark:bg-[#171720] hover:dark:bg-[#262635]" ,
40- isSelected && "bg-white" ,
41- ) }
42- >
43- < Link href = { paperLink } target = "_blank" rel = "noopener noreferrer" >
44- < Image
45- src = { paper . thumbnail_url }
46- alt = { paper . subject }
47- width = { 320 }
48- height = { 180 }
49- className = "w-full object-cover p-4 pb-3 md:h-[250px]"
50- />
51-
52- < div className = "justify-center" >
53- < div className = "flex flex-row items-center justify-between px-4 pb-2" >
54- < div className = "text-md font-play font-medium" >
55- { extractBracketContent ( paper . subject ) }
56- </ div >
57- < div className = "flex gap-2" >
58- < Link href = { paperLink } target = "_blank" rel = "noopener noreferrer" >
59- < Eye size = { 22 } />
60- </ Link >
61- < Download
62- size = { 20 }
63- onClick = { ( e ) => {
64- e . preventDefault ( ) ;
65- e . stopPropagation ( ) ;
66- void handleDownload ( paper ) ;
67- } }
68- className = "cursor-pointer"
69- />
40+ < >
41+ < div
42+ className = { cn (
43+ "overflow-hidden rounded-sm border-2 border-[#734DFF] bg-[#FFFFFF] font-play transition-all duration-150 hover:bg-[#EFEAFF] dark:border-[#36266D] dark:bg-[#171720] hover:dark:bg-[#262635]" ,
44+ isSelected && "bg-white" ,
45+ ) }
46+ >
47+ < Link href = { paperLink } target = "_blank" rel = "noopener noreferrer" >
48+ < Image
49+ src = { paper . thumbnail_url }
50+ alt = { paper . subject }
51+ width = { 320 }
52+ height = { 180 }
53+ className = "w-full object-cover p-4 pb-3 md:h-[250px]"
54+ />
55+
56+ < div className = "justify-center" >
57+ < div className = "flex flex-row items-center justify-between px-4 pb-2" >
58+ < div className = "text-md font-play font-medium" >
59+ { extractBracketContent ( paper . subject ) }
60+ </ div >
7061 </ div >
71- </ div >
7262
73- < div className = "h-[1px] w-full bg-[#734DFF] dark:bg-[#36266D]" />
63+ < div className = "h-[1px] w-full bg-[#734DFF] dark:bg-[#36266D]" />
7464
75- < div className = "space-y-2 p-4" >
76- < div className = "font-play text-lg font-semibold" >
77- { extractWithoutBracketContent ( paper . subject ) }
78- </ div >
79- < div className = "flex flex-wrap gap-2" >
80- < Capsule > { paper . exam } </ Capsule >
81- < Capsule > { paper . slot } </ Capsule >
82- < Capsule > { paper . year } </ Capsule >
83- < Capsule > { paper . semester } </ Capsule >
65+ < div className = "space-y-2 p-4" >
66+ < div className = "font-play text-lg font-semibold" >
67+ { extractWithoutBracketContent ( paper . subject ) }
68+ </ div >
69+ < div className = "flex flex-wrap gap-2" >
70+ < Capsule > { paper . exam } </ Capsule >
71+ < Capsule > { paper . slot } </ Capsule >
72+ < Capsule > { paper . year } </ Capsule >
73+ < Capsule > { paper . semester } </ Capsule >
74+ </ div >
8475 </ div >
8576 </ div >
86- </ div >
87- </ Link >
88-
89- < div className = "flex items-center justify-between gap-2 px-4 pb-4 font-play" >
90- < div className = "flex items-center gap-2" >
91- < input
92- checked = { isSelected }
93- onChange = { handleCheckboxChange }
94- className = "h-5 w-5 accent-[#7480FF]"
95- type = "checkbox"
77+ </ Link >
78+
79+ < div className = "flex justify-end gap-2 px-4 pb-2" >
80+ < Eye
81+ size = { 22 }
82+ className = "cursor-pointer"
83+ onClick = { ( e ) => {
84+ e . stopPropagation ( ) ;
85+ setPreviewOpen ( true ) ;
86+ } }
87+ />
88+
89+ < Download
90+ size = { 20 }
91+ onClick = { ( e ) => {
92+ e . stopPropagation ( ) ;
93+ void handleDownload ( paper ) ;
94+ } }
95+ className = "cursor-pointer"
9696 />
97- < p > Select</ p >
9897 </ div >
99- { paper . answer_key_included && (
100- < div className = "flex items-center gap-2 font-normal text-[#7480FF]" >
101- < Check color = "#7480FF" />
102- Answer Key
98+
99+ < div className = "flex items-center justify-between gap-2 px-4 pb-4 font-play" >
100+ < div className = "flex items-center gap-2" >
101+ < input
102+ checked = { isSelected }
103+ onChange = { handleCheckboxChange }
104+ className = "h-5 w-5 accent-[#7480FF]"
105+ type = "checkbox"
106+ />
107+ < p > Select</ p >
103108 </ div >
104- ) }
109+
110+ { paper . answer_key_included && (
111+ < div className = "flex items-center gap-2 font-normal text-[#7480FF]" >
112+ < Check color = "#7480FF" />
113+ Answer Key
114+ </ div >
115+ ) }
116+ </ div >
105117 </ div >
106- </ div >
118+
119+ { previewOpen && (
120+ < div
121+ className = "fixed inset-0 z-50 flex items-center justify-center bg-black/80"
122+ onClick = { ( ) => setPreviewOpen ( false ) }
123+ >
124+ < div
125+ className = "relative w-[95%] max-w-5xl h-[90vh] rounded-lg bg-white p-2 dark:bg-[#171720]"
126+ onClick = { ( e ) => e . stopPropagation ( ) }
127+ >
128+ < button
129+ className = "absolute right-3 top-3 z-10 text-xl"
130+ onClick = { ( ) => setPreviewOpen ( false ) }
131+ >
132+ ✕
133+ </ button >
134+ < iframe
135+ src = { paper . file_url }
136+ className = "w-full h-full rounded-md"
137+ />
138+ </ div >
139+ </ div >
140+ ) }
141+ </ >
107142 ) ;
108143} ;
109144
110- export default Card ;
145+ export default Card ;
0 commit comments