import Link from "next/link"; import { sql } from "@/lib/db"; type CityRow = { slug: string; name: string; country_code: string; status: string; last_ingested: string | null; poi_count: number; grid_count: number; error_message: string | null; }; const STATUS_STYLES: Record = { ready: { label: "Ready", className: "bg-green-100 text-green-800" }, processing: { label: "Processing", className: "bg-yellow-100 text-yellow-800" }, error: { label: "Error", className: "bg-red-100 text-red-800" }, pending: { label: "Pending", className: "bg-blue-100 text-blue-800" }, empty: { label: "Empty", className: "bg-gray-100 text-gray-600" }, }; async function getCities(): Promise { return Promise.resolve(sql` SELECT c.slug, c.name, c.country_code, c.status, c.last_ingested, c.error_message, COALESCE(p.poi_count, 0)::int AS poi_count, COALESCE(g.grid_count, 0)::int AS grid_count FROM cities c LEFT JOIN ( SELECT city_slug, COUNT(*) AS poi_count FROM raw_pois GROUP BY city_slug ) p ON p.city_slug = c.slug LEFT JOIN ( SELECT city_slug, COUNT(*) AS grid_count FROM grid_points GROUP BY city_slug ) g ON g.city_slug = c.slug ORDER BY c.name `); } export const dynamic = "force-dynamic"; export default async function AdminDashboard() { const cities = await getCities(); return (

City Management

{cities.length} {cities.length === 1 ? "city" : "cities"} configured

+ Add City
{cities.length === 0 ? (

No cities configured yet.

Add your first city
) : (
{["Name", "Country", "POIs", "Grid Points", "Last Ingested", "Status", "Actions"].map( (h) => ( ), )} {cities.map((city) => { const badge = STATUS_STYLES[city.status] ?? STATUS_STYLES.empty; return ( ); })}
{h}
{city.name} {city.country_code || "—"} {city.poi_count.toLocaleString()} {city.grid_count.toLocaleString()} {city.last_ingested ? new Date(city.last_ingested).toLocaleDateString() : "Never"} {badge.label} {city.status === "processing" && ( )} {city.error_message && (

{city.error_message}

)}
Manage
)}
); }