import React, { useMemo, useState } from "react"; import { View, Text, Image, ScrollView, TouchableOpacity, ActivityIndicator, } from "react-native"; import { ChevronRight } from "lucide-react-native"; import ScreenWrapper from "~/components/ui/ScreenWrapper"; import { Button } from "~/components/ui/button"; import { Input } from "~/components/ui/input"; import { Icons } from "~/assets/icons"; import TopBar from "~/components/ui/topBar"; import BottomSheet from "~/components/ui/bottomSheet"; import { router } from "expo-router"; import { ROUTES } from "~/lib/routes"; import { useTranslation } from "react-i18next"; import { useEvents } from "~/lib/hooks/useEvents"; import Skeleton from "~/components/ui/skeleton"; export default function EventsScreen() { const { t } = useTranslation(); const { data: events, loading, error, refetch, } = useEvents({ status: "ACTIVE", limit: 50, }); const [searchQuery, setSearchQuery] = useState(""); const [filterVisible, setFilterVisible] = useState(false); const [filterName, setFilterName] = useState(""); const [filterLocation, setFilterLocation] = useState(""); const [dateFilter, setDateFilter] = useState<"all" | "today" | "this_week">( "all" ); const normalizedQuery = searchQuery.trim().toLowerCase(); const normalizedFilterName = filterName.trim().toLowerCase(); const normalizedFilterLocation = filterLocation.trim().toLowerCase(); const filteredEvents = useMemo(() => { if (!events) return []; return events.filter((event) => { const name = (event as any).name ?? ""; const venue = (event as any).venue ?? ""; const haystack = `${name} ${venue}`.toLowerCase(); if (normalizedQuery && !haystack.includes(normalizedQuery)) { return false; } if ( normalizedFilterName && !name.toLowerCase().includes(normalizedFilterName) ) { return false; } if ( normalizedFilterLocation && !venue.toLowerCase().includes(normalizedFilterLocation) ) { return false; } if (dateFilter !== "all" && (event as any).startDate) { const start = new Date((event as any).startDate); const now = new Date(); const startDay = new Date( start.getFullYear(), start.getMonth(), start.getDate() ); const today = new Date( now.getFullYear(), now.getMonth(), now.getDate() ); if (dateFilter === "today") { if (startDay.getTime() !== today.getTime()) return false; } else if (dateFilter === "this_week") { const endOfWeek = new Date(today); endOfWeek.setDate(today.getDate() + 7); if (startDay < today || startDay > endOfWeek) return false; } } return true; }); }, [ events, normalizedQuery, normalizedFilterName, normalizedFilterLocation, dateFilter, ]); return ( {t("events.title")} {t("events.subtitle")} {t("events.featuredTitle")} {loading && ( {Array.from({ length: 3 }).map((_, index) => ( ))} )} {!loading && error && ( Failed to load events )} {!loading && !error && events && events.length === 0 && ( No events found. )} {!loading && !error && events && events.length > 0 && filteredEvents.length === 0 && ( No events match your search. )} {!loading && !error && filteredEvents && filteredEvents.length > 0 && ( {filteredEvents.map((event) => { const heroImage = event.images && event.images.length > 0 ? event.images[0] : "https://images.pexels.com/photos/1190297/pexels-photo-1190297.jpeg?auto=compress&cs=tinysrgb&w=800"; const startDate = new Date(event.startDate); const formattedDate = startDate.toLocaleDateString(); return ( router.push({ pathname: ROUTES.EVENT_DETAIL, params: { id: event.id }, }) } > {event.name} {event.venue} {t("events.ticketCountPrefix")} {event.organizer?.name || ""} - {formattedDate} ); })} )} setFilterVisible(false)} maxHeightRatio={0.7} > Filter events Filter by date, name and location Date {[ { key: "all", label: "All dates" }, { key: "today", label: "Today" }, { key: "this_week", label: "This week" }, ].map((option) => ( setDateFilter(option.key as "all" | "today" | "this_week") } className={`px-3 py-1 rounded-full mr-2 border ${ dateFilter === option.key ? "bg-[#0F7B4A] border-[#0F7B4A]" : "bg-white border-gray-300" }`} > {option.label} ))} Event name Location { setFilterName(""); setFilterLocation(""); setDateFilter("all"); }} > Clear ); }