218 lines
6.9 KiB
Markdown
218 lines
6.9 KiB
Markdown
|
|
# Обновление фронтенда: Блокировка редактирования подтверждённых данных
|
|||
|
|
|
|||
|
|
## Изменения
|
|||
|
|
|
|||
|
|
### 1. Step1Phone.tsx - Получение флага из n8n
|
|||
|
|
|
|||
|
|
**После получения ответа от n8n (после строки ~150):**
|
|||
|
|
|
|||
|
|
```typescript
|
|||
|
|
// ✅ Извлекаем флаг подтверждения данных
|
|||
|
|
const contact_data_confirmed = result.contact_data_confirmed || false;
|
|||
|
|
const contact_data_can_edit = result.contact_data_can_edit !== false; // По умолчанию true
|
|||
|
|
const contact_data_confirmed_at = result.contact_data_confirmed_at || null;
|
|||
|
|
|
|||
|
|
// Сохраняем в formData
|
|||
|
|
updateFormData({
|
|||
|
|
// ... существующие поля ...
|
|||
|
|
contact_data_confirmed: contact_data_confirmed,
|
|||
|
|
contact_data_can_edit: contact_data_can_edit,
|
|||
|
|
contact_data_confirmed_at: contact_data_confirmed_at,
|
|||
|
|
});
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
### 2. generateConfirmationFormHTML.ts - Блокировка полей
|
|||
|
|
|
|||
|
|
**Добавить параметр `contact_data_confirmed` в функцию:**
|
|||
|
|
|
|||
|
|
```typescript
|
|||
|
|
export function generateConfirmationFormHTML(
|
|||
|
|
data: any,
|
|||
|
|
contact_data_confirmed: boolean = false
|
|||
|
|
): string {
|
|||
|
|
// ... существующий код ...
|
|||
|
|
|
|||
|
|
// В функции createInputField добавить проверку:
|
|||
|
|
function createInputField(root: string, key: string, value: any, label: string, type: string = 'text') {
|
|||
|
|
const isReadOnly = contact_data_confirmed && (
|
|||
|
|
key === 'firstname' ||
|
|||
|
|
key === 'lastname' ||
|
|||
|
|
key === 'middle_name' ||
|
|||
|
|
key === 'inn' ||
|
|||
|
|
key === 'birthday' ||
|
|||
|
|
key === 'birthplace' ||
|
|||
|
|
key === 'mailingstreet' ||
|
|||
|
|
key === 'email'
|
|||
|
|
);
|
|||
|
|
|
|||
|
|
const readonlyAttr = isReadOnly ? 'readonly' : '';
|
|||
|
|
const readonlyClass = isReadOnly ? 'readonly-field' : '';
|
|||
|
|
|
|||
|
|
// ... остальной код с добавлением readonlyAttr и readonlyClass ...
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**Добавить CSS для readonly полей:**
|
|||
|
|
|
|||
|
|
```css
|
|||
|
|
.readonly-field {
|
|||
|
|
background-color: #f5f5f5 !important;
|
|||
|
|
cursor: not-allowed !important;
|
|||
|
|
opacity: 0.7;
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
### 3. StepClaimConfirmation.tsx - Передача флага в форму
|
|||
|
|
|
|||
|
|
**В useEffect (после строки ~90):**
|
|||
|
|
|
|||
|
|
```typescript
|
|||
|
|
// Получаем флаг подтверждения из claimPlanData или formData
|
|||
|
|
const contact_data_confirmed =
|
|||
|
|
claimPlanData?.contact_data_confirmed ||
|
|||
|
|
claimPlanData?.propertyName?.meta?.contact_data_confirmed ||
|
|||
|
|
formData?.contact_data_confirmed ||
|
|||
|
|
false;
|
|||
|
|
|
|||
|
|
// Передаём в generateConfirmationFormHTML
|
|||
|
|
const html = generateConfirmationFormHTML(formData, contact_data_confirmed);
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
### 4. Добавить кнопку "Изменить данные" (опционально)
|
|||
|
|
|
|||
|
|
**В generateConfirmationFormHTML.ts:**
|
|||
|
|
|
|||
|
|
```typescript
|
|||
|
|
// После заголовка формы, если contact_data_confirmed = true
|
|||
|
|
if (contact_data_confirmed) {
|
|||
|
|
html += `
|
|||
|
|
<div style="margin-bottom: 16px; padding: 12px; background: #fff7e6; border: 1px solid #ffd591; border-radius: 4px;">
|
|||
|
|
<p style="margin: 0 0 8px 0; color: #ad6800;">
|
|||
|
|
<strong>⚠️ Данные подтверждены</strong>
|
|||
|
|
</p>
|
|||
|
|
<p style="margin: 0; font-size: 14px; color: #ad6800;">
|
|||
|
|
Для изменения данных требуется подтверждение через SMS.
|
|||
|
|
</p>
|
|||
|
|
<button
|
|||
|
|
type="button"
|
|||
|
|
id="btn-edit-data"
|
|||
|
|
style="margin-top: 8px; padding: 6px 16px; background: #fa8c16; color: white; border: none; border-radius: 4px; cursor: pointer;"
|
|||
|
|
>
|
|||
|
|
Изменить данные
|
|||
|
|
</button>
|
|||
|
|
</div>
|
|||
|
|
`;
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**В JavaScript внутри формы:**
|
|||
|
|
|
|||
|
|
```javascript
|
|||
|
|
// Обработчик кнопки "Изменить данные"
|
|||
|
|
const editBtn = document.getElementById('btn-edit-data');
|
|||
|
|
if (editBtn) {
|
|||
|
|
editBtn.addEventListener('click', function() {
|
|||
|
|
// Отправляем сообщение родительскому окну
|
|||
|
|
window.parent.postMessage({
|
|||
|
|
type: 'request_edit_contact_data',
|
|||
|
|
eventData: {
|
|||
|
|
phone: state.user?.mobile || '',
|
|||
|
|
unified_id: state.meta?.unified_id || ''
|
|||
|
|
}
|
|||
|
|
}, '*');
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
### 5. Обработка запроса на изменение данных
|
|||
|
|
|
|||
|
|
**В StepClaimConfirmation.tsx:**
|
|||
|
|
|
|||
|
|
```typescript
|
|||
|
|
useEffect(() => {
|
|||
|
|
const handleMessage = (event: MessageEvent) => {
|
|||
|
|
// ... существующие обработчики ...
|
|||
|
|
|
|||
|
|
if (event.data.type === 'request_edit_contact_data') {
|
|||
|
|
const { phone, unified_id } = event.data.eventData;
|
|||
|
|
|
|||
|
|
// Показываем модалку SMS для подтверждения
|
|||
|
|
setSmsModalVisible(true);
|
|||
|
|
setSmsCodeSent(false);
|
|||
|
|
sendSMSCode(phone);
|
|||
|
|
|
|||
|
|
// Сохраняем флаг, что это запрос на изменение данных
|
|||
|
|
setPendingFormData({
|
|||
|
|
...pendingFormData,
|
|||
|
|
is_edit_request: true,
|
|||
|
|
unified_id: unified_id
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
window.addEventListener('message', handleMessage);
|
|||
|
|
return () => window.removeEventListener('message', handleMessage);
|
|||
|
|
}, []);
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
### 6. После SMS подтверждения - сброс флага
|
|||
|
|
|
|||
|
|
**В verifySMSCode (после успешной верификации):**
|
|||
|
|
|
|||
|
|
```typescript
|
|||
|
|
// Если это запрос на изменение данных
|
|||
|
|
if (pendingFormData?.is_edit_request) {
|
|||
|
|
// Отправляем запрос в n8n для сброса флага
|
|||
|
|
await fetch('/api/v1/claims/contact-data/reset-confirmed', {
|
|||
|
|
method: 'POST',
|
|||
|
|
headers: { 'Content-Type': 'application/json' },
|
|||
|
|
body: JSON.stringify({
|
|||
|
|
unified_id: pendingFormData.unified_id,
|
|||
|
|
sms_code: code
|
|||
|
|
})
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
// Обновляем флаг в formData
|
|||
|
|
updateFormData({
|
|||
|
|
contact_data_confirmed: false,
|
|||
|
|
contact_data_can_edit: true
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
// Перезагружаем форму с разблокированными полями
|
|||
|
|
// (можно просто обновить страницу или пересоздать форму)
|
|||
|
|
window.location.reload();
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## Порядок реализации
|
|||
|
|
|
|||
|
|
1. ✅ Обновить Step1Phone для получения флага
|
|||
|
|
2. ✅ Обновить generateConfirmationFormHTML для блокировки полей
|
|||
|
|
3. ✅ Обновить StepClaimConfirmation для передачи флага
|
|||
|
|
4. ⏳ Добавить кнопку "Изменить данные" (опционально)
|
|||
|
|
5. ⏳ Реализовать механизм переподтверждения через SMS
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## Тестирование
|
|||
|
|
|
|||
|
|
После обновления проверить:
|
|||
|
|
- ✅ Флаг получается из n8n
|
|||
|
|
- ✅ Поля блокируются при `contact_data_confirmed = true`
|
|||
|
|
- ✅ Данные из CRM загружаются и отображаются
|
|||
|
|
- ✅ Кнопка "Изменить данные" работает (если реализована)
|
|||
|
|
|