// Демо-данные для первого запуска const DEMO_DATA = [ { id: 1, submitter: "Алия К.", description: "Закупка СИЗ для склада", deadline: "2026-09-10", status: "Новая", dateCreated: "2026-09-01" }, { id: 2, submitter: "Ержан М.", description: "Ремонт серверной", deadline: "2026-09-15", status: "В работе", dateCreated: "2026-09-02" }, { id: 3, submitter: "Данияр С.", description: "Выдача пропуска", deadline: "2026-09-05", status: "Выполнено", dateCreated: "2026-09-01" }, { id: 4, submitter: "Гульнара Т.", description: "Обновление ПО на компьютерах", deadline: "2026-09-20", status: "Новая", dateCreated: "2026-09-03" }, { id: 5, submitter: "Серик Б.", description: "Замена картриджа в принтере", deadline: "2026-09-08", status: "В работе", dateCreated: "2026-09-02" } ]; // Ключи localStorage const KEY_REQUESTS = "requests_data"; const KEY_HISTORY = "requests_history"; // Состояние let requests = []; let history = []; let currentFilter = "all"; let searchQuery = ""; // Инициализация document.addEventListener("DOMContentLoaded", () => { loadData(); setupEventListeners(); render(); }); // Загрузка данных function loadData() { const storedRequests = localStorage.getItem(KEY_REQUESTS); if (storedRequests) { requests = JSON.parse(storedRequests); } else { requests = [...DEMO_DATA]; saveData(); } const storedHistory = localStorage.getItem(KEY_HISTORY); if (storedHistory) { history = JSON.parse(storedHistory); } } // Сохранение данных function saveData() { localStorage.setItem(KEY_REQUESTS, JSON.stringify(requests)); } function saveHistory() { localStorage.setItem(KEY_HISTORY, JSON.stringify(history)); } // Настройка обработчиков function setupEventListeners() { document.getElementById("btn-add").addEventListener("click", openModal); document.getElementById("modal-close").addEventListener("click", closeModal); document.getElementById("form-cancel").addEventListener("click", closeModal); document.getElementById("modal-overlay").addEventListener("click", (e) => { if (e.target === document.getElementById("modal-overlay")) closeModal(); }); document.getElementById("request-form").addEventListener("submit", handleFormSubmit); document.getElementById("search-input").addEventListener("input", (e) => { searchQuery = e.target.value.toLowerCase(); renderTable(); }); document.getElementById("btn-export").addEventListener("click", exportToExcel); document.getElementById("btn-history").addEventListener("click", openHistory); document.getElementById("history-close").addEventListener("click", closeHistory); document.getElementById("history-overlay").addEventListener("click", (e) => { if (e.target === document.getElementById("history-overlay")) closeHistory(); }); document.querySelectorAll(".chip").forEach(chip => { chip.addEventListener("click", () => { document.querySelectorAll(".chip").forEach(c => c.classList.remove("active")); chip.classList.add("active"); currentFilter = chip.dataset.status; renderTable(); }); }); } // Открытие модального окна function openModal(editId = null) { const modal = document.getElementById("modal-overlay"); const title = document.getElementById("modal-title"); const form = document.getElementById("request-form"); form.reset(); document.getElementById("form-id").value = ""; if (editId) { const req = requests.find(r => r.id === editId); if (req) { title.textContent = "Изменить заявку"; document.getElementById("form-id").value = req.id; document.getElementById("form-submitter").value = req.submitter; document.getElementById("form-description").value = req.description; document.getElementById("form-deadline").value = req.deadline; document.getElementById("form-status").value = req.status; } } else { title.textContent = "Добавить заявку"; } modal.classList.add("active"); } // Закрытие модального окна function closeModal() { document.getElementById("modal-overlay").classList.remove("active"); } // Обработка формы function handleFormSubmit(e) { e.preventDefault(); const id = document.getElementById("form-id").value; const submitter = document.getElementById("form-submitter").value.trim(); const description = document.getElementById("form-description").value.trim(); const deadline = document.getElementById("form-deadline").value; const status = document.getElementById("form-status").value; if (id) { // Редактирование const index = requests.findIndex(r => r.id === parseInt(id)); if (index !== -1) { requests[index] = { ...requests[index], submitter, description, deadline, status }; addToHistory(`Изменена заявка #${id}: ${description}`, "Текущий пользователь"); } } else { // Создание const newId = Date.now(); requests.push({ id: newId, submitter, description, deadline, status, dateCreated: new Date().toISOString().split("T")[0] }); addToHistory(`Добавлена заявка #${newId}: ${description}`, "Текущий пользователь"); } saveData(); closeModal(); render(); } // Добавление в историю function addToHistory(action, who) { const now = new Date(); history.unshift({ datetime: now.toLocaleString("ru-RU"), action, who }); saveHistory(); } // Удаление заявки function deleteRequest(id) { const req = requests.find(r => r.id === id); if (!req) return; if (confirm(`Вы уверены, что хотите удалить заявку #${id}?\n\n${req.description}`)) { requests = requests.filter(r => r.id !== id); addToHistory(`Удалена заявка #${id}: ${req.description}`, "Текущий пользователь"); saveData(); render(); } } // Фильтрация данных function getFilteredData() { let filtered = [...requests]; // Фильтр по статусу if (currentFilter !== "all") { filtered = filtered.filter(r => r.status === currentFilter); } // Поиск if (searchQuery) { filtered = filtered.filter(r => r.submitter.toLowerCase().includes(searchQuery) || r.description.toLowerCase().includes(searchQuery) ); } return filtered; } // Рендеринг function render() { renderStats(); renderTable(); } function renderStats() { const total = requests.length; const newCount = requests.filter(r => r.status === "Новая").length; const progressCount = requests.filter(r => r.status === "В работе").length; const doneCount = requests.filter(r => r.status === "Выполнено").length; const rejectedCount = requests.filter(r => r.status === "Отклонено").length; document.getElementById("stat-total").textContent = total; document.getElementById("stat-new").textContent = newCount; document.getElementById("stat-progress").textContent = progressCount; document.getElementById("stat-done").textContent = doneCount; document.getElementById("stat-rejected").textContent = rejectedCount; } function renderTable() { const tbody = document.getElementById("table-body"); const filtered = getFilteredData(); if (filtered.length === 0) { tbody.innerHTML = `

