/** * SchoolSearchModal Component * Modal for searching and adding schools to comparison */ "use client"; import { useState, useMemo } from "react"; import { Modal } from "./Modal"; import { useComparison } from "@/hooks/useComparison"; import { debounce } from "@/lib/utils"; import { fetchSchools } from "@/lib/api"; import type { School } from "@/lib/types"; import styles from "./SchoolSearchModal.module.css"; interface SchoolSearchModalProps { isOpen: boolean; onClose: () => void; } export function SchoolSearchModal({ isOpen, onClose }: SchoolSearchModalProps) { const { addSchool, selectedSchools, canAddMore } = useComparison(); const [searchTerm, setSearchTerm] = useState(""); const [results, setResults] = useState([]); const [isSearching, setIsSearching] = useState(false); const [hasSearched, setHasSearched] = useState(false); // Debounced search function const performSearch = useMemo( () => debounce(async (term: string) => { if (!term.trim()) { setResults([]); setHasSearched(false); return; } setIsSearching(true); try { const data = await fetchSchools( { search: term, page_size: 10 }, { cache: "no-store" }, ); setResults(data.schools || []); setHasSearched(true); } catch (error) { console.error("Search failed:", error); setResults([]); } finally { setIsSearching(false); } }, 300), [], ); const handleSearchChange = (value: string) => { setSearchTerm(value); performSearch(value); }; const handleAddSchool = (school: School) => { addSchool(school); // Don't close modal, allow adding multiple schools }; const isSchoolSelected = (urn: number) => { return selectedSchools.some((s) => s.urn === urn); }; const handleClose = () => { setSearchTerm(""); setResults([]); setHasSearched(false); onClose(); }; return (

Add School to Comparison

{!canAddMore && (
Maximum 5 schools can be compared. Remove a school to add another.
)} {/* Search Input */}
handleSearchChange(e.target.value)} placeholder="School name or postcode" className={styles.searchInput} autoFocus /> {isSearching &&
}
{/* Results */}
{hasSearched && results.length === 0 && (
No schools found matching "{searchTerm}"
)} {results.map((school) => { const alreadySelected = isSchoolSelected(school.urn); return (
{school.school_name}
{school.local_authority && ( {school.local_authority} )} {school.school_type && {school.school_type}}
); })}
{!hasSearched && (
Start typing to search for schools...
)}
); }