import React, { useCallback, useEffect, useMemo, useState } from 'react' import { useNavigate } from 'react-router-dom' import api from '../../utils/api' import { useToast } from '../../context/ToastContext' import { useAuth } from '../../context/AuthContext' import { activeClubMemberships } from '../../utils/activeClub' import { collectExercisePlacementsForModule } from '../../utils/trainingPlanModuleFromUnit' /** * Erstellt ein Trainingsmodul aus den Übungen einer gespeicherten Trainingseinheit (Mehrfachauswahl). */ export default function SaveExercisesAsModuleModal({ open, onClose, unitId, planningModalClubId, onSuccess, }) { const navigate = useNavigate() const toast = useToast() const { user } = useAuth() const memberClubs = useMemo(() => activeClubMemberships(user?.clubs), [user?.clubs]) const roleLc = String(user?.role || '').toLowerCase() const isSuperadmin = roleLc === 'superadmin' const [loading, setLoading] = useState(false) const [submitting, setSubmitting] = useState(false) const [loadErr, setLoadErr] = useState('') const [unitLabel, setUnitLabel] = useState('') const [candidates, setCandidates] = useState([]) const [selected, setSelected] = useState(() => []) const [title, setTitle] = useState('') const [visibility, setVisibility] = useState('club') const [clubId, setClubId] = useState('') const resetLocal = useCallback(() => { setLoadErr('') setUnitLabel('') setCandidates([]) setSelected([]) setTitle('') setVisibility('club') setClubId('') }, []) useEffect(() => { if (!open || !unitId) { resetLocal() return } if (planningModalClubId != null && planningModalClubId !== '') { setClubId(String(planningModalClubId)) } else if (memberClubs.length === 1) { setClubId(String(memberClubs[0].id)) } setLoading(true) setLoadErr('') api .getTrainingUnit(unitId) .then((u) => { const dateStr = (u.planned_date || '').trim() || 'Training' setUnitLabel(dateStr) setTitle(`Modul · ${dateStr}`) const c = collectExercisePlacementsForModule(u) setCandidates(c) setSelected(c.map(() => true)) }) .catch((e) => { setLoadErr(e.message || 'Einheit konnte nicht geladen werden') setCandidates([]) setSelected([]) }) .finally(() => setLoading(false)) }, [open, unitId, planningModalClubId, memberClubs.length, resetLocal]) const toggleOne = (idx) => { setSelected((prev) => { const next = [...prev] next[idx] = !next[idx] return next }) } const setAll = (on) => { setSelected(candidates.map(() => on)) } const selectedCount = selected.filter(Boolean).length const handleSubmit = async (e) => { e.preventDefault() if (!unitId || submitting) return const itemsPayload = [] let oi = 0 for (let i = 0; i < candidates.length; i += 1) { if (!selected[i]) continue const c = candidates[i] itemsPayload.push({ item_type: 'exercise', order_index: oi, exercise_id: c.exercise_id, exercise_variant_id: c.exercise_variant_id, planned_duration_min: c.planned_duration_min, notes: c.notes, }) oi += 1 } if (!itemsPayload.length) { toast.error('Mindestens eine Übung auswählen.') return } const tit = (title || '').trim() if (!tit) { toast.error('Bitte einen Modultitel angeben.') return } let cid = visibility === 'club' && clubId ? parseInt(clubId, 10) : null if (visibility === 'club' && (!Number.isFinite(cid) || cid < 1)) { toast.error('Bitte einen Verein wählen (Sichtbarkeit „Verein“).') return } if (visibility !== 'club') cid = null setSubmitting(true) try { const created = await api.createTrainingModule({ title: tit, visibility, club_id: cid, items: itemsPayload, }) toast.success('Trainingsmodul gespeichert.') if (created?.id) { navigate(`/planning/training-modules/${created.id}`) } onSuccess?.() onClose() } catch (err) { toast.error(err.message || 'Speichern fehlgeschlagen') } finally { setSubmitting(false) } } if (!open) return null return (
Es werden die gespeicherten Übungspositionen der Einheit vom{' '} {unitLabel || '…'} verwendet. Speichere die Planung vorher, wenn du den aktuellen Stand brauchst.
{loading ? (Laden …
) : loadErr ? ({loadErr}
) : candidates.length === 0 ? (In dieser Einheit sind keine Übungen im Ablauf hinterlegt.
) : ( )} {loading ? (