feat(error-book): update components, actions, data-access, and add analytics
- Add data-access-analytics for error book analytics queries - Update actions, data-access for improved error book operations - Update components: add-error-book-dialog, analytics-stats-cards, chapter-weakness-chart, class-error-bar-chart, class-filter, error-book-detail-dialog, error-book-filters, error-book-item-card, error-book-list, error-book-stats-cards, grouped-student-error-table, knowledge-point-weakness-chart, review-buttons, subject-distribution-chart, subject-tabs, top-wrong-questions - Remove class-error-overview (replaced by new components)
This commit is contained in:
@@ -3,6 +3,7 @@
|
||||
import { useState, useTransition } from "react"
|
||||
import { RotateCcw, ThumbsUp, Check, Zap } from "lucide-react"
|
||||
import { toast } from "sonner"
|
||||
import { useTranslations } from "next-intl"
|
||||
|
||||
import { Button } from "@/shared/components/ui/button"
|
||||
import { reviewErrorBookItemAction } from "../actions"
|
||||
@@ -13,47 +14,50 @@ interface ReviewButtonsProps {
|
||||
onReviewed?: () => void
|
||||
}
|
||||
|
||||
const REVIEW_OPTIONS: Array<{
|
||||
type ReviewOption = {
|
||||
result: ErrorBookReviewResultValue
|
||||
label: string
|
||||
description: string
|
||||
icon: typeof RotateCcw
|
||||
variant: "destructive" | "secondary" | "default" | "outline"
|
||||
}> = [
|
||||
{
|
||||
result: "again",
|
||||
label: "重来",
|
||||
description: "完全不会,明天再复习",
|
||||
icon: RotateCcw,
|
||||
variant: "destructive",
|
||||
},
|
||||
{
|
||||
result: "hard",
|
||||
label: "困难",
|
||||
description: "勉强答对,2 天后复习",
|
||||
icon: Zap,
|
||||
variant: "secondary",
|
||||
},
|
||||
{
|
||||
result: "good",
|
||||
label: "良好",
|
||||
description: "正常答对,4 天后复习",
|
||||
icon: ThumbsUp,
|
||||
variant: "default",
|
||||
},
|
||||
{
|
||||
result: "easy",
|
||||
label: "简单",
|
||||
description: "轻松答对,7 天后复习",
|
||||
icon: Check,
|
||||
variant: "outline",
|
||||
},
|
||||
]
|
||||
}
|
||||
|
||||
export function ReviewButtons({ itemId, onReviewed }: ReviewButtonsProps) {
|
||||
const t = useTranslations("error-book")
|
||||
const [isPending, startTransition] = useTransition()
|
||||
const [selected, setSelected] = useState<ErrorBookReviewResultValue | null>(null)
|
||||
|
||||
const reviewOptions: ReviewOption[] = [
|
||||
{
|
||||
result: "again",
|
||||
label: t("review.again"),
|
||||
description: t("review.againDesc"),
|
||||
icon: RotateCcw,
|
||||
variant: "destructive",
|
||||
},
|
||||
{
|
||||
result: "hard",
|
||||
label: t("review.hard"),
|
||||
description: t("review.hardDesc"),
|
||||
icon: Zap,
|
||||
variant: "secondary",
|
||||
},
|
||||
{
|
||||
result: "good",
|
||||
label: t("review.good"),
|
||||
description: t("review.goodDesc"),
|
||||
icon: ThumbsUp,
|
||||
variant: "default",
|
||||
},
|
||||
{
|
||||
result: "easy",
|
||||
label: t("review.easy"),
|
||||
description: t("review.easyDesc"),
|
||||
icon: Check,
|
||||
variant: "outline",
|
||||
},
|
||||
]
|
||||
|
||||
function handleReview(result: ErrorBookReviewResultValue) {
|
||||
setSelected(result)
|
||||
startTransition(async () => {
|
||||
@@ -61,10 +65,10 @@ export function ReviewButtons({ itemId, onReviewed }: ReviewButtonsProps) {
|
||||
formData.append("json", JSON.stringify({ itemId, result }))
|
||||
const res = await reviewErrorBookItemAction(undefined, formData)
|
||||
if (res.success) {
|
||||
toast.success(res.message ?? "复习结果已记录")
|
||||
toast.success(res.message ?? t("messages.reviewRecorded"))
|
||||
onReviewed?.()
|
||||
} else {
|
||||
toast.error(res.message ?? "记录失败")
|
||||
toast.error(res.message ?? t("messages.recordFailed"))
|
||||
setSelected(null)
|
||||
}
|
||||
})
|
||||
@@ -72,7 +76,7 @@ export function ReviewButtons({ itemId, onReviewed }: ReviewButtonsProps) {
|
||||
|
||||
return (
|
||||
<div className="grid grid-cols-2 gap-2 sm:grid-cols-4">
|
||||
{REVIEW_OPTIONS.map((opt) => {
|
||||
{reviewOptions.map((opt) => {
|
||||
const Icon = opt.icon
|
||||
const isLoading = isPending && selected === opt.result
|
||||
return (
|
||||
|
||||
Reference in New Issue
Block a user