
- Обновлен CLAUDE.md с новыми правилами системы - Дополнен workflow-catalog.md с процессами - Обновлены interaction-integrity-rules.md - Завершен модульный рефакторинг create-suppliers компонента - Добавлен модульный user-settings с блочной архитектурой - Система готова к следующему этапу архитектурных улучшений 🚀 Generated with Claude Code Co-Authored-By: Claude <noreply@anthropic.com>
154 lines
7.3 KiB
TypeScript
154 lines
7.3 KiB
TypeScript
/**
|
||
* БЛОК КАРТОЧЕК ТОВАРОВ (МИНИ-ПРЕВЬЮ)
|
||
*
|
||
* Выделен из create-suppliers-supply-page.tsx
|
||
* Горизонтальный скролл мини-карточек товаров поставщика
|
||
*/
|
||
|
||
'use client'
|
||
|
||
import { Package, Plus } from 'lucide-react'
|
||
import Image from 'next/image'
|
||
import React from 'react'
|
||
|
||
import { Badge } from '@/components/ui/badge'
|
||
|
||
import type { ProductCardsBlockProps } from '../types/supply-creation.types'
|
||
|
||
export const ProductCardsBlock = React.memo(function ProductCardsBlock({
|
||
products,
|
||
selectedSupplier,
|
||
onProductAdd,
|
||
}: ProductCardsBlockProps) {
|
||
if (!selectedSupplier) {
|
||
return (
|
||
<div className="bg-white/10 backdrop-blur-xl border border-white/20 rounded-2xl p-6 h-full flex flex-col">
|
||
{/* ОТКАТ: вернули h-full flex flex-col */}
|
||
<div className="text-center py-8">
|
||
<div className="bg-gradient-to-br from-blue-500/20 to-purple-500/20 rounded-full p-4 w-fit mx-auto mb-3">
|
||
<Package className="h-8 w-8 text-blue-300" />
|
||
</div>
|
||
<p className="text-white/60 text-sm font-medium mb-2">Выберите поставщика</p>
|
||
<p className="text-white/40 text-xs">Для просмотра каталога товаров сначала выберите поставщика</p>
|
||
</div>
|
||
</div>
|
||
)
|
||
}
|
||
|
||
if (products.length === 0) {
|
||
return (
|
||
<div className="bg-white/10 backdrop-blur-xl border border-white/20 rounded-2xl p-6 h-full flex flex-col">
|
||
{/* ОТКАТ: вернули h-full flex flex-col */}
|
||
<h3 className="text-white font-semibold text-lg mb-4">2. Товары поставщика (0)</h3>
|
||
<div className="text-center py-8">
|
||
<div className="bg-gradient-to-br from-orange-500/20 to-red-500/20 rounded-full p-4 w-fit mx-auto mb-3">
|
||
<Package className="h-8 w-8 text-orange-300" />
|
||
</div>
|
||
<p className="text-white/60 text-sm font-medium mb-2">Товары не найдены</p>
|
||
<p className="text-white/40 text-xs">У выбранного поставщика пока нет доступных товаров</p>
|
||
</div>
|
||
</div>
|
||
)
|
||
}
|
||
|
||
return (
|
||
<div className="bg-white/10 backdrop-blur-xl border border-white/20 rounded-2xl p-6 h-full flex flex-col">
|
||
{/* ОТКАТ: вернули h-full flex flex-col */}
|
||
<h3 className="text-white font-semibold text-lg mb-4">2. Товары поставщика ({products.length})</h3>
|
||
|
||
<div className="flex-1 overflow-x-auto overflow-y-hidden">
|
||
{/* ОТКАТ: вернули flex-1 overflow-x-auto overflow-y-hidden */}
|
||
<div className="flex gap-3 pb-2" style={{ width: 'max-content' }}>
|
||
{products.slice(0, 10).map(
|
||
(
|
||
product, // Показываем первые 10 товаров
|
||
) => (
|
||
<div
|
||
key={product.id}
|
||
className="flex-shrink-0 w-48 bg-white/5 rounded-lg border border-white/10 hover:border-white/20 hover:bg-white/8 transition-all duration-200 group"
|
||
>
|
||
{/* Изображение товара */}
|
||
<div className="relative h-24 rounded-t-lg overflow-hidden bg-white/5">
|
||
{product.mainImage || (product.images && product.images[0]) ? (
|
||
<Image
|
||
src={product.mainImage || product.images[0]}
|
||
alt={product.name}
|
||
fill
|
||
className="object-cover group-hover:scale-105 transition-transform duration-200"
|
||
/>
|
||
) : (
|
||
<div className="flex items-center justify-center h-full">
|
||
<Package className="h-8 w-8 text-white/30" />
|
||
</div>
|
||
)}
|
||
|
||
{/* Статус наличия */}
|
||
<div className="absolute top-1 right-1">
|
||
{product.quantity !== undefined && (
|
||
<div className={`w-2 h-2 rounded-full ${product.quantity > 0 ? 'bg-green-400' : 'bg-red-400'}`} />
|
||
)}
|
||
</div>
|
||
</div>
|
||
|
||
{/* Информация о товаре */}
|
||
<div className="p-3">
|
||
<div className="mb-2">
|
||
<h4 className="text-white text-sm font-medium line-clamp-2 leading-tight">{product.name}</h4>
|
||
{product.article && <p className="text-white/50 text-xs mt-1">Арт: {product.article}</p>}
|
||
</div>
|
||
|
||
{/* Категория */}
|
||
{product.category?.name && (
|
||
<Badge variant="secondary" className="text-xs mb-2 bg-white/10 text-white/70 border-white/20">
|
||
{product.category.name}
|
||
</Badge>
|
||
)}
|
||
|
||
{/* Цена и наличие */}
|
||
<div className="flex items-center justify-between mb-2">
|
||
<span className="text-white font-semibold text-sm">{product.price.toLocaleString('ru-RU')} ₽</span>
|
||
{product.quantity !== undefined && (
|
||
<span className={`text-xs ${product.quantity > 0 ? 'text-green-400' : 'text-red-400'}`}>
|
||
{product.quantity > 0 ? `${product.quantity} шт` : 'Нет в наличии'}
|
||
</span>
|
||
)}
|
||
</div>
|
||
|
||
{/* Кнопка добавления */}
|
||
<button
|
||
onClick={() => onProductAdd(product)}
|
||
disabled={product.quantity === 0}
|
||
className="w-full bg-purple-500/20 hover:bg-purple-500/30 text-purple-300 hover:text-white border border-purple-500/30 hover:border-purple-500/50 rounded px-2 py-1 text-xs font-medium transition-all duration-200 flex items-center justify-center gap-1 disabled:opacity-50 disabled:cursor-not-allowed"
|
||
>
|
||
<Plus className="h-3 w-3" />
|
||
Добавить
|
||
</button>
|
||
</div>
|
||
</div>
|
||
),
|
||
)}
|
||
|
||
{/* Показать больше товаров */}
|
||
{products.length > 10 && (
|
||
<div className="flex-shrink-0 w-48 bg-white/5 rounded-lg border border-white/10 hover:border-white/20 flex items-center justify-center cursor-pointer transition-all duration-200">
|
||
<div className="text-center p-6">
|
||
<Plus className="h-6 w-6 text-white/50 mx-auto mb-2" />
|
||
<p className="text-white/60 text-sm font-medium">Показать все</p>
|
||
<p className="text-white/40 text-xs">+{products.length - 10} товаров</p>
|
||
</div>
|
||
</div>
|
||
)}
|
||
</div>
|
||
</div>
|
||
|
||
{/* Подсказка */}
|
||
<div className="mt-4 p-3 bg-blue-500/10 border border-blue-400/30 rounded-lg">
|
||
<p className="text-blue-300 text-xs">
|
||
💡 <strong>Подсказка:</strong> Нажмите на товар для быстрого добавления или перейдите к детальному каталогу
|
||
ниже для настройки рецептуры
|
||
</p>
|
||
</div>
|
||
</div>
|
||
)
|
||
})
|