第一期:家庭自学打卡系统
- 家长手机号登录 + 孩子设备一次性激活(长期会话) - 周模板自动生成每日任务快照,支持拍照凭证直传对象存储 - 连击计算(空白日自动达成)、家长补卡带标记 - 家长端三标签:今日概览 / 任务模板 / 设备管理 - Docker 独立输出,经 Traefik 接入 jump.hn12301.net Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,62 @@
|
||||
import { Flame } from "lucide-react";
|
||||
import { redirect } from "next/navigation";
|
||||
import { todayStr } from "@/lib/dates";
|
||||
import { getSessionUser } from "@/lib/auth";
|
||||
import { streakOf } from "@/lib/streak";
|
||||
import { dayTasks } from "@/lib/tasks";
|
||||
import { TaskCard } from "./task-card";
|
||||
|
||||
export default async function KidPage() {
|
||||
const user = await getSessionUser();
|
||||
if (!user) redirect("/join");
|
||||
if (user.role !== "child") redirect("/parent");
|
||||
|
||||
const today = todayStr();
|
||||
const [tasks, streak] = await Promise.all([
|
||||
dayTasks(user.id, today),
|
||||
streakOf(user.id),
|
||||
]);
|
||||
const doneCount = tasks.filter((t) => t.status === "done").length;
|
||||
const allDone = tasks.length > 0 && doneCount === tasks.length;
|
||||
|
||||
return (
|
||||
<main className="mx-auto max-w-lg space-y-5 p-4 pb-10">
|
||||
<header className="flex items-center justify-between">
|
||||
<div>
|
||||
<h1 className="text-2xl font-bold">你好,{user.displayName}</h1>
|
||||
<p className="text-sm text-muted-foreground">{today}</p>
|
||||
</div>
|
||||
<div className="flex items-center gap-1 rounded-full bg-orange-100 px-4 py-2 text-orange-600">
|
||||
<Flame className="size-6" fill="currentColor" />
|
||||
<span className="text-xl font-bold">{streak}</span>
|
||||
<span className="text-sm">天</span>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
{tasks.length === 0 ? (
|
||||
<div className="rounded-2xl bg-muted p-8 text-center">
|
||||
<p className="text-2xl">🎉</p>
|
||||
<p className="mt-2 text-lg font-medium">今天没有任务</p>
|
||||
<p className="mt-1 text-sm text-muted-foreground">连击自动保持,去玩吧!</p>
|
||||
</div>
|
||||
) : (
|
||||
<>
|
||||
<p className="text-sm text-muted-foreground">
|
||||
已完成 {doneCount} / {tasks.length} 项
|
||||
</p>
|
||||
<div className="space-y-3">
|
||||
{tasks.map((t) => (
|
||||
<TaskCard key={t.id} task={t} />
|
||||
))}
|
||||
</div>
|
||||
{allDone && (
|
||||
<div className="rounded-2xl bg-green-100 p-6 text-center">
|
||||
<p className="text-2xl">💪</p>
|
||||
<p className="mt-2 text-lg font-bold text-green-700">今天全部完成,太棒了!</p>
|
||||
</div>
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
</main>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user