Files
ACVE/app/(protected)/teacher/page.tsx
2026-03-15 13:52:11 +00:00

108 lines
4.0 KiB
TypeScript
Executable File

export const dynamic = 'force-dynamic';
import { getTeacherCourses } from "./actions"; // Import the server action
import Link from "next/link";
import { redirect } from "next/navigation";
import { requireTeacher } from "@/lib/auth/requireTeacher";
import { logger } from "@/lib/logger";
export default async function TeacherDashboardPage() {
try {
// 1. Auth Check (Double protection)
// We log the attempt
logger.info("Accessing Teacher Dashboard");
// We wrap requireTeacher to catch potential DB/Supabase connection errors
let user;
try {
user = await requireTeacher();
} catch (authError) {
logger.error("requireTeacher failed with exception", authError);
throw authError;
}
if (!user) {
logger.info("User not authorized as teacher, redirecting");
redirect("/auth/login?role=teacher");
}
// 2. Fetch Data
const { success, data: courses, error } = await getTeacherCourses();
return (
<div className="p-6 max-w-7xl mx-auto">
{/* Header */}
<div className="flex items-center justify-between mb-8">
<div>
<h1 className="text-2xl font-bold tracking-tight">Panel del Profesor</h1>
<p className="text-gray-500">Gestiona tus cursos y contenidos.</p>
</div>
<Link
href="/teacher/courses/new"
className="bg-black text-white px-4 py-2 rounded-md hover:bg-gray-800 transition-colors"
>
+ Nuevo Curso
</Link>
</div>
{/* Error State */}
{!success && (
<div className="bg-red-50 text-red-600 p-4 rounded-md border border-red-100">
Error: {error}
</div>
)}
{/* List State */}
{success && courses && (
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
{courses.length === 0 ? (
// Empty State
<div className="col-span-full text-center py-12 border-2 border-dashed border-gray-200 rounded-lg">
<h3 className="mt-2 text-sm font-semibold text-gray-900">No hay cursos</h3>
<p className="mt-1 text-sm text-gray-500">Empieza creando tu primer curso de Inglés Jurídico.</p>
</div>
) : (
// Course Cards
courses.map((course) => (
<Link
key={course.id}
href={`/teacher/courses/${course.slug}`}
className="block group"
>
<div className="border border-gray-200 rounded-lg p-5 hover:border-black transition-all bg-white shadow-sm hover:shadow-md">
<div className="flex justify-between items-start mb-4">
<span className={`text-xs font-medium px-2 py-1 rounded-full ${course.status === 'PUBLISHED' ? 'bg-green-100 text-green-700' : 'bg-yellow-100 text-yellow-700'
}`}>
{course.status === 'PUBLISHED' ? 'Publicado' : 'Borrador'}
</span>
<span className="text-sm font-bold text-gray-900">
${course.price.toString()}
</span>
</div>
<h3 className="font-semibold text-lg text-gray-900 group-hover:text-blue-600 mb-1">
{course.title as string}
</h3>
<p className="text-sm text-gray-500 mb-4">
{course.level}
</p>
<div className="flex items-center gap-4 text-xs text-gray-500 border-t pt-4">
<span>📚 {course._count.modules} Módulos</span>
<span>👥 {course._count.enrollments} Alumnos</span>
</div>
</div>
</Link>
))
)}
</div>
)}
</div>
);
} catch (error) {
logger.error("Critical error in TeacherDashboardPage", error);
throw error;
}
}