133 lines
No EOL
5.8 KiB
TypeScript
133 lines
No EOL
5.8 KiB
TypeScript
import React, { useState, useEffect } from 'react';
|
|
import styles from './HomeStyles/Einstellungen.module.css';
|
|
import sharedStyles from './HomeStyles/pages.module.css';
|
|
import { useLanguage, Language } from '../../contexts/LanguageContext';
|
|
|
|
function Einstellungen() {
|
|
const [isDarkMode, setIsDarkMode] = useState(false);
|
|
const { currentLanguage, setLanguage, t, isLoading } = useLanguage();
|
|
|
|
// Sync component state with current theme on mount
|
|
useEffect(() => {
|
|
const savedTheme = localStorage.getItem('theme');
|
|
const prefersDark = savedTheme === 'dark' || (!savedTheme && window.matchMedia('(prefers-color-scheme: dark)').matches);
|
|
setIsDarkMode(prefersDark);
|
|
}, []);
|
|
|
|
const applyTheme = (isDark: boolean) => {
|
|
if (isDark) {
|
|
document.documentElement.classList.add('dark-theme');
|
|
document.documentElement.classList.remove('light-theme');
|
|
} else {
|
|
document.documentElement.classList.add('light-theme');
|
|
document.documentElement.classList.remove('dark-theme');
|
|
}
|
|
document.documentElement.setAttribute('data-theme', isDark ? 'dark' : 'light');
|
|
};
|
|
|
|
const toggleTheme = () => {
|
|
const newIsDarkMode = !isDarkMode;
|
|
setIsDarkMode(newIsDarkMode);
|
|
applyTheme(newIsDarkMode);
|
|
localStorage.setItem('theme', newIsDarkMode ? 'dark' : 'light');
|
|
};
|
|
|
|
const handleLanguageChange = async (language: Language) => {
|
|
if (language === currentLanguage) return;
|
|
|
|
try {
|
|
await setLanguage(language);
|
|
} catch (error) {
|
|
console.error('Failed to change language:', error);
|
|
}
|
|
};
|
|
|
|
const getLanguageLabel = (lang: Language): string => {
|
|
switch (lang) {
|
|
case 'de': return t('language.german');
|
|
case 'en': return t('language.english');
|
|
case 'fr': return t('language.french');
|
|
default: return lang;
|
|
}
|
|
};
|
|
|
|
if (isLoading) {
|
|
return (
|
|
<div className={sharedStyles.pageContainer}>
|
|
<div className={sharedStyles.pageCard}>
|
|
<div style={{ padding: '2rem', textAlign: 'center' }}>
|
|
{t('common.loading')}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
return (
|
|
<div className={sharedStyles.pageContainer}>
|
|
<div className={sharedStyles.pageCard}>
|
|
<h1 className={sharedStyles.pageTitle}>{t('settings.title')}</h1>
|
|
<div className={sharedStyles.horizontalDivider}></div>
|
|
|
|
<div className={sharedStyles.contentArea}>
|
|
<div className={styles.settingItem}>
|
|
<div className={styles.settingInfo}>
|
|
<span className={styles.settingLabel}>{t('settings.theme')}</span>
|
|
<span className={styles.settingDescription}>
|
|
{t('settings.theme.description')}
|
|
</span>
|
|
</div>
|
|
|
|
<button
|
|
className={`${styles.themeToggle} ${isDarkMode ? styles.dark : styles.light}`}
|
|
onClick={toggleTheme}
|
|
aria-label={isDarkMode ? t('settings.theme.toggle.light') : t('settings.theme.toggle.dark')}
|
|
>
|
|
<div className={styles.toggleSlider}>
|
|
<div className={styles.toggleIcon}>
|
|
{isDarkMode ? '🌙' : '☀️'}
|
|
</div>
|
|
</div>
|
|
<span className={styles.toggleLabel}>
|
|
{isDarkMode ? t('settings.theme.dark') : t('settings.theme.light')}
|
|
</span>
|
|
</button>
|
|
</div>
|
|
|
|
<div className={styles.settingItem}>
|
|
<div className={styles.settingInfo}>
|
|
<span className={styles.settingLabel}>{t('settings.language')}</span>
|
|
<span className={styles.settingDescription}>
|
|
{t('settings.language.description')}
|
|
</span>
|
|
</div>
|
|
|
|
<select
|
|
className={styles.languageSelect}
|
|
value={currentLanguage}
|
|
onChange={(e) => handleLanguageChange(e.target.value as Language)}
|
|
aria-label={t('settings.language')}
|
|
>
|
|
<option value="de">{getLanguageLabel('de')}</option>
|
|
<option value="en">{getLanguageLabel('en')}</option>
|
|
<option value="fr">{getLanguageLabel('fr')}</option>
|
|
</select>
|
|
</div>
|
|
</div>
|
|
|
|
<div className={styles.settingsSection}>
|
|
<h2 className={styles.sectionTitle}>{t('settings.about')}</h2>
|
|
<div className={styles.settingItem}>
|
|
<div className={styles.settingInfo}>
|
|
<span className={styles.settingLabel}>{t('settings.version')}</span>
|
|
<span className={styles.settingDescription}>1.0.0</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
);
|
|
}
|
|
|
|
export default Einstellungen; |