import React, { Component } from 'react'; import { Box, Paper, Typography, TextField, Button, Alert, CircularProgress, Divider, IconButton, Snackbar } from '@mui/material'; import ContentCopy from '@mui/icons-material/ContentCopy'; import { withI18n } from '../../i18n/withTranslation.js'; class SettingsTab extends Component { constructor(props) { super(props); this.state = { currentPassword: '', newPassword: '', confirmPassword: '', password: '', newEmail: '', passwordError: '', passwordSuccess: '', emailError: '', emailSuccess: '', loading: false, // API Key management state hasApiKey: false, apiKey: '', apiKeyDisplay: '', apiKeyError: '', apiKeySuccess: '', loadingApiKey: false, copySnackbarOpen: false }; } componentDidMount() { // Load user data const storedUser = sessionStorage.getItem('user'); if (storedUser) { try { const user = JSON.parse(storedUser); this.setState({ newEmail: user.email || '' }); // Check if user has an API key this.props.socket.emit('isApiKey', (response) => { if (response.success && response.hasApiKey) { this.setState({ hasApiKey: true, apiKeyDisplay: '************' }); } }); } catch (error) { console.error('Error loading user data:', error); } } } handleUpdatePassword = (e) => { e.preventDefault(); // Reset states this.setState({ passwordError: '', passwordSuccess: '' }); // Validation if (!this.state.currentPassword || !this.state.newPassword || !this.state.confirmPassword) { this.setState({ passwordError: this.props.t ? this.props.t('settings.errors.fillAllFields') : 'Bitte füllen Sie alle Felder aus' }); return; } if (this.state.newPassword !== this.state.confirmPassword) { this.setState({ passwordError: this.props.t ? this.props.t('settings.errors.passwordsNotMatch') : 'Die neuen Passwörter stimmen nicht überein' }); return; } if (this.state.newPassword.length < 8) { this.setState({ passwordError: this.props.t ? this.props.t('settings.errors.passwordTooShort') : 'Das neue Passwort muss mindestens 8 Zeichen lang sein' }); return; } this.setState({ loading: true }); // Call socket.io endpoint to update password this.props.socket.emit('updatePassword', { oldPassword: this.state.currentPassword, newPassword: this.state.newPassword }, (response) => { this.setState({ loading: false }); if (response.success) { this.setState({ passwordSuccess: this.props.t ? this.props.t('settings.success.passwordUpdated') : 'Passwort erfolgreich aktualisiert', currentPassword: '', newPassword: '', confirmPassword: '' }); } else { this.setState({ passwordError: response.message || (this.props.t ? this.props.t('settings.errors.passwordUpdateError') : 'Fehler beim Aktualisieren des Passworts') }); } } ); }; handleUpdateEmail = (e) => { e.preventDefault(); // Reset states this.setState({ emailError: '', emailSuccess: '' }); // Validation if (!this.state.password || !this.state.newEmail) { this.setState({ emailError: this.props.t ? this.props.t('settings.errors.fillAllFields') : 'Bitte füllen Sie alle Felder aus' }); return; } if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(this.state.newEmail)) { this.setState({ emailError: this.props.t ? this.props.t('settings.errors.invalidEmail') : 'Bitte geben Sie eine gültige E-Mail-Adresse ein' }); return; } this.setState({ loading: true }); // Call socket.io endpoint to update email this.props.socket.emit('updateEmail', { password: this.state.password, email: this.state.newEmail }, (response) => { this.setState({ loading: false }); if (response.success) { this.setState({ emailSuccess: this.props.t ? this.props.t('settings.success.emailUpdated') : 'E-Mail-Adresse erfolgreich aktualisiert', password: '' }); // Update user in sessionStorage try { const storedUser = sessionStorage.getItem('user'); if (storedUser) { const user = JSON.parse(storedUser); user.email = this.state.newEmail; sessionStorage.setItem('user', JSON.stringify(user)); } } catch (error) { console.error('Error updating user in sessionStorage:', error); } } else { this.setState({ emailError: response.message || (this.props.t ? this.props.t('settings.errors.emailUpdateError') : 'Fehler beim Aktualisieren der E-Mail-Adresse') }); } } ); }; handleGenerateApiKey = () => { this.setState({ apiKeyError: '', apiKeySuccess: '', loadingApiKey: true }); const storedUser = sessionStorage.getItem('user'); if (!storedUser) { this.setState({ apiKeyError: 'Benutzer nicht gefunden', loadingApiKey: false }); return; } try { const user = JSON.parse(storedUser); this.props.socket.emit('createApiKey', user.id, (response) => { this.setState({ loadingApiKey: false }); if (response.success) { this.setState({ hasApiKey: true, apiKey: response.apiKey, apiKeyDisplay: response.apiKey, apiKeySuccess: response.message || 'API-Schlüssel erfolgreich generiert' }); // After 10 seconds, hide the actual key and show asterisks setTimeout(() => { this.setState({ apiKeyDisplay: '************' }); }, 10000); } else { this.setState({ apiKeyError: response.message || 'Fehler beim Generieren des API-Schlüssels' }); } }); } catch (error) { console.error('Error generating API key:', error); this.setState({ apiKeyError: 'Fehler beim Generieren des API-Schlüssels', loadingApiKey: false }); } }; handleCopyToClipboard = () => { navigator.clipboard.writeText(this.state.apiKey).then(() => { this.setState({ copySnackbarOpen: true }); }).catch(err => { console.error('Failed to copy to clipboard:', err); // Fallback for older browsers const textArea = document.createElement('textarea'); textArea.value = this.state.apiKey; document.body.appendChild(textArea); textArea.select(); document.execCommand('copy'); document.body.removeChild(textArea); this.setState({ copySnackbarOpen: true }); }); }; handleCloseSnackbar = () => { this.setState({ copySnackbarOpen: false }); }; render() { return ( {this.props.t ? this.props.t('settings.changePassword') : 'Passwort ändern'} {this.state.passwordError && {this.state.passwordError}} {this.state.passwordSuccess && {this.state.passwordSuccess}} this.setState({ currentPassword: e.target.value })} disabled={this.state.loading} /> this.setState({ newPassword: e.target.value })} disabled={this.state.loading} /> this.setState({ confirmPassword: e.target.value })} disabled={this.state.loading} /> {this.props.t ? this.props.t('settings.changeEmail') : 'E-Mail-Adresse ändern'} {this.state.emailError && {this.state.emailError}} {this.state.emailSuccess && {this.state.emailSuccess}} this.setState({ password: e.target.value })} disabled={this.state.loading} /> this.setState({ newEmail: e.target.value })} disabled={this.state.loading} /> {this.props.t ? this.props.t('settings.apiKey') : 'API-Schlüssel'} {this.props.t ? this.props.t('settings.apiKeyDescription') : 'Verwenden Sie Ihren API-Schlüssel für die Integration mit externen Anwendungen.'} {this.state.apiKeyError && {this.state.apiKeyError}} {this.state.apiKeySuccess && ( {this.state.apiKeySuccess} {this.state.apiKey && this.state.apiKeyDisplay !== '************' && ( {this.props.t ? this.props.t('settings.success.apiKeyWarning') : 'Speichern Sie diesen Schlüssel sicher. Er wird aus Sicherheitsgründen in 10 Sekunden ausgeblendet.'} )} )} {this.props.t ? this.props.t('settings.apiDocumentation') : 'API-Dokumentation:'} {' '} {`${window.location.protocol}//${window.location.host}/api/`} {this.state.apiKeyDisplay !== '************' && this.state.apiKey && ( )} ); } } export default withI18n()(SettingsTab);