page
import React, { useState } from 'react';
import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs';
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
import { Badge } from '@/components/ui/badge';
import { Server, MapPin, ExternalLink } from 'lucide-react';
const DataCenterMonitor = () => {
const [activeCity, setActiveCity] = useState('shanghai');
const [activeLab, setActiveLab] = useState('taishan');
const labData = {
shanghai: {
name: '上海',
labs: {
taishan: {
name: '泰山稳定性实验室',
facility: '浦东电脑实验室',
link: 'https://taishan.example.com',
equipment: { online: 500, offline: 80 },
tasks: { healthy: 500, subHealthy: 50, blocked: 80 }
},
huangpu: {
name: '黄浦云计算中心',
facility: '黄浦数据处理中心',
link: 'https://huangpu.example.com',
equipment: { online: 420, offline: 45 },
tasks: { healthy: 380, subHealthy: 60, blocked: 25 }
},
minhang: {
name: '闵行AI实验室',
facility: '闵行智能计算中心',
link: 'https://minhang.example.com',
equipment: { online: 360, offline: 30 },
tasks: { healthy: 340, subHealthy: 35, blocked: 15 }
}
}
},
nanjing: {
name: '南京',
labs: {
jinling: {
name: '金陵稳定性实验室',
facility: '江宁计算中心',
link: 'https://jinling.example.com',
equipment: { online: 420, offline: 60 },
tasks: { healthy: 400, subHealthy: 40, blocked: 40 }
},
qinhuai: {
name: '秦淮数据中心',
facility: '秦淮云服务中心',
link: 'https://qinhuai.example.com',
equipment: { online: 380, offline: 50 },
tasks: { healthy: 360, subHealthy: 35, blocked: 35 }
}
}
},
xian: {
name: '西安',
labs: {
qinling: {
name: '秦岭稳定性实验室',
facility: '高新技术园区',
link: 'https://qinling.example.com',
equipment: { online: 380, offline: 50 },
tasks: { healthy: 360, subHealthy: 35, blocked: 35 }
},
gaoxin: {
name: '高新超算中心',
facility: '西部云计算基地',
link: 'https://gaoxin.example.com',
equipment: { online: 320, offline: 40 },
tasks: { healthy: 300, subHealthy: 30, blocked: 30 }
}
}
}
};
const currentCityData = labData[activeCity];
const labKeys = Object.keys(currentCityData.labs);
const currentLabData = currentCityData.labs[activeLab] || currentCityData.labs[labKeys[0]];
React.useEffect(() => {
const firstLabKey = Object.keys(labData[activeCity].labs)[0];
setActiveLab(firstLabKey);
}, [activeCity]);
return (
<div className="min-h-screen bg-gradient-to-br from-gray-50 to-gray-100">
<div className="flex h-screen">
{/* 左侧城市选择栏 */}
<div className="w-56 bg-white border-r border-gray-200 shadow-sm flex flex-col">
<div className="p-6 border-b border-gray-200">
<h1 className="text-lg font-bold text-gray-800">{currentCityData.name}</h1>
<p className="text-xs text-gray-500 mt-1">数据中心</p>
</div>
<div className="flex-1">
<Tabs value={activeCity} onValueChange={setActiveCity} orientation="vertical" className="w-full">
<TabsList className="flex flex-col w-full bg-transparent gap-1 p-2">
<TabsTrigger
value="shanghai"
className="w-full justify-start px-4 py-3 text-sm data-[state=active]:bg-blue-50 data-[state=active]:text-blue-700 data-[state=active]:font-medium data-[state=inactive]:text-gray-600 hover:bg-gray-50 transition-all rounded-md"
>
<MapPin className="w-4 h-4 mr-2" />
上海
</TabsTrigger>
<TabsTrigger
value="nanjing"
className="w-full justify-start px-4 py-3 text-sm data-[state=active]:bg-blue-50 data-[state=active]:text-blue-700 data-[state=active]:font-medium data-[state=inactive]:text-gray-600 hover:bg-gray-50 transition-all rounded-md"
>
<MapPin className="w-4 h-4 mr-2" />
南京
</TabsTrigger>
<TabsTrigger
value="xian"
className="w-full justify-start px-4 py-3 text-sm data-[state=active]:bg-blue-50 data-[state=active]:text-blue-700 data-[state=active]:font-medium data-[state=inactive]:text-gray-600 hover:bg-gray-50 transition-all rounded-md"
>
<MapPin className="w-4 h-4 mr-2" />
西安
</TabsTrigger>
</TabsList>
</Tabs>
</div>
</div>
{/* 右侧主内容区 */}
<div className="flex-1 overflow-auto bg-gray-50">
<div className="p-8">
{/* 顶部:实验室名称和设施名称 */}
<div className="grid grid-cols-2 gap-6 mb-6">
<Card className="bg-white shadow-sm border border-gray-200">
<CardHeader className="pb-3">
<CardTitle className="text-sm font-medium text-gray-600">实验室名称</CardTitle>
</CardHeader>
<CardContent>
<p className="text-lg font-semibold text-gray-900">{currentLabData.name}</p>
</CardContent>
</Card>
<Card className="bg-white shadow-sm border border-gray-200">
<CardHeader className="pb-3">
<CardTitle className="text-sm font-medium text-gray-600">实验设施</CardTitle>
</CardHeader>
<CardContent>
<p className="text-lg font-semibold text-gray-900">{currentLabData.facility}</p>
</CardContent>
</Card>
</div>
{/* 实验室选择 Tabs */}
<div className="mb-6">
<Tabs value={activeLab} onValueChange={setActiveLab}>
<TabsList className="bg-white border border-gray-200 shadow-sm p-1 inline-flex">
{Object.entries(currentCityData.labs).map(([key, lab]) => (
<TabsTrigger
key={key}
value={key}
className="data-[state=active]:bg-blue-600 data-[state=active]:text-white data-[state=inactive]:text-gray-700 px-5 py-2 text-sm font-medium transition-all"
>
{lab.name}
</TabsTrigger>
))}
</TabsList>
</Tabs>
</div>
{/* 主体内容:左侧图片 + 右侧状态 */}
<div className="grid grid-cols-1 lg:grid-cols-2 gap-6">
{/* 左侧:机房图片占位符 */}
<Card className="bg-gradient-to-br from-slate-900 to-slate-800 shadow-lg border-0 overflow-hidden">
<CardContent className="p-0 relative h-96 flex items-center justify-center">
{/* 服务器机架可视化 */}
<div className="absolute inset-0 flex items-center justify-center opacity-20">
<div className="grid grid-cols-12 gap-1">
{[...Array(120)].map((_, i) => (
<div
key={i}
className="w-2 h-14 rounded-sm"
style={{
background: i % 15 < 11 ? 'linear-gradient(to bottom, #3b82f6, #1d4ed8)' : '#475569',
animationDelay: `${i * 0.015}s`,
animation: i % 15 < 11 ? 'pulse 3s infinite' : 'none'
}}
/>
))}
</div>
</div>
{/* 中心信息 */}
<div className="relative z-10 text-center bg-slate-800/60 backdrop-blur-sm px-8 py-6 rounded-lg border border-slate-700">
<Server className="w-20 h-20 text-blue-400 mx-auto mb-3" />
<p className="text-white text-lg font-semibold mb-1">数据中心机房</p>
<p className="text-slate-300 text-sm">{currentLabData.facility}</p>
</div>
</CardContent>
</Card>
{/* 右侧:设备状态 + 任务状态 + 链接 */}
<div className="space-y-6">
{/* 设备状态 */}
<Card className="bg-white shadow-sm border border-gray-200">
<CardHeader className="pb-4">
<CardTitle className="text-base font-semibold text-gray-900">设备状态</CardTitle>
</CardHeader>
<CardContent>
<div className="grid grid-cols-2 gap-4">
<div className="text-center p-5 bg-green-50 rounded-lg border border-green-100">
<p className="text-sm text-gray-600 mb-1 font-medium">Online</p>
<p className="text-4xl font-bold text-green-600">{currentLabData.equipment.online}</p>
</div>
<div className="text-center p-5 bg-red-50 rounded-lg border border-red-100">
<p className="text-sm text-gray-600 mb-1 font-medium">Offline</p>
<p className="text-4xl font-bold text-red-600">{currentLabData.equipment.offline}</p>
</div>
</div>
</CardContent>
</Card>
{/* 任务状态 */}
<Card className="bg-white shadow-sm border border-gray-200">
<CardHeader className="pb-4">
<CardTitle className="text-base font-semibold text-gray-900">任务状态</CardTitle>
</CardHeader>
<CardContent>
<div className="grid grid-cols-3 gap-3">
<div className="text-center p-4 bg-emerald-50 rounded-lg border border-emerald-100">
<p className="text-xs text-gray-600 mb-1 font-medium">健康</p>
<p className="text-3xl font-bold text-emerald-600">{currentLabData.tasks.healthy}</p>
</div>
<div className="text-center p-4 bg-amber-50 rounded-lg border border-amber-100">
<p className="text-xs text-gray-600 mb-1 font-medium">亚健康</p>
<p className="text-3xl font-bold text-amber-600">{currentLabData.tasks.subHealthy}</p>
</div>
<div className="text-center p-4 bg-rose-50 rounded-lg border border-rose-100">
<p className="text-xs text-gray-600 mb-1 font-medium">阻塞</p>
<p className="text-3xl font-bold text-rose-600">{currentLabData.tasks.blocked}</p>
</div>
</div>
</CardContent>
</Card>
{/* 实验室链接 */}
<Card className="bg-gradient-to-r from-blue-600 to-blue-500 shadow-lg border-0">
<CardContent className="p-5">
<a
href={currentLabData.link}
target="_blank"
rel="noopener noreferrer"
className="flex items-center justify-between text-white hover:opacity-90 transition-opacity"
>
<div>
<p className="text-sm font-medium opacity-90 mb-1">访问实验室</p>
<p className="text-lg font-semibold">{currentLabData.name}</p>
</div>
<ExternalLink className="w-6 h-6" />
</a>
</CardContent>
</Card>
</div>
</div>
</div>
</div>
</div>
</div>
);
};
export default DataCenterMonitor;