mirror of
https://github.com/freeCodeCamp/freeCodeCamp.git
synced 2026-05-28 18:26:54 +00:00
feat(UI): take back to learn map after finishing a block (#50011)
Co-authored-by: moT01 <20648924+moT01@users.noreply.github.com>
This commit is contained in:
@@ -188,8 +188,14 @@ export default function completionEpic(action$, state$) {
|
||||
switchMap(({ type }) => {
|
||||
const state = state$.value;
|
||||
|
||||
const { nextChallengePath, challengeType, superBlock, block } =
|
||||
challengeMetaSelector(state);
|
||||
const {
|
||||
nextChallengeMeta: { block: nextBlock },
|
||||
nextChallengePath,
|
||||
challengeType,
|
||||
superBlock,
|
||||
block,
|
||||
blockHashSlug
|
||||
} = challengeMetaSelector(state);
|
||||
|
||||
let submitter = () => of({ type: 'no-user-signed-in' });
|
||||
if (
|
||||
@@ -206,19 +212,17 @@ export default function completionEpic(action$, state$) {
|
||||
submitter = submitters[submitTypes[challengeType]];
|
||||
}
|
||||
|
||||
const isNextChallengeInSameSuperBlock =
|
||||
nextChallengePath.includes(superBlock);
|
||||
|
||||
const pathToNavigateTo = isNextChallengeInSameSuperBlock
|
||||
? nextChallengePath
|
||||
: `/learn/${superBlock}/#${superBlock}-projects`;
|
||||
const lastChallengeInBlock = block !== nextBlock;
|
||||
let pathToNavigateTo = lastChallengeInBlock
|
||||
? blockHashSlug
|
||||
: nextChallengePath;
|
||||
|
||||
const canAllowDonationRequest = (state, action) =>
|
||||
isBlockNewlyCompletedSelector(state) &&
|
||||
action.type === submitActionTypes.submitComplete;
|
||||
|
||||
return submitter(type, state).pipe(
|
||||
concat(of(setIsAdvancing(isNextChallengeInSameSuperBlock))),
|
||||
concat(of(setIsAdvancing(!lastChallengeInBlock))),
|
||||
mergeMap(x =>
|
||||
canAllowDonationRequest(state, x)
|
||||
? of(x, allowBlockDonationRequests({ superBlock, block }))
|
||||
|
||||
@@ -20,7 +20,13 @@ const initialState = {
|
||||
challengeMeta: {
|
||||
superBlock: '',
|
||||
block: '',
|
||||
blockHashSlug: '/',
|
||||
id: '',
|
||||
nextChallengeMeta: {
|
||||
superBlock: '',
|
||||
block: '',
|
||||
blockHashSlug: '/'
|
||||
},
|
||||
nextChallengePath: '/',
|
||||
prevChallengePath: '/',
|
||||
challengeType: -1
|
||||
|
||||
@@ -75,6 +75,31 @@ function getTemplateComponent(challengeType) {
|
||||
return views[viewTypes[challengeType]];
|
||||
}
|
||||
|
||||
function getNextChallengeMeta(_node, index, nodeArray) {
|
||||
const next = nodeArray[index + 1];
|
||||
if (next) {
|
||||
const { superBlock, block } = next.node.challenge;
|
||||
return {
|
||||
superBlock,
|
||||
block,
|
||||
blockHashSlug: createBlockHashSlug(_node)
|
||||
};
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
function createBlockHashSlug(_node) {
|
||||
if (_node) {
|
||||
const {
|
||||
block,
|
||||
fields: { slug }
|
||||
} = _node;
|
||||
const re = new RegExp(`${block}.*`);
|
||||
return slug.replace(re, `#${block}`);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
exports.createChallengePages = function (createPage) {
|
||||
return function ({ node: { challenge } }, index, allChallengeEdges) {
|
||||
const {
|
||||
@@ -96,6 +121,7 @@ exports.createChallengePages = function (createPage) {
|
||||
component: getTemplateComponent(challengeType),
|
||||
context: {
|
||||
challengeMeta: {
|
||||
blockHashSlug: createBlockHashSlug(challenge),
|
||||
dashedName,
|
||||
certification,
|
||||
superBlock,
|
||||
@@ -103,6 +129,11 @@ exports.createChallengePages = function (createPage) {
|
||||
isFirstStep: getIsFirstStep(challenge, index, allChallengeEdges),
|
||||
template,
|
||||
required,
|
||||
nextChallengeMeta: getNextChallengeMeta(
|
||||
challenge,
|
||||
index,
|
||||
allChallengeEdges
|
||||
),
|
||||
nextChallengePath: getNextChallengePath(
|
||||
challenge,
|
||||
index,
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
// middle of block
|
||||
const challenge1 = {
|
||||
url: '/learn/front-end-development-libraries/front-end-development-libraries-projects/build-a-javascript-calculator',
|
||||
nextUrl:
|
||||
'/learn/front-end-development-libraries/front-end-development-libraries-projects/build-a-25--5-clock'
|
||||
};
|
||||
|
||||
// last in superblock
|
||||
const challenge2 = {
|
||||
url: '/learn/college-algebra-with-python/build-a-data-graph-explorer-project/build-a-data-graph-explorer',
|
||||
nextUrl:
|
||||
'/learn/college-algebra-with-python/#build-a-data-graph-explorer-project'
|
||||
};
|
||||
|
||||
describe('submitting a challenge', () => {
|
||||
before(() => {
|
||||
cy.exec('pnpm run seed');
|
||||
cy.login();
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
cy.preserveSession();
|
||||
});
|
||||
|
||||
it('in the middle of a block should take you to the next challenge', () => {
|
||||
cy.visit(challenge1.url);
|
||||
cy.get('#solution').type('https://example.com').type('{enter}');
|
||||
cy.contains('Submit and go to next challenge').click();
|
||||
cy.url().should('include', challenge1.nextUrl);
|
||||
});
|
||||
|
||||
it('at the end of a superblock should take you to the superblock page with the current block hash', () => {
|
||||
cy.visit(challenge2.url);
|
||||
cy.get('#solution').type('https://example.com').type('{enter}');
|
||||
cy.contains('Submit and go to next challenge').click();
|
||||
cy.url().should('include', challenge2.nextUrl);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user