From 11fa5f4be9c9f90a82ec7143ead851006b574d38 Mon Sep 17 00:00:00 2001 From: Lukas May Date: Thu, 5 Feb 2026 08:56:35 +0100 Subject: [PATCH] feat(21-02): add Skeleton component and skeleton loading states for dashboard + inbox Create reusable Skeleton component with animate-pulse styling. Replace plain "Loading..." text with structured skeleton placeholders matching card layouts in InitiativeList and inbox page. --- .../web/src/components/InitiativeList.tsx | 17 ++++++++-- packages/web/src/components/Skeleton.tsx | 11 +++++++ packages/web/src/routes/inbox.tsx | 32 +++++++++++++++++-- 3 files changed, 55 insertions(+), 5 deletions(-) create mode 100644 packages/web/src/components/Skeleton.tsx diff --git a/packages/web/src/components/InitiativeList.tsx b/packages/web/src/components/InitiativeList.tsx index e54ec5d..e458456 100644 --- a/packages/web/src/components/InitiativeList.tsx +++ b/packages/web/src/components/InitiativeList.tsx @@ -1,5 +1,7 @@ import { AlertCircle, Plus } from "lucide-react"; import { Button } from "@/components/ui/button"; +import { Card } from "@/components/ui/card"; +import { Skeleton } from "@/components/Skeleton"; import { InitiativeCard } from "@/components/InitiativeCard"; import { trpc } from "@/lib/trpc"; @@ -28,8 +30,19 @@ export function InitiativeList({ // Loading state if (initiativesQuery.isLoading) { return ( -
- Loading initiatives... +
+ {Array.from({ length: 3 }).map((_, i) => ( + +
+ +
+ + + +
+
+
+ ))}
); } diff --git a/packages/web/src/components/Skeleton.tsx b/packages/web/src/components/Skeleton.tsx new file mode 100644 index 0000000..0f690cb --- /dev/null +++ b/packages/web/src/components/Skeleton.tsx @@ -0,0 +1,11 @@ +import { cn } from "@/lib/utils"; + +interface SkeletonProps { + className?: string; +} + +export function Skeleton({ className }: SkeletonProps) { + return ( +
+ ); +} diff --git a/packages/web/src/routes/inbox.tsx b/packages/web/src/routes/inbox.tsx index 3615381..eadf8a8 100644 --- a/packages/web/src/routes/inbox.tsx +++ b/packages/web/src/routes/inbox.tsx @@ -1,7 +1,9 @@ import { useState } from "react"; -import { createFileRoute } from "@tanstack/react-router"; +import { createFileRoute, Link } from "@tanstack/react-router"; import { AlertCircle } from "lucide-react"; import { Button } from "@/components/ui/button"; +import { Card } from "@/components/ui/card"; +import { Skeleton } from "@/components/Skeleton"; import { trpc } from "@/lib/trpc"; import { InboxList } from "@/components/InboxList"; import { QuestionForm } from "@/components/QuestionForm"; @@ -89,8 +91,32 @@ function InboxPage() { // Loading state if (agentsQuery.isLoading && messagesQuery.isLoading) { return ( -
- Loading inbox... +
+ {/* Skeleton header */} +
+
+ + +
+ +
+ {/* Skeleton message rows */} +
+ {Array.from({ length: 4 }).map((_, i) => ( + +
+
+
+ + +
+ +
+ +
+
+ ))} +
); }