CampFireID/app/components/Shop.tsx
degradin 2af270e3d8 Global fixes
Добавлен демо-режим:
Можно открыть приложение с параметром ?demo в URL
В демо-режиме эмулируется Telegram WebApp SDK
Добавлена заглушка для демо-пользователя
Исправлены типы и интерфейсы:
Добавлен тип SafeUser для безопасной работы с mongoose документами
Исправлены пропсы компонентов
Обновлены типы для покупок в магазине
Улучшена обработка ошибок:
Добавлены информативные сообщения об ошибках
Реализована корректная обработка сетевых ошибок
Добавлены toast-уведомления с подробной информацией
Улучшен UI:
Добавлены спиннеры загрузки
Улучшен внешний вид карточек товаров
Добавлены информативные сообщения о состоянии
2025-03-16 12:05:42 +03:00

70 lines
1.9 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

'use client';
import React from 'react';
import { Box, SimpleGrid, Button, Text, Image, useToast } from '@chakra-ui/react';
import { IShopItem } from '../../backend/models/ShopItem';
interface ShopProps {
items: IShopItem[];
userBalance: number;
onPurchase: (item: IShopItem) => Promise<void>;
}
export function Shop({ items, userBalance, onPurchase }: ShopProps) {
const toast = useToast();
const handlePurchase = async (item: IShopItem) => {
if (userBalance < item.price) {
toast({
title: 'Недостаточно средств',
description: `Для покупки ${item.name} нужно ${item.price} монет`,
status: 'error',
duration: 3000,
isClosable: true,
});
return;
}
await onPurchase(item);
};
return (
<Box w="100%">
<Text fontSize="2xl" mb={4}>Магазин</Text>
<Text mb={4}>Ваш баланс: {userBalance} монет</Text>
<SimpleGrid columns={[1, 2, 3]} spacing={6}>
{items.map((item) => (
<Box
key={item._id.toString()}
borderWidth="1px"
borderRadius="lg"
overflow="hidden"
p={4}
>
{item.imageUrl && (
<Image
src={item.imageUrl}
alt={item.name}
height="200px"
width="100%"
objectFit="cover"
mb={4}
/>
)}
<Text fontSize="xl" mb={2}>{item.name}</Text>
<Text mb={2}>{item.description}</Text>
<Text mb={4} color="green.500">{item.price} монет</Text>
<Button
colorScheme="blue"
onClick={() => handlePurchase(item)}
isDisabled={userBalance < item.price}
w="100%"
>
Купить
</Button>
</Box>
))}
</SimpleGrid>
</Box>
);
}