From 8aefa1d0ccc5440f60d2d6f846a5fa9ac46b5c05 Mon Sep 17 00:00:00 2001 From: olyaaaa Date: Wed, 18 Jun 2025 14:07:51 +0300 Subject: [PATCH 1/3] hw --- index.html | 133 +++++++++++++++++- src/main.js | 38 ++++++ style/style.css | 349 ++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 519 insertions(+), 1 deletion(-) diff --git a/index.html b/index.html index 09c6dc0..0d7b38f 100644 --- a/index.html +++ b/index.html @@ -3,11 +3,142 @@ - Simple HTML Page + To do list +
+

To-Do List

+
+ + +
+ +
+
+ Sort by: + +
+
+ Filter: + +
+
+ +
+
+ +
+ Купити файні льоди + Medium +
+
+ June 26, 2025 +
+ + +
+
+
+ +
+ +
+ Зробити веб + High +
+
+ June 18, 2025 +
+ + +
+
+ +
+ +
+ +
+ Спекти хліб + Low +
+
+ June 21, 2025 +
+ + +
+
+
+ +
+ +
+ Купити наповнювач Мілашці + High +
+
+ June 18, 2025 +
+ + +
+
+
+
+
+ + + + + \ No newline at end of file diff --git a/src/main.js b/src/main.js index e69de29..fe6ba7b 100644 --- a/src/main.js +++ b/src/main.js @@ -0,0 +1,38 @@ +const taskPopUp = document.getElementById('taskPopUp'); +const openBtn = document.getElementById('add-button'); +const closeBtn = document.getElementById('closePopUpBtn'); +const cancelBtn = document.getElementById('cancelPopUpBtn'); + +const filterByDate = document.getElementById('filterByDate'); +const filetDateBtn = document.getElementById('sortSelect'); +const applyBtn = document.getElementById('apply-button'); + +const checkButtons = document.querySelectorAll('.checkbox-btn'); + +openBtn.addEventListener('click', () => { + taskPopUp.classList.remove('hidden'); +}); + +closeBtn.addEventListener('click', () => { + taskPopUp.classList.add('hidden'); +}); + +cancelBtn.addEventListener('click', () => { + taskPopUp.classList.add('hidden'); +}); + +filetDateBtn.addEventListener('click', () => { + filterByDate.classList.remove('hidden'); +}); + +applyBtn.addEventListener('click', () => { + filterByDate.classList.add('hidden'); +}); + +checkButtons.forEach(button => { + button.addEventListener('click', () => { + button.classList.toggle('checked'); + }); +}); + + diff --git a/style/style.css b/style/style.css index e69de29..8e75ee5 100644 --- a/style/style.css +++ b/style/style.css @@ -0,0 +1,349 @@ +body { + margin: 0; + padding: 0; +} + +.container { + max-width: 900px; + margin: 40px auto; + background-color: rgb(255, 224, 224); + padding: 24px; + border-radius: 12px; + box-shadow: 0 0 10px rgba(0, 0, 0, 0.1); +} + +.title { + text-align: center; + margin-bottom: 20px; +} + +.input-section { + display: flex; + gap: 10px; + margin-bottom: 20px; +} + +.task-input { + flex: 1; + padding: 10px; + border: 2px solid rgb(248, 204, 204); + border-radius: 8px; +} + +.add-button { + padding: 10px; + border: none; + background-color: white; + border: 2px solid rgb(248, 204, 204); + border-radius: 8px; + cursor: pointer; +} + +.controls { + display: flex; + justify-content: space-between; + margin-bottom: 20px; +} + +.sort { + display: flex; + align-items: center; + gap: 5px; + background-color: white; + border: 2px solid rgb(248, 204, 204); + border-radius: 6px; + padding-left: 10px; + padding-right: 7%; + padding-top: 6px; + padding-bottom: 6px; +} + +.select { + border: none; +} + +.task-list { + display: flex; + flex-direction: column; + border: 2px solid rgb(248, 204, 204); + background-color: white; + border-radius: 5px; +} + +.task { + display: flex; + align-items: center; + justify-content: space-between; + border-bottom: 2px solid rgb(248, 204, 204); + padding: 8px; +} + +.task-title { + font-size: 18px; +} + +.task.completed .task-title { + text-decoration: line-through; + color: #777; +} + +.task-info { + display: flex; + flex-direction: column; + gap: 4px; + flex: 1; + margin-left: 10px; +} + +.checkbox-btn { + width: 20px; + height: 20px; + border-radius: 50%; + border: 2px solid #ccc; + background-color: #fff; + position: relative; + cursor: pointer; +} + +.checkbox-btn.checked::after { + border-color: #666; + color: #9d9d9d; + content: "✓"; + position: absolute; + transform: translate(-50%, -50%); +} + +.right-side { + display: flex; + align-items: center; + gap: 5px; + font-size: 18px; + color: #666; +} + +.task-actions { + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + gap: 3px; +} + +@media (max-width: 500px) { + .task-actions { + display: none; + } +} + +.edit-btn, +.delete-btn { + background: none; + border-radius: 4px; + border: 2px solid rgb(248, 204, 204); + font-size: 13px; + cursor: pointer; + color: #a00808; + opacity: 0.7; +} + +.edit-btn:hover, +.delete-btn:hover { + opacity: 1; +} + +.priority { + display: inline-block; + padding: 2px 10px; + border-radius: 8px; + font-size: 12px; + font-weight: 600; + color: white; + width: fit-content; +} + +.priority.low { + background-color: #83c49e; +} + +.priority.medium { + background-color: #f4a261; +} + +.priority.high { + background-color: #dc1021a2; +} + +.hidden { + display: none !important; +} + +.taskPopUp { + position: absolute; + top: 100px; + left: 50%; + transform: translateX(-50%); + z-index: 999; +} + +.popUp-content { + background-color: #fff; + padding: 24px; + border-radius: 12px; + box-shadow: 0 8px 16px rgba(0, 0, 0, 0.2); + width: 300px; +} + +.popUp-content h2 { + font-size: 30px; + margin-bottom: 20px; +} + +.popUp-content input[type="text"], +.popUp-content input[type="date"] { + align-self: center; + + padding: 14px; + margin-top: 6px; + margin-bottom: 20px; + + width: 80%; + border: 1px solid #d1d5db; + border-radius: 8px; + font-size: 14px; + color: #111827; + background-color: #f9fafb; +} + +.popUp-content label { + display: block; + font-size: 17px; + margin-bottom: 4px; + color: #111; +} + +.priority-options { + display: flex; + justify-content: space-between; + margin-top: 8px; + margin-bottom: 24px; +} + +.priority-options label { + font-size: 14px; + display: flex; + align-items: center; + gap: 6px; + color: #111827; +} + +.popUp-buttons { + display: flex; + justify-content: space-between; + margin-top: 20px; +} + +.add-task-btn { + background-color: #f397bc; + color: white; + border: none; + padding: 10px 18px; + border-radius: 8px; + cursor: pointer; + font-size: 14px; + transition: background-color 0.2s ease-in-out; +} + +.add-task-btn:hover { + background-color: #f777aa; +} + +.cancel-btn { + background-color: #fff; + color: #111827; + border: 1px solid #d1d5db; + padding: 10px 18px; + border-radius: 8px; + cursor: pointer; + font-size: 14px; +} + +.cancel-btn:hover { + background-color: #f3f4f6; +} + +.close-btn { + position: absolute; + top: 16px; + right: 20px; + font-size: 24px; + color: #6b7280; + cursor: pointer; + transition: color 0.2s; +} + +.close-btn:hover { + color: #111827; +} + +.filterByDate { + position: absolute; + top: 100px; + left: 50%; + transform: translateX(-50%); + z-index: 999; +} + +.filterByDate-content { + background-color: #fff; + padding: 24px; + border-radius: 12px; + box-shadow: 0 8px 16px rgba(0, 0, 0, 0.2); + width: 300px; +} + +.filterByDate-title { + font-size: 20px; + margin-bottom: 20px; +} + +.filterByDate-select { + width: 100%; + padding: 10px; + border-radius: 8px; + border: 1px solid #ccc; + font-size: 16px; + margin-bottom: 16px; +} + +.date-field { + position: relative; +} + +.filterByDate-date { + width: 93%; + padding: 10px; + border-radius: 8px; + border: 1px solid #ccc; + font-size: 16px; + margin-bottom: 16px; +} + +.button-wrapper { + display: flex; + justify-content: flex-end; +} + +.apply-button { + width: 40%; + background-color: #f397bc; + color: white; + padding: 10px; + border: none; + border-radius: 8px; + font-size: 16px; + cursor: pointer; +} + +.apply-button:hover { + background-color: #f777aa; +} From 6fb0106225292ee0fcc20a2cb31134812fd564df Mon Sep 17 00:00:00 2001 From: olyaaaa Date: Wed, 25 Jun 2025 13:18:09 +0300 Subject: [PATCH 2/3] HW5 --- index.html | 234 +++++++++++++++++----------------- src/main.js | 284 ++++++++++++++++++++++++++++++++++++++---- style/pivot-theme.css | 67 ++++++++++ style/style.css | 33 ++++- tasks.json | 26 ++++ 5 files changed, 501 insertions(+), 143 deletions(-) create mode 100644 style/pivot-theme.css create mode 100644 tasks.json diff --git a/index.html b/index.html index 0d7b38f..4647f56 100644 --- a/index.html +++ b/index.html @@ -1,144 +1,148 @@ - - - + + + To do list - + - - -
-

To-Do List

- -
- - -
- -
-
- Sort by: - + + +
+

To-Do List

+ Переглянути звіт +
+ +
-
- Filter: - -
-
-
-
- -
- Купити файні льоди - Medium +
+
+ Sort by: +
-
- June 26, 2025 -
- - -
+
+ Filter: + All
-
- -
- Зробити веб - High +
+
+ +
+ Купити файні льоди + Medium +
+
+ June 26, 2025 +
+ + +
+
-
+ +
+ +
+ Зробити веб + High +
+
June 18, 2025 -
- - -
+
+ + +
+
-
- -
- -
- Спекти хліб - Low -
-
+
+ +
+ Спекти хліб + Low +
+
June 21, 2025 -
- - -
+
+ + +
+
-
-
- -
- Купити наповнювач Мілашці - High -
-
+
+ +
+ Купити наповнювач Мілашці + High +
+
June 18, 2025 -
- - -
+
+ + +
+
-
- - + + diff --git a/src/main.js b/src/main.js index fe6ba7b..535005b 100644 --- a/src/main.js +++ b/src/main.js @@ -1,38 +1,278 @@ -const taskPopUp = document.getElementById('taskPopUp'); -const openBtn = document.getElementById('add-button'); -const closeBtn = document.getElementById('closePopUpBtn'); -const cancelBtn = document.getElementById('cancelPopUpBtn'); +const taskList = document.querySelector(".task-list"); +const sortSelect = document.getElementById("sort-select"); +const addButton = document.getElementById("add-button"); +const taskPopUp = document.getElementById("taskPopUp"); +const closePopUpBtn = document.getElementById("closePopUpBtn"); +const cancelPopUpBtn = document.getElementById("cancelPopUpBtn"); +const addTaskBtn = document.querySelector(".add-task-btn"); +const filterSelectSpan = document.getElementById("filterSelect"); +const filterByDatePopup = document.getElementById("filterByDate"); +const filterByDateSelect = document.querySelector(".filterByDate-select"); +const filterByDateInput = document.querySelector(".filterByDate-date"); +const applyFilterBtn = document.getElementById("apply-button"); +const defaultFilterBtn = document.getElementById("default-button"); +const taskTitlePlaceholder = document.getElementById("taskTitlePlaceholder"); -const filterByDate = document.getElementById('filterByDate'); -const filetDateBtn = document.getElementById('sortSelect'); -const applyBtn = document.getElementById('apply-button'); +let tasks = []; // список всіх задач +let editingTask = null; // якщо щось редагую зараз — зберігаю +let currentFilter = { type: "All", date: null }; // що фільтрується +let currentSort = "none"; // як сортуємо -const checkButtons = document.querySelectorAll('.checkbox-btn'); +fetch("../tasks.json") + .then((res) => res.json()) + .then((data) => { + tasks = data; + renderTasksWithFilters(); + }) + .catch((err) => { + console.error("Помилка завантаження tasks.json:", err); + }); -openBtn.addEventListener('click', () => { - taskPopUp.classList.remove('hidden'); -}); +// -------- Попап відкриття (додавання) -------- +addButton.addEventListener("click", () => { + const nameInput = taskPopUp.querySelector('input[type="text"]'); + if (taskTitlePlaceholder.value.trim()) { + nameInput.placeholder = ""; + nameInput.value = taskTitlePlaceholder.value.trim(); + } else { + nameInput.value = ""; + nameInput.placeholder = "Назва завдання"; + } + + const dateInput = taskPopUp.querySelector('input[type="date"]'); + const priorityInputs = taskPopUp.querySelectorAll('input[name="priority"]'); + + dateInput.value = ""; + priorityInputs[1].checked = true; -closeBtn.addEventListener('click', () => { - taskPopUp.classList.add('hidden'); + editingTask = null; + taskPopUp.querySelector("h2").textContent = "Додати завдання"; + addTaskBtn.textContent = "Додати"; + + taskPopUp.classList.remove("hidden"); }); -cancelBtn.addEventListener('click', () => { - taskPopUp.classList.add('hidden'); +// -------- Закриття попапу -------- +closePopUpBtn.addEventListener("click", () => { + editingTask = null; + taskPopUp.classList.add("hidden"); + taskTitlePlaceholder.value = ""; }); -filetDateBtn.addEventListener('click', () => { - filterByDate.classList.remove('hidden'); +cancelPopUpBtn.addEventListener("click", () => { + editingTask = null; + taskPopUp.classList.add("hidden"); + taskTitlePlaceholder.value = ""; }); -applyBtn.addEventListener('click', () => { - filterByDate.classList.add('hidden'); +// -------- Збереження (додати або редагувати) -------- +addTaskBtn.addEventListener("click", () => { + const nameInput = taskPopUp.querySelector('input[type="text"]'); + const dateInput = taskPopUp.querySelector('input[type="date"]'); + const priorityInputs = taskPopUp.querySelectorAll('input[name="priority"]'); + + const title = nameInput.value.trim(); + const date = dateInput.value.trim(); + + let priority = "medium"; + priorityInputs.forEach((input, index) => { + if (input.checked) { + if (index === 0) priority = "high"; + else if (index === 1) priority = "medium"; + else if (index === 2) priority = "low"; + } + }); + + if (!title || !date) return; + + if (editingTask) { + editingTask.title = title; + editingTask.date = date; + editingTask.priority = priority; + } else { + tasks.push({ title, date, priority, completed: false }); + } + + editingTask = null; + nameInput.value = ""; + dateInput.value = ""; + priorityInputs[1].checked = true; + taskPopUp.classList.add("hidden"); + + + + renderTasksWithFilters(); }); -checkButtons.forEach(button => { - button.addEventListener('click', () => { - button.classList.toggle('checked'); +// ----------- Редагування кнопка ----------- +function addEditButtonListener(editBtn, task) { + editBtn.addEventListener("click", () => { + editingTask = task; + + const nameInput = taskPopUp.querySelector('input[type="text"]'); + const dateInput = taskPopUp.querySelector('input[type="date"]'); + const priorityInputs = taskPopUp.querySelectorAll('input[name="priority"]'); + + nameInput.value = task.title; + dateInput.value = task.date; + priorityInputs[0].checked = task.priority === "high"; + priorityInputs[1].checked = task.priority === "medium"; + priorityInputs[2].checked = task.priority === "low"; + + taskPopUp.querySelector("h2").textContent = "Редагувати завдання"; + addTaskBtn.textContent = "Зберегти"; + + taskPopUp.classList.remove("hidden"); }); +} + +// ---------- Сортування ---------- +sortSelect.addEventListener("change", () => { + currentSort = sortSelect.value; + renderTasksWithFilters(); +}); + +// ---------- Фільтр відкриття ---------- +filterSelectSpan.addEventListener("click", () => { + filterByDatePopup.classList.remove("hidden"); +}); + +// ---------- Застосувати фільтр ---------- +applyFilterBtn.addEventListener("click", () => { + const type = filterByDateSelect.value; + const dateStr = filterByDateInput.value; + + if (!dateStr) return alert("Вибери дату для фільтрації"); + + currentFilter.type = type; + currentFilter.date = dateStr; + + filterSelectSpan.textContent = `Filter: ${type} ${dateStr}`; + filterByDatePopup.classList.add("hidden"); + + renderTasksWithFilters(); }); +// ---------- Скидання фільтра ---------- +defaultFilterBtn.addEventListener("click", () => { + currentFilter = { type: "All", date: null }; + filterSelectSpan.textContent = "All"; + filterByDatePopup.classList.add("hidden"); + renderTasksWithFilters(); +}); + +// ------- Основний рендер з фільтрами + сортуванням + completed вниз ------- +function renderTasksWithFilters() { + let result = [...tasks]; + + if (currentFilter.date) { + const filterDate = new Date(currentFilter.date); + result = result.filter((task) => { + const taskDate = new Date(task.date); + if (currentFilter.type === "Current") { + return ( + taskDate.getFullYear() === filterDate.getFullYear() && + taskDate.getMonth() === filterDate.getMonth() && + taskDate.getDate() === filterDate.getDate() + ); + } else if (currentFilter.type === "Past") { + return taskDate < filterDate; + } else if (currentFilter.type === "Upcoming") { + return taskDate > filterDate; + } + return true; + }); + } + + if (currentSort === "date-asc") { + result.sort((a, b) => new Date(a.date) - new Date(b.date)); + } else if (currentSort === "date-desc") { + result.sort((a, b) => new Date(b.date) - new Date(a.date)); + } else if (currentSort === "priority") { + const order = { high: 1, medium: 2, low: 3 }; + result.sort((a, b) => order[a.priority] - order[b.priority]); + } + + result.sort((a, b) => { + if (a.completed === b.completed) return 0; + return a.completed ? 1 : -1; + }); + + renderTasks(result); +} + +// ---------- Рендер задач ---------- +function renderTasks(tasksArray) { + taskList.innerHTML = ""; + tasksArray.forEach((task) => { + const taskElement = createTaskElement(task); + taskList.appendChild(taskElement); + }); +} + +// ---------- Створення елементу задачі ---------- +function createTaskElement(task) { + const taskDiv = document.createElement("div"); + taskDiv.className = `task${task.completed ? " completed" : ""}`; + + const checkboxBtn = document.createElement("button"); + checkboxBtn.className = `checkbox-btn${task.completed ? " checked" : ""}`; + checkboxBtn.addEventListener("click", () => { + task.completed = !task.completed; + renderTasksWithFilters(); + }); + + const taskInfo = document.createElement("div"); + taskInfo.className = "task-info"; + + const titleSpan = document.createElement("span"); + titleSpan.className = "task-title"; + titleSpan.textContent = task.title; + + const prioritySpan = document.createElement("span"); + prioritySpan.className = `priority ${task.priority}`; + prioritySpan.textContent = task.priority; + + taskInfo.appendChild(titleSpan); + taskInfo.appendChild(prioritySpan); + + const rightSide = document.createElement("div"); + rightSide.className = "right-side"; + + const dateSpan = document.createElement("span"); + dateSpan.className = "date"; + dateSpan.textContent = new Date(task.date).toLocaleDateString("en-US", { + month: "long", + day: "numeric", + year: "numeric", + }); + + const actionsDiv = document.createElement("div"); + actionsDiv.className = "task-actions"; + + const editBtn = document.createElement("button"); + editBtn.className = "edit-btn"; + editBtn.textContent = "🖉"; + addEditButtonListener(editBtn, task); + + const deleteBtn = document.createElement("button"); + deleteBtn.className = "delete-btn"; + deleteBtn.textContent = "🗑️"; + deleteBtn.addEventListener("click", () => { + tasks = tasks.filter((t) => t !== task); + renderTasksWithFilters(); + }); + + actionsDiv.appendChild(editBtn); + actionsDiv.appendChild(deleteBtn); + + rightSide.appendChild(dateSpan); + rightSide.appendChild(actionsDiv); + + taskDiv.appendChild(checkboxBtn); + taskDiv.appendChild(taskInfo); + taskDiv.appendChild(rightSide); + return taskDiv; +} +renderTasksWithFilters(); // початковий рендер \ No newline at end of file diff --git a/style/pivot-theme.css b/style/pivot-theme.css new file mode 100644 index 0000000..da601a7 --- /dev/null +++ b/style/pivot-theme.css @@ -0,0 +1,67 @@ +#pivot-container { + background-color: #e39db9; + border-radius: 10px; + padding: 10px; +} + + +#wdr-toolbar-wrapper #wdr-toolbar { + width: 70%; + height: 78px; + list-style: none; + background: #f6cadc; + white-space: nowrap; +} + +#wdr-toolbar-wrapper #wdr-toolbar li a svg, +#wdr-toolbar-wrapper #wdr-toolbar li a svg path { + transform: translateZ(0); + fill: #ac6581; +} + +#wdr-toolbar-wrapper #wdr-toolbar, +#wdr-toolbar-wrapper #wdr-toolbar a, +#wdr-toolbar-wrapper #wdr-toolbar div, +#wdr-toolbar-wrapper #wdr-toolbar input, +#wdr-toolbar-wrapper #wdr-toolbar li, +#wdr-toolbar-wrapper #wdr-toolbar p, +#wdr-toolbar-wrapper #wdr-toolbar select, +#wdr-toolbar-wrapper #wdr-toolbar span, +#wdr-toolbar-wrapper #wdr-toolbar table, +#wdr-toolbar-wrapper #wdr-toolbar table td, +#wdr-toolbar-wrapper #wdr-toolbar table th, +#wdr-toolbar-wrapper #wdr-toolbar table tr, +#wdr-toolbar-wrapper #wdr-toolbar textarea, +#wdr-toolbar-wrapper #wdr-toolbar ul { + font-size: 14px; + color: #111827; + text-align: left; + padding: 0; + margin: 0; + font-weight: 400; + text-shadow: none; + font-weight: 500; +} + +#wdr-pivot-view .wdr-grid-layout .wdr-filters .wdr-header, #wdr-pivot-view .wdr-grid-layout.wdr-flat-view .wdr-header { + background-color: #ebc2d2; + color: #111; + font-weight: 700; + text-transform: uppercase; + position: relative; + border: none; + overflow: hidden; + text-overflow: ellipsis; +} + +#wdr-pivot-view .wdr-grid-layout .wdr-filters { + position: absolute; + background-color: #ebc2d2; + color: #111; +} + +#wdr-pivot-view .wdr-grid-layout div.wdr-header { + background-color: #ebc2d2; + color: #111; + +} \ No newline at end of file diff --git a/style/style.css b/style/style.css index 8e75ee5..01beb77 100644 --- a/style/style.css +++ b/style/style.css @@ -1,6 +1,7 @@ body { margin: 0; padding: 0; + background-color: rgba(0, 0, 0, 1); } .container { @@ -17,6 +18,21 @@ body { margin-bottom: 20px; } +.report-link { + display: inline-block; + margin-bottom: 20px; + font-size: 16px; + background-color: #f397bc; + padding: 8px 16px; + border-radius: 8px; + color: white; + text-decoration: none; + transition: background-color 0.2s ease; +} +.report-link:hover { + background-color: #f777aa; +} + .input-section { display: flex; gap: 10px; @@ -45,7 +61,7 @@ body { margin-bottom: 20px; } -.sort { +.sort, .filter { display: flex; align-items: center; gap: 5px; @@ -58,6 +74,10 @@ body { padding-bottom: 6px; } +.filter-option { + cursor: pointer; +} + .select { border: none; } @@ -144,6 +164,7 @@ body { cursor: pointer; color: #a00808; opacity: 0.7; + width:100%; } .edit-btn:hover, @@ -330,20 +351,20 @@ body { .button-wrapper { display: flex; - justify-content: flex-end; + justify-content: space-between; } -.apply-button { +.apply-button, .default-button { width: 40%; background-color: #f397bc; color: white; - padding: 10px; + padding: 6px; border: none; border-radius: 8px; - font-size: 16px; + font-size: 14px; cursor: pointer; } -.apply-button:hover { +.apply-button:hover, .default-button:hover { background-color: #f777aa; } diff --git a/tasks.json b/tasks.json new file mode 100644 index 0000000..75c82b8 --- /dev/null +++ b/tasks.json @@ -0,0 +1,26 @@ +[ + { + "title": "Купити цукерки", + "priority": "medium", + "date": "2025-06-26", + "completed": false + }, + { + "title": "Зробити веб", + "priority": "high", + "date": "2025-06-18", + "completed": true + }, + { + "title": "Спекти хліб", + "priority": "low", + "date": "2025-06-21", + "completed": false + }, + { + "title": "Купити наповнювач Мілашці", + "priority": "high", + "date": "2025-06-18", + "completed": false + } +] From 7f59aecfb7a4c8cca6b6c0755bbfe49d675e1e2c Mon Sep 17 00:00:00 2001 From: olyaaaa Date: Wed, 25 Jun 2025 13:19:35 +0300 Subject: [PATCH 3/3] Bonus task --- report.html | 24 ++++++++++++++++++++++++ src/report.js | 23 +++++++++++++++++++++++ 2 files changed, 47 insertions(+) create mode 100644 report.html create mode 100644 src/report.js diff --git a/report.html b/report.html new file mode 100644 index 0000000..59eae68 --- /dev/null +++ b/report.html @@ -0,0 +1,24 @@ + + + + + Звіт про завдання + + + + + + + + +
+

📊 Звіт про завдання

+ Назад до списку + +
+
+ + diff --git a/src/report.js b/src/report.js new file mode 100644 index 0000000..d657878 --- /dev/null +++ b/src/report.js @@ -0,0 +1,23 @@ +fetch("./tasks.json") + .then((res) => res.json()) + .then((data) => { + new WebDataRocks({ + container: "#pivot-container", + height: 430, + toolbar: true, + report: { + dataSource: { + data: data, + }, + slice: { + rows: [{ uniqueName: "priority" }], + columns: [{ uniqueName: "completed" }], + measures: [{ uniqueName: "title", aggregation: "count" }], + }, + }, + }); + }) + .catch((err) => { + alert("Помилка завантаження JSON: " + err.message); + console.log(err); + });