admin without rights

This commit is contained in:
Владимир
2026-01-09 14:08:08 +00:00
parent f5c68bf0c7
commit 36084ba590
9 changed files with 353 additions and 433 deletions

View File

@@ -171,260 +171,21 @@
</div>
<script>
let token = localStorage.getItem('token');
let selectedEmployeeId = null;
let selectedDate = null;
let currentMonth = new Date().getMonth();
let currentYear = new Date().getFullYear();
let employees = [];
let intervals = [];
const token = localStorage.getItem('auth_token');
if (!token) {
window.location.href = '/register-login.html';
}
// Проверка авторизации
if (!token) {
window.location.href = 'register-login.html';
}
// Загрузка сотрудников при старте
window.onload = async function() {
await loadEmployees();
};
// Загрузить список сотрудников
async function loadEmployees() {
try {
const response = await fetch('/api/admin/users?role=employee', {
headers: { 'Authorization': `Bearer ${token}` }
});
if (response.ok) {
const allUsers = await response.json();
employees = allUsers.filter(user => user.role === 'employee' || user.role === 'admin');
const select = document.getElementById('employeeSelect');
select.innerHTML = '<option value="">— Выберите сотрудника —</option>';
for (let employee of employees) {
select.innerHTML += `<option value="${employee.id}">${employee.name}</option>`;
}
}
} catch (error) {
alert('Ошибка загрузки сотрудников');
}
}
// При смене сотрудника
function loadEmployeeSchedule() {
const select = document.getElementById('employeeSelect');
selectedEmployeeId = select.value;
if (selectedEmployeeId) {
document.getElementById('employeeInfo').style.display = 'block';
document.getElementById('selectedEmployeeId').textContent = selectedEmployeeId;
document.getElementById('selectedEmployeeName').textContent = select.options[select.selectedIndex].text;
document.getElementById('calendarSection').style.display = 'block';
renderCalendar();
} else {
document.getElementById('calendarSection').style.display = 'none';
document.getElementById('timeIntervalsSection').style.display = 'none';
document.getElementById('employeeInfo').style.display = 'none';
}
}
// Простой календарь
function renderCalendar() {
const calendarDays = document.getElementById('calendarDays');
const monthYear = document.getElementById('monthYear');
monthYear.textContent = new Date(currentYear, currentMonth).toLocaleDateString('ru', {
year: 'numeric', month: 'long'
});
calendarDays.innerHTML = '';
const firstDay = new Date(currentYear, currentMonth, 1).getDay();
const daysInMonth = new Date(currentYear, currentMonth + 1, 0).getDate();
let dayCounter = 1 - firstDay + 1;
for (let i = 0; i < 42; i++) {
const day = document.createElement('div');
day.className = 'calendar-day';
if (dayCounter < 1) {
day.textContent = new Date(currentYear, currentMonth, 0).getDate() + dayCounter;
day.classList.add('other-month');
dayCounter++;
} else if (dayCounter <= daysInMonth) {
const dateStr = `${currentYear}-${String(currentMonth + 1).padStart(2, '0')}-${String(dayCounter).padStart(2, '0')}`;
day.textContent = dayCounter;
day.onclick = () => selectDate(dateStr);
dayCounter++;
} else {
day.textContent = dayCounter - daysInMonth;
day.classList.add('other-month');
dayCounter++;
}
calendarDays.appendChild(day);
}
}
function selectDate(date) {
selectedDate = date;
document.querySelectorAll('.calendar-day').forEach(day => day.classList.remove('selected'));
event.target.classList.add('selected');
document.getElementById('selectedDateTitle').textContent = `Интервалы на ${new Date(date).toLocaleDateString('ru')}`;
loadIntervals();
}
function prevMonth() {
currentMonth--;
if (currentMonth < 0) {
currentMonth = 11;
currentYear--;
}
renderCalendar();
}
function nextMonth() {
currentMonth++;
if (currentMonth > 11) {
currentMonth = 0;
currentYear++;
}
renderCalendar();
}
// Загрузить интервалы для даты
async function loadIntervals() {
try {
document.getElementById('timeIntervalsSection').style.display = 'block';
const response = await fetch(`/api/admin/availabilities?employee_id=${selectedEmployeeId}&date=${selectedDate}`, {
headers: { 'Authorization': `Bearer ${token}` }
});
intervals = await response.json();
renderIntervals();
} catch (error) {
intervals = [];
renderIntervals();
}
}
// Отобразить интервалы
function renderIntervals() {
const container = document.getElementById('intervalsList');
if (intervals.length === 0) {
container.innerHTML = '<div class="no-intervals">Нет интервалов на эту дату</div>';
return;
}
container.innerHTML = '';
for (let interval of intervals) {
const item = document.createElement('div');
item.className = 'interval-item';
item.innerHTML = `
<div style="display: flex; justify-content: space-between; align-items: center;">
<strong>${interval.starttime.slice(0,5)} - ${interval.endtime.slice(0,5)}</strong>
<div>
<label style="margin-right: 15px;">
<input type="checkbox" ${interval.isavailable ? '' : 'checked'} onchange="updateInterval(${interval.id}, this.checked)">
Недоступен
</label>
<button class="delete-interval" onclick="deleteInterval(${interval.id})" title="Удалить">×</button>
</div>
</div>
`;
container.appendChild(item);
}
}
// Добавить интервал
async function addInterval(event) {
event.preventDefault();
const startTime = document.getElementById('startTime').value;
const endTime = document.getElementById('endTime').value;
const isUnavailable = document.getElementById('isUnavailable').checked;
if (!startTime || !endTime) {
alert('Заполните время начала и окончания');
return;
}
try {
const response = await fetch('/api/admin/availabilities', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${token}`
},
body: JSON.stringify({
employee_id: selectedEmployeeId,
date: selectedDate,
starttime: startTime + ':00',
endtime: endTime + ':00',
isavailable: !isUnavailable
})
});
if (response.ok) {
document.getElementById('startTime').value = '';
document.getElementById('endTime').value = '';
document.getElementById('isUnavailable').checked = false;
loadIntervals();
}
} catch (error) {
alert('Ошибка добавления интервала');
}
}
// Обновить доступность
async function updateInterval(id, isAvailable) {
try {
const response = await fetch(`/api/admin/availabilities/${id}`, {
method: 'PUT',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${token}`
},
body: JSON.stringify({ isavailable: isAvailable })
});
if (!response.ok) {
alert('Ошибка обновления');
loadIntervals(); // Вернуть как было
}
} catch (error) {
alert('Ошибка сети');
loadIntervals();
}
}
// Удалить интервал
async function deleteInterval(id) {
if (confirm('Удалить интервал?')) {
try {
const response = await fetch(`/api/admin/availabilities/${id}`, {
method: 'DELETE',
headers: { 'Authorization': `Bearer ${token}` }
});
if (response.ok) {
loadIntervals();
}
} catch (error) {
alert('Ошибка удаления');
}
}
}
function logout() {
localStorage.removeItem('token');
window.location.href = 'index.html';
}
fetch('/api/admin/availabilities', {
headers: { 'Authorization': 'Bearer ' + token }
})
.then(r => r.json())
.then(data => {
const list = document.getElementById('schedule-list');
data.forEach(avail => {
list.innerHTML += `<p>${avail.employee_id} — ${avail.date} ${avail.starttime} - ${avail.endtime}</p>`;
});
});
</script>
</body>
</html>