Add homework system (admin, student, curator)
Admin: - HomeworkEditor in lesson page: create/update/delete assignment description Student: - HomeworkSection in lesson page: view assignment, submit text + files - Resubmission allowed until curator gives feedback - Shows feedback from curator with date and name Curator: - New layout with Second Brain dark sidebar (replaces green theme) - /curator/dashboard: stats cards (pending, total, reviewed this week) - /curator/homework: list of all submissions, pending highlighted - /curator/homework/[id]: review submission, write feedback, redirect after send Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,115 @@
|
||||
import { prisma } from "@/lib/prisma";
|
||||
import Link from "next/link";
|
||||
|
||||
export default async function HomeworkListPage() {
|
||||
const submissions = await prisma.homeworkSubmission.findMany({
|
||||
orderBy: { submittedAt: "desc" },
|
||||
include: {
|
||||
user: { select: { name: true, email: true } },
|
||||
feedbacks: { select: { id: true } },
|
||||
homework: {
|
||||
include: {
|
||||
lesson: {
|
||||
select: {
|
||||
title: true,
|
||||
module: { select: { title: true, course: { select: { title: true } } } },
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
const pending = submissions.filter((s) => s.feedbacks.length === 0);
|
||||
const reviewed = submissions.filter((s) => s.feedbacks.length > 0);
|
||||
|
||||
return (
|
||||
<div className="p-8 max-w-3xl">
|
||||
<h1 className="text-2xl font-bold mb-1">Домашние задания</h1>
|
||||
<p className="text-sm mb-8" style={{ color: "var(--muted-foreground)" }}>
|
||||
{pending.length} ожидают проверки · {reviewed.length} проверено
|
||||
</p>
|
||||
|
||||
{pending.length > 0 && (
|
||||
<div className="mb-8">
|
||||
<p className="text-xs font-bold uppercase tracking-widest mb-3" style={{ color: "var(--muted-foreground)" }}>
|
||||
Ожидают проверки
|
||||
</p>
|
||||
<div className="space-y-2">
|
||||
{pending.map((s) => (
|
||||
<SubmissionRow key={s.id} submission={s} pending />
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{reviewed.length > 0 && (
|
||||
<div>
|
||||
<p className="text-xs font-bold uppercase tracking-widest mb-3" style={{ color: "var(--muted-foreground)" }}>
|
||||
Проверено
|
||||
</p>
|
||||
<div className="space-y-2">
|
||||
{reviewed.map((s) => (
|
||||
<SubmissionRow key={s.id} submission={s} pending={false} />
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{submissions.length === 0 && (
|
||||
<div className="card-aubade p-10 text-center">
|
||||
<p className="text-3xl mb-2">📭</p>
|
||||
<p className="font-bold">Работ пока нет</p>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
function SubmissionRow({
|
||||
submission,
|
||||
pending,
|
||||
}: {
|
||||
submission: {
|
||||
id: string;
|
||||
submittedAt: Date;
|
||||
user: { name: string; email: string };
|
||||
homework: {
|
||||
lesson: {
|
||||
title: string;
|
||||
module: { title: string; course: { title: string } };
|
||||
};
|
||||
};
|
||||
};
|
||||
pending: boolean;
|
||||
}) {
|
||||
return (
|
||||
<Link
|
||||
href={`/curator/homework/${submission.id}`}
|
||||
className="flex items-center gap-4 px-4 py-3 text-sm transition-colors"
|
||||
style={{ border: `2px solid ${pending ? "var(--foreground)" : "var(--border)"}`, display: "flex" }}
|
||||
>
|
||||
<div className="flex-1 min-w-0">
|
||||
<p className="font-medium truncate">{submission.user.name}</p>
|
||||
<p className="text-xs truncate" style={{ color: "var(--muted-foreground)" }}>
|
||||
{submission.homework.lesson.module.course.title} · {submission.homework.lesson.title}
|
||||
</p>
|
||||
</div>
|
||||
<div className="text-right shrink-0">
|
||||
<span
|
||||
className="text-xs px-2 py-0.5"
|
||||
style={{
|
||||
border: "1px solid var(--border)",
|
||||
background: pending ? "var(--foreground)" : "transparent",
|
||||
color: pending ? "var(--background)" : "var(--muted-foreground)",
|
||||
}}
|
||||
>
|
||||
{pending ? "Новое" : "Проверено"}
|
||||
</span>
|
||||
<p className="text-xs mt-1" style={{ color: "var(--muted-foreground)" }}>
|
||||
{new Date(submission.submittedAt).toLocaleDateString("ru-RU")}
|
||||
</p>
|
||||
</div>
|
||||
</Link>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user