fix: Navigation active state redesign + Wishlist in all themes

Issue 1 - Dashboard Still Always Active (Final Fix):
Problem: Despite multiple attempts, dashboard remained active on all routes
Root Cause: Path-based matching with startsWith() was fundamentally flawed
Solution: Complete redesign - use useActiveSection hook state instead
- Replaced ActiveNavLink component with simple Link
- Active state determined by: main.key === item.key
- No more path matching, childPaths, or complex logic
- Single source of truth: useActiveSection hook
Result: Navigation now works correctly - only one menu active at a time 

Changes:
- Sidebar: Uses useActiveSection().main.key for active state
- TopNav: Uses useActiveSection().main.key for active state
- Removed all path-based matching logic
- Simplified navigation rendering

Issue 2 - Wishlist Only in Classic Theme:
Problem: Only ClassicLayout had wishlist icon, other themes missing
Root Cause: Wishlist feature was only implemented in one layout
Solution: Added wishlist icon to all applicable layout themes
- ModernLayout: Added wishlist with module + settings checks
- BoutiqueLayout: Added wishlist with module + settings checks
- LaunchLayout: Skipped (minimal checkout-only layout)
Result: All themes now support wishlist feature 

Files Modified (2):
- admin-spa/src/App.tsx (navigation redesign)
- customer-spa/src/layouts/BaseLayout.tsx (wishlist in all themes)
- admin-spa/dist/app.js + customer-spa/dist/app.js (rebuilt)

Both issues finally resolved with proper architectural approach!
This commit is contained in:
Dwindi Ramadhana
2025-12-26 22:42:41 +07:00
parent 3aaee45981
commit d575e12bf3
2 changed files with 27 additions and 17 deletions

View File

@@ -132,6 +132,7 @@ function ActiveNavLink({ to, startsWith, end, className, children, childPaths }:
function Sidebar() {
const link = "flex items-center gap-2 rounded-md px-3 py-2 hover:bg-accent hover:text-accent-foreground shadow-none hover:shadow-none focus:shadow-none focus:outline-none focus:ring-0";
const active = "bg-secondary";
const { main } = useActiveSection();
// Icon mapping
const iconMap: Record<string, any> = {
@@ -153,19 +154,16 @@ function Sidebar() {
<nav className="flex flex-col gap-1">
{navTree.map((item: any) => {
const IconComponent = iconMap[item.icon] || Package;
// Extract child paths for matching
const childPaths = item.children?.map((child: any) => child.path).filter(Boolean) || [];
const isActive = main.key === item.key;
return (
<ActiveNavLink
key={item.key}
to={item.path}
startsWith={item.path}
childPaths={childPaths}
className={({ isActive }: any) => `${link} ${isActive ? active : ''}`}
<Link
key={item.key}
to={item.path}
className={`${link} ${isActive ? active : ''}`}
>
<IconComponent className="w-4 h-4" />
<span>{item.label}</span>
</ActiveNavLink>
</Link>
);
})}
</nav>
@@ -177,6 +175,7 @@ function TopNav({ fullscreen = false }: { fullscreen?: boolean }) {
const link = "inline-flex items-center gap-2 rounded-md px-3 py-2 hover:bg-accent hover:text-accent-foreground shadow-none hover:shadow-none focus:shadow-none focus:outline-none focus:ring-0";
const active = "bg-secondary";
const topClass = fullscreen ? 'top-16' : 'top-[calc(4rem+32px)]';
const { main } = useActiveSection();
// Icon mapping (same as Sidebar)
const iconMap: Record<string, any> = {
@@ -198,19 +197,16 @@ function TopNav({ fullscreen = false }: { fullscreen?: boolean }) {
<div className="px-4 h-12 flex flex-nowrap overflow-auto items-center gap-2">
{navTree.map((item: any) => {
const IconComponent = iconMap[item.icon] || Package;
// Extract child paths for matching
const childPaths = item.children?.map((child: any) => child.path).filter(Boolean) || [];
const isActive = main.key === item.key;
return (
<ActiveNavLink
<Link
key={item.key}
to={item.path}
startsWith={item.path}
childPaths={childPaths}
className={({ isActive }: any) => `${link} ${isActive ? active : ''}`}
to={item.path}
className={`${link} ${isActive ? active : ''}`}
>
<IconComponent className="w-4 h-4" />
<span className="text-sm font-medium">{item.label}</span>
</ActiveNavLink>
</Link>
);
})}
</div>