Fixed UI misalignments
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
import React, { useState } from 'react';
|
||||
import { NavLink, Outlet, useNavigate, Link } from 'react-router-dom';
|
||||
import { NavLink, Outlet, useNavigate, Link, useLocation } from 'react-router-dom';
|
||||
import { NotificationBell } from './NotificationBell';
|
||||
import {
|
||||
Inbox,
|
||||
@@ -144,6 +144,27 @@ export const AppLayout: React.FC = () => {
|
||||
const [sidebarOpen, setSidebarOpen] = useState(true);
|
||||
const [userMenuOpen, setUserMenuOpen] = useState(false);
|
||||
const navigate = useNavigate();
|
||||
const location = useLocation();
|
||||
const [collapsedSections, setCollapsedSections] = useState<Record<string, boolean>>({});
|
||||
|
||||
const isSectionCollapsed = (path: string, subItems?: SubNavItem[]): boolean => {
|
||||
if (collapsedSections[path] !== undefined) {
|
||||
return collapsedSections[path];
|
||||
}
|
||||
if (subItems?.some((s) => location.pathname.startsWith(s.path))) {
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
const toggleSection = (path: string, e: React.MouseEvent) => {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
setCollapsedSections((prev) => ({
|
||||
...prev,
|
||||
[path]: !isSectionCollapsed(path),
|
||||
}));
|
||||
};
|
||||
|
||||
const handleLogout = async () => {
|
||||
await logout();
|
||||
@@ -344,26 +365,45 @@ export const AppLayout: React.FC = () => {
|
||||
);
|
||||
}
|
||||
|
||||
const isCollapsed = isSectionCollapsed(item.path, item.subItems);
|
||||
|
||||
return (
|
||||
<div key={item.path} className="space-y-1">
|
||||
<NavLink
|
||||
to={item.path}
|
||||
end={hasSub}
|
||||
className={({ isActive }) =>
|
||||
`flex items-center gap-3 px-3.5 py-2.5 rounded-xl text-xs font-medium transition-all min-w-0 ${
|
||||
isActive
|
||||
? 'bg-gradient-to-r from-blue-600 to-indigo-600 text-white shadow-md shadow-blue-600/25 font-semibold'
|
||||
: 'text-slate-400 hover:text-slate-100 hover:bg-slate-800/60'
|
||||
}`
|
||||
}
|
||||
title={item.name}
|
||||
>
|
||||
<Icon className="w-4.5 h-4.5 shrink-0" />
|
||||
<span className="truncate flex-1">{item.name}</span>
|
||||
</NavLink>
|
||||
<div className="flex items-center gap-1">
|
||||
<NavLink
|
||||
to={item.path}
|
||||
end={hasSub}
|
||||
className={({ isActive }) =>
|
||||
`flex-1 flex items-center gap-3 px-3.5 py-2.5 rounded-xl text-xs font-medium transition-all min-w-0 ${
|
||||
isActive
|
||||
? 'bg-gradient-to-r from-blue-600 to-indigo-600 text-white shadow-md shadow-blue-600/25 font-semibold'
|
||||
: 'text-slate-400 hover:text-slate-100 hover:bg-slate-800/60'
|
||||
}`
|
||||
}
|
||||
title={item.name}
|
||||
>
|
||||
<Icon className="w-4.5 h-4.5 shrink-0" />
|
||||
<span className="truncate flex-1">{item.name}</span>
|
||||
</NavLink>
|
||||
{hasSub && (
|
||||
<button
|
||||
type="button"
|
||||
onClick={(e) => toggleSection(item.path, e)}
|
||||
className="p-2 text-slate-400 hover:text-white hover:bg-slate-800/80 rounded-lg transition-colors cursor-pointer"
|
||||
title={isCollapsed ? `Expand ${item.name}` : `Collapse ${item.name}`}
|
||||
aria-label={isCollapsed ? `Expand ${item.name}` : `Collapse ${item.name}`}
|
||||
>
|
||||
<ChevronDown
|
||||
className={`w-3.5 h-3.5 transition-transform duration-200 ${
|
||||
isCollapsed ? '-rotate-90 text-slate-500' : 'rotate-0 text-slate-300'
|
||||
}`}
|
||||
/>
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{/* Sub-items under parent item */}
|
||||
{hasSub && (
|
||||
{hasSub && !isCollapsed && (
|
||||
<div className="pl-6 pr-1 py-1 space-y-1 border-l border-slate-800/80 ml-5">
|
||||
{item.subItems?.map((subItem) => {
|
||||
const SubIcon = subItem.icon;
|
||||
|
||||
Reference in New Issue
Block a user