/
Coderdev
/
web-nodejs-labs
Обзор
Документация
Войти
/
Coderdev
/
web-nodejs-labs
Код
Запросы
0
Задачи
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
public/lab9/task2/index.html
1 строка
5 KB
Coderdev
1
23 апр 2026, 22:48
23 апр 2026, 22:48
fe8b855
Код
Авторство
О чём код?
<!doctype html><html lang="ru"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Lab9 Task2</title><style>body{margin:0;font-family:Arial,sans-serif;background:#0f172a;color:#e2e8f0}.wrapper{max-width:1280px;margin:0 auto;padding:24px}.panel,.card{background:#111c34;border:1px solid #25314d;border-radius:20px;box-shadow:0 10px 30px rgba(0,0,0,.25)}.panel{padding:24px}.row{display:grid;grid-template-columns:1fr 120px 120px 120px;gap:12px;align-items:center}input{width:100%;min-height:42px;border-radius:12px;border:1px solid #334155;background:#0f172a;color:#fff;padding:0 12px;box-sizing:border-box}button,a.btn{display:inline-block;padding:12px 16px;border-radius:12px;background:#2563eb;color:#fff;text-decoration:none;border:none;cursor:pointer}.list-item{border-bottom:1px solid #25314d;padding:14px 0}.counter{display:flex;gap:8px;align-items:center}.muted{color:#94a3b8}.grid{display:grid;grid-template-columns:1fr 2fr;gap:18px}@media(max-width:1100px){.grid,.row{grid-template-columns:1fr}}</style></head><body><div class="wrapper"><a class="btn" href="/lab9/" style="background:#334155">← Назад</a><div class="grid" style="margin-top:16px"><div class="panel"><h2 style="margin-top:0">Статистика склада</h2><div id="stockBox" class="muted">Загрузка...</div><hr style="border-color:#25314d;margin:18px 0"><h2 style="margin-top:0">Найти товар по ID</h2><div style="display:flex;gap:12px"><input id="idInput" type="number" placeholder="Введите ID"><button id="idBtn">Показать</button></div><div id="singleBox" style="margin-top:12px" class="muted">Здесь будет товар по ID</div></div><div class="panel"><h2 style="margin-top:0">Редактирование товаров</h2><div id="productsBox">Загрузка...</div></div></div><script>const API='/api/lab9/products';const RUB=new Intl.NumberFormat('ru-RU',{style:'currency',currency:'RUB'});function formatPrice(cents){return RUB.format(Number(cents||0)/100)}function rubToCents(rub){return Math.round(parseFloat(rub||0)*100)}function centsToRub(cents){return(Number(cents||0)/100).toFixed(2)}async function loadStock(){const res=await fetch(API+'/stock');const data=await res.json();document.getElementById('stockBox').innerHTML=`<div class="card"><strong>Всего наименований:</strong> ${data.total_products}</div><div class="card" style="margin-top:12px"><strong>Всего единиц товара:</strong> ${data.total_items}</div><div class="card" style="margin-top:12px"><strong>Общая стоимость:</strong> ${formatPrice(data.total_value)}</div>`}async function loadProducts(){const res=await fetch(API);const items=await res.json();const box=document.getElementById('productsBox');box.innerHTML=items.map(p=>`<div class="list-item" data-id="${p.id}"><div class="row"><input class="titleInput" value="${p.title}"><input class="priceInput" type="number" step="0.01" value="${centsToRub(p.price)}"><div class="counter"><button class="minusBtn" style="background:#475569">-</button><input class="amountInput" type="number" min="0" value="${p.amount}"><button class="plusBtn" style="background:#16a34a">+</button></div><button class="saveBtn">Сохранить</button></div><div class="muted" style="margin-top:8px">ID: ${p.id} · Текущая цена: ${formatPrice(p.price)}</div></div>`).join('');document.querySelectorAll('.plusBtn').forEach(btn=>btn.addEventListener('click',e=>{const row=e.target.closest('.list-item');const input=row.querySelector('.amountInput');input.value=Number(input.value||0)+1}));document.querySelectorAll('.minusBtn').forEach(btn=>btn.addEventListener('click',e=>{const row=e.target.closest('.list-item');const input=row.querySelector('.amountInput');input.value=Math.max(0,Number(input.value||0)-1)}));document.querySelectorAll('.saveBtn').forEach(btn=>btn.addEventListener('click',async e=>{const row=e.target.closest('.list-item');const id=row.dataset.id;const payload={title:row.querySelector('.titleInput').value.trim(),price:rubToCents(row.querySelector('.priceInput').value),amount:Number(row.querySelector('.amountInput').value||0)};await fetch(`${API}/${id}`,{method:'PUT',headers:{'Content-Type':'application/json'},body:JSON.stringify(payload)});await loadStock();await loadProducts()}))}document.getElementById('idBtn').addEventListener('click',async()=>{const id=document.getElementById('idInput').value.trim();if(!id)return;const res=await fetch(`${API}/${id}`);const box=document.getElementById('singleBox');const data=await res.json();if(!res.ok){box.textContent=data.error||'Product not found';return}box.innerHTML=`<div class="card"><strong>${data.title}</strong><br>Цена: ${formatPrice(data.price)}<br>Остаток: ${data.amount} шт.</div>`});loadStock();loadProducts();</script></body></html>