let currentTab = 'biot';
let currentSubtab = null;
let events = { biot: [], ctpsr_main: [], gloves: [] };
let currentFilter = 'все';
async function loadEvents() {
try {
const [biotRes, ctpsrRes, glovesRes] = await Promise.all([
fetch('/api/events?tab=biot'),
fetch('/api/events?tab=ctpsr_main'),
fetch('/api/events?tab=gloves')
]);
events.biot = await biotRes.json();
events.ctpsr_main = await ctpsrRes.json();
events.gloves = await glovesRes.json();
console.log('Loaded events:', { biot: events.biot.length, ctpsr_main: events.ctpsr_main.length, gloves: events.gloves.length });
} catch (e) {
console.error('Ошибка загрузки:', e);
}
}
function switchTab(tab) {
currentTab = tab;
document.querySelectorAll('.tab').forEach(function(t) { t.classList.remove('active'); });
var activeBtn = document.querySelector('.tab[onclick="switchTab(\'' + tab + '\')"]');
if (activeBtn) activeBtn.classList.add('active');
var subtabsContainer = document.getElementById('subtabs');
if (tab === 'ctpsr') {
subtabsContainer.style.display = 'flex';
currentSubtab = 'ctpsr_main';
document.getElementById('page-title').textContent = 'Информация по ЦТПСР';
} else {
subtabsContainer.style.display = 'none';
currentSubtab = null;
document.getElementById('page-title').textContent = tab === 'biot' ? 'Информация по БиОТ' : 'Мероприятия';
}
console.log('switchTab:', tab, 'currentSubtab:', currentSubtab);
render();
}
function switchSubtab(subtab) {
currentSubtab = subtab;
document.querySelectorAll('.subtab').forEach(function(t) { t.classList.remove('active'); });
var activeBtn = document.querySelector('.subtab[onclick="switchSubtab(\'' + subtab + '\')"]');
if (activeBtn) activeBtn.classList.add('active');
console.log('switchSubtab:', subtab);
render();
}
function escapeHtml(text) {
if (!text) return '';
var div = document.createElement('div');
div.textContent = text;
return div.innerHTML;
}
function formatDate(dateStr) {
if (!dateStr) return '';
var d = new Date(dateStr);
return d.toLocaleDateString('ru-RU', { day: 'numeric', month: 'long', year: 'numeric' });
}
function setFilter(status) {
currentFilter = status;
render();
}
function render() {
var search = document.getElementById('search').value.toLowerCase();
var key = currentSubtab || currentTab;
var currentEvents = events[key] || [];
var isGloves = key === 'gloves';
console.log('render key:', key, 'events count:', currentEvents.length);
var filtered;
if (isGloves) {
filtered = currentEvents.filter(function(e) {
return (e.quantity && e.quantity.toLowerCase().includes(search)) ||
(e.location && e.location.toLowerCase().includes(search)) ||
(e.responsible && e.responsible.toLowerCase().includes(search));
});
} else {
filtered = currentEvents.filter(function(e) {
var matchSearch = e.title.toLowerCase().includes(search) ||
(e.description && e.description.toLowerCase().includes(search)) ||
(e.organizer && e.organizer.toLowerCase().includes(search));
var matchFilter = currentFilter === 'все' || e.status === currentFilter;
return matchSearch && matchFilter;
});
}
var statsEl = document.getElementById('stats');
var chipsEl = document.getElementById('chips');
if (!isGloves) {
var statuses = ['запланировано', 'в процессе', 'завершено', 'отменено'];
var counts = { все: currentEvents.length };
statuses.forEach(function(s) { counts[s] = currentEvents.filter(function(ev) { return ev.status === s; }).length; });
statsEl.innerHTML = `
${counts['запланировано']}
Запланировано
${counts['в процессе']}
В процессе
${counts['завершено']}
Завершено
`;
chipsEl.innerHTML = ['все', ...statuses].map(function(s) {
return `
${s.charAt(0).toUpperCase() + s.slice(1)} (${counts[s] || 0})
`;
}).join('');
} else {
statsEl.innerHTML = '';
chipsEl.innerHTML = '';
}
var container = document.getElementById('events');
if (filtered.length === 0) {
container.innerHTML = `
Нет записей
Нажмите «Добавить», чтобы создать первую запись
`;
return;
}
if (isGloves) {
container.innerHTML = `
| Количество |
Место эксплуатации |
Ответственное лицо |
Последнее испытание |
Следующее испытание |
Срок (мес) |
Действия |
${filtered.map(function(e) {
return `
| ${escapeHtml(e.quantity || '')} |
${escapeHtml(e.location || '')} |
${escapeHtml(e.responsible || '')} |
${e.lastTestDate ? formatDate(e.lastTestDate) : ''} |
${e.nextTestDate ? formatDate(e.nextTestDate) : ''} |
${e.expiryMonths ? e.expiryMonths + ' мес.' : ''} |
|
`;
}).join('')}
`;
} else {
container.innerHTML = filtered.map(function(e) {
return `
${e.date ? `📅 ${formatDate(e.date)}` : ''}
${e.time ? `⏰ ${e.time}` : ''}
${e.location ? `📍 ${escapeHtml(e.location)}` : ''}
${e.organizer ? `👤 ${escapeHtml(e.organizer)}` : ''}
${e.description ? `
${escapeHtml(e.description)}
` : ''}
`;
}).join('');
}
}
function openModal(editId = null) {
var modal = document.getElementById('modal');
var form = document.getElementById('form');
var title = document.getElementById('modal-title');
console.log('=== OPEN MODAL ===');
console.log('currentTab:', currentTab, 'currentSubtab:', currentSubtab);
form.reset();
document.getElementById('eventId').value = '';
var key = currentSubtab || currentTab;
var isGloves = key === 'gloves';
console.log('key:', key, 'isGloves:', isGloves);
var glovesFields = document.getElementById('gloves-fields');
var eventFields = document.getElementById('event-fields');
glovesFields.style.display = isGloves ? 'block' : 'none';
eventFields.style.display = isGloves ? 'none' : 'block';
// Убираем required у скрытых полей
var glovesInputs = glovesFields.querySelectorAll('input, textarea');
var eventInputs = eventFields.querySelectorAll('input, textarea, select');
glovesInputs.forEach(function(input) {
input.required = isGloves && input.id !== 'notes';
});
eventInputs.forEach(function(input) {
input.required = !isGloves;
});
if (editId) {
var item = events[key].find(function(e) { return e.id === editId; });
if (item) {
title.textContent = isGloves ? 'Изменить запись' : 'Изменить мероприятие';
document.getElementById('eventId').value = item.id;
if (isGloves) {
document.getElementById('quantity').value = item.quantity || '';
document.getElementById('location').value = item.location || '';
document.getElementById('responsible').value = item.responsible || '';
document.getElementById('lastTestDate').value = item.lastTestDate || '';
document.getElementById('nextTestDate').value = item.nextTestDate || '';
document.getElementById('expiryMonths').value = item.expiryMonths || '';
document.getElementById('notes').value = item.notes || '';
} else {
document.getElementById('title').value = item.title;
document.getElementById('date').value = item.date;
document.getElementById('time').value = item.time || '';
document.getElementById('eventLocation').value = item.location || '';
document.getElementById('organizer').value = item.organizer || '';
document.getElementById('status').value = item.status;
document.getElementById('description').value = item.description || '';
}
}
} else {
title.textContent = isGloves ? 'Добавить перчатки' : 'Добавить мероприятие';
}
modal.classList.add('on');
}
function closeModal() {
document.getElementById('modal').classList.remove('on');
}
function editEvent(id) {
openModal(id);
}
function addNew() {
openModal(null);
}
async function deleteEvent(id) {
if (!confirm('Вы уверены, что хотите удалить эту запись?')) return;
var key = currentSubtab || currentTab;
await fetch('/api/events/' + id + '?tab=' + key, { method: 'DELETE' });
await loadEvents();
render();
}
document.getElementById('form').addEventListener('submit', async function(e) {
e.preventDefault();
var id = document.getElementById('eventId').value;
var key = currentSubtab || currentTab;
var isGloves = key === 'gloves';
var btn = e.target.querySelector('button[type="submit"]');
var originalText = btn.textContent;
console.log('=== FORM SUBMIT ===');
console.log('key:', key, 'isGloves:', isGloves, 'currentSubtab:', currentSubtab, 'currentTab:', currentTab);
// Временно убираем required у всех полей, чтобы браузер не блокировал
var allInputs = e.target.querySelectorAll('input, textarea, select');
var requiredBackup = [];
allInputs.forEach(function(input, i) {
requiredBackup[i] = input.required;
input.required = false;
});
btn.textContent = 'Сохранение...';
btn.disabled = true;
var data = isGloves ? {
quantity: document.getElementById('quantity').value,
location: document.getElementById('location').value,
responsible: document.getElementById('responsible').value,
lastTestDate: document.getElementById('lastTestDate').value,
nextTestDate: document.getElementById('nextTestDate').value,
expiryMonths: document.getElementById('expiryMonths').value,
notes: document.getElementById('notes').value
} : {
title: document.getElementById('title').value,
date: document.getElementById('date').value,
time: document.getElementById('time').value,
location: document.getElementById('eventLocation').value,
organizer: document.getElementById('organizer').value,
status: document.getElementById('status').value,
description: document.getElementById('description').value
};
console.log('Data to save:', data);
var url = id ? '/api/events/' + id + '?tab=' + key : '/api/events?tab=' + key;
console.log('POST to:', url);
try {
var response = await fetch(url, {
method: id ? 'PUT' : 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(data)
});
var responseText = await response.text();
console.log('Response status:', response.status, 'body:', responseText);
if (!response.ok) {
throw new Error('Сервер вернул ' + response.status + ': ' + responseText);
}
var result = JSON.parse(responseText);
console.log('Server response:', result);
// Возвращаем required обратно
allInputs.forEach(function(input, i) {
input.required = requiredBackup[i];
});
closeModal();
await loadEvents();
render();
alert('✓ Запись сохранена!');
} catch (error) {
// Возвращаем required обратно
allInputs.forEach(function(input, i) {
input.required = requiredBackup[i];
});
console.error('Error saving:', error);
alert('Ошибка сохранения: ' + error.message);
} finally {
btn.textContent = originalText;
btn.disabled = false;
}
});
document.getElementById('modal').addEventListener('click', function(e) {
if (e.target === e.currentTarget) closeModal();
});
loadEvents();