CC2 R3 frontend: login.html + admin_users.html (M1+M2+M10 UI)

- static/login.html: dark Palantir-style login with PGŽ branding,
  Prijava se / Zaboravljena lozinka, demo account quick-fills,
  GDPR cookie banner, autostore tokens (local/session)
- static/admin_users.html: full user-management admin panel:
  - Collapsible left sidebar (Pregled, Korisnici, Tenanti, Audit log,
    Sigurnost, GDPR, links to ERP/CRM)
  - Users table with filters (q, tenant, role, status, limit)
  - + Dodaj korisnika modal (CRUD via /api/admin/users/*)
  - Suspend / unsuspend / reset-password / delete actions
  - Audit log viewer + Security KPIs + GDPR queue
  - Self-service: change pwd, export data (Art. 20), erasure request (Art. 17)
- pgz_sport_api.py: /login and /admin/users URL routes
- auth/seed_demo.py: added tajnik@atletski.pgz.hr/Atl2026!,
  admin@ak-kvarner.hr/Kvarner2026! demo users

5/5 live tests pass: login JWT, /me, /admin/users, /gdpr/consent, /gdpr/export

Note: existing admin.html (CC4 ERP/OCR work) preserved intact;
admin_users.html is dedicated user-mgmt page linked from sidebar.
This commit is contained in:
Damir Radulić
2026-05-05 00:20:03 +02:00
parent cef4d2575b
commit 8fe2478b84
17 changed files with 10013 additions and 37 deletions
+5 -2
View File
@@ -255,6 +255,7 @@ a.tag:hover,.tag[onclick]:hover{transform:translateY(-1px);filter:brightness(1.1
<section id="pg-manifestacije" class="section"></section>
<section id="pg-mreza" class="section"></section>
<section id="pg-forenzika" class="section"></section>
<section id="pg-audit" class="section"></section>
</div>
</main>
</div>
@@ -280,7 +281,8 @@ const NAV_ITEMS = [
{id:'objekti', ic:'\u{1F4CD}', label:'Objekti'},
{id:'manifestacije', ic:'\u{1F4C5}', label:'Manifestacije'},
{id:'mreza', ic:'\u{1F578}', label:'Mreža'},
{id:'forenzika', ic:'⚠', label:'Forenzika'}
{id:'forenzika', ic:'⚠', label:'Forenzika'},
{id:'audit', ic:'\u{1F512}', label:'Audit log'}
];
const SECTION_TITLES = {
dashboard: ['Dashboard', 'Pregled stanja PGŽ Sporta'],
@@ -291,7 +293,8 @@ const SECTION_TITLES = {
objekti: ['Sportski objekti', 'Geocodirana infrastruktura'],
manifestacije: ['Manifestacije', 'Sportski događaji'],
mreza: ['Mreža', 'Force-directed graf entiteta i veza'],
forenzika: ['Forenzika', 'Kritični nalazi i alarmi']
forenzika: ['Forenzika', 'Kritični nalazi i alarmi'],
audit: ['Audit log', 'Polygon PoS pečaćenje ključnih akcija']
};
const _cache = {savezi:null, klubovi:null, clanovi:null, objekti:null, manifestacije:null, sufin:null, dash:null};