48 lines
1.7 KiB
TypeScript
48 lines
1.7 KiB
TypeScript
"use client";
|
|
|
|
import type { CityStats, CategoryId } from "@transportationer/shared";
|
|
import { CATEGORIES } from "@transportationer/shared";
|
|
|
|
interface StatsBarProps {
|
|
stats: CityStats | null;
|
|
activeCategory: CategoryId | "composite";
|
|
}
|
|
|
|
export function StatsBar({ stats, activeCategory }: StatsBarProps) {
|
|
if (!stats) return null;
|
|
|
|
const displayStats =
|
|
activeCategory === "composite"
|
|
? stats.categoryStats
|
|
: stats.categoryStats.filter((s) => s.category === activeCategory);
|
|
|
|
return (
|
|
<div className="bg-white border-t border-gray-200 px-6 py-3 flex items-center gap-6 text-sm overflow-x-auto">
|
|
<div className="shrink-0">
|
|
<span className="text-gray-500">POIs: </span>
|
|
<span className="font-semibold">{stats.totalPois.toLocaleString()}</span>
|
|
</div>
|
|
<div className="shrink-0">
|
|
<span className="text-gray-500">Grid: </span>
|
|
<span className="font-semibold">{stats.gridPointCount.toLocaleString()}</span>
|
|
</div>
|
|
<div className="w-px h-4 bg-gray-200 shrink-0" />
|
|
{displayStats.map((s) => {
|
|
const cat = CATEGORIES.find((c) => c.id === s.category);
|
|
return (
|
|
<div key={s.category} className="shrink-0 flex items-center gap-2">
|
|
{cat && (
|
|
<span
|
|
className="w-2 h-2 rounded-full"
|
|
style={{ backgroundColor: cat.color }}
|
|
/>
|
|
)}
|
|
<span className="text-gray-600">{cat?.label ?? s.category}: </span>
|
|
<span className="font-semibold">{s.coveragePct.toFixed(0)}%</span>
|
|
<span className="text-gray-400 text-xs">within threshold</span>
|
|
</div>
|
|
);
|
|
})}
|
|
</div>
|
|
);
|
|
}
|