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/quotation_icon.svg b/assets/images/quotation_icon.svg new file mode 100644 index 00000000..3e38ecb2 --- /dev/null +++ b/assets/images/quotation_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..b9127a43 100644 --- a/lib/controllers/api_routes/urls.dart +++ b/lib/controllers/api_routes/urls.dart @@ -27,8 +27,8 @@ class URLs { static get getSiteAutoCompleteWithoutConditionSites => "$_baseUrl/Customer/GetCustomersAutoCompleteWithoutConditionSites"; // get static get nurseDashboardCountUrl=> '$_baseUrl/ServiceRequest/GetDashboardNurseCount'; static get nurseDashboardDetailsUrl=> '$_baseUrl/ServiceRequest/GetDashboardNurseDetails'; - static get nurseConfirmReopenUrl=> '$_baseUrl/ServiceRequest/NurseConfirmReopen'; - static get nurseConfirmCloseUrl=> '$_baseUrl/ServiceRequest/NurseConfirmClose'; + static get nurseRejectUrl=> '$_baseUrl/ServiceRequest/NurseReject'; + static get nurseConfirmUrl=> '$_baseUrl/ServiceRequest/NurseConfirm'; static get engineerDashboardCountUrl=> '$_baseUrl/ServiceRequest/GetDashboardEngineerCount'; static get engineerDashboardDetailsUrl=> '$_baseUrl/ServiceRequest/GetDashboardEngineerDetails'; static get engineerAcceptUrl=> '$_baseUrl/ServiceRequest/EngineerAccept'; @@ -36,9 +36,13 @@ class URLs { static get engineerFixRemotlyUrl=> '$_baseUrl/ServiceRequest/EngineerFixRemotly'; static get engineerNeedVisitUrl=> '$_baseUrl/ServiceRequest/EngineerNeedVisit'; static get engineerMarkAsFixUrl=> '$_baseUrl/ServiceRequest/EngineerMarkAsFix'; + static get engineerConfirmArriveUrl=> '$_baseUrl/ServiceRequest/EngineerConfirmArrive'; + static get engineerUpdateWorkOrderUrl=> '$_baseUrl/ServiceRequest/EngineerUpdateWorkOrder'; 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 createWorkOrderUrl=> '$_baseUrl/ServiceRequest/CreateWorkOrder'; static get updateActivitySparePartUrl=> '$_baseUrl/ServiceRequest/UpdateActivitySparePart'; static get assignEngineerToWorkOrderUrl=> '$_baseUrl/ServiceRequest/AssignEngineerToWorkOrder'; static get getDepartments => "$_baseUrl/Customer/GetDepartmentLookup"; // get diff --git a/lib/controllers/providers/api/service_requests_provider.dart b/lib/controllers/providers/api/service_requests_provider.dart index f3f60954..925f7cc9 100644 --- a/lib/controllers/providers/api/service_requests_provider.dart +++ b/lib/controllers/providers/api/service_requests_provider.dart @@ -613,7 +613,7 @@ class ServiceRequestsProvider extends ChangeNotifier { } Future getServiceRequestObjectById({required String requestId}) async { - try { + // try { isDetialLoading = true; Response response = await ApiManager.instance.get(URLs.getServiceRequestById + "?callRequestId=$requestId"); if (response.statusCode >= 200 && response.statusCode < 300) { @@ -623,10 +623,10 @@ class ServiceRequestsProvider extends ChangeNotifier { isDetialLoading = false; return null; } - } catch (error) { + // } catch (error) { isDetialLoading = false; return null; - } + // } } Future> getServiceRequestById({required String requestId}) async { diff --git a/lib/dashboard_latest/dashboard_view.dart b/lib/dashboard_latest/dashboard_view.dart index cfac3030..122038b7 100644 --- a/lib/dashboard_latest/dashboard_view.dart +++ b/lib/dashboard_latest/dashboard_view.dart @@ -36,6 +36,7 @@ class _DashboardViewState extends State { late SettingProvider settingProvider; late UserProvider userProvider; late AllRequestsProvider allRequestsProvider; + late DashBoardProvider dashBoardProvider; late NotificationsProvider notificationsProvider; late ScrollController _scrollController; late DashBoardProvider _dashBoardProvider; @@ -64,7 +65,8 @@ class _DashboardViewState extends State { user = userProvider.user!; getRequests(); // await requestDetailProvider.engineerRejectWorkOrder(id: '3', feedBack: 'Abcdef'); - + // await dashBoardProvider.getDashBoardCount(usersType: user.type!); + // await getAllRequests(); if (isFCM) { FirebaseNotificationManger.initialized(context); NotificationManger.initialisation((notificationDetails) { @@ -85,6 +87,7 @@ class _DashboardViewState extends State { // 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; // }); @@ -95,7 +98,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 e1295bf0..994d13d7 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/dashboard_latest/dashboard_provider.dart'; +import 'package:test_sa/controllers/providers/api/all_requests_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'; @@ -218,7 +219,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: [ diff --git a/lib/dashboard_latest/widgets/requests_fragment.dart b/lib/dashboard_latest/widgets/requests_fragment.dart index 1e8e37f4..df1323b0 100644 --- a/lib/dashboard_latest/widgets/requests_fragment.dart +++ b/lib/dashboard_latest/widgets/requests_fragment.dart @@ -11,7 +11,7 @@ import 'package:test_sa/models/enums/user_types.dart'; import 'package:test_sa/new_views/app_style/app_color.dart'; import 'package:test_sa/new_views/common_widgets/custom_badge.dart'; import 'package:test_sa/new_views/pages/land_page/requests_list_page.dart'; - +import 'package:test_sa/controllers/providers/api/all_requests_provider.dart'; class RequestsFragment extends StatelessWidget { const RequestsFragment({Key? key}) : super(key: key); diff --git a/lib/extensions/text_extensions.dart b/lib/extensions/text_extensions.dart index 6d1fadfc..e58043ea 100644 --- a/lib/extensions/text_extensions.dart +++ b/lib/extensions/text_extensions.dart @@ -134,6 +134,13 @@ abstract class AppTextStyles { fontStyle: FontStyle.normal, decoration: TextDecoration.none, ); + static final TextStyle textFieldLabelStyle= TextStyle( + fontSize: 11.toScreenWidth, + fontWeight: FontWeight.w500, + color: AppColor.neutral20, + fontStyle: FontStyle.normal, + decoration: TextDecoration.none, + ); static final TextStyle tinyFont2 = TextStyle( fontSize: 10.toScreenWidth, fontWeight: FontWeight.w500, 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/models/helper_data_models/workorder/nurse_action_model.dart b/lib/models/helper_data_models/workorder/nurse_action_model.dart index 9af3c560..b9a2c231 100644 --- a/lib/models/helper_data_models/workorder/nurse_action_model.dart +++ b/lib/models/helper_data_models/workorder/nurse_action_model.dart @@ -5,10 +5,6 @@ class NurseActionModel { NurseActionModel({this.workOrderId, this.feedback, this.signatureNurse}); - factory NurseActionModel.fromJson(Map json) { - return NurseActionModel(workOrderId: json['workOrderId'], feedback: json['feedback'], signatureNurse: json['signatureNurse']); - } - Map toJson() { return {'workOrderId': workOrderId, 'feedback': feedback, 'signatureNurse': signatureNurse}; } diff --git a/lib/models/helper_data_models/workorder/work_order_model.dart b/lib/models/helper_data_models/workorder/work_order_model.dart new file mode 100644 index 00000000..cb665d35 --- /dev/null +++ b/lib/models/helper_data_models/workorder/work_order_model.dart @@ -0,0 +1,116 @@ +class WorkOrderHModel { + int? assetId; + int? equipmentStatusId; + int? priorityId; + int? problemDescriptionId; + String? comments; + String? voiceNote; + List? workOrderAttachments; + + WorkOrderHModel( + {this.assetId, + this.equipmentStatusId, + this.priorityId, + this.problemDescriptionId, + this.comments, + this.voiceNote, + this.workOrderAttachments}); + + WorkOrderHModel.fromJson(Map json) { + assetId = json['assetId']; + equipmentStatusId = json['equipmentStatusId']; + priorityId = json['priorityId']; + problemDescriptionId = json['problemDescriptionId']; + comments = json['comments']; + voiceNote = json['voiceNote']; + if (json['workOrderAttachments'] != null) { + workOrderAttachments = []; + json['workOrderAttachments'].forEach((v) { + workOrderAttachments!.add( WorkOrderAttachments.fromJson(v)); + }); + } + } + + Map toJson() { + final Map data = {}; + data['assetId'] = assetId; + data['equipmentStatusId'] = equipmentStatusId; + data['priorityId'] = priorityId; + data['problemDescriptionId'] = problemDescriptionId; + data['comments'] = comments; + data['voiceNote'] = voiceNote; + if (workOrderAttachments != null) { + data['workOrderAttachments'] = + workOrderAttachments!.map((v) => v.toJson()).toList(); + } + return data; + } +} + +class WorkOrderAttachments { + int? id; + String? name; + + WorkOrderAttachments({this.id, this.name}); + + WorkOrderAttachments.fromJson(Map json) { + id = json['id']; + name = json['name']; + } + + Map toJson() { + final Map data = {}; + data['id'] = id; + data['name'] = name; + return data; + } +} +class EngineerUpdateWorkOrderHModel { + int? workOrderId; + int? equipmentStatusId; + String? returnToService; + int? serviceTypeId; + int? loanAvailabilityId; + int? loanAssetId; + int? failureReasonId; + int? faultDescriptionId; + String? solution; + + EngineerUpdateWorkOrderHModel( + {this.workOrderId, + this.equipmentStatusId, + this.returnToService, + this.serviceTypeId, + this.loanAvailabilityId, + this.loanAssetId, + this.failureReasonId, + this.faultDescriptionId, + this.solution}); + + EngineerUpdateWorkOrderHModel.fromJson(Map json) { + workOrderId = json['workOrderId']; + equipmentStatusId = json['equipmentStatusId']; + returnToService = json['returnToService']; + serviceTypeId = json['serviceTypeId']; + loanAvailabilityId = json['loanAvailabilityId']; + loanAssetId = json['loanAssetId']; + failureReasonId = json['failureReasonId']; + faultDescriptionId = json['faultDescriptionId']; + solution = json['solution']; + } + + Map toJson() { + final Map data = {}; + data['workOrderId'] = workOrderId; + data['equipmentStatusId'] = equipmentStatusId; + data['returnToService'] = returnToService; + data['serviceTypeId'] = serviceTypeId; + data['loanAvailabilityId'] = loanAvailabilityId; + data['loanAssetId'] = loanAssetId; + data['failureReasonId'] = failureReasonId; + data['faultDescriptionId'] = faultDescriptionId; + data['solution'] = solution; + return data; + } +} + diff --git a/lib/models/lookup.dart b/lib/models/lookup.dart index eee96ef2..79a03e1d 100644 --- a/lib/models/lookup.dart +++ b/lib/models/lookup.dart @@ -33,7 +33,8 @@ class Lookup extends Base { // userName = json['userName'] ?? ''; // } - factory Lookup.fromJson(Map parsedJson) { + factory Lookup.fromJson(Map? parsedJson) { + if(parsedJson==null) return Lookup(); return Lookup( name: parsedJson["name"], id: parsedJson["id"], diff --git a/lib/new_views/app_style/app_color.dart b/lib/new_views/app_style/app_color.dart index 6904f7a4..cb570392 100644 --- a/lib/new_views/app_style/app_color.dart +++ b/lib/new_views/app_style/app_color.dart @@ -27,6 +27,7 @@ class AppColor { static const Color neutral100 = Color(0xffF4F6FC); static const Color neutral110 = Color(0xffF3F5FB); static const Color neutral120 = Color(0xff7D859A); + static const Color neutral130 = Color(0xffE0E0E0); //background @@ -40,8 +41,8 @@ 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); static const Color white936 = Color(0xff212936); - //black static const Color black10 = Color(0xff3B3D4A); static const Color black20 = Color(0xff212936); 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/app_text_form_field.dart b/lib/new_views/common_widgets/app_text_form_field.dart index 45158219..65440d6c 100644 --- a/lib/new_views/common_widgets/app_text_form_field.dart +++ b/lib/new_views/common_widgets/app_text_form_field.dart @@ -110,6 +110,7 @@ class _AppTextFormFieldState extends State { focusedBorder: border, enabledBorder: border, errorBorder: border, + contentPadding: widget.contentPadding ?? EdgeInsets.symmetric(vertical: 12.toScreenHeight, horizontal: 16.toScreenWidth), constraints: const BoxConstraints(), suffixIconConstraints: const BoxConstraints(minWidth: 0), 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 _workOrderHModel; + + set workOrderHModel(WorkOrderHModel value) { + _workOrderHModel = value; + notifyListeners(); + } + + ActivityAssetRetiredModel? get activityAssetRetiredModel => _activityAssetRetiredModel; + + set activityAssetRetiredModel(ActivityAssetRetiredModel? value) { + _activityAssetRetiredModel = value; + notifyListeners(); + } + ActivitySparePartModel? get activitySparePartModel => _activitySparePartModel; set activitySparePartModel(ActivitySparePartModel? value) { @@ -130,9 +149,32 @@ class RequestDetailProvider extends ChangeNotifier { notifyListeners(); } + //create workOrder nurse ..... + Future createWorkOrder({required WorkOrderHModel workOrderHModel}) async { + isLoading = true; + try { + final response = await ApiManager.instance.post( + URLs.createWorkOrderUrl, + body: workOrderHModel.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; + } + } + //getWorkOrderById...... Future getWorkOrderById({required int id}) async { - //try { + try { isLoading = true; notifyListeners(); final response = await ApiManager.instance.get(URLs.getWorkOrderByIdUrl + "?workOrderId=$id"); @@ -142,12 +184,12 @@ class RequestDetailProvider extends ChangeNotifier { } isLoading = false; notifyListeners(); - // } catch (e) { - // log("getSubWorkOrderDetails [error] : $e"); - // isLoading = false; - // notifyListeners(); - // return null; - // } + } catch (e) { + log("getSubWorkOrderDetails [error] : $e"); + isLoading = false; + notifyListeners(); + return null; + } } //engineerAcceptWorkOrder...... @@ -277,6 +319,31 @@ class RequestDetailProvider extends ChangeNotifier { } } + //engineer Confirm Arrive...... + Future engineerConfirmArrive({required int workOrderId, required int verificationTypeId, required String photoInfo, required String otp}) async { + try { + Map body = {"workOrderId": workOrderId, "verificationTypeId": verificationTypeId, "photoInfo": photoInfo, "otp": otp}; + isLoading = true; + final response = await ApiManager.instance.post(URLs.engineerConfirmArriveUrl, body: body); + stateCode = response.statusCode; + if (response.statusCode >= 200 && response.statusCode < 300) { + CommonResponseModel commonResponseModel = CommonResponseModel.fromJson(json.decode(response.body)); + print('response of Engineer mark as fixed ${commonResponseModel.toJson()}'); + notifyListeners(); + isLoading = false; + return commonResponseModel; + } + isLoading = false; + notifyListeners(); + return CommonResponseModel(); + } catch (e) { + log("engineer accept [error] : $e"); + isLoading = false; + notifyListeners(); + return CommonResponseModel(); + } + } + //assignEngineerToWorkOrder...... Future assignEngineerWorkOrder({required String workOrderId, required String engineerId}) async { try { @@ -286,10 +353,33 @@ class RequestDetailProvider extends ChangeNotifier { }; isLoading = true; final response = await ApiManager.instance.post(URLs.assignEngineerToWorkOrderUrl, body: body); + final response = await ApiManager.instance.post(URLs.assignEngineerToWorkOrderUrl, body: body); + stateCode = response.statusCode; + if (response.statusCode >= 200 && response.statusCode < 300) { + CommonResponseModel commonResponseModel = CommonResponseModel.fromJson(json.decode(response.body)); + notifyListeners(); + isLoading = false; + return commonResponseModel; + } + isLoading = false; + notifyListeners(); + return CommonResponseModel(); + } catch (e) { + log("engineer accept [error] : $e"); + isLoading = false; + notifyListeners(); + return CommonResponseModel(); + } + } + + //engineerUpdateWorkOrder...... + Future engineerUpdateWorkOrder({required EngineerUpdateWorkOrderHModel model}) async { + try { + isLoading = true; + final response = await ApiManager.instance.post(URLs.engineerUpdateWorkOrderUrl, body: model.toJson()); 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; @@ -306,14 +396,13 @@ class RequestDetailProvider extends ChangeNotifier { } //Nurse confirm reopen - Future nurseReopen() async { + Future nurseReject({required NurseActionModel model}) async { try { isLoading = true; - final response = await ApiManager.instance.post(URLs.nurseConfirmReopenUrl, body: nurseActionModel!.toJson()); + final response = await ApiManager.instance.post(URLs.nurseRejectUrl, body: model.toJson()); 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; @@ -330,14 +419,15 @@ class RequestDetailProvider extends ChangeNotifier { } //Nurse confirm close - Future nurseClose() async { + Future nurseConfirm({required NurseActionModel model}) async { try { isLoading = true; - final response = await ApiManager.instance.post(URLs.nurseConfirmCloseUrl, body: nurseActionModel!.toJson()); + final response = await ApiManager.instance.post(URLs.nurseConfirmUrl, body: model.toJson()); + print('response i got is ${response.body}'); + 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; @@ -356,7 +446,7 @@ class RequestDetailProvider extends ChangeNotifier { Future updateActivitySparePart({required ActivitySparePartModel activitySparePartModel}) async { isLoading = true; try { - final response = await ApiManager.instance.put( + final response = await ApiManager.instance.post( URLs.updateActivitySparePartUrl, body: activitySparePartModel.toJson(), ); @@ -404,7 +494,7 @@ class RequestDetailProvider extends ChangeNotifier { Future createActivitySparePart({required ActivitySparePartModel activitySparePartModel}) async { isLoading = true; try { - final response = await ApiManager.instance.put( + final response = await ApiManager.instance.post( URLs.createActivitySparePartUrl, body: activitySparePartModel.toJson(), ); @@ -422,4 +512,26 @@ class RequestDetailProvider extends ChangeNotifier { return -1; } } + + Future createActivityAssetToBeRetired({required ActivityAssetRetiredModel activityAssetRetiredModel}) async { + isLoading = true; + try { + final response = await ApiManager.instance.post( + 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/action_button/footer_action_button.dart b/lib/service_request_latest/views/components/action_button/footer_action_button.dart index 6629b79f..0df361f6 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 @@ -20,7 +20,7 @@ class FooterActionButton { ); } - static Widget footerWidget({required int status,required BuildContext context}){ + static Widget requestDetailsFooterWidget({required int status,required BuildContext context}){ switch(status){ //accept reject... case 1: @@ -151,7 +151,7 @@ class FooterActionButton { // maxWidth: true, buttonColor: AppColor.primary10, onPressed: () async { - + ServiceRequestBottomSheet.nurseTakeActionBottomSheet(context: context); }, ) ); 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..e15a7df0 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 @@ -1,3 +1,5 @@ +import 'dart:convert'; + import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:flutter_svg/flutter_svg.dart'; @@ -9,11 +11,13 @@ import 'package:test_sa/extensions/int_extensions.dart'; import 'package:test_sa/extensions/string_extensions.dart'; import 'package:test_sa/extensions/text_extensions.dart'; import 'package:test_sa/extensions/widget_extensions.dart'; +import 'package:test_sa/models/helper_data_models/workorder/nurse_action_model.dart'; import 'package:test_sa/models/lookup.dart'; import 'package:test_sa/models/service_request/service_request.dart'; import 'package:test_sa/models/timer_model.dart'; import 'package:test_sa/new_views/common_widgets/single_item_drop_down_menu.dart'; import 'package:test_sa/providers/service_request_providers/first_action_provider.dart'; +import 'package:test_sa/service_request_latest/request_detail_provider.dart'; import 'package:test_sa/service_request_latest/views/forms/spare_part/spare_part_request.dart'; import 'package:test_sa/service_request_latest/views/components/verify_arrival_view.dart'; import 'package:test_sa/views/widgets/date_and_time/date_picker.dart'; @@ -58,7 +62,7 @@ class ServiceRequestBottomSheet { ADatePicker( label: context.translation.date, hideShadow: true, - height: 80.toScreenHeight, + // height: 60.toScreenHeight, backgroundColor: AppColor.neutral100, date: DateTime.tryParse(serviceRequestProvider.currentSelectedRequest?.startDate ?? ""), formatDateWithTime: true, @@ -78,15 +82,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}'); } }); } @@ -95,7 +99,7 @@ class ServiceRequestBottomSheet { 8.height, SizedBox( width: double.infinity, - height: 80.toScreenHeight, + height: 56.toScreenHeight, // padding: EdgeInsets.symmetric(horizontal: 20.toScreenWidth, vertical: 10.toScreenHeight), child: AppTimer( label: context.translation.workingHours, @@ -112,12 +116,12 @@ class ServiceRequestBottomSheet { return true; }, ), - ), 8.height, AppTextFormField( labelText: context.translation.comments, textInputType: TextInputType.multiline, + labelStyle: AppTextStyles.textFieldLabelStyle, showWithoutDecoration: true, backgroundColor: context.isDark ? AppColor.neutral20 : AppColor.neutral100, alignLabelWithHint: true, @@ -190,9 +194,8 @@ 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 ?? ""), formatDateWithTime: true, onDatePicker: (selectedDate) { @@ -210,11 +213,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(); } }); } @@ -257,34 +260,30 @@ class ServiceRequestBottomSheet { date: DateTime.tryParse(serviceRequestProvider.currentSelectedRequest?.endDate ?? ""), formatDateWithTime: true, onDatePicker: (selectedDate) { - if (selectedDate != null) { - 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 (selectedDateTime != null) { - serviceRequestProvider.currentSelectedRequest?.endDate = selectedDateTime?.toIso8601String(); - serviceRequestProvider.currentSelectedRequest?.workingHours = (((DateTime.parse(serviceRequestProvider.currentSelectedRequest!.endDate!) - .difference(DateTime.parse(serviceRequestProvider.currentSelectedRequest!.startDate!)) - .inSeconds ?? - 0) / - 60) / - 60) - .toStringAsFixed(2); - } - } - }); - } - }, + 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, + ); + serviceRequestProvider.currentSelectedRequest?.endDate = selectedDateTime?.toIso8601String(); + serviceRequestProvider.currentSelectedRequest?.workingHours = (((DateTime.parse(serviceRequestProvider.currentSelectedRequest!.endDate!) + .difference(DateTime.parse(serviceRequestProvider.currentSelectedRequest!.startDate!)) + .inSeconds ?? + 0) / + 60) / + 60) + .toStringAsFixed(2); + } + }); + }, ).expanded, ], ) @@ -293,6 +292,7 @@ class ServiceRequestBottomSheet { AppTextFormField( labelText: context.translation.comments, backgroundColor: AppColor.neutral100, + labelStyle: AppTextStyles.textFieldLabelStyle, showShadow: false, textInputType: TextInputType.multiline, alignLabelWithHint: true, @@ -307,7 +307,6 @@ class ServiceRequestBottomSheet { AppFilledButton( label: context.translation.save, buttonColor: AppColor.primary10, - loading: serviceRequestProvider.isLoading ?? false, onPressed: () async { _formKey.currentState?.save(); @@ -338,7 +337,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), @@ -347,9 +346,10 @@ class ServiceRequestBottomSheet { SingleItemDropDownMenu( context: context, backgroundColor: AppColor.neutral100, - height: 70.toScreenHeight, - title: context.translation.rejectionReason, - initialValue: serviceRequestProvider.currentSelectedRequest?.firstAction, //_serviceRequest.firstAction, + height: 56.toScreenHeight, + title: context.translation.reason, + initialValue: serviceRequestProvider.currentSelectedRequest?.firstAction, + //_serviceRequest.firstAction, onSelect: (value) { serviceRequestProvider.currentSelectedRequest?.firstAction = value; if (serviceRequestProvider.currentSelectedRequest?.firstAction?.value != 2) { @@ -363,6 +363,7 @@ class ServiceRequestBottomSheet { labelText: context.translation.comments, textInputType: TextInputType.multiline, alignLabelWithHint: true, + labelStyle: AppTextStyles.textFieldLabelStyle, onChange: (text) { serviceRequestProvider.currentSelectedRequest?.comments = text; }, @@ -410,7 +411,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 +435,6 @@ class ServiceRequestBottomSheet { break; case 1: - //push to specific screen... // Navigator.push( // context, @@ -476,7 +476,7 @@ class ServiceRequestBottomSheet { child: Column( mainAxisSize: MainAxisSize.min, children: [ - const SizedBox().indicatorWidget(), + const SizedBox().indicatorWidget(), 8.height, Align( alignment: AlignmentDirectional.centerStart, @@ -505,7 +505,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 +523,7 @@ class ServiceRequestBottomSheet { child: Column( mainAxisSize: MainAxisSize.min, children: [ - const SizedBox().indicatorWidget(), + const SizedBox().indicatorWidget(), 8.height, Align( alignment: AlignmentDirectional.centerStart, @@ -559,6 +559,7 @@ class ServiceRequestBottomSheet { ); })); } + static Future feedBackBottomSheet({required BuildContext context}) { final GlobalKey _formKey = GlobalKey(); return showModalBottomSheet( @@ -567,145 +568,170 @@ 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, + labelStyle: AppTextStyles.textFieldLabelStyle, + 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(); + Uint8List? newSignature; + String ?nurseSignature; return showModalBottomSheet( context: context, useSafeArea: true, 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'); + return Form( + key: _formKey, + child: SingleChildScrollView( + child: StatefulBuilder(builder: (context, setState) { - }), - 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 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) return; + newSignature = signature; + nurseSignature = "${DateTime.now().toIso8601String()}.png|${base64Encode(signature)}"; }, - ).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 { + _formKey.currentState?.save(); + if(newSignature!=null&&acknowledge){ + //TODO replace provider with new provider and also check workorder id is not correct. + Provider.of(context,listen: false).nurseReject(model: NurseActionModel( + workOrderId: int.parse(serviceRequestProvider.currentSelectedRequest!.id!), + signatureNurse: nurseSignature, + )); + Navigator.pop(context); - ], - ); - }), - ), - ).bottomSheetContainer(context); - })); + } + + }, + ).expanded, + const SizedBox( + width: 20, + ), + AppFilledButton( + label: context.translation.confirm, + maxWidth: true, + buttonColor: AppColor.green70, + onPressed: () async { + _formKey.currentState?.save(); + if(newSignature!=null&&acknowledge){ + //TODO replace provider with new provider and also check workorder id is not correct. + Provider.of(context,listen: false).nurseConfirm(model: NurseActionModel( + workOrderId: int.parse(serviceRequestProvider.currentSelectedRequest!.id!), + signatureNurse: nurseSignature, + )); + Navigator.pop(context); + } + }, + ).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 366a428c..2787211b 100644 --- a/lib/service_request_latest/views/components/request_detail_view.dart +++ b/lib/service_request_latest/views/components/request_detail_view.dart @@ -20,6 +20,9 @@ import 'package:test_sa/service_request_latest/views/components/action_button/fo 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/service_request_latest/views/forms/asset_retired/verify_asset_detail.dart'; +import 'package:test_sa/service_request_latest/views/forms/maintenance_request/maintenance_request_main.dart'; +import 'package:test_sa/service_request_latest/views/nurse/create_new_request_view.dart'; import 'package:test_sa/views/pages/user/requests/comments_bottom_sheet.dart'; import 'package:test_sa/views/pages/user/requests/update_service_request_page.dart'; import 'package:test_sa/views/widgets/images/files_list.dart'; @@ -27,7 +30,7 @@ import 'package:test_sa/views/widgets/loaders/app_loading.dart'; import 'package:test_sa/views/widgets/loaders/no_data_found.dart'; import 'package:test_sa/views/widgets/requests/request_status.dart'; import 'package:test_sa/views/widgets/sound/sound_player.dart'; - +import '../forms/spare_part/spare_part_request.dart'; class WorkOrderDetailView extends StatelessWidget { WorkOrderDetailView({Key? key}) : super(key: key); @@ -309,12 +312,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) { @@ -336,11 +334,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 @@ -366,7 +361,7 @@ class _RequestDetailViewState extends State { ], ), ), - FooterActionButton.footerWidget(status: 1, context: context), + FooterActionButton.requestDetailsFooterWidget(status: 7, context: context), TimerWidget(), ], ), @@ -588,8 +583,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) => AssetRetired())); + Navigator.push(context, MaterialPageRoute(builder: (context) => const CreateNewRequest())); }), ); } diff --git a/lib/service_request_latest/views/components/verify_assets_details.dart b/lib/service_request_latest/views/components/verify_assets_details.dart index b59a08bf..dca67b81 100644 --- a/lib/service_request_latest/views/components/verify_assets_details.dart +++ b/lib/service_request_latest/views/components/verify_assets_details.dart @@ -17,6 +17,7 @@ import 'package:test_sa/new_views/common_widgets/app_filled_button.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/work_order/reason_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/bottom_sheets/service_request_bottomsheet.dart'; import 'package:test_sa/views/widgets/images/multi_image_picker.dart'; import 'package:test_sa/views/widgets/loaders/loading_manager.dart'; @@ -29,16 +30,16 @@ import '../../../../../new_views/common_widgets/app_text_form_field.dart'; import '../../../../../new_views/common_widgets/default_app_bar.dart'; import '../../../controllers/validator/validator.dart'; -class SparePartRequest extends StatefulWidget { +class VerifyAssetDetail extends StatefulWidget { static const String id = "/verify-assets-detail"; - const SparePartRequest({Key? key}) : super(key: key); + const VerifyAssetDetail({Key? key}) : super(key: key); @override - _SparePartRequestState createState() => _SparePartRequestState(); + _VerifyAssetDetailState createState() => _VerifyAssetDetailState(); } -class _SparePartRequestState extends State with TickerProviderStateMixin { +class _VerifyAssetDetailState extends State with TickerProviderStateMixin { late UserProvider _userProvider; late SettingProvider _settingProvider; late ServiceRequestsProvider _serviceRequestsProvider; @@ -114,7 +115,7 @@ class _SparePartRequestState extends State with TickerProvider return Scaffold( key: _scaffoldKey, - appBar: DefaultAppBar(title: context.translation.sparePartRequest), + appBar: DefaultAppBar(title: context.translation.verify_asset_details), body: Consumer(builder: (context, serviceRequestProvider, child) { return SafeArea( child: LoadingManager( @@ -171,10 +172,9 @@ class _SparePartRequestState extends State with TickerProvider controller: _oracleNoController, labelText: context.translation.oracleNo, textInputType: TextInputType.number, - contentPadding: EdgeInsets.symmetric(horizontal: 16.toScreenWidth, vertical: 20.toScreenHeight), showWithoutDecoration: true, backgroundColor: context.isDark ? AppColor.neutral20 : AppColor.neutral90, - enable: serviceRequestProvider.initialSelectedSparePart != null && serviceRequestProvider.initialSelectedSparePart.sparePart?.id != null, + enable: serviceRequestProvider.initialSelectedSparePart.sparePart?.id != null, validator: (value) => value == null || value.isEmpty ? context.translation.requiredField : Validator.isNumeric(value) @@ -187,10 +187,11 @@ class _SparePartRequestState extends State with TickerProvider ), 15.height, AppTextFormField( - initialValue: _serviceReport?.comment, + initialValue: _serviceReport.comment, backgroundColor: context.isDark ? AppColor.neutral20 : AppColor.neutral90, labelText: context.translation.description, alignLabelWithHint: true, + labelStyle: AppTextStyles.tinyFont.copyWith(color: AppColor.black10), showWithoutDecoration: true, textInputType: TextInputType.multiline, onSaved: (value) { @@ -200,13 +201,13 @@ class _SparePartRequestState extends State with TickerProvider 15.height, MultiFilesPicker(label: context.translation.attachQuotation, files: _files), ], - ).paddingAll(16), + ).paddingAll(12), ), 8.height, ], ), - ).expanded, - AppFilledButton( + ).paddingAll(16).expanded, + FooterActionButton.footerContainer(child: AppFilledButton( label: context.translation.addSparePartActivity, buttonColor: AppColor.green70, onPressed: () async { @@ -234,9 +235,9 @@ class _SparePartRequestState extends State with TickerProvider // final user = Provider.of(context, listen: false).user; // await _serviceRequestsProvider.createServiceReport(context, report: _serviceReport, request: serviceRequestProvider.serviceRequest, user: user); }, - ), + )), ], - ).paddingAll(16), + ), ), ), ); diff --git a/lib/service_request_latest/views/forms/asset_retired/asset_retired.dart b/lib/service_request_latest/views/forms/asset_retired/asset_retired.dart index 26d6e0bb..302bc3af 100644 --- a/lib/service_request_latest/views/forms/asset_retired/asset_retired.dart +++ b/lib/service_request_latest/views/forms/asset_retired/asset_retired.dart @@ -109,7 +109,7 @@ class _AssetRetiredState extends State with TickerProviderStateMix context: context, title: context.translation.failureReason, backgroundColor: AppColor.neutral100, - height: 70.toScreenHeight, + height: 56.toScreenHeight, showShadow: false, // initialValue: _subWorkOrders.reason, onSelect: (value) { @@ -123,6 +123,7 @@ class _AssetRetiredState extends State with TickerProviderStateMix labelText: context.translation.comments, textInputType: TextInputType.multiline, showWithoutDecoration: true, + labelStyle: AppTextStyles.textFieldLabelStyle, backgroundColor: context.isDark ? AppColor.neutral20 : AppColor.neutral100, alignLabelWithHint: true, onChange: (text) { @@ -135,12 +136,10 @@ class _AssetRetiredState extends State with TickerProviderStateMix 23.height, MultiFilesPicker(label: context.translation.attachFiles, files: _files, - buttonIcon: 'image-plus'?.toSvgAsset(), + buttonIcon: 'image-plus'.toSvgAsset(), ), - - ], - ).paddingOnly(start:13,end: 13,top: 16,bottom: 16), + ).paddingOnly(start:13,end: 13,top: 14,bottom: 16), ).paddingAll(16), ).expanded, FooterActionButton.footerContainer( 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 656b8a65..d2c053e0 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 @@ -113,7 +113,6 @@ class _VerifyAssetDetailsState extends State with TickerProv ADatePicker( label: context.translation.returnToService, hideShadow: true, - height: 70.toScreenHeight, backgroundColor: AppColor.neutral100, date: DateTime.tryParse(serviceRequestProvider.currentSelectedRequest?.startDate ?? ""), formatDateWithTime: true, @@ -152,6 +151,7 @@ class _VerifyAssetDetailsState extends State with TickerProv SingleItemDropDownMenu( context: context, title: context.translation.loanAvailability, + height: 56.toScreenHeight, initialValue: _serviceReport?.loanAvailablity, onSelect: (status) { if (status != null) { @@ -183,7 +183,7 @@ class _VerifyAssetDetailsState extends State with TickerProv context: context, title: context.translation.failureReason, backgroundColor: AppColor.neutral100, - height: 70.toScreenHeight, + height: 56.toScreenHeight, showShadow: false, // initialValue: _subWorkOrders.reason, onSelect: (value) { @@ -197,7 +197,7 @@ class _VerifyAssetDetailsState extends State with TickerProv context: context, title: context.translation.faultDescription, backgroundColor: AppColor.neutral100, - height: 70.toScreenHeight, + height: 56.toScreenHeight, showShadow: false, // initialValue: _subWorkOrders.reason, onSelect: (value) { @@ -214,7 +214,7 @@ class _VerifyAssetDetailsState extends State with TickerProv ], ).paddingOnly(start:13,end: 13,top: 16,bottom: 16), - ).paddingAll(16), + ).paddingOnly(top: 17,start: 14,end: 14), ).expanded, Container( padding: EdgeInsets.symmetric(horizontal: 16.toScreenWidth,vertical: 16.toScreenHeight), @@ -254,10 +254,17 @@ class _VerifyAssetDetailsState extends State with TickerProv width: 20.toScreenWidth, height: 40.toScreenHeight, //TODO use the type required according data.. - child: Radio( - activeColor: AppColor.primary10, + child:Radio( value: value, groupValue: _selectedValue, + fillColor: WidgetStateProperty.resolveWith((states) { + // active + if (states.contains(WidgetState.selected)) { + return AppColor.primary10; + } + // inactive + return AppColor.neutral130; + }), onChanged: (int ?value) { setState(() { _selectedValue = value!; @@ -268,7 +275,7 @@ class _VerifyAssetDetailsState extends State with TickerProv 8.width, Text( label, - style: AppTextStyles.tinyFont, + style: AppTextStyles.tinyFont.copyWith(color: AppColor.neutral120), ), 13.width, ], diff --git a/lib/service_request_latest/views/forms/maintenance_request/components/external_request.dart b/lib/service_request_latest/views/forms/maintenance_request/components/external_request.dart index 67569da8..eab0f519 100644 --- a/lib/service_request_latest/views/forms/maintenance_request/components/external_request.dart +++ b/lib/service_request_latest/views/forms/maintenance_request/components/external_request.dart @@ -116,10 +116,9 @@ class _ExternalMaintenanceRequestState extends State child: Column( crossAxisAlignment: CrossAxisAlignment.stretch, children: [ - 8.height, SingleItemDropDownMenu( context: context, - height: 70.toScreenHeight, + height: 56.toScreenHeight, title: context.translation.supplier, showShadow: false, backgroundColor: AppColor.neutral100, @@ -129,35 +128,16 @@ class _ExternalMaintenanceRequestState extends State _serviceReport?.calllastSituation = status; }, ), - // Container( - // height: 60.toScreenHeight, - // width: 60.toScreenWidth, - // decoration: BoxDecoration( - // color: _subWorkOrders.supplier?.suppliername == null ? AppColor.neutral40 : AppColor.background(context), - // borderRadius: BorderRadius.circular(10), - // boxShadow: [BoxShadow(color: Colors.black.withOpacity(0.05), blurRadius: 10)], - // ), - // child: Icon( - // Icons.add, - // color: context.isDark ? null : AppColor.neutral60, - // ), - // ).onPress(_subWorkOrders.supplier?.suppliername == null - // ? null - // : () async { - // SuppEngineerWorkOrders suppEngineer = (await showModalBottomSheet( - // context: context, - // useSafeArea: true, - // isScrollControlled: true, - // backgroundColor: Colors.transparent, - // builder: (context) => AddSupplierEngineerBottomSheet(_subWorkOrders.supplier.id), - // )) as SuppEngineerWorkOrders; - // if (suppEngineer != null) { - // _subWorkOrders?.supplier?.suppPersons ??= []; - // _subWorkOrders?.supplier?.suppPersons?.add(SuppPersons.fromJson(suppEngineer.toJson())); - // engineer = suppEngineer; - // setState(() {}); - // } - // }), + 8.height, + AppTextFormField( + labelText: context.translation.engineerName, + backgroundColor: AppColor.neutral100, + initialValue: _serviceReport?.assignedEmployee?.name.toString(), + textAlign: TextAlign.center, + labelStyle: AppTextStyles.textFieldLabelStyle, + showShadow: false, + style: Theme.of(context).textTheme.titleMedium, + ), 8.height, Row( mainAxisSize: MainAxisSize.min, @@ -169,7 +149,7 @@ class _ExternalMaintenanceRequestState extends State icon: 'clock', withIcon: true, backgroundColor: AppColor.neutral100, - height: 70.toScreenHeight, + height: 56.toScreenHeight, time: _startTime, onTimePicker: (selectedTime) { if (selectedTime != null) { @@ -188,7 +168,7 @@ class _ExternalMaintenanceRequestState extends State withIcon: true, backgroundColor: AppColor.neutral100, withBorder: false, - height: 70.toScreenHeight, + height: 56.toScreenHeight, time: _endTime, onTimePicker: (selectedTime) { if (selectedTime != null) { @@ -204,8 +184,8 @@ class _ExternalMaintenanceRequestState extends State AppTextFormField( labelText: context.translation.workingHours, backgroundColor: AppColor.neutral80, + labelStyle: AppTextStyles.textFieldLabelStyle, suffixIcon: "clock".toSvgAsset(width: 20, color: context.isDark ? AppColor.neutral10 : null).paddingOnly(end: 16), - contentPadding: EdgeInsets.symmetric(vertical: 18.toScreenHeight, horizontal: 16.toScreenWidth), initialValue: _serviceReport?.workingHours.toString(), textAlign: TextAlign.center, showShadow: false, 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 103114f9..fedce3ed 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 @@ -115,10 +115,9 @@ class _InternalMaintenanceRequestState extends State child: Column( crossAxisAlignment: CrossAxisAlignment.stretch, children: [ - 8.height, SingleItemDropDownMenu( context: context, - height: 70.toScreenHeight, + height: 56.toScreenHeight, title: context.translation.activityStatus, showShadow: false, backgroundColor: AppColor.neutral100, @@ -139,7 +138,7 @@ class _InternalMaintenanceRequestState extends State icon: 'clock', withIcon: true, backgroundColor: AppColor.neutral100, - height: 70.toScreenHeight, + height: 56.toScreenHeight, time: _startTime, onTimePicker: (selectedTime) { if (selectedTime != null) { @@ -158,7 +157,7 @@ class _InternalMaintenanceRequestState extends State withIcon: true, backgroundColor: AppColor.neutral100, withBorder: false, - height: 70.toScreenHeight, + height: 56.toScreenHeight, time: _endTime, onTimePicker: (selectedTime) { if (selectedTime != null) { @@ -175,11 +174,12 @@ class _InternalMaintenanceRequestState extends State labelText: context.translation.workingHours, backgroundColor: AppColor.neutral80, suffixIcon: "clock".toSvgAsset(width: 20, color: context.isDark ? AppColor.neutral10 : null).paddingOnly(end: 16), - contentPadding: EdgeInsets.symmetric(vertical: 18.toScreenHeight, horizontal: 16.toScreenWidth), + // contentPadding: EdgeInsets.symmetric(vertical: 18.toScreenHeight, horizontal: 16.toScreenWidth), initialValue: _serviceReport?.workingHours.toString(), textAlign: TextAlign.center, - showShadow: false, + labelStyle: AppTextStyles.textFieldLabelStyle, enable: false, + showShadow: false, style: Theme.of(context).textTheme.titleMedium, ), 8.height, @@ -199,11 +199,12 @@ class _InternalMaintenanceRequestState extends State AppTextFormField( labelText: context.translation.travelingHours, backgroundColor: AppColor.neutral100, + showShadow: false, + labelStyle: AppTextStyles.textFieldLabelStyle, suffixIcon: "clock".toSvgAsset(width: 20, color: context.isDark ? AppColor.neutral10 : null).paddingOnly(end: 16), initialValue: _serviceReport?.travelingHours?.toString(), textInputType: TextInputType.number, - contentPadding: EdgeInsets.symmetric(vertical: 18.toScreenHeight, horizontal: 16.toScreenWidth), - showShadow: false, + // contentPadding: EdgeInsets.symmetric(vertical: 18.toScreenHeight, horizontal: 16.toScreenWidth), onSaved: (value) { _serviceReport?.travelingHours = double.tryParse(value) ?? 0.0; }, @@ -216,9 +217,9 @@ class _InternalMaintenanceRequestState extends State AppTextFormField( labelText: context.translation.assignedEmployee, backgroundColor: AppColor.neutral80, - contentPadding: EdgeInsets.symmetric(vertical: 18.toScreenHeight, horizontal: 16.toScreenWidth), - initialValue: _serviceReport?.workingHours.toString(), + initialValue: _serviceReport?.assignedEmployee?.name.toString(), textAlign: TextAlign.center, + labelStyle: AppTextStyles.textFieldLabelStyle, showShadow: false, enable: false, style: Theme.of(context).textTheme.titleMedium, @@ -229,6 +230,7 @@ class _InternalMaintenanceRequestState extends State labelText: context.translation.technicalComment, backgroundColor: AppColor.neutral100, showShadow: false, + labelStyle: AppTextStyles.textFieldLabelStyle, alignLabelWithHint: true, textInputType: TextInputType.multiline, onSaved: (value) { @@ -238,7 +240,7 @@ class _InternalMaintenanceRequestState extends State ], ), ), - ).toShadowContainer(context).paddingOnly(start: 16, end: 16, top: 12), + ).toShadowContainer(context).paddingOnly(start: 13, end: 14, top: 12), FooterActionButton.footerContainer( child: AppFilledButton( @@ -274,7 +276,14 @@ class _InternalMaintenanceRequestState extends State height: 40.toScreenHeight, //TODO use the type required according data.. child: Radio( - activeColor: AppColor.primary10, + fillColor: WidgetStateProperty.resolveWith((states) { + // active + if (states.contains(WidgetState.selected)) { + return AppColor.primary10; + } + // inactive + return AppColor.neutral130; + }), value: value, groupValue: _selectedValue, onChanged: (int ?value) { diff --git a/lib/service_request_latest/views/forms/maintenance_request/maintenance_request_main.dart b/lib/service_request_latest/views/forms/maintenance_request/maintenance_request_main.dart index a4b37723..0fb38fc0 100644 --- a/lib/service_request_latest/views/forms/maintenance_request/maintenance_request_main.dart +++ b/lib/service_request_latest/views/forms/maintenance_request/maintenance_request_main.dart @@ -27,7 +27,7 @@ class _MaintenanceRequestFormState extends State with Si @override Widget build(BuildContext context) { return Scaffold( - backgroundColor: AppColor.neutral100, + backgroundColor: AppColor.neutral110, appBar: DefaultAppBar(title: context.translation.maintenanceRequest), body: DefaultTabController( length: 2, @@ -47,6 +47,8 @@ class _MaintenanceRequestFormState extends State with Si 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), diff --git a/lib/service_request_latest/views/forms/spare_part/spare_part_request.dart b/lib/service_request_latest/views/forms/spare_part/spare_part_request.dart index de8465ee..ae2a4918 100644 --- a/lib/service_request_latest/views/forms/spare_part/spare_part_request.dart +++ b/lib/service_request_latest/views/forms/spare_part/spare_part_request.dart @@ -10,13 +10,13 @@ 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/service_request/service_report.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/single_item_drop_down_menu.dart'; import 'package:test_sa/providers/loading_list_notifier.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/service_request_latest/views/components/bottom_sheets/service_request_bottomsheet.dart'; import 'package:test_sa/views/widgets/images/multi_image_picker.dart'; import 'package:test_sa/views/widgets/loaders/loading_manager.dart'; @@ -136,7 +136,6 @@ class _SparePartRequestState extends State with TickerProvider context: context, title: context.translation.partNo, staticData: _spareParts, - height: 80.toScreenHeight, showShadow: false, initialValue: serviceRequestProvider.initialSelectedSparePart.sparePart, backgroundColor: context.isDark ? AppColor.neutral20 : AppColor.neutral90, @@ -144,15 +143,15 @@ class _SparePartRequestState extends State with TickerProvider serviceRequestProvider.initialSelectedSparePart = SparePartsWorkOrders(id: 0, sparePart: part, qty: 0); }, ), - 15.height, + 12.height, AppTextFormField( controller: _partQtyController, labelText: context.translation.quantity, textInputType: TextInputType.number, - contentPadding: EdgeInsets.symmetric(horizontal: 16.toScreenWidth, vertical: 20.toScreenHeight), + labelStyle: AppTextStyles.textFieldLabelStyle, showWithoutDecoration: true, backgroundColor: context.isDark ? AppColor.neutral20 : AppColor.neutral90, - enable: serviceRequestProvider.initialSelectedSparePart != null && serviceRequestProvider.initialSelectedSparePart.sparePart?.id != null, + enable: serviceRequestProvider.initialSelectedSparePart.sparePart?.id != null, validator: (value) => value == null || value.isEmpty ? context.translation.requiredField : Validator.isNumeric(value) @@ -162,15 +161,15 @@ class _SparePartRequestState extends State with TickerProvider serviceRequestProvider.initialSelectedSparePart.qty = num.tryParse(text ?? ""); }, ), - 15.height, + 12.height, AppTextFormField( controller: _oracleNoController, + labelStyle: AppTextStyles.textFieldLabelStyle, labelText: context.translation.oracleNo, textInputType: TextInputType.number, - contentPadding: EdgeInsets.symmetric(horizontal: 16.toScreenWidth, vertical: 20.toScreenHeight), showWithoutDecoration: true, backgroundColor: context.isDark ? AppColor.neutral20 : AppColor.neutral90, - enable: serviceRequestProvider.initialSelectedSparePart != null && serviceRequestProvider.initialSelectedSparePart.sparePart?.id != null, + enable: serviceRequestProvider.initialSelectedSparePart.sparePart?.id != null, validator: (value) => value == null || value.isEmpty ? context.translation.requiredField : Validator.isNumeric(value) @@ -181,9 +180,10 @@ class _SparePartRequestState extends State with TickerProvider // serviceRequestProvider.initialSelectedSparePart. = num.tryParse(text ?? ""); }, ), - 15.height, + 12.height, AppTextFormField( initialValue: _serviceReport?.comment, + labelStyle: AppTextStyles.textFieldLabelStyle, backgroundColor: context.isDark ? AppColor.neutral20 : AppColor.neutral90, labelText: context.translation.description, alignLabelWithHint: true, @@ -193,16 +193,20 @@ class _SparePartRequestState extends State with TickerProvider _serviceReport?.comment = value; }, ), - 15.height, - MultiFilesPicker(label: context.translation.attachQuotation, files: _files), + 12.height, + MultiFilesPicker(label: context.translation.attachQuotation, files: _files, + buttonIcon: 'quotation_icon'.toSvgAsset(), + buttonColor: AppColor.primary10, + ), ], ).paddingAll(16), ), 8.height, ], ), - ).expanded, - AppFilledButton( + ).paddingAll(12).expanded, + + FooterActionButton.footerContainer(child: AppFilledButton( label: context.translation.addSparePartActivity, buttonColor: AppColor.green70, onPressed: () async { @@ -230,9 +234,9 @@ class _SparePartRequestState extends State with TickerProvider // final user = Provider.of(context, listen: false).user; // await _serviceRequestsProvider.createServiceReport(context, report: _serviceReport, request: serviceRequestProvider.serviceRequest, user: user); }, - ), + )), ], - ).paddingAll(16), + ), ), ), ); 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..de594a53 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,105 @@ 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/helper_data_models/workorder/work_order_model.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/work_order/reason_provider.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/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/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 '../../../../../../controllers/providers/api/status_drop_down/report/service_report_last_calls_provider.dart'; +import 'package:test_sa/views/widgets/sound/TextSpeechRecordWidget.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(); } +//TODO remove unnecessary code 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 RequestDetailProvider _requestDetailProvider; + 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(); + _userProvider = Provider.of(context, listen: false); + _serviceRequestsProvider = Provider.of(context, listen: false); + _requestDetailProvider = Provider.of(context, listen: false); + getInitialData(); + 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, - ); - } + Future getInitialData() async { + WidgetsBinding.instance.addPostFrameCallback((_) async{ + await Provider.of(context,listen: false).getDate(); + await Provider.of(context,listen: false).getDate(); + await Provider.of(context,listen: false).getDate(); + await Provider.of(context,listen: false).getDate(); + }); + + } @override - Widget build(BuildContext context) { + void dispose() { + // TODO: implement dispose + _commentController.dispose(); + super.dispose(); + } - final List _files = []; + 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) { return Scaffold( key: _scaffoldKey, appBar: DefaultAppBar(title: context.translation.createNewRequest), @@ -85,84 +120,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.black10, + onlyImages: true, + buttonIcon: 'image-plus'.toSvgAsset(color: AppColor.neutral120), + ), + ], + ).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 +180,200 @@ 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 AppColor.primary10; + return AppColor.neutral130; + }), + groupValue: _serviceRequest.defectType, + onChanged: (state) { + setState(() { + _serviceRequest.defectType = element; + }); + }), + ), + 8.width, + Text(element.name??'', style: AppTextStyles.tinyFont.copyWith(color:AppColor.neutral120)), + ], + ) + ], + ).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('comments value is ${_serviceRequest.callComments}'); + 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())}"; + } + } + List attachement = []; + for (var url in _deviceImages) { + + } + + await _requestDetailProvider.createWorkOrder(workOrderHModel: WorkOrderHModel( + assetId: _serviceRequest.deviceId, + priorityId: _serviceRequest.priority?.id, + equipmentStatusId: _serviceRequest.defectType?.id, + voiceNote: _serviceRequest.audio, + comments: _serviceRequest.callComments, + //add attachments also... + )); + + // 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 0c242b85..5e6a7249 100644 --- a/lib/service_request_latest/views/request_detail_main_view.dart +++ b/lib/service_request_latest/views/request_detail_main_view.dart @@ -16,6 +16,7 @@ import 'components/request_detail_view.dart'; class RequestDetailMain extends StatefulWidget { final int requestId; + const RequestDetailMain({Key? key, required this.requestId}) : super(key: key); RequestDetailMain({Key? key, required this.requestId}) : super(key: key); @@ -76,7 +77,7 @@ class _RequestDetailMainState extends State { ), ), 12.height, - TabBarView( + TabBarView( children: [ WorkOrderDetailView(), // RequestDetailView( diff --git a/lib/views/pages/user/requests/service_request_details.dart b/lib/views/pages/user/requests/service_request_details.dart index 6e642c8f..ce3ad62c 100644 --- a/lib/views/pages/user/requests/service_request_details.dart +++ b/lib/views/pages/user/requests/service_request_details.dart @@ -49,6 +49,7 @@ class _ServiceRequestDetailsPageState extends State { WidgetsFlutterBinding.ensureInitialized().addPostFrameCallback((timeStamp) async { Provider.of(context, listen: false).reset(); serviceRequest = await Provider.of(context, listen: false).getServiceRequestObjectById(requestId: widget.serviceRequest.id!); + print('service request i got is ${serviceRequest?.id}'); loading = false; setState(() {}); }); 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)), ], ), ],