Commit Graph

84 Commits

Author SHA1 Message Date
Radosław Gierwiało
640ca2a563 feat(ui): improve password validation display with detailed requirements
- Enhance PasswordStrengthIndicator with visual checkmarks for each requirement
- Add explicit validation for uppercase, lowercase, and number requirements
- Show clear pass/fail indicators (CheckCircle/XCircle icons) for each criterion
- Add front-end validation matching production password policy
- Display specific error messages listing all missing requirements
- Align with production standards (8+ chars, uppercase, lowercase, number)
2025-12-06 18:34:03 +01:00
Radosław Gierwiało
3ee2be89e0 chore: update title and footer copy 2025-12-06 17:08:08 +01:00
Radosław Gierwiało
b02fd7151d chore: reorder and refine homepage features copy 2025-12-06 17:05:35 +01:00
Radosław Gierwiało
a7fb6261d6 chore: tweak homepage copy 2025-12-06 16:53:10 +01:00
Radosław Gierwiało
e2b10387c2 feat(beta): add beta testing features and privacy policy page
Implemented comprehensive beta testing system with tier badges and
reorganized environment configuration for better maintainability.

Beta Testing Features:
- Beta banner component with dismissible state (localStorage)
- Auto-assign SUPPORTER tier to new registrations (env controlled)
- TierBadge component with SUPPORTER/COMFORT tier display
- Badge shown in Navbar, ProfilePage, and PublicProfilePage
- Environment variables: VITE_BETA_MODE, BETA_AUTO_SUPPORTER

Environment Configuration Reorganization:
- Moved .env files from root to frontend/ and backend/ directories
- Created .env.{development,production}{,.example} structure
- Updated docker-compose.yml to use env_file for frontend
- All env vars properly namespaced and documented

Privacy Policy Implementation:
- New /privacy route with dedicated PrivacyPage component
- Comprehensive GDPR/RODO compliant privacy policy (privacy.html)
- Updated CookieConsent banner to link to /privacy
- Added Privacy Policy links to all footers (HomePage, PublicFooter)
- Removed privacy section from About Us page

HTML Content System:
- Replaced react-markdown dependency with simple HTML loader
- New HtmlContentPage component for rendering .html files
- Converted about-us.md and how-it-works.md to .html format
- Inline CSS support for full styling control
- Easier content editing without React knowledge

Backend Changes:
- Registration auto-assigns SUPPORTER tier when BETA_AUTO_SUPPORTER=true
- Added accountTier to auth middleware and user routes
- Updated public profile endpoint to include accountTier

Files:
- Added: frontend/.env.{development,production}{,.example}
- Added: backend/.env variables for BETA_AUTO_SUPPORTER
- Added: components/BetaBanner.jsx, TierBadge.jsx, HtmlContentPage.jsx
- Added: pages/PrivacyPage.jsx
- Added: public/content/{about-us,how-it-works,privacy}.html
- Modified: docker-compose.yml (env_file configuration)
- Modified: App.jsx (privacy route, beta banner)
- Modified: auth.js (auto SUPPORTER tier logic)
2025-12-06 11:50:28 +01:00
Radosław Gierwiało
76be8a4419 refactor(frontend): replace confirm() with modern confirmation modals
Replaced all confirm() dialogs with reusable ConfirmationModal component
for better UX. Modal dialogs provide clearer context, visual consistency,
and prevent accidental confirmations.

Changes:
- MatchesPage: Reject match request confirmation modal
- DashboardPage: Decline and cancel request confirmation modals
- ContactMessagesPage: Delete message confirmation modal

All modals support loading states during async operations and provide
clear action descriptions with destructive action styling.
2025-12-05 22:14:09 +01:00
Radosław Gierwiało
bb8a876ab0 refactor(frontend): replace alert() with modern toast notifications
Replaced all alert() calls with react-hot-toast notifications for better
user experience. Toast notifications are non-blocking, auto-dismiss, and
provide visual feedback with icons based on message type.

Changes:
- EventChatPage: Match request success/error toasts
- MatchChatPage: Video file selection and WebRTC connection error toasts
- MatchesPage: Match accept/reject action toasts
- RatePartnerPage: Rating submission and validation toasts
- VerifyEmailPage: Email verification sent toast
- ScheduleConfigSection: Schedule save success/error toasts
- MatchingConfigSection: Deadline save success/error toasts

