Proyectos de Subversion LeadersLinked - SPA

Rev

Rev 3520 | Ir a la última revisión | Autoría | Comparar con el anterior | Ultima modificación | Ver Log |

import React, { useState } from 'react'
import { connect } from 'react-redux'

import { startQuiz } from '@app/services/micro-learning'
import { addNotification } from '@app/redux/notification/notification.actions'

import Widget from '@app/components/UI/Widget'
import QuizSimpleQuestion from './quiz-simple-question'
import QuizMultipleQuestion from './quiz-multiple-question'
import SlideProgress from './slide-progress'
import SlideSuccessFeedback from './slide-success-feedback'
import SlideQuizStart from './slide-quiz-start'
import QuizFailureFeedback from './quiz-failure-feedback'

function SlideQuiz({
  quiz,
  slide,
  onSync,
  startUrl,
  completed,
  addNotification
}) {
  const [currentQuestion, setCurrentQuestion] = useState(0)
  const [showQuestions, setShowQuestions] = useState(false)
  const [completedQuiz, setCompletedQuiz] = useState(false)
  const [failureQuiz, setFailureQuiz] = useState(false)
  const [totalPoints, setTotalPoints] = useState(0)
  const [answer, setAnswers] = useState([])

  const { name, questions, minimum_points_required } = quiz

  const handleStart = async () => {
    try {
      const start = await startQuiz(startUrl)
      if (start) setShowQuestions(true)
    } catch (error) {
      addNotification({ style: 'danger', msg: error.message })
    }
  }

  const onError = () => {
    setFailureQuiz(true)
  }

  const restartQuiz = () => {
    setCurrentQuestion(0)
    setTotalPoints(0)
    setFailureQuiz(false)
    setCompletedQuiz(false)
    setShowQuestions(false)
  }

  const onSimpleConfirm = (question, answerId) => {
    const answer = question.answers.find((q) => q.uuid === answerId)
    const newAnswer = {
      question: question.uuid,
      answers: [answer]
    }
    setAnswers((prevAnswers) => [...prevAnswers, newAnswer])

    const isCorrect = answer.correct === 'y'
    isCorrect && setTotalPoints(totalPoints + parseInt(question.points))

    if (currentQuestion !== questions.length - 1) {
      setCurrentQuestion(currentQuestion + 1)
      return
    }

    if (totalPoints >= parseInt(minimum_points_required)) {
      setCompletedQuiz(true)
    } else {
      onError()
    }
  }

  const onMultipleConfirm = (question, answersIds) => {
    const answers = question.answers.filter((answer) =>
      answersIds.includes(answer.uuid)
    )
    const newAnswer = {
      question: question.uuid,
      answers
    }
    setAnswers((prevAnswers) => [...prevAnswers, newAnswer])

    const points = answers.reduce(
      (acc, answer) => acc + parseInt(answer.points),
      0
    )

    setTotalPoints(totalPoints + points)

    if (currentQuestion !== questions.length - 1) {
      setCurrentQuestion(currentQuestion + 1)
      return
    }

    if (totalPoints >= parseInt(minimum_points_required)) {
      setCompletedQuiz(true)
    } else {
      onError()
    }
  }

  if (completedQuiz) {
    return <SlideSuccessFeedback onConfirm={onSync} />
  }

  if (failureQuiz) {
    return <QuizFailureFeedback onConfirm={restartQuiz} />
  }

  if (!showQuestions) {
    return (
      <SlideQuizStart
        onStart={handleStart}
        completed={completed}
        slide={slide}
      />
    )
  }

  return (
    <Widget>
      <SlideProgress
        points={totalPoints}
        time={quiz.max_time}
        currentQuestion={currentQuestion + 1}
        totalQuestions={questions.length}
        onTimeEnd={onError}
      />

      <Widget.Header title={`Cuestionario sobre: ${name}`} />

      <Widget.Body>
        {questions.map((question, index) => {
          const isLastQuestion = index === questions.length - 1
          const buttonLabel = isLastQuestion ? 'Finalizar' : 'Siguiente'

          if (question.type === 's') {
            return (
              <QuizSimpleQuestion
                key={question.uuid}
                question={question}
                onConfirm={(answer) => onSimpleConfirm(question, answer)}
                buttonLabel={buttonLabel}
                isCurrent={currentQuestion === index}
              />
            )
          }

          if (question.type === 'm') {
            return (
              <QuizMultipleQuestion
                key={question.uuid}
                question={question}
                onConfirm={(answers) => onMultipleConfirm(question, answers)}
                buttonLabel={buttonLabel}
                isCurrent={currentQuestion === index}
              />
            )
          }

          return null
        })}
      </Widget.Body>
    </Widget>
  )
}

const mapDispatchToProps = {
  addNotification: (notification) => addNotification(notification)
}

export default connect(null, mapDispatchToProps)(SlideQuiz)