I am working on a Sidebar with Next.js, Tailwindcss, Shadcn-ui and i have written almost the same logic for opening the drawer if i click on a Sidebar icon. But i want to close the sidebar if i click again on the sidebar icon but my current code is not working properly. Can someone please look into it and tell where i am doing wrong.
Here is my SidebarOptions component code:
"use client";
import React, { useEffect, useRef, useState } from "react";
import { sidebarData } from "@/constants/sidebarData";
import Link from "next/link";
import {
Tooltip,
TooltipContent,
TooltipProvider,
TooltipTrigger,
} from "@/components/ui/tooltip";
import { HelpCircle, LogOut } from "lucide-react";
import { GoHome } from "react-icons/go";
const SidebarOptions = ({ onLinkClick, user }) => {
const [isSubmenuVisible, setIsSubmenuVisible] = useState(false);
const [openSection, setOpenSection] = useState(null);
const sidebarRef = useRef();
const handleSectionClick = (section) => {
const sectionData = dynamicSidebarData.find((sec) => sec.title === section);
if (!sectionData || sectionData.links.length === 0) {
return;
}
if (openSection === section) {
// Close the drawer if clicking on the same section
setIsSubmenuVisible(false);
setOpenSection(null);
} else {
// Open the drawer for a new section
setOpenSection(section);
setIsSubmenuVisible(true);
}
};
useEffect(() => {
const handleClickOutside = (event) => {
if (sidebarRef.current && !sidebarRef.current.contains(event.target)) {
setOpenSection(null);
}
};
if (openSection) {
document.addEventListener("mousedown", handleClickOutside);
} else {
document.removeEventListener("mousedown", handleClickOutside);
}
return () => {
document.removeEventListener("mousedown", handleClickOutside);
};
}, [openSection]);
// Dynamic path modification for the "Edit Public Profile" link
const dynamicSidebarData = sidebarData.map((section) => {
if (section.title === "Profile") {
return {
...section,
links: section.links.map((link) =>
link.name === "Edit Public Profile"
? {
...link,
path: `/dashboard/profile/${user._id}`,
}
: link
),
};
}
return section;
});
return (
<TooltipProvider>
<div className="flex h-screen">
<div className="flex flex-col w-12 bg-white border-r">
<div className="flex flex-col px-2 mb-2">
<Tooltip className="bg-black text-white">
<TooltipTrigger>
<Link
href="/dashboard"
className="flex flex-col items-center mb-3 p-2 text-[#F6F6F6] hover:bg-[#DFEDEE]
rounded cursor-pointertransition-all duration-200 ease-in-out transform"
>
<GoHome className="text-muted-foreground size-4" />
</Link>
</TooltipTrigger>
</Tooltip>
{dynamicSidebarData.map((section, sectionIndex) => (
<Tooltip key={sectionIndex} className="bg-black text-white">
<TooltipTrigger>
<div
className="flex flex-col items-center mb-3 p-2 text-[#F6F6F6] hover:bg-[#DFEDEE] rounded cursor-pointer
transition-all duration-200 ease-in-out transform"
onClick={() => handleSectionClick(section.title)}
>
{section.icon}
</div>
</TooltipTrigger>
<TooltipContent
side="right"
className="mr-2 bg-black text-white font-bold"
>
<p>{section.title}</p>
</TooltipContent>
</Tooltip>
))}
</div>
<div className="flex flex-col items-center mt-36 py-4">
<Tooltip className="bg-black text-white">
<TooltipTrigger>
<Link href="/help" legacyBehavior>
<a className="flex flex-col items-center mb-2 p-2 rounded">
<HelpCircle className="text-muted-foreground size-4" />
</a>
</Link>
</TooltipTrigger>
<TooltipContent side="right" className="mr-2">
<p className="">Help</p>
</TooltipContent>
</Tooltip>
<Tooltip className="bg-black text-white">
<TooltipTrigger>
<Link href="/logout" legacyBehavior>
<a className="flex flex-col items-center mb-6 p-2 rounded">
<LogOut className="text-rose-500 size-4" />
</a>
</Link>
</TooltipTrigger>
<TooltipContent side="right" className="mr-2">
<p className="">Logout</p>
</TooltipContent>
</Tooltip>
</div>
</div>
{openSection && (
<div
ref={sidebarRef}
className={`absolute left-16 top-0 backdrop-blur-md bg-white/50 bg-white border-r p-4 w-[200px] z-[99999] h-full overflow-y-auto
transform transition-all duration-300 ease-in-out
${
isSubmenuVisible
? "translate-x-0 opacity-100"
: "-translate-x-full opacity-0"
}`}
>
<h2 className="text-xl font-bold mb-4">{openSection}</h2>
{dynamicSidebarData
.find((section) => section.title === openSection)
.links.map((link, linkIndex) => (
<div
key={linkIndex}
className="flex items-center gap-2 my-2 p-2 hover:bg-gray-200 rounded cursor-pointer"
onClick={() => {
if (onLinkClick) {
onLinkClick(link.path);
}
setOpenSection(null);
}}
>
<Link href={link.path} className="text-gray-700">
{link.name}
</Link>
</div>
))}
</div>
)}
</div>
</TooltipProvider>
);
};
export default SidebarOptions;