60 lines
1.9 KiB
TypeScript
60 lines
1.9 KiB
TypeScript
'use client';
|
|
|
|
import type { NetworkMetrics } from '@/types/metrics';
|
|
import { formatTimestamp, formatBytesPerSec } from '@/lib/formatters';
|
|
|
|
interface NetworkAlertPanelProps {
|
|
data: NetworkMetrics;
|
|
height?: number;
|
|
}
|
|
|
|
interface Alert {
|
|
level: 'warning' | 'critical';
|
|
instance: string;
|
|
message: string;
|
|
}
|
|
|
|
export default function NetworkAlertPanel({ data, height = 300 }: NetworkAlertPanelProps) {
|
|
const alerts: Alert[] = [];
|
|
|
|
[...data.receive, ...data.transmit].forEach((inst) => {
|
|
const direction = data.receive.includes(inst) ? 'RX' : 'TX';
|
|
const label = `${direction} ${inst.instance || 'total'}`;
|
|
|
|
inst.peaks.peaks.forEach((peak) => {
|
|
alerts.push({
|
|
level: 'warning',
|
|
instance: label,
|
|
message: `${formatTimestamp(peak.startTime)} ~ ${formatTimestamp(peak.endTime)} 트래픽 급증 (max: ${formatBytesPerSec(peak.maxValue)})`,
|
|
});
|
|
});
|
|
});
|
|
|
|
if (alerts.length === 0) {
|
|
return (
|
|
<div className="bg-green-50 border border-green-200 rounded-lg p-3 flex items-center justify-center" style={{ height }}>
|
|
<p className="text-green-700 text-xs">특이사항 없음</p>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
return (
|
|
<div className="bg-white border rounded-lg flex flex-col" style={{ height }}>
|
|
<div className="px-3 py-2 border-b bg-gray-50 flex-shrink-0">
|
|
<h4 className="text-xs font-medium text-gray-600">주의 구간 ({alerts.length}건)</h4>
|
|
</div>
|
|
<ul className="divide-y divide-gray-100 overflow-y-auto flex-1">
|
|
{alerts.map((alert, idx) => (
|
|
<li key={idx} className="px-3 py-2 flex items-start gap-2">
|
|
<span className="mt-1 inline-block w-1.5 h-1.5 rounded-full flex-shrink-0 bg-yellow-500" />
|
|
<div className="text-xs">
|
|
<span className="font-medium text-gray-800">{alert.instance}</span>
|
|
<p className="text-gray-500">{alert.message}</p>
|
|
</div>
|
|
</li>
|
|
))}
|
|
</ul>
|
|
</div>
|
|
);
|
|
}
|