Implemented comprehensive Chromebook-specific fixes including viewport adjustments, enhanced touch and keyboard detection, improved scrolling and keyboard navigation hooks, and extensive CSS optimizations for better usability. Updated chat and dashboard interfaces for larger touch targets, better focus management, and responsive layouts. Added documentation in docs/CHROMEBOOK-FIXES.md and new hooks for Chromebook scroll and keyboard handling.
117 lines
3.8 KiB
TypeScript
117 lines
3.8 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/ui/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 "@/hooks/useUser"
|
|
|
|
const Sidebar: React.FC = () => {
|
|
const [isMobileMenuOpen, setIsMobileMenuOpen] = useState(false)
|
|
const router = useRouter()
|
|
const pathname = usePathname()
|
|
const { isAdmin } = useUser()
|
|
|
|
// 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-200 ease-in-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={() => setIsMobileMenuOpen(false)}>
|
|
{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={() => setIsMobileMenuOpen(false)}
|
|
/>
|
|
)}
|
|
</>
|
|
)
|
|
}
|
|
|
|
export default Sidebar
|
|
|