From 03c06be7dd56ffdad5e5bb1f2000fec141894fc0 Mon Sep 17 00:00:00 2001 From: Akshay Date: Fri, 11 Jul 2025 15:52:49 +0530 Subject: [PATCH] Add event page --- app/events/[id]/page.tsx | 509 ++++++++ app/events/page.tsx | 1160 ++++++++++++----- app/globals.css | 10 +- components/data/events.ts | 197 +++ components/tabs-demo.tsx | 76 ++ components/ui/tabs.tsx | 131 ++ package-lock.json | 6 + package.json | 1 + public/images/events/hackathons/coderush.jpeg | Bin 0 -> 66474 bytes .../images/events/hackathons/realitycode.jpeg | Bin 0 -> 37042 bytes 10 files changed, 1775 insertions(+), 315 deletions(-) create mode 100644 app/events/[id]/page.tsx create mode 100644 components/data/events.ts create mode 100644 components/tabs-demo.tsx create mode 100644 components/ui/tabs.tsx create mode 100644 public/images/events/hackathons/coderush.jpeg create mode 100644 public/images/events/hackathons/realitycode.jpeg diff --git a/app/events/[id]/page.tsx b/app/events/[id]/page.tsx new file mode 100644 index 00000000..2c5bd30a --- /dev/null +++ b/app/events/[id]/page.tsx @@ -0,0 +1,509 @@ +"use client" + +import { useState, useEffect } from "react" +import { useParams } from "next/navigation" +import { createClient } from "@/lib/supabase/client" +import { Button } from "@/components/ui/button" +import { Badge } from "@/components/ui/badge" +import { ArrowLeft, Clock, Calendar, Users, DollarSign, Star, Sparkles} from "lucide-react" +import Link from "next/link" +import { motion } from "framer-motion" +import { Event, mockEvents } from "@/components/data/events" +import Image from "next/image"; +import { Tabs as AnimatedTabs } from "@/components/ui/tabs"; +import React from "react"; + +// import Header from "@/components/header"; +import Footer from "@/components/footer"; + +// Add a rotating sponsors grid component above the Rules section in renderAbout: + +interface Sponsor { + name: string; + logo: string; + type: string; +} + +const RotatingSponsorsGrid = ({ sponsors }: { sponsors?: Sponsor[] }) => { + if (!sponsors || sponsors.length === 0) return null; + const shouldAnimate = sponsors.length > 4; + // Duplicate sponsors for infinite scroll + const displaySponsors = shouldAnimate ? [...sponsors, ...sponsors] : sponsors; + + return ( +
+

+ + Our Sponsors +

