150 lines
7.1 KiB
HTML
150 lines
7.1 KiB
HTML
{% extends "base.html" %}
|
|
|
|
{% block title %}{{ unit_id }} - Sound Level Meter Control Center{% endblock %}
|
|
|
|
{% block content %}
|
|
<!-- Breadcrumb Navigation -->
|
|
<div class="mb-6">
|
|
<nav class="flex items-center space-x-2 text-sm">
|
|
{% if from_project and project %}
|
|
<a href="/projects" class="text-gray-500 hover:text-seismo-orange">Projects</a>
|
|
<svg class="w-4 h-4 text-gray-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5l7 7-7 7"></path>
|
|
</svg>
|
|
<a href="/projects/{{ from_project }}" class="text-seismo-orange hover:text-seismo-navy flex items-center">
|
|
<svg class="w-4 h-4 mr-1" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 19l-7-7 7-7"></path>
|
|
</svg>
|
|
{{ project.name }}
|
|
</a>
|
|
<svg class="w-4 h-4 text-gray-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5l7 7-7 7"></path>
|
|
</svg>
|
|
<span class="text-gray-900 dark:text-white font-medium">{{ unit_id }}</span>
|
|
{% else %}
|
|
<a href="/sound-level-meters" class="text-seismo-orange hover:text-seismo-navy flex items-center">
|
|
<svg class="w-4 h-4 mr-1" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 19l-7-7 7-7"></path>
|
|
</svg>
|
|
Sound Level Meters
|
|
</a>
|
|
<svg class="w-4 h-4 text-gray-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5l7 7-7 7"></path>
|
|
</svg>
|
|
<span class="text-gray-900 dark:text-white font-medium">{{ unit_id }}</span>
|
|
{% endif %}
|
|
</nav>
|
|
</div>
|
|
|
|
<!-- Header -->
|
|
<div class="mb-8">
|
|
<div class="flex justify-between items-start">
|
|
<div>
|
|
<h1 class="text-3xl font-bold text-gray-900 dark:text-white flex items-center">
|
|
<svg class="w-8 h-8 mr-3 text-seismo-orange" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15.536 8.464a5 5 0 010 7.072m2.828-9.9a9 9 0 010 12.728M5.586 15H4a1 1 0 01-1-1v-4a1 1 0 011-1h1.586l4.707-4.707C10.923 3.663 12 4.109 12 5v14c0 .891-1.077 1.337-1.707.707L5.586 15z"></path>
|
|
</svg>
|
|
{{ unit_id }}
|
|
</h1>
|
|
<p class="text-gray-600 dark:text-gray-400 mt-1">
|
|
Sound Level Meter Control Center
|
|
</p>
|
|
</div>
|
|
<div class="flex gap-3">
|
|
<button onclick="openConfigModal()"
|
|
class="px-4 py-2 bg-gray-100 dark:bg-gray-700 text-gray-700 dark:text-gray-300 rounded-lg hover:bg-gray-200 dark:hover:bg-gray-600 transition-colors flex items-center">
|
|
<svg class="w-4 h-4 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10.325 4.317c.426-1.756 2.924-1.756 3.35 0a1.724 1.724 0 002.573 1.066c1.543-.94 3.31.826 2.37 2.37a1.724 1.724 0 001.065 2.572c1.756.426 1.756 2.924 0 3.35a1.724 1.724 0 00-1.066 2.573c.94 1.543-.826 3.31-2.37 2.37a1.724 1.724 0 00-2.572 1.065c-.426 1.756-2.924 1.756-3.35 0a1.724 1.724 0 00-2.573-1.066c-1.543.94-3.31-.826-2.37-2.37a1.724 1.724 0 00-1.065-2.572c-1.756-.426-1.756-2.924 0-3.35a1.724 1.724 0 001.066-2.573c-.94-1.543.826-3.31 2.37-2.37.996.608 2.296.07 2.572-1.065z"></path>
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 12a3 3 0 11-6 0 3 3 0 016 0z"></path>
|
|
</svg>
|
|
Configure
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Live View Panel -->
|
|
<div class="bg-white dark:bg-slate-800 rounded-xl shadow-lg">
|
|
<div id="live-view-content"
|
|
hx-get="/api/slm-dashboard/live-view/{{ unit_id }}"
|
|
hx-trigger="load"
|
|
hx-swap="innerHTML">
|
|
<!-- Loading State -->
|
|
<div class="p-12 text-center">
|
|
<div class="animate-spin rounded-full h-12 w-12 border-b-2 border-seismo-orange mx-auto mb-4"></div>
|
|
<p class="text-gray-500 dark:text-gray-400">Loading control center...</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Configuration Modal -->
|
|
<div id="config-modal" class="hidden fixed inset-0 bg-black bg-opacity-50 z-50 flex items-center justify-center">
|
|
<div class="bg-white dark:bg-slate-800 rounded-xl shadow-2xl w-full max-w-2xl max-h-[90vh] overflow-y-auto m-4">
|
|
<div class="p-6 border-b border-gray-200 dark:border-gray-700 flex items-center justify-between">
|
|
<h2 class="text-2xl font-bold text-gray-900 dark:text-white">Configure {{ unit_id }}</h2>
|
|
<button onclick="closeConfigModal()" class="text-gray-500 hover:text-gray-700 dark:text-gray-400 dark:hover:text-gray-200">
|
|
<svg class="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12"></path>
|
|
</svg>
|
|
</button>
|
|
</div>
|
|
|
|
<div id="config-modal-content"
|
|
hx-get="/api/slm-dashboard/config/{{ unit_id }}"
|
|
hx-trigger="load"
|
|
hx-swap="innerHTML">
|
|
<!-- Loading skeleton -->
|
|
<div class="p-6 space-y-4 animate-pulse">
|
|
<div class="h-4 bg-gray-200 dark:bg-gray-700 rounded w-3/4"></div>
|
|
<div class="h-4 bg-gray-200 dark:bg-gray-700 rounded"></div>
|
|
<div class="h-4 bg-gray-200 dark:bg-gray-700 rounded w-5/6"></div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<script>
|
|
// Modal functions
|
|
function openConfigModal() {
|
|
const modal = document.getElementById('config-modal');
|
|
modal.classList.remove('hidden');
|
|
// Reload config when opening
|
|
htmx.ajax('GET', '/api/slm-dashboard/config/{{ unit_id }}', {
|
|
target: '#config-modal-content',
|
|
swap: 'innerHTML'
|
|
});
|
|
}
|
|
|
|
function closeConfigModal() {
|
|
document.getElementById('config-modal').classList.add('hidden');
|
|
}
|
|
|
|
// Keyboard shortcut
|
|
document.addEventListener('keydown', function(e) {
|
|
if (e.key === 'Escape') {
|
|
closeConfigModal();
|
|
}
|
|
});
|
|
|
|
// Click outside to close
|
|
document.getElementById('config-modal')?.addEventListener('click', function(e) {
|
|
if (e.target === this) {
|
|
closeConfigModal();
|
|
}
|
|
});
|
|
|
|
// Listen for config updates to refresh live view
|
|
document.body.addEventListener('htmx:afterRequest', function(event) {
|
|
if (event.detail.pathInfo.requestPath.includes('/config/') && event.detail.successful) {
|
|
// Refresh live view after config update
|
|
htmx.ajax('GET', '/api/slm-dashboard/live-view/{{ unit_id }}', {
|
|
target: '#live-view-content',
|
|
swap: 'innerHTML'
|
|
});
|
|
closeConfigModal();
|
|
}
|
|
});
|
|
</script>
|
|
|
|
{% endblock %}
|