import { useState, useEffect } from 'react'; import { Form, Input, Button, AutoComplete, message, Space, Divider } from 'antd'; import { PhoneOutlined, SafetyOutlined, QrcodeOutlined, MailOutlined, CopyOutlined } from '@ant-design/icons'; const API_BASE_URL = import.meta.env.VITE_API_URL || 'http://localhost:8200'; const NSPK_BANKS_API = 'http://212.193.27.93/api/payouts/dictionaries/nspk-banks'; interface Bank { bankid: string; bankname: string; } interface Props { formData: any; updateFormData: (data: any) => void; onPrev: () => void; onSubmit: () => void; isPhoneVerified: boolean; setIsPhoneVerified: (verified: boolean) => void; addDebugEvent?: (type: string, status: string, message: string, data?: any) => void; } export default function Step3Payment({ formData, updateFormData, onPrev, onSubmit, isPhoneVerified, setIsPhoneVerified, addDebugEvent }: Props) { const [form] = Form.useForm(); const [codeSent, setCodeSent] = useState(false); const [loading, setLoading] = useState(false); const [verifyLoading, setVerifyLoading] = useState(false); const [submitting, setSubmitting] = useState(false); const [debugCode, setDebugCode] = useState(formData.smsDebugCode ?? null); const [banks, setBanks] = useState([]); const [banksLoading, setBanksLoading] = useState(false); // Загрузка списка банков при монтировании компонента useEffect(() => { const loadBanks = async () => { try { setBanksLoading(true); addDebugEvent?.('banks', 'pending', '📋 Загружаю список банков СБП...'); const response = await fetch(NSPK_BANKS_API); if (!response.ok) { throw new Error(`HTTP ${response.status}`); } const banksData: Bank[] = await response.json(); // Сортируем по названию для удобства banksData.sort((a, b) => a.bankname.localeCompare(b.bankname, 'ru')); setBanks(banksData); addDebugEvent?.('banks', 'success', `✅ Загружено ${banksData.length} банков`, { count: banksData.length }); // Если есть сохранённый bankName или bankId - восстанавливаем значения if (formData.bankName) { const foundBank = banksData.find(b => b.bankname.toLowerCase() === formData.bankName.toLowerCase() || b.bankname.toLowerCase().includes(formData.bankName.toLowerCase()) ); if (foundBank) { updateFormData({ bankId: foundBank.bankid, bankName: foundBank.bankname }); form.setFieldsValue({ bankId: foundBank.bankid, bankName: foundBank.bankname }); } } else if (formData.bankId) { // Если есть только bankId, находим по ID const foundBank = banksData.find(b => b.bankid === formData.bankId); if (foundBank) { updateFormData({ bankId: foundBank.bankid, bankName: foundBank.bankname }); form.setFieldsValue({ bankId: foundBank.bankid, bankName: foundBank.bankname }); } } } catch (error: any) { console.error('Ошибка загрузки банков:', error); addDebugEvent?.('banks', 'error', `❌ Ошибка загрузки банков: ${error.message}`, { error: error.message }); message.error('Не удалось загрузить список банков. Попробуйте обновить страницу.'); } finally { setBanksLoading(false); } }; loadBanks(); // eslint-disable-next-line react-hooks/exhaustive-deps }, []); // Загружаем банки только при монтировании const sendCode = async () => { try { const phone = form.getFieldValue('phone'); if (!phone) { message.error('Введите номер телефона'); return; } setLoading(true); addDebugEvent?.('sms', 'pending', `📱 Отправляю SMS на ${phone}...`, { phone }); const response = await fetch(`${API_BASE_URL}/api/v1/sms/send`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ phone }), }); const result = await response.json(); if (response.ok) { addDebugEvent?.('sms', 'success', `✅ SMS отправлен (DEBUG mode)`, { phone, debug_code: result.debug_code, message: result.message }); message.success('Код отправлен на ваш телефон'); setCodeSent(true); if (result.debug_code) { setDebugCode(result.debug_code); updateFormData({ smsDebugCode: result.debug_code }); message.info(`DEBUG: Код ${result.debug_code}`); } } else { addDebugEvent?.('sms', 'error', `❌ Ошибка SMS: ${result.detail}`, { error: result.detail }); message.error(result.detail || 'Ошибка отправки кода'); } } catch (error) { message.error('Ошибка соединения с сервером'); } finally { setLoading(false); } }; const verifyCode = async () => { try { const phone = form.getFieldValue('phone'); const code = form.getFieldValue('smsCode'); if (!code) { message.error('Введите код из SMS'); return; } setVerifyLoading(true); addDebugEvent?.('sms', 'pending', `🔐 Проверяю SMS код...`, { phone, code }); const response = await fetch(`${API_BASE_URL}/api/v1/sms/verify`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ phone, code }), }); const result = await response.json(); if (response.ok) { addDebugEvent?.('sms', 'success', `✅ Телефон подтвержден успешно`, { phone, verified: true }); message.success('Телефон подтвержден!'); setDebugCode(null); updateFormData({ smsDebugCode: undefined }); setIsPhoneVerified(true); } else { addDebugEvent?.('sms', 'error', `❌ Неверный код SMS`, { phone, code, error: result.detail }); message.error(result.detail || 'Неверный код'); } } catch (error) { message.error('Ошибка соединения с сервером'); } finally { setVerifyLoading(false); } }; const handleSubmit = async () => { try { const values = await form.validateFields(); updateFormData(values); setSubmitting(true); await onSubmit(); } catch (error) { message.error('Заполните все обязательные поля'); } finally { setSubmitting(false); } }; // Инициализация формы с bankId и bankName если есть useEffect(() => { if (formData.bankId || formData.bankName) { form.setFieldsValue({ bankId: formData.bankId, bankName: formData.bankName }); } }, [formData.bankId, formData.bankName, form]); return (
{/* Скрытые технические поля */} {/* Кнопка Назад вверху */}
{/* Блок верификации телефона */}

📱 Подтверждение телефона

} placeholder="+79001234567" disabled={isPhoneVerified} maxLength={12} size="large" /> } placeholder="example@mail.ru" size="large" type="email" disabled={isPhoneVerified} /> {!isPhoneVerified && ( <> {codeSent && ( } placeholder="123456" maxLength={6} style={{ width: '70%' }} size="large" /> )} {debugCode && !isPhoneVerified && (
DEBUG код: {debugCode}
)} )} {isPhoneVerified && (
✅ Телефон подтвержден
)}
{/* Блок выплаты (показывается только после верификации) */} {isPhoneVerified && ( <>

💳 Способ получения выплаты

СБП (Система быстрых платежей)

Выплата поступит на ваш счет в течение нескольких минут

{/* Скрытое поле для bankId */} { if (!value) { return Promise.resolve(); } const foundBank = banks.find(b => b.bankname.toLowerCase() === value.toLowerCase() ); if (!foundBank) { return Promise.reject(new Error('Выберите банк из списка')); } return Promise.resolve(); } } ]} > ({ value: bank.bankname, label: bank.bankname, }))} filterOption={(inputValue, option) => { if (!option?.label) return false; return option.label.toLowerCase().includes(inputValue.toLowerCase()); }} onSelect={(value) => { // При выборе из списка находим банк и сохраняем оба поля const selectedBank = banks.find(b => b.bankname === value); if (selectedBank) { updateFormData({ bankId: selectedBank.bankid, bankName: selectedBank.bankname }); // Устанавливаем bankId в скрытое поле form.setFieldsValue({ bankId: selectedBank.bankid }); } }} onChange={(value) => { // При вводе текста ищем точное совпадение по названию if (typeof value === 'string') { const foundBank = banks.find(b => b.bankname.toLowerCase() === value.toLowerCase() ); if (foundBank) { updateFormData({ bankId: foundBank.bankid, bankName: foundBank.bankname }); form.setFieldsValue({ bankId: foundBank.bankid }); } else if (value === '') { // Если поле очищено, очищаем и bankId updateFormData({ bankId: undefined, bankName: undefined }); form.setFieldsValue({ bankId: undefined }); } } }} style={{ width: '100%' }} />
{/* DEV MODE секция удалена для продакшена */} )} ); }