From 6f413e5c0ffed4b388d12b2b3bf146a7684d0f91 Mon Sep 17 00:00:00 2001 From: Kuz Khrystyna Date: Wed, 4 Jun 2025 11:22:53 +0300 Subject: [PATCH 1/3] PullRequest-KhrKuz --- index.html | 87 ++++++++++++++-- main.css | 297 ++++++++++++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 360 insertions(+), 24 deletions(-) diff --git a/index.html b/index.html index 5971bf7..a1aee37 100644 --- a/index.html +++ b/index.html @@ -1,16 +1,83 @@ - - - - My Page - - - + + + + BuyList + + + - - Apple - 4 +
+
+
+ + +
+
+
+ Помідори +
+ 2 +
+
+ +
+
+
+
+ +
+ + 2 + +
+
+ + +
+
+
+
+ +
+ + 1 + +
+
+ + +
+
+
+ +
+

Залишилося

+
+
+ Печиво 2 + Сир 1 +
+
+

Куплено

+
+
+ Помідори 2 +
+
+
+ + +
+
BuyList
+ + + Created by: + +
+ Кузь Христина
+
\ No newline at end of file diff --git a/main.css b/main.css index 00bc872..b27f699 100644 --- a/main.css +++ b/main.css @@ -1,17 +1,286 @@ -.product-item { - background-color: gray; - display: inline-block; - height: 25px; - padding: 5px; - border-radius: 5px; -} +body { + font-family: sans-serif; + background-color: #d0d0d0; + } + + .container { + display: flex; + padding: 20px; + gap: 20px; + } + + .first-column { + flex: 2; + background: #f8f8f8; + border-radius: 10px; + padding: 20px; + } -.amount { - background-color: yellow; + .second-column { + flex: 1; + background: #f8f8f8; border-radius: 10px; - - display: inline-block; - height: 20px; - width: 20px; + padding: 20px; + } + + .first-column, .second-column { + box-shadow: 0 4px 10px rgba(0, 0, 0, 0.34); + } + + hr { + border: none; + height: 1px; + background-color: #d9d9d9; + margin: 10px 0px; + width: 100%; + } + + /* Друк */ + @media print { + .badge { + background-color: white; + color: #4b0082; + border: 2px solid #4b0082; + content: "Кузь Христина"; + } + + .badge .author-name, .title { + display: none; + } + + .badge::before { + content: "Кузь Христина"; + } + } + + /* Зміщення для колонок */ + @media (max-width: 650px) { + .container { + flex-direction: column; + } + } + + /* Підказки для користувача */ + [data-tooltip] { + position: relative; + } + + [data-tooltip]::after { + content: attr(data-tooltip); + position: absolute; + bottom: 120%; + left: 50%; + transform: translateX(-50%) scale(0.95); + background-color: #8e35ce; + color: white; + padding: 6px 10px; + border-radius: 8px; + white-space: nowrap; + opacity: 0; + pointer-events: none; + transition: opacity 0.3s ease, transform 0.3s ease; + } + + [data-tooltip]:hover::after { + opacity: 1; + transform: translateX(-50%) scale(1); + } + + .input-row { + display: flex; + width: 100%; + border: 1px solid #ccc; + border-radius: 6px; + overflow: hidden; + background-color: white; + margin-bottom: 20px; + } + + .input { + flex: 1; + border: none; + padding: 10px 12px; + font-size: 16px; + outline: none; + } + + .add-btn { + background-color: #007bff; + color: white; + border: none; + padding: 0 20px; + font-size: 16px; + font-weight: bold; + cursor: pointer; + white-space: nowrap; + display: flex; + align-items: center; + justify-content: center; + box-shadow: -1px -4px rgba(29, 14, 195, 0.356) inset; + } + + .product-row { + display: flex; + justify-content: center; + align-items: center; + padding: 10px 0; + gap: 12px; +} + + .product-name { + flex: 1; + text-align: left; + font-size: 18px; +} + + .product-name-crossed { + justify-self: start; + width: 33.3%; + font-size: 18px; + text-decoration: line-through; + color: gray; + } + + .product-name-input { + justify-self: start; + width: 33%; + font-size: 18px; + border: none; + background: transparent; + } + + .product-counter { + display: flex; + align-items: center; + justify-content: center; + gap: 7px; + width: 33%; +} + +.product-actions { + justify-content: flex-end; + display: flex; + align-items: center; + gap: 6px; + width: 33%; +} + + .count { + background: rgb(229, 229, 229); + padding: 4px 10px; + border-radius: 6px; + } + + .plus, .minus, .minus-stop { + width: 30px; + height: 30px; + border-radius: 50%; + font-size: 20px; + border: none; + color: white; + cursor: pointer; + } + + .plus { + background-color: green; + box-shadow: -1px -3px rgba(0, 67, 8, 0.356) inset; + } + + .minus { + background-color: red; + box-shadow: -1px -3px rgba(84, 0, 0, 0.312) inset; + } + + .minus-stop { + background-color: red; + box-shadow: -1px -3px rgba(101, 36, 36, 0.312) inset; + opacity: 50%; + pointer-events: none; + } + + .status-btn { + font-size: 17px; + padding: 4px 10px; + border: 1px solid #d6d6d6; + background: rgb(229, 229, 229); + cursor: pointer; + border-radius: 4px; + box-shadow: -1px -3px rgba(0, 0, 0, 0.2) inset; + } + + .delete { + background-color: red; + color: white; + border: none; + width: 30px; + height: 30px; + font-size: 20px; + border-radius: 4px; + padding: 4px 8px; + cursor: pointer; + box-shadow: -1px -3px rgba(84, 0, 0, 0.2) inset; + } + + /* Другий контейнер */ + .badge-list { + display: flex; + flex-wrap: wrap; + gap: 10px; + margin: 10px 0; + } + + .tag { + background-color: rgb(229, 229, 229);; + padding: 5px 10px; + border-radius: 10px; + } + + .tag-count { + background: orange; + border-radius: 50%; + padding: 2px 6px; + margin-left: 5px; + color: white; + } + + /* Бейдж */ + .badge { text-align: center; -} \ No newline at end of file + position: fixed; + left: 20px; + bottom: 0px; + height: 30px; + background-color: #6d1aa8; + color: white; + font-family: sans-serif ; + font-size: 22px; + padding: 10px 20px; + border-radius: 10px 10px 0 0; + cursor: pointer; + transition: all 0.2s ease; + overflow: hidden; + } + + .badge:hover { + background-color: #3e139c; + height: 80px; + } + + .badge .author-name { + font-size: 15px; + display: block; + margin-top: 10px; + opacity: 0; + transform: translateY(10px); + transition: all 0.3s ease; + text-align: left; + } + + .created-by { + font-size: 13px; + } + + .badge:hover .author-name { + opacity: 1; + transform: translateY(0); + } \ No newline at end of file From e26f2cc4e90777214f75f11a6e3dbafa6c7d662b Mon Sep 17 00:00:00 2001 From: Kuz Khrystyna Date: Mon, 9 Jun 2025 11:33:39 +0300 Subject: [PATCH 2/3] KhrKuz_hw3_JS --- index.html | 17 ++-- main.css | 40 +++++--- script.js | 278 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 315 insertions(+), 20 deletions(-) create mode 100644 script.js diff --git a/index.html b/index.html index a1aee37..5eff20e 100644 --- a/index.html +++ b/index.html @@ -6,6 +6,7 @@ +
@@ -16,12 +17,15 @@

- Помідори +
+ 2 +
+

@@ -41,12 +45,12 @@
- + 1
- +
@@ -55,15 +59,16 @@

Залишилося


-
+
Печиво 2 Сир 1

Куплено


-
- Помідори 2 +
+ Помідори + 2
diff --git a/main.css b/main.css index b27f699..65c6931 100644 --- a/main.css +++ b/main.css @@ -113,9 +113,6 @@ body { font-weight: bold; cursor: pointer; white-space: nowrap; - display: flex; - align-items: center; - justify-content: center; box-shadow: -1px -4px rgba(29, 14, 195, 0.356) inset; } @@ -132,13 +129,11 @@ body { text-align: left; font-size: 18px; } - - .product-name-crossed { - justify-self: start; - width: 33.3%; - font-size: 18px; - text-decoration: line-through; - color: gray; + + .product-row.bought .product-counter .plus, + .product-row.bought .product-counter .minus, + .product-row.bought .product-actions .delete { + display: none; } .product-name-input { @@ -149,6 +144,14 @@ body { background: transparent; } + .product-row.bought .product-name-input { + border: none; + background: transparent; + color: gray; + text-decoration: line-through; + pointer-events: none; +} + .product-counter { display: flex; align-items: center; @@ -191,7 +194,7 @@ body { box-shadow: -1px -3px rgba(84, 0, 0, 0.312) inset; } - .minus-stop { + button:disabled { background-color: red; box-shadow: -1px -3px rgba(101, 36, 36, 0.312) inset; opacity: 50%; @@ -229,19 +232,29 @@ body { margin: 10px 0; } - .tag { + .tag, .tag-crossed { background-color: rgb(229, 229, 229);; padding: 5px 10px; border-radius: 10px; } + + .tag-crossed { + text-decoration: line-through; + color: gray; + } - .tag-count { + .tag-count, .tag-count-crossed { background: orange; border-radius: 50%; padding: 2px 6px; margin-left: 5px; color: white; } + + .tag-count-crossed { + text-decoration: line-through; + color: white; + } /* Бейдж */ .badge { @@ -252,7 +265,6 @@ body { height: 30px; background-color: #6d1aa8; color: white; - font-family: sans-serif ; font-size: 22px; padding: 10px 20px; border-radius: 10px 10px 0 0; diff --git a/script.js b/script.js new file mode 100644 index 0000000..9f321a4 --- /dev/null +++ b/script.js @@ -0,0 +1,278 @@ +document.addEventListener("DOMContentLoaded", () => { + const input = document.querySelector(".input"); + const addBtn = document.querySelector(".add-btn"); + const productList = document.querySelector(".first-column"); + + const existingNameInputs = document.querySelectorAll(".product-name-input"); + const existingMinusButtons = document.querySelectorAll(".minus"); + const existingPlusButtons = document.querySelectorAll(".plus"); + const existingStatusButtons = document.querySelectorAll(".status-btn"); + const existingDeleteButtons = document.querySelectorAll(".delete"); + + // Для існуючих назв продуктів + existingNameInputs.forEach((nameInput) => { + nameInput.addEventListener("click", () => { + nameInput.readOnly = false; + nameInput.focus(); + }); + nameInput.addEventListener("blur", () => { + nameInput.readOnly = true; + if (nameInput.value.trim() === "") { + nameInput.value = "Без назви"; + } + updateStatistics(); + }); + }); + // Для існуючих кнопок - + existingMinusButtons.forEach((minusBtn) => { + minusBtn.addEventListener("click", () => { + const countSpan = minusBtn.nextElementSibling; + + let count = parseInt(countSpan.textContent); + if (count > 1) { + count--; + countSpan.textContent = count; + if (count === 1) { + minusBtn.disabled = true; + } + } + updateStatistics(); + }); + }); + // Для існуючих кнопок + + existingPlusButtons.forEach((plusBtn) => { + plusBtn.addEventListener("click", () => { + const countSpan = plusBtn.previousElementSibling; + const minusBtn = countSpan.previousElementSibling; + + let count = parseInt(countSpan.textContent); + count++; + countSpan.textContent = count; + + if (count > 1) { + minusBtn.disabled = false; + } + updateStatistics(); + }); + }); + // Для існуючих кнопок "Куплено"/ "Не куплено" + existingStatusButtons.forEach((buyBtn) => { + buyBtn.addEventListener("click", () => { + const productRow = buyBtn.closest(".product-row"); + const nameInput = productRow.querySelector(".product-name-input") || productRow.querySelector(".product-name-crossed"); + const minusBtn = productRow.querySelector(".minus"); + const plusBtn = productRow.querySelector(".plus"); + const deleteBtn = productRow.querySelector(".delete"); + + const isBought = productRow.classList.toggle("bought"); + + if (isBought) { + buyBtn.textContent = "Не куплено"; + buyBtn.setAttribute("data-tooltip", "Позначити як не куплене"); + + if (minusBtn) minusBtn.style.display = "none"; + if (plusBtn) plusBtn.style.display = "none"; + if (deleteBtn) deleteBtn.style.display = "none"; + } else { + buyBtn.textContent = "Куплено"; + buyBtn.setAttribute("data-tooltip", "Позначити як куплене"); + + if (minusBtn) minusBtn.style.display = "inline-block"; + if (plusBtn) plusBtn.style.display = "inline-block"; + if (deleteBtn) deleteBtn.style.display = "inline-block"; + } + updateStatistics(); + }); + }); + // Для існуючих кнопок "Видалити" + existingDeleteButtons.forEach((deleteBtn) => { + deleteBtn.addEventListener("click", () => { + const productRow = deleteBtn.closest(".product-row"); + const prev = productRow.previousElementSibling; + if (prev && prev.tagName === "HR") { + productRow.parentNode.removeChild(prev); + } + productRow.remove(); + updateStatistics(); + }); + }); + + // Функція створення нового рядка з даними про продукт + function createProductElement(name) { + const productRow = document.createElement("div"); + productRow.className = "product-row"; + + // Назва + const nameInput = document.createElement("input"); + nameInput.className = "product-name-input"; + nameInput.value = name; + nameInput.readOnly = true; + + nameInput.addEventListener("click", () => { + nameInput.readOnly = false; + nameInput.focus(); + }); + nameInput.addEventListener("blur", () => { + nameInput.readOnly = true; + if (nameInput.value.trim() === "") { + nameInput.value = "Без назви"; + } + updateStatistics(); + }); + + // Лічильник + const counter = document.createElement("div"); + counter.className = "product-counter"; + + const minusBtn = document.createElement("button"); + minusBtn.className = "minus"; + minusBtn.disabled = true; + minusBtn.textContent = "−"; + minusBtn.setAttribute("data-tooltip", "Зменшити"); + + minusBtn.addEventListener("click", () => { + let count = parseInt(countSpan.textContent); + if (count > 1) { + count--; + countSpan.textContent = count; + if (count === 1) { + minusBtn.disabled = true; + } + } + updateStatistics(); + }); + + const countSpan = document.createElement("span"); + countSpan.className = "count"; + countSpan.textContent = "1"; + + const plusBtn = document.createElement("button"); + plusBtn.className = "plus"; + plusBtn.textContent = "+"; + plusBtn.setAttribute("data-tooltip", "Збільшити"); + + plusBtn.addEventListener("click", () => { + let count = parseInt(countSpan.textContent); + count++; + countSpan.textContent = count; + + if (count > 1) { + minusBtn.disabled = false; + } + updateStatistics(); + }); + + counter.appendChild(minusBtn); + counter.appendChild(countSpan); + counter.appendChild(plusBtn); + + // Дії + const actions = document.createElement("div"); + actions.className = "product-actions"; + + const buyBtn = document.createElement("button"); + buyBtn.className = "status-btn"; + buyBtn.textContent = "Куплено"; + buyBtn.setAttribute("data-tooltip", "Позначити як куплене"); + + const deleteBtn = document.createElement("button"); + deleteBtn.className = "delete"; + deleteBtn.textContent = "×"; + deleteBtn.setAttribute("data-tooltip", "Видалити"); + + // "Куплено / Не куплено" + buyBtn.addEventListener("click", () => { + const isBought = productRow.classList.toggle("bought"); + + if (isBought) { + nameInput.style.textDecoration = "line-through"; + nameInput.style.color="gray"; + buyBtn.textContent = "Не куплено"; + buyBtn.setAttribute("data-tooltip", "Позначити як не куплене"); + minusBtn.style.display = "none"; + plusBtn.style.display = "none"; + deleteBtn.style.display = "none"; + } else { + nameInput.style.textDecoration = "none"; + nameInput.style.color="black"; + buyBtn.textContent = "Куплено"; + buyBtn.setAttribute("data-tooltip", "Позначити як куплене"); + minusBtn.style.display = "inline-block"; + plusBtn.style.display = "inline-block"; + deleteBtn.style.display = "inline-block"; + } + updateStatistics(); + }); + + // Видалення + deleteBtn.addEventListener("click", () => { + const prev = productRow.previousElementSibling; + if (prev && prev.tagName === "HR") { + productRow.parentNode.removeChild(prev); + } + productRow.remove(); + updateStatistics(); + }); + + actions.appendChild(buyBtn); + actions.appendChild(deleteBtn); + + productRow.appendChild(nameInput); + productRow.appendChild(counter); + productRow.appendChild(actions); + + return productRow; + } + + // Функція, яка додає новий продукт + function addProduct() { + const name = input.value.trim(); + if (name === "") return; + + const hr = document.createElement("hr"); + const newProduct = createProductElement(name); + + productList.appendChild(hr); + productList.appendChild(newProduct); + + input.value = ""; + input.focus(); + } + + addBtn.addEventListener("click", addProduct); + input.addEventListener("keypress", (e) => { + if (e.key === "Enter") { + addProduct(); + } + updateStatistics(); + }); + + // Функція оновлення статистики + function updateStatistics() { + const notBoughtList = document.getElementById("not-bought-list"); + const boughtList = document.getElementById("bought-list"); + + notBoughtList.innerHTML = ""; + boughtList.innerHTML = ""; + + const products = document.querySelectorAll(".product-row"); + + products.forEach((productRow) => { + const isBought = productRow.classList.contains("bought"); + const name = productRow.querySelector("input").value.trim() || "Без назви"; + const count = parseInt(productRow.querySelector(".count").textContent); + + const span = document.createElement("span"); + + if (isBought) { + span.className = "tag-crossed"; + span.innerHTML = `${name} ${count}`; + boughtList.appendChild(span); + } else { + span.className = "tag"; + span.innerHTML = `${name} ${count}`; + notBoughtList.appendChild(span); + } + }); + } +}); \ No newline at end of file From 5402e971c671d27fea5ed7ce069681177a34d14d Mon Sep 17 00:00:00 2001 From: Kuz Khrystyna Date: Mon, 9 Jun 2025 11:40:35 +0300 Subject: [PATCH 3/3] KhrKuz_JS --- script.js | 1 - 1 file changed, 1 deletion(-) diff --git a/script.js b/script.js index 9f321a4..13e365c 100644 --- a/script.js +++ b/script.js @@ -216,7 +216,6 @@ document.addEventListener("DOMContentLoaded", () => { actions.appendChild(buyBtn); actions.appendChild(deleteBtn); - productRow.appendChild(nameInput); productRow.appendChild(counter); productRow.appendChild(actions);