v1.5 - history and timeline as well as many datastructure updates added, polished, fixes

This commit is contained in:
Zaldimmar 2026-09-25 02:38:51 -05:00
parent 1f0aa3078f
commit 1d84400aef
63 changed files with 7927 additions and 208 deletions

View file

@ -0,0 +1,91 @@
/* ═══════════════════════════════════════════════════════════════
PAGE STATE
The three ways a detail page can fail to be a detail page. All
four of them need the same thing, and it should be the same thing
— a visitor who hits a dead retreat link and a dead chapter link
shouldn't get two different pages.
Rendered inside PageShell so the chrome doesn't flicker in and
out between loading and loaded.
A 404 gets no retry button: the slug doesn't exist and trying
again won't change that. Anything else does, because a dropped
connection is the usual cause and one tap fixes it.
═══════════════════════════════════════════════════════════════ */
import { Link } from 'react-router-dom'
import PageShell from './PageShell.tsx'
const TEAL = '#138ba0'
const BODY = '#4a6b72'
export default function PageState({
loading,
error,
notFound,
onRetry,
noun,
backTo,
backLabel,
}: {
loading: boolean
error: string | null
notFound: boolean
onRetry: () => void
/** Lowercase, as it appears mid-sentence: "retreat", "chapter". */
noun: string
backTo: string
backLabel: string
}) {
let title: string
let content: React.ReactNode
if (notFound) {
title = 'Not found'
content = (
<div className="max-w-6xl mx-auto px-6">
<p style={{ color: BODY }}>
There’s no {noun} at this address. It may have been renamed, or taken
down.
</p>
<Link
to={backTo}
className="mt-4 inline-block rounded-full border px-4 py-1.5 text-sm font-medium transition-colors hover:bg-[#eef9fb]"
style={{ borderColor: TEAL, color: TEAL }}
>
{backLabel}
</Link>
</div>
)
} else if (error) {
title = 'Something went wrong'
content = (
<div className="max-w-6xl mx-auto px-6">
<p style={{ color: '#b3261e' }}>Couldn’t load this {noun}. {error}</p>
<button
type="button"
onClick={onRetry}
className="mt-3 rounded-full border px-4 py-1.5 text-sm font-medium transition-colors hover:bg-[#eef9fb]"
style={{ borderColor: TEAL, color: TEAL }}
>
Try again
</button>
</div>
)
} else {
title = 'Loading…'
content = (
<p className="max-w-6xl mx-auto px-6" style={{ color: BODY }} role="status">
Loading this {noun}…
</p>
)
}
return (
<PageShell
title={title}
sections={[{ id: 'status', title: '', accent: TEAL, background: '#ffffff', content }]}
/>
)
}