214 lines
13 KiB
Markdown
214 lines
13 KiB
Markdown
# Auth-Screens: Layout-Skizzen und Texte (Spec #1, Task U1)
|
||
|
||
Grundlage: `docs/specs/1-auth-registrierung-anmeldung.md` (§ 4.4 Meldungen, § 5.4 Screens, § 6 Plattform).
|
||
Komponenten: `app/lib/core/widgets/` (siehe `docs/design-system.md`). Alle Texte unten sind
|
||
**Vorschläge** und gehen über l10n (ARB); die ARB-Dateien pflegt der flutter-dev (A1/A2).
|
||
Schlüssel sind `lowerCamelCase` mit Präfix `auth`.
|
||
|
||
## 1. Gemeinsames Layout
|
||
|
||
- Alle sechs Screens nutzen `AppFormScaffold`. Kompakt (< 600 dp): Vollbild, scrollbar, Seitenrand 16 dp.
|
||
Ab 600 dp: zentrierte Karte, max. 480 dp breit (`AppBreakpoints.authCardMaxWidth`), Innenabstand 24 dp.
|
||
- Inhalt in einer Spalte, Abstand zwischen Feldern 16 dp, zwischen Gruppen 24 dp.
|
||
- Reihenfolge = Lesereihenfolge = Tab-Reihenfolge: Titel, Banner (falls vorhanden), Felder, Checkboxen,
|
||
Primärknopf, Sekundärlinks.
|
||
- Titel: `headlineSmall`, darunter optional ein Einleitungssatz in `bodyMedium`. Titel als Semantics-Überschrift
|
||
(`Semantics(header: true)`).
|
||
- Banner (`AppBanner`) stehen **über** den Feldern, direkt unter dem Titel. Fehler am Feld stehen unter dem Feld.
|
||
- Genau ein Primärknopf (`AppPrimaryButton`, volle Breite). Sekundäraktionen sind `TextButton`s (48 dp).
|
||
- Eingaben bleiben bei jedem Fehler erhalten. Während `submitting` sind Knopf und Felder gesperrt, der Knopf
|
||
zeigt den Spinner und den gesprochenen Text `authSubmitting`.
|
||
- Nach einem Fehler setzt der Screen den Fokus auf das erste fehlerhafte Feld; bei Banner-Fehlern bleibt der
|
||
Fokus am Knopf, das Banner wird als Live-Region angesagt.
|
||
- Enter im letzten Feld sendet ab (`TextInputAction.done`), sonst `next`.
|
||
|
||
Legende der Skizzen: `[ ]` Feld, `[x]` Checkbox, `( )` Primärknopf, `<…>` Link/TextButton, `!` Banner.
|
||
|
||
## 2. Skizzen
|
||
|
||
### RegisterScreen (`/register`)
|
||
|
||
```
|
||
Konto erstellen (Titel)
|
||
! Fehler-Banner (nur bei registrationRejected / network / rateLimited / unexpected)
|
||
E-Mail
|
||
[ name@example.com ] Fehler: authEmailInvalid
|
||
Passwort
|
||
[ •••••••••• (Auge) ] Hinweis: authPasswordRule / Fehler je Regel
|
||
Anzeigename
|
||
[ Alex 4/30 ] Fehler: authDisplayNameEmpty | TooLong | Invalid
|
||
[x] Ich bin mindestens 16 Jahre alt Fehler: authAgeNotConfirmed
|
||
[x] Ich habe die <Datenschutzerklärung> gelesen und stimme den <Nutzungsbedingungen> zu
|
||
Fehler: authTermsNotAccepted
|
||
( Konto erstellen )
|
||
<Schon ein Konto? Anmelden>
|
||
```
|
||
|
||
### CheckEmailScreen (`/register/check-email`, Modus Bestätigung bzw. Reset)
|
||
|
||
```
|
||
Prüfe dein Postfach (Titel)
|
||
Wir haben dir eine E-Mail geschickt, falls ... (Text, bodyLarge)
|
||
Der Link ist 1 Stunde gültig. Die E-Mail kann einige Minuten dauern. Schau auch im Spam-Ordner nach.
|
||
! Info-Banner "E-Mail wurde erneut gesendet" (nach Resend, auch bei emailSendLimited)
|
||
! Fehler-Banner bei rateLimited / network
|
||
(nur wenn E-Mail fehlt, z. B. nach Reload:) E-Mail [ ]
|
||
( E-Mail erneut senden ) -> nur Modus Bestätigung, gesperrt solange Anfrage läuft
|
||
<Zurück zur Anmeldung> (Modus Reset: <Andere E-Mail-Adresse eingeben> -> /forgot-password)
|
||
```
|
||
|
||
### LoginScreen (`/login`)
|
||
|
||
```
|
||
Anmelden
|
||
! Fehler-Banner: authInvalidCredentials | rateLimited | network (über dem Formular, nie am Feld)
|
||
! Info-Banner emailNotConfirmed + Aktion "Bestätigungs-E-Mail erneut senden"
|
||
E-Mail [ ]
|
||
Passwort [ ••••• (Auge) ]
|
||
( Anmelden )
|
||
<Passwort vergessen?>
|
||
<Konto erstellen>
|
||
```
|
||
|
||
### ForgotPasswordScreen (`/forgot-password`)
|
||
|
||
```
|
||
Passwort zurücksetzen
|
||
Gib die E-Mail-Adresse deines Kontos ein. Wir senden dir einen Link zum Zurücksetzen.
|
||
E-Mail [ ] Fehler: authEmailInvalid
|
||
( Link senden )
|
||
<Zurück zur Anmeldung>
|
||
```
|
||
|
||
### EmailLinkScreen (`/auth/confirm`)
|
||
|
||
Zustände: `idle` (Knopf), `submitting`, `success` (nur Bestätigung), `error` (Link ungültig).
|
||
|
||
```
|
||
E-Mail-Adresse bestätigen | Neues Passwort festlegen (Titel je Typ)
|
||
Ein Klick genügt, um fortzufahren.
|
||
( E-Mail-Adresse bestätigen ) | ( Weiter zum neuen Passwort )
|
||
|
||
Erfolg: ! Info-Banner "E-Mail bestätigt" (+ Mobile-Web: "Du kannst dich jetzt auch in der App anmelden.")
|
||
Fehler: ! Fehler-Banner "Der Link ist abgelaufen ..." ( Neuen Link anfordern )
|
||
```
|
||
|
||
### ResetPasswordScreen (`/reset-password`)
|
||
|
||
```
|
||
Neues Passwort festlegen
|
||
Neues Passwort
|
||
[ ••••••••• (Auge) ] Live-Regeln: authPasswordRule, Fehler je Regel / samePassword
|
||
( Passwort speichern )
|
||
<Abbrechen> -> signOut
|
||
Erfolg: Hinweis authPasswordChanged, dann Weiterleitung nach /
|
||
```
|
||
|
||
## 3. Textvorschläge
|
||
|
||
Ton: du-Form, kurz, sachlich-freundlich, keine Schuldzuweisung. Platzhalter in ICU-Syntax (`{n}`).
|
||
Neutrale Texte (Krit. 4, F12) verraten nie, ob eine Adresse registriert ist.
|
||
|
||
### 3.1 Meldungen aus § 4.4 (Fehlerabbildung)
|
||
|
||
| Schlüssel | de | en |
|
||
|---|---|---|
|
||
| `authErrorInvalidCredentials` | E-Mail-Adresse oder Passwort ist nicht korrekt. | Email address or password is incorrect. |
|
||
| `authErrorEmailNotConfirmed` | Bestätige zuerst deine E-Mail-Adresse. Wir haben dir dazu eine E-Mail geschickt. | Please confirm your email address first. We sent you an email for this. |
|
||
| `authActionResendConfirmation` | Bestätigungs-E-Mail erneut senden | Resend confirmation email |
|
||
| `authErrorRateLimited` | Zu viele Versuche. Bitte warte einige Minuten und versuche es erneut. | Too many attempts. Please wait a few minutes and try again. |
|
||
| `authErrorWeakPasswordLength` | Das Passwort ist zu kurz. | The password is too short. |
|
||
| `authErrorWeakPasswordCharacters` | Das Passwort ist zu einfach. Wähle ein anderes. | The password is too simple. Choose a different one. |
|
||
| `authErrorWeakPasswordPwned` | Dieses Passwort ist sehr verbreitet und leicht zu erraten. Wähle ein anderes. | This password is very common and easy to guess. Choose a different one. |
|
||
| `authErrorSamePassword` | Wähle ein anderes als dein bisheriges Passwort. | Choose a password different from your current one. |
|
||
| `authErrorLinkInvalidOrExpired` | Der Link ist abgelaufen oder wurde schon benutzt. | The link has expired or has already been used. |
|
||
| `authActionRequestNewLink` | Neuen Link anfordern | Request a new link |
|
||
| `authErrorEmailInvalid` | Gib eine gültige E-Mail-Adresse ein. | Enter a valid email address. |
|
||
| `authErrorRegistrationRejected` | Registrierung nicht möglich. Bitte prüfe deine Angaben. | Registration is not possible. Please check your details. |
|
||
| `authErrorNetwork` | Keine Verbindung. Für diesen Schritt brauchst du Internet. | No connection. You need internet access for this step. |
|
||
| `authErrorUnexpected` | Etwas ist schiefgelaufen. Bitte versuche es erneut. | Something went wrong. Please try again. |
|
||
| `authActionRetry` | Erneut versuchen | Try again |
|
||
|
||
`emailSendLimited` hat bewusst **keinen** eigenen Text: Register/Forgot/CheckEmail zeigen den neutralen Erfolgstext
|
||
(§ 3.3), nur der Resend im LoginScreen zeigt `authErrorRateLimited`.
|
||
|
||
### 3.2 Meldungen aus § 5.4 (Felder, Banner, Hinweise)
|
||
|
||
| Schlüssel | de | en |
|
||
|---|---|---|
|
||
| `authPasswordTooShort` | Mindestens 10 Zeichen – es fehlen noch {missing}. | At least 10 characters – {missing} more needed. |
|
||
| `authPasswordCommon` | Dieses Passwort ist sehr verbreitet und leicht zu erraten. Wähle ein anderes. | This password is very common and easy to guess. Choose a different one. |
|
||
| `authPasswordRule` | Mindestens 10 Zeichen. Kein sehr verbreitetes Passwort. | At least 10 characters. Not a very common password. |
|
||
| `authPasswordRequired` | Gib ein Passwort ein. | Enter a password. |
|
||
| `authDisplayNameEmpty` | Gib einen Anzeigenamen ein. | Enter a display name. |
|
||
| `authDisplayNameTooLong` | Der Anzeigename darf höchstens {max} Zeichen lang sein. | The display name can be at most {max} characters long. |
|
||
| `authDisplayNameInvalid` | Dieser Anzeigename ist nicht erlaubt. Verwende sichtbare Zeichen. | This display name is not allowed. Use visible characters. |
|
||
| `authAgeNotConfirmed` | Shuffle ist erst ab 16 Jahren nutzbar. | Shuffle can only be used from age 16. |
|
||
| `authTermsNotAccepted` | Bitte stimme Datenschutzerklärung und Nutzungsbedingungen zu. | Please agree to the privacy policy and the terms of use. |
|
||
| `authFieldEmailLabel` | E-Mail-Adresse | Email address |
|
||
| `authFieldPasswordLabel` | Passwort | Password |
|
||
| `authFieldNewPasswordLabel` | Neues Passwort | New password |
|
||
| `authFieldDisplayNameLabel` | Anzeigename | Display name |
|
||
| `authPasswordShow` | Passwort anzeigen | Show password |
|
||
| `authPasswordHide` | Passwort verbergen | Hide password |
|
||
| `authCheckboxAgeLabel` | Ich bin mindestens 16 Jahre alt | I am at least 16 years old |
|
||
| `authCheckboxTermsPrefix` | Ich habe die | I have read the |
|
||
| `authCheckboxTermsPrivacyLink` | Datenschutzerklärung | privacy policy |
|
||
| `authCheckboxTermsMiddle` | gelesen und stimme den | and agree to the |
|
||
| `authCheckboxTermsTermsLink` | Nutzungsbedingungen | terms of use |
|
||
| `authCheckboxTermsSuffix` | zu | (leer) |
|
||
| `authBannerTypeError` | Fehler | Error |
|
||
| `authBannerTypeInfo` | Hinweis | Note |
|
||
| `authSubmitting` | Bitte warten … | Please wait … |
|
||
|
||
Hinweis zur Checkbox „Nutzungsbedingungen“: Satzbau ist je Sprache verschieden. Der Satz wird deshalb aus den
|
||
Segmenten `Prefix`, `PrivacyLink`, `Middle`, `TermsLink`, `Suffix` zusammengesetzt (`AppCheckboxField.rich`);
|
||
im Englischen bleibt `Suffix` leer. Alternativ ein ICU-Satz mit Platzhaltern, den der Screen an den Linkstellen
|
||
teilt – Entscheidung beim flutter-dev (A2).
|
||
|
||
### 3.3 Screen-Texte
|
||
|
||
| Schlüssel | de | en |
|
||
|---|---|---|
|
||
| `authRegisterTitle` | Konto erstellen | Create account |
|
||
| `authRegisterSubmit` | Konto erstellen | Create account |
|
||
| `authRegisterHaveAccount` | Schon ein Konto? Anmelden | Already have an account? Sign in |
|
||
| `authCheckEmailTitle` | Prüfe dein Postfach | Check your inbox |
|
||
| `authCheckEmailBody` | Wir haben dir eine E-Mail geschickt, falls die Adresse noch nicht registriert ist. Folge dem Link darin, um fortzufahren. | We sent you an email if the address is not registered yet. Follow the link in it to continue. |
|
||
| `authCheckEmailBodyReset` | Wir haben dir eine E-Mail mit einem Link zum Zurücksetzen geschickt, falls zu dieser Adresse ein Konto besteht. | We sent you an email with a reset link if an account exists for this address. |
|
||
| `authCheckEmailDelayHint` | Die E-Mail kann einige Minuten dauern. Schau auch im Spam-Ordner nach. | The email can take a few minutes. Also check your spam folder. |
|
||
| `authCheckEmailValidity` | Der Link ist {duration} gültig. | The link is valid for {duration}. |
|
||
| `authCheckEmailValidityOneHour` | 1 Stunde | 1 hour |
|
||
| `authCheckEmailResend` | E-Mail erneut senden | Resend email |
|
||
| `authCheckEmailResent` | Wir haben die E-Mail erneut gesendet, falls es zu dieser Adresse etwas zu senden gibt. | We resent the email, if there is something to send for this address. |
|
||
| `authCheckEmailDifferentAddress` | Andere E-Mail-Adresse eingeben | Enter a different email address |
|
||
| `authBackToLogin` | Zurück zur Anmeldung | Back to sign in |
|
||
| `authLoginTitle` | Anmelden | Sign in |
|
||
| `authLoginSubmit` | Anmelden | Sign in |
|
||
| `authLoginForgotPassword` | Passwort vergessen? | Forgot password? |
|
||
| `authLoginCreateAccount` | Konto erstellen | Create account |
|
||
| `authForgotTitle` | Passwort zurücksetzen | Reset password |
|
||
| `authForgotBody` | Gib die E-Mail-Adresse deines Kontos ein. Wir senden dir einen Link zum Zurücksetzen. | Enter the email address of your account. We will send you a reset link. |
|
||
| `authForgotSubmit` | Link senden | Send link |
|
||
| `authConfirmTitle` | E-Mail-Adresse bestätigen | Confirm email address |
|
||
| `authConfirmBody` | Ein Klick genügt, um deine E-Mail-Adresse zu bestätigen. | One click is enough to confirm your email address. |
|
||
| `authConfirmSubmit` | E-Mail-Adresse bestätigen | Confirm email address |
|
||
| `authConfirmSuccess` | E-Mail bestätigt. | Email confirmed. |
|
||
| `authConfirmSuccessMobileWeb` | Du kannst dich jetzt auch in der App anmelden. | You can now also sign in in the app. |
|
||
| `authRecoveryTitle` | Neues Passwort festlegen | Set a new password |
|
||
| `authRecoveryBody` | Ein Klick genügt, um ein neues Passwort festzulegen. | One click is enough to set a new password. |
|
||
| `authRecoverySubmit` | Weiter zum neuen Passwort | Continue to new password |
|
||
| `authResetTitle` | Neues Passwort festlegen | Set a new password |
|
||
| `authResetSubmit` | Passwort speichern | Save password |
|
||
| `authResetCancel` | Abbrechen | Cancel |
|
||
| `authPasswordChanged` | Passwort geändert. Andere Geräte werden abgemeldet; das kann bis zu einer Stunde dauern. | Password changed. Other devices will be signed out; this can take up to an hour. |
|
||
|
||
## 4. Barrierefreiheit pro Screen (Checkliste für A2–A4 und T2)
|
||
|
||
- Jedes Feld hat ein sichtbares Label (kein Platzhalter-Label); Fehler per `errorText` (Icon + Text + Live-Region).
|
||
- Banner und Fehler werden beim Erscheinen vorgelesen (Live-Region); keine reinen Farb-Signale.
|
||
- Passwortfelder: `AppPasswordField` mit `isNewPassword: true` bei Register/Reset, sonst `false`; E-Mail mit
|
||
`AutofillHints.email` (Login: `AutofillHints.username`/`email`), `TextInputType.emailAddress`.
|
||
- Alle interaktiven Elemente >= 48 dp, Tab-Reihenfolge wie Lesereihenfolge, Fokus sichtbar.
|
||
- Test je Screen mit `textScaler` 2.0 (Android 320 x 640), `androidTapTargetGuideline`,
|
||
`labeledTapTargetGuideline`, `textContrastGuideline`, Hell und Dunkel (T2).
|