ronantakizawa/codereview-bench huggingface dataset:
Repository: freeCodeCamp/freeCodeCamp
File: tools/challenge-helper-scripts/create-project.ts (TypeScript)

Code before:
  }
}

async function updateFullStackJson(
  chapterName: string,
  moduleName: string,
  block: string,
  position: number
) {
  // Get the index of the correct chapter
  const chapterIndex = fullStackData['chapters'].findIndex(
    chapter => chapter.dashedName === chapterName
  );
  const moduleIndex = fullStackData['chapters'][chapterIndex][
    'modules'
  ].findIndex(module => module.dashedName === moduleName);
  fullStackData['chapters'][chapterIndex]['modules'][moduleIndex][
    'blocks'
  ].splice(position - 1, 0, block);
  // Insert the new block into the already present module
  // Write the new changes to the file
  const newData = JSON.stringify(fullStackData, null, 2);
  await fs.writeFile(
    '../../curriculum/structure/superblocks/full-stack-developer.json',
    newData
  );
}

async function updateIntroJson(
  superBlock: SuperBlocks,
  block: string,
  title: string
) {
  const introJsonPath = path.resolve(
    __dirname,
    '../../client/i18n/locales/english/intro.json'
  );
  const newIntro = await parseJson<IntroJson>(introJsonPath);
  newIntro[superBlock].blocks[block] = {
    title,
    intro: [title, '']
  };
  void withTrace(
    fs.writeFile,
    introJsonPath,
    await format(JSON.stringify(newIntro), { parser: 'json' })
  );
}

async function createMetaJson(
  superBlock: SuperBlocks,

Review comment (suggestion):
`updateChapterModuleSuperblockStructure` can handle this.

Code after:
  const introJsonPath = path.resolve(
    __dirname,
    '../../client/i18n/locales/english/intro.json'
  );
  const newIntro = await parseJson<IntroJson>(introJsonPath);
  newIntro[superBlock].blocks[block] = {
    title,
    intro: [title, '']
  };
  void withTrace(
    fs.writeFile,
    introJsonPath,
    await format(JSON.stringify(newIntro), { parser: 'json' })
  );
}

async function createMetaJson(
  superBlock: SuperBlocks,
  block: string,
  title: string,
  helpCategory: string,
  challengeId: ObjectID,
  order?: number,
  blockType?: string,
  blockLayout?: string
) {
  let newMeta;
  if (superBlock === SuperBlocks.FullStackDeveloper) {
    newMeta = getBaseMeta('FullStack');
    newMeta.blockType = blockType;
    newMeta.blockLayout = blockLayout;
  } else {
    newMeta = getBaseMeta('Step');
    newMeta.order = order;
  }
  newMeta.name = title;
  newMeta.dashedName = block;
  newMeta.helpCategory = helpCategory;
  // eslint-disable-next-line @typescript-eslint/no-base-to-string
  newMeta.challengeOrder = [{ id: challengeId.toString(), title: 'Step 1' }];

  await writeBlockStructure(block, newMeta);
}

async function createFirstChallenge(block: string): Promise<ObjectID> {
  const { blockContentDir } = getContentConfig('english') as {
    blockContentDir: string;
  };

  const newChallengeDir = path.resolve(blockContentDir, block);
  await fs.mkdir(newChallengeDir, { recursive: true });
Repository: freeCodeCamp/freeCodeCamp
File: tools/challenge-helper-scripts/create-project.ts (TypeScript)

Code before:
};

type IntroJson = Record<SuperBlocks, SuperBlockInfo>;

interface CreateProjectArgs {
  superBlock: SuperBlocks;
  block: string;
  helpCategory: string;
  blockType?: string;
  blockLayout?: string;
  questionCount?: number;
  order?: number;
  chapter?: string;
  position?: number;
  module?: string;
  title?: string;
}

