create-bluecopa-react-app 1.0.41 → 1.0.42

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 (102) hide show
  1. package/README.md +7 -5
  2. package/package.json +1 -1
  3. package/templates/latest/.claude/settings.local.json +56 -0
  4. package/templates/latest/.env.example +8 -0
  5. package/templates/latest/Agent.md +598 -775
  6. package/templates/latest/CLAUDE.md +759 -0
  7. package/templates/latest/README.md +11 -2
  8. package/templates/latest/app/app.css +292 -85
  9. package/templates/latest/app/app.tsx +48 -39
  10. package/templates/latest/app/components/bluecopa-logo.tsx +20 -0
  11. package/templates/latest/app/components/charts/bar-chart.tsx +132 -0
  12. package/templates/latest/app/components/charts/base-chart.tsx +149 -0
  13. package/templates/latest/app/components/charts/chart-provider.tsx +71 -0
  14. package/templates/latest/app/components/charts/chart-theme.ts +262 -0
  15. package/templates/latest/app/components/charts/chart-utils.ts +142 -0
  16. package/templates/latest/app/components/charts/donut-chart.tsx +110 -0
  17. package/templates/latest/app/components/charts/index.ts +5 -0
  18. package/templates/latest/app/components/layouts/app-layout.tsx +22 -0
  19. package/templates/latest/app/components/layouts/app-sidebar.tsx +88 -0
  20. package/templates/latest/app/components/layouts/nav-main.tsx +50 -0
  21. package/templates/latest/app/components/layouts/nav-user.tsx +38 -0
  22. package/templates/latest/app/components/layouts/site-header.tsx +93 -0
  23. package/templates/latest/app/components/loading-screen.tsx +41 -0
  24. package/templates/latest/app/components/ui/ag-grid-table.tsx +79 -0
  25. package/templates/latest/app/components/ui/button.tsx +23 -23
  26. package/templates/latest/app/components/ui/card.tsx +20 -20
  27. package/templates/latest/app/components/ui/dropdown-menu.tsx +54 -49
  28. package/templates/latest/app/components/ui/input.tsx +8 -8
  29. package/templates/latest/app/components/ui/label.tsx +8 -8
  30. package/templates/latest/app/components/ui/separator.tsx +7 -7
  31. package/templates/latest/app/components/ui/sheet.tsx +43 -32
  32. package/templates/latest/app/components/ui/sidebar.tsx +240 -235
  33. package/templates/latest/app/components/ui/skeleton.tsx +4 -4
  34. package/templates/latest/app/components/ui/sonner.tsx +6 -9
  35. package/templates/latest/app/components/ui/tabs.tsx +15 -15
  36. package/templates/latest/app/components/ui/tooltip.tsx +18 -12
  37. package/templates/latest/app/constants/index.ts +31 -0
  38. package/templates/latest/app/contexts/app-context.tsx +201 -0
  39. package/templates/latest/app/hooks/use-mobile.ts +13 -12
  40. package/templates/latest/app/main.tsx +1 -1
  41. package/templates/latest/app/pages/dashboard.tsx +246 -0
  42. package/templates/latest/app/pages/payments.tsx +182 -0
  43. package/templates/latest/app/pages/settings.tsx +128 -0
  44. package/templates/latest/app/routes/index.tsx +19 -0
  45. package/templates/latest/app/single-spa.tsx +69 -186
  46. package/templates/latest/app/types/index.ts +37 -0
  47. package/templates/latest/app/utils/ag-grid-datasource.ts +63 -0
  48. package/templates/latest/app/utils/ag-grid-license.ts +12 -0
  49. package/templates/latest/app/utils/ag-grid-theme.ts +9 -0
  50. package/templates/latest/app/utils/component-style.ts +7 -0
  51. package/templates/latest/app/utils/style-drivers.ts +24 -0
  52. package/templates/latest/app/utils/utils.ts +10 -0
  53. package/templates/latest/components.json +3 -3
  54. package/templates/latest/index.html +30 -2
  55. package/templates/latest/package-lock.json +15 -401
  56. package/templates/latest/package.json +8 -18
  57. package/templates/latest/preview/index.html +125 -285
  58. package/templates/latest/public/favicon.svg +1 -0
  59. package/templates/latest/vite.config.ts +2 -8
  60. package/templates/latest/app/components/app-sidebar.tsx +0 -182
  61. package/templates/latest/app/components/chart-area-interactive.tsx +0 -290
  62. package/templates/latest/app/components/data-table.tsx +0 -807
  63. package/templates/latest/app/components/nav-documents.tsx +0 -92
  64. package/templates/latest/app/components/nav-main.tsx +0 -40
  65. package/templates/latest/app/components/nav-secondary.tsx +0 -42
  66. package/templates/latest/app/components/nav-user.tsx +0 -111
  67. package/templates/latest/app/components/section-cards.tsx +0 -102
  68. package/templates/latest/app/components/site-header.tsx +0 -28
  69. package/templates/latest/app/components/ui/avatar.tsx +0 -53
  70. package/templates/latest/app/components/ui/badge.tsx +0 -46
  71. package/templates/latest/app/components/ui/breadcrumb.tsx +0 -109
  72. package/templates/latest/app/components/ui/chart.tsx +0 -352
  73. package/templates/latest/app/components/ui/checkbox.tsx +0 -30
  74. package/templates/latest/app/components/ui/drawer.tsx +0 -139
  75. package/templates/latest/app/components/ui/select.tsx +0 -183
  76. package/templates/latest/app/components/ui/table.tsx +0 -117
  77. package/templates/latest/app/components/ui/toggle-group.tsx +0 -73
  78. package/templates/latest/app/components/ui/toggle.tsx +0 -47
  79. package/templates/latest/app/data/data.json +0 -614
  80. package/templates/latest/app/data/mock-payments.json +0 -122
  81. package/templates/latest/app/data/mock-transactions.json +0 -128
  82. package/templates/latest/app/hooks/use-bluecopa-user.ts +0 -37
  83. package/templates/latest/app/lib/utils.ts +0 -6
  84. package/templates/latest/app/routes/apitest.tsx +0 -2118
  85. package/templates/latest/app/routes/comments.tsx +0 -588
  86. package/templates/latest/app/routes/dashboard.tsx +0 -36
  87. package/templates/latest/app/routes/payments.tsx +0 -342
  88. package/templates/latest/app/routes/statements.tsx +0 -493
  89. package/templates/latest/app/routes/websocket.tsx +0 -450
  90. package/templates/latest/app/routes.tsx +0 -22
  91. package/templates/latest/dist/assets/__federation_expose_App-D-lv9y21.js +0 -161
  92. package/templates/latest/dist/assets/__federation_fn_import-CzfA7kmP.js +0 -438
  93. package/templates/latest/dist/assets/__federation_shared_react-Bp6HVBS4.js +0 -16
  94. package/templates/latest/dist/assets/__federation_shared_react-dom-BCcRGiYp.js +0 -17
  95. package/templates/latest/dist/assets/client-Dms8K6Dw.js +0 -78879
  96. package/templates/latest/dist/assets/index-BrhXrqF7.js +0 -60
  97. package/templates/latest/dist/assets/index-BzNimew1.js +0 -69
  98. package/templates/latest/dist/assets/index-DMFtQdNS.js +0 -412
  99. package/templates/latest/dist/assets/remoteEntry.css +0 -3996
  100. package/templates/latest/dist/assets/remoteEntry.js +0 -88
  101. package/templates/latest/dist/favicon.ico +0 -0
  102. package/templates/latest/dist/index.html +0 -19
