axyenniu daily reward page

This commit is contained in:
aurinex
2025-12-13 16:18:47 +05:00
parent 226f5c1393
commit 712ae70e2a
13 changed files with 835 additions and 49 deletions

View File

@ -25,8 +25,12 @@ import CapeCard from '../components/CapeCard';
import { FullScreenLoader } from '../components/FullScreenLoader';
import { OnlinePlayersPanel } from '../components/OnlinePlayersPanel';
import DailyRewards from '../components/Profile/DailyRewards';
import CustomNotification from '../components/Notifications/CustomNotification';
import type { NotificationPosition } from '../components/Notifications/CustomNotification';
import { useNavigate } from 'react-router-dom';
export default function Profile() {
const navigate = useNavigate();
const fileInputRef = useRef<HTMLInputElement>(null);
const [walkingSpeed, setWalkingSpeed] = useState<number>(0.5);
const [skin, setSkin] = useState<string>('');
@ -46,6 +50,22 @@ export default function Profile() {
const [viewerWidth, setViewerWidth] = useState(500);
const [viewerHeight, setViewerHeight] = useState(600);
// notification
const [notifOpen, setNotifOpen] = useState(false);
const [notifMsg, setNotifMsg] = useState<React.ReactNode>('');
const [notifSeverity, setNotifSeverity] = useState<
'success' | 'info' | 'warning' | 'error'
>('success');
const [notifPos, setNotifPos] = useState<NotificationPosition>({
vertical: 'top',
horizontal: 'right',
});
const navigateDaily = () => {
navigate('/daily');
};
useEffect(() => {
const savedConfig = localStorage.getItem('launcher_config');
if (savedConfig) {
@ -154,8 +174,16 @@ export default function Profile() {
const handleUploadSkin = async () => {
setLoading(true);
if (!skinFile || !username) {
setStatusMessage('Необходимо выбрать файл и указать имя пользователя');
const msg = 'Необходимо выбрать файл и указать имя пользователя';
setStatusMessage(msg);
setUploadStatus('error');
// notification
setNotifMsg(msg);
setNotifSeverity('error');
setNotifOpen(true);
setLoading(false);
return;
}
@ -163,10 +191,15 @@ export default function Profile() {
try {
await uploadSkin(username, skinFile, skinModel);
setStatusMessage('Скин успешно загружен!');
setUploadStatus('success');
// notification
setNotifMsg('Скин успешно загружен!');
setNotifSeverity('success');
setNotifPos({ vertical: 'bottom', horizontal: 'left' });
setNotifOpen(true);
// Обновляем информацию о игроке, чтобы увидеть новый скин
const config = JSON.parse(
localStorage.getItem('launcher_config') || '{}',
@ -175,10 +208,18 @@ export default function Profile() {
loadPlayerData(config.uuid);
}
} catch (error) {
setStatusMessage(
`Ошибка: ${error instanceof Error ? error.message : 'Не удалось загрузить скин'}`,
);
const msg = `Ошибка: ${
error instanceof Error ? error.message : 'Не удалось загрузить скин'
}`;
setStatusMessage(msg);
setUploadStatus('error');
// notification
setNotifMsg(msg);
setNotifSeverity('error');
setNotifPos({ vertical: 'bottom', horizontal: 'left' });
setNotifOpen(true);
} finally {
setLoading(false);
}
@ -187,16 +228,25 @@ export default function Profile() {
return (
<Box
sx={{
my: 4,
display: 'flex',
flexDirection: 'row',
alignItems: 'center',
gap: '100px',
mt: '10vh',
display: 'grid',
gridTemplateColumns: 'minmax(0, 1fr) minmax(0, 1fr)',
gap: '3vw',
width: '100%',
height: '100%',
justifyContent: 'center',
alignItems: 'start',
overflowY: 'auto',
}}
>
<CustomNotification
open={notifOpen}
message={notifMsg}
severity={notifSeverity}
position={notifPos}
onClose={() => setNotifOpen(false)}
autoHideDuration={2500}
/>
{loading ? (
<FullScreenLoader message="Загрузка вашего профиля" />
) : (
@ -208,6 +258,9 @@ export default function Profile() {
borderRadius: 2,
overflow: 'hidden',
bgcolor: 'transparent',
display: 'flex',
flexDirection: 'column',
alignItems: 'center',
}}
>
{/* Используем переработанный компонент SkinViewer */}
@ -243,16 +296,20 @@ export default function Profile() {
display: 'flex',
flexDirection: 'column',
gap: '1vw',
width: '100%',
maxWidth: '44vw',
justifySelf: 'start'
}}
>
<Box
sx={{
width: '40vw',
maxWidth: '40vw',
width: '100%',
bgcolor: 'rgba(255, 255, 255, 0.05)',
padding: '3vw',
borderRadius: '1vw',
flexShrink: 0,
boxSizing: 'border-box',
minWidth: 0,
}}
>
<Box
@ -379,19 +436,6 @@ export default function Profile() {
<MenuItem value="classic">Классическая (Steve)</MenuItem>
</Select>
</FormControl>
{uploadStatus === 'error' && (
<Alert severity="error" sx={{ mb: 2 }}>
{statusMessage}
</Alert>
)}
{uploadStatus === 'success' && (
<Alert severity="success" sx={{ mb: 2 }}>
{statusMessage}
</Alert>
)}
<Button
sx={{
color: 'white',
@ -453,7 +497,22 @@ export default function Profile() {
</Box>
</Box>
<OnlinePlayersPanel currentUsername={username} />
<DailyRewards />
<Button
variant="contained"
fullWidth
onClick={navigateDaily}
sx={{
mt: 1,
transition: 'transform 0.3s ease',
background:
'linear-gradient(71deg, #F27121 0%, #E940CD 70%, #8A2387 100%)',
fontFamily: 'Benzin-Bold',
borderRadius: '2.5vw',
'&:hover': { transform: 'scale(1.03)' },
}}
>
Ежедневные награды
</Button>
</Box>
</>
)}