"use client" import { useEffect, useState, Suspense, useMemo } from "react" import { getApiUrl } from "@/lib/api-config" import { Loader2, Calendar } from "lucide-react" import { Skeleton } from "@/components/ui/skeleton" import { useSearchParams, useRouter, usePathname } from "next/navigation" import { Button } from "@/components/ui/button" import Link from "next/link" import { BandFilter } from "@/components/shows/band-filter" import { FeedFilter } from "@/components/shows/feed-filter" import { DateGroupedList } from "@/components/shows/date-grouped-list" interface Show { id: number slug?: string date: string youtube_link?: string vertical?: { name: string slug: string } venue: { id: number name: string city: string state: string } } function ShowsContent() { const searchParams = useSearchParams() const router = useRouter() const pathname = usePathname() // Parse query params const year = searchParams.get("year") const bandsParam = searchParams.get("bands") const tiersParam = searchParams.get("tiers") const initialBands = bandsParam ? bandsParam.split(",") : [] const initialTiers = tiersParam ? tiersParam.split(",") : [] const [shows, setShows] = useState([]) const [loading, setLoading] = useState(true) const [selectedBands, setSelectedBands] = useState(initialBands) const [selectedTiers, setSelectedTiers] = useState(initialTiers) // Update URL when filters change const updateBandFilters = (bands: string[]) => { setSelectedBands(bands) updateUrl(bands, selectedTiers) } const updateTierFilters = (tiers: string[]) => { setSelectedTiers(tiers) updateUrl(selectedBands, tiers) } const updateUrl = (bands: string[], tiers: string[]) => { const params = new URLSearchParams(searchParams.toString()) if (bands.length > 0) { params.set("bands", bands.join(",")) } else { params.delete("bands") } if (tiers.length > 0) { params.set("tiers", tiers.join(",")) } else { params.delete("tiers") } router.push(`${pathname}?${params.toString()}`) } useEffect(() => { setLoading(true) const params = new URLSearchParams() params.append("limit", "200") // Lower limit for initial partial view, or keep 2000 if needed but likely smaller is better if filtered params.append("status", "past") if (year) params.append("year", year) if (selectedBands.length > 0) { selectedBands.forEach(slug => params.append("vertical_slugs", slug)) } // If we had tiers // if (selectedTiers.length > 0) { // selectedTiers.forEach(tier => params.append("tiers", tier)) // } const url = `${getApiUrl()}/shows/?${params.toString()}` fetch(url) .then(res => res.json()) .then(data => { // Backend might not sort perfectly if multiple bands (it sorts by offset usually, or default order). // Currently backend read_shows does NO sorting (unless I missed it). // read_shows only does offset/limit. // So I should sort client side or add sort to backend. // Assuming backend returns unsorted or DB order. const sorted = data.sort((a: Show, b: Show) => new Date(b.date).getTime() - new Date(a.date).getTime() ) setShows(sorted) }) .catch(console.error) .finally(() => setLoading(false)) }, [year, selectedBands, selectedTiers]) if (loading) { return (
{Array.from({ length: 12 }).map((_, i) => ( ))}
) } return (

Shows

Browse the complete archive of performances.

) } function LoadingFallback() { return (
) } export default function ShowsPage() { return ( }> ) }