runable
This commit is contained in:
278
lib/core/utils/README_L10N.md
Normal file
278
lib/core/utils/README_L10N.md
Normal file
@@ -0,0 +1,278 @@
|
||||
# Localization Extensions - Quick Start Guide
|
||||
|
||||
## Using Localization in the Worker App
|
||||
|
||||
This file demonstrates how to use the localization utilities in the Worker Flutter app.
|
||||
|
||||
## Basic Usage
|
||||
|
||||
### 1. Import the Extension
|
||||
|
||||
```dart
|
||||
import 'package:worker/core/utils/l10n_extensions.dart';
|
||||
```
|
||||
|
||||
### 2. Access Translations
|
||||
|
||||
```dart
|
||||
// In any widget with BuildContext
|
||||
class MyWidget extends StatelessWidget {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Column(
|
||||
children: [
|
||||
Text(context.l10n.home), // "Trang chủ" or "Home"
|
||||
Text(context.l10n.products), // "Sản phẩm" or "Products"
|
||||
Text(context.l10n.loyalty), // "Hội viên" or "Loyalty"
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Helper Functions
|
||||
|
||||
### Date and Time
|
||||
|
||||
```dart
|
||||
// Format date
|
||||
final dateStr = L10nHelper.formatDate(context, DateTime.now());
|
||||
// Vietnamese: "17/10/2025"
|
||||
// English: "10/17/2025"
|
||||
|
||||
// Format date-time
|
||||
final dateTimeStr = L10nHelper.formatDateTime(context, DateTime.now());
|
||||
// Vietnamese: "17/10/2025 lúc 14:30"
|
||||
// English: "10/17/2025 at 14:30"
|
||||
|
||||
// Relative time
|
||||
final relativeTime = L10nHelper.formatRelativeTime(
|
||||
context,
|
||||
DateTime.now().subtract(Duration(minutes: 5)),
|
||||
);
|
||||
// Vietnamese: "5 phút trước"
|
||||
// English: "5 minutes ago"
|
||||
```
|
||||
|
||||
### Currency
|
||||
|
||||
```dart
|
||||
// Format Vietnamese Dong
|
||||
final price = L10nHelper.formatCurrency(context, 1500000);
|
||||
// Vietnamese: "1.500.000 ₫"
|
||||
// English: "1,500,000 ₫"
|
||||
```
|
||||
|
||||
### Status Helpers
|
||||
|
||||
```dart
|
||||
// Get localized order status
|
||||
final status = L10nHelper.getOrderStatus(context, 'pending');
|
||||
// Vietnamese: "Chờ xử lý"
|
||||
// English: "Pending"
|
||||
|
||||
// Get localized project status
|
||||
final projectStatus = L10nHelper.getProjectStatus(context, 'in_progress');
|
||||
// Vietnamese: "Đang thực hiện"
|
||||
// English: "In Progress"
|
||||
|
||||
// Get localized member tier
|
||||
final tier = L10nHelper.getMemberTier(context, 'diamond');
|
||||
// Vietnamese: "Kim cương"
|
||||
// English: "Diamond"
|
||||
|
||||
// Get localized user type
|
||||
final userType = L10nHelper.getUserType(context, 'contractor');
|
||||
// Vietnamese: "Thầu thợ"
|
||||
// English: "Contractor"
|
||||
```
|
||||
|
||||
### Counts with Pluralization
|
||||
|
||||
```dart
|
||||
// Format points with sign
|
||||
final points = L10nHelper.formatPoints(context, 100);
|
||||
// Vietnamese: "+100 điểm"
|
||||
// English: "+100 points"
|
||||
|
||||
// Format item count
|
||||
final items = L10nHelper.formatItemCount(context, 5);
|
||||
// Vietnamese: "5 sản phẩm"
|
||||
// English: "5 items"
|
||||
|
||||
// Format order count
|
||||
final orders = L10nHelper.formatOrderCount(context, 3);
|
||||
// Vietnamese: "3 đơn hàng"
|
||||
// English: "3 orders"
|
||||
|
||||
// Format project count
|
||||
final projects = L10nHelper.formatProjectCount(context, 2);
|
||||
// Vietnamese: "2 công trình"
|
||||
// English: "2 projects"
|
||||
|
||||
// Format days remaining
|
||||
final days = L10nHelper.formatDaysRemaining(context, 7);
|
||||
// Vietnamese: "Còn 7 ngày"
|
||||
// English: "7 days left"
|
||||
```
|
||||
|
||||
## Context Extensions
|
||||
|
||||
### Language Checks
|
||||
|
||||
```dart
|
||||
// Get current language code
|
||||
final languageCode = context.languageCode; // "vi" or "en"
|
||||
|
||||
// Check if Vietnamese
|
||||
if (context.isVietnamese) {
|
||||
// Do something specific for Vietnamese
|
||||
}
|
||||
|
||||
// Check if English
|
||||
if (context.isEnglish) {
|
||||
// Do something specific for English
|
||||
}
|
||||
```
|
||||
|
||||
## Parameterized Translations
|
||||
|
||||
```dart
|
||||
// Simple parameter
|
||||
final welcome = context.l10n.welcomeTo('Worker App');
|
||||
// Vietnamese: "Chào mừng đến với Worker App"
|
||||
// English: "Welcome to Worker App"
|
||||
|
||||
// Multiple parameters
|
||||
final message = context.l10n.pointsToNextTier(500, 'Platinum');
|
||||
// Vietnamese: "Còn 500 điểm để lên hạng Platinum"
|
||||
// English: "500 points to reach Platinum"
|
||||
|
||||
// Order number
|
||||
final orderNum = context.l10n.orderNumberIs('ORD-2024-001');
|
||||
// Vietnamese: "Số đơn hàng: ORD-2024-001"
|
||||
// English: "Order Number: ORD-2024-001"
|
||||
|
||||
// Redeem confirmation
|
||||
final confirm = context.l10n.redeemConfirmMessage(500, 'Gift Voucher');
|
||||
// Vietnamese: "Bạn có chắc chắn muốn đổi 500 điểm để nhận Gift Voucher?"
|
||||
// English: "Are you sure you want to redeem 500 points for Gift Voucher?"
|
||||
```
|
||||
|
||||
## Complete Example
|
||||
|
||||
```dart
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:worker/core/utils/l10n_extensions.dart';
|
||||
|
||||
class OrderDetailPage extends ConsumerWidget {
|
||||
final Order order;
|
||||
|
||||
const OrderDetailPage({required this.order});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
title: Text(context.l10n.orderDetails),
|
||||
),
|
||||
body: Padding(
|
||||
padding: const EdgeInsets.all(16.0),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
// Order number
|
||||
Text(
|
||||
context.l10n.orderNumberIs(order.orderNumber),
|
||||
style: Theme.of(context).textTheme.titleLarge,
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
|
||||
// Order date
|
||||
Text(
|
||||
'${context.l10n.orderDate}: ${L10nHelper.formatDate(context, order.createdAt)}',
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
|
||||
// Order status
|
||||
Row(
|
||||
children: [
|
||||
Text(context.l10n.orderStatus + ': '),
|
||||
Chip(
|
||||
label: Text(
|
||||
L10nHelper.getOrderStatus(context, order.status),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
|
||||
// Items count
|
||||
Text(
|
||||
L10nHelper.formatItemCount(context, order.items.length),
|
||||
style: Theme.of(context).textTheme.titleMedium,
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
|
||||
// Total amount
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Text(
|
||||
context.l10n.total,
|
||||
style: Theme.of(context).textTheme.titleMedium,
|
||||
),
|
||||
Text(
|
||||
L10nHelper.formatCurrency(context, order.total),
|
||||
style: Theme.of(context).textTheme.titleLarge?.copyWith(
|
||||
color: Theme.of(context).colorScheme.primary,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 24),
|
||||
|
||||
// Relative time
|
||||
Text(
|
||||
'${context.l10n.orderPlacedAt} ${L10nHelper.formatRelativeTime(context, order.createdAt)}',
|
||||
style: Theme.of(context).textTheme.bodySmall,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Best Practices
|
||||
|
||||
1. **Always use `context.l10n` instead of `AppLocalizations.of(context)!`**
|
||||
- Shorter and cleaner
|
||||
- Consistent throughout the codebase
|
||||
|
||||
2. **Use helper functions for formatting**
|
||||
- `L10nHelper.formatCurrency()` instead of manual formatting
|
||||
- `L10nHelper.formatDate()` for locale-aware dates
|
||||
- `L10nHelper.getOrderStatus()` for localized status strings
|
||||
|
||||
3. **Check language when needed**
|
||||
- Use `context.isVietnamese` and `context.isEnglish`
|
||||
- Useful for conditional rendering or logic
|
||||
|
||||
4. **Never hard-code strings**
|
||||
- Always use translation keys
|
||||
- Supports both Vietnamese and English automatically
|
||||
|
||||
5. **Test both languages**
|
||||
- Switch device language to test
|
||||
- Verify text fits in UI for both languages
|
||||
|
||||
## See Also
|
||||
|
||||
- Full documentation: `/Users/ssg/project/worker/LOCALIZATION.md`
|
||||
- Vietnamese translations: `/Users/ssg/project/worker/lib/l10n/app_vi.arb`
|
||||
- English translations: `/Users/ssg/project/worker/lib/l10n/app_en.arb`
|
||||
- Helper source code: `/Users/ssg/project/worker/lib/core/utils/l10n_extensions.dart`
|
||||
Reference in New Issue
Block a user