Files
ember-market-frontend/components/layout/sidebar.tsx
g fe01f31538
Some checks failed
Build Frontend / build (push) Failing after 7s
Refactor UI imports and update component paths
Replaces imports from 'components/ui' with 'components/common' across the app and dashboard pages, and updates model and API imports to use new paths under 'lib'. Removes redundant authentication checks from several dashboard pages. Adds new dashboard components and utility files, and reorganizes hooks and services into the 'lib' directory for improved structure.
2026-01-13 05:02:13 +00:00

124 lines
4.0 KiB
TypeScript

"use client"
import { useState } from "react"
import Link from "next/link"
import { useRouter, usePathname } from "next/navigation"
import { ShoppingCart, LogOut, Shield } from "lucide-react"
import { NavItem } from "./nav-item"
import { Button } from "@/components/common/button"
import { sidebarConfig } from "@/config/sidebar"
import { adminSidebarConfig } from "@/config/admin-sidebar"
import { logoutUser } from "@/lib/utils/auth"
import { toast } from "sonner"
import { useUser } from "@/lib/hooks/useUser"
const Sidebar: React.FC = () => {
const [isMobileMenuOpen, setIsMobileMenuOpen] = useState(false)
const router = useRouter()
const pathname = usePathname()
const { isAdmin } = useUser()
// Optimize mobile menu closing - use useCallback to prevent unnecessary re-renders
const handleMobileMenuClose = () => {
setIsMobileMenuOpen(false)
}
// Determine if we're in admin area
const isAdminArea = pathname?.startsWith('/dashboard/admin')
// Filter sidebar config based on admin status
const getFilteredConfig = () => {
if (isAdminArea) {
return adminSidebarConfig
}
// Filter out admin section for non-admin users
return sidebarConfig.filter(section => {
if (section.title === "Administration") {
return isAdmin
}
return true
})
}
const currentConfig = getFilteredConfig()
const homeLink = isAdminArea ? '/dashboard/admin' : '/dashboard'
const icon = isAdminArea ? Shield : ShoppingCart
const handleLogout = async () => {
try {
// Show toast notification for better user experience
toast.success("Logging out...");
// Perform the logout
await logoutUser();
// The logoutUser function will handle the redirect
} catch (error) {
console.error("Error during logout:", error);
toast.error("Failed to logout. Please try again.");
}
};
return (
<>
<nav
className={`
fixed inset-y-0 left-0 z-[70] w-64 bg-background transform transition-transform duration-150 ease-out
lg:translate-x-0 lg:static lg:w-56 xl:w-64 border-r border-border
${isMobileMenuOpen ? "translate-x-0" : "-translate-x-full"}
`}
>
<div className="h-full flex flex-col">
<Link href={homeLink} className="h-16 px-6 flex items-center border-b border-border">
<div className="flex items-center gap-3">
{icon === Shield ? <Shield className="h-6 w-6 text-foreground" /> : <ShoppingCart className="h-6 w-6 text-foreground" />}
<span className="text-lg font-semibold text-foreground">Ember</span>
</div>
</Link>
<div className="flex-1 overflow-y-auto py-4 px-4 space-y-6">
{currentConfig.map((section, index) => (
<div key={index}>
<div className="px-3 mb-2 text-xs font-semibold uppercase tracking-wider text-muted-foreground">
{section.title}
</div>
<div className="space-y-1">
{section.items.map((item, idx) => (
<NavItem key={idx} href={item.href} icon={item.icon} onClick={handleMobileMenuClose}>
{item.name}
</NavItem>
))}
</div>
</div>
))}
</div>
<div className="p-4 border-t border-border">
<Button
onClick={handleLogout}
variant="ghost"
className="w-full justify-start text-red-600 dark:text-red-400 hover:text-red-800 dark:hover:text-red-500 hover:bg-background"
>
<LogOut className="h-5 w-5 mr-3 flex-shrink-0" />
Logout
</Button>
</div>
</div>
</nav>
{isMobileMenuOpen && (
<div
className="fixed inset-0 bg-black bg-opacity-50 z-[65] lg:hidden"
onClick={handleMobileMenuClose}
/>
)}
</>
)
}
export default Sidebar