feat(client): display intro of FSD blocks in block header (#56808)

Co-authored-by: Oliver Eyton-Williams <ojeytonwilliams@gmail.com>
This commit is contained in:
Huyen Nguyen
2024-11-13 15:27:22 +07:00
committed by GitHub
parent 3279b3f2d8
commit 5270cb1288
6 changed files with 93 additions and 12 deletions
@@ -1,9 +1,12 @@
import React from 'react';
import { isEmpty } from 'lodash';
import { BlockTypes } from '../../../../../shared/config/blocks';
import { ProgressBar } from '../../../components/Progress/progress-bar';
import DropDown from '../../../assets/icons/dropdown';
import CheckMark from './check-mark';
import BlockLabel from './block-label';
import BlockIntros from './block-intros';
interface BlockHeaderProps {
blockDashed: string;
@@ -15,6 +18,7 @@ interface BlockHeaderProps {
isCompleted: boolean;
isExpanded: boolean;
percentageCompleted: number;
blockIntroArr?: string[];
}
function BlockHeader({
@@ -26,7 +30,8 @@ function BlockHeader({
handleClick,
isCompleted,
isExpanded,
percentageCompleted
percentageCompleted,
blockIntroArr
}: BlockHeaderProps): JSX.Element {
return (
<h3 className='block-grid-title'>
@@ -45,6 +50,9 @@ function BlockHeader({
</span>
<DropDown />
</span>
{!isEmpty(blockIntroArr) && (
<BlockIntros intros={blockIntroArr as string[]} />
)}
{!isExpanded && !isCompleted && completedCount > 0 && (
<div aria-hidden='true' className='progress-wrapper'>
<div>
@@ -226,11 +226,11 @@ class Block extends Component<BlockProps> {
);
/**
* ChallengeGridBlock displays challenges in a grid.
* LegacyChallengeGridBlock displays challenges in a grid.
* This layout is used for step-based blocks.
* Example: https://www.freecodecamp.org/learn/2022/responsive-web-design/#learn-html-by-building-a-cat-photo-app
* Example: https://www.freecodecamp.org/learn/javascript-algorithms-and-data-structures-v8/#learn-basic-javascript-by-building-a-role-playing-game
*/
const ChallengeGridBlock = (
const LegacyChallengeGridBlock = (
<ScrollableAnchor id={block}>
<div className={`block block-grid ${isExpanded ? 'open' : ''}`}>
<BlockHeader
@@ -323,7 +323,9 @@ class Block extends Component<BlockProps> {
*/
const ChallengeListBlock = (
<ScrollableAnchor id={block}>
<div className={`block block-grid ${isExpanded ? 'open' : ''}`}>
<div
className={`block block-grid challenge-list-block ${isExpanded ? 'open' : ''}`}
>
<BlockHeader
blockDashed={block}
blockTitle={blockTitle}
@@ -334,6 +336,7 @@ class Block extends Component<BlockProps> {
isCompleted={isBlockCompleted}
isExpanded={isExpanded}
percentageCompleted={percentageCompleted}
blockIntroArr={blockIntroArr}
/>
{!isAudited && (
<div className='tags-wrapper'>
@@ -347,7 +350,6 @@ class Block extends Component<BlockProps> {
)}
{isExpanded && (
<div id={`${block}-panel`}>
<BlockIntros intros={blockIntroArr} />
<Challenges
challengesWithCompleted={challengesWithCompleted}
isProjectBlock={isProjectBlock}
@@ -397,6 +399,51 @@ class Block extends Component<BlockProps> {
</ScrollableAnchor>
);
/**
* ChallengeGridBlock displays challenges in a grid.
* This layout is specifically used for the new Full Stack Developer Certification.
*/
const ChallengeGridBlock = (
<ScrollableAnchor id={block}>
<div
className={`block block-grid challenge-grid-block ${isExpanded ? 'open' : ''}`}
>
<BlockHeader
blockDashed={block}
blockTitle={blockTitle}
blockType={blockType}
completedCount={completedCount}
courseCompletionStatus={courseCompletionStatus()}
handleClick={this.handleBlockClick}
isCompleted={isBlockCompleted}
isExpanded={isExpanded}
percentageCompleted={percentageCompleted}
blockIntroArr={blockIntroArr}
/>
{!isAudited && (
<div className='tags-wrapper'>
<Link
className='cert-tag'
to={t('links:help-translate-link-url')}
>
{t('misc.translation-pending')}
</Link>
</div>
)}
{isExpanded && (
<div id={`${block}-panel`} className='challenge-grid-block-panel'>
<Challenges
challengesWithCompleted={challengesWithCompleted}
isProjectBlock={isProjectBlock}
isGridMap={true}
blockTitle={blockTitle}
/>
</div>
)}
</div>
</ScrollableAnchor>
);
const blockRenderer = () => {
const blockLayout = challenges[0].blockLayout;
@@ -404,7 +451,9 @@ class Block extends Component<BlockProps> {
if (!blockLayout) {
if (isProjectBlock)
return isGridBlock ? LegacyLinkBlock : ProjectListBlock;
return isGridBlock ? ChallengeGridBlock : LegacyChallengeListBlock;
return isGridBlock
? LegacyChallengeGridBlock
: LegacyChallengeListBlock;
}
// blockLayout is only being used in new certs at the moment, so I made some new components for them for now to not interfere with the existing ones
@@ -415,6 +464,8 @@ class Block extends Component<BlockProps> {
if (blockLayout === BlockLayouts.LegacyLink) return LegacyLinkBlock;
if (blockLayout === BlockLayouts.LegacyChallengeList)
return LegacyChallengeListBlock;
if (blockLayout === BlockLayouts.LegacyChallengeGrid)
return LegacyChallengeGridBlock;
};
return (
@@ -598,3 +598,22 @@ a.map-grid-item.challenge-completed {
.grid-project-block:hover:has(.tags-wrapper a:hover) {
background: var(--primary-background);
}
/* Override the `.block-description` padding (25px)
to align the description with the content in the panel. */
.block-ui .challenge-list-block .block-header .block-description,
.block-ui .challenge-grid-block .block-header .block-description {
padding: 10px;
}
.block-ui .challenge-grid-block .progress-wrapper {
/* Make the progress bar align with the description above */
padding-inline-start: 10px;
}
.block-ui .challenge-grid-block .challenge-grid-block-panel {
/* Add some space between panel content and the top edge of the container.
The value (18px) is the same value `.map-challenges-grid` uses
to create space between the grid and the bottom edge of the container. */
margin-top: 18px;
}
+2 -1
View File
@@ -137,7 +137,8 @@ const schema = Joi.object()
'link',
'project-list',
'legacy-challenge-list',
'legacy-link'
'legacy-link',
'legacy-challenge-grid'
).required()
}),
challengeOrder: Joi.number(),
+2 -1
View File
@@ -12,7 +12,8 @@ const schema = Joi.object()
'link',
'project-list',
'legacy-challenge-list',
'legacy-link'
'legacy-link',
'legacy-challenge-grid'
),
blockType: Joi.valid(
'workshop',
+4 -3
View File
@@ -9,11 +9,12 @@ export enum BlockTypes {
export enum BlockLayouts {
/**
* These two are for the new Full Stack Developer Certification,
* These three are for the new Full Stack Developer Certification,
* so we can play with them without affecting the existing block layouts
*/
ChallengeList = 'challenge-list',
Link = 'link',
ChallengeGrid = 'challenge-grid',
/**
* ChallengeList displays challenges in a list.
@@ -23,11 +24,11 @@ export enum BlockLayouts {
LegacyChallengeList = 'legacy-challenge-list',
/**
* ChallengeGrid displays challenges in a grid.
* LegacyChallengeGrid displays challenges in a grid.
* This layout is used for step-based blocks.
* Example: https://www.freecodecamp.org/learn/2022/responsive-web-design/#learn-html-by-building-a-cat-photo-app
*/
ChallengeGrid = 'challenge-grid',
LegacyChallengeGrid = 'legacy-challenge-grid',
/**
* Link displays the block as a single link.