diff --git a/frontend/app/shows/[id]/page.tsx b/frontend/app/shows/[id]/page.tsx index c50576d..e26b05e 100644 --- a/frontend/app/shows/[id]/page.tsx +++ b/frontend/app/shows/[id]/page.tsx @@ -1,6 +1,7 @@ + import { Button } from "@/components/ui/button" import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card" -import { ArrowLeft, Calendar, MapPin, Music2 } from "lucide-react" +import { ArrowLeft, Calendar, MapPin, Music2, Disc, PlayCircle, ExternalLink } from "lucide-react" import Link from "next/link" import { CommentSection } from "@/components/social/comment-section" import { EntityRating } from "@/components/social/entity-rating" @@ -24,6 +25,7 @@ async function getShow(id: string) { } } + export default async function ShowDetailPage({ params }: { params: Promise<{ id: string }> }) { const { id } = await params const show = await getShow(id) @@ -32,6 +34,35 @@ export default async function ShowDetailPage({ params }: { params: Promise<{ id: notFound() } + // Group by set + const sets: Record = {}; + if (show.performances) { + show.performances.forEach((perf: any) => { + const setName = perf.set_name || "Set 1"; // Default to Set 1 if missing + if (!sets[setName]) sets[setName] = []; + sets[setName].push(perf); + }); + } + + // Sort keys: Set 1, Set 2, Set 3, Encore, Encore 2... + const sortedKeys = Object.keys(sets).sort((a, b) => { + const aLower = a.toLowerCase(); + const bLower = b.toLowerCase(); + + // Encore always last + if (aLower.includes("encore") && !bLower.includes("encore")) return 1; + if (!aLower.includes("encore") && bLower.includes("encore")) return -1; + + // If both have Set, compare numbers + if (aLower.includes("set") && bLower.includes("set")) { + const aNum = parseInt(a.replace(/\D/g, "") || "0"); + const bNum = parseInt(b.replace(/\D/g, "") || "0"); + return aNum - bNum; + } + + return a.localeCompare(b); + }); + return (
@@ -59,12 +90,36 @@ export default async function ShowDetailPage({ params }: { params: Promise<{ id: ))}
)} - {show.tour && ( -

- - {show.tour.name} -

- )} +
+ {show.tour && ( +

+ + {show.tour.name} +

+ )} + + {/* Audio Links */} + {(show.bandcamp_link || show.nugs_link) && ( +
+ {show.bandcamp_link && ( + + + + )} + {show.nugs_link && ( + + + + )} +
+ )} +
@@ -89,45 +144,66 @@ export default async function ShowDetailPage({ params }: { params: Promise<{ id: {show.performances && show.performances.length > 0 ? ( -
- {show.performances.map((perf: any) => ( -
-
- {perf.position}. -
- {perf.song?.title || "Unknown Song"} - {perf.segue && >} -
+
+ {sortedKeys.map((setName) => ( +
+

+ {setName} +

+
+ {sets[setName].map((perf: any) => ( +
+
+
+ {perf.position}. +
+ {perf.track_url ? ( + + + {perf.song?.title || "Unknown Song"} + + ) : ( + {perf.song?.title || "Unknown Song"} + )} + {perf.segue && >} +
- {/* Nicknames */} - {perf.nicknames && perf.nicknames.length > 0 && ( -
- {perf.nicknames.map((nick: any) => ( - - "{nick.nickname}" - - ))} + {/* Nicknames */} + {perf.nicknames && perf.nicknames.length > 0 && ( +
+ {perf.nicknames.map((nick: any) => ( + + "{nick.nickname}" + + ))} +
+ )} + + {/* Suggest Nickname Button */} +
+ +
+
+ + {/* Rating Column */} + + + +
+ {perf.notes && ( +
+ {perf.notes} +
+ )}
- )} - - {/* Suggest Nickname Button */} -
- -
-
- - {/* Rating Column */} -
- - - + ))}
))}