Initial release — Salus by Stranto v1.6.1.0
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>
This commit is contained in:
103
app/templates/base.html
Normal file
103
app/templates/base.html
Normal file
@@ -0,0 +1,103 @@
|
||||
<!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>
|
||||
Reference in New Issue
Block a user