All toast notifications use appropriate types (success, error, warning, info)
for better visual distinction and user feedback.
2025-12-05 22:09:37 +01:00
Radosław Gierwiało
3ae9fd149b feat(frontend): add unified header and footer to public pages
Implemented consistent navigation across all public-facing pages with a
reusable layout system. Created PublicLayout component that wraps pages
with a header containing the logo and a footer with navigation links.

Changes:
- Created PublicHeader component with logo linking to homepage
- Created PublicFooter component with Product, Account, and Support sections
- Created PublicLayout wrapper component using flex layout
- Updated all public pages to use PublicLayout:
  - LoginPage, RegisterPage, ForgotPasswordPage, ResetPasswordPage
  - VerifyEmailPage, ContactPage, AboutUsPage, HowItWorksPage
  - NotFoundPage
- Fixed gradient background pages to use min-h-full for proper height
- Fixed content pages to avoid min-h-screen conflicts with flex-grow
- Updated About Us content
2025-12-05 21:59:56 +01:00
Radosław Gierwiało
e1138c789e fix(homepage): improve responsive layout for mobile devices
Navigation:
- Reduce logo and text size on mobile (w-6 h-6 -> w-8 h-8 on sm+)
- Reduce spacing between nav items (space-x-2 -> space-x-4 on sm+)
- Hide 'Dashboard' text on mobile, show icon only
- Adjust padding and text sizes for all nav buttons
- Add whitespace-nowrap to 'Get Started' button

Hero section:
- Responsive heading sizes (text-3xl -> text-6xl)
- Responsive paragraph sizes (text-base -> text-2xl)
- Responsive padding (py-12 -> py-20)
- Responsive button sizes (px-6/py-3 -> px-8/py-4)
2025-12-05 18:42:52 +01:00
Radosław Gierwiało
00825d56b6 fix(profile): improve responsive layout for public profile
- Add flex-wrap to stats section to prevent overflow on small screens
- Make profile header flex-col on mobile, flex-row on larger screens
- Add flex-shrink-0 to icons to prevent them from shrinking
- Reduce padding on mobile (p-4) and increase on larger screens
- Add min-w-0 to prevent text overflow issues
2025-12-05 18:40:13 +01:00
Radosław Gierwiało
fb4e0bea99 refactor(profile): remove Matches count from public profile stats
- Remove Matches stat display from public profile
- Keep only Rating and Reviews stats visible
- Remove unused Users icon import
2025-12-05 18:38:14 +01:00
Radosław Gierwiało
1f763d4558 refactor(footer): remove Events link from Product section 2025-12-05 18:34:51 +01:00
Radosław Gierwiało
c4372930dd feat(content): add How It Works page with markdown support
- Create HowItWorksPage component with markdown rendering
- Add how-it-works.md with Lorem Ipsum placeholder content
- Add /how-it-works route in App.jsx
- Add How It Works link to homepage footer (Product section)
2025-12-05 18:33:25 +01:00
Radosław Gierwiało
2c5689ac8e feat(content): add About Us page with markdown content support
- Create AboutUsPage component with markdown rendering
- Add react-markdown library for content rendering
- Create public/content directory for editable markdown files
- Add about-us.md with Lorem Ipsum placeholder content
- Create public/images/about directory for page images
- Add /about-us route in App.jsx
- Add About Us link to homepage footer
- Support for external links (open in new tab) and internal links
- Responsive image rendering with rounded corners and shadow
2025-12-05 18:30:44 +01:00
Radosław Gierwiało
d8085f828f feat(security): add Cloudflare Turnstile CAPTCHA to registration form
- Add Turnstile widget rendering in RegisterPage on step 2
- Implement programmatic widget initialization with callbacks
- Add token validation before form submission
- Update AuthContext and API service to pass turnstileToken
- Add backend verification via Cloudflare API in register controller
- Include client IP in verification request
- Add validation rule for turnstileToken
- Reset widget on registration error
2025-12-05 18:20:26 +01:00
Radosław Gierwiało
f3b8156557 feat(security): implement Cloudflare Turnstile CAPTCHA on contact form
- Add Turnstile script to frontend/index.html
- Implement programmatic widget rendering in ContactPage
- Add backend verification via Cloudflare API
- Include client IP in verification request
- Update CSP headers to allow Cloudflare resources
- Add environment variable configuration for site and secret keys
- Pass VITE_TURNSTILE_SITE_KEY to frontend container
- Add validation and error handling for CAPTCHA tokens
2025-12-05 18:08:05 +01:00
Radosław Gierwiało
25042d0fec feat(home): adapt homepage for authenticated users
Changes for logged-in users:
- Top navigation: Show "Dashboard" and "Logout" buttons instead of "Sign In" and "Get Started"
- Hero CTA: Change main button to "Go to Dashboard" instead of "Start Collaborating"
- Hide bottom CTA section (registration prompt) for authenticated users
- Footer Account section: Show "Dashboard" and "Logout" instead of "Sign In" and "Register"

