diff --git a/index.html b/index.html index 5971bf7d..2c721546 100644 --- a/index.html +++ b/index.html @@ -1,16 +1,43 @@ - - + + - My Page - - - + + Buy List + - - Apple - 4 - +
+
+ +
+
+ + +
+ +
+
+ + +
+
+ +
+ Buy List + Created by Hordii +
+ + \ No newline at end of file diff --git a/main.css b/main.css index 00bc872e..97e559f2 100644 --- a/main.css +++ b/main.css @@ -1,17 +1,99 @@ -.product-item { - background-color: gray; - display: inline-block; - height: 25px; - padding: 5px; - border-radius: 5px; +* { box-sizing: border-box; font-family: sans-serif; } +body { background: #000; display: flex; justify-content: center; padding: 40px 20px; margin: 0; } + +.app-wrapper { + background: #dfdfdf; + padding: 20px; + width: 100%; + max-width: 900px; +} + +.grid-container { display: flex; gap: 20px; } +.left-panel { flex: 2; display: flex; flex-direction: column; } +.right-panel { flex: 1; display: flex; flex-direction: column; gap: 15px; } + +@media (max-width: 500px) { + .grid-container { flex-direction: column; } +} +.add-item-bar { + display: flex; + border: 1px solid #ccc; + border-bottom: none; + border-radius: 5px 5px 0 0; + background: #fff; + overflow: hidden; +} +.add-item-bar input { flex: 1; padding: 15px; border: none; outline: none; font-size: 16px; } +.btn-blue { background: #2185d0; padding: 0 30px; font-size: 16px; } +.item-row { + display: grid; + grid-template-columns: 1fr 1fr 1fr; + align-items: center; + padding: 12px 15px; + background: #fff; + border: 1px solid #ccc; + border-bottom: none; +} +.item-row:last-child { + border-bottom: 1px solid #ccc; + border-radius: 0 0 5px 5px; +} +.item-name, .item-input { font-size: 16px; color: #333; } +.item-input { border: 1px solid #2185d0; padding: 6px 10px; border-radius: 4px; outline: none; max-width: 140px; } +.crossed { text-decoration: line-through; } +.item-controls { display: flex; justify-content: center; align-items: center; gap: 8px; } +.item-actions { display: flex; justify-content: flex-end; gap: 5px; } + +button { cursor: pointer; outline: none; border: none; color: #fff; font-weight: bold; } +.btn-circle { width: 32px; height: 32px; border-radius: 50%; font-size: 18px; } +.btn-delete { background-color: #db2828; width: 34px; height: 34px; border-radius: 4px; font-size: 16px; } +.btn-minus { background-color: #db2828; } +.btn-plus { background-color: #21ba45; } +button:disabled { opacity: 0.5; cursor: not-allowed; } +.btn-status { + background: #e0e1e2; color: #333; + padding: 8px 12px; border-radius: 4px; + border: 1px solid #ccc; font-size: 13px; } +.qty-badge { background: #e0e1e2; padding: 6px 12px; border-radius: 4px; font-weight: bold; color: #333; border: 1px solid #ccc;} +.stats-block { background: #fff; padding: 20px; border-radius: 5px; border: 1px solid #ccc; } +.stats-block h2 { margin: 0 0 15px 0; font-size: 18px; border-bottom: 1px solid #eee; padding-bottom: 10px; color: #222;} +.tag-container { display: flex; gap: 8px; } +.product-item { + background-color: #e0e1e2; + display: inline-flex; align-items: center; gap: 8px; + height: 30px; padding: 0 10px; border-radius: 4px; + font-size: 13px; font-weight: bold; color: #333; +} .amount { - background-color: yellow; - border-radius: 10px; - - display: inline-block; - height: 20px; - width: 20px; - text-align: center; -} \ No newline at end of file + background-color: #f2711c; color: white; border-radius: 50%; + display: inline-flex; justify-content: center; align-items: center; + height: 22px; width: 22px; font-size: 12px; +} + +[data-tooltip] { position: relative; } +[data-tooltip]::after { + content: attr(data-tooltip); position: absolute; + bottom: 130%; left: 50%; transform: translateX(-50%) translateY(10px) scale(0.8); + background: #8b00ff; color: #fff; padding: 6px 10px; border-radius: 5px; + font-size: 12px; opacity: 0; visibility: hidden; transition: 0.2s; z-index: 10; font-weight: normal; +} +[data-tooltip]:hover::after { opacity: 1; visibility: visible; transform: translateX(-50%) translateY(0) scale(1); } + +.author-badge { + position: fixed; bottom: 0; left: 0; background: #4b0082; color: #fff; + padding: 15px 20px; border-radius: 10px 10px 0 0; font-weight: bold; font-size: 20px; + cursor: pointer; transition: 0.3s; z-index: 9999; +} +.badge-author-name { display: block; max-height: 0; opacity: 0; overflow: hidden; transition: 0.3s; font-size: 14px; font-weight: normal; } +.author-badge:hover { background: #8b00ff; padding-bottom: 25px; } +.author-badge:hover .badge-author-name { max-height: 30px; opacity: 1; margin-top: 5px; } + +@media print { + body { background: none; } + .app-wrapper { border: none; background: none; box-shadow: none; } + .author-badge { background: #fff !important; color: #000 !important; border: 2px solid #8b00ff; border-bottom: none; } + .badge-title { display: none; } + .badge-author-name { max-height: none; opacity: 1; margin: 0; font-weight: bold; font-size: 20px; } +} diff --git a/smth.js b/smth.js new file mode 100644 index 00000000..00315661 --- /dev/null +++ b/smth.js @@ -0,0 +1,179 @@ +'use strict'; + +let buyList = JSON.parse(localStorage.getItem('buyList')) || [ + { id: 1, name: 'Помідори', qty: 2, isBought: true }, + { id: 2, name: 'Печиво', qty: 2, isBought: false }, + { id: 3, name: 'Сир', qty: 1, isBought: false } +]; + +function saveState() { + localStorage.setItem('buyList', JSON.stringify(buyList)); +} + +function render() { + const listContainer = document.getElementById('items-list'); + const leftStats = document.getElementById('left-stats'); + const boughtStats = document.getElementById('bought-stats'); + + listContainer.innerHTML = ''; + leftStats.innerHTML = ''; + boughtStats.innerHTML = ''; + + buyList.forEach(item => { + const article = document.createElement('article'); + article.className = 'item-row'; + article.dataset.id = item.id; + + const nameSpan = document.createElement('span'); + nameSpan.className = item.isBought ? 'item-name crossed' : 'item-name'; + nameSpan.setAttribute('data-tooltip', item.isBought ? 'Редагування заборонено' : 'Натисніть, щоб редагувати'); + nameSpan.textContent = item.name; + + const controlsDiv = document.createElement('div'); + controlsDiv.className = 'item-controls'; + + if (!item.isBought) { + const minusBtn = document.createElement('button'); + minusBtn.className = 'btn-circle btn-minus'; + minusBtn.dataset.action = 'minus'; + minusBtn.setAttribute('data-tooltip', 'Зменшити кількість'); + minusBtn.textContent = '-'; + if (item.qty === 1) minusBtn.disabled = true; + + const qtyBadge = document.createElement('span'); + qtyBadge.className = 'qty-badge'; + qtyBadge.textContent = item.qty; + + const plusBtn = document.createElement('button'); + plusBtn.className = 'btn-circle btn-plus'; + plusBtn.dataset.action = 'plus'; + plusBtn.setAttribute('data-tooltip', 'Збільшити кількість'); + plusBtn.textContent = '+'; + + controlsDiv.append(minusBtn, qtyBadge, plusBtn); + } else { + const qtyBadge = document.createElement('span'); + qtyBadge.className = 'qty-badge'; + qtyBadge.textContent = item.qty; + controlsDiv.append(qtyBadge); + } + + const actionsDiv = document.createElement('div'); + actionsDiv.className = 'item-actions'; + + const statusBtn = document.createElement('button'); + statusBtn.className = 'btn-status'; + statusBtn.dataset.action = 'toggle'; + statusBtn.setAttribute('data-tooltip', item.isBought ? 'Скасувати покупку' : 'Відмітити як куплене'); + statusBtn.textContent = item.isBought ? 'Не куплено' : 'Куплено'; + + actionsDiv.append(statusBtn); + + if (!item.isBought) { + const deleteBtn = document.createElement('button'); + deleteBtn.className = 'btn-delete'; + deleteBtn.dataset.action = 'delete'; + deleteBtn.setAttribute('aria-label', 'Видалити'); + deleteBtn.setAttribute('data-tooltip', 'Видалити'); + deleteBtn.textContent = '✖'; + actionsDiv.append(deleteBtn); + } + article.append(nameSpan, controlsDiv, actionsDiv); + listContainer.append(article); + + const statItem = document.createElement('span'); + statItem.className = 'product-item'; + + const statName = document.createElement('span'); + if (item.isBought) statName.className = 'crossed'; + statName.textContent = item.name; + + const statAmount = document.createElement('span'); + statAmount.className = item.isBought ? 'amount crossed' : 'amount'; + statAmount.textContent = item.qty; + + statItem.append(statName, statAmount); + + if (item.isBought) { + boughtStats.append(statItem); + } else { + leftStats.append(statItem); + } + }); + saveState(); +} + +const inputField = document.getElementById('new-item-input'); +const addBtn = document.getElementById('add-btn'); + +function addItem() { + const name = inputField.value.trim(); + if (!name) return; + buyList.push({ + id: Date.now(), + name: name, + qty: 1, + isBought: false + }); + inputField.value = ''; + inputField.focus(); + render(); +} + +addBtn.addEventListener('click', addItem); +inputField.addEventListener('keypress', (e) => { + if (e.key === 'Enter') addItem(); +}); + +document.getElementById('items-list').addEventListener('click', (e) => { + const article = e.target.closest('.item-row'); + if (!article) return; + + const id = Number(article.dataset.id); + const item = buyList.find(i => i.id === id); + if (!item) return; + + const action = e.target.dataset.action; + + if (action === 'delete') { + buyList = buyList.filter(i => i.id !== id); + render(); + } + else if (action === 'plus') { + item.qty++; + render(); + } + else if (action === 'minus') { + if (item.qty > 1) { + item.qty--; + render(); + } + } + else if (action === 'toggle') { + item.isBought = !item.isBought; + render(); + } + + if (e.target.classList.contains('item-name') && !item.isBought) { + const input = document.createElement('input'); + input.type = 'text'; + input.className = 'item-input'; + input.value = item.name; + + e.target.replaceWith(input); + input.focus(); + + const saveEdit = () => { + const newName = input.value.trim(); + if (newName) item.name = newName; + render(); + }; + + input.addEventListener('blur', saveEdit); + input.addEventListener('keypress', (event) => { + if (event.key === 'Enter') input.blur(); + }); + } +}); + +render(); \ No newline at end of file