Files
roa2web-service-auto/features/phases/phase-1-forms.md
Marius Mutu ca45737af3 feat(css): Phase 2 - Add global pattern foundation
- Create interactive.css (loading spinners, trends, collapse patterns)
- Create dashboard.css (page headers, metrics grid, breakdowns)
- Create animations.css (slideDown, fadeIn, pulse transitions)
- Create tokens.css (extended design tokens for cards/animations/metrics)
- Create primevue-overrides.css (centralized PrimeVue component styling)
- Update main.css with new pattern imports
- Zero visual changes (additive foundation only)

Files created: 5 new CSS pattern files
Lines added: 431 lines of reusable patterns
CSS bundle: 401.25 kB (before optimization)
Build status:  Successful

Phase: 2/7 complete
Next: Phase 3 - PrimeVue Centralizare

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-18 14:14:54 +02:00

760 lines
17 KiB
Markdown

# Phase 1: Standardizare Formulare ⚡
**Priority:** 🔥 High (User-facing impact)
**Duration:** 10-12 hours (Actual: 2 hours)
**Status:** ✅ Complete
**Risk Level:** Medium
---
## Obiective
1. **Elimină pattern-uri inconsistente** - 3 pattern-uri diferite → 1 standard
2. **Utilizează forms.css existent** - 460 linii de sistem complet
3. **Șterge CSS duplicat** - ~150 linii eliminate
4. **Crează template** - Pentru formulare viitoare
---
## Situație Actuală
### Problem Statement
Fiecare view reinventează formulare-le diferit:
| View | Field Wrapper | Label Class | Lines CSS | Status |
|------|--------------|-------------|-----------|--------|
| LoginView.vue | `.field` | `.field-label` | 70 lines | ❌ Custom |
| InvoicesView.vue | `.filter-group` | `.filter-label` | 80 lines | ❌ Custom |
| **forms.css** | `.form-group` | `.form-label` | 460 lines | ✅ Standard NEUTILIZAT |
### Impact
- User experience inconsistent
- Duplicate code maintenance
- forms.css (460 linii) este neutilizat
- Hardcoded PrimeVue overrides cu `!important`
---
## Task Breakdown (18 tasks)
### 1. Setup & Preparation (3 tasks)
#### Task 1.1: Create Feature Branch
**Status:** ⏸️ Not Started | **Est:** 5 min
```bash
# Create and switch to feature branch
git checkout -b feature/css-refactoring
# Verify clean state
git status
```
**Acceptance Criteria:**
- [ ] Branch created: `feature/css-refactoring`
- [ ] No uncommitted changes
- [ ] Pushed to remote
---
#### Task 1.2: Capture Playwright Baseline Snapshots
**Status:** ⏸️ Not Started | **Est:** 15 min
```bash
cd reports-app/frontend
# Capture baseline screenshots before any changes
npm run test:e2e -- --update-snapshots
# Verify snapshots created
ls -la tests/e2e/**/*.png
```
**Snapshots to Capture:**
- Login page (desktop, tablet, mobile)
- Dashboard page
- Invoices page
- All form states (empty, filled, error, valid)
**Acceptance Criteria:**
- [ ] Baseline snapshots captured for all views
- [ ] Snapshots committed to git
- [ ] Test suite passes with snapshots
---
#### Task 1.3: Review Existing forms.css
**Status:** ⏸️ Not Started | **Est:** 30 min
**File:** `reports-app/frontend/src/assets/css/components/forms.css`
**Review:**
- [ ] Read all 460 lines
- [ ] Document available classes:
- `.form` - Form container
- `.form-group` - Field wrapper
- `.form-label` - Label styling
- `.form-input` - Input styling
- `.form-row` - Horizontal layout
- `.form-error` - Error message
- `.form-help` - Help text
- [ ] Note validation states: `.valid`, `.invalid`
- [ ] Understand responsive behavior
**Acceptance Criteria:**
- [ ] All available classes documented
- [ ] Pattern examples identified
- [ ] Ready to apply to components
---
### 2. LoginView.vue Refactoring (6 tasks)
**File:** `reports-app/frontend/src/views/LoginView.vue`
#### Task 2.1: Update Template - Field Wrapper
**Status:** ⏸️ Not Started | **Est:** 20 min
**Current (lines 95-106):**
```vue
<div class="field">
<label for="username" class="field-label">Utilizator</label>
<InputText
id="username"
v-model="credentials.username"
placeholder="Introduceți numele de utilizator"
:class="{ 'p-invalid': formErrors.username }"
class="w-full"
/>
</div>
```
**Updated:**
```vue
<div class="form-group">
<label for="username" class="form-label required">Utilizator</label>
<InputText
id="username"
v-model="credentials.username"
placeholder="Introduceți numele de utilizator"
:class="{ 'invalid': formErrors.username }"
class="form-input w-full"
/>
<span v-if="formErrors.username" class="form-error">
{{ formErrors.username }}
</span>
</div>
```
**Changes:**
- `.field``.form-group`
- `.field-label``.form-label` (with `.required` for required fields)
- `p-invalid``invalid` (forms.css class)
- Add `.form-input` to InputText
- Add `.form-error` for error messages
**Acceptance Criteria:**
- [ ] All form fields updated
- [ ] Error messages use `.form-error`
- [ ] No custom field wrapper classes
---
#### Task 2.2: Update Template - Password Field
**Status:** ⏸️ Not Started | **Est:** 15 min
**Current:**
```vue
<div class="field">
<label for="password" class="field-label">Parolă</label>
<Password
id="password"
v-model="credentials.password"
:feedback="false"
toggleMask
/>
</div>
```
**Updated:**
```vue
<div class="form-group">
<label for="password" class="form-label required">Parolă</label>
<Password
id="password"
v-model="credentials.password"
:feedback="false"
toggleMask
:class="{ 'invalid': formErrors.password }"
class="w-full"
/>
<span v-if="formErrors.password" class="form-error">
{{ formErrors.password }}
</span>
</div>
```
**Acceptance Criteria:**
- [ ] Password field uses `.form-group`
- [ ] Label uses `.form-label required`
- [ ] Error handling consistent
---
#### Task 2.3: Remove Custom Form CSS
**Status:** ⏸️ Not Started | **Est:** 10 min
**Delete Lines 234-243:**
```css
/* DELETE THIS - forms.css provides these */
.field {
margin-bottom: 1.5rem;
}
.field-label {
display: block;
margin-bottom: 0.5rem;
font-weight: 600;
color: var(--text-color);
}
```
**Acceptance Criteria:**
- [ ] Lines 234-243 deleted
- [ ] No `.field` or `.field-label` in scoped styles
- [ ] Form still renders correctly
---
#### Task 2.4: Remove PrimeVue Deep Overrides
**Status:** ⏸️ Not Started | **Est:** 15 min
**Delete Lines 269-288:**
```css
/* DELETE THIS - Will be moved to global primevue-overrides.css in Phase 3 */
:deep(.p-inputtext),
:deep(.p-password input) {
border: 2px solid #e5e7eb !important;
padding: 12px !important;
font-size: 16px !important;
transition: all 0.3s ease !important;
border-radius: 8px !important;
}
:deep(.p-inputtext:focus),
:deep(.p-password input:focus) {
border-color: #3b82f6 !important;
box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.1) !important;
outline: none !important;
}
/* ... more :deep() rules ... */
```
**Note:** These will be added to global `primevue-overrides.css` in Phase 3.
**Acceptance Criteria:**
- [ ] All `:deep()` rules removed from LoginView.vue
- [ ] No `!important` in scoped styles
- [ ] Form inputs still styled (via forms.css)
---
#### Task 2.5: Test Login Functionality
**Status:** ⏸️ Not Started | **Est:** 30 min
**Test Checklist:**
- [ ] Login form renders correctly
- [ ] All fields are accessible
- [ ] Validation works on blur
- [ ] Error messages display correctly
- [ ] Form submission works
- [ ] Success login redirects to dashboard
- [ ] Failed login shows error
- [ ] Keyboard navigation works (Tab through fields)
- [ ] Enter key submits form
**Test Scenarios:**
1. Empty form submission → validation errors
2. Invalid credentials → API error message
3. Valid credentials → successful login
4. Field focus states visible
5. Error states visible
**Acceptance Criteria:**
- [ ] All test scenarios pass
- [ ] No functionality broken
- [ ] No console errors
---
#### Task 2.6: Visual Regression Test
**Status:** ⏸️ Not Started | **Est:** 15 min
```bash
# Run Playwright tests
npm run test:e2e -- tests/e2e/auth/login.spec.ts
# Check for visual differences
npm run test:e2e:report
```
**Visual Checks:**
- [ ] Login form layout identical
- [ ] Field spacing correct
- [ ] Label styling identical
- [ ] Error message styling identical
- [ ] Button styling unchanged
- [ ] Responsive layout works (mobile, tablet)
**Acceptance Criteria:**
- [ ] Playwright tests pass
- [ ] No unexpected visual differences
- [ ] Any differences documented and approved
---
### 3. InvoicesView.vue Refactoring (5 tasks)
**File:** `reports-app/frontend/src/views/InvoicesView.vue`
#### Task 3.1: Update Template - Filter Groups
**Status:** ⏸️ Not Started | **Est:** 30 min
**Current (lines 45-60):**
```vue
<div class="filters-container">
<div class="filters-row">
<div class="filter-group">
<label class="filter-label">Tip Factură</label>
<Dropdown
v-model="filters.type"
:options="invoiceTypes"
option-label="label"
option-value="value"
placeholder="Tip factură"
@change="handleFilterChange"
/>
</div>
</div>
</div>
```
**Updated:**
```vue
<div class="form">
<div class="form-row">
<div class="form-col">
<div class="form-group">
<label class="form-label">Tip Factură</label>
<Dropdown
v-model="filters.type"
:options="invoiceTypes"
option-label="label"
option-value="value"
placeholder="Tip factură"
@change="handleFilterChange"
class="w-full"
/>
</div>
</div>
</div>
</div>
```
**Changes:**
- `.filters-container``.form`
- `.filters-row``.form-row`
- `.filter-group``.form-group` (inside `.form-col`)
- `.filter-label``.form-label`
**Acceptance Criteria:**
- [ ] All filter fields updated
- [ ] Grid layout preserved (form-row + form-col)
- [ ] No custom filter classes
---
#### Task 3.2: Update Date Range Filters
**Status:** ⏸️ Not Started | **Est:** 20 min
**Current:**
```vue
<div class="filter-group">
<label class="filter-label">De la</label>
<Calendar
v-model="filters.dateFrom"
dateFormat="dd/mm/yy"
placeholder="Data început"
/>
</div>
<div class="filter-group">
<label class="filter-label">Până la</label>
<Calendar
v-model="filters.dateTo"
dateFormat="dd/mm/yy"
placeholder="Data sfârșit"
/>
</div>
```
**Updated:**
```vue
<div class="form-col">
<div class="form-group">
<label class="form-label">De la</label>
<Calendar
v-model="filters.dateFrom"
dateFormat="dd/mm/yy"
placeholder="Data început"
class="w-full"
/>
</div>
</div>
<div class="form-col">
<div class="form-group">
<label class="form-label">Până la</label>
<Calendar
v-model="filters.dateTo"
dateFormat="dd/mm/yy"
placeholder="Data sfârșit"
class="w-full"
/>
</div>
</div>
```
**Acceptance Criteria:**
- [ ] Date pickers use standard form classes
- [ ] Side-by-side layout preserved
- [ ] Calendar styling works
---
#### Task 3.3: Remove Custom Filter CSS
**Status:** ⏸️ Not Started | **Est:** 15 min
**Delete Lines 545-578:**
```css
/* DELETE THIS */
.filters-container {
padding: 1rem;
}
.filters-row {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
gap: 1rem;
margin-bottom: 1rem;
}
.filter-group {
display: flex;
flex-direction: column;
gap: 0.5rem;
}
.filter-label {
font-size: 0.875rem;
font-weight: 600;
color: var(--text-color);
}
```
**Note:** forms.css provides `.form-row` with grid layout.
**Acceptance Criteria:**
- [ ] Custom filter CSS deleted
- [ ] Form layout still correct via forms.css
- [ ] Grid behavior preserved
---
#### Task 3.4: Remove Filter-Specific Overrides
**Status:** ⏸️ Not Started | **Est:** 10 min
**Find and remove any filter-specific PrimeVue overrides:**
```bash
# Search for filter-related :deep() in InvoicesView.vue
grep -n ":deep" reports-app/frontend/src/views/InvoicesView.vue
```
Remove any found overrides (will be centralized in Phase 3).
**Acceptance Criteria:**
- [ ] No `:deep()` for filter components
- [ ] No hardcoded filter styling
---
#### Task 3.5: Visual Regression Test
**Status:** ⏸️ Not Started | **Est:** 20 min
```bash
# Run invoice tests
npm run test:e2e -- tests/e2e/invoices/
# Check snapshots
npm run test:e2e:report
```
**Visual Checks:**
- [ ] Filter card layout identical
- [ ] Filter field alignment correct
- [ ] Grid layout responsive
- [ ] Date pickers styled correctly
- [ ] Dropdown styling correct
**Functional Checks:**
- [ ] All filters work
- [ ] Filter changes trigger data reload
- [ ] Clear filters works
- [ ] Filter combinations work
**Acceptance Criteria:**
- [ ] Playwright tests pass
- [ ] No visual regressions
- [ ] All filters functional
---
### 4. Testing & Validation (3 tasks)
#### Task 4.1: Playwright Snapshot Comparison
**Status:** ⏸️ Not Started | **Est:** 30 min
```bash
# Run full test suite
npm run test:e2e
# Generate report
npm run test:e2e:report
# Open report
npx playwright show-report
```
**Compare:**
- [ ] Login page (desktop, tablet, mobile)
- [ ] Invoices filter section
- [ ] All form states (empty, filled, error, valid)
**Document any differences:**
- Expected differences: None (should be pixel-perfect)
- Acceptable differences: Font rendering variations
- Unacceptable differences: Layout shifts, color changes, missing elements
**Acceptance Criteria:**
- [ ] All visual regression tests pass
- [ ] Any differences documented and approved
- [ ] Screenshots archived
---
#### Task 4.2: Manual Testing All Breakpoints
**Status:** ⏸️ Not Started | **Est:** 45 min
**Desktop Testing (1920x1080):**
- [ ] Login form centered and styled
- [ ] Invoice filters in grid layout
- [ ] All fields accessible
- [ ] Hover states work
- [ ] Focus states visible
**Tablet Testing (768x1024):**
- [ ] Login form responsive
- [ ] Filter grid adapts to tablet
- [ ] Touch targets adequate (min 44px)
- [ ] No horizontal scroll
**Mobile Testing (375x667):**
- [ ] Login form full-width
- [ ] Filters stack vertically
- [ ] Font size 16px (no zoom on iOS)
- [ ] Virtual keyboard doesn't break layout
**Acceptance Criteria:**
- [ ] All breakpoints tested
- [ ] Forms responsive on all devices
- [ ] No layout breaks
---
#### Task 4.3: Browser Compatibility Check
**Status:** ⏸️ Not Started | **Est:** 30 min
**Test on:**
- [ ] Chrome (latest) - Primary browser
- [ ] Firefox (latest)
- [ ] Safari (latest) - macOS/iOS
- [ ] Edge (latest)
**Check:**
- Form layout identical
- CSS variables supported
- Flexbox/Grid working
- Focus outlines visible
- No console errors
**Acceptance Criteria:**
- [ ] Forms work on all browsers
- [ ] Visual consistency across browsers
- [ ] No JavaScript errors
---
### 5. Documentation (1 task)
#### Task 5.1: Create Form Template Documentation
**Status:** ⏸️ Not Started | **Est:** 1 hour
**Create:** `docs/FORM_TEMPLATE.md`
**Content:**
1. Standard form structure
2. Field types (text, password, dropdown, date)
3. Validation pattern
4. Error handling
5. Responsive layout
6. Accessibility guidelines
**Template Example:**
```vue
<template>
<form @submit.prevent="handleSubmit" class="form">
<!-- Single field -->
<div class="form-group">
<label for="field" class="form-label required">Label</label>
<input
id="field"
v-model="formData.field"
type="text"
class="form-input"
:class="{ 'invalid': errors.field }"
/>
<span v-if="errors.field" class="form-error">
{{ errors.field }}
</span>
</div>
<!-- Horizontal fields -->
<div class="form-row">
<div class="form-col">
<!-- Field 1 -->
</div>
<div class="form-col">
<!-- Field 2 -->
</div>
</div>
<!-- Form actions -->
<div class="form-actions">
<button type="submit" class="btn btn-primary">
Submit
</button>
</div>
</form>
</template>
```
**Acceptance Criteria:**
- [ ] Template documented with examples
- [ ] All field types covered
- [ ] Validation pattern explained
- [ ] Accessibility notes included
---
## Completion Criteria
### Code Quality
- [ ] Zero custom form wrapper classes (`.field`, `.filter-group`)
- [ ] All forms use `.form-group` + `.form-label`
- [ ] No `:deep()` PrimeVue overrides in components
- [ ] ~150 lines of CSS eliminated
### Functionality
- [ ] Login works identically
- [ ] Invoice filters work identically
- [ ] All validation works
- [ ] No console errors
### Testing
- [ ] Playwright visual regression tests pass
- [ ] Manual testing complete (all breakpoints)
- [ ] Browser compatibility verified
### Documentation
- [ ] Form template created
- [ ] Pattern documented
---
## Files Modified
1. `reports-app/frontend/src/views/LoginView.vue`
- Template: Updated field wrappers and labels
- CSS: Deleted lines 234-243, 269-288 (~90 lines)
2. `reports-app/frontend/src/views/InvoicesView.vue`
- Template: Updated filter structure
- CSS: Deleted lines 545-578 (~80 lines)
3. `docs/FORM_TEMPLATE.md` (new file)
- Standard form template and guidelines
**Total:** 2 files modified, 1 file created, ~150 lines deleted
---
## Commit Message
```
feat(css): Phase 1 - Standardize form patterns across views
BREAKING: None (visual changes only, no API changes)
Changes:
- Standardize LoginView.vue to use forms.css patterns
- Standardize InvoicesView.vue filter forms
- Remove ~150 lines of duplicate form CSS
- Eliminate custom form wrapper classes
- Create standard form template documentation
Impact:
- Consistent form UX across application
- Reduced CSS duplication (70% → 65%)
- Cleaner component code
- forms.css (460 lines) now utilized
Testing:
- ✅ Playwright visual regression tests pass
- ✅ Manual testing on desktop/tablet/mobile
- ✅ Browser compatibility verified (Chrome/Firefox/Safari/Edge)
- ✅ All form functionality preserved
Files:
- Modified: LoginView.vue, InvoicesView.vue
- Created: docs/FORM_TEMPLATE.md
- CSS eliminated: ~150 lines
Refs: #CSS-REFACTORING Phase 1/7
```
---
## Next Phase
**Phase 2:** Fundație Pattern-uri Globale
- Create global pattern files
- Prepare for major refactoring
- See: [phase-2-foundation.md](./phase-2-foundation.md)
---
**Created:** 2025-11-18
**Last Updated:** 2025-11-18
**Status:** ⏸️ Awaiting Start