feat: integrate sidebar state management with user store; replace local open state with sidebarIsOpen from useUserStore

This commit is contained in:
Rémi 2025-01-07 17:18:20 +01:00
parent cf9fd767f3
commit 1a3bc63d2e
2 changed files with 30 additions and 14 deletions

View File

@ -7,6 +7,7 @@ import {
} from "react-icons/bs"; } from "react-icons/bs";
import { ThemeSwitcher } from "../ThemeSwitcher/ThemeSwitcher"; import { ThemeSwitcher } from "../ThemeSwitcher/ThemeSwitcher";
import { SidebarItem } from "./item"; import { SidebarItem } from "./item";
import { useUserStore } from "@/app/stores/userStore";
export const Sidebar = ({ export const Sidebar = ({
items, items,
@ -21,11 +22,12 @@ export const Sidebar = ({
const pathName = usePathname(); const pathName = usePathname();
// State to manage menu openness // State to manage menu openness
const [open, setOpen] = useState(true); const { setSidebarIsOpen, sidebarIsOpen } = useUserStore();
const [isMobile, setIsMobile] = useState(false); const [isMobile, setIsMobile] = useState(false);
useEffect(() => { useEffect(() => {
const handleResize = () => { const handleResize = () => {
if (sidebarIsOpen) return;
if (window.innerWidth <= 1024 && !isMobile) { if (window.innerWidth <= 1024 && !isMobile) {
setIsMobile(true); setIsMobile(true);
} else if (window.innerWidth > 1024 && isMobile) { } else if (window.innerWidth > 1024 && isMobile) {
@ -33,6 +35,8 @@ export const Sidebar = ({
} }
}; };
console.log("sidebarIsOpen", sidebarIsOpen);
handleResize(); handleResize();
window.addEventListener("resize", handleResize); window.addEventListener("resize", handleResize);
return () => window.removeEventListener("resize", handleResize); return () => window.removeEventListener("resize", handleResize);
@ -40,25 +44,25 @@ export const Sidebar = ({
useEffect(() => { useEffect(() => {
if (isMobile) { if (isMobile) {
setOpen(false); setSidebarIsOpen(false);
} }
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [isMobile]); }, [isMobile]);
return ( return (
<aside <aside
className={` className={`
${open ? "w-96" : "w-20"} ${sidebarIsOpen ? "w-96" : "w-20"} z-40 h-screen transition-all bg-foreground-100
top-0 left-0 z-40 h-screen transition-all bg-foreground-100
`} `}
> >
{/* items-center lg:items-start */} {/* items-center lg:items-start */}
<div <div
className={`flex flex-col h-full px-3 py-4 overflow-y-auto scrollbar-hide ${open ? "items-start" : "items-center"}`} className={`flex flex-col h-full px-3 py-4 overflow-y-auto scrollbar-hide ${sidebarIsOpen ? "items-start" : "items-center"}`}
> >
<div <div
className={`flex flex-col gap-2 p-2 mb-4 w-full ${!open ? "items-center" : ""}`} className={`flex flex-col gap-2 p-2 mb-4 w-full ${!sidebarIsOpen ? "items-center" : ""}`}
> >
{open ? ( {sidebarIsOpen ? (
<div className="flex items-center justify-between w-full"> <div className="flex items-center justify-between w-full">
<Link <Link
className="text-2xl font-semibold text-gray-900 dark:text-white rounded-lg cursor-pointer" className="text-2xl font-semibold text-gray-900 dark:text-white rounded-lg cursor-pointer"
@ -66,24 +70,28 @@ export const Sidebar = ({
> >
Toogether Toogether
</Link> </Link>
<button onClick={() => setOpen(!open)}> <button
onClick={() => setSidebarIsOpen(!sidebarIsOpen)}
>
<BsLayoutSidebarInset className="text-xl" /> <BsLayoutSidebarInset className="text-xl" />
</button> </button>
</div> </div>
) : ( ) : (
<button onClick={() => setOpen(!open)}> <button
onClick={() => setSidebarIsOpen(!sidebarIsOpen)}
>
<BsReverseLayoutSidebarInsetReverse className="text-xl" /> <BsReverseLayoutSidebarInsetReverse className="text-xl" />
</button> </button>
)} )}
{open && ( {sidebarIsOpen && (
<p className="text-sm text-foreground-400 dark:text-gray-400"> <p className="text-sm text-foreground-400 dark:text-gray-400">
Manage classes, rooms, and users Manage classes, rooms, and users
</p> </p>
)} )}
</div> </div>
{items.map((group, index) => ( {items.map((group, index) => (
<div key={index} className={open ? "w-full" : ""}> <div key={index} className={sidebarIsOpen ? "w-full" : ""}>
<section className="flex flex-col"> <section className="flex flex-col">
<ul className={`flex flex-col gap-2 w-full`}> <ul className={`flex flex-col gap-2 w-full`}>
{group.map((item, index) => ( {group.map((item, index) => (
@ -99,8 +107,8 @@ export const Sidebar = ({
href={item.href} href={item.href}
title={item.title} title={item.title}
icon={item.icon} icon={item.icon}
setOpen={setOpen} setOpen={setSidebarIsOpen}
showTitle={open} showTitle={sidebarIsOpen}
/> />
</li> </li>
))} ))}
@ -111,7 +119,9 @@ export const Sidebar = ({
)} )}
</div> </div>
))} ))}
<section className={`mt-auto ${!open && "justify-center"}`}> <section
className={`mt-auto ${!sidebarIsOpen && "justify-center"}`}
>
<ThemeSwitcher /> <ThemeSwitcher />
</section> </section>
</div> </div>

View File

@ -3,16 +3,19 @@ import { persist, createJSONStorage } from "zustand/middleware";
type UserStoreState = { type UserStoreState = {
currentClassId: string | null; currentClassId: string | null;
sidebarIsOpen: boolean;
}; };
type UserStoreActions = { type UserStoreActions = {
setCurrentClassId: (classId: string) => void; setCurrentClassId: (classId: string) => void;
setSidebarIsOpen: (isOpen: boolean) => void;
}; };
type UserStore = UserStoreState & UserStoreActions; type UserStore = UserStoreState & UserStoreActions;
const defaultState: UserStoreState = { const defaultState: UserStoreState = {
currentClassId: null, currentClassId: null,
sidebarIsOpen: false,
}; };
export const useUserStore = create<UserStore>()( export const useUserStore = create<UserStore>()(
@ -22,6 +25,9 @@ export const useUserStore = create<UserStore>()(
setCurrentClassId: (classId: string) => { setCurrentClassId: (classId: string) => {
set({ currentClassId: classId }); set({ currentClassId: classId });
}, },
setSidebarIsOpen: (isOpen: boolean) => {
set({ sidebarIsOpen: isOpen });
},
}), }),
{ {
name: "userStore", name: "userStore",