import React from 'react'; import { QueryClientProvider } from 'react-query'; import { matchSorter } from 'match-sorter'; import ComboSearch, { ComboSearchProps } from './ComboSearch'; import { queryClient } from './shared/queryClient'; import { ComboDepartementsSearch } from './ComboDepartementsSearch'; import { useHiddenField, groupId } from './shared/hooks'; type CommuneResult = { code: string; nom: string; codesPostaux: string[] }; // Avoid hiding similar matches for precise queries (like "Sainte Marie") function searchResultsLimit(term: string) { return term.length > 5 ? 10 : 5; } function expandResultsWithMultiplePostalCodes(term: string, result: unknown) { const results = result as CommuneResult[]; // A single result may have several associated postal codes. // To make the search results more precise, we want to generate // an actual result for each postal code. const expandedResults = results.flatMap((result) => result.codesPostaux.map((codePostal) => ({ ...result, codesPostaux: [codePostal] })) ); // Some very large cities (like Paris) have A LOT of associated postal codes. // As we generated one result per postal code, we now have a lot of results // for the same city. If the number of results is above the threshold, we use // local search to narrow the results. const limit = searchResultsLimit(term); if (expandedResults.length > limit) { return matchSorter(expandedResults, term, { keys: [(item) => `${item.nom} (${item.codesPostaux[0]})`, 'code'], sorter: (rankedItems) => rankedItems }).slice(0, limit + 1); } return expandedResults; } const placeholderDepartements = [ ['63 – Puy-de-Dôme', 'Clermont-Ferrand'], ['77 – Seine-et-Marne', 'Melun'], ['22 – Côtes d’Armor', 'Saint-Brieuc'], ['47 – Lot-et-Garonne', 'Agen'] ] as const; const [placeholderDepartement, placeholderCommune] = placeholderDepartements[ Math.floor(Math.random() * (placeholderDepartements.length - 1)) ]; export default function ComboCommunesSearch({ id, ...props }: ComboSearchProps & { id: string }) { const group = groupId(id); const [departementValue, setDepartementValue] = useHiddenField( group, 'departement' ); const [codeDepartement, setCodeDepartement] = useHiddenField( group, 'code_departement' ); const departementDescribedBy = `${id}_departement_notice`; const communeDescribedBy = `${id}_commune_notice`; return (

Choisissez le département dans lequel se situe la commune. Vous pouvez entrer le nom ou le code.

{ setDepartementValue(result?.nom ?? ''); setCodeDepartement(result?.code ?? ''); }} />
{codeDepartement ? (

Choisissez la commune. Vous pouvez entrer le nom ou le code postal.

[ code, `${nom} (${codesPostaux[0]})` ]} transformResults={expandResultsWithMultiplePostalCodes} />
) : null}
); }