import React, { useMemo, useState } from 'react' import { filterFrameworkPrograms, frameworkProgramOptionLabel, frameworkSessionDurationLabel, } from '../../utils/frameworkProgramListHelpers' import { formatDurationDisplay } from '../../utils/trainingDurationUtils' /** * Modal: geplante Einheiten aus einem Trainingsrahmenprogramm (Blueprint-Slots) erzeugen. */ export default function TrainingPlanningFrameworkImportModal({ open, frameworkProgramsList, catalogFocusAreas = [], catalogTrainingTypes = [], catalogTargetGroups = [], fwImportProgramId, onProgramChange, fwImportLoading, fwImportDetail, fwImportSelectedSlots, onToggleSlot, fwImportSlotDates, onSlotDateChange, fwImportStartDate, onFwImportStartDateChange, fwImportIntervalDays, onFwImportIntervalDaysChange, fwImportSubmitting, onApplyDateSuggestions, onSubmit, onClose, }) { const [filterQuery, setFilterQuery] = useState('') const [filterFocusIds, setFilterFocusIds] = useState([]) const [filterTypeIds, setFilterTypeIds] = useState([]) const [filterTargetGroupIds, setFilterTargetGroupIds] = useState([]) const [filterDurationMin, setFilterDurationMin] = useState('') const filteredPrograms = useMemo( () => filterFrameworkPrograms(frameworkProgramsList, { query: filterQuery, focusAreaIds: filterFocusIds, trainingTypeIds: filterTypeIds, targetGroupIds: filterTargetGroupIds, durationTargetMin: filterDurationMin === '' ? null : parseInt(filterDurationMin, 10), }), [ frameworkProgramsList, filterQuery, filterFocusIds, filterTypeIds, filterTargetGroupIds, filterDurationMin, ] ) const selectedProgramSummary = useMemo(() => { if (!fwImportProgramId) return null return (frameworkProgramsList || []).find((p) => String(p.id) === String(fwImportProgramId)) }, [frameworkProgramsList, fwImportProgramId]) const toggleId = (list, setList, id) => { const s = String(id) setList((prev) => (prev.includes(s) ? prev.filter((x) => x !== s) : [...prev, s])) } if (!open) return null return (

Sessions aus Rahmen übernehmen

Wähle ein Trainingsrahmenprogramm und eine oder mehrere Sessions. Pro Session entsteht eine{' '} eigene geplante Einheit in der aktuellen Gruppe (Kopie des Ablaufs). Die{' '} Verknüpfung zum Rahmen-Slot bleibt sichtbar.

Rahmen filtern (optional)
setFilterQuery(e.target.value)} placeholder="z. B. Gürtel, Koordination …" disabled={fwImportSubmitting} />
setFilterDurationMin(e.target.value)} placeholder="z. B. 90" disabled={fwImportSubmitting} />

Zeigt Programme, deren hinterlegte Session-Dauer in etwa passt (±10 Min).

{catalogFocusAreas.length > 0 ? (
Fokusbereich
{catalogFocusAreas.map((fa) => ( ))}
) : null} {catalogTrainingTypes.length > 0 ? (
Trainingsart
{catalogTrainingTypes.map((t) => ( ))}
) : null} {catalogTargetGroups.length > 0 ? (
Zielgruppe
{catalogTargetGroups.map((tg) => ( ))}
) : null}

{filteredPrograms.length} von {frameworkProgramsList.length} Rahmenprogramm(en) sichtbar. Entwicklungsziele sind freie Texte — die Suche durchsucht auch Ziel-Titel.

{selectedProgramSummary ? (

Session-Dauer: {frameworkSessionDurationLabel(selectedProgramSummary)} {selectedProgramSummary.goal_titles_agg ? ( <> {' '} · Ziele: {selectedProgramSummary.goal_titles_agg} ) : null}

) : null}
{fwImportLoading ? (

Laden der Sessions…

) : fwImportDetail?.slots?.length ? ( <>
Sessions (mit Ablauf)
    {[...fwImportDetail.slots] .sort((a, b) => (a.sort_order ?? 0) - (b.sort_order ?? 0)) .map((slot) => { const hasBp = !!slot.blueprint_training_unit_id const checked = fwImportSelectedSlots.has(slot.id) const label = (slot.title || '').trim() || `Session ${(slot.sort_order ?? 0) + 1}` const slotDur = slot.planned_duration_min != null ? formatDurationDisplay(slot.planned_duration_min) : null return (
  • ) })}
onFwImportStartDateChange(e.target.value)} disabled={fwImportSubmitting} />
onFwImportIntervalDaysChange(parseInt(e.target.value, 10) || 0)} disabled={fwImportSubmitting} />
) : fwImportProgramId ? (

Keine Sessions in diesem Programm.

) : null}
) }