mirror of
https://github.com/donpat1to/Schichtenplaner.git
synced 2025-12-01 06:55:45 +01:00
reworked scheduling
This commit is contained in:
@@ -5,6 +5,7 @@ import { employeeService } from '../../services/employeeService';
|
||||
import { useNotification } from '../../contexts/NotificationContext';
|
||||
import AvailabilityManager from '../Employees/components/AvailabilityManager';
|
||||
import { Employee } from '../../models/Employee';
|
||||
import { styles } from './type/SettingsType';
|
||||
|
||||
const Settings: React.FC = () => {
|
||||
const { user: currentUser, updateUser } = useAuth();
|
||||
@@ -148,7 +149,12 @@ const Settings: React.FC = () => {
|
||||
};
|
||||
|
||||
if (!currentUser) {
|
||||
return <div>Nicht eingeloggt</div>;
|
||||
return <div style={{
|
||||
textAlign: 'center',
|
||||
padding: '3rem',
|
||||
color: '#666',
|
||||
fontSize: '1.1rem'
|
||||
}}>Nicht eingeloggt</div>;
|
||||
}
|
||||
|
||||
if (showAvailabilityManager) {
|
||||
@@ -161,395 +167,390 @@ const Settings: React.FC = () => {
|
||||
);
|
||||
}
|
||||
|
||||
// Style constants for consistency
|
||||
|
||||
|
||||
return (
|
||||
<div style={{ padding: '20px', maxWidth: '800px', margin: '0 auto' }}>
|
||||
<h1>⚙️ Einstellungen</h1>
|
||||
|
||||
{/* Tab Navigation */}
|
||||
<div style={{
|
||||
display: 'flex',
|
||||
borderBottom: '1px solid #e0e0e0',
|
||||
marginBottom: '30px'
|
||||
}}>
|
||||
<button
|
||||
onClick={() => setActiveTab('profile')}
|
||||
style={{
|
||||
padding: '12px 24px',
|
||||
backgroundColor: activeTab === 'profile' ? '#3498db' : 'transparent',
|
||||
color: activeTab === 'profile' ? 'white' : '#333',
|
||||
border: 'none',
|
||||
borderBottom: activeTab === 'profile' ? '3px solid #3498db' : 'none',
|
||||
cursor: 'pointer',
|
||||
fontWeight: 'bold'
|
||||
}}
|
||||
>
|
||||
👤 Profil
|
||||
</button>
|
||||
<button
|
||||
onClick={() => setActiveTab('password')}
|
||||
style={{
|
||||
padding: '12px 24px',
|
||||
backgroundColor: activeTab === 'password' ? '#3498db' : 'transparent',
|
||||
color: activeTab === 'password' ? 'white' : '#333',
|
||||
border: 'none',
|
||||
borderBottom: activeTab === 'password' ? '3px solid #3498db' : 'none',
|
||||
cursor: 'pointer',
|
||||
fontWeight: 'bold'
|
||||
}}
|
||||
>
|
||||
🔒 Passwort
|
||||
</button>
|
||||
<button
|
||||
onClick={() => setActiveTab('availability')}
|
||||
style={{
|
||||
padding: '12px 24px',
|
||||
backgroundColor: activeTab === 'availability' ? '#3498db' : 'transparent',
|
||||
color: activeTab === 'availability' ? 'white' : '#333',
|
||||
border: 'none',
|
||||
borderBottom: activeTab === 'availability' ? '3px solid #3498db' : 'none',
|
||||
cursor: 'pointer',
|
||||
fontWeight: 'bold'
|
||||
}}
|
||||
>
|
||||
📅 Verfügbarkeit
|
||||
</button>
|
||||
<div style={styles.container}>
|
||||
{/* Left Sidebar with Tabs */}
|
||||
<div style={styles.sidebar}>
|
||||
<div style={styles.header}>
|
||||
<h1 style={styles.title}>Einstellungen</h1>
|
||||
<div style={styles.subtitle}>Verwalten Sie Ihre Kontoeinstellungen und Präferenzen</div>
|
||||
</div>
|
||||
|
||||
<div style={styles.tabs}>
|
||||
<button
|
||||
onClick={() => setActiveTab('profile')}
|
||||
style={{
|
||||
...styles.tab,
|
||||
...(activeTab === 'profile' ? styles.tabActive : {})
|
||||
}}
|
||||
onMouseEnter={(e) => {
|
||||
if (activeTab !== 'profile') {
|
||||
e.currentTarget.style.background = styles.tabHover.background;
|
||||
e.currentTarget.style.color = styles.tabHover.color;
|
||||
e.currentTarget.style.transform = styles.tabHover.transform;
|
||||
}
|
||||
}}
|
||||
onMouseLeave={(e) => {
|
||||
if (activeTab !== 'profile') {
|
||||
e.currentTarget.style.background = styles.tab.background;
|
||||
e.currentTarget.style.color = styles.tab.color;
|
||||
e.currentTarget.style.transform = 'none';
|
||||
}
|
||||
}}
|
||||
>
|
||||
<span style={{ color: '#cda8f0', fontSize: '24px' }}>{'\u{1F464}\u{FE0E}'}</span>
|
||||
<div style={{ display: 'flex', flexDirection: 'column', alignItems: 'flex-start' }}>
|
||||
<span style={{ fontSize: '0.95rem', fontWeight: 500 }}>Profil</span>
|
||||
<span style={{ fontSize: '0.8rem', opacity: 0.7, marginTop: '2px' }}>Persönliche Informationen</span>
|
||||
</div>
|
||||
</button>
|
||||
|
||||
<button
|
||||
onClick={() => setActiveTab('password')}
|
||||
style={{
|
||||
...styles.tab,
|
||||
...(activeTab === 'password' ? styles.tabActive : {})
|
||||
}}
|
||||
onMouseEnter={(e) => {
|
||||
if (activeTab !== 'password') {
|
||||
e.currentTarget.style.background = styles.tabHover.background;
|
||||
e.currentTarget.style.color = styles.tabHover.color;
|
||||
e.currentTarget.style.transform = styles.tabHover.transform;
|
||||
}
|
||||
}}
|
||||
onMouseLeave={(e) => {
|
||||
if (activeTab !== 'password') {
|
||||
e.currentTarget.style.background = styles.tab.background;
|
||||
e.currentTarget.style.color = styles.tab.color;
|
||||
e.currentTarget.style.transform = 'none';
|
||||
}
|
||||
}}
|
||||
>
|
||||
<span style={{ fontSize: '1.2rem', width: '24px' }}>🔒</span>
|
||||
<div style={{ display: 'flex', flexDirection: 'column', alignItems: 'flex-start' }}>
|
||||
<span style={{ fontSize: '0.95rem', fontWeight: 500 }}>Passwort</span>
|
||||
<span style={{ fontSize: '0.8rem', opacity: 0.7, marginTop: '2px' }}>Sicherheitseinstellungen</span>
|
||||
</div>
|
||||
</button>
|
||||
|
||||
<button
|
||||
onClick={() => setActiveTab('availability')}
|
||||
style={{
|
||||
...styles.tab,
|
||||
...(activeTab === 'availability' ? styles.tabActive : {})
|
||||
}}
|
||||
onMouseEnter={(e) => {
|
||||
if (activeTab !== 'availability') {
|
||||
e.currentTarget.style.background = styles.tabHover.background;
|
||||
e.currentTarget.style.color = styles.tabHover.color;
|
||||
e.currentTarget.style.transform = styles.tabHover.transform;
|
||||
}
|
||||
}}
|
||||
onMouseLeave={(e) => {
|
||||
if (activeTab !== 'availability') {
|
||||
e.currentTarget.style.background = styles.tab.background;
|
||||
e.currentTarget.style.color = styles.tab.color;
|
||||
e.currentTarget.style.transform = 'none';
|
||||
}
|
||||
}}
|
||||
>
|
||||
<span style={{ fontSize: '1.2rem', width: '24px' }}>📅</span>
|
||||
<div style={{ display: 'flex', flexDirection: 'column', alignItems: 'flex-start' }}>
|
||||
<span style={{ fontSize: '0.95rem', fontWeight: 500 }}>Verfügbarkeit</span>
|
||||
<span style={{ fontSize: '0.8rem', opacity: 0.7, marginTop: '2px' }}>Schichtplanung</span>
|
||||
</div>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Profile Tab */}
|
||||
{activeTab === 'profile' && (
|
||||
<div style={{
|
||||
backgroundColor: 'white',
|
||||
padding: '30px',
|
||||
borderRadius: '8px',
|
||||
border: '1px solid #e0e0e0',
|
||||
boxShadow: '0 2px 4px rgba(0,0,0,0.1)'
|
||||
}}>
|
||||
<h2 style={{ marginTop: 0, color: '#2c3e50' }}>Profilinformationen</h2>
|
||||
|
||||
<form onSubmit={handleProfileUpdate}>
|
||||
<div style={{ display: 'grid', gap: '20px' }}>
|
||||
{/* Read-only information */}
|
||||
<div style={{
|
||||
padding: '15px',
|
||||
backgroundColor: '#f8f9fa',
|
||||
borderRadius: '6px',
|
||||
border: '1px solid #e9ecef'
|
||||
}}>
|
||||
<h4 style={{ margin: '0 0 15px 0', color: '#495057' }}>Systeminformationen</h4>
|
||||
<div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: '15px' }}>
|
||||
<div>
|
||||
<label style={{ display: 'block', marginBottom: '5px', fontWeight: 'bold', color: '#2c3e50' }}>
|
||||
E-Mail
|
||||
</label>
|
||||
<input
|
||||
type="email"
|
||||
value={currentUser.email}
|
||||
disabled
|
||||
style={{
|
||||
width: '95%',
|
||||
padding: '10px',
|
||||
border: '1px solid #ddd',
|
||||
borderRadius: '4px',
|
||||
backgroundColor: '#f8f9fa',
|
||||
color: '#666'
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<label style={{ display: 'block', marginBottom: '5px', fontWeight: 'bold', color: '#2c3e50' }}>
|
||||
Rolle
|
||||
</label>
|
||||
<input
|
||||
type="text"
|
||||
value={currentUser.role}
|
||||
disabled
|
||||
style={{
|
||||
width: '95%',
|
||||
padding: '10px',
|
||||
border: '1px solid #ddd',
|
||||
borderRadius: '4px',
|
||||
backgroundColor: '#f8f9fa',
|
||||
color: '#666'
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: '15px', marginTop: '15px' }}>
|
||||
<div>
|
||||
<label style={{ display: 'block', marginBottom: '5px', fontWeight: 'bold', color: '#2c3e50' }}>
|
||||
Mitarbeiter Typ
|
||||
</label>
|
||||
<input
|
||||
type="text"
|
||||
value={currentUser.employeeType}
|
||||
disabled
|
||||
style={{
|
||||
width: '95%',
|
||||
padding: '10px',
|
||||
border: '1px solid #ddd',
|
||||
borderRadius: '4px',
|
||||
backgroundColor: '#f8f9fa',
|
||||
color: '#666'
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<label style={{ display: 'block', marginBottom: '5px', fontWeight: 'bold', color: '#2c3e50' }}>
|
||||
Vertragstyp
|
||||
</label>
|
||||
<input
|
||||
type="text"
|
||||
value={currentUser.contractType}
|
||||
disabled
|
||||
style={{
|
||||
width: '95%',
|
||||
padding: '10px',
|
||||
border: '1px solid #ddd',
|
||||
borderRadius: '4px',
|
||||
backgroundColor: '#f8f9fa',
|
||||
color: '#666'
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{/* Right Content Area */}
|
||||
<div style={styles.content}>
|
||||
{/* Profile Tab */}
|
||||
{activeTab === 'profile' && (
|
||||
<>
|
||||
<div style={styles.section}>
|
||||
<h2 style={styles.sectionTitle}>Profilinformationen</h2>
|
||||
<p style={styles.sectionDescription}>
|
||||
Verwalten Sie Ihre persönlichen Informationen und Kontaktdaten
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div
|
||||
style={{
|
||||
marginTop: '10px',
|
||||
padding: '15px',
|
||||
backgroundColor: '#f8f9fa',
|
||||
borderRadius: '6px',
|
||||
border: '1px solid #e9ecef',
|
||||
}}
|
||||
>
|
||||
<label
|
||||
style={{
|
||||
display: 'block',
|
||||
marginBottom: '8px',
|
||||
fontWeight: 'bold',
|
||||
color: '#2c3e50',
|
||||
}}
|
||||
>
|
||||
Vollständiger Name *
|
||||
</label>
|
||||
<input
|
||||
type="text"
|
||||
name="name"
|
||||
value={profileForm.name}
|
||||
onChange={handleProfileChange}
|
||||
required
|
||||
style={{
|
||||
width: '97.5%',
|
||||
padding: '10px',
|
||||
border: '1px solid #ddd',
|
||||
borderRadius: '4px',
|
||||
fontSize: '16px',
|
||||
}}
|
||||
placeholder="Ihr vollständiger Name"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div style={{
|
||||
display: 'flex',
|
||||
gap: '15px',
|
||||
justifyContent: 'flex-end',
|
||||
marginTop: '30px',
|
||||
paddingTop: '20px',
|
||||
borderTop: '1px solid #f0f0f0'
|
||||
}}>
|
||||
<button
|
||||
type="submit"
|
||||
disabled={loading || !profileForm.name.trim()}
|
||||
style={{
|
||||
padding: '12px 24px',
|
||||
backgroundColor: loading ? '#bdc3c7' : (!profileForm.name.trim() ? '#95a5a6' : '#27ae60'),
|
||||
color: 'white',
|
||||
border: 'none',
|
||||
borderRadius: '6px',
|
||||
cursor: (loading || !profileForm.name.trim()) ? 'not-allowed' : 'pointer',
|
||||
fontWeight: 'bold'
|
||||
}}
|
||||
>
|
||||
{loading ? '⏳ Wird gespeichert...' : 'Profil aktualisieren'}
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* Password Tab */}
|
||||
{activeTab === 'password' && (
|
||||
<div style={{
|
||||
backgroundColor: 'white',
|
||||
padding: '30px',
|
||||
borderRadius: '8px',
|
||||
border: '1px solid #e0e0e0',
|
||||
boxShadow: '0 2px 4px rgba(0,0,0,0.1)'
|
||||
}}>
|
||||
<h2 style={{ marginTop: 0, color: '#2c3e50' }}>Passwort ändern</h2>
|
||||
|
||||
<form onSubmit={handlePasswordUpdate}>
|
||||
<div style={{ display: 'grid', gap: '20px', maxWidth: '400px' }}>
|
||||
<div>
|
||||
<label style={{ display: 'block', marginBottom: '8px', fontWeight: 'bold', color: '#2c3e50' }}>
|
||||
Aktuelles Passwort *
|
||||
</label>
|
||||
<input
|
||||
type="password"
|
||||
name="currentPassword"
|
||||
value={passwordForm.currentPassword}
|
||||
onChange={handlePasswordChange}
|
||||
required
|
||||
style={{
|
||||
width: '100%',
|
||||
padding: '10px',
|
||||
border: '1px solid #ddd',
|
||||
borderRadius: '4px',
|
||||
fontSize: '16px'
|
||||
}}
|
||||
placeholder="Aktuelles Passwort"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label style={{ display: 'block', marginBottom: '8px', fontWeight: 'bold', color: '#2c3e50' }}>
|
||||
Neues Passwort *
|
||||
</label>
|
||||
<input
|
||||
type="password"
|
||||
name="newPassword"
|
||||
value={passwordForm.newPassword}
|
||||
onChange={handlePasswordChange}
|
||||
required
|
||||
minLength={6}
|
||||
style={{
|
||||
width: '100%',
|
||||
padding: '10px',
|
||||
border: '1px solid #ddd',
|
||||
borderRadius: '4px',
|
||||
fontSize: '16px'
|
||||
}}
|
||||
placeholder="Mindestens 6 Zeichen"
|
||||
/>
|
||||
<div style={{ fontSize: '12px', color: '#7f8c8d', marginTop: '5px' }}>
|
||||
Das Passwort muss mindestens 6 Zeichen lang sein.
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label style={{ display: 'block', marginBottom: '8px', fontWeight: 'bold', color: '#2c3e50' }}>
|
||||
Neues Passwort bestätigen *
|
||||
</label>
|
||||
<input
|
||||
type="password"
|
||||
name="confirmPassword"
|
||||
value={passwordForm.confirmPassword}
|
||||
onChange={handlePasswordChange}
|
||||
required
|
||||
style={{
|
||||
width: '100%',
|
||||
padding: '10px',
|
||||
border: '1px solid #ddd',
|
||||
borderRadius: '4px',
|
||||
fontSize: '16px'
|
||||
}}
|
||||
placeholder="Passwort wiederholen"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div style={{
|
||||
display: 'flex',
|
||||
gap: '15px',
|
||||
justifyContent: 'flex-end',
|
||||
marginTop: '30px',
|
||||
paddingTop: '20px',
|
||||
borderTop: '1px solid #f0f0f0'
|
||||
}}>
|
||||
<button
|
||||
type="submit"
|
||||
disabled={loading || !passwordForm.currentPassword || !passwordForm.newPassword || !passwordForm.confirmPassword}
|
||||
style={{
|
||||
padding: '12px 24px',
|
||||
backgroundColor: loading ? '#bdc3c7' : (!passwordForm.currentPassword || !passwordForm.newPassword || !passwordForm.confirmPassword ? '#95a5a6' : '#3498db'),
|
||||
color: 'white',
|
||||
border: 'none',
|
||||
borderRadius: '6px',
|
||||
cursor: (loading || !passwordForm.currentPassword || !passwordForm.newPassword || !passwordForm.confirmPassword) ? 'not-allowed' : 'pointer',
|
||||
fontWeight: 'bold'
|
||||
}}
|
||||
>
|
||||
{loading ? '⏳ Wird geändert...' : 'Passwort ändern'}
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* Availability Tab */}
|
||||
{activeTab === 'availability' && (
|
||||
<div style={{
|
||||
backgroundColor: 'white',
|
||||
padding: '30px',
|
||||
borderRadius: '8px',
|
||||
border: '1px solid #e0e0e0',
|
||||
boxShadow: '0 2px 4px rgba(0,0,0,0.1)'
|
||||
}}>
|
||||
<h2 style={{ marginTop: 0, color: '#2c3e50' }}>Meine Verfügbarkeit</h2>
|
||||
|
||||
<div style={{
|
||||
padding: '30px',
|
||||
textAlign: 'center',
|
||||
backgroundColor: '#f8f9fa',
|
||||
borderRadius: '8px',
|
||||
border: '2px dashed #dee2e6'
|
||||
}}>
|
||||
<div style={{ fontSize: '48px', marginBottom: '20px' }}>📅</div>
|
||||
<h3 style={{ color: '#2c3e50' }}>Verfügbarkeit verwalten</h3>
|
||||
<p style={{ color: '#6c757d', marginBottom: '25px' }}>
|
||||
Hier können Sie Ihre persönliche Verfügbarkeit für Schichtpläne festlegen.
|
||||
Legen Sie für jeden Tag und jede Schicht fest, ob Sie bevorzugt, möglicherweise
|
||||
oder nicht verfügbar sind.
|
||||
</p>
|
||||
|
||||
<button
|
||||
onClick={() => setShowAvailabilityManager(true)}
|
||||
style={{
|
||||
padding: '12px 24px',
|
||||
backgroundColor: '#3498db',
|
||||
color: 'white',
|
||||
border: 'none',
|
||||
borderRadius: '6px',
|
||||
cursor: 'pointer',
|
||||
fontWeight: 'bold',
|
||||
fontSize: '16px'
|
||||
}}
|
||||
>
|
||||
Verfügbarkeit bearbeiten
|
||||
</button>
|
||||
<form onSubmit={handleProfileUpdate} style={{ marginTop: '2rem' }}>
|
||||
<div style={styles.formGrid}>
|
||||
{/* Read-only information */}
|
||||
<div style={styles.infoCard}>
|
||||
<h4 style={styles.infoCardTitle}>Systeminformationen</h4>
|
||||
<div style={styles.infoGrid}>
|
||||
<div style={styles.field}>
|
||||
<label style={styles.fieldLabel}>
|
||||
E-Mail
|
||||
</label>
|
||||
<input
|
||||
type="email"
|
||||
value={currentUser.email}
|
||||
disabled
|
||||
style={styles.fieldInputDisabled}
|
||||
/>
|
||||
</div>
|
||||
<div style={styles.field}>
|
||||
<label style={styles.fieldLabel}>
|
||||
Rolle
|
||||
</label>
|
||||
<input
|
||||
type="text"
|
||||
value={currentUser.role}
|
||||
disabled
|
||||
style={styles.fieldInputDisabled}
|
||||
/>
|
||||
</div>
|
||||
<div style={styles.field}>
|
||||
<label style={styles.fieldLabel}>
|
||||
Mitarbeiter Typ
|
||||
</label>
|
||||
<input
|
||||
type="text"
|
||||
value={currentUser.employeeType}
|
||||
disabled
|
||||
style={styles.fieldInputDisabled}
|
||||
/>
|
||||
</div>
|
||||
<div style={styles.field}>
|
||||
<label style={styles.fieldLabel}>
|
||||
Vertragstyp
|
||||
</label>
|
||||
<input
|
||||
type="text"
|
||||
value={currentUser.contractType}
|
||||
disabled
|
||||
style={styles.fieldInputDisabled}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div style={styles.infoCard}>
|
||||
{/* Editable name field */}
|
||||
<div style={{ ...styles.field, marginTop: '1rem' }}>
|
||||
<label style={styles.fieldLabel}>
|
||||
Vollständiger Name *
|
||||
</label>
|
||||
<input
|
||||
type="text"
|
||||
name="name"
|
||||
value={profileForm.name}
|
||||
onChange={handleProfileChange}
|
||||
required
|
||||
style={{
|
||||
...styles.fieldInput,
|
||||
width: '95%'
|
||||
}}
|
||||
placeholder="Ihr vollständiger Name"
|
||||
onFocus={(e) => {
|
||||
e.target.style.borderColor = '#1a1325';
|
||||
e.target.style.boxShadow = '0 0 0 3px rgba(26, 19, 37, 0.1)';
|
||||
}}
|
||||
onBlur={(e) => {
|
||||
e.target.style.borderColor = '#e8e8e8';
|
||||
e.target.style.boxShadow = 'none';
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div style={{
|
||||
marginTop: '20px',
|
||||
padding: '15px',
|
||||
backgroundColor: '#e8f4fd',
|
||||
border: '1px solid #b6d7e8',
|
||||
borderRadius: '6px',
|
||||
fontSize: '14px',
|
||||
color: '#2c3e50',
|
||||
textAlign: 'left'
|
||||
}}>
|
||||
<strong>💡 Informationen:</strong>
|
||||
<ul style={{ margin: '8px 0 0 20px', padding: 0 }}>
|
||||
<li><strong>Bevorzugt:</strong> Sie möchten diese Schicht arbeiten</li>
|
||||
<li><strong>Möglich:</strong> Sie können diese Schicht arbeiten</li>
|
||||
<li><strong>Nicht möglich:</strong> Sie können diese Schicht nicht arbeiten</li>
|
||||
</ul>
|
||||
<div style={styles.actions}>
|
||||
<button
|
||||
type="submit"
|
||||
disabled={loading || !profileForm.name.trim()}
|
||||
style={{
|
||||
...styles.button,
|
||||
...styles.buttonPrimary,
|
||||
...((loading || !profileForm.name.trim()) ? styles.buttonDisabled : {})
|
||||
}}
|
||||
onMouseEnter={(e) => {
|
||||
if (!loading && profileForm.name.trim()) {
|
||||
e.currentTarget.style.background = styles.buttonPrimaryHover.background;
|
||||
e.currentTarget.style.transform = styles.buttonPrimaryHover.transform;
|
||||
e.currentTarget.style.boxShadow = styles.buttonPrimaryHover.boxShadow;
|
||||
}
|
||||
}}
|
||||
onMouseLeave={(e) => {
|
||||
if (!loading && profileForm.name.trim()) {
|
||||
e.currentTarget.style.background = styles.buttonPrimary.background;
|
||||
e.currentTarget.style.transform = 'none';
|
||||
e.currentTarget.style.boxShadow = styles.buttonPrimary.boxShadow;
|
||||
}
|
||||
}}
|
||||
>
|
||||
{loading ? '⏳ Wird gespeichert...' : 'Profil aktualisieren'}
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</>
|
||||
)}
|
||||
|
||||
{/* Password Tab */}
|
||||
{activeTab === 'password' && (
|
||||
<>
|
||||
<div style={styles.section}>
|
||||
<h2 style={styles.sectionTitle}>Passwort ändern</h2>
|
||||
<p style={styles.sectionDescription}>
|
||||
Aktualisieren Sie Ihr Passwort für erhöhte Sicherheit
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
<form onSubmit={handlePasswordUpdate} style={{ marginTop: '2rem' }}>
|
||||
<div style={styles.formGridCompact}>
|
||||
<div style={styles.field}>
|
||||
<label style={styles.fieldLabel}>
|
||||
Aktuelles Passwort *
|
||||
</label>
|
||||
<input
|
||||
type="password"
|
||||
name="currentPassword"
|
||||
value={passwordForm.currentPassword}
|
||||
onChange={handlePasswordChange}
|
||||
required
|
||||
style={styles.fieldInput}
|
||||
placeholder="Aktuelles Passwort"
|
||||
onFocus={(e) => {
|
||||
e.target.style.borderColor = '#1a1325';
|
||||
e.target.style.boxShadow = '0 0 0 3px rgba(26, 19, 37, 0.1)';
|
||||
}}
|
||||
onBlur={(e) => {
|
||||
e.target.style.borderColor = '#e8e8e8';
|
||||
e.target.style.boxShadow = 'none';
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div style={styles.field}>
|
||||
<label style={styles.fieldLabel}>
|
||||
Neues Passwort *
|
||||
</label>
|
||||
<input
|
||||
type="password"
|
||||
name="newPassword"
|
||||
value={passwordForm.newPassword}
|
||||
onChange={handlePasswordChange}
|
||||
required
|
||||
minLength={6}
|
||||
style={styles.fieldInput}
|
||||
placeholder="Mindestens 6 Zeichen"
|
||||
onFocus={(e) => {
|
||||
e.target.style.borderColor = '#1a1325';
|
||||
e.target.style.boxShadow = '0 0 0 3px rgba(26, 19, 37, 0.1)';
|
||||
}}
|
||||
onBlur={(e) => {
|
||||
e.target.style.borderColor = '#e8e8e8';
|
||||
e.target.style.boxShadow = 'none';
|
||||
}}
|
||||
/>
|
||||
<div style={styles.fieldHint}>
|
||||
Das Passwort muss mindestens 6 Zeichen lang sein.
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div style={styles.field}>
|
||||
<label style={styles.fieldLabel}>
|
||||
Neues Passwort bestätigen *
|
||||
</label>
|
||||
<input
|
||||
type="password"
|
||||
name="confirmPassword"
|
||||
value={passwordForm.confirmPassword}
|
||||
onChange={handlePasswordChange}
|
||||
required
|
||||
style={styles.fieldInput}
|
||||
placeholder="Passwort wiederholen"
|
||||
onFocus={(e) => {
|
||||
e.target.style.borderColor = '#1a1325';
|
||||
e.target.style.boxShadow = '0 0 0 3px rgba(26, 19, 37, 0.1)';
|
||||
}}
|
||||
onBlur={(e) => {
|
||||
e.target.style.borderColor = '#e8e8e8';
|
||||
e.target.style.boxShadow = 'none';
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div style={styles.actions}>
|
||||
<button
|
||||
type="submit"
|
||||
disabled={loading || !passwordForm.currentPassword || !passwordForm.newPassword || !passwordForm.confirmPassword}
|
||||
style={{
|
||||
...styles.button,
|
||||
...styles.buttonPrimary,
|
||||
...((loading || !passwordForm.currentPassword || !passwordForm.newPassword || !passwordForm.confirmPassword) ? styles.buttonDisabled : {})
|
||||
}}
|
||||
onMouseEnter={(e) => {
|
||||
if (!loading && passwordForm.currentPassword && passwordForm.newPassword && passwordForm.confirmPassword) {
|
||||
e.currentTarget.style.background = styles.buttonPrimaryHover.background;
|
||||
e.currentTarget.style.transform = styles.buttonPrimaryHover.transform;
|
||||
e.currentTarget.style.boxShadow = styles.buttonPrimaryHover.boxShadow;
|
||||
}
|
||||
}}
|
||||
onMouseLeave={(e) => {
|
||||
if (!loading && passwordForm.currentPassword && passwordForm.newPassword && passwordForm.confirmPassword) {
|
||||
e.currentTarget.style.background = styles.buttonPrimary.background;
|
||||
e.currentTarget.style.transform = 'none';
|
||||
e.currentTarget.style.boxShadow = styles.buttonPrimary.boxShadow;
|
||||
}
|
||||
}}
|
||||
>
|
||||
{loading ? '⏳ Wird geändert...' : 'Passwort ändern'}
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</>
|
||||
)}
|
||||
|
||||
{/* Availability Tab */}
|
||||
{activeTab === 'availability' && (
|
||||
<>
|
||||
<div style={styles.section}>
|
||||
<h2 style={styles.sectionTitle}>Meine Verfügbarkeit</h2>
|
||||
<p style={styles.sectionDescription}>
|
||||
Legen Sie Ihre persönliche Verfügbarkeit für Schichtpläne fest
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div style={styles.availabilityCard}>
|
||||
<div style={styles.availabilityIcon}>📅</div>
|
||||
<h3 style={styles.availabilityTitle}>Verfügbarkeit verwalten</h3>
|
||||
<p style={styles.availabilityDescription}>
|
||||
Hier können Sie Ihre persönliche Verfügbarkeit für Schichtpläne festlegen.
|
||||
Legen Sie für jeden Tag und jede Schicht fest, ob Sie bevorzugt, möglicherweise
|
||||
oder nicht verfügbar sind.
|
||||
</p>
|
||||
|
||||
<button
|
||||
onClick={() => setShowAvailabilityManager(true)}
|
||||
style={{
|
||||
...styles.button,
|
||||
...styles.buttonPrimary,
|
||||
marginBottom: '2rem'
|
||||
}}
|
||||
onMouseEnter={(e) => {
|
||||
e.currentTarget.style.background = styles.buttonPrimaryHover.background;
|
||||
e.currentTarget.style.transform = styles.buttonPrimaryHover.transform;
|
||||
e.currentTarget.style.boxShadow = styles.buttonPrimaryHover.boxShadow;
|
||||
}}
|
||||
onMouseLeave={(e) => {
|
||||
e.currentTarget.style.background = styles.buttonPrimary.background;
|
||||
e.currentTarget.style.transform = 'none';
|
||||
e.currentTarget.style.boxShadow = styles.buttonPrimary.boxShadow;
|
||||
}}
|
||||
>
|
||||
Verfügbarkeit bearbeiten
|
||||
</button>
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user