import { useState, useEffect } from 'react';
import { useNavigate, Link } from 'react-router-dom';
import Layout from '../components/layout/Layout';
import { useAuth } from '../contexts/AuthContext';
import { matchesAPI } from '../services/api';
import { MessageCircle, Check, X, Loader2, Users, Calendar, MapPin } from 'lucide-react';
import { connectSocket, disconnectSocket, getSocket } from '../services/socket';
const MatchesPage = () => {
const { user } = useAuth();
const navigate = useNavigate();
const [matches, setMatches] = useState([]);
const [loading, setLoading] = useState(true);
const [filter, setFilter] = useState('all'); // 'all', 'pending', 'accepted'
const [processingMatchId, setProcessingMatchId] = useState(null);
useEffect(() => {
loadMatches();
// Connect to socket for real-time updates
const token = localStorage.getItem('token');
if (token && user) {
connectSocket(token, user.id);
const socket = getSocket();
if (socket) {
// Listen for match notifications
socket.on('match_request_received', handleMatchRequestReceived);
socket.on('match_accepted', handleMatchAccepted);
socket.on('match_cancelled', handleMatchCancelled);
}
}
return () => {
const socket = getSocket();
if (socket) {
socket.off('match_request_received', handleMatchRequestReceived);
socket.off('match_accepted', handleMatchAccepted);
socket.off('match_cancelled', handleMatchCancelled);
}
disconnectSocket();
};
}, [user]);
const loadMatches = async () => {
try {
setLoading(true);
const result = await matchesAPI.getMatches();
setMatches(result.data || []);
} catch (error) {
console.error('Failed to load matches:', error);
} finally {
setLoading(false);
}
};
const handleMatchRequestReceived = (data) => {
// Reload matches to show new request
loadMatches();
};
const handleMatchAccepted = (data) => {
// Reload matches to update status
loadMatches();
};
const handleMatchCancelled = (data) => {
// Remove cancelled match from list
setMatches(prev => prev.filter(m => m.slug !== data.matchSlug));
};
const handleAccept = async (matchSlug) => {
try {
setProcessingMatchId(matchSlug);
await matchesAPI.acceptMatch(matchSlug);
// Reload matches
await loadMatches();
// Show success message
alert('Match accepted! You can now chat with your partner.');
} catch (error) {
console.error('Failed to accept match:', error);
alert('Failed to accept match. Please try again.');
} finally {
setProcessingMatchId(null);
}
};
const handleReject = async (matchSlug) => {
if (!confirm('Are you sure you want to reject this match request?')) {
return;
}
try {
setProcessingMatchId(matchSlug);
await matchesAPI.deleteMatch(matchSlug);
// Remove from list
setMatches(prev => prev.filter(m => m.slug !== matchSlug));
} catch (error) {
console.error('Failed to reject match:', error);
alert('Failed to reject match. Please try again.');
} finally {
setProcessingMatchId(null);
}
};
const handleOpenChat = (match) => {
if (match.status === 'accepted' && match.roomId) {
navigate(`/matches/${match.slug}/chat`);
}
};
// Filter matches based on selected filter
const filteredMatches = matches.filter(match => {
if (filter === 'all') return true;
return match.status === filter;
});
// Separate pending incoming matches (where user is recipient)
const pendingIncoming = filteredMatches.filter(m => m.status === 'pending' && !m.isInitiator);
const otherMatches = filteredMatches.filter(m => !(m.status === 'pending' && !m.isInitiator));
return (
Manage your dance partner connections
{filter === 'all'
? 'You have no match requests yet. Connect with other dancers at events!'
: `You have no ${filter} matches.`}
Match Requests
{pendingIncoming.length > 0 ? 'Other Matches' : 'Your Matches'}
No matches found
@{match.partner.username}