Untitled
unknown
plain_text
4 years ago
4.9 kB
12
Indexable
// ARQUIVO
// pages/trivia.jsx
import React from 'react';
import Header from '../components/Header';
class Trivia extends React.Component {
constructor() {
super();
this.state = {
respondido: false,
perguntas: [],
indice: 0,
timer: 30,
};
this.chamaApi = this.chamaApi.bind(this);
this.sortArray = this.sortArray.bind(this);
this.handleClick = this.handleClick.bind(this);
this.computeAnswer = this.computeAnswer.bind(this);
}
componentDidMount() {
const { timer } = this.state;
const ONE_SECOND = 1000;
const SECONDS_TO_MILLISECONDS = 1000;
this.chamaApi();
this.timerInterval = setInterval(() => {
this.setState((prevState) => ({ timer: prevState.timer - 1 }));
}, ONE_SECOND);
setTimeout(() => (this.computeAnswer()), timer * SECONDS_TO_MILLISECONDS);
}
computeAnswer() { // Function called after an answer is clicked OR, a timeout happens
this.setState({ respondido: true });
clearInterval(this.timerInterval);
}
sortArray() {
const { perguntas, indice } = this.state;
const {
correct_answer: correct,
incorrect_answers: incorrect } = perguntas[indice];
return [...incorrect, correct].sort();
}
async chamaApi() { // Makes the API call to fetch the current questions
const TOKEN = JSON.parse(localStorage.token);
const URL = `https://opentdb.com/api.php?amount=5&encode=url3986&token=${TOKEN}`;
const response = await fetch(URL);
const result = await response.json();
this.setState({
perguntas: result.results,
});
}
handleClick() {
this.computeAnswer();
}
render() {
const { perguntas, indice, respondido, timer } = this.state;
return (
<div>
<Header />
<p>
Time Left!!:
</p>
<span>{ timer }</span>
{perguntas.length > 0
&& (
<>
<p data-testid="question-category">
{ decodeURIComponent(perguntas[indice].category) }
</p>
<p data-testid="question-text">
{ decodeURIComponent(perguntas[indice].question) }
</p>
{this.sortArray().map((atual, i) => (
<button
onClick={ this.handleClick }
type="submit"
key={ i }
data-testid={
atual === perguntas[indice].correct_answer
? 'correct-answer'
: `wrong-answer-${i}`
}
className={ respondido && (atual === perguntas[indice].correct_answer
? 'correct'
: 'incorrect') }
>
{decodeURIComponent(atual)}
</button>
))}
</>)}
</div>
);
}
}
export default Trivia;
_______________________________________________________________
// ARQUIVO
// components/Header.jsx
import React from 'react';
import md5 from 'crypto-js/md5';
class Header extends React.Component {
constructor() {
super();
this.state = {
player: {},
hashInfo: '',
};
}
componentDidMount() {
this.playerInfoStart();
}
playerInfoStart() {
const player = JSON.parse(localStorage.getItem('state'));
const hashInfo = md5(player.gravatarEmail).toString();
this.setState({
player,
hashInfo,
});
}
render() {
const { player, hashInfo } = this.state;
return (
<header>
<img
alt="Profile"
data-testid="header-profile-picture"
src={ `https://www.gravatar.com/avatar/${hashInfo}` }
/>
<span data-testid="header-player-name">{ player.name }</span>
<span data-testid="header-score">{ player.score }</span>
</header>
);
}
}
export default (Header);
__________________________________________________________________
// ARQUIVO
// App.css
.App {
text-align: center;
}
.App-logo {
height: 40vmin;
pointer-events: none;
}
.red-border {
border: 1px solid red;
}
.green-border {
border: 1px solid green;
}
@media ( prefers-reduced-motion : no-preference ) {
.App-logo {
animation: shake infinite 0.82s cubic-bezier(0.36, 0.07, 0.19, 0.97) both;
}
}
.App-header {
align-items: center;
background-color: #282c34;
color: white;
display: flex;
flex-direction: column;
font-size: calc(10px + 2vmin);
justify-content: center;
min-height: 100vh;
}
.App-link {
color: #61dafb;
}
@keyframes shake {
10%, 90% {
transform: translate3d(-1px, 0, 0);
}
20%, 80% {
transform: translate3d(2px, 0, 0);
}
30%, 50%, 70% {
transform: translate3d(-4px, 0, 0);
}
40%, 60% {
transform: translate3d(4px, 0, 0);
}
}
.correct {
border: 3px solid rgb(6, 240, 15);
}
.incorrect {
border: 3px solid rgb(255, 0, 0);
}Editor is loading...