From 41af501b51364dffe7a156e2f35214d93cd62fb2 Mon Sep 17 00:00:00 2001 From: bokhonglo Date: Wed, 29 Apr 2026 16:32:46 +0700 Subject: [PATCH] update: layout --- src/app/user/layout.tsx | 17 ++--- src/context/SidebarContext.tsx | 2 +- src/layout/AppHeader.tsx | 81 +++++++++++------------ src/layout/AppSidebar.tsx | 113 ++++++++++++++++++++++++--------- src/layout/Backdrop.tsx | 2 +- 5 files changed, 128 insertions(+), 87 deletions(-) diff --git a/src/app/user/layout.tsx b/src/app/user/layout.tsx index 210c036..239c85c 100644 --- a/src/app/user/layout.tsx +++ b/src/app/user/layout.tsx @@ -8,7 +8,6 @@ import { apiGetCurrentUser } from "@/service/auth"; import { setUserData } from "@/store/features/userSlice"; import React, { useEffect } from "react"; import { useDispatch } from "react-redux"; -import { usePathname } from "next/navigation"; export default function AdminLayout({ children, @@ -17,8 +16,6 @@ export default function AdminLayout({ }) { const { isExpanded, isHovered, isMobileOpen } = useSidebar(); const dispatch = useDispatch() - const pathname = usePathname(); - const isHomePage = pathname === "/"; useEffect(() => { const fetchUser = async () => { @@ -34,19 +31,17 @@ export default function AdminLayout({ // Dynamic class for main content margin based on sidebar state - const mainContentMargin = isHomePage + const mainContentMargin = isMobileOpen ? "ml-0" - : isMobileOpen - ? "ml-0" - : isExpanded || isHovered - ? "lg:ml-[290px]" - : "lg:ml-[90px]"; + : isExpanded || isHovered + ? "lg:ml-[290px]" + : "lg:ml-[0px]"; return (
{/* Sidebar and Backdrop */} - {!isHomePage && } - {!isHomePage && } + + {/* Main Content Area */}
{ export const SidebarProvider: React.FC<{ children: React.ReactNode }> = ({ children, }) => { - const [isExpanded, setIsExpanded] = useState(true); + const [isExpanded, setIsExpanded] = useState(false); const [isMobileOpen, setIsMobileOpen] = useState(false); const [isMobile, setIsMobile] = useState(false); const [isHovered, setIsHovered] = useState(false); diff --git a/src/layout/AppHeader.tsx b/src/layout/AppHeader.tsx index 0713588..53d95c3 100644 --- a/src/layout/AppHeader.tsx +++ b/src/layout/AppHeader.tsx @@ -5,15 +5,12 @@ import UserDropdown from "@/components/header/UserDropdown"; import { useSidebar } from "@/context/SidebarContext"; import Image from "next/image"; import Link from "next/link"; -import { usePathname } from "next/navigation"; import React, { useState ,useEffect,useRef} from "react"; const AppHeader: React.FC = () => { const [isApplicationMenuOpen, setApplicationMenuOpen] = useState(false); const { isMobileOpen, toggleSidebar, toggleMobileSidebar } = useSidebar(); - const pathname = usePathname(); - const isHomePage = pathname === "/"; const handleToggle = () => { if (window.innerWidth >= 1024) { @@ -47,46 +44,44 @@ const AppHeader: React.FC = () => {
- {!isHomePage && ( - - )} + { const { isExpanded, isMobileOpen, isHovered, setIsHovered } = useSidebar(); const pathname = usePathname(); - const [openSubmenu, setOpenSubmenu] = useState<{ type: "main" | "others"; index: number; } | null>(null); - const [subMenuHeight, setSubMenuHeight] = useState>({}); + const [subMenuHeight, setSubMenuHeight] = useState>( + {}, + ); const subMenuRefs = useRef>({}); const isActive = useCallback((path: string) => path === pathname, [pathname]); const handleSubmenuToggle = (index: number, menuType: "main" | "others") => { - setOpenSubmenu((prev) => - prev?.type === menuType && prev?.index === index ? null : { type: menuType, index } + setOpenSubmenu((prev) => + prev?.type === menuType && prev?.index === index + ? null + : { type: menuType, index }, ); }; - useEffect(() => { + useEffect(() => { let submenuMatched = false; [ { items: ALL_NAV_ITEMS, type: "main" }, @@ -151,23 +154,41 @@ const AppSidebar: React.FC = () => { onClick={() => handleSubmenuToggle(index, menuType)} className={`menu-item group uppercase ${ openSubmenu?.type === menuType && openSubmenu?.index === index - ? "menu-item-active" : "menu-item-inactive" + ? "menu-item-active" + : "menu-item-inactive" } cursor-pointer ${!isExpanded && !isHovered ? "lg:justify-center" : "lg:justify-start"}`} > - + {nav.icon} {(isExpanded || isHovered || isMobileOpen) && ( <> {nav.name} - + )} ) : ( nav.path && ( - - + + {nav.icon} {(isExpanded || isHovered || isMobileOpen) && ( @@ -178,18 +199,40 @@ const AppSidebar: React.FC = () => { )} {nav.subItems && (isExpanded || isHovered || isMobileOpen) && (
{ subMenuRefs.current[`${menuType}-${index}`] = el; }} + ref={(el) => { + subMenuRefs.current[`${menuType}-${index}`] = el; + }} className="overflow-hidden transition-all duration-300" - style={{ height: openSubmenu?.type === menuType && openSubmenu?.index === index ? `${subMenuHeight[`${menuType}-${index}`]}px` : "0px" }} + style={{ + height: + openSubmenu?.type === menuType && openSubmenu?.index === index + ? `${subMenuHeight[`${menuType}-${index}`]}px` + : "0px", + }} >
    {nav.subItems.map((subItem) => (
  • - + {subItem.name} - {subItem.new && new} - {subItem.pro && pro} + {subItem.new && ( + + new + + )} + {subItem.pro && ( + + pro + + )}
  • @@ -204,19 +247,21 @@ const AppSidebar: React.FC = () => { return (