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:
2026-04-07 14:13:24 +05:00
parent d0c8c6dd53
commit 543d5b2d5e
13 changed files with 836 additions and 31 deletions
@@ -0,0 +1,55 @@
"use client";
import { useState, useTransition } from "react";
import { useRouter } from "next/navigation";
import { submitFeedback } from "./actions";
export function FeedbackForm({ submissionId }: { submissionId: string }) {
const [text, setText] = useState("");
const [pending, startTransition] = useTransition();
const router = useRouter();
function handleSubmit(e: React.FormEvent) {
e.preventDefault();
if (!text.trim()) return;
startTransition(async () => {
await submitFeedback(submissionId, text.trim());
router.push("/curator/homework");
});
}
return (
<form onSubmit={handleSubmit} className="space-y-3">
<p className="text-xs font-bold uppercase tracking-widest" style={{ color: "var(--muted-foreground)" }}>
Написать фидбек
</p>
<textarea
value={text}
onChange={(e) => setText(e.target.value)}
required
placeholder="Напишите обратную связь студенту..."
style={{
border: "2px solid var(--border)",
background: "var(--background)",
outline: "none",
width: "100%",
padding: "0.5rem 0.75rem",
fontSize: "0.875rem",
fontFamily: "inherit",
resize: "vertical",
minHeight: "120px",
}}
onFocus={(e) => (e.currentTarget.style.borderColor = "var(--foreground)")}
onBlur={(e) => (e.currentTarget.style.borderColor = "var(--border)")}
/>
<button
type="submit"
disabled={pending || !text.trim()}
className="btn-aubade btn-aubade-accent px-5 py-2 text-sm"
style={{ opacity: pending || !text.trim() ? 0.6 : 1 }}
>
{pending ? "Отправка..." : "Отправить фидбек"}
</button>
</form>
);
}