Skip to content

Commit

Permalink
create people table
Browse files Browse the repository at this point in the history
  • Loading branch information
AlyonaV22 committed Dec 31, 2024
1 parent f874c0e commit 7628024
Show file tree
Hide file tree
Showing 15 changed files with 501 additions and 708 deletions.
37 changes: 31 additions & 6 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@
"react": "^18.3.1",
"react-dom": "^18.3.1",
"react-router-dom": "^6.25.1",
"react-transition-group": "^4.4.5"
"react-transition-group": "^4.4.5",
"uuid": "^11.0.3"
},
"devDependencies": {
"@cypress/react18": "^2.0.1",
Expand Down
14 changes: 5 additions & 9 deletions src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,20 +1,16 @@
import { PeoplePage } from './components/PeoplePage';
import { Navbar } from './components/Navbar';

import './App.scss';
import { Outlet } from 'react-router-dom';
import { Navbar } from './components/Navbar';

export const App = () => {
return (
<div data-cy="app">
<Navbar />

<div className="section">
<main className="section">
<div className="container">
<h1 className="title">Home Page</h1>
<h1 className="title">Page not found</h1>
<PeoplePage />
<Outlet />
</div>
</div>
</main>
</div>
);
};
28 changes: 28 additions & 0 deletions src/Root.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import {
HashRouter as Router,
Routes,
Route,
Navigate,
} from 'react-router-dom';

import { App } from './App';
import { HomePage } from './pages/HomePage';
import { NotFoundPage } from './pages/NotFoundPage';
import { PeoplePage } from './pages/PeoplePage';

export const Root = () => {
return (
<Router>
<Routes>
<Route path="/" element={<App />}>
<Route index element={<HomePage />} />
<Route path="people" element={<PeoplePage />}>
<Route path=":personSlug?" element={<PeoplePage />} />
</Route>
<Route path="home" element={<Navigate to="/" />} />
<Route path="*" element={<NotFoundPage />} />
</Route>
</Routes>
</Router>
);
};
21 changes: 13 additions & 8 deletions src/components/Navbar.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,13 @@
import { NavLink } from 'react-router-dom';
import cn from 'classnames';

export const Navbar = () => {
const getLinkClass = ({ isActive }: { isActive: boolean }) => {
return cn('navbar-item', {
'is-active has-background-grey-lighter': isActive,
});
};

return (
<nav
data-cy="nav"
Expand All @@ -8,17 +17,13 @@ export const Navbar = () => {
>
<div className="container">
<div className="navbar-brand">
<a className="navbar-item" href="#/">
<NavLink className={getLinkClass} to="/">
Home
</a>
</NavLink>

<a
aria-current="page"
className="navbar-item has-background-grey-lighter"
href="#/people"
>
<NavLink aria-current="page" className={getLinkClass} to="/people">
People
</a>
</NavLink>
</div>
</div>
</nav>
Expand Down
135 changes: 90 additions & 45 deletions src/components/PeopleFilters.tsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,82 @@
// eslint-disable-next-line import/no-extraneous-dependencies
import cn from 'classnames';

import { Link, useLocation, useSearchParams } from 'react-router-dom';
import { getSearchWith, SearchParams } from '../utils/searchHelper';

export const PeopleFilters = () => {
const { pathname } = useLocation();
const [searchParams, setSearchParams] = useSearchParams();

const query = searchParams.get('query') || '';
const sex = searchParams.get('sex') || '';
const centuries = searchParams.getAll('centuries') || [];

const searchNewParam = (newParams: SearchParams): void | string => {
const searchParam = getSearchWith(searchParams, newParams);

setSearchParams(searchParam);
};

const updateSearchParams = (
newParam: SearchParams,
event: React.MouseEvent<HTMLAnchorElement, MouseEvent>,
) => {
event.preventDefault();
searchNewParam(newParam);
};

function switchCentury(
century: string,
event: React.MouseEvent<HTMLAnchorElement, MouseEvent>,
) {
event.preventDefault();

const searchNewCentury = centuries.includes(century)
? centuries.filter(prevCentury => prevCentury !== century)
: [...centuries, century];

searchNewParam({ centuries: searchNewCentury });
}

const searchAllCenturies = (
event: React.MouseEvent<HTMLAnchorElement, MouseEvent>,
) => {
event.preventDefault();

searchNewParam({ centuries: [] });
};

const updateQuery = (event: React.ChangeEvent<HTMLInputElement>) => {
const value = event.target.value;

searchNewParam({ query: value || null });
};

return (
<nav className="panel">
<p className="panel-heading">Filters</p>

<p className="panel-tabs" data-cy="SexFilter">
<a className="is-active" href="#/people">
<a
className={cn({ 'is-active': !sex })}
href="/people"
onClick={event => updateSearchParams({ sex: null }, event)}
>
All
</a>
<a className="" href="#/people?sex=m">
<a
className={cn({ 'is-active': sex === 'm' })}
href="/people?sex=m"
onClick={event => updateSearchParams({ sex: 'm' }, event)}
>
Male
</a>
<a className="" href="#/people?sex=f">
<a
className={cn({ 'is-active': sex === 'f' })}
href="/people?sex=f"
onClick={event => updateSearchParams({ sex: 'f' }, event)}
>
Female
</a>
</p>
Expand All @@ -22,6 +88,8 @@ export const PeopleFilters = () => {
type="search"
className="input"
placeholder="Search"
value={query}
onChange={updateQuery}
/>

<span className="icon is-left">
Expand All @@ -33,52 +101,29 @@ export const PeopleFilters = () => {
<div className="panel-block">
<div className="level is-flex-grow-1 is-mobile" data-cy="CenturyFilter">
<div className="level-left">
<a
data-cy="century"
className="button mr-1"
href="#/people?centuries=16"
>
16
</a>

<a
data-cy="century"
className="button mr-1 is-info"
href="#/people?centuries=17"
>
17
</a>

<a
data-cy="century"
className="button mr-1 is-info"
href="#/people?centuries=18"
>
18
</a>

<a
data-cy="century"
className="button mr-1 is-info"
href="#/people?centuries=19"
>
19
</a>

<a
data-cy="century"
className="button mr-1"
href="#/people?centuries=20"
>
20
</a>
{[16, 17, 18, 19, 20].map(century => (
<a
key={century}
data-cy="century"
className={cn('button mr-1', {
'is-info': centuries.includes(century.toString()),
})}
href={`/people?centuries=${century}`}
onClick={event => switchCentury(century.toString(), event)}
>
{century}
</a>
))}
</div>

<div className="level-right ml-4">
<a
data-cy="centuryALL"
className="button is-success is-outlined"
className={cn('button is-success', {
'is-outlined': centuries.length,
})}
href="#/people"
onClick={searchAllCenturies}
>
All
</a>
Expand All @@ -87,9 +132,9 @@ export const PeopleFilters = () => {
</div>

<div className="panel-block">
<a className="button is-link is-outlined is-fullwidth" href="#/people">
<Link className="button is-link is-outlined is-fullwidth" to={pathname}>
Reset all filters
</a>
</Link>
</div>
</nav>
);
Expand Down
33 changes: 0 additions & 33 deletions src/components/PeoplePage.tsx

This file was deleted.

Loading

0 comments on commit 7628024

Please sign in to comment.