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

Code before:
}: SuperBlockTreeViewProps) => {
  const content = useMemo(() => {
    const chapters = uniq(challenges.map(({ chapter }) => chapter as string));
    const examBlock = challenges.find(
      ({ blockType }) => blockType === BlockTypes.exam
    );

    // Expand the outer layers in order to reveal the chosen block.
    const expandedChapter = challenges.find(
      ({ block }) => chosenBlock === block
    )?.chapter as string;
    const expandedModule = challenges.find(({ block }) => chosenBlock === block)
      ?.module as string;

    return chapters.map(chapter => {
      if (examBlock && chapter === examBlock.chapter) {
        return (
          <li key={examBlock.dashedName} className='exam'>
            <Block
              block={examBlock.dashedName}
              blockType={examBlock.blockType}
              challenges={[examBlock]}
              superBlock={superBlock}
            />
          </li>
        );
      }

      const modules = uniq(
        challenges
          .filter(challenge => challenge.chapter === chapter)
          .map(challenge => challenge.module as string)
      );

      return (
        <Chapter
          key={chapter}
          dashedName={chapter}
          isExpanded={expandedChapter === chapter}
        >
          {modules.map(mod => {
            const blocks = uniq(
              challenges
                .filter(
                  challenge =>
                    challenge.chapter === chapter && challenge.module === mod
                )
                .map(challenge => challenge.block)
            );

            return (

Review comment (suggestion):
There is currently an empty space after the exam:

<details>
<summary>Screenshot</summary>

<img width="773" alt="Screenshot 2024-11-14 at 01 37 27" src="https://github.com/user-attachments/assets/30b6e112-fb18-4bab-a8a3-416967aba7b9">
</details>

Fixing this requires messing with this rendering logic:

https://github.com/freeCodeCamp/freeCodeCamp/blob/4cfa10dc0437b18ce6215779c5ffb1ef28353d0d/client/src/templates/Introduction/components/block.tsx#L474

I'll wait for #57138 go to in before making any changes to this line, to avoid conflicts.

Code after:
}: SuperBlockTreeViewProps) => {
  const { allChapters, allBlocks, examChallenge } = useMemo(() => {
    const allBlocks = uniqBy(challenges, 'block').map(
      ({ block, blockType, chapter, module }) => ({
        name: block,
        blockType,
        chapter: chapter as string,
        module: module as string,
        challenges: challenges.filter(({ block: b }) => b === block)
      })
    );

    const allModules = uniqBy(allBlocks, 'module').map(
      ({ module, chapter }) => ({
        name: module,
        chapter,
        blocks: allBlocks.filter(({ module: m }) => m === module)
      })
    );

    const allChapters = uniqBy(allModules, 'chapter').map(({ chapter }) => ({
      name: chapter,
      modules: allModules.filter(({ chapter: c }) => c === chapter)
    }));

    const examChallenge = challenges.find(
      ({ blockType }) => blockType === BlockTypes.exam
    );

    return { allChapters, allModules, allBlocks, examChallenge };
  }, [challenges]);

  // Expand the outer layers in order to reveal the chosen block.
  const expandedChapter = allBlocks.find(
    ({ name }) => chosenBlock === name
  )?.chapter;
  const expandedModule = allBlocks.find(
    ({ name }) => chosenBlock === name
  )?.module;

  return (
    <ul className='super-block-accordion'>
      {allChapters.map(chapter => {
        if (examChallenge && chapter.name === examChallenge.chapter) {
          return (
            <li key={examChallenge.dashedName} className='exam'>
              <Block
                block={examChallenge.block}
                blockType={examChallenge.blockType}
                challenges={[examChallenge]}
                superBlock={superBlock}