Repository: freeCodeCamp/freeCodeCamp
File: client/src/components/settings/portfolio.tsx (TypeScript)

Code before:
      return {
        state: 'error',
        message: t('validation.title-required')
      };
    }
    const len = title.length;
    if (len < 2) {
      return { state: 'error', message: t('validation.title-short') };
    }
    if (len > 144) {
      return { state: 'error', message: t('validation.title-long') };
    }
    return { state: 'success', message: '' };
  }

  getUrlValidation(maybeUrl: string, isImage?: boolean) {
    const { t } = this.props;
    const len = maybeUrl.length;
    if (len >= 4 && !hasProtocolRE.test(maybeUrl)) {
      return {
        state: 'error',
        message: t('validation.invalid-protocol')
      } as const;
    }
    if (isImage && !maybeUrl) {
      return { state: null, message: '' } as const;
    }
    if (isImage && !/\.(png|jpg|jpeg|gif)$/.test(maybeUrl)) {
      return {
        state: 'error',
        message: t('validation.url-not-image')
      } as const;
    }
    return isURL(maybeUrl)
      ? ({ state: 'success', message: '' } as const)
      : ({ state: 'warning', message: t('validation.use-valid-url') } as const);
  }

  formCorrect(portfolio: PortfolioProjectData) {
    const { id, title, description, url, image } = portfolio;

    const { state: titleState, message: titleMessage } =
      this.getTitleValidation(title);
    const { state: urlState, message: urlMessage } = this.getUrlValidation(url);
    const { state: descriptionState, message: descriptionMessage } =
      this.getDescriptionValidation(description);
    const { state: imageState, message: imageMessage } = this.getUrlValidation(
      image,
      true
    );
    const pristine = this.isFormPristine(id);

Review comment (suggestion):
```suggestion
      return { state: null, message: '' };
```

Code after:
      return {
        state: 'error',
        message: t('validation.title-required')
      };
    }
    const len = title.length;
    if (len < 2) {
      return { state: 'error', message: t('validation.title-short') };
    }
    if (len > 144) {
      return { state: 'error', message: t('validation.title-long') };
    }
    return { state: 'success', message: '' };
  }

  getUrlValidation(maybeUrl: string, isImage?: boolean) {
    const { t } = this.props;
    const len = maybeUrl.length;
    if (len >= 4 && !hasProtocolRE.test(maybeUrl)) {
      return {
        state: 'error',
        message: t('validation.invalid-protocol')
      };
    }
    if (isImage && !maybeUrl) {
      return { state: null, message: '' };
    }
    if (isImage && !/\.(png|jpg|jpeg|gif)$/.test(maybeUrl)) {
      return {
        state: 'error',
        message: t('validation.url-not-image')
      };
    }
    return isURL(maybeUrl)
      ? { state: 'success', message: '' }
      : { state: 'warning', message: t('validation.use-valid-url') };
  }

  formCorrect(portfolio: PortfolioProjectData) {
    const { id, title, description, url, image } = portfolio;

    const { state: titleState, message: titleMessage } =
      this.getTitleValidation(title);
    const { state: urlState, message: urlMessage } = this.getUrlValidation(url);
    const { state: descriptionState, message: descriptionMessage } =
      this.getDescriptionValidation(description);
    const { state: imageState, message: imageMessage } = this.getUrlValidation(
      image,
      true
    );
    const pristine = this.isFormPristine(id);