diff --git a/src/App.component.js b/src/App.component.js index 2a28801..41e901c 100644 --- a/src/App.component.js +++ b/src/App.component.js @@ -4,7 +4,13 @@ import { BrowserRouter as Router, Route, Switch } from 'react-router-dom'; import './App.css'; -import { Quiz, Completed } from 'src/components'; +import { + Quiz, + Completed, + Landing, + NameCapture, + EmailCapture, +} from 'src/components'; class App extends Component { render() { @@ -12,7 +18,10 @@ class App extends Component {
- + + + +
diff --git a/src/components/Checkbox/Checkbox.component.js b/src/components/Checkbox/Checkbox.component.js index 75623e5..20fc212 100644 --- a/src/components/Checkbox/Checkbox.component.js +++ b/src/components/Checkbox/Checkbox.component.js @@ -7,7 +7,7 @@ import PropTypes from 'prop-types'; import './Checkbox.css'; -const greenCheckmark = require('./check.svg'); +const greenCheckmark = require('../../images/check.svg'); type CheckboxProps = { onChange: Function, diff --git a/src/components/Completed/CompletedResultsList/CompletedResultsList.component.js b/src/components/Completed/CompletedResultsList/CompletedResultsList.component.js index 0f6a388..6588844 100644 --- a/src/components/Completed/CompletedResultsList/CompletedResultsList.component.js +++ b/src/components/Completed/CompletedResultsList/CompletedResultsList.component.js @@ -12,9 +12,9 @@ import { Question, Answer, CodeFigure } from 'src/components'; import './CompletedResultsList.css'; -const greenCheckmark = require('./green-checkmark.svg'); +const greenCheckmark = require('../../../images/green-checkmark.svg'); -const redX = require('./red-x.svg'); +const redX = require('../../../images/red-x.svg'); export default class CompletedResultsList extends PureComponent { static propTypes = { diff --git a/src/components/EmailCapture/EmailCapture/EmailCapture.component.js b/src/components/EmailCapture/EmailCapture/EmailCapture.component.js index 3a2881d..840d98d 100644 --- a/src/components/EmailCapture/EmailCapture/EmailCapture.component.js +++ b/src/components/EmailCapture/EmailCapture/EmailCapture.component.js @@ -6,12 +6,26 @@ import { SubscribeToMailingListCheckbox, } from 'src/components'; +import PropTypes from 'prop-types'; + import './EmailCapture.css'; export default class EmailCapture extends PureComponent { + static propTypes = { + onSubmit: PropTypes.func.isRequired, + }; + + handleOnSubmit = (e) => { + const { onSubmit } = this.props; + + e.preventDefault(); + + onSubmit(); + }; + render() { return ( -
+

{`Ready to find out if you have what it takes to develop @@ -31,7 +45,7 @@ export default class EmailCapture extends PureComponent {

- + ); } } diff --git a/src/components/EmailCapture/EmailCapture/EmailCapture.container.js b/src/components/EmailCapture/EmailCapture/EmailCapture.container.js new file mode 100644 index 0000000..9b02931 --- /dev/null +++ b/src/components/EmailCapture/EmailCapture/EmailCapture.container.js @@ -0,0 +1,9 @@ +import { connect } from 'react-redux'; + +import EmailCapture from './EmailCapture.component'; + +import { submitQuizAction as onSubmit } from 'src/store/quiz/quiz.actions'; + +export default connect(null, { + onSubmit, +})(EmailCapture); diff --git a/src/components/EmailCapture/EmailCapture/index.js b/src/components/EmailCapture/EmailCapture/index.js index 840da0a..0966acc 100644 --- a/src/components/EmailCapture/EmailCapture/index.js +++ b/src/components/EmailCapture/EmailCapture/index.js @@ -1 +1 @@ -export { default as EmailCapture } from './EmailCapture.component'; +export { default as EmailCapture } from './EmailCapture.container'; diff --git a/src/components/Landing/Landing/Landing.component.js b/src/components/Landing/Landing/Landing.component.js new file mode 100644 index 0000000..0189c3a --- /dev/null +++ b/src/components/Landing/Landing/Landing.component.js @@ -0,0 +1,46 @@ +import * as React from 'react'; + +import { LandingGetStartedButton } from 'src/components'; + +import './Landing.css'; + +export default class Landing extends React.PureComponent { + render() { + return ( +
+
+

+ Do You Have What It Takes To Develop Mobile Apps? +

+

+ Note: This assessment is for developers who already have + a basic understanding of HTML, CSS and Javascript. To + get the most accurate results, use your current + knowledge and skills to answer each question to the best + of your ability, and avoid looking things up online. +

+

+ Don't worry about getting every answer correct. The + questions range in subject matter and difficulty to + accurately assess your readiness to successfully learn + mobile app development and determine the right next + steps for you should take to get started. +

+
+ +
+
+
+ {'iPhone +
+
+ ); + } +} diff --git a/src/components/Landing/Landing/Landing.css b/src/components/Landing/Landing/Landing.css new file mode 100644 index 0000000..24205b0 --- /dev/null +++ b/src/components/Landing/Landing/Landing.css @@ -0,0 +1,48 @@ +.Landing { + display: flex; +} + +.Landing__main-content { + margin-right: 100px; +} + +@media (max-width: 767px) { + .Landing__main-content { + margin-right: 0; + } +} + +.Landing__start-button { + margin-top: 24px; +} + +.Landing__title { + margin-top: 120px; + font-size: 3.2rem; + line-height: 4.2rem; + font-weight: 800; + margin-bottom: 20px; +} + +.Landing__image { + flex-shrink: 0; + width: 40.4980237%; + position: relative; + display: flex; + align-items: center; + justify-content: center; + margin-right: 24px; +} + +@media (max-width: 767px) { + .Landing__image { + display: none; + } +} + + +.Landing__devices { + display: block; + width: 100%; + height: auto; +} diff --git a/src/components/Landing/Landing/index.js b/src/components/Landing/Landing/index.js new file mode 100644 index 0000000..c76fd14 --- /dev/null +++ b/src/components/Landing/Landing/index.js @@ -0,0 +1 @@ +export { default as Landing } from './Landing.component'; diff --git a/src/components/Landing/LandingGetStartedButton/LandingGetStartedButton.component.js b/src/components/Landing/LandingGetStartedButton/LandingGetStartedButton.component.js new file mode 100644 index 0000000..dc9263e --- /dev/null +++ b/src/components/Landing/LandingGetStartedButton/LandingGetStartedButton.component.js @@ -0,0 +1,15 @@ +import * as React from 'react'; + +import PropTypes from 'prop-types'; + +import { ActionButton } from 'src/components'; + +export default class LandingGetStartedButton extends React.PureComponent { + static propTypes = { + onClick: PropTypes.func.isRequired, + }; + + render() { + return Get Started; + } +} diff --git a/src/components/Landing/LandingGetStartedButton/LandingGetStartedButton.container.js b/src/components/Landing/LandingGetStartedButton/LandingGetStartedButton.container.js new file mode 100644 index 0000000..ce30449 --- /dev/null +++ b/src/components/Landing/LandingGetStartedButton/LandingGetStartedButton.container.js @@ -0,0 +1,13 @@ +import { connect } from 'react-redux'; + +import { withRouter } from 'react-router-dom'; + +import { startQuizAction } from 'src/store/quiz/quiz.actions'; + +import LandingGetStartedButton from './LandingGetStartedButton.component'; + +export default withRouter( + connect(null, (dispatch, { history }) => ({ + onClick: () => dispatch(startQuizAction(history)), + }))(LandingGetStartedButton) +); diff --git a/src/components/Landing/LandingGetStartedButton/index.js b/src/components/Landing/LandingGetStartedButton/index.js new file mode 100644 index 0000000..f628f96 --- /dev/null +++ b/src/components/Landing/LandingGetStartedButton/index.js @@ -0,0 +1,3 @@ +export { + default as LandingGetStartedButton, +} from './LandingGetStartedButton.container'; diff --git a/src/components/Landing/index.js b/src/components/Landing/index.js new file mode 100644 index 0000000..5855e3f --- /dev/null +++ b/src/components/Landing/index.js @@ -0,0 +1,2 @@ +export * from './Landing'; +export * from './LandingGetStartedButton'; diff --git a/src/components/NameCapture/NameCapture/NameCapture.component.js b/src/components/NameCapture/NameCapture/NameCapture.component.js index 3f6ee79..f21b96e 100644 --- a/src/components/NameCapture/NameCapture/NameCapture.component.js +++ b/src/components/NameCapture/NameCapture/NameCapture.component.js @@ -3,6 +3,7 @@ import React, { PureComponent } from 'react'; import { NameCaptureNameInput, NameCaptureContinueButton, + QuizTitle, } from 'src/components'; import './NameCapture.css'; @@ -11,14 +12,17 @@ export default class NameCapture extends PureComponent { render() { return (
-
-

- {'What\'s your first name?'} -

-
- -
- + +
+
+

+ {'What\'s your first name?'} +

+
+ +
+ +
diff --git a/src/components/NameCapture/NameCapture/NameCapture.css b/src/components/NameCapture/NameCapture/NameCapture.css index 60fa9e0..e739574 100644 --- a/src/components/NameCapture/NameCapture/NameCapture.css +++ b/src/components/NameCapture/NameCapture/NameCapture.css @@ -1,4 +1,8 @@ .NameCapture { + flex: 1 +} + +.NameCapture__container { flex: 1; display: flex; flex-direction: column; diff --git a/src/components/Quiz/Quiz.component.js b/src/components/Quiz/Quiz.component.js index b022e4a..5b59c0d 100644 --- a/src/components/Quiz/Quiz.component.js +++ b/src/components/Quiz/Quiz.component.js @@ -1,77 +1,29 @@ import React, { PureComponent } from 'react'; -import PropTypes from 'prop-types'; - -import { - QuizQuestion, - QuizProgressIndicator, - NameCapture, - EmailCapture, -} from 'src/components'; +import { QuizQuestion, QuizProgressIndicator, QuizTitle } from 'src/components'; import { questions } from 'src/questions'; import './Quiz.css'; export default class Quiz extends PureComponent { - static propTypes = { - state: PropTypes.string.isRequired, - onSubmit: PropTypes.func.isRequired, - quizComplete: PropTypes.bool.isRequired, - }; - - handleOnSubmit = (e) => { - const { onSubmit, quizComplete, history } = this.props; - - e.preventDefault(); - - if (!quizComplete) { - return false; - } else { - onSubmit(history); - } - }; - render() { - const { state } = this.props; - - let content =
; - - switch (state) { - case 'nameCapture': - content = ; - break; - - case 'emailCapture': - content = ; - break; - - case 'question': - content = ( -
-
- -
- {questions.map((question, i) => ( - - ))} -
- ); - break; - - default: - content =
; - } - return ( -
-

Javascript Quiz

-
{content}
-
+
+ +
+
+ +
+ {questions.map((question, i) => ( + + ))} +
+
); } } diff --git a/src/components/Quiz/Quiz.container.js b/src/components/Quiz/Quiz.container.js deleted file mode 100644 index 5880619..0000000 --- a/src/components/Quiz/Quiz.container.js +++ /dev/null @@ -1,26 +0,0 @@ -import { connect } from 'react-redux'; - -import { withRouter } from 'react-router-dom'; - -import { quizStateSelector, quizIsCompleteSelector } from 'src/selectors'; - -import { submitQuizAction as onSubmit } from 'src/store/quiz/quiz.actions'; - -import Quiz from './Quiz.component'; - -export default withRouter( - connect( - (st) => { - const state = quizStateSelector(st); - const quizComplete = quizIsCompleteSelector(st); - - return { - state, - quizComplete, - }; - }, - { - onSubmit, - } - )(Quiz) -); diff --git a/src/components/Quiz/Quiz.css b/src/components/Quiz/Quiz.css index 46c84e6..ca968d8 100644 --- a/src/components/Quiz/Quiz.css +++ b/src/components/Quiz/Quiz.css @@ -9,22 +9,6 @@ } } -.Quiz__title { - font-size: 2.4rem; - line-height: 1; - color: var(--very-dark-blue); - font-weight: 700; - padding: 35px 0; - margin-bottom: 20px; -} - -@media (max-width: 600px) { - .Quiz__title { - font-size: 2rem; - padding: 25px 0; - } -} - .Quiz__progress-indicator { position: absolute; top: 0; diff --git a/src/components/Quiz/index.js b/src/components/Quiz/index.js index 07f08ac..575415a 100644 --- a/src/components/Quiz/index.js +++ b/src/components/Quiz/index.js @@ -1 +1 @@ -export { default as Quiz } from './Quiz.container'; +export { default as Quiz } from './Quiz.component'; diff --git a/src/components/QuizProgressIndicator/QuizProgressIndicator.component.js b/src/components/QuizProgressIndicator/QuizProgressIndicator.component.js index 3959863..ecb4229 100644 --- a/src/components/QuizProgressIndicator/QuizProgressIndicator.component.js +++ b/src/components/QuizProgressIndicator/QuizProgressIndicator.component.js @@ -2,7 +2,7 @@ import React, { PureComponent } from 'react'; import PropTypes from 'prop-types'; -import bg from './progress-indicator-bg.svg'; +import bg from '../../images/shield.svg'; import './QuizProgressIndicator.css'; diff --git a/src/components/QuizProgressIndicator/progress-indicator-bg.png b/src/components/QuizProgressIndicator/progress-indicator-bg.png deleted file mode 100644 index 5fa6b78..0000000 Binary files a/src/components/QuizProgressIndicator/progress-indicator-bg.png and /dev/null differ diff --git a/src/components/QuizQuestion/QuizQuestion.component.js b/src/components/QuizQuestion/QuizQuestion.component.js index f5d2d28..f4e7ba1 100644 --- a/src/components/QuizQuestion/QuizQuestion.component.js +++ b/src/components/QuizQuestion/QuizQuestion.component.js @@ -50,7 +50,7 @@ export default class QuizQuestion extends PureComponent { const active = userAnswers.length + 1 === questionNumber; const questionClasses = classNames('QuizQuestion', { - 'visuallyhidden': !active, + visuallyhidden: !active, }); const answerListClasses = classNames('QuizQuestion__answers-list', { diff --git a/src/components/QuizTitle/QuizTitle.component.js b/src/components/QuizTitle/QuizTitle.component.js new file mode 100644 index 0000000..4883403 --- /dev/null +++ b/src/components/QuizTitle/QuizTitle.component.js @@ -0,0 +1,9 @@ +import * as React from 'react'; + +import './QuizTitle.css'; + +export default class QuizTitle extends React.PureComponent { + render() { + return

Javascript Quiz

; + } +} diff --git a/src/components/QuizTitle/QuizTitle.css b/src/components/QuizTitle/QuizTitle.css new file mode 100644 index 0000000..cd0b72b --- /dev/null +++ b/src/components/QuizTitle/QuizTitle.css @@ -0,0 +1,15 @@ +.Quiz__title { + font-size: 2.4rem; + line-height: 1; + color: var(--very-dark-blue); + font-weight: 700; + padding: 35px 0; + margin-bottom: 20px; +} + +@media (max-width: 600px) { + .Quiz__title { + font-size: 2rem; + padding: 25px 0; + } +} diff --git a/src/components/QuizTitle/index.js b/src/components/QuizTitle/index.js new file mode 100644 index 0000000..6e5ce9d --- /dev/null +++ b/src/components/QuizTitle/index.js @@ -0,0 +1 @@ +export { default as QuizTitle } from './QuizTitle.component'; diff --git a/src/components/index.js b/src/components/index.js index 3eb7fde..9cc7c36 100644 --- a/src/components/index.js +++ b/src/components/index.js @@ -5,11 +5,13 @@ export * from './Checkbox'; export * from './CodeFigure'; export * from './Completed'; export * from './EmailCapture'; +export * from './Landing'; export * from './NameCapture'; export * from './Question'; export * from './QuestionAnswer'; export * from './Quiz'; export * from './QuizProgressIndicator'; export * from './QuizQuestion'; +export * from './QuizTitle'; export * from './SubscribeToMailingListCheckbox'; export * from './TextInput'; diff --git a/src/components/Checkbox/check.svg b/src/images/check.svg similarity index 100% rename from src/components/Checkbox/check.svg rename to src/images/check.svg diff --git a/src/images/devices-and-shield.svg b/src/images/devices-and-shield.svg new file mode 100644 index 0000000..b137c70 --- /dev/null +++ b/src/images/devices-and-shield.svg @@ -0,0 +1,90 @@ + + + + Group 16 + Created with Sketch. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/components/Completed/CompletedResultsList/green-checkmark.svg b/src/images/green-checkmark.svg similarity index 100% rename from src/components/Completed/CompletedResultsList/green-checkmark.svg rename to src/images/green-checkmark.svg diff --git a/src/components/Completed/CompletedResultsList/red-x.svg b/src/images/red-x.svg similarity index 100% rename from src/components/Completed/CompletedResultsList/red-x.svg rename to src/images/red-x.svg diff --git a/src/components/QuizProgressIndicator/progress-indicator-bg.svg b/src/images/shield.svg similarity index 100% rename from src/components/QuizProgressIndicator/progress-indicator-bg.svg rename to src/images/shield.svg diff --git a/src/store/quiz/quiz.actions.js b/src/store/quiz/quiz.actions.js index 40ab520..65e95f4 100644 --- a/src/store/quiz/quiz.actions.js +++ b/src/store/quiz/quiz.actions.js @@ -16,13 +16,6 @@ import { fireFetch } from 'src/services/firebase.service'; import { getRating } from 'firebaseFunctions/services/scoring.service'; -export const setStateAction = (state) => ({ - type: 'SET_QUIZ_STATE', - payload: { - state, - }, -}); - export const setSelectedAnswerAction = (selectedAnswer) => ({ type: 'SET_QUIZ_SELECTED_ANSWER', payload: { @@ -63,8 +56,15 @@ export const submitNameAction = () => ({ type: 'SUBMIT_NAME', }); +export const startQuizAction = (history) => ({ + type: 'START_QUIZ', + payload: { + history, + }, +}); + export const submitQuizAction = (history) => ({ - type: 'SUBMIT_QUIZ_ACTION', + type: 'SUBMIT_QUIZ', payload: { history, }, @@ -111,9 +111,13 @@ function* submitQuiz() { } export default function*() { + const { payload: { history } } = yield take(startQuizAction().type); + + yield call(history.push, '/name'); + yield take(submitNameAction().type); - yield put(setStateAction('question')); + yield call(history.push, '/questions'); for (let i = 0; i < questions.length; i++) { yield take(setSelectedAnswerAction().type); @@ -123,9 +127,9 @@ export default function*() { yield* addAnswer(); } - yield put(setStateAction('emailCapture')); + yield call(history.push, '/email'); - const { payload: { history } } = yield take(submitQuizAction().type); + yield take(submitQuizAction().type); yield fork(submitQuiz); diff --git a/src/store/quiz/quiz.reducer.js b/src/store/quiz/quiz.reducer.js index 8b3e3da..c7b6d6c 100644 --- a/src/store/quiz/quiz.reducer.js +++ b/src/store/quiz/quiz.reducer.js @@ -1,5 +1,4 @@ import { - setStateAction, setSelectedAnswerAction, addAnswerAction, setNameAction, @@ -11,7 +10,6 @@ import { createReducer } from 'src/helpers'; export default createReducer( { - state: 'nameCapture', selectedAnswer: null, answers: [], email: '', @@ -19,10 +17,6 @@ export default createReducer( subscribedToMailingList: false, }, { - [setStateAction().type]: (st, { state }) => ({ - ...st, - state, - }), [setSelectedAnswerAction().type]: (st, { selectedAnswer }) => ({ ...st, selectedAnswer,