fix(ui): echte Umlaute in allen sichtbaren Texten
Menüs, Dialoge, Schaltflächen, Platzhalter, Hinweise und die
Fehlermeldungen der API standen in Ersatzschreibweise (oe/ae/ue). Sie
erscheinen als Toast oder Beschriftung direkt in der Oberfläche und
gehören damit richtig geschrieben; sechs sichtbare Texte mit ss statt ß
sind gleich mit erledigt ("Schließen", "Straße", "zu groß").
Unangetastet bleibt bewusst:
- Kommentare im Quelltext - die sind durchgängig ASCII, und der Diff wäre
dreimal so groß ohne Nutzen für den Benutzer
- Protokollzeilen (console.*) - die landen im journal, nicht in der App
- Datenbankwerte und interne Kennungen: 'uebernommen', 'empfaenger',
'vorschlaege', 'laeuft-bereits' stecken in Enums, SQL und
Zustandsvergleichen. Ein Umlaut darin hätte still falsche Ergebnisse
geliefert
- server/src/mail/extract.js - die Muster decken absichtlich beide
Schreibweisen ab: /gr(ü|ue)(ß|ss)e/
- scanner/utils/crypto.js - der Ersatzschlüssel darf sich nicht ändern,
sonst sind gespeicherte Portal-Passwörter nicht mehr lesbar
Geprüft mit einem Rundgang durch die Ansichten und Dialoge: sichtbarer
Text plus title/aria-label/placeholder enthalten keine
Ersatzschreibweisen mehr.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
ea55acdb5c
commit
8b7ce448a6
@@ -31,7 +31,7 @@ export const ColorPicker: React.FC<ColorPickerProps> = ({ value, onChange, fallb
|
||||
})}
|
||||
|
||||
<label
|
||||
title="Eigene Farbe waehlen"
|
||||
title="Eigene Farbe wählen"
|
||||
className="flex h-8 w-8 cursor-pointer items-center justify-center rounded-lg border border-dashed border-ink-300 text-ink-400 transition hover:border-brand-400 hover:text-brand-600"
|
||||
>
|
||||
<svg className="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
|
||||
@@ -49,7 +49,7 @@ const AccountTab: React.FC = () => {
|
||||
const handleSubmit = async (event: React.FormEvent) => {
|
||||
event.preventDefault();
|
||||
if (newPassword !== confirmPassword) {
|
||||
addToast('Die neuen Passwoerter stimmen nicht ueberein.', 'error');
|
||||
addToast('Die neuen Passwörter stimmen nicht überein.', 'error');
|
||||
return;
|
||||
}
|
||||
if (newPassword.length < 8) {
|
||||
@@ -60,12 +60,12 @@ const AccountTab: React.FC = () => {
|
||||
setIsSaving(true);
|
||||
try {
|
||||
await authApi.changePassword(currentPassword, newPassword);
|
||||
addToast('Passwort geaendert.', 'success');
|
||||
addToast('Passwort geändert.', 'success');
|
||||
setCurrentPassword('');
|
||||
setNewPassword('');
|
||||
setConfirmPassword('');
|
||||
} catch (err) {
|
||||
addToast(err instanceof Error ? err.message : 'Aenderung fehlgeschlagen.', 'error');
|
||||
addToast(err instanceof Error ? err.message : 'Änderung fehlgeschlagen.', 'error');
|
||||
} finally {
|
||||
setIsSaving(false);
|
||||
}
|
||||
@@ -126,7 +126,7 @@ const AccountTab: React.FC = () => {
|
||||
</section>
|
||||
|
||||
<section className="rounded-2xl border border-ink-200 bg-surface p-5">
|
||||
<h3 className="text-base text-ink-900">Passwort aendern</h3>
|
||||
<h3 className="text-base text-ink-900">Passwort ändern</h3>
|
||||
<form onSubmit={handleSubmit} className="mt-4 space-y-4">
|
||||
<div>
|
||||
<label className={labelClass}>Aktuelles Passwort</label>
|
||||
@@ -152,7 +152,7 @@ const AccountTab: React.FC = () => {
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<label className={labelClass}>Neues Passwort bestaetigen</label>
|
||||
<label className={labelClass}>Neues Passwort bestätigen</label>
|
||||
<input
|
||||
type="password"
|
||||
required
|
||||
@@ -167,7 +167,7 @@ const AccountTab: React.FC = () => {
|
||||
disabled={isSaving}
|
||||
className="w-full rounded-xl bg-brand-500 py-2.5 text-sm font-bold text-white transition hover:bg-brand-600 disabled:opacity-60"
|
||||
>
|
||||
{isSaving ? 'Speichere...' : 'Passwort aendern'}
|
||||
{isSaving ? 'Speichere...' : 'Passwort ändern'}
|
||||
</button>
|
||||
</form>
|
||||
</section>
|
||||
|
||||
@@ -145,10 +145,10 @@ export const UserManagement: React.FC = () => {
|
||||
if (!userToDelete) return;
|
||||
try {
|
||||
await usersApi.remove(userToDelete.id);
|
||||
addToast(`Benutzer "${userToDelete.name}" wurde geloescht.`, 'success');
|
||||
addToast(`Benutzer "${userToDelete.name}" wurde gelöscht.`, 'success');
|
||||
await load();
|
||||
} catch (err) {
|
||||
addToast(err instanceof Error ? err.message : 'Loeschen fehlgeschlagen.', 'error');
|
||||
addToast(err instanceof Error ? err.message : 'Löschen fehlgeschlagen.', 'error');
|
||||
} finally {
|
||||
setUserToDelete(null);
|
||||
}
|
||||
@@ -222,7 +222,7 @@ export const UserManagement: React.FC = () => {
|
||||
<button
|
||||
onClick={() => setUserToDelete(user)}
|
||||
className="rounded-lg p-2 text-ink-400 transition hover:bg-red-50 hover:text-red-600"
|
||||
aria-label={`${user.name} loeschen`}
|
||||
aria-label={`${user.name} löschen`}
|
||||
>
|
||||
<svg className="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path
|
||||
@@ -243,7 +243,7 @@ export const UserManagement: React.FC = () => {
|
||||
{isModalOpen && (
|
||||
<Modal
|
||||
title={editingUser ? `${editingUser.name} bearbeiten` : 'Neuer Benutzer'}
|
||||
subtitle={editingUser ? `@${editingUser.username}` : 'Zugang fuer das perinco CRM anlegen'}
|
||||
subtitle={editingUser ? `@${editingUser.username}` : 'Zugang für das perinco CRM anlegen'}
|
||||
onClose={() => setIsModalOpen(false)}
|
||||
size="md"
|
||||
footer={
|
||||
@@ -324,7 +324,7 @@ export const UserManagement: React.FC = () => {
|
||||
required={!editingUser}
|
||||
value={form.password}
|
||||
onChange={(event) => set('password', event.target.value)}
|
||||
placeholder={editingUser ? 'Leer lassen, um es nicht zu aendern' : 'Mindestens 8 Zeichen'}
|
||||
placeholder={editingUser ? 'Leer lassen, um es nicht zu ändern' : 'Mindestens 8 Zeichen'}
|
||||
className={inputClass}
|
||||
autoComplete="new-password"
|
||||
/>
|
||||
@@ -352,7 +352,7 @@ export const UserManagement: React.FC = () => {
|
||||
|
||||
{userToDelete && (
|
||||
<ConfirmDialog
|
||||
title="Benutzer loeschen?"
|
||||
title="Benutzer löschen?"
|
||||
message={`"${userToDelete.name}" verliert den Zugang. Angelegte Kontakte bleiben erhalten, verlieren aber die Zuordnung.`}
|
||||
onConfirm={confirmDelete}
|
||||
onCancel={() => setUserToDelete(null)}
|
||||
|
||||
Reference in New Issue
Block a user