<commit_before>import { NextPage, GetStaticProps } from "next";
import { Article } from "src/article";
import { loadAllArticles } from "src/site-data";
import FilterSidebar from "src/FilterSidebar";
import { useEffect, useState } from "react";
import { useRouter } from "next/router";
import {
  deserializeSettings,
  FilterOptions,
  getFilterOptions,
  match,
  serializeSettings,
  Settings,
} from "src/filters";

interface Props {
  articles: Article[];
  filterOptions: FilterOptions;
}

const Home: NextPage<Props> = (props) => {
  const { articles, filterOptions } = props;

  const hash = typeof window !== "undefined" ? window.location.hash : "";
  const initialSettings = deserializeSettings(hash);

  const [settings, setSettings] = useState(initialSettings);
  const [matchingArticles, setMatchingArticles] = useState(articles);

  useEffect(() => {
    const matches = articles.filter((a) => match(a, settings));
    setMatchingArticles(matches);
  }, [settings, articles]);

  const router = useRouter();
  const updateUrl = (settings: Settings) =>
    router.replace("#" + serializeSettings(settings));

  const updateFilters = (id: string, newValue: string | undefined) => {
    if (newValue) {
      const newSettings = { ...settings, [id]: newValue };
      setSettings(newSettings);
      updateUrl(newSettings);
    } else {
      const { [id]: _, ...newSettings } = settings;
      setSettings(newSettings);
      updateUrl(newSettings);
    }
  };

  const removeAllFilters = () => {
    setSettings({});
    updateUrl({});
  };

  return (
    <div>
      <Header />
      <Stats articles={matchingArticles} />
      <FilterSidebar
        options={filterOptions}
        settings={settings}
        onChange={updateFilters}
        removeAllFilters={removeAllFilters}
      />
      <Results articles={matchingArticles} />
    </div>
  );
};

const Header: React.FC = () => {
  return (
    <div className="header">
      <h1>
        Ohlasy <small>archiv článků</small>
      </h1>
    </div>
  );
};

const Stats: React.FC<{ articles: Article[] }> = ({ articles }) => {
  return <div className="status">nalezených článků: {articles.length}</div>;
};

const Results: React.FC<{ articles: Article[] }> = ({ articles }) => {
  return (<commit_msg>Improve article counter<commit_after>import { NextPage, GetStaticProps } from "next";
import { Article } from "src/article";
import { loadAllArticles } from "src/site-data";
import FilterSidebar from "src/FilterSidebar";
import { useEffect, useState } from "react";
import { useRouter } from "next/router";
import {
  deserializeSettings,
  FilterOptions,
  getFilterOptions,
  match,
  serializeSettings,
  Settings,
} from "src/filters";

interface Props {
  articles: Article[];
  filterOptions: FilterOptions;
}

const Home: NextPage<Props> = (props) => {
  const { articles, filterOptions } = props;

  const hash = typeof window !== "undefined" ? window.location.hash : "";
  const initialSettings = deserializeSettings(hash);

  const [settings, setSettings] = useState(initialSettings);
  const [matchingArticles, setMatchingArticles] = useState(articles);

  useEffect(() => {
    const matches = articles.filter((a) => match(a, settings));
    setMatchingArticles(matches);
  }, [settings, articles]);

  const router = useRouter();
  const updateUrl = (settings: Settings) =>
    router.replace("#" + serializeSettings(settings));

  const updateFilters = (id: string, newValue: string | undefined) => {
    if (newValue) {
      const newSettings = { ...settings, [id]: newValue };
      setSettings(newSettings);
      updateUrl(newSettings);
    } else {
      const { [id]: _, ...newSettings } = settings;
      setSettings(newSettings);
      updateUrl(newSettings);
    }
  };

  const removeAllFilters = () => {
    setSettings({});
    updateUrl({});
  };

  return (
    <div>
      <Header />
      <div className="status">
        nalezených článků: {matchingArticles.length}/{articles.length}
      </div>
      <FilterSidebar
        options={filterOptions}
        settings={settings}
        onChange={updateFilters}
        removeAllFilters={removeAllFilters}
      />
      <Results articles={matchingArticles} />
    </div>
  );
};

const Header: React.FC = () => {
  return (
    <div className="header">
      <h1>
        Ohlasy <small>archiv článků</small>
      </h1>
    </div>
  );
};

const Results: React.FC<{ articles: Article[] }> = ({ articles }) => {
  return (
{'fraction_non_alphanumeric': 0.14793296089385474, 'fraction_numerical': 0.000893854748603352, 'mean_word_length': 3.4804804804804803, 'pattern_counts': {'":': 0, '<': 35, '<?xml version=': 0, '>': 52, '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': '456605', 'n_tokens_mistral': 1348, 'n_tokens_neox': 1338, 'n_words': 303}