UI: toast notifikacije umesto zelene kartice na vrhu stranice

Poruke o uspehu (.poruka-uspeh) konvertuju se u toast obaveštenje
u donjem desnom uglu — animacija ulaska, nestaje posle 4 sekunde,
klik za brže zatvaranje; JS sakriva original odmah pri učitavanju
This commit is contained in:
2026-06-20 01:38:42 +02:00
parent 32d7813be6
commit 880456a5ba
2 changed files with 40 additions and 2 deletions
+5 -2
View File
@@ -752,6 +752,9 @@ select {
min-width: 0;
}
/* kad JS radi, .poruka-uspeh se konvertuje u toast — sakrivamo odmah da ne treptne */
.js-on .poruka-uspeh { display: none !important; }
/* poruka o uspehu — konzistentna za sve teme */
.poruka-uspeh {
background: var(--poruka-uspeh-bg);
@@ -790,8 +793,8 @@ select {
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; }
.toast-greska { background: rgba(207, 87, 87, 0.12); color: var(--greska); border: 0.5px solid var(--greska); }
.toast-uspeh { background: var(--poruka-uspeh-bg); color: var(--poruka-uspeh-boja); border: 0.5px solid var(--poruka-uspeh-boja); }
.toast.nestaje { animation: toastOut 0.3s ease forwards; }
@keyframes toastIn {
from { opacity: 0; transform: translateY(12px); }
@@ -12,6 +12,8 @@
if (window.innerWidth > 768 && localStorage.getItem('sidebar-skupljen') === 'true') {
document.documentElement.classList.add('sidebar-init-skupljen');
}
// sakriva poruke-uspeha odmah da ne trepnu pre toast konverzije
document.documentElement.classList.add('js-on');
</script>
<!-- tema — učitava se prva -->
@@ -271,7 +273,40 @@
window._ntechPotvrdi = prikaziModal;
})();
// toast obaveštenja — prikazuje poruku u uglu ekrana, nestaje posle 4s
window.ntechToast = function(tekst, tip) {
var t = document.createElement('div');
t.className = 'toast ' + (tip === 'greska' ? 'toast-greska' : 'toast-uspeh');
// ikonica
var svg = tip === 'greska'
? '<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" viewBox="0 0 24 24"><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>'
: '<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round" viewBox="0 0 24 24"><polyline points="20 6 9 17 4 12"/></svg>';
t.innerHTML = svg + '<span>' + tekst + '</span>';
// prilagođavamo poziciju za mobilne uređaje
t.style.bottom = '24px';
t.style.right = '16px';
document.body.appendChild(t);
var ukloni = function() {
t.classList.add('nestaje');
setTimeout(function() { if (t.parentNode) t.parentNode.removeChild(t); }, 320);
};
t.addEventListener('click', ukloni);
setTimeout(ukloni, 4000);
};
// konvertuje sve .poruka-uspeh u toast i sklanja original
function ntechKonvertujPoruke() {
document.querySelectorAll('.poruka-uspeh').forEach(function(el) {
if (el.dataset.toastPrikazan) return;
el.dataset.toastPrikazan = '1';
var tekst = el.textContent.trim();
el.style.display = 'none';
if (tekst) window.ntechToast(tekst, 'uspeh');
});
}
function ntechInicijalizuj() {
ntechKonvertujPoruke();
var m = document.querySelector('meta[name="csrf-token"]');
if (m && m.content) {
document.querySelectorAll('form[method="POST"],form[method="post"]').forEach(function(f) {