import { Button } from "@/components/ui/button" import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card" import { ArrowLeft, Calendar, MapPin, ChevronRight, ChevronLeft, Music, Clock, Hash, Play, ExternalLink, Sparkles } from "lucide-react" import Link from "next/link" import { notFound } from "next/navigation" import { getApiUrl } from "@/lib/api-config" import { CommentSection } from "@/components/social/comment-section" import { EntityReviews } from "@/components/reviews/entity-reviews" import { SocialWrapper } from "@/components/social/social-wrapper" import { EntityRating } from "@/components/social/entity-rating" import { Badge } from "@/components/ui/badge" async function getPerformance(id: string) { try { const res = await fetch(`${getApiUrl()}/performances/${id}`, { cache: 'no-store' }) if (!res.ok) return null return res.json() } catch (e) { console.error(e) return null } } export default async function PerformanceDetailPage({ params }: { params: Promise<{ id: string }> }) { const { id } = await params const performance = await getPerformance(id) if (!performance) { notFound() } const showDate = new Date(performance.show.date) const formattedDate = showDate.toLocaleDateString("en-US", { weekday: "long", year: "numeric", month: "long", day: "numeric" }) return (
{/* Hero Banner - Distinct from Song page */}
{/* Breadcrumbs */}
{/* Context Badge */}
Specific Performance {performance.set_name && ( {performance.set_name} )} {performance.position && ( #{performance.position} )}
{/* Song Title (links to song page) */}

{performance.song.title}

{/* Nicknames */} {performance.nicknames && performance.nicknames.length > 0 && (
{performance.nicknames.map((nick: any) => ( "{nick.nickname}" ))}
)} {/* Show Context - THE KEY DIFFERENTIATOR */}
{formattedDate} {performance.show.venue && ( {performance.show.venue.name}, {performance.show.venue.city} {performance.show.venue.state && `, ${performance.show.venue.state}`} )}
{/* Rating Box */}
Rate This Version
{/* Version Navigation - Prominent */} Version Timeline
{performance.previous_performance_id ? ( ) : (
🎉 Debut Performance
)}
#{performance.times_played || "?"}
of all time
{performance.next_performance_id ? ( ) : (
Most Recent 🕐
)}
{/* Notes & Details */} {(performance.notes || performance.segue || performance.track_url) && ( About This Performance {performance.notes && (

Notes

{performance.notes}

)} {performance.segue && (
Segues into next song →
)} {performance.track_url && ( Listen to this performance )}
)} {/* Comments */} {/* Reviews */}
{/* Sidebar */}
{/* Quick Stats */} Performance Stats
Set Position {performance.set_name || "—"} #{performance.position || "—"}
Gap Since Last {performance.gap !== undefined ? `${performance.gap} shows` : "—"}
Times Played {performance.times_played || "—"}
{/* Top Rated Versions */} {performance.other_performances && performance.other_performances.length > 0 && ( Top Rated Versions {performance.other_performances.slice(0, 5).map((perf: any) => (
{new Date(perf.show_date).toLocaleDateString()} {perf.venue_name}
{perf.avg_rating > 0 && (
{perf.avg_rating.toFixed(1)}
)} ))} View all {performance.other_performances.length + 1} versions →
)} {/* Quick Links */} Related Pages All versions of {performance.song.title} Full show setlist {performance.show.venue && ( {performance.show.venue.name} )}
) }