/
Coderdev
/
web-nodejs-labs
Обзор
Документация
Войти
/
Coderdev
/
web-nodejs-labs
Код
Запросы
0
Задачи
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
public/lab10/task1/index.html
11 строк
6 KB
Coderdev
1
28 апр 2026, 12:34
28 апр 2026, 12:34
df65d61
Код
Авторство
О чём код?
<!doctype html><html lang="ru"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Lab10 Task1</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}.muted{color:#94a3b8}button,a.btn{display:inline-block;padding:12px 16px;border-radius:12px;background:#2563eb;color:#fff;text-decoration:none;border:none;cursor:pointer}.gray{background:#334155!important}.grid{display:grid;grid-template-columns:310px 1fr;gap:18px}.list{display:grid;grid-template-columns:repeat(auto-fill,minmax(240px,1fr));gap:14px}.product{padding:16px;border-radius:16px;background:#0f172a;border:1px solid #25314d}.price{color:#86efac;font-weight:700}input,select{width:100%;min-height:42px;border-radius:12px;border:1px solid #334155;background:#0f172a;color:#fff;padding:0 12px;box-sizing:border-box;margin-bottom:10px}table{width:100%;border-collapse:collapse}th,td{border-bottom:1px solid #25314d;padding:10px;text-align:left}@media(max-width:900px){.grid{grid-template-columns:1fr}.list{grid-template-columns:1fr}}</style></head><body><div class="wrapper"><a class="btn gray" href="/lab10/">← Назад</a><div class="panel" style="margin-top:16px"><h1 style="margin-top:0">Task 1 · Интернет-магазин</h1><p class="muted">Фильтрация, поиск, пагинация, карточка товара, покупка через транзакцию и просмотр заказов.</p></div><div class="grid" style="margin-top:18px"><div class="panel"><h2 style="margin-top:0">Фильтры</h2><select id="categorySelect"><option value="">Все категории</option></select><input id="searchInput" placeholder="Поиск по названию"><button id="searchBtn">Применить</button><button id="resetBtn" class="gray" style="margin-top:10px">Сбросить</button><hr style="border-color:#25314d;margin:18px 0"><h2>Заказы</h2><button id="loadOrdersBtn" class="gray">Показать все заказы</button><div id="ordersBox" class="muted" style="margin-top:12px"></div></div><div class="panel"><h2 style="margin-top:0">Товары</h2><div id="productsBox" class="list">Загрузка...</div><div style="margin-top:16px;display:flex;gap:12px"><button id="prevBtn" class="gray">Назад</button><span id="pageInfo" class="muted" style="align-self:center"></span><button id="nextBtn" class="gray">Вперёд</button></div><div id="detailsBox" style="margin-top:18px"></div></div></div><script> const RUB=new Intl.NumberFormat('ru-RU',{style:'currency',currency:'RUB'});const API='/api/lab10';let page=1;let pages=1; function price(v){return RUB.format(Number(v||0)/100)} async function loadCategories(){const res=await fetch(API+'/categories');const data=await res.json();document.getElementById('categorySelect').innerHTML='<option value="">Все категории</option>'+data.map(c=>`<option value="${c.id}">${c.name}</option>`).join('')} async function loadProducts(){const q=document.getElementById('searchInput').value.trim();const cat=document.getElementById('categorySelect').value;const url=`${API}/products?page=${page}${cat?'&category='+cat:''}${q?'&q='+encodeURIComponent(q):''}`;const res=await fetch(url);const data=await res.json();pages=data.pages||1;document.getElementById('pageInfo').textContent=`Страница ${data.page} / ${pages}`;document.getElementById('productsBox').innerHTML=data.data.map(p=>`<div class="product"><strong>${p.title}</strong><br><span class="muted">${p.category_title||'Без категории'}</span><br><span class="price">${price(p.price)}</span><br>Остаток: ${p.amount}<br><div style="margin-top:12px;display:flex;gap:8px;flex-wrap:wrap"><button onclick="showProduct(${p.id})">Карточка</button><button onclick="buyProduct(${p.id})" class="gray">Купить</button></div></div>`).join('')||'<div class="muted">Ничего не найдено.</div>'} async function showProduct(id){const res=await fetch(`${API}/task1/product/${id}`);const p=await res.json();document.getElementById('detailsBox').innerHTML=`<div class="product"><h2>${p.title}</h2><p>Категория: ${p.category_title}</p><p>Цена: <span class="price">${price(p.price)}</span></p><p>Остаток: ${p.amount}</p><button onclick="buyProduct(${p.id})">Купить</button></div>`} async function buyProduct(id){const res=await fetch(`${API}/products/${id}/buy`,{method:'POST'});const data=await res.json();alert(res.ok?`Покупка выполнена. Заказ №${data.orderId}`:data.error);await loadProducts();} async function loadOrders(){const res=await fetch(API+'/task1/orders');const data=await res.json();document.getElementById('ordersBox').innerHTML=data.map(o=>`<div style="padding:10px;border-bottom:1px solid #25314d">Заказ №${o.id} · ${new Date(o.created_at).toLocaleString()} · ${price(o.total_sum)} <button onclick="showOrder(${o.id})">Открыть</button></div>`).join('')||'Заказов пока нет'} async function showOrder(id){const res=await fetch(`${API}/task1/orders/${id}`);const o=await res.json();document.getElementById('detailsBox').innerHTML=`<div class="product"><h2>Заказ №${o.id}</h2><p>${new Date(o.created_at).toLocaleString()}</p><p>Итого: <span class="price">${price(o.total_sum)}</span></p><pre style="white-space:pre-wrap">${JSON.stringify(o.items,null,2)}</pre></div>`} document.getElementById('searchBtn').onclick=()=>{page=1;loadProducts()};document.getElementById('resetBtn').onclick=()=>{page=1;document.getElementById('searchInput').value='';document.getElementById('categorySelect').value='';loadProducts()};document.getElementById('prevBtn').onclick=()=>{if(page>1){page--;loadProducts()}};document.getElementById('nextBtn').onclick=()=>{if(page<pages){page++;loadProducts()}};document.getElementById('loadOrdersBtn').onclick=loadOrders;loadCategories();loadProducts(); </script></body></html>