@getjack/jack 0.1.32 → 0.1.34

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (196) hide show
  1. package/package.json +1 -1
  2. package/src/commands/deploys.ts +95 -0
  3. package/src/commands/link.ts +8 -0
  4. package/src/commands/mcp.ts +179 -4
  5. package/src/commands/rollback.ts +53 -0
  6. package/src/commands/secrets.ts +3 -1
  7. package/src/commands/services.ts +11 -1
  8. package/src/commands/ship.ts +3 -1
  9. package/src/commands/tokens.ts +16 -1
  10. package/src/commands/whoami.ts +43 -8
  11. package/src/index.ts +16 -0
  12. package/src/lib/agent-files.ts +54 -4
  13. package/src/lib/agent-integration.ts +4 -166
  14. package/src/lib/claude-hooks-installer.ts +55 -0
  15. package/src/lib/control-plane.ts +78 -40
  16. package/src/lib/crypto.ts +84 -0
  17. package/src/lib/debug.ts +2 -1
  18. package/src/lib/deploy-upload.ts +13 -3
  19. package/src/lib/hooks.ts +4 -3
  20. package/src/lib/managed-deploy.ts +12 -9
  21. package/src/lib/project-link.ts +6 -0
  22. package/src/lib/project-operations.ts +92 -30
  23. package/src/lib/prompts.ts +2 -2
  24. package/src/lib/telemetry.ts +2 -0
  25. package/src/mcp/README.md +1 -1
  26. package/src/mcp/resources/index.ts +1 -16
  27. package/src/mcp/server.ts +23 -0
  28. package/src/mcp/tools/index.ts +133 -17
  29. package/src/mcp/types.ts +1 -0
  30. package/src/mcp/utils.ts +2 -1
  31. package/src/templates/index.ts +25 -73
  32. package/templates/CLAUDE.md +62 -0
  33. package/templates/ai-chat/.jack.json +10 -5
  34. package/templates/ai-chat/bun.lock +50 -1
  35. package/templates/ai-chat/package.json +5 -0
  36. package/templates/ai-chat/public/app.js +73 -0
  37. package/templates/ai-chat/public/index.html +14 -197
  38. package/templates/ai-chat/schema.sql +14 -0
  39. package/templates/ai-chat/src/index.ts +86 -102
  40. package/templates/ai-chat/wrangler.jsonc +8 -1
  41. package/templates/cron/.jack.json +66 -0
  42. package/templates/cron/bun.lock +23 -0
  43. package/templates/cron/package.json +16 -0
  44. package/templates/cron/schema.sql +24 -0
  45. package/templates/cron/src/index.ts +117 -0
  46. package/templates/cron/src/jobs.ts +139 -0
  47. package/templates/cron/src/webhooks.ts +95 -0
  48. package/templates/cron/tsconfig.json +17 -0
  49. package/templates/cron/wrangler.jsonc +11 -0
  50. package/templates/miniapp/.jack.json +1 -1
  51. package/templates/nextjs/.jack.json +1 -1
  52. package/templates/nextjs-auth/.jack.json +44 -0
  53. package/templates/nextjs-auth/app/api/auth/[...all]/route.ts +11 -0
  54. package/templates/nextjs-auth/app/dashboard/loading.tsx +53 -0
  55. package/templates/nextjs-auth/app/dashboard/page.tsx +73 -0
  56. package/templates/nextjs-auth/app/error.tsx +44 -0
  57. package/templates/nextjs-auth/app/globals.css +1 -0
  58. package/templates/nextjs-auth/app/health/route.ts +3 -0
  59. package/templates/nextjs-auth/app/layout.tsx +24 -0
  60. package/templates/nextjs-auth/app/login/page.tsx +10 -0
  61. package/templates/nextjs-auth/app/page.tsx +86 -0
  62. package/templates/nextjs-auth/app/signup/page.tsx +10 -0
  63. package/templates/nextjs-auth/bun.lock +1065 -0
  64. package/templates/nextjs-auth/cloudflare-env.d.ts +8 -0
  65. package/templates/nextjs-auth/components/auth-form.tsx +191 -0
  66. package/templates/nextjs-auth/components/header.tsx +50 -0
  67. package/templates/nextjs-auth/components/user-menu.tsx +23 -0
  68. package/templates/nextjs-auth/lib/auth-client.ts +3 -0
  69. package/templates/nextjs-auth/lib/auth.ts +43 -0
  70. package/templates/nextjs-auth/lib/utils.ts +6 -0
  71. package/templates/nextjs-auth/middleware.ts +33 -0
  72. package/templates/nextjs-auth/next.config.ts +8 -0
  73. package/templates/nextjs-auth/open-next.config.ts +6 -0
  74. package/templates/nextjs-auth/package.json +33 -0
  75. package/templates/nextjs-auth/postcss.config.mjs +8 -0
  76. package/templates/nextjs-auth/schema.sql +49 -0
  77. package/templates/nextjs-auth/tsconfig.json +28 -0
  78. package/templates/nextjs-auth/wrangler.jsonc +23 -0
  79. package/templates/nextjs-clerk/.jack.json +54 -0
  80. package/templates/nextjs-clerk/app/dashboard/page.tsx +69 -0
  81. package/templates/nextjs-clerk/app/globals.css +1 -0
  82. package/templates/nextjs-clerk/app/health/route.ts +3 -0
  83. package/templates/nextjs-clerk/app/layout.tsx +28 -0
  84. package/templates/nextjs-clerk/app/page.tsx +86 -0
  85. package/templates/nextjs-clerk/app/sign-in/[[...sign-in]]/page.tsx +9 -0
  86. package/templates/nextjs-clerk/app/sign-up/[[...sign-up]]/page.tsx +9 -0
  87. package/templates/nextjs-clerk/bun.lock +1055 -0
  88. package/templates/nextjs-clerk/cloudflare-env.d.ts +3 -0
  89. package/templates/nextjs-clerk/components/header.tsx +40 -0
  90. package/templates/nextjs-clerk/lib/utils.ts +6 -0
  91. package/templates/nextjs-clerk/middleware.ts +18 -0
  92. package/templates/nextjs-clerk/next.config.ts +8 -0
  93. package/templates/nextjs-clerk/open-next.config.ts +6 -0
  94. package/templates/nextjs-clerk/package.json +31 -0
  95. package/templates/nextjs-clerk/postcss.config.mjs +8 -0
  96. package/templates/nextjs-clerk/tsconfig.json +28 -0
  97. package/templates/nextjs-clerk/wrangler.jsonc +17 -0
  98. package/templates/nextjs-shadcn/.jack.json +34 -0
  99. package/templates/nextjs-shadcn/app/dashboard/data.json +614 -0
  100. package/templates/nextjs-shadcn/app/dashboard/page.tsx +55 -0
  101. package/templates/nextjs-shadcn/app/globals.css +126 -0
  102. package/templates/nextjs-shadcn/app/health/route.ts +3 -0
  103. package/templates/nextjs-shadcn/app/layout.tsx +24 -0
  104. package/templates/nextjs-shadcn/app/login/page.tsx +19 -0
  105. package/templates/nextjs-shadcn/app/page.tsx +180 -0
  106. package/templates/nextjs-shadcn/app/showcase.tsx +1262 -0
  107. package/templates/nextjs-shadcn/bun.lock +1789 -0
  108. package/templates/nextjs-shadcn/cloudflare-env.d.ts +4 -0
  109. package/templates/nextjs-shadcn/components/app-sidebar.tsx +175 -0
  110. package/templates/nextjs-shadcn/components/chart-area-interactive.tsx +291 -0
  111. package/templates/nextjs-shadcn/components/data-table.tsx +807 -0
  112. package/templates/nextjs-shadcn/components/login-form.tsx +95 -0
  113. package/templates/nextjs-shadcn/components/nav-documents.tsx +92 -0
  114. package/templates/nextjs-shadcn/components/nav-main.tsx +73 -0
  115. package/templates/nextjs-shadcn/components/nav-projects.tsx +89 -0
  116. package/templates/nextjs-shadcn/components/nav-secondary.tsx +42 -0
  117. package/templates/nextjs-shadcn/components/nav-user.tsx +114 -0
  118. package/templates/nextjs-shadcn/components/section-cards.tsx +102 -0
  119. package/templates/nextjs-shadcn/components/site-header.tsx +30 -0
  120. package/templates/nextjs-shadcn/components/team-switcher.tsx +91 -0
  121. package/templates/nextjs-shadcn/components/ui/accordion.tsx +66 -0
  122. package/templates/nextjs-shadcn/components/ui/alert-dialog.tsx +196 -0
  123. package/templates/nextjs-shadcn/components/ui/alert.tsx +66 -0
  124. package/templates/nextjs-shadcn/components/ui/aspect-ratio.tsx +11 -0
  125. package/templates/nextjs-shadcn/components/ui/avatar.tsx +109 -0
  126. package/templates/nextjs-shadcn/components/ui/badge.tsx +48 -0
  127. package/templates/nextjs-shadcn/components/ui/breadcrumb.tsx +109 -0
  128. package/templates/nextjs-shadcn/components/ui/button-group.tsx +83 -0
  129. package/templates/nextjs-shadcn/components/ui/button.tsx +64 -0
  130. package/templates/nextjs-shadcn/components/ui/calendar.tsx +220 -0
  131. package/templates/nextjs-shadcn/components/ui/card.tsx +92 -0
  132. package/templates/nextjs-shadcn/components/ui/carousel.tsx +241 -0
  133. package/templates/nextjs-shadcn/components/ui/chart.tsx +357 -0
  134. package/templates/nextjs-shadcn/components/ui/checkbox.tsx +32 -0
  135. package/templates/nextjs-shadcn/components/ui/collapsible.tsx +33 -0
  136. package/templates/nextjs-shadcn/components/ui/combobox.tsx +310 -0
  137. package/templates/nextjs-shadcn/components/ui/command.tsx +184 -0
  138. package/templates/nextjs-shadcn/components/ui/context-menu.tsx +252 -0
  139. package/templates/nextjs-shadcn/components/ui/dialog.tsx +158 -0
  140. package/templates/nextjs-shadcn/components/ui/direction.tsx +22 -0
  141. package/templates/nextjs-shadcn/components/ui/drawer.tsx +135 -0
  142. package/templates/nextjs-shadcn/components/ui/dropdown-menu.tsx +257 -0
  143. package/templates/nextjs-shadcn/components/ui/empty.tsx +104 -0
  144. package/templates/nextjs-shadcn/components/ui/field.tsx +248 -0
  145. package/templates/nextjs-shadcn/components/ui/form.tsx +167 -0
  146. package/templates/nextjs-shadcn/components/ui/hover-card.tsx +44 -0
  147. package/templates/nextjs-shadcn/components/ui/input-group.tsx +170 -0
  148. package/templates/nextjs-shadcn/components/ui/input-otp.tsx +77 -0
  149. package/templates/nextjs-shadcn/components/ui/input.tsx +21 -0
  150. package/templates/nextjs-shadcn/components/ui/item.tsx +193 -0
  151. package/templates/nextjs-shadcn/components/ui/kbd.tsx +28 -0
  152. package/templates/nextjs-shadcn/components/ui/label.tsx +24 -0
  153. package/templates/nextjs-shadcn/components/ui/menubar.tsx +276 -0
  154. package/templates/nextjs-shadcn/components/ui/native-select.tsx +53 -0
  155. package/templates/nextjs-shadcn/components/ui/navigation-menu.tsx +168 -0
  156. package/templates/nextjs-shadcn/components/ui/pagination.tsx +127 -0
  157. package/templates/nextjs-shadcn/components/ui/popover.tsx +89 -0
  158. package/templates/nextjs-shadcn/components/ui/progress.tsx +31 -0
  159. package/templates/nextjs-shadcn/components/ui/radio-group.tsx +45 -0
  160. package/templates/nextjs-shadcn/components/ui/resizable.tsx +53 -0
  161. package/templates/nextjs-shadcn/components/ui/scroll-area.tsx +58 -0
  162. package/templates/nextjs-shadcn/components/ui/select.tsx +190 -0
  163. package/templates/nextjs-shadcn/components/ui/separator.tsx +28 -0
  164. package/templates/nextjs-shadcn/components/ui/sheet.tsx +143 -0
  165. package/templates/nextjs-shadcn/components/ui/sidebar.tsx +726 -0
  166. package/templates/nextjs-shadcn/components/ui/skeleton.tsx +13 -0
  167. package/templates/nextjs-shadcn/components/ui/slider.tsx +63 -0
  168. package/templates/nextjs-shadcn/components/ui/sonner.tsx +40 -0
  169. package/templates/nextjs-shadcn/components/ui/spinner.tsx +16 -0
  170. package/templates/nextjs-shadcn/components/ui/switch.tsx +35 -0
  171. package/templates/nextjs-shadcn/components/ui/table.tsx +116 -0
  172. package/templates/nextjs-shadcn/components/ui/tabs.tsx +91 -0
  173. package/templates/nextjs-shadcn/components/ui/textarea.tsx +18 -0
  174. package/templates/nextjs-shadcn/components/ui/toggle-group.tsx +83 -0
  175. package/templates/nextjs-shadcn/components/ui/toggle.tsx +47 -0
  176. package/templates/nextjs-shadcn/components/ui/tooltip.tsx +57 -0
  177. package/templates/nextjs-shadcn/components.json +23 -0
  178. package/templates/nextjs-shadcn/hooks/use-mobile.ts +19 -0
  179. package/templates/nextjs-shadcn/lib/utils.ts +6 -0
  180. package/templates/nextjs-shadcn/next-env.d.ts +6 -0
  181. package/templates/nextjs-shadcn/next.config.ts +8 -0
  182. package/templates/nextjs-shadcn/open-next.config.ts +6 -0
  183. package/templates/nextjs-shadcn/package.json +55 -0
  184. package/templates/nextjs-shadcn/postcss.config.mjs +8 -0
  185. package/templates/nextjs-shadcn/tsconfig.json +28 -0
  186. package/templates/nextjs-shadcn/wrangler.jsonc +23 -0
  187. package/templates/resend/.jack.json +64 -0
  188. package/templates/resend/bun.lock +23 -0
  189. package/templates/resend/package.json +16 -0
  190. package/templates/resend/schema.sql +13 -0
  191. package/templates/resend/src/email.ts +165 -0
  192. package/templates/resend/src/index.ts +108 -0
  193. package/templates/resend/tsconfig.json +17 -0
  194. package/templates/resend/wrangler.jsonc +11 -0
  195. package/templates/saas/.jack.json +1 -1
  196. package/templates/ai-chat/public/chat.js +0 -149
