Files
aerbim-ht-monitor/frontend/components/notifications/Notifications.tsx
2025-11-11 10:07:38 +03:00

136 lines
4.3 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 { IoClose } from 'react-icons/io5'
interface NotificationType {
id: number
detector_id: number
detector_name: string
type: string
status: string
message: string
timestamp: string
location: string
object: string
acknowledged: boolean
priority: string
}
interface DetectorType {
detector_id: number
name: string
serial_number: 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 DetectorsDataType {
detectors: Record<string, DetectorType>
}
interface NotificationsProps {
objectId?: string
detectorsData: DetectorsDataType
onNotificationClick: (notification: NotificationType) => void
onClose: () => void
}
const Notifications: React.FC<NotificationsProps> = ({ objectId, detectorsData, onNotificationClick, onClose }) => {
const allNotifications = React.useMemo(() => {
const notifications: NotificationType[] = [];
Object.values(detectorsData.detectors).forEach(detector => {
if (detector.notifications && detector.notifications.length > 0) {
detector.notifications.forEach(notification => {
notifications.push({
...notification,
detector_id: detector.detector_id,
detector_name: detector.name,
location: detector.location,
object: detector.object,
status: detector.status
});
});
}
});
return notifications;
}, [detectorsData]);
// сортировка по objectId
const filteredNotifications = objectId
? allNotifications.filter(notification => notification.object.toString() === objectId.toString())
: allNotifications
// сортировка по timestamp
const sortedNotifications = [...filteredNotifications].sort((a, b) => new Date(b.timestamp).getTime() - new Date(a.timestamp).getTime())
const getStatusColor = (type: string) => {
switch (type.toLowerCase()) {
case 'critical': return 'bg-red-500'
case 'warning': return 'bg-orange-500'
case 'info': return 'bg-green-500'
default: return 'bg-gray-500'
}
}
return (
<div className="h-full bg-[#161824] flex flex-col">
<div className="flex items-center justify-between p-4 border-b border-gray-700">
<h2 className="text-white text-lg font-medium">Уведомления</h2>
<button
onClick={onClose}
className="p-2 hover:bg-gray-700 rounded-lg transition-colors"
>
<IoClose className="w-5 h-5 text-gray-400" />
</button>
</div>
{/* Список уведомлений*/}
<div className="flex-1 overflow-y-auto p-4">
{sortedNotifications.length === 0 ? (
<div className="flex items-center justify-center h-32">
<p className="text-gray-400">Уведомления не найдены</p>
</div>
) : (
<div className="space-y-3">
{sortedNotifications.map((notification) => (
<div
key={notification.id}
className="bg-[rgb(53,58,70)] rounded-md p-3 flex items-center justify-between hover:bg-[rgb(63,68,80)] transition-colors"
>
<div className="flex items-center gap-3">
<div className={`w-3 h-3 rounded-full ${getStatusColor(notification.type)}`}></div>
<div>
<div className="text-white text-sm font-medium">{notification.detector_name}</div>
<div className="text-gray-400 text-xs">{notification.message}</div>
</div>
</div>
<button
onClick={() => onNotificationClick(notification)}
className="w-6 h-6 bg-[rgb(27,29,41)] hover:bg-[rgb(37,39,51)] rounded-full flex items-center justify-center transition-colors relative"
>
<div className="w-2 h-2 bg-white rounded-full"></div>
</button>
</div>
))}
</div>
)}
</div>
</div>
)
}
export default Notifications