/** * CommCoach Dossier View * * Shows context detail: sessions timeline, tasks checklist, scores, insights. */ import React, { useState, useCallback, useEffect } from 'react'; import { useCommcoach } from '../../../hooks/useCommcoach'; import ReactMarkdown from 'react-markdown'; import styles from './CommcoachDossierView.module.css'; export const CommcoachDossierView: React.FC = () => { const coach = useCommcoach(); const [newTaskTitle, setNewTaskTitle] = useState(''); const [activeTab, setActiveTab] = useState<'sessions' | 'tasks' | 'scores'>('tasks'); useEffect(() => { if (!coach.selectedContextId && coach.contexts.length > 0) { coach.selectContext(coach.contexts[0].id); } }, [coach.contexts, coach.selectedContextId, coach.selectContext]); const handleAddTask = useCallback(async () => { if (!newTaskTitle.trim()) return; await coach.addTask(newTaskTitle); setNewTaskTitle(''); }, [newTaskTitle, coach]); if (coach.loadingContexts) { return

Lade...

; } if (coach.contexts.length === 0) { return (

Noch keine Coaching-Themen vorhanden. Erstelle zuerst eines im Coaching-Tab.

); } return (
{/* Context Selector */}
{coach.contexts.map(ctx => ( ))}
{!coach.selectedContextId ? (

Waehle ein Coaching-Thema.

) : (<> {/* Context Header */}

{coach.selectedContext?.title}

{coach.selectedContext?.description && (

{coach.selectedContext.description}

)}
{/* Tab Navigation */}
{/* Tasks Tab */} {activeTab === 'tasks' && (
setNewTaskTitle(e.target.value)} onKeyDown={e => e.key === 'Enter' && handleAddTask()} />
{coach.tasks.length === 0 ? (
Noch keine Aufgaben. Der Coach schlaegt waehrend Sessions Aufgaben vor.
) : (
{coach.tasks.map(task => (
{task.title}
{task.description &&
{task.description}
}
{task.priority}
))}
)}
)} {/* Sessions Tab */} {activeTab === 'sessions' && (
{coach.sessions.length === 0 ? (
Noch keine abgeschlossenen Sessions.
) : (
{coach.sessions.map(s => (
{s.status === 'completed' ? 'Abgeschlossen' : s.status === 'active' ? 'Aktiv' : 'Abgebrochen'} {s.startedAt ? new Date(s.startedAt).toLocaleDateString('de-CH') : ''} {s.competenceScore != null && ( Score: {Math.round(s.competenceScore)} )}
{s.summary && (
{s.summary}
)}
{s.messageCount} Nachrichten | {Math.round(s.durationSeconds / 60)} Min.
))}
)}
)} {/* Scores Tab */} {activeTab === 'scores' && (
{coach.scores.length === 0 ? (
Noch keine Bewertungen. Schliesse eine Session ab, um Scores zu erhalten.
) : (
{_groupScoresByDimension(coach.scores).map(group => (
{_dimensionLabel(group.dimension)} {Math.round(group.latest.score)}/100 {group.latest.trend === 'improving' ? 'steigend' : group.latest.trend === 'declining' ? 'sinkend' : 'stabil'}
{group.latest.evidence && (
{group.latest.evidence}
)}
))}
)}
)} )}
); }; interface ScoreGroup { dimension: string; latest: { score: number; trend: string; evidence?: string; createdAt?: string }; history: Array<{ score: number; createdAt?: string }>; } function _groupScoresByDimension(scores: any[]): ScoreGroup[] { const groups: Record = {}; for (const s of scores) { const dim = s.dimension; if (!groups[dim]) { groups[dim] = { dimension: dim, latest: s, history: [] }; } groups[dim].history.push({ score: s.score, createdAt: s.createdAt }); if (s.createdAt > (groups[dim].latest.createdAt || '')) { groups[dim].latest = s; } } return Object.values(groups); } function _dimensionLabel(dim: string): string { const labels: Record = { empathy: 'Einfuehlungsvermoegen', clarity: 'Klarheit', assertiveness: 'Durchsetzung', listening: 'Zuhoeren', selfReflection: 'Selbstreflexion', }; return labels[dim] || dim; } export default CommcoachDossierView;