car_mms/app/components
2025-09-11 14:22:27 +03:00
..
customers init-c 2025-09-11 14:22:27 +03:00
expenses init-c 2025-09-11 14:22:27 +03:00
forms init-c 2025-09-11 14:22:27 +03:00
layout init-c 2025-09-11 14:22:27 +03:00
maintenance-visits init-c 2025-09-11 14:22:27 +03:00
tables init-c 2025-09-11 14:22:27 +03:00
ui init-c 2025-09-11 14:22:27 +03:00
users init-c 2025-09-11 14:22:27 +03:00
vehicles init-c 2025-09-11 14:22:27 +03:00
README.md init-c 2025-09-11 14:22:27 +03:00

Reusable Form Components and Validation

This document describes the enhanced reusable form components and validation utilities implemented for the car maintenance management system.

Overview

The system now includes a comprehensive set of reusable form components with RTL support, client-side and server-side validation, and enhanced data table functionality with Arabic text support.

Components

Form Input Components

Input Component (app/components/ui/Input.tsx)

Enhanced input component with RTL support, validation, and icons.

import { Input } from '~/components/ui/Input';

<Input
  label="اسم العميل"
  placeholder="أدخل اسم العميل"
  error={errors.name}
  helperText="الاسم مطلوب"
  startIcon={<UserIcon />}
  required
/>

Props:

  • label: Field label
  • error: Error message to display
  • helperText: Helper text below input
  • startIcon/endIcon: Icons for input decoration
  • fullWidth: Whether input takes full width (default: true)
  • All standard HTML input props

Select Component (app/components/ui/Select.tsx)

Dropdown select component with RTL support and validation.

import { Select } from '~/components/ui/Select';

<Select
  label="نوع الوقود"
  placeholder="اختر نوع الوقود"
  options={[
    { value: 'gasoline', label: 'بنزين' },
    { value: 'diesel', label: 'ديزل' },
  ]}
  error={errors.fuel}
/>

Props:

  • options: Array of { value, label, disabled? } objects
  • placeholder: Placeholder text
  • Other props same as Input component

Textarea Component (app/components/ui/Textarea.tsx)

Multi-line text input with RTL support.

import { Textarea } from '~/components/ui/Textarea';

<Textarea
  label="العنوان"
  placeholder="أدخل العنوان"
  rows={3}
  resize="vertical"
  error={errors.address}
/>

Props:

  • resize: Resize behavior ('none', 'vertical', 'horizontal', 'both')
  • rows: Number of visible rows
  • Other props same as Input component

FormField Component (app/components/ui/FormField.tsx)

Wrapper component for consistent field styling and validation display.

import { FormField } from '~/components/ui/FormField';

<FormField
  label="اسم العميل"
  required
  error={errors.name}
  helperText="أدخل الاسم الكامل"
>
  <input type="text" name="name" />
</FormField>

Form Layout Components

Form Component (app/components/ui/Form.tsx)

Main form wrapper with title, description, and error handling.

import { Form, FormActions, FormSection, FormGrid } from '~/components/ui/Form';

<Form
  title="إضافة عميل جديد"
  description="أدخل بيانات العميل"
  loading={isLoading}
  error={generalError}
  success={successMessage}
>
  <FormSection title="المعلومات الأساسية">
    <FormGrid columns={2}>
      {/* Form fields */}
    </FormGrid>
  </FormSection>
  
  <FormActions>
    <Button variant="outline">إلغاء</Button>
    <Button type="submit">حفظ</Button>
  </FormActions>
</Form>

Components:

  • Form: Main form wrapper
  • FormActions: Action buttons container
  • FormSection: Grouped form fields with title
  • FormGrid: Responsive grid layout for fields

Enhanced Data Table

DataTable Component (app/components/ui/DataTable.tsx)

Advanced data table with search, filtering, sorting, and pagination.

import { DataTable } from '~/components/ui/DataTable';

<DataTable
  data={customers}
  columns={[
    {
      key: 'name',
      header: 'الاسم',
      sortable: true,
      filterable: true,
      render: (customer) => <strong>{customer.name}</strong>
    },
    {
      key: 'phone',
      header: 'الهاتف',
      filterable: true,
      filterType: 'text'
    }
  ]}
  searchable
  searchPlaceholder="البحث في العملاء..."
  filterable
  pagination={{
    enabled: true,
    pageSize: 10,
    currentPage: 1,
    onPageChange: handlePageChange
  }}
  actions={{
    label: 'الإجراءات',
    render: (item) => (
      <Button onClick={() => edit(item)}>تعديل</Button>
    )
  }}
