fediversion/frontend/components/shows/band-grid.tsx
fullsizemalt c860075681
Some checks failed
Deploy Fediversion / deploy (push) Failing after 1s
feat(shows): redesign global shows hub
- Frontend: Implemented Tabbed interface (Recent, My Feed, Upcoming, By Band)
- Frontend: Added BandGrid component with selection logic
- Frontend: Added FilterPills component for active filters
- Backend: Added show_count to Verticals API
- Backend: Updated read_shows to support correct sorting for Upcoming status
2025-12-30 20:18:10 -08:00

66 lines
2.7 KiB
TypeScript

"use client"
import { Card, CardContent } from "@/components/ui/card"
import { Music2, Check } from "lucide-react"
import { Badge } from "@/components/ui/badge"
interface Vertical {
id: number
slug: string
name: string
show_count: number
logo_url?: string | null
}
interface BandGridProps {
verticals: Vertical[]
selectedBands: string[]
onToggle: (slug: string) => void
}
export function BandGrid({ verticals, selectedBands, onToggle }: BandGridProps) {
return (
<div className="grid grid-cols-2 md:grid-cols-3 lg:grid-cols-4 gap-4">
{verticals.map((v) => {
const isSelected = selectedBands.includes(v.slug)
return (
<Card
key={v.id}
className={`cursor-pointer transition-all hover:shadow-md ${isSelected ? "border-primary bg-primary/5 ring-1 ring-primary" : "hover:border-primary/50"
}`}
onClick={() => onToggle(v.slug)}
>
<CardContent className="flex flex-col items-center justify-center p-6 text-center gap-3 relative">
{isSelected && (
<div className="absolute top-2 right-2">
<Badge variant="default" className="h-5 w-5 p-0 flex items-center justify-center rounded-full">
<Check className="h-3 w-3" />
</Badge>
</div>
)}
<div className="h-16 w-16 rounded-full bg-muted flex items-center justify-center overflow-hidden shadow-sm border border-border">
{v.logo_url ? (
<img
src={v.logo_url}
alt={v.name}
className="h-full w-full object-cover"
/>
) : (
<Music2 className="h-8 w-8 text-muted-foreground/50" />
)}
</div>
<div className="space-y-1">
<h3 className="font-semibold leading-tight">{v.name}</h3>
<p className="text-xs text-muted-foreground font-medium">
{v.show_count.toLocaleString()} shows
</p>
</div>
</CardContent>
</Card>
)
})}
</div>
)
}