Добавлена страница создание кафедры/специальности
This commit is contained in:
6
.agents/rules/1.md
Normal file
6
.agents/rules/1.md
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
---
|
||||||
|
trigger: always_on
|
||||||
|
glob:
|
||||||
|
description:
|
||||||
|
---
|
||||||
|
|
||||||
29
.agents/skills/SKILL.md
Normal file
29
.agents/skills/SKILL.md
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
Контекст проекта:
|
||||||
|
|
||||||
|
Backend: Java 17, Spring Framework. Учитывай возможности этой версии языка и стандарты фреймворка.
|
||||||
|
|
||||||
|
Frontend: HTML, CSS, JavaScript.
|
||||||
|
|
||||||
|
Правила написания кода и комментариев:
|
||||||
|
|
||||||
|
Проверка: Перед написанием кода изучи проект, его структуру и используемые технологии. Не предлагай решения, которые не соответствуют текущей архитектуре или стеку.
|
||||||
|
|
||||||
|
Язык: Все комментарии и объяснения должны быть строго на русском языке.
|
||||||
|
|
||||||
|
Комментирование кода: Оставляй комментарии, объясняющие, за что отвечает та или иная часть кода. Перед крупными или смысловыми блоками обязательно ставь поясняющие метки (например: ``, /* таблица subjects */, // логика обработки subjects).
|
||||||
|
|
||||||
|
Обоснование решений: При написании нового кода кратко и максимально понятно объясняй, почему мы используем именно это решение, а не другое.
|
||||||
|
|
||||||
|
Современные подходы: На фронтенде используй самые современные и актуальные подходы (например, Flexbox, CSS Grid, семантические теги).
|
||||||
|
|
||||||
|
Правила работы с ошибками (Обучающий режим):
|
||||||
|
|
||||||
|
Если ты находишь ошибку в моем коде, не пиши сразу готовый исправленный код.
|
||||||
|
|
||||||
|
Дай мне точную подсказку, чтобы я мог сам найти и исправить баг (например: "У тебя не закрыт тег в 15 строке", "Ты забыл поставить аннотацию в контроллере Spring" или "Проверь отступы в таком-то классе"). Моя цель — научиться.
|
||||||
|
|
||||||
|
Правила работы с дизайном (UI/UX):
|
||||||
|
|
||||||
|
Перед добавлением новых стилей всегда сначала изучай, какие стили уже используются в проекте, чтобы сохранять единообразие.
|
||||||
|
|
||||||
|
Если ты видишь, что текущий дизайн откровенно плох, нелогичен или устарел — смело предлагай свои идеи по улучшению (цветовая палитра, отступы, шрифты). Я открыт к предложениям по улучшению визуала.
|
||||||
11
frontend/admin/css/departments-data.css
Normal file
11
frontend/admin/css/departments-data.css
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
/* Стили для формы создания кафедр и специальностей */
|
||||||
|
.departments-data-icon {
|
||||||
|
margin-right: 0.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
#departments-tbody .loading-row,
|
||||||
|
#specialties-tbody .loading-row {
|
||||||
|
text-align: center;
|
||||||
|
color: var(--text-muted);
|
||||||
|
padding: 2rem;
|
||||||
|
}
|
||||||
@@ -15,6 +15,7 @@
|
|||||||
<link rel="stylesheet" href="css/components.css">
|
<link rel="stylesheet" href="css/components.css">
|
||||||
<link rel="stylesheet" href="css/modals.css">
|
<link rel="stylesheet" href="css/modals.css">
|
||||||
<link rel="stylesheet" href="css/department.css">
|
<link rel="stylesheet" href="css/department.css">
|
||||||
|
<link rel="stylesheet" href="css/departments-data.css">
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
@@ -58,6 +59,13 @@
|
|||||||
</svg>
|
</svg>
|
||||||
Кафедра
|
Кафедра
|
||||||
</a>
|
</a>
|
||||||
|
<a href="#" class="nav-item" data-tab="departments-data">
|
||||||
|
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
||||||
|
<path d="M16 4h2a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2h2"></path>
|
||||||
|
<rect x="8" y="2" width="8" height="4" rx="1" ry="1"></rect>
|
||||||
|
</svg>
|
||||||
|
Создание кафедры/специальности
|
||||||
|
</a>
|
||||||
<a href="#" class="nav-item" data-tab="groups">
|
<a href="#" class="nav-item" data-tab="groups">
|
||||||
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"
|
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"
|
||||||
stroke-linecap="round" stroke-linejoin="round">
|
stroke-linecap="round" stroke-linejoin="round">
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ import { initSubjects } from './views/subjects.js';
|
|||||||
import {initSchedule} from "./views/schedule.js";
|
import {initSchedule} from "./views/schedule.js";
|
||||||
import {initDatabase} from "./views/database.js";
|
import {initDatabase} from "./views/database.js";
|
||||||
import {initDepartment} from "./views/department.js";
|
import {initDepartment} from "./views/department.js";
|
||||||
|
import {initDepartmentsData} from "./views/departments-data.js";
|
||||||
|
|
||||||
// Configuration
|
// Configuration
|
||||||
const ROUTES = {
|
const ROUTES = {
|
||||||
@@ -24,6 +25,7 @@ const ROUTES = {
|
|||||||
schedule: { title: 'Расписание занятий', file: 'views/schedule.html', init: initSchedule },
|
schedule: { title: 'Расписание занятий', file: 'views/schedule.html', init: initSchedule },
|
||||||
database: { title: 'База данных', file: 'views/database.html', init: initDatabase },
|
database: { title: 'База данных', file: 'views/database.html', init: initDatabase },
|
||||||
department: { title: 'Кафедры', file: 'views/department.html', init: initDepartment },
|
department: { title: 'Кафедры', file: 'views/department.html', init: initDepartment },
|
||||||
|
'departments-data': { title: 'Создание кафедры/специальности', file: 'views/departments-data.html', init: initDepartmentsData },
|
||||||
};
|
};
|
||||||
|
|
||||||
let currentTab = null;
|
let currentTab = null;
|
||||||
|
|||||||
103
frontend/admin/js/views/departments-data.js
Normal file
103
frontend/admin/js/views/departments-data.js
Normal file
@@ -0,0 +1,103 @@
|
|||||||
|
import { api } from '../api.js';
|
||||||
|
import { escapeHtml, showAlert, hideAlert } from '../utils.js';
|
||||||
|
|
||||||
|
export async function initDepartmentsData() {
|
||||||
|
const deptTbody = document.getElementById('departments-tbody');
|
||||||
|
const specTbody = document.getElementById('specialties-tbody');
|
||||||
|
|
||||||
|
const createDeptForm = document.getElementById('create-department-form');
|
||||||
|
const createSpecForm = document.getElementById('create-specialty-form');
|
||||||
|
|
||||||
|
let departments = [];
|
||||||
|
let specialties = [];
|
||||||
|
|
||||||
|
async function loadData() {
|
||||||
|
// Load Departments
|
||||||
|
try {
|
||||||
|
departments = await api.get('/api/departments');
|
||||||
|
renderDepartments();
|
||||||
|
} catch (e) {
|
||||||
|
deptTbody.innerHTML = '<tr><td colspan="3" class="loading-row">-</td></tr>';
|
||||||
|
}
|
||||||
|
|
||||||
|
// Load Specialties
|
||||||
|
try {
|
||||||
|
specialties = await api.get('/api/specialties');
|
||||||
|
renderSpecialties();
|
||||||
|
} catch (e) {
|
||||||
|
specTbody.innerHTML = '<tr><td colspan="3" class="loading-row">-</td></tr>';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function renderDepartments() {
|
||||||
|
if (!departments || !departments.length) {
|
||||||
|
deptTbody.innerHTML = '<tr><td colspan="3" class="loading-row">-</td></tr>';
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
deptTbody.innerHTML = departments.map(d => `
|
||||||
|
<tr>
|
||||||
|
<td>${d.id}</td>
|
||||||
|
<td>${escapeHtml(d.departmentName || d.name)}</td>
|
||||||
|
<td>${escapeHtml(String(d.departmentCode || d.code))}</td>
|
||||||
|
</tr>
|
||||||
|
`).join('');
|
||||||
|
}
|
||||||
|
|
||||||
|
function renderSpecialties() {
|
||||||
|
if (!specialties || !specialties.length) {
|
||||||
|
specTbody.innerHTML = '<tr><td colspan="3" class="loading-row">-</td></tr>';
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
specTbody.innerHTML = specialties.map(s => `
|
||||||
|
<tr>
|
||||||
|
<td>${s.id}</td>
|
||||||
|
<td>${escapeHtml(s.specialityName || s.name)}</td>
|
||||||
|
<td>${escapeHtml(s.specialityCode || s.specialtyCode || s.specialty_code)}</td>
|
||||||
|
</tr>
|
||||||
|
`).join('');
|
||||||
|
}
|
||||||
|
|
||||||
|
createDeptForm.addEventListener('submit', async (e) => {
|
||||||
|
e.preventDefault();
|
||||||
|
hideAlert('create-dept-alert');
|
||||||
|
const name = document.getElementById('dept-name').value.trim();
|
||||||
|
const code = document.getElementById('dept-code').value.trim();
|
||||||
|
|
||||||
|
if (!name || !code) {
|
||||||
|
showAlert('create-dept-alert', 'Заполните все поля', 'error');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
await api.post('/api/departments', { departmentName: name, departmentCode: Number(code) });
|
||||||
|
showAlert('create-dept-alert', `Кафедра "${name}" создана`, 'success');
|
||||||
|
createDeptForm.reset();
|
||||||
|
loadData();
|
||||||
|
} catch (error) {
|
||||||
|
showAlert('create-dept-alert', error.message || 'Ошибка создания кафедры', 'error');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
createSpecForm.addEventListener('submit', async (e) => {
|
||||||
|
e.preventDefault();
|
||||||
|
hideAlert('create-spec-alert');
|
||||||
|
const name = document.getElementById('spec-name').value.trim();
|
||||||
|
const code = document.getElementById('spec-code').value.trim();
|
||||||
|
|
||||||
|
if (!name || !code) {
|
||||||
|
showAlert('create-spec-alert', 'Заполните все поля', 'error');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
await api.post('/api/specialties', { specialityName: name, specialityCode: code });
|
||||||
|
showAlert('create-spec-alert', `Специальность "${name}" создана`, 'success');
|
||||||
|
createSpecForm.reset();
|
||||||
|
loadData();
|
||||||
|
} catch (error) {
|
||||||
|
showAlert('create-spec-alert', error.message || 'Ошибка создания специальности', 'error');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
loadData();
|
||||||
|
}
|
||||||
80
frontend/admin/views/departments-data.html
Normal file
80
frontend/admin/views/departments-data.html
Normal file
@@ -0,0 +1,80 @@
|
|||||||
|
<!-- ===== Departments and Specialties Tab ===== -->
|
||||||
|
<div class="card create-card">
|
||||||
|
<h2>Создание кафедры</h2>
|
||||||
|
<form id="create-department-form">
|
||||||
|
<div class="form-row">
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="dept-name">Название кафедры</label>
|
||||||
|
<input type="text" id="dept-name" placeholder="Например: Кафедра ИБ" required>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="dept-code">Код кафедры</label>
|
||||||
|
<input type="number" id="dept-code" placeholder="Например: 1" required>
|
||||||
|
</div>
|
||||||
|
<button type="submit" class="btn-primary">Создать</button>
|
||||||
|
</div>
|
||||||
|
<div class="form-alert" id="create-dept-alert" role="alert"></div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="card">
|
||||||
|
<div class="card-header-row">
|
||||||
|
<h2>Кафедры</h2>
|
||||||
|
</div>
|
||||||
|
<div class="table-wrap">
|
||||||
|
<table id="departments-table">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>ID</th>
|
||||||
|
<th>Название</th>
|
||||||
|
<th>Код</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody id="departments-tbody">
|
||||||
|
<tr>
|
||||||
|
<td colspan="3" class="loading-row">Загрузка...</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="card create-card">
|
||||||
|
<h2>Создание специальности</h2>
|
||||||
|
<form id="create-specialty-form">
|
||||||
|
<div class="form-row">
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="spec-name">Название специальности</label>
|
||||||
|
<input type="text" id="spec-name" placeholder="Например: Программная инженерия" required>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="spec-code">Код специальности</label>
|
||||||
|
<input type="text" id="spec-code" placeholder="Например: 09.03.04" required>
|
||||||
|
</div>
|
||||||
|
<button type="submit" class="btn-primary">Создать</button>
|
||||||
|
</div>
|
||||||
|
<div class="form-alert" id="create-spec-alert" role="alert"></div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="card">
|
||||||
|
<div class="card-header-row">
|
||||||
|
<h2>Специальности</h2>
|
||||||
|
</div>
|
||||||
|
<div class="table-wrap">
|
||||||
|
<table id="specialties-table">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>ID</th>
|
||||||
|
<th>Название</th>
|
||||||
|
<th>Код специальности</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody id="specialties-tbody">
|
||||||
|
<tr>
|
||||||
|
<td colspan="3" class="loading-row">Загрузка...</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
Reference in New Issue
Block a user