Topbar: logo firme + naslov; avatar upload; uklanjanje logo zone
- Topbar: logo slika firme (toggle on/off) pa naslov stranice; bez teksta firme - Sidebar: samo naziv firme i podnaslov (tekst), bez slike loga - Avatar: korisnik uploaduje ličnu sliku u Profil > Tema > Avatar; prikazuje se kao dugme za meni (desno u topbaru); fallback inicijali - Logo firme kartica: dugme "Ukloni sliku" + ruta /podesavanja/logo/ukloni - Logo zona iz podešavanja uklonjena; jedan iOS toggle za prikaz loga u topbaru - Migracije 049 (topbar_logo_slika/tekst) i 050 (avatar_putanja na korisnicima) - iOS-style .toggl switch u main.css
This commit is contained in:
@@ -149,6 +149,7 @@ type KorisniciRepository interface {
|
||||
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, glassOpacity string) error
|
||||
SacuvajAvatar(ctx context.Context, id int64, putanja string) error
|
||||
PostojiIjedan(ctx context.Context) (bool, error)
|
||||
Obrisi(ctx context.Context, id int64) error
|
||||
}
|
||||
|
||||
@@ -21,7 +21,7 @@ type sqliteKorisniciRepo struct {
|
||||
// NULL vrednosti — deljeno između skeniraiKorisnika (jedan red) i Lista (više redova)
|
||||
func dodeliOpcijeKorisnika(k *model.Korisnik, aktivan, koristiLokalnuTemu int,
|
||||
lokalnaTema, lokalnaPozadina, lokalnaPozadinaOpacity, lokalnaPozadinaBlur,
|
||||
lokalnaPozadinaBlurPozadine, lokalnaPozadinaGlassOpacity sql.NullString,
|
||||
lokalnaPozadinaBlurPozadine, lokalnaPozadinaGlassOpacity, avatarPutanja sql.NullString,
|
||||
datumKreiranja time.Time) {
|
||||
k.Aktivan = aktivan == 1
|
||||
k.LokalnaTema = lokalnaTema.String
|
||||
@@ -32,6 +32,7 @@ func dodeliOpcijeKorisnika(k *model.Korisnik, aktivan, koristiLokalnuTemu int,
|
||||
k.LokalnaPozadinaBlur = lokalnaPozadinaBlur.String
|
||||
k.LokalnaPozadinaBlurPozadine = lokalnaPozadinaBlurPozadine.String
|
||||
k.LokalnaPozadinaGlassOpacity = lokalnaPozadinaGlassOpacity.String
|
||||
k.AvatarPutanja = avatarPutanja.String
|
||||
}
|
||||
|
||||
// skeniraiKorisnika čita jedan red iz baze i popunjava model.Korisnik
|
||||
@@ -40,18 +41,19 @@ func skeniraiKorisnika(row interface{ Scan(...any) error }) (*model.Korisnik, er
|
||||
var aktivan, koristiLokalnuTemu int
|
||||
var lokalnaTema sql.NullString
|
||||
var lokalnaPozadina, lokalnaPozadinaOpacity, lokalnaPozadinaBlur, lokalnaPozadinaBlurPozadine, lokalnaPozadinaGlassOpacity sql.NullString
|
||||
var avatarPutanja sql.NullString
|
||||
var datumKreiranja time.Time
|
||||
if err := row.Scan(
|
||||
&k.ID, &k.KorisnickoIme, &k.LozinkaHash, &k.Uloga, &aktivan, &k.TotpTajna,
|
||||
&lokalnaTema, &koristiLokalnuTemu, &datumKreiranja,
|
||||
&lokalnaPozadina, &lokalnaPozadinaOpacity, &lokalnaPozadinaBlur,
|
||||
&lokalnaPozadinaBlurPozadine, &lokalnaPozadinaGlassOpacity,
|
||||
&lokalnaPozadinaBlurPozadine, &lokalnaPozadinaGlassOpacity, &avatarPutanja,
|
||||
); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
dodeliOpcijeKorisnika(k, aktivan, koristiLokalnuTemu, lokalnaTema,
|
||||
lokalnaPozadina, lokalnaPozadinaOpacity, lokalnaPozadinaBlur,
|
||||
lokalnaPozadinaBlurPozadine, lokalnaPozadinaGlassOpacity, datumKreiranja)
|
||||
lokalnaPozadinaBlurPozadine, lokalnaPozadinaGlassOpacity, avatarPutanja, datumKreiranja)
|
||||
return k, nil
|
||||
}
|
||||
|
||||
@@ -91,7 +93,7 @@ func (r *sqliteKorisniciRepo) DohvatiPoImenu(ctx context.Context, korisnickoIme
|
||||
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_glass_opacity, '10')
|
||||
COALESCE(lokalna_pozadina_glass_opacity, '10'), COALESCE(avatar_putanja, '')
|
||||
FROM korisnici WHERE korisnicko_ime = ?`, korisnickoIme)
|
||||
k, err := skeniraiKorisnika(row)
|
||||
if err != nil {
|
||||
@@ -107,7 +109,7 @@ func (r *sqliteKorisniciRepo) DohvatiPoID(ctx context.Context, id int64) (*model
|
||||
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_glass_opacity, '10')
|
||||
COALESCE(lokalna_pozadina_glass_opacity, '10'), COALESCE(avatar_putanja, '')
|
||||
FROM korisnici WHERE id = ?`, id)
|
||||
k, err := skeniraiKorisnika(row)
|
||||
if err != nil {
|
||||
@@ -123,7 +125,7 @@ func (r *sqliteKorisniciRepo) Lista(ctx context.Context) ([]model.Korisnik, erro
|
||||
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_glass_opacity, '10')
|
||||
COALESCE(lokalna_pozadina_glass_opacity, '10'), COALESCE(avatar_putanja, '')
|
||||
FROM korisnici ORDER BY datum_kreiranja ASC`)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("ntech: korisnici.Lista: %w", err)
|
||||
@@ -135,22 +137,32 @@ func (r *sqliteKorisniciRepo) Lista(ctx context.Context) ([]model.Korisnik, erro
|
||||
var aktivan, koristiLokalnuTemu int
|
||||
var lokalnaTema sql.NullString
|
||||
var lokalnaPozadina, lokalnaPozadinaOpacity, lokalnaPozadinaBlur, lokalnaPozadinaBlurPozadine, lokalnaPozadinaGlassOpacity sql.NullString
|
||||
var avatarPutanja sql.NullString
|
||||
var datumKreiranja time.Time
|
||||
if err := rows.Scan(&k.ID, &k.KorisnickoIme, &k.Uloga, &aktivan, &k.TotpTajna,
|
||||
&lokalnaTema, &koristiLokalnuTemu, &datumKreiranja,
|
||||
&lokalnaPozadina, &lokalnaPozadinaOpacity, &lokalnaPozadinaBlur, &lokalnaPozadinaBlurPozadine,
|
||||
&lokalnaPozadinaGlassOpacity); err != nil {
|
||||
&lokalnaPozadinaGlassOpacity, &avatarPutanja); err != nil {
|
||||
return nil, fmt.Errorf("ntech: korisnici.Lista: %w", err)
|
||||
}
|
||||
dodeliOpcijeKorisnika(&k, aktivan, koristiLokalnuTemu, lokalnaTema,
|
||||
lokalnaPozadina, lokalnaPozadinaOpacity, lokalnaPozadinaBlur,
|
||||
lokalnaPozadinaBlurPozadine, lokalnaPozadinaGlassOpacity, datumKreiranja)
|
||||
lokalnaPozadinaBlurPozadine, lokalnaPozadinaGlassOpacity, avatarPutanja, datumKreiranja)
|
||||
r.desifrujTotpTajnu(&k)
|
||||
lista = append(lista, k)
|
||||
}
|
||||
return lista, nil
|
||||
}
|
||||
|
||||
func (r *sqliteKorisniciRepo) SacuvajAvatar(ctx context.Context, id int64, putanja string) error {
|
||||
_, err := r.db.ExecContext(ctx,
|
||||
`UPDATE korisnici SET avatar_putanja = ? WHERE id = ?`, putanja, id)
|
||||
if err != nil {
|
||||
return fmt.Errorf("ntech: korisnici.SacuvajAvatar: %w", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
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 = ?, lokalna_pozadina_glass_opacity = ? WHERE id = ?`,
|
||||
|
||||
@@ -161,12 +161,13 @@ func (h *Handler) popuniPodaciStranice(r *http.Request, podesavanja map[string]s
|
||||
tema := "tamna"
|
||||
|
||||
ps := model.PodaciStranice{
|
||||
Tema: tema,
|
||||
NazivFirme: podesavanja["naziv_firme"],
|
||||
Podnazlov: podesavanja["podnazlov"],
|
||||
LogoTip: podesavanja["logo_tip"],
|
||||
LogoPutanja: podesavanja["logo_putanja"],
|
||||
Korisnik: "Admin",
|
||||
Tema: tema,
|
||||
NazivFirme: podesavanja["naziv_firme"],
|
||||
Podnazlov: podesavanja["podnazlov"],
|
||||
LogoPutanja: podesavanja["logo_putanja"],
|
||||
TopbarLogoSlika: podesavanja["topbar_logo_slika"] == "1",
|
||||
TopbarLogoTekst: podesavanja["topbar_logo_tekst"] == "1",
|
||||
Korisnik: "Admin",
|
||||
}
|
||||
var korisnik *model.Korisnik
|
||||
if k := middleware.KorisnikIzKonteksta(r.Context()); k != nil {
|
||||
@@ -174,6 +175,7 @@ func (h *Handler) popuniPodaciStranice(r *http.Request, podesavanja map[string]s
|
||||
ps.Korisnik = k.KorisnickoIme
|
||||
ps.KorisnikIme = k.KorisnickoIme
|
||||
ps.KorisnikUloga = k.Uloga
|
||||
ps.AvatarPutanja = k.AvatarPutanja
|
||||
ps.Dozvole = h.DozvoleRepo.SveDozvole(r.Context(), k.Uloga)
|
||||
// lokalna tema korisnika — primenjuje se uvek kada je postavljena, bez obzira na KoristiLokalnuTemu
|
||||
if k.LokalnaTema != "" {
|
||||
|
||||
@@ -28,8 +28,9 @@ type PodaciPodesavanja struct {
|
||||
Adresa string
|
||||
Telefon string
|
||||
PIB string
|
||||
LogoTip string
|
||||
LogoPutanja string
|
||||
LogoPutanja string
|
||||
TopbarLogoSlika bool
|
||||
TopbarLogoTekst bool
|
||||
// profil firme — pravni/poreski status (Faza 0); određuje koji se zakonski moduli pale
|
||||
FirmaPravniOblik string
|
||||
FirmaPdvObveznik string
|
||||
@@ -81,8 +82,9 @@ func (h *Handler) Podesavanja(w http.ResponseWriter, r *http.Request) {
|
||||
Adresa: podesavanja["adresa"],
|
||||
Telefon: podesavanja["telefon"],
|
||||
PIB: podesavanja["pib"],
|
||||
LogoTip: podesavanja["logo_tip"],
|
||||
LogoPutanja: podesavanja["logo_putanja"],
|
||||
TopbarLogoSlika: podesavanja["topbar_logo_slika"] == "1",
|
||||
TopbarLogoTekst: podesavanja["topbar_logo_tekst"] == "1",
|
||||
Sacuvano: r.URL.Query().Get("sacuvano") == "1",
|
||||
BackupVracen: r.URL.Query().Get("sacuvano") == "vraceno",
|
||||
Verzija: h.Verzija,
|
||||
@@ -233,13 +235,24 @@ func (h *Handler) SacuvajPodesavanja(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
// checkbox-i: šalju vrednost samo kada su čekirani, pa ih uvek eksplicitno čitamo
|
||||
topbarLogoSlika := "0"
|
||||
if r.FormValue("topbar_logo_slika") == "1" {
|
||||
topbarLogoSlika = "1"
|
||||
}
|
||||
topbarLogoTekst := "0"
|
||||
if r.FormValue("topbar_logo_tekst") == "1" {
|
||||
topbarLogoTekst = "1"
|
||||
}
|
||||
|
||||
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"),
|
||||
"naziv_firme": r.FormValue("naziv_firme"),
|
||||
"podnazlov": r.FormValue("podnazlov"),
|
||||
"adresa": r.FormValue("adresa"),
|
||||
"telefon": r.FormValue("telefon"),
|
||||
"pib": r.FormValue("pib"),
|
||||
"topbar_logo_slika": topbarLogoSlika,
|
||||
"topbar_logo_tekst": topbarLogoTekst,
|
||||
// profil firme (Faza 0) — radio dugmad uvek šalju vrednost, pa se uredno čuvaju
|
||||
"firma_pravni_oblik": r.FormValue("firma_pravni_oblik"),
|
||||
"firma_pdv_obveznik": r.FormValue("firma_pdv_obveznik"),
|
||||
@@ -412,6 +425,21 @@ func (h *Handler) OtpremiLogo(w http.ResponseWriter, r *http.Request) {
|
||||
http.Redirect(w, r, "/podesavanja?sacuvano=1", http.StatusSeeOther)
|
||||
}
|
||||
|
||||
// UkloniLogo briše logo fajl i čisti putanju iz podešavanja
|
||||
func (h *Handler) UkloniLogo(w http.ResponseWriter, r *http.Request) {
|
||||
if _, ok := h.zahtevajDozvolu(w, r, "podesavanja.izmeni"); !ok {
|
||||
return
|
||||
}
|
||||
stari, _ := filepath.Glob("web/static/uploads/logo.*")
|
||||
for _, s := range stari {
|
||||
os.Remove(s)
|
||||
}
|
||||
if err := ntechsqlite.SacuvajPodesavanje(r.Context(), h.DB, "logo_putanja", ""); err != nil {
|
||||
slog.Error("ukloni logo: greška pri čuvanju", "error", err)
|
||||
}
|
||||
http.Redirect(w, r, "/admin/podesavanja/opste?sacuvano=1", http.StatusSeeOther)
|
||||
}
|
||||
|
||||
// generisiImeUploada vraća slučajno hex ime (16 bajtova) sa datom ekstenzijom
|
||||
func generisiImeUploada(ext string) (string, error) {
|
||||
buf := make([]byte, 16)
|
||||
@@ -624,8 +652,9 @@ func (h *Handler) napuniPodaciPodesavanja(r *http.Request, naslov string) (Podac
|
||||
Adresa: podesavanja["adresa"],
|
||||
Telefon: podesavanja["telefon"],
|
||||
PIB: podesavanja["pib"],
|
||||
LogoTip: podesavanja["logo_tip"],
|
||||
LogoPutanja: podesavanja["logo_putanja"],
|
||||
TopbarLogoSlika: podesavanja["topbar_logo_slika"] == "1",
|
||||
TopbarLogoTekst: podesavanja["topbar_logo_tekst"] == "1",
|
||||
FirmaPravniOblik: vrednostIliDefault(podesavanja, "firma_pravni_oblik", "pausalac"),
|
||||
FirmaPdvObveznik: vrednostIliDefault(podesavanja, "firma_pdv_obveznik", "ne"),
|
||||
FirmaFiskalizacija: vrednostIliDefault(podesavanja, "firma_fiskalizacija", "ne"),
|
||||
|
||||
@@ -289,3 +289,118 @@ func (h *Handler) SacuvajLokalnuTemu(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
http.Redirect(w, r, "/admin/profil", http.StatusSeeOther)
|
||||
}
|
||||
|
||||
// ProfilOtpremiAvatar prima upload lične avatar slike korisnika
|
||||
func (h *Handler) ProfilOtpremiAvatar(w http.ResponseWriter, r *http.Request) {
|
||||
k := middleware.KorisnikIzKonteksta(r.Context())
|
||||
if k == nil {
|
||||
http.Redirect(w, r, "/prijava", http.StatusSeeOther)
|
||||
return
|
||||
}
|
||||
|
||||
r.Body = http.MaxBytesReader(w, r.Body, 2<<20+4096)
|
||||
if err := r.ParseMultipartForm(2 << 20); err != nil {
|
||||
middleware.SetFlash(w, r, h.DB, "greska", "Fajl je prevelik (maksimum 2 MB).")
|
||||
http.Redirect(w, r, "/profil/tema", http.StatusSeeOther)
|
||||
return
|
||||
}
|
||||
|
||||
fajl, zaglavlje, err := r.FormFile("avatar")
|
||||
if err != nil {
|
||||
middleware.SetFlash(w, r, h.DB, "greska", "Nije odabran fajl.")
|
||||
http.Redirect(w, r, "/profil/tema", http.StatusSeeOther)
|
||||
return
|
||||
}
|
||||
defer fajl.Close()
|
||||
|
||||
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, "/profil/tema", 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, "/profil/tema", 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, "/profil/tema", http.StatusSeeOther)
|
||||
return
|
||||
}
|
||||
|
||||
// briše stari avatar sa diska
|
||||
svezi, _ := h.KorisniciRepo.DohvatiPoID(r.Context(), k.ID)
|
||||
if svezi != nil && svezi.AvatarPutanja != "" {
|
||||
deo, _, _ := strings.Cut(svezi.AvatarPutanja, "?")
|
||||
os.Remove(filepath.Join("web/static/uploads", filepath.Base(deo)))
|
||||
}
|
||||
|
||||
novoIme := fmt.Sprintf("korisnik_%d_avatar%s", k.ID, ext)
|
||||
odrediste := filepath.Join("web/static/uploads", novoIme)
|
||||
dst, err := os.Create(odrediste)
|
||||
if err != nil {
|
||||
slog.Error("ProfilOtpremiAvatar: ne mogu kreirati fajl", "error", err)
|
||||
middleware.SetFlash(w, r, h.DB, "greska", "Greška pri čuvanju fajla.")
|
||||
http.Redirect(w, r, "/profil/tema", http.StatusSeeOther)
|
||||
return
|
||||
}
|
||||
defer dst.Close()
|
||||
if _, err := io.Copy(dst, fajl); err != nil {
|
||||
slog.Error("ProfilOtpremiAvatar: greška pri kopiranju", "error", err)
|
||||
middleware.SetFlash(w, r, h.DB, "greska", "Greška pri čuvanju fajla.")
|
||||
http.Redirect(w, r, "/profil/tema", http.StatusSeeOther)
|
||||
return
|
||||
}
|
||||
|
||||
// cache-buster verzija u URL-u
|
||||
v := fmt.Sprintf("%d", time.Now().Unix())
|
||||
putanja := fmt.Sprintf("/static/uploads/%s?v=%s", novoIme, v)
|
||||
|
||||
if err := h.KorisniciRepo.SacuvajAvatar(r.Context(), k.ID, putanja); err != nil {
|
||||
slog.Error("ProfilOtpremiAvatar: greška pri čuvanju u bazi", "error", err)
|
||||
middleware.SetFlash(w, r, h.DB, "greska", "Greška pri čuvanju.")
|
||||
http.Redirect(w, r, "/profil/tema", http.StatusSeeOther)
|
||||
return
|
||||
}
|
||||
|
||||
middleware.SetFlash(w, r, h.DB, "uspeh", "Avatar je sačuvan.")
|
||||
http.Redirect(w, r, "/profil/tema", http.StatusSeeOther)
|
||||
}
|
||||
|
||||
// ProfilUkloniAvatar briše ličnu avatar sliku korisnika
|
||||
func (h *Handler) ProfilUkloniAvatar(w http.ResponseWriter, r *http.Request) {
|
||||
k := middleware.KorisnikIzKonteksta(r.Context())
|
||||
if k == nil {
|
||||
http.Redirect(w, r, "/prijava", http.StatusSeeOther)
|
||||
return
|
||||
}
|
||||
|
||||
svezi, _ := h.KorisniciRepo.DohvatiPoID(r.Context(), k.ID)
|
||||
if svezi != nil && svezi.AvatarPutanja != "" {
|
||||
deo, _, _ := strings.Cut(svezi.AvatarPutanja, "?")
|
||||
os.Remove(filepath.Join("web/static/uploads", filepath.Base(deo)))
|
||||
}
|
||||
|
||||
if err := h.KorisniciRepo.SacuvajAvatar(r.Context(), k.ID, ""); err != nil {
|
||||
slog.Error("ProfilUkloniAvatar", "error", err)
|
||||
middleware.SetFlash(w, r, h.DB, "greska", "Greška pri uklanjanju avatara.")
|
||||
http.Redirect(w, r, "/profil/tema", http.StatusSeeOther)
|
||||
return
|
||||
}
|
||||
|
||||
middleware.SetFlash(w, r, h.DB, "uspeh", "Avatar je uklonjen.")
|
||||
http.Redirect(w, r, "/profil/tema", http.StatusSeeOther)
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@ type Korisnik struct {
|
||||
LokalnaPozadinaBlur string
|
||||
LokalnaPozadinaBlurPozadine string
|
||||
LokalnaPozadinaGlassOpacity string
|
||||
AvatarPutanja string
|
||||
}
|
||||
|
||||
// Sesija predstavlja aktivnu sesiju prijavljenog korisnika
|
||||
|
||||
@@ -36,9 +36,11 @@ type PodaciStranice struct {
|
||||
Tema string
|
||||
NazivFirme string
|
||||
Podnazlov string
|
||||
LogoTip string // "sa_nazivom", "bez_naziva", "slika"
|
||||
LogoPutanja string // putanja do slike, koristi se samo kada je LogoTip "slika"
|
||||
Korisnik string
|
||||
LogoPutanja string // putanja do slike loga firme
|
||||
TopbarLogoSlika bool // prikaži logo sliku u topbaru
|
||||
TopbarLogoTekst bool // prikaži naziv firme u topbaru
|
||||
AvatarPutanja string // putanja do lične avatar slike korisnika
|
||||
Korisnik string
|
||||
KorisnikIme string // korisničko ime prijavljenog korisnika
|
||||
KorisnikUloga string // uloga: "superadmin", "admin", "radnik"
|
||||
CsrfToken string // CSRF zaštitni token za forme
|
||||
|
||||
Reference in New Issue
Block a user