(function () { // Polished SPA + partners CRUD + animations const ANIM = { modalDuration: 420, sectionDuration: 420 }; function el(sel, ctx = document) { return ctx.querySelector(sel); } // Debug banner + global error handlers for easy troubleshooting function debugBanner(msg, level = 'info') { try { let b = document.getElementById('debug-banner'); if (!b) { b = document.createElement('div'); b.id = 'debug-banner'; b.style.position = 'fixed'; b.style.left = '20px'; b.style.bottom = '80px'; // Move to bottom-left to avoid top-nav overlap b.style.zIndex = 9999; b.style.padding = '12px'; b.style.borderRadius = '12px'; b.style.background = 'rgba(10,10,10,0.85)'; b.style.color = 'var(--muted)'; b.style.fontSize = '11px'; b.style.fontFamily = 'monospace'; b.style.lineHeight = '1.5'; b.style.border = '1px solid rgba(255,255,255,0.1)'; b.style.boxShadow = '0 10px 40px rgba(0,0,0,0.8)'; document.body && document.body.appendChild(b); } const line = document.createElement('div'); line.textContent = `> ${msg}`; if (level === 'error') line.style.color = '#ff3fa5'; b.appendChild(line); if (b.childNodes.length > 5) b.removeChild(b.firstChild); // Keep last 5 messages } catch (e) { console.warn('debugBanner failed', e); } } window.addEventListener('error', (ev) => { debugBanner('ERROR: ' + (ev.message || ev.reason || 'unknown'), 'error'); console.error(ev.error || ev); }); window.addEventListener('unhandledrejection', (ev) => { let m = ev.reason && ev.reason.message ? ev.reason.message : String(ev.reason); debugBanner('Promise Rejection: ' + m, 'error'); console.error('unhandledrejection', ev.reason); }); debugBanner('JS initiated'); const urlParams = new URLSearchParams(window.location.search); const debugPrintConnection = urlParams.get('debugPrintConnection') === 'true'; async function showDebugInfo() { if (!debugPrintConnection) return; try { const info = await api('admin/api/debug.php?debug=1'); if (info.ok) { let dbBox = document.getElementById('db-debug-info'); if (!dbBox) { dbBox = document.createElement('div'); dbBox.id = 'db-debug-info'; dbBox.style.position = 'fixed'; dbBox.style.top = '0'; dbBox.style.left = '0'; dbBox.style.right = '0'; dbBox.style.zIndex = 10001; dbBox.style.background = 'linear-gradient(90deg, #7d6bff, #ff3fa5)'; dbBox.style.color = '#000'; dbBox.style.padding = '4px 20px'; dbBox.style.fontSize = '12px'; dbBox.style.fontWeight = '800'; dbBox.style.textAlign = 'center'; dbBox.style.boxShadow = '0 2px 10px rgba(0,0,0,0.5)'; document.body.appendChild(dbBox); } dbBox.textContent = `DEBUG: Database "${info.db_name}" | Host: ${info.db_host} | Users: ${info.user_count} | Mode: ${info.method}`; } else { debugBanner('DB Error: ' + info.error, 'error'); } } catch (e) { debugBanner('Debug API failed: ' + e.message, 'error'); } } function els(sel, ctx = document) { return Array.from(ctx.querySelectorAll(sel)); } async function api(path, opts = {}) { let res = await fetch(path, opts); if (!res.ok) { // try to parse JSON errors first let txt = null; try { let obj = await res.json(); txt = obj.error || obj.message || JSON.stringify(obj); } catch (e) { txt = await res.text(); } throw new Error(txt || res.statusText); } return res.json(); } // --- Real Login Flow --- function showLogin() { let newName = ["admin", "portal", "artichoke", "mushroom", "avacado", "ceviche", "coffee", "super boof", "account", "global", "wasabi", "sashimi"]; newName = ["account"]; const randomName = newName[Math.floor(Math.random() * newName.length)]; const loginRoot = document.getElementById('login-root'); loginRoot.style.display = 'flex'; loginRoot.innerHTML = ` `; setTimeout(() => { loginRoot.classList.add('active'); }, 100); const form = loginRoot.querySelector('#login-form'); form.addEventListener('submit', async (ev) => { ev.preventDefault(); const email = el('#l-email').value.trim(); const password = el('#l-password').value.trim(); const btn = form.querySelector('button[type="submit"]'); const alert = el('#l-alert'); btn.disabled = true; setBtnLabel(btn, 'Authenticating...'); alert.style.display = 'none'; try { const r = await api('admin/api/auth.php?action=login', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ email, password }) }); if (r.ok) { toast('Welcome, ' + r.user.name, 'success'); // Important: we keep setRole for UI visibility logic applyRole(r.user.role); hideLogin(); } } catch (e) { alert.textContent = e.message; alert.style.display = 'block'; } finally { btn.disabled = false; setBtnLabel(btn, 'Log in'); } }); enhanceFloatWraps(loginRoot); } function hideLogin() { const loginRoot = document.getElementById('login-root'); loginRoot.classList.remove('active'); setTimeout(() => { loginRoot.style.display = 'none'; document.body.classList.remove('login-mode'); }, 600); } function applyRole(role) { // Normalize role name to match data-roles (e.g., "Admin" -> "super_admin") let normalized = String(role || '').toLowerCase().replace(/\s+/g, '_'); if (normalized === 'admin') normalized = 'super_admin'; console.log('Applying role permissions:', normalized); localStorage.setItem('user_role', role); // Immediate UI cleanup document.body.classList.remove('login-mode'); const loginRoot = document.getElementById('login-root'); if (loginRoot) { loginRoot.classList.remove('active'); loginRoot.style.display = 'none'; } const cheatWrap = document.querySelector('.debug-cheat-wrap'); if (cheatWrap) cheatWrap.remove(); // Apply visibility rules document.querySelectorAll('[data-roles]').forEach(el => { const allowed = el.dataset.roles.split(','); if (allowed.includes(normalized)) { el.classList.remove('hidden'); } else { el.classList.add('hidden'); } }); // Special Artist Sidebar Header Change const generalHeader = document.querySelector('[data-header="General"]'); if (generalHeader) { generalHeader.textContent = (normalized === 'artist') ? 'Your Designs' : generalHeader.dataset.header; } // Default view based on role if (normalized === 'artist') { showSection('home'); } else if (normalized === 'partner_admin') { showSection('users'); } else { showSection('partners'); } } function logout() { api('admin/api/auth.php?action=logout').finally(() => { localStorage.removeItem('user_role'); location.reload(); }); } // Init: ensure setup, wire events async function init() { debugBanner('init: starting...'); try { const res = await api('admin/setup.php'); console.log('Setup finished:', res); if (res.debug) { console.log('Setup Debug Log:', res.debug); } } catch (e) { debugBanner('init: setup failed: ' + (e.message || e), 'error'); console.warn('setup failed', e); } if (debugPrintConnection) await showDebugInfo(); wireNav(); wirePartners(); wireUsers(); enhanceFloatWraps(); showDevBadge(); // Wire per-page dropdowns const uP = el('#user-per-page'); if (uP) uP.addEventListener('change', () => loadUsers(1)); const pP = el('#partner-per-page'); if (pP) pP.addEventListener('change', () => loadPartners()); const logoutBtn = document.getElementById('logout-btn'); if (logoutBtn) logoutBtn.addEventListener('click', logout); // Initial State: Show login if not already "simulated" or "authenticated" (for prototype we just always show) const savedRole = localStorage.getItem('user_role'); if (savedRole) { applyRole(savedRole); } else { showLogin(); } // Hidden functionality initialization if (typeof initDebugCheat === 'function') initDebugCheat(); debugBanner('init: ready'); } function wireNav() { els('.nav-item').forEach(a => a.addEventListener('click', (ev) => { ev.preventDefault(); els('.nav-item').forEach(n => n.classList.remove('active')); a.classList.add('active'); let t = a.getAttribute('data-target'); showSection(t); // subtle nav flash let main = document.querySelector('.main'); main.classList.remove('nav-flash'); void main.offsetWidth; main.classList.add('nav-flash'); setTimeout(() => main.classList.remove('nav-flash'), 520); })); } function showSection(id) { let current = document.querySelector('.section.active'); if (current && current.id === id) return; let next = document.getElementById(id); if (!next) return; // animate out current if (current) { current.classList.remove('active'); current.style.opacity = 0; current.style.transform = 'translateY(8px) scale(.995)'; } // animate in next requestAnimationFrame(() => { next.classList.add('active'); next.style.opacity = 1; next.style.transform = 'none'; if (id === 'users') loadUsers(); else if (id === 'partners') loadPartners(); }); } // --- Partners --- function wirePartners() { let searchInput = el('#partner-search'); if (searchInput) { searchInput.addEventListener('keyup', (e) => { if (e.key === 'Enter') loadPartners(searchInput.value); }); } let searchBtn = el('#search-btn'); if (searchBtn) searchBtn.addEventListener('click', () => loadPartners(el('#partner-search') ? el('#partner-search').value : '')); el('#new-partner').addEventListener('click', () => showPartnerModal()); } // Shared Partner Form Template function getPartnerFormHtml(data = {}) { const isEdit = !!data.partner_id; const sw = (f) => (data[f] ? 'on' : ''); const val = (f) => (data[f] === null || data[f] === undefined ? '' : escapeHtml(data[f])); return ` `; } async function showPartnerModal(id = null) { console.log('showPartnerModal called', id); const modalRoot = document.getElementById('modal-root'); modalRoot.innerHTML = ''; modalRoot.style.display = 'block'; const modal = document.createElement('div'); modal.className = 'modal-backdrop'; let partnerData = {}; if (id) { modal.innerHTML = ``; modalRoot.appendChild(modal); try { let r = await api('admin/api/partners.php?action=get&id=' + encodeURIComponent(id)); partnerData = r.data; } catch (e) { toast('Error loading partner: ' + e.message, 'error'); closeModal(); return; } } modal.innerHTML = getPartnerFormHtml(partnerData); modalRoot.innerHTML = ''; // clear loading state if any modalRoot.appendChild(modal); // wire switches Array.from(modal.querySelectorAll('.form-row.toggle, .toggle')).forEach(t => { let sw = t.querySelector('.switch'); if (!sw) return; sw.setAttribute('role', 'switch'); sw.setAttribute('aria-checked', sw.classList.contains('on') ? 'true' : 'false'); t.addEventListener('click', (ev) => { if (ev.target.closest('button')) return; sw.classList.toggle('on'); sw.setAttribute('aria-checked', sw.classList.contains('on') ? 'true' : 'false'); }); }); // animations setTimeout(() => { let m = modal.querySelector('.modal'); m.classList && m.classList.add('active-bloom'); }, 60); enhanceFloatWraps(modal); modal.addEventListener('click', async (ev) => { let btn = ev.target.closest('button'); if (!btn) return; if (btn.id === 'm-cancel') { closeModal(); } else if (btn.id === 'm-save') { btn.disabled = true; setBtnLabel(btn, id ? 'Saving...' : 'Creating...'); try { await handlePartnerSave(modal, id); } catch (e) { console.error('handlePartnerSave error', e); } btn.disabled = false; setBtnLabel(btn, id ? 'Save Changes' : 'Create Partner'); } }); } async function handlePartnerSave(modal, id = null) { let getVal = id => modal.querySelector('#' + id).value.trim(); let sw = id => !!modal.querySelector('#' + id).classList.contains('on'); let payload = { name: getVal('m-name'), oms_partner_id: getVal('m-oms'), oms_order_source: getVal('m-oms-order'), shopify_product_tag: getVal('m-shopify-tag'), shopify_product_vendor: getVal('m-shopify-vendor'), customer_type: getVal('m-customer-type'), billing_type: getVal('m-billing'), partner_type: getVal('m-partner-type'), logo_url: getVal('m-logo-url'), site_domain: getVal('m-site-domain'), support_email: getVal('m-support-email'), from_email: getVal('m-from-email'), faq_url: getVal('m-faq-url'), shopify_variant_taxable: sw('m-shopify-variant-switch') ? 1 : 0, hidden_in_shopify: sw('m-hidden-switch') ? 1 : 0, third_party_shipping: sw('m-3ps-switch') ? 1 : 0, tiered_pricing: sw('m-tiered-switch') ? 1 : 0, patterns_enabled: sw('m-patterns-switch') ? 1 : 0 }; if (id) payload.partner_id = id; let alertBox = modal.querySelector('#m-alert'); alertBox.style.display = 'none'; let missing = []; if (!payload.name) missing.push('Name'); if (!payload.oms_partner_id) missing.push('OMS Partner ID'); if (!payload.oms_order_source) missing.push('OMS Order Source'); if (!payload.site_domain) missing.push('Site Domain'); if (missing.length) { alertBox.style.display = 'block'; alertBox.textContent = 'Missing: ' + missing.join(', '); return; } try { const action = id ? 'update' : 'create'; let r = await api('admin/api/partners.php?action=' + action, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(payload) }); if (r.ok) { toast(id ? 'Partner updated' : 'Partner created', 'success'); loadPartners(); closeModal(); } else { alertBox.style.display = 'block'; alertBox.textContent = r.error || JSON.stringify(r); } } catch (e) { alertBox.style.display = 'block'; alertBox.textContent = 'Error: ' + e.message; } } // --- Users UI and behavior --- function wireUsers() { let search = el('#user-search'); if (search) { search.addEventListener('keyup', (e) => { if (e.key === 'Enter') loadUsers(1, search.value); }); } let newBtn = el('#new-user'); if (newBtn) newBtn.addEventListener('click', () => openUserModal()); // table header sorting document.addEventListener('click', (ev) => { let th = ev.target.closest('th.sortable'); if (!th) return; let sortBy = th.dataset.sort; let dir = th.dataset.dir === 'asc' ? 'desc' : 'asc'; th.dataset.dir = dir; loadUsers(1, el('#user-search') ? el('#user-search').value : '', sortBy, dir); }); } async function loadUsers(page = 1, q = '', sortBy = 'user_id', sortDir = 'asc', doShow = true) { if (doShow) showSection('users'); const per = el('#user-per-page') ? el('#user-per-page').value : 25; try { let url = 'admin/api/users.php?action=list&page=' + page + '&per_page=' + per + '&q=' + encodeURIComponent(q || (el('#user-search')?.value || '')) + '&sort_by=' + encodeURIComponent(sortBy) + '&sort_dir=' + encodeURIComponent(sortDir); let r = await api(url); let tbody = el('#users-table tbody'); tbody.innerHTML = ''; r.data.forEach(u => { let role = (u.role || '').toLowerCase(); let tr = document.createElement('tr'); tr.classList.add('row-click'); tr.dataset.id = u.user_id; let links = ` `; tr.innerHTML = `${u.user_id} ${escapeHtml(u.name || '')} ${escapeHtml(u.email)} ${escapeHtml(u.partner || '—')} ${escapeHtml(u.role || 'user')} ${formatShortDate(u.created_at)} ${u.status == 1 ? 'Active' : 'Inactive'} ${links}`; tr.addEventListener('click', () => openUserModal(u.user_id)); tbody.appendChild(tr); }); // pager renderUsersPager(r.meta.page, r.meta.per_page, r.meta.total); } catch (e) { toast('Error loading users: ' + e.message, 'error'); } } function renderUsersPager(page, per, total) { let root = el('#users-pager'); root.innerHTML = ''; let pages = Math.max(1, Math.ceil(total / per)); if (page > 1) { let prev = document.createElement('button'); prev.className = 'btn secondary'; prev.textContent = 'Prev'; prev.addEventListener('click', () => loadUsers(page - 1, el('#user-search') ? el('#user-search').value : '')); root.appendChild(prev); } let info = document.createElement('div'); info.style.color = 'var(--muted)'; info.textContent = `Page ${page} / ${pages} — ${total} users`; root.appendChild(info); if (page < pages) { let next = document.createElement('button'); next.className = 'btn secondary'; next.textContent = 'Next'; next.addEventListener('click', () => loadUsers(page + 1, el('#user-search') ? el('#user-search').value : '')); root.appendChild(next); } } async function openUserModal(id) { const modalRoot = document.getElementById('modal-root'); modalRoot.innerHTML = ''; modalRoot.style.display = 'block'; const modal = document.createElement('div'); modal.className = 'modal-backdrop'; const curRawRole = localStorage.getItem('user_role'); const curRole = String(curRawRole || '').toLowerCase().replace(/\s+/g, '_'); const isSuper = curRole === 'super_admin' || curRole === 'admin'; let partners = []; if (isSuper) { try { const resp = await api('admin/api/partners.php?action=list&per_page=1000'); if (resp.ok) partners = resp.data; } catch (e) { console.error('Failed to load partners for modal', e); } } const getPartnerOptions = (selectedId) => { let html = ''; partners.forEach(p => { html += ``; }); return html; }; if (!id) { // create modal.innerHTML = ` `; modalRoot.appendChild(modal); enhanceFloatWraps(modal); modal.addEventListener('click', async (ev) => { let btn = ev.target.closest('button'); if (!btn) return; if (btn.id === 'u-cancel') { closeModal(); } else if (btn.id === 'u-save') { btn.disabled = true; setBtnLabel(btn, 'Creating...'); let payload = { email: modal.querySelector('#u-email').value.trim(), name: modal.querySelector('#u-name').value.trim(), role: modal.querySelector('#u-role').value, password: modal.querySelector('#u-password').value }; if (isSuper && modal.querySelector('#u-partner')) { payload.partner_id = modal.querySelector('#u-partner').value; } if (!payload.email || !payload.password) { let a = modal.querySelector('#u-alert'); a.style.display = 'block'; a.textContent = 'Email and password required'; btn.disabled = false; setBtnLabel(btn, 'Create'); return; } if (isSuper && !payload.partner_id) { let a = modal.querySelector('#u-alert'); a.style.display = 'block'; a.textContent = 'Partner is required'; btn.disabled = false; setBtnLabel(btn, 'Create'); return; } try { let r = await api('admin/api/users.php?action=create', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(payload) }); if (r.ok) { toast('Created', 'success'); loadUsers(); closeModal(); } else { let a = modal.querySelector('#u-alert'); a.style.display = 'block'; a.textContent = r.error || JSON.stringify(r); } } catch (e) { let a = modal.querySelector('#u-alert'); a.style.display = 'block'; a.textContent = e.message; } btn.disabled = false; setBtnLabel(btn, 'Create'); } }); } else { // edit modal.innerHTML = ``; modalRoot.appendChild(modal); try { let r = await api('admin/api/users.php?action=get&id=' + encodeURIComponent(id)); let u = r.data; modal.querySelector('.modal').innerHTML = ` `; enhanceFloatWraps(modal); modal.querySelectorAll('.modal-actions button').forEach(b => b.setAttribute('type', 'button')); modal.querySelector('#u-role').value = u.role; modal.addEventListener('click', async (ev) => { let btn = ev.target.closest('button'); if (!btn) return; if (btn.id === 'u-cancel') { closeModal(); } else if (btn.id === 'u-delete') { if (confirm('Delete user?')) { btn.disabled = true; setBtnLabel(btn, 'Deleting...'); try { await api('admin/api/users.php?action=delete&id=' + id); toast('Deleted', 'success'); closeModal(); loadUsers(); } catch (e) { let a = modal.querySelector('#u-alert'); a.style.display = 'block'; a.textContent = e.message; btn.disabled = false; setBtnLabel(btn, 'Delete'); } } } else if (btn.id === 'u-save') { btn.disabled = true; setBtnLabel(btn, 'Saving...'); let payload = { user_id: id, email: modal.querySelector('#u-email').value.trim(), name: modal.querySelector('#u-name').value.trim(), role: modal.querySelector('#u-role').value }; if (isSuper && modal.querySelector('#u-partner')) { payload.partner_id = modal.querySelector('#u-partner').value; } if (isSuper && !payload.partner_id) { let a = modal.querySelector('#u-alert'); a.style.display = 'block'; a.textContent = 'Partner is required'; btn.disabled = false; setBtnLabel(btn, 'Save'); return; } let pw = modal.querySelector('#u-password').value; if (pw) payload.password = pw; try { let r = await api('admin/api/users.php?action=update', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(payload) }); if (r.ok) { toast('Saved', 'success'); loadUsers(); closeModal(); } else { let a = modal.querySelector('#u-alert'); a.style.display = 'block'; a.textContent = r.error || JSON.stringify(r); } } catch (e) { let a = modal.querySelector('#u-alert'); a.style.display = 'block'; a.textContent = e.message; } btn.disabled = false; setBtnLabel(btn, 'Save'); } }); } catch (e) { toast('Error: ' + e.message, 'error'); } } } window.openUserModal = openUserModal; async function loadPartners(q = '') { showSection('partners'); const per = el('#partner-per-page') ? el('#partner-per-page').value : 25; try { let url = 'admin/api/partners.php?action=list&per_page=' + per + '&sort_by=partner_id&sort_dir=asc' + (q ? ('&q=' + encodeURIComponent(q)) : (el('#partner-search')?.value ? '&q=' + encodeURIComponent(el('#partner-search').value) : '')); let r = await api(url); let tbody = el('#partners-table tbody'); tbody.innerHTML = ''; r.data.forEach(row => { let tr = document.createElement('tr'); tr.classList.add('row-click'); tr.dataset.id = row.partner_id; tr.innerHTML = `${row.partner_id}${escapeHtml(row.name)}${escapeHtml(row.partner_type || '')}${escapeHtml(row.oms_partner_id || '')}`; tr.addEventListener('click', () => showPartnerModal(row.partner_id)); tbody.appendChild(tr); }); } catch (e) { toast('Error loading partners: ' + e.message, 'error'); } } function escapeHtml(s) { if (s == null) return ''; return String(s).replace(/[&<>"']/g, function (c) { return { '&': '&', '<': '<', '>': '>', '"': '"', "'": ''' }[c]; }); } function closeModal() { console.log('closeModal called'); debugBanner('Modal closed'); let r = document.getElementById('modal-root'); r.innerHTML = ''; r.style.display = 'none'; } function enhanceFloatWraps(root = document) { root = root || document; let wraps = Array.from((root || document).querySelectorAll('.float-wrap')); wraps.forEach(w => { let input = w.querySelector('input,textarea,select'); if (!input) return; const update = () => { if (input.tagName === 'SELECT') { if (input.value && input.value !== '') w.classList.add('has-value'); else w.classList.remove('has-value'); } else { if (input.value && input.value.trim() !== '') w.classList.add('has-value'); else w.classList.remove('has-value'); } }; update(); input.addEventListener('input', update); input.addEventListener('change', update); let lbl = w.querySelector('label'); if (lbl) lbl.addEventListener('click', () => input.focus()); }); } // helper to set button label inside .btn-inner if present function setBtnLabel(btn, label) { try { let bi = btn && btn.querySelector && btn.querySelector('.btn-inner'); if (bi) bi.textContent = label; else if (btn) btn.textContent = label; } catch (e) { } } // small toast helper function toast(msg, type = 'info') { const t = document.createElement('div'); t.style.position = 'fixed'; t.style.right = '20px'; t.style.bottom = '20px'; t.style.background = 'linear-gradient(90deg,var(--accent),var(--accent-2))'; t.style.color = '#07101a'; t.style.padding = '12px 16px'; t.style.borderRadius = '10px'; t.style.boxShadow = '0 8px 40px rgba(0,0,0,0.5)'; t.style.zIndex = 3000; t.textContent = msg; document.body.appendChild(t); setTimeout(() => { t.style.transition = 'all .4s'; t.style.opacity = 0; t.style.transform = 'translateY(20px)'; setTimeout(() => t.remove(), 420); }, 1800); } // small dev badge to confirm JS bundle is loaded (non-intrusive) function showDevBadge() { try { let r = document.querySelector('.top-right'); if (!r) return; let b = document.createElement('div'); b.id = 'dev-badge'; b.textContent = 'JS loaded • ' + (new Date()).toLocaleTimeString(); b.style.fontSize = '12px'; b.style.padding = '6px 8px'; b.style.borderRadius = '8px'; b.style.background = 'rgba(255,255,255,0.03)'; b.style.border = '1px solid rgba(255,255,255,0.02)'; b.style.color = 'var(--muted)'; b.style.fontWeight = '700'; b.style.backdropFilter = 'blur(4px)'; b.style.boxShadow = '0 10px 30px rgba(0,0,0,0.4)'; r.appendChild(b); setTimeout(() => { if (b) b.style.opacity = 0.9; }, 120); } catch (e) { console.warn('badge failed', e); } } function formatShortDate(ds) { if (!ds) return '—'; try { const d = new Date(ds); if (isNaN(d.getTime())) return ds; return (d.getMonth() + 1) + '/' + d.getDate() + '/' + String(d.getFullYear()).slice(-2); } catch (e) { return ds; } } // start document.addEventListener('DOMContentLoaded', init); // =========================================================================== // DEBUG CHEAT CODE FUNCTIONALITY // DELETE THIS ENTIRE CHUNK TO REMOVE THE HIDDEN DROPDOWN // =========================================================================== let cheatCount = 0; function initDebugCheat() { document.addEventListener('keydown', (e) => { // Check for '$' (Shift + 4) if (e.key === '$') { cheatCount++; if (cheatCount === 7) { showCheatDropdown(); } } }); } async function showCheatDropdown() { let wrap = document.querySelector('.debug-cheat-wrap'); if (wrap) return; wrap = document.createElement('div'); wrap.className = 'debug-cheat-wrap'; wrap.innerHTML = `
CHOOSE USER
`; document.body.appendChild(wrap); // Trigger animation setTimeout(() => wrap.classList.add('active'), 10); const select = wrap.querySelector('select'); try { const r = await api('admin/api/users.php?action=list&per_page=100'); select.innerHTML = ''; r.data.forEach(u => { const email = u.email; const role = u.role || 'user'; let pass = 'password'; if (email === 'skyouadmin') pass = 'skuniverse'; else if (role === 'Partner Admin') pass = 'skyou' + email; else if (role === 'Artist') pass = email; const opt = document.createElement('option'); opt.value = JSON.stringify({ email, pass, role }); opt.textContent = `${u.name || u.email} [${role}]`; select.appendChild(opt); }); select.addEventListener('change', () => { if (!select.value) return; const data = JSON.parse(select.value); const emailField = document.getElementById('l-email'); const passField = document.getElementById('l-password'); if (emailField && passField) { emailField.value = data.email; passField.value = data.pass; emailField.parentElement.classList.add('has-value'); passField.parentElement.classList.add('has-value'); wrap.querySelector('.debug-role-label').textContent = data.role; } }); } catch (e) { select.innerHTML = ''; console.error('Cheat dropdown error:', e); } } // =========================================================================== })();