Repository: freeCodeCamp/freeCodeCamp
File: client/src/templates/Introduction/components/block.tsx (TypeScript)

Code before:
    const collapseText = t('intro:misc-text.collapse');

    const isBlockCompleted = completedCount === challengesWithCompleted.length;

    const percentageCompleted = Math.floor(
      (completedCount / challengesWithCompleted.length) * 100
    );

    const progressBarRender = (
      <div aria-hidden='true' className='progress-wrapper'>
        <div>
          <ProgressBar now={percentageCompleted} />
        </div>
        <span>{`${percentageCompleted}%`}</span>
      </div>
    );

    /**
     * ChallengeListBlock displays challenges in a list.
     * This layout is used in backend blocks, The Odin Project blocks, and blocks in legacy certification.
     * Example: https://www.freecodecamp.org/learn/javascript-algorithms-and-data-structures/#basic-javascript
     */
    const ChallengeListBlock = (
      <>
        {' '}
        <ScrollableAnchor id={blockDashedName}>
          <div className={`block ${isExpanded ? 'open' : ''}`}>
            <div className='block-header'>
              <h3 className='big-block-title'>{blockTitle}</h3>
              {!isAudited && (
                <div className='block-cta-wrapper'>
                  <Link
                    className='block-title-translation-cta'
                    to={t('links:help-translate-link-url')}
                  >
                    {t('misc.translation-pending')}
                  </Link>
                </div>
              )}
            </div>
            <BlockIntros intros={blockIntroArr} />
            <button
              aria-expanded={isExpanded}
              className='map-title'
              onClick={() => {
                this.handleBlockClick();
              }}
            >
              <Caret />
              <div className='course-title'>
                {`${isExpanded ? collapseText : expandText}`}{' '}

Review comment (suggestion):
The current block names are _very_ confusing to me. So I... renamed them.

Mapping:

| Old | New |
| --- | --- |
| Block | ChallengeListBlock |
| ProjectBlock | ProjectListBlock |
| GridBlock | ChallengeGridBlock |
| ProjectGridBlock | LinkBlock |

I wanted the names to describe what the component would display (grid, list, link, etc.) rather than their purpose (challenge, project, etc.). But it's pretty hard to do that with the existing implementation, and the list above is the best I could do.

I think in the future (when we move/build components in fcc/ui, to share with CAP), we could have the following block components:
- Grid
- List
  - There are two *List components in the list above, but the `ProjectListBlock` one is very similar to `ChallengeListBlock`. We can just group them into a single `List` component and provide props to customize the elements displayed
- Link
- GridAndList / Mixed

Code after:
      `intro:${superBlock}.blocks.${block}.intro`
    );
    const expandText = t('intro:misc-text.expand');
    const collapseText = t('intro:misc-text.collapse');

    const isBlockCompleted = completedCount === challengesWithCompleted.length;

    const percentageCompleted = Math.floor(
      (completedCount / challengesWithCompleted.length) * 100
    );

    const progressBarRender = (
      <div aria-hidden='true' className='progress-wrapper'>
        <div>
          <ProgressBar now={percentageCompleted} />
        </div>
        <span>{`${percentageCompleted}%`}</span>
      </div>
    );

    /**
     * ChallengeListBlock displays challenges in a list.
     * This layout is used in backend blocks, The Odin Project blocks, and blocks in legacy certification.
     * Example: https://www.freecodecamp.org/learn/javascript-algorithms-and-data-structures/#basic-javascript
     */
    const ChallengeListBlock = (
      <>
        {' '}
        <ScrollableAnchor id={block}>
          <div className={`block ${isExpanded ? 'open' : ''}`}>
            <div className='block-header'>
              <h3 className='big-block-title'>{blockTitle}</h3>
              {blockType && <BlockLabel blockType={blockType} />}
              {!isAudited && (
                <div className='block-cta-wrapper'>
                  <Link
                    className='block-title-translation-cta'
                    to={t('links:help-translate-link-url')}
                  >
                    {t('misc.translation-pending')}
                  </Link>
                </div>
              )}
            </div>
            <BlockIntros intros={blockIntroArr} />
            <button
              aria-expanded={isExpanded}
              className='map-title'
              onClick={() => {
                this.handleBlockClick();
              }}