PIVOT 1.1.0
This commit is contained in:
commit
8a53234eb6
161 files changed
+31109
No files matched your search
@@ -0,0 +1,126 @@
|
||||
{% extends "base.html" %}
|
||||
|
||||
{% block title %}CO2-sensoren{% endblock %}
|
||||
{% block page_title %}CO2-sensoren{% endblock %}
|
||||
{% block main_class %}medium{% endblock %}
|
||||
{% block loader_text %}Netwerk wordt gescand...{% endblock %}
|
||||
{% block loader_sub %}<div class="loader-sub">Dit kan tot 60 seconden duren. Even geduld a.u.b.</div>{% endblock %}
|
||||
|
||||
{% block extra_css %}
|
||||
<style>
|
||||
.settings-row { display: flex; flex-wrap: wrap; gap: 12px 32px; padding: 14px 16px; margin-bottom: 18px;
|
||||
background: var(--surface-muted); border: 1px solid var(--border); border-radius: var(--radius); }
|
||||
.setting { display: flex; align-items: center; gap: 10px; }
|
||||
.status-label { font-weight: 700; min-width: 28px; color: var(--text-muted); }
|
||||
.ppm { font-variant-numeric: tabular-nums; font-weight: 600; }
|
||||
</style>
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="card">
|
||||
<div class="page-head">
|
||||
<h2>🌬️ Actuele CO2-metingen per lokaal</h2>
|
||||
<div class="actions">
|
||||
<a href="{{ url_for('co2_sensor.scan_co2') }}" class="btn btn-success" onclick="showLoader()">🔍 Handmatige scan</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="settings-row">
|
||||
<div class="setting">
|
||||
<label class="switch">
|
||||
<input type="checkbox" id="continuousScanToggle" onchange="handleToggle(this)">
|
||||
<span class="slider"></span>
|
||||
</label>
|
||||
<span>Continu scannen</span>
|
||||
<span id="status-text" class="status-label">Uit</span>
|
||||
</div>
|
||||
<div class="setting">
|
||||
<label class="switch">
|
||||
<input type="checkbox" id="autoDeleteToggle" onchange="handleDeleteToggle(this)">
|
||||
<span class="slider"></span>
|
||||
</label>
|
||||
<span>Resultaten ouder dan 7 dagen automatisch verwijderen</span>
|
||||
<span id="delete-status-text" class="status-label">Uit</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="table-wrap">
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Lokaal</th>
|
||||
<th>CO2</th>
|
||||
<th>Status</th>
|
||||
<th class="actions">Actie</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for row in sensors %}
|
||||
<tr>
|
||||
<td><strong>{{ row.lokaal }}</strong></td>
|
||||
<td class="ppm">{{ row.ppm }} ppm</td>
|
||||
<td>
|
||||
{% if row.ppm < 800 %}<span class="badge badge-success">Goed</span>
|
||||
{% elif row.ppm < 1200 %}<span class="badge badge-warning">Ventileren</span>
|
||||
{% else %}<span class="badge badge-danger">Kritiek</span>
|
||||
{% endif %}
|
||||
</td>
|
||||
<td class="actions">
|
||||
<a href="{{ url_for('co2_sensor.grafiek', lokaal=row.lokaal) }}" class="btn btn-sm">📊 Grafiek</a>
|
||||
</td>
|
||||
</tr>
|
||||
{% else %}
|
||||
<tr class="empty-row"><td colspan="4">Nog geen metingen. Start een handmatige scan.</td></tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
{% block footer %}
|
||||
<footer class="app-footer">{{ school_name_short }} – PIVOT – Versie {{ version }} – CO2-monitor</footer>
|
||||
{% endblock %}
|
||||
|
||||
{% block scripts %}
|
||||
<script>
|
||||
function setLabel(id, active) {
|
||||
const el = document.getElementById(id);
|
||||
if (!el) return;
|
||||
el.innerText = active ? "Aan" : "Uit";
|
||||
el.style.color = active ? "var(--success)" : "var(--text-muted)";
|
||||
}
|
||||
function updateUI(active) { setLabel('status-text', active); }
|
||||
function updateDeleteUI(active) { setLabel('delete-status-text', active); }
|
||||
|
||||
document.addEventListener('DOMContentLoaded', function () {
|
||||
fetch("{{ url_for('co2_sensor.get_scan_status') }}")
|
||||
.then(r => r.json())
|
||||
.then(data => {
|
||||
document.getElementById('continuousScanToggle').checked = data.active;
|
||||
updateUI(data.active);
|
||||
});
|
||||
fetch("{{ url_for('co2_sensor.get_cleanup_status') }}")
|
||||
.then(r => r.json())
|
||||
.then(data => {
|
||||
document.getElementById('autoDeleteToggle').checked = data.active;
|
||||
updateDeleteUI(data.active);
|
||||
});
|
||||
});
|
||||
|
||||
function postToggle(url, checkbox, updateFn) {
|
||||
const isActive = checkbox.checked;
|
||||
fetch(url, {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ active: isActive })
|
||||
})
|
||||
.then(r => { if (!r.ok) throw new Error('Server error'); return r.json(); })
|
||||
.then(data => { updateFn(data.active); checkbox.checked = data.active; })
|
||||
.catch(err => { console.error(err); checkbox.checked = !isActive; updateFn(!isActive); });
|
||||
}
|
||||
|
||||
function handleToggle(checkbox) { postToggle("{{ url_for('co2_sensor.toggle_continuous_scan') }}", checkbox, updateUI); }
|
||||
function handleDeleteToggle(checkbox) { postToggle("{{ url_for('co2_sensor.toggle_auto_delete') }}", checkbox, updateDeleteUI); }
|
||||
</script>
|
||||
{% endblock %}
|
||||
Reference in new issue
Block a user