Untitled
unknown
plain_text
4 years ago
4.9 kB
8
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...