This commit is contained in:
2025-10-28 23:56:47 +07:00
parent f32e1c16fb
commit 2905668358
5 changed files with 51 additions and 51 deletions

View File

@@ -72,7 +72,7 @@ class AppRouter {
context.go('/warehouses'); context.go('/warehouses');
}); });
return const _ErrorScreen( return const _ErrorScreen(
message: 'Warehouse data is required', message: 'Yêu cầu dữ liệu kho',
); );
} }
@@ -103,7 +103,7 @@ class AppRouter {
context.go('/warehouses'); context.go('/warehouses');
}); });
return const _ErrorScreen( return const _ErrorScreen(
message: 'Invalid product parameters', message: 'Tham số sản phẩm không hợp lệ',
); );
} }
@@ -143,7 +143,7 @@ class AppRouter {
context.go('/warehouses'); context.go('/warehouses');
}); });
return const _ErrorScreen( return const _ErrorScreen(
message: 'Invalid product detail parameters', message: 'Tham số chi tiết sản phẩm không hợp lệ',
); );
} }
@@ -163,7 +163,7 @@ class AppRouter {
errorBuilder: (context, state) { errorBuilder: (context, state) {
return Scaffold( return Scaffold(
appBar: AppBar( appBar: AppBar(
title: const Text('Page Not Found'), title: const Text('Không tìm thấy trang'),
), ),
body: Center( body: Center(
child: Column( child: Column(
@@ -176,12 +176,12 @@ class AppRouter {
), ),
const SizedBox(height: 16), const SizedBox(height: 16),
Text( Text(
'Page Not Found', 'Không tìm thấy trang',
style: Theme.of(context).textTheme.headlineSmall, style: Theme.of(context).textTheme.headlineSmall,
), ),
const SizedBox(height: 8), const SizedBox(height: 8),
Text( Text(
'The page "${state.uri.path}" does not exist.', 'Trang "${state.uri.path}" không tồn tại.',
style: Theme.of(context).textTheme.bodyMedium?.copyWith( style: Theme.of(context).textTheme.bodyMedium?.copyWith(
color: Theme.of(context).colorScheme.onSurfaceVariant, color: Theme.of(context).colorScheme.onSurfaceVariant,
), ),
@@ -190,7 +190,7 @@ class AppRouter {
const SizedBox(height: 24), const SizedBox(height: 24),
ElevatedButton( ElevatedButton(
onPressed: () => context.go('/login'), onPressed: () => context.go('/login'),
child: const Text('Go to Login'), child: const Text('Về trang đăng nhập'),
), ),
], ],
), ),
@@ -283,7 +283,7 @@ class _ErrorScreen extends StatelessWidget {
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Scaffold( return Scaffold(
appBar: AppBar( appBar: AppBar(
title: const Text('Error'), title: const Text('Lỗi'),
), ),
body: Center( body: Center(
child: Column( child: Column(
@@ -296,7 +296,7 @@ class _ErrorScreen extends StatelessWidget {
), ),
const SizedBox(height: 16), const SizedBox(height: 16),
Text( Text(
'Navigation Error', 'Lỗi điều hướng',
style: Theme.of(context).textTheme.headlineSmall, style: Theme.of(context).textTheme.headlineSmall,
), ),
const SizedBox(height: 8), const SizedBox(height: 8),
@@ -313,7 +313,7 @@ class _ErrorScreen extends StatelessWidget {
const SizedBox(height: 24), const SizedBox(height: 24),
ElevatedButton( ElevatedButton(
onPressed: () => context.go('/warehouses'), onPressed: () => context.go('/warehouses'),
child: const Text('Go to Warehouses'), child: const Text('Về trang kho'),
), ),
], ],
), ),

View File

@@ -33,7 +33,7 @@ class ProductStageEntity extends Equatable {
/// Get display name for the stage /// Get display name for the stage
/// Returns "No Stage" if stageName is null /// Returns "No Stage" if stageName is null
String get displayName => stageName ?? 'No Stage'; String get displayName => stageName ?? 'Không tên';
/// Check if this is a valid stage (has a stage name) /// Check if this is a valid stage (has a stage name)
bool get hasStage => stageName != null && stageName!.isNotEmpty; bool get hasStage => stageName != null && stageName!.isNotEmpty;

View File

@@ -80,10 +80,10 @@ class _ProductDetailPageState extends ConsumerState<ProductDetailPage> {
} }
Future<void> _onRefresh() async { Future<void> _onRefresh() async {
await ref.read(productDetailProvider(_providerKey).notifier).refreshProductDetail( // await ref.read(productDetailProvider(_providerKey).notifier).refreshProductDetail(
widget.warehouseId, // widget.warehouseId,
widget.productId, // widget.productId,
); // );
} }
void _clearControllers() { void _clearControllers() {
@@ -114,7 +114,7 @@ class _ProductDetailPageState extends ConsumerState<ProductDetailPage> {
final productName = stages.isNotEmpty ? stages.first.productName : 'Product'; final productName = stages.isNotEmpty ? stages.first.productName : 'Product';
// Capitalize first letter of operation type // Capitalize first letter of operation type
final operationTitle = widget.operationType == 'import' ? 'Import' : 'Export'; final operationTitle = widget.operationType == 'import' ? 'Nhập' : 'Xuất';
return Scaffold( return Scaffold(
appBar: AppBar( appBar: AppBar(
@@ -137,7 +137,7 @@ class _ProductDetailPageState extends ConsumerState<ProductDetailPage> {
IconButton( IconButton(
icon: const Icon(Icons.refresh), icon: const Icon(Icons.refresh),
onPressed: _onRefresh, onPressed: _onRefresh,
tooltip: 'Refresh', tooltip: 'Làm mới',
), ),
], ],
), ),
@@ -215,7 +215,7 @@ class _ProductDetailPageState extends ConsumerState<ProductDetailPage> {
), ),
const SizedBox(height: 16), const SizedBox(height: 16),
Text( Text(
'No stages found', 'Không tìm thấy công đoạn',
style: theme.textTheme.titleLarge, style: theme.textTheme.titleLarge,
), ),
], ],
@@ -244,14 +244,14 @@ class _ProductDetailPageState extends ConsumerState<ProductDetailPage> {
), ),
const SizedBox(height: 16), const SizedBox(height: 16),
Text( Text(
'Stage Not Found', 'Không tìm thấy công đoạn',
style: theme.textTheme.titleLarge?.copyWith( style: theme.textTheme.titleLarge?.copyWith(
color: theme.colorScheme.error, color: theme.colorScheme.error,
), ),
), ),
const SizedBox(height: 8), const SizedBox(height: 8),
Text( Text(
'Stage with ID ${widget.stageId} was not found in this product.', 'Công đoạn với ID ${widget.stageId} không được tìm thấy trong sản phẩm này.',
textAlign: TextAlign.center, textAlign: TextAlign.center,
style: theme.textTheme.bodyMedium, style: theme.textTheme.bodyMedium,
), ),
@@ -293,8 +293,8 @@ class _ProductDetailPageState extends ConsumerState<ProductDetailPage> {
children: [ children: [
Text( Text(
widget.stageId != null widget.stageId != null
? 'Selected Stage' ? 'Công đoạn'
: 'Production Stages (${displayStages.length})', : 'Công đoạn (${displayStages.length})',
style: theme.textTheme.titleSmall?.copyWith( style: theme.textTheme.titleSmall?.copyWith(
fontWeight: FontWeight.bold, fontWeight: FontWeight.bold,
), ),
@@ -383,32 +383,32 @@ class _ProductDetailPageState extends ConsumerState<ProductDetailPage> {
_buildSectionCard( _buildSectionCard(
theme: theme, theme: theme,
title: 'Stage Information', title: 'Thông tin công đoạn',
icon: Icons.info_outlined, icon: Icons.info_outlined,
children: [ children: [
_buildInfoRow('Product ID', '${stageToShow.productId}'), _buildInfoRow('Mã sản phẩm', '${stageToShow.productId}'),
if (stageToShow.productStageId != null) if (stageToShow.productStageId != null)
_buildInfoRow('Stage ID', '${stageToShow.productStageId}'), _buildInfoRow('Mã công đoạn', '${stageToShow.productStageId}'),
if (stageToShow.actionTypeId != null) if (stageToShow.actionTypeId != null)
_buildInfoRow('Action Type ID', '${stageToShow.actionTypeId}'), _buildInfoRow('Mã loại thao tác', '${stageToShow.actionTypeId}'),
_buildInfoRow('Stage Name', stageToShow.displayName), _buildInfoRow('Tên công đoạn', stageToShow.displayName),
], ],
), ),
// Current Quantity information // Current Quantity information
_buildSectionCard( _buildSectionCard(
theme: theme, theme: theme,
title: 'Current Quantities', title: 'Số lượng hiện tại',
icon: Icons.info_outlined, icon: Icons.info_outlined,
children: [ children: [
_buildInfoRow('Passed Quantity', '${stageToShow.passedQuantity}'), _buildInfoRow('Số lượng đạt', '${stageToShow.passedQuantity}'),
_buildInfoRow( _buildInfoRow(
'Passed Weight', 'Khối lượng đạt',
'${stageToShow.passedQuantityWeight.toStringAsFixed(2)} kg', '${stageToShow.passedQuantityWeight.toStringAsFixed(2)} kg',
), ),
_buildInfoRow('Issued Quantity', '${stageToShow.issuedQuantity}'), _buildInfoRow('Số lượng lỗi', '${stageToShow.issuedQuantity}'),
_buildInfoRow( _buildInfoRow(
'Issued Weight', 'Khối lượng lỗi',
'${stageToShow.issuedQuantityWeight.toStringAsFixed(2)} kg', '${stageToShow.issuedQuantityWeight.toStringAsFixed(2)} kg',
), ),
], ],
@@ -417,29 +417,29 @@ class _ProductDetailPageState extends ConsumerState<ProductDetailPage> {
// Add New Quantities section // Add New Quantities section
_buildSectionCard( _buildSectionCard(
theme: theme, theme: theme,
title: 'Add New Quantities', title: 'Thêm số lượng mới',
icon: Icons.add_circle_outline, icon: Icons.add_circle_outline,
children: [ children: [
_buildTextField( _buildTextField(
label: 'Passed Quantity', label: 'Số lượng đạt',
controller: _passedQuantityController, controller: _passedQuantityController,
keyboardType: TextInputType.number, keyboardType: TextInputType.number,
theme: theme, theme: theme,
), ),
_buildTextField( _buildTextField(
label: 'Passed Weight (kg)', label: 'Khối lượng đạt (kg)',
controller: _passedWeightController, controller: _passedWeightController,
keyboardType: const TextInputType.numberWithOptions(decimal: true), keyboardType: const TextInputType.numberWithOptions(decimal: true),
theme: theme, theme: theme,
), ),
_buildTextField( _buildTextField(
label: 'Issued Quantity', label: 'Số lượng lỗi',
controller: _issuedQuantityController, controller: _issuedQuantityController,
keyboardType: TextInputType.number, keyboardType: TextInputType.number,
theme: theme, theme: theme,
), ),
_buildTextField( _buildTextField(
label: 'Issued Weight (kg)', label: 'Khối lượng lỗi (kg)',
controller: _issuedWeightController, controller: _issuedWeightController,
keyboardType: const TextInputType.numberWithOptions(decimal: true), keyboardType: const TextInputType.numberWithOptions(decimal: true),
theme: theme, theme: theme,
@@ -450,7 +450,7 @@ class _ProductDetailPageState extends ConsumerState<ProductDetailPage> {
_buildSectionCard(theme: theme, title: "Nhân viên", icon: Icons.people, children: [ _buildSectionCard(theme: theme, title: "Nhân viên", icon: Icons.people, children: [
// Warehouse User Dropdown // Warehouse User Dropdown
_buildUserDropdown( _buildUserDropdown(
label: 'Warehouse User', label: 'Người dùng kho',
value: _selectedWarehouseUser, value: _selectedWarehouseUser,
users: ref.watch(usersListProvider) users: ref.watch(usersListProvider)
.where((user) => user.isWareHouseUser) .where((user) => user.isWareHouseUser)
@@ -464,7 +464,7 @@ class _ProductDetailPageState extends ConsumerState<ProductDetailPage> {
), ),
// All Employees Dropdown // All Employees Dropdown
_buildUserDropdown( _buildUserDropdown(
label: 'Employee', label: 'Nhân viên',
value: _selectedEmployee, value: _selectedEmployee,
users: ref.watch(usersListProvider), users: ref.watch(usersListProvider),
onChanged: (user) { onChanged: (user) {
@@ -686,7 +686,7 @@ class _ProductDetailPageState extends ConsumerState<ProductDetailPage> {
), ),
const SizedBox(height: 4), const SizedBox(height: 4),
Text( Text(
'Product ID: ${stage.productId}', 'Sản phẩm ID: ${stage.productId}',
style: theme.textTheme.bodyMedium?.copyWith( style: theme.textTheme.bodyMedium?.copyWith(
color: theme.colorScheme.onSurfaceVariant, color: theme.colorScheme.onSurfaceVariant,
), ),

View File

@@ -45,7 +45,7 @@ class ProductListItem extends StatelessWidget {
), ),
const SizedBox(height: 4), const SizedBox(height: 4),
Text( Text(
'Code: ${product.code}', ': ${product.code}',
style: textTheme.bodySmall?.copyWith( style: textTheme.bodySmall?.copyWith(
color: theme.colorScheme.primary, color: theme.colorScheme.primary,
), ),
@@ -65,7 +65,7 @@ class ProductListItem extends StatelessWidget {
borderRadius: BorderRadius.circular(4), borderRadius: BorderRadius.circular(4),
), ),
child: Text( child: Text(
'Active', 'Hoạt động',
style: textTheme.labelSmall?.copyWith( style: textTheme.labelSmall?.copyWith(
color: Colors.green, color: Colors.green,
fontWeight: FontWeight.bold, fontWeight: FontWeight.bold,
@@ -84,7 +84,7 @@ class ProductListItem extends StatelessWidget {
children: [ children: [
Expanded( Expanded(
child: _InfoItem( child: _InfoItem(
label: 'Weight', label: 'Khối lượng',
value: '${product.weight.toStringAsFixed(2)} kg', value: '${product.weight.toStringAsFixed(2)} kg',
icon: Icons.fitness_center, icon: Icons.fitness_center,
), ),
@@ -92,7 +92,7 @@ class ProductListItem extends StatelessWidget {
const SizedBox(width: 16), const SizedBox(width: 16),
Expanded( Expanded(
child: _InfoItem( child: _InfoItem(
label: 'Pieces', label: 'Số lượng',
value: product.pieces.toString(), value: product.pieces.toString(),
icon: Icons.inventory_2, icon: Icons.inventory_2,
), ),
@@ -107,7 +107,7 @@ class ProductListItem extends StatelessWidget {
children: [ children: [
Expanded( Expanded(
child: _InfoItem( child: _InfoItem(
label: 'In Stock (Pieces)', label: 'Tồn kho (SL)',
value: product.piecesInStock.toString(), value: product.piecesInStock.toString(),
icon: Icons.warehouse, icon: Icons.warehouse,
color: product.piecesInStock > 0 color: product.piecesInStock > 0
@@ -118,7 +118,7 @@ class ProductListItem extends StatelessWidget {
const SizedBox(width: 16), const SizedBox(width: 16),
Expanded( Expanded(
child: _InfoItem( child: _InfoItem(
label: 'In Stock (Weight)', label: 'Tồn kho (KL)',
value: '${product.weightInStock.toStringAsFixed(2)} kg', value: '${product.weightInStock.toStringAsFixed(2)} kg',
icon: Icons.scale, icon: Icons.scale,
color: product.weightInStock > 0 color: product.weightInStock > 0
@@ -142,7 +142,7 @@ class ProductListItem extends StatelessWidget {
mainAxisAlignment: MainAxisAlignment.spaceBetween, mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [ children: [
Text( Text(
'Conversion Rate', 'Tỷ lệ chuyển đổi',
style: textTheme.bodyMedium?.copyWith( style: textTheme.bodyMedium?.copyWith(
fontWeight: FontWeight.w500, fontWeight: FontWeight.w500,
), ),
@@ -170,7 +170,7 @@ class ProductListItem extends StatelessWidget {
), ),
const SizedBox(width: 4), const SizedBox(width: 4),
Text( Text(
'Barcode: ${product.barcode}', 'Mã vạch: ${product.barcode}',
style: textTheme.bodySmall?.copyWith( style: textTheme.bodySmall?.copyWith(
color: theme.colorScheme.onSurfaceVariant, color: theme.colorScheme.onSurfaceVariant,
), ),

View File

@@ -49,7 +49,7 @@ class WarehouseCard extends StatelessWidget {
), ),
const SizedBox(width: 4), const SizedBox(width: 4),
Text( Text(
'Code: ${warehouse.code}', ': ${warehouse.code}',
style: theme.textTheme.bodyMedium?.copyWith( style: theme.textTheme.bodyMedium?.copyWith(
color: colorScheme.onSurfaceVariant, color: colorScheme.onSurfaceVariant,
), ),
@@ -68,7 +68,7 @@ class WarehouseCard extends StatelessWidget {
), ),
const SizedBox(width: 4), const SizedBox(width: 4),
Text( Text(
'Items: ${warehouse.totalCount}', 'Sản phẩm: ${warehouse.totalCount}',
style: theme.textTheme.bodyMedium?.copyWith( style: theme.textTheme.bodyMedium?.copyWith(
color: colorScheme.onSurfaceVariant, color: colorScheme.onSurfaceVariant,
), ),
@@ -104,7 +104,7 @@ class WarehouseCard extends StatelessWidget {
borderRadius: BorderRadius.circular(4), borderRadius: BorderRadius.circular(4),
), ),
child: Text( child: Text(
'NG Warehouse', 'Kho NG',
style: theme.textTheme.labelSmall?.copyWith( style: theme.textTheme.labelSmall?.copyWith(
color: colorScheme.onErrorContainer, color: colorScheme.onErrorContainer,
fontWeight: FontWeight.bold, fontWeight: FontWeight.bold,