SPB Git forge

spb/vrai-prix

Public

Vrai-Prix — l'évaluation du vrai prix des propriétés résidentielles au Québec.

60commits 1branches 0releases
12.3 MBsize
maindefault branch
17 days agolast push
TypeScript 90.2% JavaScript 3.5% Python 3.4% CSS 1.9% HTML 0.6%
3.6 KB · 108 lines tsx
Raw Blame History
1"use client";2// Auteur : Simon-Pierre Boucher — contact@spboucher.ai3// Projet : Groupe Ka / Ka Maps (intégration Vrai-Prix)4// components/KaCarte.tsx : Vrai-Prix Maps — recherche par carte propulsée5// par le framework partagé Ka Maps (moteur Mapbox GL, style Standard 3D par6// défaut + bouton 2D). Remplace l'ancienne carte Leaflet/OSM : pastilles de7// VALEURS ESTIMÉES 2026 (grappes + moyennes), chargement piloté par le8// viewport (annulation, cache), aperçu React, bilingue FR/EN.9// À charger via next/dynamic({ ssr: false }) — Mapbox GL est navigateur-seul.1011import { useState } from "react";12import { useRouter } from "next/navigation";13import "mapbox-gl/dist/mapbox-gl.css";14import "@groupe-ka/ka-maps/styles.css";15import type { MapProperty } from "@groupe-ka/ka-maps";16import { formatFullPrice } from "@groupe-ka/ka-maps";17import {18  KaBrandBadge,19  KaMapView,20  LoadingIndicator,21  LocateControl,22  PropertyPreview,23  Tilt3DControl,24} from "@groupe-ka/ka-maps/react";25import { useLang } from "@/components/LangContext";26import {27  MAPBOX_TOKEN,28  MIN_ZOOM_FETCH,29  vraiPrixMapAdapter,30  vraiPrixMapTheme,31} from "@/lib/kamaps";3233const DEFAULT_CENTER = { lat: 45.5421, lng: -73.6646 }; // Montréal3435/** Aperçu d'une unité d'évaluation — valeur estimée, jamais un prix. */36function PreviewCard({ p, fr, close }: { p: MapProperty; fr: boolean; close: () => void }) {37  const router = useRouter();38  return (39    <div className="vpm-pop">40      <div className="klabel">{fr ? "Estimation 2026" : "2026 estimate"}</div>41      <div className="vpm-pop-value">42        {p.estimatedValue != null ? formatFullPrice(p.estimatedValue) : "—"}43      </div>44      <div className="vpm-pop-addr">{p.address}</div>45      <div className="vpm-pop-meta">46        {[p.city, p.propertyType].filter(Boolean).join(" · ")}47      </div>48      <button49        type="button"50        className="vpm-pop-cta"51        onClick={() => {52          close();53          router.push(p.originalUrl ?? "/");54        }}55      >56        {fr ? "Voir l'estimation complète →" : "See full estimate →"}57      </button>58    </div>59  );60}6162export default function KaCarte() {63  const { lang } = useLang();64  const fr = lang === "fr";65  const [zoom, setZoom] = useState(13);66  const [count, setCount] = useState<number | null>(null);6768  const zoomedOut = zoom < MIN_ZOOM_FETCH;6970  return (71    <div className="vpm-wrap">72      <KaMapView73        theme={vraiPrixMapTheme}74        adapter={vraiPrixMapAdapter}75        mapboxToken={MAPBOX_TOKEN}76        center={DEFAULT_CENTER}77        zoom={13.5}78        pitch={50}79        searchMode="auto"80        cluster={{ maxZoom: 15, radius: 44, valueClamp: [40_000, 5_000_000] }}81        onMoveEnd={(_c, z) => setZoom(z)}82        onData={(c) => setCount(c)}83      >84        <KaBrandBadge />85        <Tilt3DControl />86        <LocateControl label={fr ? "Me localiser" : "Locate me"} />87        <LoadingIndicator label={fr ? "Mise à jour des estimations…" : "Updating estimates…"} />88        <PropertyPreview89          render={(p, close) => <PreviewCard p={p} fr={fr} close={close} />}90        />91        <div className="vpm-chip" role="status">92          {zoomedOut93            ? fr94              ? "Zoomez pour voir les valeurs estimées"95              : "Zoom in to see estimated values"96            : count != null97              ? fr98                ? `${count.toLocaleString("fr-CA")} propriétés affichées`99                : `${count.toLocaleString("en-CA")} properties shown`100              : fr101                ? "Chargement…"102                : "Loading…"}103        </div>104      </KaMapView>105    </div>106  );107}108