'use client'; import React, { useEffect, useState } from 'react'; import { SidebarProvider, SidebarInset } from '@/components/ui/sidebar'; import { AppSidebar } from '@/components/app-sidebar'; import { SiteHeader } from '@/components/site-header'; import { useRouter } from 'next/navigation'; import { toast } from 'sonner'; import { Progress } from '@/components/ui/progress'; import { Card, CardContent, CardHeader, CardTitle, CardFooter, } from '@/components/ui/card'; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue, } from '@/components/ui/select'; import { Button } from '@/components/ui/button'; import { Label } from '@/components/ui/label'; import { Field, FieldGroup, FieldLabel, FieldDescription, } from '@/components/ui/field'; import { Table, TableBody, TableCaption, TableCell, TableFooter, TableHead, TableHeader, TableRow, } from '@/components/ui/table'; type User = { id: number | string; name?: string | null; email: string }; type Course = { id: number | string; title: string; code: string }; type Enrollment = { id: number; role?: string | null; createdAt?: string; user: User; course: Course; }; function AdminUI() { const [users, setUsers] = useState([]); const [courses, setCourses] = useState([]); const [enrollments, setEnrollments] = useState([]); // placeholder sentinel const [selectedUser, setSelectedUser] = useState('none'); const [selectedCourse, setSelectedCourse] = useState('none'); const [role, setRole] = useState('student'); const [loading, setLoading] = useState(false); const [saving, setSaving] = useState(false); const [error, setError] = useState(null); useEffect(() => { setLoading(true); setError(null); Promise.all([ fetch('/api/users') .then((r) => (r.ok ? r.json() : Promise.reject(r))) .catch(() => []), fetch('/api/courses') .then((r) => (r.ok ? r.json() : Promise.reject(r))) .catch(() => []), fetch('/api/enrollments') .then((r) => (r.ok ? r.json() : Promise.reject(r))) .catch(() => []), ]) .then(([u, c, e]) => { setUsers(u ?? []); setCourses(c ?? []); setEnrollments(e ?? []); }) .catch((err) => { console.error('Failed to load admin data', err); setError('Failed to load admin data'); }) .finally(() => setLoading(false)); }, []); function extractIdString(val: unknown): string | null { const s = val === null || val === undefined ? '' : String(val).trim(); console.debug('extractIdString raw value:', s); if (!s) return null; if (s.length > 0) return s; return null; } async function handleCreate(e?: React.FormEvent) { e?.preventDefault(); setError(null); const userIdStr = extractIdString(selectedUser); const courseIdStr = extractIdString(selectedCourse); if (!userIdStr || !courseIdStr) { setError( `Invalid selection. user="${String(selectedUser)}" course="${String( selectedCourse )}". Expected values containing numeric ids or direct ids.` ); return; } // send strings to the server (your Prisma schema expects String ids) const payload = { userId: String(userIdStr), courseId: String(courseIdStr), }; console.debug('Creating enrollment with payload:', payload); setSaving(true); try { const res = await fetch('/api/enrollments', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(payload), }); const data = await res.json(); if (!res.ok) { setError(data?.error || 'Failed to create enrollment'); } else { setEnrollments((prev) => [data, ...prev]); setSelectedUser('none'); setSelectedCourse('none'); setRole('student'); } } catch (err) { console.error('Network error while creating enrollment', err); setError('Network error while creating enrollment'); } finally { setSaving(false); } } async function handleDelete(id: number) { if (!confirm('Remove this enrollment?')) return; setSaving(true); setError(null); try { const res = await fetch('/api/enrollments', { method: 'DELETE', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ id }), }); const data = await res.json(); if (!res.ok && !data?.success) { setError(data?.error || 'Failed to delete enrollment'); } else { setEnrollments((prev) => prev.filter((en) => en.id !== id)); } } catch (err) { console.error('Network error while deleting enrollment', err); setError('Network error while deleting enrollment'); } finally { setSaving(false); } } return (
Assign enrollment
handleCreate(e)} className="grid grid-cols-1 md:grid-cols-4 gap-4 items-end" >
Student
Course
{error && (
{error}
)}
Current enrollments {loading && enrollments.length === 0 ? (
Loading…
) : enrollments.length === 0 ? (
No enrollments yet.
) : ( Student Email Course Role Enrolled Actions {enrollments.map((en) => ( {en.user.name ?? en.user.email} {en.user.email} {en.course.title}{' '} | {en.course.code} {en.role ?? 'student'} {en.createdAt ? new Date(en.createdAt).toLocaleString() : '—'}
))}
)}
); } export default function AdminClient() { return (
); }