import { useState, useMemo } from 'react'; import { Plus, Server, MapPin, Zap, HardDrive, Wrench, ChevronRight, Thermometer, Shield, Rocket, Clock, Lock, Cpu, Activity, DollarSign, Globe, Building2, Layers, Network, ArrowLeft, RefreshCw, ChevronDown, X, CheckCircle, } from 'lucide-react'; import { TutorialHint } from '@/components/game/TutorialHint'; import { ConfirmModal } from '@/components/common/ConfirmModal'; import { useGameStore, type InfraNav, computeFillForDC } from '@/store'; import { formatMoney, formatNumber, formatPercent, LOCATION_CONFIGS, DC_TIER_CONFIGS, RACK_SKU_CONFIGS, CAMPUS_TIER_COSTS, CLUSTER_COST_CONFIG, FIRST_CAMPUS_BUILD_TICKS, estimateNetworkSlots, maxComputeRacks, SWITCH_TIER_CONFIGS, DC_UPGRADE_COST_FRACTION, DC_UPGRADE_INCREMENT, skuTotalFlops, } from '@token-empire/shared'; import type { DCTier, RackSkuId, LocationId, PipelineStage, Era, Cluster, Campus, DataCenter, DeploymentCohort, } from '@token-empire/shared'; const ERA_ORDER: Era[] = ['startup', 'scaleup', 'bigtech', 'agi']; const STAGE_LABELS: Record = { ordered: 'Ordered', manufacturing: 'Mfg', receiving: 'Recv', installation: 'Install', testing: 'Testing', repair: 'Repair', 'network-down': 'Net Down', decommission: 'Decom', }; const STAGE_COLORS: Record = { ordered: 'bg-surface-600', manufacturing: 'bg-blue-500', receiving: 'bg-cyan-500', installation: 'bg-violet-500', testing: 'bg-amber-500', repair: 'bg-danger', 'network-down': 'bg-red-600', decommission: 'bg-surface-500', }; // ─── Shared Components ────────────────────────────────────────── function FleetStat({ label, value, sub, icon: Icon }: { label: string; value: string; sub?: string; icon: typeof Server; }) { return (
{label}
{value}
{sub &&
{sub}
}
); } function CapacityBar({ label, used, total }: { label: string; used: number; total: number }) { const pct = total > 0 ? (used / total) * 100 : 0; const color = pct > 90 ? 'bg-danger' : pct > 70 ? 'bg-amber-500' : 'bg-green-500'; return (
{label} {formatNumber(used)} / {formatNumber(total)}
); } function Breadcrumb({ nav }: { nav: InfraNav }) { const setNav = useGameStore((s) => s.setInfraNav); const clusters = useGameStore((s) => s.infrastructure.clusters); const crumbs: { label: string; nav: InfraNav }[] = [ { label: 'Infrastructure', nav: { level: 'clusters' } }, ]; if (nav.level !== 'clusters' && nav.clusterId) { const cluster = clusters.find(c => c.id === nav.clusterId); if (cluster) { crumbs.push({ label: cluster.name, nav: { level: 'cluster', clusterId: nav.clusterId } }); } if ((nav.level === 'campus' || nav.level === 'datacenter') && nav.campusId) { const campus = cluster?.campuses.find(c => c.id === nav.campusId); if (campus) { crumbs.push({ label: campus.name, nav: { level: 'campus', clusterId: nav.clusterId, campusId: nav.campusId } }); } if (nav.level === 'datacenter' && nav.datacenterId) { const dc = campus?.dataCenters.find(d => d.id === nav.datacenterId); if (dc) { crumbs.push({ label: dc.name, nav: { level: 'datacenter', clusterId: nav.clusterId, campusId: nav.campusId, datacenterId: nav.datacenterId } }); } } } } return (
{crumbs.map((crumb, i) => ( {i > 0 && } {i < crumbs.length - 1 ? ( ) : ( {crumb.label} )} ))}
); } function DeploymentProgressBar({ dc }: { dc: DataCenter }) { const tierConfig = DC_TIER_CONFIGS[dc.tier]; const maxCompute = maxComputeRacks(tierConfig.rackSlots, dc.tier); const pipelineRacks = dc.deploymentCohorts.filter(c => c.stage !== 'decommission').reduce((s, c) => s + c.count, 0); const totalTarget = dc.computeRacksOnline + pipelineRacks; const pct = totalTarget > 0 ? (dc.computeRacksOnline / totalTarget) * 100 : 0; if (totalTarget === 0 && dc.status === 'operational') return null; return (
Deployment {dc.computeRacksOnline} / {totalTarget} online
); } function CohortStageBreakdown({ cohorts }: { cohorts: DeploymentCohort[] }) { const stages: PipelineStage[] = ['ordered', 'manufacturing', 'receiving', 'installation', 'testing', 'repair']; const counts: Record = {}; for (const stage of stages) counts[stage] = 0; for (const c of cohorts) { if (c.stage in counts) counts[c.stage] += c.count; } const hasAny = stages.some(s => counts[s] > 0); if (!hasAny) return null; return (
{stages.map(stage => counts[stage] > 0 && (
{STAGE_LABELS[stage]}: {counts[stage]}
))}
); } function NetworkHealthIndicator({ dc }: { dc: DataCenter }) { const ns = dc.networkSummary; const torTotal = ns.totalByTier?.tor ?? 0; if (torTotal === 0) return null; const hasDisconnected = ns.racksDisconnected > 0; const hasDegraded = ns.racksDegraded > 0; const coreDown = (ns.healthyByTier?.t3 ?? 0) < (ns.totalByTier?.t3 ?? 0); const color = coreDown ? 'text-danger' : hasDisconnected ? 'text-danger' : hasDegraded ? 'text-amber-400' : 'text-green-400'; const bwPct = Math.round(ns.averageBandwidth * 100); return (
{coreDown ? 'Core Down' : hasDisconnected ? `${ns.racksDisconnected} disconnected` : hasDegraded ? `${bwPct}% bandwidth` : 'Healthy'}
); } // ─── Clusters List View ───────────────────────────────────────── function ClustersListView() { const clusters = useGameStore((s) => s.infrastructure.clusters); const totalFlops = useGameStore((s) => s.infrastructure.totalFlops); const totalRacks = useGameStore((s) => s.infrastructure.totalRackCount); const totalUptime = useGameStore((s) => s.infrastructure.totalUptime); const totalDCs = useGameStore((s) => s.infrastructure.totalDataCenterCount); const setNav = useGameStore((s) => s.setInfraNav); const [showBuild, setShowBuild] = useState(false); return (

