diff --git a/Bonus/bonus.css b/Bonus/bonus.css new file mode 100644 index 00000000..72cc724c --- /dev/null +++ b/Bonus/bonus.css @@ -0,0 +1,196 @@ +:root{ + --grey-color: rgb(86, 92, 106); + --blue-color: rgb(201, 225, 246); + --font-large: 52px; + --font-medium: 44px; + --font-small: 24px; +} + +body{ + box-sizing: border-box; +} + +*{ + color: var(--grey-color); + font-family: cursive; +} + +#start-screen{ + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + padding-top: 50px; + font-size: var(--font-large); + color: rgb(255, 255, 255); + width: 100vw; + height: 100vh; + color: var(--grey-color); + position: fixed; + top: 0; + left: 0; + background-color: var(--blue-color); +} + +h1{ + display: flex; + justify-content: center; + padding: 0; + margin-top: 0; + margin-bottom: 50px; +} + +section{ + font-size: var(--font-medium); + display: flex; + justify-content: center; + margin-bottom: 50px; +} + +#difficulty-select{ + border: 0; + border-radius: 50px; + margin-left: 10px; + text-align: center; + font-size: 0.8em; + font-family: inherit; + width: 200px; +} + +#difficulty-select:focus{ + outline: none; + border: 4px solid var(--grey-color); +} + +button{ + font-size: 1.4em; + font-family: inherit; + background-color: rgb(255, 255, 255); + border: 0; + border-radius: 50px; +} + +#start-bttn{ + width: 200px; + margin-top: 140px; +} + +#exit-bttn{ + width: 100px; + height: 40px; + position: absolute; + top: 20px; + right: 20px; +} + +#start-bttn:focus{ + border: 4px solid var(--grey-color); +} + +#exit-bttn:focus{ + border: 2px solid var(--grey-color); +} + +#sudoku{ + width: 652px !important; + height: 652px !important; +} + +div.wdr-cell{ + position: relative; + text-align: center !important; + font-weight: normal !important; + font-size: var(--font-small) !important; + pointer-events: none !important; +} + +/* Перший стовпець R1, R2, ... і 0-ий рядок C1, C2, ... */ +#wdr-pivot-view div[data-c="0"], #wdr-pivot-view div[data-r="0"]{ + font-weight: bold !important; + background-color: rgb(191, 197, 203) !important; +} + +/* Зробити текст у кутку невидимим */ +div.wdr-cell[data-r="0"][data-c="0"]{ + color: transparent !important; +} + +/* Зробити шахматне розфарбування */ +div.wdr-cell[data-r="1"]:is([data-c="1"], [data-c="2"], [data-c="3"], [data-c="7"], [data-c="8"], [data-c="9"]), +div.wdr-cell[data-r="2"]:is([data-c="1"], [data-c="2"], [data-c="3"], [data-c="7"], [data-c="8"], [data-c="9"]), +div.wdr-cell[data-r="3"]:is([data-c="1"], [data-c="2"], [data-c="3"], [data-c="7"], [data-c="8"], [data-c="9"]), +div.wdr-cell[data-r="4"]:is([data-c="4"], [data-c="5"], [data-c="6"]), +div.wdr-cell[data-r="5"]:is([data-c="4"], [data-c="5"], [data-c="6"]), +div.wdr-cell[data-r="6"]:is([data-c="4"], [data-c="5"], [data-c="6"]), +div.wdr-cell[data-r="7"]:is([data-c="1"], [data-c="2"], [data-c="3"], [data-c="7"], [data-c="8"], [data-c="9"]), +div.wdr-cell[data-r="8"]:is([data-c="1"], [data-c="2"], [data-c="3"], [data-c="7"], [data-c="8"], [data-c="9"]), +div.wdr-cell[data-r="9"]:is([data-c="1"], [data-c="2"], [data-c="3"], [data-c="7"], [data-c="8"], [data-c="9"]){ + background-color: rgb(225, 224, 224) !important; +} + +/* Приховати зайві елементи */ +.wdr-icon, .wdr-fields-view-wrap, .wdr-ui-element .wdr-ui .wdr-ui-list, .wdr-handle, #wdr-text-display, .wdr-ui-modal-overlay, #wdr-filter-view{ + display: none !important; +} + +.wdr-draggable{ /* заборона на перетаскування колонок */ + pointer-events: none !important; +} + +#game-screen{ + position: relative; + display: flex; + align-items: center; + justify-content: center; + width: 100vw; + height: 100vh; + position: fixed; + top: 0; + left: 0; + background-color: var(--blue-color); +} + +.user-input{ + pointer-events: all !important; + top: 0; + left: 0; + position: absolute; + background: transparent !important; + text-align: center !important; + width: 100%; + height: 100% !important; + font-size: var(--font-small) !important; +} + +.hidden{ + display: none !important; +} + +#wdr-pivot-view .wdr-ui input.correct{ + background-color: rgb(38, 167, 72, 0.4) !important; +} + +#wdr-pivot-view .wdr-ui input.incorrect{ + background-color: rgb(205, 51, 51, 0.4) !important; +} + +#win-dialog{ + border-radius: 20px; + border: 2px solid var(--grey-color); + padding: 4rem 10rem; +} + +#win-dialog::backdrop{ + background-color: rgba(0, 0, 0, 0.4); +} + +#close-dialog-bttn{ + color: rgb(208, 62, 62); + position: absolute; + top: 5px; + right: 5px; +} + +h2{ + font-size: var(--font-medium); +} \ No newline at end of file diff --git a/Bonus/bonus.js b/Bonus/bonus.js new file mode 100644 index 00000000..22f34f42 --- /dev/null +++ b/Bonus/bonus.js @@ -0,0 +1,256 @@ +let sudoku; +let userSudoku; +const gameState = {}; + +const startBttn = document.querySelector("#start-bttn"); +const startScreen = document.querySelector("#start-screen"); +// Початок гри +startBttn.addEventListener("click", function(event){ + sudoku = generateSudoku(); + userSudoku = generateUserSudoku(sudoku); + + // Для швидкої перевірки + for(row of sudoku){ + console.log(row); + } + + startScreen.classList.add("hidden"); + gameScreen.classList.remove("hidden"); + + + var pivot = new WebDataRocks({ + container: "#sudoku", + toolbar: false, + report: { + dataSource: { + data: convertToInlineJson(userSudoku) + }, + grid: { + type: "flat", + showHeaders: false, + showGrandTotals: "off", + }, + slice: { + rows: [{uniqueName: "Row", caption: " "}], + columns: Array.from({length: 9}, (_, i) => ({uniqueName: `C${i+1}`})) + }, + tableSizes: { + rows: Array.from({length: 10}, (_, i) => ({ idx: i, height: 65 })), + columns: Array.from({length: 10}, (_, i) => ({ idx: i, width: 65 })) + } + }, + global: { + options: { + sorting: "off", + configuratorButton: false, + configuratorButton: false + } + }, + reportcomplete: function() { + insertUserInput(userSudoku); + attachInputListeners(); + } + }); +}); + +// Відновити user-inputs при ресайзі +window.addEventListener("resize", function(){ + setTimeout(function(){ + insertUserInput(userSudoku); + attachInputListeners(); + renewInputs(); + }, 100); +}) + +// Вставити input для вводу цифр користувачем +function insertUserInput(userSudoku){ + const template = document.querySelector("template.input-template"); + const allCells = document.querySelectorAll("div.wdr-cell"); + + allCells.forEach(cell => { + const r = parseInt(cell.dataset.r); + const c = parseInt(cell.dataset.c); + + if(isNaN(r) || isNaN(c)) return; + if(r === 0 || c === 0) return; + if(r > 9 || c > 9) return; + + if(userSudoku[r - 1][c - 1] === " "){ + cell.textContent = ""; + const input = template.content.cloneNode(true).querySelector("input"); + + input.dataset.r = r; + input.dataset.c = c; + + cell.appendChild(input); + } + } + ) +} + +function attachInputListeners(){ + const userInputs = document.querySelectorAll(".user-input"); + const allInputs = document.querySelectorAll(".user-input"); + + userInputs.forEach(function(input){ + input.addEventListener("mousedown", function(event){ + event.stopPropagation(); + }) + }); + + // Перевірка введення + userInputs.forEach(function(input){ + input.addEventListener("input", function(event){ + const value = parseInt(event.target.value); + if(isNaN(value) || value === 0){ + event.target.value=""; + } + }) + }); + + // Перевірка на правильність, збереження даних гри + userInputs.forEach(function(input){ + input.addEventListener("blur", function(event){ + // Зберегти зміни + const key = `${event.target.dataset.r}-${event.target.dataset.c}`; + gameState[key] = {value: event.target.value}; + + if(event.target.value === ""){ + event.target.classList.remove("correct", "incorrect"); + return; + } + + const value = parseInt(event.target.value); + event.target.classList.remove("correct", "incorrect"); + const cell = event.target.closest("div.wdr-cell"); + const row = parseInt(cell.dataset.r)-1; + const column = parseInt(cell.dataset.c)-1; + if(value === sudoku[row][column]){ + event.target.classList.add("correct"); + gameState[key].cls="correct"; + // Перевірка, чи гра завершена + const allCorrect = [...allInputs].every(input => input.classList.contains("correct")); + if(allCorrect) dialogWin.showModal(); + } else{ + event.target.classList.add("incorrect"); + gameState[key].cls="incorrect"; + } + }) + }); +} + +// Оновити дані про input +function renewInputs(){ + const allInputs = document.querySelectorAll(".user-input"); + allInputs.forEach(function(input){ + const key = `${input.dataset.r}-${input.dataset.c}`; + if(gameState[key]){ + input.value = gameState[key].value; + if(gameState[key].cls){ + input.classList.add(gameState[key].cls); + } + } + }); +} + +// Кнопка виходу на стартовому вікні +const exitBttn = document.querySelector("#exit-bttn"); +const gameScreen = document.querySelector("#game-screen"); +exitBttn.addEventListener("click", function(event){ + startScreen.classList.remove("hidden"); + gameScreen.classList.add("hidden"); +}); + +// Генерація масиву для Судоку +function generateSudoku(){ + const sudoku = Array.from({ length: 9}, () => Array(9).fill(0)); // масив 9х9 + solve(sudoku); + return sudoku; +} + +// Заповнення масиву рекурсивно +function solve(arr, pos=0){ + if(pos === 81) return true; + + const row = Math.floor(pos/9); + const col = pos%9; + + for(const num of generateRandom()){ + if(isValid(arr, row, col, num)){ + arr[row][col] = num; + if(solve(arr, pos+1)) return true; + arr[row][col] = 0; + } + } + return false; +} + +// Fisher-Yates Shuffle +function generateRandom(){ + const nums = [1, 2, 3, 4, 5, 6, 7, 8, 9]; + for(let i=nums.length-1; i>0; i--){ + const j = Math.floor(Math.random()*(i+1)); + [nums[i], nums[j]] = [nums[j], nums[i]]; + } + return nums; + } + +// Перевірка на коректність +function isValid(array, row, col, num){ + if(array[row].includes(num)) return false; // у рядку + + for(let r=0; r<9; r++){ + if(array[r][col] === num) return false; // у стовпці + } + + const startRow = Math.floor(row/3)*3; // у квадраті 3х3 + const startCol = Math.floor(col/3)*3; + for(let r=startRow; r { + const rowObject = {}; + rowObject["Row"] = `R${rowIndex + 1}`; + row.forEach((num, colIndex) => { + rowObject[`C${colIndex+1}`] = num; + }); + return rowObject; + }) +} + +// Вибір складності +const diffSelect = document.querySelector("#difficulty-select"); +function generateUserSudoku(arr){ + const userSudoku = arr.map(row => [...row]); + let cellsToShow = 40; + const difficulty = diffSelect.value; + if(difficulty === "medium"){ + cellsToShow = 30; + }else if(difficulty === "hard"){ + cellsToShow = 25; + } + let cellsToRemove = 81 - cellsToShow; + while(cellsToRemove>0){ + const row = Math.floor(Math.random()*9); + const col = Math.floor(Math.random()*9); + if(userSudoku[row][col] !== " "){ + userSudoku[row][col] = " "; + cellsToRemove--; + } + } + return userSudoku; +} + +// Діалогове вікно перемоги +const dialogWin = document.querySelector("dialog"); +const dialogExitBttn = document.querySelector("#close-dialog-bttn"); +dialogExitBttn.addEventListener("click", function(event){ + dialogWin.close(); +}); \ No newline at end of file diff --git a/Bonus/mainBonus.html b/Bonus/mainBonus.html new file mode 100644 index 00000000..146e3e00 --- /dev/null +++ b/Bonus/mainBonus.html @@ -0,0 +1,49 @@ + + + + + + Гра Судоку + + + + + + + + +
+

