6080-a3-BigBrain / frontend / src / FrontendPages / PlayGamePage.jsx
PlayGamePage.jsx
Raw
import React, { useEffect, useState } from 'react'
import PropTypes from 'prop-types'
import { Link as URLlink, useParams } from 'react-router-dom'
import {
  Typography, Link, Box, Button
} from '@mui/material'
import playerService from '../BackendRequests/playerRequest.jsx'
import PlayerResult from './PlayerQuizResult.jsx'
import ReactAudioPlayer from 'react-audio-player';
import gif1 from '../lobby1.gif'
import gif2 from '../lobby2.gif'
import gif3 from '../lobby3.gif'
import waitingMusic from '../waitingMusic.mp3'

const style = {
  padding: 5,
  position: 'absolute',
  top: '30%',
  left: '50%',
  transform: 'translate(-50%, -50%)',
  width: 400,
  backgroundColor: 'white',
  border: '1px solid black',
  boxShadow: 24,
}

const joinBtnStyle = {
  mt: 7,
  mb: 1,
  backgroundColor: '#a2627c',
  '&:hover': {
    background: '#a2627c',
  },
}

const PlayGamePage = () => {
  const playerId = useParams().playerId;
  const [status, setStatus] = useState('false');
  const [question, setQuestion] = useState('');
  const [answers, setAnswers] = useState([]);
  const [questionType, setQuestionType] = useState('');
  const [timeLimit, setTimeLimit] = useState(0);
  const [qId, setQId] = useState(0);
  // collection of corrected answer Ids
  const [qResult, setQResult] = useState([]);
  const [attachmentType, setAttachmentType] = useState('');
  const [imgSource, setImgSource] = useState('');
  const [vidLink, setVidLink] = useState('')
  let answerIds = []

  const getQuestion = async () => {
    try {
      const res = await playerService.getQuestionDetails(playerId)
      setQuestion(res.question.content)
      // setAnswers(res.question.answers)
      setQuestionType(res.question.questionType)
      setQId(res.question.qId)
      console.log(res.question)
    } catch (err) {
      // setQId(0);
      console.log(err)
    }
  }

  const getAttachment = async () => {
    try {
      const res = await playerService.getQuestionDetails(playerId)
      setAttachmentType(res.question.attachmentType)
      setImgSource(res.question.picture)
      setVidLink(res.question.video)
    } catch (err) {
      console.log(err)
    }
  }

  useEffect(() => {
    getAttachment();
  }, [qId])

  const getAnswerOptions = async () => {
    try {
      const res = await playerService.getQuestionDetails(playerId)
      setAnswers(res.question.answers)
    } catch (err) {
      console.log(err)
    }
  }

  useEffect(() => {
    getAnswerOptions();
  }, [qId])

  const getTimeLimit = async () => {
    try {
      const res = await playerService.getQuestionDetails(playerId)
      setTimeLimit(res.question.timeLimit)
    } catch (err) {
      console.log(err)
    }
  }

  useEffect(() => {
    getTimeLimit();
  }, [qId])

  const sessionStatus = async () => {
    const res = await playerService.getSessionStatus(playerId)
    setStatus(res.started)
    console.log(status);
  }

  useEffect(() => {
    const refresh = setInterval(() => {
      getQuestion();
      sessionStatus();
    }, 1000);
    return () => clearInterval(refresh);
  }, [])

  const Countdown = ({ seconds }) => {
    const [timeLeft, setTimeLeft] = useState(seconds);
    useEffect(() => {
      if (!timeLeft) {
        setTimeLimit(0);
        return;
      }
      const intervalId = setInterval(() => {
        setTimeLeft(timeLeft - 1);
      }, 1000);
      return () => clearInterval(intervalId);
    }, [timeLeft]);
    return (
      <Typography>{timeLeft}</Typography>
    );
  }

  Countdown.propTypes = {
    seconds: PropTypes.number
  }

  const sendAnswer = async (playerId, ansList) => {
    try {
      await playerService.submitAnswer(playerId, ansList)
    } catch (err) {
      console.log(err)
    }
  }

  // TODO: sort to compare with result?
  const submitAnswerMultiple = (e, answerNum) => {
    if (e.target.checked) {
      answerIds.push(answerNum)
      console.log(answerIds)
    } else {
      answerIds = answerIds.filter(a => a !== answerNum)
      console.log(answerIds)
    }
    sendAnswer(playerId, answerIds)
  }

  // const [ansIds, setAnsIds]= useState([]);
  const submitAnswerSingle = (e, answerNum) => {
    if (e.target.checked) {
      answerIds = []
      answerIds.push(answerNum)
      console.log(answerIds)
    }
    sendAnswer(playerId, answerIds)
  }

  const getQResult = async () => {
    try {
      const res = await playerService.getQuestionResult(playerId)
      setQResult(res.answerIds);
      console.log(qResult)
    } catch (err) {
      console.log(err)
    }
  }

  useEffect(() => {
    getQResult();
  }, [timeLimit])

  const [count, setCount] = useState(0);

  useEffect(() => {
    setCount(count => count + 1)
  }, [qId])

  const DisplayScreen = () => {
    sessionStatus(playerId);
    if (status && timeLimit !== 0) {
      return (
        <>
        <Box backgroundColor = '#FAD02C' minHeight = '100vh' height = 'auto'>
          <Box sx={style}>
            <Typography>Question: {question}</Typography>
            {attachmentType === 'Picture'
              ? <div>
                <img src={imgSource} width="120" height="120"></img>
              </div>
              : attachmentType === 'Video'
                ? <div>
                  <Link>{vidLink}</Link>
                </div>
                : <></>}
            <Typography display='inline'>Time Left: </Typography>
            <Countdown seconds={parseInt(timeLimit, 10)} />
            <Typography>Type: {questionType}</Typography>
            <Typography>Answers:</Typography>
            {questionType === 'Multiple Choice'
              ? (answers.map((a) => (
                <div key={a.answerNum}>
                  <input
                  type='checkbox'
                  label={a.answerText}
                  onChange={e => submitAnswerMultiple(e, a.answerNum)}
                  />
                  <Typography display='inline'>
                    {a.answerText}
                  </Typography>
                </div>
                )))
              : (answers.map((a) => (
                <div key={a.answerNum}>
                  <input
                  type='radio'
                  name='single choice'
                  label={a.answerText}
                  onChange={e => submitAnswerSingle(e, a.answerNum)}
                  />
                  <Typography display='inline'>
                    {a.answerText}
                  </Typography>
                </div>
                )))
            }
            </Box>
          </Box>
        </>
      )
    } else {
      if (!status) {
        if (count === 1) {
          return (
            <>
            <Box backgroundColor = '#FAD02C' minHeight = '100vh' height = 'auto'>
              <Box sx={style}>
                <Typography>Waiting for admin to start...</Typography>
              </Box>
              <Box style={{ display: 'grid-row', paddingTop: '15%', paddingLeft: '17%', paddingRight: '100px', gap: '10px' }}>
                <img src={gif1} width="350" height="250"></img>
                <img src={gif2} width="350" height="250"></img>
                <img src={gif3} width="350" height="250"></img>
              </Box>
            </Box>
            <ReactAudioPlayer
              src={waitingMusic}
              autoPlay
              controls
              display='none'
            />
            </>
          )
        } else {
          return (
            <>
            <Box backgroundColor = '#FAD02C' minHeight = '100vh' height = 'auto'>
              <Box sx={style}>
                <Typography>End of quiz...</Typography>
                <PlayerResult playerId={playerId} />
                <Button
                  fullWidth
                  variant="contained"
                  sx={joinBtnStyle}
                  component={URLlink} to="/join">
                  Join another quiz
                </Button>
              </Box>
            </Box>
            </>
          )
        }
      } else if (status && timeLimit === 0) {
        const correctList = [...qResult]
        const displayList = correctList.map((a, index) =>
          <div key={index}>{answers.find(ans => ans.answerNum === a).answerText}</div>
        );
        return (
          <>
          <Box backgroundColor = '#FAD02C' minHeight = '100vh' height = 'auto'>
            <Box sx={style}>
              <Typography>Did you answer correctly?</Typography>
              <Typography>Correct Answer(s): </Typography>
              <div>{displayList}</div>
            </Box>
          </Box>
          </>
        )
      }
    }
  }

  return (
    <>
      <Box backgroundColor = '#FAD02C'>
        <Typography>Player: {playerId}</Typography>
        <DisplayScreen />
      </Box>
    </>

  )
}

export default PlayGamePage