Files
aerbim-ht-monitor/frontend/components/notifications/NotificationDetectorInfo.tsx
2026-01-21 03:16:52 +03:00

190 lines
7.8 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
'use client'
import React from 'react'
import * as statusColors from '../../lib/statusColors'
interface DetectorInfoType {
detector_id: number
name: string
object: string
status: string
type: string
detector_type: string
location: string
floor: number
checked: boolean
notifications: Array<{
id: number
type: string
message: string
timestamp: string
acknowledged: boolean
priority: string
}>
}
interface NotificationDetectorInfoProps {
detectorData: DetectorInfoType
onClose: () => void
}
const NotificationDetectorInfo: React.FC<NotificationDetectorInfoProps> = ({ detectorData, onClose }) => {
const detectorInfo = detectorData
if (!detectorInfo) {
return (
<div className="w-full max-w-4xl">
<div className="bg-[rgb(22,24,36)] rounded-[12px] p-6">
<div className="flex items-center justify-between mb-4">
<h2 className="text-white text-2xl font-semibold">Информация о детекторе</h2>
<button
onClick={onClose}
className="text-white hover:text-gray-300 transition-colors"
>
<svg className="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M6 18L18 6M6 6l12 12" />
</svg>
</button>
</div>
<p className="text-gray-400">Детектор не найден</p>
</div>
</div>
)
}
const getStatusColor = (status: string) => {
if (status === statusColors.STATUS_COLOR_CRITICAL) return 'text-red-400'
if (status === statusColors.STATUS_COLOR_WARNING) return 'text-orange-400'
if (status === statusColors.STATUS_COLOR_NORMAL || status === '#4caf50') return 'text-green-400'
return 'text-gray-400'
}
const getPriorityColor = (priority: string) => {
switch (priority.toLowerCase()) {
case 'high': return 'text-red-400'
case 'medium': return 'text-orange-400'
case 'low': return 'text-green-400'
default: return 'text-gray-400'
}
}
const getPriorityText = (priority: string) => {
switch (priority.toLowerCase()) {
case 'high': return 'высокий'
case 'medium': return 'средний'
case 'low': return 'низкий'
default: return priority
}
}
const latestNotification = detectorInfo.notifications && detectorInfo.notifications.length > 0
? detectorInfo.notifications.sort((a, b) => new Date(b.timestamp).getTime() - new Date(a.timestamp).getTime())[0]
: null
const formatDate = (dateString: string) => {
const date = new Date(dateString)
return date.toLocaleString('ru-RU', {
day: '2-digit',
month: '2-digit',
year: 'numeric',
hour: '2-digit',
minute: '2-digit'
})
}
return (
<div className="h-full">
<div className="h-full overflow-auto">
<div className="flex items-center justify-between mb-4">
<h3 className="text-white text-lg font-medium">
{detectorInfo.name}
</h3>
<div className="flex items-center gap-2">
<button className="bg-[rgb(27,29,41)] hover:bg-[rgb(37,39,51)] text-white px-3 py-2 rounded-[10px] text-sm font-medium transition-colors flex items-center gap-2">
<svg className="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z" />
</svg>
Отчет
</button>
<button className="bg-[rgb(27,29,41)] hover:bg-[rgb(37,39,51)] text-white px-3 py-2 rounded-[10px] text-sm font-medium transition-colors flex items-center gap-2">
<svg className="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M12 8v4l3 3m6-3a9 9 0 11-18 0 9 9 0 0118 0z" />
</svg>
История
</button>
<button
onClick={onClose}
className="text-gray-400 hover:text-white transition-colors"
>
<svg className="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M6 18L18 6M6 6l12 12" />
</svg>
</button>
</div>
</div>
{/* Табличка */}
<div className="space-y-0 border border-[rgb(30,31,36)] rounded-lg overflow-hidden">
<div className="flex">
<div className="flex-1 p-4 border-r border-[rgb(30,31,36)]">
<div className="text-[rgb(113,113,122)] text-sm font-medium mb-1">Маркировка по проекту</div>
<div className="text-white text-sm">{detectorInfo.name}</div>
</div>
<div className="flex-1 p-4">
<div className="text-[rgb(113,113,122)] text-sm font-medium mb-1">Тип детектора</div>
<div className="text-white text-sm">{detectorInfo.type}</div>
</div>
</div>
<div className="flex border-t border-[rgb(30,31,36)]">
<div className="flex-1 p-4 border-r border-[rgb(30,31,36)]">
<div className="text-[rgb(113,113,122)] text-sm font-medium mb-1">Местоположение</div>
<div className="text-white text-sm">{detectorInfo.location}</div>
</div>
<div className="flex-1 p-4">
<div className="text-[rgb(113,113,122)] text-sm font-medium mb-1">Статус</div>
<div className="flex items-center gap-2">
<div
className="w-3 h-3 rounded-full"
style={{ backgroundColor: detectorInfo.status }}
></div>
<span className={`text-sm font-medium ${getStatusColor(detectorInfo.status)}`}>
{detectorInfo.status === statusColors.STATUS_COLOR_CRITICAL
? 'Критический'
: detectorInfo.status === statusColors.STATUS_COLOR_WARNING
? 'Предупреждение'
: detectorInfo.status === statusColors.STATUS_COLOR_NORMAL || detectorInfo.status === '#4caf50'
? 'Нормальный'
: 'Неизвестно'}
</span>
</div>
</div>
</div>
{latestNotification && (
<div className="flex border-t border-[rgb(30,31,36)]">
<div className="flex-1 p-4 border-r border-[rgb(30,31,36)]">
<div className="text-[rgb(113,113,122)] text-sm font-medium mb-1">Последнее уведомление</div>
<div className="text-white text-sm">{formatDate(latestNotification.timestamp)}</div>
</div>
<div className="flex-1 p-4">
<div className="text-[rgb(113,113,122)] text-sm font-medium mb-1">Приоритет</div>
<div className={`text-sm font-medium ${getPriorityColor(latestNotification.priority)}`}>
{getPriorityText(latestNotification.priority)}
</div>
</div>
</div>
)}
{latestNotification && (
<div className="border-t border-[rgb(30,31,36)] p-4">
<div className="text-[rgb(113,113,122)] text-sm font-medium mb-1">Сообщение</div>
<div className="text-white text-sm">{latestNotification.message}</div>
</div>
)}
</div>
</div>
</div>
)
}
export default NotificationDetectorInfo