import { useState } from "react"; import { Card, CardContent } from "@/components/ui/card"; import { Input } from "@/components/ui/input"; import { Button } from "@/components/ui/button"; import { Badge } from "@/components/ui/badge"; import { Checkbox } from "@/components/ui/checkbox"; import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogFooter, DialogDescription } from "@/components/ui/dialog"; import { Label } from "@/components/ui/label"; import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table"; import { Search, Plus, Trash2, Users, UserPlus, UserMinus, Pencil } from "lucide-react"; import { useBatches, useCourses, useStudents } from "@/hooks/queries"; import { lmsService } from "@/services/lms.service"; import { useMutation, useQueryClient } from "@tanstack/react-query"; import { useToast } from "@/hooks/use-toast"; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select"; export default function ClassroomsPage() { const [search, setSearch] = useState(""); const [createOpen, setCreateOpen] = useState(false); const [form, setForm] = useState({ name: "", course_id: "", start_date: "", end_date: "", max_students: "" }); const [editOpen, setEditOpen] = useState(false); const [editBatch, setEditBatch] = useState<{ id: number; name: string; course_id: string; start_date: string; end_date: string } | null>(null); const [studentsOpen, setStudentsOpen] = useState(false); const [studentsBatchId, setStudentsBatchId] = useState(null); const [addStudentsOpen, setAddStudentsOpen] = useState(false); const [selectedAddIds, setSelectedAddIds] = useState([]); const { toast } = useToast(); const qc = useQueryClient(); const batchesQ = useBatches({ size: 200 }); const coursesQ = useCourses({ size: 200 }); const studentsQ = useStudents({ size: 200 }); const batches = batchesQ.data?.items ?? []; const courses = coursesQ.data?.items ?? []; const allStudents = studentsQ.data?.items ?? []; const createMut = useMutation({ mutationFn: (data: Parameters[0]) => lmsService.createBatch(data), onSuccess: () => { qc.invalidateQueries({ queryKey: ["lms", "batches"] }); setCreateOpen(false); setForm({ name: "", course_id: "", start_date: "", end_date: "", max_students: "" }); toast({ title: "Classroom created" }); }, onError: (err: Error) => toast({ title: "Error", description: err.message, variant: "destructive" }), }); const updateMut = useMutation({ mutationFn: ({ id, data }: { id: number; data: Record }) => lmsService.updateBatch(id, data as never), onSuccess: () => { qc.invalidateQueries({ queryKey: ["lms", "batches"] }); setEditOpen(false); toast({ title: "Classroom updated" }); }, onError: (err: Error) => toast({ title: "Error", description: err.message, variant: "destructive" }), }); const deleteMut = useMutation({ mutationFn: (id: number) => lmsService.deleteBatch(id), onSuccess: () => { qc.invalidateQueries({ queryKey: ["lms", "batches"] }); toast({ title: "Deleted" }); }, onError: (err: Error) => toast({ title: "Error", description: err.message, variant: "destructive" }), }); const addStudentsMut = useMutation({ mutationFn: ({ batchId, studentIds }: { batchId: number; studentIds: number[] }) => lmsService.addStudentsToBatch(batchId, studentIds), onSuccess: (res) => { qc.invalidateQueries({ queryKey: ["lms", "batches"] }); setAddStudentsOpen(false); setSelectedAddIds([]); toast({ title: `Added ${res.total} student(s)` }); }, onError: (err: Error) => toast({ title: "Error", description: err.message, variant: "destructive" }), }); const removeStudentMut = useMutation({ mutationFn: ({ batchId, studentIds }: { batchId: number; studentIds: number[] }) => lmsService.removeStudentsFromBatch(batchId, studentIds), onSuccess: () => { qc.invalidateQueries({ queryKey: ["lms", "batches"] }); toast({ title: "Student removed from classroom" }); }, onError: (err: Error) => toast({ title: "Error", description: err.message, variant: "destructive" }), }); const q = search.toLowerCase(); const filtered = batches.filter( (b) => b.name.toLowerCase().includes(q) || b.course_name?.toLowerCase().includes(q), ); const loading = batchesQ.isLoading; const currentBatch = batches.find((b) => b.id === studentsBatchId); const batchStudentIds = new Set(currentBatch?.student_ids ?? []); const availableStudents = allStudents.filter((s) => !batchStudentIds.has(s.id)); function openStudents(batchId: number) { setStudentsBatchId(batchId); setStudentsOpen(true); } function openEdit(b: typeof batches[0]) { setEditBatch({ id: b.id, name: b.name, course_id: String(b.course_id || ""), start_date: b.start_date, end_date: b.end_date, }); setEditOpen(true); } return (

Classrooms

Create and manage classrooms with students.

setSearch(e.target.value)} />
{batches.length} total
{loading ? (
) : ( Name Course Students Dates Status {filtered.length === 0 && ( No classrooms found. )} {filtered.map((b) => ( {b.name} {b.course_name || "—"} {b.start_date && b.end_date ? `${b.start_date} — ${b.end_date}` : "—"} {b.status}
))}
)} {/* Create Dialog */} Create Classroom
setForm((f) => ({ ...f, name: e.target.value }))} placeholder="e.g. IELTS Prep Group A" />
setForm((f) => ({ ...f, start_date: e.target.value }))} />
setForm((f) => ({ ...f, end_date: e.target.value }))} />
{/* Edit Dialog */} Edit Classroom {editBatch && (
setEditBatch((prev) => prev ? { ...prev, name: e.target.value } : prev)} />
setEditBatch((prev) => prev ? { ...prev, start_date: e.target.value } : prev)} />
setEditBatch((prev) => prev ? { ...prev, end_date: e.target.value } : prev)} />
)}
{/* Students Management Dialog */} Classroom Students — {currentBatch?.name} {currentBatch?.course_name && `Course: ${currentBatch.course_name}`} {currentBatch ? ` · ${currentBatch.student_count} student(s)` : ""}
{currentBatch?.student_ids?.length === 0 ? (

No students in this classroom yet.

) : ( allStudents .filter((s) => batchStudentIds.has(s.id)) .map((s) => (

{s.name}

{s.email}

)) )}
{/* Add Students to Batch Dialog */} Add Students to {currentBatch?.name} Select students to add to this classroom.
{availableStudents.length === 0 ? (

All students are already in this classroom.

) : ( availableStudents.map((s) => ( )) )}
); }