import React, { useCallback, useEffect, useState } from 'react' import { Link } from 'react-router-dom' import api from '../utils/api' const MODE_LABELS = { concrete: 'Konkret (Gruppe / Einheiten)', library: 'Bibliothek', } export default function TrainingFrameworkProgramsListPage() { const [rows, setRows] = useState([]) const [loading, setLoading] = useState(true) const [error, setError] = useState('') const load = useCallback(async () => { setLoading(true) setError('') try { const list = await api.listTrainingFrameworkPrograms() setRows(Array.isArray(list) ? list : []) } catch (e) { setError(e.message || 'Laden fehlgeschlagen') setRows([]) } finally { setLoading(false) } }, []) useEffect(() => { load() }, [load]) async function handleDelete(id, title) { if (!confirm(`Rahmenprogramm „${title || id}“ wirklich löschen?`)) return try { await api.deleteTrainingFrameworkProgram(id) await load() } catch (e) { alert(e.message || 'Löschen fehlgeschlagen') } } return (

Trainingsrahmenprogramme

Mehrere Entwicklungsziele und Übungen über Session‑Slots verteilen — als Vorlage in der Bibliothek oder im Kontext einer Gruppe.

+ Neues Rahmenprogramm

← Zurück zur Trainingsplanung

{error && (
{error}
)} {loading ? (

Laden…

) : rows.length === 0 ? (

Noch kein Rahmenprogramm angelegt. Über Neues Rahmenprogramm startest du mit Titel, Zielen und Slots.

) : (
    {rows.map((r) => (
  • {r.title || `Rahmen #${r.id}`}
    {MODE_LABELS[r.plan_mode] || r.plan_mode} {typeof r.goals_count === 'number' || typeof r.slots_count === 'number' ? ( {' '} · {r.goals_count ?? '—'} Ziele · {r.slots_count ?? '—'} Slots ) : null}
    {r.description ? (

    {r.description}

    ) : null}
    Bearbeiten
  • ))}
)}
) }