import { Metadata } from "next" import { notFound } from "next/navigation" import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs" import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card" import { Badge } from "@/components/ui/badge" import { Separator } from "@/components/ui/separator" import Link from "next/link" import { Music, Calendar, MapPin, Users, ExternalLink, Globe } from "lucide-react" interface BandPageProps { params: Promise<{ slug: string }> } async function getBand(slug: string) { const res = await fetch(`${process.env.INTERNAL_API_URL}/bands/${slug}`, { next: { revalidate: 60 }, }) if (!res.ok) { if (res.status === 404) return null throw new Error("Failed to fetch band") } return res.json() } export async function generateMetadata({ params }: BandPageProps): Promise { const { slug } = await params const data = await getBand(slug) if (!data) return { title: "Band Not Found" } return { title: `${data.band.name} | Fediversion`, description: data.band.description || `Band profile for ${data.band.name} on Fediversion.`, } } export default async function BandPage({ params }: BandPageProps) { const { slug } = await params const data = await getBand(slug) if (!data) return notFound() const { band, current_members, past_members, stats } = data // Format origin location const originParts = [band.origin_city, band.origin_state, band.origin_country].filter(Boolean) const originLocation = originParts.join(", ") return (
{/* Header */}
{band.logo_url ? ( {band.name} ) : (
{band.name[0]}
)}

{band.name}

{originLocation && ( {originLocation} )} {band.formed_year && ( Formed {band.formed_year} )}
{band.description && (

{band.long_description || band.description}

)} {/* External Links */}
{band.website_url && ( Website )} {band.nugs_url && ( Nugs.net )} {band.relisten_url && ( Relisten )} {band.spotify_url && ( Spotify )} {band.wikipedia_url && ( Wikipedia )}
{/* Stats Grid */}
{stats.total_shows.toLocaleString()}
Shows
{stats.total_songs.toLocaleString()}
Songs
{stats.total_venues.toLocaleString()}
Venues
{stats.first_show && stats.last_show ? new Date(stats.last_show).getFullYear() - new Date(stats.first_show).getFullYear() + 1 : '—' }
Active Years
{/* Members Section */} {(current_members.length > 0 || past_members.length > 0) && ( <>

Members

Current {current_members.length} Past {past_members.length}
{current_members.map((member: any) => ( {member.image_url ? ( {member.name} ) : (
{member.name[0]}
)}
{member.name}
{member.role || member.primary_instrument}
{member.start_date && (
Since {new Date(member.start_date).getFullYear()}
)}
))} {current_members.length === 0 && (
No current members listed.
)}
{past_members.map((member: any) => ( {member.image_url ? ( {member.name} ) : (
{member.name[0]}
)}
{member.name}
{member.role || member.primary_instrument}
{(member.start_date || member.end_date) && (
{member.start_date ? new Date(member.start_date).getFullYear() : '?'} {' - '} {member.end_date ? new Date(member.end_date).getFullYear() : '?'}
)}
))} {past_members.length === 0 && (
No past members listed.
)}
)} {/* Quick Links */}
All Shows All Songs All Venues Top Performances
) }