import React, { useState, useEffect } from 'react'; import { Employee, CreateEmployeeRequest, UpdateEmployeeRequest } from '../../../models/Employee'; import { ROLE_CONFIG, EMPLOYEE_TYPE_CONFIG } from '../../../models/defaults/employeeDefaults'; import { employeeService } from '../../../services/employeeService'; import { useAuth } from '../../../contexts/AuthContext'; interface EmployeeFormProps { mode: 'create' | 'edit'; employee?: Employee; onSuccess: () => void; onCancel: () => void; } type EmployeeType = 'manager' | 'personell' | 'apprentice' | 'guest'; type ContractType = 'small' | 'large' | 'flexible'; const EmployeeForm: React.FC = ({ mode, employee, onSuccess, onCancel }) => { const [formData, setFormData] = useState({ firstname: '', lastname: '', email: '', password: '', roles: ['user'] as string[], employeeType: 'personell' as EmployeeType, contractType: 'small' as ContractType | undefined, canWorkAlone: false, isActive: true, isTrainee: false }); const [passwordForm, setPasswordForm] = useState({ newPassword: '', confirmPassword: '' }); const [showPasswordSection, setShowPasswordSection] = useState(false); const [loading, setLoading] = useState(false); const [error, setError] = useState(''); const { hasRole } = useAuth(); // Generate email preview const generateEmailPreview = (firstname: string, lastname: string): string => { const convertUmlauts = (str: string): string => { return str .toLowerCase() .replace(/ü/g, 'ue') .replace(/ö/g, 'oe') .replace(/ä/g, 'ae') .replace(/ß/g, 'ss'); }; const cleanFirstname = convertUmlauts(firstname).replace(/[^a-z0-9]/g, ''); const cleanLastname = convertUmlauts(lastname).replace(/[^a-z0-9]/g, ''); return `${cleanFirstname}.${cleanLastname}@sp.de`; }; const emailPreview = generateEmailPreview(formData.firstname, formData.lastname); useEffect(() => { if (mode === 'edit' && employee) { setFormData({ firstname: employee.firstname, lastname: employee.lastname, email: employee.email, password: '', roles: employee.roles || ['user'], employeeType: employee.employeeType, contractType: employee.contractType, canWorkAlone: employee.canWorkAlone, isActive: employee.isActive, isTrainee: employee.isTrainee || false }); } }, [mode, employee]); const handleChange = (e: React.ChangeEvent) => { const { name, value, type } = e.target; setFormData(prev => ({ ...prev, [name]: type === 'checkbox' ? (e.target as HTMLInputElement).checked : value })); }; const handlePasswordChange = (e: React.ChangeEvent) => { const { name, value } = e.target; setPasswordForm(prev => ({ ...prev, [name]: value })); }; const handleRoleChange = (role: string, checked: boolean) => { setFormData(prev => { if (checked) { return { ...prev, roles: [role] }; } else { const newRoles = prev.roles.filter(r => r !== role); return{ ...prev, roles: newRoles.length > 0 ? newRoles : ['user'] }; } }); }; const handleEmployeeTypeChange = (employeeType: EmployeeType) => { // Determine contract type based on employee type let contractType: ContractType | undefined; if (employeeType === 'manager' || employeeType === 'apprentice') { contractType = 'flexible'; } else if (employeeType !== 'guest') { contractType = 'small'; } // Determine if can work alone based on employee type const canWorkAlone = employeeType === 'manager' || (employeeType === 'personell' && !formData.isTrainee); // Reset isTrainee if not personell const isTrainee = employeeType === 'personell' ? formData.isTrainee : false; setFormData(prev => ({ ...prev, employeeType, contractType, canWorkAlone, isTrainee })); }; const handleTraineeChange = (isTrainee: boolean) => { setFormData(prev => ({ ...prev, isTrainee, canWorkAlone: prev.employeeType === 'personell' ? !isTrainee : prev.canWorkAlone })); }; const handleContractTypeChange = (contractType: ContractType) => { setFormData(prev => ({ ...prev, contractType })); }; const handleSubmit = async (e: React.FormEvent) => { e.preventDefault(); setLoading(true); setError(''); try { if (mode === 'create') { const createData: CreateEmployeeRequest = { firstname: formData.firstname.trim(), lastname: formData.lastname.trim(), password: formData.password, roles: formData.roles, employeeType: formData.employeeType, contractType: formData.employeeType !== 'guest' ? formData.contractType : undefined, canWorkAlone: formData.canWorkAlone, isTrainee: formData.isTrainee }; await employeeService.createEmployee(createData); } else if (employee) { const updateData: UpdateEmployeeRequest = { firstname: formData.firstname.trim(), lastname: formData.lastname.trim(), roles: formData.roles, employeeType: formData.employeeType, contractType: formData.employeeType !== 'guest' ? formData.contractType : undefined, canWorkAlone: formData.canWorkAlone, isActive: formData.isActive, isTrainee: formData.isTrainee }; await employeeService.updateEmployee(employee.id, updateData); // Password change logic remains the same if (showPasswordSection && passwordForm.newPassword && hasRole(['admin'])) { if (passwordForm.newPassword.length < 6) { throw new Error('Das neue Passwort muss mindestens 6 Zeichen lang sein'); } if (passwordForm.newPassword !== passwordForm.confirmPassword) { throw new Error('Die Passwörter stimmen nicht überein'); } await employeeService.changePassword(employee.id, { currentPassword: '', newPassword: passwordForm.newPassword }); } } onSuccess(); } catch (err: any) { setError(err.message || `Fehler beim ${mode === 'create' ? 'Erstellen' : 'Aktualisieren'} des Mitarbeiters`); } finally { setLoading(false); } }; const isFormValid = mode === 'create' ? formData.firstname.trim() && formData.lastname.trim() && formData.password.length >= 6 : formData.firstname.trim() && formData.lastname.trim(); const availableRoles = hasRole(['admin']) ? ROLE_CONFIG : ROLE_CONFIG.filter(role => role.value !== 'admin'); const contractTypeOptions = [ { value: 'small' as const, label: 'Kleiner Vertrag', description: '1 Schicht pro Woche' }, { value: 'large' as const, label: 'Großer Vertrag', description: '2 Schichten pro Woche' }, { value: 'flexible' as const, label: 'Flexibler Vertrag', description: 'Flexible Arbeitszeiten' } ]; const showContractType = formData.employeeType !== 'guest'; return (

{mode === 'create' ? '👤 Neuen Mitarbeiter erstellen' : '✏️ Mitarbeiter bearbeiten'}

{error && (
Fehler: {error}
)}
{/* Grundinformationen */}

📋 Grundinformationen

{/* Email Preview */}
{emailPreview || 'max.mustermann@sp.de'}
Die E-Mail Adresse wird automatisch aus Vorname und Nachname generiert. {formData.firstname && formData.lastname && ` Beispiel: ${emailPreview}`}
{mode === 'create' && (
Das Passwort muss mindestens 6 Zeichen lang sein.
)}
{/* Mitarbeiter Kategorie */}

👥 Mitarbeiter Kategorie

{Object.values(EMPLOYEE_TYPE_CONFIG).map(type => (
handleEmployeeTypeChange(type.value)} > handleEmployeeTypeChange(type.value)} style={{ marginRight: '12px', marginTop: '2px', width: '18px', height: '18px' }} />
{type.label}
{type.description}
{type.value.toUpperCase()}
))}
{/* FIXED: Trainee checkbox for personell type */} {formData.employeeType === 'personell' && (
handleTraineeChange(e.target.checked)} style={{ width: '18px', height: '18px' }} />
Neulinge benötigen zusätzliche Betreuung und können nicht eigenständig arbeiten.
)}
{/* Vertragstyp (nur für Admins und interne Mitarbeiter) */} {hasRole(['admin']) && showContractType && (

📝 Vertragstyp

{contractTypeOptions.map(contract => { const isFlexibleDisabled = contract.value === 'flexible' && formData.employeeType === 'personell'; const isSmallLargeDisabled = (contract.value === 'small' || contract.value === 'large') && (formData.employeeType === 'manager' || formData.employeeType === 'apprentice'); const isDisabled = isFlexibleDisabled || isSmallLargeDisabled; return (
handleContractTypeChange(contract.value)} > handleContractTypeChange(contract.value)} disabled={isDisabled} style={{ marginRight: '12px', marginTop: '2px', width: '18px', height: '18px' }} />
{contract.label} {isFlexibleDisabled && ( (Nicht verfügbar für Personell) )} {isSmallLargeDisabled && ( (Nicht verfügbar für {formData.employeeType === 'manager' ? 'Manager' : 'Auszubildende'}) )}
{contract.description}
{contract.value.toUpperCase()}
); })}
)} {/* Eigenständigkeit */}

