2025-11-23 22:11:43 +01:00
|
|
|
import { Link } from 'react-router-dom';
|
|
|
|
|
import { MessageCircle, Check, X, Loader2, Calendar, MapPin } from 'lucide-react';
|
2025-11-23 22:21:12 +01:00
|
|
|
import { MATCH_STATUS } from '../../constants';
|
2025-11-23 22:11:43 +01:00
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Match card for matches list page
|
|
|
|
|
* Shows match details with accept/reject/chat actions
|
|
|
|
|
*/
|
|
|
|
|
const MatchCard = ({ match, onAccept, onReject, onOpenChat, processing }) => {
|
2025-11-23 22:21:12 +01:00
|
|
|
const isIncoming = !match.isInitiator && match.status === MATCH_STATUS.PENDING;
|
|
|
|
|
const isOutgoing = match.isInitiator && match.status === MATCH_STATUS.PENDING;
|
|
|
|
|
const isAccepted = match.status === MATCH_STATUS.ACCEPTED;
|
2025-11-23 22:11:43 +01:00
|
|
|
|
|
|
|
|
return (
|
2025-11-29 15:56:12 +01:00
|
|
|
<div className="w-full bg-white rounded-lg shadow-sm border border-gray-200 p-4 hover:shadow-md transition-shadow">
|
2025-11-23 22:11:43 +01:00
|
|
|
<div className="flex items-start justify-between">
|
|
|
|
|
<div className="flex-1">
|
|
|
|
|
<div className="flex items-center gap-3 mb-2">
|
2025-11-29 20:57:17 +01:00
|
|
|
<Link to={`/@${match.partner.username}`} className="flex-shrink-0">
|
2025-11-23 22:11:43 +01:00
|
|
|
<img
|
|
|
|
|
src={match.partner.avatar || `https://api.dicebear.com/7.x/avataaars/svg?seed=${match.partner.username}`}
|
|
|
|
|
alt={match.partner.username}
|
|
|
|
|
className="w-12 h-12 rounded-full hover:ring-2 hover:ring-primary-500 transition-all"
|
|
|
|
|
/>
|
|
|
|
|
</Link>
|
|
|
|
|
<div>
|
2025-11-29 20:57:17 +01:00
|
|
|
<Link to={`/@${match.partner.username}`}>
|
2025-11-23 22:11:43 +01:00
|
|
|
<h3 className="font-semibold text-gray-900 hover:text-primary-600 transition-colors">
|
|
|
|
|
{match.partner.firstName && match.partner.lastName
|
|
|
|
|
? `${match.partner.firstName} ${match.partner.lastName}`
|
|
|
|
|
: match.partner.username}
|
|
|
|
|
</h3>
|
|
|
|
|
</Link>
|
|
|
|
|
<p className="text-sm text-gray-600">@{match.partner.username}</p>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<div className="flex items-center gap-4 text-sm text-gray-600 mb-2">
|
|
|
|
|
<div className="flex items-center gap-1">
|
|
|
|
|
<Calendar className="w-4 h-4" />
|
|
|
|
|
<span>{match.event.name}</span>
|
|
|
|
|
</div>
|
|
|
|
|
<div className="flex items-center gap-1">
|
|
|
|
|
<MapPin className="w-4 h-4" />
|
|
|
|
|
<span>{match.event.location}</span>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<div className="flex items-center gap-2">
|
2025-11-30 15:30:49 +01:00
|
|
|
{match.type === 'auto' ? (
|
|
|
|
|
<span className="text-xs px-2 py-1 bg-purple-100 text-purple-700 rounded-full font-medium">
|
|
|
|
|
Auto
|
|
|
|
|
</span>
|
|
|
|
|
) : (
|
|
|
|
|
<span className="text-xs px-2 py-1 bg-gray-100 text-gray-700 rounded-full font-medium">
|
|
|
|
|
Manual
|
|
|
|
|
</span>
|
|
|
|
|
)}
|
2025-11-23 22:11:43 +01:00
|
|
|
{isIncoming && (
|
|
|
|
|
<span className="text-xs px-2 py-1 bg-amber-100 text-amber-700 rounded-full font-medium">
|
|
|
|
|
Incoming Request
|
|
|
|
|
</span>
|
|
|
|
|
)}
|
|
|
|
|
{isOutgoing && (
|
|
|
|
|
<span className="text-xs px-2 py-1 bg-blue-100 text-blue-700 rounded-full font-medium">
|
|
|
|
|
Sent Request
|
|
|
|
|
</span>
|
|
|
|
|
)}
|
|
|
|
|
{isAccepted && (
|
|
|
|
|
<span className="text-xs px-2 py-1 bg-green-100 text-green-700 rounded-full font-medium">
|
|
|
|
|
Active Match
|
|
|
|
|
</span>
|
|
|
|
|
)}
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<div className="flex items-center gap-2 ml-4">
|
2025-11-30 15:30:49 +01:00
|
|
|
{isIncoming && match.type === 'manual' && (
|
2025-11-23 22:11:43 +01:00
|
|
|
<>
|
|
|
|
|
<button
|
|
|
|
|
onClick={() => onAccept(match.slug)}
|
|
|
|
|
disabled={processing}
|
|
|
|
|
className="p-2 bg-green-600 text-white rounded-full hover:bg-green-700 disabled:opacity-50 disabled:cursor-not-allowed transition-colors"
|
|
|
|
|
title="Accept"
|
|
|
|
|
>
|
|
|
|
|
{processing ? (
|
|
|
|
|
<Loader2 className="w-5 h-5 animate-spin" />
|
|
|
|
|
) : (
|
|
|
|
|
<Check className="w-5 h-5" />
|
|
|
|
|
)}
|
|
|
|
|
</button>
|
|
|
|
|
<button
|
|
|
|
|
onClick={() => onReject(match.slug)}
|
|
|
|
|
disabled={processing}
|
|
|
|
|
className="p-2 bg-red-600 text-white rounded-full hover:bg-red-700 disabled:opacity-50 disabled:cursor-not-allowed transition-colors"
|
|
|
|
|
title="Reject"
|
|
|
|
|
>
|
|
|
|
|
<X className="w-5 h-5" />
|
|
|
|
|
</button>
|
|
|
|
|
</>
|
|
|
|
|
)}
|
|
|
|
|
|
2025-11-30 15:30:49 +01:00
|
|
|
{isIncoming && match.type === 'auto' && (
|
|
|
|
|
<Link
|
|
|
|
|
to={`/events/${match.event.slug}/chat?tab=records`}
|
|
|
|
|
className="px-3 py-1.5 text-sm bg-purple-600 text-white rounded-md hover:bg-purple-700 transition-colors"
|
|
|
|
|
>
|
|
|
|
|
Go to Records
|
|
|
|
|
</Link>
|
|
|
|
|
)}
|
|
|
|
|
|
|
|
|
|
{isOutgoing && match.type === 'manual' && (
|
2025-11-23 22:11:43 +01:00
|
|
|
<button
|
|
|
|
|
onClick={() => onReject(match.slug)}
|
|
|
|
|
disabled={processing}
|
|
|
|
|
className="px-3 py-1.5 text-sm border border-gray-300 text-gray-700 rounded-md hover:bg-gray-50 disabled:opacity-50 disabled:cursor-not-allowed transition-colors"
|
|
|
|
|
>
|
|
|
|
|
Cancel Request
|
|
|
|
|
</button>
|
|
|
|
|
)}
|
|
|
|
|
|
2025-11-30 15:30:49 +01:00
|
|
|
{isOutgoing && match.type === 'auto' && (
|
|
|
|
|
<Link
|
|
|
|
|
to={`/events/${match.event.slug}/chat?tab=records`}
|
|
|
|
|
className="px-3 py-1.5 text-sm bg-purple-600 text-white rounded-md hover:bg-purple-700 transition-colors"
|
|
|
|
|
>
|
|
|
|
|
Go to Records
|
|
|
|
|
</Link>
|
|
|
|
|
)}
|
|
|
|
|
|
|
|
|
|
{isAccepted && match.slug && (
|
2025-11-23 22:11:43 +01:00
|
|
|
<button
|
|
|
|
|
onClick={() => onOpenChat(match)}
|
|
|
|
|
className="flex items-center gap-2 px-4 py-2 bg-primary-600 text-white rounded-md hover:bg-primary-700 transition-colors"
|
|
|
|
|
>
|
|
|
|
|
<MessageCircle className="w-4 h-4" />
|
|
|
|
|
Open Chat
|
|
|
|
|
</button>
|
|
|
|
|
)}
|
2025-11-30 15:30:49 +01:00
|
|
|
|
|
|
|
|
{isAccepted && !match.slug && (
|
|
|
|
|
<span className="text-sm text-gray-500 italic">
|
|
|
|
|
Chat not available yet
|
|
|
|
|
</span>
|
|
|
|
|
)}
|
2025-11-23 22:11:43 +01:00
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
export default MatchCard;
|