import React, { useEffect, useState, useMemo } from 'react'; import { useVehicles } from '../hooks/useVehicles'; import { useDrivers } from '../hooks/useDrivers'; import { useFleetLists } from '../hooks/useFleetLists'; import AutocompleteInput from '../components/AutocompleteInput'; import ExcelTable from '../components/ExcelTable'; import { Plus, Filter, Search, Edit2, Trash2, MapPin, Truck, Calendar, DollarSign, Wrench, CheckCircle } from 'lucide-react'; import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogFooter, DialogDescription } from "@/components/ui/dialog"; import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs"; import { toast } from 'sonner'; import { useFeedback } from '../components/FeedbackNotification'; // --- Components Styled for Dark Theme --- const DarkInput = ({ label, ...props }) => (
{label && }
); const DarkSelect = ({ label, options, value, onChange }) => (
{label && }
); const DarkButton = ({ children, variant = 'primary', className = '', ...props }) => { const baseClass = "px-4 py-2 rounded-xl font-bold text-sm transition-all shadow-lg active:scale-95 flex items-center justify-center gap-2"; const variants = { primary: "bg-orange-600 hover:bg-orange-500 text-white shadow-orange-500/10", secondary: "bg-slate-100 dark:bg-[#2a2a2a] hover:bg-slate-200 dark:hover:bg-[#333] text-slate-700 dark:text-slate-200 border border-slate-200 dark:border-[#333]", ghost: "bg-transparent hover:bg-slate-100 dark:hover:bg-[#2a2a2a] text-slate-500 dark:text-slate-400 hover:text-slate-700 dark:hover:text-white" }; return ( ); }; // --- Inline Status Editor --- const StatusCell = ({ currentStatus, idVehicle, options, onUpdate }) => { const [isEditing, setIsEditing] = useState(false); const [tempValue, setTempValue] = useState(currentStatus); useEffect(() => { setTempValue(currentStatus); }, [currentStatus]); const handleBlur = () => { setIsEditing(false); if (tempValue !== currentStatus) { onUpdate(idVehicle, tempValue); } }; const handleChange = (e) => { setTempValue(e.target.value); // Optional: Auto-save immediately on change instead of blur? // User asked: "Clicar fora e enviaria", so blur is better. }; if (isEditing) { return ( ); } return (
{ e.stopPropagation(); setIsEditing(true); }} className={`inline-flex items-center px-2 py-0.5 rounded-full text-[9px] font-bold uppercase tracking-wider border cursor-pointer hover:opacity-80 transition-opacity ${ currentStatus === 'ATIVO' ? 'bg-orange-500/10 text-orange-500 border-orange-500/20' : 'bg-slate-500/10 text-slate-500 border-slate-500/20' }`} > {currentStatus || 'N/A'}
); }; import { prafrotStatisticsService } from '../services/prafrotStatisticsService'; export default function VehiclesView() { const { vehicles, loading, fetchVehicles, createVehicle, updateVehicle, updateVehicleStatus, deleteVehicle } = useVehicles(); const { fetchListsConfig, statusFrotaOptions } = useFleetLists(); const [searchTerm, setSearchTerm] = useState(''); const [isModalOpen, setIsModalOpen] = useState(false); const [editingVehicle, setEditingVehicle] = useState(null); const [statusStats, setStatusStats] = useState([]); const [selectedStatusRecords, setSelectedStatusRecords] = useState(null); const [isRecordsModalOpen, setIsRecordsModalOpen] = useState(false); // Initial Form State const initialFormState = { ano_fabricacao: '', ano_modelo: '', atuacao: '', base: '', categoria: 'Passeio', chassi: '', cnpj: '', combustivel: 'Gasolina', contrato: '', coordenador: '', cor: '', data_limite: '', dispatcher: '', fabricante: '', fiscal_operacao: '', geotab: 'NÃO', gestor: '', golfleet: 'NÃO', idveiculo_frota: '', modelo: '', placa: '', pooltrack: 'NÃO', primeira_locacao: '', proprietario: '', renavam: '', sascar: 'NÃO', t4s: 'NÃO', tipo_de_placa: '', tipo_frota: '', uf: '', valor_aluguel: '', valor_fipe: '', situacao: 'ATIVO', km_atual: '', observacoes: '', empresa: '', financiamento: '', locadora: '', motorista_atual: '' }; const [formData, setFormData] = useState(initialFormState); const { drivers, fetchDrivers } = useDrivers(); useEffect(() => { fetchVehicles(); fetchDrivers(); fetchListsConfig(); // Fetch Status Stats prafrotStatisticsService.getPlacasPorStatus().then(data => { if (Array.isArray(data)) setStatusStats(data); }); }, []); const getStatusData = (status) => { return statusStats.find(item => { const itemStatus = (item.status || item.status_frota || ''); return itemStatus.trim().toLowerCase() === status?.trim().toLowerCase(); }); }; const handleStatusClick = (status) => { const data = getStatusData(status); if (data && data.registros) { setSelectedStatusRecords({ title: status, records: JSON.parse(data.registros).filter(r => r !== null) }); setIsRecordsModalOpen(true); } }; const handleOpenModal = (vehicle = null) => { if (vehicle) { setEditingVehicle(vehicle); setFormData({ ...initialFormState, ...vehicle, // Fill with vehicle data tipo_placa: vehicle.tipo_de_placa || vehicle.tipo_placa || '', // Handle varied naming data_aquisicao: vehicle.data_aquisicao?.split('T')[0] || '', data_venda: vehicle.data_venda?.split('T')[0] || '', data_limite: vehicle.data_limite?.split('T')[0] || '', primeira_locacao: vehicle.primeira_locacao?.split('T')[0] || '', situacao: vehicle.situacao || vehicle.status_frota || 'ATIVO', }); } else { setEditingVehicle(null); setFormData(initialFormState); } setIsModalOpen(true); }; const { success: notifySuccess, error: notifyError, notifyFields } = useFeedback(); const handleSubmit = async (e) => { e.preventDefault(); // Validação de campos obrigatórios const requiredFields = []; if (!formData.placa) requiredFields.push('Placa'); if (!formData.modelo) requiredFields.push('Modelo'); if (!formData.fabricante) requiredFields.push('Fabricante'); if (requiredFields.length > 0) { notifyFields(requiredFields); return; } const payload = { ...formData, tipo_de_placa: formData.tipo_placa }; delete payload.motorista_atual; delete payload.empresa; delete payload.locadora; delete payload.km_atual; delete payload.data_venda; delete payload.valor_venda; delete payload.situacao; let success; if (editingVehicle) { success = await updateVehicle(editingVehicle.idveiculo_frota, payload); } else { success = await createVehicle(payload); } if (success) setIsModalOpen(false); }; const filteredVehicles = useMemo(() => Array.isArray(vehicles) ? vehicles.filter(v => v.placa?.toLowerCase().includes(searchTerm.toLowerCase()) || v.modelo?.toLowerCase().includes(searchTerm.toLowerCase()) ) : [], [vehicles, searchTerm]); return (
{/* Header Actions */}

Frota & Ativos

Gerencie os veículos cadastrados na plataforma.

setSearchTerm(e.target.value)} />
handleOpenModal()}> Novo Veículo
{/* Status Highlights */}
handleStatusClick('Veículo Alugado')} className="bg-white dark:bg-[#1c1c1c] border border-slate-200 dark:border-[#2a2a2a] rounded-xl p-6 shadow-sm hover:shadow-md transition-all flex items-center justify-between group cursor-pointer hover:border-blue-500/30" >
Veículos Alugados
{getStatusData('Veículo Alugado')?.total || 0}
handleStatusClick('Em Operação')} className="bg-white dark:bg-[#1c1c1c] border border-slate-200 dark:border-[#2a2a2a] rounded-xl p-6 shadow-sm hover:shadow-md transition-all flex items-center justify-between group cursor-pointer hover:border-orange-500/30" >
Em Operação
{getStatusData('Em Operação')?.total || 0}
{/* Modular Excel Table */}
deleteVehicle(item.idveiculo_frota)} />
{/* Modal - Dark Theme */} {editingVehicle ? `Editando: ${formData.placa}` : 'Cadastro de Novo Veículo'} Preencha os dados completos do ativo na frota.
{/* Seletor de Status Destacado */} {/* Seletor de Status removido conforme solicitacao */} {['basicos', 'operacional', 'financeiro', 'tecnico'].map(tab => ( {tab === 'tecnico' ? 'RASTREADOR' : tab} ))}
setFormData({...formData, placa: e.target.value})} required /> setFormData({...formData, chassi: e.target.value})} /> setFormData({...formData, renavam: e.target.value})} />
setFormData({...formData, modelo: e.target.value})} /> setFormData({...formData, fabricante: e.target.value})} /> setFormData({...formData, cor: e.target.value})} />
setFormData({...formData, ano_fabricacao: e.target.value})} /> setFormData({...formData, ano_modelo: e.target.value})} /> setFormData({...formData, categoria: v})} /> setFormData({...formData, combustivel: v})} />
setFormData({...formData, tipo_placa: e.target.value})} />
setFormData({...formData, base: e.target.value})} /> setFormData({...formData, uf: e.target.value})} maxLength={2} /> {/* Proprietário comentado nesta aba conforme nova solicitação para aba financeiro */} {/* setFormData({...formData, proprietario: v})} /> */}
setFormData({...formData, atuacao: e.target.value})} /> setFormData({...formData, tipo_frota: e.target.value})} />
setFormData({...formData, gestor: e.target.value})} /> setFormData({...formData, coordenador: e.target.value})} />
setFormData({...formData, dispatcher: e.target.value})} /> setFormData({...formData, fiscal_operacao: e.target.value})} />
{/* Campos motorista e status comentados para escrita e envio ao back conforme solicitado */} {/* setFormData({...formData, motorista_atual: v})} options={drivers} displayKey="NOME_FAVORECIDO" valueKey="NOME_FAVORECIDO" placeholder="Buscar motorista..." /> setFormData({...formData, status_veiculo: v})} /> */}
setFormData({...formData, valor_fipe: e.target.value})} /> setFormData({...formData, valor_aluguel: e.target.value})} />
setFormData({...formData, cnpj: e.target.value})} /> setFormData({...formData, contrato: e.target.value})} />
{/* Empresa e Locadora comentados para escrita e envio ao back */} {/* setFormData({...formData, empresa: e.target.value})} /> */} setFormData({...formData, proprietario: e.target.value})} /> setFormData({...formData, financiamento: e.target.value})} /> {/* setFormData({...formData, locadora: e.target.value})} /> */}
setFormData({...formData, data_aquisicao: e.target.value})} /> setFormData({...formData, valor_aquisicao: e.target.value})} />
{/* Campos comentados para escrita e envio ao back conforme solicitado */} {/* setFormData({...formData, data_venda: e.target.value})} /> setFormData({...formData, valor_venda: e.target.value})} /> */}
setFormData({...formData, primeira_locacao: e.target.value})} /> setFormData({...formData, data_limite: e.target.value})} />
{/* KM Atual comentado para escrita e envio ao back */} {/* setFormData({...formData, km_atual: e.target.value})} /> */}
{['geotab', 'sascar', 'golfleet', 'pooltrack', 't4s'].map(tracker => ( setFormData({...formData, [tracker]: v})} /> ))}