{m.text}
/* global React */ // Mensajería interna — versión ligera (HU.3.3) // Canal simple de comunicación CGR ↔ Institución, sin adjuntos. const { useState: useStateMs, useMemo: useMemoMs } = React; function MensajeriaScreen({ roleId, user, onOpenDetalle }) { const I = window.Icons; const [conversaciones, setConversaciones] = window.usePersistentState( 'mensajeria_' + roleId, () => (window.getConversaciones(roleId) || []).map(c => JSON.parse(JSON.stringify(c))) ); const [tab, setTab] = useStateMs('inbox'); const [q, setQ] = useStateMs(''); const [activeId, setActiveId] = useStateMs(conversaciones[0]?.id || null); const [composing, setComposing] = useStateMs(false); const ahoraTxt = () => { const d = new Date(), p = n => (n < 10 ? '0' : '') + n; return 'Hoy · ' + p(d.getHours()) + ':' + p(d.getMinutes()); }; const autorOut = (roleId === 'institucion') ? ((user && user.name) || 'Institución') + ' (' + ((user && user.initials) || 'IN') + ')' : 'C. Benítez (CGR)'; const replyTo = (convId, text) => { if (!text || !text.trim()) return; setConversaciones(list => list.map(c => c.id === convId ? { ...c, unread: 0, preview: text.trim(), mensajes: [...(c.mensajes || []), { from: 'out', author: autorOut, date: ahoraTxt(), text: text.trim(), attachments: [] }] } : c)); }; const sendNew = ({ to, subject, text }) => { if (!text || !text.trim()) return; const id = 'conv-' + Date.now().toString(36); const nueva = { id, folder: 'sent', unread: 0, with: { name: to || 'Destinatario', sub: '', initials: (to || 'D').slice(0, 2).toUpperCase(), tone: 'inst' }, subject: subject || '(sin asunto)', preview: text.trim(), compromisoId: '', compromisoText: '', mensajes: [{ from: 'out', author: autorOut, date: ahoraTxt(), text: text.trim(), attachments: [] }], }; setConversaciones(list => [nueva, ...list]); setActiveId(id); setComposing(false); setTab('sent'); }; const filtered = useMemoMs(() => { let list = conversaciones; if (tab === 'inbox') list = list.filter(c => c.folder === 'inbox'); if (tab === 'unread') list = list.filter(c => c.unread > 0); if (tab === 'sent') list = list.filter(c => c.folder === 'sent'); if (q) { list = list.filter(c => `${c.with.name} ${c.subject} ${c.preview} ${c.compromisoText || ''}` .toLowerCase().includes(q.toLowerCase()) ); } return list; }, [conversaciones, tab, q]); const active = conversaciones.find(c => c.id === activeId) || filtered[0]; const counts = useMemoMs(() => { const c = { inbox: 0, sent: 0, unread: 0 }; conversaciones.forEach(x => { c[x.folder] = (c[x.folder] || 0) + 1; c.unread += x.unread; }); return c; }, [conversaciones]); return (
Bandeja interna para enviar y recibir requerimientos, recordatorios y consultas con {roleId === 'institucion' ? ' la CGR' : ' las instituciones reportantes'} sin salir del sistema. Cada mensaje puede vincularse a una recomendación específica, queda registrado con fecha, autor y estado de lectura, y conserva la cadena completa de respuestas para trazabilidad y auditoría. Reemplaza el uso de correo electrónico para temas operativos del seguimiento.
No hay mensajes con esos criterios.
El hilo aparecerá aquí.
{m.text}