Files
Toolbox/public/tools/web_mp_time_assistant/hub.js
T
yangxiangyuan d4bf3627fd feat: 新增运动节拍训练工具套件与子工具页面
新增运动节拍RepClock全套小程序页面、后端API与数据库服务,新增subhub子工具汇总页面,优化全局主页样式与配置,为web静态资源添加版本缓存参数,补充配套调试脚本
2026-09-09 14:43:06 +08:00

85 lines
2.7 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
(function () {
const api = window.__MPTA_API__
const $grid = document.getElementById('kit-grid')
const $status = document.getElementById('status-tag')
const KIT_PAGES = {
personal_collect: 'kits/personal_collect/list.html',
rep_clock: 'kits/rep_clock/cards.html',
}
const KIT_ICONS = {
personal_collect: '📁',
rep_clock: '⏱️',
}
const HERO_EMOJI = '🧘'
const HERO_TITLE = '每一次节奏,都是一次呼吸。'
const HERO_DESC = '独立工具集合,互不干扰,可独立部署,可独立关闭。'
function setStatus(text, cls) {
$status.textContent = text
$status.className = 'status-tag' + (cls ? ' ' + cls : '')
}
function escapeHtml(s) {
if (s === null || s === undefined) return ''
return String(s)
.replace(/&/g, '&')
.replace(/</g, '&lt;')
.replace(/>/g, '&gt;')
.replace(/"/g, '&quot;')
.replace(/'/g, '&#39;')
}
function renderKits(kits) {
if (!kits || !kits.length) {
$grid.innerHTML = '<div class="kit-empty">暂无可用工具</div>'
return
}
$grid.innerHTML = kits.map((kit) => {
const page = KIT_PAGES[kit.id] || '#'
const icon = kit.icon || KIT_ICONS[kit.id] || '🧰'
const meta = kit.meta ? `<div class="kit-meta">${escapeHtml(kit.meta)}</div>` : ''
return (
`<div class="kit-card" data-kit="${escapeHtml(kit.id)}" data-page="${escapeHtml(page)}">` +
`<div class="kit-icon">${icon}</div>` +
`<div class="kit-body">` +
`<div class="kit-name">${escapeHtml(kit.name || kit.id)}</div>` +
`<div class="kit-desc">${escapeHtml(kit.description || '')}</div>` +
meta +
`</div>` +
`<div class="chevron">›</div>` +
`</div>`
)
}).join('')
Array.from($grid.querySelectorAll('.kit-card')).forEach((card) => {
card.addEventListener('click', () => {
const page = card.getAttribute('data-page')
const kitId = card.getAttribute('data-kit')
const go = () => { window.location.href = page }
if (api && api.hub && api.hub.setActiveKit) {
api.hub.setActiveKit(kitId).then(go).catch(go)
} else {
go()
}
})
})
}
async function main() {
try {
if (!api || !api.hub) throw new Error('API 未加载')
const meta = await api.hub.meta()
const kits = (meta && meta.kits) || []
setStatus('后端已连通', 'ok')
renderKits(kits)
} catch (e) {
setStatus('后端连通失败:' + (e.message || '未知错误'), 'err')
$grid.innerHTML = `<div class="kit-empty">❌ 加载失败:${escapeHtml(e.message || '后端无响应')}</div>`
}
}
document.addEventListener('DOMContentLoaded', main)
})()