feat: game practice loop with audio, scoring, and level-up modal (Task 11)
- useMorseAudio: wraps MorseAudioEngine, exposes currentSignal for FlashArea - useProgress: fetches /api/progress + /api/mnemonics, recordAnswer with local stats - FlashArea: gold flash on signal, height varies dot/dash - ScoreBar: level name, score, streak display - PracticeCard: play button, answer input, correct/incorrect feedback with mnemonic - GamePage: full practice loop, level-up modal at streak%10, anti-repeat history - Fix: incorrect attempt recorded only once per challenge (no stat inflation on retries) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
+3
-9
@@ -2,6 +2,7 @@ import { useState, useEffect } from 'react'
|
||||
import { useAuth } from './hooks/useAuth'
|
||||
import { LoginPage } from './pages/LoginPage'
|
||||
import { OnboardingPage } from './pages/OnboardingPage'
|
||||
import { GamePage } from './pages/GamePage'
|
||||
import './index.css'
|
||||
|
||||
type AppRoute = 'login' | 'sent' | 'onboarding' | 'game' | 'admin'
|
||||
@@ -51,15 +52,8 @@ export default function App() {
|
||||
{route === 'onboarding' && token && (
|
||||
<OnboardingPage token={token} onComplete={() => setRoute('game')} />
|
||||
)}
|
||||
{route === 'game' && (
|
||||
<div>
|
||||
<h1 style={{ fontFamily: 'var(--font-header)' }}>Practice</h1>
|
||||
<p>Hello, {profile?.display_name || profile?.email || 'Adventurer'}!</p>
|
||||
<p>Game loop coming in Task 11.</p>
|
||||
<button className="btn" style={{ marginTop: '1rem' }} onClick={() => { logout(); setRoute('login') }}>
|
||||
Log out
|
||||
</button>
|
||||
</div>
|
||||
{route === 'game' && token && (
|
||||
<GamePage token={token} onLogout={() => { logout(); setRoute('login') }} />
|
||||
)}
|
||||
{route === 'admin' && (
|
||||
<div>
|
||||
|
||||
Reference in New Issue
Block a user