Fixed UI misalignments

This commit is contained in:
2026-10-26 19:57:32 +02:00
parent 80c798e5e6
commit 9f132eeb29
22 changed files with 860 additions and 214 deletions
@@ -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;