This commit is contained in:
team3
2026-07-03 11:45:27 +02:00
parent 285317927d
commit abcadd145d
44 changed files with 1909 additions and 292 deletions

View File

@@ -1,12 +1,13 @@
<script setup>
import { ref, computed, watch, onMounted } from 'vue'
import { fetchGuides, fetchTopics, deleteTopic as apiDeleteTopic, createGuide as apiCreate, deleteGuide, cancelGuide as apiCancel, fetchBlocksStatus, fetchActiveBlocks, createBlocks as apiCreateBausteine, resetBlocksStage as apiResetBlocksStage, addBlocksResearch as apiAddResearch, requeueBlocksDead as apiRequeueDead, resetGuideBoard as apiResetGuideBoard, restartBlocksCard as apiRestartBlocksCard, resetGuideCard as apiResetGuideCard, cancelBlocks as apiCancelBausteine, deleteBlocks as apiDeleteBausteine, fetchProviders, fetchStats, fetchTopicProgress, fetchGuideLocks, fetchFolders, updateSource as apiUpdateQuelle } from './api.js'
import { fetchGuides, fetchTopics, deleteTopic as apiDeleteTopic, createGuide as apiCreate, deleteGuide, cancelGuide as apiCancel, fetchBlocksStatus, fetchActiveBlocks, createBlocks as apiCreateBausteine, resetBlocksStage as apiResetBlocksStage, addBlocksResearch as apiAddResearch, requeueBlocksDead as apiRequeueDead, resetGuideBoard as apiResetGuideBoard, restartBlocksCard as apiRestartBlocksCard, resetGuideCard as apiResetGuideCard, removeGuideFormat as apiRemoveGuideFormat, cancelBlocks as apiCancelBausteine, deleteBlocks as apiDeleteBausteine, fetchProviders, fetchStats, fetchTopicProgress, fetchGuideLocks, fetchFolders, updateSource as apiUpdateQuelle } from './api.js'
import { usePolling } from './composables/usePolling.js'
import TopicSidebar from './components/TopicSidebar.vue'
import TopicDetail from './components/TopicDetail.vue'
import BlocksOverview from './components/BlocksOverview.vue'
import GenerationView from './components/GenerationView.vue'
import GeneralExamPanel from './components/GeneralExamPanel.vue'
import PracticePanel from './components/PracticePanel.vue'
const guides = ref([])
const backendTopics = ref([])
@@ -26,10 +27,11 @@ const activeBlocks = ref([])
const provider = ref(localStorage.getItem('provider') || 'claude')
const providers = ref([])
const folders = ref({ projekt: [], uni: [] }) // folders for the sources picker
const mainView = ref('blocks') // blocks | generation | general | detail — exclusive main-area view
const mainView = ref('blocks') // blocks | generation | general | practice | detail — exclusive main-area view
const guideBoardFormat = ref('Guide')
const viewMode = ref('compact') // compact | erklärend — per topic, default compact
const levelView = ref(Number(localStorage.getItem('level')) || 4) // 1=A · 2=F · 3=E · 4=V (levels view)
const _storedLevel = localStorage.getItem('level')
const levelView = ref(_storedLevel === 'auto' || !_storedLevel ? 'auto' : Number(_storedLevel) || 'auto') // 'auto' | 1-4
const stats = ref(null)
const progress = ref({})
const locks = ref({}) // lock reasons per format (backend = single rule source)
@@ -326,6 +328,17 @@ function handleOpenGeneration() {
previewGuide.value = null
}
async function handleRemoveGuideFormat(format) {
uiError.value = null
try {
await apiRemoveGuideFormat(selectedTopic.value, format)
} catch (e) {
uiError.value = e.message
return
}
await loadGuides()
}
async function handleRestartCard(cardId) {
uiError.value = null
try {
@@ -370,8 +383,20 @@ function handleGeneralExam() {
previewGuide.value = null
}
function handlePractice() {
if (!selectedTopic.value) return
mainView.value = 'practice'
previewGuide.value = null
}
async function handleDeleteGuide(guideId, slots = false) {
await deleteGuide(guideId, slots)
uiError.value = null
try {
await deleteGuide(guideId, slots)
} catch (e) {
uiError.value = e.message
return
}
if (previewGuide.value?.id === guideId) {
previewGuide.value = null
}
@@ -444,6 +469,7 @@ onMounted(async () => {
@setAnsicht="setView"
@setStufe="setLevel"
@generalExam="handleGeneralExam"
@practice="handlePractice"
@select="selectTopic"
@createThema="handleCreateTopic"
@updateSource="handleUpdateSource"
@@ -488,7 +514,7 @@ onMounted(async () => {
@startGuide="handleFormatClick"
@resetGuideStage="handleGuideBoardReset"
@preview="handleGuideBoardPreview"
@deleteGuide="handleDeleteGuide"
@removeFormat="handleRemoveGuideFormat"
@restartCard="handleRestartCard"
@resetGuideCard="handleResetGuideCard"
/>
@@ -499,6 +525,11 @@ onMounted(async () => {
@progressChanged="loadStats(); loadBlocks()"
@fokus-active="focusOpen = $event"
/>
<PracticePanel
v-else-if="selectedTopic && mainView === 'practice'"
:key="selectedTopic"
:topic="selectedTopic"
/>
<TopicDetail
v-else-if="selectedTopic"
:previewGuide="previewGuide"