дашборд сертификации с данными
This commit is contained in:
parent
d44795f4e3
commit
6efe4efc76
4
.vibe42-run.log
Normal file
4
.vibe42-run.log
Normal file
@ -0,0 +1,4 @@
|
||||
--- run Wed Aug 19 06:26:14 AM UTC 2026 :: npm start --silent
|
||||
|
||||
up to date in 404ms
|
||||
Сервер запущен на порту 3000
|
||||
1
.vibe42-run.pid
Normal file
1
.vibe42-run.pid
Normal file
@ -0,0 +1 @@
|
||||
86
|
||||
131
data.json
Normal file
131
data.json
Normal file
@ -0,0 +1,131 @@
|
||||
{
|
||||
"employees": [
|
||||
{"id": 1, "city": "Астана", "name": "Әжібек Айбек Тұрғанбекұлы", "position": "Ведущий инженер службы оперативного контроля 1 уровня г.Астана", "vendor": "Cisco", "certificate": "Cisco Certified Network Associate (CCNA)", "level": "Специалист"},
|
||||
{"id": 2, "city": "Астана", "name": "Абдрахманова Гаухар Нигметовна", "position": "Ведущий инженер службы оперативного контроля 1 уровня г.Астана", "vendor": "Juniper", "certificate": "Juniper Networks Certified Internetwork Associate (JNCIA)", "level": "Специалист"},
|
||||
{"id": 3, "city": "Алматы", "name": "АБДУГАППАРОВ МАКСАТ КАЛДЫБЕКОВИЧ", "position": "Гл. менеджер СТПСР 3 уровня г.Алматы", "vendor": "Red Hat", "certificate": "Red Hat Certified System Administrator", "level": "Профессионал"},
|
||||
{"id": 4, "city": "Алматы", "name": "Абдыгалиев Назар", "position": "Гл. менеджер СТПСР 2 уровня г.Алматы", "vendor": "Juniper", "certificate": "Juniper Networks Certified Professional Service Provider (JNCIP-SP)", "level": "Профессионал"},
|
||||
{"id": 5, "city": "Астана", "name": "АБИЛЬДИНОВ МЕИРЖАН ДАРИСОВИЧ", "position": "Менеджер СТПСР 3 уровня г.Астаны", "vendor": "Gilat", "certificate": "SkyEdgeII Basic Hub Operations Course", "level": "Специалист"},
|
||||
{"id": 6, "city": "Алматы", "name": "Абуов Нуржан Зеверович", "position": "Менеджер СТПСР 3 уровня г.Алматы", "vendor": "Huawei", "certificate": "Эксплуатация и техобслуживание основного оборудования NGN", "level": "Профессионал"},
|
||||
{"id": 7, "city": "Алматы", "name": "Айтбаев Асылхан Абдыханович", "position": "Менеджер службы оперативного контроля 1 уровня г.Алматы", "vendor": "Juniper", "certificate": "Juniper Networks Certified Internetwork Associate (JNCIA)", "level": "Специалист"},
|
||||
{"id": 8, "city": "Астана", "name": "Айтжан Марғулан Мейрамбайұлы", "position": "Менеджер СТПСР 3 уровня г.Астаны", "vendor": "ZTE", "certificate": "ZTE GPON Solution Training Course", "level": "Специалист"},
|
||||
{"id": 9, "city": "Алматы", "name": "АЛЕКПАРОВ ИБРАГИМ СЕЙФАТДИНОВИЧ", "position": "Старший аналитик СТПСР 2 уровня г.Алматы", "vendor": "Red Hat", "certificate": "Red Hat RH134 Red Hat System Administration II", "level": "Специалист"},
|
||||
{"id": 10, "city": "Алматы", "name": "АЛИЕВ АБИУ ЖОЛДАСБАЕВИЧ", "position": "Менеджер службы оперативного контроля 1 уровня г.Алматы", "vendor": "Juniper", "certificate": "Juniper Networks Certified Internetwork Associate (JNCIA)", "level": "Специалист"},
|
||||
{"id": 11, "city": "Алматы", "name": "Альбекова Алина Ринатовна", "position": "Менеджер СТПСР 3 уровня г.Астаны", "vendor": "Cisco", "certificate": "Cisco Certified Network Professional Enterprise (CCNP)", "level": "Профессионал"},
|
||||
{"id": 12, "city": "Алматы", "name": "Анламасова Ризвангуль Анырдиновна", "position": "Менеджер СТПСР 2 уровня г.Алматы", "vendor": "Juniper", "certificate": "Juniper Networks Certified Professional Service Provider (JNCIP-SP)", "level": "Профессионал"},
|
||||
{"id": 14, "city": "Алматы", "name": "Антропова Наталья Ивановна", "position": "Менеджер СТПСР 2 уровня г.Алматы", "vendor": "Iskratel", "certificate": "SI3000 MSCP - управление и администрирование", "level": "Профессионал"},
|
||||
{"id": 15, "city": "Алматы", "name": "Арстанов Ерик Сисенбаевич", "position": "Менеджер СТПСР 2 уровня г.Алматы", "vendor": "Iskratel", "certificate": "SI3000 MSCP - управление и администрирование", "level": "Профессионал"},
|
||||
{"id": 16, "city": "Алматы", "name": "Ахметов Руслан Тауекелович", "position": "Менеджер СТПСР 3 уровня г.Алматы", "vendor": "Juniper", "certificate": "Juniper Networks Certified Professional Service Provider (JNCIP-SP)", "level": "Профессионал"},
|
||||
{"id": 17, "city": "Алматы", "name": "Ахметова Дина Кайрхановна", "position": "Старший аналитик департамента технической поддержки ресурсов сетей", "vendor": "Juniper", "certificate": "Juniper Networks Certified Internetwork Associate (JNCIA)", "level": "Специалист"},
|
||||
{"id": 18, "city": "Алматы", "name": "БАЙДИЛДАЕВ ГУМАР БОЛАТОВИЧ", "position": "Начальник службы СТПСР 3 уровня г.Алматы", "vendor": "Juniper", "certificate": "Juniper Networks Certified Expert", "level": "Эксперт"},
|
||||
{"id": 19, "city": "Астана", "name": "Байконурова Меруерт Бактияровна", "position": "Ведущий инженер службы оперативного контроля 1 уровня г.Астаны", "vendor": "Juniper", "certificate": "Juniper Networks Certified Professional Service Provider (JNCIP-SP)", "level": "Профессионал"},
|
||||
{"id": 20, "city": "Алматы", "name": "БАЙМЛЕР ОЛЬГА АЛЬБЕРТОВНА", "position": "", "vendor": "Genband", "certificate": "Multiservice Data Manager Toolset", "level": "Профессионал"},
|
||||
{"id": 22, "city": "Алматы", "name": "Васильков Михаил Геннадьевич", "position": "Ведущий инженер СТПСР 3 уровня г.Алматы", "vendor": "Juniper", "certificate": "Juniper Networks Certified Professional Service Provider (JNCIP-SP)", "level": "Профессионал"},
|
||||
{"id": 23, "city": "Алматы", "name": "Нарымбетов Газиз Маратович", "position": "Главный менеджер СТПСР 3 уровня г.Алматы", "vendor": "Red Hat", "certificate": "Red Hat 124 Red Hat System Administration I", "level": "Специалист"},
|
||||
{"id": 24, "city": "Астана", "name": "Галиев Азамат Бахытжанович", "position": "Гл. менеджер службы оперативного контроля 1 уровня г.Астаны", "vendor": "Nokia Siemens Networks", "certificate": "hIT7300", "level": "Специалист"},
|
||||
{"id": 25, "city": "Алматы", "name": "Глубшева Юлия Геннадьевна", "position": "Ведущий инженер СТПСР 3 уровня г.Алматы", "vendor": "Genband", "certificate": "Integrated Element Manager System (IEMS) Operations", "level": "Профессионал"},
|
||||
{"id": 26, "city": "Алматы", "name": "ДЖАПАБАЕВ АБЗАЛ КАНАТОВИЧ", "position": "Начальник службы СТПСР 2 уровня г.Алматы", "vendor": "Cisco", "certificate": "Cisco Certified Network Professional Enterprise (CCNP)", "level": "Профессионал"},
|
||||
{"id": 27, "city": "Алматы", "name": "ДЖУСУПОВ МАКСАТ МУРАТОВИЧ", "position": "Менеджер службы СТПСР 2 уровня г.Алматы", "vendor": "Iskratel", "certificate": "SI3000 NSCP - управление и администрирование", "level": "Профессионал"},
|
||||
{"id": 28, "city": "Алматы", "name": "Ержекеева Анара Кайраткызы", "position": "Ведущий инженер СТПСР 3 уровня г.Алматы", "vendor": "Juniper", "certificate": "Juniper Networks Certified Professional Service Provider (JNCIP-SP)", "level": "Профессионал"},
|
||||
{"id": 29, "city": "Алматы", "name": "Есенбаев Адилет Наурызбекович", "position": "Ведущий инженер службы оперативного контроля 1 уровня г.Алматы", "vendor": "Juniper", "certificate": "Juniper Networks Certified Professional Service Provider (JNCIP-SP)", "level": "Профессионал"},
|
||||
{"id": 30, "city": "Астана", "name": "Жабағи Ақбота Еркінқызы", "position": "Аналитик службы оперативного контроля 1 уровня г.Астаны", "vendor": "Juniper", "certificate": "Juniper Networks Certified Associate Security (JNCIA-SEC)", "level": "Специалист"},
|
||||
{"id": 31, "city": "Алматы", "name": "ЖАҚСЫБАЙ ДАСТАН НҰРДӘУЛЕТҰЛЫ", "position": "Старший аналитик службы оперативного контроля 1 уровня г.Алматы", "vendor": "Juniper", "certificate": "Juniper Networks Certified Internetwork Associate (JNCIA)", "level": "Специалист"},
|
||||
{"id": 32, "city": "Алматы", "name": "Журеров Руфат Нуредденович", "position": "Менеджер СТПСР 3 уровня г.Алматы", "vendor": "Huawei", "certificate": "Эксплуатация цифрового АТС C&C08", "level": "Специалист"},
|
||||
{"id": 33, "city": "Алматы", "name": "Зимин Олег Витальевич", "position": "Менеджер СТПСР 3 уровня г.Алматы", "vendor": "Alcatel Telecom TTC", "certificate": "Internet Protocols", "level": "Специалист"},
|
||||
{"id": 34, "city": "Алматы", "name": "Ибраимов Саят Куандыкович", "position": "Менеджер СТПСР 3 уровня г.Алматы", "vendor": "Juniper", "certificate": "Juniper Networks Certified Professional Service Provider (JNCIP-SP)", "level": "Профессионал"},
|
||||
{"id": 35, "city": "Алматы", "name": "Ибраимов Саят Куандыкович", "position": "Менеджер СТПСР 3 уровня г.Алматы", "vendor": "Cisco", "certificate": "Cisco Certified Network Associate (CCNA)", "level": "Специалист"},
|
||||
{"id": 36, "city": "Алматы", "name": "ИБРАИМОВ СЕРГЕЙ МЕРДЕНОВИЧ", "position": "МенеджерСТПСР 3 уровня г.Алматы", "vendor": "Huawei", "certificate": "Обзор концепции NGN и решение U-SYS", "level": "Специалист"},
|
||||
{"id": 37, "city": "Алматы", "name": "ИБРАИМОВА РОЗА АУЕСХАНОВНА", "position": "Старший аналитик службы оперативного контроля 1 уровня г.Алматы", "vendor": "Juniper", "certificate": "Juniper Networks Certified Internetwork Associate (JNCIA)", "level": "Специалист"},
|
||||
{"id": 38, "city": "Алматы", "name": "Иванников Дмитрий Дмитриевич", "position": "Гл. менеджер СТПСР 3 уровня г.Алматы", "vendor": "ZTE", "certificate": "ZTE GPON Solution Training Course", "level": "Специалист"},
|
||||
{"id": 39, "city": "Алматы", "name": "Игламов Жумагазы Нурланович", "position": "Гл. менеджер СТПСР 2 уровня г.Алматы", "vendor": "Juniper", "certificate": "Juniper Networks Certified Professional Service Provider (JNCIP-SP)", "level": "Профессионал"},
|
||||
{"id": 40, "city": "Алматы", "name": "Имбергенова Гульнара Абылкасыновна", "position": "Менеджер СТПСР 3 уровня г.Алматы", "vendor": "Juniper", "certificate": "Juniper Networks Certified Professional Service Provider (JNCIP-SP)", "level": "Профессионал"},
|
||||
{"id": 41, "city": "Алматы", "name": "Кабиден Рустам Ербулатулы", "position": "И.о.директора технической поддержки ресурсов сетей", "vendor": "Juniper", "certificate": "Juniper Networks Certified Professional Service Provider (JNCIP-SP)", "level": "Профессионал"},
|
||||
{"id": 42, "city": "Алматы", "name": "Камзабаев Мурат Ерикович", "position": "Гл. менеджер СТПСР 3 уровня г.Алматы", "vendor": "Huawei", "certificate": "HUAWEI ACCESS HCIA", "level": "Специалист"},
|
||||
{"id": 43, "city": "Алматы", "name": "Кан Вячеслав Дмитриевич", "position": "Ведущий инженер службы оперативного контроля 1 уровня г.Алматы", "vendor": "Juniper", "certificate": "Juniper Networks Certified Professional Service Provider (JNCIP-SP)", "level": "Профессионал"},
|
||||
{"id": 44, "city": "Алматы", "name": "Касымжанов Жарас Жастарович", "position": "Менеджер СТПСР 3 уровня г.Алматы", "vendor": "Cisco", "certificate": "Cisco Certified Specialist - Enterprise Advanced Infrastructure Implementation", "level": "Специалист"},
|
||||
{"id": 45, "city": "Алматы", "name": "Кельбатыров Аскар Бекболатович", "position": "Главный менеджер центра оперативного контроля и технической поддержки г.Алматы", "vendor": "Huawei", "certificate": "C&C08 Operation and Maintenance training", "level": "Профессионал"},
|
||||
{"id": 46, "city": "Алматы", "name": "КЕРЕЕВ АЙДЫН ЖОЛДАСКАЛИЕВИЧ", "position": "Менеджер СТПСР 2 уровня г.Алматы", "vendor": "Juniper", "certificate": "Juniper Networks Certified Professional Service Provider (JNCIP-SP)", "level": "Профессионал"},
|
||||
{"id": 47, "city": "Алматы", "name": "Кішібаев Дарын Болатұлы", "position": "Менеджер СТПСР 3 уровня г.Алматы", "vendor": "Juniper", "certificate": "Juniper Networks Certified Professional Service Provider (JNCIP-SP)", "level": "Профессионал"},
|
||||
{"id": 48, "city": "Алматы", "name": "Козлов Андрей Петрович", "position": "Менеджер СТПСР 3 уровня г.Алматы", "vendor": "Acme Packet", "certificate": "compact call server 2000 (cCS2000) overview", "level": "Специалист"},
|
||||
{"id": 49, "city": "Алматы", "name": "Козьмин Евгений Глебович", "position": "Старший аналитик службы оперативного контроля 1 уровня г.Алматы", "vendor": "Juniper", "certificate": "Juniper Networks Certified Internetwork Associate (JNCIA)", "level": "Специалист"},
|
||||
{"id": 50, "city": "Астана", "name": "Корнатовская Татьяна Викторовна", "position": "Ведущий инженер по управлению сетями службы оперативного контроля 1 уровня г.Астаны", "vendor": "Nokia Siemens Networks", "certificate": "SURPASS hiT 7070, 7050 O&M", "level": "Специалист"},
|
||||
{"id": 51, "city": "Астана", "name": "Корнатовская Татьяна Викторовна", "position": "Ведущий инженер по управлению сетями службы оперативного контроля 1 уровня г.Астаны", "vendor": "Nokia Siemens Networks", "certificate": "TNMS-Core/CDM Operation and Administration", "level": "Специалист"},
|
||||
{"id": 52, "city": "Алматы", "name": "Корнеев Александр Вячеславович", "position": "Менеджер СТПСР 3 уровня г.Алматы", "vendor": "Cisco", "certificate": "Cisco Certified Specialist - Enterprise Core", "level": "Специалист"},
|
||||
{"id": 53, "city": "Алматы", "name": "Красильникова Наталья Владимировна", "position": "Гл.менеджер СТПСР 2 уровня г.Алматы", "vendor": "Iskratel", "certificate": "SI3000 MSCP - управление и администрирование", "level": "Профессионал"},
|
||||
{"id": 54, "city": "Алматы", "name": "Крыкпаева Алия Серикпаевна", "position": "Старший аналитик центра оперативного контроля и технической поддержки г.Алматы", "vendor": "Juniper", "certificate": "Juniper Networks Certified Internetwork Associate (JNCIA)", "level": "Специалист"},
|
||||
{"id": 55, "city": "Алматы", "name": "Куанышбеков Самат Толеукадырович", "position": "Менеджер СТПСР 2 уровня г.Алматы", "vendor": "Red Hat", "certificate": "Red Hat RH134 Red Hat System Administration II", "level": "Специалист"},
|
||||
{"id": 56, "city": "Алматы", "name": "Күлмақашов Азиз Бауыржанұлы", "position": "Менеджер СТПСР 3 уровня г.Алматы", "vendor": "Juniper", "certificate": "Juniper Networks Certified Professional Service Provider (JNCIP-SP)", "level": "Профессионал"},
|
||||
{"id": 57, "city": "Алматы", "name": "КҰДАЙБЕРГЕНОВ ОЛЖАС БЕКСҰЛТАНҰЛЫ", "position": "Аналитик службы оперативного контроля 1 уровня г.Алматы", "vendor": "Juniper", "certificate": "Juniper Networks Certified Internetwork Associate (JNCIA)", "level": "Специалист"},
|
||||
{"id": 58, "city": "Алматы", "name": "Лесников Игорь Владимирович", "position": "Главный менеджер службы оперативного контроля 1 уровня г.Алматы", "vendor": "Juniper", "certificate": "Juniper Networks Certified Professional Service Provider (JNCIP-SP)", "level": "Профессионал"},
|
||||
{"id": 59, "city": "Алматы", "name": "Макашова Толкын Муратовна", "position": "Главный менеджер службы оперативного контроля 1 уровня г.Алматы", "vendor": "Juniper", "certificate": "Service Provider Routing and Switching (JNCIS-SP)", "level": "Специалист"},
|
||||
{"id": 60, "city": "Астана", "name": "МАМБЕТОВ АЗАМАТ АДИЛОВИЧ", "position": "Ведущий инженер службы оперативного контроля 1 уровня г.Астаны", "vendor": "Juniper", "certificate": "Juniper Networks Certified Internetwork Associate (JNCIA)", "level": "Специалист"},
|
||||
{"id": 61, "city": "Астана", "name": "Матис Ольга Викторовна", "position": "Ведущий инженер по управлению сетями службы оперативного контроля 1 уровня г.Астаны", "vendor": "Nokia Siemens Networks", "certificate": "hiT 7300 OAM: General Topics", "level": "Специалист"},
|
||||
{"id": 62, "city": "Алматы", "name": "Мергалиева Анаргуль Гадилшеевна", "position": "Старший аналитик центра оперативного контроля и технической поддержки г.Алматы", "vendor": "Juniper", "certificate": "Juniper Networks Certified Internetwork Associate (JNCIA)", "level": "Специалист"},
|
||||
{"id": 63, "city": "Алматы", "name": "Михайленко Анна Александровна", "position": "Менеджер службы оперативного контроля 1 уровня г.Алматы", "vendor": "Juniper", "certificate": "Juniper Networks Certified Specialist Service Provider Routing and Switching (JNCIS-SP)", "level": "Специалист"},
|
||||
{"id": 64, "city": "Астана", "name": "Муратбеков Манар Самарулы", "position": "Менеджер СТПСР 3 уровня г.Астаны", "vendor": "ZTE", "certificate": "ZTE GPON Solution Training Course", "level": "Специалист"},
|
||||
{"id": 65, "city": "Алматы", "name": "Мухатов Данияр Кайратович", "position": "Главный менеджер СТПСР 3 уровня г.Алматы", "vendor": "Juniper", "certificate": "Juniper Networks Certified Professional Service Provider (JNCIP-SP)", "level": "Профессионал"},
|
||||
{"id": 66, "city": "Алматы", "name": "Мырзакарім Данияр Бақтиярұлы", "position": "Ведущий инженер СТПСР 3 уровня г.Алматы", "vendor": "Juniper", "certificate": "Juniper Networks Certified Internetwork Associate (JNCIA)", "level": "Специалист"},
|
||||
{"id": 67, "city": "Алматы", "name": "Нарымбетов Газиз Маратович", "position": "Главный менеджер СТПСР 3 уровня г.Алматы", "vendor": "Lifeatream", "certificate": "IPTV/ОТТ платформа Лайфстрим", "level": "Профессионал"},
|
||||
{"id": 68, "city": "Алматы", "name": "Новикова Елена Михайловна", "position": "Ведущий инженер службы оперативного контроля 1 уровня г.Алматы", "vendor": "Juniper", "certificate": "Juniper Networks Certified Specialist Service Provider Routing and Switching (JNCIS-SP)", "level": "Специалист"},
|
||||
{"id": 69, "city": "Алматы", "name": "НУРАХМЕТОВ ДАУРЕН АШИРБЕКОВИЧ", "position": "Менеджер департамента технической поддержки ресурсов сетей", "vendor": "Juniper", "certificate": "Juniper Networks Certified Internetwork Associate (JNCIA)", "level": "Специалист"},
|
||||
{"id": 70, "city": "Алматы", "name": "Нурпеисов Ерканат Муратович", "position": "Менеджер СТПСР 3 уровня г.Алматы", "vendor": "Juniper", "certificate": "Juniper Networks Certified Professional Service Provider (JNCIP-SP)", "level": "Профессионал"},
|
||||
{"id": 71, "city": "Астана", "name": "Нұрпатта Нұрғазы Серікұлы", "position": "Ведущий инженер службы оперативного контроля 1 уровня г.Астаны", "vendor": "Juniper", "certificate": "Juniper Networks Certified Internetwork Associate (JNCIA)", "level": "Специалист"},
|
||||
{"id": 72, "city": "Астана", "name": "Нұрсұлтанова Айнур Бахытханқызы", "position": "Менеджер службы оперативного контроля 1 уровня г.Астаны", "vendor": "Juniper", "certificate": "Juniper Networks Certified Professional Service Provider (JNCIP-SP)", "level": "Профессионал"},
|
||||
{"id": 73, "city": "Астана", "name": "Оспанов Диас Искакович", "position": "Ведущий инженер службы оперативного контроля 1 уровня г.Астаны", "vendor": "Cisco", "certificate": "Cisco Certified Network Associate (CCNA)", "level": "Специалист"},
|
||||
{"id": 74, "city": "Алматы", "name": "Садуақасқызы Жанат", "position": "Старший аналитик службы оперативного контроля 1 уровня г.Алматы", "vendor": "Juniper", "certificate": "Juniper Networks Certified Professional Service Provider (JNCIP-SP)", "level": "Профессионал"},
|
||||
{"id": 75, "city": "Алматы", "name": "СТОЛЯРСКАЯ ОЛЕСЯ ВАЛЕРЬЕВНА", "position": "Старший аналитик службы оперативного контроля 1 уровня г.Алматы", "vendor": "GENBAND", "certificate": "Universal Signalling Point Compact (USP): OAM&P", "level": "Профессионал"},
|
||||
{"id": 76, "city": "Алматы", "name": "Сугурджанов Нуржан Сембигалиевич", "position": "Главный менеджер СТПСР 3 уровня г.Алматы", "vendor": "Red Hat", "certificate": "Red Hat 124 Red Hat System Administration I", "level": "Специалист"},
|
||||
{"id": 77, "city": "Алматы", "name": "СУЗДАЛЕВА ТАТЬЯНА ГЕННАДЬЕВНА", "position": "Ведущий инженер СТПСР 3 уровня г.Алматы", "vendor": "Genband", "certificate": "Gateway Controller Administration and Maintenance (CS2K)", "level": "Профессионал"},
|
||||
{"id": 78, "city": "Алматы", "name": "Таласбай Асқар Қуанышұлы", "position": "Менеджер СТПСР 3 уровня г.Алматы", "vendor": "Juniper", "certificate": "Juniper Networks Certified Professional Service Provider (JNCIP-SP)", "level": "Профессионал"},
|
||||
{"id": 79, "city": "Алматы", "name": "Тилешов Серик Айтжанович", "position": "Ведущий инженер СТПСР 3 уровня г.Алматы", "vendor": "Juniper", "certificate": "Juniper Networks Certified Professional Service Provider (JNCIP-SP)", "level": "Профессионал"},
|
||||
{"id": 81, "city": "Алматы", "name": "Тиржанова Айгуль Бекмурзаевна", "position": "Старший аналитик СТПСР 2 уровня г.Алматы", "vendor": "Genband", "certificate": "Communication Server 2000 - Compact Maintenance", "level": "Профессионал"},
|
||||
{"id": 82, "city": "Астана", "name": "Тобағабылов Нұрғали Салтайұлы", "position": "Главный менеджер СТПСР 3 уровня г.Астаны", "vendor": "Red Hat", "certificate": "Red Hat Certified System Administrator (RHCSA)", "level": "Специалист"},
|
||||
{"id": 83, "city": "Алматы", "name": "Төлеу Нұржан Оразалыұлы", "position": "Старший аналитик СТПСР 2 уровня г.Алматы", "vendor": "Juniper", "certificate": "Juniper Networks Certified Internetwork Associate (JNCIA)", "level": "Специалист"},
|
||||
{"id": 84, "city": "Алматы", "name": "Тулегенов Еркинбек Аюбекович", "position": "Менеджер СТПСР 3 уровня г.Алматы", "vendor": "Huawei", "certificate": "Maintenance GPON/10GPON", "level": "Специалист"},
|
||||
{"id": 85, "city": "Алматы", "name": "Турсынбаева Аружан Жандоскызы", "position": "Ведущий инженер службы оперативного контроля 1 уровня г.Алматы", "vendor": "Juniper", "certificate": "Juniper Networks Certified Specialist Service Provider Routing and Switching (JNCIS-SP)", "level": "Специалист"},
|
||||
{"id": 86, "city": "Алматы", "name": "Турусбеков Алмат Серикжанович", "position": "Старший аналитик СТПСР 2 уровня г.Алматы", "vendor": "Juniper", "certificate": "Juniper Networks Certified Internetwork Associate (JNCIA)", "level": "Специалист"},
|
||||
{"id": 87, "city": "Астана", "name": "Тұрғанбек Назым Мұратқызы", "position": "Ведущий инженер службы оперативного контроля 1 уровня г.Астаны", "vendor": "Cisco", "certificate": "Cisco Certified Network Associate (CCNA)", "level": "Специалист"},
|
||||
{"id": 88, "city": "Алматы", "name": "Утесбаева Замира Маратовна", "position": "Менеджер СТПСР 2 уровня г.Алматы", "vendor": "Genband", "certificate": "compact call server 2000 (cCS2000) overview", "level": "Профессионал"},
|
||||
{"id": 89, "city": "Алматы", "name": "Фазлиев Рамиль Наильевич", "position": "Менеджер СТПСР 3 уровня г.Алматы", "vendor": "Juniper", "certificate": "Juniper Networks Certified Professional Service Provider (JNCIP-SP)", "level": "Профессионал"},
|
||||
{"id": 90, "city": "Астана", "name": "Фриген Денис Владимирович", "position": "Системный инженер К1 СТПСР 3 уровня г.Астаны", "vendor": "Lucent Technologies", "certificate": "5ESS Switch System Introduction", "level": "Профессионал"},
|
||||
{"id": 91, "city": "Алматы", "name": "ХОРОШИЛОВ СЕРГЕЙ АНДРЕЕВИЧ", "position": "Менеджер службы оперативного контроля 1 уровня г.Алматы", "vendor": "Juniper", "certificate": "Juniper Networks Certified Internetwork Associate (JNCIA)", "level": "Специалист"},
|
||||
{"id": 92, "city": "Алматы", "name": "Хусынов Жарасхан Шапхатович", "position": "Менеджер СТПСР 3 уровня г.Алматы", "vendor": "Juniper", "certificate": "Juniper Networks Certified Professional Service Provider (JNCIP-SP)", "level": "Профессионал"},
|
||||
{"id": 93, "city": "Алматы", "name": "Чепор Дмитрий Николаевич", "position": "Менеджер СТПСР 3 уровня г.Алматы", "vendor": "Red Hat", "certificate": "Red Hat 124 Red Hat System Administration I", "level": "Специалист"},
|
||||
{"id": 94, "city": "Алматы", "name": "Чой Ирина Николаевна", "position": "Главный менеджер центра оперативного контроля и технической поддержки г.Алматы", "vendor": "Genband", "certificate": "Gateway Controller Administration and Maintenance (CS2K)", "level": "Профессионал"},
|
||||
{"id": 95, "city": "Астана", "name": "Шабала Александр Александрович", "position": "Инженер по ТО оборуд.сети телекоммун. К2 СТПСР 3 уровня г.Астаны", "vendor": "Gilat", "certificate": "SkyEdgeII Basic Hub Operations Course", "level": "Специалист"},
|
||||
{"id": 96, "city": "Астана", "name": "Эйникс Татьяна Викторовна", "position": "Старший аналитик ЦОК и ТПСР г.Астаны", "vendor": "Genband", "certificate": "Gateway Controller Administration and Maintenance (CS2K)", "level": "Профессионал"},
|
||||
{"id": 97, "city": "Алматы", "name": "Игисимбаев Ясир Муратович", "position": "Аналитик службы оперативного контроля 1 уровня г.Алматы", "vendor": "Juniper", "certificate": "Juniper Networks Certified Internetwork Associate (JNCIA)", "level": "Специалист"},
|
||||
{"id": 98, "city": "Алматы", "name": "Сугирбеков Еркебулан Сейсенбекович", "position": "Начальника СВСИ", "vendor": "Juniper", "certificate": "Service Provider Routing and Switching, Professional (JNCIP-SP)", "level": "Профессионал"},
|
||||
{"id": 99, "city": "Алматы", "name": "Иманкулов Алишер Бахытжанұлы", "position": "И.о. начальника ОМСПД", "vendor": "Juniper", "certificate": "Network Certified Associate -Security (JNCIA-SEC)", "level": "Специалист"},
|
||||
{"id": 100, "city": "Алматы", "name": "Кужамбаев Серик Бимозаевич", "position": "Ведущий инженер ОМСПД", "vendor": "Juniper", "certificate": "Service Provider Routing and Switching, Professional (JNCIP-SP)", "level": "Профессионал"},
|
||||
{"id": 101, "city": "Алматы", "name": "Глазков Анатолий Анатольевич", "position": "Главный менеджер САПРС", "vendor": "Juniper", "certificate": "Service Provider Routing and Switching, Professional (JNCIP-SP)", "level": "Профессионал"},
|
||||
{"id": 102, "city": "Алматы", "name": "Култаев Аскар Базарбайұлы", "position": "Ведущий инженер СНиИСР", "vendor": "Juniper", "certificate": "Service Provider Routing and Switching, Professional (JNCIP-SP)", "level": "Профессионал"},
|
||||
{"id": 103, "city": "Алматы", "name": "Жумадилов Айзак Аскарович", "position": "менеджер СНиИСР", "vendor": "Cisco", "certificate": "CCS-SPCore", "level": "Профессионал"},
|
||||
{"id": 104, "city": "Алматы", "name": "Рахимжанов Ахат Адильханұлы", "position": "Главный менеджер ДУСТ", "vendor": "Juniper", "certificate": "Juniper Networks Certified Expert, Service Provider Routing & Switching", "level": "Эксперт"},
|
||||
{"id": 105, "city": "Алматы", "name": "Мананников Виктор Николаевич", "position": "Ведущий инженер электросвязи ГЦУФС", "vendor": "Cisco", "certificate": "Cisco Certified Network Associate (CCNA)", "level": "Специалист"},
|
||||
{"id": 106, "city": "Алматы", "name": "Тулебаева Жанар Мынжасаровна", "position": "Ведущий инженер электросвязи ГЦУФС", "vendor": "Cisco", "certificate": "Cisco Certified Network Associate (CCNA)", "level": "Специалист"},
|
||||
{"id": 107, "city": "Алматы", "name": "Асанатдинов Санжар Жамалатдинұлы", "position": "Инженер электросвязи САСС", "vendor": "Cisco", "certificate": "Cisco Certified Network Associate (CCNA)", "level": "Специалист"},
|
||||
{"id": 108, "city": "Алматы", "name": "Иркитбаев Арман Бакытович", "position": "И.о.начальника САСС", "vendor": "Cisco", "certificate": "Cisco Certified Network Associate (CCNA)", "level": "Специалист"},
|
||||
{"id": 109, "city": "Алматы", "name": "Мазанов Тимирлан Асхатулы", "position": "Инженер электросвязи 1 категории ГЦУФС", "vendor": "Red Hat", "certificate": "Red Hat Certified System Administrator", "level": "Профессионал"},
|
||||
{"id": 110, "city": "Алматы", "name": "Абдрахимова Анар", "position": "Менеджер Службы оперативного контроля 1 уровня г.Алматы", "vendor": "Juniper", "certificate": "Juniper-Service Provider Routing and Switching, Professional (JNCIP-SP)", "level": "Профессионал"},
|
||||
{"id": 111, "city": "Астана", "name": "Кабакова Г.Е.", "position": "Главный менеджер СОК 1 уровня Астана", "vendor": "NOKIA", "certificate": "XGS-PON NOKIA", "level": "Профессионал"},
|
||||
{"id": 112, "city": "Астана", "name": "Утениязова А.Т.", "position": "Аналитик СОК 1 уровня Астана", "vendor": "NOKIA", "certificate": "XGS-PON NOKIA", "level": "Профессионал"},
|
||||
{"id": 113, "city": "Алматы", "name": "Тоембаева А.К.", "position": "Вед.инженер СТПСР3у ПД", "vendor": "Juniper", "certificate": "Juniper-Service Provider Routing and Switching, Professional (JNCIP-SP)", "level": "Профессионал"},
|
||||
{"id": 114, "city": "Алматы", "name": "Кенесбеков Д.К.", "position": "Вед.инженер СТПСР3у СД", "vendor": "Juniper", "certificate": "Juniper-Service Provider Routing and Switching, Professional (JNCIP-SP)", "level": "Профессионал"},
|
||||
{"id": 115, "city": "Алматы", "name": "Есалы Б.М.", "position": "Старший аналитик СТПСР2", "vendor": "Juniper", "certificate": "Juniper-Service Provider Routing and Switching, Professional (JNCIP-SP)", "level": "Профессионал"},
|
||||
{"id": 116, "city": "Алматы", "name": "Искакбаева", "position": "Старший аналитик СТПСР2", "vendor": "Juniper", "certificate": "Junos, Associate (JNCIA-Junos)", "level": "Специалист"},
|
||||
{"id": 117, "city": "Алматы", "name": "Хамзина Д.Е.", "position": "Старший аналитик СТПСР2", "vendor": "Juniper", "certificate": "Juniper-Service Provider Routing and Switching, Professional (JNCIP-SP)", "level": "Профессионал"},
|
||||
{"id": 118, "city": "Алматы", "name": "Иманкулова А. М.", "position": "", "vendor": "Juniper", "certificate": "Service Provider Routing and Switching (JNCIS-SP)", "level": "Специалист"},
|
||||
{"id": 119, "city": "Алматы", "name": "Гасанова Э.И.", "position": "Аналитик службы оперативного контроля 1 уровня г.Алматы", "vendor": "Juniper", "certificate": "Junos, Associate (JNCIA-Junos)", "level": "Специалист"},
|
||||
{"id": 120, "city": "Алматы", "name": "Жайшиликов Р.П.", "position": "Старший аналитик службы оперативного контроля 1 уровня г.Алматы", "vendor": "Juniper", "certificate": "Junos, Associate (JNCIA-Junos)", "level": "Специалист"},
|
||||
{"id": 121, "city": "Алматы", "name": "Тарасов М.", "position": "Менеджер СТПСР3", "vendor": "Ribbon", "certificate": "Synchronisation Network Planning Sync Architect Software", "level": "Профессионал"},
|
||||
{"id": 122, "city": "Алматы", "name": "Кенесбекова А.К.", "position": "Ведущий инженер по обслужививанию оборудования сети передачи данных", "vendor": "Juniper", "certificate": "Juniper-Service Provider Routing and Switching, Professional (JNCIP-SP)", "level": "Профессионал"},
|
||||
{"id": 123, "city": "Астана", "name": "Оспанов Диас Искакович", "position": "Ведущий инженер службы оперативного контроля 1 уровня г.Астаны", "vendor": "Juniper", "certificate": "Juniper-Service Provider Routing and Switching, Professional (JNCIP-SP)", "level": "Профессионал"},
|
||||
{"id": 124, "city": "Астана", "name": "Тұрғанбек Назым Мұратқызы", "position": "Ведущий инженер службы оперативного контроля 1 уровня г.Астаны", "vendor": "Juniper", "certificate": "Juniper-Service Provider Routing and Switching, Professional (JNCIP-SP)", "level": "Профессионал"},
|
||||
{"id": 125, "city": "Астана", "name": "Нұрпатта Нұрғазы Серікұлы", "position": "Ведущий инженер службы оперативного контроля 1 уровня г.Астаны", "vendor": "Juniper", "certificate": "Juniper-Service Provider Routing and Switching, Professional (JNCIP-SP)", "level": "Профессионал"},
|
||||
{"id": 126, "city": "Астана", "name": "Байконурова Меруерт Бактияровна", "position": "Ведущий инженер службы оперативного контроля 1 уровня г.Астаны", "vendor": "Juniper", "certificate": "Juniper-Service Provider Routing and Switching, Professional (JNCIP-SP)", "level": "Профессионал"},
|
||||
{"id": 127, "city": "Алматы", "name": "Байрашев Алибек Жуманбекович", "position": "Главный менеджер СТПСР 3 г.Алматы", "vendor": "Juniper", "certificate": "Juniper Networks Certified Expert", "level": "Эксперт"},
|
||||
{"id": 128, "city": "Алматы", "name": "Игисимбаев Ясир", "position": "Аналитик службы оперативного контроля 1 уровня г.Алматы", "vendor": "Juniper", "certificate": "Service Provider Routing and Switching (JNCIS-SP)", "level": "Специалист"},
|
||||
{"id": 129, "city": "Алматы", "name": "Касымжанов Жарас Жастарович", "position": "Главный менеджер СТПСР 3 г.Алматы", "vendor": "Juniper", "certificate": "Juniper Networks Certified Professional Data Center (JNCIP-DC)", "level": "Профессионал"},
|
||||
{"id": 130, "city": "Алматы", "name": "Ыдыят Бауыржан Нзамдинұлы", "position": "Старший аналитик службы оперативного контроля 1 уровня г.Алматы", "vendor": "Juniper", "certificate": "Junos, Associate (JNCIA-Junos)", "level": "Специалист"}
|
||||
]
|
||||
}
|
||||
521
index.html
521
index.html
@ -3,21 +3,21 @@
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>Моё расписание на неделю</title>
|
||||
<title>Дашборд сертификации сотрудников</title>
|
||||
<style>
|
||||
* { margin: 0; box-sizing: border-box; }
|
||||
body {
|
||||
font-family: -apple-system, "Segoe UI", Roboto, sans-serif;
|
||||
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
||||
background: linear-gradient(135deg, #1e3c72 0%, #2a5298 100%);
|
||||
min-height: 100vh;
|
||||
padding: 20px;
|
||||
}
|
||||
.container { max-width: 1400px; margin: 0 auto; }
|
||||
h1 { color: #fff; text-align: center; margin-bottom: 20px; font-size: clamp(24px, 4vw, 36px); }
|
||||
.container { max-width: 1600px; margin: 0 auto; }
|
||||
h1 { color: #fff; text-align: center; margin-bottom: 25px; font-size: clamp(24px, 4vw, 36px); }
|
||||
|
||||
.stats {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
|
||||
grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
|
||||
gap: 15px;
|
||||
margin-bottom: 25px;
|
||||
}
|
||||
@ -25,340 +25,349 @@
|
||||
background: rgba(255,255,255,0.95);
|
||||
border-radius: 12px;
|
||||
padding: 20px;
|
||||
text-align: center;
|
||||
box-shadow: 0 4px 15px rgba(0,0,0,0.1);
|
||||
box-shadow: 0 4px 15px rgba(0,0,0,0.15);
|
||||
}
|
||||
.stat-card .num { font-size: 32px; font-weight: bold; color: #667eea; }
|
||||
.stat-card .num { font-size: 36px; font-weight: bold; color: #1e3c72; }
|
||||
.stat-card .label { color: #666; font-size: 14px; margin-top: 5px; }
|
||||
|
||||
.add-btn {
|
||||
display: block;
|
||||
margin: 0 auto 25px;
|
||||
padding: 14px 40px;
|
||||
background: #fff;
|
||||
color: #667eea;
|
||||
border: none;
|
||||
border-radius: 30px;
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
cursor: pointer;
|
||||
box-shadow: 0 4px 15px rgba(0,0,0,0.2);
|
||||
transition: transform 0.2s;
|
||||
}
|
||||
.add-btn:hover { transform: scale(1.05); }
|
||||
|
||||
.modal {
|
||||
display: none;
|
||||
position: fixed;
|
||||
top: 0; left: 0;
|
||||
width: 100%; height: 100%;
|
||||
background: rgba(0,0,0,0.6);
|
||||
z-index: 1000;
|
||||
justify-content: center;
|
||||
.filters {
|
||||
background: rgba(255,255,255,0.95);
|
||||
border-radius: 12px;
|
||||
padding: 20px;
|
||||
margin-bottom: 20px;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 15px;
|
||||
align-items: center;
|
||||
}
|
||||
.modal.on { display: flex; }
|
||||
.modal-content {
|
||||
background: #fff;
|
||||
border-radius: 16px;
|
||||
padding: 30px;
|
||||
width: 90%;
|
||||
max-width: 450px;
|
||||
max-height: 90vh;
|
||||
overflow-y: auto;
|
||||
}
|
||||
.modal-content h2 { margin-bottom: 20px; color: #333; }
|
||||
.form-group { margin-bottom: 15px; }
|
||||
.form-group label { display: block; margin-bottom: 5px; color: #555; font-weight: 500; }
|
||||
.form-group input, .form-group select, .form-group textarea {
|
||||
width: 100%;
|
||||
padding: 12px;
|
||||
.filters label { font-weight: 600; color: #333; margin-right: 8px; }
|
||||
.filters select, .filters input {
|
||||
padding: 10px 14px;
|
||||
border: 2px solid #e0e0e0;
|
||||
border-radius: 8px;
|
||||
font-size: 15px;
|
||||
font-size: 14px;
|
||||
background: #fff;
|
||||
}
|
||||
.form-group textarea { resize: vertical; min-height: 80px; }
|
||||
.form-actions { display: flex; gap: 10px; margin-top: 20px; }
|
||||
.form-actions button {
|
||||
flex: 1;
|
||||
padding: 12px;
|
||||
border: none;
|
||||
border-radius: 8px;
|
||||
font-size: 15px;
|
||||
.filters input { flex: 1; min-width: 200px; }
|
||||
.chip {
|
||||
display: inline-block;
|
||||
padding: 6px 14px;
|
||||
border-radius: 20px;
|
||||
font-size: 13px;
|
||||
font-weight: 600;
|
||||
cursor: pointer;
|
||||
border: 2px solid transparent;
|
||||
transition: all 0.2s;
|
||||
}
|
||||
.btn-save { background: #667eea; color: #fff; }
|
||||
.btn-cancel { background: #e0e0e0; color: #333; }
|
||||
.chip.active { border-color: #1e3c72; background: #e8f0fe; }
|
||||
.chip-level-Специалист { background: #e8f5e9; color: #2e7d32; }
|
||||
.chip-level-Профессионал { background: #fff3e0; color: #ef6c00; }
|
||||
.chip-level-Эксперт { background: #f3e5f5; color: #6a1b9a; }
|
||||
|
||||
.schedule-grid {
|
||||
.charts-row {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
|
||||
gap: 20px;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
.chart-card {
|
||||
background: rgba(255,255,255,0.95);
|
||||
border-radius: 16px;
|
||||
border-radius: 12px;
|
||||
padding: 20px;
|
||||
box-shadow: 0 4px 15px rgba(0,0,0,0.1);
|
||||
}
|
||||
.chart-card h3 { margin-bottom: 15px; color: #333; font-size: 16px; }
|
||||
.bar-chart { display: flex; flex-direction: column; gap: 8px; }
|
||||
.bar-row { display: flex; align-items: center; gap: 10px; }
|
||||
.bar-label { width: 120px; font-size: 13px; color: #555; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
||||
.bar-track { flex: 1; height: 24px; background: #e0e0e0; border-radius: 4px; overflow: hidden; }
|
||||
.bar-fill { height: 100%; border-radius: 4px; transition: width 0.3s; }
|
||||
.bar-value { width: 40px; text-align: right; font-size: 13px; font-weight: 600; color: #333; }
|
||||
|
||||
.table-card {
|
||||
background: rgba(255,255,255,0.95);
|
||||
border-radius: 12px;
|
||||
padding: 20px;
|
||||
box-shadow: 0 4px 15px rgba(0,0,0,0.1);
|
||||
overflow-x: auto;
|
||||
}
|
||||
table { width: 100%; border-collapse: collapse; min-width: 800px; }
|
||||
th, td {
|
||||
padding: 12px 8px;
|
||||
text-align: left;
|
||||
border-bottom: 1px solid #e0e0e0;
|
||||
}
|
||||
th {
|
||||
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
||||
color: #fff;
|
||||
font-weight: 600;
|
||||
position: sticky;
|
||||
top: 0;
|
||||
}
|
||||
table { width: 100%; border-collapse: collapse; min-width: 900px; }
|
||||
th, td { padding: 12px 10px; text-align: left; border-bottom: 1px solid #e0e0e0; }
|
||||
th { background: linear-gradient(135deg, #1e3c72 0%, #2a5298 100%); color: #fff; font-weight: 600; position: sticky; top: 0; }
|
||||
tr:hover { background: #f5f5f5; }
|
||||
.day-badge {
|
||||
.level-badge {
|
||||
display: inline-block;
|
||||
padding: 4px 10px;
|
||||
padding: 4px 12px;
|
||||
border-radius: 20px;
|
||||
font-size: 12px;
|
||||
font-weight: 600;
|
||||
}
|
||||
.day-1 { background: #ffe0e0; color: #c62828; }
|
||||
.day-2 { background: #fff3e0; color: #ef6c00; }
|
||||
.day-3 { background: #e8f5e9; color: #2e7d32; }
|
||||
.day-4 { background: #e3f2fd; color: #1565c0; }
|
||||
.day-5 { background: #f3e5f5; color: #6a1b9a; }
|
||||
.day-6 { background: #fff8e1; color: #f9a825; }
|
||||
.day-0 { background: #fce4ec; color: #c2185b; }
|
||||
.event-title { font-weight: 600; color: #333; }
|
||||
.event-time { color: #666; font-size: 14px; }
|
||||
.event-location { color: #888; font-size: 13px; }
|
||||
.actions { display: flex; gap: 8px; }
|
||||
.actions button {
|
||||
padding: 6px 12px;
|
||||
.level-Специалист { background: #e8f5e9; color: #2e7d32; }
|
||||
.level-Профессионал { background: #fff3e0; color: #ef6c00; }
|
||||
.level-Эксперт { background: #f3e5f5; color: #6a1b9a; }
|
||||
.city-badge { background: #e3f2fd; color: #1565c0; padding: 4px 10px; border-radius: 12px; font-size: 12px; }
|
||||
|
||||
.empty-state { text-align: center; padding: 60px 20px; color: #888; }
|
||||
.export-btn {
|
||||
padding: 10px 20px;
|
||||
background: #2e7d32;
|
||||
color: #fff;
|
||||
border: none;
|
||||
border-radius: 6px;
|
||||
border-radius: 8px;
|
||||
cursor: pointer;
|
||||
font-size: 13px;
|
||||
font-weight: 600;
|
||||
margin-left: auto;
|
||||
}
|
||||
.btn-edit { background: #e3f2fd; color: #1565c0; }
|
||||
.btn-delete { background: #ffebee; color: #c62828; }
|
||||
.empty-state {
|
||||
text-align: center;
|
||||
padding: 60px 20px;
|
||||
color: #888;
|
||||
}
|
||||
.empty-state p { margin-top: 15px; font-size: 16px; }
|
||||
.export-btn:hover { background: #1b5e20; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<h1>📅 Моё расписание на неделю</h1>
|
||||
<h1>📊 Дашборд сертификации сотрудников</h1>
|
||||
|
||||
<div class="stats">
|
||||
<div class="stat-card">
|
||||
<div class="num" id="stat-total">0</div>
|
||||
<div class="label">Всего событий</div>
|
||||
<div class="label">Всего сертификатов</div>
|
||||
</div>
|
||||
<div class="stat-card">
|
||||
<div class="num" id="stat-today">0</div>
|
||||
<div class="label">Сегодня</div>
|
||||
<div class="num" id="stat-employees">0</div>
|
||||
<div class="label">Сотрудников</div>
|
||||
</div>
|
||||
<div class="stat-card">
|
||||
<div class="num" id="stat-week">0</div>
|
||||
<div class="label">На этой неделе</div>
|
||||
<div class="num" id="stat-specialist">0</div>
|
||||
<div class="label">Специалистов</div>
|
||||
</div>
|
||||
<div class="stat-card">
|
||||
<div class="num" id="stat-days">0</div>
|
||||
<div class="label">Дней занято</div>
|
||||
<div class="num" id="stat-professional">0</div>
|
||||
<div class="label">Профессионалов</div>
|
||||
</div>
|
||||
<div class="stat-card">
|
||||
<div class="num" id="stat-expert">0</div>
|
||||
<div class="label">Экспертов</div>
|
||||
</div>
|
||||
<div class="stat-card">
|
||||
<div class="num" id="stat-vendors">0</div>
|
||||
<div class="label">Вендоров</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<button class="add-btn" onclick="openModal()">+ Добавить событие</button>
|
||||
<div class="filters">
|
||||
<label>🔍 Поиск:</label>
|
||||
<input type="text" id="search" placeholder="ФИО, должность, сертификат...">
|
||||
<label>Город:</label>
|
||||
<select id="filter-city"><option value="">Все</option></select>
|
||||
<label>Уровень:</label>
|
||||
<div id="filter-levels"></div>
|
||||
<button class="export-btn" onclick="exportCsv()">📥 Выгрузить в Excel</button>
|
||||
</div>
|
||||
|
||||
<div class="schedule-grid">
|
||||
<div class="charts-row">
|
||||
<div class="chart-card">
|
||||
<h3>📈 По уровням сертификации</h3>
|
||||
<div class="bar-chart" id="chart-levels"></div>
|
||||
</div>
|
||||
<div class="chart-card">
|
||||
<h3>🏢 По городам</h3>
|
||||
<div class="bar-chart" id="chart-cities"></div>
|
||||
</div>
|
||||
<div class="chart-card">
|
||||
<h3>🏷️ Топ вендоров</h3>
|
||||
<div class="bar-chart" id="chart-vendors"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="table-card">
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>День</th>
|
||||
<th>Время</th>
|
||||
<th>Событие</th>
|
||||
<th>Место</th>
|
||||
<th>Заметки</th>
|
||||
<th>Действия</th>
|
||||
<th>№</th>
|
||||
<th>Город</th>
|
||||
<th>ФИО сотрудника</th>
|
||||
<th>Должность</th>
|
||||
<th>Вендор</th>
|
||||
<th>Сертификат</th>
|
||||
<th>Уровень</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="events-body"></tbody>
|
||||
<tbody id="table-body"></tbody>
|
||||
</table>
|
||||
<div class="empty-state" id="empty-state">
|
||||
<div style="font-size: 48px;">📝</div>
|
||||
<p>Пока нет событий. Добавьте первое!</p>
|
||||
<p>Ничего не найдено</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="modal" id="modal">
|
||||
<div class="modal-content">
|
||||
<h2 id="modal-title">Добавить событие</h2>
|
||||
<form id="event-form">
|
||||
<input type="hidden" id="event-id">
|
||||
<div class="form-group">
|
||||
<label>Название *</label>
|
||||
<input type="text" id="event-title" required placeholder="Встреча, урок, тренировка...">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>День недели *</label>
|
||||
<select id="event-day" required>
|
||||
<option value="1">Понедельник</option>
|
||||
<option value="2">Вторник</option>
|
||||
<option value="3">Среда</option>
|
||||
<option value="4">Четверг</option>
|
||||
<option value="5">Пятница</option>
|
||||
<option value="6">Суббота</option>
|
||||
<option value="0">Воскресенье</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>Время начала *</label>
|
||||
<input type="time" id="event-time" required>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>Место</label>
|
||||
<input type="text" id="event-location" placeholder="Офис, онлайн, зал...">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>Заметки</label>
|
||||
<textarea id="event-notes" placeholder="Детали, контакты, подготовка..."></textarea>
|
||||
</div>
|
||||
<div class="form-actions">
|
||||
<button type="button" class="btn-cancel" onclick="closeModal()">Отмена</button>
|
||||
<button type="submit" class="btn-save">Сохранить</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
const days = { 1: 'Пн', 2: 'Вт', 3: 'Ср', 4: 'Чт', 5: 'Пт', 6: 'Сб', 0: 'Вс' };
|
||||
let events = [];
|
||||
let editingId = null;
|
||||
let allData = [];
|
||||
let filteredData = [];
|
||||
let selectedLevels = new Set();
|
||||
|
||||
async function load() {
|
||||
const data = await fetch('/api/events').then(r => r.json());
|
||||
events = data.events || [];
|
||||
const res = await fetch('/api/events').then(r => r.json());
|
||||
allData = res.employees || [];
|
||||
filteredData = [...allData];
|
||||
initFilters();
|
||||
render();
|
||||
}
|
||||
|
||||
function initFilters() {
|
||||
const cities = [...new Set(allData.map(d => d.city))].sort();
|
||||
const citySelect = document.getElementById('filter-city');
|
||||
cities.forEach(c => {
|
||||
if (c) {
|
||||
const opt = document.createElement('option');
|
||||
opt.value = c;
|
||||
opt.textContent = c;
|
||||
citySelect.appendChild(opt);
|
||||
}
|
||||
});
|
||||
|
||||
const levels = ['Специалист', 'Профессионал', 'Эксперт'];
|
||||
const levelsContainer = document.getElementById('filter-levels');
|
||||
levels.forEach(l => {
|
||||
const chip = document.createElement('span');
|
||||
chip.className = 'chip chip-level-' + l;
|
||||
chip.textContent = l;
|
||||
chip.onclick = () => toggleLevel(l, chip);
|
||||
levelsContainer.appendChild(chip);
|
||||
});
|
||||
}
|
||||
|
||||
function toggleLevel(level, chip) {
|
||||
if (selectedLevels.has(level)) {
|
||||
selectedLevels.delete(level);
|
||||
chip.classList.remove('active');
|
||||
} else {
|
||||
selectedLevels.add(level);
|
||||
chip.classList.add('active');
|
||||
}
|
||||
applyFilters();
|
||||
}
|
||||
|
||||
function applyFilters() {
|
||||
const search = document.getElementById('search').value.toLowerCase();
|
||||
const city = document.getElementById('filter-city').value;
|
||||
|
||||
filteredData = allData.filter(d => {
|
||||
const matchSearch = !search ||
|
||||
(d.name && d.name.toLowerCase().includes(search)) ||
|
||||
(d.position && d.position.toLowerCase().includes(search)) ||
|
||||
(d.certificate && d.certificate.toLowerCase().includes(search)) ||
|
||||
(d.vendor && d.vendor.toLowerCase().includes(search));
|
||||
const matchCity = !city || d.city === city;
|
||||
const matchLevel = selectedLevels.size === 0 || selectedLevels.has(d.level);
|
||||
return matchSearch && matchCity && matchLevel;
|
||||
});
|
||||
render();
|
||||
updateStats();
|
||||
}
|
||||
|
||||
function render() {
|
||||
const tbody = document.getElementById('events-body');
|
||||
renderStats();
|
||||
renderCharts();
|
||||
renderTable();
|
||||
}
|
||||
|
||||
function renderStats() {
|
||||
const total = allData.length;
|
||||
const employees = new Set(allData.map(d => d.name)).size;
|
||||
const specialist = allData.filter(d => d.level === 'Специалист').length;
|
||||
const professional = allData.filter(d => d.level === 'Профессионал').length;
|
||||
const expert = allData.filter(d => d.level === 'Эксперт').length;
|
||||
const vendors = new Set(allData.map(d => d.vendor)).size;
|
||||
|
||||
document.getElementById('stat-total').textContent = total;
|
||||
document.getElementById('stat-employees').textContent = employees;
|
||||
document.getElementById('stat-specialist').textContent = specialist;
|
||||
document.getElementById('stat-professional').textContent = professional;
|
||||
document.getElementById('stat-expert').textContent = expert;
|
||||
document.getElementById('stat-vendors').textContent = vendors;
|
||||
}
|
||||
|
||||
function renderCharts() {
|
||||
const levelCounts = {};
|
||||
const cityCounts = {};
|
||||
const vendorCounts = {};
|
||||
|
||||
allData.forEach(d => {
|
||||
levelCounts[d.level] = (levelCounts[d.level] || 0) + 1;
|
||||
cityCounts[d.city] = (cityCounts[d.city] || 0) + 1;
|
||||
vendorCounts[d.vendor] = (vendorCounts[d.vendor] || 0) + 1;
|
||||
});
|
||||
|
||||
renderBarChart('chart-levels', levelCounts, {
|
||||
'Специалист': '#4caf50',
|
||||
'Профессионал': '#ff9800',
|
||||
'Эксперт': '#9c27b0'
|
||||
});
|
||||
|
||||
const sortedCities = Object.entries(cityCounts).sort((a, b) => b[1] - a[1]);
|
||||
renderBarChart('chart-cities', Object.fromEntries(sortedCities), '#1e3c72');
|
||||
|
||||
const sortedVendors = Object.entries(vendorCounts).sort((a, b) => b[1] - a[1]).slice(0, 8);
|
||||
renderBarChart('chart-vendors', Object.fromEntries(sortedVendors), '#2a5298');
|
||||
}
|
||||
|
||||
function renderBarChart(containerId, data, colorMap) {
|
||||
const container = document.getElementById(containerId);
|
||||
const max = Math.max(...Object.values(data), 1);
|
||||
const getColor = key => typeof colorMap === 'object' ? (colorMap[key] || '#1e3c72') : colorMap;
|
||||
|
||||
container.innerHTML = Object.entries(data).map(([key, val]) => `
|
||||
<div class="bar-row">
|
||||
<div class="bar-label">${key || 'Без города'}</div>
|
||||
<div class="bar-track">
|
||||
<div class="bar-fill" style="width: ${(val / max) * 100}%; background: ${getColor(key)}"></div>
|
||||
</div>
|
||||
<div class="bar-value">${val}</div>
|
||||
</div>
|
||||
`).join('');
|
||||
}
|
||||
|
||||
function renderTable() {
|
||||
const tbody = document.getElementById('table-body');
|
||||
const empty = document.getElementById('empty-state');
|
||||
|
||||
if (events.length === 0) {
|
||||
if (filteredData.length === 0) {
|
||||
tbody.innerHTML = '';
|
||||
empty.style.display = 'block';
|
||||
return;
|
||||
}
|
||||
|
||||
empty.style.display = 'none';
|
||||
events.sort((a, b) => {
|
||||
if (a.day !== b.day) return a.day - b.day;
|
||||
return a.time.localeCompare(b.time);
|
||||
});
|
||||
|
||||
tbody.innerHTML = events.map(e => `
|
||||
tbody.innerHTML = filteredData.map((d, i) => `
|
||||
<tr>
|
||||
<td><span class="day-badge day-${e.day}">${days[e.day]}</span></td>
|
||||
<td class="event-time">${e.time}</td>
|
||||
<td class="event-title">${escapeHtml(e.title)}</td>
|
||||
<td class="event-location">${escapeHtml(e.location || '—')}</td>
|
||||
<td class="event-location">${escapeHtml(e.notes || '—')}</td>
|
||||
<td class="actions">
|
||||
<button class="btn-edit" onclick="editEvent(${e.id})">✏️</button>
|
||||
<button class="btn-delete" onclick="deleteEvent(${e.id})">🗑️</button>
|
||||
</td>
|
||||
<td>${i + 1}</td>
|
||||
<td><span class="city-badge">${d.city}</span></td>
|
||||
<td>${escapeHtml(d.name || '—')}</td>
|
||||
<td>${escapeHtml(d.position || '—')}</td>
|
||||
<td>${escapeHtml(d.vendor || '—')}</td>
|
||||
<td>${escapeHtml(d.certificate || '—')}</td>
|
||||
<td><span class="level-badge level-${d.level}">${d.level}</span></td>
|
||||
</tr>
|
||||
`).join('');
|
||||
}
|
||||
|
||||
function updateStats() {
|
||||
const today = new Date().getDay();
|
||||
today = today === 0 ? 7 : today;
|
||||
|
||||
document.getElementById('stat-total').textContent = events.length;
|
||||
document.getElementById('stat-today').textContent = events.filter(e => e.day === today).length;
|
||||
document.getElementById('stat-week').textContent = events.length;
|
||||
|
||||
const uniqueDays = new Set(events.map(e => e.day)).size;
|
||||
document.getElementById('stat-days').textContent = uniqueDays;
|
||||
}
|
||||
|
||||
function escapeHtml(text) {
|
||||
const div = document.createElement('div');
|
||||
div.textContent = text;
|
||||
return div.innerHTML;
|
||||
}
|
||||
|
||||
function openModal() {
|
||||
document.getElementById('modal-title').textContent = 'Добавить событие';
|
||||
document.getElementById('event-form').reset();
|
||||
document.getElementById('event-id').value = '';
|
||||
editingId = null;
|
||||
document.getElementById('modal').classList.add('on');
|
||||
function exportCsv() {
|
||||
const head = ['№', 'Город', 'ФИО', 'Должность', 'Вендор', 'Сертификат', 'Уровень'];
|
||||
const body = filteredData.map((d, i) => [
|
||||
i + 1, d.city, d.name, d.position, d.vendor, d.certificate, d.level
|
||||
].map(v => '"' + String(v || '').replace(/"/g, '""') + '"').join(';'));
|
||||
const csv = '\uFEFF' + [head.join(';'), ...body].join('\n');
|
||||
const a = document.createElement('a');
|
||||
a.href = URL.createObjectURL(new Blob([csv], { type: 'text/csv' }));
|
||||
a.download = 'sertifikacii.csv';
|
||||
a.click();
|
||||
}
|
||||
|
||||
function closeModal() {
|
||||
document.getElementById('modal').classList.remove('on');
|
||||
}
|
||||
|
||||
function editEvent(id) {
|
||||
const e = events.find(ev => ev.id === id);
|
||||
if (!e) return;
|
||||
|
||||
editingId = id;
|
||||
document.getElementById('modal-title').textContent = 'Редактировать событие';
|
||||
document.getElementById('event-id').value = e.id;
|
||||
document.getElementById('event-title').value = e.title;
|
||||
document.getElementById('event-day').value = e.day;
|
||||
document.getElementById('event-time').value = e.time;
|
||||
document.getElementById('event-location').value = e.location || '';
|
||||
document.getElementById('event-notes').value = e.notes || '';
|
||||
document.getElementById('modal').classList.add('on');
|
||||
}
|
||||
|
||||
async function deleteEvent(id) {
|
||||
if (!confirm('Удалить это событие?')) return;
|
||||
await fetch('/api/events/' + id, { method: 'DELETE' });
|
||||
load();
|
||||
}
|
||||
|
||||
document.getElementById('event-form').addEventListener('submit', async (e) => {
|
||||
e.preventDefault();
|
||||
const data = {
|
||||
title: document.getElementById('event-title').value,
|
||||
day: parseInt(document.getElementById('event-day').value),
|
||||
time: document.getElementById('event-time').value,
|
||||
location: document.getElementById('event-location').value,
|
||||
notes: document.getElementById('event-notes').value
|
||||
};
|
||||
|
||||
if (editingId) {
|
||||
await fetch('/api/events/' + editingId, {
|
||||
method: 'PUT',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify(data)
|
||||
});
|
||||
} else {
|
||||
await fetch('/api/events', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify(data)
|
||||
});
|
||||
}
|
||||
|
||||
closeModal();
|
||||
load();
|
||||
});
|
||||
|
||||
document.getElementById('modal').addEventListener('click', (e) => {
|
||||
if (e.target.id === 'modal') closeModal();
|
||||
});
|
||||
document.getElementById('search').addEventListener('input', applyFilters);
|
||||
document.getElementById('filter-city').addEventListener('change', applyFilters);
|
||||
|
||||
load();
|
||||
</script>
|
||||
|
||||
10
package-lock.json
generated
Normal file
10
package-lock.json
generated
Normal file
@ -0,0 +1,10 @@
|
||||
{
|
||||
"name": "schedule-dashboard",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "schedule-dashboard"
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -36,6 +36,13 @@ http.createServer(async (req, res) => {
|
||||
return res.end(JSON.stringify(readData()));
|
||||
}
|
||||
|
||||
if (req.method === "PUT" && url === "/api/events") {
|
||||
const data = await body(req);
|
||||
writeData(data);
|
||||
res.writeHead(200, { "Content-Type": "application/json" });
|
||||
return res.end(JSON.stringify({ ok: true }));
|
||||
}
|
||||
|
||||
if (req.method === "POST" && url === "/api/events") {
|
||||
const event = await body(req);
|
||||
const data = readData();
|
||||
|
||||
Loading…
Reference in New Issue
Block a user