This commit is contained in:
Degradin 2025-03-16 11:43:25 +03:00
commit 5a252f6f29
2 changed files with 23 additions and 12 deletions

View File

@ -1,24 +1,29 @@
'use client'; 'use client';
import React, { useEffect, useState } from 'react'; import React, { useEffect, useState } from 'react';
import { Container, Tabs, TabList, TabPanels, Tab, TabPanel, useToast } from '@chakra-ui/react'; import { Container, Tabs, TabList, TabPanels, Tab, TabPanel, useToast, Spinner, Center } from '@chakra-ui/react';
import { UserProfile } from './UserProfile'; import { UserProfile } from './UserProfile';
import { Shop } from './Shop'; import { Shop } from './Shop';
import { TransferBalance } from './TransferBalance'; import { TransferBalance } from './TransferBalance';
import * as api from '../utils/api'; import * as api from '../utils/api';
import WebApp from '@twa-dev/sdk';
import { IUser } from '../../backend/models/User'; import { IUser } from '../../backend/models/User';
import { IShopItem } from '../../backend/models/ShopItem'; import { IShopItem } from '../../backend/models/ShopItem';
type SafeUser = Omit<IUser, keyof Document>;
export function MainApp() { export function MainApp() {
const [user, setUser] = useState<IUser | null>(null); const [user, setUser] = useState<SafeUser | null>(null);
const [shopItems, setShopItems] = useState<IShopItem[]>([]); const [shopItems, setShopItems] = useState<IShopItem[]>([]);
const [isLoading, setIsLoading] = useState(true);
const toast = useToast(); const toast = useToast();
useEffect(() => { useEffect(() => {
const initApp = async () => { const initApp = async () => {
try { try {
// Получаем данные из Telegram WebApp setIsLoading(true);
// Динамически импортируем SDK только на клиенте
const WebApp = (await import('@twa-dev/sdk')).default;
const initData = WebApp.initData; const initData = WebApp.initData;
if (!initData) { if (!initData) {
throw new Error('Приложение должно быть открыто в Telegram'); throw new Error('Приложение должно быть открыто в Telegram');
@ -42,6 +47,8 @@ export function MainApp() {
duration: 5000, duration: 5000,
isClosable: true, isClosable: true,
}); });
} finally {
setIsLoading(false);
} }
}; };
@ -90,8 +97,16 @@ export function MainApp() {
} }
}; };
if (isLoading) {
return (
<Center h="100vh">
<Spinner size="xl" />
</Center>
);
}
if (!user) { if (!user) {
return null; // или компонент загрузки return null;
} }
return ( return (

View File

@ -11,14 +11,10 @@ import {
useToast, useToast,
useColorModeValue, useColorModeValue,
} from '@chakra-ui/react'; } from '@chakra-ui/react';
import { InventoryItem } from '../types/user'; import { IShopItem } from '../../backend/models/ShopItem';
interface ShopItem extends InventoryItem {
price: number;
}
interface ShopProps { interface ShopProps {
items: ShopItem[]; items: IShopItem[];
userBalance: number; userBalance: number;
onPurchase: (itemId: string) => Promise<void>; onPurchase: (itemId: string) => Promise<void>;
} }
@ -28,7 +24,7 @@ export const Shop: React.FC<ShopProps> = ({ items, userBalance, onPurchase }) =>
const bgColor = useColorModeValue('white', 'gray.800'); const bgColor = useColorModeValue('white', 'gray.800');
const borderColor = useColorModeValue('gray.200', 'gray.700'); const borderColor = useColorModeValue('gray.200', 'gray.700');
const handlePurchase = async (item: ShopItem) => { const handlePurchase = async (item: IShopItem) => {
if (userBalance < item.price) { if (userBalance < item.price) {
toast({ toast({
title: 'Недостаточно средств', title: 'Недостаточно средств',