Buenos días
Cargando fecha…
Citas hoy
Firmas pend.
En pipeline
Análisis de Venta
0
Clientes en CRM · Haz clic para abrir
Firmas Pendientes
Ir a Firma Digital
Clientes en Pipeline
Ir a Agenda & Pipeline
Análisis CMA / DSCR
↑ 3 esta semana · Abrir CMA
Actividad Reciente
📋
La actividad aparecerá aquí a medida que uses los módulos
Acceso Rápido
💰
Análisis Venta
Net sheet vendedor
🏠
Análisis Compra
Calificación comprador
📊
CMA Comparables
Análisis IA de mercado
📈
Análisis DSCR
Inversión / renta
Firma Digital
Firmar documentos
🤖
Asistente IA
Redacta y consulta
Post Generator
Instagram · Facebook · MLS
📅
Agenda
Citas y pipeline
💬
WhatsApp
Mensaje en 1 clic
🏷
Ficha de Propiedad
PDF + link compartible
QR de Listing
Escanea → ficha
🗺
Mapa de Precios
Precios por zona PR
Pipeline de Clientes
Agenda de Hoy
Clientes Recientes
📝 Datos
⚡ Escenarios
📄 Reporte
Datos del Cliente
Información Base
Deudas y Obligaciones del Vendedor
Resultado Estimado
Actualiza automáticamente
Calculando…
Precio de Venta $385,000
Comisión (6%) -$23,100
Subtotal después de comisión $361,900

Hipoteca Principal -$210,000
Segunda Hipoteca -$0
HOA + CRIM + Otros -$2,000

Compraventa (1%) -$3,850
Cancelación Hipoteca (1.5%) -$5,775
Retención Hacienda (10%) -$38,500
Sobrante Neto Aproximado
$86,675
📝 Datos
⚡ Escenarios
📄 Reporte
Datos del Comprador
Datos de la Propiedad
Financiamiento
Gastos de Cierre
Análisis de Compra
Actualiza automáticamente
✓ Qualifica
Ingreso Total $11,000
Capacidad de Pago (43% DTI) $4,730

Pronto (20%) $64,000
Monto del Préstamo $256,000
Pago P&I mensual $1,620
HOA mensual $175
Pago Mensual Total $2,395
Margen vs Capacidad +$1,735

Total Gastos de Cierre $8,400
Cash to Close
$72,400
📝 Datos
⚡ Escenarios
📊 Reporte + Gráfica
Tipo de Propiedad a Evaluar
Ingresos de la Propiedad
Gastos Operacionales Anuales
Financiamiento
Resultado DSCR
Análisis de inversión
DSCR Ratio
1.24
✓ Aceptable para préstamo
Ingreso Bruto Anual $30,000
Vacancia -$2,400
Ingreso Efectivo Bruto $27,600
Gastos Operacionales -$9,200
NOI $18,400

