Topbar: logo firme + naslov; avatar upload; uklanjanje logo zone

- Topbar: logo slika firme (toggle on/off) pa naslov stranice; bez teksta firme
- Sidebar: samo naziv firme i podnaslov (tekst), bez slike loga
- Avatar: korisnik uploaduje ličnu sliku u Profil > Tema > Avatar;
  prikazuje se kao dugme za meni (desno u topbaru); fallback inicijali
- Logo firme kartica: dugme "Ukloni sliku" + ruta /podesavanja/logo/ukloni
- Logo zona iz podešavanja uklonjena; jedan iOS toggle za prikaz loga u topbaru
- Migracije 049 (topbar_logo_slika/tekst) i 050 (avatar_putanja na korisnicima)
- iOS-style .toggl switch u main.css
This commit is contained in:
2026-06-16 02:46:48 +02:00
parent 3c5c8060c1
commit 85cb1e25c7
15 changed files with 320 additions and 60 deletions
+41 -3
View File
@@ -303,12 +303,28 @@ body {
}
.topbar-naslov {
font-weight: 500;
font-size: 15px;
font-weight: 600;
font-size: 18px;
color: var(--tekst-glavni);
flex: 1;
min-width: 0;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
/* identifikacija firme u topbaru (naziv + logo) — pomera se i može da se skrati */
.topbar-firma { flex-shrink: 0; line-height: 1.2; min-width: 0; }
.topbar-firma .topbar-firma-naziv {
font-weight: 700; font-size: 14px; color: var(--tekst-glavni); letter-spacing: -0.2px;
overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.topbar-firma .topbar-firma-podnaziv {
font-size: 11px; color: var(--tekst-sporedni);
overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.topbar-logo { height: 34px; width: auto; border-radius: 6px; flex-shrink: 0; }
/* sadržaj stranice */
.sadrzaj {
flex: 1;
@@ -583,7 +599,7 @@ body {
.avatar-korisnik {
width: 32px;
height: 32px;
border-radius: 50%;
border-radius: 9px;
background: var(--sb-akcent);
display: flex;
align-items: center;
@@ -918,6 +934,11 @@ select {
#hamburger-topbar { display: flex !important; color: var(--tekst-glavni); }
#hamburger-topbar:hover { background: var(--pozadina); }
/* na telefonu sklanjamo identifikaciju firme iz topbara — naziv i logo su
već vidljivi u bočnom meniju, pa naslov stranice dobija ceo prostor */
.topbar-firma, .topbar-logo { display: none; }
.topbar-naslov { font-size: 16px; }
/* teme */
.topbar-teme { display: none; }
.teme-grid { flex-direction: column !important; }
@@ -1167,6 +1188,23 @@ select {
}
}
/* iOS-style toggle switch (.toggl > input[type=checkbox] + .toggl-klizac) */
.toggl { position:relative; display:inline-block; width:44px; height:26px; flex-shrink:0; }
.toggl input { opacity:0; width:0; height:0; position:absolute; }
.toggl-klizac {
position:absolute; inset:0; border-radius:26px; cursor:pointer;
background:var(--ivica); transition:background 0.2s;
}
.toggl-klizac::before {
content:''; position:absolute;
width:20px; height:20px; border-radius:50%;
left:3px; top:3px;
background:#fff; box-shadow:0 1px 3px rgba(0,0,0,0.25);
transition:transform 0.2s;
}
.toggl input:checked + .toggl-klizac { background:var(--sb-akcent); }
.toggl input:checked + .toggl-klizac::before { transform:translateX(18px); }
/* pomoćne klase (ranije iz Tailwind-a, sada lokalno da ne zavisimo od CDN-a) */
.grid { display: grid; }
.gap-3 { gap: 12px; }
+4 -12
View File
@@ -9,18 +9,10 @@
</svg>
</button>
<div class="logo-zona">
{{if eq .LogoTip "slika"}}
<img src="{{.LogoPutanja}}" alt="Logo"
style="max-height:48px;width:auto;border-radius:8px;padding:4px;background:var(--kartica);box-shadow:var(--senka);transition:transform 0.2s;flex-shrink:0;"
onmouseover="this.style.transform='scale(1.02)'"
onmouseout="this.style.transform='scale(1)'">
{{else if eq .LogoTip "bez_naziva"}}
{{else}}
<div>
<div class="logo-naziv">{{.NazivFirme}}</div>
<div class="logo-podnazlov">{{.Podnazlov}}</div>
</div>
{{end}}
<div>
<div class="logo-naziv">{{.NazivFirme}}</div>
{{if .Podnazlov}}<div class="logo-podnazlov">{{.Podnazlov}}</div>{{end}}
</div>
</div>
</div>
+9 -1
View File
@@ -10,11 +10,19 @@
</svg>
</button>
{{if and .TopbarLogoSlika .LogoPutanja}}
<img src="{{.LogoPutanja}}" alt="Logo" class="topbar-logo">
{{end}}
<span class="topbar-naslov">{{.NaslovStranice}}</span>
<div style="position:relative;" id="avatar-wrapper">
<div class="avatar-korisnik" id="avatar-dugme" style="cursor:pointer;" title="{{.Korisnik}}">
<div class="avatar-korisnik" id="avatar-dugme" style="cursor:pointer;overflow:hidden;" title="{{.Korisnik}}">
{{if .AvatarPutanja}}
<img src="{{.AvatarPutanja}}" alt="Avatar" style="width:100%;height:100%;object-fit:cover;display:block;">
{{else}}
{{if .Korisnik}}{{slice .Korisnik 0 2}}{{else}}NT{{end}}
{{end}}
</div>
<div id="avatar-meni" style="display:none;position:fixed;background:var(--kartica);backdrop-filter:none;-webkit-backdrop-filter:none;border:0.5px solid var(--ivica);border-radius:10px;box-shadow:var(--senka);min-width:160px;z-index:9999;overflow:hidden;transform-origin:top right;">
<a href="/admin/profil" style="display:flex;align-items:center;gap:10px;padding:10px 14px;font-size:14px;color:var(--tekst-glavni);text-decoration:none;transition:background 0.15s;"
+20 -17
View File
@@ -11,15 +11,23 @@
<!-- upload loga — posebna forma jer je multipart, mora biti van glavne forme -->
<form method="POST" action="/podesavanja/logo" enctype="multipart/form-data">
<input type="hidden" name="_csrf" value="{{.CsrfToken}}">
<div class="kartica animiraj" style="margin-bottom:16px;">
<div style="display:flex;align-items:center;gap:10px;margin-bottom:16px;padding-bottom:12px;border-bottom:0.5px solid var(--ivica);">
<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="var(--sb-akcent)" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="3" width="18" height="18" rx="2"/><circle cx="8.5" cy="8.5" r="1.5"/><polyline points="21 15 16 10 5 21"/></svg>
<span style="font-size:15px;font-weight:500;color:var(--tekst-glavni);">Logo firme</span>
</div>
{{if .LogoPutanja}}
<div style="margin-bottom:12px;">
<div style="display:flex;align-items:center;gap:12px;margin-bottom:12px;">
<img src="{{.LogoPutanja}}" alt="Trenutni logo"
style="max-height:60px;max-width:200px;object-fit:contain;border:0.5px solid var(--ivica);border-radius:8px;padding:6px;background:var(--kartica);">
style="max-height:60px;max-width:200px;object-fit:contain;border:0.5px solid var(--ivica);border-radius:8px;padding:6px;background:var(--kartica);flex-shrink:0;">
<form method="POST" action="/podesavanja/logo/ukloni" style="margin:0;">
<input type="hidden" name="_csrf" value="{{.CsrfToken}}">
<button type="submit"
style="padding:6px 14px;background:none;border:0.5px solid #dc2626;color:#dc2626;border-radius:8px;font-size:13px;cursor:pointer;white-space:nowrap;">
Ukloni sliku
</button>
</form>
</div>
{{end}}
<div style="display:flex;gap:10px;align-items:center;flex-wrap:wrap;">
@@ -43,6 +51,7 @@
<!-- firma: naziv, podnazlov, adresa, telefon, PIB, logo zona -->
<form method="POST" action="/podesavanja/sacuvaj">
<input type="hidden" name="_csrf" value="{{.CsrfToken}}">
<input type="hidden" name="_next" value="/admin/podesavanja/opste">
<div class="kartica animiraj" style="margin-bottom:16px;">
<div style="display:flex;align-items:center;gap:10px;margin-bottom:16px;padding-bottom:12px;border-bottom:0.5px solid var(--ivica);">
@@ -87,22 +96,15 @@
</div>
</div>
<div>
<label style="font-size:13px;color:var(--tekst-sporedni);display:block;margin-bottom:8px;">Logo zona</label>
<div style="display:flex;gap:10px;flex-wrap:wrap;">
<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 or (eq .LogoTip "sa_nazivom") (eq .LogoTip "tekst") (eq .LogoTip "ikonica") (not .LogoTip)}}border-color:var(--sb-akcent);background:var(--pozadina);{{end}}">
<input type="radio" name="logo_tip" value="sa_nazivom" {{if or (eq .LogoTip "sa_nazivom") (eq .LogoTip "tekst") (eq .LogoTip "ikonica") (not .LogoTip)}}checked{{end}} style="accent-color:var(--sb-akcent);">
<span style="font-size:13px;color:var(--tekst-glavni);">Sa nazivom</span>
</label>
<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 .LogoTip "bez_naziva"}}border-color:var(--sb-akcent);background:var(--pozadina);{{end}}">
<input type="radio" name="logo_tip" value="bez_naziva" {{if eq .LogoTip "bez_naziva"}}checked{{end}} style="accent-color:var(--sb-akcent);">
<span style="font-size:13px;color:var(--tekst-glavni);">Bez naziva</span>
</label>
<label style="display:flex;align-items:center;gap:8px;padding:10px 14px;border:0.5px solid var(--ivica);border-radius:8px;flex:1;{{if eq .LogoTip "slika"}}border-color:var(--sb-akcent);background:var(--pozadina);{{end}}{{if not .LogoPutanja}}opacity:0.45;cursor:not-allowed;{{else}}cursor:pointer;{{end}}">
<input type="radio" name="logo_tip" value="slika" {{if eq .LogoTip "slika"}}checked{{end}} {{if not .LogoPutanja}}disabled{{end}} style="accent-color:var(--sb-akcent);">
<span style="font-size:13px;color:var(--tekst-glavni);">Sa logom</span>
</label>
<div style="display:flex;align-items:center;justify-content:space-between;padding:10px 14px;border:0.5px solid var(--ivica);border-radius:8px;">
<div>
<div style="font-size:13px;font-weight:500;color:var(--tekst-glavni);">Prikaži logo u gornjoj traci</div>
<div style="font-size:12px;color:var(--tekst-sporedni);">Logo slika se prikazuje pored naslova stranice</div>
</div>
<label class="toggl">
<input type="checkbox" name="topbar_logo_slika" value="1" {{if .TopbarLogoSlika}}checked{{end}}>
<span class="toggl-klizac"></span>
</label>
</div>
</div>
@@ -119,6 +121,7 @@
<!-- profil firme: pravni/poreski status (Faza 0) — određuje koji se zakonski moduli pale -->
<form method="POST" action="/podesavanja/sacuvaj">
<input type="hidden" name="_csrf" value="{{.CsrfToken}}">
<input type="hidden" name="_next" value="/admin/podesavanja/opste">
<div class="kartica animiraj" style="margin-bottom:16px;">
<div style="display:flex;align-items:center;gap:10px;margin-bottom:16px;padding-bottom:12px;border-bottom:0.5px solid var(--ivica);">
+48
View File
@@ -74,6 +74,54 @@
{{end}}
</div>
<!-- kartica: moj avatar -->
<div class="kartica animiraj" style="margin-bottom:16px;">
<div style="display:flex;align-items:center;gap:10px;margin-bottom:16px;padding-bottom:12px;border-bottom:0.5px solid var(--ivica);">
<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="var(--sb-akcent)" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M20 21v-2a4 4 0 0 0-4-4H8a4 4 0 0 0-4 4v2"/><circle cx="12" cy="7" r="4"/></svg>
<span style="font-size:15px;font-weight:500;color:var(--tekst-glavni);">Moj avatar</span>
</div>
<div style="display:flex;align-items:center;gap:16px;margin-bottom:16px;">
<div style="width:64px;height:64px;border-radius:10px;overflow:hidden;border:0.5px solid var(--ivica);flex-shrink:0;background:var(--pozadina);display:flex;align-items:center;justify-content:center;">
{{if .AvatarPutanja}}
<img src="{{.AvatarPutanja}}" alt="Moj avatar" style="width:100%;height:100%;object-fit:cover;">
{{else}}
<span style="font-size:22px;font-weight:600;color:var(--tekst-sporedni);">{{if .KorisnikIme}}{{slice .KorisnikIme 0 2}}{{else}}NT{{end}}</span>
{{end}}
</div>
<div style="font-size:13px;color:var(--tekst-sporedni);line-height:1.5;">
Slika se prikazuje kao dugme u gornjoj traci.<br>
Dozvoljeni formati: JPG, PNG, WebP. Maksimum 2 MB.
</div>
</div>
{{if .AvatarPutanja}}
<form method="POST" action="/profil/avatar/ukloni" style="display:inline;margin-bottom:12px;">
<input type="hidden" name="_csrf" value="{{.CsrfToken}}">
<button type="submit" style="background:none;border:0.5px solid #dc2626;color:#dc2626;padding:6px 14px;border-radius:8px;font-size:13px;cursor:pointer;margin-bottom:12px;">
Ukloni avatar
</button>
</form>
{{end}}
<form method="POST" action="/profil/avatar" enctype="multipart/form-data">
<input type="hidden" name="_csrf" value="{{.CsrfToken}}">
<div style="display:flex;align-items:center;gap:10px;flex-wrap:wrap;">
<input type="file" id="avatar-file" name="avatar" accept=".jpg,.jpeg,.png,.webp"
style="display:none;" onchange="document.getElementById('avatar-ime').textContent=this.files[0]?this.files[0].name:'Nijedan fajl nije izabran'">
<label for="avatar-file"
style="display:inline-flex;align-items:center;gap:6px;padding:8px 14px;border:0.5px solid var(--ivica);border-radius:8px;cursor:pointer;font-size:13px;color:var(--tekst-glavni);background:var(--pozadina);">
Izaberi sliku
</label>
<span id="avatar-ime" class="pomocni-tekst">Nijedan fajl nije izabran</span>
<button type="submit"
style="background:var(--sb-akcent);color:#fff;border:none;padding:8px 16px;border-radius:8px;font-size:13px;cursor:pointer;">
Otpremi avatar
</button>
</div>
</form>
</div>
<!-- kartica: moja pozadinska slika -->
<div class="kartica animiraj" style="margin-bottom:16px;">
<div style="display:flex;align-items:center;gap:10px;margin-bottom:16px;padding-bottom:12px;border-bottom:0.5px solid var(--ivica);">