spb/auto-ka Public
Python 82.8%
TypeScript 11.9%
CSS 5.1%
1// -----------------------------------------------------------------------------2// Auto-Ka — Agrégateur de voitures usagées à vendre (province de Québec)3// Auteur : Simon-Pierre Boucher — contact@spboucher.ai4// Sources.tsx : registre des concessionnaires connectés5// -----------------------------------------------------------------------------6import { useEffect, useState } from "react";7import { Link } from "react-router-dom";8import { Source, fetchSources, fmtDate } from "../api";910export default function SourcesPage() {11 const [sources, setSources] = useState<Source[]>([]);1213 useEffect(() => {14 fetchSources().then((r) => setSources(r.sources)).catch(() => {});15 }, []);1617 const actives = sources.filter((s) => s.active_listings > 0);18 const others = sources.filter((s) => s.active_listings === 0);1920 return (21 <div className="container page">22 <span className="kicker">Registre</span>23 <h1>Les concessionnaires connectés</h1>24 <p className="lead">25 Un connecteur dédié par commerce — Auto-Ka lit chaque site à la source26 (aucune plateforme d'annonces), normalise l'inventaire et le tient à jour.27 </p>28 <div className="src-grid">29 {actives30 .sort((a, b) => b.active_listings - a.active_listings)31 .map((s) => (32 <div key={s.id} className="src-card">33 <h3>{s.name}</h3>34 <div className="meta">35 {s.city}{s.region ? ` · ${s.region}` : ""}{s.platform ? ` · ${s.platform}` : ""}36 </div>37 <div className="n">{s.active_listings.toLocaleString("fr-CA")} véhicules</div>38 <div className="meta">dernière sync : {fmtDate(s.last_sync)}</div>39 <div style={{ display: "flex", gap: 10, marginTop: 6 }}>40 <Link className="mono" style={{ fontSize: 12, textDecoration: "underline" }} to={`/?source=${s.id}`}>41 voir l'inventaire42 </Link>43 <a className="mono" style={{ fontSize: 12, textDecoration: "underline" }} href={s.url} target="_blank" rel="noreferrer">44 site officiel ↗45 </a>46 </div>47 </div>48 ))}49 </div>50 {others.length > 0 && (51 <>52 <h2 style={{ margin: "36px 0 14px" }}>En attente de première synchronisation</h2>53 <div className="src-grid">54 {others.map((s) => (55 <div key={s.id} className="src-card" style={{ opacity: 0.65 }}>56 <h3>{s.name}</h3>57 <div className="meta">{s.city}{s.region ? ` · ${s.region}` : ""}</div>58 <div className="meta">{s.status || "connecteur prêt"}</div>59 </div>60 ))}61 </div>62 </>63 )}64 </div>65 );66}67