@@ -5,6 +5,20 @@ import Footer from "../Footer/page";
55import { motion , AnimatePresence } from "framer-motion" ;
66import { sanity } from "@/lib/sanity" ; // adjust path as needed
77
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+
822// GROQ query for your event schema
923const query = `*[_type == "event"]{
1024 _id,
@@ -20,7 +34,7 @@ const query = `*[_type == "event"]{
2034 }
2135}` ;
2236
23- const EventCard = ( { event } : { event : any } ) => (
37+ const EventCard = ( { event } : { event : EventType } ) => (
2438 < motion . div
2539 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"
2640 initial = { { opacity : 0 , y : 40 , scale : 0.95 } }
@@ -56,69 +70,69 @@ const EventCard = ({ event }: { event: any }) => (
5670) ;
5771
5872const EventsPage = ( ) => {
59- const [ search , setSearch ] = useState ( "" ) ;
60- const [ events , setEvents ] = useState < any [ ] > ( [ ] ) ;
73+ const [ search , setSearch ] = useState ( "" ) ;
74+ const [ events , setEvents ] = useState < EventType [ ] > ( [ ] ) ;
6175
62- useEffect ( ( ) => {
63- sanity . fetch ( query ) . then ( setEvents ) ;
64- } , [ ] ) ;
76+ useEffect ( ( ) => {
77+ sanity . fetch ( query ) . then ( setEvents ) ;
78+ } , [ ] ) ;
6579
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+ } ) ;
7488
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+ ) ;
122136} ;
123137
124138export default EventsPage ;
0 commit comments