FastAPI/Jinja2 web app for viewing and rebooting TP-Link Omada APs across all sites. Authentik OIDC auth, SQLite audit log, Docker deploy. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
104 lines
4.0 KiB
HTML
104 lines
4.0 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="en" class="h-full bg-white">
|
|
<head>
|
|
<meta charset="UTF-8" />
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
<title>{% block title %}Salus by Stranto{% endblock %}</title>
|
|
<script src="https://cdn.tailwindcss.com"></script>
|
|
<script>
|
|
tailwind.config = {
|
|
theme: {
|
|
extend: {
|
|
colors: {
|
|
brand: { 500: '#3b82f6', 600: '#2563eb', 700: '#1d4ed8' }
|
|
}
|
|
}
|
|
}
|
|
}
|
|
</script>
|
|
<style>
|
|
[x-cloak] { display: none !important; }
|
|
.toast { animation: slide-in 0.3s ease-out; }
|
|
@keyframes slide-in {
|
|
from { transform: translateX(100%); opacity: 0; }
|
|
to { transform: translateX(0); opacity: 1; }
|
|
}
|
|
</style>
|
|
</head>
|
|
<body class="h-full text-gray-900 flex flex-col">
|
|
|
|
<!-- Nav -->
|
|
<nav class="bg-white border-b border-gray-200 shadow-sm">
|
|
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
|
|
<div class="flex items-center justify-between h-16">
|
|
<div class="flex items-center gap-8">
|
|
<a href="/" class="flex items-center gap-2 font-bold text-lg text-gray-900 hover:text-blue-600 transition-colors">
|
|
<svg class="w-6 h-6 text-blue-500" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
|
|
d="M12 9v6m-3-3h6m6 0a9 9 0 11-18 0 9 9 0 0118 0z"/>
|
|
</svg>
|
|
Salus <span class="font-normal text-gray-400 text-sm">by Stranto</span>
|
|
</a>
|
|
<div class="hidden sm:flex gap-1">
|
|
<a href="/"
|
|
class="px-3 py-2 rounded-md text-sm font-medium transition-colors
|
|
{% if request.url.path == '/' %}bg-gray-100 text-gray-900{% else %}text-gray-600 hover:text-gray-900 hover:bg-gray-100{% endif %}">
|
|
Access Points
|
|
</a>
|
|
<a href="/audit"
|
|
class="px-3 py-2 rounded-md text-sm font-medium transition-colors
|
|
{% if request.url.path == '/audit' %}bg-gray-100 text-gray-900{% else %}text-gray-600 hover:text-gray-900 hover:bg-gray-100{% endif %}">
|
|
Audit Log
|
|
</a>
|
|
</div>
|
|
</div>
|
|
{% if user %}
|
|
<div class="flex items-center gap-3">
|
|
<span class="hidden sm:block text-sm text-gray-500">
|
|
<span class="text-gray-900 font-medium">{{ user.username }}</span>
|
|
</span>
|
|
<a href="/auth/logout"
|
|
class="px-3 py-1.5 text-sm rounded-md bg-gray-100 text-gray-600 hover:bg-red-50 hover:text-red-700 border border-gray-200 transition-colors">
|
|
Logout
|
|
</a>
|
|
</div>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
</nav>
|
|
|
|
<!-- Page content -->
|
|
<main class="flex-1 max-w-7xl w-full mx-auto px-4 sm:px-6 lg:px-8 py-8">
|
|
{% block content %}{% endblock %}
|
|
</main>
|
|
|
|
<!-- Footer -->
|
|
<footer class="border-t border-gray-200 bg-white mt-auto">
|
|
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-4 flex items-center justify-between text-xs text-gray-400">
|
|
<span>Version 1.6.1.0</span>
|
|
<a href="https://www.stranto.com/" target="_blank" rel="noopener noreferrer"
|
|
class="hover:text-blue-500 transition-colors">stranto.com</a>
|
|
</div>
|
|
</footer>
|
|
|
|
<!-- Toast container -->
|
|
<div id="toast-container" class="fixed bottom-4 right-4 flex flex-col gap-2 z-50 pointer-events-none"></div>
|
|
|
|
<script>
|
|
function showToast(msg, type = 'success') {
|
|
const container = document.getElementById('toast-container');
|
|
const colors = type === 'success'
|
|
? 'bg-green-50 border-green-200 text-green-800'
|
|
: 'bg-red-50 border-red-200 text-red-800';
|
|
const el = document.createElement('div');
|
|
el.className = `toast pointer-events-auto px-4 py-3 rounded-lg border shadow text-sm max-w-xs ${colors}`;
|
|
el.textContent = msg;
|
|
container.appendChild(el);
|
|
setTimeout(() => { el.remove(); }, 4000);
|
|
}
|
|
</script>
|
|
|
|
{% block scripts %}{% endblock %}
|
|
</body>
|
|
</html>
|