create-bluecopa-react-app 1.0.19 → 1.0.21

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.
@@ -1,12 +1,24 @@
1
- import React, { useState } from 'react';
1
+ import React, { useState } from "react";
2
2
  import { AppSidebar } from "~/components/app-sidebar";
3
3
  import { SiteHeader } from "~/components/site-header";
4
4
  import { SidebarInset, SidebarProvider } from "~/components/ui/sidebar";
5
- import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "~/components/ui/card";
5
+ import {
6
+ Card,
7
+ CardContent,
8
+ CardDescription,
9
+ CardHeader,
10
+ CardTitle,
11
+ } from "~/components/ui/card";
6
12
  import { Button } from "~/components/ui/button";
7
13
  import { Input } from "~/components/ui/input";
8
14
  import { Label } from "~/components/ui/label";
9
- import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "~/components/ui/select";
15
+ import {
16
+ Select,
17
+ SelectContent,
18
+ SelectItem,
19
+ SelectTrigger,
20
+ SelectValue,
21
+ } from "~/components/ui/select";
10
22
  import { Badge } from "~/components/ui/badge";
11
23
  import { Separator } from "~/components/ui/separator";
12
24
  import { Avatar, AvatarFallback } from "~/components/ui/avatar";
@@ -21,17 +33,260 @@ import {
21
33
  useSubscribeUser,
22
34
  useUnsubscribeUser,
23
35
  useCheckSubscriptionStatus,
24
- copaApi
25
- } from '@bluecopa/react';
26
- import { MessageSquare, Plus, Send, Edit, Trash2, Bell, BellOff, Users } from 'lucide-react';
36
+ useGetAuditLogs,
37
+ useCreateAuditLog,
38
+ } from "@bluecopa/react";
39
+ import {
40
+ MessageSquare,
41
+ Plus,
42
+ Send,
43
+ Edit,
44
+ Trash2,
45
+ Bell,
46
+ BellOff,
47
+ Users,
48
+ } from "lucide-react";
27
49
 
28
50
  // Mock user data - in real app this would come from auth context
29
51
  const MOCK_USER = {
30
- id: 'user-123',
31
- name: 'John Doe',
32
- email: 'john@example.com'
52
+ id: "user-123",
53
+ name: "John Doe",
54
+ email: "john@example.com",
33
55
  };
34
56
 
