New api and zone management; highligh occlusion and highlighAll functionality; improved search in reports and alerts history + autofill; refactored alert panel

This commit is contained in:
iv_vuytsik
2025-12-25 03:10:21 +03:00
parent 31030f2997
commit ce7e39debf
36 changed files with 1562 additions and 472 deletions

View File

@@ -7,7 +7,7 @@ interface ObjectData {
object_id: string
title: string
description: string
image: string
image: string | null
location: string
floors?: number
area?: string
@@ -45,6 +45,41 @@ const ObjectCard: React.FC<ObjectCardProps> = ({ object, onSelect, isSelected =
// Логика редактирования объекта
}
// Возврат к тестовому изображению, если src отсутствует/некорректен; нормализация относительных путей
const resolveImageSrc = (src?: string | null): string => {
if (!src || typeof src !== 'string') return '/images/test_image.png'
let s = src.trim()
if (!s) return '/images/test_image.png'
// Нормализуем обратные слеши в стиле Windows
s = s.replace(/\\/g, '/')
const lower = s.toLowerCase()
// Обрабатываем явный плейсхолдер test_image.png только как заглушку
if (lower === 'test_image.png' || lower.endsWith('/test_image.png') || lower.includes('/public/images/test_image.png')) {
return '/images/test_image.png'
}
// Абсолютные URL
if (s.startsWith('http://') || s.startsWith('https://')) return s
// Пути, относительные к сайту
if (s.startsWith('/')) {
// Преобразуем /public/images/... в /images/...
if (/\/public\/images\//i.test(s)) {
return s.replace(/\/public\/images\//i, '/images/')
}
return s
}
// Нормализуем относительные имена ресурсов до путей сайта под /images
// Убираем ведущий 'public/', если он присутствует
s = s.replace(/^public\//i, '')
return s.startsWith('images/') ? `/${s}` : `/images/${s}`
}
const imgSrc = resolveImageSrc(object.image)
return (
<article
className={`flex flex-col w-full min-h-[414px] h-[414px] sm:h-auto sm:min-h-[350px] items-start gap-4 p-4 sm:p-6 relative bg-[#161824] rounded-[20px] overflow-hidden cursor-pointer transition-all duration-200 hover:bg-[#1a1d2e] ${
@@ -85,13 +120,13 @@ const ObjectCard: React.FC<ObjectCardProps> = ({ object, onSelect, isSelected =
<Image
className="absolute w-full h-full top-0 left-0 object-cover"
alt={object.title}
src={object.image}
src={imgSrc}
fill
sizes="(max-width: 768px) 100vw, (max-width: 1200px) 50vw, 33vw"
onError={(e) => {
// Заглушка при ошибке загрузки изображения
const target = e.target as HTMLImageElement
target.src = 'data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNDUyIiBoZWlnaHQ9IjMwMiIgdmlld0JveD0iMCAwIDQ1MiAzMDIiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CjxyZWN0IHdpZHRoPSI0NTIiIGhlaWdodD0iMzAyIiBmaWxsPSIjRjFGMUYxIi8+CjxwYXRoIGQ9Ik0yMjYgMTUxTDI0NiAxMzFMMjY2IDE1MUwyNDYgMTcxTDIyNiAxNTFaIiBmaWxsPSIjOTk5OTk5Ii8+Cjx0ZXh0IHg9IjIyNiIgeT0iMTkwIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBmaWxsPSIjOTk5OTk5IiBmb250LXNpemU9IjE0Ij7QntCx0YrQtdC60YI8L3RleHQ+Cjwvc3ZnPgo='
target.src = '/images/test_image.png'
}}
/>
</div>