116 lines
4.5 KiB
TypeScript
116 lines
4.5 KiB
TypeScript
import { requireAuth } from "@/lib/session";
|
||
import { db } from "@/lib/db";
|
||
import { formatPersianDate, formatPersianDateTime } from "@/lib/persianDate";
|
||
|
||
export default async function QuizHistoryPage() {
|
||
const session = await requireAuth();
|
||
const userId = (session.user as any).id;
|
||
|
||
const submissions = await db.quizSubmission.findMany({
|
||
where: { userId },
|
||
include: {
|
||
quiz: {
|
||
include: { questions: { orderBy: { order: "asc" } } },
|
||
},
|
||
},
|
||
orderBy: { submittedAt: "desc" },
|
||
});
|
||
|
||
return (
|
||
<div className="min-h-screen bg-gray-950 text-white py-10 px-4">
|
||
<div className="max-w-3xl mx-auto">
|
||
<h1 className="text-2xl font-bold mb-6">تاریخچه کوییزها</h1>
|
||
|
||
{submissions.length === 0 && (
|
||
<div className="text-center py-20 text-gray-500">
|
||
<div className="text-5xl mb-4">📋</div>
|
||
<p>هنوز در هیچ کوییزی شرکت نکردهاید</p>
|
||
</div>
|
||
)}
|
||
|
||
<div className="flex flex-col gap-4">
|
||
{submissions.map((sub) => {
|
||
const correct = sub.answers.filter((ans, i) => ans === sub.quiz.questions[i]?.correctAnswer).length;
|
||
const total = sub.quiz.questions.length;
|
||
|
||
return (
|
||
<div
|
||
key={sub.id}
|
||
className={`bg-white/5 backdrop-blur border rounded-2xl p-5 ${
|
||
sub.score === 100 ? "border-yellow-400/30" : "border-white/10"
|
||
}`}
|
||
>
|
||
<div className="flex justify-between items-start mb-3">
|
||
<div>
|
||
<p className="font-bold text-lg">
|
||
{formatPersianDate(new Date(sub.quiz.date))}
|
||
</p>
|
||
<p className="text-xs text-gray-400">
|
||
{formatPersianDateTime(new Date(sub.submittedAt))}
|
||
</p>
|
||
</div>
|
||
<div className="text-left">
|
||
<div
|
||
className={`text-2xl font-black ${
|
||
sub.score === 100
|
||
? "text-yellow-400"
|
||
: sub.score >= 50
|
||
? "text-green-400"
|
||
: "text-red-400"
|
||
}`}
|
||
>
|
||
{sub.score}%
|
||
</div>
|
||
<p className="text-xs text-gray-400">
|
||
{correct} از {total}
|
||
</p>
|
||
</div>
|
||
</div>
|
||
|
||
{sub.score === 100 && (
|
||
<div className="bg-yellow-400/10 border border-yellow-400/30 rounded-lg px-3 py-2 text-xs text-yellow-300 flex items-center gap-2">
|
||
<span>🏆</span>
|
||
<span>واجد شرایط قرعهکشی Golden Card</span>
|
||
</div>
|
||
)}
|
||
|
||
{/* Show answers */}
|
||
<details className="mt-4">
|
||
<summary className="cursor-pointer text-sm text-gray-400 hover:text-white transition">
|
||
مشاهده جزئیات
|
||
</summary>
|
||
<div className="mt-3 flex flex-col gap-3">
|
||
{sub.quiz.questions.map((q, i) => {
|
||
const userAnswer = sub.answers[i];
|
||
const isCorrect = userAnswer === q.correctAnswer;
|
||
|
||
return (
|
||
<div
|
||
key={q.id}
|
||
className={`border rounded-lg p-3 text-sm ${
|
||
isCorrect ? "border-green-500/30 bg-green-500/5" : "border-red-500/30 bg-red-500/5"
|
||
}`}
|
||
>
|
||
<p className="font-medium mb-2">{q.questionText}</p>
|
||
<div className="flex flex-col gap-1 text-xs">
|
||
<p className={isCorrect ? "text-green-400" : "text-red-400"}>
|
||
پاسخ شما: {q.options[userAnswer ?? 0]} {isCorrect ? "✓" : "✗"}
|
||
</p>
|
||
{!isCorrect && (
|
||
<p className="text-green-400">پاسخ صحیح: {q.options[q.correctAnswer]}</p>
|
||
)}
|
||
</div>
|
||
</div>
|
||
);
|
||
})}
|
||
</div>
|
||
</details>
|
||
</div>
|
||
);
|
||
})}
|
||
</div>
|
||
</div>
|
||
</div>
|
||
);
|
||
}
|