SPB Git forge

spb/uqo-eval

Public
55commits 2branches 0releases
134.4 MBsize
maindefault branch
yesterdaylast push
TypeScript 90.1% JavaScript 3.2% Python 3.2% CSS 1.8% HTML 1.8%
3.8 KB · 124 lines typescript
Raw Blame History
1// UQO Éval — laboratoire pédagogique d'évaluation immobilière2// lib/kamaps.ts : thème UQO Éval Maps (framework Ka Maps) + adaptateur /api/nearby.3// La carte affiche des VALEURS ESTIMÉES (jamais des prix demandés) :4// pastilles encre à liseré turquoise UQO, sélection bleu UQO — le langage5// visuel du site (encre #16181b, bleu #006085, turquoise #2bccae).67import type {8  BoundsQuery,9  BoundsQueryResult,10  KaAppSource,11  KaDataAdapter,12  KaMapTheme,13  MapProperty,14} from "@groupe-ka/ka-maps";1516// Le framework ka-maps fige l'union KaAppSource à ses apps d'origine ;17// « uqo-eval » n'y figure pas — l'id ne sert qu'au thème/URL, déjà fournis ici.18const APP_SOURCE = "uqo-eval" as KaAppSource;1920const INK = "#16181b";21const RED = "#2bccae"; // turquoise UQO (liseré/halo)22const BORDEAUX = "#00465f"; // bleu UQO profond (grappes)2324export const MAPBOX_TOKEN: string =25  process.env.NEXT_PUBLIC_MAPBOX_TOKEN ??26  "pk.eyJ1Ijoic3Bib3VjaGVyIiwiYSI6ImNtc3Fyb3k4djAwOTgyenB3dWt6NHBjc2kifQ.poqLf0ADy3lIh28O-pFI2Q";2728/** Zoom minimal de chargement : sous ce niveau, on invite à zoomer. */29export const MIN_ZOOM_FETCH = 12;3031export const TYPE_FR: Record<string, string> = {32  unifamilial: "Unifamiliale",33  condo_ou_multi: "Condo / multi",34  plex: "Plex",35  chalet: "Chalet",36  terrain: "Terrain",37  maison_mobile: "Maison mobile",38  autre: "Autre",39};4041export const uqoEvalMapTheme: KaMapTheme = {42  id: "uqo-eval",43  productName: "UQO Éval Maps",44  accent: "#006085", // bleu UQO45  onAccent: "#ffffff",46  fontFamily: "var(--font-inter), system-ui, sans-serif",47  markers: {48    sale: {49      background: INK,50      text: "#ffffff",51      halo: RED,52      selectedBackground: "#006085",53      selectedText: "#ffffff",54    },55    // Valeurs estimées : pastille encre, liseré turquoise — visuellement56    // distinctes d'un prix demandé (jamais présentées comme une annonce).57    valuation: {58      background: INK,59      text: "#ffffff",60      halo: RED,61      selectedBackground: "#006085",62      selectedText: "#ffffff",63    },64  },65  cluster: {66    background: BORDEAUX,67    text: "#ffffff",68    border: "rgba(43,204,174,0.5)",69  },70  supportsDark: false,71};7273interface NearbyUnit {74  id: string;75  adresse: string | null;76  apt: string | null;77  municipalite: string | null;78  typeProp: string | null;79  lat: number;80  lng: number;81  est2026: number | null;82}8384function toMapProperty(u: NearbyUnit): MapProperty {85  return {86    id: u.id,87    appSource: APP_SOURCE,88    latitude: u.lat,89    longitude: u.lng,90    kind: "valuation",91    estimatedValue: u.est2026 ?? undefined,92    propertyType: u.typeProp ? TYPE_FR[u.typeProp] ?? u.typeProp : undefined,93    address: u.apt ? `${u.adresse} app. ${u.apt}` : u.adresse ?? undefined,94    city: u.municipalite ?? undefined,95    originalUrl: `/estimation/${u.id}`,96    extra: { typeProp: u.typeProp },97  };98}99100/** Adaptateur viewport→données : /api/nearby (contrat partagé avec iOS). */101export const uqoEvalMapAdapter: KaDataAdapter = {102  id: "uqo-eval-nearby",103  appSource: APP_SOURCE,104  async fetchInBounds(query: BoundsQuery): Promise<BoundsQueryResult> {105    if (query.zoom < MIN_ZOOM_FETCH) return { properties: [] };106    const { bbox } = query;107    const lat = (bbox.north + bbox.south) / 2;108    const lng = (bbox.east + bbox.west) / 2;109    const halfLat = Math.abs(bbox.north - lat);110    const halfLng = Math.abs(bbox.east - lng);111    const params = new URLSearchParams({112      lat: lat.toFixed(6),113      lng: lng.toFixed(6),114      halfLat: halfLat.toFixed(6),115      halfLng: halfLng.toFixed(6),116      limit: "1500",117    });118    const res = await fetch(`/api/nearby?${params}`, { signal: query.signal });119    if (!res.ok) throw new Error(`Carte : API ${res.status}`);120    const data = (await res.json()) as { results: NearbyUnit[] };121    return { properties: data.results.map(toMapProperty) };122  },123};124