diff --git a/index.html b/index.html index 5971bf7..6efa9e0 100644 --- a/index.html +++ b/index.html @@ -1,16 +1,88 @@ - - + + - My Page - - + Кошик + - - Apple - 4 - +
+
+
+ + +
+ +
+
+ +
+
+ 2 +
+
+ +
+
+ +
+
+ +
+
+ + 2 + +
+
+ + +
+
+ +
+
+ +
+
+ + 1 + +
+
+ + +
+
+
+ +
+

Залишилося

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

Куплено

+
+
Помідори + 2 +
+
+
+
+ +
+ Buy List +

+ Created by: Borozniak Alina +

+
+ \ No newline at end of file diff --git a/main.css b/main.css index 00bc872..5e6b199 100644 --- a/main.css +++ b/main.css @@ -1,17 +1,339 @@ -.product-item { - background-color: gray; - display: inline-block; - height: 25px; - padding: 5px; - border-radius: 5px; -} - -.amount { - background-color: yellow; - border-radius: 10px; - - display: inline-block; - height: 20px; - width: 20px; - text-align: center; +* { + box-sizing: border-box; /*щоб додатково до ширини та висоти елементів не додавалися відступи та рамки*/ + font-family: 'Arial', sans-serif; +} + +body { + background-color: darkgrey; +} + +.container { + display: grid; + grid-template-columns: 2fr 1fr; + align-items: start; + padding: 20px; + gap: 20px; +} + +.flex-products { + display: flex; + flex-direction: column; + align-items: stretch; /*елементи заповнюють всю ширину контейнера*/ + background-color: white; + border-radius: 5px; + box-shadow: 0px 0px 10px rgba(0, 0, 0, 0.1); +} + +.product-category { + margin: 0px; + font-size: 28px; + color: black; +} + +.product-category, .remaining-products, .bought-products { + padding: 15px; + border-bottom: 2px solid #bbb; +} + +.bought-products .product-item .amount, .bought-products .product-item { + text-decoration: line-through; /*перекреслює елементи, які були придбані*/ +} + +.bought-products:last-child { + border-bottom: none; +} + +.right .product-item { + display: inline-flex; + justify-content: flex-start; /*вирівнює елементи по лівому краю*/ + align-items: center; + padding: 8px 14px; + gap: 5px; + background-color: rgb(226, 225, 225); + color: dimgray; + border-radius: 5px; + box-sizing: border-box; + font-size: 16px; + font-weight: bold; + margin: 2px; +} + +.right .amount { + display: flex; + justify-content: center; /*горизонтальне вирівнювання*/ + align-items: center; /*вертикальне вирівнювання*/ + background-color: rgb(255, 149, 0); + color: white; + border-radius: 50%; /*округлення*/ + font-size: 14px; + font-weight: bold; + height: 26px; + min-width: 26px; +} + +.search-products { + display: flex; + padding: 20px; +} + +.add-product, .add-button{ + height: 50px; /*висота поля вводу та кнопки*/ + font-size: 18px; +} + +.add-product { + flex: 7.5; + padding-left: 20px; /*відступ зліва для тексту*/ + border-top-left-radius: 5px; + border-bottom-left-radius: 5px; + border: 2px solid darkgray; + border-right: none; + outline: none; +} + +.add-button { + position: relative; + flex: 1.5; + border: none; + border-top-right-radius: 5px; + border-bottom-right-radius: 5px; + background-color: #4f66cd; + color: white; + font-weight: bold; + box-shadow: inset 0px -5px 0px rgba(0, 0, 0, 0.2); + cursor: pointer; + padding: 12px 24px; +} + +.add-product:focus { + border-color:#4f66cd; +} + +.left .product-item { + display: flex; + justify-content: space-between; + align-items: center; + border-top: 2px solid #ccc; + padding: 10px 20px; +} + +.name-of-product, .product-controls, .product-actions { + flex: 2; + display: flex; + align-items: center; /*вертикальне вирівнювання елементів*/ + gap: 5px; +} + +.name-of-product { + justify-content: flex-start; /*вирівнювання по лівому краю*/ +} + +.product-controls { + justify-content: center; /*вирівнювання по центру*/ +} + +.product-actions { + justify-content: flex-end; /*вирівнювання по правому краю*/ +} + +.product-name { + width: 70%; /*ширина поля вводу*/ + border: none; + border-radius: 2px; + font-size: 18px; + color: black; + background-color: white; +} + +.product-name:disabled{ + text-decoration: line-through; +} + +.product-name:focus { + cursor: default; + outline: none; + border: 1px solid #4f66cd; + box-shadow: 0px 0px 6px rgba(79, 102, 205, 0.5); +} + +.minus-button, .plus-button { + position: relative; + border: none; + border-radius: 50%; + width: 35px; + height: 35px; + color: white; + font-size: 18px; + font-weight: bold; + cursor: pointer; + box-shadow: inset 0px -4px 0px rgba(0, 0, 0, 0.2); +} + +.delete-button { + position: relative; + border: none; + border-radius: 5px; + width: 35px; + height: 35px; + color: white; + font-size: 18px; + font-weight: bold; + cursor: pointer; + box-shadow: inset 0px -4px 0px rgba(0, 0, 0, 0.2); +} + +.amount, .status { + display: flex; + align-items: center; + justify-content: center; + height: 35px; +} + +.status { + position: relative; + padding-left:15px; + padding-right: 15px; + background-color:rgb(239, 238, 238); + color:dimgray; + border: 2px solid #bbb; + border-radius: 5px; + font-size: 14px; + font-weight: bold; + box-shadow: inset 0px -4px 0px rgba(0, 0, 0, 0.1); +} + +.left .amount { + min-width: 35px; + font-size: 16px; + font-weight: bold; + border-radius: 4px; + color: dimgray; + background-color: rgb(226, 225, 225); + line-height: 35px; +} + +.minus-button, .delete-button { + background-color: #d9534f; +} + +.plus-button { + background-color: #5cb85c; +} + +.minus-button:disabled { + cursor: not-allowed; + opacity: 0.5; +} + +.add-button:active { + background-color: #3e5bbf; +} + +.plus-button:active { + background-color: #4cae4c; +} + +.minus-button:not(:disabled):active, .delete-button:active { + background-color: #c9302c; +} + +.status:active { + background-color: #d9d9d9; +} + + +button::after { + content: attr(data-tooltip); + position: absolute; + top: -30px; + left: 50%; /* ліва границя підказки буде по центру кнопки */ + transform: translate(-50%, 5px); /*зміщує підказку назад на пловину її ширини та трохи вниз*/ + background-color: purple; + color: white; + padding: 6px 12px; + font-size: 14px; + border-radius: 8px; + white-space: nowrap; + transition: + opacity 0.3s ease, + transform 0.3s ease; + opacity: 0; + pointer-events: none; +} + +button:hover::after { + transform: translate(-50%, 0); /* піднімається вгору */ + opacity: 1; +} + +.badge { + position: fixed; + left: 20px; + bottom: 0; + display: flex; + width: 120px; + flex-direction: column; + background-color: purple; + padding: 10px; + color: white; + border-radius: 8px 8px 0 0; + transition: transform 0.3s ease, background-color 0.3s ease; + transform: translateY(50%); +} + +.badge-name { + flex: 1; + text-align: center; + font-size: 18px; + font-weight: bold; +} + +.author { + flex: 1; + display: flex; + flex-direction: column; + gap: 5px; + justify-content: flex-start; + text-align: left; + visibility: hidden; + font-size: 12px; + transition: opacity 0.3s ease; +} + +.author-description { + font-size: 8px; +} + +.badge:hover { + transform: translateY(0); + background-color: rgb(29, 2, 128); +} + +.badge:hover .author{ + visibility: visible; +} + +@media print { + .badge-name { + display: none; + } + + .badge { + left: 20px; + bottom: 45px; + background-color: white; + border: 2px solid purple; + padding: 0px 10px; + } + + .author { + color: black; + visibility: visible; + } +} + +@media (max-width: 650px) { + .container { + grid-template-columns: 1fr; + } } \ No newline at end of file diff --git a/main.js b/main.js new file mode 100644 index 0000000..704edde --- /dev/null +++ b/main.js @@ -0,0 +1,196 @@ +document.addEventListener('DOMContentLoaded', () => { + + const inputProduct = document.querySelector('.add-product'); + const addButton = document.querySelector('.add-button'); + const productList = document.querySelector('.left'); + const remainingProducts = document.querySelector('.remaining-products'); + const boughtProducts = document.querySelector('.bought-products'); + + let products = [ + { name: "Помідори", count: 2, bought: true }, + { name: "Печиво", count: 2, bought: false }, + { name: "Сир", count: 1, bought: false }, + ]; + + function addProduct() { + const name = inputProduct.value.trim(); + if (name !== "") { + products.push({ name, count: 1, bought: false }); + inputProduct.value = ""; + inputProduct.focus(); + initialProducts(); + } + } + + addButton.addEventListener('click', () => { + addProduct(); + }); + + inputProduct.addEventListener('keydown', (e) => { + if (e.key === 'Enter') { + addProduct(); + } + }); + + function initialProducts() { + const productItems = productList.querySelectorAll('.product-item'); + productItems.forEach(item => item.remove()); + + products.forEach((product, i) => { + const productItem = document.createElement('div'); + productItem.className = 'product-item'; + + const nameContainer = document.createElement('div'); + nameContainer.className = 'name-of-product'; + + const nameProduct = document.createElement('span'); + nameProduct.className = 'product-name'; + nameProduct.textContent = product.name; + + nameContainer.appendChild(nameProduct); + + const controlsContainer = document.createElement('div'); + controlsContainer.className = 'product-controls'; + + let minusButton, plusButton, deleteButton; + + if (!product.bought) { + minusButton = document.createElement('button'); + minusButton.className = 'minus-button'; + minusButton.textContent = '−'; + minusButton.disabled = (product.count === 1); + minusButton.setAttribute('data-tooltip', 'Зменшити кількість товару'); + } + + const amount = document.createElement('span'); + amount.className = 'amount'; + amount.textContent = product.count; + + if(!product.bought) { + plusButton = document.createElement('button'); + plusButton.className = 'plus-button'; + plusButton.textContent = '+'; + plusButton.setAttribute('data-tooltip', 'Збільшити кількість товару'); + } + + if (minusButton) controlsContainer.appendChild(minusButton); + controlsContainer.appendChild(amount); + if (plusButton) controlsContainer.appendChild(plusButton); + + const actionsContainer = document.createElement('div'); + actionsContainer.className = 'product-actions'; + + const statusButton = document.createElement('button'); + statusButton.className = 'status'; + statusButton.textContent = product.bought ? 'Не куплено' : 'Куплено'; + statusButton.setAttribute('data-tooltip', 'Зробити товар купленим або не купленим'); + + if (!product.bought) { + deleteButton = document.createElement('button'); + deleteButton.className = 'delete-button'; + deleteButton.textContent = '×'; + deleteButton.setAttribute('data-tooltip', 'Видалити товар'); + } + + actionsContainer.appendChild(statusButton); + if (deleteButton) actionsContainer.appendChild(deleteButton); + + productItem.append(nameContainer, controlsContainer, actionsContainer); + productList.appendChild(productItem); + + setUpProduct(productItem, i); + }); + + updateStatistics(); + } + + function setUpProduct(productItem, i) { + const minus = productItem.querySelector('.minus-button'); + const plus = productItem.querySelector('.plus-button'); + const amount = productItem.querySelector('.amount'); + const status = productItem.querySelector('.status'); + const remove = productItem.querySelector('.delete-button'); + const name = productItem.querySelector('.product-name'); + + if(minus){ + minus.addEventListener('click', () => { + if (products[i].count > 1) { + products[i].count--; + amount.textContent = products[i].count; + if (products[i].count === 1) { + minus.disabled = true; + minus.setAttribute('data-tooltip', 'Кількість товару не може бути менше 1'); + } + updateStatistics(); + } + }); + } + + if(plus){ + plus.addEventListener('click', () => { + products[i].count++; + amount.textContent = products[i].count; + minus.disabled = false; + updateStatistics(); + }); + } + + if (remove){ + remove.addEventListener('click', () => { + products.splice(i, 1); /* видаляємо товар з масиву */ + initialProducts(); + }); + } + + status.addEventListener('click', () => { + products[i].bought = !products[i].bought; + initialProducts(); + }); + + if (!products[i].bought) { + name.addEventListener('click', () => { + const input = document.createElement('input'); + input.type = 'text'; + input.className = 'product-name'; + input.value = products[i].name; + + name.replaceWith(input); + input.focus(); + + input.addEventListener('blur', () => { + const newName = input.value.trim() || products[i].name; + products[i].name = newName; + + input.replaceWith(name); + name.textContent = newName; + updateStatistics(); + }); + }); + } + } + + function updateStatistics() { + remainingProducts.innerHTML = ''; + boughtProducts.innerHTML = ''; + + products.forEach(product => { + const productStatistics = document.createElement('div'); + productStatistics.className = 'product-item'; + productStatistics.textContent = product.name; + + const amountStatistics = document.createElement('span'); + amountStatistics.className = 'amount'; + amountStatistics.textContent = product.count; + + productStatistics.appendChild(amountStatistics); + + if (!product.bought) { + remainingProducts.appendChild(productStatistics); + } else { + boughtProducts.appendChild(productStatistics); + } + }); + } + + initialProducts(); +});