Python 67%
TypeScript 18.2%
CSS 14.4%
1// -----------------------------------------------------------------------------2// Author: Simon-Pierre Boucher3// Contact: contact@spboucher.ai4// Project: Groupe Ka / Ka Maps (House-Ka integration)5// kamaps/adapter.ts : House-Ka → MapProperty adapter.6// -----------------------------------------------------------------------------7import type {8 BoundsQuery,9 BoundsQueryResult,10 KaDataAdapter,11 MapProperty,12} from "@groupe-ka/ka-maps";13import { bboxToString } from "@groupe-ka/ka-maps";14import type { ListingFilters } from "../api";1516interface HouseKaFeatureProps {17 uid: string;18 title: string | null;19 address: string | null;20 price: number | null;21 price_label: string | null;22 property_type: string | null;23 bedrooms: number | null;24 bathrooms: number | null;25 source: string;26 city: string | null;27 sector: string | null;28 image: string | null;29}3031interface HouseKaFC {32 type: "FeatureCollection";33 features: {34 geometry: { coordinates: [number, number] };35 properties: HouseKaFeatureProps;36 }[];37 totalGeocoded?: number;38 totalMatching?: number;39}4041function toMapProperty(42 coords: [number, number],43 p: HouseKaFeatureProps,44): MapProperty {45 return {46 id: p.uid,47 appSource: "house-ka",48 longitude: coords[0],49 latitude: coords[1],50 kind: "listing",51 listingType: "sale",52 price: p.price ?? undefined,53 propertyType: p.property_type ?? undefined,54 bedrooms: p.bedrooms ?? undefined,55 bathrooms: p.bathrooms ?? 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: `/property/${encodeURIComponent(p.uid)}`,61 highlight: false,62 extra: {63 title: p.title,64 priceLabel: p.price_label,65 source: p.source,66 },67 };68}6970/** Viewport→data adapter for the House-Ka map. */71export const houseKaMapAdapter: KaDataAdapter = {72 id: "house-ka-listings",73 appSource: "house-ka",74 async fetchInBounds(query: BoundsQuery): Promise<BoundsQueryResult> {75 const params = new URLSearchParams();76 const filters = (query.filters ?? {}) as Partial<ListingFilters>;77 for (const [k, v] of Object.entries(filters)) {78 if (v && k !== "sort") params.set(k, String(v));79 }80 params.set("bbox", bboxToString(query.bbox));81 params.set("limit", "3000");8283 const res = await fetch(`/api/listings.geojson?${params}`, {84 signal: query.signal,85 });86 if (!res.ok) throw new Error(`Map: API ${res.status}`);87 const data = (await res.json()) as HouseKaFC;8889 return {90 properties: data.features.map((f) =>91 toMapProperty(f.geometry.coordinates, f.properties),92 ),93 totalCount: data.totalMatching,94 };95 },96};97