d48d088efa
Inline skript u <head> odmah postavlja klasu na <html> pre iscrtavanja, CSS je primenjuje bez tranzicije, JS je uklanja nakon što doda .skupljen. Changes to be committed: modified: build.sh modified: go.mod modified: go.sum modified: internal/config/setup.go modified: web/static/css/main.css modified: web/templates/teme/podrazumevana/base.html
110 lines
3.4 KiB
HTML
110 lines
3.4 KiB
HTML
{{define "base"}}
|
|
<!doctype html>
|
|
<html lang="sr">
|
|
<head>
|
|
<meta charset="UTF-8" />
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
<title>{{block "naslov" .}}NTech{{end}}</title>
|
|
<meta name="csrf-token" content="{{.CsrfToken}}">
|
|
|
|
<script>
|
|
if (window.innerWidth > 768 && localStorage.getItem('sidebar-skupljen') === 'true') {
|
|
document.documentElement.classList.add('sidebar-init-skupljen');
|
|
}
|
|
</script>
|
|
|
|
<!-- tema — učitava se prva -->
|
|
<link rel="stylesheet" href="/static/css/teme/{{.Tema}}.css" />
|
|
|
|
<!-- glavni stilovi -->
|
|
<link rel="stylesheet" href="/static/css/main.css" />
|
|
|
|
<!-- tailwind -->
|
|
<script src="https://cdn.tailwindcss.com"></script>
|
|
|
|
{{block "dodatni-css" .}}{{end}}
|
|
</head>
|
|
<body>
|
|
<div class="sidebar-overlay" id="sidebar-overlay"></div>
|
|
<div class="raspored">
|
|
{{template "sidebar" .}}
|
|
|
|
<div class="glavni-sadrzaj">
|
|
{{template "topbar" .}}
|
|
|
|
<main class="sadrzaj">{{block "sadrzaj" .}}{{end}}</main>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- alpine.js za interaktivnost -->
|
|
<script
|
|
src="https://cdn.jsdelivr.net/npm/alpinejs@3.x.x/dist/cdn.min.js"
|
|
defer
|
|
></script>
|
|
|
|
<!-- htmx za komunikaciju sa serverom -->
|
|
<script src="https://cdn.jsdelivr.net/npm/htmx.org@2.x.x/dist/htmx.min.js"></script>
|
|
|
|
<!-- sidebar logika -->
|
|
<!-- sidebar logika -->
|
|
<script>
|
|
const sidebar = document.getElementById("sidebar");
|
|
const hamburger = document.getElementById("hamburger");
|
|
const overlay = document.getElementById("sidebar-overlay");
|
|
const mobilni = () => window.innerWidth <= 768;
|
|
|
|
// učitaj stanje iz localStorage samo za desktop
|
|
if (!mobilni() && localStorage.getItem("sidebar-skupljen") === "true") {
|
|
sidebar.classList.add("skupljen");
|
|
}
|
|
document.documentElement.classList.remove('sidebar-init-skupljen');
|
|
|
|
hamburger.addEventListener("click", () => {
|
|
if (mobilni()) {
|
|
// mobilno — drawer ponašanje
|
|
sidebar.classList.toggle("otvoren");
|
|
overlay.classList.toggle("aktivan");
|
|
} else {
|
|
// desktop — skupljanje
|
|
sidebar.classList.toggle("skupljen");
|
|
localStorage.setItem(
|
|
"sidebar-skupljen",
|
|
sidebar.classList.contains("skupljen"),
|
|
);
|
|
}
|
|
});
|
|
|
|
// zatvori sidebar klikom na overlay
|
|
overlay.addEventListener("click", () => {
|
|
sidebar.classList.remove("otvoren");
|
|
overlay.classList.remove("aktivan");
|
|
});
|
|
|
|
// zatvori sidebar kada se promeni veličina prozora
|
|
window.addEventListener("resize", () => {
|
|
if (!mobilni()) {
|
|
sidebar.classList.remove("otvoren");
|
|
overlay.classList.remove("aktivan");
|
|
}
|
|
});
|
|
</script>
|
|
|
|
{{block "dodatni-js" .}}{{end}}
|
|
|
|
<!-- CSRF: automatski dodaje skriveno polje u sve POST forme -->
|
|
<script>
|
|
document.addEventListener('DOMContentLoaded', function() {
|
|
var m = document.querySelector('meta[name="csrf-token"]');
|
|
if (!m || !m.content) return;
|
|
document.querySelectorAll('form[method="POST"],form[method="post"]').forEach(function(f) {
|
|
if (f.querySelector('input[name="_csrf"]')) return;
|
|
var i = document.createElement('input');
|
|
i.type = 'hidden'; i.name = '_csrf'; i.value = m.content;
|
|
f.appendChild(i);
|
|
});
|
|
});
|
|
</script>
|
|
</body>
|
|
</html>
|
|
{{end}}
|