Repository: freeCodeCamp/freeCodeCamp
File: client/src/components/profile/components/internet.tsx (TypeScript)

Code before:
        ...formValues,
        [key]: value
      });
    };

  const isFormPristine = () => {
    return (Object.keys(originalValues) as Array<keyof Socials>).every(
      key => originalValues[key] === formValues[key]
    );
  };

  const isFormValid = (): boolean =>
    Object.values(formValues).every(
      (value: string) => value === '' || isURL(value)
    );

  const handleSubmit = (e: React.FormEvent) => {
    e.preventDefault();
    if (!isFormPristine() && isFormValid()) {
      // Only submit the form if is has changed, and if it is valid
      updateSocials({ ...formValues });
    }
    setIsEditing(false);
  };

  const renderCheck = (
    url: string,
    validation: FormGroupProps['validationState'],
    dataPlaywrightTestLabel: string
  ) =>
    url && validation === 'success' ? (
      <FormControl.Feedback>
        <span>
          <FontAwesomeIcon
            data-playwright-test-label={dataPlaywrightTestLabel}
            icon={faCheck}
            size='1x'
          />
        </span>
      </FormControl.Feedback>
    ) : null;

  const {
    state: githubProfileValidation,
    message: githubProfileValidationMessage
  } = getValidationStateFor(formValues.githubProfile);

  const { state: linkedinValidation, message: linkedinValidationMessage } =
    getValidationStateFor(formValues.linkedin);

  const { state: twitterValidation, message: twitterValidationMessage } =

Review comment (bug):
While were refactoring, could you convert this into a component (defined outside `InternetSettings`)?

Functions that return JSX can and do work, but they are a trap. Reason being, they look so much like components that people call hooks inside them. This does work well.

We've been bitten by this before and it was a pain to debug!

Code after:

  const handleSubmit = (e: React.FormEvent) => {
    e.preventDefault();
    if (!isFormPristine() && isFormValid()) {
      // Only submit the form if is has changed, and if it is valid
      updateSocials({ ...formValues });
    }
    setIsEditing(false);
  };

  const {
    state: githubProfileValidation,
    message: githubProfileValidationMessage
  } = getValidationStateFor(formValues.githubProfile);

  const { state: linkedinValidation, message: linkedinValidationMessage } =
    getValidationStateFor(formValues.linkedin);

  const { state: twitterValidation, message: twitterValidationMessage } =
    getValidationStateFor(formValues.twitter);

  const { state: websiteValidation, message: websiteValidationMessage } =
    getValidationStateFor(formValues.website);
  const isDisabled = isFormPristine() || !isFormValid();

  return (
    <>
      <SectionHeader>{t('settings.headings.internet')}</SectionHeader>
      <FullWidthRow>
        <form
          id='internet-presence'
          onSubmit={handleSubmit}
          data-playwright-test-label='internet-presence'
        >
          <div role='group' aria-label={t('settings.headings.internet')}>
            <FormGroup
              controlId='internet-github'
              validationState={githubProfileValidation}
            >
              <ControlLabel htmlFor='internet-github-input'>
                GitHub
              </ControlLabel>
              <FormControl
                data-playwright-test-label='internet-github-input'
                onChange={createHandleChange('githubProfile')}
                placeholder='https://github.com/user-name'
                type='url'
                value={formValues.githubProfile}
                id='internet-github-input'
              />
              <Check