"use client"; import { useMemo, useState } from "react"; import { Badge, Button, EmptyState, Table, TBody, Td, Th, THead, Tr } from "@/components/ui"; import { cn } from "@/components/ui/cn"; import { DASH, fmtInt, fmtValue } from "@/lib/format"; import { adminFetch, type RunSampleResult } from "@/lib/admin-api"; import { Disclosure, ErrorNote, ExtLink, Field, fmtMs, JsonView, LevelBadge, Mono, Panel, Select, Spinner, Textarea } from "../primitives"; import { useToast } from "../toast"; import { fieldUnion, isEmptyValue, parseUrls, type DevtoolShared } from "./state"; const HIDDEN = new Set(["provenance", "entityType", "key", "sourceUrl", "url"]); export function StepSample({ s }: { s: DevtoolShared }) { const { draft, update, sampleResult: r, setSampleResult } = s; const [busy, setBusy] = useState(false); const [error, setError] = useState(null); const [level, setLevel] = useState(""); const toast = useToast(); const urls = useMemo(() => parseUrls(draft.sampleUrls), [draft.sampleUrls]); const run = async () => { if (!draft.yaml.trim()) return setError("No YAML — generate or paste it in step 4 first."); if (urls.length === 0) return setError("Enter at least one http(s) URL (one per line)."); if (urls.length > 10) return setError("At most 10 URLs per run."); setBusy(true); setError(null); const res = await adminFetch("devtool/run-sample", { method: "POST", body: { yaml: draft.yaml, urls, level: level ? Number(level) : undefined }, timeoutMs: 290_000 }); setBusy(false); if (!res.ok) { setError(res.error); toast({ tone: "danger", title: "Sample run failed", description: res.error }); return; } setSampleResult(res.data); toast({ tone: res.data.summary.ok === res.data.summary.urls ? "ok" : "warn", title: `${res.data.summary.ok}/${res.data.summary.urls} pages produced valid entities`, description: res.data.summary.credits ? `${res.data.summary.credits} premium credits spent` : "no premium credits" }); }; const firstEntities = useMemo(() => (r ? r.results.map((x) => x.entities?.[0] ?? null) : []), [r]); const fields = useMemo(() => fieldUnion(firstEntities.filter((e): e is Record => Boolean(e)), ["name", "operatorName", "city", "countryIso2", "lat", "lng", "status", "facilityType", "itCapacityMw", "totalPowerMw", "plannedPowerMw", "openedOn"]).filter((f) => !HIDDEN.has(f)), [firstEntities]); return (