test commit
This commit is contained in:
@@ -9,6 +9,7 @@ import TableRow from '@mui/material/TableRow'
|
||||
import TextField from '@mui/material/TextField'
|
||||
import Typography from '@mui/material/Typography'
|
||||
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query'
|
||||
import { useUnit } from 'effector-react'
|
||||
import { Controller, useForm } from 'react-hook-form'
|
||||
import { Link as RouterLink } from 'react-router-dom'
|
||||
import { createAdminUser, deleteAdminUser, fetchAdminUsers, updateAdminUser } from '@/entities/user/api/user-api'
|
||||
@@ -16,6 +17,7 @@ import type { AdminUser } from '@/entities/user/model/types'
|
||||
import { getErrorMessage } from '@/shared/lib/get-error-message'
|
||||
import { invalidateQueryKeys } from '@/shared/lib/invalidate-query-keys'
|
||||
import { useEditDialogState } from '@/shared/lib/use-edit-dialog-state'
|
||||
import { $user } from '@/shared/model/auth'
|
||||
import { AdminDialog } from '@/shared/ui/AdminDialog/AdminDialog'
|
||||
import { AdminTable } from '@/shared/ui/AdminTable'
|
||||
import { EntityRowActions } from '@/shared/ui/EntityRowActions'
|
||||
@@ -44,6 +46,8 @@ export function AdminUsersPage() {
|
||||
const [q, setQ] = useState('')
|
||||
const [page, setPage] = useState(0)
|
||||
const [rowsPerPage, setRowsPerPage] = useState(20)
|
||||
const currentUser = useUnit($user)
|
||||
const currentUserId = currentUser?.id
|
||||
|
||||
const userForm = useForm<UserFormState>({
|
||||
defaultValues: emptyUserForm(),
|
||||
@@ -192,7 +196,7 @@ export function AdminUsersPage() {
|
||||
<TableCell align="right">
|
||||
<EntityRowActions
|
||||
onEdit={() => openEdit(u)}
|
||||
onDelete={() => deleteMut.mutate(u.id)}
|
||||
onDelete={u.id === currentUserId ? undefined : () => deleteMut.mutate(u.id)}
|
||||
deleteDisabled={deleteMut.isPending}
|
||||
confirmDeleteMessage={`Удалить пользователя ${u.email}?`}
|
||||
/>
|
||||
@@ -237,7 +241,15 @@ export function AdminUsersPage() {
|
||||
<Controller
|
||||
control={userForm.control}
|
||||
name="email"
|
||||
render={({ field }) => <TextField label="Почта" fullWidth required {...field} />}
|
||||
render={({ field }) => (
|
||||
<TextField
|
||||
label="Почта"
|
||||
fullWidth
|
||||
required
|
||||
disabled={Boolean(editing && editing.id === currentUserId)}
|
||||
{...field}
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
<Controller
|
||||
control={userForm.control}
|
||||
|
||||
@@ -10,14 +10,18 @@ import {
|
||||
fetchUserNotificationSettings,
|
||||
updateUserNotificationSettings,
|
||||
} from '@/entities/notification/api/notifications-api'
|
||||
import type { UserNotificationSettings } 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: 'Изменение статуса оплаты' },
|
||||
{ key: 'deliveryFeeAdjusted' as const, label: 'Корректировка стоимости доставки' },
|
||||
]
|
||||
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()
|
||||
@@ -45,9 +49,11 @@ export function NotificationsPage() {
|
||||
|
||||
const handleToggle = (field: string, value: boolean) => {
|
||||
setError(null)
|
||||
mutation.mutate({ [field]: value } as Record<string, boolean>)
|
||||
mutation.mutate({ [field]: value })
|
||||
}
|
||||
|
||||
const statusChangesOn = isOrderStatusChangesOn(settings)
|
||||
|
||||
return (
|
||||
<Box>
|
||||
<Typography variant="h4" gutterBottom>
|
||||
@@ -80,19 +86,26 @@ export function NotificationsPage() {
|
||||
</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}
|
||||
/>
|
||||
))}
|
||||
<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>
|
||||
|
||||
@@ -7,7 +7,7 @@ import Link from '@mui/material/Link'
|
||||
import Stack from '@mui/material/Stack'
|
||||
import Typography from '@mui/material/Typography'
|
||||
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query'
|
||||
import { Link as RouterLink, useParams, useSearchParams } from 'react-router-dom'
|
||||
import { Link as RouterLink, useNavigate, useParams, useSearchParams } from 'react-router-dom'
|
||||
import {
|
||||
confirmOrderReceived,
|
||||
createOrderPayment,
|
||||
@@ -30,6 +30,7 @@ import { orderStatusLabelRu } from '@/shared/lib/order-status-labels'
|
||||
export function OrderDetailPage() {
|
||||
const { id } = useParams()
|
||||
const qc = useQueryClient()
|
||||
const navigate = useNavigate()
|
||||
|
||||
const [searchParams] = useSearchParams()
|
||||
const paidParam = searchParams.get('paid')
|
||||
@@ -58,6 +59,14 @@ export function OrderDetailPage() {
|
||||
},
|
||||
})
|
||||
|
||||
useEffect(() => {
|
||||
const data = paymentStatusQuery.data
|
||||
if (data && (data.paid || data.status === 'canceled') && paidParam === '1') {
|
||||
qc.invalidateQueries({ queryKey: ['me', 'orders', id] })
|
||||
navigate(`/me/orders/${id}`, { replace: true })
|
||||
}
|
||||
}, [paymentStatusQuery.data, paidParam, qc, id, navigate])
|
||||
|
||||
const confirmMut = useMutation({
|
||||
mutationFn: () => confirmOrderReceived(id!),
|
||||
onSuccess: () =>
|
||||
@@ -224,7 +233,7 @@ export function OrderDetailPage() {
|
||||
{PICKUP_ADDRESS_FULL}
|
||||
</Typography>
|
||||
<Typography color="text.secondary" variant="body2">
|
||||
Заберите заказ точно ко времени, которое согласуем по телефону или в чате заказа.
|
||||
Заберите заказ ко времени, которое согласуем в чате заказа.
|
||||
</Typography>
|
||||
</Stack>
|
||||
)}
|
||||
@@ -274,7 +283,9 @@ export function OrderDetailPage() {
|
||||
isUploadPending={uploadReviewImageMut.isPending}
|
||||
submitError={reviewMut.error}
|
||||
uploadError={uploadReviewImageMut.error}
|
||||
onSubmitReview={(params) => reviewMut.mutate(params)}
|
||||
onSubmitReview={async (params) => {
|
||||
await reviewMut.mutateAsync(params)
|
||||
}}
|
||||
onUploadImage={async (file) => {
|
||||
const result = await uploadReviewImageMut.mutateAsync(file)
|
||||
return result
|
||||
|
||||
Reference in New Issue
Block a user