SPB Git

spb/lou-ka Public

Lou·Ka — tous les logements à louer du Québec, un seul endroit.

HTML 99.7%
2.7 KB · 75 lines tsx
Raw Blame History
1// -----------------------------------------------------------------------------2// Lou-Ka — Agrégateur de logements à louer (province de Québec)3// Auteur : Simon-Pierre Boucher — contact@spboucher.ai4// pages/Sources.tsx : registre des gestionnaires immobiliers agrégés5// -----------------------------------------------------------------------------6import { useEffect, useState } from "react";7import { Source, fetchSources } from "../api";89export default function SourcesPage() {10  const [sources, setSources] = useState<Source[] | null>(null);11  const [error, setError] = useState<string | null>(null);1213  useEffect(() => {14    fetchSources()15      .then((r) => setSources(r.sources))16      .catch((e) => setError(String(e)));17  }, []);1819  return (20    <div className="container sources">21      <span className="kicker">Registre — gestionnaires immobiliers</span>22      <h1>Sources agrégées</h1>23      <p className="sub">24        Gestionnaires immobiliers de Québec, Lévis et du Grand Montréal recensés par Lou-Ka. Chaque source «25        active » est synchronisée périodiquement par un connecteur dédié; les autres sont en26        attente de connecteur.27      </p>2829      {error && <div className="notice">⚠️ {error}</div>}30      {!sources && !error && <div className="notice">Chargement…</div>}3132      {sources && (33        <div className="src-wrap">34        <table className="src-table">35          <thead>36            <tr>37              <th>Gestionnaire</th>38              <th>Secteurs</th>39              <th>Statut</th>40              <th style={{ textAlign: "right" }}>Annonces actives</th>41              <th>Dernière synchro</th>42            </tr>43          </thead>44          <tbody>45            {sources.map((s) => (46              <tr key={s.id}>47                <td>48                  <a href={s.url} target="_blank" rel="noopener noreferrer">{s.name}</a>49                </td>50                <td style={{ color: "var(--ink-2)", maxWidth: 380 }}>{s.sectors}</td>51                <td>52                  {s.connector ? (53                    <span className="pill ok">connecté</span>54                  ) : (55                    <span className="pill todo">{s.status}</span>56                  )}57                </td>58                <td style={{ textAlign: "right" }}>59                  <span className="count-pill">{s.active_listings || "—"}</span>60                </td>61                <td style={{ color: "var(--ink-3)" }}>62                  {s.last_sync63                    ? new Date(s.last_sync * 1000).toLocaleString("fr-CA")64                    : "—"}65                </td>66              </tr>67            ))}68          </tbody>69        </table>70        </div>71      )}72    </div>73  );74}75