# shadcn/ui Dashboard Components Guide This guide provides examples of using shadcn/ui components to build modern dashboard interfaces for your TaylorDB applications. --- ## 📦 Installation ### Install Individual Components ```bash # Core components (already included) pnpm dlx shadcn@latest add button card input label textarea select tabs alert # Dashboard-specific components pnpm dlx shadcn@latest add table dialog dropdown-menu toast sheet form badge avatar skeleton # Data display components pnpm dlx shadcn@latest add separator progress scroll-area tooltip # Advanced components pnpm dlx shadcn@latest add command popover calendar date-picker ``` --- ## 🎨 Common Dashboard Patterns ### 1. Dashboard Layout with Stats Cards ```typescript import { Card, CardContent, CardDescription, CardHeader, CardTitle, } from "@/components/ui/card"; export default function DashboardPage() { return (

Dashboard

Total Users
1,234

+20% from last month

Revenue
$45,231

+12% from last month

{/* More stats cards... */}
); } ``` ### 2. Data Table with Actions ```typescript import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow, } from "@/components/ui/table"; import { Button } from "@/components/ui/button"; import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger, } from "@/components/ui/dropdown-menu"; import { MoreHorizontal, Pencil, Trash } from "lucide-react"; export default function UsersTable({ users }: { users: User[] }) { return ( Users Manage your user accounts Name Email Status Actions {users.map((user) => ( {user.name} {user.email} {user.status} Edit Delete ))}
); } ``` ### 3. Create/Edit Form in Dialog ```typescript import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, DialogTrigger, } from "@/components/ui/dialog"; import { Button } from "@/components/ui/button"; import { Input } from "@/components/ui/input"; import { Label } from "@/components/ui/label"; import { useState } from "react"; import { PlusIcon } from "lucide-react"; export default function CreateUserDialog() { const [open, setOpen] = useState(false); const [name, setName] = useState(""); const [email, setEmail] = useState(""); const createMutation = trpc.users.create.useMutation({ onSuccess: () => { setOpen(false); setName(""); setEmail(""); }, }); return ( Create New User Add a new user to your database
setName(e.target.value)} placeholder="John Doe" />
setEmail(e.target.value)} placeholder="john@example.com" />
); } ``` ### 4. Loading States with Skeleton ```typescript import { Skeleton } from "@/components/ui/skeleton"; import { Card, CardContent, CardHeader } from "@/components/ui/card"; export default function DashboardSkeleton() { return (
{[...Array(4)].map((_, i) => ( ))}
); } // Usage in main component export default function DashboardPage() { const { data: stats, isLoading } = trpc.dashboard.getStats.useQuery(); if (isLoading) { return ; } return
{/* Actual dashboard */}
; } ``` ### 5. Tabs for Different Views ```typescript import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs"; export default function DataExplorer() { return ( Data Explorer Overview Analytics Reports {/* Overview content */} {/* Analytics content */} {/* Reports content */} ); } ``` ### 6. Status Badges ```typescript import { Badge } from "@/components/ui/badge"; function StatusBadge({ status }: { status: string }) { const variants = { active: "default", pending: "secondary", inactive: "outline", error: "destructive", } as const; return ( {status} ); } // Usage ; ``` ### 7. Toast Notifications ```typescript import { useToast } from "@/hooks/use-toast"; import { Button } from "@/components/ui/button"; export default function ActionsPage() { const { toast } = useToast(); const deleteMutation = trpc.items.delete.useMutation({ onSuccess: () => { toast({ title: "Success!", description: "Item deleted successfully", }); }, onError: (error) => { toast({ title: "Error", description: error.message, variant: "destructive", }); }, }); return ( ); } // Don't forget to add in your App.tsx or layout ``` ### 8. Form with Validation ```typescript import { useForm } from "react-hook-form"; import { zodResolver } from "@hookform/resolvers/zod"; import { z } from "zod"; import { Form, FormControl, FormDescription, FormField, FormItem, FormLabel, FormMessage, } from "@/components/ui/form"; import { Input } from "@/components/ui/input"; import { Button } from "@/components/ui/button"; const formSchema = z.object({ name: z.string().min(2, "Name must be at least 2 characters"), email: z.string().email("Invalid email address"), age: z.number().min(0).max(120), }); export default function UserForm() { const form = useForm({ resolver: zodResolver(formSchema), defaultValues: { name: "", email: "", age: 0, }, }); const createMutation = trpc.users.create.useMutation({ onSuccess: () => { form.reset(); }, }); const onSubmit = (data: z.infer) => { createMutation.mutate(data); }; return (
( Name Your full name as it appears on documents. )} /> ( Email )} /> ); } ``` ### 9. Side Sheet for Details ```typescript import { Sheet, SheetContent, SheetDescription, SheetHeader, SheetTitle, SheetTrigger, } from "@/components/ui/sheet"; import { Button } from "@/components/ui/button"; export default function UserDetailsSheet({ userId }: { userId: number }) { const { data: user } = trpc.users.getById.useQuery({ id: userId }); return ( User Details Information about this user {user && (

Name

{user.name}

Email

{user.email}

{/* More fields... */}
)}
); } ``` ### 10. Command Palette (Search) ```typescript import { Command, CommandDialog, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList, } from "@/components/ui/command"; import { useState, useEffect } from "react"; export default function GlobalSearch() { const [open, setOpen] = useState(false); useEffect(() => { const down = (e: KeyboardEvent) => { if (e.key === "k" && (e.metaKey || e.ctrlKey)) { e.preventDefault(); setOpen((open) => !open); } }; document.addEventListener("keydown", down); return () => document.removeEventListener("keydown", down); }, []); return ( No results found. John Doe Jane Smith Project Alpha Project Beta ); } ``` --- ## 🎨 Design Tips ### Color Schemes Use semantic color tokens: - `bg-background` / `text-foreground` - Main background and text - `bg-card` / `text-card-foreground` - Card surfaces - `bg-primary` / `text-primary-foreground` - Primary actions - `bg-destructive` - Destructive actions (delete, etc.) - `bg-muted` / `text-muted-foreground` - Subtle UI elements ### Spacing Use consistent spacing: - `space-y-4` / `gap-4` - Between related items - `space-y-6` / `gap-6` - Between sections - `p-4` / `p-6` - Card padding - `p-8` - Page padding ### Icons Use `lucide-react` for consistent icons: ```typescript import { Home, Users, Settings, Plus, Edit, Trash, Search } from "lucide-react"; ; ``` --- ## 📱 Responsive Design ### Grid Layouts ```typescript // 1 column on mobile, 2 on tablet, 4 on desktop
{/* cards */}
// 1 column on mobile, 3 on desktop
{/* cards */}
``` ### Hide on Mobile ```typescript // Hide text on mobile, show on desktop Dashboard // Different layout on mobile
{/* content */}
``` --- ## 🚀 Performance Tips 1. **Lazy load dialogs**: Only render dialog content when open 2. **Virtualize long lists**: Use libraries like `react-window` 3. **Skeleton loaders**: Always show loading states 4. **Optimistic updates**: Update UI before server confirms 5. **Debounce search**: Don't query on every keystroke --- ## 📚 Resources - **shadcn/ui**: https://ui.shadcn.com/ - **Tailwind CSS**: https://tailwindcss.com/ - **Lucide Icons**: https://lucide.dev/ - **React Hook Form**: https://react-hook-form.com/ --- **Remember**: Always test your components in both light and dark mode, and on different screen sizes!