From 71caf0de193d21ce009ecc6b0392de7f0f5e1af4 Mon Sep 17 00:00:00 2001 From: cryptocommuniums-afk Date: Sun, 15 Mar 2026 17:34:24 +0800 Subject: [PATCH] Show precise record times and action summaries --- client/src/lib/changelog.ts | 16 +++++++ client/src/pages/Progress.tsx | 80 ++++++++++++++++++++++++++-------- client/src/pages/Reminders.tsx | 8 +++- docs/CHANGELOG.md | 18 ++++++++ 4 files changed, 103 insertions(+), 19 deletions(-) diff --git a/client/src/lib/changelog.ts b/client/src/lib/changelog.ts index 7a2fe9e..43a9373 100644 --- a/client/src/lib/changelog.ts +++ b/client/src/lib/changelog.ts @@ -8,6 +8,22 @@ export type ChangeLogEntry = { }; export const CHANGE_LOG_ENTRIES: ChangeLogEntry[] = [ + { + version: "2026.03.15-progress-time-actions", + releaseDate: "2026-03-15", + repoVersion: "pending-commit", + summary: "最近训练记录默认显示具体上海时间,并直接展示录制动作数据摘要。", + features: [ + "最近训练记录摘要行默认显示到秒的 Asia/Shanghai 时间", + "录制记录列表直接展示主动作和前 3 个动作统计,无需先展开", + "展开态动作明细统一用中文动作标签展示", + "提醒页通知时间统一切换为 Asia/Shanghai", + ], + tests: [ + "pnpm check", + "pnpm build", + ], + }, { version: "2026.03.15-session-changelog", releaseDate: "2026-03-15", diff --git a/client/src/pages/Progress.tsx b/client/src/pages/Progress.tsx index 8c109ac..76ea624 100644 --- a/client/src/pages/Progress.tsx +++ b/client/src/pages/Progress.tsx @@ -13,6 +13,28 @@ import { } from "recharts"; import { useLocation } from "wouter"; +const ACTION_LABEL_MAP: Record = { + forehand: "正手挥拍", + backhand: "反手挥拍", + serve: "发球", + volley: "截击", + overhead: "高压", + slice: "切削", + lob: "挑高球", + unknown: "未知动作", +}; + +function getRecordMetadata(record: any) { + if (!record?.metadata || typeof record.metadata !== "object") { + return null; + } + return record.metadata as Record; +} + +function getActionLabel(actionType: string) { + return ACTION_LABEL_MAP[actionType] || actionType; +} + export default function Progress() { const { user } = useAuth(); const { data: records, isLoading } = trpc.record.list.useQuery({ limit: 100 }); @@ -181,7 +203,16 @@ export default function Progress() { {(records?.length || 0) > 0 ? (
- {(records || []).slice(0, 20).map((record: any) => ( + {(records || []).slice(0, 20).map((record: any) => { + const metadata = getRecordMetadata(record); + const actionSummary = metadata?.actionSummary && typeof metadata.actionSummary === "object" + ? Object.entries(metadata.actionSummary as Record).filter(([, count]) => Number(count) > 0) + : []; + const topActions = actionSummary + .sort((left, right) => Number(right[1]) - Number(left[1])) + .slice(0, 3); + + return (
@@ -193,15 +224,27 @@ export default function Progress() {

{record.exerciseName}

- {formatDateTimeShanghai(record.trainingDate || record.createdAt)} + {formatDateTimeShanghai(record.trainingDate || record.createdAt, { second: "2-digit" })} {record.durationMinutes ? ` · ${record.durationMinutes}分钟` : ""} {record.sourceType ? ` · ${record.sourceType}` : ""}

- {record.actionCount ? ( -

- 动作数 {record.actionCount} -

- ) : null} +
+ {record.actionCount ? ( + + 动作数 {record.actionCount} + + ) : null} + {metadata?.dominantAction ? ( + + 主动作 {getActionLabel(String(metadata.dominantAction))} + + ) : null} + {topActions.map(([actionType, count]) => ( + + {getActionLabel(actionType)} {count} 次 + + ))} +
@@ -236,36 +279,36 @@ export default function Progress() {
- {record.metadata ? ( + {metadata ? (
- {record.metadata.dominantAction ? ( + {metadata.dominantAction ? (
主动作
-
{String(record.metadata.dominantAction)}
+
{getActionLabel(String(metadata.dominantAction))}
) : null} - {record.metadata.actionSummary && Object.keys(record.metadata.actionSummary).length > 0 ? ( + {metadata.actionSummary && Object.keys(metadata.actionSummary).length > 0 ? (
动作明细
- {Object.entries(record.metadata.actionSummary as Record) + {Object.entries(metadata.actionSummary as Record) .filter(([, count]) => Number(count) > 0) .map(([actionType, count]) => ( - {actionType} {count} 次 + {getActionLabel(actionType)} {count} 次 ))}
) : null} - {record.metadata.validityStatus ? ( + {metadata.validityStatus ? (
录制有效性
-
{String(record.metadata.validityStatus)}
- {record.metadata.invalidReason ? ( -
{String(record.metadata.invalidReason)}
+
{String(metadata.validityStatus)}
+ {metadata.invalidReason ? ( +
{String(metadata.invalidReason)}
) : null}
) : null} @@ -281,7 +324,8 @@ export default function Progress() {
) : null}
- ))} + ); + })}
) : (
diff --git a/client/src/pages/Reminders.tsx b/client/src/pages/Reminders.tsx index 9688a26..49f0b1d 100644 --- a/client/src/pages/Reminders.tsx +++ b/client/src/pages/Reminders.tsx @@ -1,5 +1,6 @@ import { useAuth } from "@/_core/hooks/useAuth"; import { trpc } from "@/lib/trpc"; +import { formatDateTimeShanghai } from "@/lib/time"; import { Button } from "@/components/ui/button"; import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"; import { Badge } from "@/components/ui/badge"; @@ -458,7 +459,12 @@ export default function Reminders() {
- {new Date(notif.createdAt).toLocaleString("zh-CN", { month: "short", day: "numeric", hour: "2-digit", minute: "2-digit" })} + {formatDateTimeShanghai(notif.createdAt, { + year: undefined, + second: undefined, + month: "short", + day: "numeric", + })} diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md index 138e23f..cffb57f 100644 --- a/docs/CHANGELOG.md +++ b/docs/CHANGELOG.md @@ -1,5 +1,23 @@ # Tennis Training Hub - 变更日志 +## 2026.03.15-progress-time-actions (2026-03-15) + +### 功能更新 + +- 最近训练记录摘要行默认显示到秒的具体时间,统一按 `Asia/Shanghai` 展示 +- 录制类训练记录在列表中直接显示动作数、主动作和前 3 个动作统计 +- 训练记录展开态中的动作明细改为中文动作标签,便于直接阅读 +- 提醒页通知时间统一切换为 `Asia/Shanghai` + +### 测试 + +- `pnpm check` +- `pnpm build` + +### 仓库版本 + +- `pending-commit` + ## 2026.03.15-session-changelog (2026-03-15) ### 功能更新