"use client"; import { useState } from "react"; import Link from "next/link"; import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"; import { Skeleton } from "@/components/ui/skeleton"; import { Map as MapIcon, Wind } from "lucide-react"; import { cn } from "@/lib/utils"; import { useThresholds } from "@/lib/threshold-context"; import type { RackCapacity } from "@/lib/api"; type RowLayout = { label: string; racks: string[] }; type RoomLayout = { label: string; crac_id: string; rows: RowLayout[] }; type FloorLayout = Record; interface Props { layout: FloorLayout | null; racks: RackCapacity[]; loading: boolean; } function tempBg(temp: number | null, warn: number, crit: number): string { if (temp === null) return "oklch(0.22 0.02 265)"; if (temp >= crit + 4) return "oklch(0.55 0.22 25)"; if (temp >= crit) return "oklch(0.65 0.20 45)"; if (temp >= warn) return "oklch(0.72 0.18 84)"; if (temp >= warn - 2) return "oklch(0.78 0.14 140)"; if (temp >= warn - 4) return "oklch(0.68 0.14 162)"; return "oklch(0.60 0.15 212)"; } export function MiniFloorMap({ layout, racks, loading }: Props) { const { thresholds } = useThresholds(); const warn = thresholds.temp.warn; const crit = thresholds.temp.critical; const rackMap: globalThis.Map = new globalThis.Map(racks.map(r => [r.rack_id, r] as [string, RackCapacity])); const roomIds = layout ? Object.keys(layout) : []; const [activeRoom, setActiveRoom] = useState(() => roomIds[0] ?? ""); const currentRoomId = activeRoom || roomIds[0] || ""; return (
Floor Map — Temperature Full map →
{/* Room tabs */} {roomIds.length > 1 && (
{roomIds.map(id => ( ))}
)}
{loading ? ( ) : !layout || roomIds.length === 0 ? (
No layout configured
) : (
{(layout[currentRoomId]?.rows ?? []).map((row, rowIdx, allRows) => (
{/* Rack row */}
{row.racks.map(rackId => { const rack = rackMap.get(rackId); const bg = tempBg(rack?.temp ?? null, warn, crit); return (
); })}
{/* Cold aisle separator between rows */} {rowIdx < allRows.length - 1 && (
Cold Aisle
)}
))} {/* CRAC label */} {layout[currentRoomId]?.crac_id && (
{layout[currentRoomId].crac_id.toUpperCase()}
)}
{/* Temp legend */}
Cool {(["oklch(0.60 0.15 212)","oklch(0.68 0.14 162)","oklch(0.78 0.14 140)","oklch(0.72 0.18 84)","oklch(0.65 0.20 45)","oklch(0.55 0.22 25)"] as string[]).map((c, i) => ( ))} Hot Click to open full map
)} ); }