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 (
"html/template"
"log"
"net/http"
"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 {
log.Printf("greška pri renderovanju: %v", err)
http.Error(w, "Greška pri prikazu stranice", http.StatusInternalServerError)
return
}
+99
View File
@@ -294,3 +294,102 @@ select:focus {
font-size: 14px;
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"}}
<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>
<!-- dugme za promenu teme -->
<div style="display:flex;align-items:center;gap:8px;">
<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" 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" 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" 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 class="topbar-teme" 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/svetla" class="tema-krug {{if eq .Tema "svetla"}}tema-krug-aktivan{{end}}" style="background:#e2e8f0;" 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/ljubicasta" class="tema-krug {{if eq .Tema "ljubicasta"}}tema-krug-aktivan{{end}}" style="background:#a855f7;" title="Ljubičasta"></a>
</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;">
{{if .Korisnik}}{{slice .Korisnik 0 2}}{{else}}NT{{end}}
</div>
+1 -1
View File
@@ -64,7 +64,7 @@
<div>
<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}}">
<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>
+46 -17
View File
@@ -1,16 +1,16 @@
{{define "base"}}
<!DOCTYPE html>
<!doctype html>
<html lang="sr">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>{{block "naslov" .}}NTech{{end}}</title>
<!-- 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 -->
<link rel="stylesheet" href="/static/css/main.css">
<link rel="stylesheet" href="/static/css/main.css" />
<!-- tailwind -->
<script src="https://cdn.tailwindcss.com"></script>
@@ -18,37 +18,66 @@
{{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>
<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>
<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 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
if (localStorage.getItem('sidebar-skupljen') === 'true') {
sidebar.classList.add('skupljen');
// učitaj stanje iz localStorage samo za desktop
if (!mobilni() && localStorage.getItem("sidebar-skupljen") === "true") {
sidebar.classList.add("skupljen");
}
hamburger.addEventListener('click', () => {
sidebar.classList.toggle('skupljen');
localStorage.setItem('sidebar-skupljen', sidebar.classList.contains('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>