+
+
+ {displaySponsors.map((sponsor, idx) => ( + +
+ {sponsor.name} +
+
+

{sponsor.name}

+

{sponsor.type}

+
+
+ ))} +
+
+
+ ); +}; + +export default function EventDetailPage() { + const [isAuthenticated, setIsAuthenticated] = useState(false) + const [isLoading, setIsLoading] = useState(true) + const [event, setEvent] = useState(null) + const [fetchError, setFetchError] = useState(null) + const params = useParams() + + const slug = params?.id as string + + useEffect(() => { + const checkAuth = async () => { + const supabase = createClient() + const { data: { user } } = await supabase.auth.getUser() + setIsAuthenticated(!!user) + } + checkAuth() + }, []) + + useEffect(() => { + const fetchEvent = async () => { + setIsLoading(true) + setFetchError(null) + + // For now, using mock data since events table doesn't exist yet + // In a real app, this would fetch from Supabase + try { + // Simulate API delay + await new Promise(resolve => setTimeout(resolve, 1000)) + const foundEvent = mockEvents.find(e => e.slug === slug) + if (foundEvent) { + setEvent(foundEvent) + } else { + setFetchError('Event not found.') + setEvent(null) + } + } catch { + setFetchError('Failed to fetch event.') + setEvent(null) + } + setIsLoading(false) + } + if (slug) fetchEvent() + }, [slug]) + + const getCategoryColor = (category: string) => { + switch (category) { + case "Hackathons": + return "bg-gradient-to-r from-blue-500 to-indigo-600 text-white" + case "Workshops": + return "bg-gradient-to-r from-emerald-500 to-teal-600 text-white" + case "Conferences": + return "bg-gradient-to-r from-purple-500 to-violet-600 text-white" + case "Webinars": + return "bg-gradient-to-r from-red-500 to-pink-600 text-white" + case "Career Fairs": + return "bg-gradient-to-r from-orange-500 to-amber-600 text-white" + case "Tech Talks": + return "bg-gradient-to-r from-yellow-500 to-orange-500 text-white" + case "Coding Competitions": + return "bg-gradient-to-r from-cyan-500 to-blue-500 text-white" + case "Project Showcases": + return "bg-gradient-to-r from-pink-500 to-rose-500 text-white" + case "Mentorship Programs": + return "bg-gradient-to-r from-green-500 to-emerald-500 text-white" + default: + return "bg-gradient-to-r from-gray-500 to-slate-600 text-white" + } + } + + const getStatusColor = (status: string) => { + switch (status) { + case "upcoming": + return "bg-gradient-to-r from-green-500 to-emerald-600 text-white" + case "ongoing": + return "bg-gradient-to-r from-blue-500 to-cyan-600 text-white" + case "completed": + return "bg-gradient-to-r from-gray-500 to-slate-600 text-white" + case "cancelled": + return "bg-gradient-to-r from-red-500 to-pink-600 text-white" + default: + return "bg-gradient-to-r from-gray-500 to-slate-600 text-white" + } + } + + // --- Tab Content Renderers --- + const renderAbout = () => ( +
+
+

+ + About the Event +

+

{event?.description}

+
+ {event?.tags.map((tag: string) => ( + + #{tag} + + ))} +
+
+ {/* Sponsors Grid */} + +
+ ) + + const renderRules = () => ( +
+ {event?.rules && ( +
+

Rules

+
    + {event.rules.map((rule: string) =>
  • {rule}
  • )} +
+
+ )} +
+ ) + + const renderSchedule = () => ( +
+
+

+ + Event Schedule +

+
    + {event?.schedule?.map((item: { date: string, label: string }) => ( +
  • + {item.date} + {item.label} +
  • + ))} +
+
+
+ ) + + const renderPrizes = () => ( +
+
+

+ + Prizes +

+
{event?.prize}
+

{event?.prize_details || 'Exciting rewards, sponsor goodies, and recognition.'}

+
+
+ ) + + const renderFAQ = () => ( +
+
+

+ + Frequently Asked Questions +

+
    + {event?.faq?.map((q: { question: string, answer: string }) => ( +
  • +
    {q.question}
    +
    {q.answer}
    +
  • + ))} +
+
+
+ ) + + const eventTabs = [ + { + title: "About", + value: "about", + content: ( +
{renderAbout()}
+ ), + }, + { + title: "Schedule", + value: "schedule", + content: renderSchedule(), + }, + { + title: "Rules", + value: "rules", + content: renderRules(), + }, + { + title: "Prizes", + value: "prizes", + content: renderPrizes(), + }, + { + title: "FAQ", + value: "faq", + content: renderFAQ(), + }, + ]; + + if (isLoading) { + return ( +
+
+
+
+
+
+ ) + } + + if (fetchError) { + return ( +
+ +
+ +
+
+

{fetchError}

+ +
+
+ ) + } + + return ( +
{/* Ensures footer stays at the bottom */} + {/*
*/} + {/* Back to Events - full width, above banner */} +
+
+ +
+
+ {/* Event Banner - full width, edge-to-edge */} +
+
+ {event?.image ? ( + {event.title + ) : ( +
+ +
+ )} +
+
+ {/* Main Content - centered, white background, margin-top */} +
{/* Ensures main content grows to fill space */} +
{/* Inner wrapper for centering and padding */} +
+
+ {/* Main Content with Tabs */} +
+ {/* Event Header */} +
+

{event?.title}

+ {event?.organizer && ( +
by {event.organizer}
+ )} +

{event?.excerpt}

+
+ {event?.category} + {event?.featured && (Featured)} + {event?.status} +
+
+ {/* Registration Card (mobile only) */} + {event?.registration_required && event?.status === 'live' && ( +
+
+
Registration
+
+ + {event?.registered ?? 0} participants registered +
+
+ + Registration deadline + {event?.registration_deadline ? new Date(event.registration_deadline).toLocaleDateString() : '-'} +
+ {/* Social Icons Row */} + {event?.socials && ( +
+ {event.socials.whatsapp && ( + + + + )} + {event.socials.instagram && ( + + + + )} + {event.socials.linkedin && ( + + + + )} +
+ )} + {isAuthenticated ? ( + + ) : ( + + )} +
+
+ )} + {/* Tabs */} +
+ +
+
+ {/* Sidebar (Event Details, Registration, Need Help) */} +
+ {/* Registration Card (desktop only) */} + {event?.registration_required && event?.status === 'live' && ( +
+
+
Registration
+
+ + {event?.registered ?? 0} participants registered +
+
+ + Registration deadline + {event?.registration_deadline ? new Date(event.registration_deadline).toLocaleDateString() : '-'} +
+ {/* Social Icons Row */} + {event?.socials && ( +
+ {event.socials.whatsapp && ( + + + + )} + {event.socials.instagram && ( + + + + )} + {event.socials.linkedin && ( + + + + )} +
+ )} + {isAuthenticated ? ( + + ) : ( + + )} +
+
+ )} + {/* Event Details Card */} +
+
Event Details
+
+ Event Type + {event?.eventType?.join(', ') || '-'} +
+
+ Team Size + {event?.teamSize ? (Array.isArray(event.teamSize) ? `${event.teamSize[0]}-${event.teamSize[1]}` : event.teamSize) : '-'} +
+
+ Date + {event?.date ? new Date(event.date).toLocaleDateString() : '-'} +
+
+ Location + {event?.location || '-'} +
+
+ Prize Pool + {event?.prize || event?.price || '-'} +
+
+ Skill Level + Open to All Skill Levels +
+
+ {/* Need Help Card (optional) */} +
+
Need Help?
+
Have questions about this event? Contact the organizers or check the FAQ section.
+ + +
+
+
+
+
+
+
+
+ ) +} diff --git a/app/events/page.tsx b/app/events/page.tsx index 67d53449..10048625 100644 --- a/app/events/page.tsx +++ b/app/events/page.tsx @@ -1,358 +1,902 @@ -"use client" +"use client" + +import { useState, useEffect, useRef } from "react" -import Footer from "@/components/footer"; -import Header from "@/components/header"; -import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card" import { Button } from "@/components/ui/button" +import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card" import { Badge } from "@/components/ui/badge" -import { cn } from "@/lib/utils" -import { - Calendar, - MapPin, - Clock, - Users, - Trophy, - ArrowRight, - Sparkles, - Code, -} from "lucide-react" -import { motion } from "framer-motion" -import { SparklesCore } from "@/components/ui/sparkles" +import { Input } from "@/components/ui/input" +import { Search, Clock, ArrowRight, Calendar, Star, Users, MapPin, DollarSign, Filter, Link as LinkIcon, Sparkles } from "lucide-react" import Link from "next/link" +import { motion } from "framer-motion" +import { mockEvents, Event } from "@/components/data/events" +import Header from "@/components/header"; +import Footer from "@/components/footer"; +import Image from "next/image"; +import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogClose } from "@/components/ui/dialog" +import { Checkbox } from "@/components/ui/checkbox" +import "keen-slider/keen-slider.min.css" +import { useKeenSlider } from "keen-slider/react" +import { cn } from "@/lib/utils"; + +// Event categories for dropdown +const eventCategories = [ + "All", + "Hackathons", + "Workshops", + "Conferences", + "Webinars", + "Mentorship Programs", + "Career Fairs", + "Tech Talks", + "Coding Competitions", + "Project Showcases" +]; export default function EventsPage() { + const [searchTerm, setSearchTerm] = useState("") + const [isLoading, setIsLoading] = useState(true) + const [events, setEvents] = useState([]) + const [dateFilter] = useState("Upcoming") + const [filterOpen, setFilterOpen] = useState(false) + const [selectedStatuses, setSelectedStatuses] = useState([]) + const [selectedLocations, setSelectedLocations] = useState([]) + const [selectedEventTypes, setSelectedEventTypes] = useState([]) + const [selectedTeamSizes, setSelectedTeamSizes] = useState([]) + const [selectedPayments, setSelectedPayments] = useState([]) + const [selectedUserTypes, setSelectedUserTypes] = useState([]) + const [selectedCategories, setSelectedCategories] = useState([]) + const [selectedCategory, setSelectedCategory] = useState("All") + const [copiedEventId, setCopiedEventId] = useState(null) + + // Unique values for filters + const allStatuses = ["Live", "Expired", "Closed", "Recent"] + const allLocations = Array.from(new Set(events.flatMap(e => e.locations))).sort() + const allEventTypes = ["Online", "Offline"] + const allTeamSizes = ["1", "2", "2+", "3+", "4+", "5+"] + const allPayments = ["Paid", "Free"] + const allUserTypes = ["Professionals", "Startups", "School Students", "College Students", "Fresher", "MBA Students"] + const allCategories = Array.from(new Set(events.flatMap(e => e.categories))).sort() + + const filteredEvents = events.filter((event) => { + const matchesSearch = + event.title.toLowerCase().includes(searchTerm.toLowerCase()) || + event.excerpt.toLowerCase().includes(searchTerm.toLowerCase()) || + event.tags.some((tag: string) => tag.toLowerCase().includes(searchTerm.toLowerCase())) + + // Multi-select filters: if none selected, always match + const matchesStatus = selectedStatuses.length === 0 || selectedStatuses.includes(capitalize(event.status)) + const matchesLocation = selectedLocations.length === 0 || event.locations.some(loc => selectedLocations.includes(loc)) + const matchesEventType = selectedEventTypes.length === 0 || event.eventType.some(type => selectedEventTypes.includes(type)) + const matchesTeamSize = selectedTeamSizes.length === 0 || selectedTeamSizes.some(size => { + if (typeof event.teamSize === 'number') return size === String(event.teamSize) + if (Array.isArray(event.teamSize)) { + if (size.endsWith('+')) return event.teamSize[1] >= parseInt(size) + return event.teamSize[0] <= parseInt(size) && event.teamSize[1] >= parseInt(size) + } + return false + }) + const matchesPayment = selectedPayments.length === 0 || selectedPayments.includes(event.payment) + const matchesUserType = selectedUserTypes.length === 0 || event.userTypes.some(u => selectedUserTypes.includes(u)) + const matchesCategory = selectedCategories.length === 0 || event.categories.some(cat => selectedCategories.includes(cat)) + const matchesDate = isDateMatch(event) + const matchesDropdownCategory = selectedCategory === "All" || event.category === selectedCategory + + return matchesSearch && matchesStatus && matchesLocation && matchesEventType && matchesTeamSize && matchesPayment && matchesUserType && matchesCategory && matchesDate && matchesDropdownCategory + }) + + const featuredEvents = filteredEvents.filter((event) => event.featured) + const regularEvents = filteredEvents.filter((event) => !event.featured) + + // Add keen-slider hook for featured events with autoplay and navigation + const realSliderRef = useRef(null) + const sliderTimer = useRef(null) + const [sliderRef, slider] = useKeenSlider({ + slides: { perView: 1.2, spacing: 24 }, + breakpoints: { + "(min-width: 640px)": { slides: { perView: 1.5, spacing: 24 } }, + "(min-width: 1024px)": { slides: { perView: 2.2, spacing: 32 } }, + }, + loop: featuredEvents.length > 1, + }) + + // Autoplay effect + useEffect(() => { + if (!slider) return + if (featuredEvents.length > 1) { + const autoplay = () => { + slider.current?.next() + } + sliderTimer.current = setInterval(autoplay, 3500) + // Pause on hover + const sliderEl = realSliderRef.current + if (sliderEl) { + const pause = () => sliderTimer.current && clearInterval(sliderTimer.current) + const resume = () => { sliderTimer.current = setInterval(autoplay, 3500) } + sliderEl.addEventListener("mouseenter", pause) + sliderEl.addEventListener("mouseleave", resume) + return () => { + sliderEl.removeEventListener("mouseenter", pause) + sliderEl.removeEventListener("mouseleave", resume) + } + } + return () => { + if (sliderTimer.current) clearInterval(sliderTimer.current) + } + } else { + // If less than 2, clear any existing interval + if (sliderTimer.current) clearInterval(sliderTimer.current) + } + }, [slider, featuredEvents.length]) + + useEffect(() => { + const fetchEvents = async () => { + setIsLoading(true) + + // For now, using mock data since events table doesn't exist yet + // In a real app, this would fetch from Supabase + try { + // Simulate API delay + await new Promise(resolve => setTimeout(resolve, 1000)) + setEvents(mockEvents) + } catch { + setEvents([]) + } + setIsLoading(false) + } + fetchEvents() + }, []) + + // Date filter logic + function isDateMatch(event: Event) { + const today = new Date(); + const eventDate = new Date(event.date); + if (dateFilter === "All") return true; + if (dateFilter === "Today") { + return eventDate.toDateString() === today.toDateString(); + } + if (dateFilter === "This Week") { + const weekStart = new Date(today); + weekStart.setDate(today.getDate() - today.getDay()); + const weekEnd = new Date(weekStart); + weekEnd.setDate(weekStart.getDate() + 6); + return eventDate >= weekStart && eventDate <= weekEnd; + } + // Default: Upcoming + return eventDate >= today; + } + + const getCategoryColor = (category: string) => { + switch (category) { + case "Hackathons": + return "bg-gradient-to-r from-blue-500 to-indigo-600 text-white" + case "Workshops": + return "bg-gradient-to-r from-emerald-500 to-teal-600 text-white" + case "Conferences": + return "bg-gradient-to-r from-purple-500 to-violet-600 text-white" + case "Webinars": + return "bg-gradient-to-r from-red-500 to-pink-600 text-white" + case "Career Fairs": + return "bg-gradient-to-r from-orange-500 to-amber-600 text-white" + case "Tech Talks": + return "bg-gradient-to-r from-yellow-500 to-orange-500 text-white" + case "Coding Competitions": + return "bg-gradient-to-r from-cyan-500 to-blue-500 text-white" + case "Project Showcases": + return "bg-gradient-to-r from-pink-500 to-rose-500 text-white" + case "Mentorship Programs": + return "bg-gradient-to-r from-green-500 to-emerald-500 text-white" + default: + return "bg-gradient-to-r from-gray-500 to-slate-600 text-white" + } + } + + const getStatusColor = (status: string) => { + switch (status) { + case "upcoming": + return "bg-gradient-to-r from-green-500 to-emerald-600 text-white" + case "ongoing": + return "bg-gradient-to-r from-blue-500 to-cyan-600 text-white" + case "completed": + return "bg-gradient-to-r from-gray-500 to-slate-600 text-white" + case "cancelled": + return "bg-gradient-to-r from-red-500 to-pink-600 text-white" + default: + return "bg-gradient-to-r from-gray-500 to-slate-600 text-white" + } + } + + function capitalize(str: string) { + return str.charAt(0).toUpperCase() + str.slice(1) + } + + // Helper to copy event link + const handleCopyLink = (slug: string, id: string) => { + const url = `${window.location.origin}/events/${slug}` + navigator.clipboard.writeText(url) + setCopiedEventId(id) + setTimeout(() => setCopiedEventId(null), 1500) + } + + if (isLoading) { + return ( +
+
+
+
+
+
+ ) + } + return ( -
-
+
+
- {/* hero section */} + {/* Hero Section */}
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+ + +
+ +
+ +
+
+ + Discover, Participate{" "} + + Grow + + + + Find your next hackathon, workshop, or tech event. Unlock new skills, connect with peers, and win exciting prizes! + +
+
+
+ + {/* Search and Filters - Redesigned */} +
+
+
+ {/* Search Bar */} +
+ + setSearchTerm(e.target.value)} + className="pl-10 pr-4 h-12 shadow-lg border-2 focus:border-primary/50 transition-all duration-300 bg-background/80 backdrop-blur-sm rounded-xl" + /> +
+ {/* Filters Button */} + +
- -
- + + +
+ + {/* Active Filter Chips */} +
+ {selectedStatuses.map(status => ( + + {status} + + + ))} + {selectedLocations.map(loc => ( + + {loc} + + + ))} + {selectedEventTypes.map(type => ( + + {type} + + + ))} + {selectedTeamSizes.map(size => ( + + {size} + + + ))} + {selectedPayments.map(pay => ( + + {pay} + + + ))} + {selectedUserTypes.map(user => ( + + {user} + + + ))} + {selectedCategories.map(cat => ( + + {cat} + + + ))} + {(selectedStatuses.length || selectedLocations.length || selectedEventTypes.length || selectedTeamSizes.length || selectedPayments.length || selectedUserTypes.length || selectedCategories.length) > 0 && ( + + )} +
+ + {/* Filter Modal/Sidebar */} + + +
+ + Filters + + {/* Status */} +
+
Status
+
+ {allStatuses.map(status => ( + + ))} +
+
+ {/* Location */} +
+
Location
+
+ {allLocations.map(loc => ( + + ))} +
+
+ {/* Event Type */} +
+
Event Type
+
+ {allEventTypes.map(type => ( + + ))} +
+
+ {/* Team Size */} +
+
Team Size
+
+ {allTeamSizes.map(size => ( + + ))}
- - +
+ {/* Payment */} +
+
Payment
+
+ {allPayments.map(pay => ( + + ))} +
+
+ {/* User Type */} +
+
User Type
+
+ {allUserTypes.map(user => ( + + ))} +
+
+ {/* Category */} +
+
Category
+
+ {allCategories.map(cat => ( + + ))} +
+
+ + +
-
- + +
+
+ + {/* Featured Events - Redesigned */} + {featuredEvents.length > 0 && ( +
+
+ - Join Our{" "} - + + Featured Events +
+

+ Don't Miss These Highlights +

+ + + {/* Carousel Navigation Arrows - Responsive for mobile */} + {/* Desktop: floating side arrows; Mobile: centered below slider */} +
+
- -
+ + + +
+ {/* Mobile: arrows below slider, centered */} +
+ + +
- {/* events section */} -
-
-
- { + realSliderRef.current = node; + sliderRef(node); + }} + className="keen-slider" > - -
- -
-
-
- -
-
- RealityCode by Codeunia -
- - - Hackathon - - - - ₹6,00,000 Prize Pool - + {(featuredEvents.length > 2 ? [...featuredEvents, ...featuredEvents] : featuredEvents).map((event, index) => ( + + +
+ {/* Event Image */} +
+ {event.image ? ( + {event.title + ) : ( +
+
-
+ )} + {/* Overlay Badges removed from here */}
-
- - -
-
-
-
- -
-
-

Location

-

Chandigarh University, Mohali, Punjab, India

+ +
+ + {event.title} + +
+ + {copiedEventId === String (event.id) && ( + Link copied! + )}
-
-
- -
-
-

Date

-

August 16-17, 2025

-
+ {/* Overlay Badges moved below title */} +
+ + {event.category} + + + + Featured + + + {event.status} +
-
-
- + + {event.excerpt} + + + + {/* Event Meta */} +
+
+ + + {new Date(event.date).toLocaleDateString('en-US', { month: 'short', day: 'numeric' })} + + + + {event.duration} + + + + {event.location} +
-
-

Duration

-

24 Hours

+
+ {/* Registration Info */} +
+
+
+ + {event.registered}/{event.capacity} +
+
+ + {event.price} +
+
+ + + + ))} +
+
+
+ )} + + {/* All Events - Redesigned */} +
+
+ +
+
+ + All Events +
+

+ Browse All Events +

+
+
+ {regularEvents.length} events found +
+
+ + {/* Events Grid */} +
+ {regularEvents.map((event, index) => ( + + + {/* Event Image/Logo */} +
+ {event.image ? ( + {event.title + ) : ( +
+ +
+ )} + {/* Event Type Badge */} +
+ + {event.category} +
-
-
-
- -
-
-

Expected Participants

-

500+ Developers

-
+ {/* Status Badge */} +
+ + {event.status} + +
+
+ {/* Card Content */} +
+ {/* Title and Organizer */} +
+
+ {event.organizer + .split(" ") + .map((n) => n[0]) + .join("")}
-
-
- -
-
-

Prize Pool

-

₹6,00,000

+
+
+
+ {event.title} +
+
+ + {copiedEventId === String(event.id) && ( + Link copied! + )} +
+
{event.organizer}
-
-
- -
-
-

Updated On

-

June 15, 2025

-
+
+ {/* Description/Excerpt */} +
{event.excerpt}
+ {/* Meta Row */} +
+
+ + {new Date(event.date).toLocaleDateString('en-US', { month: 'short', day: 'numeric' })} +
+
+ + {event.time} +
+
+ + {event.location} +
+
+ + {event.registered}/{event.capacity}
-
- -
-

- RealityCode is a 24-hour hackathon focused on AI and machine learning projects. - Build innovative solutions and compete for exciting prizes while networking with - fellow developers and industry experts. -

-
+ {/* Registration Deadline */} +
+ + Reg. Deadline: {new Date(event.registration_deadline).toLocaleDateString()} +
+ {/* Tags */} +
+ {event.tags.slice(0, 2).map((tag) => ( + + {tag} + + ))} +
+ {/* Action Button */} +
-
- - - + + + ))}
-
-
- - {/* cta Section */} -
-
-
-
-
- -
- -
- -
-
- -
- - More{" "} - - Events Coming Soon - - -

- Follow us on social media to stay updated with our latest events, workshops, and hackathons. -

-
- +
+
+ +
+

No events found

+

+ Try adjusting your search terms or browse different categories. +

-
-
-
+ + )} +
- -