Files
router-lists-ui/frontend/src/components/EmptyState.jsx
T

104 lines
2.5 KiB
React

/**
* EmptyState - улучшенный компонент для отображения пустого состояния
* Добавлены: иллюстрации, улучшенные CTA, варианты размеров
*/
function EmptyState({
icon: Icon,
title = 'Нет данных',
description,
action,
secondaryAction,
size = 'default', // 'small', 'default', 'large'
illustration, // URL иллюстрации
variant = 'default' // 'default', 'success', 'info', 'warning'
}) {
const sizeClasses = {
small: 'empty-sm',
default: '',
large: 'empty-lg'
}
const variantColors = {
default: 'text-muted',
success: 'text-success',
info: 'text-info',
warning: 'text-warning'
}
return (
<div className={`empty ${sizeClasses[size]}`}>
<div className="empty-icon">
{illustration ? (
<img
src={illustration}
alt={title}
style={{
maxWidth: size === 'large' ? '200px' : size === 'small' ? '80px' : '120px',
opacity: 0.6
}}
/>
) : Icon ? (
<Icon
size={size === 'large' ? 64 : size === 'small' ? 32 : 48}
className={variantColors[variant]}
/>
) : null}
</div>
<p className="empty-title">{title}</p>
{description && (
<p className="empty-subtitle text-muted">
{description}
</p>
)}
{(action || secondaryAction) && (
<div className="empty-action">
{action}
{secondaryAction && (
<span className="ms-2">{secondaryAction}</span>
)}
</div>
)}
<style jsx>{`
.empty-sm .empty-icon {
margin-bottom: 0.5rem;
}
.empty-sm .empty-title {
font-size: 1rem;
}
.empty-sm .empty-subtitle {
font-size: 0.875rem;
}
.empty-lg .empty-icon {
margin-bottom: 2rem;
}
.empty-lg .empty-title {
font-size: 1.5rem;
font-weight: 600;
}
.empty-lg .empty-subtitle {
font-size: 1.125rem;
}
.empty-icon img {
animation: float 3s ease-in-out infinite;
}
@keyframes float {
0%, 100% {
transform: translateY(0);
}
50% {
transform: translateY(-10px);
}
}
`}</style>
</div>
)
}
export default EmptyState