This commit is contained in:
team3
2026-06-18 09:58:45 +02:00
parent 1aba312242
commit 4b0cf1ef29
3 changed files with 48 additions and 3 deletions

View File

@@ -15,9 +15,20 @@ const props = defineProps({
fortschritt: { type: Object, default: () => ({ total: 0, absolviert: 0, verstanden: 0, gemeistert: 0 }) },
})
import { computed } from 'vue'
import { computed, onMounted, onUnmounted } from 'vue'
defineEmits(['close', 'prev', 'next', 'statusChanged'])
const emit = defineEmits(['close', 'prev', 'next', 'statusChanged'])
// ←/→ blättern zum vorigen/nächsten Baustein — außer beim Tippen in Feldern.
function onKey(e) {
if (e.altKey || e.ctrlKey || e.metaKey) return
const el = document.activeElement
if (el && (el.tagName === 'INPUT' || el.tagName === 'TEXTAREA' || el.isContentEditable)) return
if (e.key === 'ArrowLeft' && props.hasPrev) { e.preventDefault(); emit('prev') }
else if (e.key === 'ArrowRight' && props.hasNext) { e.preventDefault(); emit('next') }
}
onMounted(() => window.addEventListener('keydown', onKey))
onUnmounted(() => window.removeEventListener('keydown', onKey))
const pct = (n) => (100 * n / (props.fortschritt.total || 1)) + '%'

View File

@@ -1,6 +1,7 @@
<script setup>
import { computed, nextTick, onMounted, onUnmounted, ref } from 'vue'
import { computed, nextTick, onMounted, onUnmounted, ref, watch } from 'vue'
import { chatBaustein, createVertiefung, fetchVertiefung, pruefeBaustein } from '../api.js'
import { getPruef, setPruef } from '../pruefungCache.js'
import { renderMarkdown } from '../markdown.js'
import { useChat, istUnten } from '../composables/useChat.js'
@@ -94,6 +95,30 @@ const streakVorFrage = ref(0) // Streak, als die aktuelle Frage gestellt wurd
// Die aktuelle Streak lebt persistent in st.value.streak (DB → props.status, round-trip via applyPruefung).
const naechsteFrage = ref(null) // im Hintergrund vorbereitete nächste Frage (Prefetch)
let prefetchPromise = null // laufender Hintergrund-Abruf (verhindert Doppel-Prefetch)
// Session-Cache: Prüfungs-Verlauf pro Baustein über Remounts hinweg halten (nur im Fokus,
// dort läuft die Prüfung). Wiederherstellen beim Mount, bei jeder Änderung sichern.
if (props.mode === 'full') {
const pruefKey = `${props.topic}::${props.baustein}`
const c = getPruef(pruefKey)
if (c) {
pruefMessages.value = c.messages
pruefPhase.value = c.phase
aktuelleFrage.value = c.aktuelleFrage
letztesFeedback.value = c.letztesFeedback
scoreVorFrage.value = c.scoreVorFrage
streakVorFrage.value = c.streakVorFrage
}
watch(
[pruefMessages, pruefPhase, aktuelleFrage, letztesFeedback, scoreVorFrage, streakVorFrage],
() => setPruef(pruefKey, {
messages: pruefMessages.value, phase: pruefPhase.value,
aktuelleFrage: aktuelleFrage.value, letztesFeedback: letztesFeedback.value,
scoreVorFrage: scoreVorFrage.value, streakVorFrage: streakVorFrage.value,
}),
{ deep: true },
)
}
const pruefMessagesEl = ref(null)
const pruefInputEl = ref(null)
const pruefStick = ref(true) // nur auto-scrollen, wenn der Nutzer (fast) unten ist

View File

@@ -0,0 +1,9 @@
// Session-Cache für den Prüfungs-Verlauf pro Baustein.
// Lebt als Modul-Map: überlebt das Remounten von BausteinPanel (Baustein-Wechsel,
// Fokus schließen/öffnen), geht aber bei Page-Reload verloren — bewusst kein DB-Aufwand.
const store = new Map() // key "topic::baustein" -> { messages, phase, aktuelleFrage, letztesFeedback, scoreVorFrage, streakVorFrage }
export const getPruef = (key) => store.get(key)
export const setPruef = (key, val) => store.set(key, val)
export const clearPruef = (key) => store.delete(key)