2025-11-24 13:36:14 +03:00
|
|
|
|
import { useEffect, useRef, useState } from 'react';
|
|
|
|
|
|
import { Card, Spin, message } from 'antd';
|
|
|
|
|
|
|
|
|
|
|
|
interface Props {
|
|
|
|
|
|
claimPlanData: any; // Данные заявления от n8n
|
|
|
|
|
|
onNext: () => void;
|
|
|
|
|
|
onPrev: () => void;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
export default function StepClaimConfirmation({
|
|
|
|
|
|
claimPlanData,
|
|
|
|
|
|
onNext,
|
|
|
|
|
|
onPrev,
|
|
|
|
|
|
}: Props) {
|
|
|
|
|
|
const [loading, setLoading] = useState(true);
|
|
|
|
|
|
const iframeRef = useRef<HTMLIFrameElement>(null);
|
|
|
|
|
|
const [htmlContent, setHtmlContent] = useState<string>('');
|
|
|
|
|
|
|
|
|
|
|
|
useEffect(() => {
|
|
|
|
|
|
if (!claimPlanData) {
|
|
|
|
|
|
message.error('Данные заявления не получены');
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-11-24 15:16:46 +03:00
|
|
|
|
console.log('📋 StepClaimConfirmation: получены данные claimPlanData:', claimPlanData);
|
|
|
|
|
|
console.log('📋 claimPlanData.claim_id:', claimPlanData?.claim_id);
|
|
|
|
|
|
console.log('📋 claimPlanData.unified_id:', claimPlanData?.unified_id);
|
|
|
|
|
|
console.log('📋 claimPlanData.propertyName?.meta?.claim_id:', claimPlanData?.propertyName?.meta?.claim_id);
|
|
|
|
|
|
console.log('📋 claimPlanData.propertyName?.meta?.unified_id:', claimPlanData?.propertyName?.meta?.unified_id);
|
|
|
|
|
|
|
2025-11-24 13:36:14 +03:00
|
|
|
|
// Формируем данные для формы подтверждения
|
|
|
|
|
|
// Формат должен соответствовать тому, что ожидает HTML форма
|
2025-11-24 15:16:46 +03:00
|
|
|
|
const claimId = claimPlanData?.claim_id || claimPlanData?.propertyName?.meta?.claim_id || '';
|
|
|
|
|
|
const unifiedId = claimPlanData?.unified_id || claimPlanData?.propertyName?.meta?.unified_id || '';
|
|
|
|
|
|
|
|
|
|
|
|
console.log('📋 Извлечённые ID:', { claimId, unifiedId });
|
|
|
|
|
|
|
2025-11-24 13:36:14 +03:00
|
|
|
|
const formData = {
|
|
|
|
|
|
case: {
|
|
|
|
|
|
user: claimPlanData?.propertyName?.applicant || {},
|
|
|
|
|
|
project: claimPlanData?.propertyName?.case || {},
|
|
|
|
|
|
offenders: claimPlanData?.propertyName?.offenders || [],
|
|
|
|
|
|
attachments: claimPlanData?.propertyName?.attachments_names || [],
|
|
|
|
|
|
meta: {
|
|
|
|
|
|
...claimPlanData?.propertyName?.meta,
|
|
|
|
|
|
session_token: claimPlanData?.session_token || '',
|
|
|
|
|
|
prefix: claimPlanData?.prefix || '',
|
|
|
|
|
|
telegram_id: claimPlanData?.telegram_id || '',
|
2025-11-24 15:16:46 +03:00
|
|
|
|
claim_id: claimId,
|
|
|
|
|
|
unified_id: unifiedId,
|
2025-11-24 13:36:14 +03:00
|
|
|
|
user_id: claimPlanData?.user_id || claimPlanData?.propertyName?.meta?.user_id || '',
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
session_token: claimPlanData?.session_token || '',
|
|
|
|
|
|
telegram_id: claimPlanData?.telegram_id || '',
|
|
|
|
|
|
token: claimPlanData?.token || '',
|
|
|
|
|
|
sms_meta: {
|
|
|
|
|
|
session_token: claimPlanData?.session_token || '',
|
|
|
|
|
|
prefix: claimPlanData?.prefix || '',
|
|
|
|
|
|
telegram_id: claimPlanData?.telegram_id || '',
|
2025-11-24 15:16:46 +03:00
|
|
|
|
claim_id: claimId,
|
|
|
|
|
|
unified_id: unifiedId,
|
2025-11-24 13:36:14 +03:00
|
|
|
|
user_id: claimPlanData?.user_id || claimPlanData?.propertyName?.meta?.user_id || '',
|
|
|
|
|
|
},
|
|
|
|
|
|
};
|
2025-11-24 15:16:46 +03:00
|
|
|
|
|
|
|
|
|
|
console.log('📋 Сформированные formData.meta:', formData.case.meta);
|
2025-11-24 13:36:14 +03:00
|
|
|
|
|
|
|
|
|
|
// Здесь нужно будет получить HTML форму от n8n или использовать готовый шаблон
|
|
|
|
|
|
// Пока используем заглушку - в реальности нужно будет вызывать n8n workflow для генерации HTML
|
|
|
|
|
|
const html = generateConfirmationFormHTML(formData);
|
|
|
|
|
|
setHtmlContent(html);
|
|
|
|
|
|
setLoading(false);
|
|
|
|
|
|
}, [claimPlanData]);
|
|
|
|
|
|
|
|
|
|
|
|
// Функция генерации HTML формы (временная заглушка)
|
|
|
|
|
|
// В реальности это должен делать n8n workflow
|
|
|
|
|
|
const generateConfirmationFormHTML = (data: any): string => {
|
|
|
|
|
|
// Экранируем данные для безопасной вставки в HTML
|
|
|
|
|
|
const caseJson = JSON.stringify(data)
|
|
|
|
|
|
.replace(/</g, '\\u003c')
|
|
|
|
|
|
.replace(/>/g, '\\u003e');
|
|
|
|
|
|
|
|
|
|
|
|
return `<!doctype html>
|
|
|
|
|
|
<html lang="ru">
|
|
|
|
|
|
<head>
|
|
|
|
|
|
<meta charset="utf-8"/>
|
|
|
|
|
|
<meta name="viewport" content="width=device-width,initial-scale=1"/>
|
|
|
|
|
|
<title>Подтверждение данных</title>
|
|
|
|
|
|
<script src="https://telegram.org/js/telegram-web-app.js"></script>
|
|
|
|
|
|
<style>
|
|
|
|
|
|
body {
|
|
|
|
|
|
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;
|
|
|
|
|
|
margin: 0;
|
|
|
|
|
|
padding: 20px;
|
|
|
|
|
|
background: #f5f5f5;
|
|
|
|
|
|
}
|
|
|
|
|
|
.container {
|
|
|
|
|
|
max-width: 800px;
|
|
|
|
|
|
margin: 0 auto;
|
|
|
|
|
|
background: white;
|
|
|
|
|
|
padding: 24px;
|
|
|
|
|
|
border-radius: 8px;
|
|
|
|
|
|
box-shadow: 0 2px 8px rgba(0,0,0,0.1);
|
|
|
|
|
|
}
|
|
|
|
|
|
h1 {
|
|
|
|
|
|
text-align: center;
|
|
|
|
|
|
color: #1f2937;
|
|
|
|
|
|
margin-bottom: 24px;
|
|
|
|
|
|
}
|
|
|
|
|
|
.info {
|
|
|
|
|
|
background: #f0f9ff;
|
|
|
|
|
|
border: 1px solid #bae6fd;
|
|
|
|
|
|
border-radius: 6px;
|
|
|
|
|
|
padding: 16px;
|
|
|
|
|
|
margin-bottom: 24px;
|
|
|
|
|
|
}
|
|
|
|
|
|
.info p {
|
|
|
|
|
|
margin: 8px 0;
|
|
|
|
|
|
color: #1e40af;
|
|
|
|
|
|
}
|
|
|
|
|
|
.button-group {
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
gap: 12px;
|
|
|
|
|
|
margin-top: 24px;
|
|
|
|
|
|
justify-content: center;
|
|
|
|
|
|
}
|
|
|
|
|
|
button {
|
|
|
|
|
|
padding: 12px 24px;
|
|
|
|
|
|
border: none;
|
|
|
|
|
|
border-radius: 6px;
|
|
|
|
|
|
font-size: 16px;
|
|
|
|
|
|
cursor: pointer;
|
|
|
|
|
|
font-weight: 600;
|
|
|
|
|
|
}
|
|
|
|
|
|
.btn-primary {
|
|
|
|
|
|
background: #3b82f6;
|
|
|
|
|
|
color: white;
|
|
|
|
|
|
}
|
|
|
|
|
|
.btn-primary:hover {
|
|
|
|
|
|
background: #2563eb;
|
|
|
|
|
|
}
|
|
|
|
|
|
.btn-secondary {
|
|
|
|
|
|
background: #e5e7eb;
|
|
|
|
|
|
color: #374151;
|
|
|
|
|
|
}
|
|
|
|
|
|
.btn-secondary:hover {
|
|
|
|
|
|
background: #d1d5db;
|
|
|
|
|
|
}
|
|
|
|
|
|
</style>
|
|
|
|
|
|
</head>
|
|
|
|
|
|
<body>
|
|
|
|
|
|
<div class="container">
|
|
|
|
|
|
<h1>📋 Подтверждение данных заявления</h1>
|
|
|
|
|
|
|
|
|
|
|
|
<div class="info">
|
|
|
|
|
|
<p><strong>Статус:</strong> Данные заявления получены</p>
|
|
|
|
|
|
<p><strong>Claim ID:</strong> ${data.case?.meta?.claim_id || 'не указан'}</p>
|
|
|
|
|
|
<p><strong>Unified ID:</strong> ${data.case?.meta?.unified_id || 'не указан'}</p>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
<div class="button-group">
|
|
|
|
|
|
<button class="btn-primary" onclick="window.parent.postMessage({type: 'claim_confirmed'}, '*')">
|
|
|
|
|
|
✅ Подтвердить и отправить
|
|
|
|
|
|
</button>
|
|
|
|
|
|
<button class="btn-secondary" onclick="window.parent.postMessage({type: 'claim_cancelled'}, '*')">
|
|
|
|
|
|
❌ Отмена
|
|
|
|
|
|
</button>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
<script id="case-data" type="application/json">${caseJson}</script>
|
|
|
|
|
|
<script>
|
|
|
|
|
|
// Слушаем сообщения от родительского окна
|
|
|
|
|
|
window.addEventListener('message', function(event) {
|
|
|
|
|
|
console.log('Message received:', event.data);
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
// Отправляем сообщение родителю при загрузке
|
|
|
|
|
|
window.parent.postMessage({type: 'claim_form_loaded'}, '*');
|
|
|
|
|
|
</script>
|
|
|
|
|
|
</body>
|
|
|
|
|
|
</html>`;
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
useEffect(() => {
|
|
|
|
|
|
// Слушаем сообщения от iframe
|
|
|
|
|
|
const handleMessage = (event: MessageEvent) => {
|
|
|
|
|
|
console.log('📨 Message from iframe:', event.data);
|
|
|
|
|
|
|
|
|
|
|
|
if (event.data.type === 'claim_confirmed') {
|
|
|
|
|
|
message.success('Заявление подтверждено!');
|
|
|
|
|
|
onNext();
|
|
|
|
|
|
} else if (event.data.type === 'claim_cancelled') {
|
|
|
|
|
|
message.info('Подтверждение отменено');
|
|
|
|
|
|
onPrev();
|
|
|
|
|
|
} else if (event.data.type === 'claim_form_loaded') {
|
|
|
|
|
|
setLoading(false);
|
|
|
|
|
|
}
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
window.addEventListener('message', handleMessage);
|
|
|
|
|
|
return () => {
|
|
|
|
|
|
window.removeEventListener('message', handleMessage);
|
|
|
|
|
|
};
|
|
|
|
|
|
}, [onNext, onPrev]);
|
|
|
|
|
|
|
|
|
|
|
|
if (loading) {
|
|
|
|
|
|
return (
|
|
|
|
|
|
<Card>
|
|
|
|
|
|
<div style={{ textAlign: 'center', padding: '40px' }}>
|
|
|
|
|
|
<Spin size="large" />
|
|
|
|
|
|
<p style={{ marginTop: '16px' }}>Загрузка формы подтверждения...</p>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</Card>
|
|
|
|
|
|
);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return (
|
|
|
|
|
|
<Card>
|
|
|
|
|
|
<iframe
|
|
|
|
|
|
ref={iframeRef}
|
|
|
|
|
|
srcDoc={htmlContent}
|
|
|
|
|
|
style={{
|
|
|
|
|
|
width: '100%',
|
|
|
|
|
|
height: '800px',
|
|
|
|
|
|
border: 'none',
|
|
|
|
|
|
borderRadius: '8px',
|
|
|
|
|
|
}}
|
|
|
|
|
|
title="Форма подтверждения заявления"
|
|
|
|
|
|
/>
|
|
|
|
|
|
</Card>
|
|
|
|
|
|
);
|
|
|
|
|
|
}
|
|
|
|
|
|
|