PathLeaderboard.jsx
import { useState } from 'react';
import { formatNumber, formatPercent } from '../utils/formatters';
export default function PathLeaderboard({ paths, loading, onPathSelect, selectedPath }) {
const [sortKey, setSortKey] = useState('rank');
const [sortDir, setSortDir] = useState('asc');
const handleSort = (key) => {
if (sortKey === key) {
setSortDir(sortDir === 'asc' ? 'desc' : 'asc');
} else {
setSortKey(key);
setSortDir(key === 'rank' ? 'asc' : 'desc');
}
};
const sortedPaths = [...paths].sort((a, b) => {
const aVal = a[sortKey];
const bVal = b[sortKey];
return sortDir === 'asc' ? aVal - bVal : bVal - aVal;
});
if (loading) {
return (
<div className="leaderboard loading">
<h2>Path Leaderboard</h2>
{[...Array(10)].map((_, i) => (
<div key={i} className="skeleton skeleton-row"></div>
))}
</div>
);
}
return (
<div className="leaderboard">
<div className="leaderboard-header">
<h2>Path Leaderboard</h2>
<div className="filter-controls">
<button className="filter-btn active">All Paths</button>
<button className="filter-btn">Profitable</button>
</div>
</div>
<table className="leaderboard-table">
<thead>
<tr>
<th onClick={() => handleSort('rank')} className="sortable">
#
{sortKey === 'rank' && (sortDir === 'asc' ? ' ▲' : ' ▼')}
</th>
<th>Path ID</th>
<th onClick={() => handleSort('delta_roi_7d')} className="sortable">
ΔROI 7d
{sortKey === 'delta_roi_7d' && (sortDir === 'asc' ? ' ▲' : ' ▼')}
</th>
<th onClick={() => handleSort('velocity_ms')} className="sortable">
Velocity
{sortKey === 'velocity_ms' && (sortDir === 'asc' ? ' ▲' : ' ▼')}
</th>
<th onClick={() => handleSort('pcr')} className="sortable">
PCR
{sortKey === 'pcr' && (sortDir === 'asc' ? ' ▲' : ' ▼')}
</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
{sortedPaths.map((path) => (
<tr
key={path.path_id}
className={selectedPath === path.path_id ? 'selected' : ''}
onClick={() => onPathSelect(path.path_id)}
>
<td className="rank-cell">
{path.rank <= 3 && (
<span className="rank-badge">
{path.rank === 1 ? '🥇' : path.rank === 2 ? '🥈' : '🥉'}
</span>
)}
{path.rank > 3 && path.rank}
</td>
<td className="path-id-cell">
<code>{path.path_id}</code>
</td>
<td className={getRoiClass(path.delta_roi_7d)}>
<strong>{formatNumber(path.delta_roi_7d, 2)}</strong>
</td>
<td className="velocity-cell">
{Math.round(path.velocity_ms)}ms
</td>
<td>
<div className="pcr-bar-container">
<div
className="pcr-bar"
style={{ width: `${path.pcr * 100}%` }}
></div>
<span className="pcr-text">{formatPercent(path.pcr)}</span>
</div>
</td>
<td className="actions-cell">{path.total_actions}</td>
</tr>
))}
</tbody>
</table>
</div>
);
}
function getRoiClass(roi) {
if (roi > 2) return 'roi-high';
if (roi > 1) return 'roi-medium';
if (roi > 0) return 'roi-low';
return 'roi-negative';
}