Manual: full participation guide (media/accounts/decisions/safety) + Enter-to-door + provisioner env passthrough
This commit is contained in:
parent
07d2df8c53
commit
6161ac4740
5 changed files with 251 additions and 42 deletions
|
|
@ -7,6 +7,7 @@ import {
|
|||
MANUAL_INTRO,
|
||||
MANUAL_PATHS_HEADING,
|
||||
MANUAL_TITLE,
|
||||
MANUAL_TOC_HEADING,
|
||||
PARTICIPATION_MANUAL,
|
||||
PARTICIPATION_PATHS,
|
||||
isManualLanguage,
|
||||
|
|
@ -83,6 +84,17 @@ function ManualLanding(): React.ReactElement {
|
|||
|
||||
useEffect(() => setLang(readStoredLanguage()), []);
|
||||
|
||||
// Enter jumps to the door only when body has focus; interactive elements keep their own Enter.
|
||||
useEffect(() => {
|
||||
const onKey = (e: KeyboardEvent): void => {
|
||||
if (e.key === "Enter" && e.target === document.body && !e.shiftKey) {
|
||||
router.push(status === "authenticated" ? "/streams" : "/onboarding");
|
||||
}
|
||||
};
|
||||
window.addEventListener("keydown", onKey);
|
||||
return () => window.removeEventListener("keydown", onKey);
|
||||
}, [status, router]);
|
||||
|
||||
function switchLanguage(next: ManualLanguage): void {
|
||||
setLang(next);
|
||||
try {
|
||||
|
|
@ -101,7 +113,7 @@ function ManualLanding(): React.ReactElement {
|
|||
|
||||
return (
|
||||
<div className="min-h-dvh bg-bg text-text">
|
||||
<header className="border-b border-border-subtle bg-surface">
|
||||
<header className="sticky top-0 z-10 border-b border-border-subtle bg-surface">
|
||||
<div className="mx-auto flex max-w-2xl items-center gap-3 px-4 py-4">
|
||||
<Logo size={26} />
|
||||
<span className="flex-1 truncate text-xs font-bold tracking-tight text-accent">Tactical Media Broadcast Hub</span>
|
||||
|
|
@ -163,10 +175,31 @@ function ManualLanding(): React.ReactElement {
|
|||
</ul>
|
||||
</section>
|
||||
|
||||
{/* Compact table of contents, one line per section, anchor links. */}
|
||||
<nav aria-labelledby="toc-heading" className="mb-10 rounded-lg border border-border-subtle bg-surface p-4">
|
||||
<h2 id="toc-heading" className="mb-2 text-xs font-bold uppercase tracking-wider text-text-faint">
|
||||
{t(MANUAL_TOC_HEADING)}
|
||||
</h2>
|
||||
<ol className="grid gap-1.5">
|
||||
{PARTICIPATION_MANUAL.map((section, index) => (
|
||||
<li key={section.id} className="flex items-baseline gap-2.5 text-sm">
|
||||
<span className="font-mono text-xs font-bold text-text-faint">{String(index + 1).padStart(2, "0")}</span>
|
||||
<a
|
||||
href={`#section-${section.id}`}
|
||||
className="text-accent underline-offset-2 hover:underline"
|
||||
onClick={jumpToSection}
|
||||
>
|
||||
{t(section.heading)}
|
||||
</a>
|
||||
</li>
|
||||
))}
|
||||
</ol>
|
||||
</nav>
|
||||
|
||||
{/* The manual itself. */}
|
||||
<div className="flex flex-col gap-8">
|
||||
{PARTICIPATION_MANUAL.map((section, index) => (
|
||||
<section key={section.id} aria-labelledby={`section-${section.id}`}>
|
||||
<section key={section.id} aria-labelledby={`section-${section.id}`} className="scroll-mt-20">
|
||||
<h2 id={`section-${section.id}`} className="mb-2 flex items-baseline gap-2.5 text-base font-bold">
|
||||
<span className="font-mono text-xs font-bold text-accent">{String(index + 1).padStart(2, "0")}</span>
|
||||
{t(section.heading)}
|
||||
|
|
@ -188,3 +221,19 @@ function ManualLanding(): React.ReactElement {
|
|||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Smooth-scroll to the target section. The anchor itself works without
|
||||
* JavaScript; this only makes the jump gentle and keeps the sticky header from
|
||||
* covering the heading (paired with scroll-mt-20 above).
|
||||
*/
|
||||
function jumpToSection(event: React.MouseEvent<HTMLAnchorElement>): void {
|
||||
const href = event.currentTarget.getAttribute("href");
|
||||
if (href === null || !href.startsWith("#")) return;
|
||||
const target = document.getElementById(href.slice(1));
|
||||
if (target === null) return;
|
||||
event.preventDefault();
|
||||
target.scrollIntoView({ behavior: "smooth", block: "start" });
|
||||
// Reflect the jump in the URL so the link is shareable.
|
||||
window.history.replaceState(null, "", href);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue