Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Solution #1131

Open
wants to merge 13 commits into
base: master
Choose a base branch
from
11 changes: 4 additions & 7 deletions src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,18 +1,15 @@
import { PeoplePage } from './components/PeoplePage';
import { Navbar } from './components/Navbar';

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

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

<div className="section">
<div className="container">
<h1 className="title">Home Page</h1>
<h1 className="title">Page not found</h1>
<PeoplePage />
<Outlet />
</div>
</div>
</div>
Expand Down
27 changes: 27 additions & 0 deletions src/Roots.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { HashRouter, Navigate } from 'react-router-dom';
import { Routes, Route } from 'react-router-dom';
import { Suspense } from 'react';
import { App } from './App';
import { Routing } from './Routing/Routing';
import { Loader } from './components/Loader';

const { HomePage, PeoplePage, NotFoundPage } = Routing;

export const Root = () => (
<HashRouter>
<Suspense fallback={<Loader />}>
<Routes>
<Route path="/" element={<App />}>
<Route index element={<HomePage />} />
<Route path="/home" element={<Navigate to="/" />} />

<Route path="people">
<Route path=":personId?" element={<PeoplePage />} />
</Route>

<Route path="*" element={<NotFoundPage />} />
</Route>
</Routes>
</Suspense>
</HashRouter>
);
11 changes: 11 additions & 0 deletions src/Routing/Routing.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { lazy } from 'react';

const PeoplePage = lazy(() => import('../pages/PeoplePage/PeoplePage'));
const HomePage = lazy(() => import('../pages/HomePage/HomePage'));
const NotFoundPage = lazy(() => import('../pages/NotFoundPage/NotFoundPage'));

export const Routing = {
PeoplePage,
HomePage,
NotFoundPage,
};
29 changes: 29 additions & 0 deletions src/components/Nav/Nav.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import { NavLink } from 'react-router-dom';
import cn from 'classnames';
import { navLinks } from '../../constants/navLinks';

export const Nav = () => (
<nav
data-cy="nav"
className="navbar is-fixed-top has-shadow"
role="navigation"
aria-label="main navigation"
>
<div className="container">
<div className="navbar-brand">
{navLinks.map(({ path, title, id }) => (
<NavLink
key={id}
to={path}
aria-current="page"
className={({ isActive }) =>
cn('navbar-item', { 'has-background-grey-lighter': isActive })
}
>
{title}
</NavLink>
))}
</div>
</div>
</nav>
);
26 changes: 0 additions & 26 deletions src/components/Navbar.tsx

This file was deleted.

47 changes: 47 additions & 0 deletions src/components/People/People.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import { Loader } from '../Loader';
import { ErrorNotification } from '../../shared/ErrorNotification';
import { PeopleTable } from '../PeopleTable/PeopleTable';
import { usePeopleFilter } from '../../hooks/usePeopleFilter';
import { usePeople } from '../../hooks/usePeople';

export const People = () => {
const { filtredPeople, isLoading, error, people } = usePeople();
const { centuries, name, sex } = usePeopleFilter();

const isPeopleEmpty = !people.length && !isLoading;

const isFilterParamsExist = !!(centuries.length || name || sex);

const generatePeopleView = () => {
switch (true) {
case !!error:
return (
<ErrorNotification dataCy="peopleLoadingError" errorMessage={error} />
);

case isPeopleEmpty:
return (
<p data-cy="noPeopleMessage">There are no people on the server</p>
);

case !filtredPeople.length && isFilterParamsExist:
return <p>There are no people matching the current search criteria</p>;

case !!filtredPeople.length:
return <PeopleTable people={filtredPeople} />;

default:
return null;
}
};

return (
<div className="column">
<div className="box table-container">
{isLoading && <Loader />}

{generatePeopleView()}
</div>
</div>
);
};
97 changes: 97 additions & 0 deletions src/components/PeopleFilter/PeopleFilters.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
import cn from 'classnames';

import {
centuryLinksParams,
sexLinksParams,
} from '../../constants/personLinks';
import { SearchLink } from '../../shared/SearchLink';
import { usePeopleFilter } from '../../hooks/usePeopleFilter';
import { Link } from 'react-router-dom';

export const PeopleFilters = () => {
const { name, centuries, sex, handleChangeName, toogleCenturies } =
usePeopleFilter();

return (
<div className="column is-7-tablet is-narrow-desktop">
<nav className="panel">
<p className="panel-heading">Filters</p>

<p className="panel-tabs" data-cy="SexFilter">
{sexLinksParams.map(({ params, title }) => (
<SearchLink
params={params}
key={title}
className={cn({
'is-active': sex === (params.sex ? params.sex : ''),
})}
>
{title}
</SearchLink>
))}
</p>

<div className="panel-block">
<p className="control has-icons-left">
<input
data-cy="NameFilter"
type="search"
className="input"
placeholder="Search"
onChange={e => handleChangeName(e.target.value)}
value={name}
/>

<span className="icon is-left">
<i className="fas fa-search" aria-hidden="true" />
</span>
</p>
</div>

<div className="panel-block">
<div
className="level is-flex-grow-1 is-mobile"
data-cy="CenturyFilter"
>
<div className="level-left">
{centuryLinksParams.map(({ century, title }) => (
<SearchLink
key={title}
data-cy="century"
params={{ centuries: toogleCenturies(century) }}
className={cn('button mr-1', {
'is-info': centuries.includes(century),
})}
>
{title}
</SearchLink>
))}
</div>

<div className="level-right ml-4">
<SearchLink
data-cy="centuryALL"
className={cn('button', 'is-success', {
'is-outlined': centuries.length,
})}
params={{ centuries: null }}
>
All
</SearchLink>
</div>
</div>
</div>

<div className="panel-block">
<Link
data-cy="centuryALL"
className="button is-link is-outlined is-fullwidth"
to="/people"
>
Reset all filters
</Link>
</div>
</nav>
</div>
);
};
96 changes: 0 additions & 96 deletions src/components/PeopleFilters.tsx

This file was deleted.

33 changes: 0 additions & 33 deletions src/components/PeoplePage.tsx

This file was deleted.

Loading
Loading