SUDOKU

+ +
+ + +
+ +
+ +
+
+ + + +
+ + +

You won!

+
+
+ + + + \ No newline at end of file diff --git a/index.html b/index.html index 5971bf7d..e3788b91 100644 --- a/index.html +++ b/index.html @@ -1,16 +1,78 @@ - - - - My Page - - - - - - - Apple - 4 - - + + + Buy List + + + + + +
+

Buy List

+
+
+ +
+ + +
+ + + +
+ +
    + + +
+
+ + + +
+ +
+
+
Buy List
+
Created by:
Julia Sakharova
+
+
+ + + + \ No newline at end of file diff --git a/main.css b/main.css index 00bc872e..97b386f4 100644 --- a/main.css +++ b/main.css @@ -1,17 +1,261 @@ -.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; + margin: 0; + padding: 0; + outline: none; +} + +h1 { + display: flex; + justify-content: center; + color: #000000; + margin-bottom: 20px; + background-color: #f8f8f8; + padding: 10px 15px; + border-radius: 8px; + font-size: 36px; +} + +body { + font-family: Arial; + background: #dcdcdc; + padding: 20px; +} + +.layout { + display: grid; + grid-template-columns: 1fr minmax(160px, 400px); + gap: 30px +} +@media (max-width: 650px) { + .layout{ + grid-template-columns: 1fr; + } +} + +.ul { + list-style: none; +} + +.card, .sidebar{ + background: #f8f8f8; + border-radius: 8px; + padding: 16px 10px; + border: 1px solid #a5a5a5; +} + +.add-row { + height: 50px; + display: flex; + margin-bottom: 20px; +} + +.input-find { + font-size: 20px; + padding-left: 8px; + flex: 1; + border: 1px solid #c6c6c6; + border-top-left-radius: 4px; + border-bottom-left-radius: 4px; +} +.input-edit { + width: 140px; + padding: 4px; + font-size: 16px; + border-radius: 4px; + border: 1px solid #c6c6c6; +} +.input-find:focus, .input-edit:focus { + border: 2px solid #50a1db; +} + +.product-row { + display: grid; + grid-template-columns: 94px 1fr 130px; + align-items: center; + padding: 10px 0; + border-top: 1px solid #a5a5a5; + gap: 16px; +} +.quantity { + display: flex; + align-items: center; + justify-content: center; + gap: 8px; +} +.quantity-num { + background-color: #d8d8d8; + padding: 10px 14px; + border-radius: 8px; + width: 40px; + text-align: center; +} +.actions { + display: flex; + align-items: center; + justify-content: flex-end; + gap: 8px; +} + +.crossed {text-decoration: line-through;} + +button { + position: relative; + cursor: pointer; + border: none; + box-shadow: inset 0 -3px 3px #7473738e; + transition: 0.1s; +} +button:active { + box-shadow: 0 1px #7c7c7c8e; + transform: translateY(2px); +} +button:disabled { + opacity: 0.5; + cursor: default; + pointer-events: none; +} + +.btn-add { + padding: 0 30px; + font-size: 24px; + font-weight: bold; + background-color: #50a1db; + color: #f8f8f8; + border-top-right-radius: 8px; + border-bottom-right-radius: 8px; +} + +.btn-minus, .btn-plus { + height: 40px; + width: 40px; + font-size: 28px; + color: #f8f8f8; + border-radius: 50%; +} +.btn-plus {background: #84d751;} +.btn-minus {background: #e5484b;} + +.btn-status { + height: 40px; + font-size: 16px; + padding: 0 20px; + color: #000000; + background: #e1e0e0; + border-radius: 8px; +} + +.btn-del { + height: 40px; + font-size: 24px; + color: #f8f8f8; + background: #e5484b; + border-radius: 30%; + aspect-ratio: 1/1; +} + +[data-tooltip]::after { + content: attr(data-tooltip); + position: absolute; + white-space: nowrap; + padding: 8px 8px; + bottom: calc(110%); + left: 50%; + transform: translateX(-50%); + transform-origin: bottom center; + background-color: #7d0083; + color: #f8f8f8; + font-size: 14px; + border-radius: 14px; + opacity: 0; + transition: 0,3s opacity ease-out, transform 0.3s ease-out; + pointer-events: none; +} +[data-tooltip]:hover::after { + opacity: 80%; + transform: translateX(-50%); +} + +.sidebar-title { + font-size: 24px; + padding: 12px 0; +} +.product-tags { + display: flex; + flex-wrap: wrap; + gap: 4px; + padding: 28px 0; + border-top: 1px solid #a5a5a5; + border-bottom: 1px solid #a5a5a5; +} +.product-tag { + background-color: #e1e0e0; + padding: 6px 10px; + border-radius: 8px; +} +.num-tag { + color: #f8f8f8; + background-color: #f88024; + border-radius: 50%; + font-size: 16px; + padding: 2px 6px; + margin-left: 4px; + text-decoration-color: #f8f8f8; +} + +.badge { + display: flex; + flex-direction: column; + align-items: center; + height: 80px; + width: 240px; + background-color: #7d0083; + color: #f8f8f8; + border-top-left-radius: 8px; + border-top-right-radius: 8px; + cursor: pointer; + transition: background-color 0.5s ease-out, height 0.5s ease-out; + position: fixed; + bottom: 0; + left: 50px; + overflow: hidden; +} +.badge:hover { + background-color: #5f33e3; + height: 160px; +} +.badge-content{ + display: flex; + flex-direction: column; + align-items: center; + width: 100%; + height: 160px; + transition: transform 0.5s ease-out; +} +.badge-title { + height: 80px; + display: flex; + justify-content: center; + align-items: center; + font-size: 28px; + font-weight: bold; +} +.badge-creator { + height: 80px; + display: flex; + justify-content: center; + align-items: center; + font-size: 24px; +} + +@media print { + .badge { + background-color: #ffffff; + color:#000000; + border: 3px solid #7d0083; + height: 80px; + } + .badge-title { + display: none; + } } \ No newline at end of file diff --git a/main.js b/main.js new file mode 100644 index 00000000..d599e571 --- /dev/null +++ b/main.js @@ -0,0 +1,241 @@ +const form = document.querySelector('.add-row'); +const inputFind = document.querySelector('.input-find'); +const productList = document.querySelector('.product-list'); +const templateProductRow = document.querySelector('#template-product-row'); +const sidebarLeftToBuy = document.querySelector('.sidebar-left-to-buy'); +const sidebarBought = document.querySelector('.sidebar-bought'); +const templateProductTag = document.querySelector('#template-sidebar-product'); + +// Список 3 продуктів, які додаються при запуску автоматично (блоки продуктів з html видалено) +const initialProducts = ['Tomatoes', 'Cookies', 'Cheese']; + + // --- Функції: --- + +function addProduct(name){ +// Додати новий продукт у кінець списку після натискання кнопки "Add"/Enter + const formattedName = name.charAt(0).toUpperCase() + name.slice(1).toLowerCase(); + + // Перевірка, чи продукт із таким ім'ям вже доданий + const addedNames = productList.querySelectorAll('.product-name'); + for(const addedName of addedNames){ + if(addedName.textContent === formattedName) return; + } + + const newProductRow = templateProductRow.content.cloneNode(true); + newProductRow.querySelector('.product-name').textContent = formattedName; + productList.appendChild(newProductRow); +} + +function changeStatus(productRow, btnStatus){ +// Змінити статус продукту, кнопка статусу - "Buy" (некуплений), "Cancel" (куплений) + const productName = productRow.querySelector('.product-name'); + const btnMinus = productRow.querySelector('.btn-minus'); + const btnPlus = productRow.querySelector('.btn-plus'); + const btnDel = productRow.querySelector('.btn-del'); + const isBought = productName.classList.contains('crossed'); + + if(!isBought){ + productName.classList.add('crossed'); + btnMinus.style.display = 'none'; + btnPlus.style.display = 'none'; + btnDel.style.display = 'none'; + btnStatus.textContent = 'Cancel'; + } else{ + productName.classList.remove('crossed'); + btnMinus.style.display = ''; + btnPlus.style.display = ''; + btnDel.style.display = ''; + btnStatus.textContent = 'Buy'; + } +} + +function changeProductName(productRow){ +// Змінити назву некупленого продукту через натискання на нього + const productName=productRow.querySelector('.product-name'); + const isBought = productName.classList.contains('crossed'); + if(isBought) return; + + const oldValue = productName.textContent; + const newInput = document.createElement('input'); + newInput.type = 'text'; + newInput.className = 'input-edit'; + newInput.value = oldValue; + + productName.replaceWith(newInput); + newInput.focus(); + + newInput.addEventListener('blur', function(event){ + // Зберегти змінену назву, прибрати input + let newValue = newInput.value.trim(); + if(newValue === ''){ + newValue = oldValue; + } + + const newName = document.createElement('div'); + newName.className = 'product-name'; + newName.textContent=newValue.charAt(0).toUpperCase()+newValue.slice(1).toLowerCase(); + + newInput.replaceWith(newName); + updateSidebar(); + saveToStorage(); + }); + + newInput.addEventListener('keydown', function(event){ + if(event.key === 'Enter'){ + newInput.blur(); + } + }) +} + +function decreaseQuantity(productRow){ +// Зменшити кількість товару, зробити кнопку "-" неактивною, якщо кількість = 1 + const quantity = productRow.querySelector('.quantity-num'); + const btnMinus = productRow.querySelector('.btn-minus'); + quantity.textContent = Number(quantity.textContent) - 1; + if(quantity.textContent === '1'){ + btnMinus.disabled = true; + } +} + +function increaseQuantity(productRow){ +// Збільшити кількість товару + const quantity = productRow.querySelector('.quantity-num'); + const btnMinus = productRow.querySelector('.btn-minus'); + quantity.textContent = Number(quantity.textContent) + 1; + btnMinus.disabled = false; +} + +function updateSidebar(){ +// Оновлення бічної панелі (секцій "Left to buy" і "Bought") + const allProductRows = productList.querySelectorAll('.product-row'); + + sidebarLeftToBuy.querySelector('.product-tags').innerHTML = ''; + sidebarBought.querySelector('.product-tags').innerHTML = ''; + + allProductRows.forEach(function(productRow){ + const productName = productRow.querySelector('.product-name'); + if(productName === null) return; // Перейти до наступного продукта, якшо назви немає (користувач її редагує) + + const productQuantity = productRow.querySelector('.quantity-num'); + const isBought = productName.classList.contains('crossed'); + + const productTag = templateProductTag.content.cloneNode(true); + productTag.querySelector('.product-name').textContent = productName.textContent; + productTag.querySelector('.num-tag').textContent = productQuantity.textContent; + + if(isBought){ + productTag.querySelector('.product-name').classList.add('crossed'); + productTag.querySelector('.num-tag').classList.add('crossed'); + sidebarBought.querySelector('.product-tags').appendChild(productTag); + } else{ + sidebarLeftToBuy.querySelector('.product-tags').appendChild(productTag); + } + }) +} + +// --- Бонус, зберігання поточного стану кошика: --- + +function saveToStorage(){ +// Зберегти (перезааписати) усі продукти з корзини у сховище браузера + const allProductRows = productList.querySelectorAll('.product-row'); + const products = []; + + allProductRows.forEach(function(productRow){ + const productName = productRow.querySelector('.product-name'); + const productQuantity = productRow.querySelector('.quantity-num'); + const isBought = productName.classList.contains('crossed'); + + products.push({ + name: productName.textContent, + quantity: Number(productQuantity.textContent), + isBought: isBought + }); + }); + + sessionStorage.setItem('products', JSON.stringify(products)); +} + +function loadFromStorage(){ +// Завантажити попередньо збережені продукти або додати 3 продукти із початкового списку (якщо в сховищі пусто) + const savedProducts = sessionStorage.getItem('products'); + + if(savedProducts === null){ + initialProducts.forEach(function(name){ + // Додати 3 продукти до списку + addProduct(name); + }); + return; + } + + const products = JSON.parse(savedProducts); + products.forEach(function(product){ + addProduct(product.name); + + // Відновити кількість та статус + const lastRow = productList.querySelector('.product-row:last-child'); + + const quantityNum = lastRow.querySelector('.quantity-num'); + quantityNum.textContent = product.quantity; + const btnMinus = lastRow.querySelector('.btn-minus'); + if(product.quantity > 1){ + btnMinus.disabled = false; + } + + if(product.isBought){ + const btnStatus = lastRow.querySelector('.btn-status'); + changeStatus(lastRow, btnStatus); + } + }); +} + +loadFromStorage(); +updateSidebar(); + + // --- Слухачі подій: --- + +form.addEventListener('submit', function(event){ +// Слухач для додавання нових продуктів + event.preventDefault(); + + const productName = inputFind.value.trim(); + if(productName === '') return; + addProduct(productName); + + inputFind.value = ''; + inputFind.focus(); + + updateSidebar(); + saveToStorage(); +}); + +productList.addEventListener('click', function(event){ +// Подія прив'язана до батьківського елемента + const productRow = event.target.closest('.product-row'); + + if(event.target.classList.contains('btn-del')){ + // Видалення + productRow.remove(); + + } else if(event.target.classList.contains('btn-status')){ + // Зміна статусу + const btnStatus = event.target; + changeStatus(productRow, btnStatus); + + } else if(event.target.classList.contains('product-name')){ + // Редагування назви товару + changeProductName(productRow); // Викликаємо updateSidebar() та saveToStorage() усередині після 'blur' + return; + + } else if(event.target.classList.contains('btn-minus')){ + // Зменшення кількості + decreaseQuantity(productRow); + + } else if(event.target.classList.contains('btn-plus')){ + // Збільшення кількості + increaseQuantity(productRow); + + } + + updateSidebar(); + saveToStorage(); +}); \ No newline at end of file