| 1 |
/** |
| 2 |
* Shared admin shell JS for the MxChat admin design system. |
| 3 |
* |
| 4 |
* Wires tab switching, mobile menu open/close, and copy-to-clipboard |
| 5 |
* inside every .mxch-admin-wrapper on the page. Scoped to each wrapper |
| 6 |
* so multiple admin shells could in theory coexist (today we have one |
| 7 |
* per page, but no global side effects). |
| 8 |
* |
| 9 |
* Source of truth for the inline-script logic previously duplicated in |
| 10 |
* mxchat-basic/includes/admin-api-page.php and |
| 11 |
* mxchat-mcp/includes/admin-mcp-page.php. |
| 12 |
* |
| 13 |
* @package MxChat |
| 14 |
*/ |
| 15 |
(function () { |
| 16 |
function wire(wrapper) { |
| 17 |
if (!wrapper || wrapper.dataset.mxchAdminWired === '1') { |
| 18 |
return; |
| 19 |
} |
| 20 |
wrapper.dataset.mxchAdminWired = '1'; |
| 21 |
|
| 22 |
var copiedLabel = (window.MxChatAdminSidebarI18n && window.MxChatAdminSidebarI18n.copied) || 'Copied'; |
| 23 |
|
| 24 |
// Tab switcher: clicking any [data-target] button toggles .mxch-section.active. |
| 25 |
var navButtons = wrapper.querySelectorAll('[data-target]'); |
| 26 |
navButtons.forEach(function (btn) { |
| 27 |
btn.addEventListener('click', function (e) { |
| 28 |
e.preventDefault(); |
| 29 |
var targetId = btn.getAttribute('data-target'); |
| 30 |
if (!targetId) { |
| 31 |
return; |
| 32 |
} |
| 33 |
|
| 34 |
wrapper.querySelectorAll('.mxch-section').forEach(function (s) { |
| 35 |
s.classList.remove('active'); |
| 36 |
}); |
| 37 |
var target = wrapper.querySelector('#' + targetId); |
| 38 |
if (target) { |
| 39 |
target.classList.add('active'); |
| 40 |
} |
| 41 |
|
| 42 |
wrapper.querySelectorAll('.mxch-nav-link, .mxch-mobile-nav-link').forEach(function (l) { |
| 43 |
l.classList.remove('active'); |
| 44 |
}); |
| 45 |
wrapper.querySelectorAll('[data-target="' + targetId + '"]').forEach(function (l) { |
| 46 |
l.classList.add('active'); |
| 47 |
}); |
| 48 |
|
| 49 |
var mobileMenu = wrapper.querySelector('.mxch-mobile-menu'); |
| 50 |
if (mobileMenu) { mobileMenu.classList.remove('open'); } |
| 51 |
var mobileOverlay = wrapper.querySelector('.mxch-mobile-overlay'); |
| 52 |
if (mobileOverlay) { mobileOverlay.classList.remove('open'); } |
| 53 |
}); |
| 54 |
}); |
| 55 |
|
| 56 |
// Mobile menu open/close. |
| 57 |
var mobileBtn = wrapper.querySelector('.mxch-mobile-menu-btn'); |
| 58 |
var mobileMenu = wrapper.querySelector('.mxch-mobile-menu'); |
| 59 |
var mobileOverlay = wrapper.querySelector('.mxch-mobile-overlay'); |
| 60 |
var mobileClose = wrapper.querySelector('.mxch-mobile-menu-close'); |
| 61 |
|
| 62 |
function openMenu() { |
| 63 |
if (mobileMenu) { mobileMenu.classList.add('open'); } |
| 64 |
if (mobileOverlay) { mobileOverlay.classList.add('open'); } |
| 65 |
} |
| 66 |
function closeMenu() { |
| 67 |
if (mobileMenu) { mobileMenu.classList.remove('open'); } |
| 68 |
if (mobileOverlay) { mobileOverlay.classList.remove('open'); } |
| 69 |
} |
| 70 |
if (mobileBtn) { mobileBtn.addEventListener('click', openMenu); } |
| 71 |
if (mobileClose) { mobileClose.addEventListener('click', closeMenu); } |
| 72 |
if (mobileOverlay) { mobileOverlay.addEventListener('click', closeMenu); } |
| 73 |
|
| 74 |
// Copy-to-clipboard. |
| 75 |
wrapper.querySelectorAll('[data-mxch-copy]').forEach(function (btn) { |
| 76 |
btn.addEventListener('click', function () { |
| 77 |
var val = btn.getAttribute('data-mxch-copy'); |
| 78 |
if (!val) { |
| 79 |
return; |
| 80 |
} |
| 81 |
var label = btn.querySelector('span'); |
| 82 |
var original = label ? label.textContent : ''; |
| 83 |
var done = function () { |
| 84 |
if (label) { label.textContent = copiedLabel; } |
| 85 |
setTimeout(function () { |
| 86 |
if (label) { label.textContent = original; } |
| 87 |
}, 1500); |
| 88 |
}; |
| 89 |
if (navigator.clipboard && navigator.clipboard.writeText) { |
| 90 |
navigator.clipboard.writeText(val).then(done).catch(function () { done(); }); |
| 91 |
} else { |
| 92 |
var ta = document.createElement('textarea'); |
| 93 |
ta.value = val; |
| 94 |
document.body.appendChild(ta); |
| 95 |
ta.select(); |
| 96 |
try { document.execCommand('copy'); } catch (e) {} |
| 97 |
document.body.removeChild(ta); |
| 98 |
done(); |
| 99 |
} |
| 100 |
}); |
| 101 |
}); |
| 102 |
} |
| 103 |
|
| 104 |
function init() { |
| 105 |
document.querySelectorAll('.mxch-admin-wrapper').forEach(wire); |
| 106 |
} |
| 107 |
|
| 108 |
if (document.readyState === 'loading') { |
| 109 |
document.addEventListener('DOMContentLoaded', init); |
| 110 |
} else { |
| 111 |
init(); |
| 112 |
} |
| 113 |
})(); |
| 114 |
|