Initial commit
This commit is contained in:
@@ -0,0 +1,192 @@
|
||||
// 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 }
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user