diff --git a/src/pages/AssignmentsPage.tsx b/src/pages/AssignmentsPage.tsx index 4f6db8e..ca06cb8 100644 --- a/src/pages/AssignmentsPage.tsx +++ b/src/pages/AssignmentsPage.tsx @@ -114,6 +114,7 @@ export default function AssignmentsPage() { const [stateFilter, setStateFilter] = useState("all"); const [createOpen, setCreateOpen] = useState(false); const [form, setForm] = useState(emptyForm()); + const [studentQuery, setStudentQuery] = useState(""); const { toast } = useToast(); const qc = useQueryClient(); @@ -144,6 +145,14 @@ export default function AssignmentsPage() { const studentsQ = useStudents({ size: 200 }); const students = studentsQ.data?.items ?? []; + const filteredStudents = useMemo(() => { + const q = studentQuery.trim().toLowerCase(); + if (!q) return students; + return students.filter((s) => + (s.name || "").toLowerCase().includes(q) || + (s.email || "").toLowerCase().includes(q), + ); + }, [students, studentQuery]); const stateCounts = useMemo(() => { const all = schedulesQ.data?.items ?? []; @@ -468,9 +477,23 @@ export default function AssignmentsPage() { {/* Individual student selection */} {form.assign_mode === "individual" && (
- -
- {students.map((s) => ( +
+ + + {form.student_ids.size} selected · {students.length} total + +
+ {/* Search box — needed because QA reported long student lists + made bottom entries unreachable inside the inner scroll + container. Filtering keeps the list short and predictable. */} + setStudentQuery(e.target.value)} + className="h-8 text-xs" + /> +
+ {filteredStudents.map((s) => ( ))} + {filteredStudents.length === 0 && students.length > 0 && ( +

+ No students match “{studentQuery}”. +

+ )} {students.length === 0 &&

No students available

}