diff --git a/lib/controllers/api_routes/urls.dart b/lib/controllers/api_routes/urls.dart index 1072bbe9..780b7963 100644 --- a/lib/controllers/api_routes/urls.dart +++ b/lib/controllers/api_routes/urls.dart @@ -35,6 +35,7 @@ class URLs { static get nurseDashboardCountUrl=> '$_baseUrl/ServiceRequest/GetDashboardNurseCount'; static get nurseDashboardDetailsUrl=> '$_baseUrl/ServiceRequest/GetDashboardNurseDetails'; static get nurseRejectUrl=> '$_baseUrl/ServiceRequest/NurseReject'; + static get engineerStopTimer=> '$_baseUrl/ServiceRequest/EngineerStopTimer'; static get nurseConfirmUrl=> '$_baseUrl/ServiceRequest/NurseConfirm'; static get engineerDashboardCountUrl=> '$_baseUrl/ServiceRequest/GetDashboardEngineerCount'; static get engineerDashboardDetailsUrl=> '$_baseUrl/ServiceRequest/GetDashboardEngineerDetails'; diff --git a/lib/dashboard_latest/dashboard_provider.dart b/lib/dashboard_latest/dashboard_provider.dart index 617a0dc4..2f4f6d62 100644 --- a/lib/dashboard_latest/dashboard_provider.dart +++ b/lib/dashboard_latest/dashboard_provider.dart @@ -41,7 +41,8 @@ class DashBoardProvider extends ChangeNotifier { List tabs = []; - void setTabs(UsersTypes userType, context) { + void setTabs({required UsersTypes userType, required BuildContext context}) { + print('user type i got in method is ${userType}'); tabs = CategoryTabs.getTabs(userType: userType, context: context); } @@ -78,10 +79,10 @@ class DashBoardProvider extends ChangeNotifier { isAllCountLoading = true; notifyListeners(); String url = ''; - if (usersType == UsersTypes.nurse) { - url = URLs.nurseDashboardCountUrl; - } else { + if (usersType == UsersTypes.engineer) { url = URLs.engineerDashboardCountUrl; + } else { + url = URLs.nurseDashboardCountUrl; } Response response; try { @@ -159,16 +160,18 @@ class DashBoardProvider extends ChangeNotifier { notifyListeners(); } + print('i am called...${usersType}'); + Response response; String url = ''; - if (usersType == UsersTypes.nurse) { - url = URLs.nurseDashboardDetailsUrl; - } else { + if (usersType == UsersTypes.engineer) { url = URLs.engineerDashboardDetailsUrl; + } else { + url = URLs.nurseDashboardDetailsUrl; } try { Map body = {"pageNumber": pageNum, "pageSize": pageItemNumber}; - if (status != null) body["status"] = status; + if (status != null) body["statusValue"] = status; if (isHighPriority) body["isHighPriority"] = true; if (isOverdue) body["isOverdue"] = true; response = await ApiManager.instance.post(url, body: body); @@ -227,7 +230,7 @@ class CategoryTabs { tabs.add(CategoryTabs('Open Request', 1)); tabs.add(CategoryTabs('In Progress', 2)); tabs.add(CategoryTabs('Acknowledged', 3)); - tabs.add(CategoryTabs('Rejected', 4)); + tabs.add(CategoryTabs('Rejected', 6)); return tabs; } } diff --git a/lib/dashboard_latest/dashboard_view.dart b/lib/dashboard_latest/dashboard_view.dart index 3e4ff381..583e10c9 100644 --- a/lib/dashboard_latest/dashboard_view.dart +++ b/lib/dashboard_latest/dashboard_view.dart @@ -49,6 +49,7 @@ class _DashboardViewState extends State { } void getRequests() { + _dashBoardProvider.setTabs(userType:userProvider.user!.type!,context: context); _dashBoardProvider.getDashBoardCount(usersType: userProvider.user!.type!); _dashBoardProvider.resetRequestDataList(); _dashBoardProvider.getRequestDetail(usersType: userProvider.user!.type!, status: _dashBoardProvider.tabs[_dashBoardProvider.currentListIndex].tag); @@ -58,10 +59,8 @@ class _DashboardViewState extends State { scheduleMicrotask(() async { userProvider = Provider.of(context, listen: false); settingProvider = Provider.of(context, listen: false); - RequestDetailProvider requestDetailProvider = Provider.of(context, listen: false); - //allRequestsProvider = Provider.of(context, listen: false); _dashBoardProvider = Provider.of(context, listen: false); - _dashBoardProvider.setTabs(userProvider.user!.type!, context); + notificationsProvider = Provider.of(context, listen: false); user = userProvider.user!; getRequests(); diff --git a/lib/dashboard_latest/widgets/request_category_fragment.dart b/lib/dashboard_latest/widgets/request_category_fragment.dart index 84e73f81..9e265a7e 100644 --- a/lib/dashboard_latest/widgets/request_category_fragment.dart +++ b/lib/dashboard_latest/widgets/request_category_fragment.dart @@ -42,7 +42,7 @@ class RequestCategoryFragment extends StatelessWidget { } Widget getTabs({required BuildContext context, required DashBoardProvider requestsProvider, required UsersTypes userType}) { - List tabs = CategoryTabs.getTabs(userType: UsersTypes.engineer, context: context); + List tabs = CategoryTabs.getTabs(userType: userType, context: context); return SizedBox( height: 44 + 16, child: ListView.separated( diff --git a/lib/models/helper_data_models/maintenance_request/activity_maintenance_model.dart b/lib/models/helper_data_models/maintenance_request/activity_maintenance_model.dart index 08933790..7945dc38 100644 --- a/lib/models/helper_data_models/maintenance_request/activity_maintenance_model.dart +++ b/lib/models/helper_data_models/maintenance_request/activity_maintenance_model.dart @@ -76,7 +76,7 @@ class ActivityMaintenanceHelperModel { if(lastSituation!=null){ data['lastSituationId'] = lastSituation?.id; } - if (assignedEmployee != null&&assignedEmployee?.userId!=null) { + if (assistantEmployees != null&&assistantEmployees!.isNotEmpty) { data['assistantEmployees'] = [modelAssistantEmployees?.toJson()]; } else{ diff --git a/lib/new_views/common_widgets/default_app_bar.dart b/lib/new_views/common_widgets/default_app_bar.dart index 219c5768..eeb11f95 100644 --- a/lib/new_views/common_widgets/default_app_bar.dart +++ b/lib/new_views/common_widgets/default_app_bar.dart @@ -9,8 +9,9 @@ import '../app_style/app_color.dart'; class DefaultAppBar extends StatelessWidget implements PreferredSizeWidget { final String? title; final List? actions; + final VoidCallback ?onBackPress; - const DefaultAppBar({this.title, this.actions, Key? key}) : super(key: key); + const DefaultAppBar({this.title,this.onBackPress, this.actions, Key? key}) : super(key: key); @override Widget build(BuildContext context) { @@ -20,7 +21,7 @@ class DefaultAppBar extends StatelessWidget implements PreferredSizeWidget { title: Row( children: [ const Icon(Icons.arrow_back_ios).onPress(() { - Navigator.of(context).pop(); + onBackPress?? Navigator.of(context).pop(); }), 10.width, Text( diff --git a/lib/service_request_latest/request_detail_provider.dart b/lib/service_request_latest/request_detail_provider.dart index abdacbd4..b7d65286 100644 --- a/lib/service_request_latest/request_detail_provider.dart +++ b/lib/service_request_latest/request_detail_provider.dart @@ -38,8 +38,13 @@ class RequestDetailProvider extends ChangeNotifier { } void stopTimer() { + Timer.periodic(const Duration(seconds: 1), (Timer t) { + timerStartTime = timerStartTime.add(const Duration(seconds: 1)); + notifyListeners(); // Notify UI when time is updated + }); timer?.cancel(); isTimerRunning = false; + engineerStopTimer(); notifyListeners(); // Notify UI when timer stops } @@ -209,6 +214,28 @@ class RequestDetailProvider extends ChangeNotifier { notifyListeners(); return -1; } + } //engineerAcceptWorkOrder...... + Future engineerStopTimer() async { + Response response; + try { + final body = {"workOrderId": currentWorkOrder?.data?.requestId}; + isLoading = true; + notifyListeners(); + response = await ApiManager.instance.post(URLs.engineerStopTimer, body: body); + print('response of stop timer is ${response.body}'); + stateCode = response.statusCode; + if (response.statusCode >= 200 && response.statusCode < 300) { + + } + isLoading = false; + notifyListeners(); + return response.statusCode; + } catch (e) { + log("engineer accept [error] : $e"); + isLoading = false; + notifyListeners(); + return -1; + } } //engineerRejectWorkOrder...... @@ -413,6 +440,8 @@ class RequestDetailProvider extends ChangeNotifier { } } + + //Nurse confirm reopen Future nurseReject() async { try { @@ -421,14 +450,16 @@ class RequestDetailProvider extends ChangeNotifier { final response = await ApiManager.instance.post(URLs.nurseRejectUrl, body: nurseActionHelperModel!.toJson()); stateCode = response.statusCode; CommonResponseModel commonResponseModel = CommonResponseModel(); + if (response.statusCode >= 200 && response.statusCode < 300) { + commonResponseModel = CommonResponseModel.fromJson(json.decode(response.body)); } isLoading = false; notifyListeners(); return commonResponseModel; } catch (e) { - log("engineer accept [error] : $e"); + log("nurse reject [error] : $e"); isLoading = false; notifyListeners(); return CommonResponseModel(); diff --git a/lib/service_request_latest/views/components/action_button/footer_action_button.dart b/lib/service_request_latest/views/components/action_button/footer_action_button.dart index 41017883..693f1f9d 100644 --- a/lib/service_request_latest/views/components/action_button/footer_action_button.dart +++ b/lib/service_request_latest/views/components/action_button/footer_action_button.dart @@ -42,8 +42,10 @@ class FooterActionButton { return const SizedBox(); // TODO: Handle this case. case WorkOrderNextStepEnum.markedAsFixed: + break; // TODO: Handle this case. case WorkOrderNextStepEnum.nTakeAction: + print('i am here take action ..'); // const SizedBox().flushBar(context: context, title: context.translation.youMarkedThisIssueAsFixedWaitingForTheRequesterToConfirm, message: ''); return footerContainer( child: AppFilledButton( @@ -177,8 +179,12 @@ class FooterActionButton { fontSize: 12.toScreenWidth, )); } - } else if (userProvider.user?.type == UsersTypes.nurse) { + } + else { + print('value is ${workOrderNextStepStatus}'); if (workOrderNextStepStatus == WorkOrderNextStepEnum.nTakeAction) { + print('i am here take action ..'); + return footerContainer( child: AppFilledButton( label: context.translation.takeAction, diff --git a/lib/service_request_latest/views/components/bottom_sheets/service_request_bottomsheet.dart b/lib/service_request_latest/views/components/bottom_sheets/service_request_bottomsheet.dart index 63bf5079..5989533d 100644 --- a/lib/service_request_latest/views/components/bottom_sheets/service_request_bottomsheet.dart +++ b/lib/service_request_latest/views/components/bottom_sheets/service_request_bottomsheet.dart @@ -4,6 +4,7 @@ import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:provider/provider.dart'; import 'package:test_sa/app_strings/app_asset.dart'; +import 'package:test_sa/dashboard_latest/widgets/request_category_list.dart'; import 'package:test_sa/extensions/context_extension.dart'; import 'package:test_sa/extensions/int_extensions.dart'; import 'package:test_sa/extensions/string_extensions.dart'; @@ -611,6 +612,62 @@ class ServiceRequestBottomSheet { ); })); } + static Future nurseRejectBackBottomSheet({required BuildContext context}) { + String feedback = ''; + return buildBottomSheetParent( + context: context, + childWidget: Consumer(builder: (context, RequestDetailProvider requestDetailProvider, child) { + return Column( + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + const SizedBox().indicatorWidget(), + 8.height, + Align( + alignment: AlignmentDirectional.centerStart, + child: context.translation.rejectionReason.bottomSheetHeadingTextStyle(context), + ), + 21.height, + AppTextFormField( + labelText: context.translation.comments, + textInputType: TextInputType.multiline, + labelStyle: AppTextStyles.textFieldLabelStyle, + showWithoutDecoration: true, + backgroundColor: context.isDark ? AppColor.neutral20 : AppColor.neutral100, + alignLabelWithHint: true, + onChange: (text) { + feedback = text; + }, + onSaved: (text) { + feedback = text; + }, + ), + 16.height, + AppFilledButton( + label: context.translation.reject, + maxWidth: true, + buttonColor: Colors.white54, + textColor: AppColor.red30, + showBorder: true, + onPressed: () { + if (feedback.isNotEmpty) { + requestDetailProvider.nurseActionHelperModel = NurseActionHelperModel( + workOrderId: requestDetailProvider.currentWorkOrder!.data!.requestId, + feedback: feedback, + ); + requestDetailProvider.nurseReject(); + Navigator.pop(context); + if(requestDetailProvider.currentWorkOrder!.data!.requestId!=null){ + requestDetailProvider.getWorkOrderById(id: requestDetailProvider.currentWorkOrder!.data!.requestId!); + } + } + // Navigator.pop(context); + // requestDetailProvider.engineerMarkAsFixed(workOrderId: requestDetailProvider.currentWorkOrder!.data!.requestId!, feedback: feedback); + }, + ), + ], + ); + })); + } static Future nurseTakeActionBottomSheet({required BuildContext context}) { bool acknowledge = false; @@ -618,7 +675,7 @@ class ServiceRequestBottomSheet { String? nurseSignature; return buildBottomSheetParent( context: context, - childWidget: Consumer(builder: (context, requestDetailProvider, child) { + childWidget: Consumer(builder: (context, RequestDetailProvider requestDetailProvider, child) { return Column( crossAxisAlignment: CrossAxisAlignment.center, children: [ @@ -629,37 +686,63 @@ class ServiceRequestBottomSheet { child: context.translation.pleaseConfirmTheIssueHasBeenResolved.bottomSheetHeadingTextStyle(context), ), 10.height, - Row( - children: [ - InkWell( - child: acknowledge - ? const Icon( - Icons.check_box, - color: AppColor.primary10, - ) - : const Icon( - Icons.check_box_outline_blank, - color: AppColor.neutral120, + StatefulBuilder( + builder: (context, setState) { + return Column( + children: [ + Row( + children: [ + InkWell( + child: acknowledge + ? const Icon( + Icons.check_box, + color: AppColor.primary10, + ) + : const Icon( + Icons.check_box_outline_blank, + color: AppColor.neutral120, + ), + onTap: () { + setState(() { + acknowledge = !acknowledge; + }); + }, ), - onTap: () { - acknowledge = !acknowledge; - }, - ), - 6.width, - Flexible(child: context.translation.nurseAcknowledge.bodyText(context).custom(color: context.isDark ? AppColor.primary50 : AppColor.neutral120)), - ], - ), - 17.height, - ESignature( - title: '', - oldSignature: '', - newSignature: newSignature, - backgroundColor: AppColor.neutral100, - showShadow: false, - onSaved: (signature) { - if (signature == null || signature.isEmpty) return; - newSignature = signature; - nurseSignature = "${DateTime.now().toIso8601String()}.png|${base64Encode(signature)}"; + 6.width, + Flexible( + child: context.translation.nurseAcknowledge + .bodyText(context) + .custom(color: context.isDark ? AppColor.primary50 : AppColor.neutral120), + ), + ], + ), + 17.height, + ESignature( + title: '', + oldSignature: '', + newSignature: newSignature, + backgroundColor: AppColor.neutral100, + showShadow: false, + onChange:(signature){ + setState(() { + if (signature == null || signature.isEmpty) return; + newSignature = signature; + nurseSignature = "${DateTime.now().toIso8601String()}.png|${base64Encode(signature)}"; + print('signature i got is ${newSignature}'); + }); + }, + onSaved: (signature) { + + setState(() { + if (signature == null || signature.isEmpty) return; + newSignature = signature; + nurseSignature = "${DateTime.now().toIso8601String()}.png|${base64Encode(signature)}"; + print('signature i got is ${newSignature}'); + }); + }, + ), + ], + ); }, ), 36.height, @@ -674,14 +757,8 @@ class ServiceRequestBottomSheet { textColor: AppColor.red30, showBorder: true, onPressed: () async { - if (newSignature != null && acknowledge) { - requestDetailProvider.nurseActionHelperModel = NurseActionHelperModel( - workOrderId: requestDetailProvider.currentWorkOrder!.data!.requestId, - signatureNurse: nurseSignature, - ); - requestDetailProvider.nurseReject(); - Navigator.pop(context); - } + Navigator.pop(context); + nurseRejectBackBottomSheet(context: context); }, ).expanded, const SizedBox( @@ -692,14 +769,18 @@ class ServiceRequestBottomSheet { maxWidth: true, buttonColor: AppColor.green70, onPressed: () async { - if (newSignature != null && acknowledge) { - //TODO replace provider with new provider and also check workorder id is not correct. + if (newSignature != null) { requestDetailProvider.nurseActionHelperModel = NurseActionHelperModel( workOrderId: requestDetailProvider.currentWorkOrder!.data!.requestId!, signatureNurse: nurseSignature, ); requestDetailProvider.nurseConfirm(); + if(requestDetailProvider.currentWorkOrder!.data!.requestId!=null){ + requestDetailProvider.getWorkOrderById(id: requestDetailProvider.currentWorkOrder!.data!.requestId!); + } Navigator.pop(context); + }else{ + //show some toast... } }, ).expanded, diff --git a/lib/service_request_latest/views/components/request_detail_view.dart b/lib/service_request_latest/views/components/request_detail_view.dart index abc350fb..3f9af524 100644 --- a/lib/service_request_latest/views/components/request_detail_view.dart +++ b/lib/service_request_latest/views/components/request_detail_view.dart @@ -16,6 +16,7 @@ import 'package:test_sa/new_views/common_widgets/app_filled_button.dart'; import 'package:test_sa/service_request_latest/request_detail_provider.dart'; import 'package:test_sa/service_request_latest/views/components/action_button/footer_action_button.dart'; import 'package:test_sa/service_request_latest/views/components/initial_visit_card.dart'; +import 'package:test_sa/service_request_latest/views/components/timer_widget.dart'; import 'package:test_sa/service_request_latest/views/forms/asset_retired/asset_retired.dart'; import 'package:test_sa/views/widgets/images/files_list.dart'; import 'package:test_sa/views/widgets/loaders/no_data_found.dart'; @@ -29,6 +30,7 @@ class WorkOrderDetailView extends StatelessWidget { Widget build(BuildContext context) { UserProvider _userProvider = Provider.of(context, listen: false); return Consumer(builder: (pContext, requestProvider, _) { + return requestProvider.isLoading ? const CircularProgressIndicator(color: AppColor.primary10).center : requestProvider.currentWorkOrder == null @@ -56,15 +58,16 @@ class WorkOrderDetailView extends StatelessWidget { context: context), ], ), - // const TimerWidget(), + if (requestProvider.timer!=null&&requestProvider.timer!.isActive)...[ + const TimerWidget(), + ] ], ); }); } Widget workOrderDetailCard(BuildContext context, WorkOrderData workOrder, UserProvider userProvider) { - print('callids i got is ${workOrder.requestId}'); - print('work order next step value is ${workOrder.nextStep?.toJson()}'); + return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ @@ -391,7 +394,7 @@ class WorkOrderDetailView extends StatelessWidget { // ), // ), // FooterActionButton.requestDetailsFooterWidget(status: 7, context: context), -// TimerWidget(), + // ], // ), // ); diff --git a/lib/service_request_latest/views/components/timer_widget.dart b/lib/service_request_latest/views/components/timer_widget.dart index c258e5f5..82955002 100644 --- a/lib/service_request_latest/views/components/timer_widget.dart +++ b/lib/service_request_latest/views/components/timer_widget.dart @@ -22,8 +22,6 @@ class _TimerWidgetState extends State { Offset position = Offset(SizeConfig.screenWidth! - 100, SizeConfig.screenHeight! / 2 - 50); @override void initState() { - // TODO: implement initState - Provider.of(context,listen: false).startTimer(); super.initState(); } @override @@ -64,8 +62,6 @@ class _TimerWidgetState extends State { onTap: () { if (provider.isTimerRunning) { provider.stopTimer(); - } else { - provider.startTimer(); } }, child: Container( diff --git a/lib/service_request_latest/views/components/verify_arrival_view.dart b/lib/service_request_latest/views/components/verify_arrival_view.dart index 831788a4..a4132de0 100644 --- a/lib/service_request_latest/views/components/verify_arrival_view.dart +++ b/lib/service_request_latest/views/components/verify_arrival_view.dart @@ -146,18 +146,13 @@ class _VerifyArrivalViewState extends State { // showDialog(context: context, barrierDismissible: false, builder: (context) => const AppLazyLoading()); status = await requestDetailProvider.engineerConfirmArrival( - workOrderId: requestDetailProvider.currentWorkOrder!.data!.requestId!, - verificationTypeId: 1, - photoInfo: '', - otp: '', - assetNo: requestDetailProvider.currentWorkOrder!.data!.asset!.assetNumber!); - print('status i got is $status'); + workOrderId: requestDetailProvider.currentWorkOrder!.data!.requestId!, verificationTypeId: 1, photoInfo: '', otp: '', assetNo: result); if (status == 200) { requestDetailProvider.getWorkOrderById(id: requestDetailProvider.currentWorkOrder!.data!.requestId!); //Navigator.pop(context); + requestDetailProvider.startTimer(); Navigator.pushReplacement(context, MaterialPageRoute(builder: (context) => RequestDetailMain(requestId: requestDetailProvider.currentWorkOrder!.data!.requestId!))); - } - else { + } else { // Navigator.pop(context); //show some message. } @@ -172,41 +167,35 @@ class _VerifyArrivalViewState extends State { break; case 2: //TODO add loader. - // showDialog(context: context, barrierDismissible: false, builder: (context) => const AppLazyLoading()); + // showDialog(context: context, barrierDismissible: false, builder: (context) => const AppLazyLoading()); requestDetailProvider.sendOtp(workOrderId: requestDetailProvider.currentWorkOrder!.data!.requestId!); - //Navigator.pop(context); + //Navigator.pop(context); Navigator.pushReplacement( context, MaterialPageRoute(builder: (context) => const VerifyOtpView()), ); break; case 3: - File ?pickedFile = await onFilePicker(); - if(pickedFile!=null){ + File? pickedFile = await onFilePicker(); + if (pickedFile != null) { var fileObj = ("${pickedFile.path.split("/").last}|${base64Encode(File(pickedFile.path).readAsBytesSync())}"); int? status; - try{ + try { //TODO add loader // showDialog(context: context, barrierDismissible: false, builder: (context) => const AppLazyLoading()); - status = await requestDetailProvider.engineerConfirmArrival( - workOrderId: requestDetailProvider.currentWorkOrder!.data!.requestId!, - verificationTypeId: 1, - photoInfo: fileObj, - otp: '', - assetNo: requestDetailProvider.currentWorkOrder!.data!.asset?.assetNumber); + status = await requestDetailProvider.engineerConfirmArrival(workOrderId: requestDetailProvider.currentWorkOrder!.data!.requestId!, verificationTypeId: 4, photoInfo: fileObj, otp: ''); if (status == 200) { requestDetailProvider.getWorkOrderById(id: requestDetailProvider.currentWorkOrder!.data!.requestId!); // Navigator.pop(context); + requestDetailProvider.startTimer(); Navigator.pushReplacement(context, MaterialPageRoute(builder: (context) => RequestDetailMain(requestId: requestDetailProvider.currentWorkOrder!.data!.requestId!))); - } - else{ + } else { //show some message. // Navigator.pop(context); - } - }catch(e){ + } catch (e) { print('error i got is $e'); // Navigator.pop(context); } @@ -225,8 +214,8 @@ class _VerifyArrivalViewState extends State { } // ScanQr } - Future onFilePicker() async { + Future onFilePicker() async { // ImageSource? source = await showModalBottomSheet( // context: context, // builder: (BuildContext context) { @@ -276,12 +265,12 @@ class _VerifyArrivalViewState extends State { // }, // ); // if (source == null) return null; - File ?fileImage; + File? fileImage; final pickedFile = await ImagePicker().pickImage(source: ImageSource.camera, imageQuality: 70, maxWidth: 800, maxHeight: 800); if (pickedFile != null) { fileImage = File(pickedFile.path); - } -return fileImage; + } + return fileImage; } } diff --git a/lib/service_request_latest/views/components/verify_otp_view.dart b/lib/service_request_latest/views/components/verify_otp_view.dart index 994d6c7f..9c178ed8 100644 --- a/lib/service_request_latest/views/components/verify_otp_view.dart +++ b/lib/service_request_latest/views/components/verify_otp_view.dart @@ -62,6 +62,7 @@ class VerifyOtpView extends StatelessWidget { await requestDetailProvider.engineerConfirmArrival( workOrderId: requestDetailProvider.currentWorkOrder!.data!.requestId!, verificationTypeId: 3, photoInfo: '', otp: pin, assetNo: ''); // Navigator.pop(context); + requestDetailProvider.startTimer(); Navigator.pushReplacement(context, MaterialPageRoute(builder: (context) => RequestDetailMain(requestId: requestDetailProvider.currentWorkOrder!.data!.requestId!))); } }, diff --git a/lib/service_request_latest/views/forms/asset_retired/verify_asset_detail.dart b/lib/service_request_latest/views/forms/asset_retired/verify_asset_detail.dart index 7f0d2740..b1cbcad0 100644 --- a/lib/service_request_latest/views/forms/asset_retired/verify_asset_detail.dart +++ b/lib/service_request_latest/views/forms/asset_retired/verify_asset_detail.dart @@ -14,6 +14,7 @@ import 'package:test_sa/models/helper_data_models/workorder/work_order_helper_mo import 'package:test_sa/models/new_models/work_order_detail_model.dart'; import 'package:test_sa/new_views/app_style/app_color.dart'; import 'package:test_sa/new_views/common_widgets/app_filled_button.dart'; +import 'package:test_sa/new_views/common_widgets/app_lazy_loading.dart'; import 'package:test_sa/new_views/common_widgets/single_item_drop_down_menu.dart'; import 'package:test_sa/providers/loading_list_notifier.dart'; import 'package:test_sa/providers/service_request_providers/equipment_status_provider.dart'; @@ -82,7 +83,7 @@ class _VerifyAssetDetailsState extends State with TickerProv equipmentStatus: currentWorkOrderData.equipmentStatus, loanAvailability: currentWorkOrderData.loanAvailablity, failureReason: currentWorkOrderData.failureReasone, - // faultDescription: currentWorkOrderData.problemDescription, + // faultDescription: currentWorkOrderData.fa, solution: currentWorkOrderData.solution?.name, returnToService: currentWorkOrderData.returnToService, serviceType: currentWorkOrderData.serviceType, @@ -212,8 +213,11 @@ class _VerifyAssetDetailsState extends State with TickerProv label: context.translation.verify_asset_details, buttonColor: AppColor.primary10, onPressed: () async { + //TODO add loader.. + showDialog(context: context, barrierDismissible: false, builder: (context) => const AppLazyLoading()); await requestDetailProvider.engineerUpdateWorkOrder(); Navigator.pop(context); + Navigator.pop(context); }, ), ), diff --git a/lib/service_request_latest/views/forms/maintenance_request/components/assistant_employee_card.dart b/lib/service_request_latest/views/forms/maintenance_request/components/assistant_employee_card.dart index aa921bda..1f02f732 100644 --- a/lib/service_request_latest/views/forms/maintenance_request/components/assistant_employee_card.dart +++ b/lib/service_request_latest/views/forms/maintenance_request/components/assistant_employee_card.dart @@ -22,12 +22,12 @@ class AssistantEmployeeCard extends StatefulWidget { } class _AssistantEmployeeCardState extends State { - bool status = false; final TextEditingController _workingHoursController = TextEditingController(text: ''); bool isCurrentUserIsAssistantEmp = false; bool isExpanded = false; + @override void initState() { // TODO: implement initState @@ -57,147 +57,156 @@ class _AssistantEmployeeCardState extends State { @override Widget build(BuildContext context) { return Consumer(builder: (context, requestDetailProvider, child) { - return Column( + return Column( children: [ - SizedBox( - height: 56.toScreenHeight, - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - context.translation.assistantEmployee.bodyText(context).custom(color: AppColor.black20), - IconButton(onPressed: (){ - setState(() { - isExpanded=!isExpanded; - }); - }, icon: Icon(isExpanded?Icons.arrow_drop_up_outlined:Icons.arrow_drop_down)), - ],), - ), - isExpanded? Column( - crossAxisAlignment: CrossAxisAlignment.stretch, - children: [ - ServiceReportAssistantEmployeeMenu( - title: context.translation.select, - backgroundColor: AppColor.neutral100, - assetId: requestDetailProvider.currentWorkOrder!.data!.asset!.id!, - initialValue: (requestDetailProvider.activityMaintenanceHelperModel?.assistantEmployees?.isNotEmpty ?? false) - ? requestDetailProvider.activityMaintenanceHelperModel?.assistantEmployees?.first - : null, - //TODO add check... - // enable: !isCurrentUserIsAssistantEmp, - onSelect: (employee) { - print('on select called...${employee?.toJson()}'); - if (employee == null) { - requestDetailProvider.activityMaintenanceHelperModel?.assistantEmployees = []; - } else { - requestDetailProvider.activityMaintenanceHelperModel?.assistantEmployees = [employee.copyWith(id: 0)]; - requestDetailProvider.activityMaintenanceHelperModel?.modelAssistantEmployees?.user= AssignedEmployee(userId: employee.user?.id,userName:employee.user?.name ); - - } - }, - ), - 8.height, - Row( - mainAxisSize: MainAxisSize.min, + GestureDetector( + onTap: () { + setState(() { + isExpanded = !isExpanded; + }); + }, + child: Container( + color: AppColor.white10, + height: 56.toScreenHeight, + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - ADatePicker( - label: context.translation.startTime, - hideShadow: true, - backgroundColor: AppColor.neutral100, - date: requestDetailProvider.activityMaintenanceHelperModel?.modelAssistantEmployees?.startDate, - formatDateWithTime: true, - onDatePicker: (selectedDate) { - showTimePicker( - context: context, - initialTime: TimeOfDay.now(), - ).then((selectedTime) { - // Handle the selected date and time here. - if (selectedTime != null) { - DateTime selectedDateTime = DateTime( - selectedDate.year, - selectedDate.month, - selectedDate.day, - selectedTime.hour, - selectedTime.minute, - ); - requestDetailProvider.activityMaintenanceHelperModel?.modelAssistantEmployees?.startDate = selectedDateTime; - requestDetailProvider.updateActivityMaintenanceHelperModel(requestDetailProvider.activityMaintenanceHelperModel); - assignWorkingHours(requestDetailProvider: requestDetailProvider); - } - }); - }, - ).expanded, - 8.width, - ADatePicker( - label: context.translation.endTime, - hideShadow: true, - backgroundColor: AppColor.neutral100, - date: requestDetailProvider.activityMaintenanceHelperModel?.modelAssistantEmployees?.endDate, - formatDateWithTime: true, - onDatePicker: (selectedDate) { - showTimePicker( - context: context, - initialTime: TimeOfDay.now(), - ).then((selectedTime) { - // Handle the selected date and time here. - if (selectedTime != null) { - DateTime selectedDateTime = DateTime( - selectedDate.year, - selectedDate.month, - selectedDate.day, - selectedTime.hour, - selectedTime.minute, - ); - if (requestDetailProvider.activityMaintenanceHelperModel?.modelAssistantEmployees?.startDate != null && - selectedDateTime.isBefore(requestDetailProvider.activityMaintenanceHelperModel!.modelAssistantEmployees!.startDate!)) { - "End Date time must be greater then start date".showToast; - return; - } - requestDetailProvider.activityMaintenanceHelperModel?.modelAssistantEmployees?.endDate = selectedDateTime; - requestDetailProvider.updateActivityMaintenanceHelperModel(requestDetailProvider.activityMaintenanceHelperModel); - assignWorkingHours(requestDetailProvider: requestDetailProvider); - } - }); - }, - ).expanded, + context.translation.assistantEmployee.bodyText(context).custom(color: AppColor.black20), + Padding( + padding: const EdgeInsets.all(8.0), + child: Icon(isExpanded ? Icons.arrow_drop_up_outlined : Icons.arrow_drop_down), + ), ], ), - 8.height, - AppTextFormField( - labelText: context.translation.workingHours, - backgroundColor: AppColor.neutral80, - controller: _workingHoursController, - suffixIcon: "clock".toSvgAsset(width: 20, color: context.isDark ? AppColor.neutral10 : null).paddingOnly(end: 16), - initialValue: requestDetailProvider.activityMaintenanceHelperModel?.modelAssistantEmployees?.workingHours != null - ? requestDetailProvider.activityMaintenanceHelperModel!.modelAssistantEmployees!.workingHours.toString() - : '', - textAlign: TextAlign.center, - labelStyle: AppTextStyles.textFieldLabelStyle, - enable: false, - showShadow: false, - style: Theme.of(context).textTheme.titleMedium, - ), - 8.height, - AppTextFormField( - initialValue: requestDetailProvider.activityMaintenanceHelperModel?.modelAssistantEmployees?.technicalComment, - labelText: context.translation.technicalComment, - backgroundColor: AppColor.neutral100, - showShadow: false, - labelStyle: AppTextStyles.textFieldLabelStyle, - alignLabelWithHint: true, - textInputType: TextInputType.multiline, - onChange: (value) { - requestDetailProvider.activityMaintenanceHelperModel?.modelAssistantEmployees?.technicalComment = value; - }, - onSaved: (value) { - requestDetailProvider.activityMaintenanceHelperModel?.modelAssistantEmployees?.technicalComment = value; - }, - ), - 8.height, - ], - ):const SizedBox(), + ), + ), + isExpanded + ? Column( + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + ServiceReportAssistantEmployeeMenu( + title: context.translation.select, + showAsBottomSheet: true, + backgroundColor: AppColor.neutral100, + assetId: requestDetailProvider.currentWorkOrder!.data!.asset!.id!, + initialValue: (requestDetailProvider.activityMaintenanceHelperModel?.assistantEmployees?.isNotEmpty ?? false) + ? requestDetailProvider.activityMaintenanceHelperModel?.assistantEmployees?.first + : null, + //TODO add check... + // enable: !isCurrentUserIsAssistantEmp, + onSelect: (employee) { + print('on select called...${employee?.toJson()}'); + if (employee == null) { + requestDetailProvider.activityMaintenanceHelperModel?.assistantEmployees = []; + } else { + requestDetailProvider.activityMaintenanceHelperModel?.assistantEmployees = [employee.copyWith(id: 0)]; + requestDetailProvider.activityMaintenanceHelperModel?.modelAssistantEmployees?.user = AssignedEmployee(userId: employee.user?.id, userName: employee.user?.name); + } + }, + ), + 8.height, + Row( + mainAxisSize: MainAxisSize.min, + children: [ + ADatePicker( + label: context.translation.startTime, + hideShadow: true, + backgroundColor: AppColor.neutral100, + date: requestDetailProvider.activityMaintenanceHelperModel?.modelAssistantEmployees?.startDate, + formatDateWithTime: true, + onDatePicker: (selectedDate) { + showTimePicker( + context: context, + initialTime: TimeOfDay.now(), + ).then((selectedTime) { + // Handle the selected date and time here. + if (selectedTime != null) { + DateTime selectedDateTime = DateTime( + selectedDate.year, + selectedDate.month, + selectedDate.day, + selectedTime.hour, + selectedTime.minute, + ); + requestDetailProvider.activityMaintenanceHelperModel?.modelAssistantEmployees?.startDate = selectedDateTime; + requestDetailProvider.updateActivityMaintenanceHelperModel(requestDetailProvider.activityMaintenanceHelperModel); + assignWorkingHours(requestDetailProvider: requestDetailProvider); + } + }); + }, + ).expanded, + 8.width, + ADatePicker( + label: context.translation.endTime, + hideShadow: true, + backgroundColor: AppColor.neutral100, + date: requestDetailProvider.activityMaintenanceHelperModel?.modelAssistantEmployees?.endDate, + formatDateWithTime: true, + onDatePicker: (selectedDate) { + showTimePicker( + context: context, + initialTime: TimeOfDay.now(), + ).then((selectedTime) { + // Handle the selected date and time here. + if (selectedTime != null) { + DateTime selectedDateTime = DateTime( + selectedDate.year, + selectedDate.month, + selectedDate.day, + selectedTime.hour, + selectedTime.minute, + ); + if (requestDetailProvider.activityMaintenanceHelperModel?.modelAssistantEmployees?.startDate != null && + selectedDateTime.isBefore(requestDetailProvider.activityMaintenanceHelperModel!.modelAssistantEmployees!.startDate!)) { + "End Date time must be greater then start date".showToast; + return; + } + requestDetailProvider.activityMaintenanceHelperModel?.modelAssistantEmployees?.endDate = selectedDateTime; + requestDetailProvider.updateActivityMaintenanceHelperModel(requestDetailProvider.activityMaintenanceHelperModel); + assignWorkingHours(requestDetailProvider: requestDetailProvider); + } + }); + }, + ).expanded, + ], + ), + 8.height, + AppTextFormField( + labelText: context.translation.workingHours, + backgroundColor: AppColor.neutral80, + controller: _workingHoursController, + suffixIcon: "clock".toSvgAsset(width: 20, color: context.isDark ? AppColor.neutral10 : null).paddingOnly(end: 16), + initialValue: requestDetailProvider.activityMaintenanceHelperModel?.modelAssistantEmployees?.workingHours != null + ? requestDetailProvider.activityMaintenanceHelperModel!.modelAssistantEmployees!.workingHours.toString() + : '', + textAlign: TextAlign.center, + labelStyle: AppTextStyles.textFieldLabelStyle, + enable: false, + showShadow: false, + style: Theme.of(context).textTheme.titleMedium, + ), + 8.height, + AppTextFormField( + initialValue: requestDetailProvider.activityMaintenanceHelperModel?.modelAssistantEmployees?.technicalComment, + labelText: context.translation.technicalComment, + backgroundColor: AppColor.neutral100, + showShadow: false, + labelStyle: AppTextStyles.textFieldLabelStyle, + alignLabelWithHint: true, + textInputType: TextInputType.multiline, + onChange: (value) { + requestDetailProvider.activityMaintenanceHelperModel?.modelAssistantEmployees?.technicalComment = value; + }, + onSaved: (value) { + requestDetailProvider.activityMaintenanceHelperModel?.modelAssistantEmployees?.technicalComment = value; + }, + ), + 8.height, + ], + ) + : const SizedBox(), ], ); - }); } @@ -205,7 +214,7 @@ class _AssistantEmployeeCardState extends State { double calculateWorkingHours(DateTime? startTime, DateTime? endTime) { if (startTime != null && endTime != null) { Duration difference = endTime.difference(startTime); - int hours = difference.inHours ; + int hours = difference.inHours; int minutes = difference.inMinutes % 60; return hours.toDouble(); } else { diff --git a/lib/service_request_latest/views/forms/maintenance_request/components/internal_request.dart b/lib/service_request_latest/views/forms/maintenance_request/components/internal_request.dart index 0a5fc50d..2d87ab79 100644 --- a/lib/service_request_latest/views/forms/maintenance_request/components/internal_request.dart +++ b/lib/service_request_latest/views/forms/maintenance_request/components/internal_request.dart @@ -48,11 +48,13 @@ class _InternalMaintenanceRequestState extends State final GlobalKey _formKey = GlobalKey(); final TextEditingController _workingHoursController = TextEditingController(); final TextEditingController _travellingHoursController = TextEditingController(); + Lookup statusLookup = Lookup.fromJson({"id": 5619, "name": "New", "value": 1}); @override void initState() { _activityStatusProvider = Provider.of(context, listen: false); _requestDetailProvider = Provider.of(context, listen: false); + _requestDetailProvider?.activityMaintenanceHelperModel?.activityStatus = _requestDetailProvider?.activityMaintenanceHelperModel?.activityStatus ?? statusLookup; super.initState(); WidgetsBinding.instance.addPostFrameCallback((_) { _travellingHoursController.text = @@ -83,7 +85,6 @@ class _InternalMaintenanceRequestState extends State @override Widget build(BuildContext context) { return Consumer(builder: (context, requestDetailProvider, child) { - print('data in consumer is ${requestDetailProvider.activityMaintenanceHelperModel?.activityStatus?.toJson()}'); return SingleChildScrollView( child: Column( children: [ @@ -92,29 +93,30 @@ class _InternalMaintenanceRequestState extends State child: Column( crossAxisAlignment: CrossAxisAlignment.stretch, children: [ - SingleItemDropDownMenu( + SingleItemDropDownMenu( context: context, height: 56.toScreenHeight, - title: context.translation.lastSituationStatus, + title: context.translation.activityStatus, showShadow: false, backgroundColor: AppColor.neutral100, - showAsBottomSheet: true, - initialValue: requestDetailProvider.activityMaintenanceHelperModel?.lastSituation, + initialValue: requestDetailProvider.activityMaintenanceHelperModel?.activityStatus, onSelect: (status) { - requestDetailProvider.activityMaintenanceHelperModel?.lastSituation = status; - setState(() {}); + print('status i got is ${status?.toJson()}'); + requestDetailProvider.activityMaintenanceHelperModel?.activityStatus = status; }, ), 8.height, - SingleItemDropDownMenu( + SingleItemDropDownMenu( context: context, height: 56.toScreenHeight, - title: context.translation.activityStatus, + title: context.translation.lastSituationStatus, showShadow: false, backgroundColor: AppColor.neutral100, - initialValue: requestDetailProvider.activityMaintenanceHelperModel?.activityStatus, + showAsBottomSheet: true, + initialValue: requestDetailProvider.activityMaintenanceHelperModel?.lastSituation, onSelect: (status) { - requestDetailProvider.activityMaintenanceHelperModel?.activityStatus = status; + requestDetailProvider.activityMaintenanceHelperModel?.lastSituation = status; + setState(() {}); }, ), 8.height, diff --git a/lib/service_request_latest/views/request_detail_main_view.dart b/lib/service_request_latest/views/request_detail_main_view.dart index 087a68a2..5904d482 100644 --- a/lib/service_request_latest/views/request_detail_main_view.dart +++ b/lib/service_request_latest/views/request_detail_main_view.dart @@ -41,45 +41,75 @@ class _RequestDetailMainState extends State { @override Widget build(BuildContext context) { - return Scaffold( - backgroundColor: AppColor.neutral100, - appBar: DefaultAppBar(title: context.translation.serviceDetails), - body: DefaultTabController( - length: 2, - child: Column( - mainAxisSize: MainAxisSize.min, - children: [ - Container( - margin: EdgeInsets.only(left: 16.toScreenWidth, right: 16.toScreenWidth, top: 12.toScreenHeight), - decoration: BoxDecoration(color: context.isDark ? AppColor.neutral50 : AppColor.white10, borderRadius: BorderRadius.circular(10)), - child: TabBar( - //controller: _tabController, - padding: EdgeInsets.symmetric(vertical: 4.toScreenHeight, horizontal: 4.toScreenWidth), - labelColor: context.isDark ? AppColor.neutral30 : AppColor.black20, - unselectedLabelColor: context.isDark ? AppColor.neutral30 : AppColor.black20, - unselectedLabelStyle: AppTextStyles.bodyText, - labelStyle: AppTextStyles.bodyText, - indicatorPadding: EdgeInsets.zero, - indicatorSize: TabBarIndicatorSize.tab, - dividerColor: Colors.transparent, - indicator: BoxDecoration(color: context.isDark ? AppColor.neutral60 : AppColor.neutral110, borderRadius: BorderRadius.circular(7)), - onTap: (index) { - // setState(() {}); - }, - tabs: [ - Tab(text: context.translation.requestDetail, height: 57.toScreenHeight), - Tab(text: context.translation.historyLogs, height: 57.toScreenHeight), - ], + return WillPopScope( + onWillPop: () async { + // Implement custom back button handling logic here + RequestDetailProvider requestDetailProvider = Provider.of(context,listen: false); + if(requestDetailProvider.timer!=null&&requestDetailProvider.timer!.isActive){ + requestDetailProvider.stopTimer(); + } + return true; // Return true if you want to allow popping the screen, false otherwise + }, + child: Scaffold( + backgroundColor: AppColor.neutral100, + appBar:AppBar( + automaticallyImplyLeading: false, + titleSpacing: 16, + title: Row( + children: [ + const Icon(Icons.arrow_back_ios).onPress(() { + RequestDetailProvider requestDetailProvider = Provider.of(context,listen: false); + if(requestDetailProvider.timer!=null&&requestDetailProvider.timer!.isActive){ + requestDetailProvider.stopTimer(); + } + Navigator.pop(context); + + }), + 10.width, + Text( + context.translation.serviceDetails , + style: AppTextStyles.heading3.copyWith(fontWeight: FontWeight.w500, color: context.isDark ? AppColor.neutral30 : AppColor.neutral50), + ).expanded, + ], + ), + ), + body: DefaultTabController( + length: 2, + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + Container( + margin: EdgeInsets.only(left: 16.toScreenWidth, right: 16.toScreenWidth, top: 12.toScreenHeight), + decoration: BoxDecoration(color: context.isDark ? AppColor.neutral50 : AppColor.white10, borderRadius: BorderRadius.circular(10)), + child: TabBar( + //controller: _tabController, + padding: EdgeInsets.symmetric(vertical: 4.toScreenHeight, horizontal: 4.toScreenWidth), + labelColor: context.isDark ? AppColor.neutral30 : AppColor.black20, + unselectedLabelColor: context.isDark ? AppColor.neutral30 : AppColor.black20, + unselectedLabelStyle: AppTextStyles.bodyText, + labelStyle: AppTextStyles.bodyText, + indicatorPadding: EdgeInsets.zero, + indicatorSize: TabBarIndicatorSize.tab, + dividerColor: Colors.transparent, + indicator: BoxDecoration(color: context.isDark ? AppColor.neutral60 : AppColor.neutral110, borderRadius: BorderRadius.circular(7)), + onTap: (index) { + // setState(() {}); + }, + tabs: [ + Tab(text: context.translation.requestDetail, height: 57.toScreenHeight), + Tab(text: context.translation.historyLogs, height: 57.toScreenHeight), + ], + ), ), - ), - 12.height, - TabBarView( - children: [ - WorkOrderDetailView(), - const HistoryLogView(), - ], - ).expanded, - ], + 12.height, + TabBarView( + children: [ + WorkOrderDetailView(), + const HistoryLogView(), + ], + ).expanded, + ], + ), ), ), ); diff --git a/lib/views/widgets/status/assistant_employee_menu.dart b/lib/views/widgets/status/assistant_employee_menu.dart index e81307bd..5eedf668 100644 --- a/lib/views/widgets/status/assistant_employee_menu.dart +++ b/lib/views/widgets/status/assistant_employee_menu.dart @@ -1,131 +1,164 @@ import 'package:flutter/material.dart'; +import 'package:provider/provider.dart'; +import 'package:test_sa/controllers/providers/api/status_drop_down/report/service_report_assistants_employee_provider.dart'; import 'package:test_sa/extensions/context_extension.dart'; -import'package:test_sa/extensions/int_extensions.dart'; +import 'package:test_sa/extensions/int_extensions.dart'; import 'package:test_sa/extensions/text_extensions.dart'; +import 'package:test_sa/extensions/widget_extensions.dart'; +import 'package:test_sa/views/widgets/bottom_sheets/selection_bottom_sheet.dart'; import '../../../models/new_models/assistant_employee.dart'; import '../../../new_views/app_style/app_color.dart'; class AssistantEmployeeMenu extends StatefulWidget { final List statuses; - Color? backgroundColor; + Color? backgroundColor; final AssistantEmployees? initialStatus; // Now nullable final Function(AssistantEmployees?) onSelect; // Now accepts nullable values final String? title; // Now nullable final bool enable; + bool? showAsBottomSheet = false; - AssistantEmployeeMenu({Key? key, required this.statuses, this.title, required this.onSelect, this.initialStatus,this.backgroundColor, this.enable = true}) : super(key: key); + AssistantEmployeeMenu({Key? key, required this.statuses, this.title, required this.onSelect, this.initialStatus, this.showAsBottomSheet = false, this.backgroundColor, this.enable = true}) + : super(key: key); @override _SingleAssistantEmployeeMenuState createState() => _SingleAssistantEmployeeMenuState(); } -class _SingleAssistantEmployeeMenuState extends State {AssistantEmployees? _selectedStatus; // Now nullable +class _SingleAssistantEmployeeMenuState extends State { + AssistantEmployees? _selectedStatus; // Now nullable -@override -void setState(VoidCallback fn) { - if (mounted) super.setState(fn); -} + @override + void setState(VoidCallback fn) { + if (mounted) super.setState(fn); + } -@override -void didUpdateWidget(covariant AssistantEmployeeMenu oldWidget) { - if (widget.initialStatus != null) { - final result = widget.statuses.where((element) => element.user?.id == widget.initialStatus?.user?.id); - if (result.isNotEmpty) { - _selectedStatus = result.first; + @override + void didUpdateWidget(covariant AssistantEmployeeMenu oldWidget) { + if (widget.initialStatus != null) { + final result = widget.statuses.where((element) => element.user?.id == widget.initialStatus?.user?.id); + if (result.isNotEmpty) { + _selectedStatus = result.first; + } else { + _selectedStatus = null; + } + if (widget.initialStatus?.user?.id != _selectedStatus?.user?.id) { + widget.onSelect(_selectedStatus); + } } else { _selectedStatus = null; } - if (widget.initialStatus?.user?.id != _selectedStatus?.user?.id) { - widget.onSelect(_selectedStatus); - } - } else { - _selectedStatus = null; + super.didUpdateWidget(oldWidget); } - super.didUpdateWidget(oldWidget); -} -@override -void initState() { - if (widget.initialStatus != null) { - final result = widget.statuses.where((element) => element.user?.id == widget.initialStatus?.user?.id); - if (result.isNotEmpty) { - _selectedStatus = result.first; - } - if (widget.initialStatus?.user?.id != _selectedStatus?.user?.id) { - widget.onSelect(_selectedStatus); + @override + void initState() { + if (widget.initialStatus != null) { + final result = widget.statuses.where((element) => element.user?.id == widget.initialStatus?.user?.id); + if (result.isNotEmpty) { + _selectedStatus = result.first; + } + if (widget.initialStatus?.user?.id != _selectedStatus?.user?.id) { + widget.onSelect(_selectedStatus); + } } + super.initState(); } - super.initState(); -} -@override -Widget build(BuildContext context) { - return Container( - height: 60.toScreenHeight, - padding: EdgeInsets.symmetric(horizontal: 16.toScreenWidth), - decoration: BoxDecoration( - color:widget.backgroundColor ?? (context.isDark ? AppColor.neutral50 : AppColor.neutral120), - borderRadius: BorderRadius.circular(10), - boxShadow: [BoxShadow(color: Colors.black.withOpacity(0.05), blurRadius: 10)], - ), - child: Stack( - alignment: Alignment.center, - children: [ - PositionedDirectional( - end: 0, - child: Icon( - Icons.keyboard_arrow_down_rounded, - color: widget.enable ? null : Colors.grey, - ), - ), - Column( - crossAxisAlignment: CrossAxisAlignment.start, - mainAxisAlignment: MainAxisAlignment.center, - children: [ - if (widget.title != null) - Text( - widget.title!, // Non-null assertion after null check - style: Theme.of(context).textTheme.bodySmall?.copyWith(color: context.isDark ? null : AppColor.neutral20, fontWeight: FontWeight.w500), - ), - DropdownButton( - value: _selectedStatus, - dropdownColor: AppColor.white10, - iconSize: 24, - isDense: true, - icon: const SizedBox.shrink(), - elevation: 0, - isExpanded: true, - hint: Text( - context.translation.select, - style: Theme.of(context).textTheme.bodyLarge, - ), - style: AppTextStyles.bodyText2.copyWith(color: AppColor.black20), - underline: const SizedBox.shrink(), - onChanged: widget.enable - ? (AssistantEmployees? newValue) { // Now accepts nullable values - setState(() { - _selectedStatus = newValue; - }); - widget.onSelect(newValue); - } - :null, - items: widget.statuses.map>( - (AssistantEmployees value) { - return DropdownMenuItem( - value: value, - child: Text( - value.user?.name ?? "NULL", // Use null-aware operator for user.name - style: AppTextStyles.bodyText.copyWith(color: AppColor.black20), - ), - ); - }, - ).toList(), + @override + Widget build(BuildContext context) { + return Container( + height: 60.toScreenHeight, + padding: EdgeInsets.symmetric(horizontal: 16.toScreenWidth), + decoration: BoxDecoration( + color: widget.backgroundColor ?? (context.isDark ? AppColor.neutral50 : AppColor.neutral120), + borderRadius: BorderRadius.circular(10), + boxShadow: [BoxShadow(color: Colors.black.withOpacity(0.05), blurRadius: 10)], + ), + child: Stack( + alignment: Alignment.center, + children: [ + PositionedDirectional( + end: 0, + child: Icon( + Icons.keyboard_arrow_down_rounded, + color: widget.enable ? null : Colors.grey, ), - ], - ), - ], - ), - ); + ), + Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.center, + children: [ + if (widget.title != null) + Text( + widget.title!, // Non-null assertion after null check + style: Theme.of(context).textTheme.bodySmall?.copyWith(color: context.isDark ? null : AppColor.neutral20, fontWeight: FontWeight.w500), + ), + DropdownButton( + value: _selectedStatus, + dropdownColor: AppColor.white10, + iconSize: 24, + isDense: true, + icon: const SizedBox.shrink(), + elevation: 0, + isExpanded: true, + hint: Text( + context.translation.select, + style: Theme.of(context).textTheme.bodyLarge, + ), + style: AppTextStyles.bodyText2.copyWith(color: AppColor.black20), + underline: const SizedBox.shrink(), + onChanged: widget.enable + ? (AssistantEmployees? newValue) { + // Now accepts nullable values + setState(() { + _selectedStatus = newValue; + }); + widget.onSelect(newValue); + } + : null, + items: widget.statuses.map>( + (AssistantEmployees value) { + return DropdownMenuItem( + value: value, + child: Text( + value.user?.name ?? "NULL", // Use null-aware operator for user.name + style: AppTextStyles.bodyText.copyWith(color: AppColor.black20), + ), + ); + }, + ).toList(), + ).onPress(widget.showAsBottomSheet! + ? () async { + final selectedT = await showModalBottomSheet( + // Specify return type + context: context, + isScrollControlled: true, + shape: const RoundedRectangleBorder( + borderRadius: BorderRadius.vertical( + top: Radius.circular(20), + ), + ), + clipBehavior: Clip.antiAliasWithSaveLayer, + builder: (BuildContext context) => SelectionBottomSheet( + // Specify generic type + items: + (Provider.of(context, listen: false).assistantEmployees as List) ?? [], // Provide default empty list if null + selectedItem: _selectedStatus, + // title: widget.title, + builderString: (emp) => emp?.name ?? "", // Null-aware operator for emp.name + ), + ); + if (selectedT != null) { + widget.onSelect!(selectedT); // Non-null assertion after null check + } + } + : null), + ], + ), + ], + ), + ); + } } -} \ No newline at end of file diff --git a/lib/views/widgets/status/report/service_report_assistant_employee_menu.dart b/lib/views/widgets/status/report/service_report_assistant_employee_menu.dart index 06d18c77..4914cec1 100644 --- a/lib/views/widgets/status/report/service_report_assistant_employee_menu.dart +++ b/lib/views/widgets/status/report/service_report_assistant_employee_menu.dart @@ -13,8 +13,9 @@ class ServiceReportAssistantEmployeeMenu extends StatelessWidget { final String title; final num assetId; final bool enable; + bool showAsBottomSheet; - ServiceReportAssistantEmployeeMenu({Key? key, required this.onSelect, required this.title, required this.initialValue, required this.assetId, this.backgroundColor, this.enable = true}) + ServiceReportAssistantEmployeeMenu({Key? key, required this.onSelect, required this.title, required this.initialValue,this.showAsBottomSheet=false, required this.assetId, this.backgroundColor, this.enable = true}) : super(key: key); @override @@ -32,6 +33,7 @@ class ServiceReportAssistantEmployeeMenu extends StatelessWidget { title: title, statuses: menuProvider.assistantEmployees ?? [], backgroundColor: backgroundColor, + showAsBottomSheet: showAsBottomSheet, // Provide an empty list if null onSelect: onSelect, // Pass onSelect directly