diff --git a/package-lock.json b/package-lock.json index 66d8e2d..e56d338 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11,7 +11,8 @@ "@fontsource/cinzel": "^5.3.0", "@fontsource/eb-garamond": "^5.3.0", "react": "^19.2.8", - "react-dom": "^19.2.8" + "react-dom": "^19.2.8", + "react-router-dom": "^7.18.2" }, "devDependencies": { "@types/react": "^19.2.18", @@ -340,6 +341,19 @@ } } }, + "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/csstype": { "version": "3.2.3", "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.2.3.tgz", @@ -740,6 +754,44 @@ "react": "^19.2.8" } }, + "node_modules/react-router": { + "version": "7.18.2", + "resolved": "https://registry.npmjs.org/react-router/-/react-router-7.18.2.tgz", + "integrity": "sha512-aUVMjFm3GAPTTZL7oYr5E7ETiqfQCHRLH+B+5afnICvf0r7kkK4eR6SMuwbSTJw/7t+12khT/Kahij49fqOCIg==", + "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.18.2", + "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-7.18.2.tgz", + "integrity": "sha512-AIKJ/jgGlFb3EbfCXk5Gzshiwt+l3mqbCrNjmEWMMjqQxNJ3svBa6bgzFyCC2Sw3RA0VWF1kg3uQf2OFhxb8hw==", + "license": "MIT", + "dependencies": { + "react-router": "7.18.2" + }, + "engines": { + "node": ">=20.0.0" + }, + "peerDependencies": { + "react": ">=18", + "react-dom": ">=18" + } + }, "node_modules/rolldown": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/rolldown/-/rolldown-1.2.4.tgz", @@ -779,6 +831,12 @@ "integrity": "sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q==", "license": "MIT" }, + "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/source-map-js": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", diff --git a/package.json b/package.json index 5dadb88..194c994 100644 --- a/package.json +++ b/package.json @@ -19,6 +19,7 @@ "@fontsource/cinzel": "^5.3.0", "@fontsource/eb-garamond": "^5.3.0", "react": "^19.2.8", - "react-dom": "^19.2.8" + "react-dom": "^19.2.8", + "react-router-dom": "^7.18.2" } } diff --git a/src/App.tsx b/src/App.tsx index 64dedef..18733f0 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,103 +1,20 @@ -import { useCallback, useEffect, useState } from 'react' -import CandleCanvas from './Candle' -import { daySeed, loadKJV, msUntilRollover, pickForDay, type Verse } from './verse' - -type Phase = 'sealed' | 'revealing' | 'revealed' - -function formatCountdown(ms: number): string { - const s = Math.max(0, Math.ceil(ms / 1000)) - const h = Math.floor(s / 3600) - const m = Math.floor((s % 3600) / 60) - const sec = s % 60 - return `${String(h).padStart(2, '0')}h ${String(m).padStart(2, '0')}m ${String(sec).padStart(2, '0')}s` -} +import { Navigate, Route, Routes } from 'react-router-dom' +import Home from './Home' +import Reader from './Reader' +import SearchPage from './SearchPage' export default function App() { - const [phase, setPhase] = useState('sealed') - const [verse, setVerse] = useState(null) - const [countdown, setCountdown] = useState('') - const [error, setError] = useState(false) - - useEffect(() => { - const update = () => setCountdown(formatCountdown(msUntilRollover())) - update() - const id = window.setInterval(update, 1000) - return () => window.clearInterval(id) - }, []) - - const seek = useCallback(async () => { - if (phase !== 'sealed') return - setPhase('revealing') - try { - const verses = await loadKJV() - setVerse(pickForDay(verses, daySeed())) - setPhase('revealed') - } catch { - setError(true) - setPhase('sealed') - } - }, [phase]) - - const today = new Date().toLocaleDateString(undefined, { - year: 'numeric', - month: 'long', - day: 'numeric', - }) - return ( -
- + <>