import { useState } from 'react' import { NOVICE_LETTERS, MORSE, validatePhrase } from '../lib/morse' type Props = { token: string onComplete: () => void } const LETTERS = NOVICE_LETTERS // ['A','E','T','I','N','S','H','R','D','L','U','O'] export function MnemonicBuilder({ token, onComplete }: Props) { const [index, setIndex] = useState(0) const [phrase, setPhrase] = useState('') const [saving, setSaving] = useState(false) const [error, setError] = useState(null) const letter = LETTERS[index] const pattern = MORSE[letter] ?? '' // Display pattern as dots/dashes: '.' → '·', '-' → '—' const display = pattern.split('').map(c => c === '.' ? '·' : '—').join(' ') const validation = phrase.trim() ? validatePhrase(phrase.trim(), letter) : null async function save() { if (!validation?.valid) return setSaving(true) setError(null) try { const r = await fetch('/api/mnemonics', { method: 'POST', headers: { 'Content-Type': 'application/json', Authorization: `Bearer ${token}`, }, body: JSON.stringify({ letter, phrase: phrase.trim() }), }) if (!r.ok) throw new Error('Failed to save') advance() } catch { setError('Failed to save. Try again.') } finally { setSaving(false) } } function advance() { if (index + 1 >= LETTERS.length) { onComplete() } else { setIndex(i => i + 1) setPhrase('') setError(null) } } return (
{/* Progress */}

Letter {index + 1} of {LETTERS.length}

{/* Letter display */}
{letter}
{display}
{pattern.length} {pattern.length === 1 ? 'word' : 'words'} needed
{/* Phrase input */}

{pattern.length} word{pattern.length !== 1 ? 's' : ''} — short words (1-2 letters) for dots, long words (3+ letters) for dashes.

{ setPhrase(e.target.value); setError(null) }} placeholder={`${pattern.length} word${pattern.length !== 1 ? 's' : ''}, e.g. "${examplePhrase(pattern)}"`} disabled={saving} style={{ marginBottom: '0.5rem' }} /> {/* Validation feedback */} {validation && !validation.valid && (

{validation.message}

)} {validation?.valid && (

Looks good!

)} {error && (

{error}

)} {/* Actions */}
) } // Generate a simple example phrase for the placeholder function examplePhrase(pattern: string): string { return pattern.split('').map(c => c === '.' ? 'go' : 'WALKING').join(' ') }