2025-08-01
This commit is contained in:
@@ -1,9 +1,112 @@
|
||||
import React, { useEffect, useState, useRef } from "react";
|
||||
|
||||
export const useWebSocketStatus = (wsUrl) => {
|
||||
const [isConnected, setIsConnected] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
const socket = new WebSocket(wsUrl);
|
||||
|
||||
socket.onopen = () => setIsConnected(true);
|
||||
socket.onclose = () => setIsConnected(false);
|
||||
socket.onerror = () => setIsConnected(false);
|
||||
|
||||
return () => socket.close();
|
||||
}, [wsUrl]);
|
||||
|
||||
return isConnected;
|
||||
};
|
||||
|
||||
export const WebSocketStatus = ({ wsUrl }) => {
|
||||
const isConnected = useWebSocketStatus(wsUrl);
|
||||
|
||||
return (
|
||||
<div className="d-flex align-items-center gap-2">
|
||||
<span
|
||||
className="status-dot"
|
||||
style={{
|
||||
width: "10px",
|
||||
height: "10px",
|
||||
borderRadius: "50%",
|
||||
backgroundColor: isConnected ? "green" : "red",
|
||||
display: "inline-block",
|
||||
}}
|
||||
></span>
|
||||
<span>{isConnected ? "Connected" : "Disconnected"}</span>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export const DraftAdmin = ({ draftSessionId }) => {
|
||||
const [latestMessage, setLatestMessage] = useState(null);
|
||||
const [connectedParticipants, setConnectedParticipants] = useState([]);
|
||||
const [isConnected, setIsConnected] = useState(false);
|
||||
|
||||
const socketRef = useRef(null);
|
||||
const wsUrl = `ws://${window.location.host}/ws/draft/session/${draftSessionId}/`;
|
||||
const wsUrl = `ws://${window.location.host}/ws/draft/session/${draftSessionId}/admin`;
|
||||
|
||||
useEffect(() => {
|
||||
socketRef.current = new WebSocket(wsUrl);
|
||||
|
||||
socketRef.current.onmessage = (event) => {
|
||||
const data = JSON.parse(event.data);
|
||||
console.log(event)
|
||||
setLatestMessage(data);
|
||||
if (data.type == "user.joined") {
|
||||
// setConnectedParticipants =
|
||||
}
|
||||
else if (data.type == "draft_summary"){
|
||||
console.log(data)
|
||||
}
|
||||
};
|
||||
|
||||
socketRef.current.onclose = () => {
|
||||
console.warn("WebSocket connection closed.");
|
||||
};
|
||||
|
||||
return () => {
|
||||
socketRef.current.close();
|
||||
};
|
||||
}, [wsUrl]);
|
||||
|
||||
const handleStartDraft = () => {
|
||||
socketRef.current.send(JSON.stringify({ type: "start.draft" }));
|
||||
}
|
||||
|
||||
|
||||
const handleRequestDraftSummary = () => {
|
||||
socketRef.current.send(JSON.stringify({ type: 'request_summary' }))
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="container draft-panel">
|
||||
<h3>Draft Admin Panel</h3>
|
||||
<WebSocketStatus wsUrl={wsUrl} />
|
||||
<label>Latest Message</label>
|
||||
<input
|
||||
type="text"
|
||||
readOnly disabled
|
||||
value={latestMessage ? JSON.stringify(latestMessage) : ""}
|
||||
/>
|
||||
<label>Connected Particpants</label>
|
||||
<input
|
||||
type="text"
|
||||
readOnly disabled
|
||||
value={connectedParticipants ? JSON.stringify(connectedParticipants) : ""}
|
||||
/>
|
||||
<button onClick={handleStartDraft} className="btn btn-primary mt-2">
|
||||
Start Draft
|
||||
</button>
|
||||
<button onClick={handleRequestDraftSummary} className="btn btn-primary mt-2">
|
||||
Request status
|
||||
</button>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export const DraftParticipant = ({ draftSessionId }) => {
|
||||
const [latestMessage, setLatestMessage] = useState(null);
|
||||
const socketRef = useRef(null);
|
||||
const wsUrl = `ws://${window.location.host}/ws/draft/session/${draftSessionId}/participant`;
|
||||
|
||||
useEffect(() => {
|
||||
socketRef.current = new WebSocket(wsUrl);
|
||||
@@ -11,6 +114,9 @@ export const DraftAdmin = ({ draftSessionId }) => {
|
||||
socketRef.current.onmessage = (event) => {
|
||||
const data = JSON.parse(event.data);
|
||||
setLatestMessage(data);
|
||||
if (data.type == "draft_summary") {
|
||||
console.log('draft_summary', data)
|
||||
}
|
||||
};
|
||||
|
||||
socketRef.current.onclose = () => {
|
||||
@@ -27,18 +133,15 @@ export const DraftAdmin = ({ draftSessionId }) => {
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="container mt-4">
|
||||
<h1>Draft Admin Panel</h1>
|
||||
<div className="container draft-panel">
|
||||
<h3 >Draft Participant Panel</h3>
|
||||
<WebSocketStatus wsUrl={wsUrl} />
|
||||
<label>Latest Message</label>
|
||||
<input
|
||||
type="text"
|
||||
className="form-control"
|
||||
readOnly disabled
|
||||
value={latestMessage ? JSON.stringify(latestMessage) : ""}
|
||||
/>
|
||||
<button onClick={handleStartDraft} className="btn btn-primary">
|
||||
Start Draft
|
||||
</button>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
@@ -3,13 +3,20 @@ console.log("Webpack HMR loaded!");
|
||||
|
||||
import React from "react";
|
||||
import { createRoot } from "react-dom/client";
|
||||
import {DraftAdmin} from './apps/draft/index.jsx'
|
||||
import {DraftAdmin, DraftParticipant} from './apps/draft/index.jsx'
|
||||
|
||||
document.addEventListener("DOMContentLoaded", () => {
|
||||
const draftApp = document.getElementById("draft-app");
|
||||
const draftAdminApp = document.getElementById("draft-admin-app");
|
||||
const draftApp = document.getElementById("draft-app")
|
||||
if (draftApp) {
|
||||
const root = createRoot(draftApp);
|
||||
const draftId = draftApp.dataset.draftId
|
||||
root.render(<DraftParticipant draftSessionId={draftId} />);
|
||||
|
||||
}
|
||||
if (draftAdminApp) {
|
||||
const root = createRoot(draftAdminApp);
|
||||
const draftId = draftAdminApp.dataset.draftId
|
||||
root.render(<DraftAdmin draftSessionId={draftId} />);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
@@ -15,4 +15,18 @@
|
||||
font-family: "Graphique";
|
||||
font-size: x-large;
|
||||
}
|
||||
}
|
||||
|
||||
.draft-panel {
|
||||
@extend .mt-4 ;
|
||||
@extend .border ;
|
||||
@extend .rounded-2 ;
|
||||
@extend .p-2;
|
||||
@extend .pt-1;
|
||||
label {
|
||||
@extend .form-label;
|
||||
}
|
||||
input {
|
||||
@extend .form-control;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user