<commit_before>import PropTypes   from 'prop-types';
import { useMemo } from 'react';

import { Pokemon } from './pokemon';

const DEFER_CUTOFF = 120;

export function SearchResults ({ captures, hideCaught, query, setHideCaught, setQuery }) {
  const handleClearCaughtFilter = () => setHideCaught(false);
  const handleClearClick = () => setQuery('');

  const filteredCaptures = useMemo(() => {
    return captures.filter((capture) => {
      const matchesCaught = !hideCaught || !capture.captured;
      const matchesQuery = capture.pokemon.name.toLowerCase().indexOf(query) === 0;

      return matchesCaught && matchesQuery;
    });
  }, [captures, hideCaught, query]);

  if (filteredCaptures.length === 0) {
    let message = <p>No results. <a className="link" onClick={handleClearClick}>Clear your search?</a></p>;

    if (hideCaught) {
      if (query) {
        message = <p>No results in uncaught Pokémon. <a className="link" onClick={handleClearCaughtFilter}>Include caught Pokémon</a> or <a className="link" onClick={handleClearClick}>clear your search</a>?</p>;
      } else {
        message = <p>No uncaught Pokémon. <a className="link" onClick={handleClearCaughtFilter}>Show all Pokémon?</a></p>;
      }
    }

    return (
      <div className="search-results search-results-empty">
        {message}
      </div>
    );
  }

  return (
    <div className="search-results">
      {filteredCaptures.map((capture, i) => (
        <Pokemon
          capture={capture}
          delay={i > DEFER_CUTOFF ? 5 : 0}
          key={capture.pokemon.id}
        /><commit_msg>feat(search): make search a bit better (#463)<commit_after>import PropTypes   from 'prop-types';
import { useMemo } from 'react';

import { Pokemon } from './pokemon';
import { padding } from '../utils/formatting';

const DEFER_CUTOFF = 120;

export function SearchResults ({ captures, hideCaught, query, setHideCaught, setQuery }) {
  const handleClearCaughtFilter = () => setHideCaught(false);
  const handleClearClick = () => setQuery('');

  const filteredCaptures = useMemo(() => {
    return captures.filter((capture) => {
      const matchesCaught = !hideCaught || !capture.captured;
      const matchesQuery =
        // Case-insensitive name prefix match (e.g. bulba)
        capture.pokemon.name.toLowerCase().indexOf(query.toLowerCase()) === 0 ||
        // Exact national ID match (e.g. 1, 2, 3)
        capture.pokemon.national_id.toString() === query ||
        // Exact formatted national ID match (e.g. 001, 002, 003)
        padding(capture.pokemon.national_id, 3) === query;

      return matchesCaught && matchesQuery;
    });
  }, [captures, hideCaught, query]);

  if (filteredCaptures.length === 0) {
    let message = <p>No results. <a className="link" onClick={handleClearClick}>Clear your search?</a></p>;

    if (hideCaught) {
      if (query) {
        message = <p>No results in uncaught Pokémon. <a className="link" onClick={handleClearCaughtFilter}>Include caught Pokémon</a> or <a className="link" onClick={handleClearClick}>clear your search</a>?</p>;
      } else {
        message = <p>No uncaught Pokémon. <a className="link" onClick={handleClearCaughtFilter}>Show all Pokémon?</a></p>;
      }
    }

    return (
      <div className="search-results search-results-empty">
        {message}
      </div>
    );
  }

  return (
    <div className="search-results">
      {filteredCaptures.map((capture, i) => (
        <Pokemon
          capture={capture}
          delay={i > DEFER_CUTOFF ? 5 : 0}
          key={capture.pokemon.id}
        />
{'fraction_non_alphanumeric': 0.14838709677419354, 'fraction_numerical': 0.008415147265077139, 'mean_word_length': 3.2002355712603063, 'pattern_counts': {'":': 0, '<': 39, '<?xml version=': 0, '>': 51, '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': '2469871', 'n_tokens_mistral': 1134, 'n_tokens_neox': 1070, 'n_words': 256}