🎯 Eigenständigkeit

{formData.employeeType === 'manager' ? 'Chefs sind automatisch als eigenständig markiert.' : formData.employeeType === 'personell' && formData.isTrainee ? 'Auszubildende können nicht als eigenständig markiert werden.' : 'Dieser Mitarbeiter kann komplexe Aufgaben eigenständig lösen und benötigt keine ständige Betreuung.' }
{formData.canWorkAlone ? 'EIGENSTÄNDIG' : 'BETREUUNG'}
{/* Passwort ändern (nur für Admins im Edit-Modus) */} {mode === 'edit' && hasRole(['admin']) && (

🔒 Passwort zurücksetzen

{!showPasswordSection ? ( ) : (
Hinweis: Als Administrator können Sie das Passwort des Benutzers ohne Kenntnis des aktuellen Passworts zurücksetzen.
)}
)} {/* Systemrollen (nur für Admins) - AKTUALISIERT FÜR MEHRFACHE ROLLEN */} {hasRole(['admin']) && (

⚙️ Systemrollen

{availableRoles.map(role => (
handleRoleChange(role.value, !formData.roles.includes(role.value))} > handleRoleChange(role.value, e.target.checked)} style={{ marginRight: '10px', marginTop: '2px' }} />
{role.label}
{role.description}
))}
Hinweis: Ein Mitarbeiter kann mehrere Rollen haben.
)} {/* Aktiv Status (nur beim Bearbeiten) */} {mode === 'edit' && (
Inaktive Mitarbeiter können sich nicht anmelden und werden nicht für Schichten eingeplant.
)}
{/* Buttons */}
); }; export default EmployeeForm;