Skip to content

feat(frontend): form validation with inline error states (#184) - #233

Closed
ifygreg01-best wants to merge 1 commit into
Epondia:mainfrom
ifygreg01-best:feat/form-validation-inline-errors-184
Closed

feat(frontend): form validation with inline error states (#184)#233
ifygreg01-best wants to merge 1 commit into
Epondia:mainfrom
ifygreg01-best:feat/form-validation-inline-errors-184

Conversation

@ifygreg01-best

Copy link
Copy Markdown
Contributor

Summary

Implements client-side form validation with inline error messages and visual error states for all user input forms, closing #184.

Changes

Schemas (src/lib/schemas.ts)

  • loginSchema — email, password, optional rememberMe
  • registerSchema — name, email, password (complexity: uppercase, lowercase, digit, 8+ chars), confirmPassword cross-field match, acceptTerms
  • courseSchema — title, description, category, difficulty, price (decimal regex + non-negative), currency, duration, prerequisites, tags, isPublished
  • credentialIssuanceSchema — recipient name/email/wallet, credential type/title/description, issue date, optional expiration date

Reusable FormField component (src/components/forms/FormField.tsx)

  • Red border when error prop is set
  • Inline error message with role="alert" and error icon
  • Optional helper text (hidden when error shown)
  • Required * indicator and full ARIA wiring (aria-invalid, aria-describedby)
  • Supports both <input> and <textarea>

Form components (src/components/forms/)

  • LoginForm — email, password, remember-me checkbox, forgot password link; mode: 'onBlur'
  • RegisterForm — name, email, password, confirm password, terms checkbox; mode: 'onChange' (required for checkbox isValid)
  • CourseCreationForm — all course fields + selects + description character counter + publish toggle
  • CredentialIssuanceForm — recipient details, credential metadata, fieldset grouping, date validation

Auth pages

  • /app/auth/login/page.tsx — branded card, POST /api/auth/login, redirect on success
  • /app/auth/register/page.tsx — branded card, POST /api/auth/register, redirect on success

Testing

54 tests, all passing:

  • 38 schema unit tests covering valid/invalid paths for all 4 new schemas
  • 16 RTL component tests for LoginForm and RegisterForm covering render, inline errors on blur, submit-disabled state, successful submission, and server error banners
Test Suites: 2 passed
Tests:       54 passed

Acceptance criteria

  • Validation for registration and login forms
  • Validation for course creation form
  • Validation for credential issuance form
  • Inline error messages below fields
  • Invalid fields styled with red borders
  • Real-time validation on blur (onBlur mode)
  • Submit button disabled while form is invalid

- Add loginSchema, registerSchema, courseSchema, credentialIssuanceSchema
  to src/lib/schemas.ts with full Zod validation rules
- Add reusable FormField component with red-border error state, inline
  error message (role=alert), helper text, and ARIA attributes
- Add LoginForm: email/password/rememberMe, onBlur validation, server
  error banner, disabled submit while invalid
- Add RegisterForm: name/email/password/confirmPassword/acceptTerms,
  onChange validation (required for checkbox), password complexity rules,
  cross-field match check
- Add CourseCreationForm: all course fields, category/difficulty/currency
  selects, description character counter, publish toggle
- Add CredentialIssuanceForm: recipient info, credential type/title,
  fieldset grouping, issue/expiration date validation
- Add /app/auth/login and /app/auth/register pages with branded layout
- Add 54 tests: 38 schema unit tests + 16 RTL component tests

Closes Epondia#184

Copy link
Copy Markdown
Contributor

Closing: this branch has merge conflicts with main. Please rebase/merge main into your branch, resolve conflicts, and reopen if you'd like to continue.

@jobbykings jobbykings closed this Aug 15, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants