Proyectos de Subversion LeadersLinked - SPA

Rev

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

Rev Autor Línea Nro. Línea
3520 stevensc 1
import React, { useState } from 'react';
3481 stevensc 2
 
3563 stevensc 3
import { startQuiz } from '@microlearning/services';
3520 stevensc 4
import { addNotification } from '@app/redux/notification/notification.actions';
3481 stevensc 5
 
3520 stevensc 6
import Widget from '@app/components/UI/Widget';
7
import QuizSimpleQuestion from './quiz-simple-question';
8
import QuizMultipleQuestion from './quiz-multiple-question';
9
import SlideProgress from './slide-progress';
10
import SlideSuccessFeedback from './slide-success-feedback';
11
import SlideQuizStart from './slide-quiz-start';
12
import QuizFailureFeedback from './quiz-failure-feedback';
3481 stevensc 13
 
3520 stevensc 14
export function SlideQuiz({ quiz, slide, onSync, startUrl, completed }) {
15
  const [currentQuestion, setCurrentQuestion] = useState(0);
16
  const [showQuestions, setShowQuestions] = useState(false);
17
  const [completedQuiz, setCompletedQuiz] = useState(false);
18
  const [failureQuiz, setFailureQuiz] = useState(false);
19
  const [totalPoints, setTotalPoints] = useState(0);
20
  const [answer, setAnswers] = useState([]);
3481 stevensc 21
 
3520 stevensc 22
  const { name, questions, minimum_points_required } = quiz;
3481 stevensc 23
 
24
  const handleStart = async () => {
25
    try {
3520 stevensc 26
      const start = await startQuiz(startUrl);
27
      if (start) setShowQuestions(true);
3481 stevensc 28
    } catch (error) {
3520 stevensc 29
      addNotification({ style: 'danger', msg: error.message });
3481 stevensc 30
    }
3520 stevensc 31
  };
3481 stevensc 32
 
33
  const onError = () => {
3520 stevensc 34
    setFailureQuiz(true);
35
  };
3481 stevensc 36
 
37
  const restartQuiz = () => {
3520 stevensc 38
    setCurrentQuestion(0);
39
    setTotalPoints(0);
40
    setFailureQuiz(false);
41
    setCompletedQuiz(false);
42
    setShowQuestions(false);
43
  };
3481 stevensc 44
 
45
  const onSimpleConfirm = (question, answerId) => {
3520 stevensc 46
    const answer = question.answers.find((q) => q.uuid === answerId);
3481 stevensc 47
    const newAnswer = {
48
      question: question.uuid,
49
      answers: [answer]
3520 stevensc 50
    };
51
    setAnswers((prevAnswers) => [...prevAnswers, newAnswer]);
3481 stevensc 52
 
3520 stevensc 53
    const isCorrect = answer.correct === 'y';
54
    isCorrect && setTotalPoints(totalPoints + parseInt(question.points));
3481 stevensc 55
 
56
    if (currentQuestion !== questions.length - 1) {
3520 stevensc 57
      setCurrentQuestion(currentQuestion + 1);
58
      return;
3481 stevensc 59
    }
60
 
61
    if (totalPoints >= parseInt(minimum_points_required)) {
3520 stevensc 62
      setCompletedQuiz(true);
3481 stevensc 63
    } else {
3520 stevensc 64
      onError();
3481 stevensc 65
    }
3520 stevensc 66
  };
3481 stevensc 67
 
68
  const onMultipleConfirm = (question, answersIds) => {
3520 stevensc 69
    const answers = question.answers.filter((answer) => answersIds.includes(answer.uuid));
3481 stevensc 70
    const newAnswer = {
71
      question: question.uuid,
72
      answers
3520 stevensc 73
    };
74
    setAnswers((prevAnswers) => [...prevAnswers, newAnswer]);
3481 stevensc 75
 
3520 stevensc 76
    const points = answers.reduce((acc, answer) => acc + parseInt(answer.points), 0);
3481 stevensc 77
 
3520 stevensc 78
    setTotalPoints(totalPoints + points);
3481 stevensc 79
 
80
    if (currentQuestion !== questions.length - 1) {
3520 stevensc 81
      setCurrentQuestion(currentQuestion + 1);
82
      return;
3481 stevensc 83
    }
84
 
85
    if (totalPoints >= parseInt(minimum_points_required)) {
3520 stevensc 86
      setCompletedQuiz(true);
3481 stevensc 87
    } else {
3520 stevensc 88
      onError();
3481 stevensc 89
    }
3520 stevensc 90
  };
3481 stevensc 91
 
92
  if (completedQuiz) {
3520 stevensc 93
    return <SlideSuccessFeedback onConfirm={onSync} />;
3481 stevensc 94
  }
95
 
96
  if (failureQuiz) {
3520 stevensc 97
    return <QuizFailureFeedback onConfirm={restartQuiz} />;
3481 stevensc 98
  }
99
 
100
  if (!showQuestions) {
3520 stevensc 101
    return <SlideQuizStart onStart={handleStart} completed={completed} slide={slide} />;
3481 stevensc 102
  }
103
 
104
  return (
105
    <Widget>
106
      <SlideProgress
107
        points={totalPoints}
108
        time={quiz.max_time}
109
        currentQuestion={currentQuestion + 1}
110
        totalQuestions={questions.length}
111
        onTimeEnd={onError}
112
      />
113
 
114
      <Widget.Header title={`Cuestionario sobre: ${name}`} />
115
 
116
      <Widget.Body>
117
        {questions.map((question, index) => {
3520 stevensc 118
          const isLastQuestion = index === questions.length - 1;
119
          const buttonLabel = isLastQuestion ? 'Finalizar' : 'Siguiente';
3481 stevensc 120
 
121
          if (question.type === 's') {
122
            return (
123
              <QuizSimpleQuestion
124
                key={question.uuid}
125
                question={question}
126
                onConfirm={(answer) => onSimpleConfirm(question, answer)}
127
                buttonLabel={buttonLabel}
128
                isCurrent={currentQuestion === index}
129
              />
3520 stevensc 130
            );
3481 stevensc 131
          }
132
 
133
          if (question.type === 'm') {
134
            return (
135
              <QuizMultipleQuestion
136
                key={question.uuid}
137
                question={question}
138
                onConfirm={(answers) => onMultipleConfirm(question, answers)}
139
                buttonLabel={buttonLabel}
140
                isCurrent={currentQuestion === index}
141
              />
3520 stevensc 142
            );
3481 stevensc 143
          }
144
 
3520 stevensc 145
          return null;
3481 stevensc 146
        })}
147
      </Widget.Body>
148
    </Widget>
3520 stevensc 149
  );
3481 stevensc 150
}