Skip to content
Open
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,4 +28,4 @@ implement the ability to filter and sort people in the table.
- Implement a solution following the [React task guideline](https://github.com/mate-academy/react_task-guideline#react-tasks-guideline).
- Use the [React TypeScript cheat sheet](https://mate-academy.github.io/fe-program/js/extra/react-typescript).
- Open one more terminal and run tests with `npm test` to ensure your solution is correct.
- Replace `<your_account>` with your Github username in the [DEMO LINK](https://<your_account>.github.io/react_people-table-advanced/) and add it to the PR description.
- Replace `<your_account>` with your Github username in the [DEMO LINK](https://Inna-code10.github.io/react_people-table-advanced/) and add it to the PR description.
3 changes: 3 additions & 0 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />

<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.4/css/all.min.css" />

<title>Vite + React + TS</title>
</head>
<body>
Expand Down
9 changes: 5 additions & 4 deletions package-lock.json

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

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
},
"devDependencies": {
"@cypress/react18": "^2.0.1",
"@mate-academy/scripts": "^1.9.12",
"@mate-academy/scripts": "^2.1.3",
"@mate-academy/students-ts-config": "*",
"@mate-academy/stylelint-config": "*",
"@types/node": "^20.14.10",
Expand Down
19 changes: 19 additions & 0 deletions src/App.scss
Original file line number Diff line number Diff line change
@@ -1,3 +1,22 @@
iframe {
display: none;
}

.title {
padding-top: 48px;
}

.navbar {
position: fixed;
top: 0;
z-index: 1000;
}

.section {
padding-top: 70px;
}

.table-container {
position: relative;
z-index: 1001;
}
37 changes: 23 additions & 14 deletions src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,20 +1,29 @@
import { PeoplePage } from './components/PeoplePage';
import { Navigate, Route, Routes } from 'react-router-dom';

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

import './App.scss';

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

<main className="section">
<div className="container">
<Routes>
<Route path="/" element={<HomePage />} />

<Route path="/home" element={<Navigate to="/" replace />} />

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

<div className="section">
<div className="container">
<h1 className="title">Home Page</h1>
<h1 className="title">Page not found</h1>
<PeoplePage />
</div>
<Route path="*" element={<NotFoundPage />} />
</Routes>
</div>
</div>
);
};
</main>
</div>
);
54 changes: 30 additions & 24 deletions src/components/Navbar.tsx
Original file line number Diff line number Diff line change
@@ -1,26 +1,32 @@
export const Navbar = () => {
return (
<nav
data-cy="nav"
className="navbar is-fixed-top has-shadow"
role="navigation"
aria-label="main navigation"
>
<div className="container">
<div className="navbar-brand">
<a className="navbar-item" href="#/">
Home
</a>
import { NavLink } from 'react-router-dom';

<a
aria-current="page"
className="navbar-item has-background-grey-lighter"
href="#/people"
>
People
</a>
</div>
export const Navbar = () => (
<nav
data-cy="nav"
className="navbar is-fixed-top has-shadow"
role="navigation"
aria-label="main navigation"
>
<div className="container">
<div className="navbar-brand">
<NavLink
to="/"
className={({ isActive }) =>
`navbar-item ${isActive ? 'has-background-grey-lighter' : ''}`
}
>
Home
</NavLink>

<NavLink
to="/people"
className={({ isActive }) =>
`navbar-item ${isActive ? 'has-background-grey-lighter' : ''}`
}
>
People
</NavLink>
</div>
</nav>
);
};
</div>
</nav>
);
119 changes: 64 additions & 55 deletions src/components/PeopleFilters.tsx
Original file line number Diff line number Diff line change
@@ -1,27 +1,58 @@
import { useSearchParams } from 'react-router-dom';
import { ChangeEvent } from 'react';

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

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

const handleQueryChange = (event: ChangeEvent<HTMLInputElement>) => {
const value = event.target.value.trim();

const newParams = new URLSearchParams(searchParams);

if (value) {
newParams.set('query', value);
} else {
newParams.delete('query');
}

setSearchParams(newParams);
};

const handleCenturyChange = (century: string) => {
const newParams = new URLSearchParams(searchParams);
const current = newParams.getAll('centuries');

newParams.delete('centuries');

const updated = current.includes(century)
? current.filter(c => c !== century)
: [...current, century];

updated.forEach(c => newParams.append('centuries', c));

setSearchParams(newParams);
};

const resetAll = () => {
setSearchParams({});
};

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

<p className="panel-tabs" data-cy="SexFilter">
<a className="is-active" href="#/people">
All
</a>
<a className="" href="#/people?sex=m">
Male
</a>
<a className="" href="#/people?sex=f">
Female
</a>
</p>

<div className="panel-block">
<p className="control has-icons-left">
<input
data-cy="NameFilter"
type="search"
className="input"
placeholder="Search"
value={query}
onChange={handleQueryChange}
/>

<span className="icon is-left">
Expand All @@ -33,63 +64,41 @@ 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>
{['16', '17', '18', '19', '20'].map(c => {
const isActive = centuries.includes(c);

<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>
return (
<button
key={c}
data-cy="century"
className={`button mr-1 ${isActive ? 'is-info' : ''}`}
onClick={() => handleCenturyChange(c)}
>
{c}
</button>
);
})}
</div>

<div className="level-right ml-4">
<a
<button
data-cy="centuryALL"
className="button is-success is-outlined"
href="#/people"
onClick={resetAll}
>
All
</a>
</button>
</div>
</div>
</div>

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

This file was deleted.

Loading
Loading