import React, { useState } from 'react'; import { Box, Text, useInput } from 'ink'; import { useNavigation } from '../../state/navigation-context.js'; import { client } from '../../utils/api-client.js'; import { FormInput } from '../shared/FormInput.js'; import { LoadingSpinner } from '../shared/LoadingSpinner.js'; import { ErrorDisplay } from '../shared/ErrorDisplay.js'; import { SuccessDisplay } from '../shared/SuccessDisplay.js'; import { passwordSchema } from '@effigenix/validation'; type Field = 'currentPassword' | 'newPassword' | 'confirmPassword'; const FIELDS: Field[] = ['currentPassword', 'newPassword', 'confirmPassword']; function errorMessage(err: unknown): string { return err instanceof Error ? err.message : 'Unbekannter Fehler'; } export function ChangePasswordScreen() { const { params, back } = useNavigation(); const userId = params['userId'] ?? ''; const [currentPassword, setCurrentPassword] = useState(''); const [newPassword, setNewPassword] = useState(''); const [confirmPassword, setConfirmPassword] = useState(''); const [activeField, setActiveField] = useState('currentPassword'); const [loading, setLoading] = useState(false); const [error, setError] = useState(null); const [success, setSuccess] = useState(false); useInput((_input, key) => { if (loading) return; if (key.tab || key.downArrow) { setActiveField((f) => { const idx = FIELDS.indexOf(f); return FIELDS[(idx + 1) % FIELDS.length] ?? f; }); } if (key.upArrow) { setActiveField((f) => { const idx = FIELDS.indexOf(f); return FIELDS[(idx - 1 + FIELDS.length) % FIELDS.length] ?? f; }); } if (key.escape) { back(); } }); const handleSubmit = async () => { setError(null); if (!currentPassword.trim() || !newPassword.trim() || !confirmPassword.trim()) { setError('Alle Felder sind Pflichtfelder.'); return; } if (newPassword !== confirmPassword) { setError('Das neue Passwort und die Bestätigung stimmen nicht überein.'); return; } const passwordResult = passwordSchema.safeParse(newPassword.trim()); if (!passwordResult.success) { setError(passwordResult.error.errors[0]?.message ?? 'Ungültiges Passwort'); return; } setLoading(true); try { await client.users.changePassword(userId, { currentPassword: currentPassword.trim(), newPassword: newPassword.trim(), }); setSuccess(true); } catch (err) { setError(errorMessage(err)); } finally { setLoading(false); } }; const handleFieldSubmit = (field: Field) => (_value: string) => { const idx = FIELDS.indexOf(field); if (idx < FIELDS.length - 1) { setActiveField(FIELDS[idx + 1] ?? field); } else { void handleSubmit(); } }; if (loading) { return ( ); } if (success) { return ( back()} /> ); } return ( Passwort ändern {error && ( setError(null)} /> )} Tab/↑↓ Feld wechseln · Enter auf letztem Feld speichern · Escape Abbrechen ); }