Dodato go:embed - disk-first logika za statičke fajlove i šablone
This commit is contained in:
@@ -534,7 +534,7 @@ select {
|
||||
}
|
||||
|
||||
.animiraj {
|
||||
animation: fadeInUp 0.4s ease both;
|
||||
animation: fadeInUp 0.2s ease both;
|
||||
}
|
||||
|
||||
/* gornja traka magacina — responsive */
|
||||
|
||||
@@ -90,7 +90,7 @@
|
||||
<span class="nav-tooltip">Moj profil</span>
|
||||
</a>
|
||||
|
||||
{{if or (eq .KorisnikUloga "superadmin") (eq .KorisnikUloga "admin")}}
|
||||
{{if eq .KorisnikUloga "superadmin"}}
|
||||
<a href="/admin/korisnici" class="nav-stavka {{if eq .Stranica "admin"}}aktivan{{end}}">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M17 21v-2a4 4 0 0 0-4-4H5a4 4 0 0 0-4 4v2"/><circle cx="9" cy="7" r="4"/><path d="M23 21v-2a4 4 0 0 0-3-3.87"/><path d="M16 3.13a4 4 0 0 1 0 7.75"/></svg>
|
||||
<span>Korisnici</span>
|
||||
|
||||
@@ -38,6 +38,8 @@
|
||||
<div class="poruka-greska">Proverite unete podatke.</div>
|
||||
{{else if eq .Greska "2"}}
|
||||
<div class="poruka-greska">Greška pri čuvanju. Pokušajte ponovo.</div>
|
||||
{{else if eq .Greska "3"}}
|
||||
<div class="poruka-greska">Ova radnja nije dozvoljena.</div>
|
||||
{{end}}
|
||||
|
||||
<!-- lista korisnika -->
|
||||
@@ -62,18 +64,19 @@
|
||||
<tr class="animiraj" style="border-bottom:0.5px solid var(--ivica);">
|
||||
<td style="padding:10px 20px;font-size:14px;font-weight:500;color:var(--tekst-glavni);">{{.KorisnickoIme}}</td>
|
||||
<td style="padding:10px 20px;">
|
||||
{{if eq $.KorisnikUloga "superadmin"}}
|
||||
{{if eq .Uloga "superadmin"}}
|
||||
<span style="font-size:13px;color:var(--tekst-sporedni);">Superadmin</span>
|
||||
{{else if eq $.KorisnikUloga "superadmin"}}
|
||||
<form method="POST" action="/admin/korisnici/{{.ID}}/uloga" style="display:inline;">
|
||||
<select name="uloga" onchange="this.form.submit()"
|
||||
style="padding:4px 8px;border:0.5px solid var(--ivica);border-radius:6px;background:var(--pozadina);color:var(--tekst-glavni);font-size:12px;">
|
||||
<option value="superadmin" {{if eq .Uloga "superadmin"}}selected{{end}}>Superadmin</option>
|
||||
<option value="admin" {{if eq .Uloga "admin"}}selected{{end}}>Admin</option>
|
||||
<option value="radnik" {{if eq .Uloga "radnik"}}selected{{end}}>Radnik</option>
|
||||
</select>
|
||||
</form>
|
||||
{{else}}
|
||||
<span style="font-size:13px;color:var(--tekst-sporedni);">
|
||||
{{if eq .Uloga "superadmin"}}Superadmin{{else if eq .Uloga "admin"}}Admin{{else}}Radnik{{end}}
|
||||
{{if eq .Uloga "admin"}}Admin{{else}}Radnik{{end}}
|
||||
</span>
|
||||
{{end}}
|
||||
</td>
|
||||
@@ -106,6 +109,15 @@
|
||||
{{if .Aktivan}}Deaktiviraj{{else}}Aktiviraj{{end}}
|
||||
</button>
|
||||
</form>
|
||||
{{if eq .Uloga "radnik"}}
|
||||
<form method="POST" action="/admin/korisnici/{{.ID}}/obrisi" style="display:inline;"
|
||||
onsubmit="return confirm('Obrisati korisnika {{.KorisnickoIme}}? Ova radnja je trajna.')">
|
||||
<button type="submit"
|
||||
style="padding:5px 12px;border:0.5px solid #fca5a5;border-radius:6px;background:transparent;color:#dc2626;font-size:12px;cursor:pointer;">
|
||||
Obriši
|
||||
</button>
|
||||
</form>
|
||||
{{end}}
|
||||
{{end}}
|
||||
</td>
|
||||
</tr>
|
||||
@@ -124,12 +136,12 @@
|
||||
<div style="display:grid;grid-template-columns:repeat(auto-fit, minmax(180px, 1fr));gap:14px;margin-bottom:16px;">
|
||||
<div>
|
||||
<label style="font-size:13px;color:var(--tekst-sporedni);display:block;margin-bottom:6px;">Korisničko ime</label>
|
||||
<input type="text" name="korisnicko_ime" required minlength="3"
|
||||
<input type="text" name="korisnicko_ime" required minlength="3" autocomplete="off"
|
||||
style="width:100%;padding:8px 12px;border:0.5px solid var(--ivica);border-radius:8px;font-size:14px;background:var(--pozadina);color:var(--tekst-glavni);outline:none;">
|
||||
</div>
|
||||
<div>
|
||||
<label style="font-size:13px;color:var(--tekst-sporedni);display:block;margin-bottom:6px;">Lozinka</label>
|
||||
<input type="password" name="lozinka" required minlength="8"
|
||||
<input type="password" name="lozinka" required minlength="8" autocomplete="new-password"
|
||||
style="width:100%;padding:8px 12px;border:0.5px solid var(--ivica);border-radius:8px;font-size:14px;background:var(--pozadina);color:var(--tekst-glavni);outline:none;">
|
||||
</div>
|
||||
<div>
|
||||
@@ -138,7 +150,6 @@
|
||||
style="width:100%;padding:8px 12px;border:0.5px solid var(--ivica);border-radius:8px;font-size:14px;background:var(--pozadina);color:var(--tekst-glavni);outline:none;">
|
||||
<option value="radnik">Radnik</option>
|
||||
<option value="admin">Admin</option>
|
||||
{{if eq .KorisnikUloga "superadmin"}}<option value="superadmin">Superadmin</option>{{end}}
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
<div class="kartica animiraj" style="padding:0;overflow:hidden;">
|
||||
<div style="padding:16px 20px;border-bottom:0.5px solid var(--ivica);display:flex;align-items:center;justify-content:space-between;">
|
||||
<span style="font-size:15px;font-weight:500;color:var(--tekst-glavni);">Poslednjih 50 pokušaja</span>
|
||||
<span style="font-size:12px;color:var(--tekst-sporedni);">Vreme prikazano u UTC</span>
|
||||
<span style="font-size:12px;color:var(--tekst-sporedni);">Vreme prikazano po lokalnom vremenu servera</span>
|
||||
</div>
|
||||
|
||||
{{if .Istorija}}
|
||||
|
||||
@@ -8,6 +8,44 @@
|
||||
.animiraj:nth-child(2) { animation-delay: 0.16s; }
|
||||
.animiraj:nth-child(3) { animation-delay: 0.22s; }
|
||||
.animiraj:nth-child(4) { animation-delay: 0.28s; }
|
||||
|
||||
.toast {
|
||||
position: fixed;
|
||||
bottom: 24px;
|
||||
right: 24px;
|
||||
z-index: 9999;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
padding: 12px 18px;
|
||||
border-radius: 10px;
|
||||
font-size: 13px;
|
||||
font-weight: 500;
|
||||
box-shadow: 0 4px 20px rgba(0,0,0,0.15);
|
||||
animation: toastIn 0.3s ease forwards;
|
||||
max-width: 340px;
|
||||
}
|
||||
.toast-greska {
|
||||
background: #fef2f2;
|
||||
color: #dc2626;
|
||||
border: 0.5px solid #fca5a5;
|
||||
}
|
||||
.toast-uspeh {
|
||||
background: #f0fdf4;
|
||||
color: #16a34a;
|
||||
border: 0.5px solid #86efac;
|
||||
}
|
||||
@keyframes toastIn {
|
||||
from { opacity: 0; transform: translateY(12px); }
|
||||
to { opacity: 1; transform: translateY(0); }
|
||||
}
|
||||
@keyframes toastOut {
|
||||
from { opacity: 1; transform: translateY(0); }
|
||||
to { opacity: 0; transform: translateY(12px); }
|
||||
}
|
||||
.toast.nestaje {
|
||||
animation: toastOut 0.3s ease forwards;
|
||||
}
|
||||
</style>
|
||||
{{end}}
|
||||
|
||||
@@ -15,9 +53,10 @@
|
||||
<div style="width:100%;max-width:100%;">
|
||||
|
||||
{{if .Sacuvano}}
|
||||
<div class="poruka-uspeh">
|
||||
Podešavanja su uspešno sačuvana.
|
||||
</div>
|
||||
<div class="poruka-uspeh">Podešavanja su uspešno sačuvana.</div>
|
||||
{{end}}
|
||||
{{if .BackupVracen}}
|
||||
<div class="poruka-uspeh">Baza je uspešno obnovljena iz rezervne kopije.</div>
|
||||
{{end}}
|
||||
|
||||
<!-- upload loga — posebna forma jer je multipart, mora biti van glavne forme -->
|
||||
@@ -27,11 +66,6 @@
|
||||
<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 .LogoGreska}}
|
||||
<div style="background:rgba(207,87,87,0.1);border:0.5px solid var(--greska);border-radius:8px;padding:8px 12px;margin-bottom:10px;font-size:13px;color:var(--greska);">
|
||||
{{.LogoGreska}}
|
||||
</div>
|
||||
{{end}}
|
||||
{{if .LogoPutanja}}
|
||||
<div style="margin-bottom:12px;">
|
||||
<img src="{{.LogoPutanja}}" alt="Trenutni logo"
|
||||
@@ -150,12 +184,62 @@
|
||||
</div>
|
||||
<div style="display:flex;align-items:center;justify-content:space-between;flex-wrap:wrap;gap:12px;">
|
||||
<div style="font-size:13px;color:var(--tekst-sporedni);">Verzija programa: <span style="color:var(--tekst-glavni);font-weight:500;">{{.Verzija}}</span></div>
|
||||
<a href="/podesavanja/backup"
|
||||
style="display:inline-flex;align-items:center;gap:6px;padding:8px 16px;background:var(--kartica);border:0.5px solid var(--ivica);border-radius:8px;font-size:13px;color:var(--tekst-sporedni);text-decoration:none;transition:background 0.2s;"
|
||||
onmouseover="this.style.background='var(--pozadina)'" onmouseout="this.style.background='var(--kartica)'">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/><polyline points="7 10 12 15 17 10"/><line x1="12" y1="15" x2="12" y2="3"/></svg>
|
||||
Preuzmi backup baze
|
||||
</a>
|
||||
<div style="display:flex;gap:8px;flex-wrap:wrap;">
|
||||
<a href="/podesavanja/backup"
|
||||
style="display:inline-flex;align-items:center;gap:6px;padding:8px 16px;background:var(--kartica);border:0.5px solid var(--ivica);border-radius:8px;font-size:13px;color:var(--tekst-sporedni);text-decoration:none;transition:background 0.2s;"
|
||||
onmouseover="this.style.background='var(--pozadina)'" onmouseout="this.style.background='var(--kartica)'">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/><polyline points="7 10 12 15 17 10"/><line x1="12" y1="15" x2="12" y2="3"/></svg>
|
||||
Preuzmi backup baze
|
||||
</a>
|
||||
<button type="button" onclick="toggleBackupPanel()"
|
||||
style="display:inline-flex;align-items:center;gap:6px;padding:8px 16px;background:var(--kartica);border:0.5px solid var(--ivica);border-radius:8px;font-size:13px;color:var(--tekst-sporedni);cursor:pointer;transition:background 0.2s;"
|
||||
onmouseover="this.style.background='var(--pozadina)'" onmouseout="this.style.background='var(--kartica)'">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/><polyline points="7 10 12 15 17 10"/><polyline points="7 5 12 10 17 5"/></svg>
|
||||
Vrati backup baze
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- panel sa listom backupa -->
|
||||
<div id="backup-panel" style="display:none;margin-top:16px;border-top:0.5px solid var(--ivica);padding-top:16px;">
|
||||
<div style="font-size:13px;font-weight:500;color:var(--tekst-glavni);margin-bottom:10px;">Dostupne rezervne kopije</div>
|
||||
{{if .Backupi}}
|
||||
<div style="overflow-x:auto;">
|
||||
<table style="width:100%;border-collapse:collapse;font-size:13px;">
|
||||
<thead>
|
||||
<tr style="border-bottom:0.5px solid var(--ivica);">
|
||||
<th style="padding:8px 12px;text-align:left;font-weight:500;color:var(--tekst-sporedni);">Naziv fajla</th>
|
||||
<th style="padding:8px 12px;text-align:left;font-weight:500;color:var(--tekst-sporedni);">Datum</th>
|
||||
<th style="padding:8px 12px;text-align:right;font-weight:500;color:var(--tekst-sporedni);">Veličina</th>
|
||||
<th style="padding:8px 12px;text-align:right;font-weight:500;color:var(--tekst-sporedni);"></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{{range .Backupi}}
|
||||
<tr style="border-bottom:0.5px solid var(--ivica);">
|
||||
<td style="padding:8px 12px;color:var(--tekst-glavni);font-family:monospace;font-size:12px;">{{.Ime}}</td>
|
||||
<td style="padding:8px 12px;color:var(--tekst-sporedni);">{{.Datum}}</td>
|
||||
<td style="padding:8px 12px;text-align:right;color:var(--tekst-sporedni);">{{.Velicina}}</td>
|
||||
<td style="padding:8px 12px;text-align:right;">
|
||||
<form method="POST" action="/podesavanja/backup/vrati"
|
||||
onsubmit="return confirm('Vratiti bazu na stanje od: {{.Datum}}?\n\nTrenutna baza će biti automatski sačuvana pre obnove.')">
|
||||
<input type="hidden" name="ime" value="{{.Ime}}">
|
||||
<button type="submit"
|
||||
style="padding:4px 12px;background:transparent;border:0.5px solid #fca5a5;border-radius:6px;color:#dc2626;font-size:12px;cursor:pointer;">
|
||||
Vrati
|
||||
</button>
|
||||
</form>
|
||||
</td>
|
||||
</tr>
|
||||
{{end}}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
{{else}}
|
||||
<div style="padding:20px;text-align:center;color:var(--tekst-sporedni);font-size:13px;">
|
||||
Nema dostupnih rezervnih kopija.
|
||||
</div>
|
||||
{{end}}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -170,4 +254,28 @@
|
||||
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
function toggleBackupPanel() {
|
||||
var p = document.getElementById('backup-panel');
|
||||
p.style.display = p.style.display === 'none' ? 'block' : 'none';
|
||||
}
|
||||
</script>
|
||||
|
||||
{{if .LogoGreska}}
|
||||
<div id="toast-logo" class="toast toast-greska">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" style="flex-shrink:0;"><circle cx="12" cy="12" r="10"/><line x1="12" y1="8" x2="12" y2="12"/><line x1="12" y1="16" x2="12.01" y2="16"/></svg>
|
||||
{{.LogoGreska}}
|
||||
</div>
|
||||
<script>
|
||||
(function() {
|
||||
var t = document.getElementById('toast-logo');
|
||||
if (!t) return;
|
||||
setTimeout(function() {
|
||||
t.classList.add('nestaje');
|
||||
setTimeout(function() { t.remove(); }, 300);
|
||||
}, 4000);
|
||||
})();
|
||||
</script>
|
||||
{{end}}
|
||||
{{end}}
|
||||
|
||||
Reference in New Issue
Block a user