/>

Features:

  • Search across multiple fields
  • Column-based filtering
  • Sorting with Arabic text support
  • Pagination
  • Custom action buttons
  • RTL layout support
  • Loading and empty states

Validation

Server-Side Validation (app/lib/form-validation.ts)

Zod-based validation schemas with Arabic error messages.

import { validateCustomerData } from '~/lib/form-validation';

const result = validateCustomerData(formData);
if (!result.success) {
  return json({ errors: result.errors });
}

Available Validators:

  • validateUserData(data)
  • validateCustomerData(data)
  • validateVehicleData(data)
  • validateMaintenanceVisitData(data)
  • validateExpenseData(data)

Client-Side Validation Hook (app/hooks/useFormValidation.ts)

React hook for real-time form validation.

import { useFormValidation } from '~/hooks/useFormValidation';
import { customerSchema } from '~/lib/form-validation';

const {
  values,
  errors,
  isValid,
  setValue,
  getFieldProps,
  validate
} = useFormValidation({
  schema: customerSchema,
  initialValues: { name: '', email: '' },
  validateOnChange: true,
  validateOnBlur: true
});

// Use with form fields
<Input {...getFieldProps('name')} />

Validation Utilities (app/lib/validation-utils.ts)

Utility functions for field-level validation.

import { validateField, validateEmail, PATTERNS } from '~/lib/validation-utils';

// Single field validation
const result = validateField(value, {
  required: true,
  minLength: 3,
  email: true
});

// Specific validators
const emailResult = validateEmail('test@example.com');
const phoneResult = validatePhone('+966501234567');

// Pattern matching
const isValidEmail = PATTERNS.email.test(email);

Table Utilities (app/lib/table-utils.ts)

Utilities for data processing with Arabic text support.

import { 
  searchData, 
  filterData, 
  sortData, 
  processTableData 
} from '~/lib/table-utils';

// Process table data with search, filter, sort, and pagination
const result = processTableData(
  data,
  {
    search: 'محمد',
    filters: { status: 'active' },
    sort: { key: 'name', direction: 'asc' },
    pagination: { page: 1, pageSize: 10 }
  },
  ['name', 'email'] // searchable fields
);

Example Forms

Enhanced Customer Form (app/components/forms/EnhancedCustomerForm.tsx)

Complete example showing all components working together:

import { EnhancedCustomerForm } from '~/components/forms/EnhancedCustomerForm';

<EnhancedCustomerForm
  customer={customer}
  onCancel={() => setShowForm(false)}
  errors={actionData?.errors}
  isLoading={navigation.state === 'submitting'}
  onSubmit={(data) => submit(data, { method: 'post' })}
/>

Enhanced Vehicle Form (app/components/forms/EnhancedVehicleForm.tsx)

Complex form with multiple sections and validation:

import { EnhancedVehicleForm } from '~/components/forms/EnhancedVehicleForm';

<EnhancedVehicleForm
  vehicle={vehicle}
  customers={customers}
  onCancel={() => setShowForm(false)}
  errors={actionData?.errors}
  isLoading={isSubmitting}
/>

Features

RTL Support

  • All components support right-to-left layout
  • Arabic text rendering and alignment
  • Proper icon and element positioning

Validation

  • Client-side real-time validation
  • Server-side validation with Zod schemas
  • Arabic error messages
  • Field-level and form-level validation

Accessibility

  • Proper ARIA labels and descriptions
  • Keyboard navigation support
  • Screen reader compatibility
  • Focus management

Performance

  • Memoized components to prevent unnecessary re-renders
  • Debounced search functionality
  • Efficient data processing utilities
  • Lazy loading for large datasets

Usage Guidelines

  1. Always use FormField wrapper for consistent styling and error display
  2. Implement both client and server validation for security and UX
  3. Use the validation hook for real-time feedback
  4. Leverage table utilities for consistent data processing
  5. Follow RTL design patterns for Arabic text and layout
  6. Test with Arabic content to ensure proper rendering

Migration from Old Components

To migrate existing forms to use the new components:

  1. Replace basic inputs with the new Input/Select/Textarea components
  2. Wrap fields with FormField for consistent styling
  3. Add validation using the useFormValidation hook
  4. Update data tables to use the enhanced DataTable component
  5. Use Form layout components for better structure

Testing

All components include comprehensive tests:

  • app/lib/__tests__/form-validation.test.ts
  • app/lib/__tests__/validation-utils.test.ts

Run tests with:

npm run test -- --run app/lib/__tests__/form-validation.test.ts