187 lines
8.8 KiB
HTML
187 lines
8.8 KiB
HTML
{% extends "base.html" %}
|
||
|
||
{% block title %}Телефоны и службы - МКД ЛенКом 37{% endblock %}
|
||
{% block nav_phones %}active{% endblock %}
|
||
|
||
{% block extra_style %}
|
||
.service-image-preview { max-width: 120px; max-height: 80px; object-fit: contain; border: 1px solid var(--border-light); }
|
||
{% endblock %}
|
||
|
||
{% block content %}
|
||
<div class="mb-3">
|
||
<h4 class="mb-1" style="font-size: 16px; font-weight: bold;">Телефоны экстренных и обслуживающих служб</h4>
|
||
<div class="small text-muted">Справочник полезных контактов, аварийных служб и мастеров для жителей дома</div>
|
||
</div>
|
||
|
||
<!-- Добавить службу -->
|
||
<div class="card mb-3">
|
||
<div class="card-header">
|
||
<i class="bi bi-plus-circle"></i> ДОБАВЛЕНИЕ НОВОЙ СЛУЖБЫ
|
||
</div>
|
||
<div class="card-body">
|
||
<form id="addServiceForm" class="row g-2 align-items-center">
|
||
<div class="col-md-3">
|
||
<input type="text" class="form-control" id="serviceName" placeholder="Название службы" required>
|
||
</div>
|
||
<div class="col-md-2">
|
||
<input type="text" class="form-control" id="servicePhone" placeholder="Телефон" required>
|
||
</div>
|
||
<div class="col-md-2">
|
||
<select class="form-select" id="serviceCategory">
|
||
<option value="emergency">Экстренные службы</option>
|
||
<option value="utility" selected>ЖКХ и аварийные</option>
|
||
<option value="masters">Мастера и ремонт</option>
|
||
<option value="police">Полиция и охрана</option>
|
||
<option value="other">Прочие контакты</option>
|
||
</select>
|
||
</div>
|
||
<div class="col-md-3">
|
||
<input type="text" class="form-control" id="serviceDesc" placeholder="Описание / часы работы">
|
||
</div>
|
||
<div class="col-md-2">
|
||
<button type="submit" class="btn-unix btn-unix-primary w-100">Добавить</button>
|
||
</div>
|
||
</form>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Загрузить картинку -->
|
||
<div class="card mb-3">
|
||
<div class="card-header">
|
||
<i class="bi bi-image"></i> ЗАГРУЗКА ИЗОБРАЖЕНИЯ ДЛЯ КАТЕГОРИИ
|
||
</div>
|
||
<div class="card-body">
|
||
<form id="uploadImageForm" class="row g-2 align-items-center" enctype="multipart/form-data">
|
||
<div class="col-md-3">
|
||
<select class="form-select" id="imageCategory" required>
|
||
<option value="emergency">Экстренные службы</option>
|
||
<option value="utility" selected>ЖКХ и аварийные</option>
|
||
<option value="masters">Мастера и ремонт</option>
|
||
<option value="police">Полиция и охрана</option>
|
||
<option value="other">Прочие контакты</option>
|
||
</select>
|
||
</div>
|
||
<div class="col-md-5">
|
||
<input type="file" class="form-control" id="imageFile" accept="image/*" required>
|
||
</div>
|
||
<div class="col-md-4">
|
||
<button type="submit" class="btn-unix w-100">Загрузить картинку</button>
|
||
</div>
|
||
</form>
|
||
<div id="uploadResult" class="mt-2"></div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Список служб -->
|
||
<div class="card">
|
||
<div class="card-header">СПИСОК КОНТАКТОВ В БАЗЕ ДАННЫХ</div>
|
||
<div class="card-body p-0">
|
||
<div class="table-responsive">
|
||
<table class="table mb-0">
|
||
<thead>
|
||
<tr>
|
||
<th style="width: 150px;">Категория</th>
|
||
<th>Название</th>
|
||
<th style="width: 160px;">Телефон</th>
|
||
<th>Описание</th>
|
||
<th style="width: 130px;">Изображение</th>
|
||
<th class="text-end" style="width: 90px;">Удалить</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
{% for service in services %}
|
||
<tr>
|
||
<td>
|
||
{% if service.category == 'emergency' %}
|
||
<span class="badge-status badge-danger">Экстренные</span>
|
||
{% elif service.category == 'utility' %}
|
||
<span class="badge-status badge-warning">ЖКХ</span>
|
||
{% elif service.category == 'masters' %}
|
||
<span class="badge-status badge-success">Мастера</span>
|
||
{% elif service.category == 'police' %}
|
||
<span class="badge-status badge-info">Полиция</span>
|
||
{% else %}
|
||
<span class="badge-status">Другое</span>
|
||
{% endif %}
|
||
</td>
|
||
<td><b>{{ service.name }}</b></td>
|
||
<td><a href="tel:{{ service.phone }}"><b>{{ service.phone }}</b></a></td>
|
||
<td>{{ service.description or '—' }}</td>
|
||
<td>
|
||
{% if service.image_path %}
|
||
<img src="/static/service_images/{{ service.image_path.split('/')[-1] }}"
|
||
class="service-image-preview" alt="Превью">
|
||
{% else %}
|
||
<span class="text-muted small">Нет</span>
|
||
{% endif %}
|
||
</td>
|
||
<td class="text-end">
|
||
<button class="btn-unix" onclick="deleteService({{ service.service_id }})">
|
||
<i class="bi bi-trash"></i>
|
||
</button>
|
||
</td>
|
||
</tr>
|
||
{% else %}
|
||
<tr>
|
||
<td colspan="6" class="text-center text-muted py-3">Службы пока не добавлены</td>
|
||
</tr>
|
||
{% endfor %}
|
||
</tbody>
|
||
</table>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<script>
|
||
document.getElementById('addServiceForm').addEventListener('submit', async (e) => {
|
||
e.preventDefault();
|
||
const data = {
|
||
name: document.getElementById('serviceName').value,
|
||
phone: document.getElementById('servicePhone').value,
|
||
category: document.getElementById('serviceCategory').value,
|
||
description: document.getElementById('serviceDesc').value
|
||
};
|
||
const r = await fetch('/api/service/add', {
|
||
method: 'POST', headers: {'Content-Type': 'application/json'},
|
||
body: JSON.stringify(data)
|
||
});
|
||
const result = await r.json();
|
||
if (result.success) { alert('Служба добавлена'); location.reload(); }
|
||
else { alert('Ошибка: ' + (result.error || 'Неизвестная')); }
|
||
});
|
||
|
||
document.getElementById('uploadImageForm').addEventListener('submit', async (e) => {
|
||
e.preventDefault();
|
||
const formData = new FormData();
|
||
formData.append('category', document.getElementById('imageCategory').value);
|
||
formData.append('file', document.getElementById('imageFile').files[0]);
|
||
|
||
const resultDiv = document.getElementById('uploadResult');
|
||
resultDiv.innerHTML = '<div class="alert alert-info py-1 small">Загрузка...</div>';
|
||
|
||
try {
|
||
const r = await fetch('/api/service/upload_image', {
|
||
method: 'POST',
|
||
body: formData
|
||
});
|
||
const result = await r.json();
|
||
|
||
if (result.success) {
|
||
resultDiv.innerHTML = `<div class="alert alert-success py-1 small">${result.message}</div>`;
|
||
setTimeout(() => location.reload(), 1500);
|
||
} else {
|
||
resultDiv.innerHTML = `<div class="alert alert-danger py-1 small">Ошибка: ${result.error}</div>`;
|
||
}
|
||
} catch (err) {
|
||
resultDiv.innerHTML = `<div class="alert alert-danger py-1 small">Ошибка: ${err.message}</div>`;
|
||
}
|
||
});
|
||
|
||
async function deleteService(id) {
|
||
if (!confirm('Удалить эту службу?')) return;
|
||
const r = await fetch(`/api/service/${id}/delete`, { method: 'POST' });
|
||
const result = await r.json();
|
||
if (result.success) { alert('Удалено'); location.reload(); }
|
||
}
|
||
</script>
|
||
{% endblock %}
|