feat(21-02): add skeleton loading states to initiative detail page

Replace plain "Loading initiative..." and "Loading phases..." text with
structured skeleton placeholders matching the page layout: header with
back arrow/title/badge, two-column grid with phase accordions and
sidebar panels.
This commit is contained in:
Lukas May
2026-02-05 09:01:22 +01:00
parent 1e1aadaece
commit a6c2864b74

View File

@@ -2,6 +2,7 @@ import { useState, useCallback } from "react";
import { createFileRoute, useNavigate } from "@tanstack/react-router"; import { createFileRoute, useNavigate } from "@tanstack/react-router";
import { AlertCircle } from "lucide-react"; import { AlertCircle } from "lucide-react";
import { Button } from "@/components/ui/button"; import { Button } from "@/components/ui/button";
import { Skeleton } from "@/components/Skeleton";
import { trpc } from "@/lib/trpc"; import { trpc } from "@/lib/trpc";
import { InitiativeHeader } from "@/components/InitiativeHeader"; import { InitiativeHeader } from "@/components/InitiativeHeader";
import { ProgressPanel } from "@/components/ProgressPanel"; import { ProgressPanel } from "@/components/ProgressPanel";
@@ -313,8 +314,28 @@ function InitiativeDetailPage() {
// Loading state // Loading state
if (initiativeQuery.isLoading) { if (initiativeQuery.isLoading) {
return ( return (
<div className="flex items-center justify-center py-12 text-muted-foreground"> <div className="space-y-6">
Loading initiative... {/* Header skeleton */}
<div className="flex items-center gap-4">
<Skeleton className="h-4 w-4" />
<Skeleton className="h-7 w-64" />
<Skeleton className="h-5 w-20" />
</div>
{/* Two-column grid skeleton */}
<div className="grid grid-cols-1 gap-6 lg:grid-cols-[1fr_340px]">
{/* Left: phase accordion skeletons */}
<div className="space-y-1">
<Skeleton className="h-12 w-full rounded border" />
<Skeleton className="h-12 w-full rounded border" />
</div>
{/* Right: ProgressPanel + DecisionList skeletons */}
<div className="space-y-6">
<Skeleton className="h-24 w-full rounded" />
<Skeleton className="h-20 w-full rounded" />
</div>
</div>
</div> </div>
); );
} }
@@ -381,8 +402,10 @@ function InitiativeDetailPage() {
{/* Phase loading */} {/* Phase loading */}
{phasesQuery.isLoading && ( {phasesQuery.isLoading && (
<div className="py-8 text-center text-muted-foreground"> <div className="space-y-1 pt-3">
Loading phases... {Array.from({ length: 3 }).map((_, i) => (
<Skeleton key={i} className="h-10 w-full" />
))}
</div> </div>
)} )}