← back to Ken

src/app/dashboard/markets/page.js

102 lines

'use client';
import { useState, useEffect } from 'react';

export default function MarketsPage() {
  const [markets, setMarkets] = useState([]);
  const [loading, setLoading] = useState(true);
  const [ingesting, setIngesting] = useState(false);

  async function loadMarkets() {
    try {
      const res = await fetch('/api/markets');
      const data = await res.json();
      setMarkets(data.markets || []);
    } catch (err) { console.error(err); }
    setLoading(false);
  }

  useEffect(() => { loadMarkets(); }, []);

  async function ingestMarkets() {
    setIngesting(true);
    try {
      const res = await fetch('/api/markets', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ action: 'ingest' }) });
      const data = await res.json();
      alert(`Ingested ${data.ingested || 0} weather markets`);
      loadMarkets();
    } catch (err) { alert('Ingest error: ' + err.message); }
    setIngesting(false);
  }

  async function parseMarket(conditionId) {
    try {
      const res = await fetch('/api/markets', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ action: 'parse', condition_id: conditionId }) });
      const data = await res.json();
      alert(JSON.stringify(data.parsed, null, 2));
      loadMarkets();
    } catch (err) { alert('Parse error: ' + err.message); }
  }

  if (loading) return <div className="flex items-center justify-center h-64"><div className="animate-spin w-8 h-8 border-2 border-blue-500 border-t-transparent rounded-full" /></div>;

  return (
    <div className="space-y-6">
      <div className="flex items-center justify-between">
        <div>
          <h1 className="text-2xl font-bold">Markets</h1>
          <p className="text-gray-500 text-sm">Polymarket weather-related markets</p>
        </div>
        <button onClick={ingestMarkets} disabled={ingesting} className="btn btn-primary">
          {ingesting ? 'Ingesting...' : 'Ingest Markets'}
        </button>
      </div>

      <div className="grid grid-cols-3 gap-4">
        <div className="card"><p className="text-xs text-gray-500 uppercase mb-1">Total Markets</p><p className="stat-value text-blue-400">{markets.length}</p></div>
        <div className="card"><p className="text-xs text-gray-500 uppercase mb-1">Active</p><p className="stat-value text-green-400">{markets.filter(m => m.active).length}</p></div>
        <div className="card"><p className="text-xs text-gray-500 uppercase mb-1">With Predictions</p><p className="stat-value text-purple-400">{markets.filter(m => m.prediction_count > 0).length}</p></div>
      </div>

      <div className="card overflow-x-auto">
        <table>
          <thead>
            <tr>
              <th>Question</th>
              <th>Category</th>
              <th>Liquidity</th>
              <th>End Date</th>
              <th>Parsed</th>
              <th>Actions</th>
            </tr>
          </thead>
          <tbody>
            {markets.length === 0 ? (
              <tr><td colSpan={6} className="text-center text-gray-500 py-8">No markets yet. Click "Ingest Markets" to scan Polymarket.</td></tr>
            ) : markets.map(m => (
              <tr key={m.condition_id}>
                <td className="max-w-[300px]">
                  <p className="truncate font-medium">{m.question}</p>
                  <p className="text-xs text-gray-500 truncate">{m.condition_id}</p>
                </td>
                <td><span className="badge badge-blue">{m.category || 'weather'}</span></td>
                <td className="font-mono">${parseFloat(m.liquidity || 0).toFixed(0)}</td>
                <td className="text-gray-400 text-sm">{m.end_ts ? new Date(m.end_ts).toLocaleDateString() : '-'}</td>
                <td>
                  {m.parsed_event ? (
                    <span className="badge badge-green">Yes</span>
                  ) : (
                    <span className="badge badge-yellow">No</span>
                  )}
                </td>
                <td>
                  <button onClick={() => parseMarket(m.condition_id)} className="text-xs text-blue-400 hover:text-blue-300">Parse</button>
                </td>
              </tr>
            ))}
          </tbody>
        </table>
      </div>
    </div>
  );
}