diff --git a/resources/js/admin/holiday-events.js b/resources/js/admin/holiday-events.js new file mode 100644 index 0000000..540ce0e --- /dev/null +++ b/resources/js/admin/holiday-events.js @@ -0,0 +1,130 @@ +// 节日福利后台事件代理,替代 Blade 内联启停、触发和删除确认逻辑。 + +let adminHolidayEventsControlsBound = false; + +const enabledButtonClasses = + "inline-flex items-center gap-2 rounded-lg px-3 py-2 text-xs font-bold transition bg-emerald-500 text-white hover:bg-emerald-600"; +const disabledButtonClasses = + "inline-flex items-center gap-2 rounded-lg px-3 py-2 text-xs font-bold transition bg-slate-200 text-slate-600 hover:bg-slate-300"; +const enabledBadgeClasses = + "inline-flex rounded-full px-2.5 py-1 text-xs font-bold bg-emerald-100 text-emerald-700"; +const disabledBadgeClasses = + "inline-flex rounded-full px-2.5 py-1 text-xs font-bold bg-slate-100 text-slate-500"; + +/** + * 读取 CSRF 令牌,供后台 AJAX 状态切换请求使用。 + * + * @returns {string} + */ +function getCsrfToken() { + return document.querySelector('meta[name="csrf-token"]')?.getAttribute("content") ?? ""; +} + +/** + * 根据启用状态返回按钮文案。 + * + * @param {boolean} enabled + * @returns {string} + */ +function getToggleButtonLabel(enabled) { + return enabled ? "切换为停用" : "重新启用模板"; +} + +/** + * 同步当前行的启停按钮、徽标和透明度。 + * + * @param {HTMLButtonElement} button + * @param {boolean} enabled + * @returns {void} + */ +function renderHolidayEnabledState(button, enabled) { + const row = button.closest("tr"); + const dot = button.querySelector('[data-role="toggle-dot"]'); + const label = button.querySelector('[data-role="toggle-label"]'); + const enabledBadge = row?.querySelector('[data-role="enabled-badge"]'); + + button.dataset.enabled = enabled ? "1" : "0"; + button.className = enabled ? enabledButtonClasses : disabledButtonClasses; + + if (dot) { + dot.className = enabled ? "h-2 w-2 rounded-full bg-white" : "h-2 w-2 rounded-full bg-slate-500"; + } + + if (label) { + label.textContent = getToggleButtonLabel(enabled); + } + + if (enabledBadge) { + enabledBadge.className = enabled ? enabledBadgeClasses : disabledBadgeClasses; + enabledBadge.textContent = enabled ? "已启用" : "已停用"; + } + + row?.classList.toggle("opacity-60", !enabled); +} + +/** + * 切换节日活动启用状态,并在成功后刷新当前行状态。 + * + * @param {HTMLButtonElement} button + * @returns {Promise} + */ +async function toggleHolidayEvent(button) { + const toggleUrl = button.getAttribute("data-holiday-event-toggle-url"); + if (!toggleUrl) { + return; + } + + const response = await fetch(toggleUrl, { + method: "POST", + headers: { + "X-CSRF-TOKEN": getCsrfToken(), + Accept: "application/json", + }, + }); + const data = await response.json(); + + if (!data.ok) { + return; + } + + renderHolidayEnabledState(button, Boolean(data.enabled)); +} + +/** + * 绑定节日福利后台页操作。 + * + * @returns {void} + */ +export function bindAdminHolidayEventsControls() { + if (adminHolidayEventsControlsBound || typeof document === "undefined") { + return; + } + + adminHolidayEventsControlsBound = true; + + document.addEventListener("click", (event) => { + if (!(event.target instanceof Element)) { + return; + } + + const toggleButton = event.target.closest("[data-holiday-event-toggle-url]"); + if (!(toggleButton instanceof HTMLButtonElement)) { + return; + } + + event.preventDefault(); + void toggleHolidayEvent(toggleButton); + }); + + document.addEventListener("submit", (event) => { + if (!(event.target instanceof HTMLFormElement)) { + return; + } + + // 立即触发和删除都会改变活动状态,提交前统一读取 Blade 声明的确认文案。 + const confirmMessage = event.target.getAttribute("data-holiday-event-confirm"); + if (confirmMessage && !window.confirm(confirmMessage)) { + event.preventDefault(); + } + }); +} diff --git a/resources/js/app.js b/resources/js/app.js index ef5e9b4..c241ea8 100644 --- a/resources/js/app.js +++ b/resources/js/app.js @@ -2,6 +2,7 @@ import './bootstrap'; import { bindAdminAutoactControls } from './admin/autoact.js'; import { bindAdminFishingEventsControls } from './admin/fishing-events.js'; import { bindAdminGameConfigControls } from './admin/game-configs.js'; +import { bindAdminHolidayEventsControls } from './admin/holiday-events.js'; import { bindAdminOpsControls } from './admin/ops.js'; import { bindAdminRoomControls } from './admin/rooms.js'; import { bindAdminSignInRulesControls } from './admin/sign-in-rules.js'; @@ -10,6 +11,7 @@ import { bindAdminSignInRulesControls } from './admin/sign-in-rules.js'; bindAdminAutoactControls(); bindAdminFishingEventsControls(); bindAdminGameConfigControls(); +bindAdminHolidayEventsControls(); bindAdminOpsControls(); bindAdminRoomControls(); bindAdminSignInRulesControls(); diff --git a/resources/views/admin/holiday-events/index.blade.php b/resources/views/admin/holiday-events/index.blade.php index 74f37ab..e241622 100644 --- a/resources/views/admin/holiday-events/index.blade.php +++ b/resources/views/admin/holiday-events/index.blade.php @@ -178,7 +178,7 @@