"use client"; import Link from "next/link"; import { useEffect, useState } from "react"; import { Search } from "lucide-react"; import { api, type Instrument } from "@/lib/api"; import { useAsync, useDebounced } from "@/lib/hooks"; import { useToast } from "@/lib/toast"; import { fmtInt } from "@/lib/format"; import { Card, ErrorState, Field, PageHeader, StatusBadge } from "@/components/ui"; import { DataTable } from "@/components/DataTable"; interface Out { data: Instrument[]; meta: { total_instruments: number; active: number }; next_cursor: string | null; } export default function SymbolsPage() { const [q, setQ] = useState(""); const [status, setStatus] = useState(""); const [assetClass, setAssetClass] = useState(""); const dq = useDebounced(q.trim(), 300); const [rows, setRows] = useState([]); const [cursor, setCursor] = useState(null); const [more, setMore] = useState(false); const toast = useToast(); const { data, error, loading, reload } = useAsync((s) => api.get("/instruments", { query: dq, status, asset_class: assetClass, limit: 100 }, s), [dq, status, assetClass]); useEffect(() => { if (data) { setRows(data.data); setCursor(data.next_cursor); } }, [data]); async function loadMore() { if (!cursor) return; setMore(true); try { const out = await api.get("/instruments", { query: dq, status, asset_class: assetClass, limit: 100, cursor }); setRows((r) => [...r, ...out.data]); setCursor(out.next_cursor); } catch (e) { toast.error(e); } finally { setMore(false); } } return ( <> {fmtInt(data.meta.total_instruments)} instruments · {fmtInt(data.meta.active)} active : "Instrument master"} />
setQ(e.target.value)} autoFocus />
{error && } r.instrument_id} mobile="scroll" columns={[ { key: "symbol", header: "Symbol", render: (r) => ( {r.symbol} ), }, { key: "name", header: "Name", render: (r) => {r.name ?? "—"} }, { key: "asset_class", header: "Class", hideSm: true }, { key: "status", header: "Status", render: (r) => }, { key: "first_date", header: "First", hideSm: true, render: (r) => {r.first_date ?? "—"} }, { key: "last_date", header: "Last", hideSm: true, render: (r) => {r.last_date ?? "—"} }, { key: "currency", header: "Ccy", hideSm: true }, ]} empty={dq ? `No instrument matches “${dq}”.` : "No instruments yet — run a metadata job."} footer={ <> {fmtInt(rows.length)} shown {cursor && ( )} } /> ); }