Servis forma, animacije, hover efekti i pojačane senke

Servis:
- Nova polja: ostecenja, pin_uredjaja, pribor (migracija 051)
- Default garancija iz podešavanja, svič "Bez garancije" u formi
- Podešavanja → Servis: konfigurabilan rok garancije (migracija 052)
- Default datum prijema = danas; datum_prijema se eksplicitno upisuje
- Sidebar link za Servis podešavanja
PDV/Nivelacije:
- Default raspon datuma = početak/kraj tekućeg meseca (KIR, KPR, Nivelacije)
- Dodata class="tabela" na tabele bez klase (KIR, KPR, Obračun, Nivelacije)
Animacije (Moj profil → Tema):
- Korisnik bira vrstu animacije: bez, fadeInUp, fadeIn, scaleIn, slideLeft
- Čuva se po korisniku u korisnici.lokalna_animacija (migracija 053)
- CSS [data-animacija] radi na body (globalno) i na preview wrapperima (izolovano)
- Preview animacije izolovan: data-animacija na #anim-preview-wrap, ne na body
- Mobilne kartice se animiraju kad korisnik odabere stil (podrazumevano ne)
- Animacija primenjena direktno na .tabela tbody tr (bez potrebe za .animiraj)
Hover efekti (Moj profil → Tema):
- Opcije: podrazumevano, bez, podizanje, svetlost, zoom, boja
- Čuva se po korisniku u korisnici.lokalni_hover (migracija 054)
- CSS [data-hover] radi izolovano; preview menja samo #hover-preview-wrap
- Pojačane senke u oba teme (--senka i nova --senka-hover promenljiva)
- Transition dodat za transform i background na karticama
Grafikon (Izveštaji): toggle zamenjen globalnim .toggl/.toggl-klizac svičom
This commit is contained in:
2026-06-18 02:21:06 +02:00
parent 5518d2071c
commit 9e76e10307
36 changed files with 707 additions and 53 deletions
+30
View File
@@ -43,6 +43,7 @@ type PodaciPodesavanja struct {
BackupIntervalSati string
BackupBrojKopija string
KalkulacijaMarza string
ServisGarancijaMeseci string
LoginPozadina string
LoginPozadinaOpacity string
LoginPozadinaBlurPozadine string
@@ -314,6 +315,20 @@ func (h *Handler) SacuvajPodesavanja(w http.ResponseWriter, r *http.Request) {
}
}
// podrazumevani rok garancije za servis (meseci, 0120)
if v := strings.TrimSpace(r.FormValue("servis_garancija_meseci")); v != "" {
n, err := strconv.Atoi(v)
if err != nil || n < 0 || n > 120 {
middleware.SetFlash(w, r, h.DB, "greska", "Rok garancije mora biti broj između 0 i 120 meseci.")
http.Redirect(w, r, sledeci, http.StatusSeeOther)
return
}
if err := ntechsqlite.SacuvajPodesavanje(r.Context(), h.DB, "servis_garancija_meseci", strconv.Itoa(n)); err != nil {
http.Error(w, "Greška pri čuvanju podešavanja", http.StatusInternalServerError)
return
}
}
http.Redirect(w, r, sledeci+"?sacuvano=1", http.StatusSeeOther)
}
@@ -438,6 +453,20 @@ func (h *Handler) UkloniLogo(w http.ResponseWriter, r *http.Request) {
http.Redirect(w, r, "/admin/podesavanja/opste?sacuvano=1", http.StatusSeeOther)
}
// PodesavanjaServis renderuje stranicu sa podešavanjima servisnog modula
func (h *Handler) PodesavanjaServis(w http.ResponseWriter, r *http.Request) {
if _, ok := h.zahtevajDozvolu(w, r, "podesavanja.pregled"); !ok {
return
}
podaci, err := h.napuniPodaciPodesavanja(r, "Podešavanja — Servis")
if err != nil {
http.Error(w, "Greška pri učitavanju podešavanja", http.StatusInternalServerError)
return
}
podaci.Stranica = "podesavanja-servis"
h.renderujTemplate(w, "podesavanja_servis", podaci)
}
// generisiImeUploada vraća slučajno hex ime (16 bajtova) sa datom ekstenzijom
func generisiImeUploada(ext string) (string, error) {
buf := make([]byte, 16)
@@ -669,6 +698,7 @@ func (h *Handler) napuniPodaciPodesavanja(r *http.Request, naslov string) (Podac
BackupIntervalSati: vrednostIliDefault(podesavanja, "backup_interval_sati", "24"),
BackupBrojKopija: vrednostIliDefault(podesavanja, "backup_broj_kopija", "7"),
KalkulacijaMarza: vrednostIliDefault(podesavanja, "kalkulacija_marza", "20"),
ServisGarancijaMeseci: vrednostIliDefault(podesavanja, "servis_garancija_meseci", "2"),
}, nil
}