Add homework review workflow: statuses, audio, file attachments, tabs

- HomeworkSubmission: add status (PENDING/REVIEWING/APPROVED/REJECTED) + statusAt
- HomeworkFeedback: add files (Json) + audioUrl fields
- Curator detail page: meta table, content tabs, feedback history with audio/files
- FeedbackForm: file upload, audio recorder (Web Audio API + S3), action buttons
- AudioRecorder component: record → preview → upload to S3
- ContentTabs: toggle between homework description and lesson content (TipTap read-only)
- Homework list: 4-color status badges with proper filtering
- API routes: /api/curator/upload and /api/curator/audio-upload

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-04-08 14:01:55 +05:00
parent 768a38b9d3
commit 3855bbd4be
15 changed files with 743 additions and 98 deletions
@@ -0,0 +1,40 @@
"use client";
import { useTransition } from "react";
import { useRouter } from "next/navigation";
import { deleteSubmission } from "./actions";
export function DeleteSubmissionButton({
submissionId,
userName,
}: {
submissionId: string;
userName: string;
}) {
const [pending, startTransition] = useTransition();
const router = useRouter();
function handleDelete() {
if (!confirm(`Удалить работу студента ${userName}? Это действие нельзя отменить.`)) return;
startTransition(async () => {
await deleteSubmission(submissionId);
router.push("/curator/homework");
});
}
return (
<button
type="button"
onClick={handleDelete}
disabled={pending}
className="text-xs px-3 py-1.5"
style={{
border: "1px solid var(--border)",
color: "oklch(0.577 0.245 27.325)",
opacity: pending ? 0.5 : 1,
}}
>
🗑 Удалить работу
</button>
);
}