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.
This commit is contained in:
Radosław Gierwiało
2025-11-30 11:03:29 +01:00
parent 3371b53fc7
commit 8c753a7148
2 changed files with 42 additions and 5 deletions

View File

@@ -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}
/>
))}
</div>
@@ -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}
/>
))}
</div>
@@ -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 }) => {
</button>
</>
) : (
getStatusBadge()
<>
{getStatusBadge()}
{status === SUGGESTION_STATUS.ACCEPTED && match?.slug && (
<button
onClick={() => navigate(`/matches/${match.slug}/chat`)}
className="p-2 text-primary-600 hover:bg-primary-50 rounded-md transition-colors"
title="Open Chat"
>
<MessageCircle className="w-5 h-5" />
</button>
)}
</>
)}
</div>
</div>