reenhancement of employee selector
This commit is contained in:
parent
5e1379b74b
commit
6b58085434
@ -1,5 +1,6 @@
|
|||||||
import 'dart:convert';
|
import 'dart:convert';
|
||||||
import 'dart:io';
|
import 'dart:io';
|
||||||
|
import 'dart:async';
|
||||||
|
|
||||||
import 'package:file_picker/file_picker.dart';
|
import 'package:file_picker/file_picker.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
@ -50,10 +51,22 @@ class AddExpenseController extends GetxController {
|
|||||||
final isEditMode = false.obs;
|
final isEditMode = false.obs;
|
||||||
final isSearchingEmployees = false.obs;
|
final isSearchingEmployees = false.obs;
|
||||||
|
|
||||||
|
// --- Paid By (Single + Multi Selection Support) ---
|
||||||
|
|
||||||
|
// single selection
|
||||||
|
final selectedPaidBy = Rxn<EmployeeModel>();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// helper setters
|
||||||
|
void setSelectedPaidBy(EmployeeModel? emp) {
|
||||||
|
selectedPaidBy.value = emp;
|
||||||
|
}
|
||||||
|
|
||||||
// --- Dropdown Selections & Data ---
|
// --- Dropdown Selections & Data ---
|
||||||
final selectedPaymentMode = Rxn<PaymentModeModel>();
|
final selectedPaymentMode = Rxn<PaymentModeModel>();
|
||||||
final selectedExpenseType = Rxn<ExpenseTypeModel>();
|
final selectedExpenseType = Rxn<ExpenseTypeModel>();
|
||||||
final selectedPaidBy = Rxn<EmployeeModel>();
|
// final selectedPaidBy = Rxn<EmployeeModel>();
|
||||||
final selectedProject = ''.obs;
|
final selectedProject = ''.obs;
|
||||||
final selectedTransactionDate = Rxn<DateTime>();
|
final selectedTransactionDate = Rxn<DateTime>();
|
||||||
|
|
||||||
|
|||||||
@ -5,13 +5,14 @@ import 'package:on_field_work/controller/expense/add_expense_controller.dart';
|
|||||||
import 'package:on_field_work/helpers/utils/mixins/ui_mixin.dart';
|
import 'package:on_field_work/helpers/utils/mixins/ui_mixin.dart';
|
||||||
import 'package:on_field_work/model/expense/expense_type_model.dart';
|
import 'package:on_field_work/model/expense/expense_type_model.dart';
|
||||||
import 'package:on_field_work/model/expense/payment_types_model.dart';
|
import 'package:on_field_work/model/expense/payment_types_model.dart';
|
||||||
import 'package:on_field_work/model/expense/employee_selector_bottom_sheet.dart';
|
|
||||||
import 'package:on_field_work/helpers/utils/base_bottom_sheet.dart';
|
import 'package:on_field_work/helpers/utils/base_bottom_sheet.dart';
|
||||||
import 'package:on_field_work/helpers/utils/validators.dart';
|
import 'package:on_field_work/helpers/utils/validators.dart';
|
||||||
import 'package:on_field_work/helpers/widgets/my_spacing.dart';
|
import 'package:on_field_work/helpers/widgets/my_spacing.dart';
|
||||||
import 'package:on_field_work/helpers/widgets/my_snackbar.dart';
|
import 'package:on_field_work/helpers/widgets/my_snackbar.dart';
|
||||||
import 'package:on_field_work/helpers/widgets/my_confirmation_dialog.dart';
|
import 'package:on_field_work/helpers/widgets/my_confirmation_dialog.dart';
|
||||||
import 'package:on_field_work/helpers/widgets/expense/expense_form_widgets.dart';
|
import 'package:on_field_work/helpers/widgets/expense/expense_form_widgets.dart';
|
||||||
|
import 'package:on_field_work/model/employees/employee_model.dart';
|
||||||
|
import 'package:on_field_work/model/employees/multiple_select_bottomsheet.dart';
|
||||||
|
|
||||||
/// Show bottom sheet wrapper
|
/// Show bottom sheet wrapper
|
||||||
Future<T?> showAddExpenseBottomSheet<T>({
|
Future<T?> showAddExpenseBottomSheet<T>({
|
||||||
@ -52,24 +53,36 @@ class _AddExpenseBottomSheetState extends State<_AddExpenseBottomSheet>
|
|||||||
|
|
||||||
/// Show employee list
|
/// Show employee list
|
||||||
Future<void> _showEmployeeList() async {
|
Future<void> _showEmployeeList() async {
|
||||||
await showModalBottomSheet(
|
final result = await showModalBottomSheet<dynamic>(
|
||||||
context: context,
|
context: context,
|
||||||
isScrollControlled: true,
|
isScrollControlled: true,
|
||||||
backgroundColor: Colors.transparent,
|
backgroundColor: Colors.transparent,
|
||||||
shape: const RoundedRectangleBorder(
|
shape: const RoundedRectangleBorder(
|
||||||
borderRadius: BorderRadius.vertical(top: Radius.circular(16)),
|
borderRadius: BorderRadius.vertical(top: Radius.circular(16)),
|
||||||
),
|
),
|
||||||
builder: (_) => ReusableEmployeeSelectorBottomSheet(
|
builder: (_) => EmployeeSelectionBottomSheet(
|
||||||
searchController: controller.employeeSearchController,
|
initiallySelected: controller.selectedPaidBy.value != null
|
||||||
searchResults: controller.employeeSearchResults,
|
? [controller.selectedPaidBy.value!]
|
||||||
isSearching: controller.isSearchingEmployees,
|
: [],
|
||||||
onSearch: controller.searchEmployees,
|
multipleSelection: false,
|
||||||
onSelect: (emp) => controller.selectedPaidBy.value = emp,
|
title: "Select Paid By",
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
if (result == null) return;
|
||||||
|
|
||||||
|
// result will be EmployeeModel or [EmployeeModel]
|
||||||
|
if (result is EmployeeModel) {
|
||||||
|
controller.setSelectedPaidBy(result);
|
||||||
|
} else if (result is List && result.isNotEmpty) {
|
||||||
|
controller.setSelectedPaidBy(result.first as EmployeeModel);
|
||||||
|
}
|
||||||
|
|
||||||
|
// cleanup
|
||||||
|
try {
|
||||||
controller.employeeSearchController.clear();
|
controller.employeeSearchController.clear();
|
||||||
controller.employeeSearchResults.clear();
|
controller.employeeSearchResults.clear();
|
||||||
|
} catch (_) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Generic option list
|
/// Generic option list
|
||||||
@ -343,23 +356,26 @@ class _AddExpenseBottomSheetState extends State<_AddExpenseBottomSheet>
|
|||||||
const SectionTitle(
|
const SectionTitle(
|
||||||
icon: Icons.person_outline, title: "Paid By", requiredField: true),
|
icon: Icons.person_outline, title: "Paid By", requiredField: true),
|
||||||
MySpacing.height(6),
|
MySpacing.height(6),
|
||||||
|
// Main tile: tap to choose mode + selection sheet
|
||||||
GestureDetector(
|
GestureDetector(
|
||||||
onTap: _showEmployeeList,
|
onTap: _showEmployeeList,
|
||||||
child: TileContainer(
|
child: TileContainer(
|
||||||
child: Row(
|
child: Row(
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
children: [
|
children: [
|
||||||
Text(
|
Expanded(
|
||||||
controller.selectedPaidBy.value == null
|
child: Text(
|
||||||
? "Select Paid By"
|
controller.selectedPaidBy.value?.name ?? "Select Paid By",
|
||||||
: '${controller.selectedPaidBy.value?.firstName ?? ''} ${controller.selectedPaidBy.value?.lastName ?? ''}',
|
style: TextStyle(fontSize: 15),
|
||||||
style: const TextStyle(fontSize: 14),
|
overflow: TextOverflow.ellipsis,
|
||||||
),
|
),
|
||||||
const Icon(Icons.arrow_drop_down, size: 22),
|
),
|
||||||
|
Icon(Icons.arrow_drop_down, size: 22),
|
||||||
],
|
],
|
||||||
|
)),
|
||||||
),
|
),
|
||||||
),
|
// small helper: long-press to quickly open multi-select directly (optional)
|
||||||
),
|
const SizedBox(height: 6),
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user