// app/api/admin/allowed-students/route.ts import { NextResponse } from 'next/server'; import type { NextRequest } from 'next/server'; import { getServerSession } from 'next-auth'; import { authOptions } from '@/lib/auth-options'; import { prisma } from '@/lib/prisma'; import { normalizeEmail } from '@/lib/normalize-email'; // Check if user is admin async function checkAdmin(req: NextRequest) { const session = await getServerSession(authOptions); if (!session?.user?.email) { return null; } const role = (session as any)?.user?.role ?? null; if (!(role === 'admin' || role === 'superadmin')) { return null; } return session; } // GET all allowed students export async function GET(req: NextRequest) { try { const session = await checkAdmin(req); if (!session) { return NextResponse.json({ error: 'Unauthorized' }, { status: 401 }); } const students = await prisma.allowedStudent.findMany({ orderBy: { createdAt: 'desc' }, }); return NextResponse.json(students); } catch (err) { console.error('GET /api/admin/allowed-students error', err); return NextResponse.json( { error: 'Failed to fetch allowed students' }, { status: 500 } ); } } // POST create new allowed student export async function POST(req: NextRequest) { try { const session = await checkAdmin(req); if (!session) { return NextResponse.json({ error: 'Unauthorized' }, { status: 401 }); } const body = await req.json(); const { email, levels } = body; const normalizedEmail = normalizeEmail(email); if (!normalizedEmail || !levels) { return NextResponse.json( { error: 'Email and levels required' }, { status: 400 } ); } // Validate levels are valid course codes const levelArray = levels.split(',').map((l: string) => l.trim()); for (const level of levelArray) { const course = await prisma.course.findUnique({ where: { code: level } }); if (!course) { return NextResponse.json( { error: `Course code '${level}' not found` }, { status: 400 } ); } } // Check if student already exists const existing = await prisma.allowedStudent.findFirst({ where: { email: { equals: normalizedEmail, mode: 'insensitive', }, }, }); if (existing) { return NextResponse.json( { error: 'Email already registered' }, { status: 409 } ); } const student = await prisma.allowedStudent.create({ data: { email: normalizedEmail, levels: levelArray.join(','), active: true, }, }); return NextResponse.json(student, { status: 201 }); } catch (err) { console.error('POST /api/admin/allowed-students error', err); return NextResponse.json( { error: 'Failed to create allowed student' }, { status: 500 } ); } } // PUT update allowed student export async function PUT(req: NextRequest) { try { const session = await checkAdmin(req); if (!session) { return NextResponse.json({ error: 'Unauthorized' }, { status: 401 }); } const body = await req.json(); const { id, email, levels, active } = body; const normalizedEmail = email ? normalizeEmail(email) : null; if (!id) { return NextResponse.json({ error: 'Student ID required' }, { status: 400 }); } if (email && !normalizedEmail) { return NextResponse.json({ error: 'Valid email required' }, { status: 400 }); } // Validate levels if provided if (levels) { const levelArray = levels.split(',').map((l: string) => l.trim()); for (const level of levelArray) { const course = await prisma.course.findUnique({ where: { code: level } }); if (!course) { return NextResponse.json( { error: `Course code '${level}' not found` }, { status: 400 } ); } } } const student = await prisma.allowedStudent.update({ where: { id }, data: { ...(normalizedEmail && { email: normalizedEmail }), ...(levels && { levels }), ...(active !== undefined && { active }), }, }); return NextResponse.json(student); } catch (err) { console.error('PUT /api/admin/allowed-students error', err); return NextResponse.json( { error: 'Failed to update allowed student' }, { status: 500 } ); } } // DELETE allowed student export async function DELETE(req: NextRequest) { try { const session = await checkAdmin(req); if (!session) { return NextResponse.json({ error: 'Unauthorized' }, { status: 401 }); } const { searchParams } = new URL(req.url); const id = searchParams.get('id'); if (!id) { return NextResponse.json({ error: 'Student ID required' }, { status: 400 }); } await prisma.allowedStudent.delete({ where: { id }, }); return NextResponse.json({ message: 'Student removed' }); } catch (err) { console.error('DELETE /api/admin/allowed-students error', err); return NextResponse.json( { error: 'Failed to delete allowed student' }, { status: 500 } ); } }