153 lines
6.4 KiB
TypeScript
153 lines
6.4 KiB
TypeScript
import React, { useState, useEffect } from 'react';
|
||
import { Link, useNavigate } from 'react-router-dom';
|
||
import { getUserInfo, isTelegramWebAppAvailable, getCurrentUserId } from '../../constants/user';
|
||
import { images } from '../../assets';
|
||
import apiService from '../../services/api';
|
||
import TokenPacksModal from '../tokens/TokenPacksModal';
|
||
import { paymentService } from '../../services/paymentService';
|
||
import { tokenPacks } from '../../constants/tokenPacks';
|
||
import NotificationModal from '../shared/NotificationModal';
|
||
import { useBalance } from '../../contexts/BalanceContext';
|
||
import customAnalyticsService from '../../services/customAnalyticsService';
|
||
import styles from './Header.module.css';
|
||
|
||
const Header: React.FC = () => {
|
||
const navigate = useNavigate();
|
||
const { balance, updateBalance } = useBalance(); // Используем контекст баланса
|
||
const [user, setUser] = useState({
|
||
telegramId: 0,
|
||
username: '',
|
||
avatarUrl: ''
|
||
});
|
||
const [showTokensModal, setShowTokensModal] = useState(false);
|
||
const [lastPurchasedPack, setLastPurchasedPack] = useState<any>(null);
|
||
const [showNotificationModal, setShowNotificationModal] = useState(false);
|
||
const [notificationTitle, setNotificationTitle] = useState('');
|
||
const [notificationMessage, setNotificationMessage] = useState('');
|
||
|
||
useEffect(() => {
|
||
// Получаем информацию о пользователе
|
||
const userInfo = getUserInfo();
|
||
|
||
// Если есть данные из Telegram, обновляем состояние
|
||
if (isTelegramWebAppAvailable()) {
|
||
setUser({
|
||
telegramId: userInfo.id,
|
||
username: userInfo.first_name + (userInfo.last_name ? ` ${userInfo.last_name}` : ''),
|
||
avatarUrl: userInfo.photo_url || '/ava.jpg' // Используем фото из Telegram или дефолтное
|
||
});
|
||
} else {
|
||
// Для локальной разработки
|
||
setUser({
|
||
telegramId: 12345678,
|
||
username: "TestUser",
|
||
avatarUrl: "/ava.jpg"
|
||
});
|
||
}
|
||
}, []);
|
||
|
||
return (
|
||
<header className={styles.header}>
|
||
<div className={styles.container}>
|
||
<div className={styles.content}>
|
||
{/* Профиль пользователя */}
|
||
<Link to="/profile" className={styles.profile}>
|
||
<div className={styles.avatar}>
|
||
<img
|
||
src={user.avatarUrl}
|
||
alt="Avatar"
|
||
className={styles.avatarImage}
|
||
onError={(e) => {
|
||
e.currentTarget.onerror = null;
|
||
e.currentTarget.src = 'data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="%23999"><circle cx="12" cy="8" r="4"/><path d="M12 13c-4 0-8 2-8 6v1h16v-1c0-4-4-6-8-6z"/></svg>';
|
||
}}
|
||
/>
|
||
</div>
|
||
<span className={styles.username}>
|
||
{user.username}
|
||
</span>
|
||
</Link>
|
||
|
||
{/* Баланс токенов */}
|
||
<button
|
||
className={styles.balance}
|
||
onClick={() => {
|
||
// Отслеживаем событие нажатия на кнопку баланса
|
||
customAnalyticsService.trackEvent({
|
||
telegram_id: getCurrentUserId(),
|
||
event_category: 'ui_interaction',
|
||
event_name: 'balance_button_click'
|
||
});
|
||
setShowTokensModal(true);
|
||
}}
|
||
title="Нажмите чтобы пополнить баланс"
|
||
>
|
||
<span className={styles.balanceIcon}>
|
||
<img src={images.tokenIcon} alt="Токены" className={styles.tokenImage} />
|
||
</span>
|
||
<span className={styles.balanceValue}>
|
||
{balance}
|
||
</span>
|
||
</button>
|
||
</div>
|
||
</div>
|
||
|
||
{/* Модальное окно с пакетами токенов */}
|
||
<TokenPacksModal
|
||
isVisible={showTokensModal}
|
||
onClose={() => setShowTokensModal(false)}
|
||
onShowAllPacks={() => navigate('/profile')}
|
||
missingTokens={0}
|
||
onBuyPack={(packId) => {
|
||
const pack = tokenPacks.find(p => p.id === packId);
|
||
if (!pack) return;
|
||
|
||
setShowTokensModal(false);
|
||
setLastPurchasedPack(pack);
|
||
|
||
paymentService.showBuyTokensPopup(pack, async (userData) => {
|
||
if (userData) {
|
||
// Обновляем баланс через контекст
|
||
updateBalance();
|
||
|
||
// Показываем модальное окно с информацией об успешной оплате
|
||
setNotificationTitle('Оплата успешна!');
|
||
setNotificationMessage(`Вы успешно приобрели ${pack.tokens + pack.bonusTokens} токенов.`);
|
||
setShowNotificationModal(true);
|
||
} else {
|
||
// Если данные не получены, делаем запрос на получение данных пользователя
|
||
try {
|
||
// Получаем баланс пользователя
|
||
const balance = await apiService.getBalance(getCurrentUserId());
|
||
|
||
// Обновляем баланс через контекст
|
||
updateBalance();
|
||
|
||
// Показываем модальное окно с информацией об успешной оплате
|
||
setNotificationTitle('Оплата успешна!');
|
||
setNotificationMessage(`Вы успешно приобрели ${pack.tokens + pack.bonusTokens} токенов. Ваш текущий баланс: ${balance} токенов.`);
|
||
setShowNotificationModal(true);
|
||
} catch (error) {
|
||
console.error('Ошибка при обновлении данных пользователя:', error);
|
||
}
|
||
}
|
||
});
|
||
}}
|
||
/>
|
||
|
||
{/* Модальное окно уведомления */}
|
||
<NotificationModal
|
||
isVisible={showNotificationModal}
|
||
title={notificationTitle}
|
||
message={notificationMessage}
|
||
onGalleryClick={() => setShowNotificationModal(false)}
|
||
onContinueClick={() => setShowNotificationModal(false)}
|
||
showGalleryButton={false}
|
||
continueButtonText="Закрыть"
|
||
/>
|
||
</header>
|
||
);
|
||
};
|
||
|
||
export default Header;
|