/** * CommCoach Settings View * * User profile settings: voice preferences, reminders, email notifications. */ import React, { useState, useEffect, useCallback } from 'react'; import { useApiRequest } from '../../../hooks/useApi'; import { useInstanceId } from '../../../hooks/useCurrentInstance'; import { getProfileApi, updateProfileApi, getVoiceLanguagesApi, getVoiceVoicesApi, testVoiceApi, type CoachingUserProfile, } from '../../../api/commcoachApi'; import styles from './CommcoachSettingsView.module.css'; export const CommcoachSettingsView: React.FC = () => { const { request } = useApiRequest(); const instanceId = useInstanceId(); const [profile, setProfile] = useState(null); const [languages, setLanguages] = useState([]); const [voices, setVoices] = useState([]); const [loading, setLoading] = useState(true); const [saving, setSaving] = useState(false); const [testing, setTesting] = useState(false); const [error, setError] = useState(null); const [success, setSuccess] = useState(null); const [language, setLanguage] = useState('de-DE'); const [voiceId, setVoiceId] = useState(''); const [reminderEnabled, setReminderEnabled] = useState(false); const [reminderTime, setReminderTime] = useState('09:00'); const [emailEnabled, setEmailEnabled] = useState(true); useEffect(() => { if (!instanceId) return; const loadData = async () => { setLoading(true); try { const [profileData, languagesData] = await Promise.all([ getProfileApi(request, instanceId), getVoiceLanguagesApi(request, instanceId), ]); setProfile(profileData); setLanguages(languagesData || []); if (profileData) { setLanguage(profileData.preferredLanguage || 'de-DE'); setVoiceId(profileData.preferredVoice || ''); setReminderEnabled(profileData.dailyReminderEnabled || false); setReminderTime(profileData.dailyReminderTime || '09:00'); setEmailEnabled(profileData.emailSummaryEnabled !== false); } const voicesData = await getVoiceVoicesApi(request, instanceId, profileData?.preferredLanguage || 'de-DE'); setVoices(voicesData || []); } catch (err: any) { setError(err.message || 'Fehler beim Laden'); } finally { setLoading(false); } }; loadData(); }, [request, instanceId]); const handleLanguageChange = useCallback(async (newLang: string) => { setLanguage(newLang); if (!instanceId) return; try { const voicesData = await getVoiceVoicesApi(request, instanceId, newLang); setVoices(voicesData || []); setVoiceId(''); } catch { /* ignore */ } }, [request, instanceId]); const handleSave = useCallback(async () => { if (!instanceId) return; setSaving(true); setError(null); setSuccess(null); try { const updated = await updateProfileApi(request, instanceId, { preferredLanguage: language, preferredVoice: voiceId || null, dailyReminderEnabled: reminderEnabled, dailyReminderTime: reminderTime, emailSummaryEnabled: emailEnabled, }); setProfile(updated); setSuccess('Einstellungen gespeichert'); setTimeout(() => setSuccess(null), 3000); } catch (err: any) { setError(err.message || 'Fehler beim Speichern'); } finally { setSaving(false); } }, [request, instanceId, language, voiceId, reminderEnabled, reminderTime, emailEnabled]); const handleTestVoice = useCallback(async () => { if (!instanceId) return; setTesting(true); try { const result = await testVoiceApi(request, instanceId, { language, voiceId: voiceId || undefined, }); if (result.success && result.audio) { const audioData = `data:audio/mp3;base64,${result.audio}`; const audio = new Audio(audioData); audio.play(); } } catch (err: any) { setError('Sprachtest fehlgeschlagen'); } finally { setTesting(false); } }, [request, instanceId, language, voiceId]); if (loading) { return
Einstellungen werden geladen...
; } return (

Coaching-Einstellungen

{error &&
{error}
} {success &&
{success}
} {/* Voice Settings */}

Sprache und Stimme

{/* Reminder Settings */}

Erinnerungen

{reminderEnabled && (
setReminderTime(e.target.value)} />
)}
{/* Stats */} {profile && (

Statistik

{profile.totalSessions} Sessions gesamt
{profile.totalMinutes} Minuten gesamt
{profile.streakDays} Aktueller Streak
{profile.longestStreak} Laengster Streak
)}
); }; export default CommcoachSettingsView;