const { useState, useRef, useEffect } = React; function formatMarkdown(text) { if (!text) return ''; let html = text .replace(/&/g, "&") .replace(//g, ">"); // LÍNEAS DIVISORIAS ESTRUCTURADAS html = html.replace(/^---$/gim, '
'); // ENCABEZADOS DE NIVELES CON ESTILIZADO ENTERPRISE html = html.replace(/^### (.*$)/gim, '

$1

'); html = html.replace(/^## (.*$)/gim, '

$1

'); html = html.replace(/^# (.*$)/gim, '

$1

'); // NEGRITAS Y CURSIVAS html = html.replace(/\*\*(.*?)\*\*/g, '$1'); html = html.replace(/\*(.*?)\*/g, '$1'); // ENCABEZADOS DE DOCUMENTOS LEGALES (PARA, DE, FECHA, ASUNTO) html = html.replace(/\b(Para|De|Fecha|Asunto):\s*(.*$)/gim, '
$1$2
'); // TABLAS MARKDOWN ELEGANTES if (html.includes('|')) { const lines = html.split('\n'); let inTable = false; let tableHtml = '
'; let newLines = []; lines.forEach(line => { const trimmed = line.trim(); if (trimmed.startsWith('|') && trimmed.endsWith('|')) { const cells = trimmed.split('|').filter((_, i, arr) => i > 0 && i < arr.length - 1); if (trimmed.includes('---')) return; if (!inTable) { inTable = true; tableHtml += ''; cells.forEach(c => { tableHtml += ``; }); tableHtml += ''; } else { tableHtml += ''; cells.forEach(c => { tableHtml += ``; }); tableHtml += ''; } } else { if (inTable) { inTable = false; tableHtml += '
${c.trim()}
${c.trim()}
'; newLines.push(tableHtml); tableHtml = '
'; } newLines.push(line); } }); if (inTable) { tableHtml += '
'; newLines.push(tableHtml); } html = newLines.join('\n'); } // VIÑETAS LIMPIAS html = html.replace(/^\s*[\-\*•]\s+(.*$)/gim, '
$1
'); // ESPACIADO DE PÁRRAFOS html = html.replace(/\n\n/g, '
'); return html; } window.AdminAICopilot = function({ companyName, currentTab = 'logs' }) { const [isOpen, setIsOpen] = useState(false); const [keySourceUsed, setKeySourceUsed] = useState('maestra'); const [dynamicPrompts, setDynamicPrompts] = useState([]); const [loadingPrompts, setLoadingPrompts] = useState(false); const defaultPrompts = [ { title: "Resumen Ejecutivo de Asistencia", desc: "Consulta la puntualidad, tardanzas y ausencias del personal este mes.", query: "Proporciona un reporte breve de asistencia del personal este mes: puntualidad, tardanzas acumuladas y observaciones principales." }, { title: "Balance de Nómina Quincenal", desc: "Proyección de salarios brutos, INSS Patronal y retenciones de ley.", query: "Genera un balance conciso de la nómina quincenal actual: colaboradores activos, salario total y proyección de INSS Patronal." }, { title: "Documento de Llamado de Atención", desc: "Redactar llamado de atención formal según el Código del Trabajo.", query: "Redacta una plantilla formal de llamado de atención por tardanzas recurrentes conforme al Código del Trabajo de Nicaragua." } ]; const [messages, setMessages] = useState([ { sender: 'ai', text: `¡Hola! Soy **Shift Copilot AI**, tu asistente ejecutivo inteligente para **${companyName || 'tu empresa'}**.\n\nTengo acceso en tiempo real a tus registros de asistencia, horarios, nómina y expedientes de esta empresa. ¿En qué puedo apoyarte hoy?` } ]); const [inputPrompt, setInputPrompt] = useState(''); const [isLoading, setIsLoading] = useState(false); const chatEndRef = useRef(null); const loadSmartPrompts = async () => { if (dynamicPrompts.length > 0) return; setLoadingPrompts(true); try { const res = await window.apiCall('get_ai_smart_prompts', {}); if (res && res.success && res.prompts && res.prompts.length > 0) { setDynamicPrompts(res.prompts); } else { setDynamicPrompts(defaultPrompts); } } catch (e) { setDynamicPrompts(defaultPrompts); } finally { setLoadingPrompts(false); } }; useEffect(() => { if (isOpen) { loadSmartPrompts(); } }, [isOpen]); useEffect(() => { if (isOpen && chatEndRef.current) { chatEndRef.current.scrollIntoView({ behavior: 'smooth' }); } }, [messages, isOpen, isLoading]); const handleSendPrompt = async (promptToSend = null) => { const textQuery = promptToSend || inputPrompt; if (!textQuery.trim() || isLoading) return; const userMsg = { sender: 'user', text: textQuery }; setMessages(prev => [...prev, userMsg]); setInputPrompt(''); setIsLoading(true); try { const res = await window.apiCall('ask_ai_copilot', { prompt: textQuery, currentTab: currentTab }); if (res && res.success && res.response) { if (res.key_source) setKeySourceUsed(res.key_source); setMessages(prev => [...prev, { sender: 'ai', text: res.response }]); } else { setMessages(prev => [...prev, { sender: 'ai', text: res?.error || "El asistente se encuentra procesando otras solicitudes. Por favor reintente en un momento." }]); } } catch (err) { setMessages(prev => [...prev, { sender: 'ai', text: "Error de comunicación con el motor IA: " + err.message }]); } finally { setIsLoading(false); } }; const activePrompts = dynamicPrompts.length > 0 ? dynamicPrompts : defaultPrompts; return ( {/* BOTÓN FLOTANTE ENTERPRISE MINIMALISTA */} {/* MODAL / DRAWER LATERAL DE CHAT REFINADO */} {isOpen && (
setIsOpen(false)}>
e.stopPropagation()}> {/* HEADER DEL CHAT */}

Shift Copilot AI

Gemini 3.6

Aislamiento de Datos: {companyName || 'Cliente Activo'}

{/* HISTORIAL DE CONVERSACIÓN */}
{messages.map((m, idx) => (
{m.sender === 'ai' ? (
) : ( {m.text} )}
))} {/* INDICADOR DE CARGA */} {isLoading && (
Consultando expediente y registros de {companyName || 'la empresa'}...
)} {/* PROMPTS SUGERIDOS INTERACTIVOS */} {messages.length <= 2 && !isLoading && (
Consultas Frecuentes Recomendadas:
{activePrompts.map((sp, i) => (
handleSendPrompt(sp.query)} className="p-3.5 bg-white hover:bg-indigo-50/60 border border-slate-200/90 hover:border-indigo-300 rounded-2xl cursor-pointer transition-all duration-200 shadow-xs group" >

{sp.title}

{sp.desc}

))}
)}
{/* CHIPS DE ACCESO RÁPIDO */}
{/* CAJA DE ENTRADA DE MENSAJES */}
{ e.preventDefault(); handleSendPrompt(); }} className="p-4 border-t border-slate-200/80 bg-white flex items-center gap-2"> setInputPrompt(e.target.value)} placeholder="Escribe tu consulta sobre asistencia, nómina o contratos..." className="flex-1 p-3.5 bg-slate-50 border border-slate-200 rounded-2xl text-xs font-bold outline-none focus:border-indigo-600 focus:bg-white transition-all" disabled={isLoading} />
)} ); };