Spaces:
Sleeping
Sleeping
"use client"; | |
import { VERSION } from "@/lib/config"; | |
import { usePathname } from "next/navigation"; | |
import { Bars3Icon, UserCircleIcon, Cog6ToothIcon, QuestionMarkCircleIcon, BoltIcon } from "@heroicons/react/20/solid"; | |
import Link from "next/link"; | |
import { useEffect, useState, useRef } from "react"; | |
import Image from "next/image"; | |
import logo from "@assets/logo.png"; | |
export default function Sidebar() { | |
const pathname = usePathname(); | |
const [accessLevel, setAccessLevel] = useState(null); | |
const [isCollapsed, setIsCollapsed] = useState(true); | |
const sidebarRef = useRef(null); | |
const toggleSidebar = () => { | |
setIsCollapsed(!isCollapsed); | |
}; | |
useEffect(() => { | |
setAccessLevel(localStorage.getItem("a_l")); | |
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", | |
height: isCollapsed ? "60px" : "150px", | |
borderRadius: "50px", | |
transition: "width 0.3s ease, height 0.3s ease", | |
marginBottom: 0, | |
marginTop: "20px", | |
}; | |
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 versionStyle = { | |
color: "var(--hover-accent)", | |
fontSize: isCollapsed ? "0.6em" : "0.9em", | |
marginTop: "20px", | |
textAlign: "end", | |
}; | |
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", | |
}; | |
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="App Logo" /> | |
<sup style={versionStyle}>{VERSION}</sup> | |
<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) }}> | |
<UserCircleIcon style={iconStyle} /> | |
<span style={textStyle}>Profile</span> | |
</a> | |
</Link> | |
</li> | |
<li> | |
<Link href={`/su/${accessLevel}`} legacyBehavior> | |
<a style={{ ...navLinkStyle, ...(pathname === `/su/${accessLevel}` && activeNavLinkStyle) }}> | |
<BoltIcon style={iconStyle} /> | |
<span style={textStyle}>{accessLevel}</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="/support" legacyBehavior> | |
<a style={{ ...navLinkStyle, ...(pathname === "/support" && activeNavLinkStyle) }}> | |
<QuestionMarkCircleIcon style={iconStyle} /> | |
<span style={textStyle}>Support</span> | |
</a> | |
</Link> | |
</li> | |
</ul> | |
</div> | |
); | |
} | |