feat: add new file
This commit is contained in:
68
src/components/BaseStatusPanel.tsx
Normal file
68
src/components/BaseStatusPanel.tsx
Normal file
@@ -0,0 +1,68 @@
|
||||
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
|
||||
}
|
||||
|
||||
const TOTAL_BASES = 62
|
||||
|
||||
export function BaseStatusPanel({ keyLocations, className = '' }: BaseStatusPanelProps) {
|
||||
const stats = useMemo(() => {
|
||||
const bases = (keyLocations || []).filter((loc) => loc.type === 'Base')
|
||||
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 { 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" />
|
||||
美军基地态势
|
||||
</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>{TOTAL_BASES}</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="text-military-text-secondary">中度损毁</span>
|
||||
<strong className="text-amber-400">{stats.moderate}</strong>
|
||||
</div>
|
||||
<div className="flex items-center justify-between gap-2">
|
||||
<span className="text-military-text-secondary">轻度损毁</span>
|
||||
<strong className="text-amber-300">{stats.light}</strong>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user