import { useState } from 'react';
import { useNavigate } from 'react-router-dom';
import { useEdgeScanner } from '../../hooks/useEdgeScanner';
import type { EdgeEntry } from '../../hooks/useEdgeScanner';
import { formatPrice } from '../../utils/format';
const SIGNALS = ['All', 'BUY_YES', 'BUY_NO'];
const CATEGORIES = ['All', 'Sports', 'Politics', 'Crypto', 'Weather', 'Tech', 'Finance'];
function ConfBadge({ conf }: { conf: string }) {
const cls = conf === 'HIGH' ? 'es-conf-high' : conf === 'MED' ? 'es-conf-med' : 'es-conf-low';
return <span className={`es-conf ${cls}`}>{conf}</span>;
}
function SignalBadge({ signal }: { signal: string }) {
if (signal === 'NEUTRAL') return null;
const cls = signal === 'BUY_YES' ? 'es-sig-yes' : 'es-sig-no';
return <span className={`es-sig ${cls}`}>{signal === 'BUY_YES' ? 'BUY YES' : 'BUY NO'}</span>;
}
function FactorBar({ label, value }: { label: string; value: number }) {
return (
<div className="es-factor">
<span className="es-factor-label">{label}</span>
<div className="es-factor-track">
<div className="es-factor-fill" style={{ width: `${Math.round(value * 100)}%` }} />
</div>
<span className="es-factor-val">{Math.round(value * 100)}%</span>
</div>
);
}
export default function EdgeScanner() {
const [signal, setSignal] = useState('All');
const [category, setCategory] = useState('All');
const [expanded, setExpanded] = useState<string | null>(null);
const navigate = useNavigate();
const { edges, loading } = useEdgeScanner({
minScore: 0.20,
signal: signal === 'All' ? undefined : signal,
category,
limit: 30,
});
return (
<div className="es-wrap">
{/* Filters */}
<div className="es-filters">
<div className="es-filter-group">
{SIGNALS.map(s => (
<button key={s} className={`pill pill-sm ${signal === s ? 'pill-active' : ''}`}
onClick={() => setSignal(s)}>
{s === 'All' ? 'All' : s === 'BUY_YES' ? 'Buy YES' : 'Buy NO'}
</button>
))}
</div>
<select className="es-select" value={category} onChange={e => setCategory(e.target.value)}>
{CATEGORIES.map(c => <option key={c} value={c}>{c}</option>)}
</select>
</div>
{/* Disclaimer */}
<p className="es-disclaimer">Heuristic model — not financial advice. Factors: spread, volume, whale consensus, momentum, price range.</p>
{/* Loading */}
{loading && edges.length === 0 && (
<div className="es-loading">
{Array.from({ length: 5 }, (_, i) => (
<div key={i} className="es-card es-skeleton">
<div className="skeleton-img" />
<div style={{ flex: 1 }}>
<div className="skeleton-text" style={{ width: `${60 + (i % 3) * 12}%`, height: 14 }} />
<div className="skeleton-text" style={{ width: 80, height: 12, marginTop: 6 }} />
</div>
</div>
))}
</div>
)}
{/* Empty */}
{!loading && edges.length === 0 && (
<div className="sig-empty">No edge signals found. Try adjusting filters.</div>
)}
{/* Results */}
{edges.length > 0 && (
<div className="es-list">
{edges.map((e: EdgeEntry) => {
const pct = e.marketPrice * 100;
const priceColor = pct >= 70 ? 'var(--profit)' : pct <= 30 ? 'var(--loss)' : 'var(--text-primary)';
const isExpanded = expanded === e.marketId;
return (
<div key={e.marketId} className={`es-card ${isExpanded ? 'es-card-expanded' : ''}`}>
<div className="es-card-main" onClick={() => setExpanded(isExpanded ? null : e.marketId)}>
<div className="es-left">
{e.imageUrl && (
<img src={e.imageUrl} alt="" className="es-img"
onError={ev => { (ev.target as HTMLImageElement).style.display = 'none'; }} />
)}
<div className="es-info">
<span className="es-question">{e.question}</span>
<div className="es-meta">
<span className="es-cat">{e.category}</span>
<SignalBadge signal={e.signal} />
<ConfBadge conf={e.confidence} />
</div>
</div>
</div>
<div className="es-right">
<span className="es-edge">{Math.round(e.edgeScore * 100)}%</span>
<span className="es-price" style={{ color: priceColor }}>{formatPrice(e.marketPrice)}</span>
</div>
</div>
{isExpanded && (
<div className="es-detail">
<div className="es-factors">
<FactorBar label="Whale" value={e.factors.whale} />
<FactorBar label="Volume" value={e.factors.volume} />
<FactorBar label="Momentum" value={e.factors.momentum} />
<FactorBar label="Spread" value={e.factors.spread} />
<FactorBar label="Price" value={e.factors.price} />
</div>
<div className="es-detail-stats">
<span>Whale YES: {Math.round(e.whaleYesPct * 100)}%</span>
<span>Vol/Liq: {e.volumeRatio.toFixed(1)}x</span>
</div>
<button className="es-view-btn" onClick={() => navigate(`/market/${e.marketId}`)}>
View Market →
</button>
</div>
)}
</div>
);
})}
</div>
)}
</div>
);
}
📜 Git History
6c47fa4chore: local Polikopi project home + Phase 1 redesign artifacts12 days ago
Show last diff
Loading...