Other improvements:
- Removed "Explore Events" button from hero section
- Cleaned up footer: removed empty placeholder links (Features, How It Works, About, Privacy, Terms)
- Added "Support" section in footer with "Contact Us" link to /contact
- Simplified footer to 3 columns: Product (Events), Support (Contact Us), Account (dynamic based on auth)
2025-12-05 17:21:55 +01:00
Radosław Gierwiało
34f18b3b50 feat(contact): add contact form with admin panel and navbar dropdown
Database changes:
- Added ContactMessage model to Prisma schema
- Fields: userId, username, firstName, lastName, email, subject, message, status, ipAddress
- Status enum: new, read, resolved
- Relation to User model

Backend changes:
- Added POST /api/public/contact endpoint for form submissions
- Works for both authenticated and non-authenticated users
- Validation for email, subject (3-255 chars), message (10-5000 chars)
- Activity logging for submissions
- Added admin endpoints:
  - GET /api/admin/contact-messages - list with filtering by status
  - GET /api/admin/contact-messages/:id - view single message (auto-marks as read)
  - PATCH /api/admin/contact-messages/:id/status - update status
  - DELETE /api/admin/contact-messages/:id - delete message

Frontend changes:
- Created ContactPage at /contact route
- For non-logged-in users: firstName, lastName, email, subject, message fields
- For logged-in users: auto-fills username, shows only email, subject, message
- Character counter for message (max 5000)
- Success screen with auto-redirect to homepage
- Created ContactMessagesPage at /admin/contact-messages
- Two-column layout: message list + detail view
- Filter by status (all, new, read, resolved)
- View message details with sender info and IP address
- Update status and delete messages
- Added admin dropdown menu to Navbar
  - Desktop: dropdown with Activity Logs and Contact Messages
  - Mobile: expandable submenu
  - Click outside to close on desktop
  - ChevronDown icon rotates when open

Note: CAPTCHA integration planned for future enhancement
2025-12-05 17:15:25 +01:00
Radosław Gierwiało
f90945aa47 fix(profiles): make public profiles accessible without authentication and unify 404 behavior
Backend changes:
- Removed authentication requirement from GET /api/users/:username endpoint
- Removed authentication requirement from GET /api/users/:username/ratings endpoint
- These are public profile endpoints and should be accessible to all users

Frontend changes:
- PublicProfilePage now shows NotFoundPage component when user doesn't exist
- Unified 404 behavior: both invalid URLs and non-existent users show the same 404 page
- NotFoundPage "Requested URL" box now only shows in dev mode (import.meta.env.DEV)
- Removed unused AlertCircle icon import from PublicProfilePage
2025-12-05 16:54:38 +01:00
Radosław Gierwiało
948c694ed6 feat(system): implement 404 page with activity logging and change profile route format
Backend Changes:
- Added public API endpoint /api/public/log-404 (no auth required)
- Created backend/src/routes/public.js for public endpoints
- Added ACTIONS.SYSTEM_404 and CATEGORIES.system to activity log service
- Registered public routes in app.js

Frontend Changes:
- Created NotFoundPage.jsx with standalone layout (no auth required)
- Added publicAPI.log404() to log 404 access attempts
- Logs both authenticated and anonymous users
- Changed profile route from /@:username to /u/:username
- Made profile route public (removed ProtectedRoute wrapper)
- Updated all profile links from /@${username} to /u/${username} in:
  - ChatMessage.jsx
  - DashboardMatchCard.jsx
  - MatchRequestCards.jsx
  - MatchCard.jsx
  - UserListItem.jsx
  - MatchChatPage.jsx
  - PublicProfilePage.jsx

