@cometchat/skills-cli 2.0.0

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 (95) hide show
  1. package/README.md +70 -0
  2. package/bin/cometchat.mjs +7 -0
  3. package/dist/index.js +4395 -0
  4. package/dist/registry/schemas/template.schema.json +142 -0
  5. package/dist/registry/v6/experiences/1-conversation-list/astro.template.json +89 -0
  6. package/dist/registry/v6/experiences/1-conversation-list/nextjs-pages.template.json +83 -0
  7. package/dist/registry/v6/experiences/1-conversation-list/nextjs.template.json +83 -0
  8. package/dist/registry/v6/experiences/1-conversation-list/react-router.template.json +102 -0
  9. package/dist/registry/v6/experiences/1-conversation-list/reactjs.template.json +86 -0
  10. package/dist/registry/v6/experiences/1-conversation-list/templates/astro/ChatApp.css.tpl +39 -0
  11. package/dist/registry/v6/experiences/1-conversation-list/templates/astro/ChatApp.tsx.tpl +86 -0
  12. package/dist/registry/v6/experiences/1-conversation-list/templates/astro/CometChatSelector.tsx.tpl +40 -0
  13. package/dist/registry/v6/experiences/1-conversation-list/templates/astro/chat.astro.tpl +17 -0
  14. package/dist/registry/v6/experiences/1-conversation-list/templates/nextjs/CometChatNoSSR.css.tpl +39 -0
  15. package/dist/registry/v6/experiences/1-conversation-list/templates/nextjs/CometChatNoSSR.tsx.tpl +86 -0
  16. package/dist/registry/v6/experiences/1-conversation-list/templates/nextjs/CometChatSelector.tsx.tpl +41 -0
  17. package/dist/registry/v6/experiences/1-conversation-list/templates/nextjs/chat-page.tsx.tpl +11 -0
  18. package/dist/registry/v6/experiences/1-conversation-list/templates/nextjs-pages/CometChatNoSSR.css.tpl +39 -0
  19. package/dist/registry/v6/experiences/1-conversation-list/templates/nextjs-pages/CometChatNoSSR.tsx.tpl +88 -0
  20. package/dist/registry/v6/experiences/1-conversation-list/templates/nextjs-pages/CometChatSelector.tsx.tpl +41 -0
  21. package/dist/registry/v6/experiences/1-conversation-list/templates/nextjs-pages/chat-page.tsx.tpl +15 -0
  22. package/dist/registry/v6/experiences/1-conversation-list/templates/react-router/CometChat-route.tsx.tpl +22 -0
  23. package/dist/registry/v6/experiences/1-conversation-list/templates/react-router/CometChatNoSSR.css.tpl +39 -0
  24. package/dist/registry/v6/experiences/1-conversation-list/templates/react-router/CometChatNoSSR.tsx.tpl +87 -0
  25. package/dist/registry/v6/experiences/1-conversation-list/templates/react-router/CometChatSelector.tsx.tpl +40 -0
  26. package/dist/registry/v6/experiences/1-conversation-list/templates/reactjs/App.css.tpl +32 -0
  27. package/dist/registry/v6/experiences/1-conversation-list/templates/reactjs/App.tsx.tpl +55 -0
  28. package/dist/registry/v6/experiences/1-conversation-list/templates/reactjs/CometChatSelector.tsx.tpl +40 -0
  29. package/dist/registry/v6/experiences/1-conversation-list/templates/reactjs/main.tsx.tpl +46 -0
  30. package/dist/registry/v6/experiences/2-one-to-one/astro.template.json +81 -0
  31. package/dist/registry/v6/experiences/2-one-to-one/nextjs.template.json +77 -0
  32. package/dist/registry/v6/experiences/2-one-to-one/react-router.template.json +93 -0
  33. package/dist/registry/v6/experiences/2-one-to-one/reactjs.template.json +77 -0
  34. package/dist/registry/v6/experiences/2-one-to-one/templates/astro/ChatApp.css.tpl +21 -0
  35. package/dist/registry/v6/experiences/2-one-to-one/templates/astro/ChatApp.tsx.tpl +66 -0
  36. package/dist/registry/v6/experiences/2-one-to-one/templates/astro/chat.astro.tpl +17 -0
  37. package/dist/registry/v6/experiences/2-one-to-one/templates/nextjs/CometChatNoSSR.css.tpl +21 -0
  38. package/dist/registry/v6/experiences/2-one-to-one/templates/nextjs/CometChatNoSSR.tsx.tpl +66 -0
  39. package/dist/registry/v6/experiences/2-one-to-one/templates/nextjs/chat-page.tsx.tpl +11 -0
  40. package/dist/registry/v6/experiences/2-one-to-one/templates/react-router/CometChat-route.tsx.tpl +21 -0
  41. package/dist/registry/v6/experiences/2-one-to-one/templates/react-router/CometChatNoSSR.css.tpl +21 -0
  42. package/dist/registry/v6/experiences/2-one-to-one/templates/react-router/CometChatNoSSR.tsx.tpl +67 -0
  43. package/dist/registry/v6/experiences/2-one-to-one/templates/reactjs/App.css.tpl +4 -0
  44. package/dist/registry/v6/experiences/2-one-to-one/templates/reactjs/App.tsx.tpl +44 -0
  45. package/dist/registry/v6/experiences/2-one-to-one/templates/reactjs/main.tsx.tpl +46 -0
  46. package/dist/registry/v6/experiences/3-tab-based/astro.template.json +93 -0
  47. package/dist/registry/v6/experiences/3-tab-based/nextjs.template.json +90 -0
  48. package/dist/registry/v6/experiences/3-tab-based/react-router.template.json +105 -0
  49. package/dist/registry/v6/experiences/3-tab-based/reactjs.template.json +90 -0
  50. package/dist/registry/v6/experiences/3-tab-based/templates/astro/ChatApp.css.tpl +39 -0
  51. package/dist/registry/v6/experiences/3-tab-based/templates/astro/ChatApp.tsx.tpl +93 -0
  52. package/dist/registry/v6/experiences/3-tab-based/templates/astro/CometChatTabs.css.tpl +43 -0
  53. package/dist/registry/v6/experiences/3-tab-based/templates/astro/CometChatTabs.tsx.tpl +72 -0
  54. package/dist/registry/v6/experiences/3-tab-based/templates/astro/chat.astro.tpl +17 -0
  55. package/dist/registry/v6/experiences/3-tab-based/templates/nextjs/CometChatNoSSR.css.tpl +39 -0
  56. package/dist/registry/v6/experiences/3-tab-based/templates/nextjs/CometChatNoSSR.tsx.tpl +93 -0
  57. package/dist/registry/v6/experiences/3-tab-based/templates/nextjs/CometChatTabs.css.tpl +43 -0
  58. package/dist/registry/v6/experiences/3-tab-based/templates/nextjs/CometChatTabs.tsx.tpl +73 -0
  59. package/dist/registry/v6/experiences/3-tab-based/templates/nextjs/chat-page.tsx.tpl +11 -0
  60. package/dist/registry/v6/experiences/3-tab-based/templates/react-router/CometChat-route.tsx.tpl +21 -0
  61. package/dist/registry/v6/experiences/3-tab-based/templates/react-router/CometChatNoSSR.css.tpl +39 -0
  62. package/dist/registry/v6/experiences/3-tab-based/templates/react-router/CometChatNoSSR.tsx.tpl +94 -0
  63. package/dist/registry/v6/experiences/3-tab-based/templates/react-router/CometChatTabs.css.tpl +43 -0
  64. package/dist/registry/v6/experiences/3-tab-based/templates/react-router/CometChatTabs.tsx.tpl +72 -0
  65. package/dist/registry/v6/experiences/3-tab-based/templates/reactjs/App.css.tpl +7 -0
  66. package/dist/registry/v6/experiences/3-tab-based/templates/reactjs/App.tsx.tpl +62 -0
  67. package/dist/registry/v6/experiences/3-tab-based/templates/reactjs/CometChatTabs.css.tpl +43 -0
  68. package/dist/registry/v6/experiences/3-tab-based/templates/reactjs/CometChatTabs.tsx.tpl +72 -0
  69. package/dist/registry/v6/experiences/3-tab-based/templates/reactjs/main.tsx.tpl +46 -0
  70. package/dist/registry/v6/features/catalog.json +344 -0
  71. package/dist/registry/v6/production/astro/cometchat-token.ts.tpl +86 -0
  72. package/dist/registry/v6/production/astro.template.json +51 -0
  73. package/dist/registry/v6/production/nextjs/route.ts.tpl +79 -0
  74. package/dist/registry/v6/production/nextjs.template.json +50 -0
  75. package/dist/registry/v6/production/react-router/api.cometchat-token.ts.tpl +73 -0
  76. package/dist/registry/v6/production/react-router.template.json +58 -0
  77. package/dist/registry/v6/user-mgmt/astro/cometchat-user.ts.tpl +164 -0
  78. package/dist/registry/v6/user-mgmt/astro.template.json +33 -0
  79. package/dist/registry/v6/user-mgmt/nextjs/route.ts.tpl +212 -0
  80. package/dist/registry/v6/user-mgmt/nextjs.template.json +57 -0
  81. package/dist/registry/v6/user-mgmt/react-router/api.cometchat-user.ts.tpl +176 -0
  82. package/dist/registry/v6/user-mgmt/react-router.template.json +40 -0
  83. package/dist/registry/v6/widget/astro/CometChatWidget.css.tpl +105 -0
  84. package/dist/registry/v6/widget/astro/CometChatWidget.tsx.tpl +88 -0
  85. package/dist/registry/v6/widget/astro.template.json +38 -0
  86. package/dist/registry/v6/widget/nextjs/CometChatWidget.css.tpl +105 -0
  87. package/dist/registry/v6/widget/nextjs/CometChatWidget.tsx.tpl +88 -0
  88. package/dist/registry/v6/widget/nextjs.template.json +40 -0
  89. package/dist/registry/v6/widget/react-router/CometChatWidget.css.tpl +105 -0
  90. package/dist/registry/v6/widget/react-router/CometChatWidget.tsx.tpl +98 -0
  91. package/dist/registry/v6/widget/react-router.template.json +36 -0
  92. package/dist/registry/v6/widget/reactjs/CometChatWidget.css.tpl +105 -0
  93. package/dist/registry/v6/widget/reactjs/CometChatWidget.tsx.tpl +89 -0
  94. package/dist/registry/v6/widget/reactjs.template.json +36 -0
  95. package/package.json +53 -0
