Ispravke — bezbednost, CSS teme, handleri, sidebar, servis forma
This commit is contained in:
@@ -1,6 +1,6 @@
|
|||||||
# NTech
|
# NTech
|
||||||
|
|
||||||

|

|
||||||

|

|
||||||
|
|
||||||
Poslovna aplikacija za upravljanje servisom računara, magacinom delova i prodajom. Napravljena u Go-u, radi u brauzeru, ne zahteva internet vezu ni eksterne servise.
|
Poslovna aplikacija za upravljanje servisom računara, magacinom delova i prodajom. Napravljena u Go-u, radi u brauzeru, ne zahteva internet vezu ni eksterne servise.
|
||||||
@@ -23,22 +23,27 @@ Cilj je jednostavan: sve što servis treba da prati nalazi se na jednom mestu, b
|
|||||||
|
|
||||||
- Inicijalno podešavanje pri prvom pokretanju (setup wizard)
|
- Inicijalno podešavanje pri prvom pokretanju (setup wizard)
|
||||||
- Sistem migracija baze podataka
|
- Sistem migracija baze podataka
|
||||||
- Osnovna struktura baze: artikli, kategorije, klijenti, dobavljači, servisni nalozi, prodajni nalozi, podsetnici
|
- Korisnički interfejs — sidebar navigacija, sistem tema (tamna/svetla), dashboard sa statistikama
|
||||||
|
- Prijava korisnika — sesije na serveru, zaključavanje naloga
|
||||||
### U razvoju
|
- Dvofaktorska autentifikacija (TOTP) — aktivacija sa QR kodom, rezervni kodovi
|
||||||
|
- Bruteforce zaštita — IP zaključavanje nakon 5 neuspelih pokušaja u 15 minuta
|
||||||
- Korisničko sučelje — sidebar navigacija, sistem tema, dashboard
|
- CSRF zaštita — double-submit cookie pattern, automatska injekcija tokena u sve forme
|
||||||
- Magacin — praćenje stanja delova, lokacija, količina
|
- Bezbednosni HTTP headeri (CSP, X-Frame-Options, Referrer-Policy, nosniff...)
|
||||||
- Servisni nalozi — prijem, dijagnostika, statusna traka, cene
|
- Evidencija pokušaja prijave — istorija po korisniku, IP, razlog, datum
|
||||||
- Prodajni nalozi — stavke, obračun, evidencija kupaca
|
- Korisnici i uloge — admin panel, upravljanje korisnicima
|
||||||
- Klijenti i dobavljači — baza kontakata, istorija
|
- Magacin — artikli, kategorije, filtriranje, kritični nivoi zaliha
|
||||||
|
- Servisni nalozi — prijem, statusna traka, troškovi, priznanica
|
||||||
|
- Prodajni nalozi — stavke, obračun, priznanica sa podacima firme i klijenta
|
||||||
|
- Nabavke — evidencija nabavki od dobavljača
|
||||||
|
- Klijenti i dobavljači — baza kontakata
|
||||||
|
- Podsetnici — evidencija sa rokom
|
||||||
|
- Izveštaji — pregled prihoda, stanje magacina
|
||||||
|
- Podešavanja — naziv, adresa, PIB, logo firme; promena teme
|
||||||
|
|
||||||
### Planirano
|
### Planirano
|
||||||
|
|
||||||
- Prijava korisnika — sesije, zaključavanje naloga
|
|
||||||
- Dvofaktorska autentifikacija (TOTP)
|
|
||||||
- Izveštaji — prodaja, stanje magacina, prihodi
|
|
||||||
- Podrška za PostgreSQL (za višekorisničko okruženje)
|
- Podrška za PostgreSQL (za višekorisničko okruženje)
|
||||||
|
- WebAuthn / Passkey prijava (šema baze je pripremljena)
|
||||||
- Obaveštenja (e-pošta / WhatsApp) — odloženo za kasniju fazu
|
- Obaveštenja (e-pošta / WhatsApp) — odloženo za kasniju fazu
|
||||||
- Skeniranje barkodova putem kamere — odloženo za kasniju fazu
|
- Skeniranje barkodova putem kamere — odloženo za kasniju fazu
|
||||||
|
|
||||||
@@ -46,16 +51,14 @@ Cilj je jednostavan: sve što servis treba da prati nalazi se na jednom mestu, b
|
|||||||
|
|
||||||
## Tehnologije
|
## Tehnologije
|
||||||
|
|
||||||
| Tehnologija | Uloga |
|
| Tehnologija | Uloga |
|
||||||
| ------------------------------------------------------------------------------------ | -------------------------------- |
|
| ------------------------------------------------------------------------------------ | ------------------------------- |
|
||||||
| [Go](https://go.dev) | backend jezik |
|
| [Go](https://go.dev) | backend jezik |
|
||||||
| [chi](https://github.com/go-chi/chi) | HTTP ruter |
|
| [chi](https://github.com/go-chi/chi) | HTTP ruter |
|
||||||
| [html/template](https://pkg.go.dev/html/template) | serverski šabloni |
|
| [html/template](https://pkg.go.dev/html/template) | serverski šabloni |
|
||||||
| [HTMX](https://htmx.org) | interaktivnost bez build procesa |
|
| [Alpine.js](https://alpinejs.dev) | UI logika na strani klijenta |
|
||||||
| [TailwindCSS](https://tailwindcss.com) | stilizovanje |
|
| [SQLite](https://sqlite.org) + [modernc.org/sqlite](https://gitlab.com/cznic/sqlite) | glavna baza (čisti Go, bez CGO) |
|
||||||
| [Alpine.js](https://alpinejs.dev) | UI logika na strani klijenta |
|
| [PostgreSQL](https://www.postgresql.org) + [pgx/v5](https://github.com/jackc/pgx) | opciona baza za produkciju |
|
||||||
| [SQLite](https://sqlite.org) + [modernc.org/sqlite](https://gitlab.com/cznic/sqlite) | glavna baza (čisti Go, bez CGO) |
|
|
||||||
| [PostgreSQL](https://www.postgresql.org) + [pgx/v5](https://github.com/jackc/pgx) | opciona baza za produkciju |
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -73,22 +76,29 @@ Cilj je jednostavan: sve što servis treba da prati nalazi se na jednom mestu, b
|
|||||||
git clone <url-repozitorijuma>
|
git clone <url-repozitorijuma>
|
||||||
cd GoNtech
|
cd GoNtech
|
||||||
|
|
||||||
# 2. Kopiranje i popunjavanje .env fajla
|
# 2. Kopiranje konfiguracionog fajla
|
||||||
cp .env.example .env
|
cp ntech.env.example ntech.env
|
||||||
# Otvori .env i postavi vrednosti (videti tabelu ispod)
|
# Otvori ntech.env i postavi vrednosti (videti tabelu ispod)
|
||||||
|
|
||||||
# 3. Pokretanje u razvojnom okruženju
|
# 3. Učitavanje promenljivih i pokretanje u razvojnom okruženju
|
||||||
|
export $(grep -v '^#' ntech.env | xargs)
|
||||||
go run ./cmd/ntech
|
go run ./cmd/ntech
|
||||||
```
|
```
|
||||||
|
|
||||||
Program se otvara na `http://localhost:8080`.
|
Program se otvara na `http://localhost:8080` (ili na portu definisanom u `ntech.env`).
|
||||||
|
|
||||||
Pri prvom pokretanju automatski se pokreće setup wizard.
|
Pri prvom pokretanju automatski se pokreće setup wizard.
|
||||||
|
|
||||||
### Produkcioni build
|
### Produkcioni build
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
CGO_ENABLED=0 go build -o ntech ./cmd/ntech
|
# Pomoću build.sh skripte (prima opcioni argument verzije)
|
||||||
|
./build.sh 1.0.0
|
||||||
|
|
||||||
|
# Ili ručno
|
||||||
|
CGO_ENABLED=0 GOARCH=amd64 GOOS=linux go build \
|
||||||
|
-ldflags "-X main.Verzija=1.0.0 -s -w" \
|
||||||
|
-o ntech ./cmd/ntech
|
||||||
./ntech
|
./ntech
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -98,7 +108,7 @@ Rezultat je jedan statički binarni fajl bez zavisnosti.
|
|||||||
|
|
||||||
## Promenljive okruženja
|
## Promenljive okruženja
|
||||||
|
|
||||||
Kopirati `.env.example` u `.env` i popuniti vrednosti. Fajl `.env` se **ne commituje** u Git.
|
Kopirati `ntech.env.example` u `ntech.env` i popuniti vrednosti. Fajl `ntech.env` se **ne commituje** u Git.
|
||||||
|
|
||||||
| Promenljiva | Podrazumevano | Opis |
|
| Promenljiva | Podrazumevano | Opis |
|
||||||
| -------------- | ------------- | -------------------------------------------- |
|
| -------------- | ------------- | -------------------------------------------- |
|
||||||
@@ -118,19 +128,21 @@ ntech/
|
|||||||
├── cmd/
|
├── cmd/
|
||||||
│ └── ntech/ # ulazna tačka programa
|
│ └── ntech/ # ulazna tačka programa
|
||||||
├── internal/
|
├── internal/
|
||||||
│ ├── auth/ # prijava, sesije, 2FA
|
│ ├── auth/ # prijava, sesije, fail2ban log
|
||||||
│ ├── config/ # podešavanja, setup wizard
|
│ ├── config/ # podešavanja, setup wizard
|
||||||
│ ├── db/ # sloj baze podataka
|
│ ├── db/ # sloj baze podataka
|
||||||
│ │ ├── sqlite/ # SQLite implementacija
|
│ │ └── sqlite/ # SQLite implementacija
|
||||||
│ │ └── postgres/ # PostgreSQL implementacija
|
|
||||||
│ ├── handler/ # HTTP handleri
|
│ ├── handler/ # HTTP handleri
|
||||||
│ ├── middleware/ # autentifikacija, logovanje, ograničavanje zahteva
|
│ ├── middleware/ # CSRF, bezbednost headeri, autentifikacija
|
||||||
│ └── model/ # zajednički tipovi podataka
|
│ └── model/ # zajednički tipovi podataka
|
||||||
├── web/
|
├── web/
|
||||||
│ ├── static/ # CSS, JavaScript, slike
|
│ ├── static/ # CSS, JavaScript, slike, logotipi
|
||||||
│ └── templates/ # HTML šabloni
|
│ └── templates/ # HTML šabloni
|
||||||
├── migrations/ # SQL migracije (001_opis.sql, 002_opis.sql, ...)
|
├── migrations/ # SQL migracije (001_opis.sql, 002_opis.sql, ...)
|
||||||
├── .env.example # primer konfiguracije
|
├── logs/ # auth.log i ostali logovi
|
||||||
|
├── backups/ # rezervne kopije baze
|
||||||
|
├── build.sh # skripta za produkcioni build
|
||||||
|
├── ntech.env # lokalna konfiguracija (ne commituje se)
|
||||||
├── go.mod
|
├── go.mod
|
||||||
└── go.sum
|
└── go.sum
|
||||||
```
|
```
|
||||||
|
|||||||
@@ -192,7 +192,7 @@ func (h *Handler) AdminProfil(w http.ResponseWriter, r *http.Request) {
|
|||||||
|
|
||||||
podesavanja, _ := sqlite.DohvatiSvaPodesavanja(r.Context(), h.DB)
|
podesavanja, _ := sqlite.DohvatiSvaPodesavanja(r.Context(), h.DB)
|
||||||
ps := h.popuniPodaciStranice(r, podesavanja)
|
ps := h.popuniPodaciStranice(r, podesavanja)
|
||||||
ps.Stranica = "admin"
|
ps.Stranica = "profil"
|
||||||
ps.NaslovStranice = "Moj profil"
|
ps.NaslovStranice = "Moj profil"
|
||||||
|
|
||||||
podaci := podaciAdminProfil{
|
podaci := podaciAdminProfil{
|
||||||
@@ -261,7 +261,7 @@ func (h *Handler) AdminTotpPokreni(w http.ResponseWriter, r *http.Request) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ps := h.popuniPodaciStranice(r, podesavanja)
|
ps := h.popuniPodaciStranice(r, podesavanja)
|
||||||
ps.Stranica = "admin"
|
ps.Stranica = "profil"
|
||||||
ps.NaslovStranice = "Podesi 2FA"
|
ps.NaslovStranice = "Podesi 2FA"
|
||||||
|
|
||||||
podaci := podaciAdminProfil{
|
podaci := podaciAdminProfil{
|
||||||
@@ -294,7 +294,7 @@ func (h *Handler) AdminTotpAktivacija(w http.ResponseWriter, r *http.Request) {
|
|||||||
// ponovni prikaz sa greškom — regenerišemo isti tajnu
|
// ponovni prikaz sa greškom — regenerišemo isti tajnu
|
||||||
podesavanja, _ := sqlite.DohvatiSvaPodesavanja(r.Context(), h.DB)
|
podesavanja, _ := sqlite.DohvatiSvaPodesavanja(r.Context(), h.DB)
|
||||||
ps := h.popuniPodaciStranice(r, podesavanja)
|
ps := h.popuniPodaciStranice(r, podesavanja)
|
||||||
ps.Stranica = "admin"
|
ps.Stranica = "profil"
|
||||||
ps.NaslovStranice = "Podesi 2FA"
|
ps.NaslovStranice = "Podesi 2FA"
|
||||||
|
|
||||||
// regenerišemo QR za već generisanu tajnu (korisnik je video ovaj QR)
|
// regenerišemo QR za već generisanu tajnu (korisnik je video ovaj QR)
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ func (h *Handler) Dashboard(w http.ResponseWriter, r *http.Request) {
|
|||||||
|
|
||||||
if err := h.DB.QueryRowContext(ctx, `
|
if err := h.DB.QueryRowContext(ctx, `
|
||||||
SELECT COUNT(*) FROM servisni_nalozi
|
SELECT COUNT(*) FROM servisni_nalozi
|
||||||
WHERE status NOT IN ('Završeno', 'Preuzeto')`,
|
WHERE status != 'Završeno'`,
|
||||||
).Scan(&aktivniServisi); err != nil {
|
).Scan(&aktivniServisi); err != nil {
|
||||||
log.Printf("dashboard: aktivni servisi: %v", err)
|
log.Printf("dashboard: aktivni servisi: %v", err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -43,21 +43,15 @@ func (h *Handler) Dobavljaci(w http.ResponseWriter, r *http.Request) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ps := h.popuniPodaciStranice(r, podesavanja)
|
||||||
|
ps.Stranica = "dobavljaci"
|
||||||
|
ps.NaslovStranice = "Dobavljači"
|
||||||
podaci := PodaciDobavljaca{
|
podaci := PodaciDobavljaca{
|
||||||
PodaciStranice: model.PodaciStranice{
|
PodaciStranice: ps,
|
||||||
Stranica: "dobavljaci",
|
Dobavljaci: dobavljaci,
|
||||||
NaslovStranice: "Dobavljači",
|
Pretraga: pretraga,
|
||||||
Tema: podesavanja["tema"],
|
Sacuvano: r.URL.Query().Get("sacuvano") == "1",
|
||||||
NazivFirme: podesavanja["naziv_firme"],
|
Obrisan: r.URL.Query().Get("obrisan") == "1",
|
||||||
Podnazlov: podesavanja["podnazlov"],
|
|
||||||
LogoTip: podesavanja["logo_tip"],
|
|
||||||
LogoPutanja: podesavanja["logo_putanja"],
|
|
||||||
Korisnik: "Admin",
|
|
||||||
},
|
|
||||||
Dobavljaci: dobavljaci,
|
|
||||||
Pretraga: pretraga,
|
|
||||||
Sacuvano: r.URL.Query().Get("sacuvano") == "1",
|
|
||||||
Obrisan: r.URL.Query().Get("obrisan") == "1",
|
|
||||||
}
|
}
|
||||||
|
|
||||||
h.renderujTemplate(w, "dobavljaci", podaci)
|
h.renderujTemplate(w, "dobavljaci", podaci)
|
||||||
@@ -71,18 +65,12 @@ func (h *Handler) NoviDobavljac(w http.ResponseWriter, r *http.Request) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ps := h.popuniPodaciStranice(r, podesavanja)
|
||||||
|
ps.Stranica = "dobavljaci"
|
||||||
|
ps.NaslovStranice = "Novi dobavljač"
|
||||||
h.renderujFormuDobavljaca(w, PodaciFormeDobavljaca{
|
h.renderujFormuDobavljaca(w, PodaciFormeDobavljaca{
|
||||||
PodaciStranice: model.PodaciStranice{
|
PodaciStranice: ps,
|
||||||
Stranica: "dobavljaci",
|
Izmena: false,
|
||||||
NaslovStranice: "Novi dobavljač",
|
|
||||||
Tema: podesavanja["tema"],
|
|
||||||
NazivFirme: podesavanja["naziv_firme"],
|
|
||||||
Podnazlov: podesavanja["podnazlov"],
|
|
||||||
LogoTip: podesavanja["logo_tip"],
|
|
||||||
LogoPutanja: podesavanja["logo_putanja"],
|
|
||||||
Korisnik: "Admin",
|
|
||||||
},
|
|
||||||
Izmena: false,
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -96,20 +84,14 @@ func (h *Handler) SacuvajDobavljaca(w http.ResponseWriter, r *http.Request) {
|
|||||||
dobavljac, greska := parseFormuDobavljaca(r)
|
dobavljac, greska := parseFormuDobavljaca(r)
|
||||||
if greska != "" {
|
if greska != "" {
|
||||||
podesavanja, _ := sqlite.DohvatiSvaPodesavanja(r.Context(), h.DB)
|
podesavanja, _ := sqlite.DohvatiSvaPodesavanja(r.Context(), h.DB)
|
||||||
|
ps := h.popuniPodaciStranice(r, podesavanja)
|
||||||
|
ps.Stranica = "dobavljaci"
|
||||||
|
ps.NaslovStranice = "Novi dobavljač"
|
||||||
h.renderujFormuDobavljaca(w, PodaciFormeDobavljaca{
|
h.renderujFormuDobavljaca(w, PodaciFormeDobavljaca{
|
||||||
PodaciStranice: model.PodaciStranice{
|
PodaciStranice: ps,
|
||||||
Stranica: "dobavljaci",
|
Dobavljac: dobavljac,
|
||||||
NaslovStranice: "Novi dobavljač",
|
Greska: greska,
|
||||||
Tema: podesavanja["tema"],
|
Izmena: false,
|
||||||
NazivFirme: podesavanja["naziv_firme"],
|
|
||||||
Podnazlov: podesavanja["podnazlov"],
|
|
||||||
LogoTip: podesavanja["logo_tip"],
|
|
||||||
LogoPutanja: podesavanja["logo_putanja"],
|
|
||||||
Korisnik: "Admin",
|
|
||||||
},
|
|
||||||
Dobavljac: dobavljac,
|
|
||||||
Greska: greska,
|
|
||||||
Izmena: false,
|
|
||||||
})
|
})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -142,19 +124,13 @@ func (h *Handler) IzmeniDobavljaca(w http.ResponseWriter, r *http.Request) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ps := h.popuniPodaciStranice(r, podesavanja)
|
||||||
|
ps.Stranica = "dobavljaci"
|
||||||
|
ps.NaslovStranice = "Izmeni dobavljača"
|
||||||
h.renderujFormuDobavljaca(w, PodaciFormeDobavljaca{
|
h.renderujFormuDobavljaca(w, PodaciFormeDobavljaca{
|
||||||
PodaciStranice: model.PodaciStranice{
|
PodaciStranice: ps,
|
||||||
Stranica: "dobavljaci",
|
Dobavljac: *dobavljac,
|
||||||
NaslovStranice: "Izmeni dobavljača",
|
Izmena: true,
|
||||||
Tema: podesavanja["tema"],
|
|
||||||
NazivFirme: podesavanja["naziv_firme"],
|
|
||||||
Podnazlov: podesavanja["podnazlov"],
|
|
||||||
LogoTip: podesavanja["logo_tip"],
|
|
||||||
LogoPutanja: podesavanja["logo_putanja"],
|
|
||||||
Korisnik: "Admin",
|
|
||||||
},
|
|
||||||
Dobavljac: *dobavljac,
|
|
||||||
Izmena: true,
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -175,20 +151,14 @@ func (h *Handler) SacuvajIzmeneDobavljaca(w http.ResponseWriter, r *http.Request
|
|||||||
if greska != "" {
|
if greska != "" {
|
||||||
podesavanja, _ := sqlite.DohvatiSvaPodesavanja(r.Context(), h.DB)
|
podesavanja, _ := sqlite.DohvatiSvaPodesavanja(r.Context(), h.DB)
|
||||||
dobavljac.ID = id
|
dobavljac.ID = id
|
||||||
|
ps := h.popuniPodaciStranice(r, podesavanja)
|
||||||
|
ps.Stranica = "dobavljaci"
|
||||||
|
ps.NaslovStranice = "Izmeni dobavljača"
|
||||||
h.renderujFormuDobavljaca(w, PodaciFormeDobavljaca{
|
h.renderujFormuDobavljaca(w, PodaciFormeDobavljaca{
|
||||||
PodaciStranice: model.PodaciStranice{
|
PodaciStranice: ps,
|
||||||
Stranica: "dobavljaci",
|
Dobavljac: dobavljac,
|
||||||
NaslovStranice: "Izmeni dobavljača",
|
Greska: greska,
|
||||||
Tema: podesavanja["tema"],
|
Izmena: true,
|
||||||
NazivFirme: podesavanja["naziv_firme"],
|
|
||||||
Podnazlov: podesavanja["podnazlov"],
|
|
||||||
LogoTip: podesavanja["logo_tip"],
|
|
||||||
LogoPutanja: podesavanja["logo_putanja"],
|
|
||||||
Korisnik: "Admin",
|
|
||||||
},
|
|
||||||
Dobavljac: dobavljac,
|
|
||||||
Greska: greska,
|
|
||||||
Izmena: true,
|
|
||||||
})
|
})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -32,20 +32,14 @@ func (h *Handler) Kategorije(w http.ResponseWriter, r *http.Request) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ps := h.popuniPodaciStranice(r, podesavanja)
|
||||||
|
ps.Stranica = "magacin"
|
||||||
|
ps.NaslovStranice = "Kategorije"
|
||||||
podaci := PodaciKategorija{
|
podaci := PodaciKategorija{
|
||||||
PodaciStranice: model.PodaciStranice{
|
PodaciStranice: ps,
|
||||||
Stranica: "magacin",
|
Kategorije: kategorije,
|
||||||
NaslovStranice: "Kategorije",
|
Sacuvano: r.URL.Query().Get("sacuvano") == "1",
|
||||||
Tema: podesavanja["tema"],
|
Obrisana: r.URL.Query().Get("obrisana") == "1",
|
||||||
NazivFirme: podesavanja["naziv_firme"],
|
|
||||||
Podnazlov: podesavanja["podnazlov"],
|
|
||||||
LogoTip: podesavanja["logo_tip"],
|
|
||||||
LogoPutanja: podesavanja["logo_putanja"],
|
|
||||||
Korisnik: "Admin",
|
|
||||||
},
|
|
||||||
Kategorije: kategorije,
|
|
||||||
Sacuvano: r.URL.Query().Get("sacuvano") == "1",
|
|
||||||
Obrisana: r.URL.Query().Get("obrisana") == "1",
|
|
||||||
}
|
}
|
||||||
|
|
||||||
h.renderujTemplate(w, "kategorije", podaci)
|
h.renderujTemplate(w, "kategorije", podaci)
|
||||||
|
|||||||
+47
-89
@@ -44,21 +44,15 @@ func (h *Handler) Klijenti(w http.ResponseWriter, r *http.Request) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ps := h.popuniPodaciStranice(r, podesavanja)
|
||||||
|
ps.Stranica = "klijenti"
|
||||||
|
ps.NaslovStranice = "Klijenti"
|
||||||
podaci := PodaciKlijenata{
|
podaci := PodaciKlijenata{
|
||||||
PodaciStranice: model.PodaciStranice{
|
PodaciStranice: ps,
|
||||||
Stranica: "klijenti",
|
Klijenti: klijenti,
|
||||||
NaslovStranice: "Klijenti",
|
Pretraga: pretraga,
|
||||||
Tema: podesavanja["tema"],
|
Sacuvano: r.URL.Query().Get("sacuvano") == "1",
|
||||||
NazivFirme: podesavanja["naziv_firme"],
|
Obrisan: r.URL.Query().Get("obrisan") == "1",
|
||||||
Podnazlov: podesavanja["podnazlov"],
|
|
||||||
LogoTip: podesavanja["logo_tip"],
|
|
||||||
LogoPutanja: podesavanja["logo_putanja"],
|
|
||||||
Korisnik: "Admin",
|
|
||||||
},
|
|
||||||
Klijenti: klijenti,
|
|
||||||
Pretraga: pretraga,
|
|
||||||
Sacuvano: r.URL.Query().Get("sacuvano") == "1",
|
|
||||||
Obrisan: r.URL.Query().Get("obrisan") == "1",
|
|
||||||
}
|
}
|
||||||
|
|
||||||
h.renderujTemplate(w, "klijenti", podaci)
|
h.renderujTemplate(w, "klijenti", podaci)
|
||||||
@@ -72,18 +66,12 @@ func (h *Handler) NoviKlijent(w http.ResponseWriter, r *http.Request) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ps := h.popuniPodaciStranice(r, podesavanja)
|
||||||
|
ps.Stranica = "klijenti"
|
||||||
|
ps.NaslovStranice = "Novi klijent"
|
||||||
h.renderujFormuKlijenta(w, PodaciFormeKlijenta{
|
h.renderujFormuKlijenta(w, PodaciFormeKlijenta{
|
||||||
PodaciStranice: model.PodaciStranice{
|
PodaciStranice: ps,
|
||||||
Stranica: "klijenti",
|
Izmena: false,
|
||||||
NaslovStranice: "Novi klijent",
|
|
||||||
Tema: podesavanja["tema"],
|
|
||||||
NazivFirme: podesavanja["naziv_firme"],
|
|
||||||
Podnazlov: podesavanja["podnazlov"],
|
|
||||||
LogoTip: podesavanja["logo_tip"],
|
|
||||||
LogoPutanja: podesavanja["logo_putanja"],
|
|
||||||
Korisnik: "Admin",
|
|
||||||
},
|
|
||||||
Izmena: false,
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -97,20 +85,14 @@ func (h *Handler) SacuvajKlijenta(w http.ResponseWriter, r *http.Request) {
|
|||||||
klijent, greska := parseFormuKlijenta(r)
|
klijent, greska := parseFormuKlijenta(r)
|
||||||
if greska != "" {
|
if greska != "" {
|
||||||
podesavanja, _ := sqlite.DohvatiSvaPodesavanja(r.Context(), h.DB)
|
podesavanja, _ := sqlite.DohvatiSvaPodesavanja(r.Context(), h.DB)
|
||||||
|
ps := h.popuniPodaciStranice(r, podesavanja)
|
||||||
|
ps.Stranica = "klijenti"
|
||||||
|
ps.NaslovStranice = "Novi klijent"
|
||||||
h.renderujFormuKlijenta(w, PodaciFormeKlijenta{
|
h.renderujFormuKlijenta(w, PodaciFormeKlijenta{
|
||||||
PodaciStranice: model.PodaciStranice{
|
PodaciStranice: ps,
|
||||||
Stranica: "klijenti",
|
Klijent: klijent,
|
||||||
NaslovStranice: "Novi klijent",
|
Greska: greska,
|
||||||
Tema: podesavanja["tema"],
|
Izmena: false,
|
||||||
NazivFirme: podesavanja["naziv_firme"],
|
|
||||||
Podnazlov: podesavanja["podnazlov"],
|
|
||||||
LogoTip: podesavanja["logo_tip"],
|
|
||||||
LogoPutanja: podesavanja["logo_putanja"],
|
|
||||||
Korisnik: "Admin",
|
|
||||||
},
|
|
||||||
Klijent: klijent,
|
|
||||||
Greska: greska,
|
|
||||||
Izmena: false,
|
|
||||||
})
|
})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -118,20 +100,14 @@ func (h *Handler) SacuvajKlijenta(w http.ResponseWriter, r *http.Request) {
|
|||||||
if _, err := h.KlijentiRepo.Kreiraj(r.Context(), &klijent); err != nil {
|
if _, err := h.KlijentiRepo.Kreiraj(r.Context(), &klijent); err != nil {
|
||||||
log.Printf("greška pri čuvanju klijenta: %v", err)
|
log.Printf("greška pri čuvanju klijenta: %v", err)
|
||||||
podesavanja, _ := sqlite.DohvatiSvaPodesavanja(r.Context(), h.DB)
|
podesavanja, _ := sqlite.DohvatiSvaPodesavanja(r.Context(), h.DB)
|
||||||
|
ps := h.popuniPodaciStranice(r, podesavanja)
|
||||||
|
ps.Stranica = "klijenti"
|
||||||
|
ps.NaslovStranice = "Novi klijent"
|
||||||
h.renderujFormuKlijenta(w, PodaciFormeKlijenta{
|
h.renderujFormuKlijenta(w, PodaciFormeKlijenta{
|
||||||
PodaciStranice: model.PodaciStranice{
|
PodaciStranice: ps,
|
||||||
Stranica: "klijenti",
|
Klijent: klijent,
|
||||||
NaslovStranice: "Novi klijent",
|
Greska: "Došlo je do greške pri čuvanju. Pokušajte ponovo.",
|
||||||
Tema: podesavanja["tema"],
|
Izmena: false,
|
||||||
NazivFirme: podesavanja["naziv_firme"],
|
|
||||||
Podnazlov: podesavanja["podnazlov"],
|
|
||||||
LogoTip: podesavanja["logo_tip"],
|
|
||||||
LogoPutanja: podesavanja["logo_putanja"],
|
|
||||||
Korisnik: "Admin",
|
|
||||||
},
|
|
||||||
Klijent: klijent,
|
|
||||||
Greska: "Došlo je do greške pri čuvanju. Pokušajte ponovo.",
|
|
||||||
Izmena: false,
|
|
||||||
})
|
})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -159,19 +135,13 @@ func (h *Handler) IzmeniKlijenta(w http.ResponseWriter, r *http.Request) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ps := h.popuniPodaciStranice(r, podesavanja)
|
||||||
|
ps.Stranica = "klijenti"
|
||||||
|
ps.NaslovStranice = "Izmeni klijenta"
|
||||||
h.renderujFormuKlijenta(w, PodaciFormeKlijenta{
|
h.renderujFormuKlijenta(w, PodaciFormeKlijenta{
|
||||||
PodaciStranice: model.PodaciStranice{
|
PodaciStranice: ps,
|
||||||
Stranica: "klijenti",
|
Klijent: *klijent,
|
||||||
NaslovStranice: "Izmeni klijenta",
|
Izmena: true,
|
||||||
Tema: podesavanja["tema"],
|
|
||||||
NazivFirme: podesavanja["naziv_firme"],
|
|
||||||
Podnazlov: podesavanja["podnazlov"],
|
|
||||||
LogoTip: podesavanja["logo_tip"],
|
|
||||||
LogoPutanja: podesavanja["logo_putanja"],
|
|
||||||
Korisnik: "Admin",
|
|
||||||
},
|
|
||||||
Klijent: *klijent,
|
|
||||||
Izmena: true,
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -192,20 +162,14 @@ func (h *Handler) SacuvajIzmenuKlijenta(w http.ResponseWriter, r *http.Request)
|
|||||||
if greska != "" {
|
if greska != "" {
|
||||||
podesavanja, _ := sqlite.DohvatiSvaPodesavanja(r.Context(), h.DB)
|
podesavanja, _ := sqlite.DohvatiSvaPodesavanja(r.Context(), h.DB)
|
||||||
klijent.ID = id
|
klijent.ID = id
|
||||||
|
ps := h.popuniPodaciStranice(r, podesavanja)
|
||||||
|
ps.Stranica = "klijenti"
|
||||||
|
ps.NaslovStranice = "Izmeni klijenta"
|
||||||
h.renderujFormuKlijenta(w, PodaciFormeKlijenta{
|
h.renderujFormuKlijenta(w, PodaciFormeKlijenta{
|
||||||
PodaciStranice: model.PodaciStranice{
|
PodaciStranice: ps,
|
||||||
Stranica: "klijenti",
|
Klijent: klijent,
|
||||||
NaslovStranice: "Izmeni klijenta",
|
Greska: greska,
|
||||||
Tema: podesavanja["tema"],
|
Izmena: true,
|
||||||
NazivFirme: podesavanja["naziv_firme"],
|
|
||||||
Podnazlov: podesavanja["podnazlov"],
|
|
||||||
LogoTip: podesavanja["logo_tip"],
|
|
||||||
LogoPutanja: podesavanja["logo_putanja"],
|
|
||||||
Korisnik: "Admin",
|
|
||||||
},
|
|
||||||
Klijent: klijent,
|
|
||||||
Greska: greska,
|
|
||||||
Izmena: true,
|
|
||||||
})
|
})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -214,20 +178,14 @@ func (h *Handler) SacuvajIzmenuKlijenta(w http.ResponseWriter, r *http.Request)
|
|||||||
if err := h.KlijentiRepo.Izmeni(r.Context(), &klijent); err != nil {
|
if err := h.KlijentiRepo.Izmeni(r.Context(), &klijent); err != nil {
|
||||||
log.Printf("greška pri čuvanju izmene klijenta: %v", err)
|
log.Printf("greška pri čuvanju izmene klijenta: %v", err)
|
||||||
podesavanja, _ := sqlite.DohvatiSvaPodesavanja(r.Context(), h.DB)
|
podesavanja, _ := sqlite.DohvatiSvaPodesavanja(r.Context(), h.DB)
|
||||||
|
ps := h.popuniPodaciStranice(r, podesavanja)
|
||||||
|
ps.Stranica = "klijenti"
|
||||||
|
ps.NaslovStranice = "Izmeni klijenta"
|
||||||
h.renderujFormuKlijenta(w, PodaciFormeKlijenta{
|
h.renderujFormuKlijenta(w, PodaciFormeKlijenta{
|
||||||
PodaciStranice: model.PodaciStranice{
|
PodaciStranice: ps,
|
||||||
Stranica: "klijenti",
|
Klijent: klijent,
|
||||||
NaslovStranice: "Izmeni klijenta",
|
Greska: "Došlo je do greške pri čuvanju. Pokušajte ponovo.",
|
||||||
Tema: podesavanja["tema"],
|
Izmena: true,
|
||||||
NazivFirme: podesavanja["naziv_firme"],
|
|
||||||
Podnazlov: podesavanja["podnazlov"],
|
|
||||||
LogoTip: podesavanja["logo_tip"],
|
|
||||||
LogoPutanja: podesavanja["logo_putanja"],
|
|
||||||
Korisnik: "Admin",
|
|
||||||
},
|
|
||||||
Klijent: klijent,
|
|
||||||
Greska: "Došlo je do greške pri čuvanju. Pokušajte ponovo.",
|
|
||||||
Izmena: true,
|
|
||||||
})
|
})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -56,17 +56,11 @@ func (h *Handler) Magacin(w http.ResponseWriter, r *http.Request) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ps := h.popuniPodaciStranice(r, podesavanja)
|
||||||
|
ps.Stranica = "magacin"
|
||||||
|
ps.NaslovStranice = "Magacin"
|
||||||
podaci := PodaciMagacina{
|
podaci := PodaciMagacina{
|
||||||
PodaciStranice: model.PodaciStranice{
|
PodaciStranice: ps,
|
||||||
Stranica: "magacin",
|
|
||||||
NaslovStranice: "Magacin",
|
|
||||||
Tema: podesavanja["tema"],
|
|
||||||
NazivFirme: podesavanja["naziv_firme"],
|
|
||||||
Podnazlov: podesavanja["podnazlov"],
|
|
||||||
LogoTip: podesavanja["logo_tip"],
|
|
||||||
LogoPutanja: podesavanja["logo_putanja"],
|
|
||||||
Korisnik: "Admin",
|
|
||||||
},
|
|
||||||
Artikli: artikli,
|
Artikli: artikli,
|
||||||
Kategorije: kategorije,
|
Kategorije: kategorije,
|
||||||
Filter: filter,
|
Filter: filter,
|
||||||
|
|||||||
@@ -35,22 +35,14 @@ func (h *Handler) NoviArtikal(w http.ResponseWriter, r *http.Request) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
podaci := PodaciFormeArtikla{
|
ps := h.popuniPodaciStranice(r, podesavanja)
|
||||||
PodaciStranice: model.PodaciStranice{
|
ps.Stranica = "magacin"
|
||||||
Stranica: "magacin",
|
ps.NaslovStranice = "Novi artikal"
|
||||||
NaslovStranice: "Novi artikal",
|
h.renderujFormuArtikla(w, PodaciFormeArtikla{
|
||||||
Tema: podesavanja["tema"],
|
PodaciStranice: ps,
|
||||||
NazivFirme: podesavanja["naziv_firme"],
|
Kategorije: kategorije,
|
||||||
Podnazlov: podesavanja["podnazlov"],
|
Izmena: false,
|
||||||
LogoTip: podesavanja["logo_tip"],
|
})
|
||||||
LogoPutanja: podesavanja["logo_putanja"],
|
|
||||||
Korisnik: "Admin",
|
|
||||||
},
|
|
||||||
Kategorije: kategorije,
|
|
||||||
Izmena: false,
|
|
||||||
}
|
|
||||||
|
|
||||||
h.renderujFormuArtikla(w, podaci)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// SacuvajArtikal prima POST formu i čuva novi artikal
|
// SacuvajArtikal prima POST formu i čuva novi artikal
|
||||||
@@ -68,17 +60,11 @@ func (h *Handler) SacuvajArtikal(w http.ResponseWriter, r *http.Request) {
|
|||||||
if artikal.KategorijaID != nil {
|
if artikal.KategorijaID != nil {
|
||||||
katIDStr = strconv.FormatInt(*artikal.KategorijaID, 10)
|
katIDStr = strconv.FormatInt(*artikal.KategorijaID, 10)
|
||||||
}
|
}
|
||||||
|
ps := h.popuniPodaciStranice(r, podesavanja)
|
||||||
|
ps.Stranica = "magacin"
|
||||||
|
ps.NaslovStranice = "Novi artikal"
|
||||||
h.renderujFormuArtikla(w, PodaciFormeArtikla{
|
h.renderujFormuArtikla(w, PodaciFormeArtikla{
|
||||||
PodaciStranice: model.PodaciStranice{
|
PodaciStranice: ps,
|
||||||
Stranica: "magacin",
|
|
||||||
NaslovStranice: "Novi artikal",
|
|
||||||
Tema: podesavanja["tema"],
|
|
||||||
NazivFirme: podesavanja["naziv_firme"],
|
|
||||||
Podnazlov: podesavanja["podnazlov"],
|
|
||||||
LogoTip: podesavanja["logo_tip"],
|
|
||||||
LogoPutanja: podesavanja["logo_putanja"],
|
|
||||||
Korisnik: "Admin",
|
|
||||||
},
|
|
||||||
Artikal: artikal,
|
Artikal: artikal,
|
||||||
Kategorije: kategorije,
|
Kategorije: kategorije,
|
||||||
KategorijaIDStr: katIDStr,
|
KategorijaIDStr: katIDStr,
|
||||||
@@ -136,24 +122,16 @@ func (h *Handler) IzmeniArtikal(w http.ResponseWriter, r *http.Request) {
|
|||||||
katIDStr = strconv.FormatInt(*artikal.KategorijaID, 10)
|
katIDStr = strconv.FormatInt(*artikal.KategorijaID, 10)
|
||||||
}
|
}
|
||||||
|
|
||||||
podaci := PodaciFormeArtikla{
|
ps := h.popuniPodaciStranice(r, podesavanja)
|
||||||
PodaciStranice: model.PodaciStranice{
|
ps.Stranica = "magacin"
|
||||||
Stranica: "magacin",
|
ps.NaslovStranice = "Izmeni artikal"
|
||||||
NaslovStranice: "Izmeni artikal",
|
h.renderujFormuArtikla(w, PodaciFormeArtikla{
|
||||||
Tema: podesavanja["tema"],
|
PodaciStranice: ps,
|
||||||
NazivFirme: podesavanja["naziv_firme"],
|
|
||||||
Podnazlov: podesavanja["podnazlov"],
|
|
||||||
LogoTip: podesavanja["logo_tip"],
|
|
||||||
LogoPutanja: podesavanja["logo_putanja"],
|
|
||||||
Korisnik: "Admin",
|
|
||||||
},
|
|
||||||
Artikal: *artikal,
|
Artikal: *artikal,
|
||||||
Kategorije: kategorije,
|
Kategorije: kategorije,
|
||||||
KategorijaIDStr: katIDStr,
|
KategorijaIDStr: katIDStr,
|
||||||
Izmena: true,
|
Izmena: true,
|
||||||
}
|
})
|
||||||
|
|
||||||
h.renderujFormuArtikla(w, podaci)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// SacuvajIzmenuArtikla prima POST formu i čuva izmenu artikla
|
// SacuvajIzmenuArtikla prima POST formu i čuva izmenu artikla
|
||||||
@@ -179,17 +157,11 @@ func (h *Handler) SacuvajIzmenuArtikla(w http.ResponseWriter, r *http.Request) {
|
|||||||
if artikal.KategorijaID != nil {
|
if artikal.KategorijaID != nil {
|
||||||
katIDStr = strconv.FormatInt(*artikal.KategorijaID, 10)
|
katIDStr = strconv.FormatInt(*artikal.KategorijaID, 10)
|
||||||
}
|
}
|
||||||
|
ps := h.popuniPodaciStranice(r, podesavanja)
|
||||||
|
ps.Stranica = "magacin"
|
||||||
|
ps.NaslovStranice = "Izmeni artikal"
|
||||||
h.renderujFormuArtikla(w, PodaciFormeArtikla{
|
h.renderujFormuArtikla(w, PodaciFormeArtikla{
|
||||||
PodaciStranice: model.PodaciStranice{
|
PodaciStranice: ps,
|
||||||
Stranica: "magacin",
|
|
||||||
NaslovStranice: "Izmeni artikal",
|
|
||||||
Tema: podesavanja["tema"],
|
|
||||||
NazivFirme: podesavanja["naziv_firme"],
|
|
||||||
Podnazlov: podesavanja["podnazlov"],
|
|
||||||
LogoTip: podesavanja["logo_tip"],
|
|
||||||
LogoPutanja: podesavanja["logo_putanja"],
|
|
||||||
Korisnik: "Admin",
|
|
||||||
},
|
|
||||||
Artikal: artikal,
|
Artikal: artikal,
|
||||||
Kategorije: kategorije,
|
Kategorije: kategorije,
|
||||||
KategorijaIDStr: katIDStr,
|
KategorijaIDStr: katIDStr,
|
||||||
|
|||||||
+33
-57
@@ -25,11 +25,11 @@ type PodaciNabavki struct {
|
|||||||
// PodaciFormeNabavke su podaci za formu unosa nove nabavke
|
// PodaciFormeNabavke su podaci za formu unosa nove nabavke
|
||||||
type PodaciFormeNabavke struct {
|
type PodaciFormeNabavke struct {
|
||||||
model.PodaciStranice
|
model.PodaciStranice
|
||||||
Artikli []model.ArtikalSaKategorijom
|
Artikli []model.ArtikalSaKategorijom
|
||||||
ArtikliJSON template.JS // JSON niz artikala za Alpine.js — bezbedan za umetanje u <script>
|
ArtikliJSON template.JS // JSON niz artikala za Alpine.js — bezbedan za umetanje u <script>
|
||||||
Dobavljaci []model.Dobavljac
|
Dobavljaci []model.Dobavljac
|
||||||
Kategorije []model.Kategorija // za dropdown u modalu novog artikla
|
Kategorije []model.Kategorija // za dropdown u modalu novog artikla
|
||||||
Greska string
|
Greska string
|
||||||
}
|
}
|
||||||
|
|
||||||
// PodaciDetaljiNabavke su podaci za pregled jedne nabavke sa stavkama
|
// PodaciDetaljiNabavke su podaci za pregled jedne nabavke sa stavkama
|
||||||
@@ -68,20 +68,14 @@ func (h *Handler) Nabavke(w http.ResponseWriter, r *http.Request) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ps := h.popuniPodaciStranice(r, podesavanja)
|
||||||
|
ps.Stranica = "nabavke"
|
||||||
|
ps.NaslovStranice = "Nabavke"
|
||||||
podaci := PodaciNabavki{
|
podaci := PodaciNabavki{
|
||||||
PodaciStranice: model.PodaciStranice{
|
PodaciStranice: ps,
|
||||||
Stranica: "nabavke",
|
Nabavke: nabavke,
|
||||||
NaslovStranice: "Nabavke",
|
Sacuvano: r.URL.Query().Get("sacuvano") == "1",
|
||||||
Tema: podesavanja["tema"],
|
Obrisan: r.URL.Query().Get("obrisan") == "1",
|
||||||
NazivFirme: podesavanja["naziv_firme"],
|
|
||||||
Podnazlov: podesavanja["podnazlov"],
|
|
||||||
LogoTip: podesavanja["logo_tip"],
|
|
||||||
LogoPutanja: podesavanja["logo_putanja"],
|
|
||||||
Korisnik: "Admin",
|
|
||||||
},
|
|
||||||
Nabavke: nabavke,
|
|
||||||
Sacuvano: r.URL.Query().Get("sacuvano") == "1",
|
|
||||||
Obrisan: r.URL.Query().Get("obrisan") == "1",
|
|
||||||
}
|
}
|
||||||
|
|
||||||
h.renderujTemplate(w, "nabavke", podaci)
|
h.renderujTemplate(w, "nabavke", podaci)
|
||||||
@@ -113,21 +107,15 @@ func (h *Handler) NovaNabavka(w http.ResponseWriter, r *http.Request) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ps := h.popuniPodaciStranice(r, podesavanja)
|
||||||
|
ps.Stranica = "nabavke"
|
||||||
|
ps.NaslovStranice = "Nova nabavka"
|
||||||
h.renderujFormuNabavke(w, PodaciFormeNabavke{
|
h.renderujFormuNabavke(w, PodaciFormeNabavke{
|
||||||
PodaciStranice: model.PodaciStranice{
|
PodaciStranice: ps,
|
||||||
Stranica: "nabavke",
|
Artikli: artikli,
|
||||||
NaslovStranice: "Nova nabavka",
|
ArtikliJSON: artikalUJSON(artikli),
|
||||||
Tema: podesavanja["tema"],
|
Dobavljaci: dobavljaci,
|
||||||
NazivFirme: podesavanja["naziv_firme"],
|
Kategorije: kategorije,
|
||||||
Podnazlov: podesavanja["podnazlov"],
|
|
||||||
LogoTip: podesavanja["logo_tip"],
|
|
||||||
LogoPutanja: podesavanja["logo_putanja"],
|
|
||||||
Korisnik: "Admin",
|
|
||||||
},
|
|
||||||
Artikli: artikli,
|
|
||||||
ArtikliJSON: artikalUJSON(artikli),
|
|
||||||
Dobavljaci: dobavljaci,
|
|
||||||
Kategorije: kategorije,
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -144,22 +132,16 @@ func (h *Handler) SacuvajNabavku(w http.ResponseWriter, r *http.Request) {
|
|||||||
artikli, _ := h.Artikli.Lista(r.Context(), db.ArtikalFilter{})
|
artikli, _ := h.Artikli.Lista(r.Context(), db.ArtikalFilter{})
|
||||||
dobavljaci, _ := h.DobavljaciRepo.Lista(r.Context(), "")
|
dobavljaci, _ := h.DobavljaciRepo.Lista(r.Context(), "")
|
||||||
kategorije, _ := h.KategorijeRepo.Lista(r.Context())
|
kategorije, _ := h.KategorijeRepo.Lista(r.Context())
|
||||||
|
ps := h.popuniPodaciStranice(r, podesavanja)
|
||||||
|
ps.Stranica = "nabavke"
|
||||||
|
ps.NaslovStranice = "Nova nabavka"
|
||||||
h.renderujFormuNabavke(w, PodaciFormeNabavke{
|
h.renderujFormuNabavke(w, PodaciFormeNabavke{
|
||||||
PodaciStranice: model.PodaciStranice{
|
PodaciStranice: ps,
|
||||||
Stranica: "nabavke",
|
Artikli: artikli,
|
||||||
NaslovStranice: "Nova nabavka",
|
ArtikliJSON: artikalUJSON(artikli),
|
||||||
Tema: podesavanja["tema"],
|
Dobavljaci: dobavljaci,
|
||||||
NazivFirme: podesavanja["naziv_firme"],
|
Kategorije: kategorije,
|
||||||
Podnazlov: podesavanja["podnazlov"],
|
Greska: greska,
|
||||||
LogoTip: podesavanja["logo_tip"],
|
|
||||||
LogoPutanja: podesavanja["logo_putanja"],
|
|
||||||
Korisnik: "Admin",
|
|
||||||
},
|
|
||||||
Artikli: artikli,
|
|
||||||
ArtikliJSON: artikalUJSON(artikli),
|
|
||||||
Dobavljaci: dobavljaci,
|
|
||||||
Kategorije: kategorije,
|
|
||||||
Greska: greska,
|
|
||||||
})
|
})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -208,17 +190,11 @@ func (h *Handler) DetaljiNabavke(w http.ResponseWriter, r *http.Request) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ps := h.popuniPodaciStranice(r, podesavanja)
|
||||||
|
ps.Stranica = "nabavke"
|
||||||
|
ps.NaslovStranice = "Detalji nabavke"
|
||||||
podaci := PodaciDetaljiNabavke{
|
podaci := PodaciDetaljiNabavke{
|
||||||
PodaciStranice: model.PodaciStranice{
|
PodaciStranice: ps,
|
||||||
Stranica: "nabavke",
|
|
||||||
NaslovStranice: "Detalji nabavke",
|
|
||||||
Tema: podesavanja["tema"],
|
|
||||||
NazivFirme: podesavanja["naziv_firme"],
|
|
||||||
Podnazlov: podesavanja["podnazlov"],
|
|
||||||
LogoTip: podesavanja["logo_tip"],
|
|
||||||
LogoPutanja: podesavanja["logo_putanja"],
|
|
||||||
Korisnik: "Admin",
|
|
||||||
},
|
|
||||||
Nabavka: *nabavka,
|
Nabavka: *nabavka,
|
||||||
Stavke: stavke,
|
Stavke: stavke,
|
||||||
DobavljacNaziv: dobavljacNaziv,
|
DobavljacNaziv: dobavljacNaziv,
|
||||||
|
|||||||
@@ -40,28 +40,22 @@ func (h *Handler) Podesavanja(w http.ResponseWriter, r *http.Request) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ps := h.popuniPodaciStranice(r, podesavanja)
|
||||||
|
ps.Stranica = "podesavanja"
|
||||||
|
ps.NaslovStranice = "Podešavanja"
|
||||||
podaci := PodaciPodesavanja{
|
podaci := PodaciPodesavanja{
|
||||||
PodaciStranice: model.PodaciStranice{
|
PodaciStranice: ps,
|
||||||
Stranica: "podesavanja",
|
NazivFirme: podesavanja["naziv_firme"],
|
||||||
NaslovStranice: "Podešavanja",
|
Podnazlov: podesavanja["podnazlov"],
|
||||||
Tema: podesavanja["tema"],
|
Adresa: podesavanja["adresa"],
|
||||||
NazivFirme: podesavanja["naziv_firme"],
|
Telefon: podesavanja["telefon"],
|
||||||
Podnazlov: podesavanja["podnazlov"],
|
PIB: podesavanja["pib"],
|
||||||
LogoTip: podesavanja["logo_tip"],
|
LogoTip: podesavanja["logo_tip"],
|
||||||
LogoPutanja: podesavanja["logo_putanja"],
|
LogoPutanja: podesavanja["logo_putanja"],
|
||||||
Korisnik: "Admin",
|
Tema: podesavanja["tema"],
|
||||||
},
|
Sacuvano: r.URL.Query().Get("sacuvano") == "1",
|
||||||
NazivFirme: podesavanja["naziv_firme"],
|
Verzija: h.Verzija,
|
||||||
Podnazlov: podesavanja["podnazlov"],
|
LogoGreska: r.URL.Query().Get("logo_greska"),
|
||||||
Adresa: podesavanja["adresa"],
|
|
||||||
Telefon: podesavanja["telefon"],
|
|
||||||
PIB: podesavanja["pib"],
|
|
||||||
LogoTip: podesavanja["logo_tip"],
|
|
||||||
LogoPutanja: podesavanja["logo_putanja"],
|
|
||||||
Tema: podesavanja["tema"],
|
|
||||||
Sacuvano: r.URL.Query().Get("sacuvano") == "1",
|
|
||||||
Verzija: h.Verzija,
|
|
||||||
LogoGreska: r.URL.Query().Get("logo_greska"),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
h.renderujTemplate(w, "podesavanja", podaci)
|
h.renderujTemplate(w, "podesavanja", podaci)
|
||||||
|
|||||||
+31
-55
@@ -88,21 +88,15 @@ func (h *Handler) Prodaja(w http.ResponseWriter, r *http.Request) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ps := h.popuniPodaciStranice(r, podesavanja)
|
||||||
|
ps.Stranica = "prodaja"
|
||||||
|
ps.NaslovStranice = "Prodaja"
|
||||||
podaci := PodaciProdaje{
|
podaci := PodaciProdaje{
|
||||||
PodaciStranice: model.PodaciStranice{
|
PodaciStranice: ps,
|
||||||
Stranica: "prodaja",
|
Nalozi: nalozi,
|
||||||
NaslovStranice: "Prodaja",
|
Sacuvano: r.URL.Query().Get("sacuvano") == "1",
|
||||||
Tema: podesavanja["tema"],
|
Obrisan: r.URL.Query().Get("obrisan") == "1",
|
||||||
NazivFirme: podesavanja["naziv_firme"],
|
Pretraga: pretraga,
|
||||||
Podnazlov: podesavanja["podnazlov"],
|
|
||||||
LogoTip: podesavanja["logo_tip"],
|
|
||||||
LogoPutanja: podesavanja["logo_putanja"],
|
|
||||||
Korisnik: "Admin",
|
|
||||||
},
|
|
||||||
Nalozi: nalozi,
|
|
||||||
Sacuvano: r.URL.Query().Get("sacuvano") == "1",
|
|
||||||
Obrisan: r.URL.Query().Get("obrisan") == "1",
|
|
||||||
Pretraga: pretraga,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
h.renderujTemplate(w, "prodaja", podaci)
|
h.renderujTemplate(w, "prodaja", podaci)
|
||||||
@@ -128,20 +122,14 @@ func (h *Handler) NovaProdaja(w http.ResponseWriter, r *http.Request) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ps := h.popuniPodaciStranice(r, podesavanja)
|
||||||
|
ps.Stranica = "prodaja"
|
||||||
|
ps.NaslovStranice = "Nova prodaja"
|
||||||
h.renderujFormuProdaje(w, PodaciFormeProdaje{
|
h.renderujFormuProdaje(w, PodaciFormeProdaje{
|
||||||
PodaciStranice: model.PodaciStranice{
|
PodaciStranice: ps,
|
||||||
Stranica: "prodaja",
|
Artikli: artikli,
|
||||||
NaslovStranice: "Nova prodaja",
|
ArtikliJSON: artikalUJSONSaCenom(artikli),
|
||||||
Tema: podesavanja["tema"],
|
Klijenti: klijenti,
|
||||||
NazivFirme: podesavanja["naziv_firme"],
|
|
||||||
Podnazlov: podesavanja["podnazlov"],
|
|
||||||
LogoTip: podesavanja["logo_tip"],
|
|
||||||
LogoPutanja: podesavanja["logo_putanja"],
|
|
||||||
Korisnik: "Admin",
|
|
||||||
},
|
|
||||||
Artikli: artikli,
|
|
||||||
ArtikliJSON: artikalUJSONSaCenom(artikli),
|
|
||||||
Klijenti: klijenti,
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -158,21 +146,15 @@ func (h *Handler) SacuvajProdaju(w http.ResponseWriter, r *http.Request) {
|
|||||||
podesavanja, _ := sqlite.DohvatiSvaPodesavanja(r.Context(), h.DB)
|
podesavanja, _ := sqlite.DohvatiSvaPodesavanja(r.Context(), h.DB)
|
||||||
artikli, _ := h.Artikli.Lista(r.Context(), appdb.ArtikalFilter{})
|
artikli, _ := h.Artikli.Lista(r.Context(), appdb.ArtikalFilter{})
|
||||||
klijenti, _ := h.KlijentiRepo.Lista(r.Context(), "")
|
klijenti, _ := h.KlijentiRepo.Lista(r.Context(), "")
|
||||||
|
ps := h.popuniPodaciStranice(r, podesavanja)
|
||||||
|
ps.Stranica = "prodaja"
|
||||||
|
ps.NaslovStranice = "Nova prodaja"
|
||||||
h.renderujFormuProdaje(w, PodaciFormeProdaje{
|
h.renderujFormuProdaje(w, PodaciFormeProdaje{
|
||||||
PodaciStranice: model.PodaciStranice{
|
PodaciStranice: ps,
|
||||||
Stranica: "prodaja",
|
Artikli: artikli,
|
||||||
NaslovStranice: "Nova prodaja",
|
ArtikliJSON: artikalUJSONSaCenom(artikli),
|
||||||
Tema: podesavanja["tema"],
|
Klijenti: klijenti,
|
||||||
NazivFirme: podesavanja["naziv_firme"],
|
Greska: poruka,
|
||||||
Podnazlov: podesavanja["podnazlov"],
|
|
||||||
LogoTip: podesavanja["logo_tip"],
|
|
||||||
LogoPutanja: podesavanja["logo_putanja"],
|
|
||||||
Korisnik: "Admin",
|
|
||||||
},
|
|
||||||
Artikli: artikli,
|
|
||||||
ArtikliJSON: artikalUJSONSaCenom(artikli),
|
|
||||||
Klijenti: klijenti,
|
|
||||||
Greska: poruka,
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -250,21 +232,15 @@ func (h *Handler) DetaljiProdaje(w http.ResponseWriter, r *http.Request) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ps := h.popuniPodaciStranice(r, podesavanja)
|
||||||
|
ps.Stranica = "prodaja"
|
||||||
|
ps.NaslovStranice = "Detalji prodaje"
|
||||||
podaci := PodaciDetaljiProdaje{
|
podaci := PodaciDetaljiProdaje{
|
||||||
PodaciStranice: model.PodaciStranice{
|
PodaciStranice: ps,
|
||||||
Stranica: "prodaja",
|
Nalog: *nalog,
|
||||||
NaslovStranice: "Detalji prodaje",
|
Stavke: stavke,
|
||||||
Tema: podesavanja["tema"],
|
KlijentNaziv: klijentNaziv,
|
||||||
NazivFirme: podesavanja["naziv_firme"],
|
Sacuvano: r.URL.Query().Get("sacuvano") == "1",
|
||||||
Podnazlov: podesavanja["podnazlov"],
|
|
||||||
LogoTip: podesavanja["logo_tip"],
|
|
||||||
LogoPutanja: podesavanja["logo_putanja"],
|
|
||||||
Korisnik: "Admin",
|
|
||||||
},
|
|
||||||
Nalog: *nalog,
|
|
||||||
Stavke: stavke,
|
|
||||||
KlijentNaziv: klijentNaziv,
|
|
||||||
Sacuvano: r.URL.Query().Get("sacuvano") == "1",
|
|
||||||
}
|
}
|
||||||
|
|
||||||
h.renderujTemplate(w, "prodaja_detalji", podaci)
|
h.renderujTemplate(w, "prodaja_detalji", podaci)
|
||||||
|
|||||||
+69
-117
@@ -59,23 +59,17 @@ func (h *Handler) Servis(w http.ResponseWriter, r *http.Request) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ps := h.popuniPodaciStranice(r, podesavanja)
|
||||||
|
ps.Stranica = "servis"
|
||||||
|
ps.NaslovStranice = "Servis"
|
||||||
podaci := PodaciServisa{
|
podaci := PodaciServisa{
|
||||||
PodaciStranice: model.PodaciStranice{
|
PodaciStranice: ps,
|
||||||
Stranica: "servis",
|
Nalozi: nalozi,
|
||||||
NaslovStranice: "Servis",
|
Pretraga: pretraga,
|
||||||
Tema: podesavanja["tema"],
|
FilterStatus: filterStatus,
|
||||||
NazivFirme: podesavanja["naziv_firme"],
|
SviStatusi: model.SviStatusi,
|
||||||
Podnazlov: podesavanja["podnazlov"],
|
Sacuvano: r.URL.Query().Get("sacuvano") == "1",
|
||||||
LogoTip: podesavanja["logo_tip"],
|
Obrisan: r.URL.Query().Get("obrisan") == "1",
|
||||||
LogoPutanja: podesavanja["logo_putanja"],
|
|
||||||
Korisnik: "Admin",
|
|
||||||
},
|
|
||||||
Nalozi: nalozi,
|
|
||||||
Pretraga: pretraga,
|
|
||||||
FilterStatus: filterStatus,
|
|
||||||
SviStatusi: model.SviStatusi,
|
|
||||||
Sacuvano: r.URL.Query().Get("sacuvano") == "1",
|
|
||||||
Obrisan: r.URL.Query().Get("obrisan") == "1",
|
|
||||||
}
|
}
|
||||||
|
|
||||||
h.renderujTemplate(w, "servis", podaci)
|
h.renderujTemplate(w, "servis", podaci)
|
||||||
@@ -101,21 +95,15 @@ func (h *Handler) NoviNalog(w http.ResponseWriter, r *http.Request) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ps := h.popuniPodaciStranice(r, podesavanja)
|
||||||
|
ps.Stranica = "servis"
|
||||||
|
ps.NaslovStranice = "Novi nalog"
|
||||||
h.renderujFormuNaloga(w, PodaciFormeNaloga{
|
h.renderujFormuNaloga(w, PodaciFormeNaloga{
|
||||||
PodaciStranice: model.PodaciStranice{
|
PodaciStranice: ps,
|
||||||
Stranica: "servis",
|
Nalog: model.ServisniNalog{BrojNaloga: brojNaloga, Status: model.StatusPrimljeno},
|
||||||
NaslovStranice: "Novi nalog",
|
Klijenti: klijenti,
|
||||||
Tema: podesavanja["tema"],
|
SviStatusi: model.SviStatusi,
|
||||||
NazivFirme: podesavanja["naziv_firme"],
|
Izmena: false,
|
||||||
Podnazlov: podesavanja["podnazlov"],
|
|
||||||
LogoTip: podesavanja["logo_tip"],
|
|
||||||
LogoPutanja: podesavanja["logo_putanja"],
|
|
||||||
Korisnik: "Admin",
|
|
||||||
},
|
|
||||||
Nalog: model.ServisniNalog{BrojNaloga: brojNaloga, Status: model.StatusPrimljeno},
|
|
||||||
Klijenti: klijenti,
|
|
||||||
SviStatusi: model.SviStatusi,
|
|
||||||
Izmena: false,
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -130,22 +118,16 @@ func (h *Handler) SacuvajNalog(w http.ResponseWriter, r *http.Request) {
|
|||||||
if greska != "" {
|
if greska != "" {
|
||||||
podesavanja, _ := sqlite.DohvatiSvaPodesavanja(r.Context(), h.DB)
|
podesavanja, _ := sqlite.DohvatiSvaPodesavanja(r.Context(), h.DB)
|
||||||
klijenti, _ := h.KlijentiRepo.Lista(r.Context(), "")
|
klijenti, _ := h.KlijentiRepo.Lista(r.Context(), "")
|
||||||
|
ps := h.popuniPodaciStranice(r, podesavanja)
|
||||||
|
ps.Stranica = "servis"
|
||||||
|
ps.NaslovStranice = "Novi nalog"
|
||||||
h.renderujFormuNaloga(w, PodaciFormeNaloga{
|
h.renderujFormuNaloga(w, PodaciFormeNaloga{
|
||||||
PodaciStranice: model.PodaciStranice{
|
PodaciStranice: ps,
|
||||||
Stranica: "servis",
|
Nalog: nalog,
|
||||||
NaslovStranice: "Novi nalog",
|
Klijenti: klijenti,
|
||||||
Tema: podesavanja["tema"],
|
SviStatusi: model.SviStatusi,
|
||||||
NazivFirme: podesavanja["naziv_firme"],
|
Greska: greska,
|
||||||
Podnazlov: podesavanja["podnazlov"],
|
Izmena: false,
|
||||||
LogoTip: podesavanja["logo_tip"],
|
|
||||||
LogoPutanja: podesavanja["logo_putanja"],
|
|
||||||
Korisnik: "Admin",
|
|
||||||
},
|
|
||||||
Nalog: nalog,
|
|
||||||
Klijenti: klijenti,
|
|
||||||
SviStatusi: model.SviStatusi,
|
|
||||||
Greska: greska,
|
|
||||||
Izmena: false,
|
|
||||||
})
|
})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -155,22 +137,16 @@ func (h *Handler) SacuvajNalog(w http.ResponseWriter, r *http.Request) {
|
|||||||
log.Printf("greška pri čuvanju naloga: %v", err)
|
log.Printf("greška pri čuvanju naloga: %v", err)
|
||||||
podesavanja, _ := sqlite.DohvatiSvaPodesavanja(r.Context(), h.DB)
|
podesavanja, _ := sqlite.DohvatiSvaPodesavanja(r.Context(), h.DB)
|
||||||
klijenti, _ := h.KlijentiRepo.Lista(r.Context(), "")
|
klijenti, _ := h.KlijentiRepo.Lista(r.Context(), "")
|
||||||
|
ps := h.popuniPodaciStranice(r, podesavanja)
|
||||||
|
ps.Stranica = "servis"
|
||||||
|
ps.NaslovStranice = "Novi nalog"
|
||||||
h.renderujFormuNaloga(w, PodaciFormeNaloga{
|
h.renderujFormuNaloga(w, PodaciFormeNaloga{
|
||||||
PodaciStranice: model.PodaciStranice{
|
PodaciStranice: ps,
|
||||||
Stranica: "servis",
|
Nalog: nalog,
|
||||||
NaslovStranice: "Novi nalog",
|
Klijenti: klijenti,
|
||||||
Tema: podesavanja["tema"],
|
SviStatusi: model.SviStatusi,
|
||||||
NazivFirme: podesavanja["naziv_firme"],
|
Greska: "Došlo je do greške pri čuvanju. Pokušajte ponovo.",
|
||||||
Podnazlov: podesavanja["podnazlov"],
|
Izmena: false,
|
||||||
LogoTip: podesavanja["logo_tip"],
|
|
||||||
LogoPutanja: podesavanja["logo_putanja"],
|
|
||||||
Korisnik: "Admin",
|
|
||||||
},
|
|
||||||
Nalog: nalog,
|
|
||||||
Klijenti: klijenti,
|
|
||||||
SviStatusi: model.SviStatusi,
|
|
||||||
Greska: "Došlo je do greške pri čuvanju. Pokušajte ponovo.",
|
|
||||||
Izmena: false,
|
|
||||||
})
|
})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -204,21 +180,15 @@ func (h *Handler) IzmeniNalog(w http.ResponseWriter, r *http.Request) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ps := h.popuniPodaciStranice(r, podesavanja)
|
||||||
|
ps.Stranica = "servis"
|
||||||
|
ps.NaslovStranice = "Izmeni nalog"
|
||||||
h.renderujFormuNaloga(w, PodaciFormeNaloga{
|
h.renderujFormuNaloga(w, PodaciFormeNaloga{
|
||||||
PodaciStranice: model.PodaciStranice{
|
PodaciStranice: ps,
|
||||||
Stranica: "servis",
|
Nalog: *nalog,
|
||||||
NaslovStranice: "Izmeni nalog",
|
Klijenti: klijenti,
|
||||||
Tema: podesavanja["tema"],
|
SviStatusi: model.SviStatusi,
|
||||||
NazivFirme: podesavanja["naziv_firme"],
|
Izmena: true,
|
||||||
Podnazlov: podesavanja["podnazlov"],
|
|
||||||
LogoTip: podesavanja["logo_tip"],
|
|
||||||
LogoPutanja: podesavanja["logo_putanja"],
|
|
||||||
Korisnik: "Admin",
|
|
||||||
},
|
|
||||||
Nalog: *nalog,
|
|
||||||
Klijenti: klijenti,
|
|
||||||
SviStatusi: model.SviStatusi,
|
|
||||||
Izmena: true,
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -240,22 +210,16 @@ func (h *Handler) SacuvajIzmenaNaloga(w http.ResponseWriter, r *http.Request) {
|
|||||||
podesavanja, _ := sqlite.DohvatiSvaPodesavanja(r.Context(), h.DB)
|
podesavanja, _ := sqlite.DohvatiSvaPodesavanja(r.Context(), h.DB)
|
||||||
klijenti, _ := h.KlijentiRepo.Lista(r.Context(), "")
|
klijenti, _ := h.KlijentiRepo.Lista(r.Context(), "")
|
||||||
nalog.ID = id
|
nalog.ID = id
|
||||||
|
ps := h.popuniPodaciStranice(r, podesavanja)
|
||||||
|
ps.Stranica = "servis"
|
||||||
|
ps.NaslovStranice = "Izmeni nalog"
|
||||||
h.renderujFormuNaloga(w, PodaciFormeNaloga{
|
h.renderujFormuNaloga(w, PodaciFormeNaloga{
|
||||||
PodaciStranice: model.PodaciStranice{
|
PodaciStranice: ps,
|
||||||
Stranica: "servis",
|
Nalog: nalog,
|
||||||
NaslovStranice: "Izmeni nalog",
|
Klijenti: klijenti,
|
||||||
Tema: podesavanja["tema"],
|
SviStatusi: model.SviStatusi,
|
||||||
NazivFirme: podesavanja["naziv_firme"],
|
Greska: greska,
|
||||||
Podnazlov: podesavanja["podnazlov"],
|
Izmena: true,
|
||||||
LogoTip: podesavanja["logo_tip"],
|
|
||||||
LogoPutanja: podesavanja["logo_putanja"],
|
|
||||||
Korisnik: "Admin",
|
|
||||||
},
|
|
||||||
Nalog: nalog,
|
|
||||||
Klijenti: klijenti,
|
|
||||||
SviStatusi: model.SviStatusi,
|
|
||||||
Greska: greska,
|
|
||||||
Izmena: true,
|
|
||||||
})
|
})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -265,22 +229,16 @@ func (h *Handler) SacuvajIzmenaNaloga(w http.ResponseWriter, r *http.Request) {
|
|||||||
log.Printf("greška pri čuvanju izmene naloga: %v", err)
|
log.Printf("greška pri čuvanju izmene naloga: %v", err)
|
||||||
podesavanja, _ := sqlite.DohvatiSvaPodesavanja(r.Context(), h.DB)
|
podesavanja, _ := sqlite.DohvatiSvaPodesavanja(r.Context(), h.DB)
|
||||||
klijenti, _ := h.KlijentiRepo.Lista(r.Context(), "")
|
klijenti, _ := h.KlijentiRepo.Lista(r.Context(), "")
|
||||||
|
ps := h.popuniPodaciStranice(r, podesavanja)
|
||||||
|
ps.Stranica = "servis"
|
||||||
|
ps.NaslovStranice = "Izmeni nalog"
|
||||||
h.renderujFormuNaloga(w, PodaciFormeNaloga{
|
h.renderujFormuNaloga(w, PodaciFormeNaloga{
|
||||||
PodaciStranice: model.PodaciStranice{
|
PodaciStranice: ps,
|
||||||
Stranica: "servis",
|
Nalog: nalog,
|
||||||
NaslovStranice: "Izmeni nalog",
|
Klijenti: klijenti,
|
||||||
Tema: podesavanja["tema"],
|
SviStatusi: model.SviStatusi,
|
||||||
NazivFirme: podesavanja["naziv_firme"],
|
Greska: "Došlo je do greške pri čuvanju. Pokušajte ponovo.",
|
||||||
Podnazlov: podesavanja["podnazlov"],
|
Izmena: true,
|
||||||
LogoTip: podesavanja["logo_tip"],
|
|
||||||
LogoPutanja: podesavanja["logo_putanja"],
|
|
||||||
Korisnik: "Admin",
|
|
||||||
},
|
|
||||||
Nalog: nalog,
|
|
||||||
Klijenti: klijenti,
|
|
||||||
SviStatusi: model.SviStatusi,
|
|
||||||
Greska: "Došlo je do greške pri čuvanju. Pokušajte ponovo.",
|
|
||||||
Izmena: true,
|
|
||||||
})
|
})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -336,20 +294,14 @@ func (h *Handler) DetaljiNaloga(w http.ResponseWriter, r *http.Request) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ps := h.popuniPodaciStranice(r, podesavanja)
|
||||||
|
ps.Stranica = "servis"
|
||||||
|
ps.NaslovStranice = "Detalji naloga"
|
||||||
podaci := PodaciDetaljiNaloga{
|
podaci := PodaciDetaljiNaloga{
|
||||||
PodaciStranice: model.PodaciStranice{
|
PodaciStranice: ps,
|
||||||
Stranica: "servis",
|
Nalog: *nalog,
|
||||||
NaslovStranice: "Detalji naloga",
|
KlijentNaziv: klijentNaziv,
|
||||||
Tema: podesavanja["tema"],
|
Sacuvano: r.URL.Query().Get("sacuvano") == "1",
|
||||||
NazivFirme: podesavanja["naziv_firme"],
|
|
||||||
Podnazlov: podesavanja["podnazlov"],
|
|
||||||
LogoTip: podesavanja["logo_tip"],
|
|
||||||
LogoPutanja: podesavanja["logo_putanja"],
|
|
||||||
Korisnik: "Admin",
|
|
||||||
},
|
|
||||||
Nalog: *nalog,
|
|
||||||
KlijentNaziv: klijentNaziv,
|
|
||||||
Sacuvano: r.URL.Query().Get("sacuvano") == "1",
|
|
||||||
}
|
}
|
||||||
|
|
||||||
h.renderujTemplate(w, "servis_detalji", podaci)
|
h.renderujTemplate(w, "servis_detalji", podaci)
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ func BezbednostHeaders() func(http.Handler) http.Handler {
|
|||||||
h.Set("Content-Security-Policy",
|
h.Set("Content-Security-Policy",
|
||||||
"default-src 'self'; "+
|
"default-src 'self'; "+
|
||||||
"style-src 'self' 'unsafe-inline' https://cdn.tailwindcss.com; "+
|
"style-src 'self' 'unsafe-inline' https://cdn.tailwindcss.com; "+
|
||||||
"script-src 'self' 'unsafe-inline' https://cdn.tailwindcss.com https://cdn.jsdelivr.net; "+
|
"script-src 'self' 'unsafe-inline' 'unsafe-eval' https://cdn.tailwindcss.com https://cdn.jsdelivr.net; "+
|
||||||
"img-src 'self' data: blob:; "+
|
"img-src 'self' data: blob:; "+
|
||||||
"font-src 'self'; "+
|
"font-src 'self'; "+
|
||||||
"connect-src 'self'")
|
"connect-src 'self'")
|
||||||
|
|||||||
@@ -49,6 +49,14 @@ type ServisniNalogSaKlijentom struct {
|
|||||||
KlijentNaziv string
|
KlijentNaziv string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// KlijentIDVrednost vraća vrednost KlijentID pointera, ili 0 ako je nil
|
||||||
|
func (n ServisniNalog) KlijentIDVrednost() int64 {
|
||||||
|
if n.KlijentID == nil {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
return *n.KlijentID
|
||||||
|
}
|
||||||
|
|
||||||
// CenaOdStr vraća formatiranu procenu od, ili prazan string ako nije uneta
|
// CenaOdStr vraća formatiranu procenu od, ili prazan string ako nije uneta
|
||||||
func (n ServisniNalog) CenaOdStr() string {
|
func (n ServisniNalog) CenaOdStr() string {
|
||||||
if n.CenaOd == nil {
|
if n.CenaOd == nil {
|
||||||
|
|||||||
+26
-1
@@ -264,13 +264,31 @@ input[type="text"],
|
|||||||
input[type="email"],
|
input[type="email"],
|
||||||
input[type="password"],
|
input[type="password"],
|
||||||
input[type="number"],
|
input[type="number"],
|
||||||
textarea,
|
input[type="date"],
|
||||||
select {
|
select {
|
||||||
|
height: 38px;
|
||||||
|
padding: 8px 12px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
line-height: 1.5;
|
||||||
background: var(--kartica) !important;
|
background: var(--kartica) !important;
|
||||||
color: var(--tekst-glavni) !important;
|
color: var(--tekst-glavni) !important;
|
||||||
border: 0.5px solid var(--ivica) !important;
|
border: 0.5px solid var(--ivica) !important;
|
||||||
border-radius: 8px;
|
border-radius: 8px;
|
||||||
|
font-size: 14px;
|
||||||
|
outline: none;
|
||||||
|
transition: border-color 0.2s;
|
||||||
|
}
|
||||||
|
|
||||||
|
textarea {
|
||||||
|
height: auto;
|
||||||
|
min-height: 80px;
|
||||||
padding: 8px 12px;
|
padding: 8px 12px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
line-height: 1.5;
|
||||||
|
background: var(--kartica) !important;
|
||||||
|
color: var(--tekst-glavni) !important;
|
||||||
|
border: 0.5px solid var(--ivica) !important;
|
||||||
|
border-radius: 8px;
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
outline: none;
|
outline: none;
|
||||||
transition: border-color 0.2s;
|
transition: border-color 0.2s;
|
||||||
@@ -280,9 +298,16 @@ input[type="text"]:focus,
|
|||||||
input[type="email"]:focus,
|
input[type="email"]:focus,
|
||||||
input[type="password"]:focus,
|
input[type="password"]:focus,
|
||||||
input[type="number"]:focus,
|
input[type="number"]:focus,
|
||||||
|
input[type="date"]:focus,
|
||||||
textarea:focus,
|
textarea:focus,
|
||||||
select:focus {
|
select:focus {
|
||||||
border-color: var(--sb-akcent) !important;
|
border-color: var(--sb-akcent) !important;
|
||||||
|
outline: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
select {
|
||||||
|
width: 100%;
|
||||||
|
min-width: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* poruka o uspehu — konzistentna za sve teme */
|
/* poruka o uspehu — konzistentna za sve teme */
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
:root {
|
:root {
|
||||||
|
color-scheme: light;
|
||||||
--pozadina: #f6f8fa;
|
--pozadina: #f6f8fa;
|
||||||
--kartica: #ffffff;
|
--kartica: #ffffff;
|
||||||
--kartica-2: #f0f2f5;
|
--kartica-2: #f0f2f5;
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
:root {
|
:root {
|
||||||
|
color-scheme: dark;
|
||||||
--pozadina: #1f2228;
|
--pozadina: #1f2228;
|
||||||
--kartica: #22262d;
|
--kartica: #22262d;
|
||||||
--kartica-2: #2c313a;
|
--kartica-2: #2c313a;
|
||||||
|
|||||||
@@ -92,7 +92,7 @@
|
|||||||
</a>
|
</a>
|
||||||
{{end}}
|
{{end}}
|
||||||
|
|
||||||
<a href="/admin/profil" class="nav-stavka">
|
<a href="/admin/profil" class="nav-stavka {{if eq .Stranica "profil"}}aktivan{{end}}">
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M20 21v-2a4 4 0 0 0-4-4H8a4 4 0 0 0-4 4v2"/><circle cx="12" cy="7" r="4"/></svg>
|
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M20 21v-2a4 4 0 0 0-4-4H8a4 4 0 0 0-4 4v2"/><circle cx="12" cy="7" r="4"/></svg>
|
||||||
<span>Moj profil</span>
|
<span>Moj profil</span>
|
||||||
<span class="nav-tooltip">Moj profil</span>
|
<span class="nav-tooltip">Moj profil</span>
|
||||||
|
|||||||
@@ -109,7 +109,7 @@
|
|||||||
<option value="">— bez klijenta —</option>
|
<option value="">— bez klijenta —</option>
|
||||||
{{range .Klijenti}}
|
{{range .Klijenti}}
|
||||||
<option value="{{.ID}}"
|
<option value="{{.ID}}"
|
||||||
{{if $.Nalog.KlijentID}}{{if eq .ID $.Nalog.KlijentID}}selected{{end}}{{end}}>
|
{{if eq .ID $.Nalog.KlijentIDVrednost}}selected{{end}}>
|
||||||
{{if .NazivFirme}}{{.NazivFirme}}{{else}}{{.Ime}} {{.Prezime}}{{end}}
|
{{if .NazivFirme}}{{.NazivFirme}}{{else}}{{.Ime}} {{.Prezime}}{{end}}
|
||||||
</option>
|
</option>
|
||||||
{{end}}
|
{{end}}
|
||||||
|
|||||||
Reference in New Issue
Block a user