@@ -3,7 +3,7 @@ import React, { useState, useEffect } from "react";
3
3
import NavBar from "../NavBar/page" ;
4
4
import Footer from "../Footer/page" ;
5
5
import { motion , AnimatePresence } from "framer-motion" ;
6
- import { sanity } from "@/lib/sanity" ; // adjust path as needed
6
+ import { sanity } from "@/lib/sanity" ;
7
7
8
8
interface EventType {
9
9
_id : string ;
@@ -34,17 +34,27 @@ const query = `*[_type == "event"]{
34
34
}
35
35
}` ;
36
36
37
- const EventCard = ( { event } : { event : EventType } ) => (
37
+ const EventCard = ( {
38
+ event,
39
+ expanded,
40
+ onClick,
41
+ } : {
42
+ event : EventType ;
43
+ expanded : boolean ;
44
+ onClick : ( ) => void ;
45
+ } ) => (
38
46
< motion . div
39
- className = "bg-white/20 dark:bg-neutral-900/70 rounded-2xl shadow-xl overflow-hidden backdrop-blur-md border border-white/10 flex flex-col"
47
+ className = "bg-white/20 dark:bg-neutral-900/70 rounded-2xl shadow-xl overflow-hidden backdrop-blur-md border border-white/10 flex flex-col cursor-pointer transition-all "
40
48
initial = { { opacity : 0 , y : 40 , scale : 0.95 } }
41
49
animate = { { opacity : 1 , y : 0 , scale : 1 } }
42
50
transition = { { duration : 0.5 , type : "spring" , stiffness : 120 } }
43
51
whileHover = { {
44
52
scale : 1.03 ,
45
53
boxShadow : "0 8px 32px 0 rgba(0,0,0,0.18)" ,
46
54
} }
55
+ onClick = { onClick }
47
56
>
57
+ { /* Main event image */ }
48
58
{ event . images && event . images [ 0 ] ?. asset ?. url && (
49
59
< img
50
60
src = { event . images [ 0 ] . asset . url }
@@ -60,18 +70,56 @@ const EventCard = ({ event }: { event: EventType }) => (
60
70
< span >
61
71
{ event . date ? new Date ( event . date ) . toLocaleDateString ( ) : "" }
62
72
</ span >
63
- · < span > { event . location } </ span >
73
+ { event . location && (
74
+ < >
75
+ · < span > { event . location } </ span >
76
+ </ >
77
+ ) }
64
78
</ div >
65
- < p className = "text-gray-700 dark:text-gray-200 flex-1" >
79
+ < p className = "text-gray-700 dark:text-gray-200 flex-1 mb-2 " >
66
80
{ event . description }
67
81
</ p >
82
+ < AnimatePresence >
83
+ { expanded && event . images && event . images . length > 1 && (
84
+ < motion . div
85
+ initial = { { height : 0 , opacity : 0 } }
86
+ animate = { { height : "auto" , opacity : 1 } }
87
+ exit = { { height : 0 , opacity : 0 } }
88
+ className = "mt-4"
89
+ >
90
+ < div className = "font-semibold text-white mb-2" > Gallery:</ div >
91
+ < div className = "grid grid-cols-2 sm:grid-cols-3 gap-2" >
92
+ { event . images . slice ( 1 ) . map (
93
+ ( img , idx ) =>
94
+ img . asset ?. url && (
95
+ < img
96
+ key = { img . asset . _id || idx }
97
+ src = { img . asset . url }
98
+ alt = { `Gallery image ${ idx + 1 } ` }
99
+ className = "rounded-md border border-white/10 object-cover w-full h-28 sm:h-32"
100
+ loading = "lazy"
101
+ />
102
+ )
103
+ ) }
104
+ </ div >
105
+ </ motion . div >
106
+ ) }
107
+ </ AnimatePresence >
108
+ < div className = "mt-4 text-primary font-semibold text-center" >
109
+ { expanded
110
+ ? "Click to collapse"
111
+ : event . images && event . images . length > 1
112
+ ? "Click to view gallery"
113
+ : "" }
114
+ </ div >
68
115
</ div >
69
116
</ motion . div >
70
117
) ;
71
118
72
119
const EventsPage = ( ) => {
73
120
const [ search , setSearch ] = useState ( "" ) ;
74
121
const [ events , setEvents ] = useState < EventType [ ] > ( [ ] ) ;
122
+ const [ expandedId , setExpandedId ] = useState < string | null > ( null ) ;
75
123
76
124
useEffect ( ( ) => {
77
125
sanity . fetch ( query ) . then ( setEvents ) ;
@@ -97,7 +145,7 @@ const EventsPage = () => {
97
145
className = "text-center mb-12"
98
146
>
99
147
< h1 className = "text-4xl md:text-5xl font-extrabold text-white mb-3" >
100
- Upcoming < span className = "text-primary" > Events</ span >
148
+ Past < span className = "text-primary" > Events</ span >
101
149
</ h1 >
102
150
< p className = "text-gray-200 max-w-2xl mx-auto" >
103
151
Stay updated with our latest events, workshops, and meetups.
@@ -116,7 +164,14 @@ const EventsPage = () => {
116
164
< div className = "grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-8" >
117
165
{ filteredEvents . length > 0 ? (
118
166
filteredEvents . map ( ( event ) => (
119
- < EventCard key = { event . _id } event = { event } />
167
+ < EventCard
168
+ key = { event . _id }
169
+ event = { event }
170
+ expanded = { expandedId === event . _id }
171
+ onClick = { ( ) =>
172
+ setExpandedId ( expandedId === event . _id ? null : event . _id )
173
+ }
174
+ />
120
175
) )
121
176
) : (
122
177
< motion . div
0 commit comments