Paginacija, interaktivna pretraga i optimizacija prikaza

- Dodata server-side paginacija za magacin (127 artikala) i klijente (1040)
  — Limit/Offset u ArtikalFilter i KlijentFilter, 100 po stranici
  — PrebrojiPoFilteru za izračunavanje ukupnog broja stranica
- Interaktivna pretraga (search-as-you-type) sa HTMX:
  — hx-trigger="keyup changed delay:300ms" na polju pretrage
  — HTMX menja samo #magacin-rezultati / #klijenti-rezultati
  — Polje pretrage ostaje u fokusu tokom osvežavanja
- Popravljena pretraga klijenata po imenu i prezimenu:
  — Dodato (ime || ' ' || prezime) LIKE u sva tri upita
  — "Ivana Lazić" sada pronalazi klijenta
- CSS optimizacije za velike liste:
  — content-visibility: auto na redovima tabela i karticama
  — contain-intrinsic-size za stabilan scroll
  — animation-delay produžen do 20. reda / 10. kartice
This commit is contained in:
2026-06-20 16:19:42 +02:00
parent 064d6dfa2a
commit a8f368ca06
8 changed files with 346 additions and 37 deletions
+42
View File
@@ -50,6 +50,15 @@ func (r *ArtikalRepo) Lista(ctx context.Context, filter db.ArtikalFilter) ([]mod
upit += " ORDER BY a.naziv ASC"
if filter.Limit > 0 {
upit += " LIMIT ?"
args = append(args, filter.Limit)
if filter.Offset > 0 {
upit += " OFFSET ?"
args = append(args, filter.Offset)
}
}
redovi, err := r.db.QueryContext(ctx, upit, args...)
if err != nil {
return nil, fmt.Errorf("ntech: ArtikalRepo.Lista: %w", err)
@@ -258,3 +267,36 @@ func (r *ArtikalRepo) KorigujKolicinu(ctx context.Context, artikalID int64, nova
return tx.Commit()
}
// PrebrojiPoFilteru vraća ukupan broj artikala koji zadovoljavaju filter (bez LIMIT/OFFSET)
func (r *ArtikalRepo) PrebrojiPoFilteru(ctx context.Context, filter db.ArtikalFilter) (int, error) {
upit := `
SELECT COUNT(*)
FROM artikli a
LEFT JOIN kategorije k ON a.kategorija_id = k.id
WHERE 1=1`
args := []any{}
if filter.Pretraga != "" {
upit += " AND (a.naziv LIKE ? OR a.sifra LIKE ? OR a.barkod LIKE ? OR a.lokacija LIKE ? OR k.naziv LIKE ?)"
t := "%" + filter.Pretraga + "%"
args = append(args, t, t, t, t, t)
}
if filter.KategorijaID != nil {
upit += " AND a.kategorija_id = ?"
args = append(args, *filter.KategorijaID)
}
if filter.SamoKriticni {
upit += " AND a.kolicina <= a.kolicina_min"
}
var broj int
if err := r.db.QueryRowContext(ctx, upit, args...).Scan(&broj); err != nil {
return 0, fmt.Errorf("ntech: ArtikalRepo.PrebrojiPoFilteru: %w", err)
}
return broj, nil
}