Files
aerbim-ht-monitor/frontend/components/objects/ObjectCard.tsx

103 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 Image from 'next/image'
import { useNavigationService } from '@/services/navigationService'
interface ObjectData {
object_id: string
title: string
description: string
image: string
location: string
floors?: number
area?: string
type?: string
status?: string
}
interface ObjectCardProps {
object: ObjectData
onSelect?: (objectId: string) => void
isSelected?: boolean
}
// Иконка редактирования
const EditIcon = ({ className }: { className?: string }) => (
<svg className={className} fill="currentColor" viewBox="0 0 24 24">
<path d="M3 17.25V21h3.75L17.81 9.94l-3.75-3.75L3 17.25zM20.71 7.04c.39-.39.39-1.02 0-1.41l-2.34-2.34c-.39-.39-1.02-.39-1.41 0l-1.83 1.83 3.75 3.75 1.83-1.83z" />
</svg>
)
const ObjectCard: React.FC<ObjectCardProps> = ({ object, onSelect, isSelected = false }) => {
const navigationService = useNavigationService()
const handleCardClick = () => {
if (onSelect) {
onSelect(object.object_id)
}
// Навигация к дашборду с выбранным объектом
navigationService.selectObjectAndGoToDashboard(object.object_id, object.title)
}
const handleEditClick = (e: React.MouseEvent) => {
e.stopPropagation()
console.log('Edit object:', object.object_id)
// Логика редактирования объекта
}
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] ${
isSelected ? 'ring-2 ring-blue-500' : ''
}`}
onClick={handleCardClick}
role="button"
tabIndex={0}
onKeyDown={(e) => {
if (e.key === 'Enter' || e.key === ' ') {
handleCardClick()
}
}}
>
<header className="flex flex-col sm:flex-row items-start sm:items-center gap-3 sm:gap-2 relative self-stretch w-full flex-[0_0_auto]">
<div className="flex-col items-start flex-1 grow flex relative min-w-0">
<h2 className="self-stretch mt-[-1.00px] font-medium text-white text-lg leading-7 relative tracking-[0] break-words">
{object.title}
</h2>
<p className="self-stretch font-normal text-[#71717a] text-sm leading-5 relative tracking-[0] break-words">
{object.description}
</p>
</div>
<button
className="inline-flex flex-shrink-0 bg-[#3193f5] h-10 items-center justify-center gap-2 px-3 sm:px-4 py-2 relative rounded-md transition-colors duration-200 hover:bg-[#2563eb] focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-opacity-50 w-full sm:w-auto"
aria-label={`Изменить ${object.title}`}
onClick={handleEditClick}
>
<EditIcon className="!relative !w-4 !h-4 text-white flex-shrink-0" />
<span className="font-medium text-white text-sm leading-5 relative tracking-[0] sm:whitespace-nowrap">
Изменить
</span>
</button>
</header>
{/* Изображение объекта */}
<div className="relative flex-1 self-stretch w-full grow bg-[#f1f1f1] rounded-lg overflow-hidden min-h-[200px] sm:min-h-[250px]">
<Image
className="absolute w-full h-full top-0 left-0 object-cover"
alt={object.title}
src={object.image}
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='
}}
/>
</div>
</article>
)
}
export default ObjectCard
export type { ObjectData, ObjectCardProps }