From acf8cada0e0fb21e4a5593b576e6507862338f25 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dalibor=20Markovi=C4=87?= Date: Mon, 1 Jun 2026 01:16:37 +0200 Subject: [PATCH] =?UTF-8?q?Dodavanje=20pode=C5=A1avanja=20u=20bazu,=20logo?= =?UTF-8?q?=20zona=20sa=20tri=20opcije?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cmd/ntech/main.go | 7 ++-- internal/db/sqlite/podesavanja.go | 48 +++++++++++++++++++++++++++ internal/handler/dashboard.go | 20 +++++++---- internal/handler/handler.go | 13 ++++++++ internal/model/stranica.go | 28 ++++++++-------- migrations/011_podesavanja.sql | 12 +++++++ web/templates/komponente/sidebar.html | 26 +++++++++------ 7 files changed, 123 insertions(+), 31 deletions(-) create mode 100644 internal/db/sqlite/podesavanja.go create mode 100644 internal/handler/handler.go create mode 100644 migrations/011_podesavanja.sql diff --git a/cmd/ntech/main.go b/cmd/ntech/main.go index 2860337..411ee76 100644 --- a/cmd/ntech/main.go +++ b/cmd/ntech/main.go @@ -47,16 +47,19 @@ func main() { } log.Println("Migracije uspešno izvršene") + // kreiramo handler sa bazom + h := handler.Novi(db) + r := chi.NewRouter() - // statični fajlovi — CSS, JS, slike + // statični fajlovi r.Handle("/static/*", http.StripPrefix("/static/", http.FileServer(http.Dir("web/static")))) // rute r.Get("/", func(w http.ResponseWriter, r *http.Request) { http.Redirect(w, r, "/dashboard", http.StatusFound) }) - r.Get("/dashboard", handler.Dashboard) + r.Get("/dashboard", h.Dashboard) log.Printf("NTech pokrenut na portu %s", port) err = http.ListenAndServe(":"+port, r) diff --git a/internal/db/sqlite/podesavanja.go b/internal/db/sqlite/podesavanja.go new file mode 100644 index 0000000..fe11ba0 --- /dev/null +++ b/internal/db/sqlite/podesavanja.go @@ -0,0 +1,48 @@ +package sqlite + +import ( + "context" + "database/sql" + "fmt" +) + +// DohvatiPodesavanje čita jednu vrednost iz tabele podešavanja +func DohvatiPodesavanje(ctx context.Context, db *sql.DB, kljuc string) (string, error) { + var vrednost string + err := db.QueryRowContext(ctx, "SELECT vrednost FROM podesavanja WHERE kljuc = ?", kljuc).Scan(&vrednost) + if err != nil { + return "", fmt.Errorf("ntech: DohvatiPodesavanje: %s: %w", kljuc, err) + } + return vrednost, nil +} + +// SacuvajPodesavanje upisuje ili menja vrednost u tabeli podešavanja +func SacuvajPodesavanje(ctx context.Context, db *sql.DB, kljuc, vrednost string) error { + _, err := db.ExecContext(ctx, + "INSERT INTO podesavanja (kljuc, vrednost) VALUES (?, ?) ON CONFLICT(kljuc) DO UPDATE SET vrednost = excluded.vrednost", + kljuc, vrednost, + ) + if err != nil { + return fmt.Errorf("ntech: SacuvajPodesavanje: %s: %w", kljuc, err) + } + return nil +} + +// DohvatiSvaPodesavanja čita sva podešavanja i vraća ih kao mapu +func DohvatiSvaPodesavanja(ctx context.Context, db *sql.DB) (map[string]string, error) { + redovi, err := db.QueryContext(ctx, "SELECT kljuc, vrednost FROM podesavanja") + if err != nil { + return nil, fmt.Errorf("ntech: DohvatiSvaPodesavanja: %w", err) + } + defer redovi.Close() + + rezultat := make(map[string]string) + for redovi.Next() { + var kljuc, vrednost string + if err := redovi.Scan(&kljuc, &vrednost); err != nil { + return nil, fmt.Errorf("ntech: DohvatiSvaPodesavanja: scan: %w", err) + } + rezultat[kljuc] = vrednost + } + return rezultat, nil +} diff --git a/internal/handler/dashboard.go b/internal/handler/dashboard.go index ff497c2..aeadf0a 100644 --- a/internal/handler/dashboard.go +++ b/internal/handler/dashboard.go @@ -4,18 +4,28 @@ import ( "html/template" "net/http" + "ntech/internal/db/sqlite" "ntech/internal/model" ) // Dashboard renderuje početnu stranicu -func Dashboard(w http.ResponseWriter, r *http.Request) { - // za sad koristimo testne podatke — kasnije će ići iz baze +func (h *Handler) Dashboard(w http.ResponseWriter, r *http.Request) { + // čitamo sva podešavanja iz baze + podesavanja, err := sqlite.DohvatiSvaPodesavanja(r.Context(), h.DB) + if err != nil { + http.Error(w, "Greška pri učitavanju podešavanja", http.StatusInternalServerError) + return + } + podaci := model.PodaciDashboarda{ PodaciStranice: model.PodaciStranice{ Stranica: "dashboard", NaslovStranice: "Dashboard", - Tema: "tamna", - NazivFirme: "NTech", + Tema: podesavanja["tema"], + NazivFirme: podesavanja["naziv_firme"], + Podnazlov: podesavanja["podnazlov"], + LogoTip: podesavanja["logo_tip"], + LogoPutanja: podesavanja["logo_putanja"], Korisnik: "Admin", }, BrojArtikala: 0, @@ -26,7 +36,6 @@ func Dashboard(w http.ResponseWriter, r *http.Request) { KriticneZalihe: []model.StavkaZalihe{}, } - // učitavamo sve potrebne šablone zajedno tmpl, err := template.ParseFiles( "web/templates/teme/podrazumevana/base.html", "web/templates/komponente/sidebar.html", @@ -38,7 +47,6 @@ func Dashboard(w http.ResponseWriter, r *http.Request) { return } - // renderujemo base šablon sa podacima if err := tmpl.ExecuteTemplate(w, "base", podaci); err != nil { http.Error(w, "Greška pri prikazu stranice", http.StatusInternalServerError) return diff --git a/internal/handler/handler.go b/internal/handler/handler.go new file mode 100644 index 0000000..d022c19 --- /dev/null +++ b/internal/handler/handler.go @@ -0,0 +1,13 @@ +package handler + +import "database/sql" + +// Handler drži zavisnosti koje su potrebne svim handlerima +type Handler struct { + DB *sql.DB +} + +// Novi kreira novi Handler sa datom bazom +func Novi(db *sql.DB) *Handler { + return &Handler{DB: db} +} diff --git a/internal/model/stranica.go b/internal/model/stranica.go index 5b1330f..a2d5ad9 100644 --- a/internal/model/stranica.go +++ b/internal/model/stranica.go @@ -4,7 +4,7 @@ package model type StavkaServisa struct { Uredjaj string Status string - BojaTacke string // "#16a34a" zelena, "#f59e0b" žuta, "#dc2626" crvena + BojaTacke string } // StavkaZalihe prikazuje jedan artikal sa kritičnom zalihom @@ -16,21 +16,23 @@ type StavkaZalihe struct { // PodaciStranice su zajednički podaci koje svaka stranica prima type PodaciStranice struct { - Stranica string // naziv aktivne stranice za sidebar - NaslovStranice string // naslov u topbaru - Tema string // aktivna tema: "tamna", "svetla", "zelena", "ljubicasta" - NazivFirme string // naziv firme za logo zonu - Logo string // putanja do logo fajla, opciono - Korisnik string // ime korisnika za avatar + Stranica string + NaslovStranice string + Tema string + NazivFirme string + Podnazlov string + LogoTip string // "ikonica", "tekst", "slika" + LogoPutanja string // putanja do slike, koristi se samo kada je LogoTip "slika" + Korisnik string } // PodaciDashboarda su podaci specifični za dashboard stranicu type PodaciDashboarda struct { PodaciStranice - BrojArtikala int - AktivniServisi int - ProdajaOvogMeseca int - KriticnaZaliha int - PoslednjiServisi []StavkaServisa - KriticneZalihe []StavkaZalihe + BrojArtikala int + AktivniServisi int + ProdajaOvogMeseca int + KriticnaZaliha int + PoslednjiServisi []StavkaServisa + KriticneZalihe []StavkaZalihe } diff --git a/migrations/011_podesavanja.sql b/migrations/011_podesavanja.sql new file mode 100644 index 0000000..fa141b6 --- /dev/null +++ b/migrations/011_podesavanja.sql @@ -0,0 +1,12 @@ +CREATE TABLE IF NOT EXISTS podesavanja ( + kljuc TEXT PRIMARY KEY, + vrednost TEXT NOT NULL +); + +-- podrazumevane vrednosti +INSERT OR IGNORE INTO podesavanja (kljuc, vrednost) VALUES + ('naziv_firme', 'NTech'), + ('podnazlov', 'Servis računara'), + ('logo_tip', 'ikonica'), + ('logo_putanja', ''), + ('tema', 'tamna'); diff --git a/web/templates/komponente/sidebar.html b/web/templates/komponente/sidebar.html index 12b01c1..9d0230d 100644 --- a/web/templates/komponente/sidebar.html +++ b/web/templates/komponente/sidebar.html @@ -1,6 +1,5 @@ {{define "sidebar"}}