| "use client"; | |
| import { usePathname } from "next/navigation"; | |
| import { Bars3Icon, Cog6ToothIcon, ArrowRightStartOnRectangleIcon, MagnifyingGlassIcon, ChatBubbleOvalLeftEllipsisIcon } from "@heroicons/react/20/solid"; | |
| import Link from "next/link"; | |
| import { useEffect, useState, useRef } from "react"; | |
| import { useRouter } from "next/navigation"; | |
| import Image from "next/image"; | |
| import logo from "@assets/logo.jpg"; | |
| import NexusAuthApi from "@/lib/Nexus_Auth_API"; | |
| export default function ChatSidebar() { | |
| const pathname = usePathname(); | |
| const [isCollapsed, setIsCollapsed] = useState(true); | |
| const sidebarRef = useRef(null); | |
| const router = useRouter(); | |
| const toggleSidebar = () => { | |
| setIsCollapsed(!isCollapsed); | |
| }; | |
| const clearLocalStorage = () => { | |
| localStorage.removeItem("me"); | |
| localStorage.removeItem("s_tkn"); | |
| localStorage.removeItem("u_id"); | |
| localStorage.removeItem("a_l"); | |
| }; | |
| useEffect(() => { | |
| const handleClickOutside = (event) => { | |
| if (sidebarRef.current && !sidebarRef.current.contains(event.target)) { | |
| setIsCollapsed(true); | |
| } | |
| }; | |
| document.addEventListener("mousedown", handleClickOutside); | |
| return () => document.removeEventListener("mousedown", handleClickOutside); | |
| }, []); | |
| const logoStyle = { | |
| width: isCollapsed ? "60px" : "150px", | |
| borderRadius: "50px", | |
| transition: "width 0.3s ease, height 0.3s ease", | |
| marginBottom: 0, | |
| marginTop: "35px", | |
| }; | |
| const sidebarStyle = { | |
| width: "180px", | |
| left: isCollapsed ? "-180px" : "0", | |
| backgroundColor: "var(--sidebar-background)", | |
| color: "var(--foreground)", | |
| padding: isCollapsed ? "15px" : "20px", | |
| position: "fixed", | |
| height: "100vh", | |
| display: "flex", | |
| flexDirection: "column", | |
| borderRight: "1px solid rgba(255, 255, 255, 0.1)", | |
| transition: "left 0.3s ease, width 0.3s ease, padding 0.3s ease", | |
| zIndex: 10, | |
| }; | |
| const navLinkStyle = { | |
| display: "flex", | |
| alignItems: "center", | |
| gap: "5px", | |
| padding: "10px 5px", | |
| transition: "all 0.3s ease", | |
| color: "var(--foreground)", | |
| fontSize: "1em", | |
| }; | |
| const activeNavLinkStyle = { | |
| backgroundColor: "var(--hover-accent)", | |
| borderRadius: "5px", | |
| animation: "fadeIn .5s ease-in-out, pulse .5s ease-in-out", | |
| }; | |
| const textStyle = { | |
| opacity: isCollapsed ? 0 : 1, | |
| transition: "opacity 0.3s ease", | |
| pointerEvents: isCollapsed ? "none" : "auto", | |
| }; | |
| const iconStyle = { | |
| width: "30px", | |
| height: "30px", | |
| flexShrink: 0, | |
| }; | |
| const toggleButtonStyle = { | |
| position: "absolute", | |
| top: "20px", | |
| right: isCollapsed ? "-50px" : "10px", | |
| width: "35px", | |
| height: "35px", | |
| backgroundColor: "var(--button-background)", | |
| color: "var(--foreground)", | |
| border: "none", | |
| borderRadius: "10px", | |
| cursor: "pointer", | |
| display: "flex", | |
| alignItems: "center", | |
| justifyContent: "center", | |
| boxShadow: "0 2px 5px rgba(0, 0, 0, 0.2)", | |
| transition: "background-color 0.3s ease, right 0.3s ease", | |
| }; | |
| const handleLogout = () => { | |
| const userID = localStorage.getItem('u_id'); | |
| const token = localStorage.getItem('s_tkn'); | |
| NexusAuthApi.logout(userID, token) | |
| .then(() => { | |
| clearLocalStorage(); | |
| router.push('/'); | |
| window.location.reload(); | |
| }) | |
| .catch((error) => { | |
| console.error("Logout failed", error); | |
| }); | |
| }; | |
| return ( | |
| <div ref={sidebarRef} className="sidebar-container" style={sidebarStyle}> | |
| <div className="logo-container" style={{ display: "flex", flexDirection: "column", alignItems: "center" }}> | |
| <Image style={logoStyle} src={logo} alt="Chat App Logo" /> | |
| <button | |
| style={toggleButtonStyle} | |
| onClick={() => toggleSidebar(!isCollapsed)} | |
| > | |
| <Bars3Icon style={{ transform: `rotate(${isCollapsed ? 0 : 90}deg)`, transition: "transform .3s", width: "20px" }} /> | |
| </button> | |
| </div> | |
| <ul className="nav-links" style={{ listStyleType: "none", marginTop: "20px", paddingLeft: "0" }}> | |
| <li> | |
| <Link href="/" legacyBehavior> | |
| <a style={{ ...navLinkStyle, ...(pathname === "/" && activeNavLinkStyle) }}> | |
| <ChatBubbleOvalLeftEllipsisIcon style={iconStyle} /> | |
| <span style={textStyle}>Chats</span> | |
| </a> | |
| </Link> | |
| </li> | |
| <li> | |
| <Link href="/search" legacyBehavior> | |
| <a style={{ ...navLinkStyle, ...(pathname === "/search" && activeNavLinkStyle) }}> | |
| <MagnifyingGlassIcon style={iconStyle} /> | |
| <span style={textStyle}>Find</span> | |
| </a> | |
| </Link> | |
| </li> | |
| <li> | |
| <Link href="/settings" legacyBehavior> | |
| <a style={{ ...navLinkStyle, ...(pathname === "/settings" && activeNavLinkStyle) }}> | |
| <Cog6ToothIcon style={iconStyle} /> | |
| <span style={textStyle}>Settings</span> | |
| </a> | |
| </Link> | |
| </li> | |
| <li> | |
| <Link href="#logout" legacyBehavior> | |
| <a style={{ ...navLinkStyle, ...(pathname === "#logout" && activeNavLinkStyle) }} onClick={handleLogout}> | |
| <ArrowRightStartOnRectangleIcon style={iconStyle} /> | |
| <span style={textStyle}>Logout</span> | |
| </a> | |
| </Link> | |
| </li> | |
| </ul> | |
| </div> | |
| ); | |
| } | |