/
Coderdev
/
web-nodejs-labs
Обзор
Документация
Войти
/
Coderdev
/
web-nodejs-labs
Код
Запросы
0
Задачи
Пакеты
0
Релизы
0
Аналитика
Безопасность
master
public/lab9/task2/index.html
128 строк
5 KB
Coderdev
1
12 май 2026, 12:34
12 май 2026, 12:34
f5e899f
Код
Авторство
О чём код?
<!DOCTYPE html> <html lang="ru"> <head> <meta charset="UTF-8"> <title>Задание 2</title> <style> body { font-family: sans-serif; max-width: 800px; margin: 40px auto; padding: 0 20px; color: #222; } h1 { border-bottom: 2px solid #222; padding-bottom: 10px; } a { color: #2563eb; } .stock-box { background: #f4f4f4; border-radius: 8px; padding: 14px 18px; margin: 16px 0; } .lookup-row { display: flex; gap: 8px; margin: 12px 0; align-items: center; } input[type=number], input[type=text] { padding: 7px 12px; border: 1px solid #ccc; border-radius: 6px; font-size: 0.95rem; } input[type=number] { width: 100px; } button { padding: 7px 14px; background: #2563eb; color: #fff; border: none; border-radius: 6px; cursor: pointer; font-size: 0.9rem; } button:hover { background: #1d4ed8; } button.green { background: #16a34a; } button.green:hover { background: #15803d; } .lookup-result { padding: 8px 12px; border-radius: 6px; margin-top: 6px; font-size: 0.9rem; } .lookup-result.ok { background: #dcfce7; color: #15803d; } .lookup-result.err { background: #fee2e2; color: #b91c1c; } .product-card { border: 1px solid #e5e5e5; border-radius: 10px; padding: 12px 16px; margin: 8px 0; } .product-card:hover { background: #fafafa; } .product-row { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; } .product-title-input { flex: 2; min-width: 160px; } .product-price-input { width: 110px; } .amt-ctrl { display: flex; align-items: center; gap: 6px; } .amt-btn { width: 28px; height: 28px; padding: 0; font-size: 1rem; font-weight: bold; } .amt-num { min-width: 32px; text-align: center; font-weight: 600; } .muted { color: #888; font-size: 0.82rem; } </style> </head> <body> <p><a href="/lab9/">← Назад</a></p> <h1>Задание 2 — Управление товарами</h1> <h2>Статистика склада</h2> <div class="stock-box" id="stock">Загрузка...</div> <h2>Найти по ID</h2> <div class="lookup-row"> <input type="number" id="lookupId" placeholder="ID"> <button onclick="lookupById()">Найти</button> </div> <div id="lookupResult"></div> <h2>Все товары</h2> <div id="productList">Загрузка...</div> <script> const API = '/api/lab9/products'; const fmt = cents => (cents / 100).toLocaleString('ru-RU', { style: 'currency', currency: 'RUB' }); const changes = {}; async function loadStock() { const res = await fetch(`${API}/task1/stock`); const d = await res.json(); document.getElementById('stock').innerHTML = `Наименований: <b>${d.total_products}</b> | Единиц: <b>${d.total_items}</b> | Стоимость: <b>${fmt(d.total_value)}</b>`; } async function loadProducts() { const res = await fetch(API); const products = await res.json(); products.forEach(p => { changes[p.id] = { title: p.title, price: p.price, amount: p.amount }; }); renderProducts(products); } function renderProducts(products) { document.getElementById('productList').innerHTML = products.map(p => ` <div class="product-card"> <div class="muted" style="margin-bottom:6px">ID: ${p.id}</div> <div class="product-row"> <input class="product-title-input" type="text" value="${p.title}" onchange="changes[${p.id}].title = this.value" placeholder="Название"> <input class="product-price-input" type="number" step="0.01" min="0" value="${(p.price/100).toFixed(2)}" onchange="changes[${p.id}].price = Math.round(this.value * 100)" placeholder="Цена ₽"> <div class="amt-ctrl"> <button class="amt-btn" onclick="changeAmount(${p.id}, -1)">−</button> <span class="amt-num" id="amt-${p.id}">${p.amount}</span> <button class="amt-btn" onclick="changeAmount(${p.id}, +1)">+</button> </div> <button class="green" onclick="saveProduct(${p.id})">Сохранить</button> </div> </div>`).join(''); } function changeAmount(id, delta) { changes[id].amount = Math.max(0, changes[id].amount + delta); document.getElementById('amt-' + id).textContent = changes[id].amount; } async function saveProduct(id) { const res = await fetch(`${API}/${id}`, { method: 'PATCH', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(changes[id]) }); if (res.ok) { loadStock(); alert('Сохранено!'); } else alert('Ошибка!'); } async function lookupById() { const id = document.getElementById('lookupId').value; if (!id) return; const res = await fetch(`${API}/${id}`); const el = document.getElementById('lookupResult'); if (res.ok) { const p = await res.json(); el.className = 'lookup-result ok'; el.textContent = `Найдено: ${p.title} — ${fmt(p.price)} — склад: ${p.amount} шт.`; } else { el.className = 'lookup-result err'; el.textContent = `Товар с ID ${id} не найден`; } } document.getElementById('lookupId').addEventListener('keydown', e => { if (e.key === 'Enter') lookupById(); }); loadStock(); loadProducts(); </script> </body> </html>