Clues slice, accessible by host

This commit is contained in:
Dane Johnson 2023-02-12 12:59:41 -06:00
parent dfe2fb98bc
commit 366238748e
6 changed files with 98 additions and 10 deletions

View File

@ -1,25 +1,26 @@
import { useEffect } from "react";
import { useParams } from "react-router-dom";
import { Container, Stack, Button } from "react-bootstrap";
import { socket } from "./socket";
import { useAppSelector } from "./hooks";
import { selectCategories } from "./store/cluesSlice";
import Pregame from "./host/Pregame";
import CluesDisplay from "./host/CluesDisplay";
const Host = () => {
const { room } = useParams();
const categories = useAppSelector(selectCategories);
useEffect(() => {
socket.emit("host-join", { room });
}, []);
return (
<Container>
<Stack gap={3} className="text-center">
<span>
<Button onClick={() => socket.emit("host-start")}>Start Game</Button>
</span>
</Stack>
</Container>
);
if (categories.length < 6) {
return <Pregame />;
} else {
return <CluesDisplay />;
}
};
export default Host;

24
src/host/CluesDisplay.tsx Normal file
View File

@ -0,0 +1,24 @@
import { Container, Button, Stack } from "react-bootstrap";
import { useAppSelector } from "../hooks";
import { selectCategories } from "../store/cluesSlice";
const CluesDisplay = () => {
const categories = useAppSelector(selectCategories);
return (
<Container>
<Stack gap={3} className="text-center">
{categories.map(({ name }) => (
<>
<h2>{name}</h2>
{[200, 400, 600, 800, 1000].map((value) => (
<Button key={value}>{value}</Button>
))}
</>
))}
</Stack>
</Container>
);
};
export default CluesDisplay;

27
src/host/Pregame.tsx Normal file
View File

@ -0,0 +1,27 @@
import { useState } from "react";
import { Container, Stack, Button } from "react-bootstrap";
import { socket } from "../socket";
const Pregame = () => {
const [loading, setLoading] = useState(false);
return (
<Container>
<Stack gap={3} className="text-center">
<span>
<Button
disabled={loading}
onClick={() => {
socket.emit("host-start");
setLoading(true);
}}
>
{loading ? "Loading..." : "Start Game"}
</Button>
</span>
</Stack>
</Container>
);
};
export default Pregame;

View File

@ -2,6 +2,7 @@ import { io } from "socket.io-client";
import store from "./store";
import { setRoomCode } from "./store/socketSlice";
import { addContestant } from "./store/displaySlice";
import { addCategory } from "./store/cluesSlice";
export const socket = io(`${window.location.hostname}:5000`);
@ -17,4 +18,8 @@ export const setup = () => {
socket.on("contestant-joined", (data) => {
store.dispatch(addContestant(data));
});
socket.on("categories", (data) =>
data.forEach((category) => store.dispatch(addCategory(category)))
);
};

29
src/store/cluesSlice.ts Normal file
View File

@ -0,0 +1,29 @@
import { createSlice, PayloadAction } from "@reduxjs/toolkit";
import type { RootState } from "./";
interface Category {
name: string;
clues: Clue[];
}
interface Clue {
value: number;
question: string;
answer?: string;
}
const initialState: Category[] = [];
export const cluesSlice = createSlice({
name: "clues",
initialState,
reducers: {
addCategory: (state, { payload }: PayloadAction<string>) =>
(state = [...state, { name: payload, clues: [] }]),
},
});
export const { addCategory } = cluesSlice.actions;
export const selectCategories = (state: RootState) => state.clues;
export default cluesSlice.reducer;

View File

@ -2,12 +2,14 @@ import { configureStore } from "@reduxjs/toolkit";
import socketReducer from "./socketSlice";
import contestantReducer from "./contestantSlice";
import displayReducer from "./displaySlice";
import cluesReducer from "./cluesSlice";
const store = configureStore({
reducer: {
socket: socketReducer,
contestant: contestantReducer,
display: displayReducer,
clues: cluesReducer,
},
});