import { useQuery } from "@tanstack/react-query"; import { MoreHorizontal, Plus, Search } from "lucide-react"; import { Tldraw } from "tldraw"; import { Badge } from "@/components/ui/badge"; import { Button } from "@/components/ui/button"; import { Card, CardContent, CardFooter, CardHeader, } from "@/components/ui/card"; import { Input } from "@/components/ui/input"; import { listUserSpaceSnapshots } from "@/lib/appwrite-db"; import { authClient } from "@/lib/auth-client"; type SpaceCard = { id: string; name: string; lastEdited: string; snapshotText: string; itemCount: number; color: string; }; export function SpacesGrid() { const { data: session } = authClient.useSession(); const spacesQuery = useQuery({ queryKey: ["spaces", session?.$id], queryFn: async () => { if (!session?.$id) { return [] as SpaceCard[]; } const rows = await listUserSpaceSnapshots(session.$id); return rows.map(({ row, snapshot }, idx) => { const snapshotText = snapshot ? JSON.stringify(snapshot) : (row.snapshot ?? ""); const itemCount = (() => { try { const doc = snapshot?.document as unknown as | { store?: { records?: Record }; records?: Record; } | undefined; const recs = doc?.store?.records ?? doc?.records; return recs ? Object.keys(recs).length : 0; } catch { return 0; } })(); const COLORS = [ "bg-blue-500", "bg-green-500", "bg-purple-500", "bg-orange-500", "bg-pink-500", "bg-cyan-500", ] as const; return { id: row.spaceId, name: row.spaceId, lastEdited: row.$updatedAt ? new Date(row.$updatedAt).toLocaleString() : "", snapshotText, itemCount, // keep some color variety color: COLORS[idx % COLORS.length], } satisfies SpaceCard; }); }, staleTime: 10_000, }); const spaces = spacesQuery.data ?? []; return (
{/* Header */}

Your Spaces

Organize your thoughts and ideas in visual workspaces

{/* Search and Filters */}
{spacesQuery.isLoading ? "Loading…" : `${spaces.length} spaces`}
{/* Spaces Grid */}
{spaces.map((space) => (

{space.name}

{space.itemCount} items Edited {space.lastEdited} ))}
{/* Empty State (when no spaces exist) */} {!spacesQuery.isLoading && spaces.length === 0 && (

No spaces yet

Create your first space to start organizing your thoughts and ideas visually.

)}
); }