refactor: streamline exercise selection process in training pages
- Simplified the exercise selection logic in TrainingUnitSectionsEditor, TrainingFrameworkProgramEditPage, and TrainingPlanningPage by removing the multi-select option. - Updated the ExercisePickerModal to always enable multi-select, enhancing user experience when selecting exercises. - Refactored the handling of selected exercises to improve clarity and maintainability of the code.
This commit is contained in:
parent
4080088d42
commit
86192df508
|
|
@ -809,19 +809,10 @@ export default function TrainingUnitSectionsEditor({
|
|||
<button
|
||||
type="button"
|
||||
className="btn btn-secondary framework-ctrl framework-ctrl--xs"
|
||||
onClick={() => addItem(sIdx, 'exercise')}
|
||||
onClick={() => onRequestExercisePick?.({ sectionIndex: sIdx })}
|
||||
>
|
||||
+ Übung
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
className="btn btn-secondary framework-ctrl framework-ctrl--xs"
|
||||
onClick={() =>
|
||||
onRequestExercisePick?.({ sectionIndex: sIdx, multi: true })
|
||||
}
|
||||
>
|
||||
+ mehrere Übungen…
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
className="btn btn-secondary framework-ctrl framework-ctrl--xs"
|
||||
|
|
|
|||
|
|
@ -627,12 +627,11 @@ export default function TrainingFrameworkProgramEditPage() {
|
|||
),
|
||||
}))
|
||||
}}
|
||||
onRequestExercisePick={({ sectionIndex, itemIndex, multi }) =>
|
||||
onRequestExercisePick={({ sectionIndex, itemIndex }) =>
|
||||
setSectionPickerCtx({
|
||||
slotIdx: si,
|
||||
sectionIndex,
|
||||
itemIndex: typeof itemIndex === 'number' ? itemIndex : undefined,
|
||||
multi: !!multi,
|
||||
})
|
||||
}
|
||||
onPeekExercise={(id, variantId) =>
|
||||
|
|
@ -1108,75 +1107,45 @@ export default function TrainingFrameworkProgramEditPage() {
|
|||
|
||||
<ExercisePickerModal
|
||||
open={sectionPickerCtx != null}
|
||||
multiSelect={!!sectionPickerCtx?.multi}
|
||||
multiSelect
|
||||
onClose={() => setSectionPickerCtx(null)}
|
||||
onSelectExercises={
|
||||
sectionPickerCtx?.multi
|
||||
? async (picked) => {
|
||||
if (!sectionPickerCtx || !picked?.length) return
|
||||
const { slotIdx, sectionIndex: sIdx } = sectionPickerCtx
|
||||
const rows = []
|
||||
for (const ex of picked) {
|
||||
const row = await hydrateExercisePlanningRow(ex)
|
||||
if (row) rows.push(row)
|
||||
}
|
||||
if (!rows.length) return
|
||||
setForm((prev) => ({
|
||||
...prev,
|
||||
slots: prev.slots.map((sl, ii) =>
|
||||
ii !== slotIdx
|
||||
? sl
|
||||
: {
|
||||
...sl,
|
||||
sections: (
|
||||
sl.sections && sl.sections.length ? sl.sections : [defaultSection('Ablauf')]
|
||||
).map((sec, si) =>
|
||||
si !== sIdx ? sec : { ...sec, items: [...(sec.items || []), ...rows] }
|
||||
),
|
||||
}
|
||||
),
|
||||
}))
|
||||
setSectionPickerCtx(null)
|
||||
}
|
||||
: undefined
|
||||
}
|
||||
onSelectExercise={async (exercise) => {
|
||||
if (!sectionPickerCtx) return
|
||||
if (sectionPickerCtx.multi) return
|
||||
if (typeof sectionPickerCtx.itemIndex !== 'number') return
|
||||
onSelectExercises={async (picked) => {
|
||||
if (!sectionPickerCtx || !picked?.length) return
|
||||
const rows = []
|
||||
for (const ex of picked) {
|
||||
const row = await hydrateExercisePlanningRow(ex)
|
||||
if (row) rows.push(row)
|
||||
}
|
||||
if (!rows.length) return
|
||||
const { slotIdx, sectionIndex: sIdx, itemIndex: iIdx } = sectionPickerCtx
|
||||
const row = await hydrateExercisePlanningRow(exercise)
|
||||
if (!row) return
|
||||
setForm((prev) => ({
|
||||
...prev,
|
||||
slots: prev.slots.map((sl, ii) =>
|
||||
ii !== slotIdx
|
||||
? sl
|
||||
: {
|
||||
...sl,
|
||||
sections: (sl.sections && sl.sections.length ? sl.sections : [defaultSection('Ablauf')]).map(
|
||||
(sec, si) =>
|
||||
si !== sIdx
|
||||
? sec
|
||||
: {
|
||||
...sec,
|
||||
items: (sec.items || []).map((r2, ji) =>
|
||||
ji !== iIdx
|
||||
? r2
|
||||
: r2.item_type !== 'exercise'
|
||||
? r2
|
||||
: {
|
||||
...r2,
|
||||
exercise_id: row.exercise_id,
|
||||
exercise_variant_id: row.exercise_variant_id,
|
||||
exercise_title: row.exercise_title,
|
||||
variants: row.variants,
|
||||
}
|
||||
),
|
||||
}
|
||||
),
|
||||
slots: prev.slots.map((sl, ii) => {
|
||||
if (ii !== slotIdx) return sl
|
||||
const baseSecs = sl.sections && sl.sections.length ? sl.sections : [defaultSection('Ablauf')]
|
||||
return {
|
||||
...sl,
|
||||
sections: baseSecs.map((sec, si) => {
|
||||
if (si !== sIdx) return sec
|
||||
const items = [...(sec.items || [])]
|
||||
if (typeof iIdx === 'number') {
|
||||
const cur = items[iIdx]
|
||||
if (!cur || cur.item_type !== 'exercise') return sec
|
||||
const [first, ...tail] = rows
|
||||
items[iIdx] = {
|
||||
...cur,
|
||||
exercise_id: first.exercise_id,
|
||||
exercise_variant_id: first.exercise_variant_id,
|
||||
exercise_title: first.exercise_title,
|
||||
variants: first.variants,
|
||||
}
|
||||
if (tail.length) items.splice(iIdx + 1, 0, ...tail)
|
||||
return { ...sec, items }
|
||||
}
|
||||
),
|
||||
return { ...sec, items: [...items, ...rows] }
|
||||
}),
|
||||
}
|
||||
}),
|
||||
}))
|
||||
setSectionPickerCtx(null)
|
||||
}}
|
||||
|
|
|
|||
|
|
@ -709,11 +709,10 @@ function TrainingPlanningPage() {
|
|||
sections: updater(prev.sections),
|
||||
}))
|
||||
}
|
||||
onRequestExercisePick={({ sectionIndex, itemIndex, multi }) => {
|
||||
onRequestExercisePick={({ sectionIndex, itemIndex }) => {
|
||||
setExercisePickerTarget({
|
||||
sIdx: sectionIndex,
|
||||
iIdx: typeof itemIndex === 'number' ? itemIndex : undefined,
|
||||
multi: !!multi,
|
||||
})
|
||||
setExercisePickerOpen(true)
|
||||
}}
|
||||
|
|
@ -824,61 +823,41 @@ function TrainingPlanningPage() {
|
|||
)}
|
||||
<ExercisePickerModal
|
||||
open={exercisePickerOpen}
|
||||
multiSelect={!!exercisePickerTarget?.multi}
|
||||
multiSelect
|
||||
onClose={() => {
|
||||
setExercisePickerOpen(false)
|
||||
setExercisePickerTarget(null)
|
||||
}}
|
||||
onSelectExercises={
|
||||
exercisePickerTarget?.multi
|
||||
? async (picked) => {
|
||||
if (!exercisePickerTarget || !picked?.length) return
|
||||
const { sIdx } = exercisePickerTarget
|
||||
const rows = []
|
||||
for (const ex of picked) {
|
||||
const row = await hydrateExercisePlanningRow(ex)
|
||||
if (row) rows.push(row)
|
||||
}
|
||||
if (!rows.length) return
|
||||
setFormData((prev) => ({
|
||||
...prev,
|
||||
sections: prev.sections.map((s, si) =>
|
||||
si !== sIdx ? s : { ...s, items: [...(s.items || []), ...rows] }
|
||||
),
|
||||
}))
|
||||
setExercisePickerOpen(false)
|
||||
setExercisePickerTarget(null)
|
||||
}
|
||||
: undefined
|
||||
}
|
||||
onSelectExercise={async (ex) => {
|
||||
if (!exercisePickerTarget || exercisePickerTarget.multi) return
|
||||
const row = await hydrateExercisePlanningRow(ex)
|
||||
if (!row) return
|
||||
onSelectExercises={async (picked) => {
|
||||
if (!exercisePickerTarget || !picked?.length) return
|
||||
const rows = []
|
||||
for (const ex of picked) {
|
||||
const row = await hydrateExercisePlanningRow(ex)
|
||||
if (row) rows.push(row)
|
||||
}
|
||||
if (!rows.length) return
|
||||
const { sIdx, iIdx } = exercisePickerTarget
|
||||
if (typeof iIdx !== 'number') return
|
||||
setFormData((prev) => ({
|
||||
...prev,
|
||||
sections: prev.sections.map((s, si) =>
|
||||
si !== sIdx
|
||||
? s
|
||||
: {
|
||||
...s,
|
||||
items: s.items.map((r2, ii) =>
|
||||
ii !== iIdx
|
||||
? r2
|
||||
: r2.item_type !== 'exercise'
|
||||
? r2
|
||||
: {
|
||||
...r2,
|
||||
exercise_id: row.exercise_id,
|
||||
exercise_variant_id: row.exercise_variant_id,
|
||||
exercise_title: row.exercise_title,
|
||||
variants: row.variants,
|
||||
}
|
||||
),
|
||||
}
|
||||
),
|
||||
sections: prev.sections.map((s, si) => {
|
||||
if (si !== sIdx) return s
|
||||
const items = [...(s.items || [])]
|
||||
if (typeof iIdx === 'number') {
|
||||
const cur = items[iIdx]
|
||||
if (!cur || cur.item_type !== 'exercise') return s
|
||||
const [first, ...tail] = rows
|
||||
items[iIdx] = {
|
||||
...cur,
|
||||
exercise_id: first.exercise_id,
|
||||
exercise_variant_id: first.exercise_variant_id,
|
||||
exercise_title: first.exercise_title,
|
||||
variants: first.variants,
|
||||
}
|
||||
if (tail.length) items.splice(iIdx + 1, 0, ...tail)
|
||||
return { ...s, items }
|
||||
}
|
||||
return { ...s, items: [...items, ...rows] }
|
||||
}),
|
||||
}))
|
||||
setExercisePickerOpen(false)
|
||||
setExercisePickerTarget(null)
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user