Fixes:
- React Router doesn't support @ in path segments
- 404 page now accessible to non-authenticated users without redirect
- Profile route no longer catches all unmatched routes
2025-12-03 20:27:51 +01:00
Radosław Gierwiało
eb5aacd797 refactor(admin): move event details page to admin section
- Moved EventDetailsPage from /events/:slug/details to /admin/events/:slug/details
- Added admin authentication check with redirect to login/home
- Updated all navigation links across the app:
  - EventsPage: "View details (admin)" button
  - EventChatPage: "View QR Code (admin)" link
  - EventCard: handleViewDetails navigation
- Fixed relative imports after moving to admin folder

This page contains admin-only features (QR codes, participants list,
matching config, scheduler config, matching runs) and should only be
accessible to administrators.
2025-12-03 19:52:00 +01:00
Radosław Gierwiało
dd3176196e fix(chat): real-time active users list updates
Fixed issue where active users list in event chat did not update in
real-time when new users joined. Users had to refresh the page to see
newly joined participants.

Root Cause:
- getAllDisplayUsers() used checkedInUsers (loaded once from API) as
  base list, with activeUsers (Socket.IO real-time) only for isOnline flag
- When new user joined chat, they appeared in activeUsers but not in
  checkedInUsers, so they were not displayed

Solution:
- Rewrote getAllDisplayUsers() to prioritize activeUsers (real-time data)
- Merges activeUsers (online) with checkedInUsers (offline checked-in users)
- Uses Socket.IO data as source of truth for online users
- Enriches with database data when available (firstName, lastName, etc)
- Sorts online users first, offline second

Changes:
- EventChatPage.jsx: Rewrote getAllDisplayUsers() to merge activeUsers
  with checkedInUsers, prioritizing real-time Socket.IO data
- useEventChat.js: Added debug logging for active_users events
- socket/index.js: Added debug logging for active_users emissions

Testing:
- User A in chat sees User B appear immediately when B joins
- No page refresh required
- Online/offline status updates in real-time
2025-12-02 23:38:46 +01:00
Radosław Gierwiało
1051cc6754 feat(admin): implement activity logs frontend page (Phase 6-7)
Complete implementation of admin activity logs dashboard with real-time
streaming capabilities. Admin users can now monitor all system activity
through a comprehensive web interface.

Features:
- Stats dashboard with 4 key metrics (total logs, unique users, failures, 24h activity)
- Category breakdown visualization with color-coded badges
- Advanced filtering (date range, category, action type, username, success/failure)
- Paginated log table (50 entries per page) with sort by timestamp
- Real-time streaming toggle using Socket.IO
- Color-coded action badges (blue=auth, green=event, purple=match, red=admin, yellow=chat)
- Admin-only access with automatic redirect for non-admin users
- Responsive design for mobile and desktop

Frontend Changes:
- Created ActivityLogsPage.jsx (600+ lines) with complete UI implementation
- Added 3 admin API methods to api.js (getActivityLogs, getActivityLogActions, getActivityLogStats)
- Added /admin/activity-logs route to App.jsx
- Added admin navigation link to Navbar (desktop & mobile) with Shield icon
- Only visible to users with isAdmin flag

Implementation Details:
- Uses getSocket() from socket service for real-time updates
- Joins 'admin_activity_logs' Socket.IO room on streaming enable
- Receives 'activity_log_entry' events and prepends to table (first page only)
- Comprehensive error handling and loading states
- Empty states for no data
- Clean disconnect handling when streaming disabled

Testing:
- Build successful (no errors)
- Ready for manual testing and verification