@@ -0,0 +1,1262 @@
1
+ "use client";
2
+
3
+ import {
4
+ Accordion,
5
+ AccordionContent,
6
+ AccordionItem,
7
+ AccordionTrigger,
8
+ } from "@/components/ui/accordion";
9
+ import { Alert, AlertDescription, AlertTitle } from "@/components/ui/alert";
10
+ import { Avatar, AvatarFallback } from "@/components/ui/avatar";
11
+ import { Badge } from "@/components/ui/badge";
12
+ import {
13
+ Breadcrumb,
14
+ BreadcrumbItem,
15
+ BreadcrumbLink,
16
+ BreadcrumbList,
17
+ BreadcrumbPage,
18
+ BreadcrumbSeparator,
19
+ } from "@/components/ui/breadcrumb";
20
+ import { Button } from "@/components/ui/button";
21
+ import { Calendar } from "@/components/ui/calendar";
22
+ import {
23
+ Card,
24
+ CardContent,
25
+ CardHeader,
26
+ CardTitle,
27
+ } from "@/components/ui/card";
28
+ import {
29
+ Carousel,
30
+ CarouselContent,
31
+ CarouselItem,
32
+ CarouselNext,
33
+ CarouselPrevious,
34
+ } from "@/components/ui/carousel";
35
+ import { Checkbox } from "@/components/ui/checkbox";
36
+ import { Collapsible, CollapsibleContent, CollapsibleTrigger } from "@/components/ui/collapsible";
37
+ import {
38
+ Command,
39
+ CommandEmpty,
40
+ CommandGroup,
41
+ CommandInput,
42
+ CommandItem,
43
+ CommandList,
44
+ CommandSeparator,
45
+ } from "@/components/ui/command";
46
+ import {
47
+ Dialog,
48
+ DialogContent,
49
+ DialogDescription,
50
+ DialogFooter,
51
+ DialogHeader,
52
+ DialogTitle,
53
+ DialogTrigger,
54
+ } from "@/components/ui/dialog";
55
+ import { HoverCard, HoverCardContent, HoverCardTrigger } from "@/components/ui/hover-card";
56
+ import { Input } from "@/components/ui/input";
57
+ import {
58
+ InputOTP,
59
+ InputOTPGroup,
60
+ InputOTPSeparator,
61
+ InputOTPSlot,
62
+ } from "@/components/ui/input-otp";
63
+ import { Label } from "@/components/ui/label";
64
+ import {
65
+ Pagination,
66
+ PaginationContent,
67
+ PaginationItem,
68
+ PaginationLink,
69
+ PaginationNext,
70
+ PaginationPrevious,
71
+ } from "@/components/ui/pagination";
72
+ import { Popover, PopoverContent, PopoverTrigger } from "@/components/ui/popover";
73
+ import { Progress } from "@/components/ui/progress";
74
+ import { RadioGroup, RadioGroupItem } from "@/components/ui/radio-group";
75
+ import { ScrollArea } from "@/components/ui/scroll-area";
76
+ import {
77
+ Select,
78
+ SelectContent,
79
+ SelectItem,
80
+ SelectTrigger,
81
+ SelectValue,
82
+ } from "@/components/ui/select";
83
+ import { Separator } from "@/components/ui/separator";
84
+ import {
85
+ Sheet,
86
+ SheetContent,
87
+ SheetDescription,
88
+ SheetHeader,
89
+ SheetTitle,
90
+ SheetTrigger,
91
+ } from "@/components/ui/sheet";
92
+ import { Skeleton } from "@/components/ui/skeleton";
93
+ import { Slider } from "@/components/ui/slider";
94
+ import { Spinner } from "@/components/ui/spinner";
95
+ import { Switch } from "@/components/ui/switch";
96
+ import {
97
+ Table,
98
+ TableBody,
99
+ TableCell,
100
+ TableHead,
101
+ TableHeader,
102
+ TableRow,
103
+ } from "@/components/ui/table";
104
+ import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
105
+ import { Textarea } from "@/components/ui/textarea";
106
+ import { Toggle } from "@/components/ui/toggle";
107
+ import { ToggleGroup, ToggleGroupItem } from "@/components/ui/toggle-group";
108
+ import { Tooltip, TooltipContent, TooltipTrigger } from "@/components/ui/tooltip";
109
+ import {
110
+ AlertCircle,
111
+ AlignCenter,
112
+ AlignLeft,
113
+ AlignRight,
114
+ Archive,
115
+ ArrowLeft,
116
+ Bell,
117
+ Bold,
118
+ CalendarIcon,
119
+ Check,
120
+ ChevronsUpDown,
121
+ Cloud,
122
+ Copy,
123
+ CreditCard,
124
+ FileText,
125
+ Flag,
126
+ Home,
127
+ Info,
128
+ Italic,
129
+ Laptop,
130
+ Loader2,
131
+ Mail,
132
+ Minus,
133
+ Monitor,
134
+ Moon,
135
+ MoreHorizontal,
136
+ Plus,
137
+ Search,
138
+ Settings,
139
+ Sun,
140
+ Terminal,
141
+ Underline,
142
+ User,
143
+ } from "lucide-react";
144
+ import { useState } from "react";
145
+
146
+ export function ComponentShowcase() {
147
+ const [sliderValue, setSliderValue] = useState([400]);
148
+ const [gpuCount, setGpuCount] = useState(8);
149
+ const [copied, setCopied] = useState(false);
150
+ const [selectedDate, setSelectedDate] = useState<Date | undefined>(new Date());
151
+ const [collapsibleOpen, setCollapsibleOpen] = useState(false);
152
+
153
+ return (
154
+ <div className="columns-1 gap-4 sm:columns-2 lg:columns-3 xl:columns-4 [&>*]:mb-4 [&>*]:break-inside-avoid">
155
+ {/* Payment Form */}
156
+ <Card>
157
+ <CardHeader>
158
+ <CardTitle className="text-base">Payment Method</CardTitle>
159
+ <p className="text-sm text-muted-foreground">
160
+ All transactions are secure and encrypted.
161
+ </p>
162
+ </CardHeader>
163
+ <CardContent className="space-y-4">
164
+ <div className="space-y-1">
165
+ <Label>Name on Card</Label>
166
+ <Input defaultValue="John Doe" />
167
+ </div>
168
+ <div className="grid grid-cols-2 gap-3">
169
+ <div className="space-y-1">
170
+ <Label>Card Number</Label>
171
+ <Input placeholder="1234 5678 9012 3456" />
172
+ </div>
173
+ <div className="space-y-1">
174
+ <Label>CVV</Label>
175
+ <Input placeholder="123" />
176
+ </div>
177
+ </div>
178
+ <p className="text-xs text-muted-foreground">Enter your 16-digit number.</p>
179
+ <div className="grid grid-cols-2 gap-3">
180
+ <div className="space-y-1">
181
+ <Label>Month</Label>
182
+ <Select>
183
+ <SelectTrigger>
184
+ <SelectValue placeholder="MM" />
185
+ </SelectTrigger>
186
+ <SelectContent>
187
+ {Array.from({ length: 12 }, (_, i) => (
188
+ <SelectItem key={i + 1} value={String(i + 1).padStart(2, "0")}>
189
+ {String(i + 1).padStart(2, "0")}
190
+ </SelectItem>
191
+ ))}
192
+ </SelectContent>
193
+ </Select>
194
+ </div>
195
+ <div className="space-y-1">
196
+ <Label>Year</Label>
197
+ <Select>
198
+ <SelectTrigger>
199
+ <SelectValue placeholder="YYYY" />
200
+ </SelectTrigger>
201
+ <SelectContent>
202
+ {[2025, 2026, 2027, 2028, 2029].map((y) => (
203
+ <SelectItem key={y} value={String(y)}>
204
+ {y}
205
+ </SelectItem>
206
+ ))}
207
+ </SelectContent>
208
+ </Select>
209
+ </div>
210
+ </div>
211
+ <Separator />
212
+ <div>
213
+ <h4 className="mb-1 font-medium text-sm">Billing Address</h4>
214
+ <p className="text-xs text-muted-foreground">
215
+ The billing address associated with your payment method
216
+ </p>
217
+ </div>
218
+ <div className="flex items-center gap-2">
219
+ <Checkbox id="same-address" defaultChecked />
220
+ <Label htmlFor="same-address">Same as shipping address</Label>
221
+ </div>
222
+ <Separator />
223
+ <div className="space-y-1">
224
+ <Label>Comments</Label>
225
+ <Textarea placeholder="Add any additional comments" />
226
+ </div>
227
+ <div className="flex gap-2">
228
+ <Button className="flex-1">Submit</Button>
229
+ <Button variant="outline" className="flex-1">
230
+ Cancel
231
+ </Button>
232
+ </div>
233
+ </CardContent>
234
+ </Card>
235
+
236
+ {/* Status Badges & Chat */}
237
+ <Card>
238
+ <CardContent className="space-y-4 pt-6">
239
+ <div className="flex items-center justify-center gap-2">
240
+ <Badge className="bg-emerald-500/10 text-emerald-500 border-emerald-500/20">
241
+ <span className="mr-1 inline-block size-1.5 rounded-full bg-emerald-500 animate-pulse" />
242
+ Syncing
243
+ </Badge>
244
+ <Badge className="bg-blue-500/10 text-blue-500 border-blue-500/20">
245
+ <span className="mr-1 inline-block size-1.5 rounded-full bg-blue-500 animate-pulse" />
246
+ Updating
247
+ </Badge>
248
+ <Badge className="bg-orange-500/10 text-orange-500 border-orange-500/20">
249
+ <span className="mr-1 inline-block size-1.5 rounded-full bg-orange-500 animate-pulse" />
250
+ Loading
251
+ </Badge>
252
+ </div>
253
+ <div className="rounded-lg border p-3">
254
+ <div className="flex items-center gap-2">
255
+ <Button variant="ghost" size="icon" className="size-8">
256
+ <Plus className="size-4" />
257
+ </Button>
258
+ <span className="flex-1 text-sm text-muted-foreground">Send a message...</span>
259
+ <Button variant="ghost" size="icon" className="size-8">
260
+ <ArrowLeft className="size-4 rotate-90" />
261
+ </Button>
262
+ </div>
263
+ </div>
264
+ <div>
265
+ <h4 className="font-medium text-sm">Price Range</h4>
266
+ <p className="text-xs text-muted-foreground mb-3">
267
+ Set your budget range (${sliderValue[0]} - $800).
268
+ </p>
269
+ <Slider defaultValue={[200, 800]} max={1000} step={50} onValueChange={setSliderValue} />
270
+ </div>
271
+ <div className="flex items-center gap-2 rounded-lg border px-3 py-2">
272
+ <Search className="size-4 text-muted-foreground" />
273
+ <span className="flex-1 text-sm text-muted-foreground">Search...</span>
274
+ <span className="text-xs text-muted-foreground">12 results</span>
275
+ </div>
276
+ <div className="flex items-center gap-2 rounded-lg border px-3 py-2">
277
+ <span className="flex-1 text-sm text-muted-foreground truncate">
278
+ https:// example.com
279
+ </span>
280
+ <Button
281
+ variant="ghost"
282
+ size="icon"
283
+ className="size-7"
284
+ onClick={() => {
285
+ setCopied(true);
286
+ setTimeout(() => setCopied(false), 2000);
287
+ }}
288
+ >
289
+ {copied ? <Check className="size-3.5" /> : <Copy className="size-3.5" />}
290
+ </Button>
291
+ </div>
292
+ <div className="rounded-lg border p-3 space-y-2">
293
+ <Textarea
294
+ placeholder="Ask, Search or Chat..."
295
+ className="border-0 p-0 shadow-none resize-none focus-visible:ring-0"
296
+ rows={2}
297
+ />
298
+ <div className="flex items-center justify-between">
299
+ <div className="flex items-center gap-1">
300
+ <Button variant="ghost" size="icon" className="size-7">
301
+ <Plus className="size-4" />
302
+ </Button>
303
+ <span className="text-xs text-muted-foreground">Auto</span>
304
+ </div>
305
+ <div className="flex items-center gap-2">
306
+ <span className="text-xs text-muted-foreground">52% used</span>
307
+ <Button size="icon" className="size-7 rounded-full">
308
+ <ArrowLeft className="size-3 rotate-90" />
309
+ </Button>
310
+ </div>
311
+ </div>
312
+ </div>
313
+ <div className="flex items-center gap-2 rounded-lg border px-3 py-2">
314
+ <span className="text-sm">@shadcn</span>
315
+ <Check className="ml-auto size-4 text-blue-500" />
316
+ </div>
317
+ </CardContent>
318
+ </Card>
319
+
320
+ {/* Compute Environment (Radio Group) */}
321
+ <Card>
322
+ <CardHeader>
323
+ <CardTitle className="text-base">Compute Environment</CardTitle>
324
+ <p className="text-sm text-muted-foreground">
325
+ Select the compute environment for your cluster.
326
+ </p>
327
+ </CardHeader>
328
+ <CardContent className="space-y-4">
329
+ <RadioGroup defaultValue="kubernetes">
330
+ <div className="flex items-start gap-3 rounded-lg border p-3 data-[state=checked]:border-primary">
331
+ <RadioGroupItem value="kubernetes" id="k8s" className="mt-0.5" />
332
+ <div>
333
+ <Label htmlFor="k8s" className="font-medium">
334
+ Kubernetes
335
+ </Label>
336
+ <p className="text-xs text-muted-foreground">
337
+ Run GPU workloads on a K8s configured cluster. This is the default.
338
+ </p>
339
+ </div>
340
+ </div>
341
+ <div className="flex items-start gap-3 rounded-lg border p-3">
342
+ <RadioGroupItem value="vm" id="vm" className="mt-0.5" />
343
+ <div>
344
+ <Label htmlFor="vm" className="font-medium">
345
+ Virtual Machine
346
+ </Label>
347
+ <p className="text-xs text-muted-foreground">
348
+ Access a VM configured cluster to run workloads. (Coming soon)
349
+ </p>
350
+ </div>
351
+ </div>
352
+ </RadioGroup>
353
+ <Separator />
354
+ <div className="flex items-center justify-between">
355
+ <div>
356
+ <h4 className="font-medium text-sm">Number of GPUs</h4>
357
+ <p className="text-xs text-muted-foreground">You can add more later.</p>
358
+ </div>
359
+ <div className="flex items-center gap-1">
360
+ <Input className="w-14 text-center" value={gpuCount} readOnly />
361
+ <Button
362
+ variant="outline"
363
+ size="icon"
364
+ className="size-8"
365
+ onClick={() => setGpuCount(Math.max(1, gpuCount - 1))}
366
+ >
367
+ <Minus className="size-3" />
368
+ </Button>
369
+ <Button
370
+ variant="outline"
371
+ size="icon"
372
+ className="size-8"
373
+ onClick={() => setGpuCount(gpuCount + 1)}
374
+ >
375
+ <Plus className="size-3" />
376
+ </Button>
377
+ </div>
378
+ </div>
379
+ <Separator />
380
+ <div className="flex items-center justify-between">
381
+ <div>
382
+ <h4 className="font-medium text-sm">Wallpaper Tinting</h4>
383
+ <p className="text-xs text-muted-foreground">Allow the wallpaper to be tinted.</p>
384
+ </div>
385
+ <Switch defaultChecked />
386
+ </div>
387
+ </CardContent>
388
+ </Card>
389
+
390
+ {/* Actions Bar */}
391
+ <Card>
392
+ <CardContent className="space-y-4 pt-6">
393
+ <div className="flex items-center gap-1">
394
+ <Button variant="outline" size="icon" className="size-8">
395
+ <ArrowLeft className="size-4" />
396
+ </Button>
397
+ <div className="flex flex-1 items-center gap-1 justify-end">
398
+ <Button variant="outline" size="sm">
399
+ Archive
400
+ </Button>
401
+ <Button variant="outline" size="sm">
402
+ Report
403
+ </Button>
404
+ <Button variant="outline" size="sm">
405
+ Snooze
406
+ </Button>
407
+ <Button variant="outline" size="icon" className="size-8">
408
+ <MoreHorizontal className="size-4" />
409
+ </Button>
410
+ </div>
411
+ </div>
412
+ <div className="flex items-center gap-2">
413
+ <Checkbox id="terms" defaultChecked />
414
+ <Label htmlFor="terms">I agree to the terms and conditions</Label>
415
+ </div>
416
+ <Separator className="relative">
417
+ <span className="absolute left-1/2 top-1/2 -translate-x-1/2 -translate-y-1/2 bg-card px-2 text-xs text-muted-foreground">
418
+ Appearance Settings
419
+ </span>
420
+ </Separator>
421
+ <Pagination>
422
+ <PaginationContent>
423
+ <PaginationItem>
424
+ <PaginationPrevious href="#" />
425
+ </PaginationItem>
426
+ <PaginationItem>
427
+ <PaginationLink href="#" isActive>
428
+ 1
429
+ </PaginationLink>
430
+ </PaginationItem>
431
+ <PaginationItem>
432
+ <PaginationLink href="#">2</PaginationLink>
433
+ </PaginationItem>
434
+ <PaginationItem>
435
+ <PaginationLink href="#">3</PaginationLink>
436
+ </PaginationItem>
437
+ <PaginationItem>
438
+ <PaginationNext href="#" />
439
+ </PaginationItem>
440
+ </PaginationContent>
441
+ </Pagination>
442
+ </CardContent>
443
+ </Card>
444
+
445
+ {/* Survey Toggle Group */}
446
+ <Card>
447
+ <CardHeader>
448
+ <CardTitle className="text-base">How did you hear about us?</CardTitle>
449
+ <p className="text-sm text-muted-foreground">Select the option that best describes...</p>
450
+ </CardHeader>
451
+ <CardContent className="space-y-4">
452
+ <ToggleGroup type="single" defaultValue="social" className="flex-wrap">
453
+ <ToggleGroupItem value="social" className="gap-1">
454
+ <Check className="size-3" />
455
+ Social Media
456
+ </ToggleGroupItem>
457
+ <ToggleGroupItem value="search">Search Engine</ToggleGroupItem>
458
+ <ToggleGroupItem value="referral">Referral</ToggleGroupItem>
459
+ <ToggleGroupItem value="other">Other</ToggleGroupItem>
460
+ </ToggleGroup>
461
+ <Separator />
462
+ <div className="flex flex-col items-center gap-2 py-4">
463
+ <Spinner className="size-6" />
464
+ <h4 className="font-medium text-sm">Processing your request</h4>
465
+ <p className="text-xs text-muted-foreground text-center">
466
+ Please wait while we process your request. Do not refresh the page.
467
+ </p>
468
+ <Button variant="outline" size="sm" className="mt-1">
469
+ Cancel
470
+ </Button>
471
+ </div>
472
+ </CardContent>
473
+ </Card>
474
+
475
+ {/* Text Formatting Toolbar */}
476
+ <Card>
477
+ <CardHeader>
478
+ <CardTitle className="text-base">Text Formatting</CardTitle>
479
+ </CardHeader>
480
+ <CardContent className="space-y-3">
481
+ <div className="flex items-center gap-1">
482
+ <Toggle size="sm" aria-label="Bold" defaultPressed>
483
+ <Bold className="size-4" />
484
+ </Toggle>
485
+ <Toggle size="sm" aria-label="Italic">
486
+ <Italic className="size-4" />
487
+ </Toggle>
488
+ <Toggle size="sm" aria-label="Underline">
489
+ <Underline className="size-4" />
490
+ </Toggle>
491
+ <Separator orientation="vertical" className="mx-1 h-6" />
492
+ <ToggleGroup type="single" defaultValue="left">
493
+ <ToggleGroupItem value="left" size="sm">
494
+ <AlignLeft className="size-4" />
495
+ </ToggleGroupItem>
496
+ <ToggleGroupItem value="center" size="sm">
497
+ <AlignCenter className="size-4" />
498
+ </ToggleGroupItem>
499
+ <ToggleGroupItem value="right" size="sm">
500
+ <AlignRight className="size-4" />
501
+ </ToggleGroupItem>
502
+ </ToggleGroup>
503
+ </div>
504
+ <ToggleGroup type="single" defaultValue="copilot" className="justify-start">
505
+ <ToggleGroupItem value="copilot" className="gap-1 text-xs">
506
+ <Cloud className="size-3" /> Copilot
507
+ </ToggleGroupItem>
508
+ <ToggleGroupItem value="local" className="gap-1 text-xs">
509
+ <Monitor className="size-3" /> Local
510
+ </ToggleGroupItem>
511
+ </ToggleGroup>
512
+ </CardContent>
513
+ </Card>
514
+
515
+ {/* Team Members */}
516
+ <Card>
517
+ <CardContent className="space-y-4 pt-6">
518
+ <div className="flex flex-col items-center gap-2 py-2">
519
+ <div className="flex -space-x-3">
520
+ <Avatar className="border-2 border-background">
521
+ <AvatarFallback>AB</AvatarFallback>
522
+ </Avatar>
523
+ <Avatar className="border-2 border-background">
524
+ <AvatarFallback>CD</AvatarFallback>
525
+ </Avatar>
526
+ </div>
527
+ <h4 className="font-medium text-sm">No Team Members</h4>
528
+ <p className="text-xs text-muted-foreground text-center">
529
+ Invite your team to collaborate on this project.
530
+ </p>
531
+ <Button variant="outline" size="sm">
532
+ <Plus className="mr-1 size-3" /> Invite Members
533
+ </Button>
534
+ </div>
535
+ </CardContent>
536
+ </Card>
537
+
538
+ {/* Data Table */}
539
+ <Card>
540
+ <CardHeader>
541
+ <CardTitle className="text-base">Recent Invoices</CardTitle>
542
+ </CardHeader>
543
+ <CardContent>
544
+ <Table>
545
+ <TableHeader>
546
+ <TableRow>
547
+ <TableHead>Invoice</TableHead>
548
+ <TableHead>Status</TableHead>
549
+ <TableHead className="text-right">Amount</TableHead>
550
+ </TableRow>
551
+ </TableHeader>
552
+ <TableBody>
553
+ <TableRow>
554
+ <TableCell className="font-medium">INV-001</TableCell>
555
+ <TableCell>
556
+ <Badge variant="secondary" className="bg-emerald-500/10 text-emerald-600">
557
+ Paid
558
+ </Badge>
559
+ </TableCell>
560
+ <TableCell className="text-right">$250.00</TableCell>
561
+ </TableRow>
562
+ <TableRow>
563
+ <TableCell className="font-medium">INV-002</TableCell>
564
+ <TableCell>
565
+ <Badge variant="secondary">Pending</Badge>
566
+ </TableCell>
567
+ <TableCell className="text-right">$150.00</TableCell>
568
+ </TableRow>
569
+ <TableRow>
570
+ <TableCell className="font-medium">INV-003</TableCell>
571
+ <TableCell>
572
+ <Badge variant="secondary" className="bg-red-500/10 text-red-600">
573
+ Overdue
574
+ </Badge>
575
+ </TableCell>
576
+ <TableCell className="text-right">$350.00</TableCell>
577
+ </TableRow>
578
+ </TableBody>
579
+ </Table>
580
+ </CardContent>
581
+ </Card>
582
+
583
+ {/* Skeleton Loading */}
584
+ <Card>
585
+ <CardHeader>
586
+ <CardTitle className="text-base">Loading States</CardTitle>
587
+ </CardHeader>
588
+ <CardContent className="space-y-4">
589
+ <div className="flex items-center gap-3">
590
+ <Skeleton className="size-10 rounded-full" />
591
+ <div className="flex-1 space-y-2">
592
+ <Skeleton className="h-4 w-3/4" />
593
+ <Skeleton className="h-3 w-1/2" />
594
+ </div>
595
+ </div>
596
+ <Skeleton className="h-24 w-full" />
597
+ <div className="flex gap-2">
598
+ <Skeleton className="h-9 w-20" />
599
+ <Skeleton className="h-9 w-20" />
600
+ </div>
601
+ </CardContent>
602
+ </Card>
603
+
604
+ {/* Progress & Stats */}
605
+ <Card>
606
+ <CardContent className="space-y-4 pt-6">
607
+ <Tabs defaultValue="overview">
608
+ <TabsList className="w-full">
609
+ <TabsTrigger value="overview" className="flex-1">
610
+ Overview
611
+ </TabsTrigger>
612
+ <TabsTrigger value="analytics" className="flex-1">
613
+ Analytics
614
+ </TabsTrigger>
615
+ </TabsList>
616
+ <TabsContent value="overview" className="mt-3 space-y-3">
617
+ <div className="space-y-1">
618
+ <div className="flex justify-between text-sm">
619
+ <span>Storage</span>
620
+ <span className="text-muted-foreground">75%</span>
621
+ </div>
622
+ <Progress value={75} />
623
+ </div>
624
+ <div className="space-y-1">
625
+ <div className="flex justify-between text-sm">
626
+ <span>Bandwidth</span>
627
+ <span className="text-muted-foreground">45%</span>
628
+ </div>
629
+ <Progress value={45} />
630
+ </div>
631
+ <div className="space-y-1">
632
+ <div className="flex justify-between text-sm">
633
+ <span>Requests</span>
634
+ <span className="text-muted-foreground">92%</span>
635
+ </div>
636
+ <Progress value={92} />
637
+ </div>
638
+ </TabsContent>
639
+ <TabsContent value="analytics" className="mt-3 space-y-3">
640
+ <div className="space-y-1">
641
+ <div className="flex justify-between text-sm">
642
+ <span>Page Views</span>
643
+ <span className="font-medium">12,543</span>
644
+ </div>
645
+ <Progress value={62} />
646
+ </div>
647
+ <div className="space-y-1">
648
+ <div className="flex justify-between text-sm">
649
+ <span>Bounce Rate</span>
650
+ <span className="font-medium">24%</span>
651
+ </div>
652
+ <Progress value={24} />
653
+ </div>
654
+ <div className="space-y-1">
655
+ <div className="flex justify-between text-sm">
656
+ <span>Avg. Session</span>
657
+ <span className="font-medium">3m 42s</span>
658
+ </div>
659
+ <Progress value={55} />
660
+ </div>
661
+ </TabsContent>
662
+ </Tabs>
663
+ </CardContent>
664
+ </Card>
665
+
666
+ {/* Accordion */}
667
+ <Card>
668
+ <CardHeader>
669
+ <CardTitle className="text-base">FAQ</CardTitle>
670
+ </CardHeader>
671
+ <CardContent>
672
+ <Accordion type="single" collapsible defaultValue="item-1">
673
+ <AccordionItem value="item-1">
674
+ <AccordionTrigger className="text-sm">What components are included?</AccordionTrigger>
675
+ <AccordionContent>
676
+ All 57 shadcn/ui components are pre-installed and ready to import.
677
+ </AccordionContent>
678
+ </AccordionItem>
679
+ <AccordionItem value="item-2">
680
+ <AccordionTrigger className="text-sm">How do I deploy?</AccordionTrigger>
681
+ <AccordionContent>
682
+ Run <code className="bg-muted px-1 rounded">jack ship</code> to deploy to production
683
+ instantly.
684
+ </AccordionContent>
685
+ </AccordionItem>
686
+ <AccordionItem value="item-3">
687
+ <AccordionTrigger className="text-sm">Is there a database?</AccordionTrigger>
688
+ <AccordionContent>
689
+ Yes, D1 SQLite database is included and globally replicated.
690
+ </AccordionContent>
691
+ </AccordionItem>
692
+ </Accordion>
693
+ </CardContent>
694
+ </Card>
695
+
696
+ {/* Buttons Grid */}
697
+ <Card>
698
+ <CardHeader>
699
+ <CardTitle className="text-base">Button Variants</CardTitle>
700
+ </CardHeader>
701
+ <CardContent className="space-y-3">
702
+ <div className="flex flex-wrap gap-2">
703
+ <Button size="sm">Primary</Button>
704
+ <Button size="sm" variant="secondary">
705
+ Secondary
706
+ </Button>
707
+ <Button size="sm" variant="outline">
708
+ Outline
709
+ </Button>
710
+ <Button size="sm" variant="destructive">
711
+ Destructive
712
+ </Button>
713
+ <Button size="sm" variant="ghost">
714
+ Ghost
715
+ </Button>
716
+ <Button size="sm" variant="link">
717
+ Link
718
+ </Button>
719
+ </div>
720
+ <Separator />
721
+ <div className="flex flex-wrap gap-2">
722
+ <Button size="sm" disabled>
723
+ <Loader2 className="mr-1 size-3 animate-spin" />
724
+ Loading
725
+ </Button>
726
+ <Button size="sm" variant="outline">
727
+ <CreditCard className="mr-1 size-3" />
728
+ Pay Now
729
+ </Button>
730
+ <Button size="sm" variant="outline">
731
+ <Archive className="mr-1 size-3" />
732
+ Archive
733
+ </Button>
734
+ <Button size="sm" variant="outline">
735
+ <Flag className="mr-1 size-3" />
736
+ Flag
737
+ </Button>
738
+ </div>
739
+ </CardContent>
740
+ </Card>
741
+
742
+ {/* Alerts */}
743
+ <Card>
744
+ <CardHeader>
745
+ <CardTitle className="text-base">Alerts</CardTitle>
746
+ </CardHeader>
747
+ <CardContent className="space-y-3">
748
+ <Alert>
749
+ <Terminal className="size-4" />
750
+ <AlertTitle>Heads up!</AlertTitle>
751
+ <AlertDescription>You can add components using the CLI.</AlertDescription>
752
+ </Alert>
753
+ <Alert variant="destructive">
754
+ <AlertCircle className="size-4" />
755
+ <AlertTitle>Error</AlertTitle>
756
+ <AlertDescription>Your session has expired. Please log in again.</AlertDescription>
757
+ </Alert>
758
+ <Alert className="border-blue-500/50 text-blue-600 [&>svg]:text-blue-600">
759
+ <Info className="size-4" />
760
+ <AlertTitle>Note</AlertTitle>
761
+ <AlertDescription>This feature is in beta. Feedback welcome.</AlertDescription>
762
+ </Alert>
763
+ </CardContent>
764
+ </Card>
765
+
766
+ {/* Calendar */}
767
+ <Card>
768
+ <CardHeader>
769
+ <CardTitle className="text-base">Date Picker</CardTitle>
770
+ </CardHeader>
771
+ <CardContent className="flex justify-center">
772
+ <Calendar
773
+ mode="single"
774
+ selected={selectedDate}
775
+ onSelect={setSelectedDate}
776
+ className="rounded-md border"
777
+ />
778
+ </CardContent>
779
+ </Card>
780
+
781
+ {/* Dialog & Sheet */}
782
+ <Card>
783
+ <CardHeader>
784
+ <CardTitle className="text-base">Overlays</CardTitle>
785
+ <p className="text-sm text-muted-foreground">Dialog, Sheet & Popover components</p>
786
+ </CardHeader>
787
+ <CardContent className="space-y-3">
788
+ <Dialog>
789
+ <DialogTrigger asChild>
790
+ <Button variant="outline" className="w-full">
791
+ Open Dialog
792
+ </Button>
793
+ </DialogTrigger>
794
+ <DialogContent>
795
+ <DialogHeader>
796
+ <DialogTitle>Edit Profile</DialogTitle>
797
+ <DialogDescription>
798
+ Make changes to your profile here. Click save when done.
799
+ </DialogDescription>
800
+ </DialogHeader>
801
+ <div className="space-y-3 py-4">
802
+ <div className="space-y-1">
803
+ <Label htmlFor="dialog-name">Name</Label>
804
+ <Input id="dialog-name" defaultValue="John Doe" />
805
+ </div>
806
+ <div className="space-y-1">
807
+ <Label htmlFor="dialog-email">Email</Label>
808
+ <Input id="dialog-email" defaultValue="john@example.com" />
809
+ </div>
810
+ </div>
811
+ <DialogFooter>
812
+ <Button type="submit">Save changes</Button>
813
+ </DialogFooter>
814
+ </DialogContent>
815
+ </Dialog>
816
+ <Sheet>
817
+ <SheetTrigger asChild>
818
+ <Button variant="outline" className="w-full">
819
+ Open Sheet
820
+ </Button>
821
+ </SheetTrigger>
822
+ <SheetContent>
823
+ <SheetHeader>
824
+ <SheetTitle>Notifications</SheetTitle>
825
+ <SheetDescription>You have 3 unread notifications.</SheetDescription>
826
+ </SheetHeader>
827
+ <div className="mt-4 space-y-3">
828
+ {[
829
+ { icon: Mail, title: "New message", desc: "from Alice" },
830
+ { icon: Bell, title: "Reminder", desc: "Team meeting at 3pm" },
831
+ { icon: FileText, title: "Document shared", desc: "Q4 Report" },
832
+ ].map((item) => (
833
+ <div key={item.title} className="flex items-start gap-3 rounded-lg border p-3">
834
+ <item.icon className="mt-0.5 size-4 text-muted-foreground" />
835
+ <div>
836
+ <p className="text-sm font-medium">{item.title}</p>
837
+ <p className="text-xs text-muted-foreground">{item.desc}</p>
838
+ </div>
839
+ </div>
840
+ ))}
841
+ </div>
842
+ </SheetContent>
843
+ </Sheet>
844
+ <Popover>
845
+ <PopoverTrigger asChild>
846
+ <Button variant="outline" className="w-full">
847
+ Open Popover
848
+ </Button>
849
+ </PopoverTrigger>
850
+ <PopoverContent className="w-80">
851
+ <div className="space-y-2">
852
+ <h4 className="font-medium text-sm">Dimensions</h4>
853
+ <p className="text-xs text-muted-foreground">Set the dimensions for the layer.</p>
854
+ <div className="grid grid-cols-2 gap-2">
855
+ <div className="space-y-1">
856
+ <Label className="text-xs">Width</Label>
857
+ <Input defaultValue="100%" className="h-8" />
858
+ </div>
859
+ <div className="space-y-1">
860
+ <Label className="text-xs">Height</Label>
861
+ <Input defaultValue="25px" className="h-8" />
862
+ </div>
863
+ </div>
864
+ </div>
865
+ </PopoverContent>
866
+ </Popover>
867
+ </CardContent>
868
+ </Card>
869
+
870
+ {/* Breadcrumb & Navigation */}
871
+ <Card>
872
+ <CardHeader>
873
+ <CardTitle className="text-base">Navigation</CardTitle>
874
+ </CardHeader>
875
+ <CardContent className="space-y-4">
876
+ <Breadcrumb>
877
+ <BreadcrumbList>
878
+ <BreadcrumbItem>
879
+ <BreadcrumbLink href="#">
880
+ <Home className="size-3.5" />
881
+ </BreadcrumbLink>
882
+ </BreadcrumbItem>
883
+ <BreadcrumbSeparator />
884
+ <BreadcrumbItem>
885
+ <BreadcrumbLink href="#">Components</BreadcrumbLink>
886
+ </BreadcrumbItem>
887
+ <BreadcrumbSeparator />
888
+ <BreadcrumbItem>
889
+ <BreadcrumbPage>Breadcrumb</BreadcrumbPage>
890
+ </BreadcrumbItem>
891
+ </BreadcrumbList>
892
+ </Breadcrumb>
893
+ <Separator />
894
+ <div className="flex items-center gap-1">
895
+ <Tooltip>
896
+ <TooltipTrigger asChild>
897
+ <Button variant="ghost" size="icon" className="size-8">
898
+ <Home className="size-4" />
899
+ </Button>
900
+ </TooltipTrigger>
901
+ <TooltipContent>Home</TooltipContent>
902
+ </Tooltip>
903
+ <Tooltip>
904
+ <TooltipTrigger asChild>
905
+ <Button variant="ghost" size="icon" className="size-8">
906
+ <Settings className="size-4" />
907
+ </Button>
908
+ </TooltipTrigger>
909
+ <TooltipContent>Settings</TooltipContent>
910
+ </Tooltip>
911
+ <Tooltip>
912
+ <TooltipTrigger asChild>
913
+ <Button variant="ghost" size="icon" className="size-8">
914
+ <User className="size-4" />
915
+ </Button>
916
+ </TooltipTrigger>
917
+ <TooltipContent>Profile</TooltipContent>
918
+ </Tooltip>
919
+ <Tooltip>
920
+ <TooltipTrigger asChild>
921
+ <Button variant="ghost" size="icon" className="size-8">
922
+ <Bell className="size-4" />
923
+ </Button>
924
+ </TooltipTrigger>
925
+ <TooltipContent>Notifications</TooltipContent>
926
+ </Tooltip>
927
+ </div>
928
+ <Separator />
929
+ <div className="flex items-center gap-2">
930
+ <Badge variant="outline">v2.4.0</Badge>
931
+ <Badge
932
+ variant="outline"
933
+ className="bg-emerald-500/10 text-emerald-600 border-emerald-500/20"
934
+ >
935
+ Stable
936
+ </Badge>
937
+ <Badge variant="outline" className="bg-blue-500/10 text-blue-600 border-blue-500/20">
938
+ Latest
939
+ </Badge>
940
+ </div>
941
+ </CardContent>
942
+ </Card>
943
+
944
+ {/* OTP Input */}
945
+ <Card>
946
+ <CardHeader>
947
+ <CardTitle className="text-base">Verification Code</CardTitle>
948
+ <p className="text-sm text-muted-foreground">
949
+ Enter the 6-digit code sent to your email.
950
+ </p>
951
+ </CardHeader>
952
+ <CardContent className="flex flex-col items-center gap-4">
953
+ <InputOTP maxLength={6} defaultValue="482">
954
+ <InputOTPGroup>
955
+ <InputOTPSlot index={0} />
956
+ <InputOTPSlot index={1} />
957
+ <InputOTPSlot index={2} />
958
+ </InputOTPGroup>
959
+ <InputOTPSeparator />
960
+ <InputOTPGroup>
961
+ <InputOTPSlot index={3} />
962
+ <InputOTPSlot index={4} />
963
+ <InputOTPSlot index={5} />
964
+ </InputOTPGroup>
965
+ </InputOTP>
966
+ <p className="text-xs text-muted-foreground">
967
+ Didn&apos;t receive a code?{" "}
968
+ <button type="button" className="underline underline-offset-4">
969
+ Resend
970
+ </button>
971
+ </p>
972
+ </CardContent>
973
+ </Card>
974
+
975
+ {/* Command Palette */}
976
+ <Card>
977
+ <CardHeader>
978
+ <CardTitle className="text-base">Command Palette</CardTitle>
979
+ </CardHeader>
980
+ <CardContent>
981
+ <Command className="rounded-lg border">
982
+ <CommandInput placeholder="Type a command or search..." />
983
+ <CommandList>
984
+ <CommandEmpty>No results found.</CommandEmpty>
985
+ <CommandGroup heading="Suggestions">
986
+ <CommandItem>
987
+ <CalendarIcon className="mr-2 size-4" />
988
+ <span>Calendar</span>
989
+ </CommandItem>
990
+ <CommandItem>
991
+ <Search className="mr-2 size-4" />
992
+ <span>Search</span>
993
+ </CommandItem>
994
+ <CommandItem>
995
+ <Settings className="mr-2 size-4" />
996
+ <span>Settings</span>
997
+ </CommandItem>
998
+ </CommandGroup>
999
+ <CommandSeparator />
1000
+ <CommandGroup heading="Settings">
1001
+ <CommandItem>
1002
+ <User className="mr-2 size-4" />
1003
+ <span>Profile</span>
1004
+ </CommandItem>
1005
+ <CommandItem>
1006
+ <Mail className="mr-2 size-4" />
1007
+ <span>Mail</span>
1008
+ </CommandItem>
1009
+ </CommandGroup>
1010
+ </CommandList>
1011
+ </Command>
1012
+ </CardContent>
1013
+ </Card>
1014
+
1015
+ {/* Collapsible + HoverCard */}
1016
+ <Card>
1017
+ <CardHeader>
1018
+ <CardTitle className="text-base">Expandable Sections</CardTitle>
1019
+ </CardHeader>
1020
+ <CardContent className="space-y-3">
1021
+ <Collapsible open={collapsibleOpen} onOpenChange={setCollapsibleOpen}>
1022
+ <div className="flex items-center justify-between rounded-lg border px-3 py-2">
1023
+ <span className="text-sm font-medium">3 starred repositories</span>
1024
+ <CollapsibleTrigger asChild>
1025
+ <Button variant="ghost" size="icon" className="size-7">
1026
+ <ChevronsUpDown className="size-3.5" />
1027
+ </Button>
1028
+ </CollapsibleTrigger>
1029
+ </div>
1030
+ <CollapsibleContent className="mt-2 space-y-2">
1031
+ {["shadcn/ui", "vercel/next.js", "tailwindlabs/tailwindcss"].map((repo) => (
1032
+ <div key={repo} className="rounded-lg border px-3 py-2 text-sm">
1033
+ {repo}
1034
+ </div>
1035
+ ))}
1036
+ </CollapsibleContent>
1037
+ </Collapsible>
1038
+ <Separator />
1039
+ <div className="flex items-center gap-2">
1040
+ <span className="text-sm">Hover for info:</span>
1041
+ <HoverCard>
1042
+ <HoverCardTrigger asChild>
1043
+ <Button variant="link" className="h-auto p-0 text-sm">
1044
+ @shadcn
1045
+ </Button>
1046
+ </HoverCardTrigger>
1047
+ <HoverCardContent className="w-72">
1048
+ <div className="flex gap-3">
1049
+ <Avatar>
1050
+ <AvatarFallback>SC</AvatarFallback>
1051
+ </Avatar>
1052
+ <div className="space-y-1">
1053
+ <h4 className="text-sm font-semibold">@shadcn</h4>
1054
+ <p className="text-xs text-muted-foreground">
1055
+ Creator of shadcn/ui. Building in the open.
1056
+ </p>
1057
+ <div className="flex items-center text-xs text-muted-foreground">
1058
+ <CalendarIcon className="mr-1 size-3" />
1059
+ Joined December 2021
1060
+ </div>
1061
+ </div>
1062
+ </div>
1063
+ </HoverCardContent>
1064
+ </HoverCard>
1065
+ </div>
1066
+ </CardContent>
1067
+ </Card>
1068
+
1069
+ {/* Carousel */}
1070
+ <Card>
1071
+ <CardHeader>
1072
+ <CardTitle className="text-base">Carousel</CardTitle>
1073
+ </CardHeader>
1074
+ <CardContent>
1075
+ <Carousel className="mx-auto w-full max-w-xs">
1076
+ <CarouselContent>
1077
+ {Array.from({ length: 5 }, (_, i) => (
1078
+ <CarouselItem key={`slide-${i + 1}`}>
1079
+ <div className="p-1">
1080
+ <Card>
1081
+ <CardContent className="flex aspect-square items-center justify-center p-6">
1082
+ <span className="text-3xl font-semibold">{i + 1}</span>
1083
+ </CardContent>
1084
+ </Card>
1085
+ </div>
1086
+ </CarouselItem>
1087
+ ))}
1088
+ </CarouselContent>
1089
+ <CarouselPrevious />
1090
+ <CarouselNext />
1091
+ </Carousel>
1092
+ </CardContent>
1093
+ </Card>
1094
+
1095
+ {/* Scroll Area + Tags */}
1096
+ <Card>
1097
+ <CardHeader>
1098
+ <CardTitle className="text-base">Components List</CardTitle>
1099
+ <p className="text-sm text-muted-foreground">Scroll to explore all 57 components</p>
1100
+ </CardHeader>
1101
+ <CardContent>
1102
+ <ScrollArea className="h-48 rounded-md border">
1103
+ <div className="p-4 space-y-2">
1104
+ {[
1105
+ "Accordion",
1106
+ "Alert",
1107
+ "Alert Dialog",
1108
+ "Aspect Ratio",
1109
+ "Avatar",
1110
+ "Badge",
1111
+ "Breadcrumb",
1112
+ "Button",
1113
+ "Calendar",
1114
+ "Card",
1115
+ "Carousel",
1116
+ "Chart",
1117
+ "Checkbox",
1118
+ "Collapsible",
1119
+ "Combobox",
1120
+ "Command",
1121
+ "Context Menu",
1122
+ "Dialog",
1123
+ "Drawer",
1124
+ "Dropdown Menu",
1125
+ "Form",
1126
+ "Hover Card",
1127
+ "Input",
1128
+ "Input OTP",
1129
+ "Label",
1130
+ "Menubar",
1131
+ "Navigation Menu",
1132
+ "Pagination",
1133
+ "Popover",
1134
+ "Progress",
1135
+ "Radio Group",
1136
+ "Resizable",
1137
+ "Scroll Area",
1138
+ "Select",
1139
+ "Separator",
1140
+ "Sheet",
1141
+ "Sidebar",
1142
+ "Skeleton",
1143
+ "Slider",
1144
+ "Sonner",
1145
+ "Spinner",
1146
+ "Switch",
1147
+ "Table",
1148
+ "Tabs",
1149
+ "Textarea",
1150
+ "Toggle",
1151
+ "Toggle Group",
1152
+ "Tooltip",
1153
+ ].map((comp) => (
1154
+ <div
1155
+ key={comp}
1156
+ className="flex items-center justify-between rounded px-2 py-1 text-sm hover:bg-muted"
1157
+ >
1158
+ <span>{comp}</span>
1159
+ <Badge variant="outline" className="text-xs">
1160
+ installed
1161
+ </Badge>
1162
+ </div>
1163
+ ))}
1164
+ </div>
1165
+ </ScrollArea>
1166
+ </CardContent>
1167
+ </Card>
1168
+
1169
+ {/* Theme Toggle Card */}
1170
+ <Card>
1171
+ <CardHeader>
1172
+ <CardTitle className="text-base">Appearance</CardTitle>
1173
+ <p className="text-sm text-muted-foreground">Customize your experience</p>
1174
+ </CardHeader>
1175
+ <CardContent className="space-y-4">
1176
+ <div className="grid grid-cols-3 gap-2">
1177
+ {[
1178
+ { icon: Sun, label: "Light" },
1179
+ { icon: Moon, label: "Dark" },
1180
+ { icon: Laptop, label: "System" },
1181
+ ].map((theme) => (
1182
+ <Button
1183
+ key={theme.label}
1184
+ variant={theme.label === "System" ? "default" : "outline"}
1185
+ size="sm"
1186
+ className="flex-col gap-1 h-auto py-3"
1187
+ >
1188
+ <theme.icon className="size-4" />
1189
+ <span className="text-xs">{theme.label}</span>
1190
+ </Button>
1191
+ ))}
1192
+ </div>
1193
+ <Separator />
1194
+ <div className="space-y-3">
1195
+ <div className="flex items-center justify-between">
1196
+ <div>
1197
+ <p className="text-sm font-medium">Notifications</p>
1198
+ <p className="text-xs text-muted-foreground">Receive push notifications</p>
1199
+ </div>
1200
+ <Switch defaultChecked />
1201
+ </div>
1202
+ <div className="flex items-center justify-between">
1203
+ <div>
1204
+ <p className="text-sm font-medium">Marketing emails</p>
1205
+ <p className="text-xs text-muted-foreground">Receive emails about new features</p>
1206
+ </div>
1207
+ <Switch />
1208
+ </div>
1209
+ <div className="flex items-center justify-between">
1210
+ <div>
1211
+ <p className="text-sm font-medium">Social notifications</p>
1212
+ <p className="text-xs text-muted-foreground">
1213
+ Receive notifications for friend requests
1214
+ </p>
1215
+ </div>
1216
+ <Switch defaultChecked />
1217
+ </div>
1218
+ </div>
1219
+ </CardContent>
1220
+ </Card>
1221
+
1222
+ {/* User Profile Card */}
1223
+ <Card>
1224
+ <CardContent className="pt-6">
1225
+ <div className="flex flex-col items-center gap-3 text-center">
1226
+ <Avatar className="size-16">
1227
+ <AvatarFallback className="text-lg">JD</AvatarFallback>
1228
+ </Avatar>
1229
+ <div>
1230
+ <h4 className="font-semibold">Jane Doe</h4>
1231
+ <p className="text-sm text-muted-foreground">jane@example.com</p>
1232
+ </div>
1233
+ <div className="flex gap-4 text-center">
1234
+ <div>
1235
+ <p className="text-lg font-semibold">142</p>
1236
+ <p className="text-xs text-muted-foreground">Posts</p>
1237
+ </div>
1238
+ <Separator orientation="vertical" className="h-10" />
1239
+ <div>
1240
+ <p className="text-lg font-semibold">2.4k</p>
1241
+ <p className="text-xs text-muted-foreground">Followers</p>
1242
+ </div>
1243
+ <Separator orientation="vertical" className="h-10" />
1244
+ <div>
1245
+ <p className="text-lg font-semibold">891</p>
1246
+ <p className="text-xs text-muted-foreground">Following</p>
1247
+ </div>
1248
+ </div>
1249
+ <div className="flex gap-2 w-full">
1250
+ <Button size="sm" className="flex-1">
1251
+ Follow
1252
+ </Button>
1253
+ <Button size="sm" variant="outline" className="flex-1">
1254
+ Message
1255
+ </Button>
1256
+ </div>
1257
+ </div>
1258
+ </CardContent>
1259
+ </Card>
1260
+ </div>
1261
+ );
1262
+ }