229 lines
9.6 KiB
Markdown
229 lines
9.6 KiB
Markdown
---
|
|
phase: 02-layout-and-brand-identity
|
|
plan: 01
|
|
type: execute
|
|
wave: 1
|
|
depends_on: []
|
|
files_modified:
|
|
- frontend/src/components/ui/alert.tsx
|
|
- frontend/src/pages/LoginPage.tsx
|
|
- frontend/src/pages/RegisterPage.tsx
|
|
- frontend/src/pages/LoginPage.test.tsx
|
|
- frontend/src/pages/RegisterPage.test.tsx
|
|
autonomous: true
|
|
requirements: [AUTH-01, AUTH-02, AUTH-03, AUTH-04]
|
|
|
|
must_haves:
|
|
truths:
|
|
- "Login page renders on a pastel gradient background, not plain white"
|
|
- "Login page displays a gradient text wordmark for the app name"
|
|
- "Register page has the same branded gradient and wordmark as login"
|
|
- "Auth form errors display inside a styled Alert with an error icon"
|
|
artifacts:
|
|
- path: "frontend/src/components/ui/alert.tsx"
|
|
provides: "shadcn Alert component with destructive variant"
|
|
- path: "frontend/src/pages/LoginPage.tsx"
|
|
provides: "Branded login with gradient bg, wordmark, alert errors"
|
|
contains: "linear-gradient"
|
|
- path: "frontend/src/pages/RegisterPage.tsx"
|
|
provides: "Branded register matching login look"
|
|
contains: "linear-gradient"
|
|
- path: "frontend/src/pages/LoginPage.test.tsx"
|
|
provides: "Unit tests for AUTH-01, AUTH-02, AUTH-04"
|
|
- path: "frontend/src/pages/RegisterPage.test.tsx"
|
|
provides: "Unit tests for AUTH-03"
|
|
key_links:
|
|
- from: "frontend/src/pages/LoginPage.tsx"
|
|
to: "frontend/src/lib/palette.ts"
|
|
via: "import palette for gradient light shades"
|
|
pattern: "palette\\."
|
|
- from: "frontend/src/pages/LoginPage.tsx"
|
|
to: "frontend/src/components/ui/alert.tsx"
|
|
via: "Alert destructive for error display"
|
|
pattern: "Alert.*destructive"
|
|
---
|
|
|
|
<objective>
|
|
Brand the auth screens (login and register) with a pastel gradient background, gradient text wordmark, and styled error alerts -- transforming them from plain white cards into the first branded touchpoint users see.
|
|
|
|
Purpose: Login is the first impression. A branded auth surface sets the perceptual quality bar before users even reach the dashboard.
|
|
Output: Polished LoginPage.tsx and RegisterPage.tsx with gradient backgrounds, wordmark, Alert errors, and passing unit tests.
|
|
</objective>
|
|
|
|
<execution_context>
|
|
@/home/jean-luc-makiola/.claude/get-shit-done/workflows/execute-plan.md
|
|
@/home/jean-luc-makiola/.claude/get-shit-done/templates/summary.md
|
|
</execution_context>
|
|
|
|
<context>
|
|
@.planning/PROJECT.md
|
|
@.planning/ROADMAP.md
|
|
@.planning/STATE.md
|
|
@.planning/phases/02-layout-and-brand-identity/02-RESEARCH.md
|
|
@.planning/phases/02-layout-and-brand-identity/02-VALIDATION.md
|
|
|
|
@frontend/src/pages/LoginPage.tsx
|
|
@frontend/src/pages/RegisterPage.tsx
|
|
@frontend/src/lib/palette.ts
|
|
|
|
<interfaces>
|
|
<!-- Executor needs these from palette.ts for the gradient background -->
|
|
|
|
From frontend/src/lib/palette.ts:
|
|
```typescript
|
|
export const palette: Record<CategoryType, CategoryShades> = {
|
|
saving: { light: 'oklch(0.95 0.04 280)', ... },
|
|
bill: { light: 'oklch(0.96 0.03 250)', ... },
|
|
investment: { light: 'oklch(0.96 0.04 320)', ... },
|
|
// ... other types
|
|
}
|
|
```
|
|
|
|
From frontend/src/index.css (token values for wordmark gradient):
|
|
```css
|
|
--primary: oklch(0.50 0.12 260);
|
|
/* Shift hue to ~300-320 for the gradient end stop */
|
|
```
|
|
|
|
From LoginPage.tsx current structure:
|
|
```typescript
|
|
interface Props {
|
|
auth: AuthContext
|
|
onToggle: () => void
|
|
}
|
|
// Uses: useState for email, password, error, loading
|
|
// Renders: Card with CardHeader, form with CardContent, CardFooter
|
|
// Current wrapper: <div className="flex min-h-screen items-center justify-center bg-background">
|
|
// Current error: <p className="text-sm text-destructive">{error}</p>
|
|
```
|
|
</interfaces>
|
|
</context>
|
|
|
|
<tasks>
|
|
|
|
<task type="auto">
|
|
<name>Task 1: Install shadcn Alert and create test scaffolds for auth pages</name>
|
|
<files>frontend/src/components/ui/alert.tsx, frontend/src/pages/LoginPage.test.tsx, frontend/src/pages/RegisterPage.test.tsx</files>
|
|
<action>
|
|
1. Install the shadcn alert component:
|
|
```bash
|
|
cd frontend && bunx --bun shadcn add alert
|
|
```
|
|
Verify `frontend/src/components/ui/alert.tsx` exists after installation.
|
|
|
|
2. Create `frontend/src/pages/LoginPage.test.tsx` with these test cases (all should FAIL initially since the features are not yet implemented):
|
|
- AUTH-01: Login page wrapper div has an inline style containing `linear-gradient` (gradient background)
|
|
- AUTH-02: Login page renders an element with `data-testid="wordmark"` that has an inline style containing `background` (gradient text)
|
|
- AUTH-04: When error state is set, an element with `role="alert"` is rendered (shadcn Alert uses role="alert")
|
|
- AUTH-04: The alert contains an AlertCircle icon (verify by checking for an SVG inside the alert)
|
|
|
|
3. Create `frontend/src/pages/RegisterPage.test.tsx` with these test cases:
|
|
- AUTH-03: Register page wrapper div has an inline style containing `linear-gradient`
|
|
- AUTH-03: Register page renders an element with `data-testid="wordmark"`
|
|
|
|
Test setup notes:
|
|
- Import `{ render, screen }` from `@testing-library/react`
|
|
- LoginPage requires `auth` prop with `login` function and `onToggle` prop -- mock them with `vi.fn()`
|
|
- RegisterPage requires `auth` prop with `register` function and `onToggle` prop
|
|
- Both pages use `useTranslation` -- mock `react-i18next` with `vi.mock('react-i18next', () => ({ useTranslation: () => ({ t: (key: string) => key }) }))`
|
|
- The `AuthContext` type must be satisfied: `{ user: null, loading: false, login: vi.fn(), register: vi.fn(), logout: vi.fn(), token: null }`
|
|
</action>
|
|
<verify>
|
|
<automated>cd /home/jean-luc-makiola/Development/projects/SimpleFinanceDash/frontend && bun vitest run src/pages/LoginPage.test.tsx src/pages/RegisterPage.test.tsx --reporter=verbose 2>&1 | tail -20</automated>
|
|
</verify>
|
|
<done>alert.tsx exists in ui/, LoginPage.test.tsx has 4 test cases, RegisterPage.test.tsx has 2 test cases. Tests run (expected: most FAIL since features not yet implemented).</done>
|
|
</task>
|
|
|
|
<task type="auto">
|
|
<name>Task 2: Brand LoginPage and RegisterPage with gradient background, wordmark, and Alert errors</name>
|
|
<files>frontend/src/pages/LoginPage.tsx, frontend/src/pages/RegisterPage.tsx</files>
|
|
<action>
|
|
Apply all four AUTH requirements to both auth pages simultaneously (AUTH-03 requires register to mirror login).
|
|
|
|
**LoginPage.tsx changes:**
|
|
|
|
1. Add imports:
|
|
```typescript
|
|
import { palette } from '@/lib/palette'
|
|
import { Alert, AlertDescription } from '@/components/ui/alert'
|
|
import { AlertCircle } from 'lucide-react'
|
|
```
|
|
|
|
2. Replace the outer wrapper div `bg-background` with a gradient background using palette light shades (AUTH-01):
|
|
```tsx
|
|
<div
|
|
className="flex min-h-screen items-center justify-center"
|
|
style={{
|
|
background: `linear-gradient(135deg, ${palette.saving.light}, ${palette.bill.light}, ${palette.investment.light})`,
|
|
}}
|
|
>
|
|
```
|
|
Use the `light` shades (lightness 0.95-0.97, chroma 0.03-0.04) for a subtle tinted-paper feel, NOT medium or base shades which would be too saturated as backgrounds.
|
|
|
|
3. Add a gradient text wordmark in the CardHeader (AUTH-02). Replace the `<CardDescription>{t('app.title')}</CardDescription>` with a styled wordmark element:
|
|
```tsx
|
|
<span
|
|
data-testid="wordmark"
|
|
className="text-2xl font-bold tracking-tight"
|
|
style={{
|
|
background: `linear-gradient(to right, oklch(0.50 0.12 260), oklch(0.50 0.12 320))`,
|
|
WebkitBackgroundClip: 'text',
|
|
WebkitTextFillColor: 'transparent',
|
|
backgroundClip: 'text',
|
|
}}
|
|
>
|
|
{t('app.title')}
|
|
</span>
|
|
```
|
|
The gradient goes from --primary hue (260) to a pink-shifted hue (320). Keep `<CardTitle>{t('auth.login')}</CardTitle>` as-is above the wordmark.
|
|
|
|
4. Replace the plain error `<p>` with a shadcn Alert (AUTH-04):
|
|
```tsx
|
|
{error && (
|
|
<Alert variant="destructive">
|
|
<AlertCircle className="h-4 w-4" />
|
|
<AlertDescription>{error}</AlertDescription>
|
|
</Alert>
|
|
)}
|
|
```
|
|
|
|
5. Add `shadow-lg` to the Card for visual lift against the gradient: `<Card className="w-full max-w-md shadow-lg">`
|
|
|
|
**RegisterPage.tsx changes (AUTH-03):**
|
|
|
|
Apply the identical structural changes as LoginPage:
|
|
- Same gradient background wrapper with palette light shades
|
|
- Same wordmark element with `data-testid="wordmark"`
|
|
- Same Alert destructive for error display
|
|
- Same Card shadow-lg
|
|
- Keep `<CardTitle>{t('auth.register')}</CardTitle>` (not login)
|
|
- Import palette, Alert, AlertDescription, AlertCircle
|
|
|
|
Both files should be near-mirrors structurally. The only differences are: CardTitle text, form fields (register has displayName), submit handler, footer link text.
|
|
</action>
|
|
<verify>
|
|
<automated>cd /home/jean-luc-makiola/Development/projects/SimpleFinanceDash/frontend && bun vitest run src/pages/ --reporter=verbose && bun run build 2>&1 | tail -5</automated>
|
|
</verify>
|
|
<done>All 6 test cases pass (4 LoginPage + 2 RegisterPage). Production build succeeds. LoginPage and RegisterPage both render gradient backgrounds, gradient text wordmarks, and Alert-based error displays.</done>
|
|
</task>
|
|
|
|
</tasks>
|
|
|
|
<verification>
|
|
- `cd frontend && bun vitest run src/pages/ --reporter=verbose` -- all tests green
|
|
- `cd frontend && bun run build` -- zero errors
|
|
- `cd frontend && bun vitest run` -- full suite green (no regressions)
|
|
</verification>
|
|
|
|
<success_criteria>
|
|
- Login page has a pastel gradient background using palette.ts light shades (not plain white)
|
|
- Both auth pages display a gradient text wordmark for the app name
|
|
- Auth errors render in a shadcn Alert with destructive variant and AlertCircle icon
|
|
- Register page is structurally identical to login in branding treatment
|
|
- All new and existing tests pass, production build succeeds
|
|
</success_criteria>
|
|
|
|
<output>
|
|
After completion, create `.planning/phases/02-layout-and-brand-identity/02-layout-and-brand-identity-02-01-SUMMARY.md`
|
|
</output>
|