104 lines
3.7 KiB
TypeScript
104 lines
3.7 KiB
TypeScript
'use client';
|
|
|
|
import { FUEL_TYPE_COLORS } from './power-plant-marker.js';
|
|
|
|
interface MapLegendProps {
|
|
showPowerPlants?: boolean;
|
|
}
|
|
|
|
const FUEL_TYPE_DISPLAY_ORDER = [
|
|
'Natural Gas',
|
|
'Coal',
|
|
'Nuclear',
|
|
'Hydroelectric',
|
|
'Wind',
|
|
'Solar',
|
|
'Petroleum',
|
|
'Biomass',
|
|
'Geothermal',
|
|
];
|
|
|
|
export function MapLegend({ showPowerPlants = false }: MapLegendProps) {
|
|
return (
|
|
<div className="text-xs">
|
|
{/* Price heatmap gradient */}
|
|
<div className="mb-2.5">
|
|
<div className="mb-1 font-medium text-zinc-300">Price Heatmap</div>
|
|
<div
|
|
className="h-3 w-30 rounded-sm"
|
|
style={{
|
|
background: 'linear-gradient(to right, rgb(30,80,220), rgb(60,220,200), rgb(255,160,30), rgb(220,40,110))',
|
|
}}
|
|
/>
|
|
<div className="mt-0.5 flex w-30 justify-between text-zinc-500">
|
|
<span>$0</span>
|
|
<span>$50</span>
|
|
<span>$100+</span>
|
|
</div>
|
|
<div className="mt-0.5 text-zinc-500">$/MWh</div>
|
|
</div>
|
|
|
|
{/* Marker size scale */}
|
|
<div className="mb-2.5">
|
|
<div className="mb-1 font-medium text-zinc-300">Datacenter Size</div>
|
|
<div className="flex items-end gap-2.5">
|
|
<div className="flex flex-col items-center gap-0.5">
|
|
<div className="h-3.5 w-3.5 rounded-full border border-white/60 bg-zinc-500" />
|
|
<span className="text-zinc-500">50</span>
|
|
</div>
|
|
<div className="flex flex-col items-center gap-0.5">
|
|
<div className="h-5 w-5 rounded-full border border-white/60 bg-zinc-500" />
|
|
<span className="text-zinc-500">200</span>
|
|
</div>
|
|
<div className="flex flex-col items-center gap-0.5">
|
|
<div className="h-7 w-7 rounded-full border border-white/60 bg-zinc-500" />
|
|
<span className="text-zinc-500">500+</span>
|
|
</div>
|
|
<span className="pb-0.5 text-zinc-500">MW</span>
|
|
</div>
|
|
</div>
|
|
|
|
{/* Pulsing icon */}
|
|
<div className="mb-1.5 flex items-center gap-2">
|
|
<span className="relative flex h-3 w-3">
|
|
<span className="absolute inline-flex h-full w-full animate-ping rounded-full bg-amber-400 opacity-75" />
|
|
<span className="relative inline-flex h-3 w-3 rounded-full bg-amber-500" />
|
|
</span>
|
|
<span className="text-zinc-400">Price spike</span>
|
|
</div>
|
|
|
|
{/* Grid stress glow icon */}
|
|
<div className={showPowerPlants ? 'mb-2.5 flex items-center gap-2' : 'flex items-center gap-2'}>
|
|
<span className="relative flex h-3 w-3">
|
|
<span className="ambient-glow-slow absolute inline-flex h-full w-full rounded-full bg-red-500/60" />
|
|
<span className="relative inline-flex h-3 w-3 rounded-full bg-red-500/80" />
|
|
</span>
|
|
<span className="text-zinc-400">Grid stress >85%</span>
|
|
</div>
|
|
|
|
{/* Power plant fuel type legend */}
|
|
{showPowerPlants && (
|
|
<div className="border-t border-zinc-700/60 pt-2">
|
|
<div className="mb-1.5 font-medium text-zinc-300">Power Plants</div>
|
|
<div className="grid grid-cols-2 gap-x-3 gap-y-1">
|
|
{FUEL_TYPE_DISPLAY_ORDER.map(fuel => (
|
|
<div key={fuel} className="flex items-center gap-1.5">
|
|
<div
|
|
className="h-2.5 w-2.5 shrink-0"
|
|
style={{
|
|
backgroundColor: FUEL_TYPE_COLORS[fuel] ?? '#9CA3AF',
|
|
transform: 'rotate(45deg)',
|
|
borderRadius: 1,
|
|
opacity: 0.7,
|
|
}}
|
|
/>
|
|
<span className="truncate text-zinc-400">{fuel}</span>
|
|
</div>
|
|
))}
|
|
</div>
|
|
</div>
|
|
)}
|
|
</div>
|
|
);
|
|
}
|