Files
lms-sb/src/app/curator/dashboard/page.tsx
T
admins 3855bbd4be 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>
2026-04-08 14:01:55 +05:00

58 lines
2.2 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { headers } from "next/headers";
import { auth } from "@/lib/auth";
import { redirect } from "next/navigation";
import { prisma } from "@/lib/prisma";
import Link from "next/link";
export default async function CuratorDashboard() {
const session = await auth.api.getSession({ headers: await headers() });
if (!session) redirect("/login");
const [pending, total, recentFeedbacks] = await Promise.all([
prisma.homeworkSubmission.count({ where: { feedbacks: { none: {} } } }),
prisma.homeworkSubmission.count(),
prisma.homeworkFeedback.count({
where: {
createdAt: { gte: new Date(new Date().getTime() - 7 * 24 * 60 * 60 * 1000) },
curatorId: session.user.id,
},
}),
]);
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)" }}>Панель куратора</p>
<div className="grid grid-cols-3 gap-4 mb-8">
<StatCard label="Ожидают проверки" value={pending} accent={pending > 0} />
<StatCard label="Всего сдано" value={total} />
<StatCard label="Проверено за 7 дней" value={recentFeedbacks} />
</div>
{pending > 0 ? (
<Link href="/curator/homework" className="btn-aubade btn-aubade-accent inline-flex items-center gap-2 px-5 py-2.5 text-sm">
Перейти к проверке ({pending})
</Link>
) : (
<div className="card-aubade p-8 text-center">
<p className="text-3xl mb-2"></p>
<p className="font-bold">Все работы проверены</p>
<p className="text-sm mt-1" style={{ color: "var(--muted-foreground)" }}>Новых заданий нет</p>
</div>
)}
</div>
);
}
function StatCard({ label, value, accent }: { label: string; value: number; accent?: boolean }) {
return (
<div className="card-aubade p-4">
<p className="text-3xl font-bold" style={{ color: accent ? "oklch(0.577 0.245 27.325)" : "var(--foreground)" }}>
{value}
</p>
<p className="text-xs mt-1 uppercase tracking-widest" style={{ color: "var(--muted-foreground)" }}>{label}</p>
</div>
);
}