From 6104833543059d5e34b436f2054d57642a686f84 Mon Sep 17 00:00:00 2001 From: Medvid Oleksandr Date: Wed, 20 Nov 2024 20:38:18 +0200 Subject: [PATCH] Tabs with router --- README.md | 2 +- index.html | 3 ++- package-lock.json | 38 +++++++++++++++++++--------------- package.json | 4 ++-- src/App.tsx | 40 ++++++++---------------------------- src/Root.tsx | 28 +++++++++++++++++++++++++ src/components/HomePage.tsx | 7 +++++++ src/components/Tabs.tsx | 41 +++++++++++++++++++++++++++++++++++++ src/index.tsx | 11 ++++------ 9 files changed, 115 insertions(+), 59 deletions(-) create mode 100644 src/Root.tsx create mode 100644 src/components/HomePage.tsx create mode 100644 src/components/Tabs.tsx diff --git a/README.md b/README.md index 5e3bf0ea2..2a3debaf8 100644 --- a/README.md +++ b/README.md @@ -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 `` with your Github username in the [DEMO LINK](https://.github.io/react_tabs-with-router/) and add it to the PR description. +- Replace `` with your Github username in the [DEMO LINK](https://OMedvid.github.io/react_tabs-with-router/) and add it to the PR description. diff --git a/index.html b/index.html index 095fb3a45..a4090d1d9 100644 --- a/index.html +++ b/index.html @@ -1,5 +1,5 @@ - + @@ -10,3 +10,4 @@ + diff --git a/package-lock.json b/package-lock.json index 0c3f0e5bf..a12f97e15 100644 --- a/package-lock.json +++ b/package-lock.json @@ -15,12 +15,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", @@ -1184,10 +1184,11 @@ } }, "node_modules/@mate-academy/scripts": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/@mate-academy/scripts/-/scripts-1.8.5.tgz", - "integrity": "sha512-mHRY2FkuoYCf5U0ahIukkaRo5LSZsxrTSgMJheFoyf3VXsTvfM9OfWcZIDIDB521kdPrScHHnRp+JRNjCfUO5A==", + "version": "1.9.12", + "resolved": "https://registry.npmjs.org/@mate-academy/scripts/-/scripts-1.9.12.tgz", + "integrity": "sha512-/OcmxMa34lYLFlGx7Ig926W1U1qjrnXbjFJ2TzUcDaLmED+A5se652NcWwGOidXRuMAOYLPU2jNYBEkKyXrFJA==", "dev": true, + "license": "MIT", "dependencies": { "@octokit/rest": "^17.11.2", "@types/get-port": "^4.2.0", @@ -1876,9 +1877,10 @@ } }, "node_modules/@remix-run/router": { - "version": "1.18.0", - "resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.18.0.tgz", - "integrity": "sha512-L3jkqmqoSVBVKHfpGZmLrex0lxR5SucGA0sUfFzGctehw+S/ggL9L/0NnC5mw6P8HUWpFZ3nQw3cRApjjWx9Sw==", + "version": "1.21.0", + "resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.21.0.tgz", + "integrity": "sha512-xfSkCAchbdG5PnbrKqFWwia4Bi61nH+wm8wLEqfHDyp7Y3dZzgqS2itV8i4gAq9pC2HsTpwyBC6Ds8VHZ96JlA==", + "license": "MIT", "engines": { "node": ">=14.0.0" } @@ -8744,11 +8746,12 @@ } }, "node_modules/react-router": { - "version": "6.25.1", - "resolved": "https://registry.npmjs.org/react-router/-/react-router-6.25.1.tgz", - "integrity": "sha512-u8ELFr5Z6g02nUtpPAggP73Jigj1mRePSwhS/2nkTrlPU5yEkH1vYzWNyvSnSzeeE2DNqWdH+P8OhIh9wuXhTw==", + "version": "6.28.0", + "resolved": "https://registry.npmjs.org/react-router/-/react-router-6.28.0.tgz", + "integrity": "sha512-HrYdIFqdrnhDw0PqG/AKjAqEqM7AvxCz0DQ4h2W8k6nqmc5uRBYDag0SBxx9iYz5G8gnuNVLzUe13wl9eAsXXg==", + "license": "MIT", "dependencies": { - "@remix-run/router": "1.18.0" + "@remix-run/router": "1.21.0" }, "engines": { "node": ">=14.0.0" @@ -8758,12 +8761,13 @@ } }, "node_modules/react-router-dom": { - "version": "6.25.1", - "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.25.1.tgz", - "integrity": "sha512-0tUDpbFvk35iv+N89dWNrJp+afLgd+y4VtorJZuOCXK0kkCWjEvb3vTJM++SYvMEpbVwXKf3FjeVveVEb6JpDQ==", + "version": "6.28.0", + "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.28.0.tgz", + "integrity": "sha512-kQ7Unsl5YdyOltsPGl31zOjLrDv+m2VcIEcIHqYYD3Lp0UppLjrzcfJqDJwXxFw3TH/yvapbnUvPlAj7Kx5nbg==", + "license": "MIT", "dependencies": { - "@remix-run/router": "1.18.0", - "react-router": "6.25.1" + "@remix-run/router": "1.21.0", + "react-router": "6.28.0" }, "engines": { "node": ">=14.0.0" diff --git a/package.json b/package.json index 72baca675..0fc1ae951 100644 --- a/package.json +++ b/package.json @@ -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", diff --git a/src/App.tsx b/src/App.tsx index f587aebf0..cb6ad84ba 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -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 */}
-

Home page

-

Tabs page

-

Page not found

- -
- -
- -
- Please select a tab -
+
diff --git a/src/Root.tsx b/src/Root.tsx new file mode 100644 index 000000000..f1c269933 --- /dev/null +++ b/src/Root.tsx @@ -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 = () => ( + + + }> + } /> + + } /> + + + } /> + } /> + + + Page not found} /> + + + +); diff --git a/src/components/HomePage.tsx b/src/components/HomePage.tsx new file mode 100644 index 000000000..6ccd1e4bc --- /dev/null +++ b/src/components/HomePage.tsx @@ -0,0 +1,7 @@ +export const HomePage: React.FC = () => { + return ( +
+

Home page

+
+ ); +}; diff --git a/src/components/Tabs.tsx b/src/components/Tabs.tsx new file mode 100644 index 000000000..ba054e03e --- /dev/null +++ b/src/components/Tabs.tsx @@ -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 ( +
+

Tabs page

+
+
    + {tabs.map(tab => ( +
  • + {tab.title} +
  • + ))} +
+
+ + {selectedTab ? ( +
+ {selectedTab.content} +
+ ) : ( +
+ Please select a tab +
+ )} +
+ ); +}; diff --git a/src/index.tsx b/src/index.tsx index 53697a9fb..4d19d2adc 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -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( - - - , -); +const conteiner = document.getElementById('root') as HTMLElement; + +createRoot(conteiner).render();