import React, { useState, useEffect, useCallback } from 'react' import { createPortal } from 'react-dom' import { useAuth } from './auth/AuthContext' import LoadingError from './LoadingError' import Toast from './Toast' import './TaskDetail.css' function ShoppingItemDetail({ itemId, onClose, onRefresh, onItemCompleted, onNavigate }) { const { authFetch } = useAuth() const [item, setItem] = useState(null) const [loading, setLoading] = useState(true) const [error, setError] = useState(null) const [volumeValue, setVolumeValue] = useState('') const [isCompleting, setIsCompleting] = useState(false) const [toastMessage, setToastMessage] = useState(null) const fetchItem = useCallback(async () => { try { setLoading(true) setError(null) const response = await authFetch(`/api/shopping/items/${itemId}`) if (!response.ok) { throw new Error('Ошибка загрузки товара') } const data = await response.json() setItem(data) } catch (err) { setError(err.message) } finally { setLoading(false) } }, [itemId, authFetch]) useEffect(() => { if (itemId) { fetchItem() } else { setItem(null) setLoading(true) setError(null) setVolumeValue('') } }, [itemId, fetchItem]) const handleComplete = async () => { if (!item) return setIsCompleting(true) try { const payload = {} if (volumeValue.trim()) { payload.volume = parseFloat(volumeValue) if (isNaN(payload.volume)) { throw new Error('Неверное значение объёма') } } else { payload.volume = item.last_volume ?? item.volume_base } const response = await authFetch(`/api/shopping/items/${itemId}/complete`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(payload), }) if (!response.ok) { const errorData = await response.json().catch(() => ({})) throw new Error(errorData.error || 'Ошибка при выполнении') } onItemCompleted?.() onRefresh?.() onClose?.() } catch (err) { setToastMessage({ text: err.message || 'Ошибка', type: 'error' }) } finally { setIsCompleting(false) } } if (!itemId) return null const modalContent = (
onClose?.()}>
e.stopPropagation()}>

{ onClose?.(true) onNavigate?.('shopping-item-form', { itemId: itemId, boardId: item.board_id }) } : undefined} style={{ cursor: item ? 'pointer' : 'default' }} > {loading ? 'Загрузка...' : error ? 'Ошибка' : item ? ( <> {item.name} ) : 'Товар'}

{loading && (
Загрузка...
)} {error && !loading && ( )} {!loading && !error && item && ( <>
{item.description ? ( item.description.split(/(https?:\/\/[^\s<>"'`,;!)\]]+)/gi).map((part, i) => { if (/^https?:\/\//i.test(part)) { let host try { host = new URL(part).host.replace(/^www\./, '') } catch { host = 'Открыть ссылку' } return ( {host} ) } return {part} }) ) : ( Описание отсутствует )}
setVolumeValue(e.target.value)} placeholder={(item.last_volume ?? item.volume_base)?.toString() || '1'} className="progression-input" />
)}
{toastMessage && ( setToastMessage(null)} /> )}
) return typeof document !== 'undefined' ? createPortal(modalContent, document.body) : modalContent } export default ShoppingItemDetail