/
icedev
/
eks-present
Обзор
Документация
Войти
/
icedev
/
eks-present
Код
Запросы
0
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
master
employees.html
263 строки
12 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" id="employees-brand">EKS | Сотрудники</div> <nav class="nav"> <a class="nav-link" href="contractor.html">← Назад</a> <a class="nav-link" href="objects.html">Объекты</a> <a class="nav-link" href="information.html">Информация</a> <a class="nav-link" href="requests.html">Реестр заявок</a> </nav> </header> <section class="glass-card section-card"> <h1 class="title" id="org-title">Сотрудники организации</h1> <p class="subtitle" id="org-subtitle">Загрузка данных…</p> <div class="grid" style="grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));"> <article class="tile" id="org-meta" style="min-height: 120px;"> <h3>Организация</h3> <p id="org-meta-name">—</p> <p id="org-meta-note" style="margin-top: 8px; color: var(--muted); line-height: 1.45;">—</p> </article> <article class="tile" style="min-height: 120px;"> <h3>Сменить организацию</h3> <div class="field" style="margin: 0;"> <label for="org-select" style="margin-bottom: 6px;">Организация</label> <select id="org-select"></select> </div> </article> </div> </section> <section class="glass-card section-card"> <h2 class="title" style="font-size: 22px; margin-bottom: 12px;">Список сотрудников</h2> <p class="subtitle" style="margin-bottom: 16px;"> Контакты и роль сотрудника в организации. </p> <div class="table-wrap"> <table> <thead> <tr> <th>ФИО</th> <th>Должность</th> <th>Статус</th> <th>Контакты</th> <th class="actions-cell">Действия</th> </tr> </thead> <tbody id="employees-tbody"></tbody> </table> </div> <form id="add-employee-form" class="inline-form" style="margin-top: 16px;"> <div class="field" style="margin-bottom: 0;"> <label for="employee-full-name">ФИО</label> <input id="employee-full-name" name="fullName" type="text" placeholder="Иванов Иван Иванович" required /> </div> <div class="field" style="margin-bottom: 0;"> <label for="employee-position">Должность</label> <input id="employee-position" name="position" type="text" placeholder="Инженер" required /> </div> <div class="field" style="margin-bottom: 0;"> <label for="employee-status">Статус</label> <select id="employee-status" name="status"> <option value="active">Активен</option> <option value="inactive">Неактивен</option> </select> </div> <div class="field" style="margin-bottom: 0;"> <label for="employee-phone">Телефон</label> <input id="employee-phone" name="phone" type="text" placeholder="+7 (900) 000-00-00" required /> </div> <div class="field" style="margin-bottom: 0;"> <label for="employee-email">Email</label> <input id="employee-email" name="email" type="email" placeholder="mail@company.ru" required /> </div> <div style="display: flex; align-items: flex-end;"> <button class="btn btn-primary" type="submit" style="width: 100%;">Добавить сотрудника</button> </div> </form> </section> </div> <script> const ORGS_STORAGE_KEY = "eks_orgs"; const EMPLOYEES_STORAGE_KEY = "eks_employees_by_org"; const DEFAULT_ORGS = { "1": { name: 'ООО "ТехМонтаж"', note: "Ответственный подрядчик по вентиляции, отоплению и части электрики.", }, "2": { name: 'ООО "СигналПро"', note: "Ответственный подрядчик по слаботочным системам и видеонаблюдению.", }, "3": { name: 'ООО "Безопасность+"', note: "Ответственный подрядчик по пожарной автоматике и оповещению.", }, }; const DEFAULT_EMPLOYEES_BY_ORG = { "1": [ { id: "e1", fullName: "Иванов Сергей Петрович", position: "Инженер ОВиК", status: "active", phone: "+7 (900) 111-22-33", email: "s.ivanov@techmont.ru" }, { id: "e2", fullName: "Петрова Анна Дмитриевна", position: "Прораб", status: "active", phone: "+7 (900) 222-33-44", email: "a.petrova@techmont.ru" }, { id: "e3", fullName: "Смирнов Алексей Сергеевич", position: "Техник ПНР", status: "inactive", phone: "+7 (900) 333-44-55", email: "a.smirnov@techmont.ru" }, ], "2": [ { id: "e4", fullName: "Кузнецов Михаил Витальевич", position: "Инженер связи", status: "active", phone: "+7 (901) 111-22-11", email: "m.kuznetsov@signalpro.ru" }, { id: "e5", fullName: "Орлова Елена Андреевна", position: "Монтажник", status: "active", phone: "+7 (901) 222-33-22", email: "e.orlova@signalpro.ru" }, { id: "e6", fullName: "Федоров Роман Игоревич", position: "Системный администратор", status: "active", phone: "+7 (901) 333-44-33", email: "r.fedorov@signalpro.ru" }, ], "3": [ { id: "e7", fullName: "Морозов Николай Сергеевич", position: "Руководитель ПНР", status: "active", phone: "+7 (902) 111-10-10", email: "n.morozov@bezop.ru" }, { id: "e8", fullName: "Лебедева Татьяна Юрьевна", position: "Инженер проектов", status: "active", phone: "+7 (902) 222-20-20", email: "t.lebedeva@bezop.ru" }, { id: "e9", fullName: "Соколов Артем Вячеславович", position: "Сервисный инженер", status: "inactive", phone: "+7 (902) 333-30-30", email: "a.sokolov@bezop.ru" }, ], }; function getOrgId() { const params = new URLSearchParams(window.location.search); return params.get("id") || "1"; } function badgeClassForStatus(status) { if (status === "active") return "success"; if (status === "inactive") return "warn"; return "warn"; } function getOrgs() { const raw = localStorage.getItem(ORGS_STORAGE_KEY); if (!raw) { localStorage.setItem(ORGS_STORAGE_KEY, JSON.stringify(DEFAULT_ORGS)); return { ...DEFAULT_ORGS }; } try { const parsed = JSON.parse(raw); return parsed && typeof parsed === "object" ? parsed : { ...DEFAULT_ORGS }; } catch (error) { localStorage.setItem(ORGS_STORAGE_KEY, JSON.stringify(DEFAULT_ORGS)); return { ...DEFAULT_ORGS }; } } function getEmployeesByOrg() { const raw = localStorage.getItem(EMPLOYEES_STORAGE_KEY); if (!raw) { localStorage.setItem(EMPLOYEES_STORAGE_KEY, JSON.stringify(DEFAULT_EMPLOYEES_BY_ORG)); return JSON.parse(JSON.stringify(DEFAULT_EMPLOYEES_BY_ORG)); } try { const parsed = JSON.parse(raw); return parsed && typeof parsed === "object" ? parsed : JSON.parse(JSON.stringify(DEFAULT_EMPLOYEES_BY_ORG)); } catch (error) { localStorage.setItem(EMPLOYEES_STORAGE_KEY, JSON.stringify(DEFAULT_EMPLOYEES_BY_ORG)); return JSON.parse(JSON.stringify(DEFAULT_EMPLOYEES_BY_ORG)); } } function saveEmployeesByOrg(data) { localStorage.setItem(EMPLOYEES_STORAGE_KEY, JSON.stringify(data)); } function removeEmployee(orgId, employeeId) { const map = getEmployeesByOrg(); map[orgId] = (map[orgId] || []).filter((emp) => emp.id !== employeeId); saveEmployeesByOrg(map); render(); } function render() { const orgId = getOrgId(); const ORGS = getOrgs(); const EMPLOYEES_BY_ORG = getEmployeesByOrg(); const org = ORGS[orgId] || ORGS["1"]; const employees = EMPLOYEES_BY_ORG[orgId] || EMPLOYEES_BY_ORG["1"] || []; document.getElementById("org-title").textContent = "Сотрудники: " + org.name; document.getElementById("org-subtitle").textContent = "Организация: " + org.name; document.getElementById("employees-brand").textContent = "EKS | Сотрудники | " + org.name; document.getElementById("org-meta-name").textContent = org.name; document.getElementById("org-meta-note").textContent = org.note; const select = document.getElementById("org-select"); select.innerHTML = ""; Object.keys(ORGS).forEach(key => { const opt = document.createElement("option"); opt.value = key; opt.textContent = ORGS[key].name; if (key === orgId) opt.selected = true; select.appendChild(opt); }); select.onchange = () => { window.location.search = "?id=" + select.value; }; const tbody = document.getElementById("employees-tbody"); tbody.innerHTML = ""; employees.forEach(emp => { const statusClass = badgeClassForStatus(emp.status); const tr = document.createElement("tr"); tr.innerHTML = "<td>" + emp.fullName + "</td>" + "<td>" + emp.position + "</td>" + "<td><span class=\"badge " + statusClass + "\">" + (emp.status === "active" ? "Активен" : "Неактивен") + "</span></td>" + "<td>" + "<div style=\"color: var(--text); font-weight: 600; margin-bottom: 4px;\">"+ emp.phone + "</div>" + "<div style=\"color: var(--muted);\">" + emp.email + "</div>" + "</td>" + "<td><button class=\"btn btn-danger\" type=\"button\" data-delete-employee=\"" + emp.id + "\">Удалить</button></td>"; tbody.appendChild(tr); }); tbody.querySelectorAll("[data-delete-employee]").forEach((button) => { button.addEventListener("click", () => { removeEmployee(orgId, button.getAttribute("data-delete-employee")); }); }); } document.getElementById("add-employee-form").addEventListener("submit", (event) => { event.preventDefault(); const orgId = getOrgId(); const formData = new FormData(event.target); const fullName = String(formData.get("fullName") || "").trim(); const position = String(formData.get("position") || "").trim(); const status = String(formData.get("status") || "active"); const phone = String(formData.get("phone") || "").trim(); const email = String(formData.get("email") || "").trim(); if (!fullName || !position || !phone || !email) return; const map = getEmployeesByOrg(); if (!Array.isArray(map[orgId])) map[orgId] = []; map[orgId].push({ id: String(Date.now()), fullName, position, status: status === "inactive" ? "inactive" : "active", phone, email, }); saveEmployeesByOrg(map); event.target.reset(); render(); }); render(); </script> </body> </html>