222e4e45ce
After saving all 12 mnemonics, players see their full codebook — each letter with its Morse pattern (· —) and mnemonic phrase in a grid layout. Two actions: Print/Save PDF (window.print) and Start Playing. Operator name appears on the printed page. Print CSS hides UI chrome and renders a clean 3-column grid. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
42 lines
1.3 KiB
TypeScript
42 lines
1.3 KiB
TypeScript
import { useState, useCallback } from 'react'
|
|
import { MnemonicBuilder } from '../components/MnemonicBuilder'
|
|
import { MnemonicCodebook } from '../components/MnemonicCodebook'
|
|
|
|
type Props = {
|
|
token: string
|
|
operatorName: string | null
|
|
onComplete: () => void
|
|
}
|
|
|
|
export function OnboardingPage({ token, operatorName, onComplete }: Props) {
|
|
const [mnemonics, setMnemonics] = useState<Record<string, string> | null>(null)
|
|
|
|
const handleBuilderComplete = useCallback(async () => {
|
|
try {
|
|
const r = await fetch('/api/mnemonics', {
|
|
headers: { Authorization: `Bearer ${token}` },
|
|
})
|
|
const data = await r.json()
|
|
setMnemonics(data)
|
|
} catch {
|
|
onComplete()
|
|
}
|
|
}, [token, onComplete])
|
|
|
|
if (mnemonics) {
|
|
return <MnemonicCodebook mnemonics={mnemonics} operatorName={operatorName} onStartPlaying={onComplete} />
|
|
}
|
|
|
|
return (
|
|
<div>
|
|
<h1 style={{ fontFamily: 'var(--font-header)', marginBottom: '0.5rem' }}>
|
|
Build Your Codebook
|
|
</h1>
|
|
<p style={{ color: 'var(--color-brown)', marginBottom: '2rem' }}>
|
|
Create a memorable phrase for each Morse letter. Short words for dots, long words for dashes.
|
|
</p>
|
|
<MnemonicBuilder token={token} onComplete={handleBuilderComplete} />
|
|
</div>
|
|
)
|
|
}
|