/
Coderdev
/
web-nodejs-labs
Обзор
Документация
Войти
/
Coderdev
/
web-nodejs-labs
Код
Запросы
0
Задачи
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
public/lab10/task2/index.html
15 строк
8 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 Task2</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 2 · Расписание</h1><p class="muted">Фильтры, добавление расписания, добавление новых дисциплин и преподавателей.</p></div><div class="grid" style="margin-top:18px"><div class="panel"><h2 style="margin-top:0">Фильтры</h2><select id="weekFilter"><option value="">Все недели</option></select><select id="groupFilter"><option value="">Все группы</option></select><select id="dayFilter"><option value="">Все дни</option></select><select id="roomFilter"><option value="">Все аудитории</option></select><select id="subjectFilter"><option value="">Все дисциплины</option></select><select id="teacherFilter"><option value="">Все преподаватели</option></select><select id="typeFilter"><option value="">Все типы</option></select><button id="applyBtn">Применить</button><button id="resetBtn" class="gray" style="margin-top:10px">Сбросить</button><hr style="border-color:#25314d;margin:18px 0"><h2>Новые справочники</h2><input id="newSubjectInput" placeholder="Название дисциплины"><button id="addSubjectBtn">Добавить дисциплину</button><input id="newTeacherInput" style="margin-top:10px" placeholder="ФИО преподавателя"><button id="addTeacherBtn">Добавить преподавателя</button><hr style="border-color:#25314d;margin:18px 0"><h2>Добавить / изменить расписание</h2><input id="editId" placeholder="ID для редактирования"><select id="weekInput"></select><select id="groupInput"></select><select id="dayInput"></select><input id="lessonInput" type="number" placeholder="Номер пары"><select id="subjectInput"></select><select id="typeInput"></select><select id="teacherInput"></select><select id="roomInput"></select><button id="saveBtn">Сохранить</button></div><div class="panel"><h2 style="margin-top:0">Итоговое расписание</h2><div id="tableBox">Загрузка...</div></div></div><script> const API='/api/lab10';let dict={}; function fill(sel,arr,label,value='id',text='name'){document.getElementById(sel).innerHTML=`<option value="">${label}</option>`+arr.map(x=>`<option value="${x[value]}">${x[text]}</option>`).join('')} function fillReq(sel,arr,text='name'){document.getElementById(sel).innerHTML=arr.map(x=>`<option value="${x.id}">${x[text]}</option>`).join('')} async function loadDict(){const res=await fetch(API+'/task2/dictionaries');dict=await res.json();fill('weekFilter',dict.weeks,'Все недели');fill('groupFilter',dict.groups,'Все группы');fill('dayFilter',dict.days,'Все дни');fill('roomFilter',dict.rooms,'Все аудитории');fill('subjectFilter',dict.subjects,'Все дисциплины');fill('teacherFilter',dict.teachers,'Все преподаватели','id','fullname');fill('typeFilter',dict.lessonTypes,'Все типы');fillReq('weekInput',dict.weeks);fillReq('groupInput',dict.groups);fillReq('dayInput',dict.days);fillReq('roomInput',dict.rooms);fillReq('subjectInput',dict.subjects);fillReq('teacherInput',dict.teachers,'fullname');fillReq('typeInput',dict.lessonTypes)} function qs(){const p=new URLSearchParams();[['week','weekFilter'],['group','groupFilter'],['day','dayFilter'],['room','roomFilter'],['subject','subjectFilter'],['teacher','teacherFilter'],['lessonType','typeFilter']].forEach(([k,id])=>{const v=document.getElementById(id).value;if(v)p.set(k,v)});return p.toString()} async function loadSchedule(){const res=await fetch(API+'/task2/schedule?'+qs());const data=await res.json();document.getElementById('tableBox').innerHTML='<table><thead><tr><th>ID</th><th>Неделя</th><th>Группа</th><th>День</th><th>Пара</th><th>Дисциплина</th><th>Тип</th><th>Преподаватель</th><th>Аудитория</th><th></th></tr></thead><tbody>'+data.map(r=>`<tr><td>${r.id}</td><td>${r.week}</td><td>${r.group_name}</td><td>${r.day_name}</td><td>${r.lesson_number}</td><td>${r.subject}</td><td>${r.lesson_type}</td><td>${r.teacher}</td><td>${r.room}</td><td><button onclick="editRow(${r.id})" class="gray">Ред.</button> <button onclick="deleteRow(${r.id})" style="background:#dc2626">Удал.</button></td></tr>`).join('')+'</tbody></table>'} function editRow(id){document.getElementById('editId').value=id;alert('Введи новые значения в форму слева и нажми Сохранить')} async function deleteRow(id){if(!confirm('Удалить запись?'))return;await fetch(API+'/task2/schedule/'+id,{method:'DELETE'});loadSchedule()} function payload(){return {week_id:Number(weekInput.value),group_id:Number(groupInput.value),day_id:Number(dayInput.value),lesson_number:Number(lessonInput.value),subject_id:Number(subjectInput.value),lesson_type_id:Number(typeInput.value),teacher_id:Number(teacherInput.value),room_id:Number(roomInput.value)}} document.getElementById('saveBtn').onclick=async()=>{const id=document.getElementById('editId').value.trim();await fetch(API+'/task2/schedule'+(id?'/'+id:''),{method:id?'PUT':'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify(payload())});document.getElementById('editId').value='';loadSchedule()}; document.getElementById('addSubjectBtn').onclick=async()=>{const name=document.getElementById('newSubjectInput').value.trim();if(!name)return alert('Введите название дисциплины');await fetch(API+'/task2/subjects',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({name})});document.getElementById('newSubjectInput').value='';await loadDict();await loadSchedule()}; document.getElementById('addTeacherBtn').onclick=async()=>{const fullname=document.getElementById('newTeacherInput').value.trim();if(!fullname)return alert('Введите ФИО преподавателя');await fetch(API+'/task2/teachers',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({fullname})});document.getElementById('newTeacherInput').value='';await loadDict();await loadSchedule()}; document.getElementById('applyBtn').onclick=loadSchedule;document.getElementById('resetBtn').onclick=()=>{['weekFilter','groupFilter','dayFilter','roomFilter','subjectFilter','teacherFilter','typeFilter'].forEach(id=>document.getElementById(id).value='');loadSchedule()};loadDict().then(loadSchedule); </script></body></html>