Infrastructure

{clusters.length === 0 && ( Build your first cluster to establish a regional presence. Your first cluster is free! )} {clusters.length > 0 && (
)}
{clusters.map(cluster => ( ))}
{showBuild && setShowBuild(false)} />}
); } // ─── Build Cluster Modal ──────────────────────────────────────── function BuildClusterModal({ onClose }: { onClose: () => void }) { const era = useGameStore((s) => s.meta.currentEra); const money = useGameStore((s) => s.economy.money); const existingClusters = useGameStore((s) => s.infrastructure.clusters); const buildCluster = useGameStore((s) => s.buildCluster); const [name, setName] = useState(''); const [location, setLocation] = useState('us-west'); const isFirst = existingClusters.length === 0; const cost = isFirst ? 0 : CLUSTER_COST_CONFIG.baseCost; const alreadyExists = existingClusters.some(c => c.locationId === location); const locationConfig = LOCATION_CONFIGS[location]; const eraUnlocked = ERA_ORDER.indexOf(era) >= ERA_ORDER.indexOf(locationConfig.availableAt); const canBuild = name.trim() !== '' && !alreadyExists && eraUnlocked && money >= cost; return (
e.stopPropagation()}>

Build New Cluster

setName(e.target.value)} placeholder="e.g., US West Cluster" className="w-full bg-surface-800 border border-surface-600 rounded-lg px-3 py-2 text-sm" />
{alreadyExists &&

You already have a cluster in this region.

}
Cost:{isFirst ? 'Free' : formatMoney(cost)}
Build Time:{isFirst ? 'Instant' : `${CLUSTER_COST_CONFIG.buildTimeTicks}s`}
); } // ─── Cluster Fill All Modal ───────────────────────────────────── function ClusterFillAllModal({ cluster, money, era, research, onConfirm, onClose }: { cluster: Cluster; money: number; era: Era; research: string[]; onConfirm: (skuId: RackSkuId) => void; onClose: () => void; }) { const availableSkus = Object.values(RACK_SKU_CONFIGS).filter(s => { if (ERA_ORDER.indexOf(era) < ERA_ORDER.indexOf(s.era)) return false; if (s.requiredResearch.length > 0 && !s.requiredResearch.every(r => research.includes(r))) return false; return true; }); const allDCs = cluster.campuses.flatMap(c => c.dataCenters); const mostCommonSku = useMemo(() => { const counts: Record = {}; for (const dc of allDCs) { if (dc.rackSkuId) counts[dc.rackSkuId] = (counts[dc.rackSkuId] || 0) + 1; } const entries = Object.entries(counts); return entries.length > 0 ? entries.sort((a, b) => b[1] - a[1])[0][0] as RackSkuId : availableSkus[0]?.id ?? null; }, [allDCs, availableSkus]); const [selectedSku, setSelectedSku] = useState(mostCommonSku); const preview = useMemo(() => { if (!selectedSku) return { campuses: [], totalQty: 0, totalCost: 0 }; let remaining = money; const campuses = cluster.campuses.map(campus => { if (campus.status !== 'operational') return { campus, dcs: [], totalQty: 0, totalCost: 0 }; const dcs = campus.dataCenters.map(dc => { const { qty, cost } = computeFillForDC(dc, selectedSku, remaining); if (qty > 0) remaining -= cost; return { dc, qty, cost }; }); return { campus, dcs, totalQty: dcs.reduce((s, d) => s + d.qty, 0), totalCost: dcs.reduce((s, d) => s + d.cost, 0) }; }); return { campuses, totalQty: campuses.reduce((s, c) => s + c.totalQty, 0), totalCost: campuses.reduce((s, c) => s + c.totalCost, 0), }; }, [selectedSku, money, cluster.campuses]); const fillableDCCount = preview.campuses.reduce((s, c) => s + c.dcs.filter(d => d.qty > 0).length, 0); return (
e.stopPropagation()}>

