<commit_before>import React, { useContext, useMemo } from 'react';
import PropTypes from 'prop-types';
import {
  NavLink, Switch, Route, Redirect,
} from 'react-router-dom';
import AppRootContext from '../../AppRootContext';
import FormItemChangeGroup from './FormItemChangeGroup';
import { buildChangeGroups } from './FormItemChangeUtils';

function FormResponseChangeHistory({
  basePath, changes, convention, form,
}) {
  const { timezoneName } = useContext(AppRootContext);
  const changeGroups = useMemo(
    () => buildChangeGroups(changes, form),
    [changes, form],
  );

  if (changeGroups.length === 0) {
    return 'No changes.';
  }

  return (
    <div className="row">
      <nav className="col-md-3">
        <ul className="nav flex-column nav-pills">
          {changeGroups.map((changeGroup) => (
            <li className="nav-item" key={changeGroup.id}>
              <NavLink
                to={`${basePath}/${changeGroup.id}`}
                className="nav-link"
              >
                <strong>{changeGroup.changes[0].user_con_profile.name_without_nickname}</strong>
                <br />
                <small>
                  {changeGroup.timespan
                    .humanizeInTimezone(timezoneName, 'MMMM DD, YYYY - h:mma', 'h:mma')}
                </small>
              </NavLink>
            </li>
          ))}
        </ul>
      </nav>
      <div className="col-md-9">
        <Switch>
          {changeGroups.map((changeGroup) => (
            <Route
              key={changeGroup.id}
              path={`${basePath}/${changeGroup.id}`}
              render={() => (
                <FormItemChangeGroup
                  convention={convention}
                  changeGroup={changeGroup}
                />
              )}
            />
          ))}
          <Redirect to={`${basePath}/${changeGroups[0].id}`} />
        </Switch>
      </div>
    </div>
  );
}

FormResponseChangeHistory.propTypes = {
  basePath: PropTypes.string.isRequired,
  changes: PropTypes.arrayOf(PropTypes.shape({})).isRequired,<commit_msg>Use the function I extracted<commit_after>import React, { useContext, useMemo } from 'react';
import PropTypes from 'prop-types';
import {
  NavLink, Switch, Route, Redirect,
} from 'react-router-dom';
import AppRootContext from '../../AppRootContext';
import FormItemChangeGroup from './FormItemChangeGroup';
import { buildChangeGroups, getTimespanForChangeGroup } from './FormItemChangeUtils';

function FormResponseChangeHistory({
  basePath, changes, convention, form,
}) {
  const { timezoneName } = useContext(AppRootContext);
  const changeGroups = useMemo(
    () => buildChangeGroups(changes, form),
    [changes, form],
  );

  if (changeGroups.length === 0) {
    return 'No changes.';
  }

  return (
    <div className="row">
      <nav className="col-md-3">
        <ul className="nav flex-column nav-pills">
          {changeGroups.map((changeGroup) => (
            <li className="nav-item" key={changeGroup.id}>
              <NavLink
                to={`${basePath}/${changeGroup.id}`}
                className="nav-link"
              >
                <strong>{changeGroup.changes[0].user_con_profile.name_without_nickname}</strong>
                <br />
                <small>
                  {getTimespanForChangeGroup(changeGroup)
                    .humanizeInTimezone(timezoneName, 'MMMM DD, YYYY - h:mma', 'h:mma')}
                </small>
              </NavLink>
            </li>
          ))}
        </ul>
      </nav>
      <div className="col-md-9">
        <Switch>
          {changeGroups.map((changeGroup) => (
            <Route
              key={changeGroup.id}
              path={`${basePath}/${changeGroup.id}`}
              render={() => (
                <FormItemChangeGroup
                  convention={convention}
                  changeGroup={changeGroup}
                />
              )}
            />
          ))}
          <Redirect to={`${basePath}/${changeGroups[0].id}`} />
        </Switch>
      </div>
    </div>
  );
}

FormResponseChangeHistory.propTypes = {
  basePath: PropTypes.string.isRequired,
  changes: PropTypes.arrayOf(PropTypes.shape({})).isRequired,
{'fraction_non_alphanumeric': 0.144349477682811, 'fraction_numerical': 0.0023741690408357074, 'mean_word_length': 2.0071377587437547, 'pattern_counts': {'":': 0, '<': 47, '<?xml version=': 0, '>': 55, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6891961', 'n_tokens_mistral': 1207, 'n_tokens_neox': 1192, 'n_words': 210}