Popravka greške u topbaru, responsive sidebar, tačkice za teme

This commit is contained in:
2026-06-01 02:04:50 +02:00
parent 91889b7711
commit 8cc54a7fc2
5 changed files with 172 additions and 34 deletions
+2
View File
@@ -2,6 +2,7 @@ package handler
import ( import (
"html/template" "html/template"
"log"
"net/http" "net/http"
"ntech/internal/db/sqlite" "ntech/internal/db/sqlite"
@@ -48,6 +49,7 @@ func (h *Handler) Dashboard(w http.ResponseWriter, r *http.Request) {
} }
if err := tmpl.ExecuteTemplate(w, "base", podaci); err != nil { if err := tmpl.ExecuteTemplate(w, "base", podaci); err != nil {
log.Printf("greška pri renderovanju: %v", err)
http.Error(w, "Greška pri prikazu stranice", http.StatusInternalServerError) http.Error(w, "Greška pri prikazu stranice", http.StatusInternalServerError)
return return
} }
+99
View File
@@ -294,3 +294,102 @@ select:focus {
font-size: 14px; font-size: 14px;
color: var(--sb-akcent); color: var(--sb-akcent);
} }
/* overlay za mobilni — tamni sloj iza sidebara */
.sidebar-overlay {
display: none;
position: fixed;
inset: 0;
background: rgba(0,0,0,0.5);
z-index: 9;
}
.sidebar-overlay.aktivan {
display: block;
}
/* mobilni ekrani */
@media (max-width: 768px) {
.sidebar {
position: fixed;
left: 0;
top: 0;
height: 100vh;
z-index: 10;
transform: translateX(-100%);
transition: transform 0.28s cubic-bezier(.4,0,.2,1);
width: 220px !important;
}
.sidebar.otvoren {
transform: translateX(0);
}
/* na mobilnom logo zona uvek vidljiva kada je sidebar otvoren */
.sidebar.otvoren .logo-zona {
opacity: 1;
width: 160px;
pointer-events: auto;
}
.sidebar.otvoren .nav-oznaka {
opacity: 1;
}
.sidebar.otvoren .nav-stavka span {
opacity: 1;
pointer-events: auto;
}
/* glavni sadržaj zauzima celu širinu */
.glavni-sadrzaj {
width: 100%;
}
/* sakrij tooltip na mobilnom */
.nav-tooltip {
display: none !important;
}
}
/* hamburger u topbaru — samo na mobilnom */
@media (max-width: 768px) {
#hamburger-topbar {
display: flex !important;
color: var(--tekst-glavni);
}
#hamburger-topbar:hover {
background: var(--pozadina);
}
}
/* tačkice za teme u topbaru — sakrij na mobilnom */
@media (max-width: 768px) {
.topbar-teme {
display: none;
}
/* teme u podešavanjima — jedna ispod druge na mobilnom */
.teme-grid {
flex-direction: column !important;
}
}
/* tačkice za teme */
.tema-krug {
width: 20px;
height: 20px;
border-radius: 50%;
display: inline-block;
border: 2px solid transparent;
transition: border-color 0.2s;
}
.tema-krug:hover {
border-color: var(--tekst-sporedni);
}
.tema-krug-aktivan {
border-color: var(--tekst-glavni) !important;
}
+15 -7
View File
@@ -1,16 +1,24 @@
{{define "topbar"}} {{define "topbar"}}
<header class="topbar"> <header class="topbar">
<button class="hamburger" id="hamburger-topbar" aria-label="Otvori meni"
style="display:none;margin-right:8px;"
onclick="document.getElementById('hamburger').click()">
<svg xmlns="http://www.w3.org/2000/svg" width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<line x1="3" y1="6" x2="21" y2="6"/>
<line x1="3" y1="12" x2="21" y2="12"/>
<line x1="3" y1="18" x2="21" y2="18"/>
</svg>
</button>
<span class="topbar-naslov">{{.NaslovStranice}}</span> <span class="topbar-naslov">{{.NaslovStranice}}</span>
<!-- dugme za promenu teme --> <div class="topbar-teme" style="display:flex;align-items:center;gap:8px;">
<div style="display:flex;align-items:center;gap:8px;"> <a href="/tema/tamna" class="tema-krug {{if eq .Tema "tamna"}}tema-krug-aktivan{{end}}" style="background:#4f7ef8;" title="Tamna"></a>
<a href="/tema/tamna" style="width:20px;height:20px;border-radius:50%;background:#1a1d2e;border:2px solid {{if eq .Tema "tamna"}}#fff{{else}}transparent{{end}};display:inline-block;" title="Tamna"></a> <a href="/tema/svetla" class="tema-krug {{if eq .Tema "svetla"}}tema-krug-aktivan{{end}}" style="background:#e2e8f0;" title="Svetla"></a>
<a href="/tema/svetla" style="width:20px;height:20px;border-radius:50%;background:#f8fafc;border:2px solid {{if eq .Tema "svetla"}}#1a1d2e{{else}}#cbd5e1{{end}};display:inline-block;" title="Svetla"></a> <a href="/tema/zelena" class="tema-krug {{if eq .Tema "zelena"}}tema-krug-aktivan{{end}}" style="background:#22c55e;" title="Zelena"></a>
<a href="/tema/zelena" style="width:20px;height:20px;border-radius:50%;background:#338150;border:2px solid {{if eq .Tema "zelena"}}#fff{{else}}transparent{{end}};display:inline-block;" title="Zelena"></a> <a href="/tema/ljubicasta" class="tema-krug {{if eq .Tema "ljubicasta"}}tema-krug-aktivan{{end}}" style="background:#a855f7;" title="Ljubičasta"></a>
<a href="/tema/ljubicasta" style="width:20px;height:20px;border-radius:50%;background:#543b94;border:2px solid {{if eq .Tema "ljubicasta"}}#fff{{else}}transparent{{end}};display:inline-block;" title="Ljubičasta"></a>
</div> </div>
<!-- korisnik -->
<div style="width:32px;height:32px;border-radius:50%;background:var(--sb-aktivan);display:flex;align-items:center;justify-content:center;font-size:12px;font-weight:500;color:#fff;flex-shrink:0;"> <div style="width:32px;height:32px;border-radius:50%;background:var(--sb-aktivan);display:flex;align-items:center;justify-content:center;font-size:12px;font-weight:500;color:#fff;flex-shrink:0;">
{{if .Korisnik}}{{slice .Korisnik 0 2}}{{else}}NT{{end}} {{if .Korisnik}}{{slice .Korisnik 0 2}}{{else}}NT{{end}}
</div> </div>
+1 -1
View File
@@ -64,7 +64,7 @@
<div> <div>
<label style="font-size:13px;color:var(--tekst-sporedni);display:block;margin-bottom:8px;">Tema</label> <label style="font-size:13px;color:var(--tekst-sporedni);display:block;margin-bottom:8px;">Tema</label>
<div style="display:flex;gap:10px;"> <div class="teme-grid" style="display:flex;gap:10px;">
<label style="display:flex;align-items:center;gap:8px;padding:10px 14px;border:0.5px solid var(--ivica);border-radius:8px;cursor:pointer;flex:1;{{if eq .Tema "tamna"}}border-color:var(--sb-akcent);{{end}}"> <label style="display:flex;align-items:center;gap:8px;padding:10px 14px;border:0.5px solid var(--ivica);border-radius:8px;cursor:pointer;flex:1;{{if eq .Tema "tamna"}}border-color:var(--sb-akcent);{{end}}">
<input type="radio" name="tema" value="tamna" {{if eq .Tema "tamna"}}checked{{end}} style="accent-color:var(--sb-akcent);"> <input type="radio" name="tema" value="tamna" {{if eq .Tema "tamna"}}checked{{end}} style="accent-color:var(--sb-akcent);">
<div style="width:16px;height:16px;border-radius:50%;background:#1a1d2e;flex-shrink:0;"></div> <div style="width:16px;height:16px;border-radius:50%;background:#1a1d2e;flex-shrink:0;"></div>
+55 -26
View File
@@ -1,58 +1,87 @@
{{define "base"}} {{define "base"}}
<!DOCTYPE html> <!doctype html>
<html lang="sr"> <html lang="sr">
<head> <head>
<meta charset="UTF-8"> <meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>{{block "naslov" .}}NTech{{end}}</title> <title>{{block "naslov" .}}NTech{{end}}</title>
<!-- tema — učitava se prva --> <!-- tema — učitava se prva -->
<link rel="stylesheet" href="/static/css/teme/{{.Tema}}.css"> <link rel="stylesheet" href="/static/css/teme/{{.Tema}}.css" />
<!-- glavni stilovi --> <!-- glavni stilovi -->
<link rel="stylesheet" href="/static/css/main.css"> <link rel="stylesheet" href="/static/css/main.css" />
<!-- tailwind --> <!-- tailwind -->
<script src="https://cdn.tailwindcss.com"></script> <script src="https://cdn.tailwindcss.com"></script>
{{block "dodatni-css" .}}{{end}} {{block "dodatni-css" .}}{{end}}
</head> </head>
<body> <body>
<div class="sidebar-overlay" id="sidebar-overlay"></div>
<div class="raspored"> <div class="raspored">
{{template "sidebar" .}} {{template "sidebar" .}}
<div class="glavni-sadrzaj"> <div class="glavni-sadrzaj">
{{template "topbar" .}} {{template "topbar" .}}
<main class="sadrzaj"> <main class="sadrzaj">{{block "sadrzaj" .}}{{end}}</main>
{{block "sadrzaj" .}}{{end}} </div>
</main>
</div>
</div> </div>
<!-- alpine.js za interaktivnost --> <!-- alpine.js za interaktivnost -->
<script src="https://cdn.jsdelivr.net/npm/alpinejs@3.x.x/dist/cdn.min.js" defer></script> <script
src="https://cdn.jsdelivr.net/npm/alpinejs@3.x.x/dist/cdn.min.js"
defer
></script>
<!-- htmx za komunikaciju sa serverom --> <!-- htmx za komunikaciju sa serverom -->
<script src="https://cdn.jsdelivr.net/npm/htmx.org@2.x.x/dist/htmx.min.js"></script> <script src="https://cdn.jsdelivr.net/npm/htmx.org@2.x.x/dist/htmx.min.js"></script>
<!-- sidebar logika -->
<!-- sidebar logika --> <!-- sidebar logika -->
<script> <script>
const sidebar = document.getElementById('sidebar'); const sidebar = document.getElementById("sidebar");
const hamburger = document.getElementById('hamburger'); const hamburger = document.getElementById("hamburger");
const overlay = document.getElementById("sidebar-overlay");
const mobilni = () => window.innerWidth <= 768;
// učitaj stanje iz localStorage // učitaj stanje iz localStorage samo za desktop
if (localStorage.getItem('sidebar-skupljen') === 'true') { if (!mobilni() && localStorage.getItem("sidebar-skupljen") === "true") {
sidebar.classList.add('skupljen'); sidebar.classList.add("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"),
);
} }
});
hamburger.addEventListener('click', () => { // zatvori sidebar klikom na overlay
sidebar.classList.toggle('skupljen'); overlay.addEventListener("click", () => {
localStorage.setItem('sidebar-skupljen', sidebar.classList.contains('skupljen')); 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> </script>
{{block "dodatni-js" .}}{{end}} {{block "dodatni-js" .}}{{end}}
</body> </body>
</html> </html>
{{end}} {{end}}