changed static password length statements 6 -> 8

This commit is contained in:
2025-10-31 12:37:52 +01:00
parent b302c447f8
commit 3ad497dd76
7 changed files with 123 additions and 123 deletions

View File

@@ -766,7 +766,7 @@ export const changePassword = async (req: AuthRequest, res: Response): Promise<v
} }
// Validate new password // Validate new password
if (!newPassword || newPassword.length < 6) { if (!newPassword || newPassword.length < 8) {
res.status(400).json({ error: 'New password must be at least 8 characters long' }); res.status(400).json({ error: 'New password must be at least 8 characters long' });
return; return;
} }

View File

@@ -16,7 +16,7 @@ function generateEmail(firstname: string, lastname: string): string {
const cleanFirstname = convertUmlauts(firstname).replace(/[^a-z0-9]/g, ''); const cleanFirstname = convertUmlauts(firstname).replace(/[^a-z0-9]/g, '');
const cleanLastname = convertUmlauts(lastname).replace(/[^a-z0-9]/g, ''); const cleanLastname = convertUmlauts(lastname).replace(/[^a-z0-9]/g, '');
return `${cleanFirstname}.${cleanLastname}@sp.de`; return `${cleanFirstname}.${cleanLastname}@sp.de`;
} }
@@ -31,15 +31,15 @@ export const checkSetupStatus = async (req: Request, res: Response): Promise<voi
); );
console.log('Admin exists check:', adminExists); console.log('Admin exists check:', adminExists);
const needsSetup = !adminExists || adminExists['COUNT(*)'] === 0; const needsSetup = !adminExists || adminExists['COUNT(*)'] === 0;
res.json({ res.json({
needsSetup: needsSetup needsSetup: needsSetup
}); });
} catch (error) { } catch (error) {
console.error('Error checking setup status:', error); console.error('Error checking setup status:', error);
res.status(500).json({ res.status(500).json({
error: 'Internal server error during setup check' error: 'Internal server error during setup check'
}); });
} }
@@ -75,8 +75,8 @@ export const setupAdmin = async (req: Request, res: Response): Promise<void> =>
} }
// Password length validation // Password length validation
if (password.length < 6) { if (password.length < 8) {
res.status(400).json({ error: 'Das Passwort muss mindestens 6 Zeichen lang sein' }); res.status(400).json({ error: 'Das Passwort muss mindestens 8 Zeichen lang sein' });
return; return;
} }
@@ -125,15 +125,15 @@ export const setupAdmin = async (req: Request, res: Response): Promise<void> =>
} catch (dbError) { } catch (dbError) {
await db.run('ROLLBACK'); await db.run('ROLLBACK');
console.error('❌ Database error during admin creation:', dbError); console.error('❌ Database error during admin creation:', dbError);
res.status(500).json({ res.status(500).json({
error: 'Fehler beim Erstellen des Admin-Accounts' error: 'Fehler beim Erstellen des Admin-Accounts'
}); });
} }
} catch (error) { } catch (error) {
console.error('❌ Error in setup:', error); console.error('❌ Error in setup:', error);
if (!res.headersSent) { if (!res.headersSent) {
res.status(500).json({ res.status(500).json({
error: 'Ein unerwarteter Fehler ist aufgetreten' error: 'Ein unerwarteter Fehler ist aufgetreten'
}); });
} }

View File

@@ -23,7 +23,7 @@
### \[CREATE\] Employee ### \[CREATE\] Employee
* `firstname` 1-100 characters and must not be empty * `firstname` 1-100 characters and must not be empty
* `lastname` 1-100 characters and must not be empty * `lastname` 1-100 characters and must not be empty
* `password` must be at least 6 characters (in create mode) * `password` must be at least 8 characters (in create mode)
* `employeeType` must be `manager`, `personell`, `apprentice`, or `guest` * `employeeType` must be `manager`, `personell`, `apprentice`, or `guest`
* `canWorkAlone` optional boolean * `canWorkAlone` optional boolean
* `isTrainee` optional boolean * `isTrainee` optional boolean

View File

@@ -14,7 +14,7 @@ function generateEmail(firstname: string, lastname: string): string {
const cleanFirstname = convertUmlauts(firstname).replace(/[^a-z0-9]/g, ''); const cleanFirstname = convertUmlauts(firstname).replace(/[^a-z0-9]/g, '');
const cleanLastname = convertUmlauts(lastname).replace(/[^a-z0-9]/g, ''); const cleanLastname = convertUmlauts(lastname).replace(/[^a-z0-9]/g, '');
return `${cleanFirstname}.${cleanLastname}@sp.de`; return `${cleanFirstname}.${cleanLastname}@sp.de`;
} }
@@ -22,8 +22,8 @@ function generateEmail(firstname: string, lastname: string): string {
export function validateEmployeeData(employee: CreateEmployeeRequest): string[] { export function validateEmployeeData(employee: CreateEmployeeRequest): string[] {
const errors: string[] = []; const errors: string[] = [];
if (employee.password?.length < 6) { if (employee.password?.length < 8) {
errors.push('Password must be at least 6 characters long'); errors.push('Password must be at least 8 characters long');
} }
if (!employee.firstname?.trim() || employee.firstname.trim().length < 2) { if (!employee.firstname?.trim() || employee.firstname.trim().length < 2) {
@@ -72,16 +72,16 @@ export function generateEmployeeEmail(firstname: string, lastname: string): stri
} }
// UPDATED: Business logic helpers for new employee types // UPDATED: Business logic helpers for new employee types
export const isManager = (employee: Employee): boolean => export const isManager = (employee: Employee): boolean =>
employee.employeeType === 'manager'; employee.employeeType === 'manager';
export const isPersonell = (employee: Employee): boolean => export const isPersonell = (employee: Employee): boolean =>
employee.employeeType === 'personell'; employee.employeeType === 'personell';
export const isApprentice = (employee: Employee): boolean => export const isApprentice = (employee: Employee): boolean =>
employee.employeeType === 'apprentice'; employee.employeeType === 'apprentice';
export const isGuest = (employee: Employee): boolean => export const isGuest = (employee: Employee): boolean =>
employee.employeeType === 'guest'; employee.employeeType === 'guest';
export const isInternal = (employee: Employee): boolean => export const isInternal = (employee: Employee): boolean =>
@@ -91,24 +91,24 @@ export const isExternal = (employee: Employee): boolean =>
employee.employeeType === 'guest'; employee.employeeType === 'guest';
// UPDATED: Trainee logic - now based on isTrainee field for personell type // UPDATED: Trainee logic - now based on isTrainee field for personell type
export const isTrainee = (employee: Employee): boolean => export const isTrainee = (employee: Employee): boolean =>
employee.employeeType === 'personell' && employee.isTrainee; employee.employeeType === 'personell' && employee.isTrainee;
export const isExperienced = (employee: Employee): boolean => export const isExperienced = (employee: Employee): boolean =>
employee.employeeType === 'personell' && !employee.isTrainee; employee.employeeType === 'personell' && !employee.isTrainee;
// Role-based helpers // Role-based helpers
export const isAdmin = (employee: Employee): boolean => export const isAdmin = (employee: Employee): boolean =>
employee.roles?.includes('admin') || false; employee.roles?.includes('admin') || false;
export const isMaintenance = (employee: Employee): boolean => export const isMaintenance = (employee: Employee): boolean =>
employee.roles?.includes('maintenance') || false; employee.roles?.includes('maintenance') || false;
export const isUser = (employee: Employee): boolean => export const isUser = (employee: Employee): boolean =>
employee.roles?.includes('user') || false; employee.roles?.includes('user') || false;
// UPDATED: Work alone permission - managers and experienced personell can work alone // UPDATED: Work alone permission - managers and experienced personell can work alone
export const canEmployeeWorkAlone = (employee: Employee): boolean => export const canEmployeeWorkAlone = (employee: Employee): boolean =>
employee.canWorkAlone && (isManager(employee) || isExperienced(employee)); employee.canWorkAlone && (isManager(employee) || isExperienced(employee));
// Helper for full name display // Helper for full name display

View File

@@ -14,7 +14,7 @@ function generateEmail(firstname: string, lastname: string): string {
const cleanFirstname = convertUmlauts(firstname).replace(/[^a-z0-9]/g, ''); const cleanFirstname = convertUmlauts(firstname).replace(/[^a-z0-9]/g, '');
const cleanLastname = convertUmlauts(lastname).replace(/[^a-z0-9]/g, ''); const cleanLastname = convertUmlauts(lastname).replace(/[^a-z0-9]/g, '');
return `${cleanFirstname}.${cleanLastname}@sp.de`; return `${cleanFirstname}.${cleanLastname}@sp.de`;
} }
@@ -22,8 +22,8 @@ function generateEmail(firstname: string, lastname: string): string {
export function validateEmployeeData(employee: CreateEmployeeRequest): string[] { export function validateEmployeeData(employee: CreateEmployeeRequest): string[] {
const errors: string[] = []; const errors: string[] = [];
if (employee.password?.length < 6) { if (employee.password?.length < 8) {
errors.push('Password must be at least 6 characters long'); errors.push('Password must be at least 8 characters long');
} }
if (!employee.firstname?.trim() || employee.firstname.trim().length < 2) { if (!employee.firstname?.trim() || employee.firstname.trim().length < 2) {
@@ -72,16 +72,16 @@ export function generateEmployeeEmail(firstname: string, lastname: string): stri
} }
// UPDATED: Business logic helpers for new employee types // UPDATED: Business logic helpers for new employee types
export const isManager = (employee: Employee): boolean => export const isManager = (employee: Employee): boolean =>
employee.employeeType === 'manager'; employee.employeeType === 'manager';
export const isPersonell = (employee: Employee): boolean => export const isPersonell = (employee: Employee): boolean =>
employee.employeeType === 'personell'; employee.employeeType === 'personell';
export const isApprentice = (employee: Employee): boolean => export const isApprentice = (employee: Employee): boolean =>
employee.employeeType === 'apprentice'; employee.employeeType === 'apprentice';
export const isGuest = (employee: Employee): boolean => export const isGuest = (employee: Employee): boolean =>
employee.employeeType === 'guest'; employee.employeeType === 'guest';
export const isInternal = (employee: Employee): boolean => export const isInternal = (employee: Employee): boolean =>
@@ -91,24 +91,24 @@ export const isExternal = (employee: Employee): boolean =>
employee.employeeType === 'guest'; employee.employeeType === 'guest';
// UPDATED: Trainee logic - now based on isTrainee field for personell type // UPDATED: Trainee logic - now based on isTrainee field for personell type
export const isTrainee = (employee: Employee): boolean => export const isTrainee = (employee: Employee): boolean =>
employee.employeeType === 'personell' && employee.isTrainee; employee.employeeType === 'personell' && employee.isTrainee;
export const isExperienced = (employee: Employee): boolean => export const isExperienced = (employee: Employee): boolean =>
employee.employeeType === 'personell' && !employee.isTrainee; employee.employeeType === 'personell' && !employee.isTrainee;
// Role-based helpers // Role-based helpers
export const isAdmin = (employee: Employee): boolean => export const isAdmin = (employee: Employee): boolean =>
employee.roles?.includes('admin') || false; employee.roles?.includes('admin') || false;
export const isMaintenance = (employee: Employee): boolean => export const isMaintenance = (employee: Employee): boolean =>
employee.roles?.includes('maintenance') || false; employee.roles?.includes('maintenance') || false;
export const isUser = (employee: Employee): boolean => export const isUser = (employee: Employee): boolean =>
employee.roles?.includes('user') || false; employee.roles?.includes('user') || false;
// UPDATED: Work alone permission - managers and experienced personell can work alone // UPDATED: Work alone permission - managers and experienced personell can work alone
export const canEmployeeWorkAlone = (employee: Employee): boolean => export const canEmployeeWorkAlone = (employee: Employee): boolean =>
employee.canWorkAlone && (isManager(employee) || isExperienced(employee)); employee.canWorkAlone && (isManager(employee) || isExperienced(employee));
// Helper for full name display // Helper for full name display

View File

@@ -203,11 +203,11 @@ const Settings: React.FC = () => {
return; return;
} }
if (passwordForm.newPassword.length < 6) { if (passwordForm.newPassword.length < 8) {
showNotification({ showNotification({
type: 'error', type: 'error',
title: 'Fehler', title: 'Fehler',
message: 'Das neue Passwort muss mindestens 6 Zeichen lang sein' message: 'Das neue Passwort muss mindestens 8 Zeichen lang sein'
}); });
return; return;
} }
@@ -600,9 +600,9 @@ const Settings: React.FC = () => {
value={passwordForm.newPassword} value={passwordForm.newPassword}
onChange={handlePasswordChange} onChange={handlePasswordChange}
required required
minLength={6} minLength={8}
style={styles.fieldInputWithIcon} style={styles.fieldInputWithIcon}
placeholder="Mindestens 6 Zeichen" placeholder="Mindestens 8 Zeichen"
onFocus={(e) => { onFocus={(e) => {
e.target.style.borderColor = '#1a1325'; e.target.style.borderColor = '#1a1325';
e.target.style.boxShadow = '0 0 0 3px rgba(26, 19, 37, 0.1)'; e.target.style.boxShadow = '0 0 0 3px rgba(26, 19, 37, 0.1)';
@@ -631,7 +631,7 @@ const Settings: React.FC = () => {
</button> </button>
</div> </div>
<div style={styles.fieldHint}> <div style={styles.fieldHint}>
Das Passwort muss mindestens 6 Zeichen lang sein. Das Passwort muss mindestens 8 Zeichen lang sein.
</div> </div>
</div> </div>

View File

@@ -32,7 +32,7 @@ const useSetup = () => {
const steps: SetupStep[] = [ const steps: SetupStep[] = [
{ {
id: 'profile-setup', id: 'profile-setup',
title: 'Profilinformationen', title: 'Profilinformationen',
subtitle: 'Geben Sie Ihre persönlichen Daten ein' subtitle: 'Geben Sie Ihre persönlichen Daten ein'
}, },
@@ -62,8 +62,8 @@ const useSetup = () => {
}; };
const validateStep2 = (): boolean => { const validateStep2 = (): boolean => {
if (formData.password.length < 6) { if (formData.password.length < 8) {
setError('Das Passwort muss mindestens 6 Zeichen lang sein.'); setError('Das Passwort muss mindestens 8 Zeichen lang sein.');
return false; return false;
} }
if (formData.password !== formData.confirmPassword) { if (formData.password !== formData.confirmPassword) {
@@ -87,7 +87,7 @@ const useSetup = () => {
// ===== NAVIGATIONS-FUNKTIONEN ===== // ===== NAVIGATIONS-FUNKTIONEN =====
const goToNextStep = async (): Promise<void> => { const goToNextStep = async (): Promise<void> => {
setError(''); setError('');
if (!validateCurrentStep(currentStep)) { if (!validateCurrentStep(currentStep)) {
return; return;
} }
@@ -111,7 +111,7 @@ const useSetup = () => {
const handleStepChange = (stepIndex: number): void => { const handleStepChange = (stepIndex: number): void => {
setError(''); setError('');
// Nur erlauben, zu bereits validierten Schritten zu springen // Nur erlauben, zu bereits validierten Schritten zu springen
// oder zum nächsten Schritt nach dem aktuellen // oder zum nächsten Schritt nach dem aktuellen
if (stepIndex <= currentStep + 1) { if (stepIndex <= currentStep + 1) {
@@ -163,7 +163,7 @@ const useSetup = () => {
// Setup Status neu prüfen // Setup Status neu prüfen
await checkSetupStatus(); await checkSetupStatus();
} catch (err: any) { } catch (err: any) {
console.error('❌ Setup error:', err); console.error('❌ Setup error:', err);
setError(err.message || 'Ein unerwarteter Fehler ist aufgetreten'); setError(err.message || 'Ein unerwarteter Fehler ist aufgetreten');
@@ -177,7 +177,7 @@ const useSetup = () => {
if (!formData.firstname.trim() || !formData.lastname.trim()) { if (!formData.firstname.trim() || !formData.lastname.trim()) {
return 'vorname.nachname@sp.de'; return 'vorname.nachname@sp.de';
} }
const cleanFirstname = formData.firstname.toLowerCase().replace(/[^a-z0-9]/g, ''); const cleanFirstname = formData.firstname.toLowerCase().replace(/[^a-z0-9]/g, '');
const cleanLastname = formData.lastname.toLowerCase().replace(/[^a-z0-9]/g, ''); const cleanLastname = formData.lastname.toLowerCase().replace(/[^a-z0-9]/g, '');
return `${cleanFirstname}.${cleanLastname}@sp.de`; return `${cleanFirstname}.${cleanLastname}@sp.de`;
@@ -186,8 +186,8 @@ const useSetup = () => {
const isStepCompleted = (stepIndex: number): boolean => { const isStepCompleted = (stepIndex: number): boolean => {
switch (stepIndex) { switch (stepIndex) {
case 0: case 0:
return formData.password.length >= 6 && return formData.password.length >= 8 &&
formData.password === formData.confirmPassword; formData.password === formData.confirmPassword;
case 1: case 1:
return !!formData.firstname.trim() && !!formData.lastname.trim(); return !!formData.firstname.trim() && !!formData.lastname.trim();
default: default:
@@ -202,13 +202,13 @@ const useSetup = () => {
loading, loading,
error, error,
steps, steps,
// Actions // Actions
goToNextStep, goToNextStep,
goToPrevStep, goToPrevStep,
handleStepChange, handleStepChange,
handleInputChange, handleInputChange,
// Helpers // Helpers
getEmailPreview, getEmailPreview,
isStepCompleted isStepCompleted
@@ -223,16 +223,16 @@ interface StepContentProps {
currentStep: number; currentStep: number;
} }
const Step1Content: React.FC<StepContentProps> = ({ const Step1Content: React.FC<StepContentProps> = ({
formData, formData,
onInputChange, onInputChange,
getEmailPreview getEmailPreview
}) => ( }) => (
<div style={{ display: 'flex', flexDirection: 'column', gap: '1.5rem' }}> <div style={{ display: 'flex', flexDirection: 'column', gap: '1.5rem' }}>
<div> <div>
<label style={{ <label style={{
display: 'block', display: 'block',
marginBottom: '0.5rem', marginBottom: '0.5rem',
fontWeight: '600', fontWeight: '600',
color: '#495057' color: '#495057'
}}> }}>
@@ -257,9 +257,9 @@ const Step1Content: React.FC<StepContentProps> = ({
</div> </div>
<div> <div>
<label style={{ <label style={{
display: 'block', display: 'block',
marginBottom: '0.5rem', marginBottom: '0.5rem',
fontWeight: '600', fontWeight: '600',
color: '#495057' color: '#495057'
}}> }}>
@@ -284,17 +284,17 @@ const Step1Content: React.FC<StepContentProps> = ({
</div> </div>
<div> <div>
<label style={{ <label style={{
display: 'block', display: 'block',
marginBottom: '0.5rem', marginBottom: '0.5rem',
fontWeight: '600', fontWeight: '600',
color: '#495057' color: '#495057'
}}> }}>
Automatisch generierte E-Mail Automatisch generierte E-Mail
</label> </label>
<div style={{ <div style={{
padding: '0.75rem', padding: '0.75rem',
backgroundColor: '#e9ecef', backgroundColor: '#e9ecef',
border: '1px solid #ced4da', border: '1px solid #ced4da',
borderRadius: '6px', borderRadius: '6px',
color: '#495057', color: '#495057',
@@ -303,8 +303,8 @@ const Step1Content: React.FC<StepContentProps> = ({
}}> }}>
{getEmailPreview()} {getEmailPreview()}
</div> </div>
<div style={{ <div style={{
fontSize: '0.875rem', fontSize: '0.875rem',
color: '#6c757d', color: '#6c757d',
marginTop: '0.25rem' marginTop: '0.25rem'
}}> }}>
@@ -315,15 +315,15 @@ const Step1Content: React.FC<StepContentProps> = ({
); );
const Step2Content: React.FC<StepContentProps> = ({ const Step2Content: React.FC<StepContentProps> = ({
formData, formData,
onInputChange onInputChange
}) => ( }) => (
<div style={{ display: 'flex', flexDirection: 'column', gap: '1.5rem' }}> <div style={{ display: 'flex', flexDirection: 'column', gap: '1.5rem' }}>
<div> <div>
<label style={{ <label style={{
display: 'block', display: 'block',
marginBottom: '0.5rem', marginBottom: '0.5rem',
fontWeight: '600', fontWeight: '600',
color: '#495057' color: '#495057'
}}> }}>
@@ -342,16 +342,16 @@ const Step2Content: React.FC<StepContentProps> = ({
fontSize: '1rem', fontSize: '1rem',
transition: 'border-color 0.3s ease' transition: 'border-color 0.3s ease'
}} }}
placeholder="Mindestens 6 Zeichen" placeholder="Mindestens 8 Zeichen"
required required
autoComplete="new-password" autoComplete="new-password"
/> />
</div> </div>
<div> <div>
<label style={{ <label style={{
display: 'block', display: 'block',
marginBottom: '0.5rem', marginBottom: '0.5rem',
fontWeight: '600', fontWeight: '600',
color: '#495057' color: '#495057'
}}> }}>
@@ -378,26 +378,26 @@ const Step2Content: React.FC<StepContentProps> = ({
</div> </div>
); );
const Step3Content: React.FC<StepContentProps> = ({ const Step3Content: React.FC<StepContentProps> = ({
formData, formData,
getEmailPreview getEmailPreview
}) => ( }) => (
<div style={{ display: 'flex', flexDirection: 'column', gap: '1.5rem' }}> <div style={{ display: 'flex', flexDirection: 'column', gap: '1.5rem' }}>
<div style={{ <div style={{
backgroundColor: '#f8f9fa', backgroundColor: '#f8f9fa',
padding: '1.5rem', padding: '1.5rem',
borderRadius: '8px', borderRadius: '8px',
border: '1px solid #e9ecef' border: '1px solid #e9ecef'
}}> }}>
<h3 style={{ <h3 style={{
marginBottom: '1rem', marginBottom: '1rem',
color: '#2c3e50', color: '#2c3e50',
fontSize: '1.1rem', fontSize: '1.1rem',
fontWeight: '600' fontWeight: '600'
}}> }}>
Zusammenfassung Zusammenfassung
</h3> </h3>
<div style={{ display: 'flex', flexDirection: 'column', gap: '0.75rem' }}> <div style={{ display: 'flex', flexDirection: 'column', gap: '0.75rem' }}>
<div style={{ display: 'flex', justifyContent: 'space-between' }}> <div style={{ display: 'flex', justifyContent: 'space-between' }}>
<span style={{ color: '#6c757d' }}>E-Mail:</span> <span style={{ color: '#6c757d' }}>E-Mail:</span>
@@ -413,15 +413,15 @@ const Step3Content: React.FC<StepContentProps> = ({
</div> </div>
</div> </div>
</div> </div>
<div style={{ <div style={{
padding: '1rem', padding: '1rem',
backgroundColor: '#e7f3ff', backgroundColor: '#e7f3ff',
borderRadius: '6px', borderRadius: '6px',
border: '1px solid #b6d7e8', border: '1px solid #b6d7e8',
color: '#2c3e50' color: '#2c3e50'
}}> }}>
<strong>💡 Wichtig:</strong> Nach dem Setup können Sie sich mit Ihrer <strong>💡 Wichtig:</strong> Nach dem Setup können Sie sich mit Ihrer
automatisch generierten E-Mail anmelden. automatisch generierten E-Mail anmelden.
</div> </div>
</div> </div>
@@ -464,7 +464,7 @@ const Setup: React.FC = () => {
const getNextButtonText = (): string => { const getNextButtonText = (): string => {
if (loading) return '⏳ Wird verarbeitet...'; if (loading) return '⏳ Wird verarbeitet...';
switch (currentStep) { switch (currentStep) {
case 0: case 0:
return 'Weiter →'; return 'Weiter →';
@@ -479,9 +479,9 @@ const Setup: React.FC = () => {
// Inline Step Indicator Komponente // Inline Step Indicator Komponente
const StepIndicator: React.FC = () => ( const StepIndicator: React.FC = () => (
<div style={{ <div style={{
display: 'flex', display: 'flex',
justifyContent: 'space-between', justifyContent: 'space-between',
alignItems: 'center', alignItems: 'center',
marginBottom: '2.5rem', marginBottom: '2.5rem',
position: 'relative', position: 'relative',
@@ -497,18 +497,18 @@ const Setup: React.FC = () => {
backgroundColor: '#e9ecef', backgroundColor: '#e9ecef',
zIndex: 1 zIndex: 1
}} /> }} />
{steps.map((step, index) => { {steps.map((step, index) => {
const isCompleted = index < currentStep; const isCompleted = index < currentStep;
const isCurrent = index === currentStep; const isCurrent = index === currentStep;
const isClickable = index <= currentStep + 1; const isClickable = index <= currentStep + 1;
return ( return (
<div <div
key={step.id} key={step.id}
style={{ style={{
display: 'flex', display: 'flex',
flexDirection: 'column', flexDirection: 'column',
alignItems: 'center', alignItems: 'center',
zIndex: 2, zIndex: 2,
position: 'relative', position: 'relative',
@@ -538,10 +538,10 @@ const Setup: React.FC = () => {
> >
{index + 1} {index + 1}
</button> </button>
<div style={{ textAlign: 'center' }}> <div style={{ textAlign: 'center' }}>
<div style={{ <div style={{
fontSize: '14px', fontSize: '14px',
fontWeight: isCurrent ? '600' : '400', fontWeight: isCurrent ? '600' : '400',
color: isCurrent ? '#51258f' : '#6c757d' color: isCurrent ? '#51258f' : '#6c757d'
}}> }}>
@@ -555,8 +555,8 @@ const Setup: React.FC = () => {
); );
return ( return (
<div style={{ <div style={{
minHeight: '100vh', minHeight: '100vh',
backgroundColor: '#f8f9fa', backgroundColor: '#f8f9fa',
display: 'flex', display: 'flex',
alignItems: 'center', alignItems: 'center',
@@ -573,15 +573,15 @@ const Setup: React.FC = () => {
border: '1px solid #e9ecef' border: '1px solid #e9ecef'
}}> }}>
<div style={{ textAlign: 'center', marginBottom: '1rem' }}> <div style={{ textAlign: 'center', marginBottom: '1rem' }}>
<h1 style={{ <h1 style={{
fontSize: '2rem', fontSize: '2rem',
fontWeight: 'bold', fontWeight: 'bold',
marginBottom: '0.5rem', marginBottom: '0.5rem',
color: '#2c3e50' color: '#2c3e50'
}}> }}>
🚀 Erstkonfiguration 🚀 Erstkonfiguration
</h1> </h1>
<p style={{ <p style={{
color: '#6c757d', color: '#6c757d',
fontSize: '1.1rem', fontSize: '1.1rem',
marginBottom: '2rem' marginBottom: '2rem'
@@ -592,16 +592,16 @@ const Setup: React.FC = () => {
{/* Aktueller Schritt Titel und Beschreibung */} {/* Aktueller Schritt Titel und Beschreibung */}
<div style={{ textAlign: 'center', marginBottom: '1.5rem' }}> <div style={{ textAlign: 'center', marginBottom: '1.5rem' }}>
<h2 style={{ <h2 style={{
fontSize: '1.5rem', fontSize: '1.5rem',
fontWeight: 'bold', fontWeight: 'bold',
marginBottom: '0.5rem', marginBottom: '0.5rem',
color: '#2c3e50' color: '#2c3e50'
}}> }}>
{steps[currentStep].title} {steps[currentStep].title}
</h2> </h2>
{steps[currentStep].subtitle && ( {steps[currentStep].subtitle && (
<p style={{ <p style={{
color: '#6c757d', color: '#6c757d',
fontSize: '1rem' fontSize: '1rem'
}}> }}>
@@ -633,9 +633,9 @@ const Setup: React.FC = () => {
</div> </div>
{/* Navigations-Buttons */} {/* Navigations-Buttons */}
<div style={{ <div style={{
marginTop: '2rem', marginTop: '2rem',
display: 'flex', display: 'flex',
justifyContent: 'space-between', justifyContent: 'space-between',
alignItems: 'center' alignItems: 'center'
}}> }}>
@@ -655,7 +655,7 @@ const Setup: React.FC = () => {
> >
Zurück Zurück
</button> </button>
<button <button
onClick={goToNextStep} onClick={goToNextStep}
disabled={loading} disabled={loading}
@@ -677,10 +677,10 @@ const Setup: React.FC = () => {
{/* Zusätzliche Informationen */} {/* Zusätzliche Informationen */}
{currentStep === 2 && !loading && ( {currentStep === 2 && !loading && (
<div style={{ <div style={{
marginTop: '1.5rem', marginTop: '1.5rem',
textAlign: 'center', textAlign: 'center',
color: '#6c757d', color: '#6c757d',
fontSize: '0.9rem', fontSize: '0.9rem',
padding: '1rem', padding: '1rem',
backgroundColor: '#f8f9fa', backgroundColor: '#f8f9fa',