5cf9236d52
Backend (routers/crm_extras_router.py):
- POST /api/crm/clanarine/bulk/uplatnice.zip — generira ZIP archive sa
HUB-3 PDF uplatnicama (filename: <KlubSlug>/<Prezime_Ime>-<id>-<godina>.pdf),
+ _manifest.txt + _manifest.json. Header X-Batch-Count = broj PDF-ova.
- pgz_sport.email_templates tablica (NEW) + 3 default templata seed-ana:
clanarina_opomena, lijecnicki_podsjetnik, obrazac_potpis
- GET/POST/PUT /api/crm/email-templates — CRUD
- POST /api/crm/email-templates/{code}/render — popuni {{var}} → subject+body
- POST /api/crm/email-templates/{code}/send — mock send (upiše u notifications
s channel=email + inapp)
- GET /api/notifications/me + /api/crm/notifications/me — user-scope unread
notifs (resolva user_id iz JWT 'sub' ili X-User-Id headera, fallback =
broadcast s user_id IS NULL); summary za badge
Frontend (crm.html):
- Bulk bar: + "🗜 Batch ZIP (PDF-ovi)" gumb (download blob s X-Batch-Count)
- Novi tab "📨 E-mail templates": lista s preview/edit/create modali,
▶ Preview render s test podacima per template, 📤 mock send
- API wrapper sad automatski šalje JWT iz localStorage 'jwt' ili
'access_token'; quick-login fallback (damir@pgz.hr / PGZ2026!) na 401
za POST/PUT zahtjeve. Avatar upload + ZIP fetch također passu Bearer.
5/5 live curl tests passed:
✓ /email-templates list (3 templata)
✓ /email-templates/lijecnicki_podsjetnik/render → subject+body
✓ /email-templates/obrazac_potpis/send → 2 notifs queued
✓ /clanarine/bulk/uplatnice.zip (50 IDs → 40 PDFs + 2 manifests, 354 KB)
✓ /api/notifications/me (X-User-Id:1 → user_id=1, 19 unread)