diff --git a/src/Root.tsx b/src/Root.tsx index cb834b04f..163b181d8 100644 --- a/src/Root.tsx +++ b/src/Root.tsx @@ -16,8 +16,9 @@ export const Root = () => ( }> } /> } /> - } /> - } /> + + } /> + } /> diff --git a/src/api.ts b/src/api.ts index 84b0c544d..db5820724 100644 --- a/src/api.ts +++ b/src/api.ts @@ -26,7 +26,10 @@ export function addParent(people: Person[]) { }); } -export function sortPeople(people: Person[], sortParam: SortParam | string) { +export function getSortedPeople( + people: Person[], + sortParam: SortParam | string, +) { if (sortParam) { return [...people].sort((a, b) => { switch (sortParam) { @@ -50,7 +53,14 @@ export function sortPeople(people: Person[], sortParam: SortParam | string) { return [...people]; } -export function filterPeople( +const getFilteredPeopleHelper = ( + name: string | null, + query: string, +) => { + return name?.toLowerCase().includes(query); +}; + +export function getFilteredPeople( filterOption: FilterType, people: Person[], ) { @@ -71,9 +81,13 @@ export function filterPeople( if (filterOption.query) { filteredPeople = filteredPeople - .filter(person => person.name.includes(filterOption.query) - || person.motherName?.includes(filterOption.query) - || person.fatherName?.includes(filterOption.query)); + .filter(person => { + const query = filterOption.query.toLowerCase(); + + return getFilteredPeopleHelper(person.name, query) + || getFilteredPeopleHelper(person.motherName, query) + || getFilteredPeopleHelper(person.fatherName, query); + }); } return filteredPeople; diff --git a/src/components/ColumnNameItem/ColumnNameItem.tsx b/src/components/ColumnNameItem/ColumnNameItem.tsx index aa9fe1dff..8e25da3e5 100644 --- a/src/components/ColumnNameItem/ColumnNameItem.tsx +++ b/src/components/ColumnNameItem/ColumnNameItem.tsx @@ -1,5 +1,6 @@ import React from 'react'; import { useSearchParams } from 'react-router-dom'; +import cn from 'classnames'; import { SearchLink } from '../SearchLink'; import { ColumnNames } from '../../types'; @@ -28,6 +29,10 @@ export const ColumnName: React.FC = ({ value }) => { return { sort: null, order: null }; }; + const hasFaSort = lowerCasedValue !== sort; + const hasFaSortUp = lowerCasedValue === sort && !order; + const hasFaSortDown = order && lowerCasedValue === sort; + return ( @@ -36,13 +41,13 @@ export const ColumnName: React.FC = ({ value }) => { params={getSortParams(lowerCasedValue)} > - {lowerCasedValue !== sort && ()} - {lowerCasedValue === sort && !order && ( - - )} - {order && lowerCasedValue === sort && ( - + diff --git a/src/components/Navbar/Navbar.tsx b/src/components/Navbar/Navbar.tsx index 267a2df42..25a498bf5 100644 --- a/src/components/Navbar/Navbar.tsx +++ b/src/components/Navbar/Navbar.tsx @@ -1,7 +1,8 @@ -import { NavLink } from 'react-router-dom'; +import { NavLink, useSearchParams } from 'react-router-dom'; import cn from 'classnames'; export const Navbar = () => { + const [searchParams] = useSearchParams(); const getLinkClass = ({ isActive }: { isActive: boolean }) => cn( 'navbar-item', { 'has-background-grey-lighter': isActive }, @@ -24,7 +25,10 @@ export const Navbar = () => { People diff --git a/src/components/PeopleFilters/PeopleFilters.tsx b/src/components/PeopleFilters/PeopleFilters.tsx index eb8fba331..dc229d8ec 100644 --- a/src/components/PeopleFilters/PeopleFilters.tsx +++ b/src/components/PeopleFilters/PeopleFilters.tsx @@ -15,13 +15,10 @@ export const PeopleFilters = () => { const centuries = searchParams.getAll('centuries') || []; const handleQueryChange = (event: React.ChangeEvent) => { - if (!event.target.value) { - setSearchParams(getSearchWith(searchParams, - { query: null })); - } else { - setSearchParams(getSearchWith(searchParams, - { query: event.target.value })); - } + setSearchParams( + getSearchWith(searchParams, + { query: event.target.value || null }), + ); }; return ( @@ -80,12 +77,12 @@ export const PeopleFilters = () => { ); diff --git a/src/components/PeopleTable/PeopleTable.tsx b/src/components/PeopleTable/PeopleTable.tsx index 4482642c3..11c829d16 100644 --- a/src/components/PeopleTable/PeopleTable.tsx +++ b/src/components/PeopleTable/PeopleTable.tsx @@ -1,54 +1,22 @@ -import React, { useEffect, useState } from 'react'; -import { Outlet, useParams, useSearchParams } from 'react-router-dom'; +import React from 'react'; +import { Outlet, useParams } from 'react-router-dom'; import { PersonItem } from '../PersonItem'; import { ColumnName } from '../ColumnNameItem'; - -import { filterPeople, sortPeople } from '../../api'; - -import { ColumnNames, FilterType, Person } from '../../types'; -import { SortParam } from '../../types/SortParam'; -import { DESC_SORT } from '../../utils/variables'; +import { ColumnNames, Person } from '../../types'; type Props = { - people: Person[], filteredPeople: Person[], - setFilteredPeople: React.Dispatch>, }; export const PeopleTable: React.FC = ({ - people, filteredPeople, - setFilteredPeople, }) => { const { slug } = useParams(); const selectedPersonSlug = slug || ''; - const [sortedPeople, setSortedPeople] = useState(people); - - const [searchParams] = useSearchParams(); - const sort: typeof SortParam | string = searchParams.get('sort') || ''; - const order = searchParams.get('order') || ''; - const query = searchParams.get('query') || ''; - const centuries = searchParams.getAll('centuries') || []; - const sex = searchParams.get('sex') || ''; - - const filters: FilterType = { - query, - centuries, - sex, - }; - - useEffect(() => { - setSortedPeople(sortPeople(people, sort)); - }, [sort, query, centuries.length, sex]); - - useEffect(() => { - setFilteredPeople(filterPeople(filters, sortedPeople)); - }, [query, centuries.length, sex, sortedPeople]); - - if (order === DESC_SORT) { - filteredPeople.reverse(); + if (!filteredPeople.length) { + return null; } return ( diff --git a/src/components/PersonLink/PersonLink.tsx b/src/components/PersonLink/PersonLink.tsx index 23c3eda9a..3a0bf82e1 100644 --- a/src/components/PersonLink/PersonLink.tsx +++ b/src/components/PersonLink/PersonLink.tsx @@ -22,7 +22,7 @@ export const PersonLink: React.FC = ({ person }) => { return ( {name} diff --git a/src/pages/PeoplePage/PeoplePage.tsx b/src/pages/PeoplePage/PeoplePage.tsx index 9a719c7ea..451ca86de 100644 --- a/src/pages/PeoplePage/PeoplePage.tsx +++ b/src/pages/PeoplePage/PeoplePage.tsx @@ -1,24 +1,49 @@ import { useEffect, useState } from 'react'; +import { useSearchParams } from 'react-router-dom'; -import { addParent, getPeople } from '../../api'; -import { Person } from '../../types'; +import { + addParent, + getFilteredPeople, + getPeople, + getSortedPeople, +} from '../../api'; + +import { FilterType, Person } from '../../types'; import { PeopleFilters } from '../../components/PeopleFilters'; import { Loader } from '../../components/Loader'; import { PeopleTable } from '../../components/PeopleTable'; +import { SortParam } from '../../types/SortParam'; +import { DESC_SORT } from '../../utils/variables'; export const PeoplePage = () => { const [people, setPeople] = useState([]); - const [filteredPeople, setFilteredPeople] = useState([]); - const [isLoading, setIsLoading] = useState(false); + const [searchParams] = useSearchParams(); + const sort: typeof SortParam | string = searchParams.get('sort') || ''; + const sortedPeople = getSortedPeople(people, sort); + + const order = searchParams.get('order') || ''; + const query = searchParams.get('query') || ''; + const centuries = searchParams.getAll('centuries') || []; + const sex = searchParams.get('sex') || ''; + + const filters: FilterType = { + query, + centuries, + sex, + }; + + const filteredPeople = getFilteredPeople(filters, sortedPeople); + const [isLoading, setIsLoading] = useState(true); const [hasError, setHasError] = useState(false); - useEffect(() => { - setIsLoading(true); + if (order === DESC_SORT) { + filteredPeople.reverse(); + } + useEffect(() => { getPeople() .then((peopleFromServer) => { setPeople(addParent(peopleFromServer)); - setFilteredPeople(addParent(peopleFromServer)); }) .catch(() => { setHasError(true); @@ -29,6 +54,7 @@ export const PeoplePage = () => { }); }, []); + const hasPeopleFilter = !isLoading && !!people.length; const hasErrorMessage = hasError && !isLoading; const hasNoPeopleOnServer = !people.length && !hasError && !isLoading; const hasNoMatchingPeople = !isLoading @@ -42,7 +68,7 @@ export const PeoplePage = () => {
- {!isLoading && ()} + {hasPeopleFilter && ()}
@@ -67,9 +93,7 @@ export const PeoplePage = () => { {!!people.length && ( )}