Files
edubox/server/app/dashboard/students/page.tsx
root 479a8de858 fix: activation via connexion WS principale, cascade delete student→nodes, lien fiche étudiant
- agent/websocket.go: expose sendMessage() + notifyUI() pour broadcaster
  les résultats d'activation à tous les clients UI connectés
- agent/ui.go: supprime forwardActivation(), utilise sendMessage() sur
  la connexion WS principale au lieu d'une connexion temporaire
- agent/activation.go: ajoute os.MkdirAll avant l'écriture d'activation.json
- server/prisma/schema.prisma: onDelete Cascade sur Node→Student
- server/app/dashboard/students/page.tsx: nom cliquable vers fiche détail
- server/app/dashboard/students/[id]/actions.ts: deleteMany → delete
2026-06-06 22:41:15 +00:00

80 lines
3.0 KiB
TypeScript

import { prisma } from "@/lib/prisma";
import { getServerSession } from "next-auth/next";
import { authOptions } from "@/lib/auth-config";
import { redirect } from "next/navigation";
import { Table, TableHeader, TableBody, TableRow, TableHead, TableCell } from "@/components/ui/table";
import { Card, CardContent } from "@/components/ui/card";
import { Badge } from "@/components/ui/badge";
import { Button } from "@/components/ui/button";
import Link from "next/link";
export const dynamic = "force-dynamic";
export default async function StudentsPage() {
const session = await getServerSession(authOptions);
if (!session?.user) redirect("/login");
if (!session.user.establishmentId && session.user.role !== "superadmin") redirect("/dashboard");
const establishmentId = session.user.establishmentId;
const students = await prisma.student.findMany({
where: establishmentId ? { class: { establishmentId } } : {},
include: { class: true, nodes: true },
orderBy: { createdAt: "desc" },
});
return (
<div className="space-y-6">
<div className="flex items-center justify-between">
<h1 className="text-3xl font-bold">Étudiants</h1>
<Link href="/dashboard/students/new">
<Button>Ajouter</Button>
</Link>
</div>
<Card>
<CardContent className="pt-6">
<Table>
<TableHeader>
<TableRow>
<TableHead>Nom</TableHead>
<TableHead>Classe</TableHead>
<TableHead>Email</TableHead>
<TableHead>Code activation</TableHead>
<TableHead>Nœud</TableHead>
</TableRow>
</TableHeader>
<TableBody>
{students.map((s) => {
const node = s.nodes[0];
return (
<TableRow key={s.id}>
<TableCell className="font-medium">
<Link href={`/dashboard/students/${s.id}`} className="hover:underline">
{s.firstName} {s.lastName}
</Link>
</TableCell>
<TableCell>{s.class.name}</TableCell>
<TableCell>{s.email}</TableCell>
<TableCell>{s.activationCode || "-"}</TableCell>
<TableCell>
{node ? (
<Badge variant={node.status === "online" ? "success" : "secondary"}>{node.status}</Badge>
) : (
<Badge variant="outline">Non lié</Badge>
)}
</TableCell>
</TableRow>
);
})}
{students.length === 0 && (
<TableRow>
<TableCell colSpan={5} className="text-center text-muted-foreground">Aucun étudiant</TableCell>
</TableRow>
)}
</TableBody>
</Table>
</CardContent>
</Card>
</div>
);
}