{"id":7200,"date":"2026-05-19T20:02:39","date_gmt":"2026-05-20T01:02:39","guid":{"rendered":"https:\/\/jgmun.com\/?page_id=7200"},"modified":"2026-05-20T05:16:17","modified_gmt":"2026-05-20T10:16:17","slug":"calendario-actividades","status":"publish","type":"page","link":"https:\/\/jgmun.com\/index.php\/calendario-actividades\/","title":{"rendered":"Horario JGMUN"},"content":{"rendered":"\n<link href=\"https:\/\/fonts.googleapis.com\/css2?family=Plus+Jakarta+Sans:wght@400;500;600;700;800&#038;display=swap\" rel=\"stylesheet\"\/>\n\n<style>\n  #cs-wrap * { box-sizing: border-box; margin: 0; padding: 0; }\n\n  #cs-wrap {\n    font-family: 'Plus Jakarta Sans', sans-serif;\n    padding: 0 0 2.5rem;\n    margin-top: 2rem;\n    color: #111;\n  }\n\n  \/* Header *\/\n  #cs-wrap .cs-header {\n    display: flex;\n    align-items: center;\n    justify-content: space-between;\n    flex-wrap: wrap;\n    gap: 0.75rem;\n    margin-bottom: 1.5rem;\n    padding-bottom: 1rem;\n    border-bottom: 2px solid #111;\n  }\n\n  #cs-wrap .cs-title {\n    font-size: 1.5rem;\n    font-weight: 800;\n    letter-spacing: -0.02em;\n    color: #111;\n  }\n\n  \/* Toggle *\/\n  #cs-wrap .cs-toggle {\n    display: flex;\n    background: #f2f2f2;\n    border-radius: 8px;\n    padding: 3px;\n    gap: 2px;\n  }\n\n  #cs-wrap .cs-toggle button {\n    background: none;\n    border: none;\n    cursor: pointer;\n    padding: 0.35rem 0.7rem;\n    border-radius: 6px;\n    font-size: 1rem;\n    line-height: 1;\n    color: #888;\n    transition: background 0.15s, color 0.15s;\n  }\n\n  #cs-wrap .cs-toggle button.active {\n    background: #fff;\n    color: #111;\n    box-shadow: 0 1px 4px rgba(0,0,0,0.1);\n  }\n\n  \/* Loading \/ error *\/\n  #cs-wrap .cs-loading {\n    display: flex; align-items: center; gap: 0.6rem;\n    color: #999; font-size: 0.82rem; padding: 1rem 0;\n  }\n  #cs-wrap .cs-spin {\n    width: 15px; height: 15px;\n    border: 2px solid #ddd; border-top-color: #333;\n    border-radius: 50%;\n    animation: csspin 0.7s linear infinite;\n  }\n  @keyframes csspin { to { transform: rotate(360deg); } }\n  #cs-wrap .cs-error {\n    background: #fff1f0; border: 1px solid #ffc5bf;\n    color: #c0392b; border-radius: 8px;\n    padding: 0.9rem 1.1rem; font-size: 0.8rem; display: none;\n  }\n\n  \/* Day block *\/\n  #cs-wrap .cs-day { margin-bottom: 2rem; animation: csup 0.35s ease both; }\n  @keyframes csup {\n    from { opacity:0; transform:translateY(8px); }\n    to   { opacity:1; transform:translateY(0); }\n  }\n\n  #cs-wrap .cs-day-label {\n    font-size: 0.68rem;\n    font-weight: 700;\n    letter-spacing: 0.16em;\n    text-transform: uppercase;\n    color: #999;\n    margin-bottom: 0.85rem;\n  }\n\n  #cs-wrap .cs-empty {\n    color: #ccc; font-size: 0.8rem;\n  }\n\n  \/* \u2500\u2500 GRID VIEW \u2500\u2500 *\/\n  #cs-wrap .cs-grid {\n    display: grid;\n    grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));\n    gap: 0.85rem;\n  }\n\n  #cs-wrap .cs-card {\n    border-radius: 12px;\n    overflow: hidden;\n    background: #fff;\n    border: 1px solid #e8e8e8;\n    display: flex;\n    flex-direction: column;\n    transition: transform 0.18s, box-shadow 0.18s;\n  }\n  #cs-wrap .cs-card:hover {\n    transform: translateY(-2px);\n    box-shadow: 0 6px 20px rgba(0,0,0,0.09);\n  }\n\n  #cs-wrap .cs-card-img {\n    width: 100%; height: 180px;\n    object-fit: cover; display: block;\n  }\n  #cs-wrap .cs-card-placeholder {\n    width: 100%; height: 180px;\n    background: #f5f5f5;\n    display: flex; align-items: center; justify-content: center;\n    font-size: 1.6rem; color: #ccc;\n  }\n  #cs-wrap .cs-card-body {\n    padding: 0.8rem 0.9rem 1rem;\n    display: flex; flex-direction: column; gap: 0.4rem; flex: 1;\n  }\n  #cs-wrap .cs-card-time {\n    font-size: 0.78rem; font-weight: 700; color: #888; letter-spacing: 0.04em;\n  }\n  #cs-wrap .cs-card-name {\n    font-size: 1rem; font-weight: 700; color: #111; line-height: 1.35;\n  }\n  #cs-wrap .cs-tag {\n    display: inline-block; font-size: 0.6rem; font-weight: 700;\n    letter-spacing: 0.1em; text-transform: uppercase;\n    background: #f0eeff; color: #5b35c8;\n    border-radius: 20px; padding: 0.2em 0.6em; align-self: flex-start;\n  }\n\n  \/* \u2500\u2500 TABLE VIEW \u2500\u2500 *\/\n  #cs-wrap .cs-table-wrap {\n    overflow-x: auto; border-radius: 10px;\n    border: 1px solid #e8e8e8;\n  }\n  #cs-wrap table {\n    width: 100%; border-collapse: collapse;\n    font-size: 0.85rem;\n  }\n  #cs-wrap thead th {\n    background: #111; color: #fff;\n    font-size: 0.65rem; font-weight: 700;\n    letter-spacing: 0.12em; text-transform: uppercase;\n    padding: 0.75rem 1rem; text-align: left;\n  }\n  #cs-wrap thead th:first-child { border-radius: 0; width: 80px; }\n  #cs-wrap tbody tr {\n    border-bottom: 1px solid #f0f0f0;\n    transition: background 0.15s;\n  }\n  #cs-wrap tbody tr:last-child { border-bottom: none; }\n  #cs-wrap tbody tr:hover { background: #fafafa; }\n  #cs-wrap tbody td {\n    padding: 0.85rem 1rem; vertical-align: middle; color: #222;\n  }\n  #cs-wrap tbody td.cs-td-time {\n    font-weight: 700; color: #555; font-size: 0.82rem; white-space: nowrap;\n  }\n  #cs-wrap tbody td.cs-td-name { font-weight: 600; }\n  #cs-wrap .cs-td-img-row td {\n    padding: 0 0 0.75rem 0;\n  }\n  #cs-wrap .cs-td-img-row img {\n    width: 100%; max-height: 260px; object-fit: cover;\n    border-radius: 8px; display: block;\n  }\n\n  \/* hidden utility *\/\n  #cs-wrap .cs-hidden { display: none !important; }\n<\/style>\n\n<div id=\"cs-wrap\">\n  <div class=\"cs-header\">\n    <div class=\"cs-title\">Horario JGMUN<\/div>\n    <div class=\"cs-toggle\">\n      <button id=\"btn-grid\" class=\"active\" title=\"Cuadr\u00edcula\">\u229e<\/button>\n      <button id=\"btn-table\" title=\"Tabla\">\u2630<\/button>\n    <\/div>\n  <\/div>\n\n  <div class=\"cs-loading\" id=\"cs-loading\">\n    <div class=\"cs-spin\"><\/div> Cargando\u2026\n  <\/div>\n  <div class=\"cs-error\" id=\"cs-error\"><\/div>\n  <div id=\"cs-days\"><\/div>\n<\/div>\n\n<script>\n(function () {\n  const API = 'https:\/\/api.jgmun.com\/api\/schedules\/cohort2026';\n  let currentView = 'grid';\n  let scheduleData = null;\n\n  function sortDays(days) {\n    return Object.entries(days).sort((a, b) => {\n      const n = s => parseInt(s.replace(\/\\D\/g,'')) || 0;\n      return n(a[0]) - n(b[0]);\n    });\n  }\n\n  function renderGrid(events) {\n    const grid = document.createElement('div');\n    grid.className = 'cs-grid';\n    const EMOJIS = ['\ud83c\udfa4','\ud83c\udf0d','\ud83d\udce3','\ud83e\udd1d','\ud83d\uddf3\ufe0f','\ud83d\udcac','\ud83c\udfdb\ufe0f','\u2728'];\n    events.forEach((ev, i) => {\n      const card = document.createElement('div');\n      card.className = 'cs-card';\n      card.style.animationDelay = (i * 0.05) + 's';\n      const top = ev.image\n        ? `<img decoding=\"async\" class=\"cs-card-img\" src=\"${ev.image}\" alt=\"\" loading=\"lazy\"\/>`\n        : `<div class=\"cs-card-placeholder\">${EMOJIS[i % EMOJIS.length]}<\/div>`;\n      card.innerHTML = `${top}\n        <div class=\"cs-card-body\">\n          <div class=\"cs-card-time\">${ev.time || '\u2014'}<\/div>\n          <div class=\"cs-card-name\">${ev.description || 'Actividad'}<\/div>\n          ${ev.type ? `<span class=\"cs-tag\">${ev.type}<\/span>` : ''}\n        <\/div>`;\n      grid.appendChild(card);\n    });\n    return grid;\n  }\n\n  function renderTable(events) {\n    const wrap = document.createElement('div');\n    wrap.className = 'cs-table-wrap';\n    const table = document.createElement('table');\n    table.innerHTML = `<thead><tr>\n      <th>Hora<\/th><th>Actividad<\/th><th>Tipo<\/th>\n    <\/tr><\/thead>`;\n    const tbody = document.createElement('tbody');\n    events.forEach(ev => {\n      const tr = document.createElement('tr');\n      tr.innerHTML = `\n        <td class=\"cs-td-time\">${ev.time || '\u2014'}<\/td>\n        <td class=\"cs-td-name\">${ev.description || 'Actividad'}<\/td>\n        <td>${ev.type ? `<span class=\"cs-tag\">${ev.type}<\/span>` : '\u2014'}<\/td>`;\n      tbody.appendChild(tr);\n      if (ev.image) {\n        const trImg = document.createElement('tr');\n        trImg.className = 'cs-td-img-row';\n        trImg.innerHTML = `<td colspan=\"3\"><img decoding=\"async\" src=\"${ev.image}\" alt=\"\" loading=\"lazy\"\/><\/td>`;\n        tbody.appendChild(trImg);\n      }\n    });\n    table.appendChild(tbody);\n    wrap.appendChild(table);\n    return wrap;\n  }\n\n  function renderDays(view) {\n    const wrap = document.getElementById('cs-days');\n    wrap.innerHTML = '';\n    sortDays(scheduleData.days).forEach(([name, events], di) => {\n      const block = document.createElement('div');\n      block.className = 'cs-day';\n      block.style.animationDelay = (di * 0.08) + 's';\n\n      const label = document.createElement('div');\n      label.className = 'cs-day-label';\n      label.textContent = name;\n      block.appendChild(label);\n\n      if (!events || events.length === 0) {\n        const e = document.createElement('p');\n        e.className = 'cs-empty';\n        e.textContent = 'Sin actividades por ahora';\n        block.appendChild(e);\n      } else {\n        const sorted = [...events].sort((a,b) => (a.time||'').localeCompare(b.time||''));\n        block.appendChild(view === 'grid' ? renderGrid(sorted) : renderTable(sorted));\n      }\n      wrap.appendChild(block);\n    });\n  }\n\n  function setView(v) {\n    currentView = v;\n    document.getElementById('btn-grid').classList.toggle('active', v === 'grid');\n    document.getElementById('btn-table').classList.toggle('active', v === 'table');\n    if (scheduleData) renderDays(v);\n  }\n\n  document.getElementById('btn-grid').addEventListener('click', () => setView('grid'));\n  document.getElementById('btn-table').addEventListener('click', () => setView('table'));\n\n  fetch(API)\n    .then(r => { if (!r.ok) throw new Error('HTTP ' + r.status); return r.json(); })\n    .then(json => {\n      document.getElementById('cs-loading').style.display = 'none';\n      if (!json.success || !json.data?.length) throw new Error('Sin datos');\n      scheduleData = json.data[0];\n      renderDays(currentView);\n    })\n    .catch(err => {\n      document.getElementById('cs-loading').style.display = 'none';\n      const el = document.getElementById('cs-error');\n      el.textContent = 'No se pudo cargar el calendario: ' + err.message;\n      el.style.display = 'block';\n    });\n})();\n<\/script>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Horario JGMUN \u229e \u2630 Cargando\u2026<\/p>\n","protected":false},"author":1,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"footnotes":""},"class_list":["post-7200","page","type-page","status-publish","hentry"],"_links":{"self":[{"href":"https:\/\/jgmun.com\/index.php\/wp-json\/wp\/v2\/pages\/7200","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/jgmun.com\/index.php\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/jgmun.com\/index.php\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/jgmun.com\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/jgmun.com\/index.php\/wp-json\/wp\/v2\/comments?post=7200"}],"version-history":[{"count":5,"href":"https:\/\/jgmun.com\/index.php\/wp-json\/wp\/v2\/pages\/7200\/revisions"}],"predecessor-version":[{"id":7208,"href":"https:\/\/jgmun.com\/index.php\/wp-json\/wp\/v2\/pages\/7200\/revisions\/7208"}],"wp:attachment":[{"href":"https:\/\/jgmun.com\/index.php\/wp-json\/wp\/v2\/media?parent=7200"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}