// ----------------------------------------------------------------------------- // Author: Simon-Pierre Boucher // Contact: contact@spboucher.ai // Project: Groupe Ka / Ka Maps (Rent-Ka integration) // components/MapView.tsx: Rent-Ka Maps — the product map, powered by // le framework partagé Ka Maps (moteur MapLibre, pastilles de prix GPU, // clustering natif, « Rechercher dans cette zone », aperçu React). // · chargée paresseusement (React.lazy) comme avant ; // · données pilotées par le viewport : /api/listings.geojson?bbox=… // (requêtes annulables, cache, jamais de tempête pendant le pan) ; // · caméra partageable dans l'URL (?lat=…&lng=…&zoom=…). // ----------------------------------------------------------------------------- import { useCallback, useEffect, useMemo } from "react"; import { useNavigate } from "react-router-dom"; import "mapbox-gl/dist/mapbox-gl.css"; import "@groupe-ka/ka-maps/styles.css"; import type { MapProperty } from "@groupe-ka/ka-maps"; import { cameraFromParams, cameraToParams } from "@groupe-ka/ka-maps"; import { KaBrandBadge, KaMapView, LoadingIndicator, PropertyPreview, ResultCount, SearchAreaControl, Tilt3DControl, useKaMap, } from "@groupe-ka/ka-maps/react"; import { ListingFilters, sourceName } from "../api"; import { louKaMapTheme } from "../kamaps/theme"; import { louKaMapAdapter } from "../kamaps/adapter"; import { MAPBOX_TOKEN } from "../kamaps/config"; const CANADA_CENTER = { lat: 47.5, lng: -84.5 }; const fmtDispo = (iso: string | null | undefined): string => !iso ? "" : iso === "now" ? "Available now" : `Available ${new Date(iso + "T12:00:00").toLocaleDateString("en-CA", { day: "numeric", month: "short", year: "numeric" })}`; /** Compact rental preview — same visual language as ListingCard. */ function PreviewCard({ p }: { p: MapProperty }) { const navigate = useNavigate(); const extra = (p.extra ?? {}) as { title?: string | null; priceLabel?: string | null; availabilityDate?: string | null; source?: string; areaSqft?: number | null; }; const prix = p.price != null ? `$${p.price.toLocaleString("en-CA", { maximumFractionDigits: 0 })}` : extra.priceLabel || "Price on request"; const meta = [ p.propertyType, extra.areaSqft ? `${Math.round(extra.areaSqft)} sq ft` : "", fmtDispo(extra.availabilityDate), ].filter(Boolean).join(" · "); return (