@@ -5,6 +5,20 @@ import Footer from "../Footer/page";
5
5
import { motion , AnimatePresence } from "framer-motion" ;
6
6
import { sanity } from "@/lib/sanity" ; // adjust path as needed
7
7
8
+ interface EventType {
9
+ _id : string ;
10
+ title : string ;
11
+ date ?: string ;
12
+ location ?: string ;
13
+ description ?: string ;
14
+ images ?: {
15
+ asset ?: {
16
+ _id : string ;
17
+ url : string ;
18
+ } ;
19
+ } [ ] ;
20
+ }
21
+
8
22
// GROQ query for your event schema
9
23
const query = `*[_type == "event"]{
10
24
_id,
@@ -20,7 +34,7 @@ const query = `*[_type == "event"]{
20
34
}
21
35
}` ;
22
36
23
- const EventCard = ( { event } : { event : any } ) => (
37
+ const EventCard = ( { event } : { event : EventType } ) => (
24
38
< motion . div
25
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"
26
40
initial = { { opacity : 0 , y : 40 , scale : 0.95 } }
@@ -56,69 +70,69 @@ const EventCard = ({ event }: { event: any }) => (
56
70
) ;
57
71
58
72
const EventsPage = ( ) => {
59
- const [ search , setSearch ] = useState ( "" ) ;
60
- const [ events , setEvents ] = useState < any [ ] > ( [ ] ) ;
73
+ const [ search , setSearch ] = useState ( "" ) ;
74
+ const [ events , setEvents ] = useState < EventType [ ] > ( [ ] ) ;
61
75
62
- useEffect ( ( ) => {
63
- sanity . fetch ( query ) . then ( setEvents ) ;
64
- } , [ ] ) ;
76
+ useEffect ( ( ) => {
77
+ sanity . fetch ( query ) . then ( setEvents ) ;
78
+ } , [ ] ) ;
65
79
66
- const filteredEvents = events . filter ( ( event ) => {
67
- const searchText = search . toLowerCase ( ) ;
68
- return (
69
- event . title ?. toLowerCase ( ) . includes ( searchText ) ||
70
- event . description ?. toLowerCase ( ) . includes ( searchText ) ||
71
- event . location ?. toLowerCase ( ) . includes ( searchText )
72
- ) ;
73
- } ) ;
80
+ const filteredEvents = events . filter ( ( event ) => {
81
+ const searchText = search . toLowerCase ( ) ;
82
+ return (
83
+ event . title ?. toLowerCase ( ) . includes ( searchText ) ||
84
+ event . description ?. toLowerCase ( ) . includes ( searchText ) ||
85
+ event . location ?. toLowerCase ( ) . includes ( searchText )
86
+ ) ;
87
+ } ) ;
74
88
75
- return (
76
- < div className = "flex flex-col min-h-screen bg-black" >
77
- < NavBar />
78
- < main className = "flex-1 container mx-auto px-4 py-24" >
79
- < motion . div
80
- initial = { { opacity : 0 , y : 30 } }
81
- animate = { { opacity : 1 , y : 0 } }
82
- transition = { { duration : 0.7 } }
83
- className = "text-center mb-12"
84
- >
85
- < h1 className = "text-4xl md:text-5xl font-extrabold text-white mb-3" >
86
- Upcoming < span className = "text-primary" > Events</ span >
87
- </ h1 >
88
- < p className = "text-gray-200 max-w-2xl mx-auto" >
89
- Stay updated with our latest events, workshops, and meetups.
90
- </ p >
91
- </ motion . div >
92
- < div className = "flex justify-center mb-10" >
93
- < input
94
- type = "text"
95
- placeholder = "Search events..."
96
- value = { search }
97
- onChange = { ( e ) => setSearch ( e . target . value ) }
98
- className = "w-full max-w-md px-4 py-2 rounded-lg border border-gray-300 focus:outline-none focus:ring-2 focus:ring-primary text-black"
99
- />
100
- </ div >
101
- < AnimatePresence >
102
- < div className = "grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-8" >
103
- { filteredEvents . length > 0 ? (
104
- filteredEvents . map ( ( event ) => (
105
- < EventCard key = { event . _id } event = { event } />
106
- ) )
107
- ) : (
108
- < motion . div
109
- className = "col-span-full text-center text-gray-400 py-20"
110
- initial = { { opacity : 0 } }
111
- animate = { { opacity : 1 } }
112
- >
113
- No events found.
114
- </ motion . div >
115
- ) }
116
- </ div >
117
- </ AnimatePresence >
118
- </ main >
119
- < Footer />
120
- </ div >
121
- ) ;
89
+ return (
90
+ < div className = "flex flex-col min-h-screen bg-black" >
91
+ < NavBar />
92
+ < main className = "flex-1 container mx-auto px-4 py-24" >
93
+ < motion . div
94
+ initial = { { opacity : 0 , y : 30 } }
95
+ animate = { { opacity : 1 , y : 0 } }
96
+ transition = { { duration : 0.7 } }
97
+ className = "text-center mb-12"
98
+ >
99
+ < h1 className = "text-4xl md:text-5xl font-extrabold text-white mb-3" >
100
+ Upcoming < span className = "text-primary" > Events</ span >
101
+ </ h1 >
102
+ < p className = "text-gray-200 max-w-2xl mx-auto" >
103
+ Stay updated with our latest events, workshops, and meetups.
104
+ </ p >
105
+ </ motion . div >
106
+ < div className = "flex justify-center mb-10" >
107
+ < input
108
+ type = "text"
109
+ placeholder = "Search events..."
110
+ value = { search }
111
+ onChange = { ( e ) => setSearch ( e . target . value ) }
112
+ className = "w-full max-w-md px-4 py-2 rounded-lg border border-gray-300 focus:outline-none focus:ring-2 focus:ring-primary text-black"
113
+ />
114
+ </ div >
115
+ < AnimatePresence >
116
+ < div className = "grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-8" >
117
+ { filteredEvents . length > 0 ? (
118
+ filteredEvents . map ( ( event ) => (
119
+ < EventCard key = { event . _id } event = { event } />
120
+ ) )
121
+ ) : (
122
+ < motion . div
123
+ className = "col-span-full text-center text-gray-400 py-20"
124
+ initial = { { opacity : 0 } }
125
+ animate = { { opacity : 1 } }
126
+ >
127
+ No events found.
128
+ </ motion . div >
129
+ ) }
130
+ </ div >
131
+ </ AnimatePresence >
132
+ </ main >
133
+ < Footer />
134
+ </ div >
135
+ ) ;
122
136
} ;
123
137
124
138
export default EventsPage ;
0 commit comments