// ============ 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 (
);
}
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 (
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.