/** * Custom hook for managing school comparison state */ 'use client'; import { useState, useEffect, useCallback } from 'react'; import useSWR from 'swr'; import { fetcher } from '@/lib/api'; import { getFromLocalStorage, setToLocalStorage } from '@/lib/utils'; import type { School, ComparisonResponse } from '@/lib/types'; const STORAGE_KEY = 'selectedSchools'; const MAX_SCHOOLS = 5; export function useComparison() { const [selectedSchools, setSelectedSchools] = useState([]); const [isInitialized, setIsInitialized] = useState(false); // Load from localStorage on mount useEffect(() => { const stored = getFromLocalStorage(STORAGE_KEY, []); setSelectedSchools(stored); setIsInitialized(true); }, []); // Save to localStorage when schools change useEffect(() => { if (isInitialized) { setToLocalStorage(STORAGE_KEY, selectedSchools); } }, [selectedSchools, isInitialized]); // Fetch comparison data for selected schools const urns = selectedSchools.map((s) => s.urn).join(','); const { data, error, isLoading, mutate } = useSWR( selectedSchools.length > 0 ? `/compare?urns=${urns}` : null, fetcher, { revalidateOnFocus: false, dedupingInterval: 10000, // 10 seconds } ); const addSchool = useCallback((school: School) => { setSelectedSchools((prev) => { // Check if already selected if (prev.some((s) => s.urn === school.urn)) { return prev; } // Check max limit if (prev.length >= MAX_SCHOOLS) { alert(`Maximum ${MAX_SCHOOLS} schools can be compared`); return prev; } return [...prev, school]; }); }, []); const removeSchool = useCallback((urn: number) => { setSelectedSchools((prev) => prev.filter((s) => s.urn !== urn)); }, []); const clearAll = useCallback(() => { setSelectedSchools([]); }, []); const isSelected = useCallback( (urn: number) => selectedSchools.some((s) => s.urn === urn), [selectedSchools] ); return { selectedSchools, comparisonData: data?.comparison, isLoading, error, addSchool, removeSchool, clearAll, isSelected, canAddMore: selectedSchools.length < MAX_SCHOOLS, mutate, }; }