// 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 (

Lembretes pendentes

{[ { k: 'todos', label: 'Todos' }, { k: 'vencido', label: 'Vencidos' }, { k: 'proximo', label: 'Próximos' }, ].map(o => ( ))}
{grupos.length === 0 ? (
Nenhum lembrete {filtro !== 'todos' ? filtro : 'pendente'}.
) : grupos.map(g => (
{g.guincho?.marca} {g.guincho?.modelo} · {g.guincho?.placa}
{fmtKM(g.guincho?.km_atual || 0)}
{g.items.map(x => { const c = window.CORES_LEMBRETE[x.st.estado]; return (
{c.icon} {x.descricao}
{window.formatarFalta(x.st)} {x.recorrente && ' · recorrente'}
); })}
))}
); }; Object.assign(window, { LembretesConsolidadosScreen });