spb/immo-ka Public
Immo-Ka — agrégateur des propriétés à vendre au Québec (73 connecteurs, ~40 000 annonces, React+FastAPI)
Python 67.2%
TypeScript 19.4%
CSS 12.9%
HTML 0.5%
1// -----------------------------------------------------------------------------2// Immo-Ka — Agrégateur de propriétés à vendre (province de Québec)3// Auteur : Simon-Pierre Boucher — contact@spboucher.ai4// components/ListingCard.tsx : carte de propriété (grille de résultats)5// -----------------------------------------------------------------------------6import { Link } from "react-router-dom";7import { Listing, fmtArea, fmtPrice, sourceName } from "../api";89export default function ListingCard({ l }: { l: Listing }) {10 const img = l.images && l.images.length > 0 ? l.images[0] : null;11 const meta: string[] = [];12 if (l.bedrooms != null) meta.push(`${l.bedrooms} ch.`);13 if (l.bathrooms != null) meta.push(`${l.bathrooms} sdb`);14 const area = fmtArea(l.area_sqft);15 if (area) meta.push(area);1617 return (18 <Link to={`/propriete/${encodeURIComponent(l.uid)}`} className="card">19 <div className="card-img">20 {img ? (21 <img src={img} alt={l.title || l.address} loading="lazy" />22 ) : (23 <div className="noimg">🏠</div>24 )}25 {l.property_type && <span className="badge type">{l.property_type}</span>}26 {l.images.length > 1 && (27 <span className="badge right">📷 {l.images.length}</span>28 )}29 </div>30 <div className="card-body">31 <div className="card-price">{fmtPrice(l.price, l.price_label)}</div>32 <div className="card-title">{l.address || l.title}</div>33 <div className="card-meta">34 {l.sector && <span>{l.sector}</span>}35 {l.sector && l.city && <span className="sep" />}36 {l.city && <span>{l.city}</span>}37 </div>38 {meta.length > 0 && (39 <div className="card-specs">40 {meta.map((m) => (41 <span key={m}>{m}</span>42 ))}43 </div>44 )}45 <div className="card-foot">46 <span className="source-tag">{sourceName(l.source)}</span>47 {l.mls && <span className="avail">MLS {l.mls}</span>}48 </div>49 </div>50 </Link>51 );52}53