From 68a8dc250fe2ccff78662ce2dbb31278e6209b31 Mon Sep 17 00:00:00 2001 From: "muhammad.abbasi" Date: Tue, 17 Sep 2024 09:41:22 +0300 Subject: [PATCH] bug fixes --- assets/images/camera_icon.svg | 5 + assets/images/file_icon.svg | 4 + assets/images/gallery_icon.svg | 5 + assets/images/info_icon.svg | 3 + assets/images/warning_icon.svg | 5 + lib/controllers/api_routes/urls.dart | 1 + lib/dashboard_latest/dashboard_provider.dart | 2 +- lib/dashboard_latest/dashboard_view.dart | 12 +- .../widgets/progress_fragment.dart | 16 +- .../widgets/requests_fragment.dart | 15 +- lib/extensions/widget_extensions.dart | 4 +- lib/l10n/app_ar.arb | 4 + lib/l10n/app_en.arb | 4 + .../asset_retired/asset_retired_model.dart | 64 +++ lib/new_views/app_style/app_color.dart | 1 + .../common_widgets/app_bottom_nav_bar.dart | 4 +- .../common_widgets/app_filled_button.dart | 29 +- .../single_item_drop_down_menu.dart | 2 +- .../request_detail_provider.dart | 35 +- .../service_request_bottomsheet.dart | 305 ++++++------- .../views/components/request_detail_view.dart | 13 +- .../views/nurse/create_new_request_view.dart | 407 ++++++++++++------ .../views/request_detail_main_view.dart | 9 +- .../widgets/e_signature/e_signature.dart | 2 +- lib/views/widgets/equipment/asset_picker.dart | 11 +- .../widgets/images/multi_image_picker.dart | 104 ++++- .../widgets/sound/TextSpeechRecordWidget.dart | 1 + lib/views/widgets/sound/sound_player.dart | 3 +- 28 files changed, 705 insertions(+), 365 deletions(-) create mode 100644 assets/images/camera_icon.svg create mode 100644 assets/images/file_icon.svg create mode 100644 assets/images/gallery_icon.svg create mode 100644 assets/images/info_icon.svg create mode 100644 assets/images/warning_icon.svg create mode 100644 lib/models/helper_data_models/asset_retired/asset_retired_model.dart diff --git a/assets/images/camera_icon.svg b/assets/images/camera_icon.svg new file mode 100644 index 00000000..9bf393e7 --- /dev/null +++ b/assets/images/camera_icon.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/assets/images/file_icon.svg b/assets/images/file_icon.svg new file mode 100644 index 00000000..46d2c021 --- /dev/null +++ b/assets/images/file_icon.svg @@ -0,0 +1,4 @@ + + + + diff --git a/assets/images/gallery_icon.svg b/assets/images/gallery_icon.svg new file mode 100644 index 00000000..f12734c5 --- /dev/null +++ b/assets/images/gallery_icon.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/assets/images/info_icon.svg b/assets/images/info_icon.svg new file mode 100644 index 00000000..04e94b40 --- /dev/null +++ b/assets/images/info_icon.svg @@ -0,0 +1,3 @@ + + + diff --git a/assets/images/warning_icon.svg b/assets/images/warning_icon.svg new file mode 100644 index 00000000..28252dd2 --- /dev/null +++ b/assets/images/warning_icon.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/lib/controllers/api_routes/urls.dart b/lib/controllers/api_routes/urls.dart index 2722f365..69afab47 100644 --- a/lib/controllers/api_routes/urls.dart +++ b/lib/controllers/api_routes/urls.dart @@ -39,6 +39,7 @@ class URLs { static get getWorkOrderByIdUrl=> '$_baseUrl/ServiceRequest/GetWorkOrderById'; static get deleteActivitySparePartUrl=> '$_baseUrl/ServiceRequest/DeleteActivitySparePart'; static get createActivitySparePartUrl=> '$_baseUrl/ServiceRequest/CreateActivitySparePart'; + static get createActivityAssetToBeRetiredUrl=> '$_baseUrl/ServiceRequest/CreateActivityAssetToBeRetired'; static get updateActivitySparePartUrl=> '$_baseUrl/ServiceRequest/UpdateActivitySparePart'; static get assignEngineerToWorkOrderUrl=> '$_baseUrl/ServiceRequest/AssignEngineerToWorkOrder'; static get getDepartments => "$_baseUrl/Customer/GetDepartmentLookup"; // get diff --git a/lib/dashboard_latest/dashboard_provider.dart b/lib/dashboard_latest/dashboard_provider.dart index 28082d88..1df800e9 100644 --- a/lib/dashboard_latest/dashboard_provider.dart +++ b/lib/dashboard_latest/dashboard_provider.dart @@ -70,7 +70,6 @@ class DashBoardProvider extends ChangeNotifier { if (response.statusCode >= 200 && response.statusCode < 300) { dashboardCount = DashboardCount.fromJson(json.decode(response.body)); } - notifyListeners(); isAllCountLoading = false; notifyListeners(); return response.statusCode; @@ -98,6 +97,7 @@ class DashBoardProvider extends ChangeNotifier { "pageNumber": pageNum, "pageSize": pageItemNumber, }; + response = await ApiManager.instance.post(url, body: body); stateCode = response.statusCode; if (response.statusCode >= 200 && response.statusCode < 300) { diff --git a/lib/dashboard_latest/dashboard_view.dart b/lib/dashboard_latest/dashboard_view.dart index f6fea02a..c799bdd6 100644 --- a/lib/dashboard_latest/dashboard_view.dart +++ b/lib/dashboard_latest/dashboard_view.dart @@ -10,6 +10,7 @@ import 'package:test_sa/controllers/providers/api/all_requests_provider.dart'; import 'package:test_sa/controllers/providers/api/notifications_provider.dart'; import 'package:test_sa/controllers/providers/api/user_provider.dart'; import 'package:test_sa/controllers/providers/settings/setting_provider.dart'; +import 'package:test_sa/dashboard_latest/dashboard_provider.dart'; import 'package:test_sa/dashboard_latest/widgets/app_bar_widget.dart'; import 'package:test_sa/dashboard_latest/widgets/progress_fragment.dart'; import 'package:test_sa/dashboard_latest/widgets/requests_fragment.dart'; @@ -38,6 +39,7 @@ class _DashboardViewState extends State { late SettingProvider settingProvider; late UserProvider userProvider; late AllRequestsProvider allRequestsProvider; + late DashBoardProvider dashBoardProvider; late NotificationsProvider notificationsProvider; late ScrollController _scrollController; @@ -54,13 +56,11 @@ class _DashboardViewState extends State { 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); notificationsProvider = Provider.of(context, listen: false); user = userProvider.user!; - log('user token i got is ${user.token}'); - + await dashBoardProvider.getDashBoardCount(usersType: user.type!); await getAllRequests(); - await requestDetailProvider.engineerRejectWorkOrder(id: '3', feedBack: 'Abcdef'); - if (isFCM) { FirebaseNotificationManger.initialized(context); NotificationManger.initialisation((notificationDetails) { @@ -77,10 +77,12 @@ class _DashboardViewState extends State { allRequestsProvider.isFilterRequestLoading = true; allRequestsProvider.currentListIndex = 0; allRequestsProvider.filterRequest = null; + var tabs = RequestUtils.getTabs(userType: userProvider.user!.type!, context: context); allRequestsProvider.status = tabs[0]['status']; allRequestsProvider.getRequests(); allRequestsProvider.pageNum = 1; + dashBoardProvider.getRequestDetail(usersType: userProvider.user!.type!, status: tabs[0]['status']); allRequestsProvider.getFilterRequests(showLoader: true, status: tabs[0]['status']).whenComplete(() { allRequestsProvider.requestDetailList = allRequestsProvider.filterRequest; }); @@ -91,7 +93,7 @@ class _DashboardViewState extends State { void handleScroll() async { _scrollController = ScrollController(); _scrollController.addListener(() async { - if (_scrollController?.position?.pixels == _scrollController?.position?.maxScrollExtent && !allRequestsProvider.isFilterRequestLoading) { + if (_scrollController.position.pixels == _scrollController.position.maxScrollExtent && !allRequestsProvider.isFilterRequestLoading) { allRequestsProvider.pageNum = allRequestsProvider.pageNum + 1; await allRequestsProvider.getFilterRequests(showLoader: false, status: allRequestsProvider.status); } diff --git a/lib/dashboard_latest/widgets/progress_fragment.dart b/lib/dashboard_latest/widgets/progress_fragment.dart index d7ef7f18..e955687a 100644 --- a/lib/dashboard_latest/widgets/progress_fragment.dart +++ b/lib/dashboard_latest/widgets/progress_fragment.dart @@ -154,6 +154,7 @@ import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; import 'package:syncfusion_flutter_charts/charts.dart'; import 'package:test_sa/controllers/providers/api/all_requests_provider.dart'; +import 'package:test_sa/dashboard_latest/dashboard_provider.dart'; import 'package:test_sa/extensions/context_extension.dart'; import 'package:test_sa/extensions/text_extensions.dart'; import 'package:test_sa/extensions/widget_extensions.dart'; @@ -171,18 +172,19 @@ class ProgressFragment extends StatelessWidget { Widget build(BuildContext context) { _userProvider = Provider.of(context); bool isCurrentUserNotEngineer = (_userProvider.user!.type != UsersTypes.engineer); - return Consumer( + + return Consumer( builder: (context, snapshot, _) { - int total = (snapshot.completedRequests?.total?.count ?? 0) + (snapshot.inProgressRequests?.total?.count ?? 0) + (isCurrentUserNotEngineer ? (snapshot.openRequests?.total?.count ?? 0) : 0); + int total = ((snapshot.dashboardCount?.data?.countComplete ?? 0) + (snapshot.dashboardCount?.data?.countInprogress ?? 0) + (isCurrentUserNotEngineer ? (snapshot.dashboardCount?.data?.countOpen ?? 0) : 0)); final List chartData = [ - ChartData('Completed', snapshot.completedRequests?.total?.count?.toDouble() ?? 0.0, AppColor.green50), + ChartData('Completed', snapshot.dashboardCount?.data?.countComplete?.toDouble() ?? 0.0, AppColor.green50), // snapshot.openRequests?.total?.count!=0? ChartData('Open', snapshot.openRequests?.total?.count?.toDouble() ?? 0.0, AppColor.blueStatus(context)), - ChartData('In Progress', snapshot.inProgressRequests?.total?.count?.toDouble() ?? 0.0, AppColor.orange70), + ChartData('In Progress', snapshot.dashboardCount?.data?.countInprogress?.toDouble() ?? 0.0, AppColor.orange70), ]; if (isCurrentUserNotEngineer) { - chartData.insert(1, ChartData('Open', snapshot.openRequests?.total?.count?.toDouble() ?? 0.0, AppColor.blueStatus(context))); + chartData.insert(1, ChartData('Open', snapshot.dashboardCount?.data?.countOpen?.toDouble() ?? 0.0, AppColor.blueStatus(context))); } return Column( @@ -199,7 +201,7 @@ class ProgressFragment extends StatelessWidget { color: context.isDark ? const Color(0xFF111427) : const Color(0xffF7F9FB), textStyle: context.isDark ? null : const TextStyle(color: Colors.black87, fontSize: 12), ), - legend: Legend( + legend: const Legend( //isVisible: true, ), series: [ @@ -218,7 +220,7 @@ class ProgressFragment extends StatelessWidget { //useSeriesColor: true, ), ) - ]).toShimmer(isShow: snapshot.isInProgressLoading || snapshot.isCompleteLoading || snapshot.isOpenLoading, radius: 250).paddingAll(12).toShadowContainer(context), + ]).toShimmer(isShow: snapshot.isAllCountLoading, radius: 250).paddingAll(12).toShadowContainer(context), Column( mainAxisSize: MainAxisSize.min, children: [ diff --git a/lib/dashboard_latest/widgets/requests_fragment.dart b/lib/dashboard_latest/widgets/requests_fragment.dart index e24fafeb..24be5f97 100644 --- a/lib/dashboard_latest/widgets/requests_fragment.dart +++ b/lib/dashboard_latest/widgets/requests_fragment.dart @@ -3,6 +3,7 @@ import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; import 'package:test_sa/controllers/api_routes/api_manager.dart'; import 'package:test_sa/controllers/providers/api/all_requests_provider.dart'; +import 'package:test_sa/dashboard_latest/dashboard_provider.dart'; import 'package:test_sa/extensions/context_extension.dart'; import 'package:test_sa/extensions/int_extensions.dart'; import 'package:test_sa/extensions/text_extensions.dart'; @@ -17,7 +18,7 @@ class RequestsFragment extends StatelessWidget { @override Widget build(BuildContext context) { - return Consumer( + return Consumer( builder: (context, snapshot, _) => GridView( // padding: const EdgeInsets.only( bottom: 16), physics: const NeverScrollableScrollPhysics(), @@ -25,18 +26,18 @@ class RequestsFragment extends StatelessWidget { gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 4, childAspectRatio: 75 / 84, crossAxisSpacing: 2, mainAxisSpacing: 13), children: [ listItem( - snapshot.highPriorityRequests?.total?.count ?? 0, + snapshot.dashboardCount?.data?.countHighPriority ?? 0, "high_priority", context.translation.highPriority, context, - snapshot.isHighPriorityLoading, + snapshot.isAllCountLoading, 0, context.isDark ? AppColor.redStatus(context) : AppColor.red50, ), - listItem(snapshot.overdueRequests?.total?.count ?? 0, "overdue", context.translation.overdue, context, snapshot.isOverdueLoading, 1, AppColor.yellowIcon(context)), - listItem(snapshot.openRequests?.total?.count ?? 0, "new_request", ApiManager.instance.user!.type == UsersTypes.engineer ? context.translation.inProgress : context.translation.newR, context, - snapshot.isOpenLoading, 2, AppColor.primary40), - listItem(snapshot.completedRequests?.total?.count ?? 0, "complete_request", context.translation.completed, context, snapshot.isCompleteLoading, 3, AppColor.greenStatus(context)), + listItem( snapshot.dashboardCount?.data?.countOverdue ?? 0, "overdue", context.translation.overdue, context, snapshot.isAllCountLoading, 1, AppColor.yellowIcon(context)), + listItem( snapshot.dashboardCount?.data?.countOpen ?? 0, "new_request", ApiManager.instance.user!.type == UsersTypes.engineer ? context.translation.inProgress : context.translation.newR, context, + snapshot.isAllCountLoading, 2, AppColor.primary40), + listItem( snapshot.dashboardCount?.data?.countComplete ?? 0, "complete_request", context.translation.completed, context, snapshot.isAllCountLoading, 3, AppColor.greenStatus(context)), ], ), ); diff --git a/lib/extensions/widget_extensions.dart b/lib/extensions/widget_extensions.dart index 83f16cd5..7ffe0f00 100644 --- a/lib/extensions/widget_extensions.dart +++ b/lib/extensions/widget_extensions.dart @@ -77,12 +77,12 @@ extension WidgetExtensions on Widget { ).toShadowContainer(context) : this; - Widget toShadowContainer(BuildContext context, {bool showShadow = true, double padding = 16}) => showShadow + Widget toShadowContainer(BuildContext context, {bool showShadow = true,Color? backgroundColor, double padding = 16}) => showShadow ? Container( padding: EdgeInsets.all(padding), width: double.infinity, decoration: ShapeDecoration( - color: AppColor.background(context), + color: backgroundColor?? AppColor.background(context), shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(14)), shadows: [boxShadowR14], ), diff --git a/lib/l10n/app_ar.arb b/lib/l10n/app_ar.arb index da5cb730..6f535251 100644 --- a/lib/l10n/app_ar.arb +++ b/lib/l10n/app_ar.arb @@ -84,6 +84,10 @@ "workshop": "ورشة", "activityStatus": "حالة النشاط", "scanOrPickAsset": "امسح أو اختر الأصل", + "reScanOrPickAsset": "أعد المسح أو اختر الأصل", + "camera": "الكاميرا", + "gallery": "المعرض", + "files": "الملفات", "takeAction": "اتخذ إجراء", "pleaseConfirmTheIssueHasBeenResolved": "يرجى تأكيد أن المشكلة قد تم حلها", "nurseAcknowledge": "أقر بإكمال أمر العمل هذا", diff --git a/lib/l10n/app_en.arb b/lib/l10n/app_en.arb index 03163f06..ccdffced 100644 --- a/lib/l10n/app_en.arb +++ b/lib/l10n/app_en.arb @@ -71,6 +71,10 @@ "closed": "Closed", "close": "Close", "scanOrPickAsset": "Scan or Pick Asset", + "reScanOrPickAsset": "Re-Scan or Pick Asset", + "camera": "Camera", + "gallery": "Gallery", + "files": "Files", "attachFiles": "Attach Files", "activityStatus": "Activity Status", "takeAction": "Take Action", diff --git a/lib/models/helper_data_models/asset_retired/asset_retired_model.dart b/lib/models/helper_data_models/asset_retired/asset_retired_model.dart new file mode 100644 index 00000000..e3f94353 --- /dev/null +++ b/lib/models/helper_data_models/asset_retired/asset_retired_model.dart @@ -0,0 +1,64 @@ +class ActivityAssetRetiredModel { + int? id; + int? workOrderId; + int? retirmentReasonId; + String? retirementComment; + List? + activityAssetToBeRetiredAttachments; + + ActivityAssetRetiredModel( + {this.id, + this.workOrderId, + this.retirmentReasonId, + this.retirementComment, + this.activityAssetToBeRetiredAttachments}); + + ActivityAssetRetiredModel.fromJson(Map json) { + id = json['id']; + workOrderId = json['workOrderId']; + retirmentReasonId = json['retirmentReasonId']; + retirementComment = json['retirementComment']; + if (json['activityAssetToBeRetiredAttachments'] != null) { + activityAssetToBeRetiredAttachments = + []; + json['activityAssetToBeRetiredAttachments'].forEach((v) { + activityAssetToBeRetiredAttachments! + .add( ActivityAssetToBeRetiredAttachments.fromJson(v)); + }); + } + } + + Map toJson() { + final Map data = {}; + data['id'] = id; + data['workOrderId'] = workOrderId; + data['retirmentReasonId'] = retirmentReasonId; + data['retirementComment'] = retirementComment; + if (activityAssetToBeRetiredAttachments != null) { + data['activityAssetToBeRetiredAttachments'] = this + .activityAssetToBeRetiredAttachments! + .map((v) => v.toJson()) + .toList(); + } + return data; + } +} + +class ActivityAssetToBeRetiredAttachments { + int? id; + String? name; + + ActivityAssetToBeRetiredAttachments({this.id, this.name}); + + ActivityAssetToBeRetiredAttachments.fromJson(Map json) { + id = json['id']; + name = json['name']; + } + + Map toJson() { + final Map data = {}; + data['id'] = id; + data['name'] = name; + return data; + } +} diff --git a/lib/new_views/app_style/app_color.dart b/lib/new_views/app_style/app_color.dart index 54f74083..ddc78079 100644 --- a/lib/new_views/app_style/app_color.dart +++ b/lib/new_views/app_style/app_color.dart @@ -40,6 +40,7 @@ class AppColor { static const Color white40 = Color(0xffE4EBEE); static const Color white50 = Color(0xffECECEC); static const Color white60 = Color(0xffEFEFEF); + static const Color white70 = Color(0xffF1F1F1); //black static const Color black10 = Color(0xff3B3D4A); diff --git a/lib/new_views/common_widgets/app_bottom_nav_bar.dart b/lib/new_views/common_widgets/app_bottom_nav_bar.dart index 8e5f4565..4dd78f84 100644 --- a/lib/new_views/common_widgets/app_bottom_nav_bar.dart +++ b/lib/new_views/common_widgets/app_bottom_nav_bar.dart @@ -2,6 +2,7 @@ import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; import 'package:test_sa/controllers/providers/api/user_provider.dart'; import 'package:test_sa/extensions/context_extension.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/models/enums/user_types.dart'; @@ -17,12 +18,13 @@ class AppBottomNavigationBar extends StatelessWidget { Widget build(BuildContext context) { bool isEngineer = (Provider.of(context, listen: false).user!.type) == UsersTypes.engineer; return Container( - // height: 86.toScreenHeight, + height: 84.toScreenHeight, decoration: BoxDecoration( color: AppColor.background(context), boxShadow: [boxShadowR14], ), child: BottomNavigationBar( + backgroundColor: Colors.white, items: [ navBarItem(context, index: 0, iconName: "overview", label: context.translation.overview), navBarItem(context, index: 1, iconName: "request_icon", label: context.translation.request), diff --git a/lib/new_views/common_widgets/app_filled_button.dart b/lib/new_views/common_widgets/app_filled_button.dart index 193503ed..196b6c9b 100644 --- a/lib/new_views/common_widgets/app_filled_button.dart +++ b/lib/new_views/common_widgets/app_filled_button.dart @@ -8,11 +8,14 @@ class AppFilledButton extends StatelessWidget { final VoidCallback? onPressed; final String label; final bool maxWidth, loading; + final bool showIcon; + final Widget? icon; final Color? buttonColor; final Color? textColor; final bool showBorder; - const AppFilledButton({ this.onPressed, required this.label, this.maxWidth = false, this.loading = false, this.showBorder = false, this.buttonColor, this.textColor, Key? key}) + const AppFilledButton( + {this.onPressed, required this.label, this.maxWidth = false, this.showIcon = false, this.icon, this.loading = false, this.showBorder = false, this.buttonColor, this.textColor, Key? key}) : super(key: key); @override @@ -28,14 +31,22 @@ class AppFilledButton extends StatelessWidget { ), child: loading ? SizedBox( - width: 24, - height: 24, - child: CircularProgressIndicator( - color: textColor ?? AppColor.background(context), - strokeWidth: 2, - ), - ) - : label.heading6(context).custom(color: textColor ?? AppColor.background(context)), + width: 24, + height: 24, + child: CircularProgressIndicator( + color: textColor ?? AppColor.background(context), + strokeWidth: 2, + ), + ) + : showIcon && icon != null + ? Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + icon!, + 8.width, + label.heading6(context).custom(color: textColor ?? AppColor.background(context)), + ]) + : label.heading6(context).custom(color: textColor ?? AppColor.background(context)), ).onPress(onPressed); } } diff --git a/lib/new_views/common_widgets/single_item_drop_down_menu.dart b/lib/new_views/common_widgets/single_item_drop_down_menu.dart index 25f6bf53..b9fbe179 100644 --- a/lib/new_views/common_widgets/single_item_drop_down_menu.dart +++ b/lib/new_views/common_widgets/single_item_drop_down_menu.dart @@ -93,7 +93,7 @@ class _SingleItemDropDownMenuState _activityAssetRetiredModel; + + set activityAssetRetiredModel(ActivityAssetRetiredModel ?value) { + _activityAssetRetiredModel = value; + notifyListeners(); + } ActivitySparePartModel ?get activitySparePartModel => _activitySparePartModel; @@ -212,7 +221,6 @@ class RequestDetailProvider extends ChangeNotifier { stateCode = response.statusCode; if (response.statusCode >= 200 && response.statusCode < 300) { CommonResponseModel commonResponseModel = CommonResponseModel.fromJson(json.decode(response.body)); - print('response of Engineer fixremotely workorder ${commonResponseModel.toJson()}'); notifyListeners(); isLoading = false; return commonResponseModel; @@ -288,7 +296,6 @@ class RequestDetailProvider extends ChangeNotifier { stateCode = response.statusCode; if (response.statusCode >= 200 && response.statusCode < 300) { CommonResponseModel commonResponseModel = CommonResponseModel.fromJson(json.decode(response.body)); - print('response of Engineer assignEngineer workorder ${commonResponseModel.toJson()}'); notifyListeners(); isLoading = false; return commonResponseModel; @@ -312,7 +319,6 @@ class RequestDetailProvider extends ChangeNotifier { stateCode = response.statusCode; if (response.statusCode >= 200 && response.statusCode < 300) { CommonResponseModel commonResponseModel = CommonResponseModel.fromJson(json.decode(response.body)); - print('response of nurse confirmreopen workorder ${commonResponseModel.toJson()}'); notifyListeners(); isLoading = false; return commonResponseModel; @@ -352,8 +358,6 @@ class RequestDetailProvider extends ChangeNotifier { return CommonResponseModel(); } } - - Future updateActivitySparePart({required ActivitySparePartModel activitySparePartModel}) async { isLoading = true; try { @@ -421,4 +425,25 @@ class RequestDetailProvider extends ChangeNotifier { return -1; } } + Future createActivityAssetToBeRetired({required ActivityAssetRetiredModel activityAssetRetiredModel}) async { + isLoading = true; + try { + final response = await ApiManager.instance.put( + URLs.createActivityAssetToBeRetiredUrl, + body: activityAssetRetiredModel.toJson(), + ); + stateCode = response.statusCode; + if (response.statusCode >= 200 && response.statusCode < 300) { + // request.engineerName = employee.name; + notifyListeners(); + } + isLoading = false; + notifyListeners(); + return response.statusCode; + } catch (error) { + isLoading = false; + notifyListeners(); + return -1; + } + } } 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 90a9684e..dc78b181 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 @@ -78,15 +78,15 @@ class ServiceRequestBottomSheet { selectedTime.minute, ); //serviceRequestProvider.currentSelectedRequest?.date - if (selectedDateTime.isBefore(DateTime.parse(serviceRequestProvider.currentSelectedRequest!.date!))) { - "Visit Date time must be greater then request date".showToast; - return; - } + if (selectedDateTime.isBefore(DateTime.parse(serviceRequestProvider.currentSelectedRequest!.date!))) { + "Visit Date time must be greater then request date".showToast; + return; + } - setState(() { - serviceRequestProvider.currentSelectedRequest?.startDate = selectedDateTime.toIso8601String(); - }); - print('start date i got is ${serviceRequestProvider.currentSelectedRequest?.startDate}'); + setState(() { + serviceRequestProvider.currentSelectedRequest?.startDate = selectedDateTime.toIso8601String(); + }); + print('start date i got is ${serviceRequestProvider.currentSelectedRequest?.startDate}'); } }); } @@ -112,7 +112,6 @@ class ServiceRequestBottomSheet { return true; }, ), - ), 8.height, AppTextFormField( @@ -190,7 +189,7 @@ class ServiceRequestBottomSheet { 15.height, ADatePicker( label: context.translation.visitDate, - hideShadow: true, + hideShadow: true, backgroundColor: AppColor.neutral100, height: 70.toScreenHeight, date: DateTime.tryParse(serviceRequestProvider.currentSelectedRequest?.visitDate ?? ""), @@ -210,11 +209,11 @@ class ServiceRequestBottomSheet { selectedTime.hour, selectedTime.minute, ); - if (selectedDateTime.isBefore(DateTime.parse(serviceRequestProvider.currentSelectedRequest!.date!))) { - "Visit Date time must be greater then request date".showToast; - return; - } - serviceRequestProvider.currentSelectedRequest?.visitDate = selectedDateTime?.toIso8601String(); + if (selectedDateTime.isBefore(DateTime.parse(serviceRequestProvider.currentSelectedRequest!.date!))) { + "Visit Date time must be greater then request date".showToast; + return; + } + serviceRequestProvider.currentSelectedRequest?.visitDate = selectedDateTime?.toIso8601String(); } }); } @@ -307,7 +306,6 @@ class ServiceRequestBottomSheet { AppFilledButton( label: context.translation.save, buttonColor: AppColor.primary10, - loading: serviceRequestProvider.isLoading ?? false, onPressed: () async { _formKey.currentState?.save(); @@ -338,7 +336,7 @@ class ServiceRequestBottomSheet { child: SingleChildScrollView( child: Column( children: [ - const SizedBox().indicatorWidget(), + const SizedBox().indicatorWidget(), Align( alignment: AlignmentDirectional.centerStart, child: context.translation.rejectionReason.heading4(context).paddingOnly(top: 21), @@ -349,7 +347,8 @@ class ServiceRequestBottomSheet { backgroundColor: AppColor.neutral100, height: 70.toScreenHeight, title: context.translation.rejectionReason, - initialValue: serviceRequestProvider.currentSelectedRequest?.firstAction, //_serviceRequest.firstAction, + initialValue: serviceRequestProvider.currentSelectedRequest?.firstAction, + //_serviceRequest.firstAction, onSelect: (value) { serviceRequestProvider.currentSelectedRequest?.firstAction = value; if (serviceRequestProvider.currentSelectedRequest?.firstAction?.value != 2) { @@ -410,7 +409,7 @@ class ServiceRequestBottomSheet { ), // color: Colors.white, child: ListTile( - minVerticalPadding:12.toScreenWidth, + minVerticalPadding: 12.toScreenWidth, horizontalTitleGap: 2.toScreenHeight, onTap: onTap, contentPadding: const EdgeInsets.all(8), @@ -434,7 +433,6 @@ class ServiceRequestBottomSheet { break; case 1: - //push to specific screen... // Navigator.push( // context, @@ -476,7 +474,7 @@ class ServiceRequestBottomSheet { child: Column( mainAxisSize: MainAxisSize.min, children: [ - const SizedBox().indicatorWidget(), + const SizedBox().indicatorWidget(), 8.height, Align( alignment: AlignmentDirectional.centerStart, @@ -505,7 +503,7 @@ class ServiceRequestBottomSheet { })); } - static Future actionBottomSheet({required BuildContext context, required String title, String? button1Text, String ?button2Text, VoidCallback ?button1Tap, VoidCallback ?button2Tap}) { + static Future actionBottomSheet({required BuildContext context, required String title, String? button1Text, String? button2Text, VoidCallback? button1Tap, VoidCallback? button2Tap}) { return showModalBottomSheet( context: context, useSafeArea: true, @@ -523,7 +521,7 @@ class ServiceRequestBottomSheet { child: Column( mainAxisSize: MainAxisSize.min, children: [ - const SizedBox().indicatorWidget(), + const SizedBox().indicatorWidget(), 8.height, Align( alignment: AlignmentDirectional.centerStart, @@ -559,6 +557,7 @@ class ServiceRequestBottomSheet { ); })); } + static Future feedBackBottomSheet({required BuildContext context}) { final GlobalKey _formKey = GlobalKey(); return showModalBottomSheet( @@ -567,57 +566,59 @@ class ServiceRequestBottomSheet { isScrollControlled: true, backgroundColor: Colors.transparent, builder: (context) => Consumer(builder: (context, serviceRequestProvider, child) { - return Container( - clipBehavior: Clip.antiAlias, - margin: EdgeInsets.only(bottom: MediaQuery.of(context).viewInsets.bottom), - decoration: BoxDecoration( - color: AppColor.background(context), - borderRadius: const BorderRadius.only(topRight: Radius.circular(20), topLeft: Radius.circular(20)), - ), - padding: EdgeInsets.symmetric(horizontal: 16.toScreenWidth, vertical: 16.toScreenHeight), - child: Form( - key: _formKey, - child: SingleChildScrollView( - child: StatefulBuilder(builder: (context, setState) { - return Column( - crossAxisAlignment: CrossAxisAlignment.center, - children: [ - const SizedBox().indicatorWidget(), - 8.height, - Align( - alignment: AlignmentDirectional.centerStart, - child: context.translation.feedBack.bottomSheetHeadingTextStyle(context), - ), - 21.height, - AppTextFormField( - labelText: context.translation.comments, - textInputType: TextInputType.multiline, - showWithoutDecoration: true, - backgroundColor: context.isDark ? AppColor.neutral20 : AppColor.neutral100, - alignLabelWithHint: true, - onChange: (text) { - serviceRequestProvider.currentSelectedRequest?.comments = text; - }, - onSaved: (text) { - serviceRequestProvider.currentSelectedRequest?.comments = text; - }, - ), - 16.height, - AppFilledButton( - label: context.translation.fixed, - buttonColor: AppColor.green70, - loading: false, - onPressed: () {}, - ), - ], - ); - }), - ), - ), - ); - })); + return Container( + clipBehavior: Clip.antiAlias, + margin: EdgeInsets.only(bottom: MediaQuery.of(context).viewInsets.bottom), + decoration: BoxDecoration( + color: AppColor.background(context), + borderRadius: const BorderRadius.only(topRight: Radius.circular(20), topLeft: Radius.circular(20)), + ), + padding: EdgeInsets.symmetric(horizontal: 16.toScreenWidth, vertical: 16.toScreenHeight), + child: Form( + key: _formKey, + child: SingleChildScrollView( + child: StatefulBuilder(builder: (context, setState) { + return Column( + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + const SizedBox().indicatorWidget(), + 8.height, + Align( + alignment: AlignmentDirectional.centerStart, + child: context.translation.feedBack.bottomSheetHeadingTextStyle(context), + ), + 21.height, + AppTextFormField( + labelText: context.translation.comments, + textInputType: TextInputType.multiline, + showWithoutDecoration: true, + backgroundColor: context.isDark ? AppColor.neutral20 : AppColor.neutral100, + alignLabelWithHint: true, + onChange: (text) { + serviceRequestProvider.currentSelectedRequest?.comments = text; + }, + onSaved: (text) { + serviceRequestProvider.currentSelectedRequest?.comments = text; + }, + ), + 16.height, + AppFilledButton( + label: context.translation.fixed, + buttonColor: AppColor.green70, + loading: false, + onPressed: () {}, + ), + ], + ); + }), + ), + ), + ); + })); } + static Future nurseTakeActionBottomSheet({required BuildContext context}) { + bool acknowledge = false; final GlobalKey _formKey = GlobalKey(); return showModalBottomSheet( context: context, @@ -625,87 +626,91 @@ class ServiceRequestBottomSheet { isScrollControlled: true, backgroundColor: Colors.transparent, builder: (context) => Consumer(builder: (context, serviceRequestProvider, child) { - return Form( - key: _formKey, - child: SingleChildScrollView( - child: StatefulBuilder(builder: (context, setState) { - bool acknowledge = false; - Uint8List ?newSignature; - return Column( - crossAxisAlignment: CrossAxisAlignment.center, - children: [ - const SizedBox().indicatorWidget(), - 8.height, - Align( - alignment: AlignmentDirectional.centerStart, - child: context.translation.pleaseConfirmTheIssueHasBeenResolved.bottomSheetHeadingTextStyle(context), - ), - 10.height, - Row( - children: [ - Checkbox( - value: acknowledge, - activeColor: AppColor.blueStatus(context), - onChanged: (value) { - setState(() { - acknowledge = !value!; - }); - print('acknowledge value is $acknowledge'); - - }), - 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) { - // setState(() {}); - // return; - // } - if (signature == null || signature.isEmpty) return; - newSignature = signature; - // _subWorkOrders.nurseSignature = signature != null ? "${DateTime.now().toIso8601String()}.png|${base64Encode(signature)}" : null; - }, - ), - 16.height, - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - mainAxisSize: MainAxisSize.min, + return Form( + key: _formKey, + child: SingleChildScrollView( + child: StatefulBuilder(builder: (context, setState) { + Uint8List? newSignature; + return Column( + crossAxisAlignment: CrossAxisAlignment.center, children: [ - AppFilledButton( - label: context.translation.reject, - maxWidth: true, - buttonColor: Colors.white54, - textColor: AppColor.red30, - showBorder: true, - onPressed: () async { - ServiceRequestBottomSheet.rejectRequestBottomSheet(context: context); - }, - ).expanded, - const SizedBox( - width: 20, + const SizedBox().indicatorWidget(), + 8.height, + Align( + alignment: AlignmentDirectional.centerStart, + child: context.translation.pleaseConfirmTheIssueHasBeenResolved.bottomSheetHeadingTextStyle(context), ), - AppFilledButton( - label: context.translation.confirm, - maxWidth: true, - buttonColor: AppColor.green70, - onPressed: () async { + 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, + ), + onTap: () { + setState(() { + 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) { + // setState(() {}); + // return; + // } + if (signature == null || signature.isEmpty) return; + newSignature = signature; + // _subWorkOrders.nurseSignature = signature != null ? "${DateTime.now().toIso8601String()}.png|${base64Encode(signature)}" : null; }, - ).expanded, - ], - ) + ), + 36.height, + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + mainAxisSize: MainAxisSize.min, + children: [ + AppFilledButton( + label: context.translation.reject, + maxWidth: true, + buttonColor: Colors.white54, + textColor: AppColor.red30, + showBorder: true, + onPressed: () async { - ], - ); - }), - ), - ).bottomSheetContainer(context); - })); + }, + ).expanded, + const SizedBox( + width: 20, + ), + AppFilledButton( + label: context.translation.confirm, + maxWidth: true, + buttonColor: AppColor.green70, + onPressed: () async {}, + ).expanded, + ], + ) + ], + ); + }), + ), + ).bottomSheetContainer(context); + })); } } 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 dfa6b61b..0414fa81 100644 --- a/lib/service_request_latest/views/components/request_detail_view.dart +++ b/lib/service_request_latest/views/components/request_detail_view.dart @@ -25,6 +25,7 @@ import 'package:test_sa/views/widgets/loaders/app_loading.dart'; import 'package:test_sa/views/widgets/requests/request_status.dart'; import 'package:test_sa/views/widgets/sound/sound_player.dart'; + class RequestDetailView extends StatefulWidget { static const String id = "/call-details"; ServiceRequest serviceRequest; @@ -53,12 +54,7 @@ class _RequestDetailViewState extends State { }); } - final GlobalKey _detailsCardKey = GlobalKey(); - void createBreakPoint() { - // final RenderBox detailContainerBox = _detailsCardKey.currentContext?.findRenderObject() as RenderBox; - // final detailContainerHeight = detailContainerBox?.size?.height; - } @override Widget build(BuildContext context) { @@ -80,11 +76,8 @@ class _RequestDetailViewState extends State { } Widget requestDetailCard({required ServiceRequestsProvider serviceRequestsProvider, required UserProvider userProvider}) { - if (!serviceRequestsProvider.isDetialLoading) { - createBreakPoint(); - } + return SafeArea( - key: _detailsCardKey, child: serviceRequestsProvider.isDetialLoading ? const ALoading().center : serviceRequestsProvider.currentSelectedRequest == null @@ -332,8 +325,8 @@ class _RequestDetailViewState extends State { textColor: AppColor.red30, showBorder: true, onPressed: () async { - // ServiceRequestBottomSheet.nurseTakeActionBottomSheet(context: context); Navigator.push(context, MaterialPageRoute(builder: (context) => AssetRetired())); + // Navigator.push(context, MaterialPageRoute(builder: (context) => CreateNewRequest())); }), ); } diff --git a/lib/service_request_latest/views/nurse/create_new_request_view.dart b/lib/service_request_latest/views/nurse/create_new_request_view.dart index 9c5774f0..6ef846ab 100644 --- a/lib/service_request_latest/views/nurse/create_new_request_view.dart +++ b/lib/service_request_latest/views/nurse/create_new_request_view.dart @@ -1,4 +1,4 @@ - +import 'dart:convert'; import 'dart:io'; import 'package:flutter/cupertino.dart'; @@ -6,70 +6,95 @@ import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; import 'package:test_sa/controllers/providers/api/devices_provider.dart'; import 'package:test_sa/controllers/providers/api/service_requests_provider.dart'; -import 'package:test_sa/controllers/validator/validator.dart'; +import 'package:test_sa/controllers/providers/api/user_provider.dart'; +import 'package:test_sa/controllers/providers/settings/setting_provider.dart'; import 'package:test_sa/extensions/context_extension.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/models/device/asset.dart'; import 'package:test_sa/models/device/asset_search.dart'; +import 'package:test_sa/models/service_request/pending_service_request_model.dart'; +import 'package:test_sa/models/service_request/service_request.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_text_form_field.dart'; +import 'package:test_sa/providers/service_request_providers/equipment_status_provider.dart'; +import 'package:test_sa/providers/service_request_providers/priority_provider.dart'; +import 'package:test_sa/providers/service_request_providers/requested_through_provider.dart'; +import 'package:test_sa/providers/service_request_providers/type_of_request_provider.dart'; import 'package:test_sa/providers/work_order/reason_provider.dart'; import 'package:test_sa/service_request_latest/views/components/action_button/footer_action_button.dart'; +import 'package:test_sa/views/pages/user/requests/pending_requests_screen.dart'; +import 'package:test_sa/views/widgets/bottom_sheets/pending_request_bottom_sheet.dart'; +import 'package:test_sa/views/widgets/equipment/asset_picker.dart'; import 'package:test_sa/views/widgets/images/multi_image_picker.dart'; import 'package:test_sa/views/widgets/loaders/loading_manager.dart'; import 'package:test_sa/views/widgets/qr/scan_qr.dart'; +import 'package:test_sa/views/widgets/sound/TextSpeechRecordWidget.dart'; import '../../../../../../controllers/providers/api/status_drop_down/report/service_report_last_calls_provider.dart'; import '../../../../../../new_views/common_widgets/default_app_bar.dart'; + class CreateNewRequest extends StatefulWidget { static const String id = "/create-new-request"; - const CreateNewRequest({Key ?key}) : super(key: key); + const CreateNewRequest({Key? key}) : super(key: key); @override _CreateNewRequestState createState() => _CreateNewRequestState(); } class _CreateNewRequestState extends State with TickerProviderStateMixin { - AssetProvider? _devicesProvider; - bool _isLoading = false; - int _selectedEStatus = 1; - bool _isHighPriority = false; - String text=''; - + late TextEditingController _commentController; + late UserProvider _userProvider; + late SettingProvider _settingProvider; + late ServiceRequestsProvider _serviceRequestsProvider; + late ServiceRequest _serviceRequest; + final List _deviceImages = []; + final bool _isLoading = false; final GlobalKey _formKey = GlobalKey(); final GlobalKey _scaffoldKey = GlobalKey(); + bool isFirstActionSubmitted = false; + String text = ''; + DateTime? _dateTime; + bool _showDatePicker = false; + PendingAssetServiceRequest? pendingAssetServiceRequest; @override void initState() { super.initState(); - if (context.mounted) { - ServiceRequestsProvider serviceRequestsProvider = Provider.of(context, listen: false); - Provider.of(context, listen: false).reset(); - _devicesProvider = Provider.of(context, listen: false); - Provider.of(context, listen: false).reset(); - Provider.of(context, listen: false).serviceRequestId = serviceRequestsProvider.currentSelectedRequest?.id; + _commentController = TextEditingController(); + _serviceRequestsProvider = Provider.of(context, listen: false); + _userProvider = Provider.of(context, listen: false); + _serviceRequestsProvider = Provider.of(context, listen: false); + + if (_serviceRequestsProvider.currentSelectedRequest != null) { + _serviceRequest = _serviceRequestsProvider.currentSelectedRequest!; + _deviceImages.addAll(_serviceRequest.devicePhotos!.map((e) => File(e)).toList()); + _showDatePicker = _serviceRequest.firstAction != null && _serviceRequest.firstAction?.name == "Need a visit"; + if (_showDatePicker && _serviceRequest.visitDate != null) { + _dateTime = DateTime.tryParse(_serviceRequest.visitDate!); + } + } else { + _serviceRequest = ServiceRequest(); } + isFirstActionSubmitted = _serviceRequest.firstAction != null; // _isLoading = true; } - _getDevice(String? result, {bool isQr = false}) async { - if (result == null) return; - _devicesProvider!.reset(); - await _devicesProvider!.getAssets( - search: AssetSearch(assetNo: result, assetSerialNumber: ""), - isQr: isQr, - ); + + @override + void dispose() { + // TODO: implement dispose + _commentController.dispose(); + super.dispose(); } + bool _isLocalUrl(String url) { + if (url.isEmpty != false) return false; + return url.startsWith("/") || url.startsWith("file://") || url.substring(1).startsWith(':\\'); + } @override Widget build(BuildContext context) { - - final List _files = []; - return Scaffold( key: _scaffoldKey, appBar: DefaultAppBar(title: context.translation.createNewRequest), @@ -85,84 +110,56 @@ class _CreateNewRequestState extends State with TickerProvider child: Column( children: [ SingleChildScrollView( - child: Card( - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - AppFilledButton( - label: context.translation.scanOrPickAsset, - // showIcon: true, - // icon: "scan_asset".toSvgAsset(height: 20, fit: BoxFit.contain, color: Theme.of(context).scaffoldBackgroundColor), - buttonColor: AppColor.neutral50, - onPressed: () async { - String result = await Navigator.of(context).push( - MaterialPageRoute(builder: (_) => const ScanQr()), - ) as String; - _getDevice(result, isQr: true); - } , - ), - 21.height, - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - context.translation.highPriority.bodyText(context).custom(color: AppColor.black20), - CupertinoSwitch( - value: _isHighPriority, - - onChanged: (value) { - setState(() { - // listingVm.listing[listingVm.listingParameter]['bayut'] = value; - _isHighPriority = value; - }); - }, - thumbColor: AppColor.red70, - activeColor: AppColor.red30.withOpacity(0.4), - - ), - ], - ), - 20.height, - context.translation.equipmentStatus.bodyText(context).custom(color: AppColor.black20), - 12.height, - assetStatusWidget(context), - 8.height, - - 23.height, - MultiFilesPicker(label: context.translation.attachImage, - files: _files, - buttonColor: AppColor.primary10, - onlyImages: true, - buttonIcon: 'image-plus'?.toSvgAsset(color: AppColor.primary10), - ), - AppTextFormField( - labelText: "Type any comment", - backgroundColor: AppColor.neutral30, - alignLabelWithHint: true, - showShadow: false, - validator: (value) => Validator.hasValue(value) ? null : context.translation.requiredField, - textInputType: TextInputType.multiline, - suffixIcon: "comment_send".toSvgAsset().paddingOnly(end: 16).onPress(() { - if (_formKey.currentState!.validate()) { - _formKey.currentState!.save(); - // final comment = Comment(id: 0, callRequestId: num.tryParse(widget.requestId ?? ""), comment: text); - // commentsProvider.addComment(context, comment: comment); - } - }), - onSaved: (value) { - text = value; - }, - ), - - - ], - ).paddingOnly(start:13,end: 13,top: 15,bottom: 16), - ).paddingAll(16), + child: Column( + children: [ + Card( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + scanAssetButton(), + if (pendingAssetServiceRequest != null && pendingAssetServiceRequest!.details!.isNotEmpty) ...[ + 8.height, + Row( + children: [ + const Icon(Icons.warning, color: Color(0xffEE404C), size: 14), + 8.width, + Text( + "This asset already have ${pendingAssetServiceRequest!.details!.length} request pending", + style: const TextStyle(fontSize: 12, fontWeight: FontWeight.w500, color: Color(0xff7D859A), decoration: TextDecoration.underline), + ).expanded, + ], + ).onPress(() { + showPendingRequests(); + }), + ], + 21.height, + highPriorityWidget(), + 20.height, + equipmentStatusWidget(context), + 24.height, + MultiFilesPicker( + label: context.translation.attachImage, + files: _deviceImages, + buttonColor: AppColor.primary10, + onlyImages: true, + buttonIcon: 'image-plus'.toSvgAsset(color: AppColor.primary10), + ), + ], + ).paddingOnly(start: 13, end: 13, top: 15, bottom: 16), + ).paddingAll(16), + commentWidget(serviceRequest: ServiceRequest()), + ], + ), ).expanded, FooterActionButton.footerContainer( child: AppFilledButton( - label: context.translation.submitRequest, + // label: context.translation.submitRequest, buttonColor: AppColor.primary10, - onPressed: (){}, + label: (pendingAssetServiceRequest != null && (pendingAssetServiceRequest!.details?.isNotEmpty ?? false)) + ? context.translation.duplicateRequest + : context.translation.createNewRequest, + onPressed: checkPendingRequest ? null : _submit, + // buttonColor: AppColor.primary10, ), ), ], @@ -173,43 +170,189 @@ class _CreateNewRequestState extends State with TickerProvider }), ); } - Widget assetStatusWidget(BuildContext context) { - return Row( - mainAxisSize: MainAxisSize.min, - children: [ - radioButtonWidget(label: context.translation.up_and_running, value: 1), - radioButtonWidget(label: context.translation.partially_down, value: 2), - radioButtonWidget(label: context.translation.fully_down, value: 3), - ], + + Widget equipmentStatusWidget(BuildContext context) { + return Consumer(builder: (cxt, snapshot, _) { + try { + _serviceRequest.defectType ??= snapshot.items.first; + } catch (ex) { + print("snapshot.items:${snapshot.items.length}"); + } + + return Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisSize: MainAxisSize.min, + children: [ + context.translation.equipmentStatus.bodyText(context).custom(color: AppColor.black20), + 8.height, + Wrap( + runSpacing: 8, + spacing: 8, + children: [ + for (var element in snapshot.items) + Row( + mainAxisSize: MainAxisSize.min, + children: [ + SizedBox( + width: 24, + height: 24, + child: Radio( + value: element, + activeColor: Colors.red, + fillColor: WidgetStateColor.resolveWith((states) { + if (states.contains(WidgetState.selected)) return const Color(0xff3DA5E5); + return const Color(0xffE0E0E0); + }), + groupValue: _serviceRequest.defectType, + onChanged: (state) { + setState(() { + _serviceRequest.defectType = element; + }); + }), + ), + 8.width, + Text(element.name!, style: Theme.of(context).textTheme.bodySmall), + ], + ) + ], + ).toShimmer(isShow: snapshot.loading), + ], + ); + }); + } + + Widget scanAssetButton() { + return AssetPicker( + device: _serviceRequest.device, + showLoading: checkPendingRequest, + borderColor: AppColor.black20, + onPick: (asset) async { + pendingAssetServiceRequest = null; + _serviceRequest.device = asset; + await checkAssetForPendingServiceRequest(asset.id!.toInt()); + + if (pendingAssetServiceRequest != null && pendingAssetServiceRequest!.details!.isNotEmpty) { + showPendingRequestBottomSheet(); + } + }, ); } - Widget radioButtonWidget({required String label, required dynamic value}) { + Widget highPriorityWidget() { return Row( - mainAxisSize: MainAxisSize.min, + mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - SizedBox( - width: 20.toScreenWidth, - height: 40.toScreenHeight, - //TODO use the type required according data.. - child: Radio( - activeColor: AppColor.primary10, - value: value, - groupValue: _selectedEStatus, - onChanged: (int? value) { - setState(() { - _selectedEStatus = value!; - }); - }, - ), - ), - 8.width, - Text( - label, - style: AppTextStyles.tinyFont, - ), - 13.width, + context.translation.highPriority.bodyText(context).custom(color: AppColor.black20), + Consumer(builder: (cxt, snapshot, _) { + _serviceRequest.priority ??= snapshot.items.firstWhere((element) => element.value == 0, orElse: null); + + return CupertinoSwitch( + thumbColor: AppColor.red70, + activeColor: AppColor.red30.withOpacity(0.4), + value: _serviceRequest.priority?.value != 0, + onChanged: (state) { + if (state) { + _serviceRequest.priority = snapshot.items.firstWhere((element) => element.value == 1, orElse: null); + } else { + _serviceRequest.priority = snapshot.items.firstWhere((element) => element.value == 0, orElse: null); + } + setState(() {}); + }).toShimmer(isShow: snapshot.loading); + }), + // CupertinoSwitch( + // value: _isHighPriority, + // + // onChanged: (value) { + // setState(() { + // // listingVm.listing[listingVm.listingParameter]['bayut'] = value; + // _isHighPriority = value; + // }); + // }, + // thumbColor: AppColor.red70, + // activeColor: AppColor.red30.withOpacity(0.4), + // + // ), ], ); } + + Widget commentWidget({required ServiceRequest? serviceRequest}) { + return TextSpeechRecordWidget( + initialMessage: serviceRequest?.callComments ?? '', + onMessageChange: (message) { + serviceRequest?.callComments = message; + }, + onRecord: (audio) { + serviceRequest?.audio = audio; + }, + enabled: serviceRequest == null ? true : false, + ).paddingOnly(start: 16, end: 16,bottom: 16); + } + + bool checkPendingRequest = false; + + void showPendingRequests() { + Navigator.of(context).push(MaterialPageRoute(builder: (_) => PendingServiceRequestScreen(pendingAssetServiceRequest!))); + } + + void showPendingRequestBottomSheet() async { + bool view = (await showModalBottomSheet( + context: context, + isDismissible: false, + shape: const RoundedRectangleBorder( + borderRadius: BorderRadius.vertical( + top: Radius.circular(20), + ), + ), + clipBehavior: Clip.antiAliasWithSaveLayer, + builder: (BuildContext context) => PendingRequestBottomSheet(pendingAssetServiceRequest!, _serviceRequest.device!), + )) as bool; + if (view) { + showPendingRequests(); + } + } + + Future checkAssetForPendingServiceRequest(int assetId) async { + checkPendingRequest = true; + setState(() {}); + + pendingAssetServiceRequest = await _serviceRequestsProvider.checkAssetPendingRequest(assetId); + await Future.delayed(const Duration(milliseconds: 250)); + + checkPendingRequest = false; + setState(() {}); + } + + Future _submit() async { + _serviceRequest.requestedThrough = Provider.of(context, listen: false).items.firstWhere((element) => element.value == 3, orElse: null); + _serviceRequest.type = Provider.of(context, listen: false).items.firstWhere((element) => element.value == 1, orElse: null); + + // print("_serviceRequest?.requestedThrough:${_serviceRequest?.requestedThrough.toJson()}"); + // print("_serviceRequest?.type:${_serviceRequest?.type.toJson()}"); + // print("_serviceRequest?.priority:${_serviceRequest?.priority.toJson()}"); + // return; + + if (_formKey.currentState!.validate() && await _serviceRequest.validateNewRequest(context)) { + _formKey.currentState!.save(); + + // bool canSubmitRequest = await checkAssetForPendingServiceRequest(_serviceRequest.device.id); + // if (!canSubmitRequest) { + // return; + // } + + _serviceRequest.devicePhotos = _deviceImages.map((e) => _isLocalUrl(e.path) ? "${e.path.split("/").last}|${base64Encode(e.readAsBytesSync())}" : e.path).toList(); + if (_serviceRequest.audio != null) { + if (_isLocalUrl(_serviceRequest.audio!)) { + final File file = File(_serviceRequest.audio!); + _serviceRequest.audio = "${file.path.split("/").last}|${base64Encode(file.readAsBytesSync())}"; + } + } + await _serviceRequestsProvider.createRequest( + context: context, + user: _userProvider.user!, + host: _settingProvider.host!, + serviceRequest: _serviceRequest, + ); + } + } } 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 a3d72342..6939287f 100644 --- a/lib/service_request_latest/views/request_detail_main_view.dart +++ b/lib/service_request_latest/views/request_detail_main_view.dart @@ -8,13 +8,12 @@ import 'package:test_sa/new_views/app_style/app_color.dart'; import 'package:test_sa/new_views/common_widgets/default_app_bar.dart'; import 'package:test_sa/service_request_latest/views/components/history_log_view.dart'; import 'package:test_sa/service_request_latest/views/components/initial_visit_card.dart'; -import 'package:test_sa/views/pages/user/requests/service_request_details.dart'; import 'components/request_detail_view.dart'; class RequestDetailMain extends StatelessWidget { final int requestId; - const RequestDetailMain({Key? key,required this.requestId}) : super(key: key); + const RequestDetailMain({Key? key, required this.requestId}) : super(key: key); @override Widget build(BuildContext context) { @@ -48,14 +47,14 @@ class RequestDetailMain extends StatelessWidget { ), ), 12.height, - TabBarView( + TabBarView( children: [ RequestDetailView( serviceRequest: ServiceRequest(id: requestId.toString()), fromTabView: true, ), - const HistoryLogView(), - ], + const HistoryLogView(), + ], ).expanded, ], ), diff --git a/lib/views/widgets/e_signature/e_signature.dart b/lib/views/widgets/e_signature/e_signature.dart index 320cecba..23bc5f30 100644 --- a/lib/views/widgets/e_signature/e_signature.dart +++ b/lib/views/widgets/e_signature/e_signature.dart @@ -103,7 +103,7 @@ class _ESignatureState extends State { height: 135.toScreenHeight, width: MediaQuery.of(context).size.width, padding: const EdgeInsets.only(bottom: 8), - child: signature != null ? Image.memory(signature!) : ImageLoader(boxFit: BoxFit.contain, url: URLs.getFileUrl(widget.oldSignature)!), + child: signature != null ? Image.memory(signature!) : ImageLoader(boxFit: BoxFit.contain, url: URLs.getFileUrl(widget.oldSignature)??''), ) : AbsorbPointer( absorbing: !_editable, diff --git a/lib/views/widgets/equipment/asset_picker.dart b/lib/views/widgets/equipment/asset_picker.dart index 93fc91d8..bc3dcd17 100644 --- a/lib/views/widgets/equipment/asset_picker.dart +++ b/lib/views/widgets/equipment/asset_picker.dart @@ -14,10 +14,11 @@ class AssetPicker extends StatelessWidget { final Asset? device; final bool editable; final bool showAssetInfo; + final Color? borderColor; final bool forPPM; final bool showLoading; - const AssetPicker({Key? key, this.editable = true, this.device, this.onPick, this.showAssetInfo = true, this.forPPM = false, this.showLoading = false}) : super(key: key); + const AssetPicker({Key? key, this.editable = true, this.device, this.onPick,this.borderColor, this.showAssetInfo = true, this.forPPM = false, this.showLoading = false}) : super(key: key); @override Widget build(BuildContext context) { @@ -36,7 +37,7 @@ class AssetPicker extends StatelessWidget { child: Row( mainAxisSize: MainAxisSize.min, children: [ - "qr".toSvgAsset(height: 22, fit: BoxFit.fitHeight, color: context.isDark ? AppColor.neutral20 : Colors.white), + "scan_asset".toSvgAsset(height: 22, fit: BoxFit.fitHeight, color: context.isDark ? AppColor.neutral20 : Colors.white), 8.width, "Scan or Pick Asset".bodyText(context).custom(color: context.isDark ? AppColor.neutral20 : Colors.white), ], @@ -52,16 +53,16 @@ class AssetPicker extends StatelessWidget { height: 50, alignment: Alignment.center, decoration: BoxDecoration( - color: Colors.white, borderRadius: BorderRadius.circular(10), border: Border.all(color: AppColor.blueStatus(context), width: 2), + color: Colors.white, borderRadius: BorderRadius.circular(10), border: Border.all(color:borderColor?? AppColor.blueStatus(context), width: 2), // boxShadow: [BoxShadow(color: Colors.black.withOpacity(0.03), blurRadius: 14)], ), padding: EdgeInsets.symmetric(horizontal: 16.toScreenWidth, vertical: 8.toScreenHeight), child: Row( mainAxisSize: MainAxisSize.min, children: [ - "qr".toSvgAsset(height: 22, fit: BoxFit.fitHeight, color: context.isDark ? AppColor.neutral20 : Colors.black87), + "scan_asset".toSvgAsset(height: 22, fit: BoxFit.fitHeight, color: context.isDark ? AppColor.neutral20 : AppColor.neutral120), 8.width, - "Re-Scan or Pick Asset".bodyText(context).custom(color: context.isDark ? AppColor.neutral20 : Colors.black87), + "Re-Scan or Pick Asset".bodyText(context).custom(color: context.isDark ? AppColor.neutral20 : AppColor.black20), ], ), ).onPress(() async { diff --git a/lib/views/widgets/images/multi_image_picker.dart b/lib/views/widgets/images/multi_image_picker.dart index 3bf25b9b..1fe5a186 100644 --- a/lib/views/widgets/images/multi_image_picker.dart +++ b/lib/views/widgets/images/multi_image_picker.dart @@ -9,6 +9,7 @@ import 'package:test_sa/extensions/context_extension.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/new_views/app_style/app_color.dart'; import '../../../new_views/common_widgets/app_dashed_button.dart'; import 'multi_image_picker_item.dart'; @@ -183,32 +184,89 @@ class _MultiFilesPickerState extends State { Fluttertoast.showToast(msg: context.translation.maxImagesNumberIs5); return; } - ImageSource source = await showDialog( + ImageSource? source = await showModalBottomSheet( context: context, - builder: (dialogContext) => CupertinoAlertDialog( - actions: [ - TextButton( - child: Text(context.translation.pickFromCamera), - onPressed: () { - Navigator.of(dialogContext).pop(ImageSource.camera); - }, - ), - TextButton( - child: Text(context.translation.pickFromGallery), - onPressed: () { - Navigator.of(dialogContext).pop(ImageSource.gallery); - }, - ), - TextButton( - child: Text(context.translation.pickFromFiles), - onPressed: () async { - await fromFilePicker(); - Navigator.pop(context); - }, + builder: (BuildContext context) { + Widget listCard({required String icon, required String label, required VoidCallback onTap}){ + return GestureDetector( + onTap: onTap, + child: Container( + constraints: BoxConstraints(minWidth: 111.toScreenWidth,minHeight: 111.toScreenHeight), + padding: EdgeInsets.symmetric(horizontal: 12.toScreenWidth,vertical: 12.toScreenHeight), + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(12), + border: Border.all(width: 1,color:AppColor.white70) + ), + child: Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + icon.toSvgAsset(), + 24.height, + label.bodyText2(context).custom(color: AppColor.black20), + ], + ), + ), + ); + } + return Container( + padding: const EdgeInsets.all(16.0), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + listCard( + icon: 'camera_icon', + label: '${context.translation.open}\n${context.translation.camera}', + onTap: () { + Navigator.of(context).pop(ImageSource.camera); + }, + ), + listCard( + icon: 'gallery_icon', + label: '${context.translation.open}\n${context.translation.gallery}', + onTap: () { + Navigator.of(context).pop(ImageSource.gallery); + }, + ), + listCard( + icon: 'file_icon', + label: '${context.translation.open}\n${context.translation.files}', + onTap: () async { + await fromFilePicker(); + Navigator.pop(context); + }, + ), + ], ), - ], - ), + ); + }, ); + // ImageSource source = await showDialog( + // context: context, + // builder: (dialogContext) => CupertinoAlertDialog( + // actions: [ + // TextButton( + // child: Text(context.translation.pickFromCamera), + // onPressed: () { + // Navigator.of(dialogContext).pop(ImageSource.camera); + // }, + // ), + // TextButton( + // child: Text(context.translation.pickFromGallery), + // onPressed: () { + // Navigator.of(dialogContext).pop(ImageSource.gallery); + // }, + // ), + // TextButton( + // child: Text(context.translation.pickFromFiles), + // onPressed: () async { + // await fromFilePicker(); + // Navigator.pop(context); + // }, + // ), + // ], + // ), + // ); if (source == null) return; final pickedFile = await ImagePicker().pickImage(source: source, imageQuality: 70, maxWidth: 800, maxHeight: 800); diff --git a/lib/views/widgets/sound/TextSpeechRecordWidget.dart b/lib/views/widgets/sound/TextSpeechRecordWidget.dart index 3ae6f985..44c80b96 100644 --- a/lib/views/widgets/sound/TextSpeechRecordWidget.dart +++ b/lib/views/widgets/sound/TextSpeechRecordWidget.dart @@ -77,6 +77,7 @@ class _RecordSoundState extends State { _commentController = TextEditingController(); node.unfocus(); _recorderIsOpened = true; + _settingProvider = Provider.of(context,listen: false); // RecordMp3.instance.start(recordFilePath, (type) { // // record fail callback // }); diff --git a/lib/views/widgets/sound/sound_player.dart b/lib/views/widgets/sound/sound_player.dart index d0e1355b..055379f9 100644 --- a/lib/views/widgets/sound/sound_player.dart +++ b/lib/views/widgets/sound/sound_player.dart @@ -158,6 +158,7 @@ class _ASoundPlayerState extends State { if (_audio != widget.audio) { WidgetsBinding.instance.addPostFrameCallback((timeStamp) async { _audio = widget.audio; + print('audio position i got is $_audioPosition'); if (_isLocalFile) { await _audioPlayer.setSourceDeviceFile(_audio); } else { @@ -198,7 +199,7 @@ class _ASoundPlayerState extends State { ).paddingOnly(start: 8, end: 8).expanded, _failedToLoad ? Text("Failed to load", style: AppTextStyle.tiny.copyWith(color: context.isDark ? AppColor.red50 : AppColor.red60)) - : Text("${format(_audioPosition!)}/${format(_audioTime!)}", style: AppTextStyle.tiny.copyWith(color: context.isDark ? AppColor.neutral30 : AppColor.neutral50)), + : Text("${format(_audioPosition??Duration.zero)}/${format(_audioTime??Duration.zero)}", style: AppTextStyle.tiny.copyWith(color: context.isDark ? AppColor.neutral30 : AppColor.neutral50)), ], ), ],