Phase 8 (Testing) remains for manual verification of all features.
2025-12-02 23:17:19 +01:00
Radosław Gierwiało
d8799d03af feat(dashboard): add Recording Assignments section
- Extend dashboard API to include recordingSuggestions for each event
- Add toBeRecorded and toRecord arrays with heat and user details
- Export RecordingSummaryCard component
- Add Recording Assignments section to DashboardPage
- Filter and display events with recording suggestions
- Show up to 2 suggestions per event with View Details link
2025-11-30 15:14:06 +01:00
Radosław Gierwiało
6ce3111cdd feat(dashboard): improve RecordingSummaryCard styling and fix tab navigation
- Increase font size from xs to sm for better readability
- Reduce avatar size from xs to 24px for better proportions
- Add proper layout with heat names in separate line
- Add truncate for long usernames to prevent overflow
- Style status badges with colored backgrounds and icons (pending/accepted)
- Fix EventChatPage to read and handle ?tab=records URL parameter
- Map 'records' query param to 'recording' tab for proper navigation
2025-11-30 15:13:50 +01:00
Radosław Gierwiało
7e2a196f99 feat(frontend): add Run now button and matching runs list on event details page
- New adminAPI for run-now and runs listing
- MatchingRunsSection with refresh and run controls
- Integrate into EventDetailsPage under matching configuration
2025-11-30 13:20:33 +01:00
Radosław Gierwiało
a9c46f552f feat: add @ prefix to profile URLs and make usernames clickable
- Updated all profile links to use /@username format
- Made usernames clickable in chat messages
- Added URL parameter sanitization to strip @ when fetching user data
- Ensures consistent profile URL format across the application
2025-11-29 20:57:17 +01:00
Radosław Gierwiało
4e9557bd29 feat(chat): add country flags and competitor numbers with normalized data architecture
Implemented display of country flags and competitor numbers in event chat messages:
- Country flags displayed as emoji (🇸🇪, 🇵🇱, etc.) with proper emoji font support
- Competitor numbers shown in #123 format next to usernames
- Normalized data architecture with user and participant caches on frontend
- User data (username, avatar, country) and participant data (competitorNumber) cached separately
- Messages store only core data (id, content, userId, createdAt)
- Prevents data inconsistency when users update profile information
- Fixed duplicate message keys React warning with deduplication logic
- Backend sends nested user/participant objects for cache population
- Auto-updates across all messages when user changes avatar or country

Backend changes:
- Socket.IO event_message and message_history include nested user/participant data
- API /events/:slug/messages endpoint restructured with same nested format
- Batch lookup of competitor numbers for efficiency

Frontend changes:
- useEventChat hook maintains userCache and participantCache
- ChatMessage component accepts separate user/participant props
- ChatMessageList performs cache lookups during render
- Emoji font family support for cross-platform flag rendering
2025-11-29 19:49:06 +01:00
Radosław Gierwiało
c575ef6dc1 feat(frontend): add page titles to navbar on mobile
- Save vertical space on mobile by showing page title in navbar
- Mobile: "spotlight.cam - {PageTitle}" instead of separate h1
- Desktop: unchanged - page titles remain as separate headings
- Saves ~60-80px vertical space on mobile devices

Pages updated:
- Dashboard, Events, Matches, History, Profile
2025-11-29 16:12:47 +01:00
Radosław Gierwiało
58044e1d02 fix(frontend): ensure consistent width across all matches tabs
- Add w-full to MatchCard for consistent card width
- Use Layout noPadding to avoid padding conflicts
- Add explicit padding and width control to main container
- Ensure All, Pending, and Active tabs have identical width
2025-11-29 15:56:12 +01:00
Radosław Gierwiało
420209c037 fix(frontend): add error message display on login page
- Show error alert when login fails instead of console-only logging
- Display user-friendly error message: "Invalid email or password"
- Clear error state before new login attempt
- Use existing Alert component for consistency with RegisterPage
2025-11-29 15:26:40 +01:00
Radosław Gierwiało
634cd97032 refactor(frontend): simplify event chat UI
- Replace "Edit heats" button with icon-only version
- Remove connection status indicator (show "Disconnected" warning only when offline)
- Remove event location from header
- Hide Participants tab on desktop (sidebar already visible)
- Remove "Participants" header from sidebar on desktop
2025-11-29 15:18:22 +01:00
Radosław Gierwiało
dfb5313f9a refactor(frontend): implement mobile-first layout for chat pages
- Add fullWidth prop to Layout component for chat pages
- Redesign EventChatPage and MatchChatPage with fixed layout:
  - Navbar sticky to top (no gaps)
  - Event/partner header directly below navbar
  - Chat content fills available space (flex-1)
  - Input area fixed to bottom
  - Full screen width on mobile (no margins)
- Translate RecordingTab UI strings to English
- Move Leave Event button to header
- Remove unnecessary margins and max-width constraints