@@ -0,0 +1,39 @@
1
+ .conversations-with-messages {
2
+ display: flex;
3
+ height: 100vh;
4
+ width: 100%;
5
+ }
6
+
7
+ .conversations-wrapper {
8
+ height: 100%;
9
+ width: 480px;
10
+ overflow: hidden;
11
+ display: flex;
12
+ flex-direction: column;
13
+ }
14
+
15
+ .conversations-wrapper > .cometchat {
16
+ overflow: hidden;
17
+ }
18
+
19
+ .messages-wrapper {
20
+ width: calc(100% - 480px);
21
+ height: 100%;
22
+ display: flex;
23
+ flex-direction: column;
24
+ }
25
+
26
+ .empty-conversation {
27
+ height: 100%;
28
+ width: 100%;
29
+ display: flex;
30
+ justify-content: center;
31
+ align-items: center;
32
+ background: white;
33
+ color: var(--cometchat-text-color-secondary, #727272);
34
+ font: var(--cometchat-font-body-regular, 400 14px Roboto);
35
+ }
36
+
37
+ .cometchat .cometchat-message-composer {
38
+ border-radius: 0;
39
+ }
@@ -0,0 +1,93 @@
1
+ import { useEffect, useState } from "react";
2
+ import {
3
+ CometChatMessageComposer,
4
+ CometChatMessageHeader,
5
+ CometChatMessageList,
6
+ CometChatUIKit,
7
+ UIKitSettingsBuilder,
8
+ } from "@cometchat/chat-uikit-react";
9
+ import { CometChat } from "@cometchat/chat-sdk-javascript";
10
+ import { CometChatTabs, type CometChatTab } from "./CometChatTabs";
11
+ // IMPORTANT: css-variables.css MUST be imported here (inside the React island)
12
+ // — global stylesheets imported in .astro files do not apply to client:only islands.
13
+ import "@cometchat/chat-uikit-react/css-variables.css";
14
+ import "./ChatApp.css";
15
+
16
+ const COMETCHAT_CONSTANTS = {
17
+ APP_ID: import.meta.env.{{ENV_PREFIX}}COMETCHAT_APP_ID as string,
18
+ REGION: import.meta.env.{{ENV_PREFIX}}COMETCHAT_REGION as string,
19
+ AUTH_KEY: import.meta.env.{{ENV_PREFIX}}COMETCHAT_AUTH_KEY as string,
20
+ };
21
+ const UID = "{{LOGIN_UID}}";
22
+
23
+ export default function ChatApp() {
24
+ const [user, setUser] = useState<CometChat.User | undefined>();
25
+ const [error, setError] = useState<string | null>(null);
26
+ const [activeTab, setActiveTab] = useState<CometChatTab>("chats");
27
+ const [selectedUser, setSelectedUser] = useState<CometChat.User | undefined>();
28
+ const [selectedGroup, setSelectedGroup] = useState<CometChat.Group | undefined>();
29
+
30
+ useEffect(() => {
31
+ const settings = new UIKitSettingsBuilder()
32
+ .setAppId(COMETCHAT_CONSTANTS.APP_ID)
33
+ .setRegion(COMETCHAT_CONSTANTS.REGION)
34
+ .setAuthKey(COMETCHAT_CONSTANTS.AUTH_KEY)
35
+ .subscribePresenceForAllUsers()
36
+ .build();
37
+
38
+ CometChatUIKit.init(settings)?.then(() => {
39
+ CometChatUIKit.getLoggedinUser().then((u) => {
40
+ if (!u) {
41
+ CometChatUIKit.login(UID)
42
+ .then(setUser)
43
+ .catch((e: unknown) => setError(String(e)));
44
+ } else {
45
+ setUser(u);
46
+ }
47
+ });
48
+ }).catch((e: unknown) => setError(String(e)));
49
+ }, []);
50
+
51
+ const handleSelectorItemClicked = (
52
+ activeItem: CometChat.Conversation | CometChat.User | CometChat.Group,
53
+ ) => {
54
+ const item =
55
+ activeItem instanceof CometChat.Conversation
56
+ ? activeItem.getConversationWith()
57
+ : activeItem;
58
+ if (item instanceof CometChat.User) {
59
+ setSelectedUser(item);
60
+ setSelectedGroup(undefined);
61
+ } else if (item instanceof CometChat.Group) {
62
+ setSelectedUser(undefined);
63
+ setSelectedGroup(item);
64
+ }
65
+ };
66
+
67
+ if (error) return <div style={{ color: "red", padding: 16, fontFamily: "monospace" }}>{error}</div>;
68
+ if (!user) return null;
69
+
70
+ return (
71
+ <div className="conversations-with-messages">
72
+ <div className="conversations-wrapper">
73
+ <CometChatTabs
74
+ activeTab={activeTab}
75
+ onTabChange={setActiveTab}
76
+ onItemClick={handleSelectorItemClicked}
77
+ />
78
+ </div>
79
+ {selectedUser || selectedGroup ? (
80
+ <div className="messages-wrapper">
81
+ {selectedUser && <CometChatMessageHeader user={selectedUser} />}
82
+ {selectedGroup && <CometChatMessageHeader group={selectedGroup} />}
83
+ {selectedUser && <CometChatMessageList user={selectedUser} />}
84
+ {selectedGroup && <CometChatMessageList group={selectedGroup} />}
85
+ {selectedUser && <CometChatMessageComposer user={selectedUser} />}
86
+ {selectedGroup && <CometChatMessageComposer group={selectedGroup} />}
87
+ </div>
88
+ ) : (
89
+ <div className="empty-conversation">Select a conversation to start chatting</div>
90
+ )}
91
+ </div>
92
+ );
93
+ }
@@ -0,0 +1,43 @@
1
+ .cometchat-tabs {
2
+ height: 100%;
3
+ width: 100%;
4
+ display: flex;
5
+ flex-direction: column;
6
+ }
7
+
8
+ .cometchat-tabs-content {
9
+ flex: 1;
10
+ overflow: hidden;
11
+ display: flex;
12
+ flex-direction: column;
13
+ }
14
+
15
+ .cometchat-tabs-content > .cometchat {
16
+ flex: 1;
17
+ overflow: hidden;
18
+ }
19
+
20
+ .cometchat-tabs-bar {
21
+ display: flex;
22
+ border-top: 1px solid var(--cometchat-border-color-default, #e8e8e8);
23
+ background: var(--cometchat-background-color-01, #ffffff);
24
+ }
25
+
26
+ .cometchat-tabs-bar-tab {
27
+ flex: 1;
28
+ padding: 12px 8px;
29
+ border: none;
30
+ background: transparent;
31
+ font: var(--cometchat-font-body-regular, 400 14px Roboto);
32
+ color: var(--cometchat-text-color-secondary, #727272);
33
+ cursor: pointer;
34
+ }
35
+
36
+ .cometchat-tabs-bar-tab.active {
37
+ color: var(--cometchat-primary-color, #6852d6);
38
+ font-weight: 600;
39
+ }
40
+
41
+ .cometchat-tabs-bar-tab:hover {
42
+ background: var(--cometchat-background-color-02, #f8f8f8);
43
+ }
@@ -0,0 +1,72 @@
1
+ import { useEffect, useState } from "react";
2
+ import { CometChat } from "@cometchat/chat-sdk-javascript";
3
+ import {
4
+ CometChatCallLogs,
5
+ CometChatConversations,
6
+ CometChatGroups,
7
+ CometChatUIKitLoginListener,
8
+ CometChatUsers,
9
+ } from "@cometchat/chat-uikit-react";
10
+ import "./CometChatTabs.css";
11
+
12
+ export type CometChatTab = "chats" | "calls" | "users" | "groups";
13
+
14
+ interface CometChatTabsProps {
15
+ activeTab: CometChatTab;
16
+ onTabChange: (tab: CometChatTab) => void;
17
+ onItemClick: (
18
+ item: CometChat.Conversation | CometChat.User | CometChat.Group,
19
+ ) => void;
20
+ }
21
+
22
+ const TABS: { id: CometChatTab; label: string }[] = [
23
+ { id: "chats", label: "Chats" },
24
+ { id: "calls", label: "Calls" },
25
+ { id: "users", label: "Users" },
26
+ { id: "groups", label: "Groups" },
27
+ ];
28
+
29
+ export const CometChatTabs = ({
30
+ activeTab,
31
+ onTabChange,
32
+ onItemClick,
33
+ }: CometChatTabsProps) => {
34
+ const [loggedInUser, setLoggedInUser] = useState<CometChat.User | null>(null);
35
+
36
+ useEffect(() => {
37
+ setLoggedInUser(CometChatUIKitLoginListener.getLoggedInUser());
38
+ }, []);
39
+
40
+ if (!loggedInUser) return null;
41
+
42
+ return (
43
+ <div className="cometchat-tabs">
44
+ <div className="cometchat-tabs-content">
45
+ {activeTab === "chats" && (
46
+ <CometChatConversations
47
+ onItemClick={(c) => onItemClick(c)}
48
+ />
49
+ )}
50
+ {activeTab === "calls" && <CometChatCallLogs />}
51
+ {activeTab === "users" && (
52
+ <CometChatUsers onItemClick={(u) => onItemClick(u)} />
53
+ )}
54
+ {activeTab === "groups" && (
55
+ <CometChatGroups onItemClick={(g) => onItemClick(g)} />
56
+ )}
57
+ </div>
58
+ <nav className="cometchat-tabs-bar">
59
+ {TABS.map((tab) => (
60
+ <button
61
+ key={tab.id}
62
+ type="button"
63
+ className={`cometchat-tabs-bar-tab${activeTab === tab.id ? " active" : ""}`}
64
+ onClick={() => onTabChange(tab.id)}
65
+ >
66
+ {tab.label}
67
+ </button>
68
+ ))}
69
+ </nav>
70
+ </div>
71
+ );
72
+ };
@@ -0,0 +1,17 @@
1
+ ---
2
+ import ChatApp from "../cometchat/ChatApp.tsx";
3
+ ---
4
+
5
+ <html lang="en">
6
+ <head>
7
+ <meta charset="utf-8" />
8
+ <meta name="viewport" content="width=device-width" />
9
+ <title>Chat</title>
10
+ <style>
11
+ html, body { margin: 0; padding: 0; height: 100%; }
12
+ </style>
13
+ </head>
14
+ <body>
15
+ <ChatApp client:only="react" />
16
+ </body>
17
+ </html>
@@ -0,0 +1,39 @@
1
+ .conversations-with-messages {
2
+ display: flex;
3
+ height: 100vh;
4
+ width: 100%;
5
+ }
6
+
7
+ .conversations-wrapper {
8
+ height: 100%;
9
+ width: 480px;
10
+ overflow: hidden;
11
+ display: flex;
12
+ flex-direction: column;
13
+ }
14
+
15
+ .conversations-wrapper > .cometchat {
16
+ overflow: hidden;
17
+ }
18
+
19
+ .messages-wrapper {
20
+ width: calc(100% - 480px);
21
+ height: 100%;
22
+ display: flex;
23
+ flex-direction: column;
24
+ }
25
+
26
+ .empty-conversation {
27
+ height: 100%;
28
+ width: 100%;
29
+ display: flex;
30
+ justify-content: center;
31
+ align-items: center;
32
+ background: white;
33
+ color: var(--cometchat-text-color-secondary, #727272);
34
+ font: var(--cometchat-font-body-regular, 400 14px Roboto);
35
+ }
36
+
37
+ .cometchat .cometchat-message-composer {
38
+ border-radius: 0;
39
+ }
@@ -0,0 +1,93 @@
1
+ "use client";
2
+ import React, { useEffect, useState } from "react";
3
+ import {
4
+ CometChatMessageComposer,
5
+ CometChatMessageHeader,
6
+ CometChatMessageList,
7
+ CometChatUIKit,
8
+ UIKitSettingsBuilder,
9
+ } from "@cometchat/chat-uikit-react";
10
+ import { CometChat } from "@cometchat/chat-sdk-javascript";
11
+ import { CometChatTabs, type CometChatTab } from "./CometChatTabs";
12
+ // css-variables.css is imported in app/globals.css — do NOT import it here
13
+ import "./CometChatNoSSR.css";
14
+
15
+ const COMETCHAT_CONSTANTS = {
16
+ APP_ID: process.env.{{ENV_PREFIX}}COMETCHAT_APP_ID!,
17
+ REGION: process.env.{{ENV_PREFIX}}COMETCHAT_REGION!,
18
+ AUTH_KEY: process.env.{{ENV_PREFIX}}COMETCHAT_AUTH_KEY!,
19
+ };
20
+ const UID = "{{LOGIN_UID}}";
21
+
22
+ const CometChatNoSSR: React.FC = () => {
23
+ const [user, setUser] = useState<CometChat.User | undefined>();
24
+ const [error, setError] = useState<string | null>(null);
25
+ const [activeTab, setActiveTab] = useState<CometChatTab>("chats");
26
+ const [selectedUser, setSelectedUser] = useState<CometChat.User | undefined>();
27
+ const [selectedGroup, setSelectedGroup] = useState<CometChat.Group | undefined>();
28
+
29
+ useEffect(() => {
30
+ const settings = new UIKitSettingsBuilder()
31
+ .setAppId(COMETCHAT_CONSTANTS.APP_ID)
32
+ .setRegion(COMETCHAT_CONSTANTS.REGION)
33
+ .setAuthKey(COMETCHAT_CONSTANTS.AUTH_KEY)
34
+ .subscribePresenceForAllUsers()
35
+ .build();
36
+
37
+ CometChatUIKit.init(settings)?.then(() => {
38
+ CometChatUIKit.getLoggedinUser().then((u) => {
39
+ if (!u) {
40
+ CometChatUIKit.login(UID)
41
+ .then(setUser)
42
+ .catch((e: unknown) => setError(String(e)));
43
+ } else {
44
+ setUser(u);
45
+ }
46
+ });
47
+ }).catch((e: unknown) => setError(String(e)));
48
+ }, []);
49
+
50
+ const handleSelectorItemClicked = (
51
+ activeItem: CometChat.Conversation | CometChat.User | CometChat.Group,
52
+ ) => {
53
+ const item =
54
+ activeItem instanceof CometChat.Conversation
55
+ ? activeItem.getConversationWith()
56
+ : activeItem;
57
+ if (item instanceof CometChat.User) {
58
+ setSelectedUser(item);
59
+ setSelectedGroup(undefined);
60
+ } else if (item instanceof CometChat.Group) {
61
+ setSelectedUser(undefined);
62
+ setSelectedGroup(item);
63
+ }
64
+ };
65
+
66
+ if (error) return <div style={{ color: "red", padding: 16, fontFamily: "monospace" }}>{error}</div>;
67
+ if (!user) return null;
68
+
69
+ return (
70
+ <div className="conversations-with-messages">
71
+ <div className="conversations-wrapper">
72
+ <CometChatTabs
73
+ activeTab={activeTab}
74
+ onTabChange={setActiveTab}
75
+ onItemClick={handleSelectorItemClicked}
76
+ />
77
+ </div>
78
+ {selectedUser || selectedGroup ? (
79
+ <div className="messages-wrapper">
80
+ {selectedUser && <CometChatMessageHeader user={selectedUser} />}
81
+ {selectedGroup && <CometChatMessageHeader group={selectedGroup} />}
82
+ {selectedUser && <CometChatMessageList user={selectedUser} />}
83
+ {selectedGroup && <CometChatMessageList group={selectedGroup} />}
84
+ {selectedUser && <CometChatMessageComposer user={selectedUser} />}
85
+ {selectedGroup && <CometChatMessageComposer group={selectedGroup} />}
86
+ </div>
87
+ ) : (
88
+ <div className="empty-conversation">Select a conversation to start chatting</div>
89
+ )}
90
+ </div>
91
+ );
92
+ };
93
+ export default CometChatNoSSR;
@@ -0,0 +1,43 @@
1
+ .cometchat-tabs {
2
+ height: 100%;
3
+ width: 100%;
4
+ display: flex;
5
+ flex-direction: column;
6
+ }
7
+
8
+ .cometchat-tabs-content {
9
+ flex: 1;
10
+ overflow: hidden;
11
+ display: flex;
12
+ flex-direction: column;
13
+ }
14
+
15
+ .cometchat-tabs-content > .cometchat {
16
+ flex: 1;
17
+ overflow: hidden;
18
+ }
19
+
20
+ .cometchat-tabs-bar {
21
+ display: flex;
22
+ border-top: 1px solid var(--cometchat-border-color-default, #e8e8e8);
23
+ background: var(--cometchat-background-color-01, #ffffff);
24
+ }
25
+
26
+ .cometchat-tabs-bar-tab {
27
+ flex: 1;
28
+ padding: 12px 8px;
29
+ border: none;
30
+ background: transparent;
31
+ font: var(--cometchat-font-body-regular, 400 14px Roboto);
32
+ color: var(--cometchat-text-color-secondary, #727272);
33
+ cursor: pointer;
34
+ }
35
+
36
+ .cometchat-tabs-bar-tab.active {
37
+ color: var(--cometchat-primary-color, #6852d6);
38
+ font-weight: 600;
39
+ }
40
+
41
+ .cometchat-tabs-bar-tab:hover {
42
+ background: var(--cometchat-background-color-02, #f8f8f8);
43
+ }
@@ -0,0 +1,73 @@
1
+ "use client";
2
+ import { useEffect, useState } from "react";
3
+ import { CometChat } from "@cometchat/chat-sdk-javascript";
4
+ import {
5
+ CometChatCallLogs,
6
+ CometChatConversations,
7
+ CometChatGroups,
8
+ CometChatUIKitLoginListener,
9
+ CometChatUsers,
10
+ } from "@cometchat/chat-uikit-react";
11
+ import "./CometChatTabs.css";
12
+
13
+ export type CometChatTab = "chats" | "calls" | "users" | "groups";
14
+
15
+ interface CometChatTabsProps {
16
+ activeTab: CometChatTab;
17
+ onTabChange: (tab: CometChatTab) => void;
18
+ onItemClick: (
19
+ item: CometChat.Conversation | CometChat.User | CometChat.Group,
20
+ ) => void;
21
+ }
22
+
23
+ const TABS: { id: CometChatTab; label: string }[] = [
24
+ { id: "chats", label: "Chats" },
25
+ { id: "calls", label: "Calls" },
26
+ { id: "users", label: "Users" },
27
+ { id: "groups", label: "Groups" },
28
+ ];
29
+
30
+ export const CometChatTabs = ({
31
+ activeTab,
32
+ onTabChange,
33
+ onItemClick,
34
+ }: CometChatTabsProps) => {
35
+ const [loggedInUser, setLoggedInUser] = useState<CometChat.User | null>(null);
36
+
37
+ useEffect(() => {
38
+ setLoggedInUser(CometChatUIKitLoginListener.getLoggedInUser());
39
+ }, []);
40
+
41
+ if (!loggedInUser) return null;
42
+
43
+ return (
44
+ <div className="cometchat-tabs">
45
+ <div className="cometchat-tabs-content">
46
+ {activeTab === "chats" && (
47
+ <CometChatConversations
48
+ onItemClick={(c) => onItemClick(c)}
49
+ />
50
+ )}
51
+ {activeTab === "calls" && <CometChatCallLogs />}
52
+ {activeTab === "users" && (
53
+ <CometChatUsers onItemClick={(u) => onItemClick(u)} />
54
+ )}
55
+ {activeTab === "groups" && (
56
+ <CometChatGroups onItemClick={(g) => onItemClick(g)} />
57
+ )}
58
+ </div>
59
+ <nav className="cometchat-tabs-bar">
60
+ {TABS.map((tab) => (
61
+ <button
62
+ key={tab.id}
63
+ type="button"
64
+ className={`cometchat-tabs-bar-tab${activeTab === tab.id ? " active" : ""}`}
65
+ onClick={() => onTabChange(tab.id)}
66
+ >
67
+ {tab.label}
68
+ </button>
69
+ ))}
70
+ </nav>
71
+ </div>
72
+ );
73
+ };
@@ -0,0 +1,11 @@
1
+ "use client";
2
+ import dynamic from "next/dynamic";
3
+
4
+ const CometChatComponent = dynamic(
5
+ () => import("../cometchat/CometChatNoSSR"),
6
+ { ssr: false }
7
+ );
8
+
9
+ export default function ChatPage() {
10
+ return <CometChatComponent />;
11
+ }
@@ -0,0 +1,21 @@
1
+ import React, { lazy, Suspense, useEffect, useState } from "react";
2
+
3
+ const CometChatNoSSR = lazy(() => import("../cometchat/CometChatNoSSR"));
4
+
5
+ export default function CometChatRoute() {
6
+ const [mounted, setMounted] = useState(false);
7
+
8
+ useEffect(() => {
9
+ setMounted(true);
10
+ }, []);
11
+
12
+ if (!mounted) {
13
+ return <div style={{ padding: 16 }}>Loading…</div>;
14
+ }
15
+
16
+ return (
17
+ <Suspense fallback={<div style={{ padding: 16 }}>Loading…</div>}>
18
+ <CometChatNoSSR />
19
+ </Suspense>
20
+ );
21
+ }
@@ -0,0 +1,39 @@
1
+ .conversations-with-messages {
2
+ display: flex;
3
+ height: 100vh;
4
+ width: 100%;
5
+ }
6
+
7
+ .conversations-wrapper {
8
+ height: 100%;
9
+ width: 480px;
10
+ overflow: hidden;
11
+ display: flex;
12
+ flex-direction: column;
13
+ }
14
+
15
+ .conversations-wrapper > .cometchat {
16
+ overflow: hidden;
17
+ }
18
+
19
+ .messages-wrapper {
20
+ width: calc(100% - 480px);
21
+ height: 100%;
22
+ display: flex;
23
+ flex-direction: column;
24
+ }
25
+
26
+ .empty-conversation {
27
+ height: 100%;
28
+ width: 100%;
29
+ display: flex;
30
+ justify-content: center;
31
+ align-items: center;
32
+ background: white;
33
+ color: var(--cometchat-text-color-secondary, #727272);
34
+ font: var(--cometchat-font-body-regular, 400 14px Roboto);
35
+ }
36
+
37
+ .cometchat .cometchat-message-composer {
38
+ border-radius: 0;
39
+ }
@@ -0,0 +1,94 @@
1
+ import React, { useEffect, useState } from "react";
2
+ import {
3
+ CometChatMessageComposer,
4
+ CometChatMessageHeader,
5
+ CometChatMessageList,
6
+ CometChatUIKit,
7
+ UIKitSettingsBuilder,
8
+ } from "@cometchat/chat-uikit-react";
9
+ import { CometChat } from "@cometchat/chat-sdk-javascript";
10
+ import { CometChatTabs, type CometChatTab } from "./CometChatTabs";
11
+ // css-variables.css is imported in app/app.css — do NOT import it here
12
+ import "./CometChatNoSSR.css";
13
+
14
+ const COMETCHAT_CONSTANTS = {
15
+ APP_ID: import.meta.env.{{ENV_PREFIX}}COMETCHAT_APP_ID as string,
16
+ REGION: import.meta.env.{{ENV_PREFIX}}COMETCHAT_REGION as string,
17
+ AUTH_KEY: import.meta.env.{{ENV_PREFIX}}COMETCHAT_AUTH_KEY as string,
18
+ };
19
+ const UID = "{{LOGIN_UID}}";
20
+
21
+ const CometChatNoSSR: React.FC = () => {
22
+ const [user, setUser] = useState<CometChat.User | undefined>();
23
+ const [error, setError] = useState<string | null>(null);
24
+ const [activeTab, setActiveTab] = useState<CometChatTab>("chats");
25
+ const [selectedUser, setSelectedUser] = useState<CometChat.User | undefined>();
26
+ const [selectedGroup, setSelectedGroup] = useState<CometChat.Group | undefined>();
27
+
28
+ useEffect(() => {
29
+ if (typeof window === "undefined") return;
30
+
31
+ const settings = new UIKitSettingsBuilder()
32
+ .setAppId(COMETCHAT_CONSTANTS.APP_ID)
33
+ .setRegion(COMETCHAT_CONSTANTS.REGION)
34
+ .setAuthKey(COMETCHAT_CONSTANTS.AUTH_KEY)
35
+ .subscribePresenceForAllUsers()
36
+ .build();
37
+
38
+ CometChatUIKit.init(settings)?.then(() => {
39
+ CometChatUIKit.getLoggedinUser().then((u) => {
40
+ if (!u) {
41
+ CometChatUIKit.login(UID)
42
+ .then(setUser)
43
+ .catch((e: unknown) => setError(String(e)));
44
+ } else {
45
+ setUser(u);
46
+ }
47
+ });
48
+ }).catch((e: unknown) => setError(String(e)));
49
+ }, []);
50
+
51
+ const handleSelectorItemClicked = (
52
+ activeItem: CometChat.Conversation | CometChat.User | CometChat.Group,
53
+ ) => {
54
+ const item =
55
+ activeItem instanceof CometChat.Conversation
56
+ ? activeItem.getConversationWith()
57
+ : activeItem;
58
+ if (item instanceof CometChat.User) {
59
+ setSelectedUser(item);
60
+ setSelectedGroup(undefined);
61
+ } else if (item instanceof CometChat.Group) {
62
+ setSelectedUser(undefined);
63
+ setSelectedGroup(item);
64
+ }
65
+ };
66
+
67
+ if (error) return <div style={{ color: "red", padding: 16, fontFamily: "monospace" }}>{error}</div>;
68
+ if (!user) return null;
69
+
70
+ return (
71
+ <div className="conversations-with-messages">
72
+ <div className="conversations-wrapper">
73
+ <CometChatTabs
74
+ activeTab={activeTab}
75
+ onTabChange={setActiveTab}
76
+ onItemClick={handleSelectorItemClicked}
77
+ />
78
+ </div>
79
+ {selectedUser || selectedGroup ? (
80
+ <div className="messages-wrapper">
81
+ {selectedUser && <CometChatMessageHeader user={selectedUser} />}
82
+ {selectedGroup && <CometChatMessageHeader group={selectedGroup} />}
83
+ {selectedUser && <CometChatMessageList user={selectedUser} />}
84
+ {selectedGroup && <CometChatMessageList group={selectedGroup} />}
85
+ {selectedUser && <CometChatMessageComposer user={selectedUser} />}
86
+ {selectedGroup && <CometChatMessageComposer group={selectedGroup} />}
87
+ </div>
88
+ ) : (
89
+ <div className="empty-conversation">Select a conversation to start chatting</div>
90
+ )}
91
+ </div>
92
+ );
93
+ };
94
+ export default CometChatNoSSR;