298 lines
8.9 KiB
Markdown
298 lines
8.9 KiB
Markdown
# 🔧 Settings System Documentation
|
||
|
||
## Overview
|
||
The Settings System provides centralized configuration management for the Car Maintenance Management System, allowing administrators to customize date formats, currency, and number formatting across the entire application.
|
||
|
||
## 🎯 Features
|
||
|
||
### 1. **Date Format Configuration**
|
||
- **Arabic (ar-SA)**: ٢٠٢٥/١١/٩ (Arabic numerals)
|
||
- **English (en-US)**: 11/9/2025 (Western numerals)
|
||
- **Display Patterns**: dd/MM/yyyy, MM/dd/yyyy, yyyy-MM-dd
|
||
|
||
### 2. **Currency Configuration**
|
||
- **Supported Currencies**: JOD, USD, EUR, SAR, AED
|
||
- **Custom Currency Symbols**: د.أ, $, €, ر.س, د.إ
|
||
- **Automatic Formatting**: 1,234.56 د.أ
|
||
|
||
### 3. **Number Format Configuration**
|
||
- **Arabic (ar-SA)**: ١٬٢٣٤٫٥٦ (Arabic numerals with Arabic separators)
|
||
- **English (en-US)**: 1,234.56 (Western numerals with Western separators)
|
||
- **Applied to**: Costs, kilometers, all numeric displays
|
||
|
||
## 🏗️ Architecture
|
||
|
||
### Database Schema
|
||
```sql
|
||
CREATE TABLE "settings" (
|
||
"id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
|
||
"key" TEXT NOT NULL UNIQUE,
|
||
"value" TEXT NOT NULL,
|
||
"description" TEXT,
|
||
"createdDate" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||
"updateDate" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP
|
||
);
|
||
```
|
||
|
||
### Settings Keys
|
||
| Key | Description | Default Value | Options |
|
||
|-----|-------------|---------------|---------|
|
||
| `dateFormat` | Date format locale | `ar-SA` | `ar-SA`, `en-US` |
|
||
| `currency` | Currency code | `JOD` | `JOD`, `USD`, `EUR`, `SAR`, `AED` |
|
||
| `numberFormat` | Number format locale | `ar-SA` | `ar-SA`, `en-US` |
|
||
| `currencySymbol` | Currency symbol | `د.أ` | Any string |
|
||
| `dateDisplayFormat` | Date pattern | `dd/MM/yyyy` | Various patterns |
|
||
|
||
## 📁 File Structure
|
||
|
||
```
|
||
app/
|
||
├── lib/
|
||
│ └── settings-management.server.ts # Server-side settings management
|
||
├── contexts/
|
||
│ └── SettingsContext.tsx # React context for settings
|
||
├── routes/
|
||
│ └── settings.tsx # Settings management page
|
||
├── components/
|
||
│ ├── layout/
|
||
│ │ └── Sidebar.tsx # Updated with settings link
|
||
│ ├── maintenance-visits/
|
||
│ │ └── MaintenanceVisitDetailsView.tsx # Uses settings formatting
|
||
│ ├── vehicles/
|
||
│ │ └── VehicleDetailsView.tsx # Uses settings formatting
|
||
│ └── customers/
|
||
│ └── CustomerDetailsView.tsx # Uses settings formatting
|
||
└── root.tsx # Settings provider integration
|
||
|
||
prisma/
|
||
├── schema.prisma # Settings model
|
||
├── settingsSeed.ts # Settings seeding script
|
||
└── migrations/
|
||
└── add_settings.sql # Settings table migration
|
||
```
|
||
|
||
## 🔧 Implementation Details
|
||
|
||
### 1. Settings Management Server (`settings-management.server.ts`)
|
||
|
||
#### Key Functions:
|
||
- `getAppSettings()`: Retrieves all settings as typed object
|
||
- `updateSettings()`: Updates multiple settings atomically
|
||
- `createFormatter()`: Creates formatter instance with current settings
|
||
- `SettingsFormatter`: Utility class for consistent formatting
|
||
|
||
#### Usage Example:
|
||
```typescript
|
||
import { getAppSettings, createFormatter } from '~/lib/settings-management.server';
|
||
|
||
// In loader
|
||
const settings = await getAppSettings();
|
||
|
||
// Create formatter
|
||
const formatter = await createFormatter();
|
||
const formattedCurrency = formatter.formatCurrency(1234.56);
|
||
const formattedDate = formatter.formatDate(new Date());
|
||
```
|
||
|
||
### 2. Settings Context (`SettingsContext.tsx`)
|
||
|
||
#### Provides:
|
||
- `settings`: Current settings object
|
||
- `formatNumber(value)`: Format numbers according to settings
|
||
- `formatCurrency(value)`: Format currency with symbol
|
||
- `formatDate(date)`: Format dates according to settings
|
||
- `formatDateTime(date)`: Format date and time
|
||
|
||
#### Usage Example:
|
||
```typescript
|
||
import { useSettings } from '~/contexts/SettingsContext';
|
||
|
||
function MyComponent() {
|
||
const { formatCurrency, formatDate, formatNumber } = useSettings();
|
||
|
||
return (
|
||
<div>
|
||
<p>Cost: {formatCurrency(250.75)}</p>
|
||
<p>Date: {formatDate(new Date())}</p>
|
||
<p>Kilometers: {formatNumber(45000)} كم</p>
|
||
</div>
|
||
);
|
||
}
|
||
```
|
||
|
||
### 3. Root Integration (`root.tsx`)
|
||
|
||
The root layout loads settings and provides them to all components:
|
||
|
||
```typescript
|
||
export async function loader({ request }: LoaderFunctionArgs) {
|
||
await initializeDefaultSettings();
|
||
const settings = await getAppSettings();
|
||
return json({ settings });
|
||
}
|
||
|
||
export default function App() {
|
||
const { settings } = useLoaderData<typeof loader>();
|
||
|
||
return (
|
||
<SettingsProvider settings={settings}>
|
||
<Outlet />
|
||
</SettingsProvider>
|
||
);
|
||
}
|
||
```
|
||
|
||
## 🎨 Settings Page Features
|
||
|
||
### Admin Interface (`/settings`)
|
||
- **Real-time Preview**: See formatting changes immediately
|
||
- **Validation**: Ensures valid locale and currency codes
|
||
- **Reset Functionality**: Restore default settings
|
||
- **Visual Examples**: Shows how settings affect different data types
|
||
|
||
### Security
|
||
- **Admin Only**: Requires authentication level 2 (Admin) or higher
|
||
- **Input Validation**: Validates all setting values
|
||
- **Error Handling**: Graceful fallback to defaults on errors
|
||
|
||
## 🌍 Localization Support
|
||
|
||
### Arabic (ar-SA)
|
||
- **Numbers**: ١٬٢٣٤٫٥٦ (Arabic-Indic digits)
|
||
- **Dates**: ٩/١١/٢٠٢٥ (Arabic calendar format)
|
||
- **Currency**: ١٬٢٣٤٫٥٦ د.أ
|
||
|
||
### English (en-US)
|
||
- **Numbers**: 1,234.56 (Western digits)
|
||
- **Dates**: 11/9/2025 (Gregorian format)
|
||
- **Currency**: 1,234.56 JOD
|
||
|
||
## 🔄 Migration Guide
|
||
|
||
### From Hardcoded Formatting
|
||
Replace hardcoded formatting:
|
||
|
||
```typescript
|
||
// Before
|
||
{visit.cost.toLocaleString('ar-SA')} د.أ
|
||
{new Date(visit.date).toLocaleDateString('ar-SA')}
|
||
{visit.kilometers.toLocaleString('ar-SA')} كم
|
||
|
||
// After
|
||
{formatCurrency(visit.cost)}
|
||
{formatDate(visit.date)}
|
||
{formatNumber(visit.kilometers)} كم
|
||
```
|
||
|
||
### Adding New Components
|
||
1. Import settings context: `import { useSettings } from '~/contexts/SettingsContext';`
|
||
2. Use formatting functions: `const { formatCurrency, formatDate, formatNumber } = useSettings();`
|
||
3. Apply formatting: `{formatCurrency(amount)}` instead of hardcoded formatting
|
||
|
||
## 🧪 Testing
|
||
|
||
### Manual Testing
|
||
1. Navigate to `/settings` (admin required)
|
||
2. Change date format from Arabic to English
|
||
3. Verify changes appear across all pages:
|
||
- Maintenance visits
|
||
- Vehicle details
|
||
- Customer information
|
||
- Financial reports
|
||
|
||
### Automated Testing
|
||
```typescript
|
||
// Test settings formatting
|
||
import { SettingsFormatter } from '~/lib/settings-management.server';
|
||
|
||
const arabicSettings = {
|
||
dateFormat: 'ar-SA' as const,
|
||
numberFormat: 'ar-SA' as const,
|
||
currency: 'JOD',
|
||
currencySymbol: 'د.أ'
|
||
};
|
||
|
||
const formatter = new SettingsFormatter(arabicSettings);
|
||
expect(formatter.formatCurrency(1234.56)).toBe('١٬٢٣٤٫٥٦ د.أ');
|
||
```
|
||
|
||
## 🚀 Performance Considerations
|
||
|
||
### Caching
|
||
- Settings are loaded once at application startup
|
||
- Context provides settings to all components without re-fetching
|
||
- Database queries are minimized through upsert operations
|
||
|
||
### Memory Usage
|
||
- Settings object is lightweight (< 1KB)
|
||
- Formatter instances are created on-demand
|
||
- No memory leaks from event listeners
|
||
|
||
## 🔮 Future Enhancements
|
||
|
||
### Planned Features
|
||
1. **Time Zone Support**: Configure display time zones
|
||
2. **Language Switching**: Full Arabic/English interface toggle
|
||
3. **Custom Date Patterns**: User-defined date format strings
|
||
4. **Decimal Precision**: Configurable decimal places for currency
|
||
5. **Export/Import**: Settings backup and restore functionality
|
||
|
||
### Technical Improvements
|
||
1. **Settings Validation**: JSON schema validation for settings
|
||
2. **Audit Trail**: Track settings changes with timestamps
|
||
3. **Role-based Settings**: Different settings per user role
|
||
4. **Real-time Updates**: WebSocket-based settings synchronization
|
||
|
||
## 📋 Troubleshooting
|
||
|
||
### Common Issues
|
||
|
||
#### Settings Not Loading
|
||
```typescript
|
||
// Check if settings are initialized
|
||
await initializeDefaultSettings();
|
||
const settings = await getAppSettings();
|
||
console.log('Settings:', settings);
|
||
```
|
||
|
||
#### Formatting Not Applied
|
||
```typescript
|
||
// Ensure component uses settings context
|
||
import { useSettings } from '~/contexts/SettingsContext';
|
||
|
||
function MyComponent() {
|
||
const { formatCurrency } = useSettings();
|
||
// Use formatCurrency instead of hardcoded formatting
|
||
}
|
||
```
|
||
|
||
#### Database Errors
|
||
```bash
|
||
# Reset settings table
|
||
npx prisma db push --force-reset
|
||
npx tsx prisma/settingsSeed.ts
|
||
```
|
||
|
||
### Debug Mode
|
||
Enable debug logging in settings management:
|
||
|
||
```typescript
|
||
// In settings-management.server.ts
|
||
const DEBUG = process.env.NODE_ENV === 'development';
|
||
|
||
if (DEBUG) {
|
||
console.log('Settings loaded:', settings);
|
||
}
|
||
```
|
||
|
||
## 📚 Related Documentation
|
||
- [Database Schema](./prisma/schema.prisma)
|
||
- [Authentication System](./app/lib/auth-middleware.server.ts)
|
||
- [Component Architecture](./app/components/README.md)
|
||
- [Localization Guide](./LOCALIZATION.md)
|
||
|
||
---
|
||
|
||
**Last Updated**: November 9, 2025
|
||
**Version**: 1.0.0
|
||
**Maintainer**: Car MMS Development Team |