From 8c753a71485cbf2ba8efded2fb89df0e2100f45f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rados=C5=82aw=20Gierwia=C5=82o?= Date: Sun, 30 Nov 2025 11:03:29 +0100 Subject: [PATCH] feat: add match data to suggestions and chat link for accepted recordings Backend changes: - Modified getUserSuggestions to include match data (id, slug, status) - Returns match info for both toBeRecorded and toRecord suggestions Frontend changes: - Added useNavigate hook to RecordingTab - Capture match data from updateSuggestionStatus response - Added MessageCircle icon and chat button to SuggestionCard - Show "Open Chat" button for accepted suggestions with active matches - Navigate to /matches/{matchSlug}/chat when clicked This completes the recording stats flow by allowing users to easily access the match chat after accepting a recording suggestion. --- backend/src/services/matching.js | 14 ++++++++ .../components/recordings/RecordingTab.jsx | 33 ++++++++++++++++--- 2 files changed, 42 insertions(+), 5 deletions(-) diff --git a/backend/src/services/matching.js b/backend/src/services/matching.js index 738f11a..a31c1ba 100644 --- a/backend/src/services/matching.js +++ b/backend/src/services/matching.js @@ -511,6 +511,13 @@ async function getUserSuggestions(eventId, userId) { city: true, country: true, } + }, + match: { + select: { + id: true, + slug: true, + status: true, + } } } }); @@ -534,6 +541,13 @@ async function getUserSuggestions(eventId, userId) { } } } + }, + match: { + select: { + id: true, + slug: true, + status: true, + } } } }); diff --git a/frontend/src/components/recordings/RecordingTab.jsx b/frontend/src/components/recordings/RecordingTab.jsx index 372c078..b0214cc 100644 --- a/frontend/src/components/recordings/RecordingTab.jsx +++ b/frontend/src/components/recordings/RecordingTab.jsx @@ -1,5 +1,6 @@ import { useState, useEffect } from 'react'; -import { Video, VideoOff, Clock, CheckCircle, XCircle, AlertTriangle, RefreshCw } from 'lucide-react'; +import { useNavigate } from 'react-router-dom'; +import { Video, VideoOff, Clock, CheckCircle, XCircle, AlertTriangle, RefreshCw, MessageCircle } from 'lucide-react'; import { matchingAPI } from '../../services/api'; import Avatar from '../common/Avatar'; import { SUGGESTION_STATUS, SUGGESTION_TYPE } from '../../constants'; @@ -9,6 +10,7 @@ import { SUGGESTION_STATUS, SUGGESTION_TYPE } from '../../constants'; * Shows suggestions for who will record user's heats and who user needs to record */ const RecordingTab = ({ slug, event, myHeats }) => { + const navigate = useNavigate(); const [loading, setLoading] = useState(true); const [error, setError] = useState(null); const [suggestions, setSuggestions] = useState(null); @@ -49,8 +51,15 @@ const RecordingTab = ({ slug, event, myHeats }) => { const handleUpdateStatus = async (suggestionId, status) => { try { - await matchingAPI.updateSuggestionStatus(slug, suggestionId, status); - // Reload suggestions + const response = await matchingAPI.updateSuggestionStatus(slug, suggestionId, status); + + // If suggestion was accepted and a match was created, show notification + if (status === SUGGESTION_STATUS.ACCEPTED && response?.match) { + // Optional: Show toast notification here if you have a toast system + console.log('Match created:', response.match); + } + + // Reload suggestions to show updated status and match data await loadSuggestions(); } catch (err) { console.error('Failed to update suggestion status:', err); @@ -202,6 +211,7 @@ const RecordingTab = ({ slug, event, myHeats }) => { type={SUGGESTION_TYPE.TO_BE_RECORDED} onAccept={() => handleUpdateStatus(suggestion.id, SUGGESTION_STATUS.ACCEPTED)} onReject={() => handleUpdateStatus(suggestion.id, SUGGESTION_STATUS.REJECTED)} + navigate={navigate} /> ))} @@ -228,6 +238,7 @@ const RecordingTab = ({ slug, event, myHeats }) => { type={SUGGESTION_TYPE.TO_RECORD} onAccept={() => handleUpdateStatus(suggestion.id, SUGGESTION_STATUS.ACCEPTED)} onReject={() => handleUpdateStatus(suggestion.id, SUGGESTION_STATUS.REJECTED)} + navigate={navigate} /> ))} @@ -262,11 +273,12 @@ const RecordingTab = ({ slug, event, myHeats }) => { /** * SuggestionCard - Single suggestion item */ -const SuggestionCard = ({ suggestion, type, onAccept, onReject }) => { +const SuggestionCard = ({ suggestion, type, onAccept, onReject, navigate }) => { const heat = suggestion.heat; const recorder = suggestion.recorder; const dancer = heat?.user; const status = suggestion.status; + const match = suggestion.match; // Format heat info const heatInfo = heat @@ -365,7 +377,18 @@ const SuggestionCard = ({ suggestion, type, onAccept, onReject }) => { ) : ( - getStatusBadge() + <> + {getStatusBadge()} + {status === SUGGESTION_STATUS.ACCEPTED && match?.slug && ( + + )} + )}