// ============ AcademIA8 · Consola — Calculadora de costos (C2, client-side) ============ // Sin backend, sin API, sin persistencia: todo el cálculo vive en el navegador. // Las tarifas de referencia se guardan acá arriba para poder actualizarlas sin // tocar la lógica de cálculo más abajo. const COSTOS_CONFIG = { utility: 0.0260, // USD por mensaje de servicio (WhatsApp, tarifa Meta) marketing: 0.0618, // USD por mensaje de marketing/proactivo (recordatorio) kapsoMensual: 25, // USD/mes de referencia del plan Pro de Kapso (hoy: plan Free = 0, editable abajo) }; const COSTOS_DEFAULTS = { alumnos: 50, mensajes: 80, recordatorios: 4, meses: 2, costoLLM: 0.10, impositivo: 35, // % factorSeguridad: 3, margen: 8, postOctubre: false, // recargo de utility de WhatsApp entra en vigencia en octubre 2026 kapsoMensual: COSTOS_CONFIG.kapsoMensual, }; function fmtUSD(n){ return '$' + n.toLocaleString('en-US', { minimumFractionDigits:2, maximumFractionDigits:2 }); } function CostosSlider({ label, value, onChange, min, max, step, suffix, help, tip }){ return (
onChange(Number(e.target.value))} style={{flex:1, accentColor:'var(--magenta)'}} />
{ const v=Number(e.target.value); if(!Number.isNaN(v)) onChange(v); }} style={{width:74, border:'1px solid var(--linea)', borderRadius:9, padding:'8px 9px', fontSize:13.5, fontWeight:700, color:'var(--tinta)', textAlign:'right'}} /> {suffix && {suffix}}
); } function fmtFechaCorte(iso){ try{ return new Date(iso).toLocaleDateString('es-AR', { day:'2-digit', month:'2-digit', year:'numeric' }); } catch(e){ return iso; } } // Línea "Medido: $X.XX promedio por alumno (al [fecha], N alumnos)" + botón "Usar medido". // Si no hay dato para ese campo (JSON inexistente o valor null), no renderiza nada. function MedidoLine({ medido, campo, fmt, onUse }){ if (!medido || medido[campo] == null) return null; return (
Medido: {fmt(medido[campo])} promedio por alumno (al {fmtFechaCorte(medido.fecha_corte)}, {medido.alumnos_con_actividad} alumnos)
); } function CostosResult({ label, value, accent }){ return (
{fmtUSD(value)}
{label}
); } function CostosModule(){ const [alumnos, setAlumnos] = useState(COSTOS_DEFAULTS.alumnos); const [mensajes, setMensajes] = useState(COSTOS_DEFAULTS.mensajes); const [recordatorios, setRecordatorios] = useState(COSTOS_DEFAULTS.recordatorios); const [meses, setMeses] = useState(COSTOS_DEFAULTS.meses); const [costoLLM, setCostoLLM] = useState(COSTOS_DEFAULTS.costoLLM); const [impositivo, setImpositivo] = useState(COSTOS_DEFAULTS.impositivo); const [factorSeguridad, setFactorSeguridad] = useState(COSTOS_DEFAULTS.factorSeguridad); const [margen, setMargen] = useState(COSTOS_DEFAULTS.margen); const [postOctubre, setPostOctubre] = useState(COSTOS_DEFAULTS.postOctubre); const [kapsoMensual, setKapsoMensual] = useState(COSTOS_DEFAULTS.kapsoMensual); const [medido, setMedido] = useState(null); useEffect(()=>{ let cancel = false; fetch('costos-medidos.json', { cache:'no-store' }) .then(r => r.ok ? r.json() : null) .then(data => { if (!cancel) setMedido(data); }) .catch(()=>{ /* sin archivo publicado todavía: comportamiento actual intacto */ }); return ()=>{ cancel = true; }; }, []); const alumnosSeguro = Math.max(1, alumnos); const costoWhatsapp = (postOctubre ? mensajes * COSTOS_CONFIG.utility : 0) + recordatorios * COSTOS_CONFIG.marketing; const variable = (costoWhatsapp + costoLLM) * factorSeguridad; const kapsoProrrateado = (kapsoMensual * meses / alumnosSeguro) * (1 + impositivo/100); const costoTotal = variable + kapsoProrrateado; const precioSugerido = Math.ceil(costoTotal * margen); return (
Consumo y precio

Calculadora de costos

Estimación de costo y precio sugerido por alumno enrolado. Cálculo client-side, no se guarda ni se envía a ningún lado: al recargar la página vuelve a los valores por defecto.
Parámetros
v.toFixed(1)} onUse={()=>setMensajes(Math.round(medido.mensajes_promedio_por_alumno))} /> setCostoLLM(medido.costo_llm_promedio_por_alumno)} />
Tarifas avanzado Precios por mensaje de Meta para Argentina (julio 2026) y plan Pro de Kapso. Actualizar acá si Meta los cambia.
Utility (WhatsApp servicio)
{COSTOS_CONFIG.utility.toFixed(4)} USD/msj
Marketing (WhatsApp proactivo)
{COSTOS_CONFIG.marketing.toFixed(4)} USD/msj
Utility y marketing se editan en el bloque de config al tope de costos.jsx, sin tocar la lógica del cálculo.
Resultado
Precio sugerido / alumno
${precioSugerido}
Desglose
WhatsApp = {postOctubre ? `(${mensajes} × ${COSTOS_CONFIG.utility})` : '(0, pre-octubre)'} + ({recordatorios} × {COSTOS_CONFIG.marketing}) = {fmtUSD(costoWhatsapp)}
Variable = (WhatsApp {fmtUSD(costoWhatsapp)} + LLM {fmtUSD(costoLLM)}) × {factorSeguridad} = {fmtUSD(variable)}
Kapso prorrateado = ({kapsoMensual} × {meses} / {alumnosSeguro}) × (1 + {impositivo}%) = {fmtUSD(kapsoProrrateado)}
Costo total = Variable {fmtUSD(variable)} + Kapso {fmtUSD(kapsoProrrateado)} = {fmtUSD(costoTotal)}
Precio sugerido = ceil(Costo total × {margen}) = ${precioSugerido}
); } Object.assign(window, { CostosModule });