131 lines
3.5 KiB
TypeScript
131 lines
3.5 KiB
TypeScript
'use client';
|
||
|
||
import React, { useState } from 'react';
|
||
import {
|
||
Box,
|
||
Button,
|
||
FormControl,
|
||
FormLabel,
|
||
Input,
|
||
VStack,
|
||
useToast,
|
||
NumberInput,
|
||
NumberInputField,
|
||
NumberInputStepper,
|
||
NumberIncrementStepper,
|
||
NumberDecrementStepper,
|
||
useColorModeValue,
|
||
} from '@chakra-ui/react';
|
||
|
||
interface TransferBalanceProps {
|
||
userBalance: number;
|
||
onTransfer: (recipientUsername: string, amount: number) => Promise<void>;
|
||
}
|
||
|
||
export const TransferBalance: React.FC<TransferBalanceProps> = ({
|
||
userBalance,
|
||
onTransfer,
|
||
}) => {
|
||
const [recipientUsername, setRecipientUsername] = useState('');
|
||
const [amount, setAmount] = useState<number>(0);
|
||
const [isLoading, setIsLoading] = useState(false);
|
||
const toast = useToast();
|
||
|
||
const bgColor = useColorModeValue('white', 'gray.800');
|
||
const borderColor = useColorModeValue('gray.200', 'gray.700');
|
||
|
||
const handleTransfer = async () => {
|
||
if (!recipientUsername || amount <= 0) {
|
||
toast({
|
||
title: 'Ошибка валидации',
|
||
description: 'Пожалуйста, заполните все поля корректно',
|
||
status: 'error',
|
||
duration: 3000,
|
||
isClosable: true,
|
||
});
|
||
return;
|
||
}
|
||
|
||
if (amount > userBalance) {
|
||
toast({
|
||
title: 'Недостаточно средств',
|
||
description: 'У вас недостаточно Campfire монет для перевода',
|
||
status: 'error',
|
||
duration: 3000,
|
||
isClosable: true,
|
||
});
|
||
return;
|
||
}
|
||
|
||
setIsLoading(true);
|
||
try {
|
||
await onTransfer(recipientUsername, amount);
|
||
toast({
|
||
title: 'Перевод успешен!',
|
||
description: `Вы перевели ${amount} 🔥 пользователю ${recipientUsername}`,
|
||
status: 'success',
|
||
duration: 3000,
|
||
isClosable: true,
|
||
});
|
||
setRecipientUsername('');
|
||
setAmount(0);
|
||
} catch (error) {
|
||
toast({
|
||
title: 'Ошибка перевода',
|
||
description: 'Не удалось выполнить перевод. Проверьте имя пользователя и попробуйте снова',
|
||
status: 'error',
|
||
duration: 3000,
|
||
isClosable: true,
|
||
});
|
||
} finally {
|
||
setIsLoading(false);
|
||
}
|
||
};
|
||
|
||
return (
|
||
<Box
|
||
p={6}
|
||
bg={bgColor}
|
||
borderRadius="lg"
|
||
borderWidth="1px"
|
||
borderColor={borderColor}
|
||
>
|
||
<VStack spacing={4}>
|
||
<FormControl isRequired>
|
||
<FormLabel>Имя получателя</FormLabel>
|
||
<Input
|
||
value={recipientUsername}
|
||
onChange={(e) => setRecipientUsername(e.target.value)}
|
||
placeholder="Введите имя пользователя"
|
||
/>
|
||
</FormControl>
|
||
|
||
<FormControl isRequired>
|
||
<FormLabel>Сумма перевода</FormLabel>
|
||
<NumberInput
|
||
value={amount}
|
||
onChange={(_, value) => setAmount(value)}
|
||
min={1}
|
||
max={userBalance}
|
||
>
|
||
<NumberInputField />
|
||
<NumberInputStepper>
|
||
<NumberIncrementStepper />
|
||
<NumberDecrementStepper />
|
||
</NumberInputStepper>
|
||
</NumberInput>
|
||
</FormControl>
|
||
|
||
<Button
|
||
colorScheme="blue"
|
||
width="full"
|
||
onClick={handleTransfer}
|
||
isLoading={isLoading}
|
||
isDisabled={!recipientUsername || amount <= 0 || amount > userBalance}
|
||
>
|
||
Перевести {amount} 🔥
|
||
</Button>
|
||
</VStack>
|
||
</Box>
|
||
);
|
||
};
|