// Caririaçu Guincho — Frota Screen const { useState: useStateF, useEffect: useEffectF } = React; // ── Modal de Registro de Manutenção ────────────────────────────────────── const NovaManutencaoModal = ({ open, item, onClose, onSaved }) => { const [form, setForm] = useStateF({ data: new Date().toISOString().slice(0,10), tipo: 'Preventiva', descricao: '', valor: '', oficina: '' }); const set = (k, v) => setForm(f => ({ ...f, [k]: v })); if (!open || !item) return null; const handle = async () => { if (!form.descricao) { showToast('Descreva o serviço de manutenção', 'warning'); return; } const created = await db.insert('manutencoes', { guincho_id: item.id, guincho_code: item.code, data: form.data, tipo: form.tipo, descricao: form.descricao, valor: parseFloat(form.valor) || 0, oficina: form.oficina, }); if (created) { showToast(`Manutenção registrada para ${item.code}`, 'success'); setForm({ data: new Date().toISOString().slice(0,10), tipo: 'Preventiva', descricao: '', valor: '', oficina: '' }); onSaved?.(); onClose(); } }; return (
{item.modelo}
{item.placa} · {item.code}
set('data', e.target.value)} /> set('descricao', e.target.value)} />
set('oficina', e.target.value)} /> set('valor', e.target.value)} />
Cancelar Registrar
); }; const FrotaScreen = () => { const [frota, setFrota] = useStateF([]); const [loading, setLoading] = useStateF(true); const [motoristas, setMotoristas] = useStateF([]); const [modal, setModal] = useStateF(false); const [editItem, setEditItem] = useStateF(null); const [form, setForm] = useStateF({ placa: '', modelo: '', marca: '', ano: '', cor: '', status: 'ativo', motorista_id: '', obs: '' }); const set = (k, v) => setForm(f => ({ ...f, [k]: v })); const statusMap = { ativo: { label: 'Ativo', color: '#10B981' }, manutencao: { label: 'Manutenção', color: '#F59E0B' }, inativo: { label: 'Inativo', color: '#94A3B8' } }; const refresh = async () => { setLoading(true); const [f, m] = await Promise.all([ db.list('frota', { order: 'code', asc: true }), db.list('motoristas', { order: 'nome', asc: true }) ]); setFrota(f); setMotoristas(m); setLoading(false); }; useEffectF(() => { refresh(); }, []); const openNew = () => { const nextNum = (frota.length + 1).toString().padStart(3, '0'); setEditItem(null); setForm({ placa: '', modelo: '', marca: '', ano: '', cor: '', status: 'ativo', motorista_id: '', obs: '', code: `GNC-${nextNum}` }); setModal(true); }; const openEdit = (item) => { setEditItem(item); setForm({ placa: item.placa, modelo: item.modelo || '', marca: item.marca || '', ano: item.ano || '', cor: item.cor || '', status: item.status, motorista_id: item.motorista_id || '', obs: item.obs || '', code: item.code }); setModal(true); }; const handleSave = async () => { if (!form.placa || !form.modelo) { showToast('Placa e modelo são obrigatórios', 'warning'); return; } const motoristaSel = motoristas.find(m => m.id === parseInt(form.motorista_id)); const payload = { placa: form.placa, modelo: form.modelo, marca: form.marca, ano: form.ano ? parseInt(form.ano) : null, cor: form.cor, status: form.status, obs: form.obs, motorista_id: form.motorista_id ? parseInt(form.motorista_id) : null, motorista_nome: motoristaSel?.nome || null, }; if (editItem) { const updated = await db.update('frota', editItem.id, payload); if (updated) { showToast('Guincho atualizado!', 'success'); refresh(); } } else { const created = await db.insert('frota', { ...payload, code: form.code }); if (created) { showToast('Guincho cadastrado!', 'success'); if (motoristaSel) await db.update('motoristas', motoristaSel.id, { guincho_code: form.code }); refresh(); } } setModal(false); }; const toggleManutencao = async (item) => { const novoStatus = item.status === 'manutencao' ? 'ativo' : 'manutencao'; const updated = await db.update('frota', item.id, { status: novoStatus }); if (updated) { showToast('Status atualizado!', 'success'); refresh(); } }; return (

Frota de Guinchos

{frota.length} veículos cadastrados · {frota.filter(f => f.status === 'ativo').length} ativos
Novo Guincho
{[ { label: 'Total', value: frota.length, color: '#3B82F6', icon: 'truck' }, { label: 'Ativos', value: frota.filter(f=>f.status==='ativo').length, color: '#10B981', icon: 'check' }, { label: 'Manutenção', value: frota.filter(f=>f.status==='manutencao').length, color: '#F59E0B', icon: 'wrench' }, { label: 'Inativos', value: frota.filter(f=>f.status==='inativo').length, color: '#94A3B8', icon: 'x' }, ].map(c => (
{c.value}
{c.label}
))}
{loading ? ( Carregando frota... ) : frota.length === 0 ? (
Nenhum guincho cadastrado
Cadastre o primeiro veículo da sua frota
Cadastrar Primeiro Guincho
) : (
{frota.map(item => { const st = statusMap[item.status]; return ( e.currentTarget.style.boxShadow = '0 4px 16px rgba(0,0,0,0.1)'} onMouseLeave={e => e.currentTarget.style.boxShadow = '0 1px 3px rgba(0,0,0,0.07)'}>
{st.label}
{item.placa}
{item.code}
{item.modelo}
{item.marca || '—'} · {item.ano || '—'} · {item.cor || '—'}
w[0]).join('').slice(0,2).toUpperCase() : '--'} size={26} />
{item.motorista_nome || 'Sem motorista'}
Motorista vinculado
openEdit(item)} style={{ flex: 1, justifyContent: 'center' }}>Editar window.abrirGuincho?.(item.id)} style={{ flex: 1, justifyContent: 'center' }}>Histórico toggleManutencao(item)} title={item.status === 'manutencao' ? 'Reativar' : 'Marcar como manutenção'}> {item.status === 'manutencao' ? '↩' : '🔧'}
); })}
)} setModal(false)} title={editItem ? `Editar ${editItem.placa}` : 'Novo Guincho'} width={540}>
set('code', e.target.value)} /> set('placa', e.target.value)} /> set('modelo', e.target.value)} /> set('marca', e.target.value)} /> set('ano', e.target.value)} /> set('cor', e.target.value)} /> set('motorista_id', e.target.value)} options={[{value:'',label:'Sem motorista'}, ...motoristas.map(m => ({ value: m.id, label: m.nome }))]} />
set('obs', e.target.value)} />
setModal(false)}>Cancelar {editItem ? 'Salvar Alterações' : 'Cadastrar Guincho'}
); }; Object.assign(window, { FrotaScreen, NovaManutencaoModal });