diff --git a/cspell-dict.txt b/cspell-dict.txt index 4d39d3eb..8218957c 100644 --- a/cspell-dict.txt +++ b/cspell-dict.txt @@ -1,2 +1,3 @@ quicksnip +slugified slugifyed diff --git a/package-lock.json b/package-lock.json index 9f98d54f..dbc3b2fb 100644 --- a/package-lock.json +++ b/package-lock.json @@ -13,7 +13,7 @@ "prismjs": "^1.29.0", "react": "^18.3.1", "react-dom": "^18.3.1", - "react-router-dom": "^6.27.0", + "react-router-dom": "^7.1.1", "react-syntax-highlighter": "^15.6.1" }, "devDependencies": { @@ -1188,14 +1188,6 @@ "url": "https://opencollective.com/unts" } }, - "node_modules/@remix-run/router": { - "version": "1.21.0", - "resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.21.0.tgz", - "integrity": "sha512-xfSkCAchbdG5PnbrKqFWwia4Bi61nH+wm8wLEqfHDyp7Y3dZzgqS2itV8i4gAq9pC2HsTpwyBC6Ds8VHZ96JlA==", - "engines": { - "node": ">=14.0.0" - } - }, "node_modules/@rollup/rollup-android-arm-eabi": { "version": "4.29.1", "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.29.1.tgz", @@ -1662,6 +1654,11 @@ "@swc/counter": "^0.1.3" } }, + "node_modules/@types/cookie": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.6.0.tgz", + "integrity": "sha512-4Kh9a6B2bQciAhf7FSuMRRkUWecJgJu9nPnx3yzpsfXX/c50REIqpHY4C82bXP90qrLtXtkDxTZosYO3UpOwlA==" + }, "node_modules/@types/eslint": { "version": "9.6.1", "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-9.6.1.tgz", @@ -2403,6 +2400,14 @@ "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", "dev": true }, + "node_modules/cookie": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-1.0.2.tgz", + "integrity": "sha512-9Kr/j4O16ISv8zBBhJoi4bXOYNTkFLOqSL3UDB0njXxCXNezjeyVrJyGOWtgfs/q2km1gwBcfH8q1yEGoMYunA==", + "engines": { + "node": ">=18" + } + }, "node_modules/core-util-is": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", @@ -5156,33 +5161,41 @@ "dev": true }, "node_modules/react-router": { - "version": "6.28.1", - "resolved": "https://registry.npmjs.org/react-router/-/react-router-6.28.1.tgz", - "integrity": "sha512-2omQTA3rkMljmrvvo6WtewGdVh45SpL9hGiCI9uUrwGGfNFDIvGK4gYJsKlJoNVi6AQZcopSCballL+QGOm7fA==", + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/react-router/-/react-router-7.1.1.tgz", + "integrity": "sha512-39sXJkftkKWRZ2oJtHhCxmoCrBCULr/HAH4IT5DHlgu/Q0FCPV0S4Lx+abjDTx/74xoZzNYDYbOZWlJjruyuDQ==", "dependencies": { - "@remix-run/router": "1.21.0" + "@types/cookie": "^0.6.0", + "cookie": "^1.0.1", + "set-cookie-parser": "^2.6.0", + "turbo-stream": "2.4.0" }, "engines": { - "node": ">=14.0.0" + "node": ">=20.0.0" }, "peerDependencies": { - "react": ">=16.8" + "react": ">=18", + "react-dom": ">=18" + }, + "peerDependenciesMeta": { + "react-dom": { + "optional": true + } } }, "node_modules/react-router-dom": { - "version": "6.28.1", - "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.28.1.tgz", - "integrity": "sha512-YraE27C/RdjcZwl5UCqF/ffXnZDxpJdk9Q6jw38SZHjXs7NNdpViq2l2c7fO7+4uWaEfcwfGCv3RSg4e1By/fQ==", + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-7.1.1.tgz", + "integrity": "sha512-vSrQHWlJ5DCfyrhgo0k6zViOe9ToK8uT5XGSmnuC2R3/g261IdIMpZVqfjD6vWSXdnf5Czs4VA/V60oVR6/jnA==", "dependencies": { - "@remix-run/router": "1.21.0", - "react-router": "6.28.1" + "react-router": "7.1.1" }, "engines": { - "node": ">=14.0.0" + "node": ">=20.0.0" }, "peerDependencies": { - "react": ">=16.8", - "react-dom": ">=16.8" + "react": ">=18", + "react-dom": ">=18" } }, "node_modules/react-syntax-highlighter": { @@ -5458,6 +5471,11 @@ "node": ">=10" } }, + "node_modules/set-cookie-parser": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/set-cookie-parser/-/set-cookie-parser-2.7.1.tgz", + "integrity": "sha512-IOc8uWeOZgnb3ptbCURJWNjWUPcO3ZnTTdzsurqERrP6nPyv+paC55vJM0LpOlT2ne+Ix+9+CRG1MNLlyZ4GjQ==" + }, "node_modules/set-function-length": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", @@ -5870,6 +5888,11 @@ "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==" }, + "node_modules/turbo-stream": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/turbo-stream/-/turbo-stream-2.4.0.tgz", + "integrity": "sha512-FHncC10WpBd2eOmGwpmQsWLDoK4cqsA/UT/GqNoaKOQnT8uzhtCbg3EoUDMvqpOSAI0S26mr0rkjzbOO6S3v1g==" + }, "node_modules/type-check": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", diff --git a/package.json b/package.json index 290c1ea6..97231e34 100644 --- a/package.json +++ b/package.json @@ -21,7 +21,7 @@ "prismjs": "^1.29.0", "react": "^18.3.1", "react-dom": "^18.3.1", - "react-router-dom": "^6.27.0", + "react-router-dom": "^7.1.1", "react-syntax-highlighter": "^15.6.1" }, "devDependencies": { diff --git a/src/AppRouter.tsx b/src/AppRouter.tsx new file mode 100644 index 00000000..65523eb1 --- /dev/null +++ b/src/AppRouter.tsx @@ -0,0 +1,18 @@ +import { Route, Routes } from "react-router-dom"; + +import App from "@components/App"; +import SnippetList from "@components/SnippetList"; + +const AppRouter = () => { + return ( + + }> + } /> + } /> + } /> + + + ); +}; + +export default AppRouter; diff --git a/src/components/App.tsx b/src/components/App.tsx new file mode 100644 index 00000000..d8418c6d --- /dev/null +++ b/src/components/App.tsx @@ -0,0 +1,17 @@ +import { FC } from "react"; + +import { AppProvider } from "@contexts/AppContext"; + +import Container from "./Container"; + +interface AppProps {} + +const App: FC = () => { + return ( + + + + ); +}; + +export default App; diff --git a/src/components/CategoryList.tsx b/src/components/CategoryList.tsx index 4f454a92..dd2c0d6c 100644 --- a/src/components/CategoryList.tsx +++ b/src/components/CategoryList.tsx @@ -1,33 +1,57 @@ -import { useEffect } from "react"; +import { FC } from "react"; +import { useNavigate, useSearchParams } from "react-router-dom"; import { useAppContext } from "@contexts/AppContext"; import { useCategories } from "@hooks/useCategories"; +import { slugify } from "@utils/slugify"; + +interface CategoryListItemProps { + name: string; +} + +const CategoryListItem: FC = ({ name }) => { + const navigate = useNavigate(); + const [searchParams] = useSearchParams(); + + const { language, category, setCategory } = useAppContext(); + + const handleSelect = () => { + setCategory(name); + navigate({ + pathname: `/${slugify(language.name)}/${slugify(name)}`, + search: searchParams.toString(), + }); + }; + + return ( +
  • + +
  • + ); +}; const CategoryList = () => { - const { category, setCategory } = useAppContext(); const { fetchedCategories, loading, error } = useCategories(); - useEffect(() => { - setCategory(fetchedCategories[0]); - }, [setCategory, fetchedCategories]); - - if (loading) return
    Loading...
    ; + if (loading) { + return
    Loading...
    ; + } - if (error) return
    Error occurred: {error}
    ; + if (error) { + return
    Error occurred: {error}
    ; + } return ( ); diff --git a/src/App.tsx b/src/components/Container.tsx similarity index 75% rename from src/App.tsx rename to src/components/Container.tsx index d2ccddb6..dc657b26 100644 --- a/src/App.tsx +++ b/src/components/Container.tsx @@ -1,11 +1,15 @@ -import SnippetList from "@components/SnippetList"; +import { FC } from "react"; +import { Outlet } from "react-router-dom"; + import { useAppContext } from "@contexts/AppContext"; import Banner from "@layouts/Banner"; import Footer from "@layouts/Footer"; import Header from "@layouts/Header"; import Sidebar from "@layouts/Sidebar"; -const App = () => { +interface ContainerProps {} + +const Container: FC = () => { const { category } = useAppContext(); return ( @@ -18,7 +22,7 @@ const App = () => {

    {category ? category : "Select a category"}

    - +