'use client' import { useQuery, useMutation } from '@apollo/client' import { Package, Save, X, Edit, Check } from 'lucide-react' import Image from 'next/image' import { useState, useEffect, useMemo } from 'react' import { toast } from 'sonner' // Alert dialog no longer needed for supplies import { Button } from '@/components/ui/button' import { Card } from '@/components/ui/card' import { Input } from '@/components/ui/input' import { UPDATE_SUPPLY_PRICE } from '@/graphql/mutations' import { GET_MY_SUPPLIES } from '@/graphql/queries' import { useAuth } from '@/hooks/useAuth' interface Supply { id: string name: string description?: string pricePerUnit?: number | null unit: string imageUrl?: string warehouseStock: number isAvailable: boolean warehouseConsumableId: string createdAt: string updatedAt: string organization: { id: string name: string } } interface EditableSupply { id: string name: string description: string pricePerUnit: string // Цена за единицу - единственное редактируемое поле unit: string imageUrl: string warehouseStock: number isAvailable: boolean isEditing: boolean hasChanges: boolean } // PendingChange interface no longer needed export function SuppliesTab() { const { user } = useAuth() const [editableSupplies, setEditableSupplies] = useState([]) // No longer need pending changes tracking const [isSaving, setIsSaving] = useState(false) const [isInitialized, setIsInitialized] = useState(false) // Debug информация console.log('SuppliesTab - User:', user?.phone, 'Type:', user?.organization?.type) // GraphQL запросы и мутации const { data, loading, error, refetch } = useQuery(GET_MY_SUPPLIES, { skip: !user || user?.organization?.type !== 'FULFILLMENT', }) const [updateSupplyPrice] = useMutation(UPDATE_SUPPLY_PRICE) // Debug GraphQL запроса console.log('SuppliesTab - Query:', { skip: !user || user?.organization?.type !== 'FULFILLMENT', loading, error: error?.message, dataLength: data?.mySupplies?.length, }) const supplies = data?.mySupplies || [] // Преобразуем загруженные расходники в редактируемый формат useEffect(() => { if (data?.mySupplies && !isInitialized) { const convertedSupplies: EditableSupply[] = data.mySupplies.map((supply: Supply) => ({ id: supply.id, name: supply.name, description: supply.description || '', pricePerUnit: supply.pricePerUnit ? supply.pricePerUnit.toString() : '', unit: supply.unit, imageUrl: supply.imageUrl || '', warehouseStock: supply.warehouseStock, isAvailable: supply.isAvailable, isEditing: false, hasChanges: false, })) setEditableSupplies(convertedSupplies) setIsInitialized(true) } }, [data, isInitialized]) // Расходники нельзя создавать - они появляются автоматически со склада // const addNewRow = () => { ... } - REMOVED // Расходники нельзя удалять - они управляются через склад // const removeRow = async (supplyId: string, isNew: boolean) => { ... } - REMOVED // Начать редактирование существующей строки const startEditing = (supplyId: string) => { setEditableSupplies((prev) => prev.map((supply) => (supply.id === supplyId ? { ...supply, isEditing: true } : supply)), ) } // Отменить редактирование const cancelEditing = (supplyId: string) => { const supply = editableSupplies.find((s) => s.id === supplyId) if (!supply) return // Возвращаем к исходному состоянию const originalSupply = supplies.find((s: Supply) => s.id === supply.id) if (originalSupply) { setEditableSupplies((prev) => prev.map((s) => s.id === supplyId ? { id: originalSupply.id, name: originalSupply.name, description: originalSupply.description || '', pricePerUnit: originalSupply.pricePerUnit ? originalSupply.pricePerUnit.toString() : '', unit: originalSupply.unit, imageUrl: originalSupply.imageUrl || '', warehouseStock: originalSupply.warehouseStock, isAvailable: originalSupply.isAvailable, isEditing: false, hasChanges: false, } : s, ), ) } } // Обновить поле (только цену можно редактировать) const updateField = (supplyId: string, field: keyof EditableSupply, value: string) => { if (field !== 'pricePerUnit') { return // Только цену можно редактировать } setEditableSupplies((prev) => prev.map((supply) => { if (supply.id !== supplyId) return supply return { ...supply, pricePerUnit: value, hasChanges: true, } }), ) } // Image upload no longer needed - supplies are readonly except price // Сохранить все изменения (только цены) const saveAllChanges = async () => { setIsSaving(true) try { const suppliesToSave = editableSupplies.filter((s) => s.hasChanges) for (const supply of suppliesToSave) { // Проверяем валидность цены (может быть пустой) const pricePerUnit = supply.pricePerUnit.trim() ? parseFloat(supply.pricePerUnit) : null if (supply.pricePerUnit.trim() && (isNaN(pricePerUnit!) || pricePerUnit! <= 0)) { toast.error('Введите корректную цену') setIsSaving(false) return } const input = { pricePerUnit: pricePerUnit, } await updateSupplyPrice({ variables: { id: supply.id, input }, update: (cache, { data }) => { if (data?.updateSupplyPrice?.supply) { const existingData = cache.readQuery({ query: GET_MY_SUPPLIES }) as { mySupplies: Supply[] } | null if (existingData) { cache.writeQuery({ query: GET_MY_SUPPLIES, data: { mySupplies: existingData.mySupplies.map((s: Supply) => s.id === data.updateSupplyPrice.supply.id ? data.updateSupplyPrice.supply : s, ), }, }) } } }, }) } // Сбрасываем флаги изменений setEditableSupplies((prev) => prev.map((s) => ({ ...s, hasChanges: false, isEditing: false }))) toast.success('Цены успешно обновлены') } catch (error) { console.error('Error saving changes:', error) toast.error('Ошибка при сохранении цен') } finally { setIsSaving(false) } } // Проверяем есть ли несохраненные изменения (только цены) const hasUnsavedChanges = useMemo(() => { return editableSupplies.some((s) => s.hasChanges) }, [editableSupplies]) return (
{/* Заголовок и кнопки */}

Расходники со склада

Расходники появляются автоматически из поставок. Можно только установить цену.

{hasUnsavedChanges && ( )}
{/* Таблица расходников */}
{loading ? (

Загрузка расходников...

) : error ? (

Ошибка загрузки

Не удалось загрузить расходники {process.env.NODE_ENV === 'development' && ( <>
Debug: {error.message}
User type: {user?.organization?.type}
)}

) : editableSupplies.length === 0 ? (

Пока нет расходников

Расходники появятся автоматически при получении поставок

) : (
{editableSupplies.map((supply, index) => ( {/* Фото */} {/* Название */} {/* Остаток на складе */} {/* Единица измерения */} {/* Цена за единицу */} {/* Описание */} {/* Действия */} ))}
Фото Название Остаток Единица Цена за единицу (₽) Описание Действия
{index + 1} {supply.imageUrl ? (
{supply.name} {/* Увеличенная версия при hover */}
{supply.name}

{supply.name}

) : (
)}
{supply.name}
{supply.warehouseStock} {!supply.isAvailable && ( Нет в наличии )}
{supply.unit} {supply.isEditing ? ( updateField(supply.id, 'pricePerUnit', e.target.value)} className="bg-white/5 border-white/20 text-white" placeholder="Не установлена" /> ) : ( {supply.pricePerUnit ? `${parseFloat(supply.pricePerUnit).toLocaleString()} ₽` : 'Не установлена'} )} {supply.description || '—'}
{supply.isEditing ? ( <> ) : ( )}
)}
) }