uup
This commit is contained in:
363
app/components/README.md
Normal file
363
app/components/README.md
Normal file
@@ -0,0 +1,363 @@
|
||||
# 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.
|
||||
|
||||
```tsx
|
||||
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.
|
||||
|
||||
```tsx
|
||||
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.
|
||||
|
||||
```tsx
|
||||
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.
|
||||
|
||||
```tsx
|
||||
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.
|
||||
|
||||
```tsx
|
||||
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.
|
||||
|
||||
```tsx
|
||||
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.
|
||||
|
||||
```tsx
|
||||
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.
|
||||
|
||||
```tsx
|
||||
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.
|
||||
|
||||
```tsx
|
||||
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.
|
||||
|
||||
```tsx
|
||||
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:
|
||||
|
||||
```tsx
|
||||
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:
|
||||
|
||||
```tsx
|
||||
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:
|
||||
```bash
|
||||
npm run test -- --run app/lib/__tests__/form-validation.test.ts
|
||||
```
|
||||
Reference in New Issue
Block a user