diff --git a/frontend/src/components/events/ParticipantsSidebar.jsx b/frontend/src/components/events/ParticipantsSidebar.jsx
index 06468ef..39938ce 100644
--- a/frontend/src/components/events/ParticipantsSidebar.jsx
+++ b/frontend/src/components/events/ParticipantsSidebar.jsx
@@ -43,6 +43,21 @@ const ParticipantsSidebar = ({
const participantCount = users.length;
const onlineCount = activeUsers.length;
+ // Group users by status for better UX
+ const groupedUsers = users.reduce((groups, user) => {
+ const hasHeats = (userHeats.get(user.userId) || []).length > 0;
+ const isOnline = user.isOnline ?? false;
+
+ if (isOnline && hasHeats) {
+ groups.onlineWithHeats.push(user);
+ } else if (isOnline && !hasHeats) {
+ groups.onlineNoHeats.push(user);
+ } else {
+ groups.offline.push(user);
+ }
+ return groups;
+ }, { onlineWithHeats: [], onlineNoHeats: [], offline: [] });
+
return (
{/* Header */}
@@ -78,38 +93,129 @@ const ParticipantsSidebar = ({
No other participants
)}
- {/* User List */}
-
- {users.map((displayUser) => {
- const thisUserHeats = userHeats.get(displayUser.userId) || [];
- const competitorNumber = userCompetitorNumbers.get(displayUser.userId);
- const hasHeats = thisUserHeats.length > 0;
+ {/* User List - Grouped by Status */}
+
+ {/* Online with Heats - Ready to match */}
+ {groupedUsers.onlineWithHeats.length > 0 && (
+
+
+
+
+ Available ({groupedUsers.onlineWithHeats.length})
+
+
+
+ {groupedUsers.onlineWithHeats.map((displayUser) => {
+ const thisUserHeats = userHeats.get(displayUser.userId) || [];
+ const competitorNumber = userCompetitorNumbers.get(displayUser.userId);
- return (
- onMatchWith?.(displayUser.userId)}
- disabled={!hasHeats}
- className={`p-1 rounded flex-shrink-0 ${
- hasHeats
- ? 'text-primary-600 hover:bg-primary-50'
- : 'text-gray-300 cursor-not-allowed'
- }`}
- title={hasHeats ? 'Connect' : 'User has not declared heats'}
- >
-
-
- }
- />
- );
- })}
+ return (
+ onMatchWith?.(displayUser.userId)}
+ className="p-1 rounded flex-shrink-0 text-primary-600 hover:bg-primary-50"
+ title="Send match request"
+ >
+
+
+ }
+ />
+ );
+ })}
+
+
+ )}
+
+ {/* Online without Heats - Can't match yet */}
+ {groupedUsers.onlineNoHeats.length > 0 && (
+
+
+
+
+ Online - No Heats ({groupedUsers.onlineNoHeats.length})
+
+
+
+ {groupedUsers.onlineNoHeats.map((displayUser) => {
+ const competitorNumber = userCompetitorNumbers.get(displayUser.userId);
+
+ return (
+
+
+
+ }
+ />
+ );
+ })}
+
+
+ )}
+
+ {/* Offline */}
+ {groupedUsers.offline.length > 0 && (
+
+
+
+
+ Offline ({groupedUsers.offline.length})
+
+
+
+ {groupedUsers.offline.map((displayUser) => {
+ const thisUserHeats = userHeats.get(displayUser.userId) || [];
+ const competitorNumber = userCompetitorNumbers.get(displayUser.userId);
+ const hasHeats = thisUserHeats.length > 0;
+
+ return (
+
onMatchWith?.(displayUser.userId)}
+ className="p-1 rounded flex-shrink-0 text-primary-600 hover:bg-primary-50 opacity-60"
+ title="Send match request (user is offline)"
+ >
+
+
+ ) : (
+
+
+
+ )
+ }
+ />
+ );
+ })}
+
+
+ )}
);
diff --git a/frontend/src/components/users/UserListItem.jsx b/frontend/src/components/users/UserListItem.jsx
index c8c21c6..961da1f 100644
--- a/frontend/src/components/users/UserListItem.jsx
+++ b/frontend/src/components/users/UserListItem.jsx
@@ -83,12 +83,19 @@ const UserListItem = ({
{user.firstName} {user.lastName}
)}
- {/* Heat Badges */}
+ {/* Heat Badges or No Heats indicator */}
{showHeats && hasHeats && (
)}
+ {showHeats && !hasHeats && (
+
+
+ No heats declared
+
+
+ )}
{actionButton && (