diff --git a/frontend/src/components/ChatHeader.jsx b/frontend/src/components/ChatHeader.jsx index 46a810a..9688dff 100644 --- a/frontend/src/components/ChatHeader.jsx +++ b/frontend/src/components/ChatHeader.jsx @@ -10,6 +10,7 @@ import { Image, Trash, Search, + Users, } from "lucide-react"; import { useState, useRef, useEffect } from "react"; import { motion, AnimatePresence } from "framer-motion"; @@ -18,6 +19,16 @@ import { useChatStore } from "../store/useChatStore"; import GroupMembersModal from "./GroupMembersModal"; import { useCallStore } from "../store/useCallStore"; +const IconBtn = ({ children, onClick, ...props }) => ( + + {children} + +); + const ChatHeader = () => { const { selectedUser, @@ -39,21 +50,41 @@ const ChatHeader = () => { const { authUser } = useAuthStore(); const { startCall, startGroupCall } = useCallStore(); + const [showInfoPanel, setShowInfoPanel] = useState(false); + const infoRef = useRef(null); const [showMembers, setShowMembers] = useState(false); const [openMenu, setOpenMenu] = useState(false); const [showSearch, setShowSearch] = useState(false); const menuRef = useRef(null); - useEffect(() => { - const handleClickOutside = (e) => { - if (menuRef.current && !menuRef.current.contains(e.target)) { - setOpenMenu(false); - } - }; - document.addEventListener("mousedown", handleClickOutside); - return () => document.removeEventListener("mousedown", handleClickOutside); - }, []); + +useEffect(() => { + const handleClickOutside = (e) => { + if (menuRef.current && !menuRef.current.contains(e.target)) { + setOpenMenu(false); + } + if (infoRef.current && !infoRef.current.contains(e.target)) { + setShowInfoPanel(false); + } + }; + + const handleKeyDown = (e) => { + if (e.key === "Escape") { + setShowInfoPanel(false); + setOpenMenu(false); + setShowSearch(false); + } + }; + + document.addEventListener("mousedown", handleClickOutside); + document.addEventListener("keydown", handleKeyDown); + + return () => { + document.removeEventListener("mousedown", handleClickOutside); + document.removeEventListener("keydown", handleKeyDown); + }; +}, []); if (!selectedUser && !selectedGroup) return null; const isGroup = selectedChatType === "group"; @@ -110,6 +141,7 @@ const ChatHeader = () => { await removeChatWallpaper(chatId); setOpenMenu(false); }; + return ( @@ -215,61 +247,117 @@ const ChatHeader = () => { - - {isGroup ? ( - <> - setShowMembers(true)}> - - - - startGroupCall({ - groupId: selectedGroup._id, - callType: "voice", - }) - } - > - - - - startGroupCall({ - groupId: selectedGroup._id, - callType: "video", - }) - } - > - - - > - ) : ( - !isAI && ( - <> - - startCall({ - receiver: selectedUser, - callType: "voice", - }) - } - > - - - - startCall({ - receiver: selectedUser, - callType: "video", - }) - } - > - - - > - ) - )} + + {!isAI && ( + + + setShowInfoPanel(v => !v)} aria-label="Open chat info"> + + + + + {showInfoPanel && ( + <> + setShowInfoPanel(false)} + /> + + {/* Header info */} + + {isGroup ? ( + + + {selectedGroup.name[0]?.toUpperCase()} + + + ) : ( + + + {onlineUsers.includes(selectedUser?._id) && ( + + )} + + )} + + + {isGroup ? selectedGroup.name : selectedUser.fullName} + + + {isGroup + ? `${selectedGroup.members?.length || 0} members` + : onlineUsers.includes(selectedUser?._id) + ? "Active now" + : "Offline"} + + + + {/* Action buttons */} + + { + setShowInfoPanel(false); + isGroup + ? startGroupCall({ groupId: selectedGroup._id, callType: "voice" }) + : startCall({ receiver: selectedUser, callType: "voice" }); + }} + className="flex flex-col items-center gap-1" + > + + + + Voice + + { + setShowInfoPanel(false); + isGroup + ? startGroupCall({ groupId: selectedGroup._id, callType: "video" }) + : startCall({ receiver: selectedUser, callType: "video" }); + }} + className="flex flex-col items-center gap-1" + > + + + + Video + + + {isGroup && ( + { + setShowInfoPanel(false); + setShowMembers(true); + }} + className="flex flex-col items-center gap-1" + > + + + + Members + + )} + + + > + )} + + + )} {/*SEARCH */} setShowSearch((s) => !s)}> @@ -315,8 +403,7 @@ const ChatHeader = () => { > - - + {openMenu && ( { Change Wallpaper - { setShowMembers(false)} - /> + /> )} ); }; -const IconBtn = ({ children, onClick }) => ( - - {children} - -); + + export default ChatHeader;
+ {isGroup ? selectedGroup.name : selectedUser.fullName} +
+ {isGroup + ? `${selectedGroup.members?.length || 0} members` + : onlineUsers.includes(selectedUser?._id) + ? "Active now" + : "Offline"} +