撤回孩子端单词页网格;家长端跟读录音列表改一行多个(换行排布)

- 撤回 word-day 网格改动,恢复原卡片布局
- 家长端"单词跟读录音"(课程管理+学习概览)改为圆角标签自动换行,
  一行多个,每个含单词+播放按钮

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
jacobxu666
2026-08-05 21:53:01 +08:00
co-authored by Claude Opus 4.8
parent b63ccdfa9e
commit 673d1bc511
3 changed files with 22 additions and 27 deletions
+5 -5
View File
@@ -151,13 +151,13 @@ export function ParentDashboard({
</div> </div>
<div className="rounded-xl border border-slate-100 bg-white p-4 shadow-soft sm:col-span-2"> <div className="rounded-xl border border-slate-100 bg-white p-4 shadow-soft sm:col-span-2">
<p className="font-bold text-slate-900">🎙️ 单词跟读录音</p> <p className="font-bold text-slate-900">🎙️ 单词跟读录音</p>
<div className="mt-2 space-y-2"> <div className="mt-2 flex flex-wrap gap-2">
{recordings.length === 0 && <p className="text-xs text-muted-foreground">暂无跟读录音</p>} {recordings.length === 0 && <p className="text-xs text-muted-foreground">暂无跟读录音</p>}
{recordings.map((r, i) => ( {recordings.map((r, i) => (
<div key={i} className="flex items-center gap-2 text-sm"> <div key={i} className="flex items-center gap-1.5 rounded-full bg-slate-50 px-2.5 py-1 text-sm ring-1 ring-slate-100">
<span className="w-16 shrink-0 text-xs text-muted-foreground">{r.childName}</span> <span className="text-xs text-muted-foreground">{r.childName}</span>
<span className="w-20 shrink-0 font-medium text-slate-800">{r.word}</span> <span className="font-medium text-slate-800">{r.word}</span>
<PlayBtn src={r.url} /> <PlayBtn src={r.url} className="size-6" />
</div> </div>
))} ))}
</div> </div>
+4 -4
View File
@@ -157,11 +157,11 @@ export function OverviewTab({ data }: { data: OverviewData }) {
{cell.recs.length === 0 ? ( {cell.recs.length === 0 ? (
<p className="text-sm text-muted-foreground">当天无跟读录音</p> <p className="text-sm text-muted-foreground">当天无跟读录音</p>
) : ( ) : (
<div className="space-y-1.5"> <div className="flex flex-wrap gap-2">
{cell.recs.map((r, i) => ( {cell.recs.map((r, i) => (
<div key={i} className="flex items-center gap-2 text-sm"> <div key={i} className="flex items-center gap-1.5 rounded-full bg-white px-2.5 py-1 text-sm ring-1 ring-slate-100">
<span className="w-20 shrink-0 font-medium text-slate-800">{r.word}</span> <span className="font-medium text-slate-800">{r.word}</span>
<PlayBtn src={r.url} /> <PlayBtn src={r.url} className="size-6" />
</div> </div>
))} ))}
</div> </div>
+13 -18
View File
@@ -136,39 +136,34 @@ export function WordDayClient({
<span className="text-xs text-muted-foreground">已学 {learnedSet.size}/{items.length}</span> <span className="text-xs text-muted-foreground">已学 {learnedSet.size}/{items.length}</span>
</header> </header>
<div className="grid grid-cols-2 gap-2 sm:grid-cols-3"> <div className="space-y-2">
{items.map((it) => { {items.map((it) => {
const done = learnedSet.has(it.word); const done = learnedSet.has(it.word);
return ( return (
<div key={it.word} className="rounded-xl border border-slate-100 bg-white p-2.5 shadow-soft"> <div key={it.word} className="rounded-xl border border-slate-100 bg-white p-3 shadow-soft">
<div className="flex items-center gap-1.5"> <div className="flex items-center gap-2">
<button type="button" onClick={() => speak(it.word)} className="shrink-0 text-indigo-600" title="发音"> <button type="button" onClick={() => speak(it.word)} className="text-indigo-600" title="发音">
<Volume2 className="size-4" /> <Volume2 className="size-5" />
</button> </button>
<button type="button" onClick={() => openDetail(it.word)} className="min-w-0 flex-1 truncate text-left text-sm font-bold text-slate-900"> <button type="button" onClick={() => openDetail(it.word)} className="text-left">
{it.word} <span className="text-base font-bold text-slate-900">{it.word}</span>
</button> </button>
<span className="ml-1 flex-1 truncate text-sm text-muted-foreground">{it.meaning}</span>
<RecordBtn day={day} word={it.word} />
<button <button
type="button" type="button"
onClick={() => toggleLearn(it.word)} onClick={() => toggleLearn(it.word)}
className={cn( className={cn(
"flex size-6 shrink-0 items-center justify-center rounded-full border-2", "flex size-8 shrink-0 items-center justify-center rounded-full border-2",
done ? "border-transparent bg-gradient-to-br from-emerald-400 to-emerald-600 text-white" : "border-slate-300", done ? "border-transparent bg-gradient-to-br from-emerald-400 to-emerald-600 text-white" : "border-slate-300",
)} )}
title="学会" title="学会"
> >
{done && <Check className="size-3.5" strokeWidth={3} />} {done && <Check className="size-4" strokeWidth={3} />}
</button>
</div>
<p className="mt-1 truncate text-xs text-muted-foreground">{it.meaning}</p>
<div className="mt-1.5 flex items-center justify-between">
<RecordBtn day={day} word={it.word} />
<button type="button" onClick={() => openDetail(it.word)} className="text-xs text-indigo-600">
详情
</button> </button>
</div> </div>
{open === it.word && ( {open === it.word && (
<div className="mt-2 space-y-1 rounded-lg bg-slate-50 p-2 text-xs"> <div className="mt-2 space-y-1 rounded-lg bg-slate-50 p-2 text-sm">
<p className="text-slate-800"> <p className="text-slate-800">
<span className="font-medium text-indigo-600">释义:</span> <span className="font-medium text-indigo-600">释义:</span>
{it.meaning || "见例句"} {it.meaning || "见例句"}
@@ -179,7 +174,7 @@ export function WordDayClient({
</p> </p>
<p className="text-slate-700"> <p className="text-slate-700">
<span className="font-medium text-indigo-600">形近词:</span> <span className="font-medium text-indigo-600">形近词:</span>
{it.similar.map((s) => s.word).join("、") || "无"} {it.similar.map((s) => `${s.word}(${s.meaning})`).join("、") || "无"}
</p> </p>
</div> </div>
)} )}