Нет заявок для отображения

`; return; } tbody.innerHTML = filtered.map((req, index) => { const statusClass = getStatusClass(req.status); const formattedDate = formatDate(req.deadline); return ` ${index + 1} ${escapeHtml(req.submitter)} ${escapeHtml(req.description)} ${formattedDate} ${req.status}
`; }).join(""); } function getStatusClass(status) { switch (status) { case "Новая": return "status-new"; case "В работе": return "status-progress"; case "Выполнено": return "status-done"; case "Отклонено": return "status-rejected"; default: return ""; } } function formatDate(dateStr) { if (!dateStr) return ""; const [year, month, day] = dateStr.split("-"); return `${day}.${month}.${year}`; } function escapeHtml(text) { const div = document.createElement("div"); div.textContent = text; return div.innerHTML; } // Экспорт в Excel (CSV) function exportToExcel() { const filtered = getFilteredData(); if (filtered.length === 0) { alert("Нет данных для экспорта"); return; } const headers = ["№", "Кто подал", "Что нужно", "Срок", "Статус"]; const rows = filtered.map((req, index) => [ index + 1, req.submitter, req.description, formatDate(req.deadline), req.status ]); const csvContent = "\uFEFF" + [ headers.join(";"), ...rows.map(row => row.map(cell => `"${String(cell).replace(/"/g, '""')}"`).join(";")) ].join("\n"); const blob = new Blob([csvContent], { type: "text/csv;charset=utf-8;" }); const link = document.createElement("a"); link.href = URL.createObjectURL(blob); link.download = `zhurnal_zayavok_${new Date().toISOString().split("T")[0]}.csv`; link.click(); URL.revokeObjectURL(link.href); addToHistory("Экспорт данных в Excel", "Текущий пользователь"); } // История function openHistory() { const tbody = document.getElementById("history-body"); if (history.length === 0) { tbody.innerHTML = `

История пуста

`; } else { tbody.innerHTML = history.map(h => ` ${h.datetime} ${escapeHtml(h.action)} ${escapeHtml(h.who)} `).join(""); } document.getElementById("history-overlay").classList.add("active"); } function closeHistory() { document.getElementById("history-overlay").classList.remove("active"); }