Fill All DCs — {cluster.name}

{availableSkus.map(s => ( ))}
{selectedSku && (
{preview.campuses.map(({ campus, totalQty, totalCost }) => (
{campus.name} ({campus.dataCenters.length} DCs) {totalQty > 0 ? ( +{totalQty} racks ({formatMoney(totalCost)}) ) : ( No change )}
))}
)}
Total racks:{formatNumber(preview.totalQty)}
Total cost:{formatMoney(preview.totalCost)}
Remaining budget:{formatMoney(money - preview.totalCost)}
); } // ─── Cluster Detail View ──────────────────────────────────────── function ClusterDetailView({ clusterId }: { clusterId: string }) { const cluster = useGameStore((s) => s.infrastructure.clusters.find(c => c.id === clusterId)); const setNav = useGameStore((s) => s.setInfraNav); const fillCluster = useGameStore((s) => s.fillClusterToCapacity); const money = useGameStore((s) => s.economy.money); const era = useGameStore((s) => s.meta.currentEra); const research = useGameStore((s) => s.research.completedResearch); const [showBuild, setShowBuild] = useState(false); const [showFillAll, setShowFillAll] = useState(false); if (!cluster) return
Cluster not found.
; const location = LOCATION_CONFIGS[cluster.locationId]; const allDCs = cluster.campuses.flatMap(c => c.dataCenters); const hasOperationalDCs = allDCs.some(dc => dc.status === 'operational'); return (

{cluster.name}

{location.name} — {location.energyCostMultiplier}x energy cost

{hasOperationalDCs && ( )}
{cluster.campuses.length === 0 && ( Build a campus to start housing data centers. All DCs on a campus share the same tier. )}
{cluster.campuses.map(campus => ( ))}
{showBuild && setShowBuild(false)} />} {showFillAll && ( { fillCluster(clusterId, skuId); setShowFillAll(false); }} onClose={() => setShowFillAll(false)} /> )}
); } // ─── Build Campus Modal ───────────────────────────────────────── function BuildCampusModal({ clusterId, onClose }: { clusterId: string; onClose: () => void }) { const era = useGameStore((s) => s.meta.currentEra); const money = useGameStore((s) => s.economy.money); const research = useGameStore((s) => s.research.completedResearch); const buildCampus = useGameStore((s) => s.buildCampus); const isFirstCampus = useGameStore((s) => s.infrastructure.clusters.every(c => c.campuses.length === 0)); const [name, setName] = useState(''); const [tier, setTier] = useState('small'); const tierConfig = DC_TIER_CONFIGS[tier]; const campusCost = CAMPUS_TIER_COSTS[tier]; const effectiveCost = isFirstCampus ? 0 : campusCost.baseCost; const eraUnlocked = ERA_ORDER.indexOf(era) >= ERA_ORDER.indexOf(tierConfig.requiredEra); const researchUnlocked = !tierConfig.requiredResearch || research.includes(tierConfig.requiredResearch); const canBuild = name.trim() !== '' && eraUnlocked && researchUnlocked && money >= effectiveCost; return (
e.stopPropagation()}>

