SIO Dental

Sistema Integral Odontológico

Cargando...
// ========== PANEL SUPER ADMIN ========== window.renderPanelSuperAdmin = async function(container) { if(!container) { container = document.getElementById('dynamicView'); } // Verificar que sea Super Admin const usuarioActual = JSON.parse(localStorage.getItem('usuarioActual') || '{}'); if(usuarioActual.rol !== 'super_admin') { container.innerHTML = '
Acceso denegado. No eres Super Administrador.
'; return; } // Obtener datos const consultorios = JSON.parse(localStorage.getItem('sistema_consultorios') || '[]'); const usuarios = JSON.parse(localStorage.getItem('sistema_usuarios') || '[]'); const bitacora = JSON.parse(localStorage.getItem('bitacora_super_admin') || '[]'); // Calcular estadísticas const ingresosTotales = consultorios.reduce((sum, c) => { const planes = { BASICO: 199, PROFESIONAL: 399, EMPRESARIAL: 699 }; return sum + (planes[c.plan] || 0); }, 0); container.innerHTML = `

Panel de Super Administrador

Gestión centralizada de todos los consultorios

👑 ${usuarioActual.nombre}

${consultorios.length}

Consultorios Activos

${usuarios.filter(u => u.rol !== 'super_admin').length}

Usuarios Totales

$${ingresosTotales.toLocaleString()}

Ingresos por Licencias

${bitacora.length}

