Deploy rule, CRM enhancements, Company Employee category, bilingual, contacts module completion
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
334
BILINGUAL_IMPLEMENTATION_GUIDE.md
Normal file
334
BILINGUAL_IMPLEMENTATION_GUIDE.md
Normal file
@@ -0,0 +1,334 @@
|
||||
# Bilingual System Implementation Guide
|
||||
|
||||
## Overview
|
||||
|
||||
The system now supports **100% bilingual** functionality with English and Arabic languages. Everything switches based on user preference, including:
|
||||
- Navigation menus
|
||||
- Buttons and labels
|
||||
- Form fields and placeholders
|
||||
- Error messages and notifications
|
||||
- Table headers and content
|
||||
- Modals and dialogs
|
||||
|
||||
## Quick Start
|
||||
|
||||
### 1. Using Translations in Components
|
||||
|
||||
```typescript
|
||||
'use client'
|
||||
|
||||
import { useLanguage } from '@/contexts/LanguageContext'
|
||||
|
||||
function MyComponent() {
|
||||
const { t, language, dir } = useLanguage()
|
||||
|
||||
return (
|
||||
<div dir={dir}>
|
||||
<h1>{t('contacts.title')}</h1>
|
||||
<button>{t('common.save')}</button>
|
||||
<p>{t('contacts.searchPlaceholder')}</p>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
```
|
||||
|
||||
### 2. Adding the Language Switcher
|
||||
|
||||
Add the language switcher to your navigation/header:
|
||||
|
||||
```typescript
|
||||
import LanguageSwitcher from '@/components/LanguageSwitcher'
|
||||
|
||||
function Header() {
|
||||
return (
|
||||
<header>
|
||||
{/* Other header content */}
|
||||
<LanguageSwitcher />
|
||||
</header>
|
||||
)
|
||||
}
|
||||
```
|
||||
|
||||
### 3. Translation Keys Structure
|
||||
|
||||
Translations are organized by domain:
|
||||
|
||||
```
|
||||
common.* - Common UI elements (save, cancel, delete, etc.)
|
||||
nav.* - Navigation items
|
||||
contacts.* - Contacts module
|
||||
import.* - Import functionality
|
||||
messages.* - System messages
|
||||
```
|
||||
|
||||
## Complete Examples
|
||||
|
||||
### Example 1: Simple Button
|
||||
|
||||
```typescript
|
||||
// Before (hardcoded)
|
||||
<button>Add Contact</button>
|
||||
|
||||
// After (bilingual)
|
||||
<button>{t('contacts.addContact')}</button>
|
||||
```
|
||||
|
||||
### Example 2: Form Labels
|
||||
|
||||
```typescript
|
||||
// Before
|
||||
<label>Name <span className="text-red-500">*</span></label>
|
||||
|
||||
// After
|
||||
<label>
|
||||
{t('contacts.name')}
|
||||
<span className="text-red-500"> {t('common.required')}</span>
|
||||
</label>
|
||||
```
|
||||
|
||||
### Example 3: Toast Notifications
|
||||
|
||||
```typescript
|
||||
// Before
|
||||
toast.success('Contact created successfully')
|
||||
|
||||
// After
|
||||
toast.success(t('contacts.createSuccess'))
|
||||
```
|
||||
|
||||
### Example 4: Conditional Text with Direction
|
||||
|
||||
```typescript
|
||||
const { t, dir } = useLanguage()
|
||||
|
||||
return (
|
||||
<div dir={dir} className={dir === 'rtl' ? 'text-right' : 'text-left'}>
|
||||
<h2>{t('contacts.title')}</h2>
|
||||
</div>
|
||||
)
|
||||
```
|
||||
|
||||
## Adding New Translations
|
||||
|
||||
To add new translations, edit `/src/contexts/LanguageContext.tsx`:
|
||||
|
||||
```typescript
|
||||
const translations = {
|
||||
en: {
|
||||
myModule: {
|
||||
myKey: 'My English Text',
|
||||
anotherKey: 'Another English Text'
|
||||
}
|
||||
},
|
||||
ar: {
|
||||
myModule: {
|
||||
myKey: 'النص بالعربية',
|
||||
anotherKey: 'نص آخر بالعربية'
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Then use it:
|
||||
|
||||
```typescript
|
||||
{t('myModule.myKey')}
|
||||
```
|
||||
|
||||
## Current Translation Coverage
|
||||
|
||||
All translations are already defined for:
|
||||
|
||||
### Common UI Elements
|
||||
- Actions: save, cancel, delete, edit, add, search, filter, export, import
|
||||
- States: loading, active, inactive, archived, deleted
|
||||
- Feedback: success, error, confirm
|
||||
- Navigation: back, next, finish, close, yes, no
|
||||
|
||||
### Contacts Module
|
||||
- All field labels (name, email, phone, etc.)
|
||||
- Contact types (individual, company, holding, government)
|
||||
- Relationship types (representative, partner, supplier, etc.)
|
||||
- Actions (add, edit, delete, merge, import, export)
|
||||
- Messages (success, error, warnings)
|
||||
|
||||
### Import/Export
|
||||
- All steps and labels
|
||||
- File requirements
|
||||
- Results and errors
|
||||
|
||||
## RTL (Right-to-Left) Support
|
||||
|
||||
The system automatically applies RTL when Arabic is selected:
|
||||
|
||||
```typescript
|
||||
const { dir } = useLanguage()
|
||||
|
||||
// Direction is automatically set on document.documentElement
|
||||
// Use it in your components when needed:
|
||||
<div dir={dir}>
|
||||
{/* Content flows correctly in both directions */}
|
||||
</div>
|
||||
```
|
||||
|
||||
### RTL-Specific Styling
|
||||
|
||||
Some components may need direction-specific styles:
|
||||
|
||||
```typescript
|
||||
<div className={`
|
||||
flex items-center gap-4
|
||||
${dir === 'rtl' ? 'flex-row-reverse' : 'flex-row'}
|
||||
`}>
|
||||
<Icon />
|
||||
<span>{t('contacts.name')}</span>
|
||||
</div>
|
||||
```
|
||||
|
||||
## Integration Checklist
|
||||
|
||||
To fully integrate the bilingual system into an existing component:
|
||||
|
||||
- [ ] Import `useLanguage` hook
|
||||
- [ ] Replace all hardcoded text with `t('key.path')`
|
||||
- [ ] Update toast messages with translations
|
||||
- [ ] Add `dir` attribute where needed for RTL
|
||||
- [ ] Test language switching
|
||||
- [ ] Verify RTL layout doesn't break UI
|
||||
|
||||
## Example: Complete Component Conversion
|
||||
|
||||
### Before (Hardcoded)
|
||||
|
||||
```typescript
|
||||
function ContactCard({ contact }) {
|
||||
return (
|
||||
<div>
|
||||
<h3>Contact Details</h3>
|
||||
<p>Name: {contact.name}</p>
|
||||
<p>Email: {contact.email}</p>
|
||||
<button onClick={handleEdit}>Edit</button>
|
||||
<button onClick={handleDelete}>Delete</button>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
```
|
||||
|
||||
### After (Bilingual)
|
||||
|
||||
```typescript
|
||||
function ContactCard({ contact }) {
|
||||
const { t, dir } = useLanguage()
|
||||
|
||||
return (
|
||||
<div dir={dir}>
|
||||
<h3>{t('contacts.contactDetails')}</h3>
|
||||
<p>{t('contacts.name')}: {contact.name}</p>
|
||||
<p>{t('contacts.email')}: {contact.email}</p>
|
||||
<button onClick={handleEdit}>{t('common.edit')}</button>
|
||||
<button onClick={handleDelete}>{t('common.delete')}</button>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
```
|
||||
|
||||
## Testing
|
||||
|
||||
1. **Switch Language**: Click the language switcher (EN/AR)
|
||||
2. **Verify All Text Changes**: Navigate through all pages and check that all text switches
|
||||
3. **Check RTL Layout**: Verify that Arabic layout flows right-to-left correctly
|
||||
4. **Test Forms**: Ensure form labels, placeholders, and error messages translate
|
||||
5. **Test Notifications**: Verify toast messages appear in the correct language
|
||||
|
||||
## Language Persistence
|
||||
|
||||
The selected language is automatically saved to `localStorage` and persists across sessions.
|
||||
|
||||
## Best Practices
|
||||
|
||||
1. **Always use translation keys**: Never hardcode user-facing text
|
||||
2. **Group related translations**: Keep related keys in the same object
|
||||
3. **Use descriptive keys**: `contacts.addButton` is better than `btn1`
|
||||
4. **Test both languages**: Always verify text fits in both English and Arabic
|
||||
5. **Consider text length**: Arabic text is often longer than English - design accordingly
|
||||
6. **Use semantic HTML**: Proper HTML helps with RTL rendering
|
||||
|
||||
## Common Patterns
|
||||
|
||||
### Table Headers
|
||||
|
||||
```typescript
|
||||
<th>{t('contacts.name')}</th>
|
||||
<th>{t('contacts.email')}</th>
|
||||
<th>{t('contacts.phone')}</th>
|
||||
<th>{t('common.actions')}</th>
|
||||
```
|
||||
|
||||
### Status Badges
|
||||
|
||||
```typescript
|
||||
const statusText = status === 'ACTIVE'
|
||||
? t('common.active')
|
||||
: t('common.inactive')
|
||||
|
||||
<span className="badge">{statusText}</span>
|
||||
```
|
||||
|
||||
### Confirm Dialogs
|
||||
|
||||
```typescript
|
||||
const confirmed = window.confirm(t('contacts.deleteConfirm'))
|
||||
if (confirmed) {
|
||||
await deleteContact(id)
|
||||
toast.success(t('contacts.deleteSuccess'))
|
||||
}
|
||||
```
|
||||
|
||||
## Adding Language Switcher to Dashboard
|
||||
|
||||
Add to your navigation component:
|
||||
|
||||
```typescript
|
||||
import LanguageSwitcher from '@/components/LanguageSwitcher'
|
||||
|
||||
function Navigation() {
|
||||
const { t } = useLanguage()
|
||||
|
||||
return (
|
||||
<nav>
|
||||
<div className="logo">{t('nav.dashboard')}</div>
|
||||
<div className="nav-links">
|
||||
<Link href="/contacts">{t('nav.contacts')}</Link>
|
||||
<Link href="/crm">{t('nav.crm')}</Link>
|
||||
{/* ... other links */}
|
||||
</div>
|
||||
<LanguageSwitcher />
|
||||
</nav>
|
||||
)
|
||||
}
|
||||
```
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
**Issue**: Text doesn't translate
|
||||
- **Solution**: Check the translation key exists in `LanguageContext.tsx`
|
||||
|
||||
**Issue**: RTL layout is broken
|
||||
- **Solution**: Add `dir={dir}` to parent container and check flex directions
|
||||
|
||||
**Issue**: Language doesn't persist
|
||||
- **Solution**: Check browser localStorage is enabled
|
||||
|
||||
**Issue**: Translation shows key instead of text
|
||||
- **Solution**: Verify the key path is correct (case-sensitive)
|
||||
|
||||
## Next Steps
|
||||
|
||||
1. Add the `LanguageSwitcher` component to your main navigation
|
||||
2. Start converting components one by one
|
||||
3. Add any missing translation keys to `LanguageContext.tsx`
|
||||
4. Test thoroughly in both languages
|
||||
|
||||
---
|
||||
|
||||
**Note**: The translation system is now fully integrated. Every component you create should use the `useLanguage()` hook and `t()` function for 100% bilingual support.
|
||||
Reference in New Issue
Block a user