Files
popa-launcher/src/renderer/pages/PromoRedeem.tsx
2025-12-20 20:49:49 +05:00

171 lines
4.8 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { Box, Button, Typography } from '@mui/material';
import { useEffect, useState } from 'react';
import GradientTextField from '../components/GradientTextField';
import CustomNotification from '../components/Notifications/CustomNotification';
import type { NotificationPosition } from '../components/Notifications/CustomNotification';
import {
isNotificationsEnabled,
getNotifPositionFromSettings,
} from '../utils/notifications';
import { redeemPromoCode } from '../api/promocodes';
import { useNavigate } from 'react-router-dom';
export const PromoRedeem = () => {
const navigate = useNavigate();
const [username, setUsername] = useState<string>(''); // будет автозаполнение
const [code, setCode] = useState('');
const [loading, setLoading] = useState(false);
const [notifOpen, setNotifOpen] = useState(false);
const [notifMsg, setNotifMsg] = useState<React.ReactNode>('');
const [notifSeverity, setNotifSeverity] = useState<
'success' | 'info' | 'warning' | 'error'
>('info');
const [notifPos, setNotifPos] = useState<NotificationPosition>({
vertical: 'bottom',
horizontal: 'center',
});
const showNotification = (
message: React.ReactNode,
severity: 'success' | 'info' | 'warning' | 'error' = 'info',
position: NotificationPosition = getNotifPositionFromSettings(),
) => {
if (!isNotificationsEnabled()) return;
setNotifMsg(message);
setNotifSeverity(severity);
setNotifPos(position);
setNotifOpen(true);
};
// как в Profile.tsx: читаем launcher_config
useEffect(() => {
try {
const savedConfig = localStorage.getItem('launcher_config');
if (savedConfig) {
const config = JSON.parse(savedConfig);
setUsername(config.username || '');
}
} catch {
setUsername('');
}
}, []);
const handleRedeem = async () => {
if (!username) {
showNotification(
'Не удалось определить никнейм. Войдите в аккаунт заново.',
'warning',
);
// по желанию можно отправить в login/profile:
// navigate('/login', { replace: true });
return;
}
if (!code) {
showNotification('Введите промокод', 'warning');
return;
}
setLoading(true);
try {
const res = await redeemPromoCode(username, code);
showNotification(
<>
Промокод <b>{res.code}</b> успешно активирован!
</>,
'success',
);
setCode('');
} catch (e: any) {
showNotification(e?.message || 'Ошибка активации промокода', 'error');
} finally {
setLoading(false);
}
};
return (
<>
<Box
sx={{
height: 'calc(100vh - 8vh)',
pt: '8vh',
display: 'flex',
flexDirection: 'column',
alignItems: 'center',
justifyContent: 'center',
px: 2,
}}
>
<Typography
variant="h4"
sx={{
textAlign: 'center',
fontFamily: 'Benzin-Bold',
backgroundImage:
'linear-gradient( 136deg, rgb(242,113,33) 0%, rgb(233,64,87) 50%, rgb(138,35,135) 100%)',
WebkitBackgroundClip: 'text',
WebkitTextFillColor: 'transparent',
mb: 2,
}}
>
Активация промокода
</Typography>
<Box
sx={{
display: 'flex',
flexDirection: 'column',
alignItems: 'center',
width: '50vw',
}}
>
<GradientTextField
label=""
required
name="code"
value={code}
onChange={(e) => setCode(e.target.value.toUpperCase())}
/>
<Button
variant="contained"
color="primary"
disabled={loading}
sx={{
transition: 'transform 0.3s ease',
width: '100%',
mt: 2,
background:
'linear-gradient(71deg, #F27121 0%, #E940CD 70%, #8A2387 100%)',
fontFamily: 'Benzin-Bold',
borderRadius: '2.5vw',
fontSize: '2vw',
'&:hover': {
transform: loading ? 'none' : 'scale(1.1)',
},
}}
onClick={handleRedeem}
>
{loading ? 'Активируем...' : 'Активировать'}
</Button>
</Box>
<CustomNotification
open={notifOpen}
message={notifMsg}
severity={notifSeverity}
position={notifPos}
onClose={() => setNotifOpen(false)}
autoHideDuration={2500}
/>
</Box>
</>
);
};