(function(){
const enabledCb = document.getElementById('a11ybridge-cloud-enabled');
const telemetryCb = document.getElementById('a11ybridge-cloud-telemetry');
const statusEl = document.getElementById('a11ybridge-cloud-save-status');
if (!enabledCb || !telemetryCb || !statusEl) return;
const ajaxUrl = (window.A11YBRIDGE_ADMIN && window.A11YBRIDGE_ADMIN.ajaxUrl) ? window.A11YBRIDGE_ADMIN.ajaxUrl : '';
const nonce = (window.A11YBRIDGE_ADMIN && window.A11YBRIDGE_ADMIN.noncePro) ? window.A11YBRIDGE_ADMIN.noncePro : '';
if (!ajaxUrl || !nonce) return;
function setStatus(msg, isOk){
if (!statusEl) return;
statusEl.style.display = 'block';
statusEl.style.color = isOk ? '#0f5132' : '#8a2424';
statusEl.textContent = msg;
clearTimeout(setStatus._t);
setStatus._t = setTimeout(()=>{ statusEl.style.display='none'; }, 2500);
}
function syncTelemetryEnabledState(){
const cloudEnabled = !!enabledCb.checked;
telemetryCb.disabled = !cloudEnabled;
if (!cloudEnabled && telemetryCb.checked){
telemetryCb.checked = false;
}
}
async function save(){
syncTelemetryEnabledState();
const enabled = enabledCb.checked ? 1 : 0;
const telemetry = (!telemetryCb.disabled && telemetryCb.checked) ? 1 : 0;
const body = new URLSearchParams();
body.set('action', 'a11ybridge_save_cloud_settings');
body.set('nonce', nonce);
body.set('enabled', String(enabled));
body.set('telemetry', String(telemetry));
try{
const res = await fetch(ajaxUrl, {
method: 'POST',
headers: {'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'},
body: body.toString(),
credentials: 'same-origin'
});
const data = await res.json().catch(()=>null);
if (!res.ok || !data || !data.success){
const msg = (data && data.data && (data.data.message || data.data.msg)) ? (data.data.message || data.data.msg) : 'Save failed.';
setStatus(msg, false);
return;
}
// normalize server response
if (typeof data.data?.enabled !== 'undefined'){
enabledCb.checked = !!data.data.enabled;
}
if (typeof data.data?.telemetry !== 'undefined'){
telemetryCb.checked = !!data.data.telemetry;
}
syncTelemetryEnabledState();
setStatus('Saved.', true);
} catch(e){
setStatus('Save failed (network).', false);
}
}
enabledCb.addEventListener('change', save);
telemetryCb.addEventListener('change', save);
syncTelemetryEnabledState();
})();
0);
$in_future = ($has_date && $expires_ts > $now_ts);
$expires_str = $has_date
? wp_date(get_option('date_format') . ' ' . get_option('time_format'), $expires_ts)
: '';
$is_active = ($lic_status === 'active');
$is_cancel = in_array($lic_status, ['cancelled','canceled'], true);
$mode = 'unknown';
if ($has_date) {
if ($is_cancel && $in_future) $mode = 'cancelled_valid';
elseif ($is_cancel && !$in_future) $mode = 'expired';
elseif ($is_active && $in_future) $mode = 'active';
elseif ($is_active && !$in_future) $mode = 'unpaid';
}
// Human output
$status_line = '';
switch ($mode) {
case 'cancelled_valid':
/* translators: %s: date */
$status_line = sprintf(__('Cancelled, valid until %s', 'a11ybridge'), $expires_str);
break;
case 'active':
/* translators: %s: date */
$status_line = sprintf(__('Active, updates on %s', 'a11ybridge'), $expires_str);
break;
case 'expired':
/* translators: %s: date */
$status_line = sprintf(__('Expired on %s', 'a11ybridge'), $expires_str);
break;
case 'unpaid':
/* translators: %s: date */
$status_line = sprintf(__('Unpaid since %s', 'a11ybridge'), $expires_str);
break;
default:
// fallback if no expires date
if ($is_active) $status_line = __('Active', 'a11ybridge');
elseif ($is_cancel) $status_line = __('Cancelled', 'a11ybridge');
else $status_line = __('Unknown', 'a11ybridge');
break;
}
?>
einmalig an a11ybridge.de übertragen; lokal speichern wir ausschließlich den Hash.'
esc_html_e(
'Please enter your license key to connect optional AI services. The key is sent to a11ybridge.de exactly once in plain text; locally only the hash is stored.',
'a11ybridge'
);
?>
(function(){
var btn = document.getElementById('ab-unbind-domain');
if (!btn) return;
const backendDelUrl = "https://a11ybridge.de/wp-json/a11ybridge/v1/license/domains/delete";
var licenseHash = btn.getAttribute('data-license-hash') || '';
var domain = btn.getAttribute('data-domain') || '';
// Ajax endpoint + nonce for WP
var ajaxUrl = (window.A11YBRIDGE_ADMIN && window.A11YBRIDGE_ADMIN.ajaxUrl) ? window.A11YBRIDGE_ADMIN.ajaxUrl : '';
var nonce = (window.A11YBRIDGE_ADMIN && window.A11YBRIDGE_ADMIN.noncePro) ? window.A11YBRIDGE_ADMIN.noncePro : '';
globalThis.A11yBridgeLogger.debug("licenseHash:", licenseHash, "domain:", domain);
btn.addEventListener('click', async () => {
if (!licenseHash) {
// DE: 'Kein Lizenz-Hash verfügbar – bitte Lizenz neu aktivieren.'
alert('No license hash available – please re-activate the license.');
return;
}
if (!domain) {
// DE: 'Keine Domain zum Entbinden vorhanden.'
alert('No domain available to unbind.');
return;
}
// DE: 'Domain ${domain} von dieser Lizenz trennen?'
if (!confirm(`Unbind domain ${domain} from this license?`)) return;
btn.disabled = true;
// DE: '… entferne'
btn.textContent = '… removing';
try {
// 1) Delete domain in backend
var resp = await fetch(backendDelUrl, {
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({ license_hash: licenseHash, domain })
});
var data = await resp.json();
if (!resp.ok || !data?.ok) {
// DE: 'Entfernen fehlgeschlagen: '
alert('Unbinding failed: ' + (data?.error || resp.status));
btn.disabled = false;
// DE: 'Domain von Lizenz trennen'
btn.textContent = 'Unbind domain from license';
return;
}
// 2) Delete local license in WordPress
try {
var clearResp = await fetch(ajaxUrl, {
method: 'POST',
headers: {'Content-Type': 'application/x-www-form-urlencoded'},
body: new URLSearchParams({
action: 'a11ybridge_clear_license',
nonce: nonce
})
});
var clearJson = await clearResp.json();
if (!clearJson?.success) {
globalThis.A11yBridgeLogger.error('a11ybridge_clear_license failed:', clearJson);
}
} catch (e) {
globalThis.A11yBridgeLogger.error('Error calling a11ybridge_clear_license:', e);
}
// DE: 'Domain entfernt.'
alert('Domain removed.');
// location.reload();
location.href = window.location.href + '&t=' + Date.now();
} catch (e) {
// DE: 'Netzwerkfehler beim Entfernen der Domain.'
alert('Network error while removing domain.');
btn.disabled = false;
// DE: 'Domain von Lizenz trennen'
btn.textContent = 'Unbind domain from license';
}
});
})();
.a11yb-card { margin-top: 18px; }
.a11yb-stats-grid {
display: grid;
grid-template-columns: repeat(4, minmax(0,1fr));
gap: 12px;
margin: 10px 0 14px;
}
.a11yb-stat { background:#fff; border:1px solid #e5e5e5; border-radius:6px; padding:10px 12px; }
.a11yb-stat-label { font-size:12px; color:#666; margin-bottom:4px; }
.a11yb-stat-value { font-size:16px; font-weight:600; }
.a11yb-progress { background:#f1f1f1; border-radius:999px; height:10px; overflow:hidden; margin-top:6px; }
.a11yb-progress-bar { background:#2271b1; height:10px; }
.a11yb-progress-meta { margin-top:8px; color:#333; }
.a11yb-inline-msg { margin-left:8px; }
document.addEventListener('DOMContentLoaded', function() {
var refreshBtn = document.getElementById('refresh-license-btn');
var statusDiv = document.getElementById('license-status');
if (!refreshBtn || !statusDiv) {
return;
}
const restUrl = "";
refreshBtn.addEventListener('click', async function() {
const btn = this;
btn.disabled = true;
// DE: '🔄 Prüfe Lizenz...'
btn.textContent = '🔄 Checking license...';
statusDiv.className = 'a11y-status';
statusDiv.style.display = 'block';
// DE: 'Kontaktiere A11yBridge Server...'
statusDiv.textContent = 'Contacting A11yBridge server...';
try {
const resp = await fetch(restUrl, {
method: 'POST',
headers: {
'Content-Type': 'application/json'
// If your endpoint needs a nonce etc., add it here
},
body: JSON.stringify({ meta: { user_action: true } })
});
const data = await resp.json().catch(() => ({}));
if (!resp.ok) {
statusDiv.className = 'a11y-status error';
// DE: 'Fehler bei der Lizenzprüfung: '
statusDiv.textContent = 'Error while checking license: '
+ (data && data.message ? data.message : resp.status);
} else {
statusDiv.className = 'a11y-status success';
// DE: '✅ Lizenz-Status erfolgreich aktualisiert.'
statusDiv.textContent = data && data.message
? data.message
: '✅ License status successfully updated.';
// Reload page so that new values appear in UI
setTimeout(function() {
location.href = window.location.href + '&t=' + Date.now();
}, 1200);
}
} catch (e) {
globalThis.A11yBridgeLogger.error('Error calling license status:', e);
statusDiv.className = 'a11y-status error';
// DE: 'Netzwerkfehler bei der Lizenzprüfung.'
statusDiv.textContent = 'Network error while checking license.';
} finally {
btn.disabled = false;
// DE: '🔄 Lizenz-Status prüfen'
btn.textContent = '🔄 Check license status';
}
});
});
(function(){
var ajaxUrl = (window.A11YBRIDGE_ADMIN && window.A11YBRIDGE_ADMIN.ajaxUrl) ? window.A11YBRIDGE_ADMIN.ajaxUrl : '';
var nonce = (window.A11YBRIDGE_ADMIN && window.A11YBRIDGE_ADMIN.noncePro) ? window.A11YBRIDGE_ADMIN.noncePro : '';
var siteUrl = "";
var origin = window.location.origin;
const backendActivateUrl = "https://a11ybridge.de/wp-json/a11ybridge/v1/license/activate";
async function activateOrRebind(licenseKey) {
// 1) Send to a11ybridge.de (once in plain text)
const resp = await fetch(backendActivateUrl, {
method: 'POST',
headers: {'Content-Type':'application/json'},
body: JSON.stringify({
license_key: licenseKey || null,
domain: origin,
site_url: siteUrl,
plugin: 'a11ybridge',
plugin_version: (window.A11YBRIDGE_CONFIG && window.A11YBRIDGE_CONFIG.version) || ''
})
});
const data = await resp.json();
globalThis.A11yBridgeLogger.debug('A11yBridge activate response:', resp.status, data);
if (!resp.ok || !data?.ok) {
var msg = data?.error || ('Activation failed: ' + resp.status);
// DE: 'Aktivierung fehlgeschlagen: '
alert('Activation failed: ' + msg);
return;
}
// Response contains license_hash + license_hint + plan + bound_domain
// 2) Save locally (hash etc. only)
globalThis.A11yBridgeLogger.debug('Saving license data locally:', data);
globalThis.A11yBridgeLogger.debug('Sending to ajaxUrl:', ajaxUrl);
const save = await fetch(ajaxUrl, {
method:'POST',
headers:{'Content-Type':'application/x-www-form-urlencoded'},
body: new URLSearchParams({
action: 'a11ybridge_save_license_hash',
nonce: nonce,
license_hash: data.license_hash || data.license_key_hash,
license_hint: data.license_hint || '',
plan: data.plan || '',
domain: data.bound_domain || '',
domains: JSON.stringify(data.domains || []),
limit: data.limit ?? ''
})
});
var saved = await save.json();
if (!saved?.success) {
var msg = saved?.data?.msg || saved?.data || 'unknown error';
globalThis.A11yBridgeLogger.error('a11ybridge_pro_save_license_hash response:', saved);
// DE: 'Lokales Speichern fehlgeschlagen: '
alert('Saving license locally failed: ' + msg);
return;
}
// DE: 'Lizenz aktiviert.'
alert('License activated.');
// location.reload();
location.href = window.location.href + '&t=' + Date.now();
}
var btn = document.getElementById('ab-activate');
if (btn) {
btn.addEventListener('click', async () => {
var input = document.getElementById('ab-license-input');
var key = (input && input.value || '').trim();
if (!key || key.length < 16) {
// DE: 'Bitte gültigen Lizenzschlüssel eingeben.'
alert('Please enter a valid license key.');
return;
}
btn.disabled = true;
// DE: '… aktiviere'
btn.textContent = '… activating';
try {
await activateOrRebind(key);
} finally {
btn.disabled = false;
// DE: 'Lizenz aktivieren'
btn.textContent = 'Activate license';
}
});
}
var rebind = document.getElementById('ab-rebind');
if (rebind) {
rebind.addEventListener('click', async () => {
// DE: 'Diese Domain wird mit deiner Lizenz neu gebunden. Fortfahren?'
if (!confirm('This domain will be re-bound to your license. Continue?')) return;
rebind.disabled = true;
// DE: '… binde neu'
rebind.textContent = '… re-binding';
try {
await activateOrRebind(null);
} finally {
rebind.disabled = false;
// DE: 'Domain neu binden'
rebind.textContent = 'Re-bind domain';
}
});
}
})();