Refaktoring: uklanjanje globalne teme i app pozadine, dozvole u podešavanja, UI ispravke
- Uklonjena globalna tema i pozadinska slika aplikacije (ostala samo lična pozadina po korisniku) - Uklonjena animacija treperenja pozadine pri navigaciji; dodat sessionStorage za instant prikaz - Dozvole premeštene iz sidebar-a u Podešavanja → Sistem; vidljive i adminu (samo Radnik kolona) - Admin može menjati samo dozvole uloge Radnik, superadmin menja i Radnik i Admin - Zatamnjivanje kartice NTech na stranici prijave — novi slider u Podešavanja → Izgled - Upozorenje na dashboard-u (kritične zalihe) — popravljen kontrast boje
This commit is contained in:
@@ -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
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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"
|
||||
|
||||
+10
-46
@@ -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"
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+26
-350
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -17,6 +17,7 @@ type Korisnik struct {
|
||||
LokalnaPozadinaOpacity string
|
||||
LokalnaPozadinaBlur string
|
||||
LokalnaPozadinaBlurPozadine string
|
||||
LokalnaPozadinaGlassOpacity string
|
||||
}
|
||||
|
||||
// Sesija predstavlja aktivnu sesiju prijavljenog korisnika
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user