From 0576f442986bc7baba76bdae95dfa03f7df454e2 Mon Sep 17 00:00:00 2001 From: David Leclerc Date: Mon, 25 Mar 2024 12:58:09 +0100 Subject: [PATCH] Chore: move selectors to their own directory and files. --- .../src/components/forms/AdminQuizForm.tsx | 2 +- .../Client/src/components/forms/LoginForm.tsx | 2 +- .../src/components/overlays/AnswerOverlay.tsx | 2 +- .../components/overlays/LoadingOverlay.tsx | 2 +- Apps/Client/src/pages/QuizPage.tsx | 2 +- Apps/Client/src/reducers/QuizReducer.ts | 97 ------------------- Apps/Client/src/reducers/UserReducer.ts | 3 - Apps/Client/src/selectors/QuizSelectors.ts | 95 ++++++++++++++++++ Apps/Client/src/selectors/UserSelectors.ts | 3 + 9 files changed, 103 insertions(+), 105 deletions(-) create mode 100644 Apps/Client/src/selectors/QuizSelectors.ts create mode 100644 Apps/Client/src/selectors/UserSelectors.ts diff --git a/Apps/Client/src/components/forms/AdminQuizForm.tsx b/Apps/Client/src/components/forms/AdminQuizForm.tsx index 2c902b0..8bf6456 100644 --- a/Apps/Client/src/components/forms/AdminQuizForm.tsx +++ b/Apps/Client/src/components/forms/AdminQuizForm.tsx @@ -3,9 +3,9 @@ import { useDispatch, useSelector } from '../../hooks/redux'; import './AdminQuizForm.scss'; import { deleteQuiz, startQuiz } from '../../actions/QuizActions'; import { Trans, useTranslation } from 'react-i18next'; -import { selectPlayers } from '../../reducers/QuizReducer'; import { deleteDatabase } from '../../actions/DatabaseActions'; import { logout } from '../../actions/AuthActions'; +import { selectPlayers } from '../../selectors/QuizSelectors'; const AdminQuizForm: React.FC = () => { const dispatch = useDispatch(); diff --git a/Apps/Client/src/components/forms/LoginForm.tsx b/Apps/Client/src/components/forms/LoginForm.tsx index 3a6ae8f..162c2de 100644 --- a/Apps/Client/src/components/forms/LoginForm.tsx +++ b/Apps/Client/src/components/forms/LoginForm.tsx @@ -1,10 +1,10 @@ import React, { useEffect, useState } from 'react'; import { useNavigate } from 'react-router-dom'; import { useDispatch, useSelector } from '../../hooks/redux'; -import { selectAuthentication } from '../../reducers/UserReducer'; import './LoginForm.scss'; import { login } from '../../actions/AuthActions'; import { useTranslation } from 'react-i18next'; +import { selectAuthentication } from '../../selectors/UserSelectors'; type Props = { quizId: string | null, diff --git a/Apps/Client/src/components/overlays/AnswerOverlay.tsx b/Apps/Client/src/components/overlays/AnswerOverlay.tsx index ae15de5..7fb985e 100644 --- a/Apps/Client/src/components/overlays/AnswerOverlay.tsx +++ b/Apps/Client/src/components/overlays/AnswerOverlay.tsx @@ -1,6 +1,5 @@ import './AnswerOverlay.scss'; import { useDispatch, useSelector } from '../../hooks/redux'; -import { selectAnswer, selectPlayers, selectCorrectAnswer } from '../../reducers/QuizReducer'; import { closeAnswerOverlay } from '../../reducers/OverlaysReducer'; import { setQuestionIndex } from '../../reducers/AppReducer'; import { useNavigate } from 'react-router-dom'; @@ -9,6 +8,7 @@ import WrongIcon from '@mui/icons-material/Close'; import WaitIcon from '@mui/icons-material/Schedule'; import { startQuestion } from '../../actions/QuizActions'; import { useTranslation } from 'react-i18next'; +import { selectPlayers, selectAnswer, selectCorrectAnswer } from '../../selectors/QuizSelectors'; const AnswerOverlay: React.FC = () => { const dispatch = useDispatch(); diff --git a/Apps/Client/src/components/overlays/LoadingOverlay.tsx b/Apps/Client/src/components/overlays/LoadingOverlay.tsx index 6d9b54c..e03a860 100644 --- a/Apps/Client/src/components/overlays/LoadingOverlay.tsx +++ b/Apps/Client/src/components/overlays/LoadingOverlay.tsx @@ -1,7 +1,7 @@ import { Trans, useTranslation } from 'react-i18next'; import { useSelector } from '../../hooks/redux'; import './LoadingOverlay.scss'; -import { selectPlayers } from '../../reducers/QuizReducer'; +import { selectPlayers } from '../../selectors/QuizSelectors'; const LoadingOverlay: React.FC = () => { const { t } = useTranslation(); diff --git a/Apps/Client/src/pages/QuizPage.tsx b/Apps/Client/src/pages/QuizPage.tsx index 412fb3c..93a25e2 100644 --- a/Apps/Client/src/pages/QuizPage.tsx +++ b/Apps/Client/src/pages/QuizPage.tsx @@ -4,13 +4,13 @@ import QuestionForm from '../components/forms/QuestionForm'; import { useDispatch, useSelector } from '../hooks/redux'; import { REFRESH_STATUS_INTERVAL } from '../config'; import { fetchStatus, fetchQuizData, fetchQuestions } from '../actions/DataActions'; -import { selectVote } from '../reducers/QuizReducer'; import { closeAnswerOverlay, closeLoadingOverlay, openAnswerOverlay, openLoadingOverlay } from '../reducers/OverlaysReducer'; import AdminQuizForm from '../components/forms/AdminQuizForm'; import { useTranslation } from 'react-i18next'; import { AspectRatio, Language, QuestionType } from '../constants'; import { logout } from '../actions/AuthActions'; import Page from './Page'; +import { selectVote } from '../selectors/QuizSelectors'; const QuizPage: React.FC = () => { const { t, i18n } = useTranslation(); diff --git a/Apps/Client/src/reducers/QuizReducer.ts b/Apps/Client/src/reducers/QuizReducer.ts index 78bb095..3ea62e1 100644 --- a/Apps/Client/src/reducers/QuizReducer.ts +++ b/Apps/Client/src/reducers/QuizReducer.ts @@ -4,7 +4,6 @@ import { getInitialFetchedData } from '../utils'; import { startQuiz, startQuestion, vote } from '../actions/QuizActions'; import { login, logout, ping } from '../actions/AuthActions'; import { QuizJSON } from '../types/JSONTypes'; -import { RootState } from '../stores/store'; import { QuizName } from '../constants'; import { fetchStatus, fetchQuestions, fetchVotes, fetchScores } from '../actions/DataActions'; @@ -141,102 +140,6 @@ export const quizSlice = createSlice({ }, }); -// export const { } = quizSlice.actions; - -export const selectPlayers = (state: RootState) => { - const status = state.quiz.status.data; - - if (status === null) { - return []; - } - - return status.players; -} - -export const selectQuestion = (state: RootState, questionIndex: number) => { - const quiz = state.quiz; - - const questions = quiz.questions.data; - const votes = quiz.votes.data; - - if (questions === null || votes === null) { - return null; - } - - return questions[questionIndex]; -} - -export const selectAnswer = (state: RootState, questionIndex: number) => { - const quiz = state.quiz; - - const questions = quiz.questions.data; - const votes = quiz.votes.data; - - if (questions === null || votes === null) { - return null; - } - - const question = questions[questionIndex]; - const vote = votes[questionIndex]; - const answer = question.options[vote]; - - return answer; -} - -export const selectCorrectAnswer = (state: RootState, questionIndex: number) => { - const quiz = state.quiz; - - const questions = quiz.questions.data; - - if (questions === null) { - return null; - } - - const question = questions[questionIndex]; - const answer = question.options[question.answer]; - - return answer; -} - -export const selectVote = (state: RootState, questionIndex: number) => { - const quiz = state.quiz; - - const questions = quiz.questions.data; - const votes = quiz.votes.data; - - if (questions === null || votes === null || votes.length < questionIndex + 1) { - return { - voteIndex: null, - vote: null, - }; - } - - const question = questions[questionIndex]; - const voteIndex = votes[questionIndex]; - const vote = question.options[voteIndex]; - - return { - voteIndex, - vote, - }; -} - -export const haveAllPlayersAnswered = (state: RootState, questionIndex: number) => { - const quiz = state.quiz; - - const status = quiz.status.data; - const votes = quiz.votes.data; - const players = selectPlayers(state); - - if (status === null || votes === null || players === null) { - return false; - } - - const { votesCount } = status; - - return votesCount[questionIndex] === players.length; -} - export const { setQuizName } = quizSlice.actions; export default quizSlice.reducer; \ No newline at end of file diff --git a/Apps/Client/src/reducers/UserReducer.ts b/Apps/Client/src/reducers/UserReducer.ts index 4b91fe3..1c8d5f7 100644 --- a/Apps/Client/src/reducers/UserReducer.ts +++ b/Apps/Client/src/reducers/UserReducer.ts @@ -1,5 +1,4 @@ import { createSlice } from '@reduxjs/toolkit'; -import { RootState } from '../stores/store'; import { login, logout, ping } from '../actions/AuthActions'; interface UserState { @@ -67,6 +66,4 @@ export const userSlice = createSlice({ }, }); -export const selectAuthentication = (state: RootState) => state.user; - export default userSlice.reducer; \ No newline at end of file diff --git a/Apps/Client/src/selectors/QuizSelectors.ts b/Apps/Client/src/selectors/QuizSelectors.ts new file mode 100644 index 0000000..73facb3 --- /dev/null +++ b/Apps/Client/src/selectors/QuizSelectors.ts @@ -0,0 +1,95 @@ +import { RootState } from '../stores/store'; + +export const selectPlayers = (state: RootState) => { + const status = state.quiz.status.data; + + if (status === null) { + return []; + } + + return status.players; + } + + export const selectQuestion = (state: RootState, questionIndex: number) => { + const quiz = state.quiz; + + const questions = quiz.questions.data; + const votes = quiz.votes.data; + + if (questions === null || votes === null) { + return null; + } + + return questions[questionIndex]; + } + + export const selectAnswer = (state: RootState, questionIndex: number) => { + const quiz = state.quiz; + + const questions = quiz.questions.data; + const votes = quiz.votes.data; + + if (questions === null || votes === null) { + return null; + } + + const question = questions[questionIndex]; + const vote = votes[questionIndex]; + const answer = question.options[vote]; + + return answer; + } + + export const selectCorrectAnswer = (state: RootState, questionIndex: number) => { + const quiz = state.quiz; + + const questions = quiz.questions.data; + + if (questions === null) { + return null; + } + + const question = questions[questionIndex]; + const answer = question.options[question.answer]; + + return answer; + } + + export const selectVote = (state: RootState, questionIndex: number) => { + const quiz = state.quiz; + + const questions = quiz.questions.data; + const votes = quiz.votes.data; + + if (questions === null || votes === null || votes.length < questionIndex + 1) { + return { + voteIndex: null, + vote: null, + }; + } + + const question = questions[questionIndex]; + const voteIndex = votes[questionIndex]; + const vote = question.options[voteIndex]; + + return { + voteIndex, + vote, + }; + } + + export const haveAllPlayersAnswered = (state: RootState, questionIndex: number) => { + const quiz = state.quiz; + + const status = quiz.status.data; + const votes = quiz.votes.data; + const players = selectPlayers(state); + + if (status === null || votes === null || players === null) { + return false; + } + + const { votesCount } = status; + + return votesCount[questionIndex] === players.length; + } \ No newline at end of file diff --git a/Apps/Client/src/selectors/UserSelectors.ts b/Apps/Client/src/selectors/UserSelectors.ts new file mode 100644 index 0000000..07d90ed --- /dev/null +++ b/Apps/Client/src/selectors/UserSelectors.ts @@ -0,0 +1,3 @@ +import { RootState } from '../stores/store'; + +export const selectAuthentication = (state: RootState) => state.user; \ No newline at end of file