feat: add user notification settings page
This commit is contained in:
@@ -0,0 +1,99 @@
|
||||
import { useState } from 'react'
|
||||
import Alert from '@mui/material/Alert'
|
||||
import Box from '@mui/material/Box'
|
||||
import FormControlLabel from '@mui/material/FormControlLabel'
|
||||
import Stack from '@mui/material/Stack'
|
||||
import Switch from '@mui/material/Switch'
|
||||
import Typography from '@mui/material/Typography'
|
||||
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query'
|
||||
import {
|
||||
fetchUserNotificationSettings,
|
||||
updateUserNotificationSettings,
|
||||
} from '@/entities/notification/api/notifications-api'
|
||||
|
||||
const eventFields = [
|
||||
{ key: 'orderCreated' as const, label: 'Заказ создан' },
|
||||
{ key: 'orderStatusChanged' as const, label: 'Изменение статуса заказа' },
|
||||
{ key: 'orderMessageReceived' as const, label: 'Сообщение в чате заказа' },
|
||||
{ key: 'paymentStatusChanged' as const, label: 'Изменение статуса оплаты' },
|
||||
]
|
||||
|
||||
export function NotificationsPage() {
|
||||
const queryClient = useQueryClient()
|
||||
const [error, setError] = useState<string | null>(null)
|
||||
|
||||
const { data, isLoading } = useQuery({
|
||||
queryKey: ['me', 'notifications', 'settings'],
|
||||
queryFn: fetchUserNotificationSettings,
|
||||
})
|
||||
|
||||
const mutation = useMutation({
|
||||
mutationFn: updateUserNotificationSettings,
|
||||
onSuccess: () => {
|
||||
queryClient.invalidateQueries({ queryKey: ['me', 'notifications', 'settings'] })
|
||||
},
|
||||
onError: (err: { response?: { data?: { error?: string } } }) => {
|
||||
setError(err.response?.data?.error || 'Ошибка сохранения')
|
||||
},
|
||||
})
|
||||
|
||||
if (isLoading) return <Typography>Загрузка...</Typography>
|
||||
|
||||
const settings = data?.settings
|
||||
if (!settings) return <Alert severity="error">Не удалось загрузить настройки</Alert>
|
||||
|
||||
const handleToggle = (field: string, value: boolean) => {
|
||||
setError(null)
|
||||
mutation.mutate({ [field]: value } as Record<string, boolean>)
|
||||
}
|
||||
|
||||
return (
|
||||
<Box>
|
||||
<Typography variant="h4" gutterBottom>
|
||||
Оповещения
|
||||
</Typography>
|
||||
<Typography color="text.secondary" sx={{ mb: 3 }}>
|
||||
Настройте, какие уведомления вы хотите получать на почту.
|
||||
</Typography>
|
||||
|
||||
{error && (
|
||||
<Alert severity="error" sx={{ mb: 2 }}>
|
||||
{error}
|
||||
</Alert>
|
||||
)}
|
||||
|
||||
<Stack spacing={3} sx={{ maxWidth: 480 }}>
|
||||
<Box>
|
||||
<FormControlLabel
|
||||
control={
|
||||
<Switch
|
||||
checked={settings.globalEnabled}
|
||||
onChange={(e) => handleToggle('globalEnabled', e.target.checked)}
|
||||
/>
|
||||
}
|
||||
label={<Typography sx={{ fontWeight: 600 }}>Получать оповещения</Typography>}
|
||||
/>
|
||||
<Typography variant="body2" color="text.secondary" sx={{ ml: 4 }}>
|
||||
Включите, чтобы получать уведомления о заказах на почту.
|
||||
</Typography>
|
||||
</Box>
|
||||
|
||||
<Box sx={{ pl: 4 }}>
|
||||
{eventFields.map(({ key, label }) => (
|
||||
<FormControlLabel
|
||||
key={key}
|
||||
control={
|
||||
<Switch
|
||||
checked={settings[key]}
|
||||
disabled={!settings.globalEnabled}
|
||||
onChange={(e) => handleToggle(key, e.target.checked)}
|
||||
/>
|
||||
}
|
||||
label={label}
|
||||
/>
|
||||
))}
|
||||
</Box>
|
||||
</Stack>
|
||||
</Box>
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user