@@ -1,588 +0,0 @@
1
- import React, { useState } from "react";
2
- import { AppSidebar } from "~/components/app-sidebar";
3
- import { SiteHeader } from "~/components/site-header";
4
- import { SidebarInset, SidebarProvider } from "~/components/ui/sidebar";
5
- import {
6
- Card,
7
- CardContent,
8
- CardDescription,
9
- CardHeader,
10
- CardTitle,
11
- } from "~/components/ui/card";
12
- import { Button } from "~/components/ui/button";
13
- import { Input } from "~/components/ui/input";
14
- import { Label } from "~/components/ui/label";
15
- import {
16
- Select,
17
- SelectContent,
18
- SelectItem,
19
- SelectTrigger,
20
- SelectValue,
21
- } from "~/components/ui/select";
22
- import { Badge } from "~/components/ui/badge";
23
- import { Separator } from "~/components/ui/separator";
24
- import { Avatar, AvatarFallback } from "~/components/ui/avatar";
25
- import { Skeleton } from "~/components/ui/skeleton";
26
- import { toast } from "sonner";
27
- import {
28
- useCreateThread,
29
- useGetCommentsByThreadId,
30
- usePostComment,
31
- useUpdateComment,
32
- useDeleteComment,
33
- useSubscribeUser,
34
- useUnsubscribeUser,
35
- useCheckSubscriptionStatus,
36
- } from "@bluecopa/react";
37
- import {
38
- MessageSquare,
39
- Plus,
40
- Send,
41
- Edit,
42
- Trash2,
43
- Bell,
44
- BellOff,
45
- Users,
46
- } from "lucide-react";
47
-
48
- // Mock user data - in real app this would come from auth context
49
- const MOCK_USER = {
50
- id: "user-123",
51
- name: "John Doe",
52
- email: "john@example.com",
53
- };
54
-
55
- // Component types for better organization
56
- interface ThreadFormProps {
57
- onThreadCreated: (threadId: string) => void;
58
- }
59
-
60
- interface CommentFormProps {
61
- threadId: string;
62
- onCommentPosted: () => void;
63
- }
64
-
65
- interface CommentItemProps {
66
- comment: any;
67
- onCommentUpdated: () => void;
68
- onCommentDeleted: () => void;
69
- }
70
-
71
- interface SubscriptionControlsProps {
72
- userId: string;
73
- threadId: string;
74
- }
75
-
76
- // Thread Creation Form Component
77
- function ThreadForm({ onThreadCreated }: ThreadFormProps) {
78
- const [componentId, setComponentId] = useState("");
79
- const [componentType, setComponentType] = useState<string>("");
80
-
81
- const createThreadMutation = useCreateThread({
82
- onSuccess: (data) => {
83
- toast.success("Thread created successfully!");
84
- onThreadCreated(data.data.id || "");
85
- setComponentId("");
86
- setComponentType("");
87
- },
88
- onError: (error) => {
89
- toast.error(`Failed to create thread: ${error.message}`);
90
- },
91
- });
92
-
93
- const handleSubmit = (e: React.FormEvent) => {
94
- e.preventDefault();
95
- if (!componentId || !componentType) {
96
- toast.error("Please fill in all fields");
97
- return;
98
- }
99
-
100
- createThreadMutation.mutate({
101
- data: {
102
- forComponentId: componentId,
103
- forComponentType: componentType as any,
104
- },
105
- });
106
- };
107
-
108
- return (
109
- <Card>
110
- <CardHeader>
111
- <CardTitle className="flex items-center gap-2">
112
- <Plus className="h-5 w-5" />
113
- Create New Thread
114
- </CardTitle>
115
- <CardDescription>
116
- Start a new discussion thread for a component
117
- </CardDescription>
118
- </CardHeader>
119
- <CardContent>
120
- <form onSubmit={handleSubmit} className="space-y-4">
121
- <div>
122
- <Label htmlFor="componentId">Component ID</Label>
123
- <Input
124
- id="componentId"
125
- value={componentId}
126
- onChange={(e) => setComponentId(e.target.value)}
127
- placeholder="Enter component ID (e.g., workbook-123)"
128
- />
129
- </div>
130
- <div>
131
- <Label htmlFor="componentType">Component Type</Label>
132
- <Select value={componentType} onValueChange={setComponentType}>
133
- <SelectTrigger>
134
- <SelectValue placeholder="Select component type" />
135
- </SelectTrigger>
136
- <SelectContent>
137
- <SelectItem value="WORKBOOK">Workbook</SelectItem>
138
- <SelectItem value="DASHBOARD">Dashboard</SelectItem>
139
- <SelectItem value="WORKSHEET">Worksheet</SelectItem>
140
- <SelectItem value="DATASET">Dataset</SelectItem>
141
- <SelectItem value="PROCESS">Process</SelectItem>
142
- <SelectItem value="FORM">Form</SelectItem>
143
- </SelectContent>
144
- </Select>
145
- </div>
146
- <Button
147
- type="submit"
148
- disabled={createThreadMutation.isPending}
149
- className="w-full"
150
- >
151
- {createThreadMutation.isPending ? "Creating..." : "Create Thread"}
152
- </Button>
153
- </form>
154
- </CardContent>
155
- </Card>
156
- );
157
- }
158
-
159
- // Comment Form Component
160
- function CommentForm({ threadId, onCommentPosted }: CommentFormProps) {
161
- const [comment, setComment] = useState("");
162
-
163
- const postCommentMutation = usePostComment({
164
- onSuccess: () => {
165
- toast.success("Comment posted successfully!");
166
- setComment("");
167
- onCommentPosted();
168
- },
169
- onError: (error) => {
170
- toast.error(`Failed to post comment: ${error.message}`);
171
- },
172
- });
173
-
174
- const handleSubmit = (e: React.FormEvent) => {
175
- e.preventDefault();
176
- if (!comment.trim()) {
177
- toast.error("Please enter a comment");
178
- return;
179
- }
180
-
181
- postCommentMutation.mutate({
182
- data: {
183
- chatThreadId: threadId,
184
- comment: comment.trim(),
185
- parentId: threadId,
186
- },
187
- });
188
- };
189
-
190
- return (
191
- <Card>
192
- <CardHeader>
193
- <CardTitle className="flex items-center gap-2">
194
- <Send className="h-5 w-5" />
195
- Add Comment
196
- </CardTitle>
197
- </CardHeader>
198
- <CardContent>
199
- <form onSubmit={handleSubmit} className="space-y-4">
200
- <div>
201
- <Label htmlFor="comment">Your Comment</Label>
202
- <Input
203
- id="comment"
204
- value={comment}
205
- onChange={(e) => setComment(e.target.value)}
206
- placeholder="Enter your comment..."
207
- className="min-h-[80px]"
208
- />
209
- </div>
210
- <Button
211
- type="submit"
212
- disabled={postCommentMutation.isPending}
213
- className="w-full"
214
- >
215
- {postCommentMutation.isPending ? "Posting..." : "Post Comment"}
216
- </Button>
217
- </form>
218
- </CardContent>
219
- </Card>
220
- );
221
- }
222
-
223
- // Individual Comment Component
224
- function CommentItem({
225
- comment,
226
- onCommentUpdated,
227
- onCommentDeleted,
228
- }: CommentItemProps) {
229
- const [isEditing, setIsEditing] = useState(false);
230
- const [editText, setEditText] = useState(comment.comment || "");
231
-
232
- const updateCommentMutation = useUpdateComment({
233
- onSuccess: () => {
234
- toast.success("Comment updated successfully!");
235
- setIsEditing(false);
236
- onCommentUpdated();
237
- },
238
- onError: (error) => {
239
- toast.error(`Failed to update comment: ${error.message}`);
240
- },
241
- });
242
-
243
- const deleteCommentMutation = useDeleteComment({
244
- onSuccess: () => {
245
- toast.success("Comment deleted successfully!");
246
- onCommentDeleted();
247
- },
248
- onError: (error) => {
249
- toast.error(`Failed to delete comment: ${error.message}`);
250
- },
251
- });
252
-
253
- const handleUpdate = () => {
254
- if (!editText.trim()) {
255
- toast.error("Comment cannot be empty");
256
- return;
257
- }
258
-
259
- updateCommentMutation.mutate({
260
- data: {
261
- ...comment,
262
- comment: editText.trim(),
263
- },
264
- commentId: comment.id,
265
- });
266
- };
267
-
268
- const handleDelete = () => {
269
- if (window.confirm("Are you sure you want to delete this comment?")) {
270
- deleteCommentMutation.mutate(comment.id);
271
- }
272
- };
273
-
274
- return (
275
- <div className="border rounded-lg p-4 space-y-3">
276
- <div className="flex items-start justify-between">
277
- <div className="flex items-center gap-3">
278
- <Avatar className="h-8 w-8">
279
- <AvatarFallback>
280
- {comment.createdBy?.charAt(0)?.toUpperCase() || "U"}
281
- </AvatarFallback>
282
- </Avatar>
283
- <div>
284
- <p className="font-medium text-sm">
285
- {comment.createdBy || "Unknown User"}
286
- </p>
287
- <p className="text-xs text-muted-foreground">
288
- {comment.createdDate
289
- ? new Date(comment.createdDate).toLocaleString()
290
- : "Just now"}
291
- </p>
292
- </div>
293
- </div>
294
- <div className="flex items-center gap-2">
295
- <Button
296
- variant="ghost"
297
- size="sm"
298
- onClick={() => setIsEditing(!isEditing)}
299
- disabled={updateCommentMutation.isPending}
300
- >
301
- <Edit className="h-4 w-4" />
302
- </Button>
303
- <Button
304
- variant="ghost"
305
- size="sm"
306
- onClick={handleDelete}
307
- disabled={deleteCommentMutation.isPending}
308
- >
309
- <Trash2 className="h-4 w-4" />
310
- </Button>
311
- </div>
312
- </div>
313
-
314
- {isEditing ? (
315
- <div className="space-y-2">
316
- <Input
317
- value={editText}
318
- onChange={(e) => setEditText(e.target.value)}
319
- className="min-h-[60px]"
320
- />
321
- <div className="flex gap-2">
322
- <Button
323
- size="sm"
324
- onClick={handleUpdate}
325
- disabled={updateCommentMutation.isPending}
326
- >
327
- {updateCommentMutation.isPending ? "Saving..." : "Save"}
328
- </Button>
329
- <Button
330
- size="sm"
331
- variant="outline"
332
- onClick={() => {
333
- setIsEditing(false);
334
- setEditText(comment.comment || "");
335
- }}
336
- >
337
- Cancel
338
- </Button>
339
- </div>
340
- </div>
341
- ) : (
342
- <p className="text-sm">{comment.comment}</p>
343
- )}
344
- </div>
345
- );
346
- }
347
-
348
- // Subscription Controls Component
349
- function SubscriptionControls({ userId, threadId }: SubscriptionControlsProps) {
350
- const { data: subscriptionStatus, isLoading } = useCheckSubscriptionStatus(
351
- userId,
352
- threadId
353
- );
354
-
355
- const subscribeUserMutation = useSubscribeUser({
356
- onSuccess: () => {
357
- toast.success("Successfully subscribed to thread!");
358
- },
359
- onError: (error) => {
360
- toast.error(`Failed to subscribe: ${error.message}`);
361
- },
362
- });
363
-
364
- const unsubscribeUserMutation = useUnsubscribeUser({
365
- onSuccess: () => {
366
- toast.success("Successfully unsubscribed from thread!");
367
- },
368
- onError: (error) => {
369
- toast.error(`Failed to unsubscribe: ${error.message}`);
370
- },
371
- });
372
-
373
- const handleSubscribe = () => {
374
- subscribeUserMutation.mutate({
375
- params: { userId, threadId },
376
- });
377
- };
378
-
379
- const handleUnsubscribe = () => {
380
- unsubscribeUserMutation.mutate({
381
- params: { userId, threadId },
382
- });
383
- };
384
-
385
- if (isLoading) {
386
- return <Skeleton className="h-10 w-32" />;
387
- }
388
-
389
- const isSubscribed = subscriptionStatus?.data?.isSubscribed;
390
-
391
- return (
392
- <div className="flex items-center gap-2">
393
- <Button
394
- variant={isSubscribed ? "outline" : "default"}
395
- size="sm"
396
- onClick={isSubscribed ? handleUnsubscribe : handleSubscribe}
397
- disabled={
398
- subscribeUserMutation.isPending || unsubscribeUserMutation.isPending
399
- }
400
- >
401
- {isSubscribed ? (
402
- <>
403
- <BellOff className="h-4 w-4 mr-2" />
404
- Unsubscribe
405
- </>
406
- ) : (
407
- <>
408
- <Bell className="h-4 w-4 mr-2" />
409
- Subscribe
410
- </>
411
- )}
412
- </Button>
413
- <Badge variant={isSubscribed ? "default" : "secondary"}>
414
- {isSubscribed ? "Subscribed" : "Not Subscribed"}
415
- </Badge>
416
- </div>
417
- );
418
- }
419
-
420
- // Main Comments Page Component
421
- export default function CommentsPage() {
422
- const [selectedThreadId, setSelectedThreadId] = useState<string>("");
423
-
424
- const {
425
- data: commentsData,
426
- isLoading: commentsLoading,
427
- refetch: refetchComments,
428
- } = useGetCommentsByThreadId(selectedThreadId, {
429
- enabled: !!selectedThreadId,
430
- });
431
-
432
- const handleThreadCreated = (threadId: string) => {
433
- setSelectedThreadId(threadId);
434
- };
435
-
436
- const handleCommentAction = () => {
437
- refetchComments();
438
- };
439
-
440
- return (
441
- <SidebarProvider
442
- style={
443
- {
444
- "--sidebar-width": "calc(var(--spacing) * 72)",
445
- "--header-height": "calc(var(--spacing) * 12)",
446
- } as React.CSSProperties
447
- }
448
- >
449
- <AppSidebar variant="inset" />
450
- <SidebarInset>
451
- <SiteHeader />
452
- <div className="flex flex-1 flex-col">
453
- <div className="@container/main flex flex-1 flex-col gap-6 p-6">
454
- {/* Page Header */}
455
- <div className="flex items-center justify-between">
456
- <div>
457
- <h1 className="text-3xl font-bold tracking-tight flex items-center gap-2">
458
- <MessageSquare className="h-8 w-8" />
459
- Comments API Demo
460
- </h1>
461
- <p className="text-muted-foreground">
462
- Comprehensive example of the chat/comments API functionality
463
- </p>
464
- </div>
465
- {selectedThreadId && (
466
- <Badge variant="outline" className="text-sm">
467
- Thread: {selectedThreadId.slice(0, 8)}...
468
- </Badge>
469
- )}
470
- </div>
471
-
472
- <div className="grid grid-cols-1 lg:grid-cols-2 gap-6">
473
- {/* Left Column - Thread Creation */}
474
- <div className="space-y-6">
475
- <ThreadForm onThreadCreated={handleThreadCreated} />
476
-
477
- {selectedThreadId && (
478
- <>
479
- <CommentForm
480
- threadId={selectedThreadId}
481
- onCommentPosted={handleCommentAction}
482
- />
483
-
484
- <Card>
485
- <CardHeader>
486
- <CardTitle className="flex items-center gap-2">
487
- <Users className="h-5 w-5" />
488
- Subscription Controls
489
- </CardTitle>
490
- <CardDescription>
491
- Manage your subscription to this thread
492
- </CardDescription>
493
- </CardHeader>
494
- <CardContent>
495
- <SubscriptionControls
496
- userId={MOCK_USER.id}
497
- threadId={selectedThreadId}
498
- />
499
- </CardContent>
500
- </Card>
501
- </>
502
- )}
503
- </div>
504
-
505
- {/* Right Column - Comments Display */}
506
- <div className="space-y-6">
507
- <Card>
508
- <CardHeader>
509
- <CardTitle>Comments</CardTitle>
510
- <CardDescription>
511
- {selectedThreadId
512
- ? `Comments for thread ${selectedThreadId.slice(0, 8)}...`
513
- : "Create a thread to see comments"}
514
- </CardDescription>
515
- </CardHeader>
516
- <CardContent>
517
- {!selectedThreadId ? (
518
- <div className="text-center py-8 text-muted-foreground">
519
- <MessageSquare className="h-12 w-12 mx-auto mb-4 opacity-50" />
520
- <p>Create a thread to start the conversation</p>
521
- </div>
522
- ) : commentsLoading ? (
523
- <div className="space-y-4">
524
- {[1, 2, 3].map((i) => (
525
- <div key={i} className="space-y-2">
526
- <Skeleton className="h-4 w-32" />
527
- <Skeleton className="h-16 w-full" />
528
- </div>
529
- ))}
530
- </div>
531
- ) : commentsData?.data?.length === 0 ? (
532
- <div className="text-center py-8 text-muted-foreground">
533
- <MessageSquare className="h-12 w-12 mx-auto mb-4 opacity-50" />
534
- <p>No comments yet. Be the first to comment!</p>
535
- </div>
536
- ) : (
537
- <div className="space-y-4 max-h-96 overflow-y-auto">
538
- {commentsData?.data?.map((comment: any) => (
539
- <CommentItem
540
- key={comment.id}
541
- comment={comment}
542
- onCommentUpdated={handleCommentAction}
543
- onCommentDeleted={handleCommentAction}
544
- />
545
- ))}
546
- </div>
547
- )}
548
- </CardContent>
549
- </Card>
550
-
551
- {/* API Status Card */}
552
- <Card>
553
- <CardHeader>
554
- <CardTitle>API Status</CardTitle>
555
- </CardHeader>
556
- <CardContent className="space-y-2">
557
- <div className="flex justify-between items-center">
558
- <span className="text-sm">Thread Selected:</span>
559
- <Badge
560
- variant={selectedThreadId ? "default" : "secondary"}
561
- >
562
- {selectedThreadId ? "Yes" : "No"}
563
- </Badge>
564
- </div>
565
- <div className="flex justify-between items-center">
566
- <span className="text-sm">Comments Loading:</span>
567
- <Badge
568
- variant={commentsLoading ? "default" : "secondary"}
569
- >
570
- {commentsLoading ? "Yes" : "No"}
571
- </Badge>
572
- </div>
573
- <div className="flex justify-between items-center">
574
- <span className="text-sm">Comments Count:</span>
575
- <Badge variant="outline">
576
- {commentsData?.data?.length || 0}
577
- </Badge>
578
- </div>
579
- </CardContent>
580
- </Card>
581
- </div>
582
- </div>
583
- </div>
584
- </div>
585
- </SidebarInset>
586
- </SidebarProvider>
587
- );
588
- }
@@ -1,36 +0,0 @@
1
- import { AppSidebar } from "~/components/app-sidebar";
2
- import { ChartAreaInteractive } from "~/components/chart-area-interactive";
3
- import { DataTable } from "~/components/data-table";
4
- import { SectionCards } from "~/components/section-cards";
5
- import { SiteHeader } from "~/components/site-header";
6
- import { SidebarInset, SidebarProvider } from "~/components/ui/sidebar";
7
- import data from "~/data/data.json";
8
-
9
- export default function Page() {
10
- return (
11
- <SidebarProvider
12
- style={
13
- {
14
- "--sidebar-width": "calc(var(--spacing) * 72)",
15
- "--header-height": "calc(var(--spacing) * 12)",
16
- } as React.CSSProperties
17
- }
18
- >
19
- <AppSidebar variant="inset" />
20
- <SidebarInset>
21
- <SiteHeader />
22
- <div className="flex flex-1 flex-col">
23
- <div className="@container/main flex flex-1 flex-col gap-2">
24
- <div className="flex flex-col gap-4 py-4 md:gap-6 md:py-6">
25
- <SectionCards />
26
- <div className="px-4 lg:px-6">
27
- <ChartAreaInteractive />
28
- </div>
29
- <DataTable data={data} />
30
- </div>
31
- </div>
32
- </div>
33
- </SidebarInset>
34
- </SidebarProvider>
35
- );
36
- }