import React, { useState, useEffect } from 'react' import { Link } from 'react-router-dom' import { useAuth } from '../context/AuthContext' import api from '../utils/api' import EmailVerificationBanner from '../components/EmailVerificationBanner' function unitWhenLabel(u) { const d = u.planned_date ? String(u.planned_date).slice(0, 10) : '' const t = u.planned_time_start ? String(u.planned_time_start).slice(0, 5) : '' const bits = [d, t].filter(Boolean) return bits.length ? bits.join(' · ') : 'Termin' } function Dashboard() { const [version, setVersion] = useState(null) const [profile, setProfile] = useState(null) const [loading, setLoading] = useState(true) const [trainingHome, setTrainingHome] = useState(null) const [trainingHomeErr, setTrainingHomeErr] = useState(null) const { user } = useAuth() useEffect(() => { loadData() }, []) useEffect(() => { if (!user?.id) { setTrainingHome(null) setTrainingHomeErr(null) return undefined } let cancelled = false ;(async () => { setTrainingHomeErr(null) try { const today = new Date().toISOString().slice(0, 10) const [upcomingRaw, recentRaw, plannedPool] = await Promise.all([ api.listTrainingUnits({ assigned_to_me: true, status: 'planned', start_date: today, sort: 'asc', limit: 8 }), api.listTrainingUnits({ assigned_to_me: true, status: 'completed', sort: 'desc', limit: 6 }), api.listTrainingUnits({ assigned_to_me: true, status: 'planned', start_date: today, sort: 'asc', limit: 40 }) ]) const noteHits = (plannedPool || []).filter((u) => { const tn = (u.trainer_notes || '').trim() const n = (u.notes || '').trim() return Boolean(tn || n) }).slice(0, 5) if (!cancelled) { setTrainingHome({ upcoming: Array.isArray(upcomingRaw) ? upcomingRaw : [], recent: Array.isArray(recentRaw) ? recentRaw : [], plannedWithNotes: noteHits }) } } catch (e) { if (!cancelled) { console.error('Dashboard Trainingsübersicht:', e) setTrainingHomeErr(e.message || 'Konnte Trainingsdaten nicht laden') setTrainingHome(null) } } })() return () => { cancelled = true } }, [user?.id]) const loadData = async () => { try { const [versionData, profileData] = await Promise.all([ api.getVersion(), api.getCurrentProfile() ]) setVersion(versionData) setProfile(profileData) } catch (err) { console.error('Failed to load data:', err) } finally { setLoading(false) } } if (loading) { return (

Laden...

) } return (

Dashboard

Willkommen, {user?.name || user?.email}!

{profile && } {/* Welcome Card */}

Willkommen bei Shinkan Jinkendo

Trainer- und Vereinsplattform für Kampfsport-Trainingsplanung

{user?.id && (

Deine nächsten Trainings

{trainingHomeErr ? (

{trainingHomeErr}

) : trainingHome?.upcoming?.length ? (
    {trainingHome.upcoming.map((u) => (
  • {unitWhenLabel(u)} {u.group_name ? ( {` — ${u.group_name}`} ) : null} {u.lead_trainer_name ? ( Leitung: {u.lead_trainer_name} ) : null}
  • ))}
) : (

Keine anstehenden Termine mit dir als Leitung oder Co‑Trainer. Unter{' '} Trainingsplanung {' '} kannst du den Vereins‑ oder Gruppen‑Zeitraum einblenden.

)}

Vermerk / Hinweise (anstehend)

{trainingHomeErr ? (

{trainingHomeErr}

) : trainingHome?.plannedWithNotes?.length ? (
    {trainingHome.plannedWithNotes.map((u) => { const snippet = (u.trainer_notes || u.notes || '').trim().slice(0, 120) return (
  • {unitWhenLabel(u)} {u.group_name ? {` · ${u.group_name}`} : null}
    {snippet} {(u.trainer_notes || u.notes || '').trim().length > 120 ? '…' : ''}
  • ) })}
) : (

Keine Einträge mit Allgemein‑ oder Trainer‑Notizen in deinen nächsten geplanten Terminen.

)}

Rückschau (durchgeführt)

{trainingHomeErr ? (

{trainingHomeErr}

) : trainingHome?.recent?.length ? (
    {trainingHome.recent.map((u) => (
  • {(u.actual_date || u.planned_date || '').toString().slice(0, 10) || 'Datum'} {u.group_name ? ( {` — ${u.group_name}`} ) : null}
  • ))}
) : (

Noch keine abgeschlossenen Einheiten in der Kurzliste.

)}
)} {/* Status Grid */}

✅ Fertig

  • Backend-Basis
  • Datenbank-Schema
  • Auth-System
  • Login & Registrierung

🚧 In Arbeit

  • Übungsverwaltung
  • Trainingsplanung
  • Kataloge (Skills, Methods)

📋 Geplant

  • MediaWiki-Import
  • Trainingsprogramme
  • Admin-Panel
{/* System Info */} {version && (

System-Information

Version: {version.app_version} Build: {version.build_date} Umgebung: {version.environment} DB Schema: {version.db_schema_version} Dein Tier: {profile?.tier || 'free'} Rolle: {profile?.role || 'user'}
)}
) } export default Dashboard