← back to Bertha

kalshi-dash/src/setup/steps/FetchWeather.jsx

80 lines

import React, { useState, useEffect } from 'react';
import { post } from '../../api';

export default function FetchWeather({ data, update, next, back }) {
  const [loading, setLoading] = useState(true);
  const [result, setResult] = useState(null);
  const [error, setError] = useState(null);

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

  async function runFetch() {
    setLoading(true); setError(null);
    try {
      const r = await post('/weather', { action: 'fetch_all' });
      setResult(r);
      update({ weatherFetched: true });
    } catch { setError('Failed to fetch weather data'); }
    setLoading(false);
  }

  return (
    <div className="space-y-6">
      <div className="text-center">
        <h2 className="text-2xl font-bold mb-2">Checking the Weather, Darling</h2>
        <p className="text-gray-400 text-sm">I'm schlepping in the government weather reports. In my day we just looked outside.</p>
      </div>

      <div className="card">
        {loading ? (
          <div className="flex flex-col items-center justify-center py-12 gap-4">
            <div className="animate-spin w-10 h-10 border-3 border-blue-500 border-t-transparent rounded-full" />
            <p className="text-sm text-gray-400">Fetching from the National Weather Service... they take their sweet time</p>
          </div>
        ) : error ? (
          <div className="text-center py-8">
            <p className="text-red-400 text-sm mb-3">{error}</p>
            <button onClick={runFetch} className="btn btn-s text-sm">Retry</button>
          </div>
        ) : (
          <div className="space-y-4">
            <div className="flex items-center justify-center gap-3 py-4">
              <div className="w-12 h-12 rounded-full bg-green-500/10 flex items-center justify-center">
                <svg className="w-6 h-6 text-green-400" fill="none" stroke="currentColor" strokeWidth="2" viewBox="0 0 24 24"><path strokeLinecap="round" strokeLinejoin="round" d="M5 13l4 4L19 7" /></svg>
              </div>
              <div>
                <p className="font-semibold text-green-400">Got the Weather, Finally</p>
                <p className="text-xs text-gray-400">All the fancy government data, right here in your tuchas seat</p>
              </div>
            </div>
            <div className="grid grid-cols-3 gap-4">
              <div className="text-center p-3 bg-gray-800/30 rounded-lg">
                <p className="stat-v text-blue-400">{result?.stations || '—'}</p>
                <p className="text-xs text-gray-500 mt-1">Stations</p>
              </div>
              <div className="text-center p-3 bg-gray-800/30 rounded-lg">
                <p className="stat-v text-amber-400">{result?.data_points || '—'}</p>
                <p className="text-xs text-gray-500 mt-1">Data Points</p>
              </div>
              <div className="text-center p-3 bg-gray-800/30 rounded-lg">
                <p className="stat-v text-green-400">{result?.metrics?.length || '—'}</p>
                <p className="text-xs text-gray-500 mt-1">Metrics</p>
              </div>
            </div>
          </div>
        )}
      </div>

      <div className="card bg-gray-800/30">
        <p className="text-xs text-gray-500 mb-1 font-medium">How They Settle (Pay Attention)</p>
        <p className="text-xs text-gray-400">Ken settles on the <span className="text-amber-400">final NWS Daily Climate Report</span>. A trace of rain? That's zero. Missing data? Also zero. And listen — the first report is the last word. They don't go back and change it, even if the weatherman was wrong. Such is life.</p>
      </div>

      <div className="flex items-center justify-between">
        <button onClick={back} className="text-sm text-gray-500 hover:text-gray-300">Back</button>
        <button onClick={next} disabled={loading} className="btn btn-p">{loading ? 'Fetching...' : 'Continue'}</button>
      </div>
    </div>
  );
}