@@ -0,0 +1,36 @@
|
||||
import { Library, GraduationCap, Star, Repeat } from "lucide-react"
|
||||
import type { KnowledgeItem } from "@/lib/types"
|
||||
|
||||
export function StatsBar({ items }: { items: KnowledgeItem[] }) {
|
||||
const total = items.length
|
||||
const mastered = items.filter((i) => i.mastery === "mastered").length
|
||||
const favorites = items.filter((i) => i.is_favorite).length
|
||||
const now = Date.now()
|
||||
const due = items.filter((i) => i.next_review_at && new Date(i.next_review_at).getTime() <= now).length
|
||||
const masteredPct = total ? Math.round((mastered / total) * 100) : 0
|
||||
|
||||
const stats = [
|
||||
{ label: "知识点总数", value: total, icon: Library, hint: "全部收录" },
|
||||
{ label: "已掌握", value: mastered, icon: GraduationCap, hint: `${masteredPct}% 掌握率` },
|
||||
{ label: "已收藏", value: favorites, icon: Star, hint: "重点关注" },
|
||||
{ label: "待复习", value: due, icon: Repeat, hint: "今日到期" },
|
||||
]
|
||||
|
||||
return (
|
||||
<div className="grid grid-cols-2 gap-3 lg:grid-cols-4">
|
||||
{stats.map((s) => (
|
||||
<div
|
||||
key={s.label}
|
||||
className="rounded-xl border border-border bg-card/60 p-4 backdrop-blur-sm"
|
||||
>
|
||||
<div className="flex items-center justify-between">
|
||||
<span className="text-xs text-muted-foreground">{s.label}</span>
|
||||
<s.icon className="size-4 text-primary" />
|
||||
</div>
|
||||
<p className="mt-2 font-mono text-2xl font-semibold tracking-tight">{s.value}</p>
|
||||
<p className="mt-1 text-xs text-muted-foreground">{s.hint}</p>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user