diff --git a/frontend/src/components/form/generateConfirmationFormHTML.ts b/frontend/src/components/form/generateConfirmationFormHTML.ts index 63a87a2..a964fca 100644 --- a/frontend/src/components/form/generateConfirmationFormHTML.ts +++ b/frontend/src/components/form/generateConfirmationFormHTML.ts @@ -123,9 +123,11 @@ export function generateConfirmationFormHTML(data: any): string { console.log('period_end_fmt:', contract.period_end_fmt); // Получаем список приложенных документов - const attachments = props.attachments_names || []; + // ✅ Используем полный массив attachments с field_label, если есть, иначе attachments_names + const attachments = props.attachments || props.attachments_names || []; console.log('=== ОТЛАДКА ПРИЛОЖЕНИЙ ==='); - console.log('attachments_names:', attachments); + console.log('attachments:', attachments); + console.log('attachments_names:', props.attachments_names); return { user: { @@ -152,7 +154,7 @@ export function generateConfirmationFormHTML(data: any): string { description: claim.description || null, reason: claim.reason || caseData.category || null, }, - attachments: attachments, + attachments: attachments, // ✅ Теперь это массив объектов с field_label или массив строк offenders: offenders.map((o: any) => ({ accountname: o.name || null, address: o.address || null, @@ -346,6 +348,20 @@ export function generateConfirmationFormHTML(data: any): string { background:#f8fafc; } .inline-field:hover{border-color:#d1d5db} + /* ✅ Зеленая рамка для заполненных полей */ + .inline-field.filled{ + border-color:#10b981; + background-color:#f0fdf4; + } + .inline-field.filled:focus{ + border-color:#10b981; + box-shadow:0 0 0 2px rgba(16,185,129,0.1); + background-color:#f0fdf4; + } + textarea.inline-field.filled{ + border-color:#10b981; + background-color:#f0fdf4; + } .inline-field.large{ min-width:200px;max-width:500px; } @@ -568,7 +584,8 @@ export function generateConfirmationFormHTML(data: any): string { var claim = props.claim || {}; var meta = props.meta || {}; - var attachments = props.attachments_names || []; + // ✅ Используем полный массив attachments с field_label, если есть, иначе attachments_names + var attachments = props.attachments || props.attachments_names || []; return { user: { @@ -595,7 +612,7 @@ export function generateConfirmationFormHTML(data: any): string { description: claim.description || null, reason: claim.reason || caseData.category || null, }, - attachments: attachments, + attachments: attachments, // ✅ Теперь это массив объектов с field_label или массив строк offenders: offenders.map(function(o) { return { accountname: o.name || null, @@ -974,10 +991,18 @@ export function generateConfirmationFormHTML(data: any): string { html += '
'; for (var i = 0; i < state.attachments.length; i++) { - var fileName = state.attachments[i]; + var attachment = state.attachments[i]; + // ✅ Используем field_label если это объект, иначе имя файла + var displayName = ''; + if (typeof attachment === 'object' && attachment !== null) { + displayName = attachment.field_label || attachment.label || attachment.original_file_name || attachment.file_name || 'Документ'; + } else { + displayName = String(attachment); + } + html += '
'; html += '📎'; - html += '' + esc(fileName) + ''; + html += '' + esc(displayName) + ''; html += '
'; } @@ -1147,15 +1172,34 @@ export function generateConfirmationFormHTML(data: any): string { } } + // ✅ Функция для обновления стиля заполненных полей + function updateFieldStyle(field) { + var value = field.type === 'checkbox' ? field.checked : (field.value || '').trim(); + var hasValue = field.type === 'checkbox' ? value : value.length > 0; + + if (hasValue) { + field.classList.add('filled'); + } else { + field.classList.remove('filled'); + } + } + function attachBindings() { console.log('Attaching bindings...'); var fields = document.querySelectorAll('.bind'); console.log('Found fields:', fields.length); + // ✅ Устанавливаем начальный стиль для всех полей + Array.prototype.forEach.call(fields, function(field) { + updateFieldStyle(field); + }); + Array.prototype.forEach.call(fields, function(field) { // Обработка ввода field.addEventListener('input', function() { + // ✅ Обновляем стиль при изменении + updateFieldStyle(this); // Автозамена запятой на точку для денежных полей if (this.classList.contains('money-field') && this.value.includes(',')) { this.value = this.value.replace(/,/g, '.'); @@ -1240,12 +1284,21 @@ export function generateConfirmationFormHTML(data: any): string { // Валидация при потере фокуса field.addEventListener('blur', function() { + updateFieldStyle(this); // ✅ Обновляем стиль при потере фокуса updateSubmitButton(); }); + // ✅ Обновление стиля для чекбоксов при изменении + if (field.type === 'checkbox') { + field.addEventListener('change', function() { + updateFieldStyle(this); + }); + } + // Дополнительная обработка для чекбоксов if (field.type === 'checkbox') { field.addEventListener('change', function() { + updateFieldStyle(this); // ✅ Обновляем стиль при изменении чекбокса var root = this.getAttribute('data-root'); var key = this.getAttribute('data-key'); var value = this.checked; diff --git a/frontend/src/pages/ClaimForm.tsx b/frontend/src/pages/ClaimForm.tsx index 94349e6..10568eb 100644 --- a/frontend/src/pages/ClaimForm.tsx +++ b/frontend/src/pages/ClaimForm.tsx @@ -445,7 +445,8 @@ export default function ClaimForm() { // Формируем attachments с полной информацией const attachments = documentsMeta.map((doc: any) => ({ - label: doc.original_file_name || doc.file_name || doc.field_name || 'Документ', + label: doc.field_label || doc.original_file_name || doc.file_name || doc.field_name || 'Документ', // ✅ Используем field_label + field_label: doc.field_label || doc.field_name || doc.original_file_name || doc.file_name || 'Документ', // ✅ Добавляем field_label отдельно url: doc.file_id ? `https://s3.twcstorage.ru${doc.file_id}` : '', file_id: doc.file_id || '', stored_file_name: doc.file_name || '',