Skip to content

Commit

Permalink
Tabs with router
Browse files Browse the repository at this point in the history
  • Loading branch information
OMedvid committed Nov 20, 2024
1 parent 75d6142 commit 6104833
Show file tree
Hide file tree
Showing 9 changed files with 115 additions and 59 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,5 +32,5 @@ or [React Tabs](https://github.com/mate-academy/react_tabs#react-tabs).
- 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_tabs-with-router/) and add it to the PR description.
- Replace `<your_account>` with your Github username in the [DEMO LINK](https://OMedvid.github.io/react_tabs-with-router/) and add it to the PR description.

3 changes: 2 additions & 1 deletion index.html
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<!doctype html>
<html lang="en">
<html lang="en" class="has-navbar-fixed-top">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
Expand All @@ -10,3 +10,4 @@
<script type="module" src="/src/index.tsx"></script>
</body>
</html>

38 changes: 21 additions & 17 deletions package-lock.json

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

4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,12 @@
"classnames": "^2.5.1",
"react": "^18.3.1",
"react-dom": "^18.3.1",
"react-router-dom": "^6.25.1",
"react-router-dom": "^6.28.0",
"react-transition-group": "^4.4.5"
},
"devDependencies": {
"@cypress/react18": "^2.0.1",
"@mate-academy/scripts": "^1.8.5",
"@mate-academy/scripts": "^1.9.12",
"@mate-academy/students-ts-config": "*",
"@mate-academy/stylelint-config": "*",
"@types/node": "^20.14.10",
Expand Down
40 changes: 9 additions & 31 deletions src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,55 +1,33 @@
import 'bulma/css/bulma.css';
import '@fortawesome/fontawesome-free/css/all.css';
import './App.scss';
import { Outlet, NavLink } from 'react-router-dom';
import classNames from 'classnames';

// const tabs = [
// { id: 'tab-1', title: 'Tab 1', content: 'Some text 1' },
// { id: 'tab-2', title: 'Tab 2', content: 'Some text 2' },
// { id: 'tab-3', title: 'Tab 3', content: 'Some text 3' },
// ];
const GetLinkClass = ({ isActive }: { isActive: boolean }) =>
classNames('navbar-item', { 'is-active': isActive });

export const App = () => (
<>
{/* Also requires <html class="has-navbar-fixed-top"> */}
<nav
className="navbar is-light is-fixed-top is-mobile has-shadow"
data-cy="Nav"
>
<div className="container">
<div className="navbar-brand">
<a href="/" className="navbar-item is-active">
<NavLink to="/" className={GetLinkClass}>
Home
</a>
<a href="/tabs" className="navbar-item">
</NavLink>
<NavLink to="/tabs" className={GetLinkClass}>
Tabs
</a>
</NavLink>
</div>
</div>
</nav>

<div className="section">
<div className="container">
<h1 className="title">Home page</h1>
<h1 className="title">Tabs page</h1>
<h1 className="title">Page not found</h1>

<div className="tabs is-boxed">
<ul>
<li data-cy="Tab" className="is-active">
<a href="#/">Tab 1</a>
</li>
<li data-cy="Tab">
<a href="#/">Tab 2</a>
</li>
<li data-cy="Tab">
<a href="#/">Tab 3</a>
</li>
</ul>
</div>

<div className="block" data-cy="TabContent">
Please select a tab
</div>
<Outlet />
</div>
</div>
</>
Expand Down
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 { TabsPage } from './components/Tabs';
import { App } from './App';
import { HomePage } from './components/HomePage';

export const Root = () => (
<Router>
<Routes>
<Route path="/" element={<App />}>
<Route index element={<HomePage />} />

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

<Route path="tabs">
<Route index element={<TabsPage />} />
<Route path=":tabId" element={<TabsPage />} />
</Route>

<Route path="*" element={<h1 className="title">Page not found</h1>} />
</Route>
</Routes>
</Router>
);
7 changes: 7 additions & 0 deletions src/components/HomePage.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
export const HomePage: React.FC = () => {
return (
<div className="container">
<h1 className="title">Home page</h1>
</div>
);
};
41 changes: 41 additions & 0 deletions src/components/Tabs.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import { Link, useParams } from 'react-router-dom';

const tabs = [
{ id: 'tab-1', title: 'Tab 1', content: 'Some text 1' },
{ id: 'tab-2', title: 'Tab 2', content: 'Some text 2' },
{ id: 'tab-3', title: 'Tab 3', content: 'Some text 3' },
];

export const TabsPage: React.FC = () => {
const { tabId } = useParams();
const selectedTab = tabs.find(tab => tab.id === tabId);

return (
<div className="container">
<h1 className="title">Tabs page</h1>
<div className="tabs is-boxed">
<ul>
{tabs.map(tab => (
<li
data-cy="Tab"
className={tabId === tab.id ? 'is-active' : ''}
key={tab.id}
>
<Link to={`/tabs/${tab.id}`}>{tab.title}</Link>
</li>
))}
</ul>
</div>

{selectedTab ? (
<div className="block" data-cy="TabContent">
{selectedTab.content}
</div>
) : (
<div className="block" data-cy="TabContent">
Please select a tab
</div>
)}
</div>
);
};
11 changes: 4 additions & 7 deletions src/index.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
import { createRoot } from 'react-dom/client';
import { HashRouter } from 'react-router-dom';
import { App } from './App';
import { Root } from './Root';

createRoot(document.getElementById('root') as HTMLElement).render(
<HashRouter>
<App />
</HashRouter>,
);
const conteiner = document.getElementById('root') as HTMLElement;

createRoot(conteiner).render(<Root />);

0 comments on commit 6104833

Please sign in to comment.