145 lines
4.3 KiB
TypeScript
145 lines
4.3 KiB
TypeScript
"use client"
|
|
|
|
import { useState, useRef, useEffect } from "react"
|
|
import Link from "next/link"
|
|
import { useAuth } from "@/hooks/useAuth"
|
|
import { UserRole } from "@/types/auth"
|
|
import { Pill, ChevronDown } from "lucide-react"
|
|
|
|
interface NavItem {
|
|
label: string
|
|
href: string
|
|
}
|
|
|
|
const LojaVirtualMenu = () => {
|
|
const [isOpen, setIsOpen] = useState(false)
|
|
const timeoutRef = useRef<NodeJS.Timeout | null>(null)
|
|
const dropdownRef = useRef<HTMLDivElement>(null)
|
|
const { user } = useAuth()
|
|
|
|
// Função para filtrar itens baseado no role do usuário
|
|
const filterItemsByRole = (items: NavItem[], userRole?: UserRole): NavItem[] => {
|
|
if (!userRole) return []
|
|
|
|
// COLABORADOR: acesso básico
|
|
if (userRole === UserRole.COLABORADOR) {
|
|
const allowedPaths = [
|
|
'/entregas',
|
|
'/produtos',
|
|
'/carrinhos',
|
|
'/pedidos'
|
|
]
|
|
return items.filter(item => allowedPaths.includes(item.href))
|
|
}
|
|
|
|
// ADMIN: acesso intermediário
|
|
if (userRole === UserRole.ADMIN) {
|
|
const restrictedPaths = [
|
|
'/usuarios', // Apenas SUPERADMIN
|
|
'/enderecos', // Apenas SUPERADMIN
|
|
'/dashboard/empresa-novo' // Apenas SUPERADMIN
|
|
]
|
|
return items.filter(item => !restrictedPaths.includes(item.href))
|
|
}
|
|
|
|
// SUPERADMIN: acesso completo a todos os itens
|
|
if (userRole === UserRole.SUPERADMIN) {
|
|
return items // Mostra todos os itens
|
|
}
|
|
|
|
return []
|
|
}
|
|
|
|
const allItems: NavItem[] = [
|
|
{ label: "Produtos", href: "/produtos" },
|
|
{ label: "Categorias", href: "/categorias" },
|
|
{ label: "Carrinhos", href: "/carrinhos" },
|
|
{ label: "Pedidos", href: "/pedidos" },
|
|
{ label: "Entregas", href: "/entregas" },
|
|
{ label: "Faturas", href: "/faturas" },
|
|
{ label: "Pagamentos", href: "/pagamentos" },
|
|
{ label: "Laboratórios", href: "/laboratorios" },
|
|
{ label: "Usuários", href: "/usuarios" },
|
|
{ label: "Endereços", href: "/enderecos" },
|
|
{ label: "Empresas", href: "/dashboard/empresa-novo" },
|
|
]
|
|
|
|
// Filtrar itens baseado no role do usuário
|
|
const items = filterItemsByRole(allItems, user?.nivel as UserRole)
|
|
|
|
const handleMouseEnter = () => {
|
|
if (timeoutRef.current) {
|
|
clearTimeout(timeoutRef.current)
|
|
}
|
|
setIsOpen(true)
|
|
}
|
|
|
|
const handleMouseLeave = () => {
|
|
timeoutRef.current = setTimeout(() => {
|
|
setIsOpen(false)
|
|
}, 150) // 150ms delay antes de fechar
|
|
}
|
|
|
|
useEffect(() => {
|
|
const handleClickOutside = (event: MouseEvent) => {
|
|
if (dropdownRef.current && !dropdownRef.current.contains(event.target as Node)) {
|
|
setIsOpen(false)
|
|
}
|
|
};
|
|
document.addEventListener('mousedown', handleClickOutside);
|
|
return () => {
|
|
document.removeEventListener('mousedown', handleClickOutside);
|
|
if (timeoutRef.current) {
|
|
clearTimeout(timeoutRef.current)
|
|
}
|
|
}
|
|
}, [])
|
|
|
|
// Se não há itens visíveis para o usuário, não renderiza o menu
|
|
if (items.length === 0) return null
|
|
|
|
return (
|
|
<div
|
|
className="relative hidden lg:block"
|
|
onMouseEnter={handleMouseEnter}
|
|
onMouseLeave={handleMouseLeave}
|
|
ref={dropdownRef}
|
|
>
|
|
<button
|
|
onClick={() => setIsOpen(!isOpen)}
|
|
className="flex items-center space-x-2 text-gray-700 hover:text-blue-600 px-3 py-2 rounded-md text-sm font-medium transition-colors cursor-pointer"
|
|
role="button"
|
|
aria-haspopup="true"
|
|
aria-expanded={isOpen}
|
|
>
|
|
<Pill className="w-4 h-4" />
|
|
<span className="hidden lg:block">Loja Virtual</span>
|
|
<ChevronDown className="w-4 h-4" />
|
|
</button>
|
|
|
|
{/* Dropdown Menu */}
|
|
{isOpen && (
|
|
<div
|
|
className="absolute top-full right-0 mt-1 w-56 bg-white rounded-md shadow-lg border border-gray-200 z-50"
|
|
onMouseEnter={handleMouseEnter}
|
|
onMouseLeave={handleMouseLeave}
|
|
>
|
|
<div className="py-1">
|
|
{items.map((item) => (
|
|
<Link
|
|
key={item.href}
|
|
href={item.href}
|
|
className="block px-4 py-2 text-sm text-gray-700 hover:bg-gray-50 hover:text-blue-600 transition-colors cursor-pointer"
|
|
onClick={() => setIsOpen(false)}
|
|
>
|
|
{item.label}
|
|
</Link>
|
|
))}
|
|
</div>
|
|
</div>
|
|
)}
|
|
</div>
|
|
)
|
|
}
|
|
|
|
export default LojaVirtualMenu
|