add dropdown

This commit is contained in:
Phuoc Nguyen
2025-10-28 16:24:17 +07:00
parent 0010446298
commit 5cfc56f40d
20 changed files with 912 additions and 12 deletions

View File

@@ -2,6 +2,7 @@ import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import '../../../../core/di/providers.dart';
import '../../../users/domain/entities/user_entity.dart';
import '../../domain/entities/product_stage_entity.dart';
/// Product detail page
@@ -34,13 +35,20 @@ class _ProductDetailPageState extends ConsumerState<ProductDetailPage> {
final TextEditingController _issuedQuantityController = TextEditingController();
final TextEditingController _issuedWeightController = TextEditingController();
// Selected users for dropdowns
UserEntity? _selectedWarehouseUser;
UserEntity? _selectedEmployee;
@override
void initState() {
super.initState();
_providerKey = '${widget.warehouseId}_${widget.productId}';
// Load product stages when page is initialized
// Load product stages and users when page is initialized
Future.microtask(() async {
// Load users from Hive (no API call)
await ref.read(usersProvider.notifier).getUsers();
await ref.read(productDetailProvider(_providerKey).notifier).loadProductDetail(
widget.warehouseId,
widget.productId,
@@ -80,6 +88,10 @@ class _ProductDetailPageState extends ConsumerState<ProductDetailPage> {
_passedWeightController.clear();
_issuedQuantityController.clear();
_issuedWeightController.clear();
setState(() {
_selectedWarehouseUser = null;
_selectedEmployee = null;
});
}
@override
@@ -385,7 +397,6 @@ class _ProductDetailPageState extends ConsumerState<ProductDetailPage> {
'Passed Weight',
'${stageToShow.passedQuantityWeight.toStringAsFixed(2)} kg',
),
const Divider(height: 24),
_buildInfoRow('Issued Quantity', '${stageToShow.issuedQuantity}'),
_buildInfoRow(
'Issued Weight',
@@ -406,21 +417,18 @@ class _ProductDetailPageState extends ConsumerState<ProductDetailPage> {
keyboardType: TextInputType.number,
theme: theme,
),
const SizedBox(height: 12),
_buildTextField(
label: 'Passed Weight (kg)',
controller: _passedWeightController,
keyboardType: const TextInputType.numberWithOptions(decimal: true),
theme: theme,
),
const Divider(height: 24),
_buildTextField(
label: 'Issued Quantity',
controller: _issuedQuantityController,
keyboardType: TextInputType.number,
theme: theme,
),
const SizedBox(height: 12),
_buildTextField(
label: 'Issued Weight (kg)',
controller: _issuedWeightController,
@@ -430,9 +438,34 @@ class _ProductDetailPageState extends ConsumerState<ProductDetailPage> {
],
),
// Stage information
_buildSectionCard(theme: theme, title: "Nhân viên", icon: Icons.people, children: [
// Warehouse User Dropdown
_buildUserDropdown(
label: 'Warehouse User',
value: _selectedWarehouseUser,
users: ref.watch(usersListProvider)
.where((user) => user.isWareHouseUser)
.toList(),
onChanged: (user) {
setState(() {
_selectedWarehouseUser = user;
});
},
theme: theme,
),
// All Employees Dropdown
_buildUserDropdown(
label: 'Employee',
value: _selectedEmployee,
users: ref.watch(usersListProvider),
onChanged: (user) {
setState(() {
_selectedEmployee = user;
});
},
theme: theme,
),
]),
// Add button
SizedBox(
@@ -489,6 +522,10 @@ class _ProductDetailPageState extends ConsumerState<ProductDetailPage> {
// Log the values for debugging
debugPrint('Adding new quantities for stage ${stage.productStageId}:');
debugPrint(' Warehouse User: ${_selectedWarehouseUser?.fullName ?? "Not selected"}');
debugPrint(' Warehouse User ID: ${_selectedWarehouseUser?.id}');
debugPrint(' Employee: ${_selectedEmployee?.fullName ?? "Not selected"}');
debugPrint(' Employee ID: ${_selectedEmployee?.id}');
debugPrint(' Passed Quantity: $passedQuantity');
debugPrint(' Passed Weight: $passedWeight');
debugPrint(' Issued Quantity: $issuedQuantity');
@@ -556,6 +593,7 @@ class _ProductDetailPageState extends ConsumerState<ProductDetailPage> {
padding: const EdgeInsets.all(16),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
spacing: 12,
children: [
Row(
children: [
@@ -583,7 +621,7 @@ class _ProductDetailPageState extends ConsumerState<ProductDetailPage> {
Widget _buildInfoRow(String label, String value) {
return Padding(
padding: const EdgeInsets.only(bottom: 12),
padding: const EdgeInsets.only(bottom: 4),
child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
@@ -699,6 +737,60 @@ class _ProductDetailPageState extends ConsumerState<ProductDetailPage> {
);
}
Widget _buildUserDropdown({
required String label,
required UserEntity? value,
required List<UserEntity> users,
required Function(UserEntity?) onChanged,
required ThemeData theme,
}) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
DropdownButtonFormField<UserEntity>(
value: value,
decoration: InputDecoration(
labelText: label,
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(8),
),
enabledBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(8),
borderSide: BorderSide(
color: theme.colorScheme.outline,
),
),
focusedBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(8),
borderSide: BorderSide(
color: theme.colorScheme.primary,
width: 2,
),
),
filled: true,
fillColor: theme.colorScheme.surface,
contentPadding: const EdgeInsets.symmetric(
horizontal: 16,
vertical: 12,
),
),
hint: Text('Select $label'),
items: users.map((user) {
return DropdownMenuItem<UserEntity>(
value: user,
child: Text(
user.name.isNotEmpty ? '${user.name} ${user.firstName}' : user.email,
overflow: TextOverflow.ellipsis,
),
);
}).toList(),
onChanged: onChanged,
isExpanded: true,
),
],
);
}
void _incrementValue(TextEditingController controller, double increment) {
final currentValue = double.tryParse(controller.text) ?? 0.0;
final newValue = currentValue + increment;