Build New Campus

setName(e.target.value)} placeholder="e.g., Campus Alpha" className="w-full bg-surface-800 border border-surface-600 rounded-lg px-3 py-2 text-sm" />
Campus Cost:{isFirstCampus ? 'Free' : formatMoney(campusCost.baseCost)}
Build Time:{isFirstCampus ? `${FIRST_CAMPUS_BUILD_TICKS}s` : `${campusCost.buildTimeTicks}s`}
DC Slots:{tierConfig.rackSlots} racks/DC
DC Power:{formatNumber(tierConfig.powerBudgetKW)} kW/DC
); } // ─── Campus Bulk Action Components ───────────────────────────── function FillAllDCsModal({ campus, money, era, research, onConfirm, onClose }: { campus: Campus; money: number; era: Era; research: string[]; onConfirm: (skuId: RackSkuId) => void; onClose: () => void; }) { const availableSkus = Object.values(RACK_SKU_CONFIGS).filter(s => { if (ERA_ORDER.indexOf(era) < ERA_ORDER.indexOf(s.era)) return false; if (s.requiredResearch.length > 0 && !s.requiredResearch.every(r => research.includes(r))) return false; return true; }); const mostCommonSku = useMemo(() => { const counts: Record = {}; for (const dc of campus.dataCenters) { if (dc.rackSkuId) counts[dc.rackSkuId] = (counts[dc.rackSkuId] || 0) + 1; } const entries = Object.entries(counts); return entries.length > 0 ? entries.sort((a, b) => b[1] - a[1])[0][0] as RackSkuId : availableSkus[0]?.id ?? null; }, [campus.dataCenters, availableSkus]); const [selectedSku, setSelectedSku] = useState(mostCommonSku); const preview = useMemo(() => { if (!selectedSku) return { dcs: [], totalQty: 0, totalCost: 0 }; let remaining = money; const dcs = campus.dataCenters.map(dc => { if (dc.status !== 'operational') return { dc, qty: 0, cost: 0, reason: dc.status === 'constructing' ? 'Constructing' : 'Retrofitting' as string | null }; if (dc.status === 'operational' && dc.rackSkuId && dc.rackSkuId !== selectedSku) return { dc, qty: 0, cost: 0, reason: `Different SKU (${RACK_SKU_CONFIGS[dc.rackSkuId].name})` }; const { qty, cost } = computeFillForDC(dc, selectedSku, remaining); if (qty === 0) { const tierConfig = DC_TIER_CONFIGS[dc.tier]; const maxCompute = maxComputeRacks(tierConfig.rackSlots, dc.tier); const pipelineCount = dc.deploymentCohorts.filter(c => c.stage !== 'decommission').reduce((sum, c) => sum + c.count, 0); const isFull = maxCompute - (dc.computeRacksOnline + pipelineCount) <= 0; return { dc, qty: 0, cost: 0, reason: isFull ? 'Already full' : 'No budget' }; } remaining -= cost; return { dc, qty, cost, reason: null }; }); return { dcs, totalQty: dcs.reduce((s, d) => s + d.qty, 0), totalCost: dcs.reduce((s, d) => s + d.cost, 0) }; }, [selectedSku, money, campus.dataCenters]); const fillableDCCount = preview.dcs.filter(d => d.qty > 0).length; return (
e.stopPropagation()}>

Fill All DCs

