/* global React, ChIcon, NavIcon, CHANNELS, StateBadge, FOCUSED_CASE, CASE_EMAIL, CASE_WEB, SUB_PHASES, EQUIPMENT_HISTORY, ATTACHMENTS_2841, SLA_2841, AUDIT_2841 */ // Resolve case by ticket id — falls back to FOCUSED_CASE const CASE_MAP = { "CNL-2841": () => FOCUSED_CASE, "CNL-2836": () => CASE_EMAIL, "CNL-2838": () => CASE_WEB, }; const getCase = (id) => (CASE_MAP[id] || (() => FOCUSED_CASE))(); // =========== Channel-specific conversation renderers =========== const WaConversation = ({ messages }) => (
{messages.map((m, i) => (
{m.time} {m.dir === "out" && "✓✓"}
))}
); const IgConversation = ({ messages }) => (
{messages.map((m, i) => (
{m.time}
))}
); const FbConversation = ({ messages }) => (
{messages.map((m, i) => (
{m.time}
))}
); const WebConversation = ({ messages, customer }) => (
S
SOF.IA · Canella asistente · típicamente responde al instante
● en línea
{messages.map((m, i) => (
{m.time}
))}
); const EmailConversation = ({ thread }) => (
{thread.map((e, i) => (
{e.direction === "in" ? "KE" : "S"}
{e.fromName} {e.from}
{e.time}
{e.subject}
Para: {e.to} {e.cc && CC: {e.cc}}
{e.body}
{e.hasAttachments && (
📎 display_error.jpg · 0.8 MB 📎 atasco_papel.jpg · 1.2 MB
)}
))}
); const ConversationByChannel = ({ c }) => { if (c.channel === "whatsapp") return ; if (c.channel === "web") return ; if (c.channel === "email") return ; return ; }; const BubbleText = ({ text }) => (
{text.split("\n").map((line, i) => (
$1")}}/> ))}
); // =========== Phase strip =========== const PhaseStrip = ({ currentIdx }) => (
Fase actual {SUB_PHASES.map((p, i) => ( {i < currentIdx && } {p} {i < SUB_PHASES.length - 1 && } ))}
); // =========== Equipment history card =========== const HistoryCard = ({ serial }) => { const eq = EQUIPMENT_HISTORY[serial]; if (!eq) return null; return (

Historial del equipo

{eq.pastTickets.length} tickets previos · SN {serial}
Instalado
{eq.installed}
Contador
{eq.counter.toLocaleString()}
Promedio mensual
{eq.avgMonthly.toLocaleString()}
{eq.alerts.map((a, i) => (
{a}
))}
{eq.pastTickets.map(t => (
{t.date}
{t.issue}
#{t.id} · {t.solver} · {t.duration}
))}
); }; // =========== Attachments =========== const AttachmentsCard = () => (

Adjuntos del cliente

{ATTACHMENTS_2841.length} archivos
{ATTACHMENTS_2841.map((a, i) => (
{a.kind === "image" && (
)} {a.kind === "audio" && (
{Array.from({length:18}).map((_,k) => )}
)}
{a.label} {a.time} · {a.size}
))}
); // =========== SLA card =========== const SlaCard = () => (

Línea de tiempo / SLA

{SLA_2841.target}
A tiempo · captura total {SLA_2841.totalCapture}

Todos los segmentos dentro del objetivo. SOF.IA cerró el caso 3:42 después del primer mensaje.

A TIEMPO
{SLA_2841.segments.map((s, i) => (
{s.phase}
{s.duration}
))}
); // =========== Audit trail =========== const AuditCard = () => (

Trazabilidad · auditoría

{AUDIT_2841.length} eventos · 100% auditable
{AUDIT_2841.map((row, i) => (
{row.time} {row.actor === "sofia" ? "S" : row.actor === "system" ? "·" : "H"}
{row.action} {row.note}
))}
); // =========== Reasoning timeline (existing) =========== const Reasoning = ({ c }) => (
S

Registro de razonamiento de SOF.IA

{c.reasoning?.length || 0} pasos · 100% auto
{(c.reasoning || []).map(step => (
{step.idx}
{step.title}

$1").replace(/\*\*([^*]+)\*\*/g,"$1").replace(/\*([^*]+)\*/g,"$1")}}/>

AUTO {step.time}
))}
); const KbHitsCard = ({ c }) => ( c.kbHits ? (

Knowledge Base · consultada

{c.kbHits.length} resultados
{c.kbHits.map((h, i) => (
{h.score}
{h.title}

{h.snippet}

{h.section}
))}
) : null ); // =========== Main case screen =========== const CaseScreen = ({ ticketId, goToQueue, goToEscalation }) => { const c = getCase(ticketId || "CNL-2841"); const channelMeta = CHANNELS.find(x => x.id === c.channel); const isFocused = c.id === "CNL-2841"; const phaseIdx = isFocused ? 7 : c.channel === "email" ? 5 : 3; return (

Ticket #{c.id} · {c.customer}

{c.state === "auto" ? "Resuelto por SOF.IA" : c.state === "progress" ? "En curso con SOF.IA" : "Caso escalado"} {" · captura "}{c.duration}{" · canal "}{channelMeta.label}
{/* Context strip */}
Canal de origen
{channelMeta.label}
Cliente
{c.customer}
{c.company}
Equipo
{c.printer}
SN · {c.serial}
Contrato
{c.contract}
Resultado
{c.channel === "email" ? "visita técnica miércoles" : c.channel === "web" ? "consumible despachado" : "visita técnica agendada"}
{/* LEFT — conversation */}
{c.customer} {c.customerSub} · vía {channelMeta.label}
{c.startedAt || ""}
{c.state === "auto" ? "SOF.IA cerró la conversación" : "Conversación en curso"}
{/* RIGHT — reasoning + KB hits */}
{c.reasoning ? : (
Razonamiento en curso SOF.IA está procesando este caso. El registro completo aparece cuando se cierra el ticket o se escala. Aún {c.duration} de captura · indagando falla.
)}
{/* Enrichments only for the fully-fleshed focused case */} {isFocused && ( <>
{/* Email panel */}

Correo redactado por SOF.IA

Enviado automáticamente · 10:46
Para:{c.email.to} CC:{c.email.cc} Asunto:{c.email.subject}
{c.email.body}
{/* Star case callout */}

Caso estrella · serie pronunciada de forma ambigua

Patrón #41 · HP M-series
La cliente dictó la serie como "VNB tres K uno dos cero ochenta y nueve". El parser de SOF.IA convirtió palabras a dígitos (ochenta y nueve → 89), normalizó separadores y validó el formato HP de 10 caracteres alfanuméricos. Cuando hubo coincidencia múltiple por los últimos 4 dígitos, verificó nombre y dirección contra la BD para desambiguar — sin pedir al cliente que volviera a deletrear. Tiempo total de captura: 11 segundos.
)}
); }; window.CaseScreen = CaseScreen;