diff --git a/cmd/ntech/main.go b/cmd/ntech/main.go index dd60fbe..3c02549 100644 --- a/cmd/ntech/main.go +++ b/cmd/ntech/main.go @@ -156,14 +156,9 @@ func main() { r.Post("/podesavanja/login-pozadina", h.OtpremiLoginPozadinu) r.Post("/podesavanja/login-pozadina/ukloni", h.UkloniLoginPozadinu) r.Post("/podesavanja/login-pozadina/stilovi", h.SacuvajLoginPozadinaStilove) - r.Post("/podesavanja/app-pozadina", h.OtpremiAppPozadinu) - r.Post("/podesavanja/app-pozadina/ukloni", h.UkloniAppPozadinu) - r.Post("/podesavanja/app-pozadina/stilovi", h.SacuvajAppPozadinaStilove) + r.Get("/podesavanja/backup", h.BackupBaze) r.Post("/podesavanja/backup/vrati", h.VratiBackup) - r.Get("/tema/{tema}", h.PromeniTemu) - r.Post("/podesavanja/tema", h.PromeniGlobalnuTemu) - r.Post("/podesavanja/tema/globalno", h.PrimeniGlobalnuTemu) r.Get("/magacin", h.Magacin) r.Get("/magacin/novi", h.NoviArtikal) r.Post("/magacin/novi", h.SacuvajArtikal) diff --git a/internal/db/repository.go b/internal/db/repository.go index e7bb78c..4e34793 100644 --- a/internal/db/repository.go +++ b/internal/db/repository.go @@ -87,7 +87,7 @@ type KorisniciRepository interface { PromeniLozinku(ctx context.Context, id int64, hash string) error SacuvajTotpTajnu(ctx context.Context, id int64, tajna string) error SacuvajLokalnuTemu(ctx context.Context, id int64, lokalnaTema string, koristi bool) error - SacuvajLokalnuPozadinu(ctx context.Context, id int64, pozadina, opacity, blur, blurPozadine string) error + SacuvajLokalnuPozadinu(ctx context.Context, id int64, pozadina, opacity, blur, blurPozadine, glassOpacity string) error PostojiIjedan(ctx context.Context) (bool, error) Obrisi(ctx context.Context, id int64) error } diff --git a/internal/db/sqlite/korisnici.go b/internal/db/sqlite/korisnici.go index b691a4c..8edc9e6 100644 --- a/internal/db/sqlite/korisnici.go +++ b/internal/db/sqlite/korisnici.go @@ -31,17 +31,19 @@ func (r *sqliteKorisniciRepo) DohvatiPoImenu(ctx context.Context, korisnickoIme k := &model.Korisnik{} var aktivan, koristiLokalnuTemu int var totpTajna, lokalnaTema sql.NullString - var lokalnaPozadina, lokalnaPozadinaOpacity, lokalnaPozadinaBlur, lokalnaPozadinaBlurPozadine sql.NullString + var lokalnaPozadina, lokalnaPozadinaOpacity, lokalnaPozadinaBlur, lokalnaPozadinaBlurPozadine, lokalnaPozadinaGlassOpacity sql.NullString var datumKreiranja time.Time err := r.db.QueryRowContext(ctx, `SELECT id, korisnicko_ime, lozinka_hash, uloga, aktivan, COALESCE(totp_tajna, ''), COALESCE(lokalna_tema, ''), koristi_lokalnu_temu, datum_kreiranja, COALESCE(lokalna_pozadina, ''), COALESCE(lokalna_pozadina_opacity, '50'), - COALESCE(lokalna_pozadina_blur, '12'), COALESCE(lokalna_pozadina_blur_pozadine, '0') + COALESCE(lokalna_pozadina_blur, '12'), COALESCE(lokalna_pozadina_blur_pozadine, '0'), + COALESCE(lokalna_pozadina_glass_opacity, '10') FROM korisnici WHERE korisnicko_ime = ?`, korisnickoIme). Scan(&k.ID, &k.KorisnickoIme, &k.LozinkaHash, &k.Uloga, &aktivan, &totpTajna, &lokalnaTema, &koristiLokalnuTemu, &datumKreiranja, - &lokalnaPozadina, &lokalnaPozadinaOpacity, &lokalnaPozadinaBlur, &lokalnaPozadinaBlurPozadine) + &lokalnaPozadina, &lokalnaPozadinaOpacity, &lokalnaPozadinaBlur, &lokalnaPozadinaBlurPozadine, + &lokalnaPozadinaGlassOpacity) if err != nil { return nil, fmt.Errorf("ntech: korisnici.DohvatiPoImenu: %w", err) } @@ -54,6 +56,7 @@ func (r *sqliteKorisniciRepo) DohvatiPoImenu(ctx context.Context, korisnickoIme k.LokalnaPozadinaOpacity = lokalnaPozadinaOpacity.String k.LokalnaPozadinaBlur = lokalnaPozadinaBlur.String k.LokalnaPozadinaBlurPozadine = lokalnaPozadinaBlurPozadine.String + k.LokalnaPozadinaGlassOpacity = lokalnaPozadinaGlassOpacity.String return k, nil } @@ -61,17 +64,19 @@ func (r *sqliteKorisniciRepo) DohvatiPoID(ctx context.Context, id int64) (*model k := &model.Korisnik{} var aktivan, koristiLokalnuTemu int var lokalnaTema sql.NullString - var lokalnaPozadina, lokalnaPozadinaOpacity, lokalnaPozadinaBlur, lokalnaPozadinaBlurPozadine sql.NullString + var lokalnaPozadina, lokalnaPozadinaOpacity, lokalnaPozadinaBlur, lokalnaPozadinaBlurPozadine, lokalnaPozadinaGlassOpacity sql.NullString var datumKreiranja time.Time err := r.db.QueryRowContext(ctx, `SELECT id, korisnicko_ime, lozinka_hash, uloga, aktivan, COALESCE(totp_tajna, ''), COALESCE(lokalna_tema, ''), koristi_lokalnu_temu, datum_kreiranja, COALESCE(lokalna_pozadina, ''), COALESCE(lokalna_pozadina_opacity, '50'), - COALESCE(lokalna_pozadina_blur, '12'), COALESCE(lokalna_pozadina_blur_pozadine, '0') + COALESCE(lokalna_pozadina_blur, '12'), COALESCE(lokalna_pozadina_blur_pozadine, '0'), + COALESCE(lokalna_pozadina_glass_opacity, '10') FROM korisnici WHERE id = ?`, id). Scan(&k.ID, &k.KorisnickoIme, &k.LozinkaHash, &k.Uloga, &aktivan, &k.TotpTajna, &lokalnaTema, &koristiLokalnuTemu, &datumKreiranja, - &lokalnaPozadina, &lokalnaPozadinaOpacity, &lokalnaPozadinaBlur, &lokalnaPozadinaBlurPozadine) + &lokalnaPozadina, &lokalnaPozadinaOpacity, &lokalnaPozadinaBlur, &lokalnaPozadinaBlurPozadine, + &lokalnaPozadinaGlassOpacity) if err != nil { return nil, fmt.Errorf("ntech: korisnici.DohvatiPoID: %w", err) } @@ -83,6 +88,7 @@ func (r *sqliteKorisniciRepo) DohvatiPoID(ctx context.Context, id int64) (*model k.LokalnaPozadinaOpacity = lokalnaPozadinaOpacity.String k.LokalnaPozadinaBlur = lokalnaPozadinaBlur.String k.LokalnaPozadinaBlurPozadine = lokalnaPozadinaBlurPozadine.String + k.LokalnaPozadinaGlassOpacity = lokalnaPozadinaGlassOpacity.String return k, nil } @@ -91,7 +97,8 @@ func (r *sqliteKorisniciRepo) Lista(ctx context.Context) ([]model.Korisnik, erro `SELECT id, korisnicko_ime, lozinka_hash, uloga, aktivan, COALESCE(totp_tajna, ''), COALESCE(lokalna_tema, ''), koristi_lokalnu_temu, datum_kreiranja, COALESCE(lokalna_pozadina, ''), COALESCE(lokalna_pozadina_opacity, '50'), - COALESCE(lokalna_pozadina_blur, '12'), COALESCE(lokalna_pozadina_blur_pozadine, '0') + COALESCE(lokalna_pozadina_blur, '12'), COALESCE(lokalna_pozadina_blur_pozadine, '0'), + COALESCE(lokalna_pozadina_glass_opacity, '10') FROM korisnici ORDER BY datum_kreiranja ASC`) if err != nil { return nil, fmt.Errorf("ntech: korisnici.Lista: %w", err) @@ -102,11 +109,12 @@ func (r *sqliteKorisniciRepo) Lista(ctx context.Context) ([]model.Korisnik, erro var k model.Korisnik var aktivan, koristiLokalnuTemu int var lokalnaTema sql.NullString - var lokalnaPozadina, lokalnaPozadinaOpacity, lokalnaPozadinaBlur, lokalnaPozadinaBlurPozadine sql.NullString + var lokalnaPozadina, lokalnaPozadinaOpacity, lokalnaPozadinaBlur, lokalnaPozadinaBlurPozadine, lokalnaPozadinaGlassOpacity sql.NullString var datumKreiranja time.Time if err := rows.Scan(&k.ID, &k.KorisnickoIme, &k.LozinkaHash, &k.Uloga, &aktivan, &k.TotpTajna, &lokalnaTema, &koristiLokalnuTemu, &datumKreiranja, - &lokalnaPozadina, &lokalnaPozadinaOpacity, &lokalnaPozadinaBlur, &lokalnaPozadinaBlurPozadine); err != nil { + &lokalnaPozadina, &lokalnaPozadinaOpacity, &lokalnaPozadinaBlur, &lokalnaPozadinaBlurPozadine, + &lokalnaPozadinaGlassOpacity); err != nil { return nil, fmt.Errorf("ntech: korisnici.Lista: %w", err) } k.Aktivan = aktivan == 1 @@ -117,15 +125,16 @@ func (r *sqliteKorisniciRepo) Lista(ctx context.Context) ([]model.Korisnik, erro k.LokalnaPozadinaOpacity = lokalnaPozadinaOpacity.String k.LokalnaPozadinaBlur = lokalnaPozadinaBlur.String k.LokalnaPozadinaBlurPozadine = lokalnaPozadinaBlurPozadine.String + k.LokalnaPozadinaGlassOpacity = lokalnaPozadinaGlassOpacity.String lista = append(lista, k) } return lista, nil } -func (r *sqliteKorisniciRepo) SacuvajLokalnuPozadinu(ctx context.Context, id int64, pozadina, opacity, blur, blurPozadine string) error { +func (r *sqliteKorisniciRepo) SacuvajLokalnuPozadinu(ctx context.Context, id int64, pozadina, opacity, blur, blurPozadine, glassOpacity string) error { _, err := r.db.ExecContext(ctx, - `UPDATE korisnici SET lokalna_pozadina = ?, lokalna_pozadina_opacity = ?, lokalna_pozadina_blur = ?, lokalna_pozadina_blur_pozadine = ? WHERE id = ?`, - pozadina, opacity, blur, blurPozadine, id) + `UPDATE korisnici SET lokalna_pozadina = ?, lokalna_pozadina_opacity = ?, lokalna_pozadina_blur = ?, lokalna_pozadina_blur_pozadine = ?, lokalna_pozadina_glass_opacity = ? WHERE id = ?`, + pozadina, opacity, blur, blurPozadine, glassOpacity, id) if err != nil { return fmt.Errorf("ntech: korisnici.SacuvajLokalnuPozadinu: %w", err) } diff --git a/internal/handler/admin.go b/internal/handler/admin.go index 8fadd01..5efb5f8 100644 --- a/internal/handler/admin.go +++ b/internal/handler/admin.go @@ -33,19 +33,17 @@ type podaciAdminProfil struct { TotpAktivan bool LokalnaTema string KoristiLokalnuTemu bool - GlobalnaTema string } type podaciProfilTema struct { model.PodaciStranice LokalnaTema string KoristiLokalnuTemu bool - KoristiGlobalnuTemu bool // !KoristiLokalnuTemu — za Alpine.js svič "Koristi globalnu temu" - GlobalnaTema string LokalnaPozadina string LokalnaPozadinaOpacity string LokalnaPozadinaBlur string LokalnaPozadinaBlurPozadine string + LokalnaPozadinaGlassOpacity string } // AdminKorisnici prikazuje listu korisnika @@ -304,7 +302,6 @@ func (h *Handler) AdminProfil(w http.ResponseWriter, r *http.Request) { TotpAktivan: svezi.TotpTajna != "", LokalnaTema: svezi.LokalnaTema, KoristiLokalnuTemu: svezi.KoristiLokalnuTemu, - GlobalnaTema: podesavanja["globalna_tema"], }) } @@ -561,13 +558,20 @@ func (h *Handler) AdminDozvole(w http.ResponseWriter, r *http.Request) { ps.Stranica = "dozvole" ps.NaslovStranice = "Dozvole" + dozvoleAdmin := map[string]bool{} + dozvoleSuperadmin := map[string]bool{} + if k.Uloga == "superadmin" { + dozvoleAdmin = h.DozvoleRepo.SveDozvole(r.Context(), "admin") + dozvoleSuperadmin = h.DozvoleRepo.SveDozvole(r.Context(), "superadmin") + } + h.renderujTemplate(w, "admin_dozvole", podaciAdminDozvole{ PodaciStranice: ps, Korisnici: lista, TrenutniID: k.ID, DozvoleRadnik: h.DozvoleRepo.SveDozvole(r.Context(), "radnik"), - DozvoleAdmin: h.DozvoleRepo.SveDozvole(r.Context(), "admin"), - DozvoleSuperadmin: h.DozvoleRepo.SveDozvole(r.Context(), "superadmin"), + DozvoleAdmin: dozvoleAdmin, + DozvoleSuperadmin: dozvoleSuperadmin, }) } @@ -644,8 +648,12 @@ func (h *Handler) AdminDozvoleSacuvaj(w http.ResponseWriter, r *http.Request) { http.Redirect(w, r, "/admin/dozvole", http.StatusSeeOther) return } - // čuvamo dozvole samo za radnik i admin — superadmin uvek ima sve - for _, uloga := range []string{"radnik", "admin"} { + // čuvamo dozvole: superadmin menja radnik i admin, admin menja samo radnik + uloge := []string{"radnik", "admin"} + if k.Uloga != "superadmin" { + uloge = []string{"radnik"} + } + for _, uloga := range uloge { for _, akcija := range middleware.SveAkcije() { kljuc := uloga + "__" + akcija dozvoljeno := r.FormValue(kljuc) == "on" diff --git a/internal/handler/handler.go b/internal/handler/handler.go index 6b26d2c..83906d0 100644 --- a/internal/handler/handler.go +++ b/internal/handler/handler.go @@ -74,15 +74,8 @@ func (h *Handler) reinicijalzijRepozitorijume(novaDB *sql.DB) { // popuniPodaciStranice popunjava zajednička polja stranice uključujući prijavljenog korisnika func (h *Handler) popuniPodaciStranice(r *http.Request, podesavanja map[string]string) model.PodaciStranice { - // redosled prioriteta teme: pozadinska slika → lokalna → globalna → fallback - globalnaTema := podesavanja["globalna_tema"] - if globalnaTema == "" { - globalnaTema = podesavanja["tema"] - } - if globalnaTema == "" { - globalnaTema = "tamna" - } - tema := globalnaTema + // podrazumevana tema je tamna; korisnik može imati svoju lokalnu temu + tema := "tamna" ps := model.PodaciStranice{ Tema: tema, @@ -99,8 +92,8 @@ func (h *Handler) popuniPodaciStranice(r *http.Request, podesavanja map[string]s ps.KorisnikIme = k.KorisnickoIme ps.KorisnikUloga = k.Uloga ps.Dozvole = h.DozvoleRepo.SveDozvole(r.Context(), k.Uloga) - // lokalna tema korisnika - if k.KoristiLokalnuTemu && k.LokalnaTema != "" { + // lokalna tema korisnika — primenjuje se uvek kada je postavljena, bez obzira na KoristiLokalnuTemu + if k.LokalnaTema != "" { ps.Tema = k.LokalnaTema } } @@ -108,10 +101,10 @@ func (h *Handler) popuniPodaciStranice(r *http.Request, podesavanja map[string]s ps.Flash = middleware.GetFlash(r, h.DB) // logika pozadine: - // - lična pozadina (samo kada je lokalni režim aktivan) → zamenjuje globalnu + // - lična pozadina → uvek se prikazuje i forsira tamnu temu, bez obzira na KoristiLokalnuTemu // - globalna pozadina → prikazuje se svima koji nemaju ličnu - // KoristiLokalnuTemu utiče na izbor tamne/svetle teme, ne na vidljivost pozadine - if korisnik != nil && korisnik.KoristiLokalnuTemu && korisnik.LokalnaPozadina != "" { + // KoristiLokalnuTemu i LokalnaTema važe samo kada nema lične pozadine + if korisnik != nil && korisnik.LokalnaPozadina != "" { ps.AppPozadina = korisnik.LokalnaPozadina ps.Tema = "tamna" ps.AppPozadinaOpacity = korisnik.LokalnaPozadinaOpacity @@ -126,38 +119,9 @@ func (h *Handler) popuniPodaciStranice(r *http.Request, podesavanja map[string]s if ps.AppPozadinaBlurPozadine == "" { ps.AppPozadinaBlurPozadine = "0" } - } else { - ps.AppPozadina = podesavanja["app_pozadina"] - if ps.AppPozadina != "" { - // globalna pozadina forsira tamnu temu, osim ako korisnik ima aktivnu lokalnu temu - if korisnik == nil || !korisnik.KoristiLokalnuTemu { - ps.Tema = "tamna" - } - ps.AppPozadinaOpacity = podesavanja["app_pozadina_opacity"] - if ps.AppPozadinaOpacity == "" { - ps.AppPozadinaOpacity = "50" - } - ps.AppPozadinaBlur = podesavanja["app_pozadina_blur"] - if ps.AppPozadinaBlur == "" { - ps.AppPozadinaBlur = "12" - } - ps.AppPozadinaBlurPozadine = podesavanja["app_pozadina_blur_pozadine"] - if ps.AppPozadinaBlurPozadine == "" { - ps.AppPozadinaBlurPozadine = "0" - } - } else { - ps.AppPozadinaOpacity = podesavanja["app_pozadina_opacity"] - if ps.AppPozadinaOpacity == "" { - ps.AppPozadinaOpacity = "50" - } - ps.AppPozadinaBlur = podesavanja["app_pozadina_blur"] - if ps.AppPozadinaBlur == "" { - ps.AppPozadinaBlur = "12" - } - ps.AppPozadinaBlurPozadine = podesavanja["app_pozadina_blur_pozadine"] - if ps.AppPozadinaBlurPozadine == "" { - ps.AppPozadinaBlurPozadine = "0" - } + ps.AppPozadinaGlassOpacity = korisnik.LokalnaPozadinaGlassOpacity + if ps.AppPozadinaGlassOpacity == "" { + ps.AppPozadinaGlassOpacity = "10" } } diff --git a/internal/handler/podesavanja.go b/internal/handler/podesavanja.go index 53ea3a2..d07fa5f 100644 --- a/internal/handler/podesavanja.go +++ b/internal/handler/podesavanja.go @@ -18,8 +18,6 @@ import ( ntechsqlite "ntech/internal/db/sqlite" "ntech/internal/middleware" "ntech/internal/model" - - "github.com/go-chi/chi/v5" ) // PodaciPodesavanja su podaci za stranicu podešavanja @@ -32,20 +30,16 @@ type PodaciPodesavanja struct { PIB string LogoTip string LogoPutanja string - GlobalnaTema string // stvarna vrednost iz podešavanja (ne senči PodaciStranice.Tema) Sacuvano bool Verzija string LogoGreska string BackupVracen bool Backupi []BackupInfo - LoginPozadina string - LoginPozadinaOpacity string - LoginPozadinaBlurPozadine string - LoginPozadinaBlurKartice string - AppPozadina string - AppPozadinaOpacity string - AppPozadinaBlur string - AppPozadinaBlurPozadine string + LoginPozadina string + LoginPozadinaOpacity string + LoginPozadinaBlurPozadine string + LoginPozadinaBlurKartice string + LoginPozadinaZatamnjenjeKartice string } // BackupInfo opisuje jedan backup fajl @@ -83,15 +77,6 @@ func (h *Handler) Podesavanja(w http.ResponseWriter, r *http.Request) { PIB: podesavanja["pib"], LogoTip: podesavanja["logo_tip"], LogoPutanja: podesavanja["logo_putanja"], - GlobalnaTema: func() string { - if v := podesavanja["globalna_tema"]; v != "" { - return v - } - if v := podesavanja["tema"]; v != "" { - return v - } - return "tamna" - }(), Sacuvano: r.URL.Query().Get("sacuvano") == "1", BackupVracen: r.URL.Query().Get("sacuvano") == "vraceno", Verzija: h.Verzija, @@ -113,19 +98,8 @@ func (h *Handler) Podesavanja(w http.ResponseWriter, r *http.Request) { if v == "" { return "12" } return v }(), - AppPozadina: podesavanja["app_pozadina"], - AppPozadinaOpacity: func() string { - v := podesavanja["app_pozadina_opacity"] - if v == "" { return "50" } - return v - }(), - AppPozadinaBlur: func() string { - v := podesavanja["app_pozadina_blur"] - if v == "" { return "12" } - return v - }(), - AppPozadinaBlurPozadine: func() string { - v := podesavanja["app_pozadina_blur_pozadine"] + LoginPozadinaZatamnjenjeKartice: func() string { + v := podesavanja["login_pozadina_zatamnjenje_kartice"] if v == "" { return "0" } return v }(), @@ -260,14 +234,12 @@ func (h *Handler) SacuvajPodesavanja(w http.ResponseWriter, r *http.Request) { } polja := map[string]string{ - "naziv_firme": r.FormValue("naziv_firme"), - "podnazlov": r.FormValue("podnazlov"), - "adresa": r.FormValue("adresa"), - "telefon": r.FormValue("telefon"), - "pib": r.FormValue("pib"), - "logo_tip": r.FormValue("logo_tip"), - "tema": r.FormValue("tema"), - "globalna_tema": r.FormValue("globalna_tema"), + "naziv_firme": r.FormValue("naziv_firme"), + "podnazlov": r.FormValue("podnazlov"), + "adresa": r.FormValue("adresa"), + "telefon": r.FormValue("telefon"), + "pib": r.FormValue("pib"), + "logo_tip": r.FormValue("logo_tip"), } for kljuc, vrednost := range polja { @@ -539,210 +511,6 @@ func (h *Handler) UkloniLoginPozadinu(w http.ResponseWriter, r *http.Request) { http.Redirect(w, r, "/admin/podesavanja/izgled", http.StatusSeeOther) } -// OtpremiAppPozadinu prima multipart upload slike i čuva je kao pozadinsku sliku aplikacije -func (h *Handler) OtpremiAppPozadinu(w http.ResponseWriter, r *http.Request) { - k := middleware.KorisnikIzKonteksta(r.Context()) - if k == nil || !h.DozvoleRepo.ImaDozvolu(r.Context(), k.Uloga, "podesavanja.app_pozadina") { - http.Error(w, "Nemate dozvolu za ovu akciju.", http.StatusForbidden) - return - } - - r.Body = http.MaxBytesReader(w, r.Body, 5<<20+4096) - if err := r.ParseMultipartForm(5 << 20); err != nil { - middleware.SetFlash(w, r, h.DB, "greska", "Fajl je prevelik (maksimum 5 MB).") - http.Redirect(w, r, "/admin/podesavanja/izgled", http.StatusSeeOther) - return - } - - fajl, zaglavlje, err := r.FormFile("app_pozadina") - if err != nil { - middleware.SetFlash(w, r, h.DB, "greska", "Nije odabran fajl.") - http.Redirect(w, r, "/admin/podesavanja/izgled", http.StatusSeeOther) - return - } - defer fajl.Close() - - if zaglavlje.Size > 5<<20 { - middleware.SetFlash(w, r, h.DB, "greska", "Fajl je prevelik (maksimum 5 MB).") - http.Redirect(w, r, "/admin/podesavanja/izgled", http.StatusSeeOther) - return - } - - ext := strings.ToLower(filepath.Ext(zaglavlje.Filename)) - dozvoljenoExt := map[string]string{ - ".jpg": "image/jpeg", - ".jpeg": "image/jpeg", - ".png": "image/png", - ".webp": "image/webp", - } - ocekivaniMime, ok := dozvoljenoExt[ext] - if !ok { - middleware.SetFlash(w, r, h.DB, "greska", "Dozvoljeni formati su JPG, PNG i WebP.") - http.Redirect(w, r, "/admin/podesavanja/izgled", http.StatusSeeOther) - return - } - - buf := make([]byte, 512) - n, _ := fajl.Read(buf) - stvarniMime := http.DetectContentType(buf[:n]) - if !strings.HasPrefix(stvarniMime, ocekivaniMime) { - middleware.SetFlash(w, r, h.DB, "greska", "Sadržaj fajla ne odgovara odabranoj ekstenziji.") - http.Redirect(w, r, "/admin/podesavanja/izgled", http.StatusSeeOther) - return - } - if _, err := fajl.Seek(0, io.SeekStart); err != nil { - middleware.SetFlash(w, r, h.DB, "greska", "Greška pri obradi fajla.") - http.Redirect(w, r, "/admin/podesavanja/izgled", http.StatusSeeOther) - return - } - - // briše staru app pozadinu sa diska ako postoji - staraPodesavanja, _ := ntechsqlite.DohvatiSvaPodesavanja(r.Context(), h.DB) - if stara := staraPodesavanja["app_pozadina"]; stara != "" { - deoBezverzije := strings.Split(stara, "?")[0] - staroIme := filepath.Base(deoBezverzije) - os.Remove(filepath.Join("web/static/uploads", staroIme)) - } - - novoIme, err := generisiImeUploada(ext) - if err != nil { - log.Printf("upload app pozadine: greška pri generisanju imena: %v", err) - middleware.SetFlash(w, r, h.DB, "greska", "Greška pri čuvanju fajla.") - http.Redirect(w, r, "/admin/podesavanja/izgled", http.StatusSeeOther) - return - } - - odrediste := filepath.Join("web/static/uploads", novoIme) - dst, err := os.Create(odrediste) - if err != nil { - log.Printf("upload app pozadine: ne mogu kreirati fajl: %v", err) - middleware.SetFlash(w, r, h.DB, "greska", "Greška pri čuvanju fajla.") - http.Redirect(w, r, "/admin/podesavanja/izgled", http.StatusSeeOther) - return - } - defer dst.Close() - - if _, err := io.Copy(dst, fajl); err != nil { - log.Printf("upload app pozadine: greška pri kopiranju: %v", err) - middleware.SetFlash(w, r, h.DB, "greska", "Greška pri čuvanju fajla.") - http.Redirect(w, r, "/admin/podesavanja/izgled", http.StatusSeeOther) - return - } - - putanja := fmt.Sprintf("/static/uploads/%s?v=%d", novoIme, time.Now().Unix()) - if err := ntechsqlite.SacuvajPodesavanje(r.Context(), h.DB, "app_pozadina", putanja); err != nil { - log.Printf("upload app pozadine: greška pri čuvanju putanje: %v", err) - middleware.SetFlash(w, r, h.DB, "greska", "Greška pri čuvanju podešavanja.") - http.Redirect(w, r, "/admin/podesavanja/izgled", http.StatusSeeOther) - return - } - - // zapamti trenutnu globalnu temu pre nego što je forsiramo na tamnu - trenutnaTema := staraPodesavanja["globalna_tema"] - if trenutnaTema == "" { - trenutnaTema = staraPodesavanja["tema"] - } - if trenutnaTema == "" { - trenutnaTema = "tamna" - } - _ = ntechsqlite.SacuvajPodesavanje(r.Context(), h.DB, "tema_pre_slike", trenutnaTema) - _ = ntechsqlite.SacuvajPodesavanje(r.Context(), h.DB, "globalna_tema", "tamna") - - middleware.SetFlash(w, r, h.DB, "uspeh", "Pozadinska slika aplikacije je uspešno otpremljena.") - http.Redirect(w, r, "/admin/podesavanja/izgled", http.StatusSeeOther) -} - -// UkloniAppPozadinu briše pozadinsku sliku aplikacije sa diska i iz podešavanja -func (h *Handler) UkloniAppPozadinu(w http.ResponseWriter, r *http.Request) { - k := middleware.KorisnikIzKonteksta(r.Context()) - if k == nil || !h.DozvoleRepo.ImaDozvolu(r.Context(), k.Uloga, "podesavanja.app_pozadina") { - http.Error(w, "Nemate dozvolu za ovu akciju.", http.StatusForbidden) - return - } - - podesavanja, err := ntechsqlite.DohvatiSvaPodesavanja(r.Context(), h.DB) - if err == nil { - if stara := podesavanja["app_pozadina"]; stara != "" { - deoBezverzije := strings.Split(stara, "?")[0] - staroIme := filepath.Base(deoBezverzije) - os.Remove(filepath.Join("web/static/uploads", staroIme)) - } - } - - if err := ntechsqlite.SacuvajPodesavanje(r.Context(), h.DB, "app_pozadina", ""); err != nil { - log.Printf("ukloni app pozadinu: greška pri čuvanju: %v", err) - middleware.SetFlash(w, r, h.DB, "greska", "Greška pri uklanjanju slike.") - http.Redirect(w, r, "/admin/podesavanja/izgled", http.StatusSeeOther) - return - } - - // vrati temu koja je bila aktivna pre dodavanja slike - if err == nil { - temaPreSlike := podesavanja["tema_pre_slike"] - if temaPreSlike == "" { - temaPreSlike = "tamna" - } - _ = ntechsqlite.SacuvajPodesavanje(r.Context(), h.DB, "globalna_tema", temaPreSlike) - _ = ntechsqlite.SacuvajPodesavanje(r.Context(), h.DB, "tema_pre_slike", "") - } - - middleware.SetFlash(w, r, h.DB, "uspeh", "Pozadinska slika aplikacije je uklonjena.") - http.Redirect(w, r, "/admin/podesavanja/izgled", http.StatusSeeOther) -} - -// SacuvajAppPozadinaStilove čuva vrednosti zamućenja i prozirnosti pozadine aplikacije -func (h *Handler) SacuvajAppPozadinaStilove(w http.ResponseWriter, r *http.Request) { - k := middleware.KorisnikIzKonteksta(r.Context()) - if k == nil || !h.DozvoleRepo.ImaDozvolu(r.Context(), k.Uloga, "podesavanja.app_pozadina") { - http.Error(w, "Nemate dozvolu za ovu akciju.", http.StatusForbidden) - return - } - if err := r.ParseForm(); err != nil { - middleware.SetFlash(w, r, h.DB, "greska", "Greška pri čitanju forme.") - http.Redirect(w, r, "/admin/podesavanja/izgled", http.StatusSeeOther) - return - } - - blurStr := r.FormValue("blur") - blurPozadineStr := r.FormValue("blur_pozadine") - opacityStr := r.FormValue("opacity") - - blurVal, err := strconv.Atoi(blurStr) - if err != nil || blurVal < 0 || blurVal > 20 { - middleware.SetFlash(w, r, h.DB, "greska", "Neispravna vrednost zamućenja stakla.") - http.Redirect(w, r, "/admin/podesavanja/izgled", http.StatusSeeOther) - return - } - blurPozadineVal, err := strconv.Atoi(blurPozadineStr) - if err != nil || blurPozadineVal < 0 || blurPozadineVal > 20 { - middleware.SetFlash(w, r, h.DB, "greska", "Neispravna vrednost zamućenja pozadine.") - http.Redirect(w, r, "/admin/podesavanja/izgled", http.StatusSeeOther) - return - } - opacityVal, err := strconv.Atoi(opacityStr) - if err != nil || opacityVal < 0 || opacityVal > 80 { - middleware.SetFlash(w, r, h.DB, "greska", "Neispravna vrednost prozirnosti.") - http.Redirect(w, r, "/admin/podesavanja/izgled", http.StatusSeeOther) - return - } - - for kljuc, vrednost := range map[string]string{ - "app_pozadina_blur": blurStr, - "app_pozadina_blur_pozadine": blurPozadineStr, - "app_pozadina_opacity": opacityStr, - } { - if err := ntechsqlite.SacuvajPodesavanje(r.Context(), h.DB, kljuc, vrednost); err != nil { - log.Printf("stilovi app pozadine: greška pri čuvanju %s: %v", kljuc, err) - middleware.SetFlash(w, r, h.DB, "greska", "Greška pri čuvanju podešavanja.") - http.Redirect(w, r, "/admin/podesavanja/izgled", http.StatusSeeOther) - return - } - } - - middleware.SetFlash(w, r, h.DB, "uspeh", "Izgled pozadine aplikacije je sačuvan.") - http.Redirect(w, r, "/admin/podesavanja/izgled", http.StatusSeeOther) -} - // SacuvajLoginPozadinaStilove čuva vrednosti zamućenja i prozirnosti pozadine login stranice func (h *Handler) SacuvajLoginPozadinaStilove(w http.ResponseWriter, r *http.Request) { k := middleware.KorisnikIzKonteksta(r.Context()) @@ -759,6 +527,7 @@ func (h *Handler) SacuvajLoginPozadinaStilove(w http.ResponseWriter, r *http.Req blurPozadineStr := r.FormValue("blur_pozadine") blurKarticeStr := r.FormValue("blur_kartice") opacityStr := r.FormValue("opacity") + zatamnjenjeKarticeStr := r.FormValue("zatamnjenje_kartice") blurPozadineVal, err := strconv.Atoi(blurPozadineStr) if err != nil || blurPozadineVal < 0 || blurPozadineVal > 20 { @@ -778,11 +547,18 @@ func (h *Handler) SacuvajLoginPozadinaStilove(w http.ResponseWriter, r *http.Req http.Redirect(w, r, "/admin/podesavanja/izgled", http.StatusSeeOther) return } + zatamnjenjeKarticeVal, err := strconv.Atoi(zatamnjenjeKarticeStr) + if err != nil || zatamnjenjeKarticeVal < 0 || zatamnjenjeKarticeVal > 80 { + middleware.SetFlash(w, r, h.DB, "greska", "Neispravna vrednost zatamnjivanja kartice.") + http.Redirect(w, r, "/admin/podesavanja/izgled", http.StatusSeeOther) + return + } for kljuc, vrednost := range map[string]string{ - "login_pozadina_blur_pozadine": blurPozadineStr, - "login_pozadina_blur_kartice": blurKarticeStr, - "login_pozadina_opacity": opacityStr, + "login_pozadina_blur_pozadine": blurPozadineStr, + "login_pozadina_blur_kartice": blurKarticeStr, + "login_pozadina_opacity": opacityStr, + "login_pozadina_zatamnjenje_kartice": zatamnjenjeKarticeStr, } { if err := ntechsqlite.SacuvajPodesavanje(r.Context(), h.DB, kljuc, vrednost); err != nil { log.Printf("stilovi login pozadine: greška pri čuvanju %s: %v", kljuc, err) @@ -814,15 +590,6 @@ func (h *Handler) napuniPodaciPodesavanja(r *http.Request, naslov string) (Podac PIB: podesavanja["pib"], LogoTip: podesavanja["logo_tip"], LogoPutanja: podesavanja["logo_putanja"], - GlobalnaTema: func() string { - if v := podesavanja["globalna_tema"]; v != "" { - return v - } - if v := podesavanja["tema"]; v != "" { - return v - } - return "tamna" - }(), Sacuvano: r.URL.Query().Get("sacuvano") == "1", BackupVracen: r.URL.Query().Get("sacuvano") == "vraceno", Verzija: h.Verzija, @@ -847,21 +614,8 @@ func (h *Handler) napuniPodaciPodesavanja(r *http.Request, naslov string) (Podac } return "12" }(), - AppPozadina: podesavanja["app_pozadina"], - AppPozadinaOpacity: func() string { - if v := podesavanja["app_pozadina_opacity"]; v != "" { - return v - } - return "50" - }(), - AppPozadinaBlur: func() string { - if v := podesavanja["app_pozadina_blur"]; v != "" { - return v - } - return "12" - }(), - AppPozadinaBlurPozadine: func() string { - if v := podesavanja["app_pozadina_blur_pozadine"]; v != "" { + LoginPozadinaZatamnjenjeKartice: func() string { + if v := podesavanja["login_pozadina_zatamnjenje_kartice"]; v != "" { return v } return "0" @@ -914,81 +668,3 @@ func (h *Handler) PodesavanjaSistem(w http.ResponseWriter, r *http.Request) { h.renderujTemplate(w, "podesavanja_sistem", podaci) } -// PromeniTemu menja aktivnu temu i vraća na prethodnu stranicu (stara GET ruta, zadržana za kompatibilnost) -func (h *Handler) PromeniTemu(w http.ResponseWriter, r *http.Request) { - tema := chi.URLParam(r, "tema") - - validne := map[string]bool{"tamna": true, "svetla": true} - if !validne[tema] { - http.Redirect(w, r, "/dashboard", http.StatusSeeOther) - return - } - - _ = ntechsqlite.SacuvajPodesavanje(r.Context(), h.DB, "globalna_tema", tema) - - referer := r.Header.Get("Referer") - if referer == "" { - referer = "/dashboard" - } - http.Redirect(w, r, referer, http.StatusSeeOther) -} - -// PromeniGlobalnuTemu prima POST sa poljem "tema" i čuva u globalna_tema u podešavanjima -func (h *Handler) PromeniGlobalnuTemu(w http.ResponseWriter, r *http.Request) { - if err := r.ParseForm(); err != nil { - http.Error(w, "Greška pri čitanju forme", http.StatusBadRequest) - return - } - - tema := r.FormValue("tema") - validne := map[string]bool{"tamna": true, "svetla": true} - if !validne[tema] { - tema = "tamna" - } - - if err := ntechsqlite.SacuvajPodesavanje(r.Context(), h.DB, "globalna_tema", tema); err != nil { - http.Error(w, "Greška pri promeni teme", http.StatusInternalServerError) - return - } - - referer := r.Header.Get("Referer") - if referer == "" { - referer = "/dashboard" - } - http.Redirect(w, r, referer, http.StatusSeeOther) -} - -// PrimeniGlobalnuTemu čuva globalnu temu i resetuje lokalne teme svih korisnika -func (h *Handler) PrimeniGlobalnuTemu(w http.ResponseWriter, r *http.Request) { - k := middleware.KorisnikIzKonteksta(r.Context()) - if !h.DozvoleRepo.ImaDozvolu(r.Context(), k.Uloga, "tema.globalno") { - http.Error(w, "Nemate dozvolu za ovu akciju.", http.StatusForbidden) - return - } - - if err := r.ParseForm(); err != nil { - http.Error(w, "Greška pri čitanju forme", http.StatusBadRequest) - return - } - - tema := r.FormValue("globalna_tema") - validne := map[string]bool{"tamna": true, "svetla": true} - if !validne[tema] { - tema = "tamna" - } - - if err := ntechsqlite.SacuvajPodesavanje(r.Context(), h.DB, "globalna_tema", tema); err != nil { - http.Error(w, "Greška pri čuvanju teme", http.StatusInternalServerError) - return - } - - // poništi lokalne teme svih korisnika — tema se primenjuje globalno - if _, err := h.DB.ExecContext(r.Context(), - "UPDATE korisnici SET koristi_lokalnu_temu = 0, lokalna_tema = ''", - ); err != nil { - log.Printf("PrimeniGlobalnuTemu: reset lokalnih tema: %v", err) - } - - middleware.SetFlash(w, r, h.DB, "uspeh", "Globalna tema primenjena na sve korisnike.") - http.Redirect(w, r, "/admin/podesavanja/izgled", http.StatusSeeOther) -} diff --git a/internal/handler/prijava.go b/internal/handler/prijava.go index 5113a65..27e402f 100644 --- a/internal/handler/prijava.go +++ b/internal/handler/prijava.go @@ -36,6 +36,7 @@ func (h *Handler) PrikazPrijave(w http.ResponseWriter, r *http.Request) { loginOpacity := "50" loginBlurPozadine := "0" loginBlurKartice := "12" + loginZatamnjenjeKartice := "0" if podesavanja, err := ntechsqlite.DohvatiSvaPodesavanja(context.Background(), h.DB); err == nil { loginPozadina = podesavanja["login_pozadina"] if v := podesavanja["login_pozadina_opacity"]; v != "" { @@ -47,15 +48,19 @@ func (h *Handler) PrikazPrijave(w http.ResponseWriter, r *http.Request) { if v := podesavanja["login_pozadina_blur_kartice"]; v != "" { loginBlurKartice = v } + if v := podesavanja["login_pozadina_zatamnjenje_kartice"]; v != "" { + loginZatamnjenjeKartice = v + } } h.renderujStandalone(w, "prijava", map[string]any{ - "Greska": greska, - "CsrfToken": middleware.CsrfToken(r.Context()), - "LoginPozadina": loginPozadina, - "LoginPozadinaOpacity": loginOpacity, - "LoginPozadinaBlurPozadine": loginBlurPozadine, - "LoginPozadinaBlurKartice": loginBlurKartice, + "Greska": greska, + "CsrfToken": middleware.CsrfToken(r.Context()), + "LoginPozadina": loginPozadina, + "LoginPozadinaOpacity": loginOpacity, + "LoginPozadinaBlurPozadine": loginBlurPozadine, + "LoginPozadinaBlurKartice": loginBlurKartice, + "LoginPozadinaZatamnjenjeKartice": loginZatamnjenjeKartice, }) } diff --git a/internal/handler/profil.go b/internal/handler/profil.go index 201bb2b..5b61d72 100644 --- a/internal/handler/profil.go +++ b/internal/handler/profil.go @@ -42,12 +42,11 @@ func (h *Handler) ProfilTema(w http.ResponseWriter, r *http.Request) { PodaciStranice: ps, LokalnaTema: svezi.LokalnaTema, KoristiLokalnuTemu: svezi.KoristiLokalnuTemu, - KoristiGlobalnuTemu: !svezi.KoristiLokalnuTemu, - GlobalnaTema: podesavanja["globalna_tema"], LokalnaPozadina: svezi.LokalnaPozadina, LokalnaPozadinaOpacity: svezi.LokalnaPozadinaOpacity, LokalnaPozadinaBlur: svezi.LokalnaPozadinaBlur, LokalnaPozadinaBlurPozadine: svezi.LokalnaPozadinaBlurPozadine, + LokalnaPozadinaGlassOpacity: svezi.LokalnaPozadinaGlassOpacity, } if podaci.LokalnaPozadinaOpacity == "" { podaci.LokalnaPozadinaOpacity = "50" @@ -58,6 +57,9 @@ func (h *Handler) ProfilTema(w http.ResponseWriter, r *http.Request) { if podaci.LokalnaPozadinaBlurPozadine == "" { podaci.LokalnaPozadinaBlurPozadine = "0" } + if podaci.LokalnaPozadinaGlassOpacity == "" { + podaci.LokalnaPozadinaGlassOpacity = "10" + } h.renderujTemplate(w, "profil_tema", podaci) } @@ -149,6 +151,7 @@ func (h *Handler) ProfilOtpremiPozadinu(w http.ResponseWriter, r *http.Request) opacity := "50" blur := "12" blurPozadine := "0" + glassOpacity := "10" if svezi != nil { if svezi.LokalnaPozadinaOpacity != "" { opacity = svezi.LokalnaPozadinaOpacity @@ -159,9 +162,12 @@ func (h *Handler) ProfilOtpremiPozadinu(w http.ResponseWriter, r *http.Request) if svezi.LokalnaPozadinaBlurPozadine != "" { blurPozadine = svezi.LokalnaPozadinaBlurPozadine } + if svezi.LokalnaPozadinaGlassOpacity != "" { + glassOpacity = svezi.LokalnaPozadinaGlassOpacity + } } - if err := h.KorisniciRepo.SacuvajLokalnuPozadinu(r.Context(), k.ID, putanja, opacity, blur, blurPozadine); err != nil { + if err := h.KorisniciRepo.SacuvajLokalnuPozadinu(r.Context(), k.ID, putanja, opacity, blur, blurPozadine, glassOpacity); err != nil { log.Printf("ProfilOtpremiPozadinu: greška pri čuvanju: %v", err) middleware.SetFlash(w, r, h.DB, "greska", "Greška pri čuvanju podešavanja.") http.Redirect(w, r, "/profil/tema", http.StatusSeeOther) @@ -186,7 +192,7 @@ func (h *Handler) ProfilUkloniPozadinu(w http.ResponseWriter, r *http.Request) { os.Remove(filepath.Join("web/static/uploads", filepath.Base(deo))) } - if err := h.KorisniciRepo.SacuvajLokalnuPozadinu(r.Context(), k.ID, "", "50", "12", "0"); err != nil { + if err := h.KorisniciRepo.SacuvajLokalnuPozadinu(r.Context(), k.ID, "", "50", "12", "0", "10"); err != nil { log.Printf("ProfilUkloniPozadinu: %v", err) middleware.SetFlash(w, r, h.DB, "greska", "Greška pri uklanjanju slike.") http.Redirect(w, r, "/profil/tema", http.StatusSeeOther) @@ -220,6 +226,7 @@ func (h *Handler) ProfilSacuvajPozadinuStilove(w http.ResponseWriter, r *http.Re opacity := r.FormValue("lokalna_pozadina_opacity") blur := r.FormValue("lokalna_pozadina_blur") blurPozadineSt := r.FormValue("lokalna_pozadina_blur_pozadine") + glassOpacitySt := r.FormValue("lokalna_pozadina_glass_opacity") if opacity == "" { opacity = "50" } @@ -229,8 +236,11 @@ func (h *Handler) ProfilSacuvajPozadinuStilove(w http.ResponseWriter, r *http.Re if blurPozadineSt == "" { blurPozadineSt = "0" } + if glassOpacitySt == "" { + glassOpacitySt = "10" + } - if err := h.KorisniciRepo.SacuvajLokalnuPozadinu(r.Context(), k.ID, pozadina, opacity, blur, blurPozadineSt); err != nil { + if err := h.KorisniciRepo.SacuvajLokalnuPozadinu(r.Context(), k.ID, pozadina, opacity, blur, blurPozadineSt, glassOpacitySt); err != nil { log.Printf("ProfilSacuvajPozadinuStilove: %v", err) middleware.SetFlash(w, r, h.DB, "greska", "Greška pri čuvanju podešavanja.") http.Redirect(w, r, "/profil/tema", http.StatusSeeOther) diff --git a/internal/model/korisnik.go b/internal/model/korisnik.go index c171b45..32b1263 100644 --- a/internal/model/korisnik.go +++ b/internal/model/korisnik.go @@ -17,6 +17,7 @@ type Korisnik struct { LokalnaPozadinaOpacity string LokalnaPozadinaBlur string LokalnaPozadinaBlurPozadine string + LokalnaPozadinaGlassOpacity string } // Sesija predstavlja aktivnu sesiju prijavljenog korisnika diff --git a/internal/model/stranica.go b/internal/model/stranica.go index 9d769c3..8d10e37 100644 --- a/internal/model/stranica.go +++ b/internal/model/stranica.go @@ -49,6 +49,7 @@ type PodaciStranice struct { AppPozadinaOpacity string // vrednost 0-80 (% overlay zatamnjivanja) AppPozadinaBlur string // vrednost 0-20 (px backdrop-filter blur na elementima) AppPozadinaBlurPozadine string // vrednost 0-20 (px filter blur na pozadinskoj slici) + AppPozadinaGlassOpacity string // vrednost 0-80 (% zatamnjivanje glass elemenata) — samo za ličnu pozadinu } // PodaciDashboarda su podaci specifični za dashboard stranicu diff --git a/migrations/032_korisnik_pozadina_glass_opacity.sql b/migrations/032_korisnik_pozadina_glass_opacity.sql new file mode 100644 index 0000000..76ceac8 --- /dev/null +++ b/migrations/032_korisnik_pozadina_glass_opacity.sql @@ -0,0 +1 @@ +ALTER TABLE korisnici ADD COLUMN lokalna_pozadina_glass_opacity TEXT DEFAULT '10'; diff --git a/migrations/033_ukloni_globalnu_temu.sql b/migrations/033_ukloni_globalnu_temu.sql new file mode 100644 index 0000000..9830db3 --- /dev/null +++ b/migrations/033_ukloni_globalnu_temu.sql @@ -0,0 +1 @@ +DELETE FROM podesavanja WHERE kljuc IN ('globalna_tema', 'tema', 'tema_pre_slike'); diff --git a/migrations/034_ukloni_app_pozadinu.sql b/migrations/034_ukloni_app_pozadinu.sql new file mode 100644 index 0000000..9983b77 --- /dev/null +++ b/migrations/034_ukloni_app_pozadinu.sql @@ -0,0 +1 @@ +DELETE FROM podesavanja WHERE kljuc IN ('app_pozadina', 'app_pozadina_opacity', 'app_pozadina_blur', 'app_pozadina_blur_pozadine'); diff --git a/web/templates/komponente/sidebar.html b/web/templates/komponente/sidebar.html index e9a7470..6afe19a 100644 --- a/web/templates/komponente/sidebar.html +++ b/web/templates/komponente/sidebar.html @@ -132,20 +132,12 @@ {{end}} - {{if eq .KorisnikUloga "superadmin"}} - - - Dozvole - Dozvole - - {{end}} - {{if ne .KorisnikUloga "radnik"}} {{if index .Dozvole "podesavanja.pregled"}} -
+
{{end}} diff --git a/web/templates/komponente/topbar.html b/web/templates/komponente/topbar.html index 1a7d136..0694c4f 100644 --- a/web/templates/komponente/topbar.html +++ b/web/templates/komponente/topbar.html @@ -12,23 +12,6 @@ {{.NaslovStranice}} - {{if not .AppPozadina}} -
-
- - - -
-
- - - -
-
- {{end}} -
{{if .Korisnik}}{{slice .Korisnik 0 2}}{{else}}NT{{end}} diff --git a/web/templates/stranice/admin_dozvole.html b/web/templates/stranice/admin_dozvole.html index f2aeaa6..d817b6b 100644 --- a/web/templates/stranice/admin_dozvole.html +++ b/web/templates/stranice/admin_dozvole.html @@ -42,290 +42,292 @@ Akcija Radnik + {{if eq .KorisnikUloga "superadmin"}} Admin + {{end}} - Magacin + Magacin Pregled artikala - + {{if eq .KorisnikUloga "superadmin"}}{{end}} Dodavanje artikala - + {{if eq .KorisnikUloga "superadmin"}}{{end}} Izmena artikala - + {{if eq .KorisnikUloga "superadmin"}}{{end}} Brisanje artikala - + {{if eq .KorisnikUloga "superadmin"}}{{end}} Premeštanje artikala - + {{if eq .KorisnikUloga "superadmin"}}{{end}} - Kategorije + Kategorije Pregled kategorija - + {{if eq .KorisnikUloga "superadmin"}}{{end}} Dodavanje kategorija - + {{if eq .KorisnikUloga "superadmin"}}{{end}} Izmena kategorija - + {{if eq .KorisnikUloga "superadmin"}}{{end}} Brisanje kategorija - + {{if eq .KorisnikUloga "superadmin"}}{{end}} - Nabavke + Nabavke Pregled nabavki - + {{if eq .KorisnikUloga "superadmin"}}{{end}} Dodavanje nabavki - + {{if eq .KorisnikUloga "superadmin"}}{{end}} Brisanje nabavki - + {{if eq .KorisnikUloga "superadmin"}}{{end}} - Dobavljači + Dobavljači Pregled dobavljača - + {{if eq .KorisnikUloga "superadmin"}}{{end}} Dodavanje dobavljača - + {{if eq .KorisnikUloga "superadmin"}}{{end}} Izmena dobavljača - + {{if eq .KorisnikUloga "superadmin"}}{{end}} Brisanje dobavljača - + {{if eq .KorisnikUloga "superadmin"}}{{end}} - Servis + Servis Pregled servisnih naloga - + {{if eq .KorisnikUloga "superadmin"}}{{end}} Dodavanje servisnih naloga - + {{if eq .KorisnikUloga "superadmin"}}{{end}} Izmena servisnih naloga - + {{if eq .KorisnikUloga "superadmin"}}{{end}} Brisanje servisnih naloga - + {{if eq .KorisnikUloga "superadmin"}}{{end}} - Prodaja + Prodaja Pregled prodaje - + {{if eq .KorisnikUloga "superadmin"}}{{end}} Dodavanje prodaje - + {{if eq .KorisnikUloga "superadmin"}}{{end}} Brisanje prodaje - + {{if eq .KorisnikUloga "superadmin"}}{{end}} - Klijenti + Klijenti Pregled klijenata - + {{if eq .KorisnikUloga "superadmin"}}{{end}} Dodavanje klijenata - + {{if eq .KorisnikUloga "superadmin"}}{{end}} Izmena klijenata - + {{if eq .KorisnikUloga "superadmin"}}{{end}} Brisanje klijenata - + {{if eq .KorisnikUloga "superadmin"}}{{end}} - Podsetnici + Podsetnici Pregled podsetnika - + {{if eq .KorisnikUloga "superadmin"}}{{end}} Dodavanje podsetnika - + {{if eq .KorisnikUloga "superadmin"}}{{end}} Izmena podsetnika - + {{if eq .KorisnikUloga "superadmin"}}{{end}} Brisanje podsetnika - + {{if eq .KorisnikUloga "superadmin"}}{{end}} - Izveštaji + Izveštaji Pregled izveštaja - + {{if eq .KorisnikUloga "superadmin"}}{{end}} - Podešavanja + Podešavanja Pregled podešavanja - + {{if eq .KorisnikUloga "superadmin"}}{{end}} Izmena podešavanja - + {{if eq .KorisnikUloga "superadmin"}}{{end}} - Korisnici + Korisnici Pregled korisnika - + {{if eq .KorisnikUloga "superadmin"}}{{end}} Dodavanje korisnika - + {{if eq .KorisnikUloga "superadmin"}}{{end}} Izmena korisnika - + {{if eq .KorisnikUloga "superadmin"}}{{end}} Brisanje korisnika - + {{if eq .KorisnikUloga "superadmin"}}{{end}} Promena uloge korisnika - + {{if eq .KorisnikUloga "superadmin"}}{{end}} - Backup + Backup Pregled rezervnih kopija - + {{if eq .KorisnikUloga "superadmin"}}{{end}} Pokretanje bekapa - + {{if eq .KorisnikUloga "superadmin"}}{{end}} diff --git a/web/templates/stranice/dashboard.html b/web/templates/stranice/dashboard.html index 912a213..33c654c 100644 --- a/web/templates/stranice/dashboard.html +++ b/web/templates/stranice/dashboard.html @@ -86,7 +86,7 @@
Kritične zalihe - Upozorenje + Upozorenje
{{range .KriticneZalihe}}
diff --git a/web/templates/stranice/podesavanja.html b/web/templates/stranice/podesavanja.html index d37ec9d..64554dd 100644 --- a/web/templates/stranice/podesavanja.html +++ b/web/templates/stranice/podesavanja.html @@ -198,136 +198,6 @@
- -
- - -
- Pozadinska slika aplikacije -
- - - {{if .AppPozadina}} -
- Trenutna pozadina -
- - -
-
- {{end}} - - -
- -
- - - -
-
JPG, PNG ili WebP — maksimum 5 MB
-
- - -
- - -
- - -
- - -
- - -
-
- - - - - - -
- - -
-
-
Artikli
-
1.284
-
-
-
Servis
-
47
-
-
-
Prihodi
-
284.500
-
-
- -
- - -
-
- Zamućenje pozadine - -
- -
- - -
-
- Zamućenje stakla - -
- -
- - -
-
- Zatamnjivanje - -
- -
- - -
- - - - - -
- -
- -
-
@@ -363,27 +233,21 @@ -
-
- -
- -
-
+
NTech
-
@@ -406,22 +270,33 @@ style="width:100%;accent-color:var(--sb-akcent);cursor:pointer;">
- +
- Zatamnjivanje + Zatamnjivanje pozadine
+ +
+
+ Zatamnjivanje kartice NTech + +
+ +
+
+
- - -
-
- - Tema -
- -
- -
- - -
-
- -
- -
-
- -
diff --git a/web/templates/stranice/podesavanja_izgled.html b/web/templates/stranice/podesavanja_izgled.html index 9d9917d..c4d4f81 100644 --- a/web/templates/stranice/podesavanja_izgled.html +++ b/web/templates/stranice/podesavanja_izgled.html @@ -27,115 +27,6 @@
Podešavanja su uspešno sačuvana.
{{end}} - -
- -
- Pozadinska slika aplikacije -
- - {{if .AppPozadina}} -
- Trenutna pozadina -
- - -
-
- {{end}} - -
- -
- - - -
-
JPG, PNG ili WebP — maksimum 5 MB
-
- -
- -
-
-
-
-
- - - - - - -
-
-
-
Artikli
-
1.284
-
-
-
Servis
-
47
-
-
-
Prihodi
-
284.500
-
-
-
- -
-
- Zamućenje pozadine - -
- -
-
-
- Zamućenje stakla - -
- -
-
-
- Zatamnjivanje - -
- -
-
- - - - - -
- -
- -
- {{if index .Dozvole "podesavanja.login_pozadina"}}
@@ -171,14 +62,14 @@
JPG, PNG ili WebP — maksimum 5 MB
-
-
+
NTech
@@ -205,17 +96,26 @@
- Zatamnjivanje + Zatamnjivanje pozadine
+
+
+ Zatamnjivanje kartice NTech + +
+ +
+
{{end}} - {{if index .Dozvole "tema.globalno"}} - - - -
-
- - Globalna tema -
-
Primenuje se na sve korisnike koji ne koriste svoju lokalnu temu.
- -
-
- - -
-
- -
- - -
-
- - {{end}}
{{end}} diff --git a/web/templates/stranice/prijava.html b/web/templates/stranice/prijava.html index 54cd281..404f1d8 100644 --- a/web/templates/stranice/prijava.html +++ b/web/templates/stranice/prijava.html @@ -26,7 +26,7 @@ } {{if .LoginPozadina}} .kartica { - background: rgba(255,255,255,0.08) !important; + background: rgba(0,0,0,{{.LoginPozadinaZatamnjenjeKartice}}%) !important; backdrop-filter: blur({{.LoginPozadinaBlurKartice}}px); -webkit-backdrop-filter: blur({{.LoginPozadinaBlurKartice}}px); border: 1px solid rgba(255,255,255,0.18) !important; diff --git a/web/templates/stranice/profil_tema.html b/web/templates/stranice/profil_tema.html index 9495a8e..c9c0b34 100644 --- a/web/templates/stranice/profil_tema.html +++ b/web/templates/stranice/profil_tema.html @@ -15,48 +15,52 @@
Moja tema
- {{if not .AppPozadina}} -
+ {{if .LokalnaPozadina}} + +
+
-
Koristi globalnu temu
-
Nema aktivne pozadinske slike
+
Tamna tema je aktivna
+
Lična pozadinska slika automatski primenjuje tamnu temu.
-
- {{else}}
-
- - -
-
-
Koristi globalnu temu
-
-
-