Files
wordpress-theme-aksrt/assets/js/links-submit.js
T
kate522andClaude Opus 5 4c562428b4 feat(links): move friend links to native WordPress links with review flow
- enable the native Links manager and drop the custom friend-link option/REST path
- add per-page link settings for the friends template
- render link categories from get_bookmarks() with search and page-content options
- add a validated public link submission endpoint with logo upload, captcha, rate limiting and duplicate checks
- create pending links for review and notify administrators by email and in-app message
- add native Links admin pending count, columns and edit notes
- cover the new submission and cleanup contracts

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-11-05 19:54:33 +08:00

88 lines
3.0 KiB
JavaScript

/**
* Native link submission form.
*
* @package Jio
*/
(function () {
'use strict';
var cfg = window.jioLinksSubmit || {};
var i18n = cfg.i18n || {};
var form = document.querySelector('.jio-links-submit-form');
if (!form) return;
var button = form.querySelector('.jio-links-submit-btn');
var status = form.querySelector('.jio-links-submit-status');
var logoInput = form.querySelector('.jio-links-logo-input');
var preview = form.querySelector('.jio-links-logo-preview');
function setStatus(message, type) {
if (!status) return;
status.textContent = message || '';
status.className = 'jio-links-submit-status' + (type ? ' text-' + type : '');
}
if (logoInput && preview) {
logoInput.addEventListener('change', function () {
var file = logoInput.files && logoInput.files[0];
if (!file) return;
preview.src = URL.createObjectURL(file);
});
}
form.addEventListener('submit', function (event) {
event.preventDefault();
if (button && button.disabled) return;
var payload = new FormData(form);
var original = button ? button.innerHTML : '';
if (button) {
button.disabled = true;
button.innerHTML = '<i class="fa fas fa-spinner fa-spin"></i> ' + (i18n.submitting || '正在提交…');
}
setStatus(i18n.submitting || '正在提交…', 'muted');
var captcha = window.JioCaptcha;
var captchaPromise = captcha ? captcha.run('friend_link', form) : Promise.resolve({});
captchaPromise.then(function (tokens) {
if (tokens === null) throw new Error(i18n.captcha || '请完成人机验证');
Object.keys(tokens || {}).forEach(function (key) {
payload.set(key, tokens[key]);
});
return fetch(cfg.ajaxUrl || '/wp-admin/admin-ajax.php', {
method: 'POST',
credentials: 'same-origin',
body: payload,
});
}).then(function (response) {
return response.json().then(function (body) {
return { ok: response.ok, body: body };
});
}).then(function (result) {
var body = result.body || {};
var data = body.data || {};
if (!result.ok || !body.success) {
throw new Error(data.message || i18n.error || '提交失败,请重试');
}
setStatus(data.message || i18n.success || '提交成功', 'success');
form.reset();
if (preview) preview.src = '';
if (button) button.disabled = false;
if (button) button.innerHTML = original;
if (captcha) captcha.reset('friend_link', form);
window.setTimeout(function () {
var modal = document.getElementById('submit-links-modal');
if (modal) modal.classList.remove('show', 'is-open');
setStatus('', '');
}, 1800);
}).catch(function (error) {
setStatus(error.message || i18n.error || '提交失败,请重试', 'danger');
if (button) {
button.disabled = false;
button.innerHTML = original;
}
if (captcha) captcha.reset('friend_link', form);
});
});
})();