fix+polish(frontend): 预测弹窗打磨 + 全量语义色替换 + 前台交互小项

预测弹窗:
- 修复模板字符串直写 JSX,反引号原样显示在结果面板的 bug
- 入场动画(遮罩淡入+面板上浮);初始聚焦/Tab 焦点陷阱/关闭还焦;
  打开时锁定背景滚动
- 「关闭窗口即取消」→ 如实描述:前端仅停止进度显示,后台任务
  可能仍在执行并消耗额度

语义色:全部 emerald/amber/rose 裸色替换为 ok/warn/bad token
(Standings 分区与走势、KeyRing、定时任务、任务状态点、
数据完整性进度条、预测命中标记、净胜球)。

前台交互:
- 空态跳后台 a[href] → Link,不再整页刷新
- 联赛 tab 溢出右缘渐隐提示 + aria-current
- 状态行右侧计数组加细线分隔,小屏 wrap 后层级仍清晰
This commit is contained in:
WorkBuddy
2026-09-22 16:56:19 +08:00
parent 9c77efaa4b
commit 83a1eed283
7 changed files with 122 additions and 97 deletions
+3 -3
View File
@@ -333,8 +333,8 @@ export default function CollectionPage() {
)}
{taskStatus === 'done' && (
<div className="space-y-2">
<div className="flex items-center gap-2 text-xs text-emerald-700">
<span className="inline-block h-2 w-2 rounded-full bg-emerald-500" />
<div className="flex items-center gap-2 text-xs text-ok-700">
<span className="inline-block h-2 w-2 rounded-full bg-ok-500" />
<span>{jobId ? `(job ${jobId.slice(0, 8)}…)` : ''}</span>
</div>
{summary && <p className="text-2xs text-ink-500">{summary.detail}</p>}
@@ -373,7 +373,7 @@ export default function CollectionPage() {
<div>
{recentJobs.map(j => {
const st = j.status
const dot = st === 'success' ? 'bg-ink-900' : st === 'failed' ? 'bg-press' : 'bg-amber-500 animate-pulse'
const dot = st === 'success' ? 'bg-ink-900' : st === 'failed' ? 'bg-press' : 'bg-warn-500 animate-pulse'
const label = st === 'success' ? '完成' : st === 'failed' ? '失败' : st === 'running' ? '执行中' : '排队中'
return (
<div key={j.id} className="flex items-center gap-3 border-b border-ink-200 px-4 py-2.5 last:border-b-0 sm:px-5">
@@ -26,9 +26,9 @@ const FIELD_LABELS: Record<string, string> = {
}
function pctColor(pct: number): string {
if (pct >= 80) return 'bg-emerald-500'
if (pct >= 50) return 'bg-amber-500'
return 'bg-rose-500'
if (pct >= 80) return 'bg-ok-500'
if (pct >= 50) return 'bg-warn-500'
return 'bg-bad-500'
}
/** 根据问题描述生成可操作的修复链接 */
@@ -90,7 +90,7 @@ export default function PredictionHistoryPage() {
</Card>
<Card>
<CardBody className="text-center">
<p className="text-2xl font-bold text-emerald-700">{hitCount}</p>
<p className="text-2xl font-bold text-ok-700">{hitCount}</p>
<p className="text-xs text-ink-500"></p>
</CardBody>
</Card>
@@ -194,7 +194,7 @@ export default function PredictionHistoryPage() {
<td className="px-4 py-3">
{p.pred_1x2 ? (
<span className={`inline-block border px-1.5 py-0.5 text-2xs ${
predHit === true ? 'border-emerald-300 text-emerald-700 bg-emerald-50' :
predHit === true ? 'border-ok-300 text-ok-700 bg-ok-50' :
predHit === false ? 'border-press text-press bg-press-wash' :
'border-ink-200 text-ink-600'
}`}>
+3 -3
View File
@@ -317,11 +317,11 @@ export default function SettingsPage() {
return (
<div key={i} className={`flex items-center justify-between gap-3 border-b border-ink-100 py-2 last:border-b-0 ${isBlocked ? 'opacity-70' : ''}`}>
<div className="flex items-center gap-2">
<span className={`inline-block h-2 w-2 rounded-full ${isBlocked ? 'bg-amber-500' : 'bg-emerald-500'}`} />
<span className={`inline-block h-2 w-2 rounded-full ${isBlocked ? 'bg-warn-500' : 'bg-ok-500'}`} />
<span className="font-mono text-xs text-ink-700">{k.masked}</span>
{i === keyRing.active_index && <span className="rounded bg-ink-900 px-1.5 py-0.5 text-2xs text-paper-500"></span>}
</div>
<span className={`text-2xs tabular-nums ${isBlocked ? 'text-amber-600' : 'text-ink-400'}`}>
<span className={`text-2xs tabular-nums ${isBlocked ? 'text-warn-700' : 'text-ink-400'}`}>
{isBlocked ? `冷却中 ${k.blocked_remaining.toFixed(0)}s` : '可用'}
</span>
</div>
@@ -489,7 +489,7 @@ export default function SettingsPage() {
<div key={s.id} className="flex flex-col gap-2 border-b border-ink-100 py-3 last:border-b-0 sm:flex-row sm:items-center sm:justify-between">
<div className="flex-1 space-y-1">
<div className="flex items-center gap-2">
<span className={`inline-block h-2 w-2 rounded-full ${s.enabled ? 'bg-emerald-500' : 'bg-ink-300'}`} />
<span className={`inline-block h-2 w-2 rounded-full ${s.enabled ? 'bg-ok-500' : 'bg-ink-300'}`} />
<span className="text-xs font-medium text-ink-800">{s.id}</span>
<Badge status={s.enabled ? 'success' : 'muted'}>{s.task}</Badge>
</div>