This provides a better mobile experience with full-screen chat
interface similar to native messaging apps.
2025-11-29 15:04:41 +01:00
Radosław Gierwiało
408317b974 refactor(frontend): add CONNECTION_STATE and SUGGESTION_TYPE constants
- Add CONNECTION_STATE (disconnected, connecting, connected, failed)
- Add SUGGESTION_TYPE (toBeRecorded, toRecord)
- Update useWebRTC.js to use CONNECTION_STATE
- Update MatchChatPage.jsx to use CONNECTION_STATE
- Update RecordingTab.jsx to use SUGGESTION_TYPE
2025-11-23 22:28:54 +01:00
Radosław Gierwiało
b3a6d39d7a refactor(frontend): replace status string literals with constants
- Create constants/statuses.js with MATCH_STATUS, SUGGESTION_STATUS, MATCH_FILTER
- Update MatchCard, MatchesPage, HistoryPage, RatePartnerPage to use MATCH_STATUS
- Update RecordingTab to use SUGGESTION_STATUS
- Update Navbar to use MATCH_STATUS for API calls
2025-11-23 22:21:12 +01:00
Radosław Gierwiało
93ff331bfb refactor(frontend): extract ProfileForm and PasswordChangeForm from ProfilePage
- Create components/profile/ProfileForm.jsx (192 lines)
- Create components/profile/PasswordChangeForm.jsx (99 lines)
- Create components/profile/index.js barrel export
- Reduce ProfilePage.jsx from 394 → 84 lines (-79%)
2025-11-23 22:13:56 +01:00
Radosław Gierwiało
185c485ec7 refactor(frontend): extract MatchCard component from MatchesPage
- Create components/matches/MatchCard.jsx (119 lines)
- Create components/matches/index.js barrel export
- Reduce MatchesPage.jsx from 349 → 240 lines (-31%)
2025-11-23 22:11:43 +01:00
Radosław Gierwiało
8e17c10353 refactor(frontend): extract DashboardPage into components
Split DashboardPage (578 lines) into focused components:
- DashboardEventCard: event card with chat access
- DashboardMatchCard: match card with status indicators
- MatchRequestCards: incoming/outgoing request cards
- EmptyState: reusable empty state component (in common/)

DashboardPage now 295 lines (-49%)
2025-11-23 22:08:16 +01:00
Radosław Gierwiało
bddcf5f4f9 refactor(frontend): extract EventDetailsPage into components
Split large EventDetailsPage (545 lines) into smaller, focused components:
- QRCodeSection: QR code display and copy link functionality
- ParticipantsSection: participants list with avatars
- MatchingConfigSection: deadline and matching controls
- ScheduleConfigSection: division slot configuration

EventDetailsPage now 148 lines (-73%)
2025-11-23 22:02:09 +01:00
Radosław Gierwiało
4467c570b0 feat(matching): add schedule config for division collision groups
Allow event organizers to configure which divisions run in parallel
(same time slot) for accurate collision detection in the auto-matching
algorithm. Divisions in the same slot will collide with each other.

- Add scheduleConfig JSON field to Event model
- Add PUT /events/:slug/schedule-config API endpoint
- Update matching algorithm to use slot-based collision detection
- Add UI in EventDetailsPage for managing division slots
- Add unit tests for schedule-based collision detection
2025-11-23 19:05:25 +01:00
Radosław Gierwiało
a5a1296a4e feat(frontend): add recording matching UI
Add frontend components for auto-matching recording partners:

- RecordingTab component with suggestions list and opt-out toggle
- Tab navigation in EventChatPage (Chat, Uczestnicy, Nagrywanie)
- Matching configuration in EventDetailsPage (deadline, run matching)
- matchingAPI functions in api.js
- Return registrationDeadline and matchingRunAt in GET /events/:slug/details

UI allows users to:
- View who will record their heats
- View heats they need to record
- Accept/reject suggestions
- Opt-out from being a recorder
- Set registration deadline (admin)
- Manually trigger matching (admin)
2025-11-23 18:50:35 +01:00
Radosław Gierwiało
edf68f2489 feat(events): add competitor number (bib) support
Allow participants to set their bib/competitor number per event.
Display as badge next to username in participant lists.