57
+ // Default values for audit log examples
58
+ const DEFAULT_AUDIT_LOG_REQUEST = {
59
+ entityId: "0TOlmUqx0TKseTn8W6gW",
60
+ source: "UI",
61
+ limit: 20,
62
+ };
63
+
64
+ const DEFAULT_AUDIT_RECORD = [
65
+ {
66
+ "source": "UI",
67
+ "userId": "0TOlmUqx0TKseTn8W6gW",
68
+ "entityId": "0TOlmUqx0TKseTn8W6gW",
69
+ "entityType": "Dataset",
70
+ "action": "CREATE",
71
+ "eventType": "API"
72
+ }
73
+ ];
74
+
75
+ // Get Audit Logs Test Component
76
+ function GetAuditLogsTestSection() {
77
+ const [auditLogRequest, setAuditLogRequest] = useState<string>("");
78
+ const [auditLogsResult, setAuditLogsResult] = useState<any>(null);
79
+
80
+ // Get Audit Logs Hook
81
+ const getAuditLogsMutation = useGetAuditLogs();
82
+
83
+ // Handle Load Example
84
+ const handleLoadExample = () => {
85
+ setAuditLogRequest(JSON.stringify(DEFAULT_AUDIT_LOG_REQUEST, null, 2));
86
+ toast.info(
87
+ 'Example audit log request loaded. Click "Get Audit Logs" to fetch.'
88
+ );
89
+ };
90
+
91
+ // Handle Get Audit Logs
92
+ const handleGetAuditLogs = async () => {
93
+ if (!auditLogRequest) {
94
+ toast.error("Please enter audit log request (JSON)");
95
+ return;
96
+ }
97
+ try {
98
+ let parsedRequest;
99
+ try {
100
+ parsedRequest = JSON.parse(auditLogRequest);
101
+ } catch (e) {
102
+ toast.error("Invalid JSON format");
103
+ return;
104
+ }
105
+
106
+ const result = await getAuditLogsMutation.mutateAsync(parsedRequest);
107
+ setAuditLogsResult(result);
108
+ toast.success("Audit logs loaded! Check console for data.");
109
+ } catch (error: any) {
110
+ console.error("Get audit logs error:", error);
111
+ toast.error(`Get audit logs failed: ${error.message}`);
112
+ }
113
+ };
114
+
115
+ return (
116
+ <Card className="mb-6">
117
+ <CardHeader>
118
+ <CardTitle>Get Audit Logs Operations Test</CardTitle>
119
+ <CardDescription>Get audit logs with filter criteria</CardDescription>
120
+ </CardHeader>
121
+ <CardContent className="space-y-4">
122
+ <div className="space-y-2">
123
+ <Label htmlFor="auditLogRequest">Audit Log Request (JSON)</Label>
124
+ <div className="flex gap-2 mb-2">
125
+ <Button onClick={handleLoadExample} variant="outline" type="button">
126
+ Load Example
127
+ </Button>
128
+ </div>
129
+ <textarea
130
+ id="auditLogRequest"
131
+ value={auditLogRequest}
132
+ onChange={(e) => setAuditLogRequest(e.target.value)}
133
+ placeholder="Enter audit log request JSON"
134
+ className="w-full min-h-[150px] p-2 border rounded-md font-mono text-xs"
135
+ />
136
+ <p className="text-xs text-muted-foreground">
137
+ Example: Click "Load Example" button above to load sample request
138
+ </p>
139
+ </div>
140
+
141
+ <div className="flex gap-4">
142
+ <Button
143
+ onClick={handleGetAuditLogs}
144
+ disabled={getAuditLogsMutation.isPending || !auditLogRequest}
145
+ variant="default"
146
+ >
147
+ {getAuditLogsMutation.isPending ? "Loading..." : "Get Audit Logs"}
148
+ </Button>
149
+ </div>
150
+
151
+ {/* Status Messages */}
152
+ {getAuditLogsMutation.isError && (
153
+ <p className="text-red-500">
154
+ Get Error: {getAuditLogsMutation.error?.message}
155
+ </p>
156
+ )}
157
+ {getAuditLogsMutation.isSuccess && auditLogsResult && (
158
+ <p className="text-green-500">
159
+ ✓ Audit logs loaded successfully (Count:{" "}
160
+ {auditLogsResult.count || 0})
161
+ </p>
162
+ )}
163
+
164
+ {/* Audit Logs Result Preview */}
165
+ {auditLogsResult && (
166
+ <div className="mt-4 p-4 bg-muted rounded-lg">
167
+ <p className="text-sm font-semibold mb-2">Audit Logs Result:</p>
168
+ <pre className="text-xs overflow-auto max-h-60">
169
+ {JSON.stringify(auditLogsResult, null, 2)}
170
+ </pre>
171
+ </div>
172
+ )}
173
+ </CardContent>
174
+ </Card>
175
+ );
176
+ }
177
+
178
+ // Create Audit Log Test Component
179
+ function CreateAuditLogTestSection() {
180
+ const [auditRecords, setAuditRecords] = useState<string>("");
181
+ const [createResult, setCreateResult] = useState<any>(null);
182
+
183
+ // Create Audit Log Hook
184
+ const createAuditLogMutation = useCreateAuditLog();
185
+
186
+ // Handle Load Example
187
+ const handleLoadExample = () => {
188
+ const exampleRecords = DEFAULT_AUDIT_RECORD;
189
+ setAuditRecords(JSON.stringify(exampleRecords, null, 2));
190
+ toast.info(
191
+ 'Example audit record loaded. Click "Create Audit Log" to create.'
192
+ );
193
+ };
194
+
195
+ // Handle Create Audit Log
196
+ const handleCreateAuditLog = async () => {
197
+ if (!auditRecords) {
198
+ toast.error("Please enter audit records (JSON array)");
199
+ return;
200
+ }
201
+ try {
202
+ let parsedRecords;
203
+ try {
204
+ parsedRecords = JSON.parse(auditRecords);
205
+ } catch (e) {
206
+ toast.error("Invalid JSON format");
207
+ return;
208
+ }
209
+
210
+ if (!Array.isArray(parsedRecords)) {
211
+ toast.error("Audit records must be an array");
212
+ return;
213
+ }
214
+
215
+ const result = await createAuditLogMutation.mutateAsync({
216
+ auditRecords: parsedRecords,
217
+ });
218
+ console.log("Audit log created:", result);
219
+ setCreateResult(result);
220
+ toast.success("Audit log created successfully! Check console for data.");
221
+ } catch (error: any) {
222
+ console.error("Create audit log error:", error);
223
+ toast.error(`Create audit log failed: ${error.message}`);
224
+ }
225
+ };
226
+
227
+ return (
228
+ <Card className="mb-6">
229
+ <CardHeader>
230
+ <CardTitle>Create Audit Log Operations Test</CardTitle>
231
+ <CardDescription>Create audit log records</CardDescription>
232
+ </CardHeader>
233
+ <CardContent className="space-y-4">
234
+ <div className="space-y-2">
235
+ <Label htmlFor="auditRecords">Audit Records (JSON Array)</Label>
236
+ <div className="flex gap-2 mb-2">
237
+ <Button onClick={handleLoadExample} variant="outline" type="button">
238
+ Load Example
239
+ </Button>
240
+ </div>
241
+ <textarea
242
+ id="auditRecords"
243
+ value={auditRecords}
244
+ onChange={(e) => setAuditRecords(e.target.value)}
245
+ placeholder="Enter audit records as JSON array"
246
+ className="w-full min-h-[200px] p-2 border rounded-md font-mono text-xs"
247
+ />
248
+ <p className="text-xs text-muted-foreground">
249
+ Example: Click "Load Example" button above to load sample audit
250
+ record
251
+ </p>
252
+ </div>
253
+
254
+ <div className="flex gap-4">
255
+ <Button
256
+ onClick={handleCreateAuditLog}
257
+ disabled={createAuditLogMutation.isPending || !auditRecords}
258
+ variant="default"
259
+ >
260
+ {createAuditLogMutation.isPending
261
+ ? "Creating..."
262
+ : "Create Audit Log"}
263
+ </Button>
264
+ </div>
265
+
266
+ {/* Status Messages */}
267
+ {createAuditLogMutation.isError && (
268
+ <p className="text-red-500">
269
+ Create Error: {createAuditLogMutation.error?.message}
270
+ </p>
271
+ )}
272
+ {createAuditLogMutation.isSuccess && createResult && (
273
+ <p className="text-green-500">✓ Audit log created successfully</p>
274
+ )}
275
+
276
+ {/* Create Result Preview */}
277
+ {createResult && (
278
+ <div className="mt-4 p-4 bg-muted rounded-lg">
279
+ <p className="text-sm font-semibold mb-2">Create Result:</p>
280
+ <pre className="text-xs overflow-auto max-h-60">
281
+ {JSON.stringify(createResult, null, 2)}
282
+ </pre>
283
+ </div>
284
+ )}
285
+ </CardContent>
286
+ </Card>
287
+ );
288
+ }
289
+
35
290
  // Component types for better organization
