/
icedev
/
eks-present
Обзор
Документация
Войти
/
icedev
/
eks-present
Код
Запросы
0
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
master
suppliers.html
217 строк
10 KB
ICEDEV
init
12 май 2026, 12:50
12 май 2026, 12:50
872c4b8
Код
Авторство
О чём код?
<!DOCTYPE html> <html lang="ru"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>Поставщики оборудования - EKS</title> <link rel="stylesheet" href="styles.css" /> </head> <body> <div class="container"> <header class="topbar"> <div class="brand">EKS | Поставщики оборудования</div> <nav class="nav"> <a class="nav-link" href="manager.html">← Руководитель</a> <a class="nav-link" href="objects.html">Объекты</a> <a class="nav-link" href="information.html">Информация</a> <a class="nav-link active" href="suppliers.html">Поставщики</a> <a class="nav-link" href="requests.html">Реестр заявок</a> </nav> </header> <section class="glass-card section-card"> <h1 class="title">Реестр поставщиков оборудования</h1> <p class="subtitle"> Контроль надежности поставок, сроков отгрузки и доступности критичных позиций для строительных объектов. </p> <div class="grid" style="margin-bottom: 12px;"> <article class="tile"> <h3>Активных поставщиков</h3> <p><strong style="color: #e2e8f0; font-size: 24px;">18</strong> компаний в пуле поставок</p> </article> <article class="tile"> <h3>Средний SLA</h3> <p><strong style="color: #e2e8f0; font-size: 24px;">96.4%</strong> за последние 90 дней</p> </article> <article class="tile"> <h3>Риски по срокам</h3> <p><strong style="color: #fcd34d; font-size: 24px;">3</strong> поставки в зоне внимания</p> </article> <article class="tile"> <h3>Критичные позиции</h3> <p><strong style="color: #86efac; font-size: 24px;">42</strong> единицы на контроле склада</p> </article> </div> </section> <section class="glass-card section-card"> <h2 class="title" style="font-size: 22px; margin-bottom: 8px;">Список поставщиков</h2> <p class="subtitle"> Для каждого поставщика отображаются профиль оборудования, сроки, качество исполнения и контактное лицо. </p> <form id="add-supplier-form" class="inline-form"> <div class="field" style="margin-bottom: 0;"> <label for="supplier-name">Поставщик</label> <input id="supplier-name" name="name" type="text" placeholder='ООО "Новый поставщик"' required /> </div> <div class="field" style="margin-bottom: 0;"> <label for="supplier-category">Категория</label> <input id="supplier-category" name="category" type="text" placeholder="Категория оборудования" required /> </div> <div class="field" style="margin-bottom: 0;"> <label for="supplier-phone">Телефон</label> <input id="supplier-phone" name="phone" type="text" placeholder="+7 (900) 000-00-00" required /> </div> <div class="field" style="margin-bottom: 0;"> <label for="supplier-email">Email</label> <input id="supplier-email" name="email" type="email" placeholder="sales@company.ru" required /> </div> <div class="field" style="margin-bottom: 0;"> <label for="supplier-sla">SLA (%)</label> <input id="supplier-sla" name="sla" type="number" min="0" max="100" placeholder="95" required /> </div> <div class="field" style="margin-bottom: 0;"> <label for="supplier-delivery">Срок поставки (дни)</label> <input id="supplier-delivery" name="deliveryDays" type="number" min="1" placeholder="7" required /> </div> <div style="display: flex; align-items: flex-end;"> <button class="btn btn-primary" type="submit" style="width: 100%;">Добавить</button> </div> </form> <div class="table-wrap"> <table> <thead> <tr> <th>Поставщик</th> <th>Категория оборудования</th> <th>Контакт</th> <th>SLA</th> <th>Средний срок поставки</th> <th>Статус</th> <th class="actions-cell">Действия</th> </tr> </thead> <tbody id="suppliers-tbody"></tbody> </table> </div> </section> <section class="glass-card section-card"> <h2 class="title" style="font-size: 22px; margin-bottom: 8px;">Тематические акценты</h2> <div class="grid"> <article class="tile"> <h3>Надежность цепочки поставок</h3> <p>Приоритет на прогнозируемость сроков и резервирование критичных позиций под ключевые этапы строительства.</p> </article> <article class="tile"> <h3>Управление рисками</h3> <p>Раннее выявление отклонений по SLA помогает снизить простои монтажных бригад и избежать каскадных задержек.</p> </article> <article class="tile"> <h3>Прозрачная коммуникация</h3> <p>Единый реестр поставщиков ускоряет согласования между руководителем, складом, подрядчиками и бухгалтерией.</p> </article> </div> </section> </div> <script> const SUPPLIERS_STORAGE_KEY = "eks_suppliers"; const DEFAULT_SUPPLIERS = [ { id: "s1", name: 'ООО "ЭлектроСнаб Групп"', category: "Щитовое оборудование, кабельная продукция", phone: "+7 (900) 500-10-10", email: "sales@elsnab.ru", sla: 98, deliveryDays: 6 }, { id: "s2", name: 'ООО "Климат Инжиниринг"', category: "Вентиляция, чиллеры, фанкойлы", phone: "+7 (901) 611-22-33", email: "supply@climate-eng.ru", sla: 95, deliveryDays: 9 }, { id: "s3", name: 'ООО "ПожСистем Трейд"', category: "Пожарная автоматика, датчики, шкафы", phone: "+7 (902) 700-88-44", email: "manager@pozhtrade.ru", sla: 91, deliveryDays: 12 }, { id: "s4", name: 'АО "Сигнал Тех"', category: "СКУД, видеонаблюдение, сетевое оборудование", phone: "+7 (903) 411-00-55", email: "contracts@signaltech.ru", sla: 89, deliveryDays: 14 }, { id: "s5", name: 'ООО "Пром Логистика"', category: "Кабеленесущие системы, металл, крепеж", phone: "+7 (904) 322-14-77", email: "b2b@promlog.ru", sla: 84, deliveryDays: 16 }, ]; function getSuppliers() { const raw = localStorage.getItem(SUPPLIERS_STORAGE_KEY); if (!raw) { localStorage.setItem(SUPPLIERS_STORAGE_KEY, JSON.stringify(DEFAULT_SUPPLIERS)); return [...DEFAULT_SUPPLIERS]; } try { const parsed = JSON.parse(raw); return Array.isArray(parsed) ? parsed : [...DEFAULT_SUPPLIERS]; } catch (error) { localStorage.setItem(SUPPLIERS_STORAGE_KEY, JSON.stringify(DEFAULT_SUPPLIERS)); return [...DEFAULT_SUPPLIERS]; } } function saveSuppliers(items) { localStorage.setItem(SUPPLIERS_STORAGE_KEY, JSON.stringify(items)); } function statusBySla(sla) { if (sla >= 95) return { cls: "success", text: "Стабильно" }; if (sla >= 88) return { cls: "warn", text: "Требует контроля" }; return { cls: "danger", text: "Критичный риск" }; } function removeSupplier(id) { const items = getSuppliers().filter((item) => item.id !== id); saveSuppliers(items); renderSuppliers(); } function renderSuppliers() { const tbody = document.getElementById("suppliers-tbody"); const items = getSuppliers(); tbody.innerHTML = ""; items.forEach((item) => { const status = statusBySla(Number(item.sla)); const tr = document.createElement("tr"); tr.innerHTML = "<td>" + item.name + "</td>" + "<td>" + item.category + "</td>" + "<td><div>" + item.phone + "</div><div style=\"color: var(--muted);\">" + item.email + "</div></td>" + "<td>" + item.sla + "%</td>" + "<td>" + item.deliveryDays + " дней</td>" + "<td><span class=\"badge " + status.cls + "\">" + status.text + "</span></td>" + "<td><button class=\"btn btn-danger\" type=\"button\" data-delete-supplier=\"" + item.id + "\">Удалить</button></td>"; tbody.appendChild(tr); }); tbody.querySelectorAll("[data-delete-supplier]").forEach((button) => { button.addEventListener("click", () => removeSupplier(button.getAttribute("data-delete-supplier"))); }); } document.getElementById("add-supplier-form").addEventListener("submit", (event) => { event.preventDefault(); const formData = new FormData(event.target); const name = String(formData.get("name") || "").trim(); const category = String(formData.get("category") || "").trim(); const phone = String(formData.get("phone") || "").trim(); const email = String(formData.get("email") || "").trim(); const sla = Number(formData.get("sla")); const deliveryDays = Number(formData.get("deliveryDays")); if (!name || !category || !phone || !email || Number.isNaN(sla) || Number.isNaN(deliveryDays)) { return; } const items = getSuppliers(); items.push({ id: String(Date.now()), name, category, phone, email, sla: Math.min(100, Math.max(0, sla)), deliveryDays: Math.max(1, deliveryDays), }); saveSuppliers(items); event.target.reset(); renderSuppliers(); }); renderSuppliers(); </script> </body> </html>