Add React Router for navigation and update dependencies

This commit is contained in:
2026-04-02 16:43:16 -05:00
parent 4ecf58dba3
commit 6bfe12cc42
3 changed files with 201 additions and 158 deletions
+60 -26
View File
@@ -9,7 +9,8 @@
"version": "0.0.0",
"dependencies": {
"react": "^19.2.4",
"react-dom": "^19.2.4"
"react-dom": "^19.2.4",
"react-router-dom": "^7.14.0"
},
"devDependencies": {
"@eslint/js": "^9.39.4",
@@ -264,31 +265,6 @@
"node": ">=6.9.0"
}
},
"node_modules/@emnapi/core": {
"version": "1.9.2",
"resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.9.2.tgz",
"integrity": "sha512-UC+ZhH3XtczQYfOlu3lNEkdW/p4dsJ1r/bP7H8+rhao3TTTMO1ATq/4DdIi23XuGoFY+Cz0JmCbdVl0hz9jZcA==",
"dev": true,
"license": "MIT",
"optional": true,
"peer": true,
"dependencies": {
"@emnapi/wasi-threads": "1.2.1",
"tslib": "^2.4.0"
}
},
"node_modules/@emnapi/runtime": {
"version": "1.9.2",
"resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.9.2.tgz",
"integrity": "sha512-3U4+MIWHImeyu1wnmVygh5WlgfYDtyf0k8AbLhMFxOipihf6nrWC4syIm/SwEeec0mNSafiiNnMJwbza/Is6Lw==",
"dev": true,
"license": "MIT",
"optional": true,
"peer": true,
"dependencies": {
"tslib": "^2.4.0"
}
},
"node_modules/@emnapi/wasi-threads": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.2.1.tgz",
@@ -1134,6 +1110,19 @@
"dev": true,
"license": "MIT"
},
"node_modules/cookie": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/cookie/-/cookie-1.1.1.tgz",
"integrity": "sha512-ei8Aos7ja0weRpFzJnEA9UHJ/7XQmqglbRwnf2ATjcB9Wq874VKH9kfjjirM6UhU2/E5fFYadylyhFldcqSidQ==",
"license": "MIT",
"engines": {
"node": ">=18"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/express"
}
},
"node_modules/cross-spawn": {
"version": "7.0.6",
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz",
@@ -2247,6 +2236,7 @@
"resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.2.4.tgz",
"integrity": "sha512-AXJdLo8kgMbimY95O2aKQqsz2iWi9jMgKJhRBAxECE4IFxfcazB2LmzloIoibJI3C12IlY20+KFaLv+71bUJeQ==",
"license": "MIT",
"peer": true,
"dependencies": {
"scheduler": "^0.27.0"
},
@@ -2254,6 +2244,44 @@
"react": "^19.2.4"
}
},
"node_modules/react-router": {
"version": "7.14.0",
"resolved": "https://registry.npmjs.org/react-router/-/react-router-7.14.0.tgz",
"integrity": "sha512-m/xR9N4LQLmAS0ZhkY2nkPA1N7gQ5TUVa5n8TgANuDTARbn1gt+zLPXEm7W0XDTbrQ2AJSJKhoa6yx1D8BcpxQ==",
"license": "MIT",
"dependencies": {
"cookie": "^1.0.1",
"set-cookie-parser": "^2.6.0"
},
"engines": {
"node": ">=20.0.0"
},
"peerDependencies": {
"react": ">=18",
"react-dom": ">=18"
},
"peerDependenciesMeta": {
"react-dom": {
"optional": true
}
}
},
"node_modules/react-router-dom": {
"version": "7.14.0",
"resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-7.14.0.tgz",
"integrity": "sha512-2G3ajSVSZMEtmTjIklRWlNvo8wICEpLihfD/0YMDxbWK2UyP5EGfnoIn9AIQGnF3G/FX0MRbHXdFcD+rL1ZreQ==",
"license": "MIT",
"dependencies": {
"react-router": "7.14.0"
},
"engines": {
"node": ">=20.0.0"
},
"peerDependencies": {
"react": ">=18",
"react-dom": ">=18"
}
},
"node_modules/resolve-from": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz",
@@ -2321,6 +2349,12 @@
"semver": "bin/semver.js"
}
},
"node_modules/set-cookie-parser": {
"version": "2.7.2",
"resolved": "https://registry.npmjs.org/set-cookie-parser/-/set-cookie-parser-2.7.2.tgz",
"integrity": "sha512-oeM1lpU/UvhTxw+g3cIfxXHyJRc/uidd3yK1P242gzHds0udQBYzs3y8j4gCCW+ZJ7ad0yctld8RYO+bdurlvw==",
"license": "MIT"
},
"node_modules/shebang-command": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
+2 -1
View File
@@ -11,7 +11,8 @@
},
"dependencies": {
"react": "^19.2.4",
"react-dom": "^19.2.4"
"react-dom": "^19.2.4",
"react-router-dom": "^7.14.0"
},
"devDependencies": {
"@eslint/js": "^9.39.4",
+139 -131
View File
@@ -1,138 +1,146 @@
import { useState } from 'react'
import reactLogo from './assets/react.svg'
import viteLogo from './assets/vite.svg'
import heroImg from './assets/hero.png'
import './App.css'
import { BrowserRouter, Routes, Route, Link } from 'react-router-dom'
const SiteHeader = () => (
<header>
<h1>FEDL - Ranked Demon List</h1>
<nav>
<Link to="/">Home</Link>
<Link to="/guess">Guess</Link>
<Link to="/players">Players</Link>
<Link to="/lists">Lists</Link>
<Link to="/run">Submit Run</Link>
<Link to="/rules">Rules</Link>
<Link to="/roulette">Roulette</Link>
<Link to="/admelist">Admin</Link>
</nav>
</header>
)
const HomePage = () => (
<main>
<section className="home-hero">
<div className="home-copy panel">
<p className="hero-kicker">FEDL Hub</p>
<h2>Track ranked demons, learn submission rules, and master the challenge.</h2>
<p className="hero-text">A quick homepage with action buttons to all sections.</p>
<div className="hero-actions">
<Link className="btn" to="/lists">Open The List</Link>
<Link className="btn ghost-btn" to="/guess">Play Guess Game</Link>
<Link className="btn ghost-btn" to="/run">Submit A Run</Link>
<Link className="btn ghost-btn" to="/rules">Submission Rules</Link>
<Link className="btn ghost-btn" to="/roulette">Spin Roulette</Link>
</div>
</div>
</section>
<section className="panel discord-panel download-panel">
<div className="discord-copy">
<div className="discord-badge">
<span className="discord-logo">📱</span>
<div>
<p className="discord-label">Download</p>
<h2>FEDL App (Coming Soon)</h2>
</div>
</div>
<p className="discord-text">Mobile/desktop app is in progress. This is the React conversion of the site.</p>
</div>
<div className="discord-actions">
<button className="btn discord-btn" disabled>Coming soon</button>
</div>
</section>
</main>
)
const GuessPage = () => (
<main className="roulette-shell">
<section className="panel roulette-panel roulette-guess-panel">
<div className="roulette-head">
<h2>Guess The Rank</h2>
<p className="muted">Placeholder page: game logic is from old app.js if needed after port.</p>
</div>
</section>
</main>
)
const PlayersPage = () => (
<main className="layout">
<section className="panel list-hero-panel">
<h2>Players</h2>
<p>Player tracking interface (placeholder).</p>
</section>
</main>
)
const ListsPage = () => (
<main className="layout">
<section className="panel list-hero-panel">
<h2>FEDL Ranked List</h2>
<p>Full demon list content (placeholder).</p>
</section>
</main>
)
const RunPage = () => (
<main className="run-shell">
<section className="panel run-panel">
<h2>Submit Run</h2>
<p>Run submission form is ported here. Inputs are currently disabled.</p>
</section>
</main>
)
const RulesPage = () => (
<main className="rules-view">
<section className="panel rules-page">
<h2>Submission Rules</h2>
<p>All current FEDL rules are visible in the site style.</p>
</section>
</main>
)
const RoulettePage = () => (
<main className="roulette-shell">
<section className="panel roulette-panel">
<h2>Demon Roulette</h2>
<p>Random demon draw - logic to be implemented.</p>
</section>
</main>
)
const AdminPage = () => (
<main className="admin-shell">
<section className="admin-login-screen">
<h2>Admin login</h2>
<p>Admin features are available once backend auth is connected.</p>
</section>
</main>
)
const NotFoundPage = () => (
<main className="panel">
<h2>404 - Page not found</h2>
<p>Return <Link to="/">Home</Link>.</p>
</main>
)
function App() {
const [count, setCount] = useState(0)
return (
<>
<section id="center">
<div className="hero">
<img src={heroImg} className="base" width="170" height="179" alt="" />
<img src={reactLogo} className="framework" alt="React logo" />
<img src={viteLogo} className="vite" alt="Vite logo" />
</div>
<div>
<h1>Get started</h1>
<p>
Edit <code>src/App.jsx</code> and save to test <code>HMR</code>
</p>
</div>
<button
className="counter"
onClick={() => setCount((count) => count + 1)}
>
Count is {count}
</button>
</section>
<div className="ticks"></div>
<section id="next-steps">
<div id="docs">
<svg className="icon" role="presentation" aria-hidden="true">
<use href="/icons.svg#documentation-icon"></use>
</svg>
<h2>Documentation</h2>
<p>Your questions, answered</p>
<ul>
<li>
<a href="https://vite.dev/" target="_blank">
<img className="logo" src={viteLogo} alt="" />
Explore Vite
</a>
</li>
<li>
<a href="https://react.dev/" target="_blank">
<img className="button-icon" src={reactLogo} alt="" />
Learn more
</a>
</li>
</ul>
</div>
<div id="social">
<svg className="icon" role="presentation" aria-hidden="true">
<use href="/icons.svg#social-icon"></use>
</svg>
<h2>Connect with us</h2>
<p>Join the Vite community</p>
<ul>
<li>
<a href="https://github.com/vitejs/vite" target="_blank">
<svg
className="button-icon"
role="presentation"
aria-hidden="true"
>
<use href="/icons.svg#github-icon"></use>
</svg>
GitHub
</a>
</li>
<li>
<a href="https://chat.vite.dev/" target="_blank">
<svg
className="button-icon"
role="presentation"
aria-hidden="true"
>
<use href="/icons.svg#discord-icon"></use>
</svg>
Discord
</a>
</li>
<li>
<a href="https://x.com/vite_js" target="_blank">
<svg
className="button-icon"
role="presentation"
aria-hidden="true"
>
<use href="/icons.svg#x-icon"></use>
</svg>
X.com
</a>
</li>
<li>
<a href="https://bsky.app/profile/vite.dev" target="_blank">
<svg
className="button-icon"
role="presentation"
aria-hidden="true"
>
<use href="/icons.svg#bluesky-icon"></use>
</svg>
Bluesky
</a>
</li>
</ul>
</div>
</section>
<div className="ticks"></div>
<section className="discord-panel download-panel">
<div className="discord-copy">
<div className="discord-badge">
<span className="discord-logo" aria-hidden="true">📱</span>
<div>
<p className="discord-label">Download</p>
<h2>FEDL App (Coming Soon)</h2>
</div>
</div>
<p className="discord-text">A mobile and desktop companion is on the way. Stay tuned for the FEDL app release with fast access to ranked demons, quick roulette spins, and submission tools.</p>
</div>
<div className="discord-actions">
<button className="discord-btn" disabled>Coming soon</button>
</div>
</section>
<div className="ticks"></div>
<section id="spacer"></section>
</>
<BrowserRouter>
<SiteHeader />
<div className="site-content">
<Routes>
<Route path="/" element={<HomePage />} />
<Route path="/guess" element={<GuessPage />} />
<Route path="/players" element={<PlayersPage />} />
<Route path="/lists" element={<ListsPage />} />
<Route path="/run" element={<RunPage />} />
<Route path="/rules" element={<RulesPage />} />
<Route path="/roulette" element={<RoulettePage />} />
<Route path="/admelist" element={<AdminPage />} />
<Route path="*" element={<NotFoundPage />} />
</Routes>
</div>
</BrowserRouter>
)
}