Files
PriceForge/web/templates/base.html

86 lines
3.7 KiB
HTML

{{define "base"}}
<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{{template "title" .}}</title>
<script src="https://cdn.tailwindcss.com"></script>
<script src="https://unpkg.com/htmx.org@1.9.10"></script>
<style>
.htmx-request { opacity: 0.5; }
.line-clamp-2 { display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
</style>
</head>
<body class="bg-gray-100 min-h-screen">
<nav class="bg-white shadow-sm sticky top-0 z-40">
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
<div class="flex justify-between h-14">
<div class="flex items-center space-x-8">
<a href="/" class="text-xl font-bold text-blue-600">PriceForge</a>
<div class="hidden md:flex space-x-4">
<a id="admin-pricing-link" href="/admin/pricing" class="text-gray-600 hover:text-gray-900 px-3 py-2 text-sm">Администратор цен</a>
<a href="/pricelists" class="text-gray-600 hover:text-gray-900 px-3 py-2 text-sm">Прайслисты</a>
<a href="/admin/pricing" class="text-gray-600 hover:text-gray-900 px-3 py-2 text-sm">Настройки</a>
</div>
</div>
<div class="flex items-center space-x-4">
<span id="db-connection-status" class="inline-flex items-center gap-1 text-xs text-gray-600">
<span class="inline-block w-2 h-2 rounded-full bg-gray-400"></span>
DB: checking
</span>
<span id="db-user" class="text-sm text-gray-600"></span>
</div>
</div>
</div>
</nav>
<main class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-6">
{{template "content" .}}
</main>
<div id="toast" class="fixed bottom-4 right-4 z-50"></div>
<script>
function showToast(msg, type) {
const colors = { success: 'bg-green-500', error: 'bg-red-500', info: 'bg-blue-500' };
const el = document.getElementById('toast');
el.innerHTML = '<div class="' + (colors[type] || colors.info) + ' text-white px-4 py-2 rounded shadow">' + msg + '</div>';
setTimeout(() => el.innerHTML = '', 3000);
}
function renderDBStatus(connected, errorText) {
const el = document.getElementById('db-connection-status');
if (!el) return;
if (connected) {
el.innerHTML = '<span class="inline-block w-2 h-2 rounded-full bg-green-500"></span>DB: online';
el.title = '';
return;
}
el.innerHTML = '<span class="inline-block w-2 h-2 rounded-full bg-red-500"></span>DB: offline';
el.title = errorText || 'Database not connected';
}
async function refreshDBConnectionStatus() {
try {
const resp = await fetch('/api/db-status');
const data = await resp.json();
renderDBStatus(data.connected === true, data.error || '');
const userEl = document.getElementById('db-user');
if (data.connected && data.db_user) {
userEl.innerHTML = '<span class="text-gray-500">@</span>' + data.db_user;
}
} catch (e) {
renderDBStatus(false, 'Status request failed');
}
}
document.addEventListener('DOMContentLoaded', function () {
refreshDBConnectionStatus();
setInterval(refreshDBConnectionStatus, 10000);
});
</script>
</body>
</html>
{{end}}