import React, { useState } from 'react'; import { useAuth } from '../../contexts/AuthContext'; import StepSetup, { Step } from '../../components/StepSetup/StepSetup'; const API_BASE_URL = '/api'; // ===== TYP-DEFINITIONEN ===== interface SetupFormData { password: string; confirmPassword: string; firstname: string; lastname: string; } interface SetupStep { id: string; title: string; subtitle?: string; } // ===== HOOK FÜR SETUP-LOGIK ===== const useSetup = () => { const [currentStep, setCurrentStep] = useState(0); const [formData, setFormData] = useState({ password: '', confirmPassword: '', firstname: '', lastname: '' }); const [loading, setLoading] = useState(false); const [error, setError] = useState(''); const { checkSetupStatus } = useAuth(); const steps: SetupStep[] = [ { id: 'password-setup', title: 'Passwort erstellen', subtitle: 'Legen Sie ein sicheres Passwort fest' }, { id: 'profile-setup', title: 'Profilinformationen', subtitle: 'Geben Sie Ihre persönlichen Daten ein' }, { id: 'confirmation', title: 'Bestätigung', subtitle: 'Setup abschließen' } ]; // ===== VALIDIERUNGS-FUNKTIONEN ===== const validateStep1 = (): boolean => { if (formData.password.length < 6) { setError('Das Passwort muss mindestens 6 Zeichen lang sein.'); return false; } if (formData.password !== formData.confirmPassword) { setError('Die Passwörter stimmen nicht überein.'); return false; } return true; }; const validateStep2 = (): boolean => { if (!formData.firstname.trim()) { setError('Bitte geben Sie einen Vornamen ein.'); return false; } if (!formData.lastname.trim()) { setError('Bitte geben Sie einen Nachnamen ein.'); return false; } return true; }; const validateCurrentStep = (stepIndex: number): boolean => { switch (stepIndex) { case 0: return validateStep1(); case 1: return validateStep2(); default: return true; } }; // ===== NAVIGATIONS-FUNKTIONEN ===== const goToNextStep = async (): Promise => { setError(''); if (!validateCurrentStep(currentStep)) { return; } // Wenn wir beim letzten Schritt sind, Submit ausführen if (currentStep === steps.length - 1) { await handleSubmit(); return; } // Ansonsten zum nächsten Schritt gehen setCurrentStep(prev => prev + 1); }; const goToPrevStep = (): void => { setError(''); if (currentStep > 0) { setCurrentStep(prev => prev - 1); } }; const handleStepChange = (stepIndex: number): void => { setError(''); // Nur erlauben, zu bereits validierten Schritten zu springen // oder zum nächsten Schritt nach dem aktuellen if (stepIndex <= currentStep + 1) { // Vor dem Wechsel validieren if (stepIndex > currentStep && !validateCurrentStep(currentStep)) { return; } setCurrentStep(stepIndex); } }; // ===== FORM HANDLER ===== const handleInputChange = (e: React.ChangeEvent): void => { const { name, value } = e.target; setFormData(prev => ({ ...prev, [name]: value })); }; const handleSubmit = async (): Promise => { try { setLoading(true); setError(''); const payload = { password: formData.password, firstname: formData.firstname, lastname: formData.lastname }; console.log('🚀 Sending setup request...', payload); const response = await fetch(`${API_BASE_URL}/setup/admin`, { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify(payload), }); if (!response.ok) { const data = await response.json(); throw new Error(data.error || 'Setup fehlgeschlagen'); } const result = await response.json(); console.log('✅ Setup successful:', result); // Setup Status neu prüfen await checkSetupStatus(); } catch (err: any) { console.error('❌ Setup error:', err); setError(err.message || 'Ein unerwarteter Fehler ist aufgetreten'); } finally { setLoading(false); } }; // ===== HELPER FUNCTIONS ===== const getEmailPreview = (): string => { if (!formData.firstname.trim() || !formData.lastname.trim()) { return 'vorname.nachname@sp.de'; } const cleanFirstname = formData.firstname.toLowerCase().replace(/[^a-z0-9]/g, ''); const cleanLastname = formData.lastname.toLowerCase().replace(/[^a-z0-9]/g, ''); return `${cleanFirstname}.${cleanLastname}@sp.de`; }; const isStepCompleted = (stepIndex: number): boolean => { switch (stepIndex) { case 0: return formData.password.length >= 6 && formData.password === formData.confirmPassword; case 1: return !!formData.firstname.trim() && !!formData.lastname.trim(); default: return false; } }; return { // State currentStep, formData, loading, error, steps, // Actions goToNextStep, goToPrevStep, handleStepChange, handleInputChange, // Helpers getEmailPreview, isStepCompleted }; }; // ===== STEP-INHALTS-KOMPONENTEN ===== interface StepContentProps { formData: SetupFormData; onInputChange: (e: React.ChangeEvent) => void; getEmailPreview: () => string; currentStep: number; } const Step1Content: React.FC = ({ formData, onInputChange }) => (
); const Step2Content: React.FC = ({ formData, onInputChange, getEmailPreview }) => (
{getEmailPreview()}
Die E-Mail wird automatisch aus Vor- und Nachname generiert
); const Step3Content: React.FC = ({ formData, getEmailPreview }) => (

Zusammenfassung

E-Mail: {getEmailPreview()}
Vorname: {formData.firstname || '-'}
Nachname: {formData.lastname || '-'}
💡 Wichtig: Nach dem Setup können Sie sich mit Ihrer automatisch generierten E-Mail anmelden.
); // ===== HAUPTKOMPONENTE ===== const Setup: React.FC = () => { const { currentStep, formData, loading, error, steps, goToNextStep, goToPrevStep, handleStepChange, handleInputChange, getEmailPreview } = useSetup(); const renderStepContent = (): React.ReactNode => { const stepProps = { formData, onInputChange: handleInputChange, getEmailPreview, currentStep }; switch (currentStep) { case 0: return ; case 1: return ; case 2: return ; default: return null; } }; const getNextButtonText = (): string => { if (loading) return '⏳ Wird verarbeitet...'; switch (currentStep) { case 0: return 'Weiter →'; case 1: return 'Weiter →'; case 2: return 'Setup abschließen'; default: return 'Weiter →'; } }; return (

🚀 Erstkonfiguration

Richten Sie Ihren Administrator-Account ein

{/* Aktueller Schritt Titel und Beschreibung */}

{steps[currentStep].title}

{steps[currentStep].subtitle && (

{steps[currentStep].subtitle}

)}
{/* StepSetup Komponente - nur die Steps ohne Beschreibung */}
({ ...step, subtitle: undefined }))} current={currentStep} onChange={handleStepChange} orientation="horizontal" clickable={true} size="md" animated={true} />
{/* Fehleranzeige */} {error && (
{error}
)} {/* Schritt-Inhalt */}
{renderStepContent()}
{/* Navigations-Buttons */}
{/* Zusätzliche Informationen */} {currentStep === 2 && !loading && (
Überprüfen Sie Ihre Daten, bevor Sie das Setup abschließen
)}
); }; export default Setup;