From bffc0702965e03fc6a8fd2753c427d4f1d88158d Mon Sep 17 00:00:00 2001 From: cspark Date: Sat, 13 Apr 2024 12:16:18 +0100 Subject: [PATCH] Implement react routing --- package-lock.json | 42 +++++++++++++++++++++ package.json | 3 +- src/App.tsx | 59 +++++++++++------------------- src/components/NavbarButton.tsx | 14 +++---- src/index.css | 65 ++++++++++++++++++++++----------- src/pages/About.tsx | 11 ++++++ src/pages/Home.tsx | 39 ++++++++++++++++++++ src/pages/Login.tsx | 9 +++++ webpack.config.js | 4 ++ 9 files changed, 178 insertions(+), 68 deletions(-) create mode 100644 src/pages/About.tsx create mode 100644 src/pages/Home.tsx create mode 100644 src/pages/Login.tsx diff --git a/package-lock.json b/package-lock.json index 4648f77..c322ab2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -21,6 +21,7 @@ "css-loader": "^7.1.1", "html-webpack-plugin": "^5.6.0", "prettier": "3.2.5", + "react-router-dom": "^6.22.3", "style-loader": "^4.0.0", "typescript": "^5.4.5", "webpack": "^5.91.0", @@ -1915,6 +1916,15 @@ "node": ">=14" } }, + "node_modules/@remix-run/router": { + "version": "1.15.3", + "resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.15.3.tgz", + "integrity": "sha512-Oy8rmScVrVxWZVOpEF57ovlnhpZ8CCPlnIIumVcV9nFdiSIrus99+Lw78ekXyGvVDlIsFJbSfmSovJUhCWYV3w==", + "dev": true, + "engines": { + "node": ">=14.0.0" + } + }, "node_modules/@types/body-parser": { "version": "1.19.5", "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.5.tgz", @@ -5379,6 +5389,38 @@ "react": "^18.2.0" } }, + "node_modules/react-router": { + "version": "6.22.3", + "resolved": "https://registry.npmjs.org/react-router/-/react-router-6.22.3.tgz", + "integrity": "sha512-dr2eb3Mj5zK2YISHK++foM9w4eBnO23eKnZEDs7c880P6oKbrjz/Svg9+nxqtHQK+oMW4OtjZca0RqPglXxguQ==", + "dev": true, + "dependencies": { + "@remix-run/router": "1.15.3" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "react": ">=16.8" + } + }, + "node_modules/react-router-dom": { + "version": "6.22.3", + "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.22.3.tgz", + "integrity": "sha512-7ZILI7HjcE+p31oQvwbokjk6OA/bnFxrhJ19n82Ex9Ph8fNAq+Hm/7KchpMGlTgWhUxRHMMCut+vEtNpWpowKw==", + "dev": true, + "dependencies": { + "@remix-run/router": "1.15.3", + "react-router": "6.22.3" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "react": ">=16.8", + "react-dom": ">=16.8" + } + }, "node_modules/readable-stream": { "version": "3.6.2", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", diff --git a/package.json b/package.json index 2683b12..7c7b2d0 100644 --- a/package.json +++ b/package.json @@ -6,7 +6,7 @@ "scripts": { "test": "echo \"Error: no test specified\" && exit 1", "build": "webpack", - "dev": "webpack-dev-server --mode development --open --hot" + "dev": "webpack-dev-server --mode development --open --hot --history-api-fallback" }, "repository": { "type": "git", @@ -20,6 +20,7 @@ "css-loader": "^7.1.1", "html-webpack-plugin": "^5.6.0", "prettier": "3.2.5", + "react-router-dom": "^6.22.3", "style-loader": "^4.0.0", "typescript": "^5.4.5", "webpack": "^5.91.0", diff --git a/src/App.tsx b/src/App.tsx index 1450246..3a02da9 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,46 +1,29 @@ import * as React from "react"; -import BlogEntryCard from "./components/BlogEntryCard.tsx"; +import { BrowserRouter, Routes, Route } from "react-router-dom"; + import Navbar from "./components/Navbar.tsx"; import NavbarButton from "./components/NavbarButton.tsx"; -export default function App() { - // A mock of what the data from the getBlogEntries JSON return would look like - const blogEntries = [ - { - blogImage: - "https://git.cspark.dev/avatars/1c230bfe7494b1a62932d94ed8558dc61189437b1b6e0cecdb0c45c3d899bea4?size=512", - blogTitle: "Test Blog Entry 1", - blogDatePosted: "12/04/2024 4PM", // In reality this would probably be an actual correct format/standardised timestamp - blogDescription: "This is a first blog entry test", // If no description, we'd want to get a small snippet of the intro of the blog - }, - { - blogImage: - "https://www.google.com/images/branding/googlelogo/1x/googlelogo_color_272x92dp.png", - blogTitle: "Test Blog Entry 2", - blogDatePosted: "8/04/2024 6PM", // In reality this would probably be an actual correct format/standardised timestamp - blogDescription: "This is a test blog entry number 2", // If no description, we'd want to get a small snippet of the intro of the blog - }, - ]; +import Home from "./pages/Home.tsx"; +import Login from "./pages/Login.tsx"; +import About from "./pages/About.tsx"; +export default function App() { return ( -
- - - - - - -
- {blogEntries.map((item, index) => ( - - ))} -
-
+ <> + + + Home + Login + About + + + } /> + } /> + } /> + } /> + + + ); } diff --git a/src/components/NavbarButton.tsx b/src/components/NavbarButton.tsx index 578b020..3c89745 100644 --- a/src/components/NavbarButton.tsx +++ b/src/components/NavbarButton.tsx @@ -1,18 +1,16 @@ import * as React from "react"; +import { Link } from "react-router-dom"; interface Props { - blogImage: string; // This needs a placeholder/default variable - blogTitle: string; - blogDatePosted: string; - blogDescription: string; + children: string; } -export default function NavbarButton() { +export default function NavbarButton({ children }: Props) { return ( <> - + +

{children}

+ ); } diff --git a/src/index.css b/src/index.css index 96a557a..b4c92e9 100644 --- a/src/index.css +++ b/src/index.css @@ -1,8 +1,12 @@ body { margin: 0px; padding: 0px; - background-color: white; font-family: "consolas", sans-serif; + background-color: white; + + --nav-bar-height: 25px; + --blog-card-width: 18rem; + --blog-card-height: 20rem; } a { @@ -11,15 +15,34 @@ a { .navBar { width: 100%; - height: 30px; - max-height: 30px; - background-color: black; + height: var(--nav-bar-height); + max-height: var(--nav-bar-height); + max-width: 100%; display: grid; - gap: 20px; - padding: 10px; + gap: 10px; + padding: 5px; grid-auto-flow: column; grid-auto-rows: 100%; grid-auto-columns: 5rem; + background-color: black; +} + +.navBarButton { + height: 100%; + width: 100%; + max-height: 100%; + max-width: 100%; + border-radius: 5px; + display: flex; + align-items: center; + justify-content: center; + background: white; +} + +.navBarButtonText { + margin: 0px; + padding: 0px; + text-align: center; } .blogEntryGrid { @@ -27,43 +50,43 @@ a { gap: 20px; padding: 10px; grid-auto-flow: column; - grid-auto-rows: 18rem; - grid-auto-columns: 18rem; + grid-auto-rows: var(--blog-card-height); + grid-auto-columns: var(--blog-card-width); } .blogEntryCard { - width: 18rem; - max-width: 18rem; - height: 20rem; - max-height: 20rem; + width: var(--blog-card-width); + height: var(--blog-card-height); + max-width: var(--blog-card-width); + max-height: var(--blog-card-height); } .blogEntry { + position: relative; width: 100%; height: 100%; border-style: solid; border-width: 5px; - border-color: black; border-radius: 10px; + border-color: black; background-color: white; - position: relative; } .blogEntryImage { - width: 18rem; - max-width: 18rem; - max-height: 18rem; + width: var(--blog-card-width); + max-width: var(--blog-card-width); + max-height: var(--blog-card-width); border-radius: 4px; } .blogEntryBody { - background-color: grey; - padding: 20px; position: absolute; - top: 8rem; - /* TODO: Need to switch to CSS grid positioning to sort this out */ width: 86%; height: 45%; + padding: 20px; + top: 8rem; + /* TODO: Need to switch to CSS grid positioning to sort this out */ + background-color: grey; } .blogEntryTitle { diff --git a/src/pages/About.tsx b/src/pages/About.tsx new file mode 100644 index 0000000..67bc757 --- /dev/null +++ b/src/pages/About.tsx @@ -0,0 +1,11 @@ +import * as React from "react"; + +export default function About() { + return ( +
+

This is an about me.

+

Developed by Curt Spark

+ Link to Project Page +
+ ); +} diff --git a/src/pages/Home.tsx b/src/pages/Home.tsx new file mode 100644 index 0000000..ed64a58 --- /dev/null +++ b/src/pages/Home.tsx @@ -0,0 +1,39 @@ +import * as React from "react"; + +import BlogEntryCard from "./../components/BlogEntryCard.tsx"; + +export default function Home() { + // A mock of what the data from the getBlogEntries JSON return would look like + const blogEntries = [ + { + blogImage: + "https://git.cspark.dev/avatars/1c230bfe7494b1a62932d94ed8558dc61189437b1b6e0cecdb0c45c3d899bea4?size=512", + blogTitle: "Test Blog Entry 1", + blogDatePosted: "12/04/2024 4PM", // In reality this would probably be an actual correct format/standardised timestamp + blogDescription: "This is a first blog entry test", // If no description, we'd want to get a small snippet of the intro of the blog + }, + { + blogImage: + "https://www.google.com/images/branding/googlelogo/1x/googlelogo_color_272x92dp.png", + blogTitle: "Test Blog Entry 2", + blogDatePosted: "8/04/2024 6PM", // In reality this would probably be an actual correct format/standardised timestamp + blogDescription: "This is a test blog entry number 2", // If no description, we'd want to get a small snippet of the intro of the blog + }, + ]; + + return ( +
+
+ {blogEntries.map((item, index) => ( + + ))} +
+
+ ); +} diff --git a/src/pages/Login.tsx b/src/pages/Login.tsx new file mode 100644 index 0000000..e47146a --- /dev/null +++ b/src/pages/Login.tsx @@ -0,0 +1,9 @@ +import * as React from "react"; + +export default function Login() { + return ( +
+

Login Page

+
+ ); +} diff --git a/webpack.config.js b/webpack.config.js index 6c446f7..5c7308d 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -6,6 +6,10 @@ module.exports = { output: { filename: "main.js", path: path.resolve(__dirname, "dist"), + publicPath: "/", + }, + devServer: { + historyApiFallback: true, }, module: { rules: [