Initial commit: Queensway Europe Telco Portal (Flask + SQLite, Docker deploy)
This commit is contained in:
Executable
+148
@@ -0,0 +1,148 @@
|
||||
{% extends "base.html" %}
|
||||
{% block title %}Internet Connectivity - Queensway Europe Telco Portal{% endblock %}
|
||||
{% block content %}
|
||||
<div class="d-flex justify-content-between align-items-center mb-3">
|
||||
<h2 class="mb-0 d-flex align-items-center gap-2">{% include "icons/wifi.svg" %} Internet Connectivity</h2>
|
||||
{% if session.role == 'admin' %}
|
||||
<button type="button" class="btn btn-success" onclick="openConnModal(null)">+ Add Connection</button>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
<div class="table-responsive">
|
||||
<table class="table table-striped table-hover align-middle bg-white">
|
||||
<thead class="table-dark">
|
||||
<tr>
|
||||
<th>Venue</th>
|
||||
<th>ISP Provider</th>
|
||||
<th>Plan</th>
|
||||
<th>Contract Expiration</th>
|
||||
<th>Notes</th>
|
||||
{% if session.role == 'admin' %}<th class="text-end">Actions</th>{% endif %}
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for c in connections %}
|
||||
<tr>
|
||||
<td>{{ c.venue }}</td>
|
||||
<td>{{ c.isp_provider or "" }}</td>
|
||||
<td>{{ c.plan or "" }}</td>
|
||||
<td>{{ c.contract_expiration.strftime("%d-%m-%Y") if c.contract_expiration else "" }}</td>
|
||||
<td>{{ c.notes or "" }}</td>
|
||||
{% if session.role == 'admin' %}
|
||||
<td class="text-end">
|
||||
<button type="button" class="btn btn-sm btn-outline-primary"
|
||||
onclick='openConnModal({{ c.to_dict() | tojson }})'>Edit</button>
|
||||
<button type="button" class="btn btn-sm btn-outline-danger"
|
||||
onclick="deleteConn({{ c.id }}, {{ c.venue | tojson }})">Delete</button>
|
||||
</td>
|
||||
{% endif %}
|
||||
</tr>
|
||||
{% else %}
|
||||
<tr><td colspan="{{ 6 if session.role == 'admin' else 5 }}" class="text-center text-muted py-4">No internet connections recorded yet.</td></tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<!-- Edit / Add modal -->
|
||||
<div class="modal fade" id="connModal" tabindex="-1" aria-hidden="true">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<form id="connForm">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title" id="connModalTitle">Edit Connection</h5>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<input type="hidden" id="connId">
|
||||
<div class="mb-3">
|
||||
<label class="form-label">Venue</label>
|
||||
<input type="text" class="form-control" id="connVenue" required>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label class="form-label">ISP Provider</label>
|
||||
<input type="text" class="form-control" id="connProvider">
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label class="form-label">Plan</label>
|
||||
<input type="text" class="form-control" id="connPlan">
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label class="form-label">Contract Expiration</label>
|
||||
<input type="date" class="form-control" id="connContractExpiration">
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label class="form-label">Notes</label>
|
||||
<textarea class="form-control" id="connNotes" rows="3"></textarea>
|
||||
</div>
|
||||
<div id="connError" class="text-danger small"></div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Cancel</button>
|
||||
<button type="submit" class="btn btn-primary">Save</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
{% block scripts %}
|
||||
<script>
|
||||
const connModalEl = document.getElementById('connModal');
|
||||
const connModal = new bootstrap.Modal(connModalEl);
|
||||
|
||||
function openConnModal(conn) {
|
||||
document.getElementById('connForm').reset();
|
||||
document.getElementById('connError').textContent = '';
|
||||
if (conn) {
|
||||
document.getElementById('connModalTitle').textContent = 'Edit Connection';
|
||||
document.getElementById('connId').value = conn.id;
|
||||
document.getElementById('connVenue').value = conn.venue || '';
|
||||
document.getElementById('connProvider').value = conn.isp_provider || '';
|
||||
document.getElementById('connPlan').value = conn.plan || '';
|
||||
document.getElementById('connContractExpiration').value = conn.contract_expiration || '';
|
||||
document.getElementById('connNotes').value = conn.notes || '';
|
||||
} else {
|
||||
document.getElementById('connModalTitle').textContent = 'Add Connection';
|
||||
document.getElementById('connId').value = '';
|
||||
}
|
||||
connModal.show();
|
||||
}
|
||||
|
||||
document.getElementById('connForm').addEventListener('submit', async function (e) {
|
||||
e.preventDefault();
|
||||
const id = document.getElementById('connId').value;
|
||||
const payload = {
|
||||
venue: document.getElementById('connVenue').value,
|
||||
isp_provider: document.getElementById('connProvider').value,
|
||||
plan: document.getElementById('connPlan').value,
|
||||
contract_expiration: document.getElementById('connContractExpiration').value,
|
||||
notes: document.getElementById('connNotes').value,
|
||||
};
|
||||
const url = id ? `/api/internet/${id}` : '/api/internet';
|
||||
const method = id ? 'PUT' : 'POST';
|
||||
const resp = await fetch(url, {
|
||||
method,
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify(payload),
|
||||
});
|
||||
if (resp.ok) {
|
||||
window.location.reload();
|
||||
} else {
|
||||
const data = await resp.json().catch(() => ({}));
|
||||
document.getElementById('connError').textContent = data.error || 'Failed to save. Please check the fields.';
|
||||
}
|
||||
});
|
||||
|
||||
async function deleteConn(id, venue) {
|
||||
if (!confirm(`Delete internet connection for "${venue}"? This cannot be undone.`)) return;
|
||||
const resp = await fetch(`/api/internet/${id}`, { method: 'DELETE' });
|
||||
if (resp.ok) {
|
||||
window.location.reload();
|
||||
} else {
|
||||
alert('Failed to delete.');
|
||||
}
|
||||
}
|
||||
</script>
|
||||
{% endblock %}
|
||||
Reference in New Issue
Block a user