| @@ -0,0 +1,25 @@ | ||
| .counter-info { | ||
| border: 1px solid black; | ||
| background-color: white; | ||
| color: black; | ||
| padding: 7px 10px; | ||
| margin-bottom: 26px; | ||
| color: #59605f; | ||
| text-align: center; | ||
| } | ||
|
|
||
| @media (min-width:601px) { | ||
| .counter-info { | ||
| position: fixed; | ||
| margin-top: 535px; | ||
| width: 100% | ||
| } | ||
| } | ||
|
|
||
| @media (max-width:600px) { | ||
| .counter-info { | ||
| position: fixed; | ||
| margin-top: 539px; | ||
| width: 100%; | ||
| } | ||
| } |
| @@ -0,0 +1,21 @@ | ||
| import React, { Component } from 'react'; | ||
| import './Counter.css'; | ||
| import PropTypes from 'prop-types'; | ||
|
|
||
| class Counter extends Component { | ||
| static propTypes = { | ||
| totalscore: PropTypes.number.isRequired | ||
| } | ||
| render() { | ||
| return ( | ||
| <div className="counter-info"> | ||
| <p>Your score is: {this.props.totalscore}</p> | ||
| </div> | ||
| ) | ||
| } | ||
| } | ||
|
|
||
|
|
||
|
|
||
|
|
||
| export default Counter; |
| @@ -0,0 +1,87 @@ | ||
| .App .quiz-title { | ||
| text-align: center; | ||
| padding-bottom: 40px; | ||
| position: relative; | ||
| } | ||
|
|
||
| .App .quiz-title .quiz-name { | ||
| font-size: 48px; | ||
| margin-top: 5px; | ||
| color: #59605f; | ||
| width: 80%; | ||
| margin-left: auto; | ||
| margin-right: auto; | ||
| text-align: center; | ||
| display: inline-block; | ||
| } | ||
|
|
||
| .App .sum { | ||
| margin: 25px 5px 25px 5px; | ||
| color: #59605f; | ||
| } | ||
|
|
||
| .App .Quiz-pic { | ||
| border-radius: 10px; | ||
| } | ||
|
|
||
| .App .begin-quiz { | ||
| padding: 10px 15px; | ||
| border-radius: 10px; | ||
| font-size: 16px; | ||
| background-color: #6EC8B2; | ||
| margin-bottom: 30px; | ||
| } | ||
|
|
||
|
|
||
| @media (min-width:801px) { | ||
| .App .quiz-title { | ||
| max-width: 60%; | ||
| min-width: 800px; | ||
| margin-left: auto; | ||
| margin-right: auto; | ||
| margin-top: 30px; | ||
| margin-bottom: 10px; | ||
| } | ||
| .App .quiz-title .quiz-name { | ||
| margin-right: 20px; | ||
| margin-left: 20px; | ||
| } | ||
| .App .quiz-title .sum { | ||
| margin-right: 30px; | ||
| margin-left: 30px; | ||
| } | ||
| .App .Quiz-pic { | ||
| max-height: 260px; | ||
| margin-left: 0 auto; | ||
| text-align: center; | ||
| margin-right: 0 auto; | ||
| } | ||
| } | ||
|
|
||
| @media (max-width:800px) { | ||
| .quiz-title { | ||
| margin-right: 30px; | ||
| margin-left: 30px; | ||
| max-width: 800px; | ||
| min-width: 320px; | ||
| text-align: center; | ||
| padding-bottom: 35px; | ||
| } | ||
| .App .quiz-title .quiz-name { | ||
| margin-right: 20px; | ||
| margin-left: 20px; | ||
| margin-bottom: 20px; | ||
| font-size: 42px; | ||
| } | ||
| .App .quiz-title .sum { | ||
| line-height: 22px; | ||
| margin-right: 50px; | ||
| margin-left: 50px; | ||
| margin-bottom: 20px; | ||
| } | ||
| .Quiz-pic { | ||
| text-align: center; | ||
| max-height: 200px; | ||
| } | ||
| } | ||
|
|
| @@ -0,0 +1,30 @@ | ||
| import React, { Component } from 'react'; | ||
| import './Introquiz.css'; | ||
| import PropTypes from 'prop-types'; | ||
| import scrollToElement from 'scroll-to-element'; | ||
|
|
||
| class Introquiz extends Component { | ||
| static propTypes = { | ||
| quiztitle: PropTypes.string.isRequired, | ||
| intropic: PropTypes.string, | ||
| quizsummary: PropTypes.string, | ||
| onClick: PropTypes.func.isRequired | ||
| } | ||
| render() { | ||
| return ( | ||
| <div className="quiz-title"> | ||
| <h1 className ="quiz-name">{this.props.quiztitle}</h1> | ||
| <img src={this.props.intropic} className="Quiz-pic" /> | ||
| <div className="sum"> | ||
| {this.props.quizsummary} | ||
| </div> | ||
| <button className="begin-quiz" onClick={this.props.onClick}>Begin Quiz</button> | ||
| </div> | ||
| ) | ||
| } | ||
| } | ||
|
|
||
| export default Introquiz; | ||
|
|
||
|
|
||
|
|
| @@ -0,0 +1,86 @@ | ||
| .question { | ||
| border: 4px #6ec8b2 solid; | ||
| padding: 8px 5px; | ||
| margin: 25px 250px; | ||
| background-color: white; | ||
| border-radius: 25px; | ||
| text-align: center; | ||
| display: block; | ||
| color: #59605f; | ||
| } | ||
|
|
||
| .question h3 { | ||
| font-size: 36px; | ||
| margin-top: 2px; | ||
| margin-bottom: 15px; | ||
| } | ||
|
|
||
| .question img { | ||
| max-width: 60%; | ||
| max-height: 300px; | ||
| text-align: center; | ||
| display: inline-block; | ||
| margin-bottom: 10px; | ||
| border-radius: 10px; | ||
| } | ||
|
|
||
| .question .possible-choices { | ||
| margin-top: 5px; | ||
| margin-bottom: 5px; | ||
| text-align: center; | ||
| display: block; | ||
| } | ||
|
|
||
| .question .possible-choices .choice { | ||
| margin-bottom: 5px; | ||
| margin-top: 5px; | ||
| background-color: rgb(229, 229, 229); | ||
| padding: 10px; | ||
| width: 80%; | ||
| text-align: left; | ||
| border-radius: 20px; | ||
| } | ||
|
|
||
| .question .possible-choices .choice:hover { | ||
| box-shadow: 2px 2px 2px 1px rgba(0, 0, 0, 0.2); | ||
| } | ||
|
|
||
| .question .possible-choices .choice.rightAnswer { | ||
| background-color: #bee2d5; | ||
| } | ||
|
|
||
| .question .possible-choices .choice.wrongAnswer { | ||
| background-color: #ddbaba; | ||
| } | ||
|
|
||
| .question .possible-choices .choice.answered { | ||
| box-shadow: none; | ||
| } | ||
|
|
||
| @media (min-width:801px) { | ||
| .question { | ||
| max-width: 60%; | ||
| min-width: 800px; | ||
| margin-left: auto; | ||
| margin-right: auto; | ||
| margin-top: 10px; | ||
| margin-bottom: 10px; | ||
| } | ||
| .question .img { | ||
| min-width: 40px; | ||
| } | ||
| } | ||
|
|
||
| @media (max-width:800px) { | ||
| .question { | ||
| margin: auto; | ||
| border-left: none; | ||
| border-right: none; | ||
| max-width: 800px; | ||
| border-radius: 1px; | ||
| min-width: 320px; | ||
| } | ||
| .question .img { | ||
| min-width: 40px; | ||
| } | ||
| } |
| @@ -0,0 +1,67 @@ | ||
| import React, { Component } from 'react'; | ||
| import './Question.css'; | ||
| import PropTypes from 'prop-types'; | ||
| import classNames from 'classnames'; | ||
|
|
||
| class Question extends Component { | ||
| static propTypes = { | ||
| text: PropTypes.string.isRequired, | ||
| picture: PropTypes.string, | ||
| answers: PropTypes.arrayOf(PropTypes.shape({ | ||
| option: PropTypes.string.isRequired, | ||
| correct: PropTypes.bool.isRequired | ||
| })), | ||
| onClick: PropTypes.func.isRequired, | ||
| questionNumber: PropTypes.number.isRequired, | ||
| userAnswer: PropTypes.shape({ | ||
| option: PropTypes.string.isRequired, | ||
| correct: PropTypes.string.isRequired | ||
| }) | ||
| } | ||
| getQuestionClassName() { | ||
| return classNames({ | ||
| question: true, | ||
| rightAnswer: this.props.userAnswer && (this.props.userAnswer.correct === true), | ||
| wrongAnswer: this.props.userAnswer && (this.props.userAnswer.correct === false), | ||
| answered: this.props.userAnswer | ||
| }); | ||
| } | ||
| getButtonClassName(answer) { | ||
| const classes = { choice: true }; | ||
| if (this.props.userAnswer && this.props.userAnswer.option === answer.option) { | ||
| if (this.props.userAnswer.correct) { | ||
| classes.rightAnswer = true; | ||
| } else { | ||
| classes.wrongAnswer = true; | ||
| } | ||
| } | ||
| if (!!this.props.userAnswer) { | ||
| classes.answered = true; | ||
| } else { | ||
| classes.answered = false; | ||
| } | ||
| return classNames(classes); | ||
| } | ||
| render() { | ||
| return ( | ||
| <div className={this.getQuestionClassName()} > | ||
| <h3>{this.props.text}</h3> | ||
| <img src={this.props.picture} alt="" /> | ||
| <div className="possible-choices"> | ||
| {this.props.answers.map((answer, index) => | ||
| <button | ||
| key={index} | ||
| className={this.getButtonClassName(answer)} | ||
| onClick={() => this.props.onClick(answer, this.props.questionNumber)} | ||
| disabled={!!this.props.userAnswer}> | ||
| {answer.option} | ||
| </button> | ||
| )} | ||
| </div> | ||
| </div> | ||
| ); | ||
| } | ||
| } | ||
|
|
||
|
|
||
| export default Question; |
| @@ -0,0 +1,7 @@ | ||
| .App { | ||
| background-color: #white; | ||
| } | ||
|
|
||
| .App .Introduction { | ||
| display: inline; | ||
| } |
| @@ -0,0 +1,81 @@ | ||
| import React, { Component } from 'react'; | ||
| import Introquiz from './Introquiz.js'; | ||
| import Counter from './Counter.js'; | ||
| import Question from './Question.js'; | ||
| import './Quiz.css'; | ||
| import Results from './Results.js'; | ||
|
|
||
| export default class Quiz extends Component { | ||
| constructor() { | ||
| super(); | ||
| this.handleAnswerSelected = this.handleAnswerSelected.bind(this) | ||
| this.handleQuizStart = this.handleQuizStart.bind(this) | ||
| } | ||
| componentWillMount() { | ||
| this.setState({ | ||
| correctAnswers: 0, | ||
| userAnswers: [], | ||
| showIntro: true | ||
| }) | ||
| } | ||
| handleQuizStart() { | ||
| this.setState({ showIntro: false }) | ||
| } | ||
| handleAnswerSelected(answer, questionNumber) { | ||
| const updatedUserAnswers = this.state.userAnswers.slice(); | ||
| updatedUserAnswers[questionNumber] = answer | ||
| this.setState({ | ||
| userAnswers: updatedUserAnswers | ||
| }); | ||
| } | ||
| getCorrectAnswerCount() { | ||
| return this.state.userAnswers | ||
| .filter(answer => answer.correct) | ||
| .length; | ||
| } | ||
| getResults() { | ||
| const totalQuestions = quizInfo.questions.length; | ||
| const totalAnswered = this.state.userAnswers.length; | ||
| if ( totalAnswered === totalQuestions ) { | ||
| const score = this.getCorrectAnswerCount() / totalQuestions; | ||
| const resultNumber = Math.round((quizInfo.results.length - 1) * score); | ||
| return <Results | ||
| headline={quizInfo.results[resultNumber].headline} | ||
| resultpic={quizInfo.results[resultNumber].resultpic} | ||
| summary={quizInfo.results[resultNumber].summary} /> | ||
| } | ||
| } | ||
| render() { | ||
| const isQuizIntro = this.state.showIntro; | ||
| return ( | ||
| <div className="App"> | ||
| {isQuizIntro ? ( | ||
| <div className="Introduction"> | ||
| <Introquiz | ||
| quiztitle={quizInfo.quizheadline.quiztitle} | ||
| intropic={quizInfo.quizheadline.intropic} | ||
| quizsummary={quizInfo.quizheadline.quizsummary} | ||
| onClick={this.handleQuizStart}/> | ||
| </div> | ||
| ) : ( | ||
| <div className="Quiz-Display"> | ||
| <Counter | ||
| totalscore={this.getCorrectAnswerCount()} | ||
| className="counterpos" /> | ||
| {quizInfo.questions.map((question, index) => | ||
| <Question | ||
| key={index} | ||
| questionNumber={index} | ||
| text={question.text} | ||
| picture={question.picture} | ||
| answers={question.answers} | ||
| onClick={this.handleAnswerSelected} | ||
| userAnswer={this.state.userAnswers[index]}/> | ||
| )} | ||
| </div> | ||
| )} | ||
| {this.getResults()} | ||
| </div> | ||
| ) | ||
| } | ||
| } |
| @@ -0,0 +1,63 @@ | ||
| .result-box { | ||
| border: 1px #6ec8b2 solid; | ||
| padding: 10px 10px; | ||
| margin: 30px 250px; | ||
| background-color: white; | ||
| border-radius: 50px; | ||
| text-align: center; | ||
| } | ||
|
|
||
| .result-box h1 { | ||
| font-size: 24px; | ||
| margin-bottom: -20px; | ||
| } | ||
|
|
||
| .result-box h2 { | ||
| font-size: 36px; | ||
| } | ||
|
|
||
| .result-box img { | ||
| width: 75%; | ||
| border-radius: 20px; | ||
| } | ||
|
|
||
| .result-box p { | ||
| padding: 20px 80px; | ||
| } | ||
|
|
||
| .result-box .share-this a { | ||
| display: block; | ||
| } | ||
|
|
||
| .result-box .share-this .fbpic { | ||
| display: inline-block; | ||
| width: 145px; | ||
| } | ||
|
|
||
| @media (min-width:801px) { | ||
| .result-box { | ||
| max-width: 60%; | ||
| min-width: 800px; | ||
| margin-left: auto; | ||
| margin-right: auto; | ||
| margin-top: 10px; | ||
| margin-bottom: 10px; | ||
| } | ||
| .result-box .img { | ||
| min-width: 40px; | ||
| } | ||
| } | ||
|
|
||
| @media (max-width:800px) { | ||
| .result-box { | ||
| margin: auto; | ||
| border-left: none; | ||
| border-right: none; | ||
| border-radius: 10px; | ||
| max-width: 800px; | ||
| min-width: 320px; | ||
| } | ||
| .result-box .img { | ||
| min-width: 40px; | ||
| } | ||
| } |
| @@ -0,0 +1,37 @@ | ||
| import React, { Component } from 'react'; | ||
| import PropTypes from 'prop-types'; | ||
| import './Results.css'; | ||
| import scrollToElement from 'scroll-to-element'; | ||
|
|
||
| class Results extends Component { | ||
| static propTypes = { | ||
| score: PropTypes.number.isRequired, | ||
| headline: PropTypes.string.isRequired, | ||
| resultpic: PropTypes.string.isRequired, | ||
| summary: PropTypes.string.isRequired, | ||
| } | ||
| componentDidMount() { | ||
| window.setTimeout(() => { | ||
| scrollToElement('.share-this', { | ||
| align: 'middle', | ||
| duration: 500 | ||
| }) | ||
| }, 500) | ||
| } | ||
| render() { | ||
| return ( | ||
| <div className="result-box" > | ||
| <h1>You scored: {this.props.score}</h1> | ||
| <h2>{this.props.headline}</h2> | ||
| <img src={this.props.resultpic} /> | ||
| <p>{this.props.summary}</p> | ||
| <div className= "share-this"> | ||
| <a href="www.google.com">Share your result with your friends!</a> | ||
| <img className="fbpic" src="https://www.butsch-meier.de/wp-content/uploads/facebook-footer.png" href="www.facebook.com" /> | ||
| </div> | ||
| </div> | ||
| ) | ||
| } | ||
| } | ||
|
|
||
| export default Results; |