feat: remove old manual payment dialog and api method

This commit is contained in:
Kirill
2026-05-20 19:22:51 +05:00
parent dcf601d4a2
commit 698293e2f1
4 changed files with 0 additions and 173 deletions
@@ -73,20 +73,6 @@ export async function postOrderMessage(id: string, text: string): Promise<void>
await apiClient.post(`me/orders/${id}/messages`, { text })
}
/** Подтверждение оплаты переводом: multipart detail + необязательный файл receipt (хотя бы одно нужно на сервере). */
export async function submitOrderPayment(
orderId: string,
payload: { detail: string; receiptFile: File | null },
): Promise<{ ok: boolean; status: string }> {
const formData = new FormData()
formData.append('detail', payload.detail)
if (payload.receiptFile) {
formData.append('receipt', payload.receiptFile)
}
const { data } = await apiClient.post<{ ok: boolean; status: string }>(`me/orders/${orderId}/pay`, formData)
return data
}
export async function confirmOrderReceived(id: string): Promise<{ ok: boolean; status: string }> {
const { data } = await apiClient.post<{ ok: boolean; status: string }>(`me/orders/${id}/confirm-received`)
return data
@@ -1,2 +1 @@
export { OrderPaymentSection } from './ui/OrderPaymentSection'
export { PaymentDialog } from './ui/PaymentDialog'
@@ -1,146 +0,0 @@
import { useEffect, useMemo, useState } from 'react'
import Alert from '@mui/material/Alert'
import Box from '@mui/material/Box'
import Button from '@mui/material/Button'
import Dialog from '@mui/material/Dialog'
import DialogActions from '@mui/material/DialogActions'
import DialogContent from '@mui/material/DialogContent'
import DialogTitle from '@mui/material/DialogTitle'
import Stack from '@mui/material/Stack'
import TextField from '@mui/material/TextField'
import Typography from '@mui/material/Typography'
import axios from 'axios'
import { PAYMENT_TRANSFER_INSTRUCTIONS_PLAIN } from '@/shared/constants/payment-instructions'
type Props = {
open: boolean
isPending: boolean
error: unknown
onClose: () => void
onSubmit: (params: { detail: string; receiptFile: File | null }) => void
}
function paySubmitErrorMessage(err: unknown): string {
if (axios.isAxiosError(err)) {
const raw = err.response?.data
const apiMsg =
raw && typeof raw === 'object' && 'error' in raw && typeof (raw as { error: unknown }).error === 'string'
? (raw as { error: string }).error
: null
return apiMsg || err.message || 'Не удалось отправить данные оплаты'
}
if (err instanceof Error) return err.message
return 'Не удалось отправить данные оплаты'
}
export function PaymentDialog({ open, isPending, error, onClose, onSubmit }: Props) {
const [detail, setDetail] = useState('')
const [receiptFile, setReceiptFile] = useState<File | null>(null)
const [clientError, setClientError] = useState<string | null>(null)
const receiptPreviewUrl = useMemo(() => {
if (!receiptFile) return null
return URL.createObjectURL(receiptFile)
}, [receiptFile])
useEffect(() => {
if (!receiptPreviewUrl) return
return () => URL.revokeObjectURL(receiptPreviewUrl)
}, [receiptPreviewUrl])
const reset = () => {
setDetail('')
setReceiptFile(null)
setClientError(null)
}
const handleClose = () => {
if (isPending) return
reset()
onClose()
}
const handleSubmit = () => {
const hasText = detail.trim().length > 0
const hasFile = Boolean(receiptFile)
if (!hasText && !hasFile) {
setClientError('Укажите комментарий и/или прикрепите чек.')
return
}
setClientError(null)
onSubmit({ detail: detail.trim(), receiptFile })
}
return (
<Dialog open={open} onClose={handleClose} fullWidth maxWidth="sm">
<DialogTitle>Подтверждение оплаты</DialogTitle>
<DialogContent>
<Typography variant="body2" sx={{ whiteSpace: 'pre-wrap', mb: 2 }}>
{PAYMENT_TRANSFER_INSTRUCTIONS_PLAIN}
</Typography>
<TextField
label="Комментарий об оплате (сумма, время перевода и т.д.)"
value={detail}
onChange={(e) => {
setDetail(e.target.value)
setClientError(null)
}}
fullWidth
multiline
minRows={3}
sx={{ mb: 2 }}
/>
<Stack direction={{ xs: 'column', sm: 'row' }} spacing={1.5} sx={{ mb: 1, alignItems: { sm: 'center' } }}>
<Button component="label" variant="outlined">
Прикрепить чек (png, jpg, webp)
<input
hidden
type="file"
accept="image/png,image/jpeg,image/webp"
onChange={(e) => {
const file = e.target.files?.[0]
setReceiptFile(file ?? null)
setClientError(null)
e.currentTarget.value = ''
}}
/>
</Button>
{receiptFile && (
<Button color="error" variant="text" onClick={() => setReceiptFile(null)}>
Убрать файл
</Button>
)}
</Stack>
<Typography variant="caption" color="text.secondary" sx={{ mb: 1, display: 'block' }}>
Нужен текст комментария и/или изображение чека.
</Typography>
{receiptPreviewUrl && (
<Box
component="img"
src={receiptPreviewUrl}
alt="Предпросмотр чека"
sx={{ maxWidth: '100%', maxHeight: 200, borderRadius: 1, border: 1, borderColor: 'divider', mb: 1 }}
/>
)}
{clientError && (
<Alert severity="warning" sx={{ mb: 1 }}>
{clientError}
</Alert>
)}
{error ? (
<Alert severity="error" sx={{ mt: 1 }}>
{paySubmitErrorMessage(error)}
</Alert>
) : null}
</DialogContent>
<DialogActions>
<Button onClick={handleClose} disabled={isPending}>
Отмена
</Button>
<Button variant="contained" disabled={isPending} onClick={handleSubmit}>
Подтвердить оплату
</Button>
</DialogActions>
</Dialog>
)
}
@@ -1,12 +0,0 @@
/** Текст модалки оплаты (можно переопределить через VITE_PAYMENT_INSTRUCTIONS — многострочная строка \n). */
const fromEnv =
typeof import.meta.env.VITE_PAYMENT_INSTRUCTIONS === 'string' ? import.meta.env.VITE_PAYMENT_INSTRUCTIONS.trim() : ''
export const PAYMENT_TRANSFER_INSTRUCTIONS_PLAIN =
fromEnv ||
[
'Временно оплата доступна только переводом на ВТБ / Сбербанк.',
'',
'По номеру +79524181624',
'Получатель: Лариса К',
].join('\n')