const STATUSES = ['Новая', 'В работе', 'На согласовании', 'Готово']; const DEMO_TASKS = [ { id: 1, task: 'Подготовить отчёт по итогам квартала', person: 'Айжан Сәрсен', date: '10.08.2026', priority: 'Высокий', status: 'В работе' }, { id: 2, task: 'Согласовать бюджет на следующий месяц', person: 'Ерлан Нурбек', date: '12.08.2026', priority: 'Критичный', status: 'Новая' }, { id: 3, task: 'Провести обучение сотрудников', person: 'Динара Қуат', date: '14.08.2026', priority: 'Средний', status: 'В работе' }, { id: 4, task: 'Обновить документацию проекта', person: 'Тимур Аскаров', date: '08.08.2026', priority: 'Низкий', status: 'На согласовании' }, { id: 5, task: 'Настроить автоматическую рассылку', person: 'Айжан Сәрсен', date: '05.08.2026', priority: 'Средний', status: 'Новая' }, { id: 6, task: 'Подготовить презентацию для руководства', person: 'Ерлан Нурбек', date: '18.08.2026', priority: 'Высокий', status: 'Готово' }, { id: 7, task: 'Проверить договоры с контрагентами', person: 'Динара Қуат', date: '22.08.2026', priority: 'Средний', status: 'Готово' } ]; let tasks = []; let log = []; let filterStatus = null; function init() { const saved = localStorage.getItem('tasks'); if (saved) { tasks = JSON.parse(saved); } else { tasks = [...DEMO_TASKS]; saveTasks(); } const savedLog = localStorage.getItem('taskLog'); if (savedLog) { log = JSON.parse(savedLog); } else { log = [{ when: new Date().toLocaleString('ru-RU'), what: 'Инициализация демо-данных', who: 'Система' }]; saveLog(); } render(); } function saveTasks() { localStorage.setItem('tasks', JSON.stringify(tasks)); } function saveLog() { localStorage.setItem('taskLog', JSON.stringify(log)); } function addLogEntry(what) { log.unshift({ when: new Date().toLocaleString('ru-RU'), what: what, who: 'Пользователь' }); if (log.length > 50) log.pop(); saveLog(); } function parseDate(dateStr) { const parts = dateStr.split('.'); return new Date(parts[2], parts[1] - 1, parts[0]); } function isOverdue(task) { if (task.status === 'Готово') return false; const taskDate = parseDate(task.date); const today = new Date(); today.setHours(0, 0, 0, 0); return taskDate < today; } function getStatusClass(status) { switch (status) { case 'Новая': return 'status-new'; case 'В работе': return 'status-progress'; case 'На согласовании': return 'status-review'; case 'Готово': return 'status-done'; default: return ''; } } function getPriorityClass(priority) { switch (priority) { case 'Низкий': return 'priority-low'; case 'Средний': return 'priority-medium'; case 'Высокий': return 'priority-high'; case 'Критичный': return 'priority-critical'; default: return ''; } } function updateStats() { const stats = { total: tasks.length, 'Новая': 0, 'В работе': 0, 'На согласовании': 0, 'Готово': 0 }; tasks.forEach(t => stats[t.status]++); document.getElementById('stat-total').textContent = stats.total; document.getElementById('stat-new').textContent = stats['Новая']; document.getElementById('stat-progress').textContent = stats['В работе']; document.getElementById('stat-review').textContent = stats['На согласовании']; document.getElementById('stat-done').textContent = stats['Готово']; } function renderChips() { const container = document.getElementById('chips'); container.innerHTML = STATUSES.map(s => `` ).join('') + ``; container.querySelectorAll('.chip').forEach(chip => { chip.addEventListener('click', () => { filterStatus = chip.dataset.status || null; renderTasks(); }); }); } function renderTasks() { const search = document.getElementById('search').value.toLowerCase(); let filtered = tasks.filter(t => { const matchesSearch = t.task.toLowerCase().includes(search) || t.person.toLowerCase().includes(search) || t.date.toLowerCase().includes(search) || t.priority.toLowerCase().includes(search) || t.status.toLowerCase().includes(search); const matchesStatus = filterStatus === null || t.status === filterStatus; return matchesSearch && matchesStatus; }); const tbody = document.getElementById('tasks-body'); if (filtered.length === 0) { tbody.innerHTML = 'Нет задач для отображения'; return; } tbody.innerHTML = filtered.map(t => { const overdue = isOverdue(t); return ` ${t.task} ${t.person} ${t.date} ${t.priority} ${t.status} `; }).join(''); } function renderLog() { const container = document.getElementById('log'); container.innerHTML = log.map(entry => `
${entry.what} — ${entry.who} (${entry.when})
` ).join(''); } function render() { updateStats(); renderChips(); renderTasks(); renderLog(); } function openModal(editId = null) { const modal = document.getElementById('modal'); const form = document.getElementById('task-form'); form.reset(); document.getElementById('edit-id').value = ''; document.getElementById('modal-title').textContent = 'Новая задача'; if (editId !== null) { const task = tasks.find(t => t.id === editId); if (task) { document.getElementById('edit-id').value = task.id; document.getElementById('f-task').value = task.task; document.getElementById('f-person').value = task.person; document.getElementById('f-date').value = task.date; document.getElementById('f-priority').value = task.priority; document.getElementById('f-status').value = task.status; document.getElementById('modal-title').textContent = 'Редактирование задачи'; } } modal.showModal(); } function closeModal() { document.getElementById('modal').close(); } function saveTask(e) { e.preventDefault(); const editId = document.getElementById('edit-id').value; const taskData = { task: document.getElementById('f-task').value, person: document.getElementById('f-person').value, date: document.getElementById('f-date').value, priority: document.getElementById('f-priority').value, status: document.getElementById('f-status').value }; if (editId) { const id = parseInt(editId); const index = tasks.findIndex(t => t.id === id); if (index !== -1) { tasks[index] = { ...tasks[index], ...taskData }; addLogEntry(`Изменена задача: "${taskData.task}"`); } } else { const newId = Math.max(0, ...tasks.map(t => t.id)) + 1; tasks.push({ id: newId, ...taskData }); addLogEntry(`Добавлена задача: "${taskData.task}"`); } saveTasks(); closeModal(); render(); } window.editTask = function(id) { openModal(id); }; window.deleteTask = function(id) { const task = tasks.find(t => t.id === id); if (!task) return; if (confirm(`Удалить задачу "${task.task}"?`)) { tasks = tasks.filter(t => t.id !== id); addLogEntry(`Удалена задача: "${task.task}"`); saveTasks(); render(); } }; function exportCSV() { const headers = ['Задача', 'Исполнитель', 'Срок', 'Приоритет', 'Статус']; const rows = tasks.map(t => [t.task, t.person, t.date, t.priority, t.status] .map(v => '"' + String(v ?? '').replace(/"/g, '""') + '"') .join(';') ); const csv = '\uFEFF' + [headers.join(';'), ...rows].join('\n'); const blob = new Blob([csv], { type: 'text/csv;charset=utf-8;' }); const url = URL.createObjectURL(blob); const a = document.createElement('a'); a.href = url; a.download = 'zadachi_otdela.csv'; a.click(); URL.revokeObjectURL(url); addLogEntry('Выгружен список задач в CSV'); saveLog(); } function resetDemo() { if (confirm('Сбросить все данные к демо-версии? Все изменения будут потеряны.')) { tasks = [...DEMO_TASKS]; log = [{ when: new Date().toLocaleString('ru-RU'), what: 'Сброшено к демо-данным', who: 'Пользователь' }]; saveTasks(); saveLog(); render(); } } document.getElementById('btn-add').addEventListener('click', () => openModal()); document.getElementById('btn-cancel').addEventListener('click', closeModal); document.getElementById('task-form').addEventListener('submit', saveTask); document.getElementById('search').addEventListener('input', renderTasks); document.getElementById('btn-export').addEventListener('click', exportCSV); document.getElementById('btn-reset').addEventListener('click', resetDemo); init();