feat: implement Phase 2 - Matches API with real-time notifications

Backend changes:
- Add matches API routes (POST, GET, PUT, DELETE)
- Create/accept/reject match requests
- Auto-create private chat rooms on match acceptance
- Socket.IO notifications for match events (received, accepted, cancelled)
- Users join personal rooms (user_{id}) for notifications

Frontend changes:
- Add MatchesPage component with inbox UI
- Matches navigation link with notification badge
- Real-time match request count updates
- Accept/reject match functionality
- Filter matches by status (all/pending/accepted)
- Integrate match requests in EventChatPage (UserPlus button)

Features:
- Send match requests to event participants
- Accept incoming match requests
- Real-time notifications via Socket.IO
- Automatic private chat room creation
- Match status tracking (pending/accepted/completed)
- Authorization checks (only participants can match)
- Duplicate match prevention
This commit is contained in:
Radosław Gierwiało
2025-11-14 19:22:23 +01:00
parent eaf80c6c6f
commit 4a3e32f3b6
8 changed files with 1102 additions and 9 deletions

View File

@@ -264,4 +264,46 @@ export const heatsAPI = {
},
};
// Matches API (Phase 2)
export const matchesAPI = {
async createMatch(targetUserId, eventSlug) {
const data = await fetchAPI('/matches', {
method: 'POST',
body: JSON.stringify({ targetUserId, eventSlug }),
});
return data;
},
async getMatches(eventSlug = null, status = null) {
const params = new URLSearchParams();
if (eventSlug) params.append('eventSlug', eventSlug);
if (status) params.append('status', status);
const queryString = params.toString();
const endpoint = queryString ? `/matches?${queryString}` : '/matches';
const data = await fetchAPI(endpoint);
return data;
},
async getMatch(matchId) {
const data = await fetchAPI(`/matches/${matchId}`);
return data;
},
async acceptMatch(matchId) {
const data = await fetchAPI(`/matches/${matchId}/accept`, {
method: 'PUT',
});
return data;
},
async deleteMatch(matchId) {
const data = await fetchAPI(`/matches/${matchId}`, {
method: 'DELETE',
});
return data;
},
};
export { ApiError };