{availableSkus.map(s => ( ))}
{selectedSku && (
{preview.dcs.map(({ dc, qty, cost, reason }) => (
{dc.name} {reason ? ( {reason} ) : ( +{qty} racks ({formatMoney(cost)}) )}
))}
)}
Total racks:{formatNumber(preview.totalQty)}
Total cost:{formatMoney(preview.totalCost)}
Remaining budget:{formatMoney(money - preview.totalCost)}
); } function RetrofitCampusModal({ campus, era, research, onConfirm, onClose }: { campus: Campus; era: Era; research: string[]; onConfirm: (skuId: RackSkuId, maxConcurrent: number) => void; onClose: () => void; }) { const [selectedSku, setSelectedSku] = useState(null); const [concurrencyMode, setConcurrencyMode] = useState<'1' | '10' | '25' | 'custom'>('10'); const [customCount, setCustomCount] = useState(1); const currentSkuIds = [...new Set(campus.dataCenters.filter(dc => dc.rackSkuId).map(dc => dc.rackSkuId!))]; const targetSkus = Object.values(RACK_SKU_CONFIGS).filter(s => { if (ERA_ORDER.indexOf(era) < ERA_ORDER.indexOf(s.era)) return false; if (s.requiredResearch.length > 0 && !s.requiredResearch.every(r => research.includes(r))) return false; return true; }); const eligible = useMemo(() => { if (!selectedSku) return { count: 0, skipped: 0 }; let count = 0; let skipped = 0; for (const dc of campus.dataCenters) { if (dc.status !== 'operational' || !dc.rackSkuId || dc.rackSkuId === selectedSku) { skipped++; continue; } const pipelineCount = dc.deploymentCohorts.filter(c => c.stage !== 'decommission').reduce((sum, c) => sum + c.count, 0); if (dc.computeRacksOnline + pipelineCount <= 0) { skipped++; continue; } count++; } return { count, skipped }; }, [selectedSku, campus.dataCenters]); const maxConcurrent = useMemo(() => { if (eligible.count === 0) return 1; switch (concurrencyMode) { case '1': return 1; case '10': return Math.max(1, Math.ceil(eligible.count * 0.1)); case '25': return Math.max(1, Math.ceil(eligible.count * 0.25)); case 'custom': return Math.max(1, Math.min(customCount, eligible.count)); } }, [concurrencyMode, customCount, eligible.count]); const capacityMaintained = eligible.count > 0 ? Math.round(((eligible.count - maxConcurrent) / eligible.count) * 100) : 100; const estimatedBatches = eligible.count > 0 ? Math.ceil(eligible.count / maxConcurrent) : 0; return (
e.stopPropagation()}>

Retrofit Campus

{targetSkus.map(s => { const isCurrentOnly = currentSkuIds.length === 1 && currentSkuIds[0] === s.id; return ( ); })}
{selectedSku && eligible.count > 0 && ( <>
{([ { key: '1' as const, label: '1 at a time' }, { key: '10' as const, label: `10% = ${Math.max(1, Math.ceil(eligible.count * 0.1))}` }, { key: '25' as const, label: `25% = ${Math.max(1, Math.ceil(eligible.count * 0.25))}` }, { key: 'custom' as const, label: 'Custom' }, ]).map(opt => ( ))}
{concurrencyMode === 'custom' && ( setCustomCount(Math.max(1, parseInt(e.target.value) || 1))} className="mt-2 w-full bg-surface-800 border border-surface-600 rounded-lg px-3 py-2 text-sm" /> )}
DCs to retrofit:{eligible.count} of {campus.dataCenters.length}
Concurrent retrofits:{maxConcurrent}
Estimated batches:{estimatedBatches}
Capacity maintained: = 75 ? 'text-green-400' : capacityMaintained >= 50 ? 'text-amber-400' : 'text-red-400'}>~{capacityMaintained}%
{eligible.skipped > 0 && (
{eligible.skipped} DCs skipped (constructing, empty, or already target SKU)
)}
)}
); } function CampusRetrofitProgress({ campus, onCancel }: { campus: Campus; onCancel: () => void }) { const queue = campus.retrofitQueue; if (!queue) return null; const total = queue.pendingDCIds.length + queue.activeDCIds.length + queue.completedDCIds.length; const completed = queue.completedDCIds.length; const active = queue.activeDCIds.length; const pending = queue.pendingDCIds.length; const pct = total > 0 ? (completed / total) * 100 : 0; return (
Campus Retrofit — {RACK_SKU_CONFIGS[queue.targetSkuId].name}
{completed} of {total} complete {active} active | {pending} pending
); } // ─── Campus Detail View ────────────────────────────────────────��� function CampusDetailView({ clusterId, campusId }: { clusterId: string; campusId: string }) { const cluster = useGameStore((s) => s.infrastructure.clusters.find(c => c.id === clusterId)); const campus = cluster?.campuses.find(c => c.id === campusId); const setNav = useGameStore((s) => s.setInfraNav); const buildDC = useGameStore((s) => s.buildDataCenter); const addDCs = useGameStore((s) => s.addDCsToCampus); const fillCampus = useGameStore((s) => s.fillCampusToCapacity); const startRetrofit = useGameStore((s) => s.startCampusRetrofit); const cancelRetrofit = useGameStore((s) => s.cancelCampusRetrofit); const money = useGameStore((s) => s.economy.money); const era = useGameStore((s) => s.meta.currentEra); const research = useGameStore((s) => s.research.completedResearch); const [showAddDC, setShowAddDC] = useState(false); const [dcName, setDcName] = useState(''); const [bulkCount, setBulkCount] = useState(1); const [showFillAll, setShowFillAll] = useState(false); const [showRetrofit, setShowRetrofit] = useState(false); if (!campus || !cluster) return
Campus not found.
; const tierConfig = DC_TIER_CONFIGS[campus.dcTier]; const operationalDCs = campus.dataCenters.filter(dc => dc.status === 'operational'); const hasRetrofitQueue = !!campus.retrofitQueue; const fillableDCs = operationalDCs.filter(dc => { const maxCompute = maxComputeRacks(tierConfig.rackSlots, dc.tier); const pipelineCount = dc.deploymentCohorts.filter(c => c.stage !== 'decommission').reduce((sum, c) => sum + c.count, 0); return maxCompute - (dc.computeRacksOnline + pipelineCount) > 0; }); const retrofitEligibleDCs = operationalDCs.filter(dc => dc.rackSkuId && (dc.computeRacksOnline + dc.deploymentCohorts.filter(c => c.stage !== 'decommission').reduce((sum, c) => sum + c.count, 0)) > 0, ); return (

{campus.name}

{tierConfig.name} campus — {campus.dataCenters.length} DCs

{operationalDCs.length > 0 && !hasRetrofitQueue && ( <> )}
{/* Campus Retrofit Progress Banner */} {campus.retrofitQueue && ( cancelRetrofit(campusId)} /> )} {campus.dataCenters.length === 0 && ( Add a data center to this campus. Once built, you can deploy racks to start generating compute. )}
{campus.dataCenters.map(dc => { const queueStatus = campus.retrofitQueue ? campus.retrofitQueue.pendingDCIds.includes(dc.id) ? 'queued' : campus.retrofitQueue.completedDCIds.includes(dc.id) ? 'retrofit-done' : null : null; return ( ); })}
{showAddDC && (
setShowAddDC(false)}>
e.stopPropagation()}>