Eventos Registrados
Registrar Nuevo Consultorio (Cliente)
Consultorios Registrados
${consultorios.length === 0 ? '
No hay consultorios registrados
' : consultorios.map(c => { const fechaExp = new Date(c.licencia?.fechaExpiracion || c.fechaExpiracion); const hoy = new Date(); const diasRestantes = Math.ceil((fechaExp - hoy) / (1000 * 60 * 60 * 24)); let estadoClass = 'activo'; let estadoTexto = `Vence en ${diasRestantes} días`; if(diasRestantes < 0) { estadoClass = 'expirado'; estadoTexto = 'EXPIRADO'; } else if(diasRestantes <= 30) { estadoClass = 'por-vencer'; } const admin = usuarios.find(u => u.consultorioId === c.id && u.rol === 'admin_consultorio'); return `
${c.nombre}
${c.email} | ${c.telefono || 'N/A'}
Plan: ${c.plan || 'BASICO'} ${estadoTexto}
ID: ${c.id}
Admin: ${admin?.username || 'No asignado'} | Pass: ${admin?.password || 'admin123'}
Registrado: ${new Date(c.fechaRegistro).toLocaleDateString()}
Expira: ${fechaExp.toLocaleDateString()}
`; }).join('') }
Bitácora de Eventos
${bitacora.length === 0 ? '
No hay eventos registrados
' : bitacora.slice().reverse().slice(0, 30).map(b => `
${b.accion}
${b.consultorioNombre || 'N/A'}
${new Date(b.fecha).toLocaleString()}
${b.detalles || ''}
`).join('') }
`; }; // Funciones del Panel // ========== PANEL SUPER ADMIN MEJORADO ========== // 1. REGISTRAR CONSULTORIO (con email y teléfono) window.registrarNuevoConsultorioPanel = function() { const nombre = document.getElementById('newNombre')?.value.trim(); const email = document.getElementById('newEmail')?.value.trim(); const telefono = document.getElementById('newTelefono')?.value.trim(); const plan = document.getElementById('newPlan')?.value || 'PROFESIONAL'; if(!nombre || !email) { alert('Complete nombre y email'); return; } const consultorioId = `CONS_${Date.now()}_${Math.random().toString(36).substr(2, 6)}`; const username = generarUsername(nombre); const password = generarPassword(); const fechaExpiracion = new Date(); fechaExpiracion.setFullYear(fechaExpiracion.getFullYear() + 1); // Guardar consultorio const nuevoConsultorio = { id: consultorioId, nombre: nombre, email: email, telefono: telefono, plan: plan, username: username, password: password, fechaRegistro: new Date().toISOString(), fechaExpiracion: fechaExpiracion.toISOString(), activo: true }; let consultorios = JSON.parse(localStorage.getItem('sistema_consultorios') || '[]'); consultorios.push(nuevoConsultorio); localStorage.setItem('sistema_consultorios', JSON.stringify(consultorios)); // Crear usuario Admin const nuevoAdmin = { id: `ADMIN_${consultorioId}`, username: username, password: password, email: email, telefono: telefono, nombre: `Administrador de ${nombre}`, rol: 'admin_consultorio', consultorioId: consultorioId, activo: true, fechaRegistro: new Date().toISOString() }; let usuarios = JSON.parse(localStorage.getItem('sistema_usuarios') || '[]'); usuarios.push(nuevoAdmin); localStorage.setItem('sistema_usuarios', JSON.stringify(usuarios)); // Bitácora let bitacora = JSON.parse(localStorage.getItem('bitacora_super_admin') || '[]'); bitacora.push({ id: Date.now(), fecha: new Date().toISOString(), accion: 'REGISTRO_CONSULTORIO', consultorioId: consultorioId, consultorioNombre: nombre, detalles: `Nuevo consultorio: ${nombre} - Usuario: ${username} - Email: ${email} - Tel: ${telefono}` }); localStorage.setItem('bitacora_super_admin', JSON.stringify(bitacora)); alert(`✅ CONSULTORIO REGISTRADO!\n\n📛 Nombre: ${nombre}\n👤 Usuario: ${username}\n🔑 Contraseña: ${password}\n📧 Email: ${email}\n📞 Teléfono: ${telefono || 'No registrado'}\n📅 Expira: ${fechaExpiracion.toLocaleDateString()}`); window.renderPanelSuperAdmin(); }; // 2. EDITAR CONSULTORIO (cambiar usuario, email, teléfono, resetear contraseña) window.editarConsultorioPanel = function(consultorioId) { let consultorios = JSON.parse(localStorage.getItem('sistema_consultorios') || '[]'); let usuarios = JSON.parse(localStorage.getItem('sistema_usuarios') || '[]'); const consultorio = consultorios.find(c => c.id === consultorioId); const admin = usuarios.find(u => u.consultorioId === consultorioId && u.rol === 'admin_consultorio'); if(!consultorio) return; const modalHTML = ` `; // Remover modal existente const modalExistente = document.getElementById('modalEditarConsultorio'); if(modalExistente) modalExistente.remove(); document.body.insertAdjacentHTML('beforeend', modalHTML); }; // Guardar edición window.guardarEdicionConsultorio = function(consultorioId) { let consultorios = JSON.parse(localStorage.getItem('sistema_consultorios') || '[]'); let usuarios = JSON.parse(localStorage.getItem('sistema_usuarios') || '[]'); const index = consultorios.findIndex(c => c.id === consultorioId); const adminIndex = usuarios.findIndex(u => u.consultorioId === consultorioId && u.rol === 'admin_consultorio'); if(index === -1) return; const nuevoNombre = document.getElementById('editNombre')?.value.trim(); const nuevoUsername = document.getElementById('editUsername')?.value.trim(); const nuevoEmail = document.getElementById('editEmail')?.value.trim(); const nuevoTelefono = document.getElementById('editTelefono')?.value.trim(); const nuevaExpiracion = document.getElementById('editExpiracion')?.value; if(!nuevoNombre || !nuevoUsername || !nuevoEmail) { alert('Nombre, usuario y email son requeridos'); return; } // Actualizar consultorio consultorios[index].nombre = nuevoNombre; consultorios[index].email = nuevoEmail; consultorios[index].telefono = nuevoTelefono; if(nuevaExpiracion) consultorios[index].fechaExpiracion = nuevaExpiracion; consultorios[index].username = nuevoUsername; // Actualizar usuario admin if(adminIndex !== -1) { usuarios[adminIndex].username = nuevoUsername; usuarios[adminIndex].email = nuevoEmail; usuarios[adminIndex].telefono = nuevoTelefono; usuarios[adminIndex].nombre = `Administrador de ${nuevoNombre}`; } localStorage.setItem('sistema_consultorios', JSON.stringify(consultorios)); localStorage.setItem('sistema_usuarios', JSON.stringify(usuarios)); // Bitácora let bitacora = JSON.parse(localStorage.getItem('bitacora_super_admin') || '[]'); bitacora.push({ id: Date.now(), fecha: new Date().toISOString(), accion: 'EDICION_CONSULTORIO', consultorioId: consultorioId, consultorioNombre: nuevoNombre, detalles: `Consultorio editado - Nuevo usuario: ${nuevoUsername}` }); localStorage.setItem('bitacora_super_admin', JSON.stringify(bitacora)); alert('✅ Consultorio actualizado correctamente'); cerrarModalEditar(); window.renderPanelSuperAdmin(); }; // Resetear contraseña window.resetearPasswordConsultorio = function(consultorioId) { const nuevaPassword = generarPassword(); let consultorios = JSON.parse(localStorage.getItem('sistema_consultorios') || '[]'); let usuarios = JSON.parse(localStorage.getItem('sistema_usuarios') || '[]'); const consultorioIndex = consultorios.findIndex(c => c.id === consultorioId); const adminIndex = usuarios.findIndex(u => u.consultorioId === consultorioId && u.rol === 'admin_consultorio'); if(consultorioIndex !== -1) { consultorios[consultorioIndex].password = nuevaPassword; } if(adminIndex !== -1) { usuarios[adminIndex].password = nuevaPassword; } localStorage.setItem('sistema_consultorios', JSON.stringify(consultorios)); localStorage.setItem('sistema_usuarios', JSON.stringify(usuarios)); // Actualizar el campo en el modal const passwordInput = document.getElementById('editPassword'); if(passwordInput) passwordInput.value = nuevaPassword; alert(`✅ Nueva contraseña: ${nuevaPassword}\n\nRecomendamos que el usuario la cambie al iniciar sesión.`); }; // Cerrar modal window.cerrarModalEditar = function() { const modal = document.getElementById('modalEditarConsultorio'); if(modal) modal.remove(); }; // Generar username automático function generarUsername(nombre) { return nombre .toLowerCase() .normalize('NFD').replace(/[\u0300-\u036f]/g, '') // Eliminar acentos .replace(/[^a-z0-9]/g, '_') .substring(0, 30) + '_' + Math.floor(Math.random() * 1000); } // Generar contraseña segura function generarPassword() { const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'; let password = ''; for(let i = 0; i < 10; i++) { password += chars.charAt(Math.floor(Math.random() * chars.length)); } return password; } // 3. LOGIN MEJORADO (acepta usuario, email O teléfono) window.login = async function(loginInput, password) { // Si es un evento, extraer valores if(typeof loginInput === 'object') { password = document.getElementById('loginPass').value; loginInput = document.getElementById('loginUser').value; } // Buscar por usuario, email o teléfono let usuario = null; // Buscar en tabla de usuarios const usuarios = JSON.parse(localStorage.getItem('sistema_usuarios') || '[]'); usuario = usuarios.find(u => u.username === loginInput || u.email === loginInput || u.telefono === loginInput ); // Verificar Super Admin if(loginInput === 'superadmin' && password === 'SuperAdmin2025!') { currentUser = { id: 'super_admin', username: 'superadmin', nombre: 'Administrador General', rol: 'super_admin', nivel: 0 }; localStorage.setItem('usuarioActual', JSON.stringify(currentUser)); document.getElementById('loginScreen').style.display = 'none'; document.getElementById('appMain').style.display = 'block'; if(typeof buildMenu === 'function') buildMenu(); if(typeof showSection === 'function') showSection('dashboard'); return; } // Validar credenciales if(usuario && usuario.password === password && usuario.activo !== false) { // Verificar expiración de licencia const consultorios = JSON.parse(localStorage.getItem('sistema_consultorios') || '[]'); const consultorio = consultorios.find(c => c.id === usuario.consultorioId); if(consultorio) { const fechaExpiracion = new Date(consultorio.fechaExpiracion); if(new Date() > fechaExpiracion) { alert('⚠️ La licencia de este consultorio ha expirado. Contacte al administrador para renovar.'); return; } } currentUser = usuario; localStorage.setItem('usuarioActual', JSON.stringify(currentUser)); document.getElementById('loginScreen').style.display = 'none'; document.getElementById('appMain').style.display = 'block'; if(typeof buildMenu === 'function') buildMenu(); if(typeof showSection === 'function') showSection('dashboard'); } else { alert('❌ Credenciales incorrectas. Verifique usuario/email/teléfono y contraseña.'); } }; // 4. Agregar campos al formulario de registro en el Panel // Modifica el HTML del panel para incluir selector de plan // ========== PANEL SUPER ADMIN - CÓDIGO COMPLETO ========== (function() { 'use strict'; // Función principal del Panel Super Admin window.renderPanelSuperAdmin = async function(container) { if(!container) { container = document.getElementById('dynamicView'); } // Verificar que sea Super Admin const usuarioActual = JSON.parse(localStorage.getItem('usuarioActual') || '{}'); if(usuarioActual.rol !== 'super_admin') { if(container) container.innerHTML = '
Acceso denegado. No eres Super Administrador.
'; return; } // Obtener datos const consultorios = JSON.parse(localStorage.getItem('sistema_consultorios') || '[]'); const usuarios = JSON.parse(localStorage.getItem('sistema_usuarios') || '[]'); const bitacora = JSON.parse(localStorage.getItem('bitacora_super_admin') || '[]'); // Calcular estadísticas const planes = { BASICO: 199, PROFESIONAL: 399, EMPRESARIAL: 699 }; const ingresosTotales = consultorios.reduce((sum, c) => sum + (planes[c.plan] || 0), 0); if(!container) return; container.innerHTML = `

