330f30d8bb
- Boja tačke na kritičnim zalihama: crvena kad je količina upola manja od minimalne - Uklonjen preload pozadinske slike (nepotreban, izazivao warning u konzoli) - @view-transition umotan u @supports da ne izaziva warning u browserima koji ne podržavaju
161 lines
4.4 KiB
Go
161 lines
4.4 KiB
Go
package handler
|
|
|
|
import (
|
|
"log/slog"
|
|
"net/http"
|
|
|
|
appdb "ntech/internal/db"
|
|
"ntech/internal/db/sqlite"
|
|
"ntech/internal/middleware"
|
|
"ntech/internal/model"
|
|
)
|
|
|
|
// Dashboard renderuje početnu stranicu sa pravim podacima iz baze
|
|
func (h *Handler) Dashboard(w http.ResponseWriter, r *http.Request) {
|
|
ctx := r.Context()
|
|
|
|
// pročitaj i odmah obrišt flash poruku ako postoji
|
|
var flashGreska string
|
|
if kol, err := r.Cookie("ntech_flash_greska"); err == nil {
|
|
flashGreska = kol.Value
|
|
http.SetCookie(w, &http.Cookie{
|
|
Name: "ntech_flash_greska",
|
|
Value: "",
|
|
Path: "/",
|
|
MaxAge: -1,
|
|
})
|
|
}
|
|
|
|
podesavanja, err := sqlite.DohvatiSvaPodesavanja(ctx, h.DB)
|
|
if err != nil {
|
|
http.Error(w, "Greška pri učitavanju podešavanja", http.StatusInternalServerError)
|
|
return
|
|
}
|
|
|
|
var brojArtikala, aktivniServisi, kriticnaZaliha, aktivniPodsetnici int
|
|
var prihodOvogMeseca float64
|
|
|
|
if n, err := h.IzvestajRepo.BrojArtikala(ctx); err != nil {
|
|
slog.Error("dashboard: broj artikala", "error", err)
|
|
} else {
|
|
brojArtikala = n
|
|
}
|
|
|
|
if n, err := h.IzvestajRepo.BrojAktivnihServisa(ctx); err != nil {
|
|
slog.Error("dashboard: aktivni servisi", "error", err)
|
|
} else {
|
|
aktivniServisi = n
|
|
}
|
|
|
|
// prihod se dohvata samo ako korisnik ima dozvolu dashboard.prihod
|
|
korisnikDash := middleware.KorisnikIzKonteksta(ctx)
|
|
if h.DozvoleRepo.ImaDozvolu(ctx, korisnikDash.Uloga, "dashboard.prihod") {
|
|
if v, err := h.IzvestajRepo.PrihodTekuciMesec(ctx); err != nil {
|
|
slog.Error("dashboard: prihod ovog meseca", "error", err)
|
|
} else {
|
|
prihodOvogMeseca = v
|
|
}
|
|
}
|
|
|
|
if n, err := h.IzvestajRepo.BrojKriticnihZaliha(ctx); err != nil {
|
|
slog.Error("dashboard: kriticna zaliha", "error", err)
|
|
} else {
|
|
kriticnaZaliha = n
|
|
}
|
|
|
|
korisnikFilter := appdb.PodsetnikFilter{}
|
|
if korisnikDash.Uloga == "radnik" {
|
|
korisnikFilter.KorisnikID = &korisnikDash.ID
|
|
}
|
|
if n, err := h.PodsetnikRepo.BrojAktivnih(ctx, korisnikFilter); err != nil {
|
|
slog.Error("dashboard: aktivni podsetnici", "error", err)
|
|
} else {
|
|
aktivniPodsetnici = n
|
|
}
|
|
|
|
// poslednjih 5 servisnih naloga — repo vraća sirove redove, ovde formatiramo
|
|
var poslednjiServisi []model.StavkaServisa
|
|
if redovi, err := h.IzvestajRepo.PoslednjiServisi(ctx, 5); err != nil {
|
|
slog.Error("dashboard: poslednji servisi", "error", err)
|
|
} else {
|
|
for _, s := range redovi {
|
|
poslednjiServisi = append(poslednjiServisi, model.StavkaServisa{
|
|
Uredjaj: s.Uredjaj,
|
|
Status: s.Status,
|
|
BojaTacke: bojaTackeServisa(s.Status),
|
|
DatumPrijema: s.DatumPrijema.Format("02.01."),
|
|
})
|
|
}
|
|
}
|
|
|
|
// artikli sa kritičnom zalihom
|
|
var kriticneZalihe []model.StavkaZalihe
|
|
if redovi, err := h.IzvestajRepo.KriticneZalihe(ctx, 5); err != nil {
|
|
slog.Error("dashboard: kriticne zalihe", "error", err)
|
|
} else {
|
|
for _, z := range redovi {
|
|
boja := "#f97316"
|
|
if z.Kolicina == 0 || (z.KolicinaMin > 0 && z.Kolicina <= z.KolicinaMin/2) {
|
|
boja = "#dc2626"
|
|
}
|
|
kriticneZalihe = append(kriticneZalihe, model.StavkaZalihe{
|
|
Naziv: z.Naziv,
|
|
Kolicina: z.Kolicina,
|
|
BojaTacke: boja,
|
|
})
|
|
}
|
|
}
|
|
|
|
// poslednjih 5 prodajnih naloga
|
|
var poslednjeProdaje []model.StavkaProdajePregled
|
|
if redovi, err := h.IzvestajRepo.PoslednjeProdaje(ctx, 5); err != nil {
|
|
slog.Error("dashboard: poslednje prodaje", "error", err)
|
|
} else {
|
|
for _, p := range redovi {
|
|
poslednjeProdaje = append(poslednjeProdaje, model.StavkaProdajePregled{
|
|
BrojNaloga: p.BrojNaloga,
|
|
Ukupno: p.Ukupno,
|
|
Datum: p.Datum.Format("02.01."),
|
|
KlijentNaziv: p.KlijentNaziv,
|
|
})
|
|
}
|
|
}
|
|
|
|
ps := h.popuniPodaciStranice(r, podesavanja)
|
|
ps.Stranica = "dashboard"
|
|
ps.NaslovStranice = "Dashboard"
|
|
|
|
podaci := model.PodaciDashboarda{
|
|
PodaciStranice: ps,
|
|
BrojArtikala: brojArtikala,
|
|
AktivniServisi: aktivniServisi,
|
|
PrihodOvogMeseca: prihodOvogMeseca,
|
|
KriticnaZaliha: kriticnaZaliha,
|
|
AktivniPodsetnici: aktivniPodsetnici,
|
|
PoslednjiServisi: poslednjiServisi,
|
|
KriticneZalihe: kriticneZalihe,
|
|
PoslednjeProdaje: poslednjeProdaje,
|
|
FlashGreska: flashGreska,
|
|
}
|
|
|
|
h.renderujTemplate(w, "dashboard", podaci)
|
|
}
|
|
|
|
// bojaTackeServisa vraća hex boju tačke prema statusu naloga
|
|
func bojaTackeServisa(status string) string {
|
|
switch status {
|
|
case "U dijagnostici":
|
|
return "#3b82f6"
|
|
case "Čeka delove":
|
|
return "#f97316"
|
|
case "U popravci":
|
|
return "#ca8a04"
|
|
case "Završeno":
|
|
return "#16a34a"
|
|
case "Preuzeto":
|
|
return "#15803d"
|
|
default:
|
|
return "#94a3b8"
|
|
}
|
|
}
|