frontend_nyla/src/components/Navigation/UserSection.tsx
2026-04-17 11:50:25 +02:00

196 lines
6.2 KiB
TypeScript
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**
* UserSection Component
*
* Zeigt Benutzerinformationen und Logout-Button in der Sidebar.
*/
import React, { useState } from 'react';
import { useNavigate } from 'react-router-dom';
import { useCurrentUser } from '../../hooks/useUsers';
import { NotificationBell } from '../NotificationBell';
import { _isOnboardingHidden, _showOnboarding } from '../OnboardingAssistant';
import styles from './UserSection.module.css';
import { useLanguage } from '../../providers/language/LanguageContext';
export const UserSection: React.FC = () => {
const { t } = useLanguage();
const { user, logout } = useCurrentUser();
const navigate = useNavigate();
const [isLoggingOut, setIsLoggingOut] = useState(false);
const [showMenu, setShowMenu] = useState(false);
const [showLegalModal, setShowLegalModal] = useState(false);
const [onboardingHidden, setOnboardingHidden] = useState(() => _isOnboardingHidden());
const handleLogout = async () => {
setIsLoggingOut(true);
try {
await logout();
} catch (error) {
console.error('Logout failed:', error);
setIsLoggingOut(false);
}
};
const handleSettings = () => {
navigate('/settings');
setShowMenu(false);
};
const handleBilling = () => {
navigate('/billing/transactions');
setShowMenu(false);
};
const handleLegal = () => {
setShowLegalModal(true);
setShowMenu(false);
};
const handleOnboarding = () => {
_showOnboarding();
setOnboardingHidden(false);
navigate('/', { state: { showOnboarding: Date.now() } });
setShowMenu(false);
};
if (!user) {
return null;
}
// Initialen für Avatar
const initials = (() => {
const name = user.fullName || user.username || '';
const parts = name.trim().split(/\s+/);
if (parts.length >= 2) return (parts[0][0] + parts[parts.length - 1][0]).toLocaleUpperCase();
return [...name.trim()].slice(0, 2).join('').toLocaleUpperCase() || '?';
})();
return (
<div className={styles.userSection}>
{/* Notification Bell */}
<NotificationBell className={styles.notificationBell} />
<button
className={styles.userButton}
onClick={() => { setShowMenu(!showMenu); setOnboardingHidden(_isOnboardingHidden()); }}
aria-expanded={showMenu}
>
<div className={styles.avatar}>
{initials}
</div>
<div className={styles.userInfo}>
<span className={styles.userName}>{user.fullName || user.username}</span>
<span className={styles.userEmail}>{user.email}</span>
</div>
<span className={styles.chevron}>
{showMenu ? '▲' : '▼'}
</span>
</button>
{showMenu && (
<div className={styles.menu}>
<button
className={styles.menuItem}
onClick={handleBilling}
>
<span className={styles.menuIcon}>💰</span>
{t('Guthaben')}
</button>
<button
className={styles.menuItem}
onClick={handleSettings}
>
<span className={styles.menuIcon}></span>
{t('Einstellungen')}
</button>
{onboardingHidden && (
<button
className={styles.menuItem}
onClick={handleOnboarding}
>
<span className={styles.menuIcon}>{'\uD83E\uDDED'}</span>
{t('Onboarding-Assistent')}
</button>
)}
<button
className={styles.menuItem}
onClick={handleLegal}
>
<span className={styles.menuIcon}>📜</span>
{t('Rechtliche Hinweise')}
</button>
<div className={styles.menuDivider} />
<button
className={styles.menuItem}
onClick={handleLogout}
disabled={isLoggingOut}
>
<span className={styles.menuIcon}>🚪</span>
{isLoggingOut ? t('Abmelden...') : t('Abmelden')}
</button>
</div>
)}
{/* Legal Modal */}
{showLegalModal && (
<div className={styles.modalOverlay}>
<div className={styles.modal}>
<div className={styles.modalHeader}>
<h2>{t('Legal notices')}</h2>
<button
className={styles.modalClose}
onClick={() => setShowLegalModal(false)}
>
</button>
</div>
<div className={styles.modalContent}>
<div className={styles.legalSection}>
<h3>{t('Datenverarbeitung und KI-Nutzung')}</h3>
<h4>{t('userSection.1EinwilligungZurDatenverarbeitung')}</h4>
<p>{t('By using this application')}</p>
<ul>
<li>{t('You authorize the collection and processing')}</li>
<li>{t('User data may be shared with third-party providers of')}</li>
<li>{t('This consent extends to')}</li>
</ul>
<h4>{t('userSection.2AnerkennungDerKiverarbeitungsrisiken')}</h4>
<ul>
<li>{t('AI systems may produce unexpected or inaccurate')}</li>
<li>{t('AI services can process data according to their')}</li>
<li>{t('Despite security measures, data may be vulnerable')}</li>
</ul>
<h4>{t('userSection.3Haftungsausschluss')}</h4>
<p>{t('To the fullest extent possible, you waive')}</p>
</div>
<div className={styles.legalLinks}>
<a href="/poweron-privacy.html" target="_blank" rel="noopener noreferrer">
{t('Datenschutzrichtlinie')}
</a>
<a href="/poweron-terms.html" target="_blank" rel="noopener noreferrer">
{t('Nutzungsbedingungen')}
</a>
<a href="/poweron-home.html" target="_blank" rel="noopener noreferrer">
{t('Über PowerOn')}
</a>
</div>
</div>
</div>
</div>
)}
</div>
);
};
export default UserSection;