'use client'; /** * CutoffMapPanel — "Where the last place went". * * The rings and the postcode check live in one component because they are one * question asked twice: the form answers "how far are we?" and the map shows * that answer against the cut-offs. Entering a postcode drops a pin on the same * rings rather than producing a separate verdict elsewhere on the page. * * The map is not rendered until asked for. Before a postcode is entered it is a * circle drawn round a school, and it costs a Leaflet bundle and 240px of * section height to say that; a successful check opens it automatically, * because that is the point at which it starts answering something. * * The postcode never leaves the browser except to postcodes.io for a lat/long, * and nothing is stored — this is a client-side measurement, not a lookup * against the family. */ import { useState, useMemo, type FormEvent } from 'react'; import dynamic from 'next/dynamic'; import type { School } from '@/lib/types'; import { geocodePostcode, calculateDistance } from '@/lib/api'; import { isValidPostcode } from '@/lib/utils'; import { compareToCutoffs, type CutoffYearRow, type CutoffCheckResult, type CutoffVerdict, } from './lastDistanceOffered'; import type { CutoffRing } from '../LeafletCutoffMapInner'; import styles from './schoolSections.module.css'; const CutoffMap = dynamic(() => import('../LeafletCutoffMapInner'), { ssr: false, loading: () =>