Выплата возмещения возможна по системе быстрых платежей (СБП) по номеру телефона заявителя: ' + esc(u.mobile || '') + '
';
+
+ html += '';
+
+ // Заявление
html += '
ЗАЯВЛЕНИЕ
';
+ // Тема обращения (только для чтения)
html += '
Тема обращения: ';
html += createReadonlyField('project', 'category', p.category);
html += '
';
+ // Название договора / предмет
html += '
Предмет договора: ';
html += createField('project', 'subject', p.subject, 'Название договора или предмет услуг');
html += '
';
+ // Дата события / заключения договора
html += '
Дата события / заключения договора: ';
html += createDateField('project', 'agrdate', p.agrdate);
html += '
';
+ // Сумма оплаты / стоимость
html += '
Сумма оплаты / стоимость: ';
html += createMoneyField('project', 'agrprice', p.agrprice);
html += '
';
+ // Период
+ html += '
Период: ';
+ if (p.startdate || p.finishdate) {
+ html += 'с ';
+ html += createDateField('project', 'startdate', p.startdate);
+ html += ' по ';
+ html += createDateField('project', 'finishdate', p.finishdate);
+ } else {
+ html += createField('project', 'period_text', p.period_text, 'Период действия');
+ }
+ html += '
';
+
html += '';
+ // Контрагенты / участники
html += '
Контрагенты / участники:
';
for (var i = 0; i < state.offenders.length; i++) {
var offender = state.offenders[i];
html += '
';
+
html += '
Наименование: ';
html += createField('offender', 'accountname', offender.accountname, 'Название организации', i);
html += '
';
+
html += '
ИНН: ';
html += createField('offender', 'inn', offender.inn, 'ИНН организации (10 или 12 цифр)', i);
html += '
';
+
html += '
ОГРН: ';
html += createField('offender', 'ogrn', offender.ogrn, 'ОГРН', i);
html += '
';
+
html += '
Адрес: ';
html += createField('offender', 'address', offender.address, 'Адрес', i);
html += '
';
+
+ html += '
E-mail: ';
+ html += createField('offender', 'email', offender.email, 'email@example.com', i);
+ html += '
';
+
+ html += '
Телефон: ';
+ html += createField('offender', 'phone', offender.phone, '+7 (___) ___-__-__', i);
+ html += '
';
+
+ html += '
Сайт: ';
+ html += createField('offender', 'website', offender.website, 'https://example.com', i);
+ html += '
';
+
html += '
';
}
html += '';
+ // Причина обращения (редактируемая)
html += '
Причина обращения: ';
html += createField('project', 'reason', p.reason, 'Можете уточнить или изменить причину обращения');
html += '
';
@@ -456,24 +587,237 @@ export function generateConfirmationFormHTML(data: any): string {
html += '
Описание проблемы:
';
html += createTextarea('project', 'description', p.description);
+ html += '
На основании вышеизложенного и руководствуясь ст. 45 Закона «О защите прав потребителей», ст. 3, ч. 1 ст. 46 ГПК РФ, прошу вас защитить мои потребительские права, обратиться в суд с заявлением о защите моих потребительских прав и/или с коллективным иском о защите группы потребителей, и представлять мои интересы во всех судебных органах РФ, а также обращаться с заявлениями во все госорганы, подавать претензии, письма и жалобы.
';
+
+ html += '';
+
+ // Согласие на обработку персональных данных
+ html += '
';
+ html += createCheckbox('meta', 'privacyConsent', state.meta && state.meta.privacyConsent,
+ 'Я ознакомлен(а) и согласен(а) с Политикой обработки персональных данных и даю согласие на обработку моих персональных данных в соответствии с Федеральным законом от 27.07.2006 №152-ФЗ «О персональных данных»',
+ true);
+ html += '
';
+
+ // Список приложенных документов
+ if (state.attachments && state.attachments.length > 0) {
+ html += '';
+ html += '
Приложенные документы:
';
+ html += '
';
+
+ for (var i = 0; i < state.attachments.length; i++) {
+ var fileName = state.attachments[i];
+ html += '
';
+ html += '📎';
+ html += '' + esc(fileName) + '';
+ html += '
';
+ }
+
+ html += '
';
+ html += 'Всего документов: ' + state.attachments.length;
+ html += '
';
+ html += '
';
+ }
+
var statementEl = document.getElementById('statement');
if (statementEl) {
+ console.log('Setting innerHTML, HTML length:', html.length);
statementEl.innerHTML = html;
+ console.log('innerHTML set, calling attachBindings...');
attachBindings();
+ console.log('attachBindings completed');
+
+ // Обновляем состояние кнопки отправки
+ setTimeout(function() {
+ updateSubmitButton();
+ }, 100);
+
+ console.log('=== РЕНДЕРИНГ ЗАВЕРШЕН УСПЕШНО ===');
+ } else {
+ console.error('ОШИБКА: элемент #statement не найден в renderStatement!');
+ }
+ }
+
+ // Простые функции валидации
+ function isValidPhone(phone) {
+ if (!phone) return false;
+ var clean = phone.replace(/\D/g, '');
+ return clean.length >= 10 && clean.length <= 11;
+ }
+
+ function isValidEmail(email) {
+ if (!email) return false;
+ return email.includes('@') && email.includes('.') && email.length > 5;
+ }
+
+ function isNotEmpty(value) {
+ return value && value.trim().length > 0;
+ }
+
+ // Преобразования дат
+ function parseDDMMYYYY(s) {
+ if (!/^[0-9]{2}\.[0-9]{2}\.[0-9]{4}$/.test(s)) return null;
+ var [d,m,y] = s.split('.').map(Number);
+ var dt = new Date(y, m-1, d);
+ var isValid = (dt.getFullYear()===y && dt.getMonth()===m-1 && dt.getDate()===d);
+ return isValid ? dt : null;
+ }
+
+ function parseYMD(s) {
+ var cleanS = s.trim().replace(/[\u2012\u2013\u2014\u2015\u2212\uFF0D]/g, '-');
+ if (!/^[0-9]{4}-[0-9]{2}-[0-9]{2}$/.test(cleanS)) return null;
+ var [y,m,d] = cleanS.split('-').map(Number);
+ var dt = new Date(y, m-1, d);
+ var isValid = (dt.getFullYear()===y && dt.getMonth()===m-1 && dt.getDate()===d);
+ return isValid ? dt : null;
+ }
+
+ function toYMD(dt) {
+ var y = dt.getFullYear();
+ var m = String(dt.getMonth()+1).padStart(2,'0');
+ var d = String(dt.getDate()).padStart(2,'0');
+ return y+'-'+m+'-'+d;
+ }
+
+ function isValidINN(inn, isIndividual) {
+ if (!inn) return false;
+ var clean = String(inn).replace(/\D/g, '');
+ if (isIndividual) {
+ return clean.length === 12;
+ } else {
+ return clean.length === 10 || clean.length === 12;
+ }
+ }
+
+ function isValidName(name) {
+ if (!name) return false;
+ var trimmed = name.trim();
+ if (trimmed.length < 2) return false;
+ var hasCyrillic = /[а-яёА-ЯЁ]/.test(trimmed);
+ var hasInvalidChars = /[a-zA-Z0-9]/.test(trimmed);
+ return hasCyrillic && !hasInvalidChars;
+ }
+
+ function isValidAddress(address) {
+ if (!address) return false;
+ var trimmed = address.trim();
+ if (trimmed.length < 10) return false;
+ var hasNumbers = /[0-9]/.test(trimmed);
+ var cyrillicPattern = new RegExp('[а-яёА-ЯЁ]');
+ var hasLetters = cyrillicPattern.test(trimmed);
+ return hasNumbers && hasLetters;
+ }
+
+ function isValidMoney(v) {
+ if (!v) return false;
+ var s = String(v).replace(/\s+/g,'').replace(',', '.');
+ if (!/^[0-9]+(\.[0-9]{1,2})?$/.test(s)) return false;
+ return parseFloat(s) > 0;
+ }
+
+ // Функция проверки всех обязательных полей
+ function validateAllFields() {
+ var requiredFields = [
+ { root: 'user', key: 'lastname', name: 'Фамилия' },
+ { root: 'user', key: 'firstname', name: 'Имя' },
+ { root: 'user', key: 'birthday', name: 'Дата рождения' },
+ { root: 'user', key: 'birthplace', name: 'Место рождения' },
+ { root: 'user', key: 'mailingstreet', name: 'Адрес' },
+ { root: 'user', key: 'inn', name: 'ИНН' },
+ { root: 'project', key: 'agrdate', name: 'Дата договора' },
+ { root: 'project', key: 'agrprice', name: 'Сумма' },
+ { root: 'project', key: 'reason', name: 'Причина обращения' },
+ { root: 'project', key: 'description', name: 'Описание проблемы' },
+ { root: 'offender', key: 'accountname', name: 'Название организации' },
+ { root: 'offender', key: 'address', name: 'Адрес организации' }
+ ];
+
+ var errors = [];
+
+ for (var i = 0; i < requiredFields.length; i++) {
+ var field = requiredFields[i];
+ var value = '';
+ if (field.root === 'user') {
+ value = state.user[field.key] || '';
+ } else if (field.root === 'project') {
+ value = state.project[field.key] || '';
+ } else if (field.root === 'offender') {
+ value = (state.offenders[0] && state.offenders[0][field.key]) || '';
+ }
+ if (!value || (typeof value === 'string' && value.trim() === '')) {
+ errors.push(field.name);
+ }
+ }
+
+ return errors;
+ }
+
+ // Функция обновления состояния кнопки отправки
+ function updateSubmitButton() {
+ var confirmBtn = document.getElementById('confirmBtn');
+ if (!confirmBtn) return;
+
+ var isConsentGiven = state.meta && state.meta.privacyConsent === true;
+ var validationErrors = validateAllFields();
+
+ if (!isConsentGiven) {
+ confirmBtn.disabled = true;
+ confirmBtn.style.opacity = '0.6';
+ confirmBtn.style.cursor = 'not-allowed';
+ confirmBtn.textContent = '✅ Подтвердить и отправить';
+ } else if (validationErrors.length === 0) {
+ confirmBtn.disabled = false;
+ confirmBtn.style.opacity = '1';
+ confirmBtn.style.cursor = 'pointer';
+ confirmBtn.textContent = '✅ Подтвердить и отправить';
+ } else {
+ confirmBtn.disabled = true;
+ confirmBtn.style.opacity = '0.6';
+ confirmBtn.style.cursor = 'not-allowed';
+ confirmBtn.textContent = '❌ Заполните все поля (' + validationErrors.length + ')';
+ confirmBtn.title = 'Не заполнены: ' + validationErrors.join(', ');
}
}
function attachBindings() {
+ console.log('Attaching bindings...');
+
var fields = document.querySelectorAll('.bind');
+ console.log('Found fields:', fields.length);
+
Array.prototype.forEach.call(fields, function(field) {
+ // Обработка ввода
field.addEventListener('input', function() {
+ // Автозамена запятой на точку для денежных полей
+ if (this.classList.contains('money-field') && this.value.includes(',')) {
+ this.value = this.value.replace(/,/g, '.');
+ }
+
var root = this.getAttribute('data-root');
var key = this.getAttribute('data-key');
var value = this.type === 'checkbox' ? this.checked : this.value;
+ // Для полей дат конвертируем YYYY-MM-DD в DD.MM.YYYY для сохранения
+ if (this.classList.contains('date-field') && value) {
+ var parts = value.split('-');
+ if (parts.length === 3) {
+ value = parts[2] + '.' + parts[1] + '.' + parts[0];
+ }
+ }
+
+ console.log('Field changed:', root, key, value);
+
+ // Обновляем состояние
if (root === 'user') {
state.user = state.user || {};
state.user[key] = value;
+
+ // Обновляем телефон в СБП
+ if (key === 'mobile') {
+ var phoneDisplay = document.getElementById('phone-display');
+ if (phoneDisplay) {
+ phoneDisplay.textContent = value;
+ }
+ }
} else if (root === 'project') {
state.project = state.project || {};
state.project[key] = value;
@@ -481,37 +825,221 @@ export function generateConfirmationFormHTML(data: any): string {
var index = parseInt(this.getAttribute('data-index') || '0', 10);
state.offenders[index] = state.offenders[index] || {};
state.offenders[index][key] = value;
+ } else if (root === 'meta') {
+ state.meta = state.meta || {};
+ state.meta[key] = value;
+
+ // Для чекбокса согласия обновляем состояние кнопки
+ if (key === 'privacyConsent') {
+ updateSubmitButton();
+ }
+ }
+
+ // Обновляем состояние кнопки при изменении любого поля
+ updateSubmitButton();
+ });
+
+ // Блокировка нечисловых символов для ИНН
+ field.addEventListener('keydown', function(e) {
+ var key = this.getAttribute('data-key');
+ if (key === 'inn') {
+ var isDigit = (e.key >= '0' && e.key <= '9');
+ var isServiceKey = ['Backspace', 'Delete', 'Tab', 'ArrowLeft', 'ArrowRight', 'ArrowUp', 'ArrowDown', 'Home', 'End'].includes(e.key);
+ var isCtrlKey = e.ctrlKey && ['a', 'c', 'v', 'x', 'z'].includes(e.key.toLowerCase());
+ if (!isDigit && !isServiceKey && !isCtrlKey) {
+ e.preventDefault();
+ }
}
});
+
+ // Фильтрация при вставке для ИНН
+ field.addEventListener('paste', function(e) {
+ var key = this.getAttribute('data-key');
+ if (key === 'inn') {
+ e.preventDefault();
+ var paste = (e.clipboardData || window.clipboardData).getData('text');
+ var cleanPaste = paste.replace(/\D/g, '');
+ var root = this.getAttribute('data-root');
+ var isIndividual = (root === 'user');
+ var maxLength = 12;
+ cleanPaste = cleanPaste.slice(0, maxLength);
+ this.value = cleanPaste;
+ var inputEvent = new Event('input', { bubbles: true });
+ this.dispatchEvent(inputEvent);
+ }
+ });
+
+ // Валидация при потере фокуса
+ field.addEventListener('blur', function() {
+ updateSubmitButton();
+ });
+
+ // Дополнительная обработка для чекбоксов
+ if (field.type === 'checkbox') {
+ field.addEventListener('change', function() {
+ var root = this.getAttribute('data-root');
+ var key = this.getAttribute('data-key');
+ var value = this.checked;
+
+ if (root === 'meta' && key === 'privacyConsent') {
+ state.meta = state.meta || {};
+ state.meta[key] = value;
+ updateSubmitButton();
+
+ var container = this.closest('.checkbox-container');
+ if (container) {
+ if (value) {
+ container.classList.remove('error');
+ } else {
+ container.classList.add('error');
+ }
+ }
+ }
+ });
+ }
});
}
function initialize() {
- renderStatement();
-
- var confirmBtn = document.getElementById('confirmBtn');
- if (confirmBtn) {
- confirmBtn.addEventListener('click', function(e) {
- e.preventDefault();
- window.parent.postMessage({
- type: 'claim_confirmed',
- data: {
- user: state.user,
- project: state.project,
- offenders: state.offenders,
- meta: state.meta
- },
- originalData: injected
- }, '*');
- });
+ try {
+ console.log('=== НАЧАЛО ИНИЦИАЛИЗАЦИИ ===');
+ console.log('injected data:', injected);
+ console.log('state before render:', state);
+
+ // Проверяем, что элемент statement существует
+ var statementEl = document.getElementById('statement');
+ console.log('statement element found:', !!statementEl);
+
+ if (!statementEl) {
+ console.error('КРИТИЧЕСКАЯ ОШИБКА: элемент #statement не найден!');
+ return;
+ }
+
+ // Инициализируем поля для шаблонов, если их нет
+ if (!state.project.serviceType) state.project.serviceType = 'education';
+ if (!state.project.customServiceType) state.project.customServiceType = '';
+ if (!state.project.customReason) state.project.customReason = '';
+
+ // Добавляем поле согласия на обработку персданных
+ if (state.meta.privacyConsent === undefined) state.meta.privacyConsent = false;
+
+ console.log('Calling renderStatement...');
+ renderStatement();
+ console.log('renderStatement completed');
+
+ // Валидируем уже заполненные поля
+ setTimeout(function(){
+ console.log('Starting field validation...');
+ var fields = document.querySelectorAll('.bind');
+ console.log('Found fields for validation:', fields.length);
+ Array.prototype.forEach.call(fields, function(field){
+ // Валидация будет выполнена при первом взаимодействии
+ });
+ console.log('Initial validation completed');
+ }, 100);
+
+ var confirmBtn = document.getElementById('confirmBtn');
+ console.log('confirmBtn found:', !!confirmBtn);
+ if (confirmBtn) {
+ confirmBtn.addEventListener('click', function(e) {
+ e.preventDefault();
+ console.log('Confirm button clicked');
+
+ // Проверяем согласие
+ if (!state.meta || !state.meta.privacyConsent) {
+ alert('Необходимо дать согласие на обработку персональных данных');
+ return;
+ }
+
+ // Проверяем валидность полей
+ var validationErrors = validateAllFields();
+ if (validationErrors.length > 0) {
+ alert('Заполните все обязательные поля: ' + validationErrors.join(', '));
+ return;
+ }
+
+ window.parent.postMessage({
+ type: 'claim_confirmed',
+ data: {
+ user: state.user,
+ project: state.project,
+ offenders: state.offenders,
+ meta: state.meta
+ },
+ originalData: injected
+ }, '*');
+ });
+ }
+
+ // Делегированная фильтрация ИНН
+ if (!window.__innFilterAttached) {
+ document.addEventListener('input', function (e) {
+ var el = e.target;
+ if (!el || !el.classList) return;
+
+ var isInn = el.classList.contains('bind') && el.getAttribute('data-key') === 'inn';
+ if (!isInn) return;
+
+ // Логика из test/index.php - фильтрация по типу ИНН
+ var root = el.getAttribute('data-root');
+ var isIndividual = (root === 'user'); // user = физлицо, offender = юрлицо
+
+ // Оставляем только цифры
+ var v = (el.value || '').replace(/\D/g, '');
+
+ if (isIndividual) {
+ // Физлицо: максимум 12 цифр (как js-inn-mask: "999999999999")
+ v = v.slice(0, 12);
+ } else {
+ // Юрлицо: максимум 12 цифр, но валидны 10 или 12 (как js-inn-mask2: "9{10,12}")
+ v = v.slice(0, 12);
+ }
+
+ if (el.value !== v) el.value = v;
+
+ // Синхронизируем state
+ var root = el.getAttribute('data-root');
+ if (root === 'user') {
+ state.user = state.user || {};
+ state.user.inn = v;
+ } else if (root === 'offender') {
+ var idx = parseInt(el.getAttribute('data-index') || '0', 10);
+ state.offenders = state.offenders || [];
+ state.offenders[idx] = state.offenders[idx] || {};
+ state.offenders[idx].inn = v;
+ }
+
+ // Моментальная валидация и обновление кнопки
+ updateSubmitButton();
+ }, { passive: true });
+
+ window.__innFilterAttached = true;
+ }
+
+ // Отправляем сообщение родителю при загрузке
+ window.parent.postMessage({type: 'claim_form_loaded'}, '*');
+
+ console.log('=== ИНИЦИАЛИЗАЦИЯ ЗАВЕРШЕНА ===');
+ } catch (e) {
+ console.error('=== ОШИБКА ИНИЦИАЛИЗАЦИИ ===');
+ console.error('Error details:', e);
+ console.error('Error stack:', e.stack);
+ var statementEl = document.getElementById('statement');
+ if (statementEl) {
+ statementEl.innerHTML = '
Ошибка загрузки: ' + e.message + '
Проверьте консоль браузера (F12) для деталей.
';
+ }
}
-
- window.parent.postMessage({type: 'claim_form_loaded'}, '*');
}
+ // Запускаем инициализацию когда DOM готов
if (document.readyState === 'loading') {
- document.addEventListener('DOMContentLoaded', initialize);
+ console.log('DOM еще загружается, ждем события DOMContentLoaded...');
+ document.addEventListener('DOMContentLoaded', function() {
+ console.log('DOMContentLoaded fired, starting initialization...');
+ initialize();
+ });
} else {
+ console.log('DOM уже готов, запускаем инициализацию сразу...');
initialize();
}
})();