live updates
This commit is contained in:
@@ -2,12 +2,14 @@ import React, { useState, useEffect, useRef } from 'react';
|
||||
import { useParams, Link } from 'react-router-dom';
|
||||
import toast from 'react-hot-toast';
|
||||
import { useAuth } from '../AuthContext';
|
||||
import { useSocket } from '../SocketContext';
|
||||
import api from '../api';
|
||||
import { useClickOutside } from '../hooks/useClickOutside';
|
||||
|
||||
export default function ChallengeDetail() {
|
||||
const { id } = useParams();
|
||||
const { user } = useAuth();
|
||||
const { socket, joinChallenge, leaveChallenge } = useSocket();
|
||||
const [challenge, setChallenge] = useState(null);
|
||||
const [predictions, setPredictions] = useState([]);
|
||||
const [leaderboard, setLeaderboard] = useState([]);
|
||||
@@ -29,6 +31,59 @@ export default function ChallengeDetail() {
|
||||
loadLeaderboard();
|
||||
}, [id]);
|
||||
|
||||
// Join challenge room for real-time updates
|
||||
useEffect(() => {
|
||||
if (socket && id) {
|
||||
joinChallenge(id);
|
||||
|
||||
return () => {
|
||||
leaveChallenge(id);
|
||||
};
|
||||
}
|
||||
}, [socket, id]);
|
||||
|
||||
// Listen for real-time prediction events
|
||||
useEffect(() => {
|
||||
if (!socket) return;
|
||||
|
||||
const handlePredictionCreated = (prediction) => {
|
||||
setPredictions(prev => [prediction, ...prev]);
|
||||
toast.success(`New prediction from ${prediction.username}`);
|
||||
};
|
||||
|
||||
const handlePredictionValidated = (prediction) => {
|
||||
setPredictions(prev =>
|
||||
prev.map(p => p.id === prediction.id ? prediction : p)
|
||||
);
|
||||
loadLeaderboard(); // Refresh leaderboard when points change
|
||||
|
||||
if (prediction.user_id === user.id) {
|
||||
toast.success(
|
||||
prediction.status === 'validated'
|
||||
? '🎉 Your prediction was validated!'
|
||||
: '❌ Your prediction was invalidated'
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
const handleInvitationResponse = (response) => {
|
||||
if (response.status === 'accepted') {
|
||||
toast.success(`${response.username} joined the challenge!`);
|
||||
loadChallenge(); // Refresh participant list
|
||||
}
|
||||
};
|
||||
|
||||
socket.on('prediction:created', handlePredictionCreated);
|
||||
socket.on('prediction:validated', handlePredictionValidated);
|
||||
socket.on('challenge:invitation_response', handleInvitationResponse);
|
||||
|
||||
return () => {
|
||||
socket.off('prediction:created', handlePredictionCreated);
|
||||
socket.off('prediction:validated', handlePredictionValidated);
|
||||
socket.off('challenge:invitation_response', handleInvitationResponse);
|
||||
};
|
||||
}, [socket, user]);
|
||||
|
||||
const loadChallenge = async () => {
|
||||
try {
|
||||
const data = await api.getChallenge(id);
|
||||
|
||||
Reference in New Issue
Block a user