Add interactive learning modules MVP (Phases 1-3.1)
Some checks failed
CI / go-lint (push) Has been skipped
CI / python-lint (push) Has been skipped
CI / nodejs-lint (push) Has been skipped
CI / test-go-school (push) Successful in 44s
CI / test-go-edu-search (push) Successful in 51s
CI / test-python-klausur (push) Failing after 2m44s
CI / test-python-agent-core (push) Successful in 33s
CI / test-nodejs-website (push) Successful in 34s
Some checks failed
CI / go-lint (push) Has been skipped
CI / python-lint (push) Has been skipped
CI / nodejs-lint (push) Has been skipped
CI / test-go-school (push) Successful in 44s
CI / test-go-edu-search (push) Successful in 51s
CI / test-python-klausur (push) Failing after 2m44s
CI / test-python-agent-core (push) Successful in 33s
CI / test-nodejs-website (push) Successful in 34s
New feature: After OCR vocabulary extraction, users can generate interactive
learning modules (flashcards, quiz, type trainer) with one click.
Frontend (studio-v2):
- Fortune Sheet spreadsheet editor tab in vocab-worksheet
- "Lernmodule generieren" button in ExportTab
- /learn page with unit overview and exercise type cards
- /learn/[unitId]/flashcards — Flip-card trainer with Leitner spaced repetition
- /learn/[unitId]/quiz — Multiple choice quiz with explanations
- /learn/[unitId]/type — Type-in trainer with Levenshtein distance feedback
- AudioButton component using Web Speech API for EN+DE TTS
Backend (klausur-service):
- vocab_learn_bridge.py: Converts VocabularyEntry[] to analysis_data format
- POST /sessions/{id}/generate-learning-unit endpoint
Backend (backend-lehrer):
- generate-qa, generate-mc, generate-cloze endpoints on learning units
- get-qa/mc/cloze data retrieval endpoints
- Leitner progress update + next review items endpoints
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -8,6 +8,7 @@ import { PageSelection } from './components/PageSelection'
|
||||
import { VocabularyTab } from './components/VocabularyTab'
|
||||
import { WorksheetTab } from './components/WorksheetTab'
|
||||
import { ExportTab } from './components/ExportTab'
|
||||
import { SpreadsheetTab } from './components/SpreadsheetTab'
|
||||
import { OcrSettingsPanel } from './components/OcrSettingsPanel'
|
||||
import { FullscreenPreview } from './components/FullscreenPreview'
|
||||
import { QRCodeModal } from './components/QRCodeModal'
|
||||
@@ -144,6 +145,7 @@ export default function VocabWorksheetPage() {
|
||||
{!session && <UploadScreen h={h} />}
|
||||
{session && activeTab === 'pages' && <PageSelection h={h} />}
|
||||
{session && activeTab === 'vocabulary' && <VocabularyTab h={h} />}
|
||||
{session && activeTab === 'spreadsheet' && <SpreadsheetTab h={h} />}
|
||||
{session && activeTab === 'worksheet' && <WorksheetTab h={h} />}
|
||||
{session && activeTab === 'export' && <ExportTab h={h} />}
|
||||
|
||||
@@ -151,7 +153,7 @@ export default function VocabWorksheetPage() {
|
||||
{session && activeTab !== 'pages' && (
|
||||
<div className={`mt-6 border-t pt-4 ${isDark ? 'border-white/10' : 'border-black/5'}`}>
|
||||
<div className="flex justify-center gap-2">
|
||||
{(['vocabulary', 'worksheet', 'export'] as TabId[]).map((tab) => (
|
||||
{(['vocabulary', 'spreadsheet', 'worksheet', 'export'] as TabId[]).map((tab) => (
|
||||
<button
|
||||
key={tab}
|
||||
onClick={() => h.setActiveTab(tab)}
|
||||
@@ -161,7 +163,7 @@ export default function VocabWorksheetPage() {
|
||||
: (isDark ? 'bg-white/10 text-white/80 hover:bg-white/20' : 'bg-slate-100 text-slate-700 hover:bg-slate-200')
|
||||
}`}
|
||||
>
|
||||
{tab === 'vocabulary' ? 'Vokabeln' : tab === 'worksheet' ? 'Arbeitsblatt' : 'Export'}
|
||||
{tab === 'vocabulary' ? 'Vokabeln' : tab === 'spreadsheet' ? 'Spreadsheet' : tab === 'worksheet' ? 'Arbeitsblatt' : 'Export'}
|
||||
</button>
|
||||
))}
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user