From 685f51be89e6ad8c957a67a6bee8f110b8c3b550 Mon Sep 17 00:00:00 2001 From: David Gridley Date: Thu, 1 Nov 2018 17:36:46 +0000 Subject: [PATCH 01/20] added question component and container --- README.md | 2 ++ src/components/Question.js | 26 ++++++++++++++++++++++++++ src/containers/QuestionContainer.js | 21 +++++++++++++++++++++ src/index.js | 12 ++++++++---- 4 files changed, 57 insertions(+), 4 deletions(-) create mode 100644 src/components/Question.js create mode 100644 src/containers/QuestionContainer.js diff --git a/README.md b/README.md index 60b569e..30c7c67 100644 --- a/README.md +++ b/README.md @@ -88,6 +88,8 @@ If you are using planning to use Redux, use the steps below to help you get star - In `QuestionContainer` implement a `mapDispatchToProps` method which we will use to receive the `fetchQuestion` call from the `QuestionComponent`. Add a console.log inside the method which implements `fetchQuestion` in `mapDispatchToProps` saying `Step 2: getting action creator` +------------------------------------------------------------------------------------- + - Create an asynchronous action creator in `actions/index.js` called `fetchQuestionFromAPI`. It should return a function which will receive `dispatch`. Inside the function, implement a `fetch` to the API to receive the question. Add a console.log just inside the action creator saying `Step 3: calling fetch`. Add another console.log inside the second `then` of the `fetch` and console.log the returned data. - Import the `fetchQuestionFromAPI` action creator from previous step into `QuestionContainer` call it using `dispatch` from `mapDispatchToProps`. diff --git a/src/components/Question.js b/src/components/Question.js new file mode 100644 index 0000000..dd9c28a --- /dev/null +++ b/src/components/Question.js @@ -0,0 +1,26 @@ +import React from "react"; + +class Question extends React.Component { + constructor() { + super(); + } + + componentDidMount() { + console.log("Step 1: calling fetchQuestion"); + this.props.fetchQuestion(); + } + + render() { + return ( +
+

QUESTION:

+ + + + +
+ ); + } +} + +export default Question; diff --git a/src/containers/QuestionContainer.js b/src/containers/QuestionContainer.js new file mode 100644 index 0000000..841bb03 --- /dev/null +++ b/src/containers/QuestionContainer.js @@ -0,0 +1,21 @@ +import { connect } from 'react-redux'; +import Question from '../components/Question'; +import {} from '../actions'; + +const mapStateToProps = state => { + return { + question: state.question + } +} + +const mapDispatchToProps = dispatch => { + console.log("Step 2: getting action creator") + return { + fetchQuestion: () => fetchQuestion() + } +} + +export default connect( + mapStateToProps, + mapDispatchToProps +)(Question) \ No newline at end of file diff --git a/src/index.js b/src/index.js index 846662e..8213dfc 100644 --- a/src/index.js +++ b/src/index.js @@ -3,13 +3,17 @@ import ReactDOM from 'react-dom'; import App from './components/App'; import thunkMiddleware from 'redux-thunk'; -import { createStore, applyMiddleware } from 'redux'; +import { createStore, applyMiddleware, compose } from 'redux'; import { Provider } from 'react-redux'; import rootReducer from './reducers'; -const store = createStore(rootReducer, applyMiddleware( - thunkMiddleware -)); + +const enhansers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose; + + +const store = createStore(rootReducer, enhansers(applyMiddleware( + thunkMiddleware) +)) ReactDOM.render( From 65548881d50e9c393bab4279b22927dfb44609e7 Mon Sep 17 00:00:00 2001 From: David Gridley Date: Fri, 2 Nov 2018 10:25:04 +0000 Subject: [PATCH 02/20] added fetch question, randomized answers --- README.md | 3 +-- package-lock.json | 5 +++++ package.json | 3 ++- src/actions/index.js | 15 +++++++++++++++ src/components/App.js | 3 ++- src/components/Question.js | 25 ++++++++++++++++++++----- src/containers/QuestionContainer.js | 5 +++-- src/reducers/index.js | 4 ++-- src/reducers/placeholder.js | 8 -------- src/reducers/question.js | 11 +++++++++++ 10 files changed, 61 insertions(+), 21 deletions(-) delete mode 100644 src/reducers/placeholder.js create mode 100644 src/reducers/question.js diff --git a/README.md b/README.md index 30c7c67..8a12bfb 100644 --- a/README.md +++ b/README.md @@ -88,8 +88,6 @@ If you are using planning to use Redux, use the steps below to help you get star - In `QuestionContainer` implement a `mapDispatchToProps` method which we will use to receive the `fetchQuestion` call from the `QuestionComponent`. Add a console.log inside the method which implements `fetchQuestion` in `mapDispatchToProps` saying `Step 2: getting action creator` -------------------------------------------------------------------------------------- - - Create an asynchronous action creator in `actions/index.js` called `fetchQuestionFromAPI`. It should return a function which will receive `dispatch`. Inside the function, implement a `fetch` to the API to receive the question. Add a console.log just inside the action creator saying `Step 3: calling fetch`. Add another console.log inside the second `then` of the `fetch` and console.log the returned data. - Import the `fetchQuestionFromAPI` action creator from previous step into `QuestionContainer` call it using `dispatch` from `mapDispatchToProps`. @@ -99,6 +97,7 @@ If you are using planning to use Redux, use the steps below to help you get star - Implement a reducer called `question` to handle the `RECEIVE_QUESTION` action and set it in state. Add a console.log with `Step 5 - setting question in state`. You may want to initialise the default value of state to be an empty object. Don't forget to implement the default case. - Add the `question` reducer to `reducers/index.js` and remove the `placeholder` reducer as we no longer need it. +--------------------------------------------------------------------------------------------- - Implement `mapStateToProps` in `QuestionContainer` which should take the `question` from reducer state and pass it as a `question` prop to the `Question` component. Add a console.log to `mapStateToProps` which outputs `Step 6 - calling mapStateToProps in QuestionContainer`. diff --git a/package-lock.json b/package-lock.json index 90154a0..babd7ed 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9127,6 +9127,11 @@ "integrity": "sha512-vFwSUfQvqybiICwZY5+DAWIPLKsWO31Q91JSKl3UYv+K5c2QRPzn0qzec6QPu1Qc9eHYItiP3NdJqNVqetYAww==", "dev": true }, + "shuffle-array": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/shuffle-array/-/shuffle-array-1.0.1.tgz", + "integrity": "sha1-xP88/nTRb5NzBZIwGyXmV3sSiYs=" + }, "signal-exit": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", diff --git a/package.json b/package.json index 7102a0e..10e74eb 100644 --- a/package.json +++ b/package.json @@ -25,7 +25,8 @@ "react-dom": "^16.2.0", "react-redux": "^5.0.7", "redux": "^4.0.0", - "redux-thunk": "^2.3.0" + "redux-thunk": "^2.3.0", + "shuffle-array": "^1.0.1" }, "devDependencies": { "babel-jest": "^22.4.1", diff --git a/src/actions/index.js b/src/actions/index.js index a1d9430..3edb063 100644 --- a/src/actions/index.js +++ b/src/actions/index.js @@ -1,5 +1,20 @@ export function fetchQuestion(){ return function(dispatch){ + fetch('https://opentdb.com/api.php?amount=1&type=multiple') + .then(response => response.json()) + .then(result => { + const questionObj = result.results[0] + console.log('Step 3: calling fetch', questionObj) + dispatch(receiveQuestion(questionObj)); + }) + .catch(error => console.log(error)) + } +} +export function receiveQuestion(question){ + console.log('Step 4 - creating RECEIVE_QUESTION question object') + return{ + type: 'RECEIVE_QUESTION', + question, } } diff --git a/src/components/App.js b/src/components/App.js index ef2abb3..1c87a7e 100644 --- a/src/components/App.js +++ b/src/components/App.js @@ -1,10 +1,11 @@ import React from 'react'; +import QuestionContainer from '../containers/QuestionContainer' class App extends React.Component { render(){ return (
- App contents go here +
) } diff --git a/src/components/Question.js b/src/components/Question.js index dd9c28a..1e64c78 100644 --- a/src/components/Question.js +++ b/src/components/Question.js @@ -1,4 +1,6 @@ import React from "react"; +import question from "../reducers/question"; +const shuffle = require("shuffle-array"); class Question extends React.Component { constructor() { @@ -10,14 +12,27 @@ class Question extends React.Component { this.props.fetchQuestion(); } + randomizeAnswers(correctAnswer, incorrectAnswers) { + const answerArray = incorrectAnswers.concat(correctAnswer); + return shuffle(answerArray); + } + render() { + const correctAnswer = this.props.question.correct_answer; + const incorrectAnswers = this.props.question.incorrect_answers; + return (
-

QUESTION:

- - - - + {this.props.question.question && ( +
+

{this.props.question.question}

+ {this.randomizeAnswers(correctAnswer, incorrectAnswers).map( + answer => ( + + ) + )} +
+ )}
); } diff --git a/src/containers/QuestionContainer.js b/src/containers/QuestionContainer.js index 841bb03..2ea22cf 100644 --- a/src/containers/QuestionContainer.js +++ b/src/containers/QuestionContainer.js @@ -1,8 +1,9 @@ import { connect } from 'react-redux'; import Question from '../components/Question'; -import {} from '../actions'; +import { fetchQuestion } from '../actions'; const mapStateToProps = state => { + console.log('Step 6 - calling mapStateToProps in QuestionContainer') return { question: state.question } @@ -11,7 +12,7 @@ const mapStateToProps = state => { const mapDispatchToProps = dispatch => { console.log("Step 2: getting action creator") return { - fetchQuestion: () => fetchQuestion() + fetchQuestion: () => dispatch(fetchQuestion()) } } diff --git a/src/reducers/index.js b/src/reducers/index.js index 8e738e8..cfbc8d9 100644 --- a/src/reducers/index.js +++ b/src/reducers/index.js @@ -1,6 +1,6 @@ import { combineReducers } from 'redux'; -import placeholder from './placeholder'; +import question from './question'; export default combineReducers({ - placeholder + question }); diff --git a/src/reducers/placeholder.js b/src/reducers/placeholder.js deleted file mode 100644 index 25755c5..0000000 --- a/src/reducers/placeholder.js +++ /dev/null @@ -1,8 +0,0 @@ -function placeholder(state = '', action){ - switch (action.type) { - default: - return state - } -} - -export default placeholder; diff --git a/src/reducers/question.js b/src/reducers/question.js new file mode 100644 index 0000000..cd82798 --- /dev/null +++ b/src/reducers/question.js @@ -0,0 +1,11 @@ +function question(state = {}, action){ + switch (action.type) { + case 'RECEIVE_QUESTION': + console.log('Step 5 - setting question in state') + return action.question + default: + return state + } +} + +export default question; From 77d7c546ecfdd774dc01d162d19de62a95c64315 Mon Sep 17 00:00:00 2001 From: David Gridley Date: Fri, 2 Nov 2018 11:20:40 +0000 Subject: [PATCH 03/20] added points section, implimenting functionality --- README.md | 1 - index.html | 2 +- src/actions/index.js | 15 +++++++++++++++ src/components/App.js | 2 ++ src/components/Points.js | 12 ++++++++++++ src/components/Question.js | 10 ++++++++-- src/containers/PointsContainer.js | 13 +++++++++++++ src/containers/QuestionContainer.js | 5 +++-- src/reducers/points.js | 14 ++++++++++++++ 9 files changed, 68 insertions(+), 6 deletions(-) create mode 100644 src/components/Points.js create mode 100644 src/containers/PointsContainer.js create mode 100644 src/reducers/points.js diff --git a/README.md b/README.md index 8a12bfb..60b569e 100644 --- a/README.md +++ b/README.md @@ -97,7 +97,6 @@ If you are using planning to use Redux, use the steps below to help you get star - Implement a reducer called `question` to handle the `RECEIVE_QUESTION` action and set it in state. Add a console.log with `Step 5 - setting question in state`. You may want to initialise the default value of state to be an empty object. Don't forget to implement the default case. - Add the `question` reducer to `reducers/index.js` and remove the `placeholder` reducer as we no longer need it. ---------------------------------------------------------------------------------------------- - Implement `mapStateToProps` in `QuestionContainer` which should take the `question` from reducer state and pass it as a `question` prop to the `Question` component. Add a console.log to `mapStateToProps` which outputs `Step 6 - calling mapStateToProps in QuestionContainer`. diff --git a/index.html b/index.html index 20c7415..fdd8f6f 100644 --- a/index.html +++ b/index.html @@ -1,7 +1,7 @@ - Redux intro + Quizness Time diff --git a/src/actions/index.js b/src/actions/index.js index 3edb063..b6b2b63 100644 --- a/src/actions/index.js +++ b/src/actions/index.js @@ -18,3 +18,18 @@ export function receiveQuestion(question){ question, } } + +export function receiveAnswer(answer, getState) { + const reduxState = getState(); + const correctAnswer = reduxState.question.correct_answer + const difficulty = reduxState.question.difficulty + if (answer === correctAnswer) { + return { + type: 'CORRECT_ANSWER' + } + } else { + return { + type: 'INCORRECT_ANSWER' + } + } +} diff --git a/src/components/App.js b/src/components/App.js index 1c87a7e..c178087 100644 --- a/src/components/App.js +++ b/src/components/App.js @@ -1,11 +1,13 @@ import React from 'react'; import QuestionContainer from '../containers/QuestionContainer' +import PointsContainer from '../containers/PointsContainer' class App extends React.Component { render(){ return (
+
) } diff --git a/src/components/Points.js b/src/components/Points.js new file mode 100644 index 0000000..dbe7da5 --- /dev/null +++ b/src/components/Points.js @@ -0,0 +1,12 @@ +import React from 'react'; + +function Points({ points }) { + + return( +
+

POINTS: {points}

+
+ ) +} + +export default Points; \ No newline at end of file diff --git a/src/components/Question.js b/src/components/Question.js index 1e64c78..707f284 100644 --- a/src/components/Question.js +++ b/src/components/Question.js @@ -25,10 +25,16 @@ class Question extends React.Component {
{this.props.question.question && (
-

{this.props.question.question}

+

{this.props.question.question}

+

Difficulty: {this.props.question.difficulty}

{this.randomizeAnswers(correctAnswer, incorrectAnswers).map( answer => ( - + ) )}
diff --git a/src/containers/PointsContainer.js b/src/containers/PointsContainer.js new file mode 100644 index 0000000..a4f6785 --- /dev/null +++ b/src/containers/PointsContainer.js @@ -0,0 +1,13 @@ +import { connect } from 'react-redux'; +import Points from '../components/Points'; +import {} from '../actions' + +const mapStateToProps = state => { + return { + points: state.points + } +} + +export default connect( + mapStateToProps +)(Points) \ No newline at end of file diff --git a/src/containers/QuestionContainer.js b/src/containers/QuestionContainer.js index 2ea22cf..13b8bf8 100644 --- a/src/containers/QuestionContainer.js +++ b/src/containers/QuestionContainer.js @@ -1,6 +1,6 @@ import { connect } from 'react-redux'; import Question from '../components/Question'; -import { fetchQuestion } from '../actions'; +import { fetchQuestion, receiveAnswer } from '../actions'; const mapStateToProps = state => { console.log('Step 6 - calling mapStateToProps in QuestionContainer') @@ -12,7 +12,8 @@ const mapStateToProps = state => { const mapDispatchToProps = dispatch => { console.log("Step 2: getting action creator") return { - fetchQuestion: () => dispatch(fetchQuestion()) + fetchQuestion: () => dispatch(fetchQuestion()), + receiveAnswer: (answer) => dispatch(receiveAnswer(answer)) } } diff --git a/src/reducers/points.js b/src/reducers/points.js new file mode 100644 index 0000000..6d1941a --- /dev/null +++ b/src/reducers/points.js @@ -0,0 +1,14 @@ +function points(state = 0, action){ + switch (action.type) { + case 'CORRECT_ANSWER': + const points = state + 1; + return points; + case 'INCORRECT_ANSWER': + const points = state - 1; + return points; + default: + return state; + } +} + +export default points; \ No newline at end of file From 5aae01c3911c7521077aa6c1d0d7bd06d09eb200 Mon Sep 17 00:00:00 2001 From: David Gridley Date: Fri, 2 Nov 2018 11:39:36 +0000 Subject: [PATCH 04/20] implimented basic points functionality --- src/actions/index.js | 9 +++------ src/components/Question.js | 3 +-- src/containers/PointsContainer.js | 1 + src/containers/QuestionContainer.js | 4 +--- src/reducers/index.js | 4 +++- src/reducers/points.js | 8 ++++---- src/reducers/question.js | 1 - 7 files changed, 13 insertions(+), 17 deletions(-) diff --git a/src/actions/index.js b/src/actions/index.js index b6b2b63..47e96be 100644 --- a/src/actions/index.js +++ b/src/actions/index.js @@ -4,7 +4,7 @@ export function fetchQuestion(){ .then(response => response.json()) .then(result => { const questionObj = result.results[0] - console.log('Step 3: calling fetch', questionObj) + console.log(questionObj) dispatch(receiveQuestion(questionObj)); }) .catch(error => console.log(error)) @@ -12,17 +12,14 @@ export function fetchQuestion(){ } export function receiveQuestion(question){ - console.log('Step 4 - creating RECEIVE_QUESTION question object') return{ type: 'RECEIVE_QUESTION', question, } } -export function receiveAnswer(answer, getState) { - const reduxState = getState(); - const correctAnswer = reduxState.question.correct_answer - const difficulty = reduxState.question.difficulty +export function receiveAnswer(answer, question) { + const correctAnswer = question.correct_answer if (answer === correctAnswer) { return { type: 'CORRECT_ANSWER' diff --git a/src/components/Question.js b/src/components/Question.js index 707f284..6126582 100644 --- a/src/components/Question.js +++ b/src/components/Question.js @@ -8,7 +8,6 @@ class Question extends React.Component { } componentDidMount() { - console.log("Step 1: calling fetchQuestion"); this.props.fetchQuestion(); } @@ -31,7 +30,7 @@ class Question extends React.Component { answer => ( diff --git a/src/containers/PointsContainer.js b/src/containers/PointsContainer.js index a4f6785..049691c 100644 --- a/src/containers/PointsContainer.js +++ b/src/containers/PointsContainer.js @@ -3,6 +3,7 @@ import Points from '../components/Points'; import {} from '../actions' const mapStateToProps = state => { + console return { points: state.points } diff --git a/src/containers/QuestionContainer.js b/src/containers/QuestionContainer.js index 13b8bf8..510a215 100644 --- a/src/containers/QuestionContainer.js +++ b/src/containers/QuestionContainer.js @@ -3,17 +3,15 @@ import Question from '../components/Question'; import { fetchQuestion, receiveAnswer } from '../actions'; const mapStateToProps = state => { - console.log('Step 6 - calling mapStateToProps in QuestionContainer') return { question: state.question } } const mapDispatchToProps = dispatch => { - console.log("Step 2: getting action creator") return { fetchQuestion: () => dispatch(fetchQuestion()), - receiveAnswer: (answer) => dispatch(receiveAnswer(answer)) + receiveAnswer: (answer, question) => dispatch(receiveAnswer(answer, question)) } } diff --git a/src/reducers/index.js b/src/reducers/index.js index cfbc8d9..216dfd7 100644 --- a/src/reducers/index.js +++ b/src/reducers/index.js @@ -1,6 +1,8 @@ import { combineReducers } from 'redux'; import question from './question'; +import points from './points' export default combineReducers({ - question + question, + points }); diff --git a/src/reducers/points.js b/src/reducers/points.js index 6d1941a..148374a 100644 --- a/src/reducers/points.js +++ b/src/reducers/points.js @@ -1,11 +1,11 @@ function points(state = 0, action){ switch (action.type) { case 'CORRECT_ANSWER': - const points = state + 1; - return points; + const morePoints = state + 1; + return morePoints; case 'INCORRECT_ANSWER': - const points = state - 1; - return points; + const lessPoints = state - 1; + return lessPoints; default: return state; } diff --git a/src/reducers/question.js b/src/reducers/question.js index cd82798..1339f14 100644 --- a/src/reducers/question.js +++ b/src/reducers/question.js @@ -1,7 +1,6 @@ function question(state = {}, action){ switch (action.type) { case 'RECEIVE_QUESTION': - console.log('Step 5 - setting question in state') return action.question default: return state From 22eaf8917f218a50dc50bd1a1aeb28e0434eed48 Mon Sep 17 00:00:00 2001 From: David Gridley Date: Fri, 2 Nov 2018 11:49:37 +0000 Subject: [PATCH 05/20] continual question loading --- src/components/Question.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/components/Question.js b/src/components/Question.js index 6126582..79e5585 100644 --- a/src/components/Question.js +++ b/src/components/Question.js @@ -30,7 +30,10 @@ class Question extends React.Component { answer => ( From 79879a1fd0fc1147f88e61e8aae4009e5403bbde Mon Sep 17 00:00:00 2001 From: David Gridley Date: Fri, 2 Nov 2018 15:04:24 +0000 Subject: [PATCH 06/20] added question count --- package-lock.json | 5 +++++ package.json | 1 + src/actions/index.js | 1 + src/components/Question.js | 16 ++++++++++++---- src/containers/PointsContainer.js | 3 +-- src/containers/QuestionContainer.js | 4 +++- src/reducers/points.js | 27 ++++++++++++++++++++++----- src/reducers/question.js | 8 ++++++-- 8 files changed, 51 insertions(+), 14 deletions(-) diff --git a/package-lock.json b/package-lock.json index babd7ed..e506249 100644 --- a/package-lock.json +++ b/package-lock.json @@ -4674,6 +4674,11 @@ "minimalistic-assert": "^1.0.1" } }, + "he": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", + "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==" + }, "hmac-drbg": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", diff --git a/package.json b/package.json index 10e74eb..9680d09 100644 --- a/package.json +++ b/package.json @@ -20,6 +20,7 @@ "classnames": "^2.2.6", "enzyme": "^3.3.0", "enzyme-adapter-react-16": "^1.1.1", + "he": "^1.2.0", "prop-types": "^15.6.2", "react": "^16.2.0", "react-dom": "^16.2.0", diff --git a/src/actions/index.js b/src/actions/index.js index 47e96be..15fd906 100644 --- a/src/actions/index.js +++ b/src/actions/index.js @@ -15,6 +15,7 @@ export function receiveQuestion(question){ return{ type: 'RECEIVE_QUESTION', question, + correct: "" } } diff --git a/src/components/Question.js b/src/components/Question.js index 79e5585..8d92870 100644 --- a/src/components/Question.js +++ b/src/components/Question.js @@ -1,6 +1,7 @@ import React from "react"; import question from "../reducers/question"; -const shuffle = require("shuffle-array"); +import shuffle from "shuffle-array"; +import { decode } from 'he'; class Question extends React.Component { constructor() { @@ -16,15 +17,20 @@ class Question extends React.Component { return shuffle(answerArray); } + fetchNextQuestion(){ + setTimeout(this.props.fetchQuestion, 4000) + } + render() { const correctAnswer = this.props.question.correct_answer; const incorrectAnswers = this.props.question.incorrect_answers; return (
+

{this.props.numberOfQuestions}/30

{this.props.question.question && (
-

{this.props.question.question}

+

{decode(this.props.question.question)}

Difficulty: {this.props.question.difficulty}

{this.randomizeAnswers(correctAnswer, incorrectAnswers).map( answer => ( @@ -32,13 +38,15 @@ class Question extends React.Component { key={answer} onClick={() => { this.props.receiveAnswer(answer, this.props.question); - this.props.fetchQuestion() + this.fetchNextQuestion(); }} > - {answer} + {decode(answer)} ) )} + {this.props.correct === 'yes' &&

Correct! Well Done

} + {this.props.correct === 'no' &&

Incorrect! The correct answer was: {decode(correctAnswer)}

}
)}
diff --git a/src/containers/PointsContainer.js b/src/containers/PointsContainer.js index 049691c..2ed1153 100644 --- a/src/containers/PointsContainer.js +++ b/src/containers/PointsContainer.js @@ -3,9 +3,8 @@ import Points from '../components/Points'; import {} from '../actions' const mapStateToProps = state => { - console return { - points: state.points + points: state.points.points } } diff --git a/src/containers/QuestionContainer.js b/src/containers/QuestionContainer.js index 510a215..530af78 100644 --- a/src/containers/QuestionContainer.js +++ b/src/containers/QuestionContainer.js @@ -4,7 +4,9 @@ import { fetchQuestion, receiveAnswer } from '../actions'; const mapStateToProps = state => { return { - question: state.question + question: state.question.question, + numberOfQuestions: state.question.numberOfQuestions, + correct: state.points.correct } } diff --git a/src/reducers/points.js b/src/reducers/points.js index 148374a..27a65a5 100644 --- a/src/reducers/points.js +++ b/src/reducers/points.js @@ -1,11 +1,28 @@ -function points(state = 0, action){ +const initialState = { + points : 0, + correct: "" +} + + +function points(state = initialState, action){ switch (action.type) { + case 'RECEIVE_QUESTION': + return { + points: state.points, + correct: action.correct + } case 'CORRECT_ANSWER': - const morePoints = state + 1; - return morePoints; + const addOnePoint = state.points + 1; + return { + points: addOnePoint, + correct: 'yes' + } + case 'INCORRECT_ANSWER': - const lessPoints = state - 1; - return lessPoints; + return { + points: state.points, + correct: 'no' + } default: return state; } diff --git a/src/reducers/question.js b/src/reducers/question.js index 1339f14..0ec1b8e 100644 --- a/src/reducers/question.js +++ b/src/reducers/question.js @@ -1,7 +1,11 @@ -function question(state = {}, action){ +function question(state = {question: {}, numberOfQuestions: 0}, action){ switch (action.type) { case 'RECEIVE_QUESTION': - return action.question + const incrementNumberOfQuestions = state.numberOfQuestions + 1; + return{ + question: action.question, + numberOfQuestions: incrementNumberOfQuestions + } default: return state } From 622354dc33974128609e2de67ac33a7ae84fdbba Mon Sep 17 00:00:00 2001 From: David Gridley Date: Fri, 2 Nov 2018 16:19:49 +0000 Subject: [PATCH 07/20] added select menu, implimented page switiching --- src/actions/index.js | 11 ++++++++++- src/components/App.js | 6 ++---- src/components/Content.js | 19 +++++++++++++++++++ src/components/Menu.js | 21 +++++++++++++++++++++ src/components/Question.js | 9 +-------- src/containers/ContentContainer.js | 12 ++++++++++++ src/containers/MenuContainer.js | 20 ++++++++++++++++++++ src/reducers/content.js | 12 ++++++++++++ src/reducers/index.js | 4 +++- 9 files changed, 100 insertions(+), 14 deletions(-) create mode 100644 src/components/Content.js create mode 100644 src/components/Menu.js create mode 100644 src/containers/ContentContainer.js create mode 100644 src/containers/MenuContainer.js create mode 100644 src/reducers/content.js diff --git a/src/actions/index.js b/src/actions/index.js index 15fd906..b99c137 100644 --- a/src/actions/index.js +++ b/src/actions/index.js @@ -1,10 +1,11 @@ +import shuffle from "shuffle-array"; + export function fetchQuestion(){ return function(dispatch){ fetch('https://opentdb.com/api.php?amount=1&type=multiple') .then(response => response.json()) .then(result => { const questionObj = result.results[0] - console.log(questionObj) dispatch(receiveQuestion(questionObj)); }) .catch(error => console.log(error)) @@ -12,6 +13,7 @@ export function fetchQuestion(){ } export function receiveQuestion(question){ + question.answerArr = shuffle(question.incorrect_answers.concat(question.correct_answer)); return{ type: 'RECEIVE_QUESTION', question, @@ -31,3 +33,10 @@ export function receiveAnswer(answer, question) { } } } + +export function receiveView(view){ + return{ + type: 'RECEIVE_VIEW', + view + } +} diff --git a/src/components/App.js b/src/components/App.js index c178087..44c24ed 100644 --- a/src/components/App.js +++ b/src/components/App.js @@ -1,13 +1,11 @@ import React from 'react'; -import QuestionContainer from '../containers/QuestionContainer' -import PointsContainer from '../containers/PointsContainer' +import ContentContainer from '../containers/ContentContainer' class App extends React.Component { render(){ return (
- - +
) } diff --git a/src/components/Content.js b/src/components/Content.js new file mode 100644 index 0000000..fcc5a7d --- /dev/null +++ b/src/components/Content.js @@ -0,0 +1,19 @@ +import React from "react"; +import QuestionContainer from "../containers/QuestionContainer"; +import PointsContainer from "../containers/PointsContainer"; +import MenuContainer from "../containers/MenuContainer"; + +function Content({ view }) { + return ( +
+ {view === "menu" && } + {view === "quiz" && ( + + + + )} +
+ ); +} + +export default Content; diff --git a/src/components/Menu.js b/src/components/Menu.js new file mode 100644 index 0000000..8ac3cfd --- /dev/null +++ b/src/components/Menu.js @@ -0,0 +1,21 @@ +import React from 'react'; + +function Menu({ receiveView }){ + + return( +
+

It's Quizness Time!

+ + + +
+ ) +} + + +export default Menu; \ No newline at end of file diff --git a/src/components/Question.js b/src/components/Question.js index 8d92870..be503d7 100644 --- a/src/components/Question.js +++ b/src/components/Question.js @@ -1,6 +1,5 @@ import React from "react"; import question from "../reducers/question"; -import shuffle from "shuffle-array"; import { decode } from 'he'; class Question extends React.Component { @@ -12,18 +11,12 @@ class Question extends React.Component { this.props.fetchQuestion(); } - randomizeAnswers(correctAnswer, incorrectAnswers) { - const answerArray = incorrectAnswers.concat(correctAnswer); - return shuffle(answerArray); - } - fetchNextQuestion(){ setTimeout(this.props.fetchQuestion, 4000) } render() { const correctAnswer = this.props.question.correct_answer; - const incorrectAnswers = this.props.question.incorrect_answers; return (
@@ -32,7 +25,7 @@ class Question extends React.Component {

{decode(this.props.question.question)}

Difficulty: {this.props.question.difficulty}

- {this.randomizeAnswers(correctAnswer, incorrectAnswers).map( + {this.props.question.answerArr.map( answer => ( -
- ) +function Menu({ difficulty, receiveView, receiveDifficulty }) { + return ( +
+

It's Quizness Time!

+ + + +
+ ); } - -export default Menu; \ No newline at end of file +export default Menu; diff --git a/src/components/Question.js b/src/components/Question.js index be503d7..9d7cc24 100644 --- a/src/components/Question.js +++ b/src/components/Question.js @@ -8,11 +8,11 @@ class Question extends React.Component { } componentDidMount() { - this.props.fetchQuestion(); + this.props.fetchQuestion(this.props.difficulty); } fetchNextQuestion(){ - setTimeout(this.props.fetchQuestion, 4000) + setTimeout(() => this.props.fetchQuestion(this.props.difficulty), 4000) } render() { diff --git a/src/containers/MenuContainer.js b/src/containers/MenuContainer.js index 0cc8236..0997efd 100644 --- a/src/containers/MenuContainer.js +++ b/src/containers/MenuContainer.js @@ -1,16 +1,17 @@ import { connect } from 'react-redux'; import Menu from '../components/Menu'; -import {receiveView} from '../actions'; +import { receiveView, receiveDifficulty } from '../actions'; const mapStateToProps = state => { return { - + difficulty: state.menu.difficulty } } const mapDispatchToProps = dispatch => { return { - receiveView: (view) => dispatch(receiveView(view)) + receiveView: (view) => dispatch(receiveView(view)), + receiveDifficulty: (difficulty) => dispatch(receiveDifficulty(difficulty)) } } diff --git a/src/containers/QuestionContainer.js b/src/containers/QuestionContainer.js index 530af78..b043d01 100644 --- a/src/containers/QuestionContainer.js +++ b/src/containers/QuestionContainer.js @@ -6,13 +6,14 @@ const mapStateToProps = state => { return { question: state.question.question, numberOfQuestions: state.question.numberOfQuestions, - correct: state.points.correct + correct: state.points.correct, + difficulty: state.menu.difficulty } } const mapDispatchToProps = dispatch => { return { - fetchQuestion: () => dispatch(fetchQuestion()), + fetchQuestion: (difficulty) => dispatch(fetchQuestion(difficulty)), receiveAnswer: (answer, question) => dispatch(receiveAnswer(answer, question)) } } diff --git a/src/reducers/index.js b/src/reducers/index.js index c124865..bf39aaf 100644 --- a/src/reducers/index.js +++ b/src/reducers/index.js @@ -1,10 +1,12 @@ import { combineReducers } from 'redux'; import question from './question'; -import points from './points' -import content from './content' +import points from './points'; +import content from './content'; +import menu from './menu'; export default combineReducers({ question, points, - content + content, + menu }); diff --git a/src/reducers/menu.js b/src/reducers/menu.js new file mode 100644 index 0000000..d5f04ad --- /dev/null +++ b/src/reducers/menu.js @@ -0,0 +1,12 @@ +function menu(state = {difficulty: ""}, action) { + switch(action.type) { + case 'RECEIVE_DIFFICULTY': + return { + difficulty: action.difficulty + } + default: + return state; + } +} + +export default menu; \ No newline at end of file From 78af76c1d36290b4e6b3e8633935461aa5252e97 Mon Sep 17 00:00:00 2001 From: David Gridley Date: Sat, 3 Nov 2018 13:20:12 +0000 Subject: [PATCH 09/20] added varying points for random difficulty setting --- README.md | 20 ++++++------- src/actions/index.js | 6 ++-- src/components/Menu.js | 20 ++++++++++++- src/components/Question.js | 46 +++++++++++++++++------------ src/containers/QuestionContainer.js | 39 +++++++++++++----------- src/reducers/menu.js | 2 +- src/reducers/points.js | 29 +++++++++++++++--- 7 files changed, 107 insertions(+), 55 deletions(-) diff --git a/README.md b/README.md index 60b569e..e4b1ec5 100644 --- a/README.md +++ b/README.md @@ -33,7 +33,7 @@ See [https://opentdb.com/api\_config.php](https://opentdb.com/api_config.php) fo ## Instructions -* Fork and clone this repo. Run `npm install` to get all dependencies. + -* Make the app responsive and look good at all screen sizes. +* ------ Make the app responsive and look good at all screen sizes. ## Stretch goals - feel free to pick -* Show the user a 'happy' animated gif on a correct answer and a 'sad' gif on incorrect answer. +* ------ Show the user a 'happy' animated gif on a correct answer and a 'sad' gif on incorrect answer. -* Allow user to select question category +* ------ Allow user to select question category -* Allow user to select difficulty level + * Add some unit tests -* Implement a scoring system that gives higher scores for more difficult questions + -* Create a high score table. When a user finishes the game, for example answers a question incorrectly, allow them to enter their name and add it along with score to a high score table. +* ------ Create a high score table. When a user finishes the game, for example answers a question incorrectly, allow them to enter their name and add it along with score to a high score table. * Display statistics about player performance such as total questions played, average score, most popular category, category with highest percentage of correct etc. @@ -71,7 +71,7 @@ See [https://opentdb.com/api\_config.php](https://opentdb.com/api_config.php) fo * Make frequent commits * Create a pull request at the end -## Redux getting started guide + diff --git a/src/actions/index.js b/src/actions/index.js index 759fd51..7b7556e 100644 --- a/src/actions/index.js +++ b/src/actions/index.js @@ -21,11 +21,13 @@ export function receiveQuestion(question){ } } -export function receiveAnswer(answer, question) { +export function receiveAnswer(answer, question, quizDifficulty) { const correctAnswer = question.correct_answer if (answer === correctAnswer) { return { - type: 'CORRECT_ANSWER' + type: 'CORRECT_ANSWER', + quizDifficulty, + questionDifficulty: question.difficulty } } else { return { diff --git a/src/components/Menu.js b/src/components/Menu.js index 596478f..2404a39 100644 --- a/src/components/Menu.js +++ b/src/components/Menu.js @@ -7,13 +7,31 @@ function Menu({ difficulty, receiveView, receiveDifficulty }) { + {difficulty === "&difficulty=easy" && ( +

Just the basics, easy questions for easy going players.

+ )} + {difficulty === "&difficulty=medium" && ( +

Not quite easy, not quite hard.

+ )} + {difficulty === "&difficulty=hard" && ( +

Challenging to say the least.

+ )} + {difficulty === "" && ( +

+ A mixed bag of question difficulties! Easy questions are worth 1 + point, medium questions are worth 2 points and hard questions are + worth 3 points. +

+ )} diff --git a/src/components/Question.js b/src/components/Question.js index 9d7cc24..d5f03f5 100644 --- a/src/components/Question.js +++ b/src/components/Question.js @@ -1,6 +1,6 @@ import React from "react"; import question from "../reducers/question"; -import { decode } from 'he'; +import { decode } from "he"; class Question extends React.Component { constructor() { @@ -11,8 +11,8 @@ class Question extends React.Component { this.props.fetchQuestion(this.props.difficulty); } - fetchNextQuestion(){ - setTimeout(() => this.props.fetchQuestion(this.props.difficulty), 4000) + fetchNextQuestion() { + setTimeout(() => this.props.fetchQuestion(this.props.difficulty), 4000); } render() { @@ -20,26 +20,34 @@ class Question extends React.Component { return (
-

{this.props.numberOfQuestions}/30

+

+ {this.props.numberOfQuestions} + /30 +

{this.props.question.question && (

{decode(this.props.question.question)}

-

Difficulty: {this.props.question.difficulty}

- {this.props.question.answerArr.map( - answer => ( - - ) + {this.props.difficulty === "" && ( +

Difficulty: {this.props.question.difficulty}

+ )} + {this.props.question.answerArr.map(answer => ( + + ))} + {this.props.correct === "yes" &&

Correct! Well Done

} + {this.props.correct === "no" && ( +

+ Incorrect! The correct answer was: {decode(correctAnswer)}{" "} +

)} - {this.props.correct === 'yes' &&

Correct! Well Done

} - {this.props.correct === 'no' &&

Incorrect! The correct answer was: {decode(correctAnswer)}

}
)}
diff --git a/src/containers/QuestionContainer.js b/src/containers/QuestionContainer.js index b043d01..e2f24f4 100644 --- a/src/containers/QuestionContainer.js +++ b/src/containers/QuestionContainer.js @@ -1,24 +1,27 @@ -import { connect } from 'react-redux'; -import Question from '../components/Question'; -import { fetchQuestion, receiveAnswer } from '../actions'; +import { connect } from "react-redux"; +import Question from "../components/Question"; +import { fetchQuestion, receiveAnswer } from "../actions"; const mapStateToProps = state => { - return { - question: state.question.question, - numberOfQuestions: state.question.numberOfQuestions, - correct: state.points.correct, - difficulty: state.menu.difficulty - } -} + return { + question: state.question.question, + numberOfQuestions: state.question.numberOfQuestions, + correct: state.points.correct, + difficulty: state.menu.difficulty + }; +}; const mapDispatchToProps = dispatch => { - return { - fetchQuestion: (difficulty) => dispatch(fetchQuestion(difficulty)), - receiveAnswer: (answer, question) => dispatch(receiveAnswer(answer, question)) - } -} + return { + fetchQuestion: difficulty => dispatch(fetchQuestion(difficulty)), + receiveAnswer: (answer, question, quizDifficulty) => + dispatch( + receiveAnswer(answer, question, quizDifficulty) + ) + }; +}; export default connect( - mapStateToProps, - mapDispatchToProps -)(Question) \ No newline at end of file + mapStateToProps, + mapDispatchToProps +)(Question); diff --git a/src/reducers/menu.js b/src/reducers/menu.js index d5f04ad..29d845f 100644 --- a/src/reducers/menu.js +++ b/src/reducers/menu.js @@ -1,4 +1,4 @@ -function menu(state = {difficulty: ""}, action) { +function menu(state = {difficulty: "&difficulty=easy"}, action) { switch(action.type) { case 'RECEIVE_DIFFICULTY': return { diff --git a/src/reducers/points.js b/src/reducers/points.js index 27a65a5..c279b9d 100644 --- a/src/reducers/points.js +++ b/src/reducers/points.js @@ -5,6 +5,9 @@ const initialState = { function points(state = initialState, action){ + const addOnePoint = state.points + 1; + const addTwoPoints = state.points + 2; + const addThreePoints = state.points + 3; switch (action.type) { case 'RECEIVE_QUESTION': return { @@ -12,10 +15,28 @@ function points(state = initialState, action){ correct: action.correct } case 'CORRECT_ANSWER': - const addOnePoint = state.points + 1; - return { - points: addOnePoint, - correct: 'yes' + if (action.quizDifficulty !== "") { + return { + points: addOnePoint, + correct: 'yes' + } + } else if (action.quizDifficulty === "") { + if(action.questionDifficulty === "easy") { + return { + points: addOnePoint, + correct: 'yes' + } + } else if (action.questionDifficulty === "medium") { + return { + points: addTwoPoints, + correct: 'yes' + } + } else if (action.questionDifficulty === "hard") { + return { + points: addThreePoints, + correct: 'yes' + } + } } case 'INCORRECT_ANSWER': From d5e49f63c05e5b6be92c528fbbea995bc8c9d034 Mon Sep 17 00:00:00 2001 From: David Gridley Date: Sat, 3 Nov 2018 14:30:05 +0000 Subject: [PATCH 10/20] added scoreboard component --- README.md | 2 +- src/actions/index.js | 2 +- src/components/Content.js | 2 ++ src/components/Question.js | 35 +++++++++++++++++++++------ src/components/Scoreboard.js | 12 +++++++++ src/containers/QuestionContainer.js | 5 ++-- src/containers/ScoreboardContainer.js | 20 +++++++++++++++ 7 files changed, 66 insertions(+), 12 deletions(-) create mode 100644 src/components/Scoreboard.js create mode 100644 src/containers/ScoreboardContainer.js diff --git a/README.md b/README.md index e4b1ec5..9b25507 100644 --- a/README.md +++ b/README.md @@ -47,7 +47,7 @@ See [https://opentdb.com/api\_config.php](https://opentdb.com/api_config.php) fo ## Stretch goals - feel free to pick -* ------ Show the user a 'happy' animated gif on a correct answer and a 'sad' gif on incorrect answer. + * ------ Allow user to select question category diff --git a/src/actions/index.js b/src/actions/index.js index 7b7556e..7097924 100644 --- a/src/actions/index.js +++ b/src/actions/index.js @@ -49,4 +49,4 @@ export function receiveDifficulty(difficulty){ type: 'RECEIVE_DIFFICULTY', difficulty } -} +} \ No newline at end of file diff --git a/src/components/Content.js b/src/components/Content.js index fcc5a7d..0fd8a4a 100644 --- a/src/components/Content.js +++ b/src/components/Content.js @@ -2,6 +2,7 @@ import React from "react"; import QuestionContainer from "../containers/QuestionContainer"; import PointsContainer from "../containers/PointsContainer"; import MenuContainer from "../containers/MenuContainer"; +import ScoreboardContainer from "../containers/ScoreboardContainer"; function Content({ view }) { return ( @@ -12,6 +13,7 @@ function Content({ view }) { )} + {view === 'scoreboard' && }
); } diff --git a/src/components/Question.js b/src/components/Question.js index d5f03f5..d923b66 100644 --- a/src/components/Question.js +++ b/src/components/Question.js @@ -12,7 +12,11 @@ class Question extends React.Component { } fetchNextQuestion() { - setTimeout(() => this.props.fetchQuestion(this.props.difficulty), 4000); + setTimeout(() => this.props.fetchQuestion(this.props.difficulty), 1500); + } + + goToScoreboard() { + setTimeout(() => this.props.receiveView("scoreboard"), 2000) } render() { @@ -22,7 +26,7 @@ class Question extends React.Component {

{this.props.numberOfQuestions} - /30 + /20

{this.props.question.question && (
@@ -35,18 +39,33 @@ class Question extends React.Component { key={answer} disabled={this.props.correct} onClick={() => { - this.props.receiveAnswer(answer, this.props.question, this.props.difficulty); - this.fetchNextQuestion(); + this.props.receiveAnswer( + answer, + this.props.question, + this.props.difficulty + ); + this.props.numberOfQuestions >= 20 + ? this.goToScoreboard() + : this.fetchNextQuestion(); }} > {decode(answer)} ))} - {this.props.correct === "yes" &&

Correct! Well Done

} + {this.props.correct === "yes" && ( +
+ {" "} +

Correct! Well Done

{" "} + +
+ )} {this.props.correct === "no" && ( -

- Incorrect! The correct answer was: {decode(correctAnswer)}{" "} -

+
+

+ Incorrect! The correct answer was: {decode(correctAnswer)}{" "} +

+ +
)}
)} diff --git a/src/components/Scoreboard.js b/src/components/Scoreboard.js new file mode 100644 index 0000000..d46473a --- /dev/null +++ b/src/components/Scoreboard.js @@ -0,0 +1,12 @@ +import React from 'react'; + +function Scoreboard({}) { + + return( +
+ Scoreboard +
+ ) +} + +export default Scoreboard; \ No newline at end of file diff --git a/src/containers/QuestionContainer.js b/src/containers/QuestionContainer.js index e2f24f4..f110303 100644 --- a/src/containers/QuestionContainer.js +++ b/src/containers/QuestionContainer.js @@ -1,6 +1,6 @@ import { connect } from "react-redux"; import Question from "../components/Question"; -import { fetchQuestion, receiveAnswer } from "../actions"; +import { fetchQuestion, receiveAnswer, receiveView } from "../actions"; const mapStateToProps = state => { return { @@ -17,7 +17,8 @@ const mapDispatchToProps = dispatch => { receiveAnswer: (answer, question, quizDifficulty) => dispatch( receiveAnswer(answer, question, quizDifficulty) - ) + ), + receiveView: view => dispatch(receiveView(view)) }; }; diff --git a/src/containers/ScoreboardContainer.js b/src/containers/ScoreboardContainer.js new file mode 100644 index 0000000..67896fb --- /dev/null +++ b/src/containers/ScoreboardContainer.js @@ -0,0 +1,20 @@ +import { connect } from 'react-redux'; +import Scoreboard from '../components/Scoreboard'; +import { } from '../actions'; + +const mapStateToProps = state => { + return { + + } +} + +const mapDispatchToProps = dispatch => { + return { + + } +} + +export default connect( + mapStateToProps, + mapDispatchToProps +)(Scoreboard) \ No newline at end of file From e2b265ac063ddd2b4a804eb94147bde8c3e92ffe Mon Sep 17 00:00:00 2001 From: David Gridley Date: Sat, 3 Nov 2018 17:12:11 +0000 Subject: [PATCH 11/20] implimenting localStorage, not working currently --- src/actions/index.js | 92 +++++++++++++++++++-------- src/components/Question.js | 2 +- src/components/Scoreboard.js | 36 +++++++++-- src/containers/ScoreboardContainer.js | 31 +++++---- src/reducers/index.js | 4 +- 5 files changed, 115 insertions(+), 50 deletions(-) diff --git a/src/actions/index.js b/src/actions/index.js index 7097924..335252e 100644 --- a/src/actions/index.js +++ b/src/actions/index.js @@ -1,52 +1,88 @@ -import shuffle from "shuffle-array"; +import shuffle from "shuffle-array"; -export function fetchQuestion(difficulty){ - return function(dispatch){ +export function fetchQuestion(difficulty) { + return function(dispatch) { fetch(`https://opentdb.com/api.php?amount=1&type=multiple${difficulty}`) - .then(response => response.json()) - .then(result => { - const questionObj = result.results[0] - dispatch(receiveQuestion(questionObj)); - }) - .catch(error => console.log(error)) - } + .then(response => response.json()) + .then(result => { + const questionObj = result.results[0]; + dispatch(receiveQuestion(questionObj)); + }) + .catch(error => console.log(error)); + }; } -export function receiveQuestion(question){ - question.answerArr = shuffle(question.incorrect_answers.concat(question.correct_answer)); - return{ - type: 'RECEIVE_QUESTION', +export function receiveQuestion(question) { + question.answerArr = shuffle( + question.incorrect_answers.concat(question.correct_answer) + ); + return { + type: "RECEIVE_QUESTION", question, correct: "" - } + }; } export function receiveAnswer(answer, question, quizDifficulty) { - const correctAnswer = question.correct_answer + const correctAnswer = question.correct_answer; if (answer === correctAnswer) { return { - type: 'CORRECT_ANSWER', + type: "CORRECT_ANSWER", quizDifficulty, questionDifficulty: question.difficulty - } + }; } else { return { - type: 'INCORRECT_ANSWER' - } + type: "INCORRECT_ANSWER" + }; } } -export function receiveView(view){ - return{ - type: 'RECEIVE_VIEW', +export function receiveView(view) { + return { + type: "RECEIVE_VIEW", view - } + }; } -export function receiveDifficulty(difficulty){ - console.log(difficulty) +export function receiveDifficulty(difficulty) { return { - type: 'RECEIVE_DIFFICULTY', + type: "RECEIVE_DIFFICULTY", difficulty + }; +} + +export function receivePlayerName(name) { + return { + type: "RECEIVE_PLAYER_NAME", + name + }; +} + +export function fetchScoreboard(difficulty) { + return function(dispatch) { + const scoreboard = JSON.parse(localStorage.getItem(difficulty)) + dispatch(receiveScoreboard(scoreboard)) + } +} + +export function receiveScoreboard(scoreboard) { + console.log(scoreboard) +} + +export function submitScore(name, points, difficulty) { + return function(dispatch) { + const quizDifficulty = !difficulty ? "random" : difficulty; + const scoreboardArray = dispatch(fetchScoreboard(quizDifficulty)); + console.log(scoreboardArray) + const playerScoreObject = { name: name, points: points }; + if (scoreboardArray === undefined) { + localStorage.setItem(quizDifficulty, JSON.stringify([playerScoreObject])); + } else if (scoreboardArray) { + const newScoreboard = scoreboardArray.concat(playerScoreObject) + newScoreboard.sort((a, b) => b.points - a.points); + localStorage.setItem(difficulty, JSON.stringify(newScoreboard)) + } } -} \ No newline at end of file +} + diff --git a/src/components/Question.js b/src/components/Question.js index d923b66..fab6ecd 100644 --- a/src/components/Question.js +++ b/src/components/Question.js @@ -44,7 +44,7 @@ class Question extends React.Component { this.props.question, this.props.difficulty ); - this.props.numberOfQuestions >= 20 + this.props.numberOfQuestions >= 1 ? this.goToScoreboard() : this.fetchNextQuestion(); }} diff --git a/src/components/Scoreboard.js b/src/components/Scoreboard.js index d46473a..596b20d 100644 --- a/src/components/Scoreboard.js +++ b/src/components/Scoreboard.js @@ -1,12 +1,36 @@ -import React from 'react'; +import React from "react"; -function Scoreboard({}) { - return( + +class Scoreboard extends React.Component { + constructor() { + super(); + } + + componentDidMount() { + + } + + render() { + return (
- Scoreboard +

Well done, you scored {this.props.points} points!

+

Enter your name below to add your score to the scoreboard

+
{ + event.preventDefault(); + this.props.submitScore(this.props.name, this.props.points, this.props.difficulty); + }} + > + this.props.receivePlayerName(event.target.value)} + placeholder="Please enter your name here" + /> + +
- ) + ) + } } -export default Scoreboard; \ No newline at end of file +export default Scoreboard; diff --git a/src/containers/ScoreboardContainer.js b/src/containers/ScoreboardContainer.js index 67896fb..0867ae2 100644 --- a/src/containers/ScoreboardContainer.js +++ b/src/containers/ScoreboardContainer.js @@ -1,20 +1,23 @@ -import { connect } from 'react-redux'; -import Scoreboard from '../components/Scoreboard'; -import { } from '../actions'; +import { connect } from "react-redux"; +import Scoreboard from "../components/Scoreboard"; +import { receivePlayerName, submitScore } from "../actions"; const mapStateToProps = state => { - return { - - } -} + return { + points: state.points.points, + difficulty: state.menu.difficulty, + name: state.scoreboard.name + }; +}; const mapDispatchToProps = dispatch => { - return { - - } -} + return { + receivePlayerName: name => dispatch(receivePlayerName(name)), + submitScore: (name, points, difficulty) => dispatch(submitScore(name, points, difficulty)) + }; +}; export default connect( - mapStateToProps, - mapDispatchToProps -)(Scoreboard) \ No newline at end of file + mapStateToProps, + mapDispatchToProps +)(Scoreboard); diff --git a/src/reducers/index.js b/src/reducers/index.js index bf39aaf..3a89590 100644 --- a/src/reducers/index.js +++ b/src/reducers/index.js @@ -3,10 +3,12 @@ import question from './question'; import points from './points'; import content from './content'; import menu from './menu'; +import scoreboard from './scoreboard'; export default combineReducers({ question, points, content, - menu + menu, + scoreboard }); From 9a36882c84e13fa18ce9c52450af12d618dc0917 Mon Sep 17 00:00:00 2001 From: David Gridley Date: Sat, 3 Nov 2018 17:12:24 +0000 Subject: [PATCH 12/20] implimenting localStorage, not working currently --- src/reducers/scoreboard.js | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 src/reducers/scoreboard.js diff --git a/src/reducers/scoreboard.js b/src/reducers/scoreboard.js new file mode 100644 index 0000000..76634dd --- /dev/null +++ b/src/reducers/scoreboard.js @@ -0,0 +1,12 @@ +function scoreboard(state = {name: ""}, action) { + switch(action.type){ + case 'RECEIVE_PLAYER_NAME': + return { + name: action.name + } + default: + return state; + } +} + +export default scoreboard; \ No newline at end of file From 6600d224e58c4fcb308c9544767ff71325deb25b Mon Sep 17 00:00:00 2001 From: David Gridley Date: Sat, 3 Nov 2018 18:42:01 +0000 Subject: [PATCH 13/20] local storage is working --- src/actions/index.js | 22 ++++++++++------------ src/components/Question.js | 2 +- src/reducers/scoreboard.js | 7 ++++++- 3 files changed, 17 insertions(+), 14 deletions(-) diff --git a/src/actions/index.js b/src/actions/index.js index 335252e..a96a448 100644 --- a/src/actions/index.js +++ b/src/actions/index.js @@ -60,29 +60,27 @@ export function receivePlayerName(name) { } export function fetchScoreboard(difficulty) { - return function(dispatch) { const scoreboard = JSON.parse(localStorage.getItem(difficulty)) - dispatch(receiveScoreboard(scoreboard)) - } + return { + scoreboard + } } -export function receiveScoreboard(scoreboard) { - console.log(scoreboard) -} export function submitScore(name, points, difficulty) { - return function(dispatch) { const quizDifficulty = !difficulty ? "random" : difficulty; - const scoreboardArray = dispatch(fetchScoreboard(quizDifficulty)); - console.log(scoreboardArray) + const scoreboardArray = fetchScoreboard(quizDifficulty); const playerScoreObject = { name: name, points: points }; - if (scoreboardArray === undefined) { + if (scoreboardArray.scoreboard === null) { localStorage.setItem(quizDifficulty, JSON.stringify([playerScoreObject])); } else if (scoreboardArray) { - const newScoreboard = scoreboardArray.concat(playerScoreObject) + const newScoreboard = scoreboardArray.scoreboard.concat(playerScoreObject) newScoreboard.sort((a, b) => b.points - a.points); localStorage.setItem(difficulty, JSON.stringify(newScoreboard)) } - } + return { + type: "RECEIVE_SCOREBOARD", + scoreboard: scoreboardArray + } } diff --git a/src/components/Question.js b/src/components/Question.js index fab6ecd..d923b66 100644 --- a/src/components/Question.js +++ b/src/components/Question.js @@ -44,7 +44,7 @@ class Question extends React.Component { this.props.question, this.props.difficulty ); - this.props.numberOfQuestions >= 1 + this.props.numberOfQuestions >= 20 ? this.goToScoreboard() : this.fetchNextQuestion(); }} diff --git a/src/reducers/scoreboard.js b/src/reducers/scoreboard.js index 76634dd..cccb9b7 100644 --- a/src/reducers/scoreboard.js +++ b/src/reducers/scoreboard.js @@ -1,9 +1,14 @@ -function scoreboard(state = {name: ""}, action) { +function scoreboard(state = {name: "", scoreboard: []}, action) { switch(action.type){ case 'RECEIVE_PLAYER_NAME': return { name: action.name } + + case 'RECEIVE_SCOREBOARD': + return { + scoreboard: action.scoreboard + } default: return state; } From 4af89cded13e4c1c7b53e9336e746c0f168b283b Mon Sep 17 00:00:00 2001 From: David Gridley Date: Sat, 3 Nov 2018 20:06:18 +0000 Subject: [PATCH 14/20] implamented score submit --- src/actions/index.js | 21 ++++++++--- src/components/Question.js | 1 + src/components/Scoreboard.js | 50 +++++++++++++++++---------- src/containers/QuestionContainer.js | 5 +-- src/containers/ScoreboardContainer.js | 4 ++- src/reducers/scoreboard.js | 10 ++++-- 6 files changed, 61 insertions(+), 30 deletions(-) diff --git a/src/actions/index.js b/src/actions/index.js index a96a448..35ba0b4 100644 --- a/src/actions/index.js +++ b/src/actions/index.js @@ -59,13 +59,22 @@ export function receivePlayerName(name) { }; } + export function fetchScoreboard(difficulty) { - const scoreboard = JSON.parse(localStorage.getItem(difficulty)) - return { - scoreboard - } + const scoreboard = JSON.parse(localStorage.getItem(difficulty)) + return { + scoreboard + } } +export function initializeStateScoreboard(difficulty){ + const scoreboard = JSON.parse(localStorage.getItem(difficulty)) + return { + type: "RECEIVE_SCOREBOARD", + scoreboard: scoreboard, + formVisible: "yes" + } +} export function submitScore(name, points, difficulty) { const quizDifficulty = !difficulty ? "random" : difficulty; @@ -78,9 +87,11 @@ export function submitScore(name, points, difficulty) { newScoreboard.sort((a, b) => b.points - a.points); localStorage.setItem(difficulty, JSON.stringify(newScoreboard)) } + const updatedScoreboard = fetchScoreboard(quizDifficulty); return { type: "RECEIVE_SCOREBOARD", - scoreboard: scoreboardArray + scoreboard: updatedScoreboard.scoreboard, + formVisible: "no" } } diff --git a/src/components/Question.js b/src/components/Question.js index d923b66..3947ede 100644 --- a/src/components/Question.js +++ b/src/components/Question.js @@ -9,6 +9,7 @@ class Question extends React.Component { componentDidMount() { this.props.fetchQuestion(this.props.difficulty); + this.props.initializeStateScoreboard(this.props.difficulty) } fetchNextQuestion() { diff --git a/src/components/Scoreboard.js b/src/components/Scoreboard.js index 596b20d..3054f7f 100644 --- a/src/components/Scoreboard.js +++ b/src/components/Scoreboard.js @@ -1,36 +1,48 @@ import React from "react"; - - class Scoreboard extends React.Component { - constructor() { - super(); - } - - componentDidMount() { + constructor() { + super(); + } - } + componentDidMount() {} - render() { - return ( -
-

Well done, you scored {this.props.points} points!

-

Enter your name below to add your score to the scoreboard

+ render() { + return ( +
+

Well done, you scored {this.props.points} points!

+
    + {this.props.scoreboard.map(score => ( +
  1. + {" "} + {score.name}: {score.points}{" "} +
  2. + ))} +
+

Enter your name below to add your score to the scoreboard

+ {this.props.formVisible == "yes" && (
{ + onSubmit={event => { event.preventDefault(); - this.props.submitScore(this.props.name, this.props.points, this.props.difficulty); + this.props.submitScore( + this.props.name, + this.props.points, + this.props.difficulty + ); }} > this.props.receivePlayerName(event.target.value)} + onChange={event => + this.props.receivePlayerName(event.target.value) + } placeholder="Please enter your name here" />
-
- ) - } + )} +
+ ); + } } export default Scoreboard; diff --git a/src/containers/QuestionContainer.js b/src/containers/QuestionContainer.js index f110303..05a071d 100644 --- a/src/containers/QuestionContainer.js +++ b/src/containers/QuestionContainer.js @@ -1,6 +1,6 @@ import { connect } from "react-redux"; import Question from "../components/Question"; -import { fetchQuestion, receiveAnswer, receiveView } from "../actions"; +import { fetchQuestion, receiveAnswer, receiveView, initializeStateScoreboard } from "../actions"; const mapStateToProps = state => { return { @@ -18,7 +18,8 @@ const mapDispatchToProps = dispatch => { dispatch( receiveAnswer(answer, question, quizDifficulty) ), - receiveView: view => dispatch(receiveView(view)) + receiveView: view => dispatch(receiveView(view)), + initializeStateScoreboard: difficulty => dispatch(initializeStateScoreboard(difficulty)) }; }; diff --git a/src/containers/ScoreboardContainer.js b/src/containers/ScoreboardContainer.js index 0867ae2..280dd4b 100644 --- a/src/containers/ScoreboardContainer.js +++ b/src/containers/ScoreboardContainer.js @@ -6,7 +6,9 @@ const mapStateToProps = state => { return { points: state.points.points, difficulty: state.menu.difficulty, - name: state.scoreboard.name + name: state.scoreboard.name, + scoreboard: state.scoreboard.scoreboard, + formVisible: state.scoreboard.formVisible }; }; diff --git a/src/reducers/scoreboard.js b/src/reducers/scoreboard.js index cccb9b7..aca09d9 100644 --- a/src/reducers/scoreboard.js +++ b/src/reducers/scoreboard.js @@ -1,13 +1,17 @@ -function scoreboard(state = {name: "", scoreboard: []}, action) { +function scoreboard(state = {name: "", scoreboard: [], formVisible: "yes"}, action) { switch(action.type){ case 'RECEIVE_PLAYER_NAME': return { - name: action.name + name: action.name, + scoreboard: state.scoreboard, + formVisible: state.formVisible } case 'RECEIVE_SCOREBOARD': return { - scoreboard: action.scoreboard + name: state.name, + scoreboard: action.scoreboard, + formVisible: action.formVisible } default: return state; From 01ff6d583506977f8452abb3d99fd41f40dd9c23 Mon Sep 17 00:00:00 2001 From: David Gridley Date: Sun, 4 Nov 2018 19:27:32 +0000 Subject: [PATCH 15/20] styled menu and questions --- README.md | 2 +- index.html | 28 ++++--- src/components/Menu.js | 17 ++-- src/components/Question.js | 41 +++++++--- src/reducers/content.js | 2 +- style.css | 155 ++++++++++++++++++++++++++++++++++--- 6 files changed, 201 insertions(+), 44 deletions(-) diff --git a/README.md b/README.md index 9b25507..5f9dca1 100644 --- a/README.md +++ b/README.md @@ -57,7 +57,7 @@ See [https://opentdb.com/api\_config.php](https://opentdb.com/api_config.php) fo -* ------ Create a high score table. When a user finishes the game, for example answers a question incorrectly, allow them to enter their name and add it along with score to a high score table. + * Display statistics about player performance such as total questions played, average score, most popular category, category with highest percentage of correct etc. diff --git a/index.html b/index.html index fdd8f6f..048f512 100644 --- a/index.html +++ b/index.html @@ -1,13 +1,19 @@ - - Quizness Time - - - -
- -
- - - + + + Quizness Time + + + + + + + +
+ +
+ + + + \ No newline at end of file diff --git a/src/components/Menu.js b/src/components/Menu.js index 2404a39..61445e3 100644 --- a/src/components/Menu.js +++ b/src/components/Menu.js @@ -2,14 +2,15 @@ import React from "react"; function Menu({ difficulty, receiveView, receiveDifficulty }) { return ( -
-

It's Quizness Time!

- +
+

It's Quizness Time!

+ {difficulty === "&difficulty=easy" && ( -

Just the basics, easy questions for easy going players.

+

Just the basics, easy questions for easy going players.

)} {difficulty === "&difficulty=medium" && ( -

Not quite easy, not quite hard.

+

Not quite easy, not quite hard.

)} {difficulty === "&difficulty=hard" && ( -

Challenging to say the least.

+

Challenging to say the least.

)} {difficulty === "" && ( -

+

A mixed bag of question difficulties! Easy questions are worth 1 point, medium questions are worth 2 points and hard questions are worth 3 points.

)} -
diff --git a/src/components/Question.js b/src/components/Question.js index 3947ede..9e87240 100644 --- a/src/components/Question.js +++ b/src/components/Question.js @@ -9,7 +9,7 @@ class Question extends React.Component { componentDidMount() { this.props.fetchQuestion(this.props.difficulty); - this.props.initializeStateScoreboard(this.props.difficulty) + this.props.initializeStateScoreboard(this.props.difficulty); } fetchNextQuestion() { @@ -17,21 +17,23 @@ class Question extends React.Component { } goToScoreboard() { - setTimeout(() => this.props.receiveView("scoreboard"), 2000) + setTimeout(() => this.props.receiveView("scoreboard"), 2000); } render() { const correctAnswer = this.props.question.correct_answer; return ( -
-

+

+

{this.props.numberOfQuestions} /20

{this.props.question.question && ( -
-

{decode(this.props.question.question)}

+
+

+ {decode(this.props.question.question)}{" "} +

{this.props.difficulty === "" && (

Difficulty: {this.props.question.difficulty}

)} @@ -39,6 +41,13 @@ class Question extends React.Component { ))} {this.props.correct === "yes" && ( -
+
{" "} -

Correct! Well Done

{" "} - +

+ Correct! Well Done +

{" "} +
)} {this.props.correct === "no" && ( -
-

+

+

Incorrect! The correct answer was: {decode(correctAnswer)}{" "}

- +
)}
diff --git a/src/reducers/content.js b/src/reducers/content.js index e9364d1..bb52054 100644 --- a/src/reducers/content.js +++ b/src/reducers/content.js @@ -1,4 +1,4 @@ -function content(state = {view: "menu"}, action){ +function content(state = {view: "quiz"}, action){ switch(action.type) { case 'RECEIVE_VIEW': return { diff --git a/style.css b/style.css index d9bbbe0..cb697cc 100644 --- a/style.css +++ b/style.css @@ -1,15 +1,148 @@ -.voting-button { - color: #550527; - font-size: 24px; - padding: 10px; - margin: 10px; +:root { + --heading-font: 'Lobster', cursive; + --question-font: 'Encode Sans Condensed', sans-serif; +} + +html, body, ul, ol { + margin: 0; + padding: 0; + background-color: #1A8FE3; +} + +.menu__container { + height: 100vh; + width: 100vw; + display: flex; + flex-direction: column; + justify-content: center; +} + +.menu__title { + font-family: var(--heading-font); + display: flex; + justify-content: center; + color: #DE541E; + -webkit-text-stroke: 0.1px #F7F7FF; + font-size: 4.5em; +} + +.menu__select__label { + margin-left: 10px; + color: #F7F7FF; + font-family: var(--question-font); + margin-left: 7.5vw; +} + +.menu__select__dropdown{ + width: 85vw; + display: flex; + align-self: center; + margin-top: 10px; + font-family: var(--question-font); + font-size: 1.5em +} + +.menu__select__description{ + margin-left: 10px; + color: #F7F7FF; + font-family: var(--question-font); + display: flex; + justify-content: center; + font-size: 1.5em; +} + +.menu__select__button { + width: 50vw; + display: flex; + align-self: center; + justify-content: center; + height: 50px; border-radius: 5px; - background-color: white; - border: 2px solid #550527; + border: 2px solid #F7F7FF; + font-size: 1.3em; + font-family: var(--question-font); + background-color: #DE541E; + color: #F7F7FF +} + +.menu__select__button:hover{ + background-color: #F7F7FF; + color: #DE541E; + border: 2px solid #DE541E; +} + + +.question__container{ + display: flex; + flex-direction: column; + font-family: var(--question-font); + color: #F7F7FF; + height: 90vh; + width: 100vw; } -.voting-button--selected { - color: #FFF; - background-color: #550527; - border: 2px solid white; +.question__number{ + font-size: 1.5em; + margin-left: 10px; } + +.question__question__container { + display: flex; + flex-direction: column; + justify-content: center; +} + +.question__question__question { + align-self: center; + font-size: 1.5em; + margin-left: 10px; + text-align: center; +} + +.question__answer__button, +.question__answer__button--correct, +.question__answer__button--incorrect { + display: flex; + width: 50vw; + align-self: center; + height: 50px; + font-size: 1.3em; + margin-top: 10px; + justify-content: center; +} + + +.question__answer__button{ + color: #F7F7FF; + background-color: #DE541E; +} + +.question__answer__button--correct { + background-color: green; + color: #F7F7FF; +} + +.question__answer__button--incorrect { + background-color: red; + color: #F7F7FF; +} + +.question__correct, +.question__incorrect{ + display: flex; + flex-direction: column; +} + +.question__correct__text, +.question__incorrect__text{ + align-self: center; + font-size: 1.2em; + margin-left: 10px; +} + +.question__correct__image, +.question__incorrect__image { + max-height: 15vh; + max-width: 35vw; + align-self: center; +} \ No newline at end of file From 0ef92622b94e2506ecf6e3c1e605efca96c8758d Mon Sep 17 00:00:00 2001 From: David Gridley Date: Sun, 4 Nov 2018 19:37:23 +0000 Subject: [PATCH 16/20] styled points --- src/components/Points.js | 4 ++-- style.css | 27 +++++++++++++++++++++++---- 2 files changed, 25 insertions(+), 6 deletions(-) diff --git a/src/components/Points.js b/src/components/Points.js index dbe7da5..16f0a3f 100644 --- a/src/components/Points.js +++ b/src/components/Points.js @@ -3,8 +3,8 @@ import React from 'react'; function Points({ points }) { return( -
-

POINTS: {points}

+
+

POINTS: {points}

) } diff --git a/style.css b/style.css index cb697cc..0dcc88f 100644 --- a/style.css +++ b/style.css @@ -83,7 +83,9 @@ html, body, ul, ol { .question__number{ font-size: 1.5em; - margin-left: 10px; + margin-right: 10px; + margin-bottom: 0; + align-self: flex-end; } .question__question__container { @@ -106,7 +108,7 @@ html, body, ul, ol { width: 50vw; align-self: center; height: 50px; - font-size: 1.3em; + font-size: 100%; margin-top: 10px; justify-content: center; } @@ -142,7 +144,24 @@ html, body, ul, ol { .question__correct__image, .question__incorrect__image { - max-height: 15vh; - max-width: 35vw; + max-height: 25vh; + max-width: 45vw; + align-self: center; +} + +.points__container { + position: fixed; + display: flex; + height: 5vh; + flex-direction: column; + bottom: 0; + width: 100vw; +} + +.points__number{ align-self: center; + margin: 0; + color: #F7F7FF; + font-family: var(--question-font); + font-size: 1.5em; } \ No newline at end of file From 9e99113249320c978143e5da584115fba353aeba Mon Sep 17 00:00:00 2001 From: David Gridley Date: Sun, 4 Nov 2018 20:28:28 +0000 Subject: [PATCH 17/20] finished styling --- src/components/Content.js | 2 +- src/components/Question.js | 2 +- src/components/Scoreboard.js | 23 ++++++++++++++------ src/reducers/content.js | 2 +- style.css | 42 ++++++++++++++++++++++++++++++++++++ 5 files changed, 62 insertions(+), 9 deletions(-) diff --git a/src/components/Content.js b/src/components/Content.js index 0fd8a4a..3f3cb85 100644 --- a/src/components/Content.js +++ b/src/components/Content.js @@ -13,7 +13,7 @@ function Content({ view }) { )} - {view === 'scoreboard' && } + {view === "scoreboard" && }
); } diff --git a/src/components/Question.js b/src/components/Question.js index 9e87240..0b50713 100644 --- a/src/components/Question.js +++ b/src/components/Question.js @@ -54,7 +54,7 @@ class Question extends React.Component { this.props.question, this.props.difficulty ); - this.props.numberOfQuestions >= 20 + this.props.numberOfQuestions >= 1 ? this.goToScoreboard() : this.fetchNextQuestion(); }} diff --git a/src/components/Scoreboard.js b/src/components/Scoreboard.js index 3054f7f..24c0672 100644 --- a/src/components/Scoreboard.js +++ b/src/components/Scoreboard.js @@ -9,19 +9,27 @@ class Scoreboard extends React.Component { render() { return ( -
-

Well done, you scored {this.props.points} points!

-
    +
    +

    + Well done, you scored {this.props.points} points! +

    +
      {this.props.scoreboard.map(score => ( -
    1. +
    2. {" "} {score.name}: {score.points}{" "}
    3. ))}
    -

    Enter your name below to add your score to the scoreboard

    +

    + Enter your name below to add your score to the scoreboard +

    {this.props.formVisible == "yes" && (
    { event.preventDefault(); this.props.submitScore( @@ -32,12 +40,15 @@ class Scoreboard extends React.Component { }} > this.props.receivePlayerName(event.target.value) } placeholder="Please enter your name here" /> - +
    )}
    diff --git a/src/reducers/content.js b/src/reducers/content.js index bb52054..e9364d1 100644 --- a/src/reducers/content.js +++ b/src/reducers/content.js @@ -1,4 +1,4 @@ -function content(state = {view: "quiz"}, action){ +function content(state = {view: "menu"}, action){ switch(action.type) { case 'RECEIVE_VIEW': return { diff --git a/style.css b/style.css index 0dcc88f..37e6cd2 100644 --- a/style.css +++ b/style.css @@ -164,4 +164,46 @@ html, body, ul, ol { color: #F7F7FF; font-family: var(--question-font); font-size: 1.5em; +} + +.scoreboard__container { + font-family: var(--question-font); + color: #F7F7FF; + width: 100vw; + display: flex; + flex-direction: column; + align-items: center; + font-size: 1.7em; + margin-left: 10px; +} + +.scoreboard__form{ + display: flex; + flex-direction: column; +} + +.scoreboard__form__input{ + height: 5vh; + font-size: 100%; +} + +.scoreboard__form__button{ + margin-top: 15px; + width: 50vw; + display: flex; + align-self: center; + justify-content: center; + height: 50px; + border-radius: 5px; + border: 2px solid #F7F7FF; + font-size: 1.3em; + font-family: var(--question-font); + background-color: #DE541E; + color: #F7F7FF +} + +.scoreboard__form__button:hover{ + background-color: #F7F7FF; + color: #DE541E; + border: 2px solid #DE541E; } \ No newline at end of file From eba7c9c9ba486f9630e385c3659437126f2fd494 Mon Sep 17 00:00:00 2001 From: David Gridley Date: Mon, 5 Nov 2018 09:33:52 +0000 Subject: [PATCH 18/20] pre demo commit, README and test suit to come --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 5f9dca1..b00ee47 100644 --- a/README.md +++ b/README.md @@ -43,13 +43,13 @@ See [https://opentdb.com/api\_config.php](https://opentdb.com/api_config.php) fo * Each correct answer should increment the score. It's up to you how you want to score answers. You could apply a different score for different difficulty grades. After each correct answer display the next question --> -* ------ Make the app responsive and look good at all screen sizes. + ## Stretch goals - feel free to pick -* ------ Allow user to select question category +* Allow user to select question category From ada3d64afc6b77a772f39e81e98a0b5f22ca62b3 Mon Sep 17 00:00:00 2001 From: David Gridley Date: Mon, 5 Nov 2018 09:41:38 +0000 Subject: [PATCH 19/20] pre demo commit, README and test suit to come --- src/components/Question.js | 6 +++--- src/components/Scoreboard.js | 6 +++--- style.css | 1 + 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/src/components/Question.js b/src/components/Question.js index 0b50713..a1f3211 100644 --- a/src/components/Question.js +++ b/src/components/Question.js @@ -13,11 +13,11 @@ class Question extends React.Component { } fetchNextQuestion() { - setTimeout(() => this.props.fetchQuestion(this.props.difficulty), 1500); + setTimeout(() => this.props.fetchQuestion(this.props.difficulty), 3000); } goToScoreboard() { - setTimeout(() => this.props.receiveView("scoreboard"), 2000); + setTimeout(() => this.props.receiveView("scoreboard"), 3000); } render() { @@ -54,7 +54,7 @@ class Question extends React.Component { this.props.question, this.props.difficulty ); - this.props.numberOfQuestions >= 1 + this.props.numberOfQuestions >= 5 ? this.goToScoreboard() : this.fetchNextQuestion(); }} diff --git a/src/components/Scoreboard.js b/src/components/Scoreboard.js index 24c0672..53d84f1 100644 --- a/src/components/Scoreboard.js +++ b/src/components/Scoreboard.js @@ -24,9 +24,6 @@ class Scoreboard extends React.Component { ))}
-

- Enter your name below to add your score to the scoreboard -

{this.props.formVisible == "yes" && (
+

+ Enter your name below to add your score to the scoreboard +

diff --git a/style.css b/style.css index 37e6cd2..7d5727e 100644 --- a/style.css +++ b/style.css @@ -180,6 +180,7 @@ html, body, ul, ol { .scoreboard__form{ display: flex; flex-direction: column; + width: 80vw; } .scoreboard__form__input{ From 0cd37cceb6708cd02bfe8b97bc3d954b219f023b Mon Sep 17 00:00:00 2001 From: David Gridley Date: Mon, 5 Nov 2018 09:47:27 +0000 Subject: [PATCH 20/20] final style tweaks --- style.css | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/style.css b/style.css index 7d5727e..9307152 100644 --- a/style.css +++ b/style.css @@ -39,7 +39,7 @@ html, body, ul, ol { align-self: center; margin-top: 10px; font-family: var(--question-font); - font-size: 1.5em + font-size: 1.5em; } .menu__select__description{ @@ -59,7 +59,7 @@ html, body, ul, ol { height: 50px; border-radius: 5px; border: 2px solid #F7F7FF; - font-size: 1.3em; + font-size: 100%; font-family: var(--question-font); background-color: #DE541E; color: #F7F7FF