// ----------------------------------------------------------------------------- // Home-Ka — US real-estate aggregator (Groupe KA) // Author: Simon-Pierre Boucher — contact@spboucher.ai // pages/Sources.tsx : public registry of data sources (/api/sources) // ----------------------------------------------------------------------------- import { useEffect, useState } from "react"; import { Link } from "react-router-dom"; import { Source, fetchSources, registerSourceNames } from "../api"; function ago(ts: number | null): string { if (ts == null) return "never"; const s = Math.max(0, Math.floor(Date.now() / 1000 - (ts > 1e12 ? ts / 1000 : ts))); if (s < 3600) return `${Math.round(s / 60)} min ago`; if (s < 172800) return `${Math.round(s / 3600)} h ago`; return `${Math.round(s / 86400)} d ago`; } export default function SourcesPage() { const [sources, setSources] = useState(null); const [error, setError] = useState(null); useEffect(() => { fetchSources() .then((r) => { registerSourceNames(r.sources); setSources(r.sources); }) .catch((e) => setError(String(e))); }, []); const totalListings = (sources ?? []).reduce((s, x) => s + x.active_listings, 0); const enabled = (sources ?? []).filter((s) => s.enabled).length; return (
Registry — data sources

Data sources

Every listing on Home-Ka comes from a registered source — brokerage feeds, MLS/RESO APIs and listing platforms. Each source is synced by a dedicated connector and de-duplicated by MLS number and property match. Click a count to browse its homes.

{error &&
{error}
} {!sources && !error &&
Loading…
} {sources && ( <>

{totalListings.toLocaleString("en-US")} active listings ·{" "} {sources.length} sources ·{" "} {enabled} enabled

{sources.map((s) => ( ))}
SourceConnectorStates Active listingsLast sync
{s.name || s.id} {!s.enabled && disabled} {s.connector_type ?? "—"} {s.states?.length ? s.states.join(", ") : "—"} {s.active_listings > 0 ? {s.active_listings.toLocaleString("en-US")} : "0"} {ago(s.last_sync)}

Listings published by more than one source are de-duplicated by MLS number and by matching the underlying property — no double counting.

)}
); }