TypeScript 87.7%
CSS 12.3%
1/**2 * Author: Simon-Pierre Boucher3 * Contact: contact@spboucher.ai4 * Project: Groupe Ka / Ka Maps5 *6 * KaDrawAreaMode — l'interface TEMPORAIRE du dessin de zone (v2). Plus de7 * grosse boîte permanente : pendant le tracé, un bandeau d'instructions8 * discret ; une fois la zone posée, un CTA contextuel « Voir N propriétés9 * dans cette zone » + retrait en un geste. Tout disparaît hors du mode.10 */1112import {13 useEffect,14 useState,15 type ReactElement,16} from "react";17import { useKaMap } from "./KaMapView.js";1819export interface KaDrawAreaModeProps {20 /** « 184 propriétés » — libellé du compte (le compte vient de l'événement21 * data du moteur ; l'app peut le surcharger avec son total serveur). */22 formatCount?: (n: number) => string;23 /** Total maîtrisé par l'app (prime sur le compte du moteur). */24 count?: number | null;25 /** Clic sur le CTA (défaut : cadrer la zone). */26 onSee?: () => void;27 /** Zone retirée. */28 onClear?: () => void;29}3031export function KaDrawAreaMode(props: KaDrawAreaModeProps): ReactElement | null {32 const map = useKaMap();33 const [drawing, setDrawing] = useState(false);34 const [hasZone, setHasZone] = useState(false);35 const [engineCount, setEngineCount] = useState<number | null>(null);3637 useEffect(() => {38 if (!map) return;39 setDrawing(map.isDrawing());40 setHasZone(map.getDrawnPolygon() !== null);41 const offs = [42 map.events.on("draw", ({ polygon, drawing: d }) => {43 setDrawing(d);44 setHasZone(polygon !== null);45 }),46 map.events.on("data", ({ count }) => setEngineCount(count)),47 ];48 return () => offs.forEach((off) => off());49 }, [map]);5051 if (!map) return null;5253 if (drawing) {54 return (55 <div className="ka-drawmode" role="status">56 <span className="ka-drawmode-hint">57 Touchez la carte pour poser des points — refermez sur le premier58 </span>59 <button60 type="button"61 className="ka-drawmode-cancel"62 onClick={() => map.cancelDraw()}63 >64 Annuler65 </button>66 </div>67 );68 }6970 if (!hasZone) return null;7172 const n = props.count ?? engineCount;73 const label =74 n == null75 ? "Zone dessinée"76 : props.formatCount77 ? props.formatCount(n)78 : `${n.toLocaleString("fr-CA")} résultat${n > 1 ? "s" : ""}`;7980 return (81 <div className="ka-drawzone" role="group" aria-label="Zone dessinée">82 <button83 type="button"84 className="ka-drawzone-see"85 onClick={() => {86 if (props.onSee) {87 props.onSee();88 return;89 }90 const poly = map.getDrawnPolygon();91 if (poly) {92 const lngs = poly.map((p) => p[0]);93 const lats = poly.map((p) => p[1]);94 map.fitBounds(95 {96 west: Math.min(...lngs),97 south: Math.min(...lats),98 east: Math.max(...lngs),99 north: Math.max(...lats),100 },101 { padding: 64 },102 );103 }104 }}105 >106 {label} dans cette zone107 </button>108 <button109 type="button"110 className="ka-drawzone-clear"111 onClick={() => {112 map.clearDrawnPolygon();113 props.onClear?.();114 }}115 aria-label="Retirer la zone dessinée"116 >117 ✕118 </button>119 </div>120 );121}122