Panel de Super Administrador

Gestión centralizada de todos los consultorios

👑 ${usuarioActual.nombre}

${consultorios.length}

Consultorios Activos

${usuarios.filter(u => u.rol !== 'super_admin').length}

Usuarios Totales

$${ingresosTotales.toLocaleString()}

Ingresos por Licencias

${bitacora.length}

Eventos Registrados
// Reemplaza el div del formulario por este:
Registrar Nuevo Consultorio (Cliente)
Consultorios Registrados
${consultorios.length === 0 ? '
No hay consultorios registrados
' : consultorios.map(c => { const fechaExp = new Date(c.licencia?.fechaExpiracion || c.fechaExpiracion); const hoy = new Date(); const diasRestantes = Math.ceil((fechaExp - hoy) / (1000 * 60 * 60 * 24)); let estadoClass = 'activo'; let estadoTexto = `Vence en ${diasRestantes} días`; if(diasRestantes < 0) { estadoClass = 'expirado'; estadoTexto = 'EXPIRADO'; } else if(diasRestantes <= 30) { estadoClass = 'por-vencer'; } const admin = usuarios.find(u => u.consultorioId === c.id && u.rol === 'admin_consultorio'); return `
${c.nombre}
${c.email} | ${c.telefono || 'N/A'}
Plan: ${c.plan || 'BASICO'} ${estadoTexto}
ID: ${c.id}
Admin: ${admin?.username || 'No asignado'} | Pass: ${admin?.password || 'admin123'}
Registrado: ${new Date(c.fechaRegistro).toLocaleDateString()}
Expira: ${fechaExp.toLocaleDateString()}
`; }).join('') }
Bitácora de Eventos
${bitacora.length === 0 ? '
No hay eventos registrados
' : bitacora.slice().reverse().slice(0, 30).map(b => `
${b.accion}
${b.consultorioNombre || 'N/A'}
${new Date(b.fecha).toLocaleString()}
${b.detalles || ''}
`).join('') }
`; }; // Función para registrar nuevo consultorio window.registrarNuevoConsultorioPanel = function() { const nombre = document.getElementById('newNombre')?.value.trim(); const email = document.getElementById('newEmail')?.value.trim(); const telefono = document.getElementById('newTelefono')?.value.trim(); if(!nombre || !email) { alert('Complete nombre y email'); return; } const consultorioId = `CONS_${Date.now()}_${Math.random().toString(36).substr(2, 6)}`; const fechaExpiracion = new Date(); fechaExpiracion.setFullYear(fechaExpiracion.getFullYear() + 1); const nuevoConsultorio = { id: consultorioId, nombre: nombre, email: email, telefono: telefono, plan: 'PROFESIONAL', fechaRegistro: new Date().toISOString(), fechaExpiracion: fechaExpiracion.toISOString(), activo: true, licencia: { tipo: 'PROFESIONAL', fechaActivacion: new Date().toISOString(), fechaExpiracion: fechaExpiracion.toISOString(), activa: true } }; // Guardar consultorio let consultorios = JSON.parse(localStorage.getItem('sistema_consultorios') || '[]'); consultorios.push(nuevoConsultorio); localStorage.setItem('sistema_consultorios', JSON.stringify(consultorios)); // Crear usuario Admin const nuevoAdmin = { id: `ADMIN_${consultorioId}`, username: `admin_${consultorioId.substring(0, 8)}`, password: 'admin123', nombre: `Administrador de ${nombre}`, rol: 'admin_consultorio', consultorioId: consultorioId, email: email, telefono: telefono, activo: true, fechaRegistro: new Date().toISOString() }; let usuarios = JSON.parse(localStorage.getItem('sistema_usuarios') || '[]'); usuarios.push(nuevoAdmin); localStorage.setItem('sistema_usuarios', JSON.stringify(usuarios)); // Bitácora let bitacora = JSON.parse(localStorage.getItem('bitacora_super_admin') || '[]'); bitacora.push({ id: Date.now(), fecha: new Date().toISOString(), accion: 'REGISTRO_CONSULTORIO', consultorioId: consultorioId, consultorioNombre: nombre, detalles: `Nuevo consultorio: ${nombre} - Admin: ${nuevoAdmin.username}` }); localStorage.setItem('bitacora_super_admin', JSON.stringify(bitacora)); alert(`✅ Consultorio registrado!\n\nUsuario Admin: ${nuevoAdmin.username}\nContraseña: admin123\nExpira: ${fechaExpiracion.toLocaleDateString()}`); window.renderPanelSuperAdmin(); }; // Renovar licencia window.renovarLicenciaPanel = function(consultorioId) { const nuevoPlan = prompt('Seleccione plan (BASICO, PROFESIONAL, EMPRESARIAL):', 'PROFESIONAL'); if(!nuevoPlan) return; let consultorios = JSON.parse(localStorage.getItem('sistema_consultorios') || '[]'); const index = consultorios.findIndex(c => c.id === consultorioId); if(index !== -1) { const nuevaExpiracion = new Date(); nuevaExpiracion.setFullYear(nuevaExpiracion.getFullYear() + 1); consultorios[index].plan = nuevoPlan; consultorios[index].fechaExpiracion = nuevaExpiracion.toISOString(); consultorios[index].licencia = { tipo: nuevoPlan, fechaActivacion: new Date().toISOString(), fechaExpiracion: nuevaExpiracion.toISOString(), activa: true }; localStorage.setItem('sistema_consultorios', JSON.stringify(consultorios)); let bitacora = JSON.parse(localStorage.getItem('bitacora_super_admin') || '[]'); bitacora.push({ id: Date.now(), fecha: new Date().toISOString(), accion: 'RENOVACION_LICENCIA', consultorioId: consultorioId, consultorioNombre: consultorios[index].nombre, detalles: `Licencia renovada - Plan ${nuevoPlan}` }); localStorage.setItem('bitacora_super_admin', JSON.stringify(bitacora)); alert(`✅ Licencia renovada para ${consultorios[index].nombre}\nNueva expiración: ${nuevaExpiracion.toLocaleDateString()}`); window.renderPanelSuperAdmin(); } }; // Eliminar consultorio window.eliminarConsultorioPanel = function(consultorioId) { if(!confirm('¿Eliminar este consultorio? Se perderán TODOS sus datos.')) return; let consultorios = JSON.parse(localStorage.getItem('sistema_consultorios') || '[]'); const consultorio = consultorios.find(c => c.id === consultorioId); consultorios = consultorios.filter(c => c.id !== consultorioId); localStorage.setItem('sistema_consultorios', JSON.stringify(consultorios)); let usuarios = JSON.parse(localStorage.getItem('sistema_usuarios') || '[]'); usuarios = usuarios.filter(u => u.consultorioId !== consultorioId); localStorage.setItem('sistema_usuarios', JSON.stringify(usuarios)); let bitacora = JSON.parse(localStorage.getItem('bitacora_super_admin') || '[]'); bitacora.push({ id: Date.now(), fecha: new Date().toISOString(), accion: 'ELIMINACION_CONSULTORIO', consultorioId: consultorioId, consultorioNombre: consultorio?.nombre, detalles: `Consultorio eliminado` }); localStorage.setItem('bitacora_super_admin', JSON.stringify(bitacora)); alert('✅ Consultorio eliminado'); window.renderPanelSuperAdmin(); }; console.log('✅ Panel Super Admin cargado'); })(); async function login(username, password) { const response = await fetch('https://crm-siodentalpro-api.workers.dev/api/login', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ username, password }) }); const data = await response.json(); if (data.success) { localStorage.setItem('usuarioActual', JSON.stringify(data.usuario)); localStorage.setItem('consultorio_id', data.usuario.consultorio_id); return true; } return false; }