75 lines
2.9 KiB
TypeScript
75 lines
2.9 KiB
TypeScript
import { useMemo } from 'react'
|
||
import { MapPin, AlertTriangle, AlertCircle } from 'lucide-react'
|
||
import type { MilitarySituation } from '@/data/mockData'
|
||
|
||
interface BaseStatusPanelProps {
|
||
keyLocations: MilitarySituation['usForces']['keyLocations']
|
||
className?: string
|
||
}
|
||
|
||
export function BaseStatusPanel({ keyLocations, className = '' }: BaseStatusPanelProps) {
|
||
const stats = useMemo(() => {
|
||
const bases = (keyLocations || []).filter((loc) => loc.type === 'Base')
|
||
const total = bases.length
|
||
let attacked = 0
|
||
let severe = 0
|
||
let moderate = 0
|
||
let light = 0
|
||
for (const b of bases) {
|
||
const s = b.status ?? 'operational'
|
||
if (s === 'attacked') attacked++
|
||
const lvl = b.damage_level
|
||
if (lvl === 3) severe++
|
||
else if (lvl === 2) moderate++
|
||
else if (lvl === 1) light++
|
||
}
|
||
return { total, attacked, severe, moderate, light }
|
||
}, [keyLocations])
|
||
|
||
return (
|
||
<div
|
||
className={`rounded-lg border border-military-border bg-military-panel/80 p-3 font-orbitron ${className}`}
|
||
>
|
||
<div className="mb-2 flex items-center gap-1.5 text-[10px] uppercase tracking-wider text-military-text-secondary">
|
||
<MapPin className="h-3 w-3 shrink-0 text-blue-400" />
|
||
美军基地态势
|
||
<span className="normal-case opacity-75">(随爬虫 AI 实时更新)</span>
|
||
</div>
|
||
<div className="flex flex-col gap-1.5 text-xs tabular-nums">
|
||
<div className="flex items-center justify-between gap-2">
|
||
<span className="text-military-text-secondary">总基地数</span>
|
||
<strong>{stats.total}</strong>
|
||
</div>
|
||
<div className="flex items-center justify-between gap-2">
|
||
<span className="flex items-center gap-1 text-military-text-secondary">
|
||
<AlertCircle className="h-3 w-3 text-red-400" />
|
||
被袭击
|
||
</span>
|
||
<strong className="text-red-400">{stats.attacked}</strong>
|
||
</div>
|
||
<div className="flex items-center justify-between gap-2">
|
||
<span className="flex items-center gap-1 text-military-text-secondary">
|
||
<AlertTriangle className="h-3 w-3 text-amber-500" />
|
||
严重损毁
|
||
</span>
|
||
<strong className="text-amber-500">{stats.severe}</strong>
|
||
</div>
|
||
<div className="flex items-center justify-between gap-2">
|
||
<span className="flex items-center gap-1 text-military-text-secondary">
|
||
<AlertTriangle className="h-3 w-3 text-amber-400" />
|
||
中度损毁
|
||
</span>
|
||
<strong className="text-amber-400">{stats.moderate}</strong>
|
||
</div>
|
||
<div className="flex items-center justify-between gap-2">
|
||
<span className="flex items-center gap-1 text-military-text-secondary">
|
||
<AlertTriangle className="h-3 w-3 text-amber-300" />
|
||
轻度损毁
|
||
</span>
|
||
<strong className="text-amber-300">{stats.light}</strong>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
)
|
||
}
|