// src/renderer/components/PlayerInventory.tsx import { useEffect, useState } from 'react'; import { Box, Typography, Grid, Card, CardMedia, CardContent, Button, CircularProgress, Dialog, DialogTitle, DialogContent, DialogActions, TextField, Alert, } from '@mui/material'; import { RequestPlayerInventory, getPlayerInventory, sellItem, PlayerInventoryItem, } from '../api'; interface PlayerInventoryProps { username: string; serverIp: string; onSellSuccess?: () => void; // Callback для обновления маркетплейса после продажи } export default function PlayerInventory({ username, serverIp, onSellSuccess, }: PlayerInventoryProps) { const [loading, setLoading] = useState(false); const [inventoryItems, setInventoryItems] = useState( [], ); const [error, setError] = useState(null); const [sellDialogOpen, setSellDialogOpen] = useState(false); const [selectedItem, setSelectedItem] = useState( null, ); const [price, setPrice] = useState(0); const [amount, setAmount] = useState(1); const [sellLoading, setSellLoading] = useState(false); const [sellError, setSellError] = useState(null); // Функция для запроса инвентаря игрока const fetchPlayerInventory = async () => { try { setLoading(true); setError(null); // Сначала делаем запрос на получение идентификатора запроса инвентаря const inventoryRequest = await RequestPlayerInventory(serverIp, username); const requestId = inventoryRequest.request_id; // Затем начинаем опрашивать API для получения результата let inventoryData = null; let attempts = 0; const maxAttempts = 10; // Максимальное количество попыток while (!inventoryData && attempts < maxAttempts) { attempts++; try { // Пауза перед следующим запросом await new Promise((resolve) => setTimeout(resolve, 1000)); // Запрашиваем состояние инвентаря const response = await getPlayerInventory(requestId); // Если инвентарь загружен, сохраняем его if (response.status === 'completed') { inventoryData = response.result.inventory_data; break; } } catch (e) { console.log('Ожидание завершения запроса инвентаря...'); } } if (inventoryData) { setInventoryItems(inventoryData); } else { setError('Не удалось получить инвентарь. Попробуйте еще раз.'); } } catch (e) { console.error('Ошибка при получении инвентаря:', e); setError('Произошла ошибка при загрузке инвентаря.'); } finally { setLoading(false); } }; // Открываем диалог для продажи предмета const handleOpenSellDialog = (item: PlayerInventoryItem) => { setSelectedItem(item); setAmount(1); setPrice(0); setSellError(null); setSellDialogOpen(true); }; // Закрываем диалог const handleCloseSellDialog = () => { setSellDialogOpen(false); setSelectedItem(null); }; // Выставляем предмет на продажу const handleSellItem = async () => { if (!selectedItem) return; try { setSellLoading(true); setSellError(null); // Проверяем валидность введенных данных if (price <= 0) { setSellError('Цена должна быть больше 0'); return; } if (amount <= 0 || amount > selectedItem.amount) { setSellError(`Количество должно быть от 1 до ${selectedItem.amount}`); return; } // Отправляем запрос на продажу const result = await sellItem( username, selectedItem.slot, amount, price, serverIp, ); // Проверяем статус операции if (result.status === 'pending') { // Закрываем диалог и обновляем инвентарь handleCloseSellDialog(); // Показываем уведомление о том, что операция обрабатывается // setNotification({ // Assuming setNotification is available in the context // open: true, // message: 'Предмет выставляется на продажу. Это может занять некоторое время.', // type: 'info' // }); // Через 5 секунд обновляем инвентарь setTimeout(() => { fetchPlayerInventory(); // Вызываем callback для обновления маркетплейса if (onSellSuccess) { onSellSuccess(); } }, 5000); } } catch (e) { console.error('Ошибка при продаже предмета:', e); setSellError('Произошла ошибка при продаже предмета.'); } finally { setSellLoading(false); } }; // Загружаем инвентарь при монтировании компонента useEffect(() => { fetchPlayerInventory(); }, [username, serverIp]); // Получаем отображаемое имя предмета const getItemDisplayName = (material: string) => { return material .replace(/_/g, ' ') .toLowerCase() .replace(/\b\w/g, (l) => l.toUpperCase()); }; return ( Ваш инвентарь {error && ( {error} )} {loading ? ( ) : ( <> {inventoryItems.length === 0 ? ( Ваш инвентарь пуст или не удалось загрузить предметы. ) : ( {inventoryItems.map((item) => item.material !== 'AIR' && item.amount > 0 ? ( handleOpenSellDialog(item)} > {getItemDisplayName(item.material)} {item.amount > 1 ? `x${item.amount}` : ''} {Object.keys(item.enchants || {}).length > 0 && ( Зачарования: {Object.keys(item.enchants).length} )} ) : null, )} )} )} {/* Диалог для продажи предмета */} Продать предмет {selectedItem && ( {getItemDisplayName(selectedItem.material)} Всего доступно: {selectedItem.amount} setAmount( Math.min( parseInt(e.target.value) || 0, selectedItem.amount, ), ) } inputProps={{ min: 1, max: selectedItem.amount }} /> setPrice(parseInt(e.target.value) || 0)} inputProps={{ min: 1 }} /> {sellError && ( {sellError} )} )} ); }