From 8a521d307ca0a269924305de3d7e761f23144838 Mon Sep 17 00:00:00 2001 From: fullsizemalt <106900403+fullsizemalt@users.noreply.github.com> Date: Thu, 25 Dec 2025 21:58:03 -0800 Subject: [PATCH] Add loading skeletons for shows and songs pages --- frontend/app/shows/[slug]/loading.tsx | 57 ++++++++++++++++ frontend/app/shows/loading.tsx | 23 +++++++ frontend/app/songs/loading.tsx | 19 ++++++ frontend/components/ui/skeleton.tsx | 94 +++++++++++++++++++++++++-- 4 files changed, 187 insertions(+), 6 deletions(-) create mode 100644 frontend/app/shows/[slug]/loading.tsx create mode 100644 frontend/app/shows/loading.tsx create mode 100644 frontend/app/songs/loading.tsx diff --git a/frontend/app/shows/[slug]/loading.tsx b/frontend/app/shows/[slug]/loading.tsx new file mode 100644 index 0000000..8570fca --- /dev/null +++ b/frontend/app/shows/[slug]/loading.tsx @@ -0,0 +1,57 @@ +import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card" +import { Skeleton, SetlistSkeleton } from "@/components/ui/skeleton" + +export default function ShowLoading() { + return ( +
+ {/* Header */} +
+
+ +
+ + +
+
+
+ +
+
+ {/* Setlist Card */} + + + + + + + + + + +
+ + {/* Sidebar */} +
+ + + + + + + + + + + + + + + + + + +
+
+
+ ) +} diff --git a/frontend/app/shows/loading.tsx b/frontend/app/shows/loading.tsx new file mode 100644 index 0000000..0a09d0b --- /dev/null +++ b/frontend/app/shows/loading.tsx @@ -0,0 +1,23 @@ +import { Skeleton, ShowCardSkeleton, PageHeaderSkeleton } from "@/components/ui/skeleton" + +export default function ShowsLoading() { + return ( +
+ + + {/* Filters skeleton */} +
+ + + +
+ + {/* Shows grid */} +
+ {Array.from({ length: 12 }).map((_, i) => ( + + ))} +
+
+ ) +} diff --git a/frontend/app/songs/loading.tsx b/frontend/app/songs/loading.tsx new file mode 100644 index 0000000..9e0bfeb --- /dev/null +++ b/frontend/app/songs/loading.tsx @@ -0,0 +1,19 @@ +import { Skeleton, SongCardSkeleton, PageHeaderSkeleton } from "@/components/ui/skeleton" + +export default function SongsLoading() { + return ( +
+ + + {/* Search skeleton */} + + + {/* Songs grid */} +
+ {Array.from({ length: 16 }).map((_, i) => ( + + ))} +
+
+ ) +} diff --git a/frontend/components/ui/skeleton.tsx b/frontend/components/ui/skeleton.tsx index cbb1704..8811e0f 100644 --- a/frontend/components/ui/skeleton.tsx +++ b/frontend/components/ui/skeleton.tsx @@ -1,15 +1,97 @@ +"use client" + import { cn } from "@/lib/utils" -function Skeleton({ - className, - ...props -}: React.HTMLAttributes) { +interface SkeletonProps extends React.HTMLAttributes { } + +export function Skeleton({ className, ...props }: SkeletonProps) { return (
) } -export { Skeleton } +// Preset skeleton layouts for common patterns +export function ShowCardSkeleton() { + return ( +
+ + +
+ + +
+
+ ) +} + +export function SongCardSkeleton() { + return ( +
+ + +
+ ) +} + +export function SetlistSkeleton() { + return ( +
+ {/* Set 1 */} +
+ + {Array.from({ length: 8 }).map((_, i) => ( +
+ + +
+ ))} +
+ {/* Set 2 */} +
+ + {Array.from({ length: 6 }).map((_, i) => ( +
+ + +
+ ))} +
+
+ ) +} + +export function TableSkeleton({ rows = 5, cols = 4 }: { rows?: number; cols?: number }) { + return ( +
+ {/* Header */} +
+ {Array.from({ length: cols }).map((_, i) => ( + + ))} +
+ {/* Rows */} + {Array.from({ length: rows }).map((_, i) => ( +
+ {Array.from({ length: cols }).map((_, j) => ( + + ))} +
+ ))} +
+ ) +} + +export function PageHeaderSkeleton() { + return ( +
+ + +
+ ) +}