SPB Git

spb/auto-ka Public

Python 82.8% TypeScript 11.9% CSS 5.1%
2.8 KB · 67 lines tsx
Raw Blame History
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