create-bluecopa-react-app 1.0.20 → 1.0.22

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,15 +33,23 @@ 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
+ } 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";
27
47
 
28
48
  // Mock user data - in real app this would come from auth context
29
49
  const MOCK_USER = {
30
- id: 'user-123',
31
- name: 'John Doe',
32
- email: 'john@example.com'
50
+ id: "user-123",
51
+ name: "John Doe",
52
+ email: "john@example.com",
33
53
  };
34
54
 
35
55
  // Component types for better organization
@@ -55,15 +75,15 @@ interface SubscriptionControlsProps {
55
75
 
56
76
  // Thread Creation Form Component
57
77
  function ThreadForm({ onThreadCreated }: ThreadFormProps) {
58
- const [componentId, setComponentId] = useState('');
59
- const [componentType, setComponentType] = useState<string>('');
78
+ const [componentId, setComponentId] = useState("");
79
+ const [componentType, setComponentType] = useState<string>("");
60
80
 
61
81
  const createThreadMutation = useCreateThread({
62
82
  onSuccess: (data) => {
63
- toast.success('Thread created successfully!');
64
- onThreadCreated(data.data.id || '');
65
- setComponentId('');
66
- setComponentType('');
83
+ toast.success("Thread created successfully!");
84
+ onThreadCreated(data.data.id || "");
85
+ setComponentId("");
86
+ setComponentType("");
67
87
  },
68
88
  onError: (error) => {
69
89
  toast.error(`Failed to create thread: ${error.message}`);
@@ -73,7 +93,7 @@ function ThreadForm({ onThreadCreated }: ThreadFormProps) {
73
93
  const handleSubmit = (e: React.FormEvent) => {
74
94
  e.preventDefault();
75
95
  if (!componentId || !componentType) {
76
- toast.error('Please fill in all fields');
96
+ toast.error("Please fill in all fields");
77
97
  return;
78
98
  }
79
99
 
@@ -123,12 +143,12 @@ function ThreadForm({ onThreadCreated }: ThreadFormProps) {
123
143
  </SelectContent>
124
144
  </Select>
125
145
  </div>
126
- <Button
127
- type="submit"
146
+ <Button
147
+ type="submit"
128
148
  disabled={createThreadMutation.isPending}
129
149
  className="w-full"
130
150
  >
131
- {createThreadMutation.isPending ? 'Creating...' : 'Create Thread'}
151
+ {createThreadMutation.isPending ? "Creating..." : "Create Thread"}
132
152
  </Button>
133
153
  </form>
134
154
  </CardContent>
@@ -138,12 +158,12 @@ function ThreadForm({ onThreadCreated }: ThreadFormProps) {
138
158
 
139
159
  // Comment Form Component
140
160
  function CommentForm({ threadId, onCommentPosted }: CommentFormProps) {
141
- const [comment, setComment] = useState('');
161
+ const [comment, setComment] = useState("");
142
162
 
143
163
  const postCommentMutation = usePostComment({
144
164
  onSuccess: () => {
145
- toast.success('Comment posted successfully!');
146
- setComment('');
165
+ toast.success("Comment posted successfully!");
166
+ setComment("");
147
167
  onCommentPosted();
148
168
  },
149
169
  onError: (error) => {
@@ -154,7 +174,7 @@ function CommentForm({ threadId, onCommentPosted }: CommentFormProps) {
154
174
  const handleSubmit = (e: React.FormEvent) => {
155
175
  e.preventDefault();
156
176
  if (!comment.trim()) {
157
- toast.error('Please enter a comment');
177
+ toast.error("Please enter a comment");
158
178
  return;
159
179
  }
160
180
 
@@ -162,7 +182,7 @@ function CommentForm({ threadId, onCommentPosted }: CommentFormProps) {
162
182
  data: {
163
183
  chatThreadId: threadId,
164
184
  comment: comment.trim(),
165
- parentId: threadId
185
+ parentId: threadId,
166
186
  },
167
187
  });
168
188
  };
@@ -187,12 +207,12 @@ function CommentForm({ threadId, onCommentPosted }: CommentFormProps) {
187
207
  className="min-h-[80px]"
188
208
  />
189
209
  </div>
190
- <Button
191
- type="submit"
210
+ <Button
211
+ type="submit"
192
212
  disabled={postCommentMutation.isPending}
193
213
  className="w-full"
194
214
  >
195
- {postCommentMutation.isPending ? 'Posting...' : 'Post Comment'}
215
+ {postCommentMutation.isPending ? "Posting..." : "Post Comment"}
196
216
  </Button>
197
217
  </form>
198
218
  </CardContent>
@@ -201,13 +221,17 @@ function CommentForm({ threadId, onCommentPosted }: CommentFormProps) {
201
221
  }
202
222
 
203
223
  // Individual Comment Component
204
- function CommentItem({ comment, onCommentUpdated, onCommentDeleted }: CommentItemProps) {
224
+ function CommentItem({
225
+ comment,
226
+ onCommentUpdated,
227
+ onCommentDeleted,
228
+ }: CommentItemProps) {
205
229
  const [isEditing, setIsEditing] = useState(false);
206
- const [editText, setEditText] = useState(comment.comment || '');
230
+ const [editText, setEditText] = useState(comment.comment || "");
207
231
 
208
232
  const updateCommentMutation = useUpdateComment({
209
233
  onSuccess: () => {
210
- toast.success('Comment updated successfully!');
234
+ toast.success("Comment updated successfully!");
211
235
  setIsEditing(false);
212
236
  onCommentUpdated();
213
237
  },
@@ -218,7 +242,7 @@ function CommentItem({ comment, onCommentUpdated, onCommentDeleted }: CommentIte
218
242
 
219
243
  const deleteCommentMutation = useDeleteComment({
220
244
  onSuccess: () => {
221
- toast.success('Comment deleted successfully!');
245
+ toast.success("Comment deleted successfully!");
222
246
  onCommentDeleted();
223
247
  },
224
248
  onError: (error) => {
@@ -228,7 +252,7 @@ function CommentItem({ comment, onCommentUpdated, onCommentDeleted }: CommentIte
228
252
 
229
253
  const handleUpdate = () => {
230
254
  if (!editText.trim()) {
231
- toast.error('Comment cannot be empty');
255
+ toast.error("Comment cannot be empty");
232
256
  return;
233
257
  }
234
258
 
@@ -242,7 +266,7 @@ function CommentItem({ comment, onCommentUpdated, onCommentDeleted }: CommentIte
242
266
  };
243
267
 
244
268
  const handleDelete = () => {
245
- if (window.confirm('Are you sure you want to delete this comment?')) {
269
+ if (window.confirm("Are you sure you want to delete this comment?")) {
246
270
  deleteCommentMutation.mutate(comment.id);
247
271
  }
248
272
  };
@@ -253,13 +277,17 @@ function CommentItem({ comment, onCommentUpdated, onCommentDeleted }: CommentIte
253
277
  <div className="flex items-center gap-3">
254
278
  <Avatar className="h-8 w-8">
255
279
  <AvatarFallback>
256
- {comment.createdBy?.charAt(0)?.toUpperCase() || 'U'}
280
+ {comment.createdBy?.charAt(0)?.toUpperCase() || "U"}
257
281
  </AvatarFallback>
258
282
  </Avatar>
259
283
  <div>
260
- <p className="font-medium text-sm">{comment.createdBy || 'Unknown User'}</p>
284
+ <p className="font-medium text-sm">
285
+ {comment.createdBy || "Unknown User"}
286
+ </p>
261
287
  <p className="text-xs text-muted-foreground">
262
- {comment.createdDate ? new Date(comment.createdDate).toLocaleString() : 'Just now'}
288
+ {comment.createdDate
289
+ ? new Date(comment.createdDate).toLocaleString()
290
+ : "Just now"}
263
291
  </p>
264
292
  </div>
265
293
  </div>
@@ -296,14 +324,14 @@ function CommentItem({ comment, onCommentUpdated, onCommentDeleted }: CommentIte
296
324
  onClick={handleUpdate}
297
325
  disabled={updateCommentMutation.isPending}
298
326
  >
299
- {updateCommentMutation.isPending ? 'Saving...' : 'Save'}
327
+ {updateCommentMutation.isPending ? "Saving..." : "Save"}
300
328
  </Button>
301
329
  <Button
302
330
  size="sm"
303
331
  variant="outline"
304
332
  onClick={() => {
305
333
  setIsEditing(false);
306
- setEditText(comment.comment || '');
334
+ setEditText(comment.comment || "");
307
335
  }}
308
336
  >
309
337
  Cancel
@@ -319,11 +347,14 @@ function CommentItem({ comment, onCommentUpdated, onCommentDeleted }: CommentIte
319
347
 
320
348
  // Subscription Controls Component
321
349
  function SubscriptionControls({ userId, threadId }: SubscriptionControlsProps) {
322
- const { data: subscriptionStatus, isLoading } = useCheckSubscriptionStatus(userId, threadId);
350
+ const { data: subscriptionStatus, isLoading } = useCheckSubscriptionStatus(
351
+ userId,
352
+ threadId
353
+ );
323
354
 
324
355
  const subscribeUserMutation = useSubscribeUser({
325
356
  onSuccess: () => {
326
- toast.success('Successfully subscribed to thread!');
357
+ toast.success("Successfully subscribed to thread!");
327
358
  },
328
359
  onError: (error) => {
329
360
  toast.error(`Failed to subscribe: ${error.message}`);
@@ -332,7 +363,7 @@ function SubscriptionControls({ userId, threadId }: SubscriptionControlsProps) {
332
363
 
333
364
  const unsubscribeUserMutation = useUnsubscribeUser({
334
365
  onSuccess: () => {
335
- toast.success('Successfully unsubscribed from thread!');
366
+ toast.success("Successfully unsubscribed from thread!");
336
367
  },
337
368
  onError: (error) => {
338
369
  toast.error(`Failed to unsubscribe: ${error.message}`);
@@ -363,7 +394,9 @@ function SubscriptionControls({ userId, threadId }: SubscriptionControlsProps) {
363
394
  variant={isSubscribed ? "outline" : "default"}
364
395
  size="sm"
365
396
  onClick={isSubscribed ? handleUnsubscribe : handleSubscribe}
366
- disabled={subscribeUserMutation.isPending || unsubscribeUserMutation.isPending}
397
+ disabled={
398
+ subscribeUserMutation.isPending || unsubscribeUserMutation.isPending
399
+ }
367
400
  >
368
401
  {isSubscribed ? (
369
402
  <>
@@ -386,12 +419,12 @@ function SubscriptionControls({ userId, threadId }: SubscriptionControlsProps) {
386
419
 
387
420
  // Main Comments Page Component
388
421
  export default function CommentsPage() {
389
- const [selectedThreadId, setSelectedThreadId] = useState<string>('');
422
+ const [selectedThreadId, setSelectedThreadId] = useState<string>("");
390
423
 
391
- const {
392
- data: commentsData,
393
- isLoading: commentsLoading,
394
- refetch: refetchComments
424
+ const {
425
+ data: commentsData,
426
+ isLoading: commentsLoading,
427
+ refetch: refetchComments,
395
428
  } = useGetCommentsByThreadId(selectedThreadId, {
396
429
  enabled: !!selectedThreadId,
397
430
  });
@@ -440,14 +473,14 @@ export default function CommentsPage() {
440
473
  {/* Left Column - Thread Creation */}
441
474
  <div className="space-y-6">
442
475
  <ThreadForm onThreadCreated={handleThreadCreated} />
443
-
476
+
444
477
  {selectedThreadId && (
445
478
  <>
446
- <CommentForm
447
- threadId={selectedThreadId}
448
- onCommentPosted={handleCommentAction}
479
+ <CommentForm
480
+ threadId={selectedThreadId}
481
+ onCommentPosted={handleCommentAction}
449
482
  />
450
-
483
+
451
484
  <Card>
452
485
  <CardHeader>
453
486
  <CardTitle className="flex items-center gap-2">
@@ -459,9 +492,9 @@ export default function CommentsPage() {
459
492
  </CardDescription>
460
493
  </CardHeader>
461
494
  <CardContent>
462
- <SubscriptionControls
463
- userId={MOCK_USER.id}
464
- threadId={selectedThreadId}
495
+ <SubscriptionControls
496
+ userId={MOCK_USER.id}
497
+ threadId={selectedThreadId}
465
498
  />
466
499
  </CardContent>
467
500
  </Card>
@@ -475,10 +508,9 @@ export default function CommentsPage() {
475
508
  <CardHeader>
476
509
  <CardTitle>Comments</CardTitle>
477
510
  <CardDescription>
478
- {selectedThreadId
511
+ {selectedThreadId
479
512
  ? `Comments for thread ${selectedThreadId.slice(0, 8)}...`
480
- : 'Create a thread to see comments'
481
- }
513
+ : "Create a thread to see comments"}
482
514
  </CardDescription>
483
515
  </CardHeader>
484
516
  <CardContent>
@@ -524,13 +556,17 @@ export default function CommentsPage() {
524
556
  <CardContent className="space-y-2">
525
557
  <div className="flex justify-between items-center">
526
558
  <span className="text-sm">Thread Selected:</span>
527
- <Badge variant={selectedThreadId ? "default" : "secondary"}>
559
+ <Badge
560
+ variant={selectedThreadId ? "default" : "secondary"}
561
+ >
528
562
  {selectedThreadId ? "Yes" : "No"}
529
563
  </Badge>
530
564
  </div>
531
565
  <div className="flex justify-between items-center">
532
566
  <span className="text-sm">Comments Loading:</span>
533
- <Badge variant={commentsLoading ? "default" : "secondary"}>
567
+ <Badge
568
+ variant={commentsLoading ? "default" : "secondary"}
569
+ >
534
570
  {commentsLoading ? "Yes" : "No"}
535
571
  </Badge>
536
572
  </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 {