async function createProject(projectArgs: CreateProjectArgs) {
  if (!projectArgs.title) {
    projectArgs.title = projectArgs.block;
  }

  const order = projectArgs.order!;
  const chapter = projectArgs.chapter!;
  const module = projectArgs.module!;

  const superblockFilename = (
    superBlockToFilename as Record<SuperBlocks, string>
  )[projectArgs.superBlock];

  if (projectArgs.superBlock !== SuperBlocks.FullStackDeveloper) {
    void updateSimpleSuperblockStructure(
      projectArgs.block,
      { order },
      superblockFilename
    );
  } else {
    void updateChapterModuleSuperblockStructure(
      projectArgs.block,
      { order, chapter, module },
      superblockFilename
    );
  }

  void updateIntroJson(
    projectArgs.superBlock,
    projectArgs.block,
    projectArgs.title
  );


Review comment (suggestion):
```suggestion
  const order = projectArgs.order;
  const chapter = projectArgs.chapter;
  const module = projectArgs.module;
```
These aren't guaranteed to exist.

Code after:
};

type IntroJson = Record<SuperBlocks, SuperBlockInfo>;

interface CreateProjectArgs {
  superBlock: SuperBlocks;
  block: string;
  helpCategory: string;
  blockType?: string;
  blockLayout?: string;
  questionCount?: number;
  order?: number;
  chapter?: string;
  position?: number;
  module?: string;
  title?: string;
}

async function createProject(projectArgs: CreateProjectArgs) {
  if (!projectArgs.title) {
    projectArgs.title = projectArgs.block;
  }

  const order = projectArgs.order;
  const chapter = projectArgs.chapter;
  const module = projectArgs.module;
  const position = projectArgs.position;

  const superblockFilename = (
    superBlockToFilename as Record<SuperBlocks, string>
  )[projectArgs.superBlock];

  if (projectArgs.superBlock === SuperBlocks.FullStackDeveloper) {
    if (!chapter || !module || typeof position == 'undefined') {
      throw Error(
        'Missing one of the following arguments: chapter, module, position'
      );
    }
    void updateChapterModuleSuperblockStructure(
      projectArgs.block,
      { order: position, chapter, module },
      superblockFilename
    );
  } else {
    if (typeof order == 'undefined') {
      throw Error('Missing argument: order');
    }
    void updateSimpleSuperblockStructure(
      projectArgs.block,
      { order },
      superblockFilename
Repository: freeCodeCamp/freeCodeCamp
File: api/src/plugins/growth-book.ts (TypeScript)

Code before:
import { GrowthBook, Options } from '@growthbook/growthbook';
import { FastifyPluginAsync } from 'fastify';
import fp from 'fastify-plugin';

declare module 'fastify' {
  interface FastifyInstance {
    gb: GrowthBook;
  }
}

const growthBook: FastifyPluginAsync<Options> = async (fastify, options) => {
  const gb = new GrowthBook(options);
  const res = await gb.init({ timeout: 3000 });

  if (res.error) {
    fastify.log.error('Failed to initialize GrowthBook');
    fastify.Sentry.captureException(res.error);
  }

  fastify.decorate('gb', gb);

  fastify.addHook('onClose', () => {
    gb.destroy();
  });
};

export default fp(growthBook);


Review comment (bug):
Just so we do not **have** to go to Sentry to find the specific reason behind the error.

```suggestion
    fastify.log.error({ error: res.error }, 'Failed to initialize GrowthBook');
```

Code after:
import { GrowthBook, Options } from '@growthbook/growthbook';
import { FastifyPluginAsync } from 'fastify';
import fp from 'fastify-plugin';

declare module 'fastify' {
  interface FastifyInstance {
    gb: GrowthBook;
  }
}

const growthBook: FastifyPluginAsync<Options> = async (fastify, options) => {
  const gb = new GrowthBook(options);
  const res = await gb.init({ timeout: 3000 });

  if (res.error) {
    fastify.log.error(res.error, 'Failed to initialize GrowthBook');
    fastify.Sentry.captureException(res.error);
  }

  fastify.decorate('gb', gb);

  fastify.addHook('onClose', () => {
    gb.destroy();
  });
};

export default fp(growthBook);
Repository: freeCodeCamp/freeCodeCamp
File: client/src/templates/Challenges/components/scene/scene-assets.tsx (TypeScript)

Code before:
  Jim: characterImages.npcMan,
  Josh: characterImages.npcMan,
  Linda: characterImages.linda,
  Lisa: characterImages.lisa,
  Maria: characterImages.maria,
  Mark: characterImages.npcBoy,
  Riker: characterImages.npcMan,
  Sarah: characterImages.sarah,
  'Second Candidate': characterImages.npcMan,
  Sophie: characterImages.sophie,
  Tom: characterImages.tom,

  // Spanish
  Ángela: characterImages.sarah,
  Camila: characterImages.sophie,
  Carlos: characterImages.brian,
  Elena: characterImages.anna,
  Esteban: characterImages.james,
  Joaquín: characterImages.jake,
  Julieta: characterImages.maria,
  Luis: characterImages.bob,
  Luna: characterImages.lisa,
  Marisol: characterImages.linda,
  Mateo: characterImages.npcBoy,
  Noelia: characterImages.npcWoman,
  Nomes: characterImages.npcGirl,
  René: characterImages.npcMan,
  Sebastián: characterImages.david,
  Diego: characterImages.tom,
  Valeria: characterImages.alice
};


Review comment (suggestion):
```suggestion
  Alex: characterImages.npcGirl,
```

Code after:
  Jim: characterImages.npcMan,
  Josh: characterImages.npcMan,
  Linda: characterImages.linda,
  Lisa: characterImages.lisa,
  Maria: characterImages.maria,
  Mark: characterImages.npcBoy,
  Riker: characterImages.npcMan,
  Sarah: characterImages.sarah,
  'Second Candidate': characterImages.npcMan,
  Sophie: characterImages.sophie,
  Tom: characterImages.tom,

  // Spanish
  Alex: characterImages.npcGirl,
  Ángela: characterImages.sarah,
  Camila: characterImages.sophie,
  Carlos: characterImages.brian,
  Elena: characterImages.anna,
  Esteban: characterImages.james,
  Joaquín: characterImages.jake,
  Julieta: characterImages.maria,
  Luis: characterImages.bob,
  Luna: characterImages.lisa,
  Marisol: characterImages.linda,
  Mateo: characterImages.npcBoy,
  Noelia: characterImages.npcWoman,
  René: characterImages.npcMan,
  Sebastián: characterImages.david,
  Diego: characterImages.tom,
  Valeria: characterImages.alice
};
Repository: freeCodeCamp/freeCodeCamp
File: client/src/templates/Introduction/components/super-block-intro.tsx (TypeScript)

Code before:
                  <h3>{t('misc.fsd-b-benefit-2-title')}</h3>
                  <p>{t('misc.fsd-b-benefit-2-description')}</p>
                </div>
              </div>
              <div>
                <DumbleIcon />
                <div className='benefit-text'>
                  <h3>{t('misc.fsd-b-benefit-3-title')}</h3>
                  <p>{t('misc.fsd-b-benefit-3-description')}</p>
                </div>
              </div>
            </Col>
          </Row>
        </Container>
      </Container>
      <Spacer size='l' />
    </>
  );

  const showFSDnewIntro = useFeatureIsOn('fsd-new-intro');

  const showIntroTopB = completedChallenges.length === 0 && showFSDnewIntro;

  return (
    <>
      {showIntroTopB ? introTopA : introTopB}
      <ConditionalDonationAlert
        superBlock={superBlock}
        onCertificationDonationAlertClick={onCertificationDonationAlertClick}
        isDonating={isDonating}
      />
    </>
  );
}

