"use client"; import Link from "next/link"; import { useEffect, useMemo, useState } from "react"; import { ArrowLeft, CheckCircle2, Circle, ListChecks } from "lucide-react"; import { Progress } from "@/components/ui/progress"; import { TaskKey, plan } from "../plan"; type Rec = { doneTasks: string }; const groups: { key: TaskKey; title: string; hint: string; color: string }[] = [ { key: "vocab", title: "词汇", hint: "积累与回炉高频词、搭配和错词", color: "blue" }, { key: "listening", title: "听力", hint: "长对话、讲座、精听与模考", color: "violet" }, { key: "reading", title: "阅读", hint: "仔细阅读、长篇匹配和错题复盘", color: "teal" }, { key: "output", title: "输出", hint: "写作、翻译与可复用表达", color: "orange" }, { key: "review", title: "复盘", hint: "记录错因、用时与下阶段重点", color: "rose" }, ]; const parsed = (value?: string) => { try { return JSON.parse(value || "[]") as string[]; } catch { return []; } }; export default function TasksClient() { const [records, setRecords] = useState>({}); const [active, setActive] = useState("vocab"); const [status, setStatus] = useState("正在读取完成情况…"); useEffect(() => { fetch("/api/progress").then(async r => { const x = await r.json(); if (!r.ok) throw Error(x.error); const all: Record = {}; x.progress.forEach((p: Rec & { planDate: string }) => all[p.planDate] = p); setRecords(all); setStatus("已同步云端进度"); }).catch(e => setStatus(e.message)); }, []); const overview = useMemo(() => groups.map(group => { const tasks = plan.flatMap(day => day.tasks.filter(task => task.key === group.key).map(task => ({ ...task, date: day.date, week: day.week, phase: day.phase }))); const complete = tasks.filter(task => parsed(records[task.date]?.doneTasks).includes(group.key)).length; return { ...group, tasks, complete }; }), [records]); const selected = overview.find(x => x.key === active)!; return

PLAN OVERVIEW

任务总览

按任务类型查看全部安排和完成情况。

返回打卡

{status}

{overview.map(group => )}

{selected.title.toUpperCase()}

{selected.title}任务

{selected.hint}

{selected.complete} / {selected.tasks.length}已完成
{selected.tasks.map((task, i) => { const complete = parsed(records[task.date]?.doneTasks).includes(active); return {complete ? : }
{task.date.slice(5).replace("-", "月")}日 · {task.week}

{task.text}

{task.phase}; })}
; }