minor bugs
This commit is contained in:
@@ -387,22 +387,23 @@ export function App() {
|
||||
</div>
|
||||
|
||||
<div className="grid2">
|
||||
{/* Verification leaderboard — assigned users ranked by completion speed */}
|
||||
{/* Verification leaderboard — assigned users ranked by annotation throughput
|
||||
(most annotations in the least time), not by video count. */}
|
||||
<section className="panel">
|
||||
<h3>Verification leaderboard <span className="dim">· fastest first</span></h3>
|
||||
<h3>Verification leaderboard <span className="dim">· most annotations / min</span></h3>
|
||||
<table>
|
||||
<thead>
|
||||
<tr><th>Rank</th><th>User</th><th>Verified</th><th>Speed (avg/video)</th><th>Annotations</th><th>Total time</th></tr>
|
||||
<tr><th>Rank</th><th>User</th><th>Annotations</th><th>Anno/min</th><th>Verified</th><th>Total time</th></tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{stats?.verifiers.map((r) => (
|
||||
<tr key={r.user} className={r.rank === 1 ? "rank-top" : undefined}>
|
||||
<td>{r.rank > 0 ? (r.rank === 1 ? "🥇 1" : `#${r.rank}`) : <span className="dim">—</span>}</td>
|
||||
<td>{r.user}</td>
|
||||
<td>{r.videos > 0 ? r.videos : <span className="dim">0</span>}</td>
|
||||
<td>{r.videos > 0 ? fmtDuration(r.avg_time_ms) : <span className="dim">—</span>}</td>
|
||||
<td>{r.annotations > 0 ? r.annotations : <span className="dim">0</span>}</td>
|
||||
<td>{r.videos > 0 ? fmtDuration(r.total_time_ms) : <span className="dim">—</span>}</td>
|
||||
<td>{r.annotations_per_min > 0 ? r.annotations_per_min.toFixed(1) : <span className="dim">—</span>}</td>
|
||||
<td>{r.videos > 0 ? r.videos : <span className="dim">0</span>}</td>
|
||||
<td>{r.total_time_ms > 0 ? fmtDuration(r.total_time_ms) : <span className="dim">—</span>}</td>
|
||||
</tr>
|
||||
))}
|
||||
{(!stats || stats.verifiers.length === 0) && (
|
||||
|
||||
@@ -91,7 +91,8 @@ export interface VerifierRow {
|
||||
total_time_ms: number;
|
||||
avg_time_ms: number;
|
||||
annotations: number; // total annotations this user authored
|
||||
rank: number; // 1 = fastest; 0 = no completions yet
|
||||
annotations_per_min: number; // throughput: annotations added per minute (ranking metric)
|
||||
rank: number; // 1 = highest throughput; 0 = not yet ranked
|
||||
}
|
||||
|
||||
export interface ProjectTime {
|
||||
@@ -288,12 +289,20 @@ export function fmtBytes(n: number): string {
|
||||
return `${(n / 1024 ** i).toFixed(i ? 1 : 0)} ${u[i]}`;
|
||||
}
|
||||
|
||||
/** Readable local date+time for a server ISO timestamp; "" when missing/invalid. */
|
||||
/** Readable date+time for a server ISO timestamp, shown in IST (Asia/Kolkata)
|
||||
* regardless of the viewer's/VM's timezone; "" when missing/invalid. Server
|
||||
* timestamps are UTC (TIMESTAMPTZ), so the instant is converted, not relabelled. */
|
||||
export function fmtWhen(iso: string | null): string {
|
||||
if (!iso) return "";
|
||||
const d = new Date(iso);
|
||||
if (isNaN(d.getTime())) return "";
|
||||
return d.toLocaleString([], { month: "short", day: "numeric", hour: "2-digit", minute: "2-digit" });
|
||||
return d.toLocaleString("en-IN", {
|
||||
timeZone: "Asia/Kolkata",
|
||||
month: "short",
|
||||
day: "numeric",
|
||||
hour: "2-digit",
|
||||
minute: "2-digit",
|
||||
}) + " IST";
|
||||
}
|
||||
|
||||
export function fmtDuration(ms: number): string {
|
||||
|
||||
Reference in New Issue
Block a user