Pago Mensual P&I $1,595
Servicio Anual Deuda -$19,140
Cash Flow Anual -$740
Total clientes
0
Nuevos leads
0
En proceso
0
Activos
0
Cerrados
0
Información de contacto
Estado del cliente
Acciones rápidas
Notas del corredor
Historial de actividad
Nuevo Contacto
?
Tu Nombre
Tu Brokerage
Lic. RE-0000
Información profesional
Redes sociales
Estadísticas de tu cuenta
0
Reportes generados
0
Documentos firmados
0
Posts generados
Plan de Suscripción
💡 Reemplaza 6+ herramientas separadas
🚀
Precio Fundadores — Solo 50 corredores
Bloquea tu precio de por vida antes que se acabe el cupo
Quedan
47
Starter
Corredor nuevo — herramientas esenciales
$79/mes
Fundadores: $49/mes
✓ 1 agente  ·  ✓ CRM hasta 100 contactos  ·  ✓ Calculadoras completas
✓ Venta · Compra · DSCR · CMA  ·  ✓ PDF profesional · Presentación al cliente
✓ Ficha + QR + Post Generator IA  ·  ✓ WhatsApp directo  ·  ✓ Firma digital · Vault
✓ Agenda & Pipeline · Recordatorios  ·  ✓ Asistente IA (10 usos/día)
✓ Mercado Divio (publica propiedades)  ·  ✓ Mapa de Precios
MÁS POPULAR
Pro
Corredor activo — opera TODO tu negocio con IA
$159/mes
Fundadores: $99/mes
✓ Todo Starter  ·  ✓ Asistente IA ilimitado  ·  ✓ Chat IA 24/7
✓ Coach de Negociación IA  ·  ✓ Reporte de Mercado IA  ·  ✓ Generador de Contratos IA
✓ Bot WhatsApp IA 24/7  ·  ✓ Comparador de Propiedades  ·  ✓ Analytics avanzado
✓ Mapa de Precios  ·  ✓ Mercado Divio  ·  ✓ CRM ilimitado
✓ Alertas de Compradores Activos  ·  ✓ MLS (próximo)
Team Hasta 3 agentes
Equipos pequeños — $133/agente
$399/mes
Fundadores: $269/mes
✓ 3 agentes incluidos  ·  ✓ Todo Pro  ·  ✓ CRM compartido del equipo
✓ Dashboard del equipo  ·  ✓ Bot WhatsApp compartido  ·  ✓ Soporte prioritario
✓ Reportes por agente  ·  ✓ Gestión de usuarios
Enterprise Para Brokerías
White-label · MLS USA completo · Precio por volumen
desde $120/agente
S — Hasta 15 agentes
$999/mes
$67/agente · Ahorro 55%
M — Hasta 35 agentes
$1,990/mes
$57/agente · Ahorro 62%
L — Hasta 75 agentes
$3,500/mes
$47/agente · Ahorro 68%
XL — 75+ agentes
Cotización
mín. $40/agente · White-label
✓ Todo Team  ·  ✓ White-label (tu marca)  ·  ✓ MLS Grid USA todos los estados
✓ CRM con jerarquías de brokería  ·  ✓ Account manager dedicado
✓ Onboarding personalizado  ·  ✓ Integración con tu website actual
💰 ¿Cuánto ahorras con Divio Pro vs herramientas separadas?
Follow Up Boss CRM: $69–500/mes
Cloud CMA: $99/mes
DocuSign firma: $45/mes
Post generator: $55/mes
WhatsApp bot: $100/mes
MLS tools: $150/mes
Sin Divio: $518–949/mes  ·  Con Divio Pro: $159/mes  ·  ✓ Ahorras hasta $790/mes
Vista previa en reportes
Tu Brokerage
Tu Nombre
CR
Tu Nombre
Esta tarjeta aparece en todos tus reportes de Venta, Compra, DSCR, CMA y Fichas de Propiedad.
Generar Publicación
IA escribe el post por ti
✦ IA
Tipo de Propiedad
Características destacadas
Escribe las cualidades más atractivas — la IA las convierte en copy persuasivo
Plataformas
📸 Instagram
📘 Facebook
🏠 MLS
𝕏 X / Twitter
Tono del mensaje
🤝
Profesional
Formal y confiable
Enérgico
Urgente y emocionante
Aspiracional
Lifestyle y sueños
😊
Amigable
Cercano y humano
💎
Lujo
Premium y exclusivo
📈
Inversión
ROI y números
Idioma
Español
English
Ambos
Generados recientemente
Los posts generados aparecerán aquí
Tu post aparecerá aquí
Llena los datos de la propiedad, selecciona las plataformas y haz clic en Generar. La IA escribe un post optimizado para cada red social.
Análisis Comparativo de Mercado
CMA con inteligencia artificial
✦ IA
Propiedad del cliente
Condición y extras
Parámetros del análisis
Propósito del análisis
El reporte CMA aparecerá aquí
Ingresa los datos de la propiedad y la IA generará comparables del mercado de Puerto Rico, rango de precios recomendado y análisis de tendencias.
12
Clientes activos
3
Cierres este mes
5
Citas esta semana
2
Firmas pendientes
Marzo 2026
Hoy
Selecciona un día para ver eventos
Tareas Pendientes
Pipeline de Clientes
Arrastra las tarjetas entre columnas
Nueva Cita / Evento
Nueva Tarea
Agregar al Pipeline
Accesos Rápidos
✦ IA
Documentos
Emails
Consultas Legales
Análisis
Contexto de la Conversación
🤖
Asistente Divio
Activo
Sugerencias:
Pendientes de firma
3
Firmados este mes
8
En proceso
2
Expirados
1
Documentos para Firma
Todos
Pendientes
Enviados
Firmados
Panel de Firma
Selecciona un documento
✍ Digital
Selecciona un documento de la lista para firmar
Firma aquí
Firma con el mouse o dedo
Arrastra para firmar · Haz clic en Limpiar para borrar
O escribe tu nombre
Acciones Rápidas
Nuevo Documento para Firma
¡Documento Firmado!
El documento ha sido firmado exitosamente.
Datos de la Propiedad
Información principal
Especificaciones
Características destacadas
Contacto del agente
Fotos de la Propiedad
📷
Agregar fotos
Arrastra imágenes aquí o haz clic para buscar
JPG, PNG — hasta 10 fotos
Vista Previa
🏷
La ficha aparecerá aquí
Llena los datos y haz clic en Generar Ficha
Configurar QR
⬛ QR Code
Datos del listing
Link de la ficha generada, MLS, o cualquier URL
Estilo del QR
Usos recomendados
🏠
Flyer impreso
El comprador escanea → ve la ficha completa
🪧
Cartel en la propiedad
QR en el letrero de "Se Vende"
📱
Tarjeta de presentación
QR personal del agente → portafolio
📸
Post de Instagram
QR en la esquina del post → más info
Vista Previa
Configura y genera el QR
Total documentos
0
Contratos
0
Reportes guardados
0
Espacio usado
0 MB
Carpetas
Agregar documento
📁
Subir documento
PDF, Word, imágenes
Todos los documentos
Agregar Documento
📎
Simula subida de archivo
PDF, Word, JPG, PNG (máx. 10MB)
Nueva Carpeta
${['📁','👤','🏠','📄','💰','⚖️','🔑','📸','🗂'].map(ic => `
${ic}
` ).join('')}
Filtros del Mapa
Leyenda de calor
Bajo precioPrecio promedioAlto precio
Los precios son estimados basados en datos históricos y comparables del mercado de Puerto Rico.
Puerto Rico — Mapa de Precios
Actualizado: hoy
Hasta $250K
$250K–$400K
$400K–$600K
$600K+
Precios por Zona
🔍 Buscar Propiedades
📊 Estadísticas del Mercado
Cargando...
📋 Mis Listings
Cargando...
Mercado Divio — Listings Activos
Cargando propiedades...
Cargando listings...
Enviar por WhatsApp
Mensajes profesionales en 1 clic
💬
0 caracteres
Abre WhatsApp con el mensaje listo para enviar
Contactos recientes
Vista previa del mensaje
WhatsApp
El mensaje aparecerá aquí…
✓✓
Envío masivo a lista
Selecciona clientes del CRM para enviar el mismo mensaje a varios
Historial de mensajes
Categorías
Todas las plantillas
Nueva Plantilla
Las variables entre corchetes se reemplazan automáticamente al usar la plantilla
Usar plantilla
Contexto de la negociación
El coach analiza la situación y te da la estrategia
🎯 IA
La propiedad
Tu cliente
Tipo de ayuda que necesitas
🎯
Coach IA de Negociación
Describe la situación y el coach te dirá exactamente qué decir, cómo negociar, cuánto ofrecer y cómo responder a cada objeción del otro lado.
Configurar Reporte
PDF profesional para enviar a clientes
✦ IA
Enviar reporte
📰
Reporte de Mercado IA
La IA genera un reporte profesional del mercado inmobiliario de PR que puedes enviar a tus clientes por WhatsApp o email. Construye autoridad y mantiene tu nombre top-of-mind.
Pregunta sobre…
Preguntas sugeridas
💡
Divio IA
Especialista en bienes raíces PR · Disponible 24/7
Modo:
Enter para enviar · Shift+Enter para nueva línea 0 mensajes
Mi Negocio
Métricas reales de tu actividad en Divio
Actividad por semana
Análisis Firmas
Uso por módulo
Embudo de conversión
Actividad reciente
Metas del mes
Metas del mes
0
Leads este mes
0
Calificados
0
Auto-respuestas
0%
Tasa conversión
Twilio WhatsApp
Sin conectar
🔗 Webhook URL para Twilio
https://tu-backend.railway.app/api/bot/webhook
🤖 Personalidad del Bot
Bot activo 24/7
Responde automáticamente
Flujos Automáticos
🎯 Lead Scoring
Conversaciones
Setup Twilio
Flujos que el bot ejecuta automáticamente
Calculadora de Comisiones
Cuánto ganas en cada transacción
💵
La transacción
Si trabajas con broker, escribe tu % (ej: 70)
Descuentos y gastos
% de la comisión que pagas por el referido
Fotos, anuncios, flyers de esta propiedad
Proyección anual
Escenarios rápidos
Tu ganancia neta en esta transacción
$0
Configura los datos para calcular
Desglose completo
Proyección anual
Distribución de la comisión
Comparador de Propiedades
Compara hasta 3 propiedades lado a lado para ayudar al cliente a decidir
Característica
Análisis IA — ¿Cuál es la mejor opción?
La IA analiza las 3 propiedades y recomienda según el perfil del cliente
Llena los datos de las propiedades y haz clic en "Analizar con IA" para obtener la recomendación
Calculadora de Hipoteca
Pago mensual, amortización y más
🏦
Préstamo
Gastos adicionales
Tipo de préstamo
Comparar tasas
Pago mensual total (PITI)
$0
Solo principal e interés
Puntos clave de amortización
Principal vs Intereses por año
Principal Intereses
Comparación de tasas
Generador de Contratos
Documentos legales con IA para PR
✦ IA
Partes involucradas
La propiedad
Términos principales
Nivel de detalle
⚖️ Para uso orientativo. Siempre revisar con un abogado licenciado en PR antes de firmar.
¿Qué documento necesitas?
Selecciona el tipo de documento arriba para ver una descripción.
Documento generado
📃
El contrato aparecerá aquí
Llena los datos y haz clic en Generar. La IA redacta el documento completo con cláusulas apropiadas para Puerto Rico.
ROI de Inversión
Análisis completo de retorno para PR
💹
La propiedad
Ingresos
Gastos operativos ($/mes)
Apreciación y salida
💹
Configura los datos para analizar el ROI
Análisis completo: cash flow, cap rate, COC return, ROI total y proyección de salida
Presentación al Cliente
Propuesta profesional con IA
✦ IA
Plantillas de éxito
Presentación generada
🎨
La presentación aparecerá aquí
Configura el tipo de presentación y haz clic en Generar. La IA crea una propuesta personalizada lista para usar con el cliente.
Hoy
0
Esta semana
0
Completados
0
Total activos
0
Nuevo recordatorio
Plantillas rápidas
Mis recordatorios
Categorías
Calculadora de Arrendamiento
Renta óptima, rentabilidad y más
🏘
La propiedad
Costos mensuales del propietario
Contrato de arrendamiento
🏘
Configura los datos para calcular la renta
Renta óptima por mercado, desglose de rentabilidad y términos sugeridos del contrato
🌎
Mercado Activo
Selecciona el mercado donde operas
🇵🇷
Puerto Rico
DACO · CRIM · Español
✓ ACTIVO
🇵🇷 Puerto Rico — DACO · Impuesto compraventa 1% · Retención Hacienda · 78 municipios
🤖
Configuración de IA
Requerido para todos los módulos con IA
¿Cómo obtener tu API Key?
1. Ve a console.anthropic.com
2. Crea una cuenta gratuita
3. Ve a "API Keys" → "Create Key"
4. Copia y pega aquí tu key
Apariencia
Modo oscuro
Cambia el tema del sistema
Sidebar colapsado por defecto
Más espacio para el contenido
Animaciones
Transiciones entre páginas
Notificaciones
Recordatorios del día
Aviso al abrir Divio
Vencimientos de contratos
7 días antes
Resumen semanal
Cada lunes por email
Leads del bot WhatsApp
Notificar nuevo lead capturado
Valores por defecto
Integraciones
💬
WhatsApp Business API
Para el bot automático
Sin configurar
📅
Google Calendar
Sincronizar citas
Sin configurar
🏠
MLS Puerto Rico
Importar listings
Próximamente
💳
Stripe / Pagos
Procesar suscripciones
Próximamente
Mis datos
Plan activo
Plan actual
Pro — $159/mes
✓ Módulos ilimitados · ✓ IA incluida · ✓ 50 reportes PDF/mes · ✓ Soporte prioritario
Acerca de Divio
Divio — El sistema de bienes raíces más completo para corredores de Puerto Rico.
Versión 2.0 · Puerto Rico · 2026
32 módulos · Potenciado por Claude IA (Anthropic)
📊 Mi Progreso
✅ Cursos completados
🔍 Buscar cursos PR
🔔 Recordatorios de licencia
Créditos del período actual
Período de renovación activo
0
de 24
créditos
Cursos completados este período
🪪
Tipo de licencia Corredor (Broker)
Fecha de vencimiento 30 jun 2026
Créditos requeridos 24 créditos
Créditos completados 0 créditos
Agregar curso rápido
Requisitos DACO / PRREA 2025-2026
Corredores: 24 créditos cada 2 años
Vendedores: 21 créditos cada 2 años
Mínimo 3 créditos de ética profesional
// ======================== // DIVIO LISTINGS DATABASE // ======================== // Shared listing pool — all Divio agents contribute and benefit let divioListings = []; // in-memory cache let listingsLoaded = false; // Fetch all public listings from backend async function fetchDivioListings(filters = {}) { const token = getAuthToken(); const params = new URLSearchParams(); if(filters.municipio) params.set('municipio', filters.municipio); if(filters.tipo) params.set('tipo', filters.tipo); if(filters.proposito) params.set('proposito', filters.proposito); if(filters.precioMin) params.set('precioMin', filters.precioMin); if(filters.precioMax) params.set('precioMax', filters.precioMax); if(filters.market) params.set('market', filters.market || MARKET?.id || 'PR'); try { const url = `${BACKEND_URL}/api/listings/public?${params}`; const r = await fetch(url, { headers: backendHeaders() }); if(!r.ok) return []; const d = await r.json(); divioListings = d.listings || []; listingsLoaded = true; return divioListings; } catch(err) { console.warn('Listings fetch failed (offline mode):', err.message); return []; } } // Publish a listing from Ficha de Propiedad to the shared database async function publicarListingDivio() { const token = getAuthToken(); const data = { direccion: document.getElementById('fi-dir')?.value || '', municipio: document.getElementById('fi-municipio')?.value || '', tipo: document.getElementById('fi-tipo')?.value || '', proposito: document.getElementById('fi-proposito')?.value || 'venta', precio: getVal('fi-precio'), habitaciones: parseInt(document.getElementById('fi-hab')?.value) || 0, banos: parseFloat(document.getElementById('fi-ban')?.value) || 0, area: parseFloat(document.getElementById('fi-area')?.value) || 0, year_construccion: parseInt(document.getElementById('fi-year')?.value) || null, hoa: getVal('fi-hoa') || null, descripcion: document.getElementById('fi-desc')?.value || '', caracteristicas: [...fichaFeaturesSelected], fotos: fichaPhotos.slice(0, 5), // max 5 photos to keep payload small market: MARKET?.id || 'PR', }; if(!data.direccion || !data.precio) { alert('Necesitas al menos la dirección y el precio para publicar.'); return; } const btn = document.getElementById('btn-publicar-divio'); if(btn) { btn.disabled = true; btn.textContent = '⏳ Publicando...'; } try { if(!token) { // Local mode — save to localStorage pool const local = JSON.parse(localStorage.getItem('divio_local_listings') || '[]'); local.unshift({ ...data, id: 'local-' + Date.now(), createdAt: new Date().toISOString(), agentName: document.getElementById('p-nombre')?.value || 'Agente' }); localStorage.setItem('divio_local_listings', JSON.stringify(local.slice(0, 100))); showPublishSuccess(data); return; } const r = await fetch(`${BACKEND_URL}/api/listings`, { method: 'POST', headers: backendHeaders(), body: JSON.stringify(data), }); const d = await r.json(); if(!r.ok) throw new Error(d.error || 'Error al publicar'); showPublishSuccess(data); // Refresh map if on mapa page if(document.getElementById('page-mapa')?.classList.contains('active')) { loadListingsOnMap(); } } catch(err) { alert('Error al publicar: ' + err.message); } finally { if(btn) { btn.disabled = false; btn.textContent = '🌐 Publicar en Divio'; } } } function showPublishSuccess(data) { const precio = fmt(data.precio); alert(`✅ ¡Listing publicado exitosamente!\n\n📍 ${data.direccion}\n💰 ${precio}\n🏠 ${data.tipo}\n\nAhora aparece en el mapa de todos los corredores de Divio.\nOtros corredores lo pueden ver para comparables y CMA.`); } // Load listings as markers on the map async function loadListingsOnMap() { if(!divioMap) return; const listings = await fetchDivioListings({ market: MARKET?.id || 'PR' }); // Also load from localStorage if no backend const local = JSON.parse(localStorage.getItem('divio_local_listings') || '[]'); const all = [...listings, ...local]; if(all.length === 0) return; // Add listing markers (different style from price avg markers) all.forEach(l => { const coords = MUNI_COORDS[l.municipio]; if(!coords) return; // Offset slightly so they don't stack on the avg price bubble const lat = coords[0] + (Math.random() - 0.5) * 0.02; const lng = coords[1] + (Math.random() - 0.5) * 0.02; const tipo = l.proposito === 'alquiler' ? '🔑' : '🏠'; const precio = '$' + Math.round(l.precio/1000) + 'K'; const icon = L.divIcon({ className: '', html: `
${tipo} ${precio}
`, iconAnchor: [28, 14], }); const hab = l.habitaciones ? `${l.habitaciones}h ` : ''; const ban = l.banos ? `${l.banos}b ` : ''; const area = l.area ? `${l.area} pie² ` : ''; L.marker([lat, lng], { icon }) .addTo(divioMap) .bindPopup(`
${l.direccion || l.municipio}
$${l.precio?.toLocaleString()}
${hab}${ban}${area}${l.tipo || ''}
${l.descripcion ? `
${l.descripcion.slice(0,100)}${l.descripcion.length>100?'...':''}
` : ''}
📋 Por: ${l.agentName || 'Corredor Divio'}
`, { maxWidth: 280 }); }); // Update the update label const lbl = document.getElementById('mapa-update-label'); if(lbl) lbl.textContent = `${all.length} listings activos`; } function verListingDivio(id) { // Navigate to listings browser or show full detail showPage('ficha'); } // ── GET LISTINGS FOR CMA / COMPARABLES ────────────────────────────────────── // Used by CMA module to get real comparables async function getComparableListings(municipio, tipo, precioRef) { await fetchDivioListings({ municipio, tipo, market: MARKET?.id || 'PR' }); const local = JSON.parse(localStorage.getItem('divio_local_listings') || '[]'); const all = [...divioListings, ...local]; return all .filter(l => { const priceDiff = Math.abs(l.precio - precioRef) / precioRef; return priceDiff < 0.35; // within 35% of reference price }) .slice(0, 6); // max 6 comparables } // ── LISTINGS BROWSER (search all Divio listings) ───────────────────────────── let listingsBrowserPage = 1; let listingsBrowserFilters = {}; async function initListingsBrowser() { await fetchDivioListings({ market: MARKET?.id || 'PR' }); renderListingsBrowser(); } function renderListingsBrowser() { const local = JSON.parse(localStorage.getItem('divio_local_listings') || '[]'); const all = [...divioListings, ...local]; const container= document.getElementById('listings-browser-grid'); if(!container) return; if(all.length === 0) { container.innerHTML = `
🏠
Aún no hay listings publicados
Sé el primero — crea una Ficha de Propiedad y publícala en Divio
`; return; } container.innerHTML = all.map(l => `
${l.fotos && l.fotos[0] ? `` : `
🏠
` }
${l.proposito === 'alquiler' ? 'Alquiler' : 'Venta'}
${(()=>{const s=getStatusConfig(l);return l.status&&l.status!=='activo'&&l.status!=='alquiler_activo'?`
${s.label}
`:''})()}
${(()=>{const s=getStatusConfig(l);return (l.status==='vendido'||l.status==='alquilado')?`
✓ ${s.label.toUpperCase()}
`:''})()} ${l.fotos && l.fotos.length > 1 ? `
+${l.fotos.length-1} fotos
` : ''}
$${l.precio?.toLocaleString()}
${l.tipo || 'Propiedad'} — ${l.municipio}
${l.direccion || ''}
${l.habitaciones ? `🛏 ${l.habitaciones}` : ''} ${l.banos ? `🚿 ${l.banos}` : ''} ${l.area ? `📐 ${l.area} pie²` : ''}
📋 ${l.agentName || 'Corredor Divio'}
${(l.status==='vendido'||l.status==='alquilado') ? `✓ ${getStatusConfig(l).label}` : `` }
`).join(''); // Update count const count = document.getElementById('listings-count'); if(count) count.textContent = `${all.length} propiedades activas`; } function contactarAgenteListing(tel) { if(!tel) { alert('Contacta al agente a través del sistema de mensajes.'); return; } window.open(`https://wa.me/${tel.replace(/\D/g,'')}`, '_blank'); } function filterListings() { const muni = document.getElementById('lb-municipio')?.value || ''; const tipo = document.getElementById('lb-tipo')?.value || ''; const pmax = getVal('lb-precio-max') || 0; const pmin = getVal('lb-precio-min') || 0; const local = JSON.parse(localStorage.getItem('divio_local_listings') || '[]'); const all = [...divioListings, ...local]; const filtered = all.filter(l => { if(muni && l.municipio !== muni) return false; if(tipo && l.tipo !== tipo) return false; if(pmax && l.precio > pmax) return false; if(pmin && l.precio < pmin) return false; return true; }); divioListings = filtered; renderListingsBrowser(); divioListings = [...JSON.parse(localStorage.getItem('divio_local_listings') || '[]')]; } const BACKEND_URL = window.DIVIO_BACKEND || 'http://localhost:3000'; // ======================== // BILLING / UPGRADE // ======================== const PLAN_PRICES = { starter: { monthly: 79, founder: 49, name: 'Starter', agents: 1 }, pro: { monthly: 159, founder: 99, name: 'Pro', agents: 1 }, team: { monthly: 399, founder: 269, name: 'Team', agents: 3 }, enterprise_s: { monthly: 999, founder: null, name: 'Enterprise S', agents: 15 }, enterprise_m: { monthly: 1990, founder: null, name: 'Enterprise M', agents: 35 }, enterprise_l: { monthly: 3500, founder: null, name: 'Enterprise L', agents: 75 }, }; async function handleUpgrade(plan) { const token = getAuthToken(); if(!token) { // Not logged in — show login first showAuthScreen(); return; } try { const r = await fetch(BACKEND_URL + '/api/billing/checkout', { method: 'POST', headers: backendHeaders(), body: JSON.stringify({ plan }), }); const d = await r.json(); if(d.url) { window.open(d.url, '_blank'); } else { alert('Error al procesar el pago. Intenta de nuevo.'); } } catch(err) { // Local mode — show info const price = PLAN_PRICES[plan]; alert(`Plan ${price.name} — $${price.monthly}/mes\n\nPara suscribirte necesitas que el backend esté activo.\nContacta: [email protected]`); } } function handleEnterpriseContact() { const msg = encodeURIComponent('Hola, soy corredor/bróker y me interesa el plan Enterprise de Divio para mi brokería. ¿Pueden contactarme para una demo?'); window.open('https://wa.me/17875550000?text=' + msg, '_blank'); } // Listing status config const LISTING_STATUS = { activo: { label: 'Activo', color: '#059669', bg: 'rgba(5,150,105,0.12)', icon: '🟢' }, opcionado: { label: 'Opcionado', color: '#d97706', bg: 'rgba(217,119,6,0.12)', icon: '🟡' }, vendido: { label: 'Vendido', color: '#6b7280', bg: 'rgba(107,114,128,0.12)',icon: '⚫' }, alquiler_activo:{ label: 'Disponible', color: '#059669', bg: 'rgba(5,150,105,0.12)', icon: '🟢' }, alquilado: { label: 'Alquilado', color: '#6b7280', bg: 'rgba(107,114,128,0.12)',icon: '⚫' }, }; function getStatusConfig(listing) { if(listing.status) return LISTING_STATUS[listing.status] || LISTING_STATUS.activo; if(listing.proposito === 'alquiler') return LISTING_STATUS.alquiler_activo; return LISTING_STATUS.activo; } // Update listing status (owner only) async function updateListingStatus(listingId, newStatus) { // Update locally const local = JSON.parse(localStorage.getItem('divio_local_listings') || '[]'); const updated = local.map(l => l.id === listingId ? {...l, status: newStatus, updatedAt: new Date().toISOString()} : l); localStorage.setItem('divio_local_listings', JSON.stringify(updated)); // Update in backend if connected const token = getAuthToken(); if(token) { try { await fetch(`${BACKEND_URL}/api/listings/${listingId}/status`, { method: 'PATCH', headers: backendHeaders(), body: JSON.stringify({ status: newStatus }), }); } catch(e) {} } // Re-render renderListingsBrowser(); renderMisListings(); } function handleBillingPortal() { const token = getAuthToken(); if(!token) { showAuthScreen(); return; } fetch(BACKEND_URL + '/api/billing/portal', { method: 'POST', headers: backendHeaders() }).then(r => r.json()).then(d => { if(d.url) window.open(d.url, '_blank'); }).catch(() => { alert('Portal de facturación no disponible en modo local.'); }); } function getAuthToken() { return localStorage.getItem('divio_token') || ''; } function setAuthToken(t) { t ? localStorage.setItem('divio_token', t) : localStorage.removeItem('divio_token'); } function getAgentData() { const r = localStorage.getItem('divio_agent'); return r ? JSON.parse(r) : null; } function setAgentData(a) { a ? localStorage.setItem('divio_agent', JSON.stringify(a)) : localStorage.removeItem('divio_agent'); } function backendHeaders() { const t=getAuthToken(); return {'Content-Type':'application/json',...(t?{'Authorization':'Bearer '+t}:{})}; } function isAuthenticated() { return !!getAuthToken(); } async function callBackendAI({module:mod,messages,systemContext,maxTokens=1500}) { const token=getAuthToken(); if(!token) { const key=getApiKey(); if(!key){requireApiKey();throw new Error('No API key');} const sysStr = systemContext ? (typeof systemContext==='string' ? systemContext : JSON.stringify(systemContext)) : null; const body = {model:'claude-haiku-4-5',max_tokens:maxTokens,messages:messages}; if(sysStr) body.system = sysStr; const r=await fetch('https://api.anthropic.com/v1/messages',{method:'POST',headers:{'Content-Type':'application/json','x-api-key':key,'anthropic-version':'2023-06-01','anthropic-dangerous-direct-browser-access':'true'},body:JSON.stringify(body)}); const d=await r.json(); if(!r.ok) throw new Error(d.error?.message||'AI error'); return d.content?.map(b=>b.text||'').join('')||''; } const r=await fetch(BACKEND_URL+'/api/ai/generate',{method:'POST',headers:backendHeaders(),body:JSON.stringify({module:mod,messages,systemContext,maxTokens})}); if(r.status===401){logout();throw new Error('Session expired');} if(r.status===403){const d=await r.json();throw new Error(d.error||'Plan upgrade required');} const d=await r.json(); if(!r.ok) throw new Error(d.error||'AI failed'); return d.text||''; } async function loginAgent(email,password) { const r=await fetch(BACKEND_URL+'/api/auth/login',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({email,password})}); const d=await r.json(); if(!r.ok) throw new Error(d.error||'Login failed'); setAuthToken(d.token); setAgentData(d.agent); return d.agent; } async function registerAgent(fields) { const r=await fetch(BACKEND_URL+'/api/auth/register',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify(fields)}); const d=await r.json(); if(!r.ok) throw new Error(d.error||'Registration failed'); setAuthToken(d.token); setAgentData(d.agent); return d.agent; } function logout() { setAuthToken(null); setAgentData(null); showAuthScreen(); } function populateProfileFromBackend() { const a=getAgentData(); if(!a) return; [['p-nombre',a.nombre||''],['p-email',a.email||''],['p-tel',a.telefono||''],['p-licencia',a.licencia||''],['p-comercial',a.comercial||'']].forEach(([id,v])=>{const el=document.getElementById(id);if(el)el.value=v;}); const sn=document.getElementById('sidebar-name'); if(sn) sn.textContent=a.nombre||'Tu Nombre'; const sl=document.getElementById('sidebar-lic'); if(sl) sl.textContent=a.licencia||'Lic. --'; const sa=document.getElementById('sidebar-avatar'); if(sa) sa.textContent=(a.nombre||'A')[0].toUpperCase(); if(a.market&&MARKETS[a.market]) setMarket(a.market); } function showAuthScreen() { const overlay = document.getElementById('auth-overlay'); const app = document.getElementById('app'); if(overlay) overlay.style.display='flex'; if(app) app.style.display='none'; } function hideAuthScreen() { const overlay = document.getElementById('auth-overlay'); const app = document.getElementById('app'); if(overlay) overlay.style.display='none'; if(app) app.style.display='flex'; } function continueWithoutAccount() { hideAuthScreen(); showPage('dashboard'); } function switchAuthTab(tab) { const lt=document.getElementById('auth-login-tab'),rt=document.getElementById('auth-reg-tab'); const lf=document.getElementById('auth-login-form'),rf=document.getElementById('auth-reg-form'); if(tab==='login'){lt.style.borderBottom='2px solid var(--accent)';lt.style.color='var(--accent)';rt.style.borderBottom='2px solid transparent';rt.style.color='var(--text3)';lf.style.display='';rf.style.display='none';} else{rt.style.borderBottom='2px solid var(--accent)';rt.style.color='var(--accent)';lt.style.borderBottom='2px solid transparent';lt.style.color='var(--text3)';lf.style.display='none';rf.style.display='';} } async function handleLogin(e) { if(e)e.preventDefault(); const email=document.getElementById('auth-email').value.trim(); const password=document.getElementById('auth-password').value; const btn=document.getElementById('auth-submit-btn'); const err=document.getElementById('auth-error'); if(!email||!password){err.textContent='Email y contraseña requeridos';return;} btn.disabled=true; btn.textContent='Entrando...'; err.textContent=''; try{await loginAgent(email,password);hideAuthScreen();populateProfileFromBackend();showPage('dashboard');} catch(ex){err.textContent=ex.message;} finally{btn.disabled=false;btn.textContent='Entrar';} } async function handleRegister(e) { if(e)e.preventDefault(); const nombre=document.getElementById('reg-nombre').value.trim(); const email=document.getElementById('reg-email').value.trim(); const password=document.getElementById('reg-password').value; const licencia=document.getElementById('reg-licencia').value.trim(); const market=document.getElementById('reg-market').value; const btn=document.getElementById('reg-submit-btn'); const err=document.getElementById('reg-error'); if(!email||!password||!nombre){err.textContent='Nombre, email y contraseña son requeridos';return;} if(password.length<8){err.textContent='Contraseña debe tener al menos 8 caracteres';return;} btn.disabled=true; btn.textContent='Creando cuenta...'; err.textContent=''; try{await registerAgent({nombre,email,password,licencia,market});hideAuthScreen();populateProfileFromBackend();showPage('dashboard');} catch(ex){err.textContent=ex.message;} finally{btn.disabled=false;btn.textContent='Crear Cuenta';} } // ======================== // MARKET CONFIGURATION SYSTEM // ======================== // To add a new market: copy one market object, adjust values, add to MARKETS const MARKETS = { PR: { id: 'PR', name: 'Puerto Rico', flag: '🇵🇷', langs: ['es', 'en'], defaultLang: 'es', currency: 'USD', currencySymbol: '$', areaUnit: 'pie²', // USA uses sqft label too but labeled differently areaUnitLabel: 'pie cuadrado', // Geography mapCenter: { lat: 18.2208, lng: -66.5901 }, mapZoom: 10, geoLabel: 'Municipio', geoLabelPlural: 'Municipios', stateLabel: null, // PR has no states/counties zipLabel: 'Código postal', // Regulatory regulatoryBody: 'DACO', licenseLabel: 'Lic. DACO', licenseFormat: 'RE-XXXX', licenseUrl: 'https://www.daco.pr.gov', mls: 'MLS Puerto Rico', disclosure: 'PR', // which disclosure template to use notaryRequired: true, // PR requires notario for deed deedName: 'Escritura', agencyName: 'Agencia de licencias - DACO', // Taxes & closing costs taxes: { propertyTaxAgency: 'CRIM', propertyTaxRate: 0.0083, // ~0.83% avg transferTaxRate: 0.01, // 1% compraventa cancelationTaxRate: 0.015, // 1.5% cancelación de hipoteca withholdingRates: [0, 0.10, 0.15, 0.20], // Hacienda retencion defaultWithholding: 0.10, salesTax: 0.115, // IVU 11.5% hasCapGains: true, capGainsExemption: 'primary', // primary residence exemption }, // Loans loans: { types: [ { value: '0.035', label: 'FHA (3.5%)', mip: 0.0085, available: true }, { value: '0.05', label: 'Convencional (5%)', pmi: 0.008, available: true }, { value: '0.10', label: 'Convencional (10%)',pmi: 0.005, available: true }, { value: '0.20', label: 'Convencional (20%)',pmi: 0, available: true }, { value: '0', label: 'VA (0%)', pmi: 0, available: true }, { value: '0', label: 'USDA (0%)', pmi: 0.0035, available: true }, { value: 'custom',label: 'Custom', pmi: 0, available: true }, ], defaultRate: 0.0725, // 7.25% default defaultTerm: 30, terms: [15, 20, 30], dtiLimit: 0.43, // 43% DTI max dtiWarning: 0.36, // warning at 36% fhaLoanLimit: 498257, // 2024 FHA limit PR conventionalLimit: 766550, vaLimit: null, // VA has no limit }, // Commissions commissions: { defaultRate: 0.06, // 6% standard options: [0.04, 0.05, 0.06, 0.07, 0.08], buyerAgentSplit: false, // PR: listing agent gets full commission negotiable: true, }, // DSCR Investment dscr: { minRatio: 1.25, goodRatio: 1.35, excellentRatio: 1.5, vacancyDefault: 0.08, // 8% default vacancy defaultCapRate: 0.07, }, // UI Labels (Spanish PR) labels: { propertyTax: 'CRIM', closingCosts: 'Gastos de cierre', earnestMoney: 'Depósito de buena fe', downPayment: 'Pronto', loanAmount: 'Monto del préstamo', netProceeds: 'Neto al vendedor', hoaFee: 'HOA mensual', insurance: 'Seguro del hogar', appraisal: 'Tasación', inspection: 'Inspección', titleSearch: 'Búsqueda de título', notaryFee: 'Honorarios notariales', deed: 'Escritura de compraventa', sellerLabel: 'Vendedor', buyerLabel: 'Comprador', agentLabel: 'Corredor', brokerLabel: 'Bróker', listingLabel: 'Listado', offerLabel: 'Oferta', closingLabel: 'Cierre', contractLabel: 'Contrato', dueDiligence: 'Debida diligencia', escrow: 'Depósito en garantía', }, // Property types propertyTypes: [ 'Casa residencial', 'Apartamento', 'Townhouse', 'Villa', 'Condominio', 'Terreno', 'Local comercial', 'Edificio', 'Propiedad de inversión', 'Casa vacacional', ], // Arrendamiento multipliers by zone (rent index vs base) rentMultipliers: { 'San Juan': 1.18, 'Guaynabo': 1.15, 'Dorado': 1.22, 'Bayamón': 1.08, 'Carolina': 1.12, 'Caguas': 1.06, 'Ponce': 1.00, 'Arecibo': 0.95, 'Aguadilla': 0.98, 'Mayagüez': 1.02, 'Humacao': 1.04, 'Fajardo': 1.08, }, // AI system prompt additions aiContext: `Especialista en bienes raíces de Puerto Rico. Conoce las leyes locales: DACO, ARPE, CRIM, Hacienda PR, notarías. El proceso de cierre en PR requiere escritura ante notario. Los impuestos incluyen: compraventa (1%), cancelación hipoteca (1.5%), CRIM. La retención de Hacienda aplica según el caso (0%, 10%, 15%, 20%). Responde en español de Puerto Rico a menos que el usuario escriba en inglés.`, }, }; // Active market - loaded from localStorage or default to PR let MARKET = MARKETS[localStorage.getItem('divio_market') || 'PR']; function setMarket(marketId) { if(!MARKETS[marketId]) return; MARKET = MARKETS[marketId]; localStorage.setItem('divio_market', marketId); // Reload the app with the new market applyMarket(); } function applyMarket() { // Update document title document.title = `Divio — ${MARKET.name}`; // Update loan type dropdowns const loanSelects = document.querySelectorAll('#c-prestamo, #hip-tipo-prestamo'); loanSelects.forEach(sel => { if(!sel) return; const currentVal = sel.value; sel.innerHTML = MARKET.loans.types .map(t => ``) .join('') + ''; sel.value = currentVal; }); // Update withholding rates (PR only) const retSel = document.getElementById('v-retencion'); if(retSel) { if(MARKET.taxes.withholdingRates.length > 0) { retSel.parentElement.style.display = ''; retSel.innerHTML = MARKET.taxes.withholdingRates .map(r => ``) .join('') + ''; } else { retSel.parentElement.style.display = 'none'; // Hide for markets without withholding } } // Update property type dropdowns const typeSelects = document.querySelectorAll('#fi-tipo, #pg-tipo, #cma-tipo'); typeSelects.forEach(sel => { if(!sel) return; sel.innerHTML = MARKET.propertyTypes .map(t => ``) .join(''); }); // Update geo label placeholders document.querySelectorAll('[data-geo-label]').forEach(el => { el.textContent = MARKET.labels[el.dataset.geoLabel] || el.textContent; }); // Update commission default const comSel = document.getElementById('v-comision'); if(comSel) { comSel.innerHTML = MARKET.commissions.options .map(r => ``) .join('') + ''; } // Recalculate with new market values if(typeof calcVenta === 'function') calcVenta(); if(typeof calcCompra === 'function') calcCompra(); if(typeof calcDSCR === 'function') calcDSCR(); if(typeof calcHipoteca === 'function') calcHipoteca(); if(typeof calcROI === 'function') calcROI(); updateMarketSelectorUI(); MAPA_DATA = getMarketData(); console.log('Divio market set to:', MARKET.id, MARKET.name); } // ======================== // API KEY MANAGEMENT // ======================== function getApiKey() { return localStorage.getItem('divio_api_key') || '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'; } function saveApiKey() { const key = document.getElementById('cfg-api-key')?.value.trim() || ''; if(key) { localStorage.setItem('divio_api_key', key); showApiStatus('✅ API Key guardada', 'var(--green)'); } else { localStorage.removeItem('divio_api_key'); showApiStatus('', ''); } } function showApiStatus(msg, color) { const el = document.getElementById('cfg-api-status'); if(el) { el.textContent = msg; el.style.color = color; } } function toggleApiKeyVisibility() { const inp = document.getElementById('cfg-api-key'); const btn = document.getElementById('cfg-api-toggle'); if(!inp) return; if(inp.type === 'password') { inp.type = 'text'; if(btn) btn.textContent = '🙈 Ocultar'; } else { inp.type = 'password'; if(btn) btn.textContent = '👁 Ver'; } } async async function testApiKey() { const key = getApiKey(); if(!key) { showApiStatus('⚠ Ingresa tu API Key primero', 'var(--gold)'); return; } showApiStatus('⏳ Probando conexión...', 'var(--accent)'); try { const res = await fetch('https://api.anthropic.com/v1/messages', { method: 'POST', headers: { 'Content-Type': 'application/json', 'x-api-key': key, 'anthropic-version': '2023-06-01', 'anthropic-dangerous-direct-browser-access': 'true' }, body: JSON.stringify({ model: 'claude-sonnet-4-20250514', max_tokens: 10, messages: [{ role: 'user', content: 'Di solo: OK' }] }) }); const data = await res.json(); if(data.content?.[0]?.text) { showApiStatus('✅ ¡Conexión exitosa! La IA está lista.', 'var(--green)'); } else if(data.error) { showApiStatus('❌ Error: ' + data.error.message, 'var(--red)'); } } catch(err) { showApiStatus('❌ Error de conexión: ' + err.message, 'var(--red)'); } } function requireApiKey() { const key = getApiKey(); if(!key) { alert('⚠ Configura tu API Key de Anthropic en Configuración → IA para usar esta función.\n\nVe a console.anthropic.com para obtener tu key gratuita.'); showPage('configuracion'); return null; } return key; } // Build standard Anthropic API headers function apiHeaders() { const key = getApiKey(); return { 'Content-Type': 'application/json', 'x-api-key': key, 'anthropic-version': '2023-06-01', 'anthropic-dangerous-direct-browser-access': 'true' }; } function initConfiguracion() { // Load saved API key const saved = getApiKey(); const inp = document.getElementById('cfg-api-key'); if(inp && saved) { inp.value = saved; showApiStatus('✅ API Key configurada', 'var(--green)'); } // Update market selector UI updateMarketSelectorUI(); } const pageTitles = { dashboard:'Dashboard', venta:'Módulo de Venta', compra:'Módulo de Compra', dscr:'Módulo DSCR', cma:'Comparables CMA', agenda:'Agenda & Pipeline', crm:'CRM — Clientes y Leads', posts:'Post Generator IA', asistente:'Asistente IA', firma:'Firma Digital', ficha:'Ficha de Propiedad', qr:'QR de Listing', vault:'Vault de Documentos', mapa:'Mapa de Precios', whatsapp:'WhatsApp Directo', plantillas:'Plantillas', valuacion:'Valuación IA de Propiedades', coach:'Coach IA de Negociación', reportemercado:'Reporte de Mercado IA', chatia:'Chat IA — Tu asistente de todo', analytics:'Analytics — Mi Negocio', botwa:'Bot WhatsApp IA', comisiones:'Comisiones', comparador:'Comparador', hipoteca:'Hipoteca', contratos:'Generador de Contratos IA', roi:'ROI de Inversión', presentacion:'Presentación al Cliente', recordatorios:'Recordatorios', educacion:'Centro Educativo', arrendamiento:'Arrendamiento', configuracion:'Configuración del Sistema', educacion_continua:'Educación Continua PR', perfil:'Perfil del Agente' };