add components
Безопасная работа с Telegram Web App SDK Улучшенная обработка ошибок Плавная загрузка с индикаторами Корректная работа в демо-режиме
This commit is contained in:
parent
8c152a47bd
commit
8af9c21cb1
@ -1,6 +1,7 @@
|
|||||||
'use client';
|
'use client';
|
||||||
|
|
||||||
import { useEffect, useState } from 'react';
|
import { useEffect, useState } from 'react';
|
||||||
|
import { Center, Spinner } from '@chakra-ui/react';
|
||||||
|
|
||||||
export default function ClientOnly({ children }: { children: React.ReactNode }) {
|
export default function ClientOnly({ children }: { children: React.ReactNode }) {
|
||||||
const [hasMounted, setHasMounted] = useState(false);
|
const [hasMounted, setHasMounted] = useState(false);
|
||||||
@ -10,7 +11,11 @@ export default function ClientOnly({ children }: { children: React.ReactNode })
|
|||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
if (!hasMounted) {
|
if (!hasMounted) {
|
||||||
return null;
|
return (
|
||||||
|
<Center h="100vh">
|
||||||
|
<Spinner size="xl" />
|
||||||
|
</Center>
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return <>{children}</>;
|
return <>{children}</>;
|
||||||
|
@ -8,8 +8,7 @@ import TransferBalance from './TransferBalance';
|
|||||||
import { auth, getProfile, getShopItems, purchaseItem, transferBalance } from '../utils/api';
|
import { auth, getProfile, getShopItems, purchaseItem, transferBalance } from '../utils/api';
|
||||||
import { IUser } from '../../backend/models/User';
|
import { IUser } from '../../backend/models/User';
|
||||||
import { IShopItem } from '../../backend/models/ShopItem';
|
import { IShopItem } from '../../backend/models/ShopItem';
|
||||||
import { isDemoMode, getDemoWebApp } from '../utils/demo';
|
import { useTelegramWebApp } from '../hooks/useTelegramWebApp';
|
||||||
import WebApp from '@twa-dev/sdk';
|
|
||||||
|
|
||||||
type SafeUser = Omit<IUser, keyof Document>;
|
type SafeUser = Omit<IUser, keyof Document>;
|
||||||
|
|
||||||
@ -18,18 +17,20 @@ export default function MainApp() {
|
|||||||
const [user, setUser] = useState<SafeUser | null>(null);
|
const [user, setUser] = useState<SafeUser | null>(null);
|
||||||
const [shopItems, setShopItems] = useState<IShopItem[]>([]);
|
const [shopItems, setShopItems] = useState<IShopItem[]>([]);
|
||||||
const toast = useToast();
|
const toast = useToast();
|
||||||
|
const { webApp, error: webAppError } = useTelegramWebApp();
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (webApp) {
|
||||||
|
initApp();
|
||||||
|
}
|
||||||
|
}, [webApp]);
|
||||||
|
|
||||||
const initApp = async () => {
|
const initApp = async () => {
|
||||||
try {
|
try {
|
||||||
setIsLoading(true);
|
setIsLoading(true);
|
||||||
|
|
||||||
let webApp;
|
if (!webApp) {
|
||||||
if (isDemoMode()) {
|
throw new Error('Telegram Web App не инициализирован');
|
||||||
webApp = getDemoWebApp();
|
|
||||||
} else if (typeof window !== 'undefined') {
|
|
||||||
webApp = WebApp;
|
|
||||||
} else {
|
|
||||||
throw new Error('Приложение должно быть открыто в браузере');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Авторизация пользователя
|
// Авторизация пользователя
|
||||||
@ -58,11 +59,17 @@ export default function MainApp() {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
if (webAppError) {
|
||||||
initApp();
|
return (
|
||||||
}, []);
|
<Center h="100vh">
|
||||||
|
<Box p={4} textAlign="center" color="red.500">
|
||||||
|
{webAppError}
|
||||||
|
</Box>
|
||||||
|
</Center>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
if (isLoading) {
|
if (isLoading || !webApp) {
|
||||||
return (
|
return (
|
||||||
<Center h="100vh">
|
<Center h="100vh">
|
||||||
<Spinner size="xl" />
|
<Spinner size="xl" />
|
||||||
|
29
app/hooks/useTelegramWebApp.ts
Normal file
29
app/hooks/useTelegramWebApp.ts
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
'use client';
|
||||||
|
|
||||||
|
import { useEffect, useState } from 'react';
|
||||||
|
import { isDemoMode, getDemoWebApp } from '../utils/demo';
|
||||||
|
|
||||||
|
export function useTelegramWebApp() {
|
||||||
|
const [webApp, setWebApp] = useState<any>(null);
|
||||||
|
const [error, setError] = useState<string | null>(null);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const initWebApp = async () => {
|
||||||
|
try {
|
||||||
|
if (isDemoMode()) {
|
||||||
|
setWebApp(getDemoWebApp());
|
||||||
|
} else if (typeof window !== 'undefined') {
|
||||||
|
const WebAppModule = await import('@twa-dev/sdk');
|
||||||
|
setWebApp(WebAppModule.default);
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
setError('Ошибка инициализации Telegram Web App');
|
||||||
|
console.error('WebApp initialization error:', err);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
initWebApp();
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
return { webApp, error };
|
||||||
|
}
|
@ -1,8 +1,14 @@
|
|||||||
import dynamic from 'next/dynamic';
|
import dynamic from 'next/dynamic';
|
||||||
|
import { Center, Spinner } from '@chakra-ui/react';
|
||||||
import ClientOnly from './components/ClientOnly';
|
import ClientOnly from './components/ClientOnly';
|
||||||
|
|
||||||
const MainApp = dynamic(() => import('./components/MainApp'), {
|
const MainApp = dynamic(() => import('./components/MainApp'), {
|
||||||
ssr: false,
|
ssr: false,
|
||||||
|
loading: () => (
|
||||||
|
<Center h="100vh">
|
||||||
|
<Spinner size="xl" />
|
||||||
|
</Center>
|
||||||
|
),
|
||||||
});
|
});
|
||||||
|
|
||||||
export default function Home() {
|
export default function Home() {
|
||||||
|
Loading…
Reference in New Issue
Block a user