124 lines
4.3 KiB
TypeScript
124 lines
4.3 KiB
TypeScript
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 { useUnit } from 'effector-react'
|
||
import {
|
||
fetchUserNotificationSettings,
|
||
updateUserNotificationSettings,
|
||
} from '@/entities/notification/api/notifications-api'
|
||
import type { UserNotificationSettings } from '@/entities/notification/api/notifications-api'
|
||
import { isSyntheticEmail } from '@/shared/lib/is-synthetic-email'
|
||
import { $user } from '@/shared/model/auth'
|
||
|
||
function isOrderStatusChangesOn(s: UserNotificationSettings): boolean {
|
||
return s.orderCreated && s.orderStatusChanged && s.paymentStatusChanged && s.deliveryFeeAdjusted
|
||
}
|
||
|
||
const orderStatusChangesPayload = (on: boolean) => ({
|
||
orderCreated: on,
|
||
orderStatusChanged: on,
|
||
paymentStatusChanged: on,
|
||
deliveryFeeAdjusted: on,
|
||
})
|
||
|
||
export function NotificationsPage() {
|
||
const queryClient = useQueryClient()
|
||
const [error, setError] = useState<string | null>(null)
|
||
const user = useUnit($user)
|
||
|
||
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 })
|
||
}
|
||
|
||
const statusChangesOn = isOrderStatusChangesOn(settings)
|
||
|
||
return (
|
||
<Box>
|
||
<Typography variant="h4" gutterBottom>
|
||
Уведомления
|
||
</Typography>
|
||
<Typography color="text.secondary" sx={{ mb: 3 }}>
|
||
Настройте, какие уведомления вы хотите получать на почту.
|
||
</Typography>
|
||
|
||
{user && isSyntheticEmail(user.email) && (
|
||
<Alert severity="info" sx={{ mb: 2 }}>
|
||
Ваша почта сгенерирована автоматически. Для получения уведомлений укажите реальную почту в настройках профиля.
|
||
</Alert>
|
||
)}
|
||
|
||
{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 }}>
|
||
<FormControlLabel
|
||
control={
|
||
<Switch
|
||
checked={statusChangesOn}
|
||
disabled={!settings.globalEnabled}
|
||
onChange={(e) => mutation.mutate(orderStatusChangesPayload(e.target.checked))}
|
||
/>
|
||
}
|
||
label="Изменения статуса заказа"
|
||
/>
|
||
<FormControlLabel
|
||
control={
|
||
<Switch
|
||
checked={settings.orderMessageReceived}
|
||
disabled={!settings.globalEnabled}
|
||
onChange={(e) => handleToggle('orderMessageReceived', e.target.checked)}
|
||
/>
|
||
}
|
||
label="Сообщения в чате заказа"
|
||
/>
|
||
</Box>
|
||
</Stack>
|
||
</Box>
|
||
)
|
||
}
|