(function(){ var REST = '/wp-json/wp/v2'; var CAT = 109; var STORAGE_KEY = 'sm_ee_creds_v1'; function $(s, p){return (p||document).querySelector(s);} function el(tag, attrs, kids){ var e = document.createElement(tag); if (attrs) for (var k in attrs){if (k==='class') e.className=attrs[k]; else if (k==='html') e.innerHTML=attrs[k]; else if (k==='on') {for(var ev in attrs[k]) e.addEventListener(ev, attrs[k][ev]);} else e.setAttribute(k, attrs[k]);} (kids||[]).forEach(function(k){ if(typeof k==='string') e.appendChild(document.createTextNode(k)); else if(k) e.appendChild(k); }); return e; } function msg(text, ok){ var area = $('#ee-msg-area'); area.innerHTML=''; area.appendChild(el('div',{class:'ee-msg '+(ok?'ee-ok':'ee-err'),html:text})); setTimeout(function(){area.innerHTML='';}, 6000); } function getCreds(){ try { return JSON.parse(localStorage.getItem(STORAGE_KEY)||'null'); } catch(e){ return null; } } function setCreds(u,p){ localStorage.setItem(STORAGE_KEY, JSON.stringify({u:u,p:p})); } function authHeader(){ var c = getCreds(); if (!c) return null; return 'Basic ' + btoa(c.u + ':' + c.p); } function fetchJSON(url, opts){ opts = opts || {}; opts.headers = opts.headers || {}; var ah = authHeader(); if (ah) opts.headers['Authorization'] = ah; return fetch(url, opts).then(function(r){ if (r.status === 401 || r.status === 403){ localStorage.removeItem(STORAGE_KEY); location.reload(); throw new Error('unauthorized'); } return r.json().then(function(j){ if (!r.ok) throw new Error(j.message || ('HTTP ' + r.status)); return j; }); }); } function parseExcerpt(post){ var raw = (post.excerpt && post.excerpt.raw) || (post.excerpt && post.excerpt.rendered ? post.excerpt.rendered.replace(/<[^>]+>/g,'') : '') || ''; var t = document.createElement('textarea'); t.innerHTML = raw; var s = t.value.replace(/[“”]/g,'"').replace(/[‘’]/g,"'").trim(); try { return JSON.parse(s); } catch(e){ return {}; } } function fmtDateBadge(iso){if(!iso) return '—'; var p=iso.split('-'); if(p.length!==3) return iso; return p[1]+'.'+p[2];} // ───── Login modal ───── function showLogin(){ var modal = el('div',{class:'ee-modal'}); var card = el('div',{class:'ee-modal-card',style:'max-width:440px;'}); card.innerHTML = '
Enter your WordPress credentials. Use an Application Password (Users → Profile → Application Passwords), not your login password.
' + '' + '' + '' + ''; modal.appendChild(card); document.body.appendChild(modal); $('#ee-li-go').addEventListener('click', function(){ var u = $('#ee-li-u').value.trim(); var p = $('#ee-li-p').value.trim(); if (!u || !p) { $('#ee-li-err').innerHTML = 'Loading events…
'; fetchJSON(REST+'/posts?categories='+CAT+'&per_page=100&status=publish,draft,future&context=edit&_embed=wp:featuredmedia') .then(function(posts){ renderList(posts); }) .catch(function(e){ listEl.innerHTML = 'Load failed: '+e.message+'
'; }); } function renderList(posts){ var showPast = $('#ee-show-past').checked; var today = new Date(); today.setHours(0,0,0,0); var rows = posts.map(function(p){ p._meta = parseExcerpt(p); return p; }) .sort(function(a,b){ return (b._meta.date||'').localeCompare(a._meta.date||''); }); var listEl = $('#ee-list'); listEl.innerHTML = ''; var rendered = 0; rows.forEach(function(p){ var date = p._meta.date || ''; var isPast = date ? (new Date(date+'T00:00:00') < today) : false; if (isPast && !showPast) return; rendered++; var img = (p._embedded && p._embedded['wp:featuredmedia'] && p._embedded['wp:featuredmedia'][0] && p._embedded['wp:featuredmedia'][0].source_url) || ''; var thumb = el('div',{class:'ee-thumb'}, [img ? el('img',{src:img,alt:''}) : 'No image']); var dateBox = el('div',{}, [ el('div',{class:'ee-date'},[fmtDateBadge(date)]), el('div',{class:'ee-time'},[p._meta.time || '']) ]); var titleBox = el('div',{}, [ el('div',{class:'ee-title',html: p.title.rendered}), el('div',{class:'ee-tags'},(function(){ var t = []; t.push(el('span',{class:'ee-tag '+(isPast?'ee-past':'ee-upcoming')},[isPast?'Past':'Upcoming'])); if (p._meta.source === 'facebook' || p._meta.fb_event_id) t.push(el('span',{class:'ee-tag ee-fb'},['FB'])); if (p.status === 'draft') t.push(el('span',{class:'ee-tag ee-draft'},['Draft'])); if (p._meta.adopted_from_manual) t.push(el('span',{class:'ee-tag ee-fb'},['Adopted'])); return t; })()) ]); var actions = el('div',{class:'ee-actions'}, [ el('button',{class:'ee-btn ee-small', on:{click:function(){openEdit(p);}}},['Edit']), el('button',{class:'ee-btn ee-small ee-ghost', on:{click:function(){copyEvent(p);}}},['Copy']), el('button',{class:'ee-btn ee-small ee-danger', on:{click:function(){trashEvent(p);}}, title:'Move to draft (hides from public page)'},[p.status==='draft'?'Restore':'Hide']) ]); var row = el('div',{class:'ee-row '+(isPast?'ee-past':'')}, [thumb, dateBox, titleBox, actions]); listEl.appendChild(row); }); if (rendered === 0) listEl.innerHTML = 'No events to show. ' + (showPast?'':'Try enabling "Show past events".') + '
'; } // ───── Edit / Create / Copy ───── function blankPost(){ return {id:0, title:{raw:''}, content:{raw:''}, status:'publish', featured_media:0, _meta:{date:new Date().toISOString().slice(0,10), time:'7:00 PM', subtitle:'', price:'', cta_url:'', cta_text:'Reserve'}}; } function copyEvent(orig){ var copy = JSON.parse(JSON.stringify(orig)); copy.id = 0; copy.title.raw = (orig.title.raw || orig.title.rendered || '') + ' (copy)'; copy._meta.fb_event_id = ''; copy._meta.fb_event_url = ''; copy._meta.source = ''; copy._meta.adopted_from_manual = false; openEdit(copy); } function openEdit(post){ var isNew = !post.id; var modal = el('div',{class:'ee-modal'}); var card = el('div',{class:'ee-modal-card'}); card.innerHTML = '