@greatapps/greatchat-ui 0.1.3 → 0.1.5

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.
package/package.json CHANGED
@@ -1,16 +1,20 @@
1
1
  {
2
2
  "name": "@greatapps/greatchat-ui",
3
- "version": "0.1.3",
3
+ "version": "0.1.5",
4
4
  "type": "module",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",
7
7
  "exports": {
8
8
  ".": {
9
9
  "types": "./dist/index.d.ts",
10
- "import": "./dist/index.js"
10
+ "import": "./dist/index.js",
11
+ "default": "./dist/index.js"
11
12
  }
12
13
  },
13
- "files": ["dist", "src"],
14
+ "files": [
15
+ "dist",
16
+ "src"
17
+ ],
14
18
  "scripts": {
15
19
  "build": "tsup",
16
20
  "dev": "tsup --watch"
@@ -24,6 +28,8 @@
24
28
  "sonner": "*"
25
29
  },
26
30
  "dependencies": {
31
+ "@greatapps/greatauth-ui": "^0.1.4",
32
+ "@greatapps/greatchat-ui": "^0.1.4",
27
33
  "class-variance-authority": "^0.7.1",
28
34
  "clsx": "^2",
29
35
  "cmdk": "^1.1.1",
@@ -0,0 +1,100 @@
1
+ "use client";
2
+
3
+ import type { ReactNode } from "react";
4
+ import type { Channel } from "../types";
5
+ import type { GchatHookConfig } from "../hooks/types";
6
+ import { useChannelWhatsappStatus } from "../hooks/use-channels";
7
+ import { WhatsappStatusBadge } from "./whatsapp-status-badge";
8
+ import { Button } from "./ui/button";
9
+
10
+ export interface ChannelCardProps {
11
+ channel: Channel;
12
+ config: GchatHookConfig;
13
+ onEdit?: () => void;
14
+ onDelete?: () => void;
15
+ linkedAgentName?: string;
16
+ linkedAgentActive?: boolean;
17
+ actions?: ReactNode;
18
+ }
19
+
20
+ export function ChannelCard({
21
+ channel,
22
+ config,
23
+ onEdit,
24
+ onDelete,
25
+ linkedAgentName,
26
+ linkedAgentActive = true,
27
+ actions,
28
+ }: ChannelCardProps) {
29
+ const { data: status } = useChannelWhatsappStatus(config, channel.id);
30
+ const hasSession = !!channel.external_id;
31
+
32
+ return (
33
+ <div className="rounded-lg border bg-card text-card-foreground shadow-sm">
34
+ <div className="flex flex-row items-start justify-between p-4 pb-2">
35
+ <div className="flex items-center gap-2">
36
+ <div className="flex h-9 w-9 items-center justify-center rounded-md bg-green-500/10">
37
+ <svg className="h-5 w-5 text-green-600" viewBox="0 0 24 24" fill="currentColor">
38
+ <path d="M17.472 14.382c-.297-.149-1.758-.867-2.03-.967-.273-.099-.471-.148-.67.15-.197.297-.767.966-.94 1.164-.173.199-.347.223-.644.075-.297-.15-1.255-.463-2.39-1.475-.883-.788-1.48-1.761-1.653-2.059-.173-.297-.018-.458.13-.606.134-.133.298-.347.446-.52.149-.174.198-.298.298-.497.099-.198.05-.371-.025-.52-.075-.149-.669-1.612-.916-2.207-.242-.579-.487-.5-.669-.51-.173-.008-.371-.01-.57-.01-.198 0-.52.074-.792.372-.272.297-1.04 1.016-1.04 2.479 0 1.462 1.065 2.875 1.213 3.074.149.198 2.096 3.2 5.077 4.487.709.306 1.262.489 1.694.625.712.227 1.36.195 1.871.118.571-.085 1.758-.719 2.006-1.413.248-.694.248-1.289.173-1.413-.074-.124-.272-.198-.57-.347m-5.421 7.403h-.004a9.87 9.87 0 01-5.031-1.378l-.361-.214-3.741.982.998-3.648-.235-.374a9.86 9.86 0 01-1.51-5.26c.001-5.45 4.436-9.884 9.888-9.884 2.64 0 5.122 1.03 6.988 2.898a9.825 9.825 0 012.893 6.994c-.003 5.45-4.437 9.884-9.885 9.884m8.413-18.297A11.815 11.815 0 0012.05 0C5.495 0 .16 5.335.157 11.892c0 2.096.547 4.142 1.588 5.945L.057 24l6.305-1.654a11.882 11.882 0 005.683 1.448h.005c6.554 0 11.89-5.335 11.893-11.893a11.821 11.821 0 00-3.48-8.413z" />
39
+ </svg>
40
+ </div>
41
+ <div>
42
+ <h3 className="text-sm font-medium">{channel.name}</h3>
43
+ <p className="text-xs text-muted-foreground">
44
+ {channel.identifier || "Sem número"}
45
+ </p>
46
+ </div>
47
+ </div>
48
+ <div className="flex items-center gap-1">
49
+ {onEdit && (
50
+ <Button
51
+ variant="ghost"
52
+ size="icon"
53
+ className="h-7 w-7"
54
+ onClick={onEdit}
55
+ >
56
+ <svg className="h-3.5 w-3.5" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
57
+ <path d="M17 3a2.85 2.83 0 1 1 4 4L7.5 20.5 2 22l1.5-5.5Z" />
58
+ <path d="m15 5 4 4" />
59
+ </svg>
60
+ </Button>
61
+ )}
62
+ {onDelete && (
63
+ <Button
64
+ variant="ghost"
65
+ size="icon"
66
+ className="h-7 w-7 text-destructive hover:text-destructive"
67
+ onClick={onDelete}
68
+ >
69
+ <svg className="h-3.5 w-3.5" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
70
+ <path d="M3 6h18" />
71
+ <path d="M19 6v14c0 1-1 2-2 2H7c-1 0-2-1-2-2V6" />
72
+ <path d="M8 6V4c0-1 1-2 2-2h4c1 0 2 1 2 2v2" />
73
+ </svg>
74
+ </Button>
75
+ )}
76
+ <WhatsappStatusBadge status={status} hasSession={hasSession} />
77
+ </div>
78
+ </div>
79
+ <div className="p-4 pt-0 space-y-3">
80
+ {linkedAgentName && (
81
+ <div className="flex items-center gap-1.5 text-xs text-muted-foreground">
82
+ <svg className="h-3.5 w-3.5" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
83
+ <path d="M12 8V4H8" />
84
+ <rect width="16" height="12" x="4" y="8" rx="2" />
85
+ <path d="M2 14h2" />
86
+ <path d="M20 14h2" />
87
+ <path d="M15 13v2" />
88
+ <path d="M9 13v2" />
89
+ </svg>
90
+ <span>Agent: <strong>{linkedAgentName}</strong></span>
91
+ {!linkedAgentActive && (
92
+ <span className="text-[10px] px-1 py-0 border rounded">inativo</span>
93
+ )}
94
+ </div>
95
+ )}
96
+ {actions}
97
+ </div>
98
+ </div>
99
+ );
100
+ }
@@ -21,3 +21,9 @@ export type { ContactInfoPanelProps } from "./contact-info-panel";
21
21
 
22
22
  export { NewConversationDialog } from "./new-conversation-dialog";
23
23
  export type { NewConversationDialogProps } from "./new-conversation-dialog";
24
+
25
+ export { ChannelCard } from "./channel-card";
26
+ export type { ChannelCardProps } from "./channel-card";
27
+
28
+ export { WhatsappStatusBadge } from "./whatsapp-status-badge";
29
+ export type { WhatsappStatusBadgeProps } from "./whatsapp-status-badge";
@@ -0,0 +1,72 @@
1
+ "use client";
2
+
3
+ import type { WhatsappStatus } from "../types";
4
+ import { Badge } from "./ui/badge";
5
+
6
+ export interface WhatsappStatusBadgeProps {
7
+ status: WhatsappStatus | undefined | null;
8
+ hasSession: boolean;
9
+ }
10
+
11
+ export function WhatsappStatusBadge({
12
+ status,
13
+ hasSession,
14
+ }: WhatsappStatusBadgeProps) {
15
+ if (!hasSession) {
16
+ return (
17
+ <Badge variant="outline" className="text-xs text-zinc-500 border-zinc-300">
18
+ Sem sessão
19
+ </Badge>
20
+ );
21
+ }
22
+
23
+ if (!status) {
24
+ return (
25
+ <Badge variant="outline" className="text-xs text-zinc-500 border-zinc-300">
26
+ Verificando...
27
+ </Badge>
28
+ );
29
+ }
30
+
31
+ if (status.connected && status.logged_in) {
32
+ return (
33
+ <Badge
34
+ variant="outline"
35
+ className="text-xs bg-green-500/10 text-green-600 border-green-200"
36
+ >
37
+ Conectado
38
+ </Badge>
39
+ );
40
+ }
41
+
42
+ if (status.connected && !status.logged_in) {
43
+ return (
44
+ <Badge
45
+ variant="outline"
46
+ className="text-xs bg-yellow-500/10 text-yellow-600 border-yellow-200"
47
+ >
48
+ Reconectando...
49
+ </Badge>
50
+ );
51
+ }
52
+
53
+ if (status.logged_in && !status.connected) {
54
+ return (
55
+ <Badge
56
+ variant="outline"
57
+ className="text-xs bg-yellow-500/10 text-yellow-600 border-yellow-200"
58
+ >
59
+ Desconectado
60
+ </Badge>
61
+ );
62
+ }
63
+
64
+ return (
65
+ <Badge
66
+ variant="outline"
67
+ className="text-xs bg-red-500/10 text-red-600 border-red-200"
68
+ >
69
+ Offline
70
+ </Badge>
71
+ );
72
+ }
package/src/index.ts CHANGED
@@ -31,6 +31,8 @@ export {
31
31
  InboxSidebar,
32
32
  ContactInfoPanel,
33
33
  NewConversationDialog,
34
+ ChannelCard,
35
+ WhatsappStatusBadge,
34
36
  } from "./components";
35
37
  export type {
36
38
  ChatViewProps,
@@ -41,4 +43,6 @@ export type {
41
43
  InboxSidebarProps,
42
44
  ContactInfoPanelProps,
43
45
  NewConversationDialogProps,
46
+ ChannelCardProps,
47
+ WhatsappStatusBadgeProps,
44
48
  } from "./components";