36
291
  interface ThreadFormProps {
37
292
  onThreadCreated: (threadId: string) => void;
@@ -55,15 +310,15 @@ interface SubscriptionControlsProps {
55
310
 
56
311
  // Thread Creation Form Component
57
312
  function ThreadForm({ onThreadCreated }: ThreadFormProps) {
58
- const [componentId, setComponentId] = useState('');
59
- const [componentType, setComponentType] = useState<string>('');
313
+ const [componentId, setComponentId] = useState("");
314
+ const [componentType, setComponentType] = useState<string>("");
60
315
 
61
316
  const createThreadMutation = useCreateThread({
62
317
  onSuccess: (data) => {
63
- toast.success('Thread created successfully!');
64
- onThreadCreated(data.data.id || '');
65
- setComponentId('');
66
- setComponentType('');
318
+ toast.success("Thread created successfully!");
319
+ onThreadCreated(data.data.id || "");
320
+ setComponentId("");
321
+ setComponentType("");
67
322
  },
68
323
  onError: (error) => {
69
324
  toast.error(`Failed to create thread: ${error.message}`);
@@ -73,7 +328,7 @@ function ThreadForm({ onThreadCreated }: ThreadFormProps) {
73
328
  const handleSubmit = (e: React.FormEvent) => {
74
329
  e.preventDefault();
75
330
  if (!componentId || !componentType) {
76
- toast.error('Please fill in all fields');
331
+ toast.error("Please fill in all fields");
77
332
  return;
78
333
  }
79
334
 
@@ -123,12 +378,12 @@ function ThreadForm({ onThreadCreated }: ThreadFormProps) {
123
378
  </SelectContent>
124
379
  </Select>
125
380
  </div>
126
- <Button
127
- type="submit"
381
+ <Button
382
+ type="submit"
128
383
  disabled={createThreadMutation.isPending}
129
384
  className="w-full"
130
385
  >
131
- {createThreadMutation.isPending ? 'Creating...' : 'Create Thread'}
386
+ {createThreadMutation.isPending ? "Creating..." : "Create Thread"}
132
387
  </Button>
133
388
  </form>
134
389
  </CardContent>
@@ -138,12 +393,12 @@ function ThreadForm({ onThreadCreated }: ThreadFormProps) {
138
393
 
139
394
  // Comment Form Component
140
395
  function CommentForm({ threadId, onCommentPosted }: CommentFormProps) {
141
- const [comment, setComment] = useState('');
396
+ const [comment, setComment] = useState("");
142
397
 
143
398
  const postCommentMutation = usePostComment({
144
399
  onSuccess: () => {
145
- toast.success('Comment posted successfully!');
146
- setComment('');
400
+ toast.success("Comment posted successfully!");
401
+ setComment("");
147
402
  onCommentPosted();
148
403
  },
149
404
  onError: (error) => {
@@ -154,7 +409,7 @@ function CommentForm({ threadId, onCommentPosted }: CommentFormProps) {
154
409
  const handleSubmit = (e: React.FormEvent) => {
155
410
  e.preventDefault();
156
411
  if (!comment.trim()) {
157
- toast.error('Please enter a comment');
412
+ toast.error("Please enter a comment");
158
413
  return;
159
414
  }
160
415
 
@@ -162,7 +417,7 @@ function CommentForm({ threadId, onCommentPosted }: CommentFormProps) {
162
417
  data: {
163
418
  chatThreadId: threadId,
164
419
  comment: comment.trim(),
165
- parentId: threadId
420
+ parentId: threadId,
166
421
  },
167
422
  });
168
423
  };
@@ -187,12 +442,12 @@ function CommentForm({ threadId, onCommentPosted }: CommentFormProps) {
187
442
  className="min-h-[80px]"
188
443
  />
189
444
  </div>
190
- <Button
191
- type="submit"
445
+ <Button
446
+ type="submit"
192
447
  disabled={postCommentMutation.isPending}
193
448
  className="w-full"
194
449
  >
195
- {postCommentMutation.isPending ? 'Posting...' : 'Post Comment'}
450
+ {postCommentMutation.isPending ? "Posting..." : "Post Comment"}
196
451
  </Button>
197
452
  </form>
198
453
  </CardContent>
@@ -201,13 +456,17 @@ function CommentForm({ threadId, onCommentPosted }: CommentFormProps) {
201
456
  }
202
457
 
203
458
  // Individual Comment Component
204
- function CommentItem({ comment, onCommentUpdated, onCommentDeleted }: CommentItemProps) {
459
+ function CommentItem({
460
+ comment,
461
+ onCommentUpdated,
462
+ onCommentDeleted,
463
+ }: CommentItemProps) {
205
464
  const [isEditing, setIsEditing] = useState(false);
206
- const [editText, setEditText] = useState(comment.comment || '');
465
+ const [editText, setEditText] = useState(comment.comment || "");
207
466
 
208
467
  const updateCommentMutation = useUpdateComment({
209
468
  onSuccess: () => {
210
- toast.success('Comment updated successfully!');
469
+ toast.success("Comment updated successfully!");
211
470
  setIsEditing(false);
212
471
  onCommentUpdated();
213
472
  },
@@ -218,7 +477,7 @@ function CommentItem({ comment, onCommentUpdated, onCommentDeleted }: CommentIte
218
477
 
219
478
  const deleteCommentMutation = useDeleteComment({
220
479
  onSuccess: () => {
221
- toast.success('Comment deleted successfully!');
480
+ toast.success("Comment deleted successfully!");
222
481
  onCommentDeleted();
223
482
  },
224
483
  onError: (error) => {
@@ -228,7 +487,7 @@ function CommentItem({ comment, onCommentUpdated, onCommentDeleted }: CommentIte
228
487
 
229
488
  const handleUpdate = () => {
230
489
  if (!editText.trim()) {
231
- toast.error('Comment cannot be empty');
490
+ toast.error("Comment cannot be empty");
232
491
  return;
233
492
  }
234
493
 
@@ -242,7 +501,7 @@ function CommentItem({ comment, onCommentUpdated, onCommentDeleted }: CommentIte
242
501
  };
243
502
 
244
503
  const handleDelete = () => {
245
- if (window.confirm('Are you sure you want to delete this comment?')) {
504
+ if (window.confirm("Are you sure you want to delete this comment?")) {
246
505
  deleteCommentMutation.mutate(comment.id);
247
506
  }
248
507
  };
@@ -253,13 +512,17 @@ function CommentItem({ comment, onCommentUpdated, onCommentDeleted }: CommentIte
253
512
  <div className="flex items-center gap-3">
254
513
  <Avatar className="h-8 w-8">
255
514
  <AvatarFallback>
256
- {comment.createdBy?.charAt(0)?.toUpperCase() || 'U'}
515
+ {comment.createdBy?.charAt(0)?.toUpperCase() || "U"}
257
516
  </AvatarFallback>
258
517
  </Avatar>
259
518
  <div>
260
- <p className="font-medium text-sm">{comment.createdBy || 'Unknown User'}</p>
519
+ <p className="font-medium text-sm">
520
+ {comment.createdBy || "Unknown User"}
521
+ </p>
261
522
  <p className="text-xs text-muted-foreground">
262
- {comment.createdDate ? new Date(comment.createdDate).toLocaleString() : 'Just now'}
523
+ {comment.createdDate
524
+ ? new Date(comment.createdDate).toLocaleString()
525
+ : "Just now"}
263
526
  </p>
264
527
  </div>
265
528
  </div>
@@ -296,14 +559,14 @@ function CommentItem({ comment, onCommentUpdated, onCommentDeleted }: CommentIte
296
559
  onClick={handleUpdate}
297
560
  disabled={updateCommentMutation.isPending}
298
561
  >
299
- {updateCommentMutation.isPending ? 'Saving...' : 'Save'}
562
+ {updateCommentMutation.isPending ? "Saving..." : "Save"}
300
563
  </Button>
301
564
  <Button
302
565
  size="sm"
303
566
  variant="outline"
304
567
  onClick={() => {
305
568
  setIsEditing(false);
306
- setEditText(comment.comment || '');
569
+ setEditText(comment.comment || "");
307
570
  }}
308
571
  >
309
572
  Cancel
@@ -319,11 +582,14 @@ function CommentItem({ comment, onCommentUpdated, onCommentDeleted }: CommentIte
319
582
 
320
583
  // Subscription Controls Component
321
584
  function SubscriptionControls({ userId, threadId }: SubscriptionControlsProps) {
322
- const { data: subscriptionStatus, isLoading } = useCheckSubscriptionStatus(userId, threadId);
585
+ const { data: subscriptionStatus, isLoading } = useCheckSubscriptionStatus(
586
+ userId,
587
+ threadId
588
+ );
323
589
 
324
590
  const subscribeUserMutation = useSubscribeUser({
325
591
  onSuccess: () => {
326
- toast.success('Successfully subscribed to thread!');
592
+ toast.success("Successfully subscribed to thread!");
327
593
  },
328
594
  onError: (error) => {
329
595
  toast.error(`Failed to subscribe: ${error.message}`);
@@ -332,7 +598,7 @@ function SubscriptionControls({ userId, threadId }: SubscriptionControlsProps) {
332
598
 
333
599
  const unsubscribeUserMutation = useUnsubscribeUser({
334
600
  onSuccess: () => {
335
- toast.success('Successfully unsubscribed from thread!');
601
+ toast.success("Successfully unsubscribed from thread!");
336
602
  },
337
603
  onError: (error) => {
338
604
  toast.error(`Failed to unsubscribe: ${error.message}`);
@@ -363,7 +629,9 @@ function SubscriptionControls({ userId, threadId }: SubscriptionControlsProps) {
363
629
  variant={isSubscribed ? "outline" : "default"}
364
630
  size="sm"
365
631
  onClick={isSubscribed ? handleUnsubscribe : handleSubscribe}
366
- disabled={subscribeUserMutation.isPending || unsubscribeUserMutation.isPending}
632
+ disabled={
633
+ subscribeUserMutation.isPending || unsubscribeUserMutation.isPending
634
+ }
367
635
  >
368
636
  {isSubscribed ? (
369
637
  <>
@@ -386,12 +654,12 @@ function SubscriptionControls({ userId, threadId }: SubscriptionControlsProps) {
386
654
 
387
655
  // Main Comments Page Component
388
656
  export default function CommentsPage() {
389
- const [selectedThreadId, setSelectedThreadId] = useState<string>('');
657
+ const [selectedThreadId, setSelectedThreadId] = useState<string>("");
390
658
 
391
- const {
392
- data: commentsData,
393
- isLoading: commentsLoading,
394
- refetch: refetchComments
659
+ const {
660
+ data: commentsData,
661
+ isLoading: commentsLoading,
662
+ refetch: refetchComments,
395
663
  } = useGetCommentsByThreadId(selectedThreadId, {
396
664
  enabled: !!selectedThreadId,
397
665
  });
@@ -418,6 +686,10 @@ export default function CommentsPage() {
418
686
  <SiteHeader />
419
687
  <div className="flex flex-1 flex-col">
420
688
  <div className="@container/main flex flex-1 flex-col gap-6 p-6">
689
+ {/* Audit Log Test Sections */}
690
+ <GetAuditLogsTestSection />
691
+ <CreateAuditLogTestSection />
692
+
421
693
  {/* Page Header */}
422
694
  <div className="flex items-center justify-between">
423
695
  <div>
@@ -440,14 +712,14 @@ export default function CommentsPage() {
440
712
  {/* Left Column - Thread Creation */}
441
713
  <div className="space-y-6">
442
714
  <ThreadForm onThreadCreated={handleThreadCreated} />
443
-
715
+
444
716
  {selectedThreadId && (
445
717
  <>
446
- <CommentForm
447
- threadId={selectedThreadId}
448
- onCommentPosted={handleCommentAction}
718
+ <CommentForm
719
+ threadId={selectedThreadId}
720
+ onCommentPosted={handleCommentAction}
449
721
  />
450
-
722
+
451
723
  <Card>
452
724
  <CardHeader>
453
725
  <CardTitle className="flex items-center gap-2">
@@ -459,9 +731,9 @@ export default function CommentsPage() {
459
731
  </CardDescription>
460
732
  </CardHeader>
461
733
  <CardContent>
462
- <SubscriptionControls
463
- userId={MOCK_USER.id}
464
- threadId={selectedThreadId}
734
+ <SubscriptionControls
735
+ userId={MOCK_USER.id}
736
+ threadId={selectedThreadId}
465
737
  />
466
738
  </CardContent>
467
739
  </Card>
@@ -475,10 +747,9 @@ export default function CommentsPage() {
475
747
  <CardHeader>
476
748
  <CardTitle>Comments</CardTitle>
477
749
  <CardDescription>
478
- {selectedThreadId
750
+ {selectedThreadId
479
751
  ? `Comments for thread ${selectedThreadId.slice(0, 8)}...`
480
- : 'Create a thread to see comments'
481
- }
752
+ : "Create a thread to see comments"}
482
753
  </CardDescription>
483
754
  </CardHeader>
484
755
  <CardContent>
@@ -524,13 +795,17 @@ export default function CommentsPage() {
524
795
  <CardContent className="space-y-2">
525
796
  <div className="flex justify-between items-center">
526
797
  <span className="text-sm">Thread Selected:</span>
527
- <Badge variant={selectedThreadId ? "default" : "secondary"}>
798
+ <Badge
799
+ variant={selectedThreadId ? "default" : "secondary"}
800
+ >
528
801
  {selectedThreadId ? "Yes" : "No"}
529
802
  </Badge>
530
803
  </div>
531
804
  <div className="flex justify-between items-center">
532
805
  <span className="text-sm">Comments Loading:</span>
533
- <Badge variant={commentsLoading ? "default" : "secondary"}>
806
+ <Badge
807
+ variant={commentsLoading ? "default" : "secondary"}
808
+ >
534
809
  {commentsLoading ? "Yes" : "No"}
535
810
  </Badge>
536
811
  </div>
@@ -5,6 +5,7 @@ import Comments from "./routes/comments";
5
5
  import Websocket from "./routes/websocket";
6
6
  import Payments from "./routes/payments";
7
7
  import Statements from "./routes/statements";
8
+ import ApiTest from "./routes/apitest";
8
9
 
9
10
  export default function RouteConfig() {
10
11
  return (
@@ -14,6 +15,7 @@ export default function RouteConfig() {
14
15
  <Route path="/websocket" element={<Websocket />} />
15
16
  <Route path="/payments" element={<Payments />} />
16
17
  <Route path="/statements" element={<Statements />} />
18
+ <Route path="/apitest" element={<ApiTest />} />
17
19
  <Route path="*" element={<Navigate to="/" replace />} />
18
20
  </Routes>
19
21
  );
@@ -1,4 +1,4 @@
1
- System.register(['./__federation_fn_import-CzfA7kmP.js', './client-uh-HfYnI.js'], (function (exports, module) {
1
+ System.register(['./__federation_fn_import-CzfA7kmP.js', './client-CjZD2orr.js'], (function (exports, module) {
2
2
  'use strict';
3
3
  var importShared, clientExports, jsxRuntimeExports, MemoryRouter, BrowserRouter, App;
4
4
  return {