import { useState, useRef, useEffect } from 'react'; import { useParams, useNavigate } from 'react-router-dom'; import Layout from '../components/layout/Layout'; import { useAuth } from '../contexts/AuthContext'; import { mockPrivateMessages } from '../mocks/messages'; import { mockUsers } from '../mocks/users'; import { Send, Video, Upload, X, Check, Link as LinkIcon } from 'lucide-react'; const MatchChatPage = () => { const { matchId } = useParams(); const { user } = useAuth(); const navigate = useNavigate(); const [messages, setMessages] = useState(mockPrivateMessages); const [newMessage, setNewMessage] = useState(''); const [selectedFile, setSelectedFile] = useState(null); const [isTransferring, setIsTransferring] = useState(false); const [transferProgress, setTransferProgress] = useState(0); const [webrtcStatus, setWebrtcStatus] = useState('disconnected'); // disconnected, connecting, connected, failed const [showLinkInput, setShowLinkInput] = useState(false); const [videoLink, setVideoLink] = useState(''); const messagesEndRef = useRef(null); const fileInputRef = useRef(null); // Partner user (mockup) const partner = mockUsers[1]; // sarah_swing const scrollToBottom = () => { messagesEndRef.current?.scrollIntoView({ behavior: 'smooth' }); }; useEffect(() => { scrollToBottom(); }, [messages]); const handleSendMessage = (e) => { e.preventDefault(); if (!newMessage.trim()) return; const message = { id: messages.length + 1, room_id: 10, user_id: user.id, username: user.username, content: newMessage, type: 'text', created_at: new Date().toISOString(), }; setMessages([...messages, message]); setNewMessage(''); }; const handleFileSelect = (e) => { const file = e.target.files[0]; if (file && file.type.startsWith('video/')) { setSelectedFile(file); } else { alert('Proszę wybrać plik wideo'); } }; const simulateWebRTCConnection = () => { setWebrtcStatus('connecting'); setTimeout(() => { setWebrtcStatus('connected'); }, 1500); }; const handleStartTransfer = () => { if (!selectedFile) return; // Simulate WebRTC connection simulateWebRTCConnection(); setTimeout(() => { setIsTransferring(true); setTransferProgress(0); // Simulate transfer progress const interval = setInterval(() => { setTransferProgress((prev) => { if (prev >= 100) { clearInterval(interval); setIsTransferring(false); setSelectedFile(null); setWebrtcStatus('disconnected'); // Add message about completed transfer const message = { id: messages.length + 1, room_id: 10, user_id: user.id, username: user.username, content: `📹 Video sent: ${selectedFile.name} (${(selectedFile.size / 1024 / 1024).toFixed(2)} MB)`, type: 'video', created_at: new Date().toISOString(), }; setMessages((prev) => [...prev, message]); return 0; } return prev + 5; }); }, 200); }, 2000); }; const handleCancelTransfer = () => { setIsTransferring(false); setTransferProgress(0); setSelectedFile(null); setWebrtcStatus('disconnected'); }; const handleSendLink = (e) => { e.preventDefault(); if (!videoLink.trim()) return; const message = { id: messages.length + 1, room_id: 10, user_id: user.id, username: user.username, content: `🔗 Video link: ${videoLink}`, type: 'link', created_at: new Date().toISOString(), }; setMessages([...messages, message]); setVideoLink(''); setShowLinkInput(false); }; const handleEndMatch = () => { navigate(`/matches/${matchId}/rate`); }; const getWebRTCStatusColor = () => { switch (webrtcStatus) { case 'connected': return 'text-green-600'; case 'connecting': return 'text-yellow-600'; case 'failed': return 'text-red-600'; default: return 'text-gray-400'; } }; const getWebRTCStatusText = () => { switch (webrtcStatus) { case 'connected': return 'Connected (P2P)'; case 'connecting': return 'Connecting...'; case 'failed': return 'Connection failed'; default: return 'Disconnected'; } }; return (
{/* Header with Partner Info */}
{partner.username}

{partner.username}

⭐ {partner.rating} • {partner.matches_count} collaborations

{/* WebRTC Status Bar */}
{getWebRTCStatusText()}
{webrtcStatus === 'connected' ? '🔒 E2E Encrypted (DTLS/SRTP)' : 'WebRTC ready to connect'}
{/* Messages */}
{messages.map((message) => { const isOwnMessage = message.user_id === user.id; return (
{message.username}
{message.username} {new Date(message.created_at).toLocaleTimeString('en-US', { hour: '2-digit', minute: '2-digit' })}
{message.content}
); })}
{/* Video Transfer Section */} {(selectedFile || isTransferring) && (
{!isTransferring && ( )}
{isTransferring ? ( <>
Transferring via WebRTC... {transferProgress}%
) : ( )}
)} {/* Link Input Section */} {showLinkInput && (
setVideoLink(e.target.value)} placeholder="https://drive.google.com/..." className="w-full px-3 py-2 border border-gray-300 rounded-md focus:ring-primary-500 focus:border-primary-500" required />
)} {/* Message Input & Actions */}
setNewMessage(e.target.value)} placeholder="Write a message..." className="flex-1 px-4 py-2 border border-gray-300 rounded-lg focus:ring-primary-500 focus:border-primary-500" />
{/* Info Box */}

🚀 WebRTC P2P Functionality Mockup: In the full version, videos will be transferred directly between users via RTCDataChannel, with chunking and progress monitoring. The server is only used for SDP/ICE exchange (signaling).

); }; export default MatchChatPage;