Massive fixes
This commit is contained in:
parent
0e304a8b2e
commit
33248392ff
@ -1,15 +1,29 @@
|
||||
'use client';
|
||||
|
||||
import dynamic from 'next/dynamic';
|
||||
import React, { useState, useEffect } from 'react';
|
||||
import { Box, VStack, Spinner, Center, useToast } from '@chakra-ui/react';
|
||||
import UserProfile from './UserProfile';
|
||||
import Shop from './Shop';
|
||||
import TransferBalance from './TransferBalance';
|
||||
import { auth, getProfile, getShopItems, purchaseItem, transferBalance } from '../utils/api';
|
||||
import { IUser } from '../../backend/models/User';
|
||||
import { IShopItem } from '../../backend/models/ShopItem';
|
||||
import { useTelegramWebApp } from '../hooks/useTelegramWebApp';
|
||||
|
||||
// Динамический импорт компонентов для клиентской стороны
|
||||
const UserProfile = dynamic(() => import('./UserProfile'), {
|
||||
loading: () => <Spinner />,
|
||||
ssr: false
|
||||
});
|
||||
|
||||
const Shop = dynamic(() => import('./Shop'), {
|
||||
loading: () => <Spinner />,
|
||||
ssr: false
|
||||
});
|
||||
|
||||
const TransferBalance = dynamic(() => import('./TransferBalance'), {
|
||||
loading: () => <Spinner />,
|
||||
ssr: false
|
||||
});
|
||||
|
||||
type SafeUser = Omit<IUser, keyof Document>;
|
||||
|
||||
export default function MainApp() {
|
||||
|
@ -2,73 +2,72 @@
|
||||
|
||||
import { useEffect, useState } from 'react';
|
||||
import { isDemoMode, getDemoWebApp } from '../utils/demo';
|
||||
import type { WebApp } from '@twa-dev/types';
|
||||
|
||||
export type WebApp = {
|
||||
initData: string;
|
||||
initDataUnsafe: {
|
||||
query_id: string;
|
||||
user: {
|
||||
id: string;
|
||||
first_name: string;
|
||||
username?: string;
|
||||
language_code: string;
|
||||
};
|
||||
auth_date: number;
|
||||
hash: string;
|
||||
};
|
||||
platform: string;
|
||||
colorScheme: string;
|
||||
themeParams: {
|
||||
bg_color: string;
|
||||
text_color: string;
|
||||
hint_color: string;
|
||||
link_color: string;
|
||||
button_color: string;
|
||||
button_text_color: string;
|
||||
};
|
||||
isExpanded: boolean;
|
||||
viewportHeight: number;
|
||||
viewportStableHeight: number;
|
||||
headerColor: string;
|
||||
backgroundColor: string;
|
||||
ready: () => void;
|
||||
expand: () => void;
|
||||
close: () => void;
|
||||
};
|
||||
type SafeWebApp = Partial<Pick<WebApp,
|
||||
| 'initData'
|
||||
| 'initDataUnsafe'
|
||||
| 'platform'
|
||||
| 'colorScheme'
|
||||
| 'themeParams'
|
||||
| 'isExpanded'
|
||||
| 'viewportHeight'
|
||||
| 'viewportStableHeight'
|
||||
| 'headerColor'
|
||||
| 'backgroundColor'
|
||||
| 'isClosingConfirmationEnabled'
|
||||
| 'BackButton'
|
||||
| 'MainButton'
|
||||
| 'ready'
|
||||
| 'expand'
|
||||
| 'close'
|
||||
>>;
|
||||
|
||||
export function useTelegramWebApp() {
|
||||
const [webApp, setWebApp] = useState<WebApp | null>(null);
|
||||
const [webApp, setWebApp] = useState<SafeWebApp | null>(null);
|
||||
const [error, setError] = useState<string | null>(null);
|
||||
const [isInitialized, setIsInitialized] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
let isMounted = true;
|
||||
|
||||
const initWebApp = async () => {
|
||||
try {
|
||||
if (isDemoMode()) {
|
||||
const demoWebApp = getDemoWebApp();
|
||||
setWebApp(demoWebApp);
|
||||
setIsInitialized(true);
|
||||
if (isMounted) {
|
||||
const demoWebApp = getDemoWebApp();
|
||||
setWebApp(demoWebApp);
|
||||
setIsInitialized(true);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (typeof window !== 'undefined') {
|
||||
const WebAppModule = await import('@twa-dev/sdk');
|
||||
if (WebAppModule.default) {
|
||||
setWebApp(WebAppModule.default);
|
||||
setIsInitialized(true);
|
||||
} else {
|
||||
throw new Error('WebApp не найден');
|
||||
if (isMounted) {
|
||||
if (WebAppModule.default) {
|
||||
setWebApp(WebAppModule.default as SafeWebApp);
|
||||
setIsInitialized(true);
|
||||
} else {
|
||||
throw new Error('WebApp не найден');
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('WebApp initialization error:', err);
|
||||
setError('Ошибка инициализации Telegram Web App');
|
||||
if (isMounted) {
|
||||
setError('Ошибка инициализации Telegram Web App');
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
if (!isInitialized) {
|
||||
initWebApp();
|
||||
}
|
||||
|
||||
return () => {
|
||||
isMounted = false;
|
||||
};
|
||||
}, [isInitialized]);
|
||||
|
||||
return { webApp, error, isInitialized };
|
||||
|
@ -1,28 +1,54 @@
|
||||
'use client';
|
||||
|
||||
import type { WebApp, WebAppUser, WebAppInitData, Platforms } from '@twa-dev/types';
|
||||
|
||||
// Демо данные для тестирования без Telegram
|
||||
const demoUser = {
|
||||
id: 'demo_user_123',
|
||||
const demoUser: WebAppUser = {
|
||||
id: 12345,
|
||||
first_name: 'Demo',
|
||||
username: 'demo_user',
|
||||
language_code: 'ru'
|
||||
language_code: 'ru',
|
||||
is_premium: false
|
||||
};
|
||||
|
||||
const demoInitData = {
|
||||
const demoInitData: WebAppInitData = {
|
||||
query_id: 'demo_query',
|
||||
user: demoUser,
|
||||
auth_date: Date.now(),
|
||||
hash: 'demo_hash'
|
||||
hash: 'demo_hash',
|
||||
start_param: ''
|
||||
};
|
||||
|
||||
export const isDemoMode = () => {
|
||||
return typeof window !== 'undefined' && new URLSearchParams(window.location.search).has('demo');
|
||||
};
|
||||
|
||||
export const getDemoWebApp = () => ({
|
||||
// Создаем заглушки для методов WebApp
|
||||
const createNoopFunction = () => () => {};
|
||||
|
||||
type SafeWebApp = Pick<WebApp,
|
||||
| 'initData'
|
||||
| 'initDataUnsafe'
|
||||
| 'platform'
|
||||
| 'colorScheme'
|
||||
| 'themeParams'
|
||||
| 'isExpanded'
|
||||
| 'viewportHeight'
|
||||
| 'viewportStableHeight'
|
||||
| 'headerColor'
|
||||
| 'backgroundColor'
|
||||
| 'isClosingConfirmationEnabled'
|
||||
| 'BackButton'
|
||||
| 'MainButton'
|
||||
| 'ready'
|
||||
| 'expand'
|
||||
| 'close'
|
||||
>;
|
||||
|
||||
export const getDemoWebApp = (): SafeWebApp => ({
|
||||
initData: 'demo_mode',
|
||||
initDataUnsafe: demoInitData,
|
||||
platform: 'demo',
|
||||
platform: 'WEBVIEW' as Platforms,
|
||||
colorScheme: 'light',
|
||||
themeParams: {
|
||||
bg_color: '#ffffff',
|
||||
@ -30,7 +56,8 @@ export const getDemoWebApp = () => ({
|
||||
hint_color: '#999999',
|
||||
link_color: '#2481cc',
|
||||
button_color: '#2481cc',
|
||||
button_text_color: '#ffffff'
|
||||
button_text_color: '#ffffff',
|
||||
secondary_bg_color: '#f0f0f0'
|
||||
},
|
||||
isExpanded: true,
|
||||
viewportHeight: typeof window !== 'undefined' ? window.innerHeight : 800,
|
||||
@ -40,7 +67,10 @@ export const getDemoWebApp = () => ({
|
||||
isClosingConfirmationEnabled: true,
|
||||
BackButton: {
|
||||
isVisible: false,
|
||||
onClick: () => {},
|
||||
onClick: createNoopFunction(),
|
||||
offClick: createNoopFunction(),
|
||||
show: createNoopFunction(),
|
||||
hide: createNoopFunction()
|
||||
},
|
||||
MainButton: {
|
||||
text: '',
|
||||
@ -49,16 +79,18 @@ export const getDemoWebApp = () => ({
|
||||
isVisible: false,
|
||||
isProgressVisible: false,
|
||||
isActive: true,
|
||||
setText: () => {},
|
||||
onClick: () => {},
|
||||
show: () => {},
|
||||
hide: () => {},
|
||||
enable: () => {},
|
||||
disable: () => {},
|
||||
showProgress: () => {},
|
||||
hideProgress: () => {},
|
||||
setText: createNoopFunction(),
|
||||
onClick: createNoopFunction(),
|
||||
offClick: createNoopFunction(),
|
||||
show: createNoopFunction(),
|
||||
hide: createNoopFunction(),
|
||||
enable: createNoopFunction(),
|
||||
disable: createNoopFunction(),
|
||||
showProgress: createNoopFunction(),
|
||||
hideProgress: createNoopFunction(),
|
||||
setParams: createNoopFunction()
|
||||
},
|
||||
ready: () => {},
|
||||
expand: () => {},
|
||||
close: () => {},
|
||||
ready: createNoopFunction(),
|
||||
expand: createNoopFunction(),
|
||||
close: createNoopFunction(),
|
||||
});
|
Loading…
Reference in New Issue
Block a user