- Introduced `/api/movie/<id>/detail` endpoint returning TMDB data for a movie. - Moved draft detail fetching logic into `common/utils.js` for reuse. - Updated Draft Admin panel: - Added phase navigation buttons with bootstrap icons. - Improved layout with refresh and status controls. - Updated Draft Participant panel: - Added movie pool display with links to movie details. - Added bootstrap-icons stylesheet and corresponding SCSS styles for new UI.
98 lines
2.6 KiB
JavaScript
98 lines
2.6 KiB
JavaScript
// DraftAdmin.jsx
|
|
import React, { useEffect, useState } from "react";
|
|
|
|
import { useWebSocket } from "../WebSocketContext.jsx";
|
|
import { WebSocketStatus } from "../common/WebSocketStatus.jsx";
|
|
import { DraftMessage, DraftPhases } from '../constants.js';
|
|
import { fetchDraftDetails } from "../common/utils.js"
|
|
|
|
const DraftMoviePool = ({ movies }) => {
|
|
return (
|
|
<div className="movie-pool-container">
|
|
<ul>
|
|
{movies.map(m => (
|
|
<li id={m?.id}>
|
|
<a href={`/api/movie/${m.id}/detail`}>
|
|
{m.title}
|
|
</a>
|
|
</li>
|
|
))}
|
|
</ul>
|
|
</div>
|
|
)
|
|
}
|
|
|
|
export const DraftParticipant = ({ draftSessionId }) => {
|
|
const socket = useWebSocket();
|
|
const [participants, setParticipants] = useState([]);
|
|
const [draftPhase, setDraftPhase] = useState();
|
|
const [movies, setMovies] = useState([]);
|
|
console.log(socket)
|
|
|
|
useEffect(() => {
|
|
fetchDraftDetails(draftSessionId)
|
|
.then((data) => {
|
|
console.log("Fetched draft data", data)
|
|
setMovies(data.movies)
|
|
})
|
|
}, [])
|
|
|
|
|
|
useEffect(() => {
|
|
if (!socket) return;
|
|
else {
|
|
console.warn("socket doesn't exist")
|
|
}
|
|
console.log('socket created', socket)
|
|
|
|
const handleMessage = (event) => {
|
|
const message = JSON.parse(event.data)
|
|
const { type, payload } = message;
|
|
console.log(type, event)
|
|
if (type == DraftMessage.REQUEST.JOIN_PARTICIPANT) {
|
|
console.log('join request', data)
|
|
}
|
|
else if (type == DraftMessage.CONFIRM.JOIN_PARTICIPANT) {
|
|
setConnectedParticipants(data.connected_participants)
|
|
}
|
|
else if (type == DraftMessage.CONFIRM.PHASE_CHANGE || type == DraftMessage.INFORM.PHASE) {
|
|
console.log('phase_change')
|
|
setDraftPhase(payload.phase)
|
|
}
|
|
}
|
|
|
|
socket.addEventListener('message', handleMessage);
|
|
|
|
socket.onclose = (event) => {
|
|
console.log('Websocket Closed')
|
|
socket = null;
|
|
}
|
|
|
|
return () => {
|
|
socket.removeEventListener('message', handleMessage)
|
|
socket.close();
|
|
};
|
|
}, [socket]);
|
|
|
|
const handlePhaseChange = (destinationPhase) => {
|
|
socket.send(
|
|
JSON.stringify({ type: DraftMessage.REQUEST.PHASE_CHANGE, "destination": destinationPhase })
|
|
);
|
|
}
|
|
|
|
|
|
const handleRequestDraftSummary = () => {
|
|
socket.send(JSON.stringify({ type: 'request_summary' }))
|
|
}
|
|
|
|
return (
|
|
<div className="container draft-panel">
|
|
<div className="d-flex justify-content-between border-bottom mb-2 p-1">
|
|
<h3>Draft Panel</h3>
|
|
<WebSocketStatus socket={socket} />
|
|
</div>
|
|
|
|
<DraftMoviePool movies={movies}></DraftMoviePool>
|
|
</div>
|
|
);
|
|
}; |