From fcb5b84188c3f1a29d22f4681ce35ea9e1cde097 Mon Sep 17 00:00:00 2001
From: Albin Henriksson <albhe428@student.liu.se>
Date: Thu, 20 May 2021 15:31:47 +0000
Subject: [PATCH] Fix bug where answers were locked for questions which

---
 .../components/answerComponents/AnswerMatch.tsx     | 13 +++++++++++--
 .../components/answerComponents/AnswerMultiple.tsx  |  4 +++-
 .../components/answerComponents/AnswerSingle.tsx    | 13 +++++++++----
 .../components/answerComponents/AnswerText.tsx      | 10 +++++++---
 4 files changed, 30 insertions(+), 10 deletions(-)

diff --git a/client/src/pages/presentationEditor/components/answerComponents/AnswerMatch.tsx b/client/src/pages/presentationEditor/components/answerComponents/AnswerMatch.tsx
index d2d6c3e2..15fabf0e 100644
--- a/client/src/pages/presentationEditor/components/answerComponents/AnswerMatch.tsx
+++ b/client/src/pages/presentationEditor/components/answerComponents/AnswerMatch.tsx
@@ -37,6 +37,7 @@ const AnswerMatch = ({ variant, activeSlide, competitionId }: AnswerMultipleProp
   const [sortedAlternatives, setSortedAlternatives] = useState<QuestionAlternative[]>([])
   const [sortedAnswers, setSortedAnswers] = useState<QuestionAlternative[]>([])
   const team = useAppSelector((state) => state.presentation.competition.teams.find((team) => team.id === teamId))
+  const timer = useAppSelector((state) => state.presentation.timer)
 
   useEffect(() => {
     if (activeSlide) {
@@ -68,9 +69,17 @@ const AnswerMatch = ({ variant, activeSlide, competitionId }: AnswerMultipleProp
     }
   }, [teamId])
 
+  const getButtonStyle = () => {
+    if (!(timer.value === null || (timer.enabled && timer.value))) {
+      return { fill: '#AAAAAA' } // Buttons are light grey if  timer is not on
+    }
+    return {}
+  }
+
   const onMove = async (previousIndex: number, resultIndex: number) => {
     // moved outside the list
     if (resultIndex < 0 || resultIndex >= sortedAnswers.length || variant !== 'presentation') return
+    if (!(timer.value === null || (timer.enabled && timer.value))) return
     const answersCopy = [...sortedAnswers]
     const [removed] = answersCopy.splice(previousIndex, 1)
     answersCopy.splice(resultIndex, 0, removed)
@@ -117,10 +126,10 @@ const AnswerMatch = ({ variant, activeSlide, competitionId }: AnswerMultipleProp
               </MatchCorrectContainer>
               <MatchButtonContainer>
                 <Clickable>
-                  <KeyboardArrowUpIcon onClick={() => onMove(index, index - 1)} />
+                  <KeyboardArrowUpIcon style={getButtonStyle()} onClick={() => onMove(index, index - 1)} />
                 </Clickable>
                 <Clickable>
-                  <KeyboardArrowDownIcon onClick={() => onMove(index, index + 1)} />
+                  <KeyboardArrowDownIcon style={getButtonStyle()} onClick={() => onMove(index, index + 1)} />
                 </Clickable>
               </MatchButtonContainer>
             </MatchCard>
diff --git a/client/src/pages/presentationEditor/components/answerComponents/AnswerMultiple.tsx b/client/src/pages/presentationEditor/components/answerComponents/AnswerMultiple.tsx
index 5868ef11..e648845a 100644
--- a/client/src/pages/presentationEditor/components/answerComponents/AnswerMultiple.tsx
+++ b/client/src/pages/presentationEditor/components/answerComponents/AnswerMultiple.tsx
@@ -34,6 +34,7 @@ const AnswerMultiple = ({ variant, activeSlide, competitionId }: AnswerMultipleP
   const dispatch = useAppDispatch()
   const teamId = useAppSelector((state) => state.competitionLogin.data?.team_id)
   const team = useAppSelector((state) => state.presentation.competition.teams.find((team) => team.id === teamId))
+  const timer = useAppSelector((state) => state.presentation.timer)
 
   const decideChecked = (alternative: QuestionAlternative) => {
     const answer = team?.question_alternative_answers.find(
@@ -47,7 +48,7 @@ const AnswerMultiple = ({ variant, activeSlide, competitionId }: AnswerMultipleP
 
   const updateAnswer = async (alternative: QuestionAlternative, checked: boolean) => {
     // TODO: fix. Make list of alternatives and delete & post instead of put to allow multiple boxes checked.
-    if (!activeSlide) {
+    if (!(activeSlide && (timer.value === null || (timer.enabled && timer.value)))) {
       return
     }
     const url = `/api/competitions/${competitionId}/teams/${teamId}/answers/question_alternatives/${alternative.id}`
@@ -90,6 +91,7 @@ const AnswerMultiple = ({ variant, activeSlide, competitionId }: AnswerMultipleP
           <div key={alt.id}>
             <ListItem divider>
               <GreenCheckbox
+                disabled={!(timer.value === null || (timer.enabled && timer.value))}
                 checked={decideChecked(alt)}
                 onChange={(event: any) => updateAnswer(alt, event.target.checked)}
               />
diff --git a/client/src/pages/presentationEditor/components/answerComponents/AnswerSingle.tsx b/client/src/pages/presentationEditor/components/answerComponents/AnswerSingle.tsx
index 1bd16da5..29389c44 100644
--- a/client/src/pages/presentationEditor/components/answerComponents/AnswerSingle.tsx
+++ b/client/src/pages/presentationEditor/components/answerComponents/AnswerSingle.tsx
@@ -37,6 +37,7 @@ const AnswerSingle = ({ variant, activeSlide, competitionId }: AnswerSingleProps
     if (variant === 'editor') return state.editor.competition.teams.find((team) => team.id === teamId)
     return state.presentation.competition.teams.find((team) => team.id === teamId)
   })
+  const timer = useAppSelector((state) => state.presentation.timer)
 
   const decideChecked = (alternative: QuestionAlternative) => {
     const answer = team?.question_alternative_answers.find(
@@ -49,7 +50,7 @@ const AnswerSingle = ({ variant, activeSlide, competitionId }: AnswerSingleProps
   }
 
   const updateAnswer = async (alternative: QuestionAlternative) => {
-    if (!activeSlide) {
+    if (!(activeSlide && (timer.value === null || (timer.enabled && timer.value)))) {
       return
     }
 
@@ -77,22 +78,26 @@ const AnswerSingle = ({ variant, activeSlide, competitionId }: AnswerSingleProps
    * Renders the radio button which the participants will click to mark their answer.
    */
   const renderRadioButton = (alt: QuestionAlternative) => {
+    let disabledStyle
+    if (!(timer.value === null || (timer.enabled && timer.value))) {
+      disabledStyle = { fill: '#AAAAAA' } // Buttons are light grey if  timer is not on
+    }
     if (variant === 'presentation') {
       if (decideChecked(alt)) {
         return (
           <Clickable>
-            <RadioButtonCheckedIcon onClick={() => updateAnswer(alt)} />
+            <RadioButtonCheckedIcon style={disabledStyle} onClick={() => updateAnswer(alt)} />
           </Clickable>
         )
       } else {
         return (
           <Clickable>
-            <RadioButtonUncheckedIcon onClick={() => updateAnswer(alt)} />
+            <RadioButtonUncheckedIcon style={disabledStyle} onClick={() => updateAnswer(alt)} />
           </Clickable>
         )
       }
     } else {
-      return <RadioButtonUncheckedIcon onClick={() => updateAnswer(alt)} />
+      return <RadioButtonUncheckedIcon style={disabledStyle} onClick={() => updateAnswer(alt)} />
     }
   }
 
diff --git a/client/src/pages/presentationEditor/components/answerComponents/AnswerText.tsx b/client/src/pages/presentationEditor/components/answerComponents/AnswerText.tsx
index f3dccfd5..b7f0d687 100644
--- a/client/src/pages/presentationEditor/components/answerComponents/AnswerText.tsx
+++ b/client/src/pages/presentationEditor/components/answerComponents/AnswerText.tsx
@@ -31,14 +31,18 @@ const AnswerText = ({ activeSlide, competitionId }: AnswerTextProps) => {
   const dispatch = useAppDispatch()
   const teamId = useAppSelector((state) => state.competitionLogin.data?.team_id)
   const team = useAppSelector((state) => state.presentation.competition.teams.find((team) => team.id === teamId))
+  const timer = useAppSelector((state) => state.presentation.timer)
 
   const onAnswerChange = (answer: string) => {
     if (timerHandle) {
       clearTimeout(timerHandle)
       setTimerHandle(undefined)
     }
-    //Only updates answer 100ms after last input was made
-    setTimerHandle(window.setTimeout(() => updateAnswer(answer), 100))
+    //Only updates answer if the timer is on
+    if (timer.value === null || (timer.enabled && timer.value)) {
+      //Only updates answer 100ms after last input was made
+      setTimerHandle(window.setTimeout(() => updateAnswer(answer), 100))
+    }
   }
 
   const updateAnswer = async (answer: string) => {
@@ -75,7 +79,7 @@ const AnswerText = ({ activeSlide, competitionId }: AnswerTextProps) => {
       </ListItem>
       <ListItem style={{ height: '100%' }}>
         <TextField
-          disabled={team === undefined}
+          disabled={team === undefined || !(timer.value === null || (timer.enabled && timer.value))}
           defaultValue={getDefaultString()}
           style={{ height: '100%' }}
           variant="outlined"
-- 
GitLab