import api from './api' export function defaultSection(title = 'Hauptteil') { return { title, guidance_notes: '', items: [] } } export function exerciseRow() { return { item_type: 'exercise', exercise_id: '', exercise_variant_id: '', exercise_title: '', variants: [], planned_duration_min: '', actual_duration_min: '', notes: '', modifications: '', } } export async function hydrateExercisePlanningRow(exercise) { let variants = Array.isArray(exercise?.variants) ? exercise.variants : [] let title = exercise?.title || '' const id = exercise?.id if (!id) return null if (!variants.length) { try { const full = await api.getExercise(id) variants = Array.isArray(full?.variants) ? full.variants : [] title = full?.title || title } catch { variants = [] } } const row = exerciseRow() row.exercise_id = id row.exercise_variant_id = '' row.exercise_title = title row.variants = variants return row } export function noteRow() { return { item_type: 'note', note_body: '' } } export function normalizeUnitToForm(fullUnit) { if (fullUnit.sections && fullUnit.sections.length) { return fullUnit.sections.map((sec) => ({ title: sec.title, guidance_notes: sec.guidance_notes || '', items: (sec.items || []).map((it) => { if (it.item_type === 'note') { return { item_type: 'note', note_body: it.note_body || '' } } return { item_type: 'exercise', exercise_id: it.exercise_id, exercise_variant_id: it.exercise_variant_id ?? '', exercise_title: it.exercise_title || '', variants: [], planned_duration_min: it.planned_duration_min !== null && it.planned_duration_min !== undefined ? String(it.planned_duration_min) : '', actual_duration_min: it.actual_duration_min !== null && it.actual_duration_min !== undefined ? String(it.actual_duration_min) : '', notes: it.notes ?? '', modifications: it.modifications ?? '', } }), })) } if (fullUnit.exercises && fullUnit.exercises.length) { return [ { title: 'Übungen', guidance_notes: '', items: fullUnit.exercises.map((ex) => ({ item_type: 'exercise', exercise_id: ex.exercise_id, exercise_variant_id: ex.exercise_variant_id ?? '', exercise_title: ex.exercise_title || '', variants: [], planned_duration_min: ex.planned_duration_min !== null && ex.planned_duration_min !== undefined ? String(ex.planned_duration_min) : '', actual_duration_min: ex.actual_duration_min !== null && ex.actual_duration_min !== undefined ? String(ex.actual_duration_min) : '', notes: ex.notes ?? '', modifications: ex.modifications ?? '', })), }, ] } return [defaultSection()] } export async function enrichSectionsWithVariants(sections) { if (!sections?.length) return sections const ids = [] for (const sec of sections) { for (const it of sec.items || []) { if (it.item_type === 'note') continue if (it.exercise_id) ids.push(it.exercise_id) } } const unique = [...new Set(ids)] const cache = new Map() await Promise.all( unique.map(async (id) => { try { const ex = await api.getExercise(id) cache.set(id, { title: ex.title || '', variants: Array.isArray(ex.variants) ? ex.variants : [], }) } catch { cache.set(id, { title: '', variants: [] }) } }) ) return sections.map((sec) => ({ ...sec, items: (sec.items || []).map((it) => { if (it.item_type === 'note') return it if (!it.exercise_id) return it const c = cache.get(it.exercise_id) if (!c) return it return { ...it, exercise_title: it.exercise_title || c.title, variants: Array.isArray(it.variants) && it.variants.length > 0 ? it.variants : c.variants, } }), })) } export function parseMin(v) { if (v === '' || v === null || v === undefined) return null const n = parseInt(String(v), 10) return Number.isFinite(n) ? n : null } export function buildSectionsPayload(sections) { return sections.map((sec, si) => ({ order_index: si, title: (sec.title || '').trim() || 'Abschnitt', guidance_notes: sec.guidance_notes?.trim() ? sec.guidance_notes.trim() : null, items: (sec.items || []) .map((it, ii) => { if (it.item_type === 'note') { return { item_type: 'note', order_index: ii, note_body: it.note_body ?? '', } } if (it.exercise_id === '' || it.exercise_id == null || Number.isNaN(Number(it.exercise_id))) { return null } const vid = it.exercise_variant_id return { item_type: 'exercise', order_index: ii, exercise_id: parseInt(it.exercise_id, 10), exercise_variant_id: vid !== '' && vid != null && !Number.isNaN(Number(vid)) ? parseInt(vid, 10) : null, planned_duration_min: parseMin(it.planned_duration_min), actual_duration_min: parseMin(it.actual_duration_min), notes: it.notes?.trim() ? it.notes.trim() : null, modifications: it.modifications?.trim() ? it.modifications.trim() : null, } }) .filter(Boolean), })) } export function sectionPlannedMinutes(sec) { return (sec.items || []).reduce((sum, it) => { if (it.item_type !== 'exercise') return sum const m = parseMin(it.planned_duration_min) return sum + (m || 0) }, 0) }