113 lines
2.9 KiB
TypeScript
113 lines
2.9 KiB
TypeScript
'use client';
|
||
|
||
import React from 'react';
|
||
import {
|
||
Box,
|
||
Grid,
|
||
Text,
|
||
Button,
|
||
Image,
|
||
VStack,
|
||
useToast,
|
||
useColorModeValue,
|
||
} from '@chakra-ui/react';
|
||
import { InventoryItem } from '../types/user';
|
||
|
||
interface ShopItem extends InventoryItem {
|
||
price: number;
|
||
}
|
||
|
||
interface ShopProps {
|
||
items: ShopItem[];
|
||
userBalance: number;
|
||
onPurchase: (itemId: string) => Promise<void>;
|
||
}
|
||
|
||
export const Shop: React.FC<ShopProps> = ({ items, userBalance, onPurchase }) => {
|
||
const toast = useToast();
|
||
const bgColor = useColorModeValue('white', 'gray.800');
|
||
const borderColor = useColorModeValue('gray.200', 'gray.700');
|
||
|
||
const handlePurchase = async (item: ShopItem) => {
|
||
if (userBalance < item.price) {
|
||
toast({
|
||
title: 'Недостаточно средств',
|
||
description: 'У вас недостаточно Campfire монет для покупки этого предмета',
|
||
status: 'error',
|
||
duration: 3000,
|
||
isClosable: true,
|
||
});
|
||
return;
|
||
}
|
||
|
||
try {
|
||
await onPurchase(item.id);
|
||
toast({
|
||
title: 'Покупка успешна!',
|
||
description: `Вы приобрели ${item.name}`,
|
||
status: 'success',
|
||
duration: 3000,
|
||
isClosable: true,
|
||
});
|
||
} catch (error) {
|
||
toast({
|
||
title: 'Ошибка при покупке',
|
||
description: 'Произошла ошибка при совершении покупки',
|
||
status: 'error',
|
||
duration: 3000,
|
||
isClosable: true,
|
||
});
|
||
}
|
||
};
|
||
|
||
return (
|
||
<Box p={4}>
|
||
<Text fontSize="2xl" fontWeight="bold" mb={4}>
|
||
Магазин
|
||
</Text>
|
||
<Text mb={4}>
|
||
Ваш баланс: {userBalance} 🔥
|
||
</Text>
|
||
|
||
<Grid templateColumns={['1fr', 'repeat(2, 1fr)', 'repeat(3, 1fr)']} gap={4}>
|
||
{items.map((item) => (
|
||
<Box
|
||
key={item.id}
|
||
p={4}
|
||
borderWidth="1px"
|
||
borderRadius="lg"
|
||
borderColor={borderColor}
|
||
bg={bgColor}
|
||
>
|
||
<VStack spacing={3}>
|
||
{item.imageUrl && (
|
||
<Image
|
||
src={item.imageUrl}
|
||
alt={item.name}
|
||
boxSize="100px"
|
||
objectFit="cover"
|
||
borderRadius="md"
|
||
/>
|
||
)}
|
||
<Text fontWeight="bold">{item.name}</Text>
|
||
<Text fontSize="sm" color="gray.500">
|
||
{item.description}
|
||
</Text>
|
||
<Text color="green.500" fontWeight="bold">
|
||
{item.price} 🔥
|
||
</Text>
|
||
<Button
|
||
colorScheme="blue"
|
||
width="full"
|
||
onClick={() => handlePurchase(item)}
|
||
isDisabled={userBalance < item.price}
|
||
>
|
||
Купить
|
||
</Button>
|
||
</VStack>
|
||
</Box>
|
||
))}
|
||
</Grid>
|
||
</Box>
|
||
);
|
||
};
|