Files
Inv_web/templates/cabinets.html
2026-02-23 20:59:05 +03:00

200 lines
6.6 KiB
HTML
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
{% extends "base.html" %}
{% block body_class %}page-bg bg-cabinets{% endblock %}
{% block content %}
<style>
body.bg-cabinets {
background-color: #B3B3DA;
background-image:
linear-gradient(rgba(179, 179, 218, 0.75), rgba(179, 179, 218, 0.75)),
url('{{ url_for("static", filename="bg/bg_zdanie.png", v=1) }}');
background-size: auto 40vh;
}
.row-actions {
background: #f8f9fa;
}
.row-actions__inner {
max-height: 0;
opacity: 0;
transform: translateY(-6px);
transition: max-height 0.2s ease, opacity 0.2s ease, transform 0.2s ease;
overflow: hidden;
padding: 0 0.75rem;
}
.row-actions.show .row-actions__inner {
max-height: 60px;
opacity: 1;
transform: translateY(0);
}
.edit-modal {
position: fixed;
inset: 0;
background: rgba(15, 23, 32, 0.55);
display: none;
align-items: center;
justify-content: center;
z-index: 1050;
padding: 1rem;
}
.edit-modal.show {
display: flex;
}
.edit-modal__dialog {
background: #fff;
border-radius: 0.75rem;
width: min(720px, 100%);
max-height: 85vh;
overflow: auto;
}
.edit-modal__header {
display: flex;
align-items: center;
justify-content: space-between;
padding: 0.75rem 1rem;
border-bottom: 1px solid #e2e2e2;
}
.edit-modal__title {
margin: 0;
font-size: 1.05rem;
}
.edit-modal__footer {
display: flex;
justify-content: flex-end;
gap: 0.5rem;
padding: 0.75rem 1rem;
border-top: 1px solid #e2e2e2;
}
</style>
<h3>Кабинеты</h3>
{% if session.get('role') not in ('admin','storekeeper') %}
<div class="alert alert-secondary">Режим просмотра: изменения доступны только администратору.</div>
{% endif %}
{% if session.get('role') in ('admin','storekeeper') %}
<form method="post" action="/cabinets/add" class="row g-2 mb-3">
<div class="col-md-4">
<input name="building" class="form-control" placeholder="Здание (например: 1, А, Корпус 2)">
</div>
<div class="col-md-4">
<input name="cabinet" class="form-control" placeholder="Кабинет (например: 101, 2-14)">
</div>
<div class="col-md-2 d-grid">
<button class="btn btn-success">Добавить</button>
</div>
</form>
{% endif %}
{% for building, rows in grouped.items() %}
<h5 class="mt-3 mb-2">Здание: {{ building if building else 'Без здания' }}</h5>
<table class="table table-striped">
<tr><th>Кабинет</th></tr>
{% for row in rows %}
<tr class="js-cabinet-row"
data-id="{{ row.id }}"
data-building="{{ row.building }}"
data-cabinet="{{ row.cabinet }}">
<td>{{ row.cabinet }}</td>
</tr>
{% endfor %}
</table>
{% endfor %}
{% if session.get('role') in ('admin','storekeeper') %}
<div class="edit-modal" id="cabinetEditModal" aria-hidden="true">
<div class="edit-modal__dialog">
<div class="edit-modal__header">
<h4 class="edit-modal__title">Редактирование кабинета</h4>
<button type="button" class="btn btn-sm btn-outline-secondary" data-modal-close>Закрыть</button>
</div>
<form method="post" action="/cabinets/edit" id="cabinetEditForm">
<input type="hidden" name="id" id="cabinetModalId">
<div class="row g-2 px-3 py-3">
<div class="col-md-6">
<input name="building" id="cabinetModalBuilding" class="form-control" placeholder="Здание">
</div>
<div class="col-md-6">
<input name="cabinet" id="cabinetModalCabinet" class="form-control" placeholder="Кабинет">
</div>
</div>
<div class="edit-modal__footer">
<button type="button" class="btn btn-outline-secondary" data-modal-close>Отмена</button>
<button class="btn btn-primary">Сохранить</button>
</div>
</form>
</div>
</div>
{% endif %}
<script>
(function() {
const canEdit = {{ 'true' if session.get('role') in ('admin','storekeeper') else 'false' }};
if (!canEdit) return;
const rows = document.querySelectorAll('.js-cabinet-row');
if (!rows.length) return;
const modal = document.getElementById('cabinetEditModal');
if (!modal) return;
const fields = {
id: document.getElementById('cabinetModalId'),
building: document.getElementById('cabinetModalBuilding'),
cabinet: document.getElementById('cabinetModalCabinet'),
};
function closeModal() {
modal.classList.remove('show');
modal.setAttribute('aria-hidden', 'true');
}
function openModal() {
modal.classList.add('show');
modal.setAttribute('aria-hidden', 'false');
}
modal.addEventListener('click', (e) => {
if (e.target === modal || e.target.hasAttribute('data-modal-close')) {
closeModal();
}
});
function fillModalFromRow(row) {
fields.id.value = row.getAttribute('data-id') || '';
fields.building.value = row.getAttribute('data-building') || '';
fields.cabinet.value = row.getAttribute('data-cabinet') || '';
return true;
}
function showActionRow(row) {
const existing = row.parentElement.querySelector('.row-actions');
if (existing) existing.remove();
const rowId = row.getAttribute('data-id') || '';
const actionRow = document.createElement('tr');
actionRow.className = 'row-actions';
actionRow.innerHTML = `<td colspan="2">
<div class="row-actions__inner">
<button type="button" class="btn btn-sm btn-outline-primary js-open-cabinet-modal">Редактировать</button>
<form method="post" action="/cabinets/delete" class="d-inline ms-2" onsubmit="return confirm('Удалить кабинет?')">
<input type="hidden" name="id" value="${rowId}">
<button class="btn btn-sm btn-outline-danger" type="submit">Удалить</button>
</form>
</div>
</td>`;
row.insertAdjacentElement('afterend', actionRow);
const btn = actionRow.querySelector('.js-open-cabinet-modal');
btn.addEventListener('click', () => {
if (fillModalFromRow(row)) openModal();
});
requestAnimationFrame(() => actionRow.classList.add('show'));
}
rows.forEach((row) => {
row.addEventListener('click', (e) => {
if (e.target.closest('button, input, select, textarea, a')) return;
showActionRow(row);
});
row.addEventListener('dblclick', (e) => {
if (e.target.closest('button, input, select, textarea, a')) return;
if (fillModalFromRow(row)) openModal();
});
});
})();
</script>
{% endblock %}