stylize Notifier update

This commit is contained in:
2025-12-28 14:32:39 +05:00
parent a4a10c164e
commit 4efa8c4437

View File

@ -1,12 +1,77 @@
import { Alert, Box, Snackbar, Button } from '@mui/material'; import {
Alert,
Box,
Snackbar,
Button,
Stack,
Typography,
Paper,
} from '@mui/material';
import { useEffect, useState } from 'react'; import { useEffect, useState } from 'react';
import { styled, alpha, keyframes } from '@mui/material/styles';
export const GRADIENT =
'linear-gradient(71deg, #F27121 0%, #E940CD 70%, #8A2387 100%)';
const glowPulse = keyframes`
0% { opacity: .6 }
50% { opacity: 1 }
100% { opacity: .6 }
`;
export const GlassCard = styled(Paper)(() => ({
position: 'relative',
overflow: 'hidden',
borderRadius: 18,
background: 'rgba(0,0,0,0.45)',
border: '1px solid rgba(255,255,255,0.12)',
backdropFilter: 'blur(14px)',
boxShadow: '0 16px 40px rgba(0,0,0,0.45)',
}));
export const Glow = styled('div')(() => ({
position: 'absolute',
inset: -2,
background:
'radial-gradient(400px 120px at 10% 0%, rgba(242,113,33,0.25), transparent 60%),' +
'radial-gradient(400px 120px at 90% 0%, rgba(233,64,205,0.25), transparent 60%)',
pointerEvents: 'none',
animation: `${glowPulse} 5s ease-in-out infinite`,
}));
export const GradientButton = styled(Button)(() => ({
background: GRADIENT,
borderRadius: 999,
textTransform: 'none',
fontWeight: 700,
'&:hover': {
background: GRADIENT,
filter: 'brightness(1.08)',
},
}));
export const SoftButton = styled(Button)(() => ({
borderRadius: 999,
textTransform: 'none',
color: '#fff',
border: '1px solid rgba(255,255,255,0.14)',
background: 'rgba(255,255,255,0.06)',
'&:hover': { background: 'rgba(255,255,255,0.1)' },
}));
type Severity = 'error' | 'warning' | 'info' | 'success';
const severityColor: Record<Severity, string> = {
info: '#4fc3f7',
success: '#4caf50',
warning: '#ff9800',
error: '#f44336',
};
export const Notifier = () => { export const Notifier = () => {
const [open, setOpen] = useState(false); const [open, setOpen] = useState(false);
const [message, setMessage] = useState(''); const [message, setMessage] = useState('');
const [severity, setSeverity] = useState< const [severity, setSeverity] = useState<Severity>('info');
'error' | 'warning' | 'info' | 'success'
>('info');
const [hasUpdateAvailable, setHasUpdateAvailable] = useState(false); const [hasUpdateAvailable, setHasUpdateAvailable] = useState(false);
useEffect(() => { useEffect(() => {
@ -24,6 +89,15 @@ export const Notifier = () => {
}; };
}, []); }, []);
useEffect(() => {
if (process.env.NODE_ENV === 'development') {
setMessage('Доступно новое обновление (dev preview)');
setSeverity('info');
setHasUpdateAvailable(true);
setOpen(true);
}
}, []);
const handleClose = () => { const handleClose = () => {
setOpen(false); setOpen(false);
}; };
@ -34,30 +108,48 @@ export const Notifier = () => {
}; };
return ( return (
<Box> <Snackbar
<Snackbar open={open}
open={open} onClose={handleClose}
autoHideDuration={hasUpdateAvailable ? null : 6000} autoHideDuration={hasUpdateAvailable ? null : 5000}
onClose={handleClose} anchorOrigin={{ vertical: 'bottom', horizontal: 'center' }}
> >
<Alert <GlassCard sx={{ minWidth: 340 }}>
severity={severity} <Glow />
action={
hasUpdateAvailable && ( <Box
<> sx={{
<Button color="primary" size="small" onClick={handleUpdate}> p: 2,
Обновить сейчас position: 'relative',
</Button> gap: 1,
<Button color="secondary" size="small" onClick={handleClose}> display: 'flex',
Позже flexDirection: 'column',
</Button> }}
</>
)
}
> >
{message} <Typography
</Alert> sx={{
</Snackbar> color: 'rgba(255,255,255,0.82)',
</Box> fontSize: 13.5,
lineHeight: 1.35,
pr: hasUpdateAvailable ? 1 : 0,
}}
>
{message}
</Typography>
{hasUpdateAvailable && (
<Stack direction="row" spacing={1} justifyContent="center" gap={1}>
<SoftButton size="small" onClick={handleUpdate}>
Обновить
</SoftButton>
<SoftButton size="small" onClick={handleClose}>
Позже
</SoftButton>
</Stack>
)}
</Box>
</GlassCard>
</Snackbar>
); );
}; };