saveinmed/saveinmed-frontend/src/components/LojaVirtualMenu.tsx
Tiago Yamamoto b39caf0fd0 first commit
2025-12-17 13:58:26 -03:00

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