diff --git a/index.html b/index.html
deleted file mode 100644
index 20c7415..0000000
--- a/index.html
+++ /dev/null
@@ -1,13 +0,0 @@
-
-
-
-
+ {this.renderRedirect()}
+ {
+ this.state.shuffled_answers.map(answer => {
+ return
+ })
+ }
+
+ )
+ }
+}
+
+export default Answers;
\ No newline at end of file
diff --git a/src/components/App.js b/src/components/App.js
index ef2abb3..83a8b48 100644
--- a/src/components/App.js
+++ b/src/components/App.js
@@ -1,10 +1,50 @@
import React from 'react';
+import { Route, Switch } from 'react-router-dom';
+
+import Header from './Header';
+import StartContainer from '../containers/StartContainer';
+import OptionsContainer from '../containers/OptionsContainer';
+import ScoreContainer from '../containers/ScoreContainer';
+import QuestionContainer from '../containers/QuestionContainer';
+import AnswersContainer from '../containers/AnswersContainer';
+import MessageContainer from '../containers/MessageContainer';
+import ButtonSkipQuestionContainer from '../containers/ButtonSkipQuestionContainer';
+import LeaderboardContainer from '../containers/LeaderboardContainer';
+
+import '../static/styles/style.scss';
class App extends React.Component {
- render(){
+ render() {
return (
-
- App contents go here
+
+
+
+ {
+ return
+ }} />
+ {
+ return
+ }} />
+ {
+ return
+ }} />
+ />
+ {
+ return
+
+
+ }} />
+ />
+
+
+
)
}
diff --git a/src/components/ButtonAnswer.js b/src/components/ButtonAnswer.js
new file mode 100644
index 0000000..cbd4c79
--- /dev/null
+++ b/src/components/ButtonAnswer.js
@@ -0,0 +1,45 @@
+import React from 'react';
+import cx from 'classnames';
+
+class ButtonAnswer extends React.Component {
+ constructor(props) {
+ super(props);
+
+ this.state = {
+ isClicked: false
+ }
+
+ this.onClickHandler = this.onClickHandler.bind(this);
+ }
+
+ onClickHandler() {
+ this.setState({
+ isClicked: true
+ })
+ }
+
+
+ render() {
+ return (
+
+ )
+ }
+}
+
+export default ButtonAnswer;
\ No newline at end of file
diff --git a/src/components/ButtonSkipQuestion.js b/src/components/ButtonSkipQuestion.js
new file mode 100644
index 0000000..cf79192
--- /dev/null
+++ b/src/components/ButtonSkipQuestion.js
@@ -0,0 +1,34 @@
+import React from 'react';
+import cx from 'classnames';
+import "../static/styles/buttonSkipQuestion.scss";
+
+function ButtonSkipQuestion({
+ requestQuestion,
+ isRightAnswer,
+ scoreUpdate,
+ score,
+ category,
+ difficulty,
+ currentQuestion,
+ incrementCurrentQuestion,
+ totalQuestions
+}) {
+ return (
+
+
+
+ );
+}
+
+export default ButtonSkipQuestion;
\ No newline at end of file
diff --git a/src/components/Header.js b/src/components/Header.js
new file mode 100644
index 0000000..36cc74e
--- /dev/null
+++ b/src/components/Header.js
@@ -0,0 +1,15 @@
+import React from 'react';
+import Navigation from './Navigation';
+
+import '../static/styles/header.scss';
+
+function Header() {
+ return (
+
+ );
+}
+export default Header;
\ No newline at end of file
diff --git a/src/components/Leaderboard.js b/src/components/Leaderboard.js
new file mode 100644
index 0000000..8535440
--- /dev/null
+++ b/src/components/Leaderboard.js
@@ -0,0 +1,103 @@
+import React from 'react';
+import cx from 'classnames';
+
+import '../static/styles/leaderboard.scss';
+
+class Leaderboard extends React.Component {
+ constructor(props) {
+ super(props)
+ this.state = {
+ id: [Object.keys(this.props.leaderboard).length],
+ playerName: '',
+ sorted: [],
+ leaderboardNameAdded: false
+ }
+ this.onSubmitHandler = this.onSubmitHandler.bind(this);
+ this.onChangeHandler = this.onChangeHandler.bind(this);
+ }
+
+ componentWillMount() {
+ const sorted = Object.keys(this.props.leaderboard).sort((a, b) => {
+ return this.props.leaderboard[b].points - this.props.leaderboard[a].points
+ });
+
+ this.setState({
+ sorted: sorted
+ })
+ }
+
+ onSubmitHandler(e) {
+ e.preventDefault();
+ this.setState({
+ [+this.state.id + 1]: {
+ player: this.state.playerName,
+ points: this.props.score
+ }
+ });
+
+ const leaders = Object.assign({}, this.props.leaderboard, {
+ [+this.state.id + 1]: {
+ player: this.state.playerName,
+ points: this.props.score
+ }
+ }
+ )
+ this.props.leaderboardList(leaders);
+
+ const sorted = Object.keys(leaders).sort((a, b) => {
+ return leaders[b].points - leaders[a].points
+ });
+
+ this.setState({
+ sorted: sorted,
+ leaderboardNameAdded: true
+ })
+ }
+
+ onChangeHandler(e) {
+ this.setState({
+ playerName: e.target.value
+ });
+ }
+
+ render() {
+ return (
+
+
Leaderboard
+
+
+
+
+
+ {
+ Object.keys(this.props.leaderboard).map((rank, index) => {
+ return
+
{index + 1}
+
{this.props.leaderboard[this.state.sorted[index]].player}
+
{this.props.leaderboard[this.state.sorted[index]].points}
+
+ })
+ }
+
+
+
+ );
+ }
+}
+export default Leaderboard;
\ No newline at end of file
diff --git a/src/components/Message.js b/src/components/Message.js
new file mode 100644
index 0000000..9a7fe9b
--- /dev/null
+++ b/src/components/Message.js
@@ -0,0 +1,31 @@
+import React from 'react';
+import '../static/styles/message.scss';
+import cx from 'classnames';
+
+function Message({ questionAnswer, score, viewMessage, updateMessage }) {
+ const CSSClasses = cx('message ', {
+ visible: viewMessage,
+ animated: questionAnswer,
+ fadeIn: questionAnswer,
+ correct: questionAnswer
+ });
+ const CoverClasses = cx('cover ', {
+ visible: viewMessage
+ });
+
+ setTimeout(() => {
+ updateMessage(false);
+ }, 1500);
+
+ return (
+
+
+ {questionAnswer ? "+ 10!" : "- 10!"}
+
+
+
+
+ );
+}
+
+export default Message;
\ No newline at end of file
diff --git a/src/components/Navigation.js b/src/components/Navigation.js
new file mode 100644
index 0000000..8beb5d0
--- /dev/null
+++ b/src/components/Navigation.js
@@ -0,0 +1,15 @@
+import React from 'react';
+import { Link } from 'react-router-dom';
+
+import "../static/styles/navigation.scss";
+
+function Navigation(props) {
+ return (
+
+ Start
+ {/* Quiz */}
+ Leaderboard
+
+ )
+}
+export default Navigation;
\ No newline at end of file
diff --git a/src/components/Options.js b/src/components/Options.js
new file mode 100644
index 0000000..5310af1
--- /dev/null
+++ b/src/components/Options.js
@@ -0,0 +1,184 @@
+import React from 'react';
+import cx from 'classnames';
+import { Redirect } from 'react-router-dom';
+import "../static/styles/options.scss";
+
+class Options extends React.Component {
+ constructor(props) {
+ super(props);
+ this.state = {
+ category: '',
+ categoryName: '',
+ difficulty: '',
+
+ redirect: false,
+ // optionsOpen: false,
+ questionsAmount: 10
+ }
+
+ this.updateCategory = this.updateCategory.bind(this);
+ this.updateDifficulty = this.updateDifficulty.bind(this);
+ this.setRedirect = this.setRedirect.bind(this);
+ this.renderRedirect = this.renderRedirect.bind(this);
+ // this.toggleOptions = this.toggleOptions.bind(this);
+ this.updateCategory = this.updateCategory.bind(this);
+ this.updateDifficulty = this.updateDifficulty.bind(this);
+ this.updateQuestionsAmount = this.updateQuestionsAmount.bind(this);
+ }
+
+ updateCategory(e) {
+ this.setState({
+ category: e.target.value,
+ categoryName: e.target.selectedOptions ? e.target.selectedOptions[0].text : "All", // get text of the option tag not the value
+ // questionsAmount:
+ });
+ }
+
+ updateDifficulty(e) {
+ this.setState({
+ difficulty: e.target.value
+ });
+ }
+
+ updateQuestionsAmount(e) {
+ this.setState({
+ questionsAmount: e.target.value
+ });
+ }
+
+ updateReduxCategory() {
+ this.props.optionsCategory(this.state.category);
+ this.props.optionsCategoryName(this.state.categoryName);
+ }
+
+ updateReduxDifficulty() {
+ this.props.optionsDifficulty(this.state.difficulty);
+ this.setRedirect();
+ }
+
+ updateReduxQuestionsAmount() {
+ // console.log("this.state.questionsAmount", this.state.questionsAmount)
+ this.props.updateReduxQuestionsAmount(this.state.questionsAmount);
+ }
+
+ // toggleOptions() {
+ // this.setState({
+ // optionsOpen: !this.state.optionsOpen
+ // })
+ // }
+
+ setRedirect() {
+ this.setState({
+ redirect: true
+ });
+ }
+
+ renderRedirect() {
+ if (this.state.redirect) {
+ return
;
+ }
+ }
+
+ render() {
+ const CSSClasses = cx('options__list ', {
+ visible: this.state.optionsOpen
+ });
+ return (
+
+ {this.renderRedirect()}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ );
+ };
+}
+export default Options;
diff --git a/src/components/Question.js b/src/components/Question.js
new file mode 100644
index 0000000..25475e6
--- /dev/null
+++ b/src/components/Question.js
@@ -0,0 +1,30 @@
+import React from 'react';
+import "../static/styles/question.scss";
+
+class Question extends React.Component {
+ constructor(props) {
+ super(props);
+ }
+
+ componentDidMount() {
+ // this.props.requestQuestion();
+ }
+
+ render() {
+ const { quizQuestion, currentQuestion } = this.props;
+ return (
+
+ {
+ quizQuestion
+ ?
+ {decodeURIComponent(quizQuestion.results[0].question)}
+
+ : ""
+
+ }
+
+ );
+ };
+}
+export default Question;
diff --git a/src/components/Score.js b/src/components/Score.js
new file mode 100644
index 0000000..7886a70
--- /dev/null
+++ b/src/components/Score.js
@@ -0,0 +1,20 @@
+import React from 'react';
+import '../static/styles/score.scss';
+
+function Score({ score, categoryName, difficulty, totalQuestions, currentQuestion }) {
+ return (
+
+
+ Category: {categoryName !== "" ? categoryName : "All"}
+ Difficulty: {difficulty !== "" ? difficulty : "Easy"}
+
+
+ Points: {score}
+ {currentQuestion}/{totalQuestions}
+
+
+
+ );
+}
+
+export default Score;
\ No newline at end of file
diff --git a/src/components/Start.js b/src/components/Start.js
new file mode 100644
index 0000000..be2c611
--- /dev/null
+++ b/src/components/Start.js
@@ -0,0 +1,10 @@
+import React from 'react';
+import OptionsContainer from '../containers/OptionsContainer';
+
+function Start() {
+ return (
+
+ )
+}
+
+export default Start;
\ No newline at end of file
diff --git a/src/containers/AnswersContainer.js b/src/containers/AnswersContainer.js
new file mode 100644
index 0000000..d681808
--- /dev/null
+++ b/src/containers/AnswersContainer.js
@@ -0,0 +1,39 @@
+import { connect } from 'react-redux'
+import Answers from '../components/Answers';
+import {
+ viewMessage,
+ isRightAnswer,
+ scoreUpdate,
+ fetchQuestion,
+ currentQuestion,
+ generateArray
+}
+ from '../actions';
+
+export const mapStateToProps = reduxStore => {
+ return {
+ randomArray: reduxStore.randomArray,
+ answers: reduxStore.quizQuestion,
+ score: reduxStore.score,
+ category: reduxStore.optionsCategory,
+ difficulty: reduxStore.optionsDifficulty,
+ currentQuestion: reduxStore.currentQuestion,
+ totalQuestions: reduxStore.updateReduxQuestionsAmount
+ };
+};
+
+const mapDispatchToProps = dispatch => {
+ return {
+ generateArray: array => dispatch(generateArray(array)),
+ requestQuestion: (category, difficulty) => dispatch(fetchQuestion(category, difficulty)),
+ scoreUpdate: score => dispatch(scoreUpdate(score)),
+ isRightAnswer: isRight => dispatch(isRightAnswer(isRight)),
+ incrementCurrentQuestion: current => dispatch(currentQuestion(current)),
+ viewMessage: isVisible => dispatch(viewMessage(isVisible))
+ }
+};
+
+export default connect(
+ mapStateToProps,
+ mapDispatchToProps
+)(Answers);
\ No newline at end of file
diff --git a/src/containers/ButtonSkipQuestionContainer.js b/src/containers/ButtonSkipQuestionContainer.js
new file mode 100644
index 0000000..60fd49f
--- /dev/null
+++ b/src/containers/ButtonSkipQuestionContainer.js
@@ -0,0 +1,32 @@
+import { connect } from 'react-redux'
+import ButtonSkipQuestion from '../components/ButtonSkipQuestion';
+import {
+ fetchQuestion,
+ isRightAnswer,
+ scoreUpdate,
+ currentQuestion
+} from '../actions';
+
+export const mapStateToProps = reduxStore => {
+ return {
+ score: reduxStore.score,
+ category: reduxStore.optionsCategory,
+ difficulty: reduxStore.optionsDifficulty,
+ currentQuestion: reduxStore.currentQuestion,
+ totalQuestions: reduxStore.updateReduxQuestionsAmount
+ };
+};
+
+const mapDispatchToProps = dispatch => {
+ return {
+ scoreUpdate: score => dispatch(scoreUpdate(score)),
+ isRightAnswer: isRight => dispatch(isRightAnswer(isRight)),
+ requestQuestion: (category, difficulty) => dispatch(fetchQuestion(category, difficulty)),
+ incrementCurrentQuestion: current => dispatch(currentQuestion(current))
+ }
+};
+
+export default connect(
+ mapStateToProps,
+ mapDispatchToProps
+)(ButtonSkipQuestion);
\ No newline at end of file
diff --git a/src/containers/LeaderboardContainer.js b/src/containers/LeaderboardContainer.js
new file mode 100644
index 0000000..5bdd786
--- /dev/null
+++ b/src/containers/LeaderboardContainer.js
@@ -0,0 +1,23 @@
+import { connect } from 'react-redux'
+import Leaderboard from '../components/Leaderboard';
+import {
+ leaderboardList
+} from '../actions';
+
+export const mapStateToProps = reduxStore => {
+ return {
+ score: reduxStore.score,
+ leaderboard: reduxStore.leaderboard
+ };
+};
+
+const mapDispatchToProps = dispatch => {
+ return {
+ leaderboardList: data => dispatch(leaderboardList(data))
+ }
+};
+
+export default connect(
+ mapStateToProps,
+ mapDispatchToProps
+)(Leaderboard);
\ No newline at end of file
diff --git a/src/containers/MessageContainer.js b/src/containers/MessageContainer.js
new file mode 100644
index 0000000..2c8ac67
--- /dev/null
+++ b/src/containers/MessageContainer.js
@@ -0,0 +1,23 @@
+import React from 'react';
+import { connect } from 'react-redux';
+import Message from '../components/Message';
+import { viewMessage } from '../actions';
+
+export const mapStateToProps = reduxStore => {
+ return {
+ questionAnswer: reduxStore.quizAnswer,
+ score: reduxStore.score,
+ viewMessage: reduxStore.viewMessage
+ }
+}
+
+const mapDispatchToProps = dispatch => {
+ return {
+ updateMessage: isVisible => dispatch(viewMessage(isVisible))
+ }
+};
+
+export default connect(
+ mapStateToProps,
+ mapDispatchToProps
+)(Message);
\ No newline at end of file
diff --git a/src/containers/OptionsContainer.js b/src/containers/OptionsContainer.js
new file mode 100644
index 0000000..cf12619
--- /dev/null
+++ b/src/containers/OptionsContainer.js
@@ -0,0 +1,34 @@
+import { connect } from 'react-redux'
+import Options from '../components/Options';
+import {
+ fetchQuestion,
+ optionsDifficulty,
+ optionsCategory,
+ optionsCategoryName,
+ updateReduxQuestionsAmount,
+ currentQuestion,
+ scoreUpdate
+} from '../actions';
+
+export const mapStateToProps = reduxStore => {
+ return {
+ currentQuestionValue: reduxStore.currentQuestion
+ };
+};
+
+const mapDispatchToProps = dispatch => {
+ return {
+ requestQuestionsUpdate: (category, difficulty, amount) => dispatch(fetchQuestion(category, difficulty, amount)),
+ optionsDifficulty: difficulty => dispatch(optionsDifficulty(difficulty)),
+ optionsCategory: category => dispatch(optionsCategory(category)),
+ optionsCategoryName: categoryName => dispatch(optionsCategoryName(categoryName)),
+ updateReduxQuestionsAmount: questionsAmount => dispatch(updateReduxQuestionsAmount(questionsAmount)),
+ currentQuestion: questionsCount => dispatch(currentQuestion(questionsCount)),
+ scoreUpdate: score => dispatch(scoreUpdate(score))
+ }
+};
+
+export default connect(
+ null,
+ mapDispatchToProps
+)(Options);
\ No newline at end of file
diff --git a/src/containers/QuestionContainer.js b/src/containers/QuestionContainer.js
new file mode 100644
index 0000000..a89a6c3
--- /dev/null
+++ b/src/containers/QuestionContainer.js
@@ -0,0 +1,21 @@
+import { connect } from 'react-redux'
+import Question from '../components/Question';
+import { fetchQuestion } from '../actions';
+
+export const mapStateToProps = reduxStore => {
+ return {
+ quizQuestion: reduxStore.quizQuestion,
+ currentQuestion: reduxStore.currentQuestion
+ };
+};
+
+const mapDispatchToProps = dispatch => {
+ return {
+ requestQuestion: () => dispatch(fetchQuestion())
+ }
+};
+
+export default connect(
+ mapStateToProps,
+ mapDispatchToProps
+)(Question);
\ No newline at end of file
diff --git a/src/containers/ScoreContainer.js b/src/containers/ScoreContainer.js
new file mode 100644
index 0000000..7f63ec0
--- /dev/null
+++ b/src/containers/ScoreContainer.js
@@ -0,0 +1,25 @@
+import { connect } from 'react-redux'
+import Score from '../components/Score';
+// import { isRightAnswer } from '../actions';
+
+
+export const mapStateToProps = reduxStore => {
+ return {
+ score: reduxStore.score,
+ categoryName: reduxStore.optionsCategoryName,
+ difficulty: reduxStore.optionsDifficulty,
+ totalQuestions: reduxStore.updateReduxQuestionsAmount,
+ currentQuestion: reduxStore.currentQuestion
+ };
+};
+
+// const mapDispatchToProps = dispatch => {
+// return {
+// isRightAnswer: isRight => dispatch(isRightAnswer(isRight))
+// }
+// };
+
+export default connect(
+ mapStateToProps,
+ null
+)(Score);
\ No newline at end of file
diff --git a/src/containers/StartContainer.js b/src/containers/StartContainer.js
new file mode 100644
index 0000000..9d0c403
--- /dev/null
+++ b/src/containers/StartContainer.js
@@ -0,0 +1,21 @@
+import React from 'react';
+import Start from '../components/Start';
+import { connect } from 'react-redux';
+
+// const mapStateToProps = reduxStore => {
+// return {
+
+// }
+// }
+
+// const mapDispatchToProps = reduxStore => {
+// return {
+
+// }
+// }
+
+export default connect(
+ null, null
+ // mapStateToProps,
+ // mapDispatchToProps
+)(Start);
\ No newline at end of file
diff --git a/src/index.js b/src/index.js
index 846662e..321c6bd 100644
--- a/src/index.js
+++ b/src/index.js
@@ -1,5 +1,6 @@
import React from 'react';
import ReactDOM from 'react-dom';
+import { BrowserRouter, Route } from 'react-router-dom';
import App from './components/App';
import thunkMiddleware from 'redux-thunk';
@@ -13,7 +14,9 @@ const store = createStore(rootReducer, applyMiddleware(
ReactDOM.render(
-
+
+
+
,
document.getElementById('root')
);
diff --git a/src/reducers/currentQuestion.js b/src/reducers/currentQuestion.js
new file mode 100644
index 0000000..6b55d4b
--- /dev/null
+++ b/src/reducers/currentQuestion.js
@@ -0,0 +1,12 @@
+function currentQuestion(
+ state = 1, action) {
+ switch (action.type) {
+ case 'RECEIVE_CURRENT_QUESTION':
+ return action.currentQuestion
+
+ default:
+ return state
+ }
+}
+
+export default currentQuestion;
\ No newline at end of file
diff --git a/src/reducers/index.js b/src/reducers/index.js
index 8e738e8..a350ccd 100644
--- a/src/reducers/index.js
+++ b/src/reducers/index.js
@@ -1,6 +1,26 @@
import { combineReducers } from 'redux';
-import placeholder from './placeholder';
+import quizQuestion from './quizQuestion';
+import quizAnswer from './quizAnswer';
+import score from './score';
+import optionsDifficulty from './optionsDifficulty';
+import optionsCategory from './optionsCategory';
+import optionsCategoryName from './optionsCategoryName';
+import currentQuestion from './currentQuestion';
+import updateReduxQuestionsAmount from './updateReduxQuestionsAmount';
+import viewMessage from './viewMessage';
+import randomArray from './randomArray';
+import leaderboard from './leaderboard';
export default combineReducers({
- placeholder
+ quizQuestion,
+ quizAnswer,
+ score,
+ optionsDifficulty,
+ optionsCategory,
+ optionsCategoryName,
+ currentQuestion,
+ updateReduxQuestionsAmount,
+ viewMessage,
+ randomArray,
+ leaderboard
});
diff --git a/src/reducers/leaderboard.js b/src/reducers/leaderboard.js
new file mode 100644
index 0000000..0aff26c
--- /dev/null
+++ b/src/reducers/leaderboard.js
@@ -0,0 +1,31 @@
+function leaderboard(state = {
+ 1: {
+ player: "Bear",
+ points: "60"
+ },
+ 2: {
+ player: "Wolf",
+ points: "20"
+ },
+ 3: {
+ player: "Ant",
+ points: "30"
+ },
+ 4: {
+ player: "Bob",
+ points: "300"
+ },
+ 5: {
+ player: "Core",
+ points: "0"
+ }
+}, action) {
+ switch (action.type) {
+ case 'RECEIVE_LEADERBOARD':
+ return action.leaderboard
+ default:
+ return state
+ }
+}
+
+export default leaderboard;
\ No newline at end of file
diff --git a/src/reducers/optionsCategory.js b/src/reducers/optionsCategory.js
new file mode 100644
index 0000000..c677279
--- /dev/null
+++ b/src/reducers/optionsCategory.js
@@ -0,0 +1,11 @@
+function optionsCategory(
+ state = '', action) {
+ switch (action.type) {
+ case 'RECEIVE_OPTIONS_CATEGORY':
+ return action.optionsCategory
+ default:
+ return state
+ }
+}
+
+export default optionsCategory;
\ No newline at end of file
diff --git a/src/reducers/optionsCategoryName.js b/src/reducers/optionsCategoryName.js
new file mode 100644
index 0000000..415de22
--- /dev/null
+++ b/src/reducers/optionsCategoryName.js
@@ -0,0 +1,11 @@
+function optionsCategoryName(
+ state = '', action) {
+ switch (action.type) {
+ case 'RECEIVE_OPTIONS_CATEGORY_NAME':
+ return action.optionsCategoryName
+ default:
+ return state
+ }
+}
+
+export default optionsCategoryName;
\ No newline at end of file
diff --git a/src/reducers/optionsDifficulty.js b/src/reducers/optionsDifficulty.js
new file mode 100644
index 0000000..3faa36c
--- /dev/null
+++ b/src/reducers/optionsDifficulty.js
@@ -0,0 +1,11 @@
+function optionsDifficulty(
+ state = '', action) {
+ switch (action.type) {
+ case 'RECEIVE_OPTIONS_DIFFICULTY':
+ return action.optionsDifficulty
+ default:
+ return state
+ }
+}
+
+export default optionsDifficulty;
\ No newline at end of file
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/quizAnswer.js b/src/reducers/quizAnswer.js
new file mode 100644
index 0000000..9135ad9
--- /dev/null
+++ b/src/reducers/quizAnswer.js
@@ -0,0 +1,10 @@
+function quizAnswer(state = '', action) {
+ switch (action.type) {
+ case 'RECEIVE_ANSWER':
+ return action.questionAnswer
+ default:
+ return state
+ }
+}
+
+export default quizAnswer;
\ No newline at end of file
diff --git a/src/reducers/quizQuestion.js b/src/reducers/quizQuestion.js
new file mode 100644
index 0000000..3f28e1c
--- /dev/null
+++ b/src/reducers/quizQuestion.js
@@ -0,0 +1,10 @@
+function quizQuestion(state = '', action) {
+ switch (action.type) {
+ case 'RECEIVE_QUESTION':
+ return action.quizQuestion
+ default:
+ return state
+ }
+}
+
+export default quizQuestion;
diff --git a/src/reducers/randomArray.js b/src/reducers/randomArray.js
new file mode 100644
index 0000000..f15f2f6
--- /dev/null
+++ b/src/reducers/randomArray.js
@@ -0,0 +1,11 @@
+function randomArray(
+ state = [0, 1, 2, 3], action) {
+ switch (action.type) {
+ case 'ARRAY_RECEIVE':
+ return action.randomArray
+ default:
+ return state
+ }
+}
+
+export default randomArray;
\ No newline at end of file
diff --git a/src/reducers/score.js b/src/reducers/score.js
new file mode 100644
index 0000000..b5b1daf
--- /dev/null
+++ b/src/reducers/score.js
@@ -0,0 +1,10 @@
+function score(score = 0, action) {
+ switch (action.type) {
+ case 'RECEIVE_SCORE':
+ return action.score
+ default:
+ return score
+ }
+}
+
+export default score;
\ No newline at end of file
diff --git a/src/reducers/updateReduxQuestionsAmount.js b/src/reducers/updateReduxQuestionsAmount.js
new file mode 100644
index 0000000..79c0a9d
--- /dev/null
+++ b/src/reducers/updateReduxQuestionsAmount.js
@@ -0,0 +1,11 @@
+function updateReduxQuestionsAmount(
+ state = 10, action) {
+ switch (action.type) {
+ case 'RECEIVE_QUESTION_AMOUNT':
+ return action.updateReduxQuestionsAmount
+ default:
+ return state
+ }
+}
+
+export default updateReduxQuestionsAmount;
\ No newline at end of file
diff --git a/src/reducers/viewMessage.js b/src/reducers/viewMessage.js
new file mode 100644
index 0000000..47c5557
--- /dev/null
+++ b/src/reducers/viewMessage.js
@@ -0,0 +1,10 @@
+function viewMessage(state = false, action) {
+ switch (action.type) {
+ case 'RECEIVE_VIEW_MESSAGE':
+ return action.viewMessage
+ default:
+ return state
+ }
+}
+
+export default viewMessage;
\ No newline at end of file
diff --git a/src/static/styles/_animations.scss b/src/static/styles/_animations.scss
new file mode 100644
index 0000000..96267b2
--- /dev/null
+++ b/src/static/styles/_animations.scss
@@ -0,0 +1,68 @@
+/* originally authored by Dan Eden - https://github.com/daneden/animate.css */
+
+.animated {
+ animation-duration: 1s;
+ animation-fill-mode: both;
+ }
+
+ .animated.infinite {
+ animation-iteration-count: infinite;
+ }
+
+ @keyframes fadeIn {
+ from {
+ opacity: 0;
+ }
+
+ to {
+ opacity: 1;
+ }
+}
+
+.fadeIn {
+ animation-name: fadeIn;
+}
+
+ @keyframes pulse {
+ from {
+ transform: scale3d(1, 1, 1);
+ }
+
+ 50% {
+ transform: scale3d(1.05, 1.05, 1.05);
+ }
+
+ to {
+ transform: scale3d(1, 1, 1);
+ }
+ }
+
+ .pulse {
+ animation-name: pulse;
+ }
+
+@keyframes shake {
+ from,
+ to {
+ transform: translate3d(0, 0, 0);
+ }
+
+ 10%,
+ 30%,
+ 50%,
+ 70%,
+ 90% {
+ transform: translate3d(-3px, 0, 0);
+ }
+
+ 20%,
+ 40%,
+ 60%,
+ 80% {
+ transform: translate3d(3px, 0, 0);
+ }
+ }
+
+ .shake {
+ animation-name: shake;
+ }
\ No newline at end of file
diff --git a/src/static/styles/_colors.scss b/src/static/styles/_colors.scss
new file mode 100644
index 0000000..8c69b9e
--- /dev/null
+++ b/src/static/styles/_colors.scss
@@ -0,0 +1,7 @@
+:root {
+ --primary-color: #27CC92;
+ --secondary-color: #18986B;
+ --tertiary-color: #cf8c00;
+ --correct-answer-color: green;
+ --wrong-answer-color: tomato;
+}
\ No newline at end of file
diff --git a/src/static/styles/_fonts.scss b/src/static/styles/_fonts.scss
new file mode 100644
index 0000000..b3d5ca5
--- /dev/null
+++ b/src/static/styles/_fonts.scss
@@ -0,0 +1,8 @@
+@import url('https://fonts.googleapis.com/css?family=Bitter');
+// font-family: 'Bitter', serif;
+
+@import url('https://fonts.googleapis.com/css?family=Open+Sans');
+//font-family: 'Open Sans', sans-serif;
+
+@import url('https://fonts.googleapis.com/css?family=Dancing+Script');
+//font-family: 'Dancing Script', cursive;
\ No newline at end of file
diff --git a/src/static/styles/_global.scss b/src/static/styles/_global.scss
new file mode 100644
index 0000000..e3a079d
--- /dev/null
+++ b/src/static/styles/_global.scss
@@ -0,0 +1,4 @@
+body {
+ background-color: var(--primary-color);
+ font-family: 'Open Sans', sans-serif;
+}
\ No newline at end of file
diff --git a/src/static/styles/_layout.scss b/src/static/styles/_layout.scss
new file mode 100644
index 0000000..1b2b69d
--- /dev/null
+++ b/src/static/styles/_layout.scss
@@ -0,0 +1,5 @@
+.quiz-wrapper {
+ width: 1200px;
+ max-width: 100%;
+ margin: 0 auto;
+}
\ No newline at end of file
diff --git a/src/static/styles/answers.scss b/src/static/styles/answers.scss
new file mode 100644
index 0000000..9e8719c
--- /dev/null
+++ b/src/static/styles/answers.scss
@@ -0,0 +1,36 @@
+.answers {
+ display: grid;
+ grid-template-columns: 100%;
+ grid-gap: 10px;
+ width: 800px;
+ max-width: 100%;
+ margin-left: auto;
+ margin-right: auto;
+
+ .answers__button {
+ padding: 10px 20px;
+ font-size: 0.9rem;
+ border: none;
+ background-color: #fff;
+ color: var(--background-color);
+
+ &:not([disabled]):hover {
+ cursor: pointer;
+ opacity: .8;
+ }
+
+ &.answers__button--correct-answer {
+ background-color:var(--correct-answer-color);
+ color: #fff;
+ }
+
+ &.answers__button--wrong-answer {
+ background-color:var(--wrong-answer-color);
+ color: #fff;
+ }
+ }
+
+ @media(min-width: 768px){
+ grid-template-columns: 50% 50%;
+ }
+}
\ No newline at end of file
diff --git a/src/static/styles/buttonSkipQuestion.scss b/src/static/styles/buttonSkipQuestion.scss
new file mode 100644
index 0000000..4f52c04
--- /dev/null
+++ b/src/static/styles/buttonSkipQuestion.scss
@@ -0,0 +1,21 @@
+.skip-question {
+ display: flex;
+ justify-content: flex-end;
+
+ .skip-question-button {
+ padding: 10px 20px;
+ background-color: var(--tertiary-color);
+ border: none;
+ color: #fff;
+ margin-top: 20px;
+
+ &:hover {
+ cursor: pointer;
+ opacity: .8;
+ }
+ }
+
+ &.skip-question--hidden {
+ display: none;
+ }
+}
\ No newline at end of file
diff --git a/src/static/styles/header.scss b/src/static/styles/header.scss
new file mode 100644
index 0000000..75277e4
--- /dev/null
+++ b/src/static/styles/header.scss
@@ -0,0 +1,14 @@
+.main-header__logo {
+ font-size: 7rem;
+ text-align: center;
+ color: #fff;
+ font-family: 'Dancing Script', cursive;
+ margin: 0;
+}
+.main-header__subtext {
+ font-size: 1.8rem;
+ text-align: center;
+ color: #fff;
+ font-family: 'Dancing Script', cursive;
+ margin: -20px 0 30px 10px;
+}
\ No newline at end of file
diff --git a/src/static/styles/leaderboard.scss b/src/static/styles/leaderboard.scss
new file mode 100644
index 0000000..8262098
--- /dev/null
+++ b/src/static/styles/leaderboard.scss
@@ -0,0 +1,67 @@
+.leaderboard {
+ padding-bottom: 50px;
+
+ .leaderboard__list{
+ display: table;
+ width: 100%;
+
+ .leaderboard__list--row {
+ display: table-row;
+ }
+
+ .leaderboard__list--cell, .leaderboard__list--head {
+ border-bottom: 1px solid #fff;
+ color: #fff;
+ display: table-cell;
+ padding: 3px 10px;
+ }
+ .leaderboard__list--heading {
+ background-color: #EEE;
+ display: table-header-group;
+ font-weight: bold;
+ }
+ .leaderboard__list--body {
+ display: table-row-group;
+ }
+ }
+
+
+ .leaderboard__form {
+ display: flex;
+ flex-direction: column;
+ padding: 0px 0 40px;
+
+ .leaderboard__form--wrapper {
+ border: 1px solid #fff;
+ }
+
+ &.leaderboard__form--name-added {
+ display: none;
+ }
+
+ .leaderboard__form-input--box {
+ display: flex;
+ margin-top: 20px;
+ }
+
+ .leaderboard__form-input {
+ flex: 1;
+ padding: 8px;
+ border: none;
+ background-color: #fff;
+ box-sizing: border-box;
+ }
+ .leaderboard__form-button {
+ padding: 8px;
+ border: none;
+ background-color: var(--tertiary-color);
+ width: 100px;
+ color: #fff;
+
+ &:hover {
+ cursor: pointer;
+ opacity: .8;
+ }
+ }
+ }
+}
diff --git a/src/static/styles/message.scss b/src/static/styles/message.scss
new file mode 100644
index 0000000..7f5b801
--- /dev/null
+++ b/src/static/styles/message.scss
@@ -0,0 +1,83 @@
+.message {
+ position: fixed;
+ top: 50px;
+ right: 30px;
+ color: #fff;
+ font-size: 19px;
+ transform: rotate(-4deg);
+ font-family: 'Bitter', serif;
+ z-index: 2;
+ width: 50px;
+ height: 50px;
+ border-radius: 5px;
+ z-index: 9999;
+ display: none;
+
+ background-color: var(--wrong-answer-color);
+ &:before {
+ background-color: var(--wrong-answer-color);
+ }
+ &:after {
+ background-color: var(--wrong-answer-color);
+ }
+
+ &.correct {
+ background-color: var(--correct-answer-color);
+ &:before {
+ background-color: var(--correct-answer-color);
+ }
+ &:after {
+ background-color: var(--correct-answer-color);
+ }
+ }
+
+ &.visible {
+ display: block;
+ }
+
+ &:after {
+ content: "";
+ width: 50px;
+ height: 50px;
+ border-radius: 5px;
+ transform: rotate(30deg);
+ position: absolute;
+ top: 0;
+ left: 0;
+ }
+
+ &:before {
+ content: "";
+ width: 50px;
+ height: 50px;
+ border-radius: 5px;
+ transform: rotate(60deg);
+ position: absolute;
+ top: 0;
+ left: 0;
+ }
+
+ .message__text {
+ z-index: 99999;
+ position: fixed;
+ top: 24%;
+ left: 4%;
+ text-align: center;
+ }
+}
+
+.cover {
+ position: fixed;
+ background-color: var(--primary-color);
+ opacity: .1;
+ top: 0;
+ right: 0;
+ bottom: 0;
+ left: 0;
+ z-index: 1;
+ display: none;
+
+ &.visible {
+ display: block;
+ }
+}
\ No newline at end of file
diff --git a/src/static/styles/navigation.scss b/src/static/styles/navigation.scss
new file mode 100644
index 0000000..90aea5a
--- /dev/null
+++ b/src/static/styles/navigation.scss
@@ -0,0 +1,14 @@
+.navigation {
+ display: flex;
+ justify-content: flex-end;
+
+ .navigation__item {
+ color: var(--secondary-color);
+ margin-left: 10px;
+ text-decoration: none;
+
+ &:hover {
+ color: #fff;
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/static/styles/options.scss b/src/static/styles/options.scss
new file mode 100644
index 0000000..9c79aac
--- /dev/null
+++ b/src/static/styles/options.scss
@@ -0,0 +1,83 @@
+.options {
+ // .options__list {
+ // display: none;
+
+ // &.visible {
+ // display: block;
+ // }
+ // }
+
+ .options__toggle {
+ display: flex;
+ justify-content: flex-end;
+
+ .options__toggle__button {
+ background: none;
+ border: none;
+ font-size: 0.9rem;
+ padding: 0;
+ margin-bottom: 10px;
+ color: #fff;
+
+ // &:hover {
+ // cursor: pointer;
+ // opacity: .8;
+ // }
+ }
+ }
+
+ .options__button-update {
+ padding: 10px 20px;
+ background-color: var(--tertiary-color);
+ border: none;
+ color: #fff;
+ margin-bottom: 20px;
+ width: 100%;
+
+ &:hover {
+ cursor: pointer;
+ opacity: .8;
+ }
+ }
+}
+
+.custom-select {
+ background-color: var(--secondary-color);
+ border: 0;
+ overflow: hidden;
+ width: 100%;
+ height: 35px;
+ position: relative;
+ margin-bottom: 10px;
+
+ &:after {
+ content: "▾";
+ position: absolute;
+ right: 10px;
+ top: 5px;
+ color: var(--primary-color);
+ }
+
+ select {
+ padding: 8px;
+ width: 100%;
+ border: none;
+ box-shadow: none;
+ background: transparent;
+ background-image: none;
+ -webkit-appearance: none;
+ -moz-appearance: none;
+ appearance: none;
+ color: #fff;
+ font-size: 0.8rem;
+
+ &:focus {
+ border: 0;
+ box-shadow: none !important;
+ }
+
+ option {
+ width: 100%;
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/static/styles/question.scss b/src/static/styles/question.scss
new file mode 100644
index 0000000..2a6cbc8
--- /dev/null
+++ b/src/static/styles/question.scss
@@ -0,0 +1,19 @@
+.question {
+ .question__text {
+ text-align: center;
+ font-size: 1.8rem;
+ color: var(--secondary-color);
+ position: relative;
+ font-family: 'Bitter', serif;
+
+ &::before {
+ content: "Q";
+ position: absolute;
+ font-size: 6rem;
+ top: -30px;
+ left: -6px;
+ opacity: 0.3;
+
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/static/styles/score.scss b/src/static/styles/score.scss
new file mode 100644
index 0000000..08283dd
--- /dev/null
+++ b/src/static/styles/score.scss
@@ -0,0 +1,20 @@
+.score {
+ display: flex;
+ justify-content: space-between;
+
+ background-color: #dff0d8;
+ padding: 2px 5px;
+ color: var(--secondary-color);
+
+ .score__text {
+ display: flex;
+ flex-direction: column;
+ text-align: right;
+ }
+
+ .category {
+ display: flex;
+ flex-direction: column;
+ font-size: 0.9rem;
+ }
+}
\ No newline at end of file
diff --git a/src/static/styles/style.scss b/src/static/styles/style.scss
new file mode 100644
index 0000000..f097e2f
--- /dev/null
+++ b/src/static/styles/style.scss
@@ -0,0 +1,5 @@
+@import './_fonts';
+@import './_colors';
+@import './_layout';
+@import './_global';
+@import './_animations';
\ No newline at end of file
diff --git a/style.css b/style.css
index d9bbbe0..e69de29 100644
--- a/style.css
+++ b/style.css
@@ -1,15 +0,0 @@
-.voting-button {
- color: #550527;
- font-size: 24px;
- padding: 10px;
- margin: 10px;
- border-radius: 5px;
- background-color: white;
- border: 2px solid #550527;
-}
-
-.voting-button--selected {
- color: #FFF;
- background-color: #550527;
- border: 2px solid white;
-}
diff --git a/views/index.hbs b/views/index.hbs
new file mode 100644
index 0000000..262adbe
--- /dev/null
+++ b/views/index.hbs
@@ -0,0 +1,16 @@
+
+
+
+
+
Quiz Machine
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/webpack.config.js b/webpack.config.js
index 9355dc3..535a579 100644
--- a/webpack.config.js
+++ b/webpack.config.js
@@ -13,6 +13,18 @@ module.exports = {
test: /\.js$/,
exclude: /(node_modules)/,
loader: require.resolve('babel-loader')
+ },
+ {
+ test: /\.scss$/,
+ use: [
+ {
+ loader: "style-loader"
+ }, {
+ loader: "css-loader"
+ }, {
+ loader: "sass-loader"
+ }
+ ]
}
]
}