advance
This commit is contained in:
108
app/(protected)/teacher/page.tsx
Normal file → Executable file
108
app/(protected)/teacher/page.tsx
Normal file → Executable file
@@ -1,7 +1,107 @@
|
||||
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 TeacherDashboardClient from "@/components/teacher/TeacherDashboardClient";
|
||||
import { logger } from "@/lib/logger";
|
||||
|
||||
export default async function TeacherDashboardPage() {
|
||||
await requireTeacher();
|
||||
return <TeacherDashboardClient />;
|
||||
}
|
||||
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("/login");
|
||||
}
|
||||
|
||||
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user