Files
shop-server/client/src/shared/ui/NotificationStack/NotificationStack.tsx
T
2026-05-27 23:43:22 +05:00

107 lines
3.4 KiB
TypeScript

import CloseIcon from '@mui/icons-material/Close'
import { Snackbar, Alert, IconButton, Button } from '@mui/material'
import { useUnit } from 'effector-react'
import { useNavigate } from 'react-router-dom'
import { $notifications, dismissNotification as dismissNotificationEvent } from '../../model/notification'
const GAP = 76
export function NotificationStack() {
const notifications = useUnit($notifications)
const dismissNotification = useUnit(dismissNotificationEvent)
const navigate = useNavigate()
if (notifications.length === 0) return null
return (
<>
{notifications.map((n, index) => (
<Snackbar
key={n.id}
open
autoHideDuration={n.autoHideDuration}
onClose={() => dismissNotification(n.id)}
anchorOrigin={{ vertical: 'bottom', horizontal: 'center' }}
sx={{
bottom: `${88 + (notifications.length - 1 - index) * GAP}px !important`,
zIndex: 2000 + index,
}}
>
<Alert
severity={n.type}
variant="standard"
onClose={() => dismissNotification(n.id)}
sx={(theme) => ({
width: '100%',
minWidth: 360,
maxWidth: 440,
px: 2,
py: 1.5,
alignItems: 'center',
color: `${theme.palette.primary.main} !important`,
boxShadow: '0 4px 16px rgba(0,0,0,0.3)',
WebkitBackdropFilter: 'blur(8px)',
backdropFilter: 'blur(8px)',
backgroundColor: 'rgba(255,255,255,0.7)',
'& .MuiAlert-icon': {
py: 0.5,
mr: 1.5,
display: 'flex',
alignItems: 'center',
color: `${theme.palette.primary.main} !important`,
},
'& .MuiAlert-message': {
py: 0.5,
fontSize: '0.875rem',
fontWeight: 600,
lineHeight: 1.5,
},
'& .MuiAlert-action': {
py: 0.5,
pr: 0,
ml: 1.5,
display: 'flex',
alignItems: 'center',
gap: 1,
},
})}
action={
<>
{n.actionLabel && n.actionPath && (
<Button
size="small"
variant="text"
onClick={() => {
dismissNotification(n.id)
navigate(n.actionPath!)
}}
sx={{
fontWeight: 700,
fontSize: '0.8125rem',
px: 1.5,
py: 0.5,
borderRadius: 8,
whiteSpace: 'nowrap',
color: 'primary.main',
'&:hover': {
bgcolor: 'action.hover',
},
}}
>
{n.actionLabel}
</Button>
)}
<IconButton size="small" onClick={() => dismissNotification(n.id)} sx={{ color: 'primary.main' }}>
<CloseIcon fontSize="small" />
</IconButton>
</>
}
>
{n.message}
</Alert>
</Snackbar>
))}
</>
)
}