import React, { useState, useEffect } from 'react' import api from '../utils/api' import { useAuth } from '../context/AuthContext' function TrainingPlanningPage() { const { user } = useAuth() const [groups, setGroups] = useState([]) const [selectedGroupId, setSelectedGroupId] = useState('') const [units, setUnits] = useState([]) const [exercises, setExercises] = useState([]) const [loading, setLoading] = useState(true) const [showModal, setShowModal] = useState(false) const [editingUnit, setEditingUnit] = useState(null) // Date range (default: next 30 days) const today = new Date().toISOString().split('T')[0] const thirtyDaysLater = new Date(Date.now() + 30 * 24 * 60 * 60 * 1000).toISOString().split('T')[0] const [startDate, setStartDate] = useState(today) const [endDate, setEndDate] = useState(thirtyDaysLater) // Form state const [formData, setFormData] = useState({ group_id: '', planned_date: '', planned_time_start: '', planned_time_end: '', planned_focus: '', actual_date: '', actual_time_start: '', actual_time_end: '', attendance_count: '', status: 'planned', notes: '', trainer_notes: '', exercises: [] }) useEffect(() => { loadData() }, []) useEffect(() => { if (selectedGroupId) { loadUnits() } }, [selectedGroupId, startDate, endDate]) const loadData = async () => { try { const [groupsData, exercisesData] = await Promise.all([ api.listTrainingGroups({ status: 'active' }), api.listExercises({ include_variants: true }) ]) setGroups(groupsData) setExercises(exercisesData) // Auto-select first group if trainer owns it if (groupsData.length > 0) { const ownGroup = groupsData.find(g => g.trainer_id === user?.id) if (ownGroup) { setSelectedGroupId(ownGroup.id) } else if (groupsData.length === 1) { setSelectedGroupId(groupsData[0].id) } } } catch (err) { console.error('Failed to load data:', err) alert('Fehler beim Laden: ' + err.message) } finally { setLoading(false) } } const loadUnits = async () => { if (!selectedGroupId) return try { const unitsData = await api.listTrainingUnits({ group_id: selectedGroupId, start_date: startDate, end_date: endDate }) setUnits(unitsData) } catch (err) { console.error('Failed to load units:', err) } } const handleQuickCreate = async () => { if (!selectedGroupId) { alert('Bitte wähle zuerst eine Trainingsgruppe') return } const date = prompt('Datum für neue Trainingseinheit (YYYY-MM-DD):', today) if (!date) return try { await api.quickCreateTrainingUnit({ group_id: parseInt(selectedGroupId), planned_date: date }) await loadUnits() } catch (err) { alert('Fehler beim Erstellen: ' + err.message) } } const handleCreate = () => { if (!selectedGroupId) { alert('Bitte wähle zuerst eine Trainingsgruppe') return } const group = groups.find(g => g.id === parseInt(selectedGroupId)) setEditingUnit(null) setFormData({ group_id: selectedGroupId, planned_date: today, planned_time_start: group?.time_start?.slice(0, 5) || '', planned_time_end: group?.time_end?.slice(0, 5) || '', planned_focus: '', actual_date: '', actual_time_start: '', actual_time_end: '', attendance_count: '', status: 'planned', notes: '', trainer_notes: '', exercises: [] }) setShowModal(true) } const handleEdit = async (unit) => { try { const fullUnit = await api.getTrainingUnit(unit.id) setEditingUnit(fullUnit) setFormData({ group_id: fullUnit.group_id, planned_date: fullUnit.planned_date || '', planned_time_start: fullUnit.planned_time_start?.slice(0, 5) || '', planned_time_end: fullUnit.planned_time_end?.slice(0, 5) || '', planned_focus: fullUnit.planned_focus || '', actual_date: fullUnit.actual_date || '', actual_time_start: fullUnit.actual_time_start?.slice(0, 5) || '', actual_time_end: fullUnit.actual_time_end?.slice(0, 5) || '', attendance_count: fullUnit.attendance_count || '', status: fullUnit.status || 'planned', notes: fullUnit.notes || '', trainer_notes: fullUnit.trainer_notes || '', exercises: fullUnit.exercises || [] }) setShowModal(true) } catch (err) { alert('Fehler beim Laden: ' + err.message) } } const handleDelete = async (unit) => { if (!confirm(`Trainingseinheit vom ${unit.planned_date} wirklich löschen?`)) return try { await api.deleteTrainingUnit(unit.id) await loadUnits() } catch (err) { alert('Fehler beim Löschen: ' + err.message) } } const handleSubmit = async (e) => { e.preventDefault() if (!formData.group_id || !formData.planned_date) { alert('Gruppe und Datum sind Pflichtfelder') return } try { const payload = { ...formData, group_id: parseInt(formData.group_id), attendance_count: formData.attendance_count ? parseInt(formData.attendance_count) : null, exercises: formData.exercises .filter( (ex) => ex.exercise_id !== '' && ex.exercise_id != null && !Number.isNaN(Number(ex.exercise_id)) ) .map((ex, idx) => ({ exercise_id: ex.exercise_id, order_index: idx, exercise_variant_id: ex.exercise_variant_id !== '' && ex.exercise_variant_id != null ? parseInt(ex.exercise_variant_id, 10) : null, planned_duration_min: ex.planned_duration_min ? parseInt(ex.planned_duration_min) : null, actual_duration_min: ex.actual_duration_min ? parseInt(ex.actual_duration_min) : null, notes: ex.notes || null, modifications: ex.modifications || null })) } if (editingUnit) { await api.updateTrainingUnit(editingUnit.id, payload) } else { await api.createTrainingUnit(payload) } setShowModal(false) await loadUnits() } catch (err) { alert('Fehler beim Speichern: ' + err.message) } } const updateFormField = (field, value) => { setFormData(prev => ({ ...prev, [field]: value })) } const addExercise = () => { setFormData(prev => ({ ...prev, exercises: [...prev.exercises, { exercise_id: '', exercise_variant_id: '', planned_duration_min: '', actual_duration_min: '', notes: '', modifications: '' }] })) } const updateExercise = (index, field, value) => { setFormData(prev => ({ ...prev, exercises: prev.exercises.map((ex, i) => { if (i !== index) return ex const next = { ...ex, [field]: value } if (field === 'exercise_id') { next.exercise_variant_id = '' } return next }) })) } const removeExercise = (index) => { setFormData(prev => ({ ...prev, exercises: prev.exercises.filter((_, i) => i !== index) })) } const moveExercise = (index, direction) => { const newExercises = [...formData.exercises] const target = index + direction if (target < 0 || target >= newExercises.length) return [newExercises[index], newExercises[target]] = [newExercises[target], newExercises[index]] setFormData(prev => ({ ...prev, exercises: newExercises })) } if (loading) { return (

Laden...

) } const selectedGroup = groups.find(g => g.id === parseInt(selectedGroupId)) return (

Trainingsplanung

{/* Group & Date Controls */}
setStartDate(e.target.value)} />
setEndDate(e.target.value)} />
{selectedGroup && (

📍 {selectedGroup.location || 'Kein Ort angegeben'} {selectedGroup.weekday && ` · ${selectedGroup.weekday}`} {selectedGroup.time_start && ` · ${selectedGroup.time_start.slice(0, 5)} - ${selectedGroup.time_end?.slice(0, 5)}`}

)}
{/* Action Buttons */} {selectedGroupId && (
)} {/* Units List */} {!selectedGroupId ? (

Bitte wähle eine Trainingsgruppe aus

) : units.length === 0 ? (

Keine Trainingseinheiten im gewählten Zeitraum

) : (
{units.map(unit => (

{unit.planned_date} {unit.planned_time_start && ` · ${unit.planned_time_start.slice(0, 5)} - ${unit.planned_time_end?.slice(0, 5)}`}

{unit.planned_focus && (

🎯 {unit.planned_focus}

)}
{unit.status === 'planned' && '📅 Geplant'} {unit.status === 'completed' && '✓ Durchgeführt'} {unit.status === 'cancelled' && '✗ Abgesagt'} {unit.attendance_count !== null && ( 👥 {unit.attendance_count} Teilnehmer )}
{unit.notes && (

💬 {unit.notes}

)}
))}
)} {/* Create/Edit Modal */} {showModal && (

{editingUnit ? 'Trainingseinheit bearbeiten' : 'Neue Trainingseinheit'}

{/* Basic Info */}

Planung

updateFormField('planned_date', e.target.value)} required />
updateFormField('planned_time_start', e.target.value)} />
updateFormField('planned_time_end', e.target.value)} />
updateFormField('planned_focus', e.target.value)} placeholder="z.B. Kihon Grundlagen, Kata Heian Shodan" />
{/* Exercises */}

Übungen

{formData.exercises.length === 0 ? (

Noch keine Übungen hinzugefügt

) : (
{formData.exercises.map((ex, idx) => { const picked = exercises.find((e) => e.id === ex.exercise_id) const variantOpts = Array.isArray(picked?.variants) ? picked.variants : [] return (
updateExercise(idx, 'planned_duration_min', e.target.value)} placeholder="min" style={{ margin: 0 }} />
) })}
)} {/* Durchführung (nur bei Edit) */} {editingUnit && ( <>

Durchführung

updateFormField('actual_date', e.target.value)} />
updateFormField('actual_time_start', e.target.value)} />
updateFormField('actual_time_end', e.target.value)} />
updateFormField('attendance_count', e.target.value)} />
)} {/* Notes */}

Notizen