diff --git a/package-lock.json b/package-lock.json
index 66e2247..2280c50 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -15,6 +15,7 @@
"react": "19.0.0",
"react-bootstrap": "2.10.7",
"react-dom": "19.0.0",
+ "react-router-dom": "7.1.3",
"react-scripts": "5.0.1",
"use-query-params": "1.2.3"
},
@@ -3461,6 +3462,12 @@
"@types/node": "*"
}
},
+ "node_modules/@types/cookie": {
+ "version": "0.6.0",
+ "resolved": "http://94.130.170.209:4873/@types%2fcookie/-/cookie-0.6.0.tgz",
+ "integrity": "sha512-4Kh9a6B2bQciAhf7FSuMRRkUWecJgJu9nPnx3yzpsfXX/c50REIqpHY4C82bXP90qrLtXtkDxTZosYO3UpOwlA==",
+ "license": "MIT"
+ },
"node_modules/@types/eslint": {
"version": "7.29.0",
"license": "MIT",
@@ -12792,6 +12799,8 @@
"node_modules/node-fetch": {
"name": "@achingbrain/node-fetch",
"version": "2.6.7",
+ "resolved": "https://registry.npmjs.org/@achingbrain/node-fetch/-/node-fetch-2.6.7.tgz",
+ "integrity": "sha512-iTASGs+HTFK5E4ZqcMsHmeJ4zodyq8L38lZV33jwqcBJYoUt3HjN4+ot+O9/0b+ke8ddE7UgOtVuZN/OkV19/g==",
"dev": true,
"license": "MIT",
"engines": {
@@ -15109,6 +15118,55 @@
"node": ">=0.10.0"
}
},
+ "node_modules/react-router": {
+ "version": "7.1.3",
+ "resolved": "http://94.130.170.209:4873/react-router/-/react-router-7.1.3.tgz",
+ "integrity": "sha512-EezYymLY6Guk/zLQ2vRA8WvdUhWFEj5fcE3RfWihhxXBW7+cd1LsIiA3lmx+KCmneAGQuyBv820o44L2+TtkSA==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/cookie": "^0.6.0",
+ "cookie": "^1.0.1",
+ "set-cookie-parser": "^2.6.0",
+ "turbo-stream": "2.4.0"
+ },
+ "engines": {
+ "node": ">=20.0.0"
+ },
+ "peerDependencies": {
+ "react": ">=18",
+ "react-dom": ">=18"
+ },
+ "peerDependenciesMeta": {
+ "react-dom": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/react-router-dom": {
+ "version": "7.1.3",
+ "resolved": "http://94.130.170.209:4873/react-router-dom/-/react-router-dom-7.1.3.tgz",
+ "integrity": "sha512-qQGTE+77hleBzv9SIUIkGRvuFBQGagW+TQKy53UTZAO/3+YFNBYvRsNIZ1GT17yHbc63FylMOdS+m3oUriF1GA==",
+ "license": "MIT",
+ "dependencies": {
+ "react-router": "7.1.3"
+ },
+ "engines": {
+ "node": ">=20.0.0"
+ },
+ "peerDependencies": {
+ "react": ">=18",
+ "react-dom": ">=18"
+ }
+ },
+ "node_modules/react-router/node_modules/cookie": {
+ "version": "1.0.2",
+ "resolved": "http://94.130.170.209:4873/cookie/-/cookie-1.0.2.tgz",
+ "integrity": "sha512-9Kr/j4O16ISv8zBBhJoi4bXOYNTkFLOqSL3UDB0njXxCXNezjeyVrJyGOWtgfs/q2km1gwBcfH8q1yEGoMYunA==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=18"
+ }
+ },
"node_modules/react-scripts": {
"version": "5.0.1",
"license": "MIT",
@@ -16033,6 +16091,12 @@
"node": ">= 0.8.0"
}
},
+ "node_modules/set-cookie-parser": {
+ "version": "2.7.1",
+ "resolved": "http://94.130.170.209:4873/set-cookie-parser/-/set-cookie-parser-2.7.1.tgz",
+ "integrity": "sha512-IOc8uWeOZgnb3ptbCURJWNjWUPcO3ZnTTdzsurqERrP6nPyv+paC55vJM0LpOlT2ne+Ix+9+CRG1MNLlyZ4GjQ==",
+ "license": "MIT"
+ },
"node_modules/setprototypeof": {
"version": "1.2.0",
"license": "ISC"
@@ -17131,6 +17195,12 @@
"version": "1.14.1",
"license": "0BSD"
},
+ "node_modules/turbo-stream": {
+ "version": "2.4.0",
+ "resolved": "http://94.130.170.209:4873/turbo-stream/-/turbo-stream-2.4.0.tgz",
+ "integrity": "sha512-FHncC10WpBd2eOmGwpmQsWLDoK4cqsA/UT/GqNoaKOQnT8uzhtCbg3EoUDMvqpOSAI0S26mr0rkjzbOO6S3v1g==",
+ "license": "ISC"
+ },
"node_modules/type-check": {
"version": "0.4.0",
"license": "MIT",
diff --git a/package.json b/package.json
index f825e56..cd9bd07 100644
--- a/package.json
+++ b/package.json
@@ -9,6 +9,7 @@
"react": "19.0.0",
"react-bootstrap": "2.10.7",
"react-dom": "19.0.0",
+ "react-router-dom": "7.1.3",
"react-scripts": "5.0.1",
"use-query-params": "1.2.3"
},
diff --git a/src/App.css b/src/App.css
index be9d527..01396d1 100644
--- a/src/App.css
+++ b/src/App.css
@@ -21,8 +21,13 @@
.nav-link-active {
color: white !important;
+ text-decoration: none;
+ padding: 0.5rem;
}
.nav-link-inactive {
color: gray !important;
+ text-decoration: none;
+ padding: 0.5rem;
+
}
diff --git a/src/App.js b/src/App.js
index a819a3d..f814837 100644
--- a/src/App.js
+++ b/src/App.js
@@ -9,7 +9,6 @@ import React, { useEffect, useCallback } from 'react'
import './App.css'
import LoadScripts from './components/load-scripts'
import AsyncLoad from './services/async-load'
-import SelectServerButton from './components/app-body/servers/select-server-button'
import Footer from './components/footer'
import NavMenu from './components/nav-menu'
import useAppState from './hooks/state'
@@ -99,7 +98,6 @@ function App (props) {
? ()
: ()
}
-
diff --git a/src/components/app-body/index.js b/src/components/app-body/index.js
index eaa1670..8305005 100644
--- a/src/components/app-body/index.js
+++ b/src/components/app-body/index.js
@@ -8,41 +8,30 @@
// Global npm libraries
import React from 'react'
+import { Route, Routes } from 'react-router-dom'
// Local libraries
import GetBalance from './balance'
import Placeholder2 from './placeholder2'
import Placeholder3 from './placeholder3'
import ServerSelectView from './servers/select-server-view'
+import SelectServerButton from './servers/select-server-button'
function AppBody (props) {
// Dependency injection through props
const appData = props.appData
- const menuState = props.menuState
- // console.log('AppBody() menuState: ', menuState)
-
- function chooseView (menuState) {
- // console.log(`chooseView() menuState: ${menuState}`)
-
- switch (menuState) {
- case 0:
- return ()
- case 1:
- return ()
- case 2:
- return ()
-
- // Special Views
- case 100:
- return ()
- default:
- return ()
- }
- }
return (
<>
- {chooseView(menuState)}
+
+ } />
+ } />
+ } />
+ } />
+ } />
+
+ {/** Show in all paths except the servers view */}
+ {appData.currentPath !== '/servers' && }
>
)
}
diff --git a/src/components/app-body/servers/select-server-button.js b/src/components/app-body/servers/select-server-button.js
index 3d544a2..7e6d13d 100644
--- a/src/components/app-body/servers/select-server-button.js
+++ b/src/components/app-body/servers/select-server-button.js
@@ -6,32 +6,39 @@
// Global npm libraries
import React from 'react'
import { Container, Row, Col, Button } from 'react-bootstrap'
+import { useNavigate } from 'react-router-dom'
const ServerSelect = (props) => {
- const { appData } = props
+ const { linkTo } = props
+
+ // Use the navigate function to navigate to the servers view
+ const navigate = useNavigate()
// This is a click handler for the server select button. It brings up the
// server selection View.
const handleServerSelect = () => {
console.log('This function should navigate to the server selection view.')
- appData.setMenuState(100)
+ navigate(linkTo)
}
return (
-
-
-
-
-
- Having trouble loading? Try selecting a different back-end server.
-
-
-
-
-
+ <>
+
+
+
+
+
+ Having trouble loading? Try selecting a different back-end server.
+
+
+
+
+
+
+ >
)
}
diff --git a/src/components/nav-menu/index.js b/src/components/nav-menu/index.js
index 23e8c4e..e33f311 100644
--- a/src/components/nav-menu/index.js
+++ b/src/components/nav-menu/index.js
@@ -6,20 +6,29 @@
*/
// Global npm libraries
-import React from 'react'
-import { Nav, Navbar, Image } from 'react-bootstrap'
+import React, { useState } from 'react'
+import { Nav, Navbar, Image } from 'react-bootstrap' // Used for Navbar Style and Layouts .
+import { NavLink } from 'react-router-dom' // Used to navigate between routes
+
+// Assets
import Logo from './psf-logo.png'
function NavMenu (props) {
- const selectedMenu = props.appData.menuState
- const handleClickEvent = (menuItem) => {
- // Pass the selected menu item up to the parent component.
- props.appData.setMenuState(menuItem)
+ // Get the current path
+ const { currentPath } = props.appData
+
+ // Navbar state
+ const [expanded, setExpanded] = useState(false)
+
+ // Handle click event
+ const handleClickEvent = () => {
+ // Collapse the navbar
+ setExpanded(false)
}
return (
<>
-
+
{' '}
PSF Web3 Demo
@@ -28,27 +37,28 @@ function NavMenu (props) {
diff --git a/src/components/starter-views.js b/src/components/starter-views.js
index f1644aa..906de1a 100644
--- a/src/components/starter-views.js
+++ b/src/components/starter-views.js
@@ -4,7 +4,6 @@
import React from 'react'
import WaitingModal from './waiting-modal'
import AppBody from './app-body'
-
// This is rendered *before* the BCH wallet is initialized.
export function UninitializedView (props = {}) {
// console.log('UninitializedView props: ', props)
diff --git a/src/hooks/state.js b/src/hooks/state.js
index 56c2843..6ce8091 100644
--- a/src/hooks/state.js
+++ b/src/hooks/state.js
@@ -1,7 +1,9 @@
import { useState } from 'react'
import { useQueryParam, StringParam } from 'use-query-params'
-
+import { useLocation } from 'react-router-dom'
function useAppState () {
+ const location = useLocation()
+
// Get the CashStack URL from query parameter or use default
let [restURL] = useQueryParam('restURL', StringParam)
if (!restURL) restURL = 'https://free-bch.fullstack.cash'
@@ -44,7 +46,9 @@ function useAppState () {
hideSpinner,
setHideSpinner,
denyClose,
- setDenyClose
+ setDenyClose,
+ currentPath: location.pathname
+
}
}
diff --git a/src/index.js b/src/index.js
index 4108f8e..d2fb9f9 100644
--- a/src/index.js
+++ b/src/index.js
@@ -8,12 +8,16 @@ import { QueryParamProvider } from 'use-query-params'
// Importing the Bootstrap CSS
import 'bootstrap/dist/css/bootstrap.min.css'
+import { BrowserRouter } from 'react-router-dom'
const root = ReactDOM.createRoot(document.getElementById('root'))
root.render(
-
+ {/* should be wrap all the components that use react-router-dom */}
+
+
+
)