Mobile menu stayed open after history.back() due to bfcache restoring
the page with menu in active state. Now closes menu before navigating
back, and on pageshow event to handle bfcache restore.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Shows a ← back button in the navbar only when running as installed
PWA (display-mode: standalone). Uses history.back() for navigation.
Hidden in regular browser where native back button exists.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Browser's native anchor scroll races with JS. Run doScroll at 50ms,
300ms, and 600ms after load to ensure it wins regardless of timing.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Use window 'load' event and scrollRestoration=manual to ensure scroll
happens after all content is rendered, overriding browser's native
anchor scroll which fires too early.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
When opening a forum topic from a notification link (e.g. #reply-55),
the page now smoothly scrolls to the specific reply with a brief
highlight, accounting for the sticky header offset.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Server stores timestamps in UTC without timezone suffix. JavaScript
new Date() treated them as local time, showing times 2h behind.
Added parseUTC() helper that appends 'Z' to naive ISO dates so the
browser correctly converts UTC → user's local timezone.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The template always rendered initials instead of checking for avatar_path.
Now displays the user's photo when available, with initials as fallback.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
JDG companies don't have board members or shareholders. When CEIDG
returns data for a company, automatically remove company_people
records sourced from ekrs.ms.gov.pl.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
When fetching company data by NIP, check CEIDG first (JDG) before
trying Biała Lista/KRS. This prevents JDG companies from being
overwritten with spółka data. Also auto-clears KRS fields when
CEIDG confirms the company is a JDG.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1. Fixed missing rx parameter in SVG arc command (a2 0 → a2 2 0)
that caused console error on every page load
2. Removed preload of favicon-512.png — only used in meta tags,
not rendered on page, causing "preloaded but not used" warning
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Renumbered all versions from v1.53+ down by 1 to eliminate the
v1.51→v1.53 gap. Current latest: v1.62.0.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Link keys must match the <strong>title</strong> text exactly for the
template macro to render "Wypróbuj →" buttons next to each item.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Merged same-day releases into v1.57.0. Renumbered v1.58-v1.63.
Added links to homepage and other key pages.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
New features: company wizard, paid events, homepage redesign, new members
page, group messaging UI, recipient search, group management panel.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
A previous replace-all of 'currentConversation' → 'currentConversationId'
doubled the suffix on the existing 'currentConversationId' variable,
breaking all conversation state references including the group panel.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The panel was showing 0 members because it used cached conversation
details that might have been loaded before the panel was opened.
Now it always fetches fresh data from the API.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- New PATCH /api/conversations/<id>/members/<uid> endpoint for role changes
- Owner can promote members to admin and demote back to member
- Admin can add/remove members and edit group name (same as owner except role changes)
- Member list shows role labels (Właściciel/Administrator/Członek)
- Fix: state.currentConversation → state.currentConversationId (panel was empty)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
When viewing a group conversation, a settings button appears in the chat
header. Clicking it opens a panel to: rename the group (owner only),
view members with roles, remove members (owner only), and add new members
via search. Uses existing API endpoints.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
New button next to "Nowa wiadomość" with outline style. Modal includes
group name field, multi-member search picker, and optional first message.
Uses the existing POST /api/conversations endpoint with is_group=true.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
When composing a new message to someone you already have a conversation
with, the dedup logic returned the existing conversation without adding
the message. Now it creates the message and publishes SSE notification.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The modal had no CSS — it was rendering as unstyled HTML. Added proper
overlay, card layout, input styling, suggestion list, and footer buttons
matching the NordaBiz design system.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The compose button was just a small pencil icon with no label. Now it shows
"Nowa wiadomość" text (hidden on mobile). Recipient search was broken because
window.__USERS__ was always empty — replaced with /api/users/search API endpoint
that queries active users by name/email with autocomplete suggestions.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
JS reads from API JSON which returns 'attendee_count' field (already includes
guests after previous fix). Using 'total_attendee_count' caused 'undefined'.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Event attendee counts were inconsistent - event detail page showed total
(members + guests = 42) but event list and homepage showed only members (39).
Now all views use total_attendee_count including guests (osoby towarzyszące).
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Logo images were cached for 30 days by nginx. After selecting a new logo
from the gallery, the browser still showed the old/placeholder image.
- Add cache-bust query param (?v=timestamp) to logo <img> src
- Update company.last_updated when logo is confirmed
- Use Date.now() redirect instead of reload() after confirm
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Flash success message showing format conversion (e.g. "JPG do WebP")
- Flash error message if conversion fails with suggestion to try another file
- Flash warning for unsupported file formats
- Form hint explains automatic WebP conversion
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Templates expect logo at {slug}.webp with SVG fallback. When users uploaded
JPG/PNG files, the logo was saved with original extension and never displayed.
Now all raster uploads are converted to .webp via Pillow; SVG stays as-is.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Onboarding steps had hardcoded /company/{id}/edit URLs that don't exist.
Changed to /firma/edytuj/{id} which is the actual company edit route.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Description is managed by portal admin (via CLI/DB), not editable in form.
Office manager edits only structured fields (title, date, time, prices, etc).
New events still get a plain textarea for initial description.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Admin action bar (edit + payments) moved to top of event detail page
- Quill WYSIWYG editor replaces raw textarea in event create/edit form
- Back-to-event link in edit form
- Removed duplicate admin buttons from bottom of event page
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Route GET/POST /admin/kalendarz/<id>/edytuj
- Reuses admin_new.html template with pre-filled fields in edit mode
- Edit button on event detail page and admin calendar list
- Supports all fields including paid event settings and attachments
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- EventGuest.guest_type: 'member' (member rate) or 'external' (guest rate)
- Dropdown of company colleagues when adding member-type guest
- Manual entry option for members not on portal
- Admin payment panel: "Dodaj osobę" with "Dodaj + opłacone" shortcut
- Migration 064: guest_type column
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add is_paid, price_member, price_guest to NordaEvent. Add payment_status,
payment_amount, payment_confirmed_by/at to EventAttendee and EventGuest.
Auto-assign amounts on RSVP. Admin panel at /admin/kalendarz/<id>/platnosci
for OFFICE_MANAGER to confirm payments. User sees payment status on event page.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
PWA smart banner displayed icon at 40x40 but loaded 192x192 PNG (17KB).
Now uses 48x48 WebP (1.9KB) — 89% smaller, with explicit dimensions.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Browser starts downloading fonts immediately instead of waiting
for CSS parse. Reduces the window between system font and Poppins,
which should lower CLS from font-display: swap reflow.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
d3.v7.min.js (225KB) and connections_modal.html (~1100 lines) were
loaded on every page but only used by owner-only "Mapa Powiązań" tool.
- Removed d3.js and connections_modal include from base.html
- Added {% block extra_scripts %} for pages that need external JS
- admin/zopk_knowledge_graph.html loads d3 via extra_scripts block
- connections_map.html already had its own d3 import
- "Mapa Powiązań" link now points to /connections page instead of modal
- zopk/index.html d3 code was disabled ({% if false %}) — no change needed
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Replace external Google Fonts CSS request (780ms render-blocking) with
self-hosted woff2 files served from /static/fonts/ with 30-day cache.
- 8 woff2 files: Poppins 400/500/600/700 × latin/latin-ext (53KB total)
- Inline @font-face declarations in <style> tag (no external request)
- font-display: swap preserved (no FOIT)
- CSP updated: removed fonts.googleapis.com and fonts.gstatic.com
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Missed 2 occurrences of #94a3b8 in previous commit. Now zero instances
of the old color remain in base.html.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Previous contrast ratio 3.58:1 (FAIL), now 4.82:1 (PASS).
Affects footer section text, links, footer-bottom, and inline span.
All 18 elements flagged by Lighthouse are resolved.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>