- Add competitorNumber field to EventParticipant model
- Add PUT /events/:slug/competitor-number endpoint
- Include competitorNumber in heats/me and heats/all responses
- Add input field in HeatsBanner component
- Display badge in UserListItem component
- Add unit tests for competitor number feature
2025-11-23 17:55:25 +01:00
Radosław Gierwiało
78280ca8d8 feat(dashboard): add unread count for match chats
Track unread messages in match chats and display count badge:
- Schema: Add user1LastReadAt/user2LastReadAt to Match model
- Backend: Calculate unreadCount in dashboard API
- Socket: Update lastReadAt when user joins match room
- Frontend: Display red badge with unread count on match avatar
2025-11-21 21:46:00 +01:00
Radosław Gierwiało
2c0620db6a feat(dashboard): add online count for events
Show real-time count of users currently in each event chat room.
- Backend: Export getEventsOnlineCounts from socket module
- Dashboard API: Include onlineCount for each active event
- Frontend: Display online count with animated green dot indicator
2025-11-21 21:41:16 +01:00
Radosław Gierwiało
c15031db9f feat(frontend): add skeleton loading state for dashboard
Replace simple spinner with skeleton loading placeholders that match
the dashboard layout structure, providing better visual feedback during
data loading.
2025-11-21 21:37:05 +01:00
Radosław Gierwiało
87b0079b84 feat(frontend): add toast notifications for dashboard actions
- Install react-hot-toast library
- Add Toaster component to App.jsx
- Show success/error toasts for match accept/reject/cancel
- Show toasts for real-time match events
- Update tests with toast mocks
2025-11-21 21:27:03 +01:00
Radosław Gierwiało
4187157b94 feat(frontend): add Rate Partner button and dashboard tests
- Add Rate button to MatchCard (shows when video exchange complete & not rated)
- Add 15 comprehensive tests for DashboardPage component
- Tests cover: loading, empty states, events, matches, requests, navigation
2025-11-21 21:21:58 +01:00
Radosław Gierwiało
f3bd169dbf feat(frontend): implement dashboard page
- Create DashboardPage with active events, matches, and requests
- Add dashboardAPI.getData() to services/api.js
- Add /dashboard route as default landing after login
- Update Navbar with Dashboard and Events links
- Show video exchange and rating status for matches
- Handle match accept/reject/cancel actions
2025-11-21 21:12:25 +01:00
Radosław Gierwiało
ade5190d7b fix(frontend): resolve missing formatHeat function in EventChatPage
Bug: EventChatPage referenced formatHeat() function in header's heat display
(line 365) but the function was removed during Phase 3 refactoring when
creating the HeatBadges component.

Solution:
1. Enhanced HeatBadges component with badgeClassName prop to support
   custom styling (needed for dark header background)
2. Replaced manual heat rendering in EventChatPage header with
   HeatBadges component
3. Passed custom badge styling to match the dark primary-700 header

Changes:
- HeatBadges.jsx: Added badgeClassName prop for style customization
- EventChatPage.jsx: Replaced manual heat map with HeatBadges component

Fixes: "Uncaught ReferenceError: formatHeat is not defined" error
2025-11-21 17:29:12 +01:00
Radosław Gierwiało
082105c5bf refactor(frontend): Phase 3 - create advanced composite components
Extract complex UI sections into reusable composite components

New Components Created:
1. HeatBadges (heats/HeatBadges.jsx)
   - Displays competition heats with compact notation
   - Configurable max visible badges with "+X more" overflow
   - Tooltips with full heat information

2. UserListItem (users/UserListItem.jsx)
   - Reusable user entry with avatar, username, full name
   - Optional heat badges display
   - Flexible action button slot (render props pattern)
   - Online/offline status support

3. ParticipantsSidebar (events/ParticipantsSidebar.jsx)
   - Complete sidebar component for event participants
   - Filter checkbox for hiding users from own heats
   - Participant and online counters
   - Integrated UserListItem with match actions

4. FileTransferProgress (webrtc/FileTransferProgress.jsx)
   - WebRTC P2P file transfer UI
   - Progress bar with percentage
   - Send/Cancel actions

5. LinkShareInput (webrtc/LinkShareInput.jsx)
   - Fallback link sharing when WebRTC unavailable
   - Google Drive, Dropbox link support

Pages Refactored:
- EventChatPage: 564 → 471 lines (-93 lines, -16%)
  * Replaced 90-line participants sidebar with <ParticipantsSidebar />
  * Removed duplicate formatHeat logic (now in HeatBadges)

- MatchChatPage: 446 → 369 lines (-77 lines, -17%)
  * Replaced 56-line file transfer UI with <FileTransferProgress />
  * Replaced 39-line link input form with <LinkShareInput />

Phase 3 Total: -170 lines
Grand Total (Phase 1+2+3): -559 lines (-17%)

Final Results:
- EventChatPage: 761 → 471 lines (-290 lines, -38% reduction)
- MatchChatPage: 567 → 369 lines (-198 lines, -35% reduction)

Benefits:
- Massive complexity reduction in largest components
- Composite components can be reused across pages
- Better testability - each component tested independently
- Cleaner code organization - single responsibility principle
- Easier maintenance - changes in one place propagate everywhere
2025-11-21 17:10:53 +01:00