diff --git a/src/components/PeopleFilters/PeopleFilters.tsx b/src/components/PeopleFilters/PeopleFilters.tsx index 17cb9a39a..39755d0fc 100644 --- a/src/components/PeopleFilters/PeopleFilters.tsx +++ b/src/components/PeopleFilters/PeopleFilters.tsx @@ -1,5 +1,5 @@ import { debounce } from 'lodash'; -import { useSearchParams } from 'react-router-dom'; +import { Link, useSearchParams } from 'react-router-dom'; import { useCallback, useEffect } from 'react'; import classNames from 'classnames'; import { SearchLink } from '../SearchLink'; @@ -76,7 +76,6 @@ export const PeopleFilters = () => { type="search" className="input" placeholder="Search" - value={query} onChange={handleQueryChange} /> @@ -120,9 +119,12 @@ export const PeopleFilters = () => {
- + Reset all filters - +
); diff --git a/src/components/PeopleTable/PeopleTable.tsx b/src/components/PeopleTable/PeopleTable.tsx index 36cb487ea..52c70e8e4 100644 --- a/src/components/PeopleTable/PeopleTable.tsx +++ b/src/components/PeopleTable/PeopleTable.tsx @@ -1,17 +1,18 @@ -import { useParams } from 'react-router-dom'; +import { useParams, useSearchParams } from 'react-router-dom'; import classNames from 'classnames'; import { Person } from '../../types'; import { PersonLink } from '../PersonLink'; type Props = { - peopleData: Person[]; + filteredPeople: Person[]; }; /* eslint-disable jsx-a11y/control-has-associated-label */ -export const PeopleTable: React.FC = ({ peopleData }) => { +export const PeopleTable: React.FC = ({ filteredPeople }) => { const { slug } = useParams(); - const isSelect = peopleData.find(person => person.slug === slug); + const [searchParams] = useSearchParams(); + const isSelect = filteredPeople.find(person => person.slug === slug); return ( = ({ peopleData }) => { - {peopleData.map(person => { + {filteredPeople.map(person => { const { sex, born, died, fatherName, motherName, slug } = person; - const mother = peopleData.find(p => p.name === motherName); - const father = peopleData.find(p => p.name === fatherName); + const getParent = (parentName: string | null) => { + if (!parentName) return '-'; + + const parent = filteredPeople.find( + ({ name }) => name === parentName, + ); + + return parent ? ( + + ) : ( + parentName + ); + }; return ( = ({ peopleData }) => { - - + + ); })} diff --git a/src/components/PersonLink/PersonLink.tsx b/src/components/PersonLink/PersonLink.tsx index afe37c8a4..2c3f50816 100644 --- a/src/components/PersonLink/PersonLink.tsx +++ b/src/components/PersonLink/PersonLink.tsx @@ -1,18 +1,20 @@ import React from 'react'; import { Person } from '../../types'; import { Link } from 'react-router-dom'; +import classNames from 'classnames'; type Props = { person: Person; + search?: string; }; -export const PersonLink: React.FC = ({ person }) => { +export const PersonLink: React.FC = ({ person, search = '' }) => { const { name, slug, sex } = person; return ( {name} diff --git a/src/pages/PeoplePage.tsx b/src/pages/PeoplePage.tsx index f50940f2f..c15558e52 100644 --- a/src/pages/PeoplePage.tsx +++ b/src/pages/PeoplePage.tsx @@ -1,14 +1,16 @@ -import { useEffect, useState } from 'react'; +import { useEffect, useMemo, useState } from 'react'; import { Loader } from '../components/Loader'; import { PeopleFilters } from '../components/PeopleFilters'; import { PeopleTable } from '../components/PeopleTable'; import { Person } from '../types'; +import { useSearchParams } from 'react-router-dom'; export const PeoplePage = () => { const [peopleData, setPeopleData] = useState([]); const [isLoading, setIsLoading] = useState(true); const [error, setError] = useState(''); + const [searchParams] = useSearchParams(); const fetchPeopleData = async () => { try { @@ -30,6 +32,23 @@ export const PeoplePage = () => { fetchPeopleData(); }, []); + console.log(peopleData); + + const filteredPeople = useMemo(() => { + const query = searchParams.get('query')?.toLowerCase() || ''; + const sex = searchParams.get('sex'); + const centuries = searchParams.getAll('centuries').map(Number); + + return peopleData.filter(person => { + const matchesQuery = !query || person.name.toLowerCase().includes(query); + const matchesSex = !sex || person.sex === sex; + const matchesCentury = + !centuries.length || centuries.includes(Math.ceil(person.died / 100)); + + return matchesQuery && matchesSex && matchesCentury; + }); + }, [peopleData, searchParams]); + return ( <>

People Page

@@ -50,15 +69,23 @@ export const PeoplePage = () => {

)} - {peopleData.length === 0 && !isLoading && !error && ( + {!isLoading && !error && peopleData.length === 0 && (

There are no people on the server

)} -

There are no people matching the current search criteria

- {peopleData.length > 0 && !isLoading && !error && ( - + {!isLoading && + !error && + peopleData.length > 0 && + filteredPeople.length === 0 && ( +

+ There are no people matching the current search criteria +

+ )} + + {!isLoading && !error && filteredPeople.length > 0 && ( + )}
{sex} {born} {died}{mother ? : '-'}{father ? : '-'}{getParent(motherName)}{getParent(fatherName)}