Redesign the setup flow and consolidate the CSS into one primitives layer
Onboarding asks explicitly for one or two parents and shows one card per parent for balances; the balance form is per parent with inline validation; the partner can be filled from the FK deduction or added from it. Settings and Dashboard reuse the same form. CSS: bare buttons carry no colour any more; buttons, cards, choice cards, fields, alerts, badges, eyebrow and modal chrome are defined once in primitives.css. Media queries live only in responsive.css. A style guard test blocks hex, !important and stray media queries. Bilingual fixes: calendar selects size by content, header no longer wraps. Vitest is capped at four workers. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
+72
-26
@@ -38,45 +38,91 @@ export function Auth() {
|
||||
}
|
||||
}
|
||||
|
||||
// Switching tabs clears any error from the previous tab's attempt — a
|
||||
// failed login's error text should not linger, confusingly, once the
|
||||
// person has moved on to creating an account (or back).
|
||||
const switchTab = (register: boolean) => {
|
||||
setIsRegister(register)
|
||||
setError(null)
|
||||
}
|
||||
|
||||
return (
|
||||
<main className="auth-page">
|
||||
<div className="auth-page__card">
|
||||
<p className="auth-page__brand">{t('app.name')}</p>
|
||||
<div className="auth-page__card card">
|
||||
<p className="eyebrow auth-page__brand">{t('app.name')}</p>
|
||||
<div className="auth-page__tabs">
|
||||
<button
|
||||
type="button"
|
||||
className="btn btn--ghost auth-page__tab"
|
||||
aria-pressed={!isRegister}
|
||||
onClick={() => switchTab(false)}
|
||||
data-testid="auth-tab-login"
|
||||
>
|
||||
{t('auth.loginButton')}
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
className="btn btn--ghost auth-page__tab"
|
||||
aria-pressed={isRegister}
|
||||
onClick={() => switchTab(true)}
|
||||
data-testid="auth-tab-register"
|
||||
>
|
||||
{t('auth.createAccountButton')}
|
||||
</button>
|
||||
</div>
|
||||
<h1 className="auth-page__title">{isRegister ? t('auth.createAccountTitle') : t('auth.loginTitle')}</h1>
|
||||
<form className="auth-page__form" onSubmit={(e) => void handleSubmit(e)}>
|
||||
{isRegister && (
|
||||
<input
|
||||
placeholder={t('auth.namePlaceholder')}
|
||||
value={displayName}
|
||||
onChange={(e) => setDisplayName(e.target.value)}
|
||||
/>
|
||||
<div className="field">
|
||||
<label htmlFor="auth-name" className="field__label">
|
||||
{t('auth.nameLabel')}
|
||||
</label>
|
||||
<input
|
||||
id="auth-name"
|
||||
className="field__control"
|
||||
placeholder={t('auth.namePlaceholder')}
|
||||
value={displayName}
|
||||
onChange={(e) => setDisplayName(e.target.value)}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
<input
|
||||
type="email"
|
||||
data-testid="auth-email"
|
||||
placeholder={t('auth.emailPlaceholder')}
|
||||
value={email}
|
||||
onChange={(e) => setEmail(e.target.value)}
|
||||
/>
|
||||
<input
|
||||
type="password"
|
||||
data-testid="auth-password"
|
||||
placeholder={t('auth.passwordPlaceholder')}
|
||||
value={password}
|
||||
onChange={(e) => setPassword(e.target.value)}
|
||||
/>
|
||||
<div className="field">
|
||||
<label htmlFor="auth-email" className="field__label">
|
||||
{t('auth.emailLabel')}
|
||||
</label>
|
||||
<input
|
||||
id="auth-email"
|
||||
type="email"
|
||||
data-testid="auth-email"
|
||||
className="field__control"
|
||||
placeholder={t('auth.emailPlaceholder')}
|
||||
value={email}
|
||||
onChange={(e) => setEmail(e.target.value)}
|
||||
/>
|
||||
</div>
|
||||
<div className="field">
|
||||
<label htmlFor="auth-password" className="field__label">
|
||||
{t('auth.passwordLabel')}
|
||||
</label>
|
||||
<input
|
||||
id="auth-password"
|
||||
type="password"
|
||||
data-testid="auth-password"
|
||||
className="field__control"
|
||||
placeholder={t('auth.passwordPlaceholder')}
|
||||
value={password}
|
||||
onChange={(e) => setPassword(e.target.value)}
|
||||
/>
|
||||
</div>
|
||||
{error && (
|
||||
<p role="alert" className="auth-page__error">
|
||||
<p role="alert" className="alert alert--error">
|
||||
{error}
|
||||
</p>
|
||||
)}
|
||||
<button type="submit" data-testid="auth-submit">
|
||||
<button type="submit" className="btn btn--primary btn--block" data-testid="auth-submit">
|
||||
{isRegister ? t('auth.registerButton') : t('auth.loginButton')}
|
||||
</button>
|
||||
</form>
|
||||
<button type="button" className="auth-page__switch button--ghost" onClick={() => setIsRegister((v) => !v)}>
|
||||
{isRegister ? t('auth.haveAccountButton') : t('auth.createAccountButton')}
|
||||
</button>
|
||||
</div>
|
||||
</main>
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user