Replace company_id from current_user with active company from session in
the colleagues API endpoint, and autofill guest org from active_company.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Users with multiple companies now see a dropdown to choose which company
a B2B classified ad is posted for. Single-company users get a hidden field.
Server-side validates the selected company_id against user's actual memberships.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Replace single "Moja firma" link with a switchable company list for users
with multiple companies, using POST forms with CSRF and active-state highlighting.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Replace textarea with Quill editor in new/edit classified forms
- Sanitize HTML with sanitize_html() on save (XSS prevention)
- Render HTML in classified detail view, strip tags in list view
- New script: classified_expiry_notifier.py sends email 3 days before
expiry with link to extend. Run daily via cron at 8:00.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Added to GeoIP tab:
- Last 20 blocked requests with IP, country, path, timestamp
- Top 10 most targeted URL paths with hit counts
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Reply seen-by section was hardcoded to show initials only.
Added avatar_path check matching topic readers pattern.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Added CSS rule for .reader-avatar img with absolute positioning
to properly display avatar photos inside the 28px circles.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Portal is production - no more test topics. Changed topic #1 category
from 'test' to 'announcement'. Removed toggle-test UI from forum list.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Expired classifieds show 'Wygasło' badge on list and detail view
- Closed classifieds show 'Zamknięte' badge on list
- Author can extend by 30 days with one click
- Homepage 'Nowe na portalu' excludes expired classifieds
- List shows all classifieds, active first
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Use raw SQL UPDATE for views_count to bypass SQLAlchemy onupdate.
Restore updated_at display in homepage cards - now accurate.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
updated_at was being triggered by views_count increment on every page
view, making dates misleading. Reverted to created_at for display and sort.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Forum cards now show date of latest reply (not topic creation).
B2B cards show updated_at (not created_at), sorted by most recent activity.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Replace 'Najnowszy wpis na forum' (duplicate with Nowe na portalu)
with 'Nowi użytkownicy portalu' showing 4 latest registered users
with avatars, names, dates and company names.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Shows 2 latest forum topics + 2 latest B2B classifieds in a 4-column
grid between events and NordaGPT banner. Responsive 2-col on mobile.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- New edit route with form pre-filled with existing data
- Edit existing attachments (mark for deletion) + add new ones
- Edit button visible to classified author on detail view
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- New ClassifiedAttachment model with migration
- FileUploadService extended with 'classified' type
- Dropzone with drag & drop, paste, multi-file preview in creation form
- Image gallery with lightbox in classified detail view
- Max 10 files, 5MB each, JPG/PNG/GIF
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Left-align grid (max-width 900px)
- Show 12 events instead of 8
- Add filter buttons (Wszystkie / Norda Biznes / Zewnętrzne)
- Green gradient for external events matching homepage style
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
New "Karty" view shows up to 8 upcoming events as dark gradient cards
in a 2-column grid, matching the homepage event banner style.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add profile links to usernames and avatars across forum, classifieds,
announcements, company recommendations, board members, and group messages.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Added global parseUTC() helper in base.html that appends 'Z' to
naive ISO dates from server. Applied to:
- Notification bell (base.html) — formatTimeAgo
- NordaGPT conversation sort (chat.html)
- B2B interest dates (classifieds/view.html)
- Admin forum moderation dates (admin/forum.html)
- Admin AI insights dates (admin/insights.html)
Same fix as conversations.js parseUTC, now available globally.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The clipboard.onPaste override broke text pasting in Quill 2.x
where this internal API is no longer public. Replaced with a DOM
paste event listener on quill.root that only intercepts image
pastes and lets Quill handle text paste natively.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Added "X odpow." counter next to views count on each classified
card in the B2B board listing.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Added avatar_path photo display for: author avatar, seen-by readers,
and Q&A question authors on the classified detail page. Falls back
to colored initial circle when no photo is uploaded.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
When clicking "Skontaktuj się" on a classified ad, the conversation
now starts with a pre-filled message: "Hej, piszę w sprawie ogłoszenia
na tablicy B2B: „<tytuł>"". If conversation already exists, the
context is pre-filled in the editor for the user to send.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The interest endpoint was returning 400 because fetch sent
Content-Type:application/json with an empty body, causing Flask
to fail JSON parsing. Removed the header since no JSON body is
sent. Also reverted unnecessary CSRF blueprint exemption.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Changed B2B classified contact link from old messages_new to new
conversations page with ?new_to=USER_ID parameter. JS creates a
1:1 conversation via API and opens it, or opens existing one if
already present. Messages now visible in the conversations inbox.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
New /admin/roadmap page showing feature requests from members in
three columns: Planned, In Progress, Done. Cards expand on click
to show implementation details. First item: multi-location support
requested by Daniel Kochański (Stalpunkt).
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
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>
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>
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>