← Back
import { useState, useEffect, useCallback } from 'react';
import type { Market, MarketsMeta, ScreenerStats } from '../types/market';

interface MarketsParams {
  category?: string;
  search?: string;
  min_volume?: number;
  min_liquidity?: number;
  min_price?: number;
  max_price?: number;
  ending?: string;
  sort?: string;
  order?: string;
  limit?: number;
  offset?: number;
}

interface MarketsState {
  markets: Market[];
  meta: MarketsMeta | null;
  loading: boolean;
  error: string | null;
}

export function useMarkets(params: MarketsParams) {
  const [state, setState] = useState<MarketsState>({
    markets: [],
    meta: null,
    loading: true,
    error: null,
  });

  const fetchMarkets = useCallback(async () => {
    setState(prev => ({ ...prev, loading: true, error: null }));
    try {
      const qs = new URLSearchParams();
      if (params.category && params.category !== 'All') qs.set('category', params.category);
      if (params.search) qs.set('search', params.search);
      if (params.min_volume) qs.set('min_volume', String(params.min_volume));
      if (params.min_liquidity) qs.set('min_liquidity', String(params.min_liquidity));
      if (params.min_price) qs.set('min_price', String(params.min_price));
      if (params.max_price !== undefined && params.max_price < 1) qs.set('max_price', String(params.max_price));
      if (params.ending) qs.set('ending', params.ending);
      if (params.sort) qs.set('sort', params.sort);
      if (params.order) qs.set('order', params.order);
      qs.set('limit', String(params.limit || 50));
      qs.set('offset', String(params.offset || 0));

      const res = await fetch(`/api/screener/markets?${qs}`);
      const json = await res.json();

      if (json.success) {
        setState({
          markets: json.data.markets,
          meta: json.data.meta,
          loading: false,
          error: null,
        });
      } else {
        setState(prev => ({ ...prev, loading: false, error: json.error || 'Failed to load' }));
      }
    } catch {
      setState(prev => ({ ...prev, loading: false, error: 'Network error' }));
    }
  }, [
    params.category, params.search, params.min_volume, params.min_liquidity,
    params.min_price, params.max_price, params.ending, params.sort,
    params.order, params.limit, params.offset
  ]);

  useEffect(() => {
    const t = setTimeout(fetchMarkets, 0);
    return () => { clearTimeout(t); };
  }, [fetchMarkets]);

  return { ...state, refetch: fetchMarkets };
}

export function useStats() {
  const [stats, setStats] = useState<ScreenerStats | null>(null);
  const [loading, setLoading] = useState(true);

  useEffect(() => {
    const t = setTimeout(() => {
      fetch('/api/screener/stats')
        .then(r => r.json())
        .then(d => { if (d.success) setStats(d.data); })
        .catch(() => {})
        .finally(() => setLoading(false));
    }, 0);
    return () => { clearTimeout(t); };
  }, []);

  return { stats, loading };
}

📜 Git History

6c47fa4chore: local Polikopi project home + Phase 1 redesign artifacts12 days ago
Show last diff
Loading...