Added protected routes, jotai dev tools
This commit is contained in:
parent
2d248c2364
commit
fc5f553042
2084
pac-man-board-game/ClientApp/package-lock.json
generated
2084
pac-man-board-game/ClientApp/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -3,9 +3,11 @@
|
||||
"version": "0.1.1",
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"@emotion/react": "^11.11.1",
|
||||
"@headlessui/react": "^1.7.15",
|
||||
"@heroicons/react": "^2.0.18",
|
||||
"jotai": "^2.2.2",
|
||||
"jotai-devtools": "^0.6.0",
|
||||
"oidc-client": "^1.11.5",
|
||||
"react": "^18.2.0",
|
||||
"react-dom": "^18.2.0",
|
||||
@ -23,6 +25,7 @@
|
||||
"tailwindcss": "^3.3.2",
|
||||
"typescript": "^5.1.6",
|
||||
"vite": "^4.4.2",
|
||||
"vite-plugin-node-polyfills": "^0.9.0",
|
||||
"vite-plugin-svgr": "^3.2.0",
|
||||
"vite-tsconfig-paths": "^4.2.0",
|
||||
"vitest": "^0.31.4"
|
||||
|
@ -1,16 +1,42 @@
|
||||
import React, {FC} from "react";
|
||||
import {Route, Routes} from "react-router-dom";
|
||||
import React, {FC, useEffect} from "react";
|
||||
import {Route, Routes, useNavigate} from "react-router-dom";
|
||||
import Layout from "./components/layout";
|
||||
import AppRoutes from "./AppRoutes";
|
||||
import "./index.css";
|
||||
import {useAtomValue} from "jotai";
|
||||
import {thisPlayerAtom} from "./utils/state";
|
||||
|
||||
export const App: FC = () => (
|
||||
<Layout>
|
||||
<Routes>
|
||||
{AppRoutes.map((route, index) => {
|
||||
const {element, ...rest} = route;
|
||||
return <Route key={index} {...rest} element={element}/>;
|
||||
const {element, secured = false, ...rest} = route;
|
||||
return <Route key={index} {...rest} element={<Secured secured={secured}>{element}</Secured>}/>;
|
||||
})}
|
||||
</Routes>
|
||||
</Layout>
|
||||
);
|
||||
|
||||
/**
|
||||
* This component is used to redirect the user to the login page if they are not logged in and the page is secured.
|
||||
* @param children The children to render if the user is logged in or the page is not secured.
|
||||
* @param secured Whether or not the page is secured.
|
||||
* @constructor The Secured component.
|
||||
*/
|
||||
const Secured: FC<{ secured: boolean } & ChildProps> = ({children, secured}) => {
|
||||
const player = useAtomValue(thisPlayerAtom);
|
||||
const navigate = useNavigate();
|
||||
const redirect = secured && player === undefined
|
||||
|
||||
useEffect(() => {
|
||||
if (redirect) {
|
||||
navigate("/login");
|
||||
}
|
||||
}, []);
|
||||
|
||||
if (!redirect) {
|
||||
return (
|
||||
<>{children}</>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -7,7 +7,7 @@ import Login from "./pages/login";
|
||||
const AppRoutes = [
|
||||
{
|
||||
index: true,
|
||||
element: <LobbyPage/>
|
||||
element: <LobbyPage/> // TODO change to home page
|
||||
},
|
||||
{
|
||||
path: "/counter",
|
||||
@ -16,10 +16,12 @@ const AppRoutes = [
|
||||
{
|
||||
path: "/game/:id",
|
||||
element: <Game/>,
|
||||
secured: true
|
||||
},
|
||||
{
|
||||
path: "/lobby",
|
||||
element: <LobbyPage/>,
|
||||
secured: true
|
||||
},
|
||||
{
|
||||
path: "/login",
|
||||
|
@ -1,16 +1,33 @@
|
||||
import React, {FC} from "react";
|
||||
import {Link} from "react-router-dom";
|
||||
import {Link, useNavigate} from "react-router-dom";
|
||||
import {useAtom} from "jotai";
|
||||
import {thisPlayerAtom} from "../utils/state";
|
||||
|
||||
const NavMenu: FC = () => {
|
||||
const [player, setPlayer] = useAtom(thisPlayerAtom);
|
||||
const navigate = useNavigate();
|
||||
|
||||
async function logout(): Promise<void> {
|
||||
setPlayer(undefined);
|
||||
navigate("/login");
|
||||
}
|
||||
|
||||
return (
|
||||
<header>
|
||||
<nav className="mb-3 flex justify-between border-b-2">
|
||||
<Link to="/"><h2 className={"my-1"}>Pac-Man Board Game</h2></Link>
|
||||
<Link to="/"><h2 className={"m-1"}>Pac-Man Board Game</h2></Link>
|
||||
|
||||
<ul className="inline-flex gap-2 items-center mr-5">
|
||||
<NavItem to="/">Home</NavItem>
|
||||
<NavItem to={"/lobby"}>Lobby</NavItem>
|
||||
<NavItem className={"mx-2"} to={"/login"}>Login</NavItem>
|
||||
{
|
||||
player === undefined ? /* TODO thisPlayerAtom contains a player object, from sessionStorage */
|
||||
<NavItem className={"mx-2"} to={"/login"}>Login</NavItem>
|
||||
:
|
||||
<li className={"mx-2"}>
|
||||
<button onClick={logout} className={"hover:underline"}>Logout</button>
|
||||
</li>
|
||||
}
|
||||
|
||||
{/*TODO show signed in user when signed in, otherwise login button*/}
|
||||
</ul>
|
||||
|
@ -4,6 +4,7 @@ import {BrowserRouter} from 'react-router-dom';
|
||||
import {App} from './App';
|
||||
// @ts-ignore
|
||||
import reportWebVitals from './reportWebVitals';
|
||||
import {DevTools} from "jotai-devtools";
|
||||
|
||||
const baseUrl = document.getElementsByTagName('base')[0].getAttribute('href');
|
||||
const rootElement = document.getElementById('root');
|
||||
@ -12,6 +13,7 @@ const root = createRoot(rootElement);
|
||||
|
||||
root.render(
|
||||
<BrowserRouter basename={baseUrl ?? undefined}>
|
||||
<DevTools/>
|
||||
<App/>
|
||||
</BrowserRouter>);
|
||||
|
||||
|
18
pac-man-board-game/ClientApp/src/utils/utils.ts
Normal file
18
pac-man-board-game/ClientApp/src/utils/utils.ts
Normal file
@ -0,0 +1,18 @@
|
||||
/**
|
||||
* Waits until the predicate is true
|
||||
* @param predicate The predicate to wait for.
|
||||
* @param timeout The timeout between checks.
|
||||
* @returns A promise that resolves when the predicate is true.
|
||||
*/
|
||||
export function wait(predicate: Predicate<void>, timeout: number = 50): Promise<void> {
|
||||
return new Promise<void>((resolve) => {
|
||||
const f = () => {
|
||||
if (predicate()) {
|
||||
return resolve();
|
||||
}
|
||||
setTimeout(f, timeout);
|
||||
};
|
||||
|
||||
f();
|
||||
});
|
||||
}
|
@ -7,9 +7,15 @@ import fs from "fs";
|
||||
// @ts-ignore
|
||||
import path from "path";
|
||||
import {execSync} from "child_process";
|
||||
import jotaiDebugLabel from 'jotai/babel/plugin-debug-label'
|
||||
import jotaiReactRefresh from 'jotai/babel/plugin-react-refresh'
|
||||
import {nodePolyfills} from "vite-plugin-node-polyfills";
|
||||
|
||||
export default defineConfig({
|
||||
plugins: [react()],
|
||||
plugins: [
|
||||
react({babel: {plugins: [jotaiDebugLabel, jotaiReactRefresh]}}),
|
||||
nodePolyfills()
|
||||
],
|
||||
build: {
|
||||
outDir: "build",
|
||||
},
|
||||
|
Loading…
x
Reference in New Issue
Block a user