Frames

Untitled

0
1import React, { Component } from 'react';
2
3import './App.css';
4
5import ErrorBoundary from './ErrorBoundary';
6import Introduction from './Introduction';
7import Progress from './Progress';
8import Quiz from './Quiz';
9import Reward from './Reward';
10
11class App extends Component {
12 constructor(props) {
13 super(props);
14
15 this.state = {
16 answers: [],
17 currentQuestion: 0,
18 startQuiz: false
19 };
20 }
21
22 componentDidMount() {
23 document.body.addEventListener('keyup', this.handleArrows);
24 }
25
26 componentWillUnmount() {
27 document.body.removeEventListener('keyup', this.handleArrows);
28 }
29
30 handleArrows = event => {
31 const { startQuiz } = this.state;
32 const key = event.key;
33
34 if (startQuiz) {
35 if (key === 'ArrowRight') {
36 this.handleProgress('next');
37 } else if (key === 'ArrowLeft') {
38 this.handleProgress('back');
39 }
40 }
41 };
42
43 handleAnswer = answer => {
44 const { answers, currentQuestion } = this.state;
45 const newAnswers = [...answers];
46
47 newAnswers[currentQuestion] = answer.target.value;
48
49 this.setState({
50 answers: newAnswers
51 });
52 };
53
54 handleProgress = progress => {
55 const { questions } = this.props;
56 const progressTarget = progress.currentTarget || {};
57 const progressValue = progressTarget.value || progress;
58
59 this.setState(
60 prevState => {
61 const { currentQuestion } = prevState;
62
63 let nextQuestion;
64 if (progressValue === 'next') {
65 nextQuestion = currentQuestion + 1;
66 } else if (progressValue === 'back') {
67 nextQuestion = currentQuestion - 1;
68 } else {
69 nextQuestion = parseInt(progressValue, 10);
70 }
71
72 if (nextQuestion >= questions.length) {
73 nextQuestion = questions.length - 1;
74 } else if (nextQuestion < 0) {
75 nextQuestion = 0;
76 }
77
78 return {
79 currentQuestion: nextQuestion
80 };
81 },
82 () => window.scrollTo(0, 0)
83 );
84 };
85
86 startQuiz = () => {
87 this.setState({
88 startQuiz: true
89 });
90 };
91
92 render() {
93 const { preambles, questions, rewards } = this.props;
94 const { answers, currentQuestion, startQuiz } = this.state;
95
96 const activeAnswer = answers[currentQuestion];
97 const activeQuestion = questions[currentQuestion] || {};
98 const activePreamble = preambles[activeQuestion.preamble];
99 const activeReward = rewards[activeQuestion.correctAnswer];
100
101 return (
102 <main className="app">
103 {startQuiz ? (
104 <>
105 <ErrorBoundary>
106 <Progress
107 current={currentQuestion}
108 onChange={this.handleProgress}
109 showSteps={true}
110 totalSteps={questions.length}
111 />
112 </ErrorBoundary>
113
114 {activePreamble && (
115 <div
116 className="app__preamble"
117 children={activePreamble}
118 />
119 )}
120
121 <ErrorBoundary>
122 <Quiz
123 question={activeQuestion.question}
124 answers={activeQuestion.answers}
125 correctAnswer={activeQuestion.correctAnswer}
126 selectedAnswer={activeAnswer}
127 onAnswer={this.handleAnswer}
128 />
129 </ErrorBoundary>
130
131 <ErrorBoundary>
132 <Reward
133 image={activeReward.image}
134 show={!!activeAnswer}
135 video={activeReward.video}
136 >
137 {activeReward.content}
138 </Reward>
139
140 {!!activeAnswer &&
141 currentQuestion < questions.length - 1 && (
142 <button
143 className="btn btn--primary"
144 onClick={this.handleProgress}
145 value="next"
146 >
147 Next Question
148 </button>
149 )}
150 </ErrorBoundary>
151 </>
152 ) : (
153 <ErrorBoundary>
154 <Introduction onStart={this.startQuiz} />
155 </ErrorBoundary>
156 )}
157 </main>
158 );
159 }
160}
161
162export default App;
163