This guide walks you through creating a tab-based messaging UI using React and CometChat UIKit. The UI will include different sections for Chats, Calls, Users, and Groups, allowing seamless navigation.
To manage navigation, let’s build a CometChatTabs component. This component will render different tabs and allow switching between sections dynamically.
Create a CometChatTabs folder inside your src directory and add the following files:
Report incorrect code
Copy
Ask AI
public/├── assets # These are the images you need to save│ ├── chats.svg│ ├── calls.svg│ ├── users.svg│ ├── groups.svgsrc/app/│── CometChatTabs/│ ├── CometChatTabs.tsx│ ├── CometChatTabs.css
import { useEffect, useState } from "react";import { Call, Conversation, Group, User, CometChat} from "@cometchat/chat-sdk-javascript";import { CometChatCallLogs, CometChatConversations, CometChatGroups, CometChatUIKit, CometChatUIKitLoginListener, CometChatUsers} from "@cometchat/chat-uikit-react";import { CometChatTabs } from "../CometChatTabs/CometChatTabs";// Define props interface for selectorinterface SelectorProps { onSelectorItemClicked?: (input: User | Group | Conversation | Call, type: string) => void;}export const CometChatSelector = (props: SelectorProps) => { const { onSelectorItemClicked = () => {}, } = props; // State to manage currently logged in user const [loggedInUser, setLoggedInUser] = useState<CometChat.User | null>(); // State to track selected conversation, user, group, or call const [activeItem, setActiveItem] = useState< Conversation | User | Group | Call | undefined >(); // State to track currently active tab: "chats", "calls", "users", or "groups" const [activeTab, setActiveTab] = useState<string>("chats"); // Fetch logged-in user once component mounts useEffect(() => { const user = CometChatUIKitLoginListener.getLoggedInUser(); setLoggedInUser(user); }, [CometChatUIKitLoginListener?.getLoggedInUser()]); // Logout function to clear user session const logOut = () => { CometChatUIKit.logout() .then(() => { setLoggedInUser(null); }) .catch((error) => { console.log("Logout error:", error); }); }; return ( <> {/* Render selector content only if a user is logged in */} {loggedInUser && ( <> {activeTab === "chats" && ( <CometChatConversations activeConversation={activeItem instanceof CometChat.Conversation ? activeItem : undefined} onItemClick={(item) => { setActiveItem(item); onSelectorItemClicked(item, "updateSelectedItem"); }} /> )} {activeTab === "calls" && ( <CometChatCallLogs activeCall={activeItem as Call} onItemClick={(item: Call) => { setActiveItem(item); onSelectorItemClicked(item, "updateSelectedItemCall"); }} /> )} {activeTab === "users" && ( <CometChatUsers activeUser={activeItem as User} onItemClick={(item) => { setActiveItem(item); onSelectorItemClicked(item, "updateSelectedItemUser"); }} /> )} {activeTab === "groups" && ( <CometChatGroups activeGroup={activeItem as Group} onItemClick={(item) => { setActiveItem(item); onSelectorItemClicked(item, "updateSelectedItemGroup"); }} /> )} </> )} {/* Render the tab switcher at the bottom */} <CometChatTabs activeTab={activeTab} onTabClicked={(item) => { setActiveTab(item.name.toLowerCase()); // Update tab on click }} /> </> );};
CometChatSelector.css
Report incorrect code
Copy
Ask AI
/* Style the icon inside header menu in conversation list */.selector-wrapper .cometchat-conversations .cometchat-list__header-menu .cometchat-button__icon { background: var(--cometchat-icon-color-primary); /* Primary icon color */}/* Highlight icon on hover */.cometchat-conversations .cometchat-list__header-menu .cometchat-button__icon:hover { background: var(--cometchat-icon-color-highlight); /* Highlighted icon color on hover */}/* Remove right border from the search bar inside the list */.cometchat-list__header-search-bar { border-right: none;}/* Align menu list items to the left */.cometchat .cometchat-menu-list__sub-menu-list-item { text-align: left;}/* Positioning for the submenu inside conversations menu */.cometchat .cometchat-conversations .cometchat-menu-list__sub-menu-list { width: 212px; top: 40px !important; left: 172px !important;}/* Style for the logged-in user section with bottom border */#logged-in-user { border-bottom: 2px solid var(--cometchat-border-color-default, #E8E8E8);}/* Make submenu items under logged-in user non-clickable */#logged-in-user .cometchat-menu-list__sub-menu-item-title,#logged-in-user .cometchat-menu-list__sub-menu-list-item { cursor: default;}/* Logout icon color inside submenu */.cometchat-menu-list__sub-menu-list-item-icon-log-out { background-color: var(--cometchat-error-color, #F44649); /* Error color */}/* Logout label/text color inside submenu */.cometchat-menu-list__sub-menu-item-title-log-out { color: var(--cometchat-error-color, #F44649);}/* Enable pointer cursor for chat menu item titles */.chat-menu .cometchat .cometchat-menu-list__sub-menu-item-title { cursor: pointer;}/* Remove shadow from the chat menu's submenu */.chat-menu .cometchat .cometchat-menu-list__sub-menu { box-shadow: none;}/* Style the icons inside chat menu items */.chat-menu .cometchat .cometchat-menu-list__sub-menu-icon { background-color: var(--cometchat-icon-color-primary, #141414); width: 24px; height: 24px;}
Now, create a route for CometChat in your routes file:
Report incorrect code
Copy
Ask AI
import { type RouteConfig, index, route } from "@react-router/dev/routes";export default [ index("routes/home.tsx"), route("chat", "routes/CometChat.tsx"), // Chat Route] satisfies RouteConfig;
Why disable SSR? CometChat UI Kit Builder relies on browser APIs such as window, document, and WebSockets. Since React Router renders on the server by default, disabling SSR for this component prevents runtime errors.