SuperBlockIntro.displayName = 'SuperBlockIntro';

export default connect(mapStateToProps)(SuperBlockIntro);


Review comment (suggestion):
```suggestion
      {showIntroTopB ? introTopB : introTopA}
```

Code after:
              <div>
                <CapIcon />
                <div className='benefit-text'>
                  <h3>{t('misc.fsd-b-benefit-2-title')}</h3>
                  <p>{t('misc.fsd-b-benefit-2-description')}</p>
                </div>
              </div>
              <div>
                <DumbbellIcon />
                <div className='benefit-text'>
                  <h3>{t('misc.fsd-b-benefit-3-title')}</h3>
                  <p>{t('misc.fsd-b-benefit-3-description')}</p>
                </div>
              </div>
            </Col>
          </Row>
        </Container>
      </Container>
      <Spacer size='l' />
    </>
  );

  const showFSDnewIntro = useFeatureIsOn('fsd-new-intro');

  const showIntroTopB = completedChallenges.length === 0 && showFSDnewIntro;

  return (
    <>
      {showIntroTopB ? introTopB : introTopA}
      <ConditionalDonationAlert
        superBlock={superBlock}
        onCertificationDonationAlertClick={onCertificationDonationAlertClick}
        isDonating={isDonating}
      />
    </>
  );
}

