+ justified={ true }
+ >
diff --git a/common/app/routes/challenges/redux/next-challenge-saga.js b/common/app/routes/challenges/redux/next-challenge-saga.js
index 6403045292..06a15c11d8 100644
--- a/common/app/routes/challenges/redux/next-challenge-saga.js
+++ b/common/app/routes/challenges/redux/next-challenge-saga.js
@@ -1,24 +1,68 @@
import { Observable } from 'rx';
import { push } from 'react-router-redux';
import { moveToNextChallenge } from './types';
-import { getNextChallenge } from '../utils';
import { resetUi, updateCurrentChallenge } from './actions';
-// import { createErrorObservable, makeToast } from '../../../redux/actions';
+import { createErrorObservable, makeToast } from '../../../redux/actions';
+import {
+ getNextChallenge,
+ getFirstChallengeOfNextBlock,
+ getFirstChallengeOfNextSuperBlock
+} from '../utils';
+import { getRandomVerb } from '../../../utils/get-words';
export default function nextChallengeSaga(actions$, getState) {
return actions$
.filter(({ type }) => type === moveToNextChallenge)
.flatMap(() => {
- const state = getState();
- const nextChallenge = getNextChallenge(
- state.challengesApp.challenge,
- state.entities,
- state.challengesApp.superBlocks
- );
- return Observable.of(
- updateCurrentChallenge(nextChallenge),
- resetUi(),
- push(`/challenges/${nextChallenge.block}/${nextChallenge.dashedName}`)
- );
+ let nextChallenge;
+ // let message = '';
+ // let isNewBlock = false;
+ // let isNewSuperBlock = false;
+ try {
+ const state = getState();
+ const { challenge, superBlocks } = state.challengesApp;
+ const { entities } = state;
+ nextChallenge = getNextChallenge(challenge, entities);
+ // block completed.
+ if (!nextChallenge) {
+ // isNewBlock = true;
+ nextChallenge = getFirstChallengeOfNextBlock(challenge, entities);
+ }
+ // superBlock completed
+ if (!nextChallenge) {
+ // isNewSuperBlock = true;
+ nextChallenge = getFirstChallengeOfNextSuperBlock(
+ challenge,
+ entities,
+ superBlocks
+ );
+ }
+ /* this requires user data not available yet
+ if (isNewSuperBlock || isNewBlock) {
+ const getName = isNewSuperBlock ?
+ getCurrentSuperBlockName :
+ getCurrentBlockName;
+ const blockType = isNewSuperBlock ? 'SuperBlock' : 'Block';
+ message =
+ `You've competed the ${getName(challenge, entities)} ${blockType}!`;
+ }
+ message += ' Your next challenge has arrived.';
+ const toast = {
+ // title: isNewSuperBlock || isNewBlock ? getRandomVerb() : null,
+ message
+ };
+ */
+ return Observable.of(
+ updateCurrentChallenge(nextChallenge),
+ resetUi(),
+ makeToast({
+ title: getRandomVerb(),
+ message: 'Your next challenge has arrived.'
+ }),
+ push(`/challenges/${nextChallenge.block}/${nextChallenge.dashedName}`)
+ );
+ } catch (err) {
+ return createErrorObservable(err);
+ }
});
}
diff --git a/common/app/routes/challenges/redux/reducer.js b/common/app/routes/challenges/redux/reducer.js
index 9fce3e35b8..f224ec9801 100644
--- a/common/app/routes/challenges/redux/reducer.js
+++ b/common/app/routes/challenges/redux/reducer.js
@@ -15,7 +15,12 @@ const initialUiState = {
currentIndex: 0,
previousIndex: -1,
isActionCompleted: false,
- isSubmitting: true
+ isSubmitting: true,
+ output: `/**
+ * Any console.log()
+ * statements will appear in
+ * here console.
+ */`
};
const initialState = {
id: '',
diff --git a/common/app/routes/challenges/utils.js b/common/app/routes/challenges/utils.js
index 74da4aebce..dff8cfffdd 100644
--- a/common/app/routes/challenges/utils.js
+++ b/common/app/routes/challenges/utils.js
@@ -91,20 +91,80 @@ export function getFirstChallenge(
];
}
-export function getNextChallenge(
- current,
- entites,
- superBlocks
-) {
+export function getNextChallenge(current, entites) {
const { challenge: challengeMap, block: blockMap } = entites;
// find current challenge
// find current block
// find next challenge in block
const currentChallenge = challengeMap[current];
- if (currentChallenge) {
- const block = blockMap[currentChallenge.block];
- const index = block.challenges.indexOf(currentChallenge.dashedName);
- return challengeMap[block.challenges[index + 1]];
+ if (!currentChallenge) {
+ return null;
}
- return getFirstChallenge(entites, superBlocks);
+ const block = blockMap[currentChallenge.block];
+ const index = block.challenges.indexOf(currentChallenge.dashedName);
+ return challengeMap[block.challenges[index + 1]];
+}
+
+export function getFirstChallengeOfNextBlock(current, entites) {
+ const {
+ challenge: challengeMap,
+ block: blockMap,
+ superBlock: SuperBlockMap
+ } = entites;
+ const currentChallenge = challengeMap[current];
+ if (!currentChallenge) {
+ return null;
+ }
+ const block = blockMap[currentChallenge.block];
+ if (!block) {
+ return null;
+ }
+ const superBlock = SuperBlockMap[block.superBlock];
+ const index = superBlock.blocks.indexOf(block.dashedName);
+ const newBlock = superBlock.blocks[ index + 1 ];
+ if (!newBlock) {
+ return null;
+ }
+ return challengeMap[newBlock.challenges[0]];
+}
+
+export function getFirstChallengeOfNextSuperBlock(
+ current,
+ entites,
+ superBlocks
+) {
+ const {
+ challenge: challengeMap,
+ block: blockMap,
+ superBlock: SuperBlockMap
+ } = entites;
+ const currentChallenge = challengeMap[current];
+ if (!currentChallenge) {
+ return null;
+ }
+ const block = blockMap[currentChallenge.block];
+ if (!block) {
+ return null;
+ }
+ const superBlock = SuperBlockMap[block.superBlock];
+ const index = superBlocks.indexOf(superBlock.dashedName);
+ const newSuperBlock = SuperBlockMap[superBlocks[ index + 1]];
+ if (!newSuperBlock) {
+ return null;
+ }
+ const newBlock = blockMap[newSuperBlock.blocks[0]];
+ return challengeMap[newBlock.challenges[0]];
+}
+
+export function getCurrentBlockName(current, entities) {
+ const { challenge: challengeMap } = entities;
+ const challenge = challengeMap[current];
+ return challenge.block;
+}
+
+export function getCurrentSuperBlockName(current, entities) {
+ const { challenge: challengeMap, block: blockMap } = entities;
+ const challenge = challengeMap[current];
+ const block = blockMap[challenge.block];
+ return block.superBlock;
}
diff --git a/seed/challenges/01-front-end-development-certification/html5-and-css.json b/seed/challenges/01-front-end-development-certification/html5-and-css.json
index 30a9bc002e..37159cfcce 100644
--- a/seed/challenges/01-front-end-development-certification/html5-and-css.json
+++ b/seed/challenges/01-front-end-development-certification/html5-and-css.json
@@ -265,7 +265,7 @@
"assert($(\"h1\").length > 0, 'message: Make your h1 element visible on your page by uncommenting it.');",
"assert($(\"h2\").length > 0, 'message: Make your h2 element visible on your page by uncommenting it.');",
"assert($(\"p\").length > 0, 'message: Make your p element visible on your page by uncommenting it.');",
- "assert(!/-->/gi.test(code.replace(/ */gi.test(code.replace(/ */g).length > 1, 'message: Be sure to close each of your comments with -->.');",
+ "assert(code.match(/[^fc]-->/g).length > 1, 'message: Be sure to close each of your comments with -->.');",
"assert((code.match(/<([a-z0-9]){1,2}>/g)[0]===\"
\" && code.match(/<([a-z0-9]){1,2}>/g)[1]===\"
\" && code.match(/<([a-z0-9]){1,2}>/g)[2]===\"
\") , 'message: Do not change the order of the h1h2 or p in the code.');"
],
"type": "waypoint",
@@ -1071,8 +1071,8 @@
"tests": [
"assert($(\"h2\").css(\"font-family\").match(/^\"?lobster/i), 'message: Your h2 element should use the font Lobster.');",
"assert($(\"h2\").css(\"font-family\").match(/lobster.*,.*monospace/i), 'message: Your h2 element should degrade to the font Monospace when Lobster is not available.');",
- "assert(new RegExp(\"\", \"gi\").test(code), 'message: Be sure to close your comment by adding -->.');"
+ "assert(new RegExp(\"\", \"gi\").test(code), 'message: Be sure to close your comment by adding -->.');"
],
"type": "waypoint",
"titleEs": "Especifica cómo deben degradarse los tipos de letra",