225 lines
12 KiB
JavaScript
225 lines
12 KiB
JavaScript
import React, { useState, useMemo } from 'react';
|
|
import { useAutoLab } from '../hooks/useAutoLab';
|
|
// Uso de componente local para respeitar o isolamento total entre módulos
|
|
import ExcelTable from '../components/ExcelTable';
|
|
import { AutoLabDetailPanel } from '../components/AutoLabDetailPanel';
|
|
import {
|
|
Plus, Car, Users, Building2, Landmark, UserPlus, Layers,
|
|
Info, Tag, Hash, FileText, MapPin, Phone, Mail, Briefcase, Settings2
|
|
} from 'lucide-react';
|
|
import { Tabs, TabsList, TabsTrigger } from "@/components/ui/tabs";
|
|
import { Button } from "@/components/ui/button";
|
|
import { toast } from 'sonner';
|
|
|
|
export const CadastroView = () => {
|
|
const [activeTab, setActiveTab] = useState('veiculos');
|
|
const [selectedItem, setSelectedItem] = useState(null);
|
|
const [isPanelOpen, setIsPanelOpen] = useState(false);
|
|
|
|
const getFetchType = () => {
|
|
if (activeTab === 'veiculos') return 'veiculos';
|
|
if (activeTab === 'transportadoras' || activeTab === 'fornecedores') return 'companies';
|
|
if (activeTab === 'vendedores') return 'vendedores';
|
|
if (activeTab === 'setores') return 'setores';
|
|
if (activeTab === 'bancos') return 'bancos';
|
|
return 'veiculos';
|
|
};
|
|
|
|
const { data, loading } = useAutoLab(getFetchType());
|
|
|
|
const handleRowClick = (row) => {
|
|
setSelectedItem(row);
|
|
setIsPanelOpen(true);
|
|
};
|
|
|
|
const columns = useMemo(() => {
|
|
switch (activeTab) {
|
|
case 'veiculos':
|
|
return [
|
|
{ header: 'Ano/Mod Chassi', field: 'ano_modelo_chassi', width: '120px' },
|
|
{ header: 'Chassi', field: 'chassi', width: '180px', className: 'font-mono' },
|
|
{ header: 'Cor Chassi', field: 'cor_chassi', width: '120px' },
|
|
{ header: 'Descrição', field: 'descrisao', width: '300px' },
|
|
{ header: 'DI Chassi', field: 'di_chassi', width: '150px' },
|
|
{ header: 'Modelo', field: 'modelo', width: '120px' },
|
|
{ header: 'Nº Motor', field: 'n_motor', width: '150px' },
|
|
{ header: 'Placa', field: 'placa', width: '120px', className: 'font-mono font-bold text-emerald-600' },
|
|
{ header: 'Tipo Veículo', field: 'tipo_veiculo', width: '150px' },
|
|
];
|
|
case 'transportadoras':
|
|
case 'fornecedores':
|
|
return [
|
|
{ header: 'Bairro', field: 'bairro', width: '180px' },
|
|
{ header: 'Cep', field: 'cep', width: '120px' },
|
|
{ header: 'Compl.', field: 'compl', width: '180px' },
|
|
{ header: 'Inclusão', field: 'inclusao', width: '150px' },
|
|
{ header: 'Doc.', field: 'doc', width: '100px' },
|
|
{ header: 'Email', field: 'email', width: '250px' },
|
|
{ header: 'IE', field: 'ie', width: '180px' },
|
|
{ header: 'Logr.', field: 'logr', width: '250px' },
|
|
{ header: 'Município', field: 'municipio', width: '180px' },
|
|
{ header: 'Nome Fant.', field: 'nome_fant', width: '200px' },
|
|
{ header: 'Razão Social', field: 'razao_social', width: '300px', className: 'font-bold' },
|
|
{ header: 'Nome Repres.', field: 'nome_repres', width: '180px' },
|
|
{ header: 'Nº', field: 'n', width: '100px' },
|
|
];
|
|
case 'vendedores':
|
|
return [
|
|
{ header: 'Nome', field: 'nome', width: '300px', className: 'font-bold' },
|
|
{ header: 'Comissão Produto (%)', field: 'comissao_produto', width: '200px', className: 'text-center' },
|
|
{ header: 'Comissão Serviços (%)', field: 'comissao_servicos', width: '200px', className: 'text-center' },
|
|
];
|
|
case 'setores':
|
|
return [
|
|
{ header: 'Setor', field: 'setor', width: '400px', className: 'font-bold' },
|
|
];
|
|
case 'bancos':
|
|
return [
|
|
{ header: 'Banco', field: 'banco', width: '250px', className: 'font-bold' },
|
|
{ header: 'Agência', field: 'agencia', width: '120px' },
|
|
{ header: 'Conta', field: 'conta', width: '180px' },
|
|
];
|
|
default:
|
|
return [];
|
|
}
|
|
}, [activeTab]);
|
|
|
|
return (
|
|
<div className="flex flex-col h-full bg-white dark:bg-[#1b1b1b]">
|
|
<div className="p-4 border-b dark:border-zinc-800 bg-slate-50/50 dark:bg-zinc-900/20 flex flex-wrap items-center justify-between gap-4">
|
|
<div className="flex items-center gap-4 flex-1 overflow-hidden">
|
|
<Tabs value={activeTab} onValueChange={setActiveTab} className="bg-white dark:bg-zinc-900 p-1 rounded-xl border dark:border-zinc-800 shadow-sm w-full overflow-x-auto no-scrollbar">
|
|
<TabsList className="bg-transparent border-none gap-1 h-8">
|
|
<TabsTrigger value="veiculos" className="data-[state=active]:bg-[#1b4332] data-[state=active]:text-white rounded-lg px-4 transition-all uppercase text-[10px] font-bold shrink-0">
|
|
<Car size={16} className="mr-2" /> Veículos
|
|
</TabsTrigger>
|
|
<TabsTrigger value="transportadoras" className="data-[state=active]:bg-[#1b4332] data-[state=active]:text-white rounded-lg px-4 transition-all uppercase text-[10px] font-bold shrink-0">
|
|
<Building2 size={16} className="mr-2" /> Transportadoras
|
|
</TabsTrigger>
|
|
<TabsTrigger value="fornecedores" className="data-[state=active]:bg-[#1b4332] data-[state=active]:text-white rounded-lg px-4 transition-all uppercase text-[10px] font-bold shrink-0">
|
|
<Users size={16} className="mr-2" /> Fornecedores
|
|
</TabsTrigger>
|
|
<TabsTrigger value="bancos" className="data-[state=active]:bg-[#1b4332] data-[state=active]:text-white rounded-lg px-4 transition-all uppercase text-[10px] font-bold shrink-0">
|
|
<Landmark size={16} className="mr-2" /> Bancos
|
|
</TabsTrigger>
|
|
<TabsTrigger value="vendedores" className="data-[state=active]:bg-[#1b4332] data-[state=active]:text-white rounded-lg px-4 transition-all uppercase text-[10px] font-bold shrink-0">
|
|
<UserPlus size={16} className="mr-2" /> Vendedores
|
|
</TabsTrigger>
|
|
<TabsTrigger value="setores" className="data-[state=active]:bg-[#1b4332] data-[state=active]:text-white rounded-lg px-4 transition-all uppercase text-[10px] font-bold shrink-0">
|
|
<Briefcase size={16} className="mr-2" /> Setores
|
|
</TabsTrigger>
|
|
</TabsList>
|
|
</Tabs>
|
|
</div>
|
|
|
|
<div className="flex items-center gap-3">
|
|
<Button className="bg-[#1b4332] hover:bg-[#2d6a4f] text-white rounded-xl px-4 py-2 font-bold shadow-lg shadow-emerald-900/10 flex items-center gap-2 uppercase text-[10px]">
|
|
<Plus size={18} /> Novo Registro
|
|
</Button>
|
|
</div>
|
|
</div>
|
|
|
|
<div className="flex-1 overflow-hidden">
|
|
<ExcelTable
|
|
data={data}
|
|
loading={loading}
|
|
columns={columns}
|
|
onRowClick={handleRowClick}
|
|
rowKey="id"
|
|
/>
|
|
</div>
|
|
|
|
<AutoLabDetailPanel
|
|
isOpen={isPanelOpen}
|
|
onClose={() => setIsPanelOpen(false)}
|
|
title={selectedItem?.placa || selectedItem?.razao_social || selectedItem?.nome || selectedItem?.setor || selectedItem?.banco || 'Detalhes'}
|
|
subtitle={activeTab.toUpperCase()}
|
|
status="ATIVO"
|
|
statusColor="bg-emerald-500/10 text-emerald-600"
|
|
actions={[
|
|
{ label: 'Editar', onClick: () => toast.info('Modo edição ativado'), variant: 'default', className: 'bg-[#1b4332] text-white' },
|
|
{ label: 'Excluir', isDestructive: true, onClick: () => toast.error('Exclusão solicitada') }
|
|
]}
|
|
tabs={[
|
|
{
|
|
id: 'info',
|
|
label: 'Informações Detalhadas',
|
|
content: (
|
|
<div className="space-y-6">
|
|
{activeTab === 'veiculos' && (
|
|
<div className="grid grid-cols-2 gap-6">
|
|
<DetailItem icon={<Tag size={16} />} label="Tipo Veículo" value={selectedItem?.tipo_veiculo} />
|
|
<DetailItem icon={<Layers size={16} />} label="Modelo" value={selectedItem?.modelo} />
|
|
<DetailItem icon={<Hash size={16} />} label="Chassi" value={selectedItem?.chassi} />
|
|
<DetailItem icon={<Hash size={16} />} label="Nº Motor" value={selectedItem?.n_motor} />
|
|
<div className="col-span-2">
|
|
<DetailItem icon={<FileText size={16} />} label="Descrição" value={selectedItem?.descrisao} />
|
|
</div>
|
|
</div>
|
|
)}
|
|
|
|
{(activeTab === 'transportadoras' || activeTab === 'fornecedores') && (
|
|
<div className="grid grid-cols-2 gap-6">
|
|
<DetailItem icon={<Tag size={16} />} label="Razão Social" value={selectedItem?.razao_social} />
|
|
<DetailItem icon={<Briefcase size={16} />} label="Nome Fantasia" value={selectedItem?.nome_fant} />
|
|
<DetailItem icon={<Hash size={16} />} label="Doc. / Nº" value={`${selectedItem?.doc || ''} ${selectedItem?.n_doc || ''}`} />
|
|
<DetailItem icon={<Landmark size={16} />} label="IE / RG" value={selectedItem?.ie} />
|
|
<DetailItem icon={<Mail size={16} />} label="Email" value={selectedItem?.email} />
|
|
<DetailItem icon={<Phone size={16} />} label="Telefone" value={selectedItem?.tel} />
|
|
|
|
<Separator className="col-span-2" />
|
|
|
|
<div className="col-span-2">
|
|
<DetailItem icon={<MapPin size={16} />} label="Endereço Completo" value={`${selectedItem?.logr || ''}, ${selectedItem?.n || ''} - ${selectedItem?.compl || ''} - ${selectedItem?.bairro || ''}, ${selectedItem?.municipio || ''} - ${selectedItem?.uf || ''}`} />
|
|
</div>
|
|
</div>
|
|
)}
|
|
|
|
{activeTab === 'vendedores' && (
|
|
<div className="grid grid-cols-1 gap-6">
|
|
<DetailItem icon={<Users size={16} />} label="Nome do Vendedor" value={selectedItem?.nome} />
|
|
<div className="grid grid-cols-2 gap-4 p-4 bg-emerald-500/5 rounded-xl border border-emerald-500/10">
|
|
<DetailItem icon={<Tag size={16} />} label="Comissão Produto" value={`${selectedItem?.comissao_produto}%`} />
|
|
<DetailItem icon={<Settings2 size={16} />} label="Comissão Serviços" value={`${selectedItem?.comissao_servicos}%`} />
|
|
</div>
|
|
</div>
|
|
)}
|
|
|
|
{activeTab === 'setores' && (
|
|
<div className="grid grid-cols-1 gap-6">
|
|
<DetailItem icon={<Briefcase size={16} />} label="Setor" value={selectedItem?.setor} />
|
|
</div>
|
|
)}
|
|
|
|
{activeTab === 'bancos' && (
|
|
<div className="grid grid-cols-1 gap-6">
|
|
<DetailItem icon={<Landmark size={16} />} label="Banco" value={selectedItem?.banco} />
|
|
<div className="grid grid-cols-2 gap-4">
|
|
<DetailItem icon={<Hash size={16} />} label="Agência" value={selectedItem?.agencia} />
|
|
<DetailItem icon={<Hash size={16} />} label="Conta" value={selectedItem?.conta} />
|
|
</div>
|
|
</div>
|
|
)}
|
|
</div>
|
|
)
|
|
}
|
|
]}
|
|
/>
|
|
</div>
|
|
);
|
|
};
|
|
|
|
const DetailItem = ({ icon, label, value }) => (
|
|
<div className="flex flex-col gap-1.5">
|
|
<div className="flex items-center gap-2 text-slate-400">
|
|
<div className="p-1 bg-slate-100 dark:bg-zinc-800 rounded">
|
|
{icon}
|
|
</div>
|
|
<span className="text-[10px] font-bold uppercase tracking-widest leading-none">{label}</span>
|
|
</div>
|
|
<span className="text-sm font-bold text-slate-800 dark:text-slate-100 ml-7">{value || '---'}</span>
|
|
</div>
|
|
);
|
|
|
|
const Separator = ({ className }) => <div className={`h-px w-full bg-slate-100 dark:bg-zinc-800 ${className}`} />;
|