SuperBlockIntro.displayName = 'SuperBlockIntro';

export default connector(SuperBlockIntro);
Repository: freeCodeCamp/freeCodeCamp
File: client/src/templates/Introduction/components/super-block-intro.tsx (TypeScript)

Code before:
import { CompletedChallenge } from '../../../redux/prop-types';
import { completedChallengesSelector } from '../../../redux/selectors';

interface SuperBlockIntroQueryData {
  challengeNode: {
    challenge: {
      fields: {
        slug: string;
      };
    };
  };
}

interface SuperBlockIntroProps {
  superBlock: SuperBlocks;
  onCertificationDonationAlertClick: () => void;
  isDonating: boolean;
  completedChallenges: CompletedChallenge[];
}

const mapStateToProps = createSelector(
  completedChallengesSelector,
  (completedChallenges: CompletedChallenge[]) => ({
    completedChallenges
  })
);

export const ConditionalDonationAlert = ({
  superBlock,
  onCertificationDonationAlertClick,
  isDonating
}: Omit<SuperBlockIntroProps, 'completedChallenges'>): JSX.Element | null => {
  const { t } = useTranslation();

  const betaCertifications: SuperBlocks[] = [];

  const unfinishedCertifications = [
    SuperBlocks.A2English,
    SuperBlocks.B1English,
    SuperBlocks.A2Spanish,
    SuperBlocks.FullStackDeveloper
  ];

  if (!isDonating && betaCertifications.includes(superBlock))
    return (
      <Alert variant='info' className='annual-donation-alert'>
        <p>{t('donate.beta-certification')}</p>
        <hr />
        <p className='btn-container'>
          <Link
            className='btn donate-button'

Review comment (suggestion):
```suggestion
const mapStateToProps = (state: unknown) => ({
  completedChallenges: completedChallengesSelector(
    state
  ) as CompletedChallenge[]
});
```
There's nothing to memoize since nothing is computed, so we can just use a normal selector.

Code after:
import { completedChallengesSelector } from '../../../redux/selectors';

interface SuperBlockIntroQueryData {
  challengeNode: {
    challenge: {
      fields: {
        slug: string;
      };
    };
  };
}

type ReduxProps = ConnectedProps<typeof connector>;

interface ConditionalDonationAlertProps {
  superBlock: SuperBlocks;
  onCertificationDonationAlertClick: () => void;
  isDonating: boolean;
}

interface SuperBlockIntroProps
  extends ConditionalDonationAlertProps,
    ReduxProps {}

const mapStateToProps = (state: unknown) => ({
  completedChallenges: completedChallengesSelector(
    state
  ) as CompletedChallenge[]
});

const connector = connect(mapStateToProps);

export const ConditionalDonationAlert = ({
  superBlock,
  onCertificationDonationAlertClick,
  isDonating
}: ConditionalDonationAlertProps): JSX.Element | null => {
  const { t } = useTranslation();

  const betaCertifications: SuperBlocks[] = [];

  const unfinishedCertifications = [
    SuperBlocks.A2English,
    SuperBlocks.B1English,
    SuperBlocks.A2Spanish,
    SuperBlocks.FullStackDeveloper
  ];

  if (!isDonating && betaCertifications.includes(superBlock))
    return (
      <Alert variant='info' className='annual-donation-alert'>
Repository: freeCodeCamp/freeCodeCamp
File: client/src/templates/Introduction/components/super-block-intro.tsx (TypeScript)

Code before:
    query SuperBlockIntroQuery {
      challengeNode(
        challenge: {
          superOrder: { eq: 0 }
          order: { eq: 0 }
          challengeOrder: { eq: 0 }
        }
      ) {
        challenge {
          fields {
            slug
          }
        }
      }
    }
  `);

  const {
    title: i18nSuperBlock,
    intro: superBlockIntroText,
    note: superBlockNoteText
  } = superBlockIntroObj;

  const introTopA = (
    <>
      {' '}
      <h1 id='content-start' className='text-center big-heading'>
        {i18nSuperBlock}
      </h1>
      <Spacer size='m' />
      <SuperBlockIcon className='cert-header-icon' superBlock={superBlock} />
      <Spacer size='m' />
      {superBlockIntroText.map((str, i) => (
        <p dangerouslySetInnerHTML={{ __html: str }} key={i} />
      ))}
      {superBlockNoteText && (
        <div className='alert alert-info' style={{ marginTop: '2rem' }}>
          {superBlockNoteText}
        </div>
      )}
    </>
  );

  const introTopB = (
    <>
      {' '}
      <SuperBlockIcon className='cert-header-icon' superBlock={superBlock} />
      <Spacer size='m' />
      <h1 id='content-start' className='text-center big-heading'>
        {i18nSuperBlock}
      </h1>

Review comment (suggestion):
```suggestion
```
This doesn't seem to do anything.

Code after:
      challenge: {
        fields: { slug: firstChallengeSlug }
      }
    }
  } = useStaticQuery<SuperBlockIntroQueryData>(graphql`
    query SuperBlockIntroQuery {
      challengeNode(
        challenge: {
          superOrder: { eq: 0 }
          order: { eq: 0 }
          challengeOrder: { eq: 0 }
        }
      ) {
        challenge {
          fields {
            slug
          }
        }
      }
    }
  `);

  const {
    title: i18nSuperBlock,
    intro: superBlockIntroText,
    note: superBlockNoteText
  } = superBlockIntroObj;

  const introTopA = (
    <>
      <h1 id='content-start' className='text-center big-heading'>
        {i18nSuperBlock}
      </h1>
      <Spacer size='m' />
      <SuperBlockIcon className='cert-header-icon' superBlock={superBlock} />
      <Spacer size='m' />
      {superBlockIntroText.map((str, i) => (
        <p dangerouslySetInnerHTML={{ __html: str }} key={i} />
      ))}
      {superBlockNoteText && (
        <div className='alert alert-info' style={{ marginTop: '2rem' }}>
          {superBlockNoteText}
        </div>
      )}
    </>
  );

  const introTopB = (
    <>
      <SuperBlockIcon className='cert-header-icon' superBlock={superBlock} />
      <Spacer size='m' />
Repository: freeCodeCamp/freeCodeCamp
File: client/src/templates/Introduction/components/super-block-intro.tsx (TypeScript)

Code before:
import React from 'react';
import { graphql, useStaticQuery } from 'gatsby';
import { useTranslation, Trans } from 'react-i18next';
import { Alert, Spacer, Container, Row, Col } from '@freecodecamp/ui';
import { connect } from 'react-redux';
import { createSelector } from 'reselect';
import { useFeatureIsOn } from '@growthbook/growthbook-react';
import { SuperBlocks } from '../../../../../shared/config/curriculum';
import { SuperBlockIcon } from '../../../assets/superblock-icon';
import { Link } from '../../../components/helpers';
import CapIcon from '../../../assets/icons/cap';
import DumbbellIcon from '../../../assets/icons/dumbbell';
import CommunityIcon from '../../../assets/icons/community';
import { CompletedChallenge } from '../../../redux/prop-types';
import { completedChallengesSelector } from '../../../redux/selectors';

interface SuperBlockIntroQueryData {
  challengeNode: {
    challenge: {
      fields: {
        slug: string;
      };
    };
  };
}

interface SuperBlockIntroProps {
  superBlock: SuperBlocks;
  onCertificationDonationAlertClick: () => void;
  isDonating: boolean;
  completedChallenges: CompletedChallenge[];

Review comment (suggestion):
```suggestion
```
If we just use normal selectors this won't be needed.

Code after:
import React from 'react';
import { graphql, useStaticQuery } from 'gatsby';
import { useTranslation, Trans } from 'react-i18next';
import { Alert, Spacer, Container, Row, Col } from '@freecodecamp/ui';
import { ConnectedProps, connect } from 'react-redux';
import { useFeatureIsOn } from '@growthbook/growthbook-react';
import { SuperBlocks } from '../../../../../shared/config/curriculum';
import { SuperBlockIcon } from '../../../assets/superblock-icon';
import { Link } from '../../../components/helpers';
import CapIcon from '../../../assets/icons/cap';
import DumbbellIcon from '../../../assets/icons/dumbbell';
import CommunityIcon from '../../../assets/icons/community';
import { CompletedChallenge } from '../../../redux/prop-types';
import { completedChallengesSelector } from '../../../redux/selectors';

interface SuperBlockIntroQueryData {
  challengeNode: {
    challenge: {
      fields: {
        slug: string;
      };
    };
  };
}

type ReduxProps = ConnectedProps<typeof connector>;

interface ConditionalDonationAlertProps {
  superBlock: SuperBlocks;
  onCertificationDonationAlertClick: () => void;
  isDonating: boolean;
Repository: freeCodeCamp/freeCodeCamp
File: client/src/assets/icons/top-contributor-badge-emblem.tsx (TypeScript)

Code before:
      />
      <path
        d='M144.581 135.589C152.702 135.903 164.191 140.246 164.915 131.798C165.649 123.225 152.999 125.36 144.868 125.333C137.124 125.307 126.028 131.075 126.028 131.075C126.028 131.075 137.185 135.303 144.581 135.589Z'
        fill='var(--primary-color)'
        stroke='var(--primary-color)'
      />
      <path
        d='M158.661 119.993C165.771 121.593 176.308 127.349 177.629 119.698C178.906 112.295 168.719 111.733 161.527 110.401C154.678 109.132 143.385 112.768 143.385 112.768C143.385 112.768 152.187 118.535 158.661 119.993Z'
        fill='var(--primary-color)'
        stroke='var(--primary-color)'
      />
      <path
        d='M176.384 103.057C183.263 103.854 192.769 108.289 193.879 101.165C195.004 93.9389 184.139 94.9224 177.235 94.3687C170.66 93.8414 160.894 98.0127 160.894 98.0127C160.894 98.0127 170.119 102.331 176.384 103.057Z'
        fill='var(--primary-color)'
        stroke='var(--primary-color)'
      />
      <path
        d='M187.793 85.638C195.268 82.32 207.396 81.1802 204.667 73.1742C201.897 65.0459 191.294 72.6167 183.926 76.1997C176.908 79.6123 169.188 89.771 169.188 89.771C169.188 89.771 180.986 88.6596 187.793 85.638Z'
        fill='var(--primary-color)'
        stroke='var(--primary-color)'
      />
    </svg>
  );
}

TopContributorBadgeEmblem.displayName = 'TopContibutorBadgeEmblem';

export default TopContributorBadgeEmblem;


Review comment (suggestion):
```suggestion
TopContributorBadgeEmblem.displayName = 'TopContributorBadgeEmblem';
```

Code after:
      />
      <path
        d='M144.581 135.589C152.702 135.903 164.191 140.246 164.915 131.798C165.649 123.225 152.999 125.36 144.868 125.333C137.124 125.307 126.028 131.075 126.028 131.075C126.028 131.075 137.185 135.303 144.581 135.589Z'
        fill='var(--primary-color)'
        stroke='var(--primary-color)'
      />
      <path
        d='M158.661 119.993C165.771 121.593 176.308 127.349 177.629 119.698C178.906 112.295 168.719 111.733 161.527 110.401C154.678 109.132 143.385 112.768 143.385 112.768C143.385 112.768 152.187 118.535 158.661 119.993Z'
        fill='var(--primary-color)'
        stroke='var(--primary-color)'
      />
      <path
        d='M176.384 103.057C183.263 103.854 192.769 108.289 193.879 101.165C195.004 93.9389 184.139 94.9224 177.235 94.3687C170.66 93.8414 160.894 98.0127 160.894 98.0127C160.894 98.0127 170.119 102.331 176.384 103.057Z'
        fill='var(--primary-color)'
        stroke='var(--primary-color)'
      />
      <path
        d='M187.793 85.638C195.268 82.32 207.396 81.1802 204.667 73.1742C201.897 65.0459 191.294 72.6167 183.926 76.1997C176.908 79.6123 169.188 89.771 169.188 89.771C169.188 89.771 180.986 88.6596 187.793 85.638Z'
        fill='var(--primary-color)'
        stroke='var(--primary-color)'
      />
    </svg>
  );
}

TopContributorBadgeEmblem.displayName = 'TopContributorBadgeEmblem';

export default TopContributorBadgeEmblem;