first commit

This commit is contained in:
DuOtto
2026-10-19 22:27:05 +02:00
commit afbdc4b139
28 changed files with 4242 additions and 0 deletions
+55
View File
@@ -0,0 +1,55 @@
import { useEffect, useState } from 'react'
import Creator from './Creator.jsx'
import Rules from './Rules.jsx'
import Characters from './Characters.jsx'
import Presets from './Presets.jsx'
const useHash = () => {
const [h, setH] = useState(window.location.hash.slice(1) || 'creator')
useEffect(() => {
const f = () => setH(window.location.hash.slice(1) || 'creator')
window.addEventListener('hashchange', f)
return () => window.removeEventListener('hashchange', f)
}, [])
return h
}
export default function App() {
const hash = useHash()
const [rules, setRules] = useState(null)
const [error, setError] = useState('')
// Used to load a saved character into the creator
const [loadRequest, setLoadRequest] = useState(null)
const loadRules = () => fetch('/api/rules').then((r) => r.json()).then(setRules).catch(() => setError('Could not load the rules.'))
useEffect(() => { loadRules() }, [])
const page = hash.split('/')[0]
const nav = [['creator', 'Create character'], ['rules', 'Rules'], ['presets', 'Presets'], ['characters', 'My characters']]
return (
<>
<header className="top">
<a className="brand" href="#creator">
<span className="brand-mark" aria-hidden="true" />
<span>Arcane Wasteland</span>
</a>
<nav>
{nav.map(([id, label]) => (
<a key={id} href={`#${id}`} className={page === id ? 'active' : ''}>{label}</a>
))}
</nav>
</header>
<main>
{error && <p className="warn">{error}</p>}
{!rules && !error && <p className="muted">Loading rules …</p>}
{rules && page === 'creator' && <Creator rules={rules} loadRequest={loadRequest} clearLoad={() => setLoadRequest(null)} />}
{rules && page === 'rules' && <Rules rules={rules} section={hash.split('/')[1]} />}
{rules && page === 'presets' && <Presets rules={rules} reload={loadRules} />}
{rules && page === 'characters' && (
<Characters onOpen={(entry) => { setLoadRequest(entry); window.location.hash = 'creator' }} />
)}
</main>
</>
)
}