🍪
Usamos cookies para mejorar tu experiencia, analizar el tráfico y guardar tus seguidos.
'),
fetch('./footer.html').then(r=>r.text()).catch(()=>'')
]);
document.querySelector('header').innerHTML = h;
document.querySelector('footer').innerHTML = f;
document.dispatchEvent(new CustomEvent('layout:ready'));
}
injectLayout();
const key='favorites';
const list = document.getElementById('listaFavs');
const tpl = document.getElementById('tplFav');
const btnCmp = document.getElementById('btnComparar');
const selAll = document.getElementById('selAll');
const toastWrap = document.getElementById('toast_t9x4y');
const cmpDialog = document.getElementById('modalComparar');
const cmpWrap = document.getElementById('cmpWrap');
const cmpDelta = document.getElementById('cmpDelta');
const cmpTimer = document.getElementById('cmpTimer');
let timerInt = null;
let data = [];
let consent = localStorage.getItem('consent');
function showToast(msg, type='info'){
const id = 't_'+Math.random().toString(36).slice(2,8);
const base = document.createElement('div');
base.id=id;
const colors = type==='error'
? 'bg-red-600 text-white'
: type==='success'
? 'bg-emerald-600 text-white'
: 'bg-gray-900 text-white dark:bg-white dark:text-gray-900';
base.className = 'rounded-md px-3 py-2 text-sm shadow '+colors;
base.textContent = msg;
toastWrap.appendChild(base);
setTimeout(()=>{ base.classList.add('opacity-0','transition'); }, 3000);
setTimeout(()=>{ base.remove(); }, 3500);
return id;
}
function fmtARS(n){
try{ return n.toLocaleString('es-AR', { style:'currency', currency:'ARS', maximumFractionDigits:0 }); }
catch(e){ return 'ARS $ '+Number(n||0).toFixed(0); }
}
async function load(){
try{
const res = await fetch('./catalog.json', { cache:'no-store' });
if(!res.ok) throw new Error('No se pudo cargar el catálogo');
data = await res.json();
render();
}catch(e){
showToast('Error al cargar datos: '+(e.message||'desconocido'), 'error');
list.innerHTML = '';
const empty = document.createElement('li');
empty.className = 'col-span-full border-2 border-dashed rounded-xl p-8 text-center text-gray-600 dark:text-gray-300';
empty.textContent = 'No se pudo cargar el catálogo. Reintentá en unos minutos.';
list.appendChild(empty);
}
}
function getFavs(){
try{
const arr = JSON.parse(localStorage.getItem(key)||'[]');
return Array.isArray(arr) ? arr : [];
}catch(e){ return []; }
}
function setFavs(setOrArr){
const arr = Array.isArray(setOrArr) ? setOrArr : [...setOrArr];
localStorage.setItem(key, JSON.stringify(arr));
}
function render(){
const favs = new Set(getFavs());
const arr = data.filter(d=>favs.has(d.id));
list.innerHTML='';
if(arr.length===0){
const empty = document.createElement('li');
empty.className = 'col-span-full border-2 border-dashed rounded-xl p-8 text-center text-gray-600 dark:text-gray-300';
empty.innerHTML = 'Todavía no seguís ningún curso. Volvé al catálogo y marcá algunos como favoritos ⭐';
list.appendChild(empty);
btnCmp.disabled = true;
btnCmp.textContent = 'Comparar (0)';
selAll.checked = false;
return;
}
arr.forEach(c=>{
const li = tpl.content.cloneNode(true);
const root = li.querySelector('li');
root.dataset.id = c.id;
root.dataset.price = c.priceARS || 0;
li.querySelector('h3').textContent = c.title;
const img = li.querySelector('img'); img.src=c.image; img.alt=c.title;
li.querySelector('p').textContent = c.shortDescription || '';
const priceRow = li.querySelector('.priceRow');
priceRow.textContent = c.priceARS ? fmtARS(c.priceARS) : 'Consultar precio';
const meta = li.querySelector('.metaRow');
meta.textContent = [c.level,c.format,(c.durationHours?c.durationHours+' h': '')].filter(Boolean).join(' • ');
const rm = li.querySelector('.btnRemove');
rm.addEventListener('click', ()=>{
const ok = confirm('¿Quitar "'+c.title+'"?');
if(!ok) return;
favs.delete(c.id);
setFavs(favs);
showToast('Quitado de Seguidos', 'success');
render();
});
const chk = li.querySelector('.chkComparar');
chk.addEventListener('change', onCheckChange);
list.appendChild(li);
});
updateCmpState();
}
function selectedIds(){
return [...document.querySelectorAll('#listaFavs .chkComparar')]
.map((el,idx)=>({el, idx, id: el.closest('li')?.dataset.id}))
.filter(x=>x.el.checked)
.map(x=>x.id);
}
function onCheckChange(e){
const checks = [...document.querySelectorAll('.chkComparar')];
const selected = checks.filter(c=>c.checked);
if(selected.length>2){
e.target.checked = false;
showToast('Solo podés comparar 2 cursos a la vez', 'info');
}
updateCmpState();
syncSelAllState();
}
function updateCmpState(){
const count = selectedIds().length;
btnCmp.disabled = !(count===2);
btnCmp.textContent = 'Comparar ('+count+')';
}
function syncSelAllState(){
const checks = [...document.querySelectorAll('.chkComparar')];
if(checks.length===0){ selAll.checked=false; return; }
selAll.checked = checks.every(c=>c.checked);
selAll.indeterminate = !selAll.checked && checks.some(c=>c.checked);
}
selAll.addEventListener('change', ()=>{
const checks = [...document.querySelectorAll('.chkComparar')];
if(selAll.checked){
let cnt=0;
for(const c of checks){
if(cnt>=2){ c.checked=false; continue; }
c.checked=true; cnt++;
}
if(checks.length>2) showToast('Se seleccionaron los 2 primeros para comparar', 'info');
}else{
checks.forEach(c=>c.checked=false);
}
updateCmpState();
syncSelAllState();
});
document.getElementById('btnComparar').addEventListener('click', ()=>{
const ids = selectedIds();
if(ids.length!==2) return;
const selected = data.filter(d=> ids.includes(String(d.id)));
buildComparison(selected[0], selected[1]);
cmpDialog.showModal();
startCmpTimer(120);
});
function buildComparison(a,b){
cmpWrap.innerHTML='';
cmpDelta.innerHTML='';
const card = (c)=>{
const box = document.createElement('div');
box.className = 'border rounded-lg p-4 dark:border-gray-800';
box.innerHTML =
''+c.title+'
'+
'
'+
''+
'- Precio: '+(c.priceARS?fmtARS(c.priceARS):'Consultar')+'
'+
'- Nivel: '+(c.level||'-')+'
'+
'- Formato: '+(c.format||'-')+'
'+
'- Duración: '+(c.durationHours?c.durationHours+' h':'-')+'
'+
'
'+
''+(c.shortDescription||'')+'
';
return box;
};
cmpWrap.appendChild(card(a));
cmpWrap.appendChild(card(b));
const pa = Number(a.priceARS||0), pb = Number(b.priceARS||0);
if(pa && pb){
const diff = Math.abs(pa-pb);
const cheaper = pa. Más económico: '+cheaper+'.';
}
}
function startCmpTimer(sec){
clearInterval(timerInt);
let t = sec;
const tick = ()=>{
const m = String(Math.floor(t/60)).padStart(2,'0');
const s = String(t%60).padStart(2,'0');
cmpTimer.textContent = 'Cierre automático en '+m+':'+s;
if(t<=0){
clearInterval(timerInt);
cmpDialog.close();
cmpTimer.textContent = '';
}
t--;
};
tick();
timerInt = setInterval(tick,1000);
}
document.addEventListener('click', (e)=>{
const closers = e.target.closest('[data-close]');
if(closers){
const sel = closers.getAttribute('data-close');
const el = document.querySelector(sel);
if(el && typeof el.close==='function') el.close();
}
});
cmpDialog.addEventListener('close', ()=>{ clearInterval(timerInt); cmpTimer.textContent=''; });
const alertEmail = document.getElementById('alertEmail');
const btnAlert = document.getElementById('btnAlert');
(function initEmail(){
const saved = localStorage.getItem('alertsEmail')||'';
if(saved) alertEmail.value = saved;
})();
function validEmail(v){
return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(String(v).trim());
}
btnAlert.addEventListener('click', ()=>{
const v = alertEmail.value.trim();
if(!validEmail(v)){
alertEmail.classList.add('ring-2','ring-red-500');
showToast('Ingresá un email válido', 'error');
setTimeout(()=>alertEmail.classList.remove('ring-2','ring-red-500'),1200);
return;
}
localStorage.setItem('alertsEmail', v);
showToast('Alertas activadas para '+v, 'success');
});
const themeBtn = document.getElementById('tToggle_a7vmm');
const themeIcon = document.getElementById('tIcon_a7vmm');
function refreshThemeIcon(){
const dark = document.documentElement.classList.contains('dark');
themeIcon.textContent = dark ? '☀️' : '🌙';
}
themeBtn.addEventListener('click', ()=>{
const isDark = document.documentElement.classList.toggle('dark');
localStorage.setItem('theme', isDark ? 'dark' : 'light');
refreshThemeIcon();
});
refreshThemeIcon();
const cookieBar = document.getElementById('cookie_u9z31');
const btnAccept = document.getElementById('cookieAccept_b2k8m');
const btnDecline = document.getElementById('cookieDecline_k0p4d');
function ensureConsent(){
consent = localStorage.getItem('consent');
if(!consent){
cookieBar.classList.remove('hidden');
}
}
btnAccept.addEventListener('click', ()=>{
localStorage.setItem('consent','yes');
cookieBar.classList.add('hidden');
showToast('Gracias, preferencias guardadas', 'success');
});
btnDecline.addEventListener('click', ()=>{
localStorage.setItem('consent','no');
cookieBar.classList.add('hidden');
showToast('Podés cambiar tus preferencias más tarde', 'info');
});
ensureConsent();
document.addEventListener('keydown', (e)=>{
if(e.key==='Escape' && cmpDialog.open) cmpDialog.close();
});
load();