Component properties
Props interface for DashboardLayout component
Optional
isLoading?: booleanOptional boolean that controls the display of skeleton loading states. When true, placeholder skeletons appear instead of content panels.
Optional
statisticsSummary?: ReactNodeOptional React node for statistics summary content. Displays key metrics and overall usage data.
Optional
recentTracks?: ReactNodeOptional React node for recently skipped tracks listing. Shows chronological list of songs the user has skipped.
Optional
artistSummary?: ReactNodeOptional React node for artist analytics content. Displays statistics grouped by artist/creator.
Optional
sessionOverview?: ReactNodeOptional React node for listening session information. Shows detailed data about user listening patterns.
Dashboard layout with responsive arrangement of statistics panels
export function DashboardLayout({
isLoading = false,
statisticsSummary,
recentTracks,
artistSummary,
sessionOverview,
}: DashboardLayoutProps) {
return (
<div className="container mx-auto">
{/* Desktop layout - Grid system */}
<div className="hidden md:grid md:grid-cols-12 md:gap-4">
{/* Top row - Statistics Summary (spans full width) */}
<div className="col-span-12 mb-4">
{isLoading ? (
<div className="space-y-4">
<Skeleton className="h-6 w-2/3" />
<Skeleton className="h-20 w-full" />
</div>
) : (
statisticsSummary || (
<div className="text-muted-foreground flex h-48 items-center justify-center">
Statistics summary will be displayed here
</div>
)
)}
</div>
{/* Middle row - Recent Tracks (spans full width) */}
<div className="col-span-12 mb-4">
{isLoading ? (
<div className="space-y-4">
<Skeleton className="h-6 w-1/3" />
<Skeleton className="h-12 w-full" />
<Skeleton className="h-12 w-full" />
<Skeleton className="h-12 w-full" />
</div>
) : (
recentTracks || (
<div className="text-muted-foreground flex h-48 items-center justify-center">
Recent skipped tracks will be displayed here
</div>
)
)}
</div>
{/* Bottom row - Artist Summary (spans 6 columns) and Session Overview (spans 6 columns) */}
<div className="col-span-6 mb-4">
{isLoading ? (
<div className="space-y-4">
<Skeleton className="h-6 w-1/3" />
<Skeleton className="h-12 w-full" />
<Skeleton className="h-12 w-full" />
</div>
) : (
artistSummary || (
<div className="text-muted-foreground flex h-48 items-center justify-center">
Artist summary will be displayed here
</div>
)
)}
</div>
<div className="col-span-6 mb-4">
{isLoading ? (
<div className="space-y-4">
<Skeleton className="h-6 w-1/3" />
<Skeleton className="h-12 w-full" />
<Skeleton className="h-12 w-full" />
</div>
) : (
sessionOverview || (
<div className="text-muted-foreground flex h-48 items-center justify-center">
Session overview will be displayed here
</div>
)
)}
</div>
</div>
{/* Mobile layout - Tabbed interface */}
<div className="md:hidden">
<Tabs defaultValue="overview" className="w-full">
<TabsList className="grid w-full grid-cols-4">
<TabsTrigger
value="overview"
className="flex flex-col items-center justify-center text-xs"
>
<BarChart2 className="mb-1 h-4 w-4" />
<span>Overview</span>
</TabsTrigger>
<TabsTrigger
value="tracks"
className="flex flex-col items-center justify-center text-xs"
>
<ListMusic className="mb-1 h-4 w-4" />
<span>Tracks</span>
</TabsTrigger>
<TabsTrigger
value="artists"
className="flex flex-col items-center justify-center text-xs"
>
<Users className="mb-1 h-4 w-4" />
<span>Artists</span>
</TabsTrigger>
<TabsTrigger
value="sessions"
className="flex flex-col items-center justify-center text-xs"
>
<Clock className="mb-1 h-4 w-4" />
<span>Sessions</span>
</TabsTrigger>
</TabsList>
<TabsContent value="overview" className="mt-4">
{isLoading ? (
<div className="space-y-4">
<Skeleton className="h-6 w-2/3" />
<Skeleton className="h-20 w-full" />
</div>
) : (
statisticsSummary || (
<div className="text-muted-foreground flex h-48 items-center justify-center">
Statistics summary will be displayed here
</div>
)
)}
</TabsContent>
<TabsContent value="tracks" className="mt-4">
{isLoading ? (
<div className="space-y-4">
<Skeleton className="h-6 w-1/3" />
<Skeleton className="h-12 w-full" />
<Skeleton className="h-12 w-full" />
<Skeleton className="h-12 w-full" />
</div>
) : (
recentTracks || (
<div className="text-muted-foreground flex h-48 items-center justify-center">
Recent skipped tracks will be displayed here
</div>
)
)}
</TabsContent>
<TabsContent value="artists" className="mt-4">
{isLoading ? (
<div className="space-y-4">
<Skeleton className="h-6 w-1/3" />
<Skeleton className="h-12 w-full" />
<Skeleton className="h-12 w-full" />
</div>
) : (
artistSummary || (
<div className="text-muted-foreground flex h-48 items-center justify-center">
Artist summary will be displayed here
</div>
)
)}
</TabsContent>
<TabsContent value="sessions" className="mt-4">
{isLoading ? (
<div className="space-y-4">
<Skeleton className="h-6 w-1/3" />
<Skeleton className="h-12 w-full" />
<Skeleton className="h-12 w-full" />
</div>
) : (
sessionOverview || (
<div className="text-muted-foreground flex h-48 items-center justify-center">
Session overview will be displayed here
</div>
)
)}
</TabsContent>
</Tabs>
</div>
</div>
);
}
Dashboard layout component for data visualization
Creates a responsive layout system for displaying Spotify listening statistics and skipped track analytics. Adapts between grid layout (desktop) and tab-based navigation (mobile) based on viewport size.