From 2bf65f1641fe9923745a07923d139960e5618623 Mon Sep 17 00:00:00 2001 From: Jane-Kriuchko Date: Sat, 16 May 2026 16:44:33 +0300 Subject: [PATCH 1/4] Homework 1 --- index.html | 61 +++++++++++++++++++-- main.css | 158 ++++++++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 212 insertions(+), 7 deletions(-) diff --git a/index.html b/index.html index 5971bf7d..64d28ee7 100644 --- a/index.html +++ b/index.html @@ -8,9 +8,62 @@ - - Apple - 4 - +
+
+ + +
+ + + Apple +
+ + 4 + +
+ + +
+ + + Orange +
+ + 4 + +
+ + +
+ + + Cheese +
+ + 1 + +
+ + +
+ + + + Coockie +
+ + 2 + +
+ + +
+
+ + \ No newline at end of file diff --git a/main.css b/main.css index 00bc872e..443722bd 100644 --- a/main.css +++ b/main.css @@ -1,17 +1,169 @@ +body { + background-color: rgb(175, 175, 175); +} + +[data-tooltip] { + position: relative; + cursor: pointer; +} + +[data-tooltip]::after { + content: attr(data-tooltip); + position: absolute; + bottom: 125%; + left: 0%; + border: none; + background-color: #d00ad7; + color: #ffffff; + border-radius: 10px; + font-size: 14px; + white-space: nowrap; + + opacity: 0; + transition: 1s; + pointer-events: none; +} + +[data-tooltip]:hover::after { + display: block; + position: absolute; + padding: 7px; + border-radius: 7px; + opacity: 1; +} + +.badge { + border: none; + background-color: #d00ad7; + color: #ffffff; + border-radius: 10px 10px 0px 0; + font-size: 16px; + padding: 13px; + position: fixed; + bottom: 0; + left: 5px; + text-align: left; + transition: background-color 1s, height 2s linear; +} + +.badge-by { + display: block; + font-size: 10px; + margin: 10px 0 2px 0; + visibility: hidden; + height: 0; + transition: height 2s linear; +} + +.badge-name{ + display: block; + visibility: hidden; + height: 0; + transition: height 2s linear; +} + +.badge:hover { + background-color: #2954ca; +} + +.badge:hover .badge-by, .badge:hover .badge-name { + visibility: visible; + height: auto; +} + +.badge:active { + background-color: aliceblue; + border: 2px solid #d00ad7; + color: #d00ad7; +} + +.badge:active b { + display: none; +} + +.add-product-item { + color: lightslategray; + padding-bottom: 5px; + font-size: 20px; +} + +.text_input { + width: 300px; + padding: 3px; +} + +.button-add { + background-color: #2954ca; + color: white; + border: none; + padding: 4px 8px; +} + .product-item { - background-color: gray; + width: 450px; + background-color: rgb(255, 255, 255); display: inline-block; height: 25px; padding: 5px; border-radius: 5px; + margin: 0px 0px 5px 0px; + position: relative; +} + +.amount-block { + display: inline-block; + position: absolute; + right: 40%; } .amount { - background-color: yellow; - border-radius: 10px; + background-color: rgb(175, 175, 175); + border-radius: 5px; display: inline-block; height: 20px; width: 20px; text-align: center; +} + +.plus { + background-color: #2ac92f; + color: white; + border: none; + padding: 4px 8px; + border-radius: 15px; +} + +.plus:hover { + background-color: #166818; +} + +.minus { + background-color: #ca2929; + color: white; + border: none; + padding: 4px 8px; + border-radius: 15px; +} + +.minus:hover { + background-color: #991e1e; +} + +.button-bought { + position: absolute; + right: 15%; +} + +.button-del { + background-color: #ca2929; + color: white; + border: none; + padding: 4px 8px; + border-radius: 5px; + float: right; +} + +.button-del:hover { + background-color: #991e1e; } \ No newline at end of file From 6dbe136cef5aa18a4084cea99e940e88e9526af0 Mon Sep 17 00:00:00 2001 From: Jane-Kriuchko Date: Sat, 23 May 2026 15:39:41 +0300 Subject: [PATCH 2/4] Homework 2 --- .js | 158 +++++++++++++++++++++++++++++++++++++++++++++++++++++ index.html | 58 +++++--------------- main.css | 63 +++++++++++++++++++++ 3 files changed, 234 insertions(+), 45 deletions(-) create mode 100644 .js diff --git a/.js b/.js new file mode 100644 index 00000000..e99470a6 --- /dev/null +++ b/.js @@ -0,0 +1,158 @@ +const input = document.querySelector('.text_input'); +const addButton = document.querySelector('.button-add'); +const productList = document.querySelector('.block'); +const initialProducts = ['Apple', 'Orange', 'Cheese']; + +initialProducts.forEach(name => { + productList.appendChild(createProductItem(name)); +}); + +function createProductItem(name) { + const productItem = document.createElement('span'); + productItem.className = 'product-item'; + productItem.innerHTML = ` + ${name} +
+ + 1 + +
+ + + `; + attachProductHandlers(productItem); + return productItem; +} + +function attachProductHandlers(productItem) { + const nameSpan = productItem.querySelector('.product-name'); + const deleteButton = productItem.querySelector('.button-del'); + const boughtButton = productItem.querySelector('.button-bought'); + const minusButton = productItem.querySelector('.minus'); + const plusButton = productItem.querySelector('.plus'); + const amountSpan = productItem.querySelector('.amount'); + + function updateAmountSymbolState() { + const currentAmount = Number(amountSpan.textContent); + minusButton.disabled = currentAmount <= 1; + plusButton.disabled = currentAmount >= 99; + } + + updateAmountSymbolState(); + + nameSpan.addEventListener('click', () => { + if (!productItem.classList.contains('bought')) { + editProductName(nameSpan); + } + }); + + deleteButton.addEventListener('click', () => { + productItem.remove(); + refreshStatistics(); + }); + + plusButton.addEventListener('click', () => { + const currentAmount = Number(amountSpan.textContent); + amountSpan.textContent = currentAmount + 1; + updateAmountSymbolState(); + refreshStatistics(); + }); + + minusButton.addEventListener('click', () => { + const currentAmount = Number(amountSpan.textContent); + if (currentAmount > 1) { + amountSpan.textContent = currentAmount - 1; + updateAmountSymbolState(); + refreshStatistics(); + } + }); + + boughtButton.addEventListener('click', () => { + productItem.classList.toggle('bought'); + boughtButton.textContent = productItem.classList.contains('bought') ? 'Undo' : 'Bought'; + refreshStatistics(); + }); +} + +function refreshStatistics() { + const leftContainer = document.getElementById('stats-left'); + const boughtContainer = document.getElementById('stats-bought'); + leftContainer.innerHTML = ''; + boughtContainer.innerHTML = ''; + + document.querySelectorAll('.product-item').forEach(item => { + const name = item.querySelector('.product-name').textContent.trim(); + const amount = item.querySelector('.amount').textContent.trim(); + const statItem = document.createElement('div'); + statItem.className = 'stats-item'; + statItem.innerHTML = ` + ${name} + ${amount} + `; + + if (item.classList.contains('bought')) { + boughtContainer.appendChild(statItem); + } else { + leftContainer.appendChild(statItem); + } + }); +} + + +function editProductName(nameSpan) { + const currentName = nameSpan.textContent; + const input = document.createElement('input'); + input.type = 'text'; + input.className = 'product-name-edit'; + input.value = currentName; + + nameSpan.replaceWith(input); + input.focus(); + input.select(); + + function saveEdit() { + const newName = input.value.trim() || currentName; + const newNameSpan = document.createElement('span'); + newNameSpan.className = 'product-name'; + newNameSpan.textContent = newName; + + input.replaceWith(newNameSpan); + newNameSpan.addEventListener('click', () => { + if (!newNameSpan.closest('.product-item').classList.contains('bought')) { + editProductName(newNameSpan); + } + }); + refreshStatistics(); + } + + input.addEventListener('blur', saveEdit); + input.addEventListener('keydown', event => { + if (event.key === 'Enter') { + input.blur(); + } + }); +} + +function addProduct() { + const value = input.value.trim(); + if (!value) { + input.value = ''; + input.focus(); + return; + } + + productList.appendChild(createProductItem(value)); + refreshStatistics(); + input.value = ''; + input.focus(); +} + +addButton.addEventListener('click', addProduct); +input.addEventListener('keydown', event => { + if (event.key === 'Enter') { + event.preventDefault(); + addProduct(); + } +}); + +refreshStatistics(); diff --git a/index.html b/index.html index 64d28ee7..a04d02ec 100644 --- a/index.html +++ b/index.html @@ -1,6 +1,6 @@ - + My Page @@ -13,51 +13,18 @@ + - - Apple -
- - 4 - -
- - -
- - - Orange -
- - 4 - -
- - -
- - - Cheese -
- - 1 - -
- - -
- - - - Coockie -
- - 2 - -
- - -
+
+
+
To Buy
+
+
+
+
+
Bought
+
+
+ \ No newline at end of file diff --git a/main.css b/main.css index 443722bd..87f84d84 100644 --- a/main.css +++ b/main.css @@ -166,4 +166,67 @@ body { .button-del:hover { background-color: #991e1e; +} + +.minus:disabled, +.plus:disabled { + opacity: 0.5; + cursor: not-allowed; +} + +.stats-section { + width: 450px; + margin-top: 20px; + padding: 10px; + background-color: white; + border-radius: 8px; +} + +.stats-group { + padding: 10px 0; +} + +.stats-title { + font-weight: bold; + margin-bottom: 8px; +} + +.stats-divider { + height: 1px; + background-color: rgb(175, 175, 175); +} + +.stats-list { + display: block; +} + +.stats-item { + display: inline-block; + align-items: center; + gap: 8px; + padding: 4px 6px; + background-color: rgb(175, 175, 175); + border-radius: 6px; + margin: 5px; +} + +.stats-product-name { + font-size: 14px; +} + +.stats-amount { + background-color: orange; + color: white; + padding: 2px 7px; + border-radius: 12px; + font-weight: bold; + text-align: center; +} + +.product-item.bought .product-name { + text-decoration: line-through; +} + +.product-item.bought .amount-block, .product-item.bought .button-del { + display: none; } \ No newline at end of file From d052cdab423ead48dd60b9e2fab1501b4338a08e Mon Sep 17 00:00:00 2001 From: Jane-Kriuchko Date: Sat, 23 May 2026 15:58:27 +0300 Subject: [PATCH 3/4] Homework 2 --- .js | 2 +- index.html | 1 + main.css | 28 ++++++++++++++-------------- 3 files changed, 16 insertions(+), 15 deletions(-) diff --git a/.js b/.js index e99470a6..08e3377a 100644 --- a/.js +++ b/.js @@ -155,4 +155,4 @@ input.addEventListener('keydown', event => { } }); -refreshStatistics(); +refreshStatistics(); \ No newline at end of file diff --git a/index.html b/index.html index a04d02ec..8a852a23 100644 --- a/index.html +++ b/index.html @@ -7,6 +7,7 @@ +
diff --git a/main.css b/main.css index 87f84d84..800be954 100644 --- a/main.css +++ b/main.css @@ -1,5 +1,5 @@ body { - background-color: rgb(175, 175, 175); + background-color: #afafaf; } [data-tooltip] { @@ -72,7 +72,7 @@ body { } .badge:active { - background-color: aliceblue; + background-color: #f0f8ff; border: 2px solid #d00ad7; color: #d00ad7; } @@ -82,7 +82,7 @@ body { } .add-product-item { - color: lightslategray; + color: #778899; padding-bottom: 5px; font-size: 20px; } @@ -94,14 +94,14 @@ body { .button-add { background-color: #2954ca; - color: white; + color: #ffffff; border: none; padding: 4px 8px; } .product-item { width: 450px; - background-color: rgb(255, 255, 255); + background-color: #ffffff; display: inline-block; height: 25px; padding: 5px; @@ -117,7 +117,7 @@ body { } .amount { - background-color: rgb(175, 175, 175); + background-color: #afafaf; border-radius: 5px; display: inline-block; @@ -128,7 +128,7 @@ body { .plus { background-color: #2ac92f; - color: white; + color: #ffffff; border: none; padding: 4px 8px; border-radius: 15px; @@ -140,7 +140,7 @@ body { .minus { background-color: #ca2929; - color: white; + color: #ffffff; border: none; padding: 4px 8px; border-radius: 15px; @@ -157,7 +157,7 @@ body { .button-del { background-color: #ca2929; - color: white; + color: #ffffff; border: none; padding: 4px 8px; border-radius: 5px; @@ -178,7 +178,7 @@ body { width: 450px; margin-top: 20px; padding: 10px; - background-color: white; + background-color: #ffffff; border-radius: 8px; } @@ -193,7 +193,7 @@ body { .stats-divider { height: 1px; - background-color: rgb(175, 175, 175); + background-color: #afafaf; } .stats-list { @@ -205,7 +205,7 @@ body { align-items: center; gap: 8px; padding: 4px 6px; - background-color: rgb(175, 175, 175); + background-color: #afafaf; border-radius: 6px; margin: 5px; } @@ -215,8 +215,8 @@ body { } .stats-amount { - background-color: orange; - color: white; + background-color: #ffa500; + color: #ffffff; padding: 2px 7px; border-radius: 12px; font-weight: bold; From 90da42215bc3bf974cb9a88c720336dd415a8361 Mon Sep 17 00:00:00 2001 From: Jane-Kriuchko Date: Fri, 19 Jun 2026 12:12:15 +0300 Subject: [PATCH 4/4] Bonus 15-tiles --- bonus/my.js | 153 ++++++++++++++++++++++++++++++++++++++++++++++++ bonus/page.html | 19 ++++++ 2 files changed, 172 insertions(+) create mode 100644 bonus/my.js create mode 100644 bonus/page.html diff --git a/bonus/my.js b/bonus/my.js new file mode 100644 index 00000000..bfc004de --- /dev/null +++ b/bonus/my.js @@ -0,0 +1,153 @@ +let testInitial = [{row:1, column:1, value:1}, + {row:1, column:2, value:2}, + {row:1, column:3, value:3}, + {row:1, column:4, value:4}, + {row:2, column:1, value:5}, + {row:2, column:2, value:6}, + {row:2, column:3, value:7}, + {row:2, column:4, value:8}, + {row:3, column:1, value:9}, + {row:3, column:2, value:10}, + {row:3, column:3, value:11}, + {row:3, column:4, value:12}, + {row:4, column:1, value:13}, + {row:4, column:2, value:14}, + {row:4, column:3, value:" "}, + {row:4, column:4, value:15}] + +const size = 4; +const totalCells = 16; + +let currentGrid = generateSolvableGrid(); +//let currentGrid = testInitial; + +var pivot = new WebDataRocks({ + container: "#wdr-component", + toolbar: false, + height: 152, + width: 502, + report: { + dataSource: {data: currentGrid}, + slice: { + rows:[{uniqueName: "row"}], + columns:[{uniqueName: "column"}], + measures: [{uniqueName: "value"}]}, + options: { + configuratorButton: false, + drillThrough: false, + sorting: "off", + showHeaders: false, + showGrandTotals: "none", + showTotals: "none", + showHierarchyCaptions: false + } + + } +}); + + + +function handleClick(cell) { + //console.log("1. row, col " + cell.rowIndex + " " + cell.columnIndex); + const emptyCell = currentGrid.find(c => c.value === " "); + if (cell.value === " ") return; + //console.log('cell:', cell); + //console.log('emptyCell:', emptyCell); + + const rows = [1,2,3,4]; + const columns = [1,2,3,4]; + const clickedR = rows.indexOf(cell.rowIndex)+1; + const emptyR = emptyCell.row; + const clickedC = columns.indexOf(cell.columnIndex)+1; + const emptyC = emptyCell.column; + //console.log("2. row, col " + cell.rowIndex + " " + cell.columnIndex); + const isClose = ((Math.abs(clickedR - emptyR) === 1 && clickedC === emptyC) || (Math.abs(clickedC - emptyC) === 1 && clickedR === emptyR)); + //console.log(isClose, clickedR, emptyR, clickedC , emptyC, Math.abs(clickedR - emptyR)) + //console.log("3. row, col " + cell.rowIndex + " " + cell.columnIndex); + + if(isClose) { + //console.log("cell aaaaaa " + cell.value) + //console.log("empty aaaaaa " + emptyCell.value) + emptyCell.value = cell.value; + //console.log("empty aaaaaa " + emptyCell.value) + //console.log("cell aaaaaa " + cell.value) + let record = currentGrid.find(item => item.row === clickedR && item.column === clickedC); + if (record) { + record.value = " "; + } + + //console.log("4. row, col " + cell.rowIndex + " " + cell.columnIndex); + + pivot.updateData({data: currentGrid}); + checkWin(currentGrid); + //console.log("empty aaaaaa " + emptyCell.value) + //console.log("5. row, col " + cell.rowIndex + " " + cell.columnIndex); + } + //console.log("6. row, col " + cell.rowIndex + " " + cell.columnIndex); + +}; + +function checkWin(data) { + for (let cell of data) { + const index = (cell.row - 1) * size + (cell.column - 1); + const expectedValue = (index === totalCells - 1) ? " " : index + 1; + if (cell.value !== expectedValue) return false; + } + console.log("You won"); + alert("You have won!"); + return true; +}; + +pivot.on('cellclick', handleClick); + + + +function generateRandomGrid() { + const numbers = Array.from({ length: totalCells - 1 }, (_, i) => i + 1); + numbers.push(" "); + + for (let i = numbers.length - 1; i > 0; i--) { + const j = Math.floor(Math.random() * (i + 1)); + [numbers[i], numbers[j]] = [numbers[j], numbers[i]]; + } + + const grid = []; + for (let index = 0; index < totalCells; index++) { + const row = Math.floor(index / size) + 1; + const col = (index % size) + 1; + grid.push({ + row: row, + column: col, + value: numbers[index] + }); + } + return grid; +} + +function isSolvable(grid) { + const arr = grid.map(c => c.value).filter(val => val !== ""); + let invCount = 0; + + for (let i = 0; i < arr.length - 1; i++) { + for (let j = i + 1; j < arr.length; j++) { + if (arr[i] > arr[j]) invCount++; + } + } + + const blankIndex = grid.findIndex(c => c.value === " "); + const blankRow = Math.floor(blankIndex / size); + + if (size % 2 !== 0) { + return invCount % 2 === 0; + } else { + return (invCount + blankRow) % 2 !== 0; + } +} + +function generateSolvableGrid() { + let grid; + do { + grid = generateRandomGrid(); + } while (!isSolvable(grid)); + return grid; +} \ No newline at end of file diff --git a/bonus/page.html b/bonus/page.html new file mode 100644 index 00000000..e1b3c9a9 --- /dev/null +++ b/bonus/page.html @@ -0,0 +1,19 @@ + + + + + 15-tiles + + + + + + + + +
+ + + + + \ No newline at end of file