833 lines
36 KiB
TypeScript
833 lines
36 KiB
TypeScript
"use client";
|
||
|
||
import { useAuth } from "@/contexts/AuthContext";
|
||
import { useRouter } from "next/navigation";
|
||
import { useState, useEffect } from "react";
|
||
import { UserRole } from "@/types/auth";
|
||
import { UserRoundCog, Rocket, Crown } from "lucide-react";
|
||
import Header from "@/components/Header";
|
||
import { useDashboardData } from "@/hooks/useDashboardData";
|
||
import { CadastroSuperadminModal } from "./components";
|
||
|
||
const Dashboard = () => {
|
||
const { user: authUser, userRole, isAuthenticated } = useAuth();
|
||
const router = useRouter();
|
||
const [loading, setLoading] = useState(true);
|
||
const [showCadastroSuperadminModal, setShowCadastroSuperadminModal] = useState(false);
|
||
|
||
// Estado para controlar exibição rápida das ações
|
||
const [showQuickActions, setShowQuickActions] = useState(false);
|
||
|
||
// Estados para controle do registro completo
|
||
const [registroIncompleto, setRegistroIncompleto] = useState(false);
|
||
const [userData, setUserData] = useState<any>(null);
|
||
|
||
// Obter ID da empresa do usuário (se não for superadmin)
|
||
const empresaId = (authUser as any)?.empresas?.[0] || null;
|
||
|
||
// Hook para buscar dados reais do dashboard
|
||
const {
|
||
stats,
|
||
atividades,
|
||
pedidosPendentes,
|
||
loading: dashboardLoading,
|
||
error: dashboardError,
|
||
} = useDashboardData({
|
||
userRole: userRole || "",
|
||
empresaId: empresaId || undefined,
|
||
});
|
||
|
||
// Verificar autenticação simples
|
||
useEffect(() => {
|
||
const checkAuth = async () => {
|
||
try {
|
||
// Verificar se há token armazenado
|
||
const storedToken = localStorage.getItem('access_token');
|
||
|
||
if (!storedToken) {
|
||
router.push("/login");
|
||
return;
|
||
}
|
||
|
||
|
||
// Buscar dados do usuário da API
|
||
const response = await fetch(`${process.env.NEXT_PUBLIC_BFF_API_URL}/auth/me`, {
|
||
method: "GET",
|
||
headers: {
|
||
"accept": "application/json",
|
||
"Authorization": `Bearer ${storedToken}`,
|
||
},
|
||
});
|
||
|
||
if (response.ok) {
|
||
const userData = await response.json();
|
||
setUserData(userData);
|
||
|
||
// Verificar se registro-completo é false
|
||
if (userData["registro-completo"] === false) {
|
||
setRegistroIncompleto(true);
|
||
}
|
||
} else {
|
||
localStorage.removeItem('access_token');
|
||
router.push("/login");
|
||
return;
|
||
}
|
||
|
||
setShowQuickActions(true);
|
||
} catch (error) {
|
||
console.error("Erro ao verificar autenticação:", error);
|
||
router.push("/login");
|
||
} finally {
|
||
setLoading(false);
|
||
}
|
||
};
|
||
checkAuth();
|
||
}, [router]);
|
||
|
||
// Funções para lidar com o banner de registro completo
|
||
const handleCompletarCadastro = () => {
|
||
setRegistroIncompleto(false);
|
||
router.push("/completar-registro");
|
||
};
|
||
|
||
const handleFecharBanner = () => {
|
||
setRegistroIncompleto(false);
|
||
};
|
||
|
||
// Se ainda está carregando, mostrar loading
|
||
if (loading) {
|
||
return (
|
||
<div className="min-h-screen bg-gray-50 flex items-center justify-center">
|
||
<div className="text-center">
|
||
<div className="w-16 h-16 border-4 border-gray-900 border-t-transparent rounded-full animate-spin mx-auto mb-4"></div>
|
||
<p className="text-gray-600">Carregando...</p>
|
||
</div>
|
||
</div>
|
||
);
|
||
}
|
||
|
||
return (
|
||
<div className="min-h-screen bg-gray-50">
|
||
{/* Header unificado */}
|
||
<Header user={userData} />
|
||
|
||
{/* Conteúdo principal com espaçamento adequado */}
|
||
<main className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-8">
|
||
{/* Seção de boas-vindas */}
|
||
<div className="mb-8">
|
||
<h2 className="text-3xl font-bold text-gray-900 mb-2">
|
||
Bem-vindo,{" "}
|
||
{userData?.nome ||
|
||
userData?.["nome-civil"] ||
|
||
userData?.["nome-social"] ||
|
||
authUser?.["nome-civil"] ||
|
||
authUser?.["nome-social"] ||
|
||
"Usuário"}
|
||
{userRole === UserRole.SUPERADMIN && " (Super Admin)"}
|
||
{userRole === UserRole.ADMIN && " (Admin)"}
|
||
{userRole === UserRole.COLABORADOR && " (Colaborador)"}
|
||
</h2>
|
||
<p className="text-gray-600">
|
||
Gerencie seus medicamentos próximos ao vencimento e conecte-se com
|
||
outras farmácias.
|
||
{userRole === UserRole.COLABORADOR &&
|
||
" Acesse suas entregas através do menu."}
|
||
</p>
|
||
|
||
|
||
</div>
|
||
|
||
{/* Banner de Registro Incompleto */}
|
||
{registroIncompleto && (
|
||
<div className="mb-8 bg-gradient-to-r from-yellow-50 to-orange-50 border border-yellow-200 rounded-xl p-6 shadow-sm">
|
||
<div className="flex items-start space-x-4">
|
||
<div className="flex-shrink-0">
|
||
<div className="w-10 h-10 bg-yellow-100 rounded-full flex items-center justify-center">
|
||
<svg
|
||
className="w-5 h-5 text-yellow-600"
|
||
fill="none"
|
||
stroke="currentColor"
|
||
viewBox="0 0 24 24"
|
||
>
|
||
<path
|
||
strokeLinecap="round"
|
||
strokeLinejoin="round"
|
||
strokeWidth={2}
|
||
d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-2.5L13.732 4c-.77-.833-1.964-.833-2.732 0L4.082 16.5c-.77.833.192 2.5 1.732 2.5z"
|
||
/>
|
||
</svg>
|
||
</div>
|
||
</div>
|
||
<div className="flex-1">
|
||
<h3 className="text-lg font-semibold text-gray-900 mb-2">
|
||
🚀 Complete seu cadastro
|
||
</h3>
|
||
<p className="text-gray-700 mb-4">
|
||
Seu cadastro ainda não está completo. Para ter acesso a todas as funcionalidades da plataforma SaveInMed, você precisa finalizar seu registro com algumas informações adicionais.
|
||
</p>
|
||
<div className="flex flex-col sm:flex-row gap-3">
|
||
<button
|
||
onClick={handleCompletarCadastro}
|
||
className="inline-flex items-center px-4 py-2 bg-blue-600 hover:bg-blue-700 text-white font-medium rounded-lg transition-colors duration-200"
|
||
>
|
||
<svg
|
||
className="w-4 h-4 mr-2"
|
||
fill="none"
|
||
stroke="currentColor"
|
||
viewBox="0 0 24 24"
|
||
>
|
||
<path
|
||
strokeLinecap="round"
|
||
strokeLinejoin="round"
|
||
strokeWidth={2}
|
||
d="M13 7l5 5m0 0l-5 5m5-5H6"
|
||
/>
|
||
</svg>
|
||
Completar cadastro agora
|
||
</button>
|
||
<button
|
||
onClick={handleFecharBanner}
|
||
className="inline-flex items-center px-4 py-2 bg-gray-100 hover:bg-gray-200 text-gray-700 font-medium rounded-lg transition-colors duration-200"
|
||
>
|
||
Lembrar depois
|
||
</button>
|
||
</div>
|
||
</div>
|
||
<button
|
||
onClick={handleFecharBanner}
|
||
className="flex-shrink-0 text-gray-400 hover:text-gray-600 transition-colors"
|
||
>
|
||
<svg
|
||
className="w-5 h-5"
|
||
fill="none"
|
||
stroke="currentColor"
|
||
viewBox="0 0 24 24"
|
||
>
|
||
<path
|
||
strokeLinecap="round"
|
||
strokeLinejoin="round"
|
||
strokeWidth={2}
|
||
d="M6 18L18 6M6 6l12 12"
|
||
/>
|
||
</svg>
|
||
</button>
|
||
</div>
|
||
</div>
|
||
)}
|
||
{/* Cards de estatísticas B2B - Ocultos para usuários ADMIN */}
|
||
{(userRole === UserRole.SUPERADMIN ||
|
||
userRole === UserRole.COLABORADOR) &&
|
||
stats && (
|
||
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-6 mb-8">
|
||
{/* Medicamentos Disponíveis */}
|
||
<div className="bg-white rounded-xl shadow-sm p-6 border border-gray-100">
|
||
<div className="flex items-center justify-between">
|
||
<div>
|
||
<p className="text-sm font-medium text-gray-600">
|
||
Medicamentos Disponíveis
|
||
</p>
|
||
<p className="text-3xl font-bold text-gray-900">
|
||
{stats.medicamentosDisponiveis}
|
||
</p>
|
||
<p className="text-xs text-gray-600 mt-1">
|
||
<span className="font-medium">
|
||
{stats.medicamentosVencimento}
|
||
</span>{" "}
|
||
próximos ao vencimento
|
||
</p>
|
||
</div>
|
||
<div className="w-12 h-12 bg-blue-100 rounded-lg flex items-center justify-center">
|
||
<svg
|
||
className="w-6 h-6 text-blue-600"
|
||
fill="none"
|
||
stroke="currentColor"
|
||
viewBox="0 0 24 24"
|
||
>
|
||
<path
|
||
strokeLinecap="round"
|
||
strokeLinejoin="round"
|
||
strokeWidth={2}
|
||
d="M19 11H5m14 0a2 2 0 012 2v6a2 2 0 01-2 2H5a2 2 0 01-2-2v-6a2 2 0 012-2m14 0V9a2 2 0 00-2-2M5 11V9a2 2 0 012-2m0 0V5a2 2 0 012-2h6a2 2 0 012 2v2M7 7h10"
|
||
/>
|
||
</svg>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
{/* Pedidos Recebidos - Apenas para SUPERADMIN */}
|
||
{userRole === UserRole.SUPERADMIN && (
|
||
<div className="bg-white rounded-xl shadow-sm p-6 border border-gray-100">
|
||
<div className="flex items-center justify-between">
|
||
<div>
|
||
<p className="text-sm font-medium text-gray-600">
|
||
Pedidos Recebidos
|
||
</p>
|
||
<p className="text-3xl font-bold text-gray-900">
|
||
{stats.pedidosRecebidos}
|
||
</p>
|
||
<p className="text-xs text-gray-600 mt-1">
|
||
<span className="font-medium">
|
||
{stats.pedidosPendentes}
|
||
</span>{" "}
|
||
pendentes
|
||
</p>
|
||
</div>
|
||
<div className="w-12 h-12 bg-green-100 rounded-lg flex items-center justify-center">
|
||
<svg
|
||
className="w-6 h-6 text-green-600"
|
||
fill="none"
|
||
stroke="currentColor"
|
||
viewBox="0 0 24 24"
|
||
>
|
||
<path
|
||
strokeLinecap="round"
|
||
strokeLinejoin="round"
|
||
strokeWidth={2}
|
||
d="M16 11V7a4 4 0 00-8 0v4M5 9h14l1 12H4L5 9z"
|
||
/>
|
||
</svg>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
)}
|
||
|
||
{/* Vendas do Mês - Apenas para SUPERADMIN */}
|
||
{userRole === UserRole.SUPERADMIN && (
|
||
<div className="bg-white rounded-xl shadow-sm p-6 border border-gray-100">
|
||
<div className="flex items-center justify-between">
|
||
<div>
|
||
<p className="text-sm font-medium text-gray-600">
|
||
Vendas do Mês
|
||
</p>
|
||
<p className="text-3xl font-bold text-gray-900">
|
||
{stats.vendasMes}
|
||
</p>
|
||
<p className="text-xs text-gray-600 mt-1">
|
||
<span className="font-medium">
|
||
+{stats.crescimentoVendas}%
|
||
</span>{" "}
|
||
vs mês anterior
|
||
</p>
|
||
</div>
|
||
<div className="w-12 h-12 bg-orange-100 rounded-lg flex items-center justify-center">
|
||
<svg
|
||
className="w-6 h-6 text-orange-600"
|
||
fill="none"
|
||
stroke="currentColor"
|
||
viewBox="0 0 24 24"
|
||
>
|
||
<path
|
||
strokeLinecap="round"
|
||
strokeLinejoin="round"
|
||
strokeWidth={2}
|
||
d="M13 7h8m0 0v8m0-8l-8 8-4-4-6 6"
|
||
/>
|
||
</svg>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
)}
|
||
|
||
{/* Economia Gerada - Apenas para SUPERADMIN */}
|
||
{userRole === UserRole.SUPERADMIN && (
|
||
<div className="bg-white rounded-xl shadow-sm p-6 border border-gray-100">
|
||
<div className="flex items-center justify-between">
|
||
<div>
|
||
<p className="text-sm font-medium text-gray-600">
|
||
Economia Gerada
|
||
</p>
|
||
<p className="text-3xl font-bold text-gray-900">
|
||
R$ {stats.economiaGerada.toLocaleString()}
|
||
</p>
|
||
<p className="text-xs text-gray-600 mt-1">
|
||
Recuperação de investimento
|
||
</p>
|
||
</div>
|
||
<div className="w-12 h-12 bg-gray-100 rounded-lg flex items-center justify-center">
|
||
<svg
|
||
className="w-6 h-6 text-gray-600"
|
||
fill="none"
|
||
stroke="currentColor"
|
||
viewBox="0 0 24 24"
|
||
>
|
||
<path
|
||
strokeLinecap="round"
|
||
strokeLinejoin="round"
|
||
strokeWidth={2}
|
||
d="M12 8c-1.657 0-3 .895-3 2s1.343 2 3 2 3 .895 3 2-1.343 2-3 2m0-8c1.11 0 2.08.402 2.599 1M12 8V7m0 1v8m0 0v1m0-1c-1.11 0-2.08-.402-2.599-1"
|
||
/>
|
||
</svg>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
)}
|
||
</div>
|
||
)}{" "}
|
||
{/* Seções do Dashboard - Layout Responsivo */}
|
||
{(userRole === UserRole.SUPERADMIN || userRole === UserRole.ADMIN) && (
|
||
<div className="grid grid-cols-1 lg:grid-cols-2 gap-6 mb-8">
|
||
{/* Atividade Recente */}
|
||
<div className="bg-white rounded-xl shadow-sm p-6 border border-gray-100">
|
||
<h3 className="text-lg font-semibold text-gray-900 mb-4">
|
||
Atividade Recente{" "}
|
||
{userRole === UserRole.SUPERADMIN ? "Global" : "da Empresa"}
|
||
</h3>
|
||
{dashboardLoading ? (
|
||
<div className="space-y-3">
|
||
<div className="animate-pulse bg-gray-200 h-16 rounded-md"></div>
|
||
<div className="animate-pulse bg-gray-200 h-16 rounded-md"></div>
|
||
</div>
|
||
) : atividades.length > 0 ? (
|
||
<div className="space-y-3">
|
||
{atividades.map((atividade) => (
|
||
<div
|
||
key={atividade.id}
|
||
className="flex items-center justify-between p-3 bg-gray-50 rounded-md"
|
||
>
|
||
<div className="flex-1 min-w-0">
|
||
<p className="text-sm font-medium text-gray-900 truncate">
|
||
{atividade.titulo}
|
||
</p>
|
||
<p className="text-xs text-gray-500">
|
||
{new Date(atividade.data).toLocaleDateString("pt-BR")}{" "}
|
||
- {atividade.descricao}
|
||
</p>
|
||
</div>
|
||
<span
|
||
className={`inline-flex items-center px-2 py-1 rounded-full text-xs font-medium flex-shrink-0 ${atividade.status === "novo"
|
||
? "bg-green-100 text-green-800"
|
||
: atividade.status === "atualizado"
|
||
? "bg-blue-100 text-blue-800"
|
||
: "bg-gray-100 text-gray-800"
|
||
}`}
|
||
>
|
||
{atividade.status === "novo"
|
||
? "Novo"
|
||
: atividade.status === "atualizado"
|
||
? "Atualizado"
|
||
: atividade.status}
|
||
</span>
|
||
</div>
|
||
))}
|
||
</div>
|
||
) : (
|
||
<div className="text-center py-4">
|
||
<p className="text-gray-500">
|
||
Nenhuma atividade recente encontrada
|
||
</p>
|
||
</div>
|
||
)}
|
||
</div>
|
||
|
||
{/* Pedidos Pendentes */}
|
||
<div className="bg-white rounded-xl shadow-sm p-6 border border-gray-100">
|
||
<h3 className="text-lg font-semibold text-gray-900 mb-4">
|
||
Pedidos Pendentes
|
||
</h3>
|
||
{dashboardLoading ? (
|
||
<div className="space-y-3">
|
||
<div className="animate-pulse bg-gray-200 h-16 rounded-md"></div>
|
||
</div>
|
||
) : pedidosPendentes.length > 0 ? (
|
||
<div className="space-y-3">
|
||
{pedidosPendentes.map((pedido) => (
|
||
<div
|
||
key={pedido.id}
|
||
className="flex items-center justify-between p-3 bg-yellow-50 rounded-md"
|
||
>
|
||
<div className="flex-1 min-w-0">
|
||
<p className="text-sm font-medium text-gray-900 truncate">
|
||
{pedido.numero}
|
||
</p>
|
||
<p className="text-xs text-gray-500">
|
||
R${" "}
|
||
{Number.isFinite(pedido.valor)
|
||
? pedido.valor.toFixed(2)
|
||
: "0.00"}{" "}
|
||
- {pedido.comprador}
|
||
</p>
|
||
</div>
|
||
<span className="inline-flex items-center px-2 py-1 rounded-full text-xs font-medium bg-yellow-100 text-yellow-800 flex-shrink-0">
|
||
{pedido.status}
|
||
</span>
|
||
</div>
|
||
))}
|
||
</div>
|
||
) : (
|
||
<div className="text-center py-4">
|
||
<p className="text-gray-500">
|
||
Nenhum pedido pendente encontrado
|
||
</p>
|
||
</div>
|
||
)}
|
||
</div>
|
||
</div>
|
||
)}
|
||
{/* Indicador de erro se houver */}
|
||
{dashboardError && (
|
||
<div className="mb-6 p-4 bg-red-50 border border-red-200 rounded-lg">
|
||
<p className="text-red-800 text-sm">
|
||
⚠️ Erro ao carregar dados do dashboard: {dashboardError}
|
||
</p>
|
||
</div>
|
||
)}
|
||
|
||
|
||
{/* 🚀 Seção de Ações Rápidas - Carregamento rápido para melhor UX */}
|
||
{showQuickActions && (
|
||
<div className="bg-white rounded-lg shadow-sm border py-4 px-5 animate-in slide-in-from-bottom-4 duration-300">
|
||
<div className="flex items-center gap-3 py-4 px-5 min-h-[48px]">
|
||
<div className="w-6 h-6 flex items-center justify-center">
|
||
<Rocket className="w-6 h-6 text-blue-600" />
|
||
</div>
|
||
<h2 className="text-xl font-semibold text-gray-900">
|
||
Ações Rápidas
|
||
</h2>
|
||
</div>
|
||
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6 px-5 pb-4">
|
||
{/* Gestão de Produtos Venda - Oculto para colaborador */}
|
||
<button
|
||
onClick={() => router.push("/gestao-produtos-venda")}
|
||
className="bg-white hover:bg-gray-50 border border-gray-200 rounded-xl p-6 text-center transition-colors duration-200 cursor-pointer group min-h-[48px]"
|
||
>
|
||
<div className="w-12 h-12 bg-orange-100 rounded-lg mx-auto mb-4 flex items-center justify-center group-hover:bg-orange-200 transition-colors">
|
||
<svg
|
||
className="w-6 h-6 text-orange-600"
|
||
fill="none"
|
||
stroke="currentColor"
|
||
viewBox="0 0 24 24"
|
||
>
|
||
<path
|
||
strokeLinecap="round"
|
||
strokeLinejoin="round"
|
||
strokeWidth={2}
|
||
d="M9 7h6m0 10v-3m-3 3h.01M9 17h.01M9 14h.01M12 14h.01M15 11h.01M12 11h.01M9 11h.01M7 21h10a2 2 0 002-2V5a2 2 0 00-2-2H7a2 2 0 00-2 2v14a2 2 0 002 2z"
|
||
/>
|
||
</svg>
|
||
</div>
|
||
<h3 className="font-medium text-gray-900 mb-2">
|
||
Meu Estoque
|
||
</h3>
|
||
<p className="text-sm text-gray-500">
|
||
Gerenciar produtos disponíveis para venda
|
||
</p>
|
||
</button>
|
||
|
||
|
||
{/* Produtos Venda */}
|
||
<button
|
||
onClick={() => router.push("/produtos")}
|
||
className="bg-white hover:bg-gray-50 border border-gray-200 rounded-xl p-6 text-center transition-colors duration-200 cursor-pointer group min-h-[48px]"
|
||
>
|
||
<div className="w-12 h-12 bg-green-100 rounded-lg mx-auto mb-4 flex items-center justify-center group-hover:bg-green-200 transition-colors">
|
||
<svg
|
||
className="w-6 h-6 text-green-600"
|
||
fill="none"
|
||
stroke="currentColor"
|
||
viewBox="0 0 24 24"
|
||
>
|
||
<path
|
||
strokeLinecap="round"
|
||
strokeLinejoin="round"
|
||
strokeWidth={2}
|
||
d="M16 11V7a4 4 0 00-8 0v4M5 9h14l1 12H4L5 9z"
|
||
/>
|
||
</svg>
|
||
</div>
|
||
<h3 className="font-medium text-gray-900 mb-2">
|
||
Comprar
|
||
</h3>
|
||
<p className="text-sm text-gray-500">
|
||
Produtos disponíveis para compra
|
||
</p>
|
||
</button>
|
||
|
||
{/* Cadastrar Medicamento */}
|
||
<button
|
||
onClick={() =>
|
||
router.push("/dashboard/cadastrar-medicamentos")
|
||
}
|
||
className="bg-white hover:bg-gray-50 border border-gray-200 rounded-xl p-6 text-center transition-colors duration-200 cursor-pointer group min-h-[48px]"
|
||
>
|
||
<div className="w-12 h-12 bg-green-100 rounded-lg mx-auto mb-4 flex items-center justify-center group-hover:bg-green-200 transition-colors">
|
||
<svg
|
||
className="w-6 h-6 text-gray-600"
|
||
fill="none"
|
||
stroke="currentColor"
|
||
viewBox="0 0 24 24"
|
||
>
|
||
<path
|
||
strokeLinecap="round"
|
||
strokeLinejoin="round"
|
||
strokeWidth={2}
|
||
d="M12 6v6m0 0v6m0-6h6m-6 0H6"
|
||
/>
|
||
</svg>
|
||
</div>
|
||
<h3 className="font-medium text-gray-900 mb-2">
|
||
Cadastrar Medicamento
|
||
</h3>
|
||
<p className="text-sm text-gray-500">
|
||
Adicionar novos medicamentos
|
||
</p>
|
||
</button>
|
||
|
||
{/* Catálogo de Produtos - Oculto para colaborador e admin (não superadmin) */}
|
||
{userData?.nivel !== "colaborador" && !(userData?.nivel === "admin" && userData?.superadmin === false) && (
|
||
<button
|
||
onClick={() => router.push("/catalogo-produtos-api")}
|
||
className="bg-white hover:bg-gray-50 border border-gray-200 rounded-xl p-6 text-center transition-colors duration-200 cursor-pointer group min-h-[48px]"
|
||
>
|
||
<div className="w-12 h-12 bg-purple-100 rounded-lg mx-auto mb-4 flex items-center justify-center group-hover:bg-purple-200 transition-colors">
|
||
<svg
|
||
className="w-6 h-6 text-purple-600"
|
||
fill="none"
|
||
stroke="currentColor"
|
||
viewBox="0 0 24 24"
|
||
>
|
||
<path
|
||
strokeLinecap="round"
|
||
strokeLinejoin="round"
|
||
strokeWidth={2}
|
||
d="M19 11H5m14 0a2 2 0 012 2v6a2 2 0 01-2 2H5a2 2 0 01-2-2v-6a2 2 0 012-2m14 0V9a2 2 0 00-2-2M5 11V9a2 2 0 012-2m0 0V5a2 2 0 012-2h6a2 2 0 012 2v2M7 7h10"
|
||
/>
|
||
</svg>
|
||
</div>
|
||
<h3 className="font-medium text-gray-900 mb-2">
|
||
Catálogo de Produtos
|
||
</h3>
|
||
<p className="text-sm text-gray-500">
|
||
Listar produtos do catálogo
|
||
</p>
|
||
</button>
|
||
)}
|
||
|
||
|
||
{/* Usuários Pendentes - Apenas para superadmins */}
|
||
{userData?.superadmin === true && (
|
||
<button
|
||
onClick={() => router.push("/usuarios-pendentes")}
|
||
className="bg-white hover:bg-gray-50 border border-gray-200 rounded-xl p-6 text-center transition-colors duration-200 cursor-pointer group min-h-[48px]"
|
||
>
|
||
<div className="w-12 h-12 bg-amber-100 rounded-lg mx-auto mb-4 flex items-center justify-center group-hover:bg-amber-200 transition-colors">
|
||
<svg
|
||
className="w-6 h-6 text-amber-600"
|
||
fill="none"
|
||
stroke="currentColor"
|
||
viewBox="0 0 24 24"
|
||
>
|
||
<path
|
||
strokeLinecap="round"
|
||
strokeLinejoin="round"
|
||
strokeWidth={2}
|
||
d="M12 8v4l3 3m6-3a9 9 0 11-18 0 9 9 0 0118 0z"
|
||
/>
|
||
</svg>
|
||
</div>
|
||
<h3 className="font-medium text-gray-900 mb-2">
|
||
Usuários Pendentes
|
||
</h3>
|
||
<p className="text-sm text-gray-500">
|
||
Validar cadastros aguardando aprovação
|
||
</p>
|
||
</button>
|
||
)}
|
||
|
||
{/* Cadastrar Superadmin - Apenas para superadmins */}
|
||
{userData?.superadmin === true && (
|
||
<button
|
||
onClick={() => setShowCadastroSuperadminModal(true)}
|
||
className="bg-white hover:bg-gray-50 border border-gray-200 rounded-xl p-6 text-center transition-colors duration-200 cursor-pointer group min-h-[48px]"
|
||
>
|
||
<div className="w-12 h-12 bg-purple-100 rounded-lg mx-auto mb-4 flex items-center justify-center group-hover:bg-purple-200 transition-colors">
|
||
<Crown className="w-6 h-6 text-purple-600" />
|
||
</div>
|
||
<h3 className="font-medium text-gray-900 mb-2">
|
||
Cadastrar Superadmin
|
||
</h3>
|
||
<p className="text-sm text-gray-500">
|
||
Criar novo usuário superadmin
|
||
</p>
|
||
</button>
|
||
)}
|
||
|
||
{/* Entregas - Visível para todos os roles */}
|
||
<button
|
||
onClick={() => router.push("/entregas")}
|
||
className="bg-white hover:bg-gray-50 border border-gray-200 rounded-xl p-6 text-center transition-colors duration-150 cursor-pointer group min-h-[48px]"
|
||
>
|
||
<div className="w-12 h-12 bg-blue-100 rounded-lg mx-auto mb-4 flex items-center justify-center group-hover:bg-blue-200 transition-colors duration-150">
|
||
<svg
|
||
className="w-6 h-6 text-blue-600"
|
||
fill="none"
|
||
stroke="currentColor"
|
||
viewBox="0 0 24 24"
|
||
>
|
||
<path
|
||
strokeLinecap="round"
|
||
strokeLinejoin="round"
|
||
strokeWidth={2}
|
||
d="M20 7l-8-4-8 4m16 0l-8 4m8-4v10l-8 4m0-10L4 7m8 4v10M4 7v10l8 4"
|
||
/>
|
||
</svg>
|
||
</div>
|
||
<h3 className="font-medium text-gray-900 mb-2">Entregas</h3>
|
||
<p className="text-sm text-gray-500">
|
||
Gerenciar entregas e logística
|
||
</p>
|
||
</button>
|
||
|
||
{/* Gestão de Pedidos - Oculto para colaborador */}
|
||
{userData?.nivel !== "colaborador" && (
|
||
<button
|
||
onClick={() => router.push("/gestao-pedidos")}
|
||
className="bg-white hover:bg-gray-50 border border-gray-200 rounded-xl p-6 text-center transition-colors duration-200 cursor-pointer group min-h-[48px]"
|
||
>
|
||
<div className="w-12 h-12 bg-gray-100 rounded-lg mx-auto mb-4 flex items-center justify-center group-hover:bg-gray-200 transition-colors">
|
||
<svg
|
||
className="w-6 h-6 text-blue-600"
|
||
fill="none"
|
||
stroke="currentColor"
|
||
viewBox="0 0 24 24"
|
||
>
|
||
<path
|
||
strokeLinecap="round"
|
||
strokeLinejoin="round"
|
||
strokeWidth={2}
|
||
d="M9 5H7a2 2 0 00-2 2v10a2 2 0 002 2h8a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"
|
||
/>
|
||
</svg>
|
||
</div>
|
||
<h3 className="font-medium text-gray-900 mb-2">
|
||
Gestão de Pedidos
|
||
</h3>
|
||
<p className="text-sm text-gray-500">
|
||
Gerenciar pedidos e vendas
|
||
</p>
|
||
</button>
|
||
)}
|
||
|
||
{/* Relatórios - Oculto para colaborador */}
|
||
{userData?.nivel !== "colaborador" && (
|
||
<button
|
||
onClick={() => router.push("/relatorios")}
|
||
className="bg-white hover:bg-gray-50 border border-gray-200 rounded-xl p-6 text-center transition-colors duration-200 cursor-pointer group min-h-[48px]"
|
||
>
|
||
<div className="w-12 h-12 bg-gray-100 rounded-lg mx-auto mb-4 flex items-center justify-center group-hover:bg-gray-200 transition-colors">
|
||
<svg
|
||
className="w-6 h-6 text-blue-600"
|
||
fill="none"
|
||
stroke="currentColor"
|
||
viewBox="0 0 24 24"
|
||
>
|
||
<path
|
||
strokeLinecap="round"
|
||
strokeLinejoin="round"
|
||
strokeWidth={2}
|
||
d="M9 17v-2m3 2v-4m3 4v-6m2 10H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z"
|
||
/>
|
||
</svg>
|
||
</div>
|
||
<h3 className="font-medium text-gray-900 mb-2">Relatórios</h3>
|
||
<p className="text-sm text-gray-500">
|
||
Visualizar relatórios e métricas
|
||
</p>
|
||
</button>
|
||
)}
|
||
|
||
{/* Gestão de Usuários - Oculto para colaborador e admin (não superadmin) */}
|
||
{userData?.nivel !== "colaborador" && !(userData?.nivel === "admin" && userData?.superadmin === false) && (
|
||
<button
|
||
onClick={() => router.push("/gestao-usuarios")}
|
||
className="bg-white hover:bg-gray-50 border border-gray-200 rounded-xl p-6 text-center transition-colors duration-200 cursor-pointer group min-h-[48px]"
|
||
>
|
||
<div className="w-12 h-12 bg-indigo-100 rounded-lg mx-auto mb-4 flex items-center justify-center group-hover:bg-indigo-200 transition-colors">
|
||
<UserRoundCog className="w-6 h-6 text-indigo-600" />
|
||
</div>
|
||
<h3 className="font-medium text-gray-900 mb-2">
|
||
Gestão de Usuários
|
||
</h3>
|
||
<p className="text-sm text-gray-500">
|
||
Gerenciar usuários do sistema
|
||
</p>
|
||
</button>
|
||
)}
|
||
|
||
|
||
{/* Gestão de Colaboradores - Oculto para colaborador */}
|
||
{userData?.nivel !== "colaborador" && (
|
||
<button
|
||
onClick={() => router.push("/gestao-colaboradores")}
|
||
className="bg-white hover:bg-gray-50 border border-gray-200 rounded-xl p-6 text-center transition-colors duration-200 cursor-pointer group min-h-[48px]"
|
||
>
|
||
<div className="w-12 h-12 bg-teal-100 rounded-lg mx-auto mb-4 flex items-center justify-center group-hover:bg-teal-200 transition-colors">
|
||
<svg
|
||
className="w-6 h-6 text-teal-600"
|
||
fill="none"
|
||
stroke="currentColor"
|
||
viewBox="0 0 24 24"
|
||
>
|
||
<path
|
||
strokeLinecap="round"
|
||
strokeLinejoin="round"
|
||
strokeWidth={2}
|
||
d="M17 20h5v-2a3 3 0 00-5.356-1.857M17 20H7m10 0v-2c0-.656-.126-1.283-.356-1.857M7 20H2v-2a3 3 0 015.356-1.857M7 20v-2c0-.656.126-1.283.356-1.857m0 0a5.002 5.002 0 019.288 0M15 7a3 3 0 11-6 0 3 3 0 016 0zm6 3a2 2 0 11-4 0 2 2 0 014 0zM7 10a2 2 0 11-4 0 2 2 0 014 0z"
|
||
/>
|
||
</svg>
|
||
</div>
|
||
<h3 className="font-medium text-gray-900 mb-2">
|
||
Gestão de Colaboradores
|
||
</h3>
|
||
<p className="text-sm text-gray-500">
|
||
Gerenciar colaboradores da empresa
|
||
</p>
|
||
</button>
|
||
)}
|
||
|
||
{/* Gestão de Laboratórios - Oculto para colaborador e admin (não superadmin) */}
|
||
{userData?.nivel !== "colaborador" && !(userData?.nivel === "admin" && userData?.superadmin === false) && (
|
||
<button
|
||
onClick={() => router.push("/laboratorios")}
|
||
className="bg-white hover:bg-gray-50 border border-gray-200 rounded-xl p-6 text-center transition-colors duration-200 cursor-pointer group min-h-[48px]"
|
||
>
|
||
<div className="w-12 h-12 bg-cyan-100 rounded-lg mx-auto mb-4 flex items-center justify-center group-hover:bg-cyan-200 transition-colors">
|
||
<svg
|
||
className="w-6 h-6 text-cyan-600"
|
||
fill="none"
|
||
stroke="currentColor"
|
||
viewBox="0 0 24 24"
|
||
>
|
||
<path
|
||
strokeLinecap="round"
|
||
strokeLinejoin="round"
|
||
strokeWidth={2}
|
||
d="M19.428 15.428a2 2 0 00-1.022-.547l-2.387-.477a6 6 0 00-3.86.517l-.318.158a6 6 0 01-3.86.517L6.05 15.21a2 2 0 00-1.806.547M8 4h8l-1 1v5.172a2 2 0 00.586 1.414l5 5c1.26 1.26.367 3.414-1.415 3.414H4.828c-1.782 0-2.674-2.154-1.414-3.414l5-5A2 2 0 009 10.172V5L8 4z"
|
||
/>
|
||
</svg>
|
||
</div>
|
||
<h3 className="font-medium text-gray-900 mb-2">
|
||
Gestão de Laboratórios
|
||
</h3>
|
||
<p className="text-sm text-gray-500">
|
||
Gerenciar laboratórios e fabricantes
|
||
</p>
|
||
</button>
|
||
)}
|
||
</div>
|
||
</div>
|
||
)}
|
||
</main>
|
||
|
||
{/* Modal de Cadastro de Superadmin */}
|
||
<CadastroSuperadminModal
|
||
isOpen={showCadastroSuperadminModal}
|
||
onClose={() => setShowCadastroSuperadminModal(false)}
|
||
onSuccess={() => {
|
||
setShowCadastroSuperadminModal(false);
|
||
}}
|
||
/>
|
||
</div>
|
||
);
|
||
};
|
||
|
||
export default Dashboard;
|