From 7e3804af72ec05f2426832f55f4ae646d630ad01 Mon Sep 17 00:00:00 2001 From: Kavalar Date: Wed, 27 May 2026 19:10:23 +0300 Subject: [PATCH] First --- index.html | 590 ++++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 493 insertions(+), 97 deletions(-) diff --git a/index.html b/index.html index 5844781..30a2147 100644 --- a/index.html +++ b/index.html @@ -23,33 +23,50 @@ .admin-toggle:hover { background: #0f2b40; transform: scale(1.02); } .tabs { display: flex; flex-wrap: wrap; justify-content: center; gap: 0.75rem; margin-bottom: 2rem; border-bottom: 2px solid #e2e8f0; padding-bottom: 0.75rem; } - .tab-btn { background: transparent; border: none; font-size: 0.95rem; font-weight: 600; padding: 0.6rem 1.5rem; border-radius: 40px; cursor: pointer; color: #475569; } + .tab-btn { background: transparent; border: none; font-size: 0.95rem; font-weight: 600; padding: 0.6rem 1.5rem; border-radius: 40px; cursor: pointer; color: #475569; transition: all 0.2s; } .tab-btn i { margin-right: 8px; } .tab-btn.active { background: #1e3a5f; color: white; } .tab-panel { display: none; animation: fadeIn 0.25s ease; } .tab-panel.active-panel { display: block; } @keyframes fadeIn { from { opacity: 0; transform: translateY(5px);} to { opacity: 1; transform: translateY(0);} } - .org-grid { display: flex; flex-direction: column; gap: 1rem; } - .org-card { background: white; border-radius: 20px; box-shadow: 0 1px 3px rgba(0,0,0,0.05); border: 1px solid #eef2f6; overflow: hidden; } + .org-grid { display: flex; flex-direction: column; gap: 1.5rem; } + .org-card { background: white; border-radius: 24px; box-shadow: 0 1px 3px rgba(0,0,0,0.05); border: 1px solid #eef2f6; overflow: hidden; transition: all 0.2s; } + .org-card:hover { box-shadow: 0 8px 25px rgba(0,0,0,0.08); } .org-header { display: flex; flex-wrap: wrap; justify-content: space-between; align-items: center; padding: 1.2rem 1.5rem; background: #ffffff; border-bottom: 1px solid #f0f2f5; cursor: pointer; } .org-title { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; } - .org-name { font-weight: 700; font-size: 1.1rem; color: #0f172a; } - .priority-badge { background: #eef2ff; color: #1e40af; border-radius: 40px; padding: 0.2rem 0.7rem; font-size: 0.7rem; font-weight: 600; } - .status-badge { border-radius: 40px; padding: 0.2rem 0.7rem; font-size: 0.7rem; font-weight: 600; } + .org-name { font-weight: 700; font-size: 1.2rem; color: #0f172a; } + .priority-badge { background: #eef2ff; color: #1e40af; border-radius: 40px; padding: 0.25rem 0.8rem; font-size: 0.7rem; font-weight: 600; } + .status-badge { border-radius: 40px; padding: 0.25rem 0.8rem; font-size: 0.7rem; font-weight: 600; } .status-active { background: #dcfce7; color: #15803d; } .status-warning { background: #fff3e3; color: #b45309; } - .toggle-icon { font-size: 1.2rem; color: #64748b; } - .org-details { padding: 0 1.5rem 1.2rem 1.5rem; background: #fefefe; border-top: 1px solid #f1f5f9; display: none; } + .toggle-icon { font-size: 1.2rem; color: #64748b; transition: transform 0.2s; } + .org-details { padding: 1.5rem; background: #fefefe; border-top: 1px solid #f1f5f9; display: none; } .org-details.open { display: block; } - .details-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); gap: 1rem; margin-top: 1.2rem; } - .detail-item { background: #f9fafb; padding: 0.8rem 1rem; border-radius: 16px; } - .detail-label { font-size: 0.7rem; text-transform: uppercase; letter-spacing: 0.5px; font-weight: 600; color: #5b6e8c; } - .detail-value { font-size: 0.9rem; font-weight: 500; color: #1e2a44; margin-top: 4px; word-break: break-word; } - hr { margin: 1.2rem 0; border-color: #ecf3f9; } + .details-section { margin-bottom: 1.5rem; } + .section-title { font-weight: 700; font-size: 0.9rem; text-transform: uppercase; letter-spacing: 0.5px; color: #5b6e8c; margin-bottom: 0.8rem; border-left: 3px solid #1e3a5f; padding-left: 10px; } + + .info-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); gap: 1rem; } + .info-card { background: #f8fafc; border-radius: 16px; padding: 0.8rem 1rem; transition: all 0.2s; } + .info-card .label { font-size: 0.7rem; text-transform: uppercase; letter-spacing: 0.3px; font-weight: 600; color: #6c86a3; margin-bottom: 0.3rem; } + .info-card .value { font-size: 0.9rem; font-weight: 500; color: #1e2a44; line-height: 1.4; word-break: break-word; } + .info-card .value a { color: #1e3a5f; text-decoration: none; } + .info-card .value a:hover { text-decoration: underline; } + + .full-width { grid-column: 1 / -1; } + .tags { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 5px; } + .tag { background: #e2e8f0; padding: 3px 10px; border-radius: 20px; font-size: 0.75rem; color: #334155; } + .links-list { display: flex; flex-wrap: wrap; gap: 8px; } + .link-item { background: #e2e8f0; padding: 4px 12px; border-radius: 20px; font-size: 0.8rem; } + .link-item a { color: #1e3a5f; text-decoration: none; } + .link-item a:hover { text-decoration: underline; } + + hr { margin: 1rem 0; border-color: #ecf3f9; } + + /* Admin Panel */ .admin-panel { - position: fixed; top: 0; right: -550px; width: 550px; height: 100vh; + position: fixed; top: 0; right: -650px; width: 650px; height: 100vh; background: white; box-shadow: -5px 0 30px rgba(0,0,0,0.2); z-index: 1001; transition: right 0.3s ease; overflow-y: auto; padding: 1.5rem; } @@ -59,20 +76,37 @@ .close-admin { background: none; border: none; font-size: 1.5rem; cursor: pointer; color: #64748b; } .org-selector { margin-bottom: 1.5rem; } .org-selector select { width: 100%; padding: 10px; border-radius: 12px; border: 1px solid #cbd5e1; font-size: 0.9rem; } - .org-type-selector { margin-bottom: 1rem; display: flex; gap: 1rem; align-items: center; } + .org-type-selector { margin-bottom: 1rem; display: flex; gap: 1rem; align-items: center; flex-wrap: wrap; } .org-type-selector label { display: flex; align-items: center; gap: 8px; cursor: pointer; } .edit-form { display: flex; flex-direction: column; gap: 1rem; } .form-group { display: flex; flex-direction: column; gap: 0.3rem; } .form-group label { font-weight: 600; font-size: 0.8rem; color: #475569; } + .form-group label .hint { font-weight: normal; color: #6c86a3; font-size: 0.7rem; } .form-group input, .form-group textarea, .form-group select { padding: 8px 12px; border-radius: 10px; border: 1px solid #cbd5e1; font-family: 'Inter', sans-serif; font-size: 0.85rem; } .form-group textarea { min-height: 60px; resize: vertical; } .form-row { display: grid; grid-template-columns: 1fr 1fr; gap: 1rem; } - .save-btn { background: #1e3a5f; color: white; border: none; padding: 12px; border-radius: 12px; font-weight: 600; cursor: pointer; margin-top: 1rem; } + .form-3col { display: grid; grid-template-columns: 1fr 1fr 1fr; gap: 1rem; } + + /* Dynamic links */ + .links-container { border: 1px solid #e2e8f0; border-radius: 12px; padding: 0.75rem; background: #fafcff; } + .link-input-group { display: flex; gap: 8px; margin-bottom: 8px; align-items: center; } + .link-input-group input { flex: 1; } + .remove-link-btn { background: #fee2e2; color: #dc2626; border: none; width: 32px; height: 32px; border-radius: 8px; cursor: pointer; } + .remove-link-btn:hover { background: #fecaca; } + .add-link-btn { background: #e2e8f0; border: none; padding: 6px 12px; border-radius: 8px; cursor: pointer; font-size: 0.8rem; margin-top: 8px; } + .add-link-btn:hover { background: #cbd5e1; } + + .btn-group { display: flex; flex-direction: column; gap: 0.75rem; margin-top: 1rem; } + .save-btn { background: #1e3a5f; color: white; border: none; padding: 12px; border-radius: 12px; font-weight: 600; cursor: pointer; } .save-btn:hover { background: #0f2b40; } - .delete-btn { background: #dc2626; color: white; border: none; padding: 12px; border-radius: 12px; font-weight: 600; cursor: pointer; margin-top: 0.5rem; } + .delete-btn { background: #dc2626; color: white; border: none; padding: 12px; border-radius: 12px; font-weight: 600; cursor: pointer; } .delete-btn:hover { background: #b91c1c; } - .add-btn { background: #10b981; color: white; border: none; padding: 12px; border-radius: 12px; font-weight: 600; cursor: pointer; margin-top: 0.5rem; } + .add-btn { background: #10b981; color: white; border: none; padding: 12px; border-radius: 12px; font-weight: 600; cursor: pointer; } .add-btn:hover { background: #059669; } + .move-btn { background: #f59e0b; color: white; border: none; padding: 12px; border-radius: 12px; font-weight: 600; cursor: pointer; } + .move-btn:hover { background: #d97706; } + .reset-btn { background: #e2e8f0; color: #1e293b; border: none; padding: 12px; border-radius: 12px; font-weight: 600; cursor: pointer; } + .reset-btn:hover { background: #cbd5e1; } .toast { position: fixed; bottom: 80px; right: 30px; background: #15803d; color: white; padding: 12px 20px; border-radius: 50px; z-index: 1002; display: none; } .toast.error { background: #dc2626; } @@ -82,22 +116,42 @@ .summary-wrapper { overflow-x: auto; background: white; border-radius: 24px; } .summary-table { width: 100%; border-collapse: collapse; } .summary-table th { background: #f1f5f9; padding: 14px; text-align: left; font-weight: 600; font-size: 0.85rem; } - .summary-table td { padding: 14px; border-bottom: 1px solid #eef2f8; font-size: 0.85rem; } + .summary-table td { padding: 14px; border-bottom: 1px solid #eef2f8; font-size: 0.85rem; vertical-align: middle; } + .summary-table tr:hover { background: #fafcff; } + .action-btns { display: flex; gap: 8px; flex-wrap: wrap; } + .edit-row-btn, .move-to-main-btn, .move-to-additional-btn, .delete-row-btn { + background: none; border: none; cursor: pointer; font-size: 1rem; padding: 4px 8px; + border-radius: 8px; transition: all 0.2s; + } + .edit-row-btn { color: #1e3a5f; } + .edit-row-btn:hover { background: #eef2ff; } + .move-to-main-btn { color: #10b981; } + .move-to-main-btn:hover { background: #dcfce7; } + .move-to-additional-btn { color: #f59e0b; } + .move-to-additional-btn:hover { background: #fef3c7; } + .delete-row-btn { color: #dc2626; } + .delete-row-btn:hover { background: #fee2e2; } + .footer-note { margin-top: 2rem; text-align: center; font-size: 0.75rem; color: #6c86a3; } .loading { text-align: center; padding: 3rem; color: #64748b; } - @media (max-width: 600px) { .admin-panel { width: 100%; right: -100%; } .form-row { grid-template-columns: 1fr; } } + @media (max-width: 750px) { + .admin-panel { width: 100%; right: -100%; } + .form-row, .form-3col { grid-template-columns: 1fr; } + .info-grid { grid-template-columns: 1fr; } + .action-btns { flex-direction: column; gap: 4px; } + }

Бизнес-объединения ДНР

-

Аналитический обзор + Админ-панель (данные хранятся в data.json)

+

Аналитический обзор с расширенной информацией по основным организациям

- +
@@ -108,14 +162,16 @@
- - + + +
НазваниеТипСтатусЧленствоПриоритетРесурс
Загрузка...
НазваниеТипСтатусЧленствоПриоритетРесурсДействия
Загрузка...
@@ -131,8 +187,8 @@
- - + +
@@ -160,14 +216,68 @@
+ +
- - + +
+ +
- - + +
+ + + +
@@ -180,10 +290,24 @@
- - - - +
+
+ + +
+
+ + +
+
+ +
+ + + + + +
✅ Данные сохранены
@@ -192,6 +316,7 @@ let currentData = null; let currentEditId = null; let currentEditType = 'main'; + let currentLinks = []; // Массив ссылок для текущей организации function showToast(msg, isError = false) { const toast = document.getElementById('toast'); @@ -206,6 +331,8 @@ const response = await fetch('/data.json'); if (!response.ok) throw new Error('Ошибка загрузки'); currentData = await response.json(); + if (!currentData.organizations) currentData.organizations = []; + if (!currentData.additionalOrganizations) currentData.additionalOrganizations = []; renderDetailed(); renderSummaryTable(); initAdminSelect(); @@ -236,6 +363,19 @@ } } + async function saveAndRefresh() { + const success = await saveDataToServer(); + if (success) { + await loadDataFromServer(); + } + return success; + } + + function renderLinks(links) { + if (!links || links.length === 0) return ''; + return ``; + } + function renderDetailed() { const container = document.getElementById('detailedContainer'); if (!currentData) return; @@ -244,58 +384,255 @@ const d = org.detailed || {}; const priorityText = org.priority === 'high' ? 'Высокий' : (org.priority === 'medium' ? 'Средний' : 'Низкий'); const statusClass = org.status === 'active' ? 'status-active' : 'status-warning'; - const statusText = org.status === 'active' ? '✔ Действует' : 'Требует уточнения'; + const statusText = org.status === 'active' ? '✔ Действует' : '⚠️ Требует уточнения'; + + // Получаем ссылки из org.resources или org.links + const links = org.resources?.links || org.links || []; + const card = document.createElement('div'); card.className = 'org-card'; card.innerHTML = `
${escapeHtml(org.name)} - Приоритет: ${priorityText} + ⭐ Приоритет: ${priorityText} ${statusText}
-
-
Руководитель
${escapeHtml(d.leadership?.head || '—')}
-
Цели
${escapeHtml(d.goals || '—')}
-
Активность
${escapeHtml(d.activity || '—')}
-
Членство
${escapeHtml(org.summaryMembership || '—')}
+
+
Общая информация
+
+
📌 Полное наименование
${escapeHtml(d.general?.fullName || org.name)}
+
📅 Дата создания
${escapeHtml(d.general?.created || 'Не указана')}
+
🏛️ Юридическая форма
${escapeHtml(d.general?.legalForm || 'Не указана')}
+
📍 Адрес
${escapeHtml(d.general?.address || 'Не указан')}
+
📊 Статус
${escapeHtml(d.general?.statusText || 'Действует')}
+
🔗 Ресурсы
${renderLinks(links)}
+
+
+ +
+
Руководство и структура
+
+
👤 Руководитель
${escapeHtml(d.leadership?.head || '—')}
+
👥 Ключевые лица
${escapeHtml(d.leadership?.keyPeople || '—')}
+
🏢 Отделения
${escapeHtml(d.leadership?.branches || '—')}
+
+
+ +
+
Членство и состав
+
+
👥 Количество членов
${escapeHtml(org.membersCount || d.membership?.count || org.summaryMembership || '—')}
+
📋 Критерии вступления
${escapeHtml(d.membership?.criteria || '—')}
+
💰 Членские взносы
${escapeHtml(d.membership?.fees || '—')}
+
🏭 Отраслевой состав
${renderTags(d.membership?.sectors || org.sectors || '—')}
+
+
+ +
+
Деятельность и влияние
+
+
🎯 Цели и задачи
${escapeHtml(d.goals || '—')}
+
⚡ Основная деятельность
${escapeHtml(d.activity || '—')}
+
📧 Контакты
${escapeHtml(d.resources?.contacts || '—')}
+
+
+ +
+
SWOT-анализ
+
+
✅ Сильные стороны
${escapeHtml(d.assessment?.strengths || '—')}
+
⚠️ Слабые стороны
${escapeHtml(d.assessment?.weaknesses || '—')}
+
🎯 Рекомендации
${escapeHtml(d.assessment?.priority || '—')}
+
-
-
${escapeHtml(org.link)}
`; container.appendChild(card); }); } + function renderTags(tagsStr) { + if (!tagsStr || tagsStr === '—') return ''; + const tags = tagsStr.split(',').map(t => t.trim()); + return tags.map(tag => `${escapeHtml(tag)}`).join(''); + } + function renderSummaryTable() { const tbody = document.getElementById('summaryTableBody'); if (!currentData) return; tbody.innerHTML = ''; - const mainOrgs = (currentData.organizations || []).map(o => ({ ...o, displayType: o.shortType || 'Основная' })); - const additionalOrgs = (currentData.additionalOrganizations || []).map(a => ({ ...a, displayType: a.type || 'Дополнительная' })); - const allOrgs = [...mainOrgs, ...additionalOrgs]; - allOrgs.forEach(org => { - const statusClass = org.status === 'active' ? 'status-active' : 'status-warning'; - const statusText = org.status === 'active' ? 'Действует' : 'Требует уточнения'; - const priorityText = org.priority === 'high' ? 'Высокий' : (org.priority === 'medium' ? 'Средний' : 'Низкий'); - const row = document.createElement('tr'); - row.innerHTML = ` - ${escapeHtml(org.name)} - ${escapeHtml(org.displayType || org.type || '—')} - ${statusText} - ${escapeHtml(org.members || org.summaryMembership || '—')} - ${priorityText} - ${org.link && org.link !== '—' ? `ресурс` : '—'} + (currentData.organizations || []).forEach(org => { appendSummaryRow(tbody, org, 'main'); }); + (currentData.additionalOrganizations || []).forEach(org => { appendSummaryRow(tbody, org, 'additional'); }); + } + + function appendSummaryRow(tbody, org, type) { + const statusClass = org.status === 'active' ? 'status-active' : 'status-warning'; + const statusText = org.status === 'active' ? 'Действует' : 'Требует уточнения'; + const priorityText = org.priority === 'high' ? 'Высокий' : (org.priority === 'medium' ? 'Средний' : 'Низкий'); + const displayType = type === 'main' ? (org.shortType || 'Основная') : (org.type || 'Дополнительная'); + const members = org.membersCount || (type === 'main' ? (org.summaryMembership || '—') : (org.members || '—')); + + const row = document.createElement('tr'); + row.setAttribute('data-id', org.id); + row.setAttribute('data-type', type); + row.innerHTML = ` + ${escapeHtml(org.name)} + ${escapeHtml(displayType)} + ${statusText} + ${escapeHtml(members)} + ${priorityText} + ${org.link && org.link !== '—' ? `ресурс` : '—'} + + + ${type === 'additional' ? + `` : + `` + } + + + `; + tbody.appendChild(row); + } + + // Функции для работы со ссылками + function renderLinkInputs() { + const container = document.getElementById('linksList'); + container.innerHTML = ''; + currentLinks.forEach((link, index) => { + const div = document.createElement('div'); + div.className = 'link-input-group'; + div.innerHTML = ` + + `; - tbody.appendChild(row); + container.appendChild(div); + }); + + // Добавляем обработчики удаления + document.querySelectorAll('.remove-link-btn').forEach(btn => { + btn.addEventListener('click', (e) => { + const idx = parseInt(btn.dataset.index); + currentLinks.splice(idx, 1); + renderLinkInputs(); + }); + }); + + // Добавляем обработчики изменения + document.querySelectorAll('.link-input').forEach((input, idx) => { + input.addEventListener('change', (e) => { + currentLinks[idx] = e.target.value; + }); }); } + function collectLinks() { + const inputs = document.querySelectorAll('.link-input'); + const links = []; + inputs.forEach(input => { + if (input.value.trim()) { + links.push(input.value.trim()); + } + }); + return links; + } + + window.editOrganization = function(type, id) { + currentEditType = type; + currentEditId = id; + document.getElementById('adminPanel').classList.add('open'); + document.getElementById('overlay').classList.add('show'); + document.querySelector(`input[name="orgTypeRadio"][value="${type}"]`).checked = true; + toggleMainFields(type === 'main'); + initAdminSelect(); + const select = document.getElementById('orgSelect'); + select.value = `${type}|${id}`; + populateAdminForm(); + }; + + function toggleMainFields(show) { + const fields = document.getElementById('mainOrgFields'); + fields.style.display = show ? 'block' : 'none'; + } + + window.moveToMain = async function(id) { + const org = currentData.additionalOrganizations?.find(a => a.id === id); + if (!org) return; + + const newMainOrg = { + id: org.id, + name: org.name, + priority: org.priority, + status: org.status, + shortType: org.type || 'Организация', + membersCount: org.members || org.membersCount || 'Данные отсутствуют', + link: org.link || '', + sectors: org.sectors || '', + resources: { links: org.links || [] }, + detailed: { + general: { fullName: org.name, created: '', legalForm: '', address: '', statusText: 'Действует' }, + leadership: { head: org.detailed?.leadership?.head || '', keyPeople: '', branches: '' }, + membership: { count: org.members || 'Данные отсутствуют', criteria: '', fees: '', sectors: org.sectors || '' }, + goals: org.detailed?.goals || '', + activity: org.detailed?.activity || '', + resources: { contacts: '' }, + assessment: { strengths: '', weaknesses: '', priority: '' } + } + }; + + currentData.additionalOrganizations = currentData.additionalOrganizations.filter(a => a.id !== id); + currentData.organizations.push(newMainOrg); + await saveAndRefresh(); + showToast(`✅ "${org.name}" перемещена в основные`); + }; + + window.moveToAdditional = async function(id) { + const org = currentData.organizations?.find(o => o.id === id); + if (!org) return; + + const newAdditionalOrg = { + id: org.id, + name: org.name, + priority: org.priority, + status: org.status, + type: org.shortType || 'Основная', + members: org.membersCount || org.summaryMembership || 'Данные отсутствуют', + link: org.link || '', + sectors: org.sectors || '', + links: org.resources?.links || [], + detailed: { + leadership: { head: org.detailed?.leadership?.head || '' }, + goals: org.detailed?.goals || '', + activity: org.detailed?.activity || '', + assessment: { strengths: org.detailed?.assessment?.strengths || '', weaknesses: org.detailed?.assessment?.weaknesses || '' } + } + }; + + currentData.organizations = currentData.organizations.filter(o => o.id !== id); + currentData.additionalOrganizations.push(newAdditionalOrg); + await saveAndRefresh(); + showToast(`✅ "${org.name}" перемещена в дополнительные`); + }; + + window.deleteOrganization = async function(type, id) { + const name = type === 'main' + ? currentData.organizations?.find(o => o.id === id)?.name + : currentData.additionalOrganizations?.find(a => a.id === id)?.name; + if (!confirm(`Удалить "${name}"?`)) return; + + if (type === 'main') { + currentData.organizations = currentData.organizations.filter(o => o.id !== id); + } else { + currentData.additionalOrganizations = currentData.additionalOrganizations.filter(a => a.id !== id); + } + await saveAndRefresh(); + showToast(`🗑️ "${name}" удалена`); + }; + function initAdminSelect() { const select = document.getElementById('orgSelect'); select.innerHTML = ''; @@ -314,6 +651,7 @@ const [type, id] = e.target.value.split('|'); currentEditType = type; currentEditId = parseInt(id); + toggleMainFields(type === 'main'); populateAdminForm(); document.querySelector(`input[name="orgTypeRadio"][value="${type}"]`).checked = true; }); @@ -331,49 +669,95 @@ document.getElementById('orgName').value = org.name || ''; document.getElementById('orgPriority').value = org.priority || 'medium'; document.getElementById('orgStatus').value = org.status || 'active'; - document.getElementById('orgType').value = org.shortType || org.type || ''; - document.getElementById('orgMembership').value = org.summaryMembership || org.members || ''; - document.getElementById('orgLink').value = org.link || ''; + document.getElementById('orgType').value = currentEditType === 'main' ? (org.shortType || '') : (org.type || ''); + + // Количество членов + const membersCount = org.membersCount || (currentEditType === 'main' ? org.summaryMembership : org.members) || ''; + document.getElementById('orgMembersCount').value = membersCount; + + // Ссылки + currentLinks = org.resources?.links || org.links || []; + if (currentLinks.length === 0 && org.link) currentLinks = [org.link]; + renderLinkInputs(); + + if (currentEditType === 'main') { + const d = org.detailed || {}; + document.getElementById('orgFullName').value = d.general?.fullName || ''; + document.getElementById('orgCreated').value = d.general?.created || ''; + document.getElementById('orgLegalForm').value = d.general?.legalForm || ''; + document.getElementById('orgAddress').value = d.general?.address || ''; + document.getElementById('orgKeyPeople').value = d.leadership?.keyPeople || ''; + document.getElementById('orgSectors').value = d.membership?.sectors || org.sectors || ''; + document.getElementById('orgCriteria').value = d.membership?.criteria || ''; + document.getElementById('orgFees').value = d.membership?.fees || ''; + document.getElementById('orgContacts').value = d.resources?.contacts || ''; + } + document.getElementById('orgHead').value = org.detailed?.leadership?.head || ''; document.getElementById('orgGoals').value = org.detailed?.goals || ''; document.getElementById('orgActivity').value = org.detailed?.activity || ''; + document.getElementById('orgStrengths').value = org.detailed?.assessment?.strengths || ''; + document.getElementById('orgWeaknesses').value = org.detailed?.assessment?.weaknesses || ''; } function updateOrgFromForm() { let org = null; if (currentEditType === 'main') { org = currentData.organizations?.find(o => o.id === currentEditId); + if (!org) return; + + org.name = document.getElementById('orgName').value; + org.priority = document.getElementById('orgPriority').value; + org.status = document.getElementById('orgStatus').value; + org.shortType = document.getElementById('orgType').value; + org.membersCount = document.getElementById('orgMembersCount').value; + + // Сохраняем ссылки + org.resources = org.resources || {}; + org.resources.links = collectLinks(); + + if (!org.detailed) org.detailed = {}; + if (!org.detailed.general) org.detailed.general = {}; + if (!org.detailed.leadership) org.detailed.leadership = {}; + if (!org.detailed.membership) org.detailed.membership = {}; + if (!org.detailed.resources) org.detailed.resources = {}; + if (!org.detailed.assessment) org.detailed.assessment = {}; + + org.detailed.general.fullName = document.getElementById('orgFullName').value; + org.detailed.general.created = document.getElementById('orgCreated').value; + org.detailed.general.legalForm = document.getElementById('orgLegalForm').value; + org.detailed.general.address = document.getElementById('orgAddress').value; + org.detailed.leadership.keyPeople = document.getElementById('orgKeyPeople').value; + org.detailed.membership.sectors = document.getElementById('orgSectors').value; + org.detailed.membership.criteria = document.getElementById('orgCriteria').value; + org.detailed.membership.fees = document.getElementById('orgFees').value; + org.detailed.resources.contacts = document.getElementById('orgContacts').value; + org.detailed.leadership.head = document.getElementById('orgHead').value; + org.detailed.goals = document.getElementById('orgGoals').value; + org.detailed.activity = document.getElementById('orgActivity').value; + org.detailed.assessment.strengths = document.getElementById('orgStrengths').value; + org.detailed.assessment.weaknesses = document.getElementById('orgWeaknesses').value; } else { org = currentData.additionalOrganizations?.find(a => a.id === currentEditId); - } - if (!org) return; + if (!org) return; - org.name = document.getElementById('orgName').value; - org.priority = document.getElementById('orgPriority').value; - org.status = document.getElementById('orgStatus').value; - - if (currentEditType === 'main') { - org.shortType = document.getElementById('orgType').value; - org.summaryMembership = document.getElementById('orgMembership').value; - } else { + org.name = document.getElementById('orgName').value; + org.priority = document.getElementById('orgPriority').value; + org.status = document.getElementById('orgStatus').value; org.type = document.getElementById('orgType').value; - org.members = document.getElementById('orgMembership').value; + org.members = document.getElementById('orgMembersCount').value; + org.links = collectLinks(); + + if (!org.detailed) org.detailed = { leadership: {}, assessment: {} }; + org.detailed.leadership.head = document.getElementById('orgHead').value; + org.detailed.goals = document.getElementById('orgGoals').value; + org.detailed.activity = document.getElementById('orgActivity').value; + if (!org.detailed.assessment) org.detailed.assessment = {}; + org.detailed.assessment.strengths = document.getElementById('orgStrengths').value; + org.detailed.assessment.weaknesses = document.getElementById('orgWeaknesses').value; } - org.link = document.getElementById('orgLink').value; - if (!org.detailed) org.detailed = { leadership: {} }; - if (!org.detailed.leadership) org.detailed.leadership = {}; - org.detailed.leadership.head = document.getElementById('orgHead').value; - org.detailed.goals = document.getElementById('orgGoals').value; - org.detailed.activity = document.getElementById('orgActivity').value; - - saveDataToServer().then(success => { - if (success) { - renderDetailed(); - renderSummaryTable(); - initAdminSelect(); - } - }); + saveAndRefresh().then(() => { initAdminSelect(); }); } async function addNewOrganization() { @@ -389,37 +773,42 @@ status: "active", type: "Новый тип", members: "Данные отсутствуют", + membersCount: "Данные отсутствуют", link: "", + links: [], detailed: { leadership: { head: "" }, goals: "", - activity: "" + activity: "", + assessment: { strengths: "", weaknesses: "" } } }; - // По умолчанию добавляем в дополнительную категорию if (!currentData.additionalOrganizations) currentData.additionalOrganizations = []; currentData.additionalOrganizations.push(newOrg); - - await saveDataToServer(); - await loadDataFromServer(); - showToast('➕ Новая организация добавлена'); + await saveAndRefresh(); + showToast('➕ Новая организация добавлена в дополнительные'); } async function deleteCurrentOrganization() { if (!confirm(`Удалить "${document.getElementById('orgName').value}"?`)) return; - if (currentEditType === 'main') { currentData.organizations = currentData.organizations.filter(o => o.id !== currentEditId); } else { currentData.additionalOrganizations = currentData.additionalOrganizations.filter(a => a.id !== currentEditId); } - - await saveDataToServer(); - await loadDataFromServer(); + await saveAndRefresh(); showToast('🗑️ Организация удалена'); } + async function moveCurrentOrganization() { + if (currentEditType === 'main') { + await moveToAdditional(currentEditId); + } else { + await moveToMain(currentEditId); + } + } + async function resetToDefault() { if (confirm('Сбросить все данные к исходным? Все изменения будут потеряны.')) { try { @@ -457,6 +846,7 @@ adminPanel.classList.add('open'); overlay.classList.add('show'); initAdminSelect(); + toggleMainFields(currentEditType === 'main'); }); function closeAdmin() { adminPanel.classList.remove('open'); overlay.classList.remove('show'); } document.getElementById('closeAdminBtn').addEventListener('click', closeAdmin); @@ -464,11 +854,17 @@ document.getElementById('editForm').addEventListener('submit', (e) => { e.preventDefault(); updateOrgFromForm(); }); document.getElementById('addNewBtn').addEventListener('click', addNewOrganization); document.getElementById('deleteOrgBtn').addEventListener('click', deleteCurrentOrganization); + document.getElementById('moveOrgBtn').addEventListener('click', moveCurrentOrganization); document.getElementById('resetDataBtn').addEventListener('click', resetToDefault); + document.getElementById('addLinkBtn').addEventListener('click', () => { + currentLinks.push(''); + renderLinkInputs(); + }); document.querySelectorAll('input[name="orgTypeRadio"]').forEach(radio => { radio.addEventListener('change', (e) => { if (e.target.checked) { + toggleMainFields(e.target.value === 'main'); const select = document.getElementById('orgSelect'); const options = Array.from(select.options); const matchingOption = options.find(opt => opt.value.startsWith(e.target.value + '|'));