// Caririaçu Guincho — Tela consolidada de lembretes (toda a frota) const { useState: useStateLC, useEffect: useEffectLC, useMemo: useMemoLC } = React; const LembretesConsolidadosScreen = () => { const [lembretes, setLembretes] = useStateLC([]); const [frota, setFrota] = useStateLC([]); const [filtro, setFiltro] = useStateLC('todos'); // todos | vencido | proximo const [tick, setTick] = useStateLC(0); useEffectLC(() => { Promise.all([ db.list('lembretes', { eq: { status: 'ativo' } }), db.list('frota'), ]).then(([ls, fs]) => { setLembretes(ls); setFrota(fs); }); }, [tick]); const fmap = useMemoLC(() => Object.fromEntries(frota.map(g => [g.id, g])), [frota]); const itemsComStatus = useMemoLC(() => { const order = { vencido: 0, proximo: 1, ativo: 2 }; const arr = lembretes.map(l => ({ ...l, guincho: fmap[l.guincho_id], st: window.statusLembrete(l, fmap[l.guincho_id]?.km_atual) })); return arr .filter(x => filtro === 'todos' ? x.st.estado !== 'ativo' : filtro === 'vencido' ? x.st.estado === 'vencido' : filtro === 'proximo' ? x.st.estado === 'proximo' : true) .sort((a, b) => order[a.st.estado] - order[b.st.estado]); }, [lembretes, fmap, filtro]); // agrupado por guincho const grupos = useMemoLC(() => { const map = {}; itemsComStatus.forEach(x => { const k = x.guincho_id; map[k] = map[k] || { guincho: x.guincho, items: [] }; map[k].items.push(x); }); return Object.values(map); }, [itemsComStatus]); const concluir = async (item) => { if (!confirm(`Marcar "${item.descricao}" como concluído?`)) return; const { error } = await sb.rpc('concluir_lembrete', { p_lembrete_id: item.id }); if (error) { showToast('Erro: ' + error.message, 'error'); return; } setTick(t => t + 1); showToast(item.recorrente ? 'Concluído (próximo lembrete criado)' : 'Concluído', 'success'); }; return (