Add Data Center{bulkCount > 1 ? 's' : ''}

setDcName(e.target.value)} placeholder={`${campus.name}-DC-${campus.dataCenters.length + 1}`} className="w-full bg-surface-800 border border-surface-600 rounded-lg px-3 py-2 text-sm" />
setBulkCount(Math.max(1, parseInt(e.target.value) || 1))} className="w-full bg-surface-800 border border-surface-600 rounded-lg px-3 py-2 text-sm" />
Tier:{tierConfig.name}
Cost per DC:{formatMoney(tierConfig.baseCost)}
Total:{formatMoney(tierConfig.baseCost * bulkCount)}
)} {showFillAll && ( { fillCampus(campusId, skuId); setShowFillAll(false); }} onClose={() => setShowFillAll(false)} /> )} {showRetrofit && ( { startRetrofit(campusId, skuId, maxConcurrent); setShowRetrofit(false); }} onClose={() => setShowRetrofit(false)} /> )}
); } // ─── Data Center Detail View ──────────────────────────────────── function DataCenterDetailView({ clusterId, campusId, datacenterId }: { clusterId: string; campusId: string; datacenterId: string; }) { const cluster = useGameStore((s) => s.infrastructure.clusters.find(c => c.id === clusterId)); const campus = cluster?.campuses.find(c => c.id === campusId); const dc = campus?.dataCenters.find(d => d.id === datacenterId); const money = useGameStore((s) => s.economy.money); const era = useGameStore((s) => s.meta.currentEra); const research = useGameStore((s) => s.research.completedResearch); const deployRacks = useGameStore((s) => s.deployRacks); const fillToCapacity = useGameStore((s) => s.fillDCToCapacity); const retrofitDC = useGameStore((s) => s.retrofitDC); const cancelRetrofit = useGameStore((s) => s.cancelRetrofit); const upgradeDataCenter = useGameStore((s) => s.upgradeDataCenter); const [activeTab, setActiveTab] = useState<'deploy' | 'retrofit' | 'upgrades' | 'network'>('deploy'); const [selectedSku, setSelectedSku] = useState(null); const [deployQty, setDeployQty] = useState(10); const [confirmRetrofit, setConfirmRetrofit] = useState(null); if (!dc || !cluster) return
Data center not found.
; const tierConfig = DC_TIER_CONFIGS[dc.tier]; const maxCompute = maxComputeRacks(tierConfig.rackSlots, dc.tier); const pipelineCount = dc.deploymentCohorts.filter(c => c.stage !== 'decommission').reduce((s, c) => s + c.count, 0); const existingCompute = dc.computeRacksOnline + pipelineCount; const availableSlots = maxCompute - existingCompute; const sku = dc.rackSkuId ? RACK_SKU_CONFIGS[dc.rackSkuId] : null; const netSlots = estimateNetworkSlots(existingCompute, dc.tier); const availableSkus = Object.values(RACK_SKU_CONFIGS).filter(s => { if (ERA_ORDER.indexOf(era) < ERA_ORDER.indexOf(s.era)) return false; if (s.requiredResearch.length > 0 && !s.requiredResearch.every(r => research.includes(r))) return false; if (dc.rackSkuId && dc.rackSkuId !== s.id) return false; return true; }); const effectiveSku = selectedSku ? RACK_SKU_CONFIGS[selectedSku] : null; return (
{/* Header */}

{dc.name}

{tierConfig.name} — {sku?.name ?? 'No racks deployed'} — {LOCATION_CONFIGS[cluster.locationId].name}

{dc.status === 'retrofitting' && ( Retrofitting to {dc.retrofitState ? RACK_SKU_CONFIGS[dc.retrofitState.toSkuId].name : '...'} )}
{/* Stats Grid */}
{/* Capacity Bars */}
{/* Deployment Progress */}
{dc.deploymentCohorts.length > 0 && (
)} {dc.computeRacksFailed > 0 && (
{dc.computeRacksFailed} rack{dc.computeRacksFailed > 1 ? 's' : ''} under repair
)}
{/* Retrofit Progress */} {dc.status === 'retrofitting' && dc.retrofitState && (
Retrofit: {dc.retrofitState.phase}
{RACK_SKU_CONFIGS[dc.retrofitState.fromSkuId].name} → {RACK_SKU_CONFIGS[dc.retrofitState.toSkuId].name} {Math.floor((dc.retrofitState.progress / dc.retrofitState.total) * 100)}%
)} {/* Tabs */} {dc.status === 'operational' && ( <>
{(['deploy', 'retrofit', 'upgrades', 'network'] as const).map(tab => ( ))}
{/* Deploy Tab */} {activeTab === 'deploy' && (
{dc.rackSkuId === null ? ( <>

Select a rack SKU for this data center. All racks in a DC must be the same type.

{availableSkus.map(s => ( ))}
) : (
This DC runs {sku!.name}. Available: {availableSlots} compute slots.
)} {(dc.rackSkuId || selectedSku) && availableSlots > 0 && (
setDeployQty(Math.max(1, Math.min(availableSlots, parseInt(e.target.value) || 1)))} className="w-full bg-surface-900 border border-surface-600 rounded-lg px-3 py-2 text-sm" />
{(() => { const skuToUse = dc.rackSkuId ?? selectedSku!; const skuConfig = RACK_SKU_CONFIGS[skuToUse]; const newNetSlots = estimateNetworkSlots(existingCompute + deployQty, dc.tier); const addedNet = newNetSlots - netSlots; const totalCost = skuConfig.baseCost * deployQty; return (
{deployQty} compute racks ({skuConfig.name}){formatMoney(totalCost)}
+ {addedNet} network racks (auto)included
= {existingCompute + deployQty + newNetSlots} / {tierConfig.rackSlots} total slots
Power: {formatNumber((existingCompute + deployQty) * skuConfig.powerDrawKW)} / {formatNumber(tierConfig.powerBudgetKW)} kW
); })()}
)}
)} {/* Retrofit Tab */} {activeTab === 'retrofit' && (
{!dc.rackSkuId ? (

No racks deployed yet. Deploy racks first before retrofitting.

) : ( <>

Retrofit swaps all {dc.computeRacksOnline + pipelineCount} {sku!.name} racks to a new SKU. The DC goes offline during retrofit.

{Object.values(RACK_SKU_CONFIGS).filter(s => { if (s.id === dc.rackSkuId) return false; if (ERA_ORDER.indexOf(era) < ERA_ORDER.indexOf(s.era)) return false; if (s.requiredResearch.length > 0 && !s.requiredResearch.every(r => research.includes(r))) return false; return true; }).map(s => ( ))}
)}
)} {/* Upgrades Tab */} {activeTab === 'upgrades' && (
{/* Cooling & Network Fabric */}
Cooling Type
{dc.coolingType}
Network Fabric
{dc.networkFabric}
{(['cooling', 'redundancy'] as const).map(upgrade => { const level = upgrade === 'cooling' ? dc.coolingLevel : dc.redundancyLevel; const cost = tierConfig.baseCost * DC_UPGRADE_COST_FRACTION; const maxed = level >= 1.0; return (
{upgrade === 'cooling' ? : }
{upgrade}
Level {Math.round(level * 10)}/10 — reduces {upgrade === 'cooling' ? 'test' : 'production'} failure rates
); })}
)} {/* Network Tab */} {activeTab === 'network' && (

Network Topology

{dc.computeRacksOnline === 0 ? (

No racks online. Deploy racks to see network topology.

) : (
{/* Bandwidth gauge */}
Bandwidth {formatPercent(dc.networkSummary.averageBandwidth)}
= 0.8 ? 'bg-green-500' : dc.networkSummary.averageBandwidth >= 0.5 ? 'bg-yellow-500' : 'bg-red-500'}`} style={{ width: `${dc.networkSummary.averageBandwidth * 100}%` }} />
Effective FLOPS: {formatPercent(dc.networkSummary.effectiveFlopsFraction)} {dc.networkSummary.racksDegraded} degraded
{/* Per-tier switch health */} {(['tor', 't1', 't2', 't3'] as const).map(tier => { const total = dc.networkSummary.totalByTier[tier] ?? 0; if (total === 0) return null; const healthy = dc.networkSummary.healthyByTier[tier] ?? 0; const failed = total - healthy; const config = SWITCH_TIER_CONFIGS[tier]; return (
{config.name}
{tier === 'tor' ? '1 per rack (embedded)' : `Fan-out ${config.fanOut}, ${config.uplinkCount} uplinks`}
0 ? 'text-danger' : 'text-green-400'}`}> {healthy} / {total}
); })} {dc.networkSummary.racksDisconnected > 0 && (
{dc.networkSummary.racksDisconnected} compute racks disconnected due to network failures
)}
)}
)} )} {/* Retrofit Confirmation Modal */} {confirmRetrofit && ( { retrofitDC(datacenterId, confirmRetrofit); setConfirmRetrofit(null); }} onCancel={() => setConfirmRetrofit(null)} /> )}
); } // ─── Main Page ────────────────────────────────────────────────── export function InfrastructurePage() { const nav = useGameStore((s) => s.infraNav); return (
{nav.level === 'clusters' && } {nav.level === 'cluster' && nav.clusterId && } {nav.level === 'campus' && nav.clusterId && nav.campusId && } {nav.level === 'datacenter' && nav.clusterId && nav.campusId && nav.datacenterId && ( )}
); }