diff --git a/frontend/src/components/TrainingUnitSectionsEditor.jsx b/frontend/src/components/TrainingUnitSectionsEditor.jsx index c824305..201fc13 100644 --- a/frontend/src/components/TrainingUnitSectionsEditor.jsx +++ b/frontend/src/components/TrainingUnitSectionsEditor.jsx @@ -2,6 +2,7 @@ import React, { Fragment, useCallback, useEffect, useState } from 'react' import { GripVertical, Pencil } from 'lucide-react' import CombinationMethodProfileEditor from './CombinationMethodProfileEditor' import { comboPlanningProfileJsonForEditor } from '../utils/comboPlanningMethodProfile' +import { combinationArchetypeLabel } from '../constants/combinationArchetypes' import { defaultSection, exerciseRow, @@ -59,6 +60,20 @@ function gatherPlanningModuleOutline(items, startIdx, moduleId) { const MODULE_OUTLINE_PREVIEW_MAX = 8 +/** Statuszeile: Planungs‑Override vs. Katalog, inkl. Archetyp‑Label wenn bekannt. */ +function compactComboPlanningCaption(it) { + const overridden = + it.planning_method_profile != null && + typeof it.planning_method_profile === 'object' && + !Array.isArray(it.planning_method_profile) + const archRaw = String(it.catalog_method_archetype || '').trim() + const archLbl = archRaw ? combinationArchetypeLabel(archRaw) : null + if (overridden) { + return archLbl ? `${archLbl} · Planung angepasst` : 'Planung angepasst' + } + return archLbl ? `${archLbl} · wie Katalog` : 'wie im Katalog' +} + /** Stabile Farbzurodnung aus Modul-ID (nur Darstellung). */ function planningModulePalette(moduleId) { const id = normalizedPlanningModuleChainId(moduleId) @@ -290,6 +305,8 @@ export default function TrainingUnitSectionsEditor({ } const [textEdit, setTextEdit] = useState(null) + /** Kombi: Ablaufprofil in Modal statt einzuklappender Karte */ + const [comboPlanningModal, setComboPlanningModal] = useState(null) /** { sIdx: number, beforeIx: number } – Einfüge-Popup („+“ zwischen Zeilen) */ const [insertChooser, setInsertChooser] = useState(null) const [draggingPos, setDraggingPos] = useState(null) @@ -316,6 +333,27 @@ export default function TrainingUnitSectionsEditor({ return () => window.removeEventListener('keydown', onKey) }, [insertChooser]) + useEffect(() => { + if (!comboPlanningModal) return + const onKey = (e) => { + if (e.key === 'Escape') setComboPlanningModal(null) + } + window.addEventListener('keydown', onKey) + return () => window.removeEventListener('keydown', onKey) + }, [comboPlanningModal]) + + useEffect(() => { + if (!comboPlanningModal) return + const L = ensure(sections) + const { sIdx, iIdx } = comboPlanningModal + const row = L[sIdx]?.items?.[iIdx] + const ok = + row && + String(row.exercise_kind || '').toLowerCase().trim() === 'combination' && + row.exercise_id + if (!ok) setComboPlanningModal(null) + }, [sections, comboPlanningModal]) + const closeInsertChooser = useCallback(() => setInsertChooser(null), []) const insertSlotKeyPrefix = @@ -533,6 +571,23 @@ export default function TrainingUnitSectionsEditor({ const list = ensure(sections) + let comboPlanningModalItem = null + let comboPlanningModalSX = null + let comboPlanningModalIX = null + if (comboPlanningModal) { + const { sIdx, iIdx } = comboPlanningModal + const cand = list[sIdx]?.items?.[iIdx] + if ( + cand && + String(cand.exercise_kind || '').toLowerCase().trim() === 'combination' && + cand.exercise_id + ) { + comboPlanningModalItem = cand + comboPlanningModalSX = sIdx + comboPlanningModalIX = iIdx + } + } + return (
+ + {(comboPlanningModalItem.exercise_title || '').trim() || + `Kombination #${comboPlanningModalItem.exercise_id}`} + + + ({compactComboPlanningCaption(comboPlanningModalItem)}) + +
+