import React, { useCallback, useEffect, useState } from 'react'
import { Link } from 'react-router-dom'
import api from '../utils/api'
function dashIfEmpty(val) {
const s = (val ?? '').toString().trim()
return s.length ? s : '—'
}
function FrameworkSummaryMeta({ r }) {
const trainingTypes =
typeof r.training_type_names_agg === 'string' ? r.training_type_names_agg.trim() : ''
const targetGroups =
typeof r.target_group_names_agg === 'string' ? r.target_group_names_agg.trim() : ''
const styleDir = typeof r.style_direction_name === 'string' ? r.style_direction_name.trim() : ''
const focus = typeof r.focus_area_name === 'string' ? r.focus_area_name.trim() : ''
const rowStyle = {
display: 'grid',
gridTemplateColumns: 'minmax(6.5rem, 32%) 1fr',
gap: '0.25rem 0.75rem',
alignItems: 'start',
marginTop: '0.35rem',
lineHeight: 1.45,
}
return (
Fokusbereich
{dashIfEmpty(focus)}
{styleDir ? (
Stilrichtung
{styleDir}
) : null}
Trainingsarten
{trainingTypes.length ? trainingTypes : '—'}
Zielgruppen
{targetGroups.length ? targetGroups : '—'}
Kurzbeschreibung
{(r.description && String(r.description).trim()) || '—'}
)
}
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
Wiederverwendbare Vorlagen für Ziele und Sessions. Die Verknüpfung mit{' '}
konkreten Gruppeneinheiten erfolgt aus der Planung der Gruppe (Übernahme
mit Bezug zum Rahmen).
Rahmenprogramm anlegen
← Zurück zur Trainingsplanung
{error && (
{error}
)}
{loading ? (
) : rows.length === 0 ? (
Noch kein Rahmenprogramm gespeichert. Lege ein neues an — mit Titel, mindestens einem Ziel und optional
Slots samt Übungen.
Rahmenprogramm anlegen
) : (
{rows.map((r) => (
{r.title || `Rahmen #${r.id}`}
{(r.goals_count ?? '—') + ' Ziele · '}
{(r.slots_count ?? '—') + ' Slots'}
Bearbeiten
handleDelete(r.id, r.title)}>
Löschen
))}
)}
)
}