Flash poruke: toast notifikacije umesto ?greska= i ?sacuvano= u URL-u

This commit is contained in:
2026-06-05 23:15:49 +02:00
parent 2b3636528f
commit 9af712edd3
10 changed files with 267 additions and 116 deletions
+77
View File
@@ -583,3 +583,80 @@ select {
min-width: 200px;
flex-wrap: wrap;
}
/* flash toast — jednokratna poruka u gornjem desnom uglu */
@keyframes flashUlaz {
from { opacity: 0; transform: translateX(20px); }
to { opacity: 1; transform: translateX(0); }
}
@keyframes flashIzlaz {
from { opacity: 1; transform: translateX(0); }
to { opacity: 0; transform: translateX(20px); }
}
.flash-toast {
position: fixed;
top: 20px;
right: 20px;
z-index: 9999;
display: flex;
align-items: center;
gap: 10px;
padding: 12px 16px;
border-radius: 10px;
font-size: 14px;
max-width: 380px;
box-shadow: 0 4px 16px rgba(0,0,0,0.12);
animation: flashUlaz 0.3s ease forwards;
}
.flash-toast.flash-izlaz {
animation: flashIzlaz 0.35s ease forwards;
}
.flash-toast.flash-uspeh {
background: #f0fdf4;
color: #15803d;
border: 0.5px solid #bbf7d0;
}
.flash-toast.flash-greska {
background: #fef2f2;
color: #dc2626;
border: 0.5px solid #fecaca;
}
.flash-ikona {
font-weight: 700;
font-size: 15px;
flex-shrink: 0;
}
.flash-tekst {
flex: 1;
line-height: 1.4;
}
.flash-zatvori {
background: none;
border: none;
cursor: pointer;
font-size: 18px;
line-height: 1;
color: inherit;
opacity: 0.6;
padding: 0 0 0 4px;
flex-shrink: 0;
}
.flash-zatvori:hover { opacity: 1; }
@media (max-width: 480px) {
.flash-toast {
top: auto;
bottom: 20px;
right: 12px;
left: 12px;
max-width: none;
}
}
@@ -30,13 +30,6 @@
{{define "sadrzaj"}}
<div style="display:flex;flex-direction:column;gap:20px;">
{{if .Sacuvano}}
<div class="poruka-uspeh">Promene su uspešno sačuvane.</div>
{{end}}
{{if .Greska}}
<div class="poruka-greska">Greška pri čuvanju promena.</div>
{{end}}
<!-- matrica dozvola — editabilna forma -->
<div class="kartica animiraj" style="padding:0;overflow:hidden;">
<div style="padding:14px 16px;border-bottom:0.5px solid var(--ivica);">
@@ -26,18 +26,6 @@
{{define "sadrzaj"}}
<div style="display:flex;flex-direction:column;gap:16px;">
{{if .Sacuvano}}
<div class="poruka-uspeh poruka-animacija">Promene su uspešno sačuvane.</div>
{{end}}
{{if eq .Greska "1"}}
<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 -->
<div class="kartica animiraj" style="padding:0;overflow:hidden;">
<div style="padding:16px 20px;border-bottom:0.5px solid var(--ivica);">
-14
View File
@@ -14,26 +14,12 @@
{{define "sadrzaj"}}
<div style="display:flex;flex-direction:column;gap:16px;max-width:560px;">
{{if eq .Sacuvano "lozinka"}}
<div class="poruka-uspeh">Lozinka je uspešno promenjena.</div>
{{else if eq .Sacuvano "totp"}}
<div class="poruka-uspeh">Dvostepena verifikacija je uspešno uključena.</div>
{{else if eq .Sacuvano "totp_off"}}
<div class="poruka-uspeh">Dvostepena verifikacija je isključena.</div>
{{end}}
<!-- promena lozinke -->
<div class="kartica animiraj">
<div style="font-size:15px;font-weight:500;color:var(--tekst-glavni);margin-bottom:16px;padding-bottom:12px;border-bottom:0.5px solid var(--ivica);">
Promena lozinke
</div>
{{if eq .Greska "lozinka"}}
<div class="poruka-greska" style="margin-bottom:14px;">Stara lozinka nije ispravna.</div>
{{else if eq .Greska "lozinka2"}}
<div class="poruka-greska" style="margin-bottom:14px;">Nova lozinka mora imati najmanje 8 karaktera i lozinke moraju biti iste.</div>
{{end}}
<form method="POST" action="/admin/profil/lozinka">
<div style="display:flex;flex-direction:column;gap:12px;">
<div>
@@ -36,6 +36,25 @@
</div>
</div>
<!-- flash poruka — prikazuje se kao toast u gornjem desnom uglu -->
{{if .Flash}}
<div id="flash-toast" class="flash-toast flash-{{.Flash.Tip}}" role="alert">
<span class="flash-ikona">{{if eq .Flash.Tip "uspeh"}}✓{{else}}!{{end}}</span>
<span class="flash-tekst">{{.Flash.Poruka}}</span>
<button class="flash-zatvori" onclick="this.parentElement.remove()" aria-label="Zatvori">×</button>
</div>
<script>
(function() {
var t = document.getElementById('flash-toast');
if (!t) return;
setTimeout(function() {
t.classList.add('flash-izlaz');
setTimeout(function() { if (t.parentElement) t.remove(); }, 350);
}, 4000);
})();
</script>
{{end}}
<!-- alpine.js za interaktivnost -->
<script
src="https://cdn.jsdelivr.net/npm/alpinejs@3.x.x/dist/cdn.min.js"