SPB Git forge

spb/rent-ka

Public
8commits 1branches 0releases
7.4 MBsize
maindefault branch
19 days agolast push
Python 68.8% TypeScript 18.6% CSS 8.7% JavaScript 3.3% HTML 0.6%
2.8 KB · 99 lines typescript
Raw Blame History
1// -----------------------------------------------------------------------------2// Author: Simon-Pierre Boucher3// Contact: contact@spboucher.ai4// Project: Groupe Ka / Ka Maps (Rent-Ka integration)5// kamaps/adapter.ts: Rent-Ka data adapter → MapProperty.6// Transforms /api/listings.geojson (bbox + filters) into the framework's7// canonical model — the Rent-Ka domain stays in the app, the map knows nothing.8// -----------------------------------------------------------------------------9import type {10  BoundsQuery,11  BoundsQueryResult,12  KaDataAdapter,13  MapProperty,14} from "@groupe-ka/ka-maps";15import { bboxToString } from "@groupe-ka/ka-maps";16import type { ListingFilters } from "../api";1718interface LouKaFeatureProps {19  uid: string;20  title: string | null;21  address: string | null;22  price: number | null;23  price_label: string | null;24  unit_type: string | null;25  availability_date: string | null;26  source: string;27  city: string | null;28  sector: string | null;29  area_sqft: number | null;30  image: string | null;31}3233interface LouKaFC {34  type: "FeatureCollection";35  features: {36    geometry: { coordinates: [number, number] };37    properties: LouKaFeatureProps;38  }[];39  totalGeocoded?: number;40  totalMatching?: number;41}4243function toMapProperty(44  coords: [number, number],45  p: LouKaFeatureProps,46): MapProperty {47  return {48    id: p.uid,49    appSource: "rent-ka",50    longitude: coords[0],51    latitude: coords[1],52    kind: "listing",53    listingType: "rent",54    price: p.price ?? undefined,55    propertyType: p.unit_type ?? undefined,56    address: p.address ?? p.title ?? undefined,57    city: p.city ?? undefined,58    region: p.sector ?? undefined,59    thumbnailUrl: p.image ?? undefined,60    originalUrl: `/listing/${encodeURIComponent(p.uid)}`,61    extra: {62      title: p.title,63      priceLabel: p.price_label,64      availabilityDate: p.availability_date,65      source: p.source,66      areaSqft: p.area_sqft,67      sector: p.sector,68    },69  };70}7172/** Viewport→data adapter for the Rent-Ka map. */73export const louKaMapAdapter: KaDataAdapter = {74  id: "rent-ka-listings",75  appSource: "rent-ka",76  async fetchInBounds(query: BoundsQuery): Promise<BoundsQueryResult> {77    const params = new URLSearchParams();78    const filters = (query.filters ?? {}) as Partial<ListingFilters>;79    for (const [k, v] of Object.entries(filters)) {80      if (v) params.set(k, String(v));81    }82    params.set("bbox", bboxToString(query.bbox));83    params.set("limit", "3000");8485    const res = await fetch(`/api/listings.geojson?${params}`, {86      signal: query.signal,87    });88    if (!res.ok) throw new Error(`Map: API ${res.status}`);89    const data = (await res.json()) as LouKaFC;9091    return {92      properties: data.features.map((f) =>93        toMapProperty(f.geometry.coordinates, f.properties),94      ),95      totalCount: data.totalMatching,96    };97  },98};99