From d181c8102962018c3134c4a1017ff870946d495e Mon Sep 17 00:00:00 2001 From: WaseemAbbasi22 Date: Thu, 6 Feb 2025 09:23:21 +0300 Subject: [PATCH] save and complete api integrated for recurrent task --- lib/controllers/api_routes/urls.dart | 3 +- .../providers/api/all_requests_provider.dart | 62 ++++- lib/extensions/enum_extensions.dart | 15 + .../recurrent_task_inspection_data_type.dart | 4 + lib/models/ppm/recurrent_wo.dart | 257 +++++++++--------- lib/new_views/app_style/app_color.dart | 2 + .../requests/recurrent_wo_item_view.dart | 8 +- .../components/internal_request.dart | 1 + .../maintenance_request_main.dart | 6 - .../components/asset_info_widget.dart | 125 +++++---- .../components/room_inspection_card.dart | 123 ++++++--- .../components/room_tabs_widget.dart | 76 +++--- .../recurrent_work_order_view.dart | 176 ++++++------ 13 files changed, 498 insertions(+), 360 deletions(-) create mode 100644 lib/models/enums/recurrent_task_inspection_data_type.dart diff --git a/lib/controllers/api_routes/urls.dart b/lib/controllers/api_routes/urls.dart index b1959cfc..b40f11c2 100644 --- a/lib/controllers/api_routes/urls.dart +++ b/lib/controllers/api_routes/urls.dart @@ -80,8 +80,9 @@ class URLs { static get swipeUrl=> '$_baseUrl/Swipe/Swipe'; static get getSwipeLastTransactionUrl=> '$_baseUrl/Swipe/GetLastTransaction'; static get getSwipeTransactionHistoryUrl=> '$_baseUrl/Swipe/GetTransactions'; - static get getRecurrentPlanByIdUrl=> '$_baseUrl/PlanRecurrentTasks/GetPlanRecurrentTaskById'; //Recurrent plan Api... + static get getRecurrentPlanByIdUrl=> '$_baseUrl/PlanRecurrentTasks/GetPlanRecurrentTaskById'; + static get updateRecurrentPlanUrl=> '$_baseUrl/PlanRecurrentTasks/UpdateTaskByEngineer'; //service request..... diff --git a/lib/controllers/providers/api/all_requests_provider.dart b/lib/controllers/providers/api/all_requests_provider.dart index 88cf8f95..ca8801b2 100644 --- a/lib/controllers/providers/api/all_requests_provider.dart +++ b/lib/controllers/providers/api/all_requests_provider.dart @@ -8,6 +8,7 @@ import 'package:test_sa/extensions/context_extension.dart'; import 'package:test_sa/models/all_requests_and_count_model.dart'; import 'package:test_sa/models/enums/user_types.dart'; import 'package:test_sa/models/ppm/recurrent_wo.dart'; +import 'package:test_sa/models/timer_model.dart'; import '../../../models/search_all_requests_model.dart'; @@ -19,6 +20,8 @@ class AllRequestsProvider extends ChangeNotifier { bool isOverdueLoading = false; bool isHighPriorityLoading = false; bool isCalendarLoading = false; + bool isLoading = false; + bool _isFilterRequestLoading = false; bool _isRequestCategoryLoading = false; @@ -50,12 +53,24 @@ class AllRequestsProvider extends ChangeNotifier { AllRequestsAndCount? _requestDetailList; AllRequestsAndCount? get allRequestsAndCount => _allRequestsAndCount; + AllRequestsAndCount? get highPriorityRequests => _highPriorityRequests; + AllRequestsAndCount? get overdueRequests => _overdueRequests; + // AllRequestsAndCount? get openRequests => _openRequests; // AllRequestsAndCount? get completedRequests => _completedRequests; AllRequestsAndCount? get requestDetailList => _requestDetailList; + RecurrentWoData? _recurrentWoData; + + RecurrentWoData? get recurrentWoData => _recurrentWoData; + + set recurrentWoData(RecurrentWoData? value) { + _recurrentWoData = value; + notifyListeners(); + } + set requestDetailList(AllRequestsAndCount? value) { _requestDetailList = value; notifyListeners(); @@ -117,10 +132,9 @@ class AllRequestsProvider extends ChangeNotifier { SearchAllRequestsModel? searchedModel; Future getAllRequests(BuildContext context, {int? typeTransaction, SearchAllRequestsModel? search}) async { - print('loading value is $isAllLoading'); if (isAllLoading == true) return -2; isAllLoading = true; - if (_allRequestsAndCount == null) notifyListeners(); + if (_allRequestsAndCount == null) notifyListeners(); Response response; try { if (search != null) { @@ -130,7 +144,7 @@ class AllRequestsProvider extends ChangeNotifier { } final type = typeTransaction == null ? search?.typeTransaction == null || (search?.typeTransaction?.isEmpty ?? false) - ? [1, 2, 3, 4,5]//added 5 to get recurrent wo ... + ? [1, 2, 3, 4, 5] //added 5 to get recurrent wo ... : search!.typeTransaction : [typeTransaction]; List status = (search?.statuses == null || (search?.statuses?.isEmpty ?? false)) ? (((search?.isArchived ?? false) ? [3] : [1, 2, 4])) : search!.statuses!; @@ -179,23 +193,51 @@ class AllRequestsProvider extends ChangeNotifier { } } - Future getRecurrentWoById(BuildContext context, {required int id}) async { + Future getRecurrentWoById({required int id}) async { + isLoading = true; Response response; try { response = await ApiManager.instance.get(URLs.getRecurrentPlanByIdUrl + "?planRecurrentTaskId=$id"); + stateCode = response.statusCode; + if (response.statusCode >= 200 && response.statusCode < 300) { + recurrentWoData = RecurrentWoData.fromJson(json.decode(response.body)["data"]); + notifyListeners(); + } + isLoading = false; + notifyListeners(); + return response.statusCode; } catch (error) { - throw (context.translation.failedToCompleteRequest); + isLoading = false; + stateCode = -1; + notifyListeners(); + return -1; } - if (response.statusCode >= 200 && response.statusCode < 300) { - RecurrentWo recurrentWo = RecurrentWo.fromJson(json.decode(response.body)); - return recurrentWo; + } - } else { - throw (("${context.translation.failedToCompleteRequest} ${jsonDecode(response.body)["message"]}")); + Future updateRecurrentWo({required int status}) async { + isLoading = true; + Response response; + try { + response = await ApiManager.instance.post(URLs.updateRecurrentPlanUrl, body: recurrentWoData!.toJson(status: status)); + print('response i got back is ${response.body}'); + stateCode = response.statusCode; + isLoading = false; + notifyListeners(); + return response.statusCode; + } catch (error) { + isLoading = false; + stateCode = -1; + notifyListeners(); + return -1; } } + void updateRecurrentWoTimer({TimerModel? timer}) { + recurrentWoData?.recurrentWoTimerModel = timer; + notifyListeners(); + } + Future getCalendarRequests({required DateTime from, DateTime? to}) async { if (isCalendarLoading == true) return -2; isCalendarLoading = true; diff --git a/lib/extensions/enum_extensions.dart b/lib/extensions/enum_extensions.dart index 0325affb..c6d10640 100644 --- a/lib/extensions/enum_extensions.dart +++ b/lib/extensions/enum_extensions.dart @@ -1,4 +1,5 @@ import 'package:test_sa/app_strings/app_asset.dart'; +import 'package:test_sa/models/enums/recurrent_task_inspection_data_type.dart'; import 'package:test_sa/models/enums/swipe_type.dart'; import 'package:test_sa/models/enums/work_order_next_step.dart'; @@ -94,6 +95,8 @@ extension IntExtensionsWorkOrder on int { } } + + extension EnumExtensionsSwipeType on SwipeTypeEnum { int getIntFromSwipeTypeEnum() { switch (this) { @@ -106,3 +109,15 @@ extension EnumExtensionsSwipeType on SwipeTypeEnum { } } } +extension StringExtensionsRecurrentTaskInpesctionDataType on String { + RecurrentTaskInspectionDataTypeEnum toRecurrentTaskInspectionDataTypeEnum() { + switch (this) { + case 'bool': + return RecurrentTaskInspectionDataTypeEnum.bool; + case 'number': + return RecurrentTaskInspectionDataTypeEnum.number; + default: + return RecurrentTaskInspectionDataTypeEnum.bool; + } + } +} diff --git a/lib/models/enums/recurrent_task_inspection_data_type.dart b/lib/models/enums/recurrent_task_inspection_data_type.dart new file mode 100644 index 00000000..478f780f --- /dev/null +++ b/lib/models/enums/recurrent_task_inspection_data_type.dart @@ -0,0 +1,4 @@ +enum RecurrentTaskInspectionDataTypeEnum { + bool, //bool + number, // number +} diff --git a/lib/models/ppm/recurrent_wo.dart b/lib/models/ppm/recurrent_wo.dart index 19d5d233..0fcc44c9 100644 --- a/lib/models/ppm/recurrent_wo.dart +++ b/lib/models/ppm/recurrent_wo.dart @@ -1,3 +1,5 @@ +import 'package:test_sa/extensions/enum_extensions.dart'; +import 'package:test_sa/models/enums/recurrent_task_inspection_data_type.dart'; import 'package:test_sa/models/lookup.dart'; import 'package:test_sa/models/timer_model.dart'; @@ -9,16 +11,10 @@ class RecurrentWo { int? responseCode; bool? isSuccess; - RecurrentWo( - {this.recurrentWoData, - this.message, - this.title, - this.innerMessage, - this.responseCode, - this.isSuccess}); + RecurrentWo({this.recurrentWoData, this.message, this.title, this.innerMessage, this.responseCode, this.isSuccess}); RecurrentWo.fromJson(Map json) { - recurrentWoData = json['data'] != null ? RecurrentWoData.fromJson(json['data']) : null; + recurrentWoData = json['data'] != null ? RecurrentWoData.fromJson(json['data']) : null; message = json['message']; title = json['title']; innerMessage = json['innerMessage']; @@ -27,7 +23,7 @@ class RecurrentWo { } Map toJson() { - final Map data = {}; + final Map data = {}; if (recurrentWoData != null) { data['data'] = recurrentWoData!.toJson(); } @@ -51,75 +47,74 @@ class RecurrentWoData { Lookup? department; Lookup? room; List? planRecurrentMedicalTaskRooms; - List? planRecurrentTaskTimers; + List? planRecurrentTaskTimers; TimerModel? recurrentWoTimerModel = TimerModel(); + double? totalWorkingHours=0.0; RecurrentWoData( {this.id, - this.engineer, - this.scheduleDate, - this.status, - this.site, - this.building, - this.recurrentWoTimerModel, - this.floor, - this.department, - this.room, - this.planRecurrentMedicalTaskRooms, - this.planRecurrentTaskTimers}); + this.engineer, + this.scheduleDate, + this.status, + this.site, + this.building, + this.recurrentWoTimerModel, + this.floor, + this.department, + this.room, + this.planRecurrentMedicalTaskRooms, + this.planRecurrentTaskTimers, + this.totalWorkingHours}); RecurrentWoData.fromJson(Map json) { id = json['id']; - engineer = json['engineer'] != null - ? new Engineer.fromJson(json['engineer']) - : null; + engineer = json['engineer'] != null ? new Engineer.fromJson(json['engineer']) : null; scheduleDate = json['scheduleDate']; - status = - json['status'] != null ? Status.fromJson(json['status']) : null; + status = json['status'] != null ? Status.fromJson(json['status']) : null; site = json['site'] != null ? Site.fromJson(json['site']) : null; - building= json["building"] == null ? null : Lookup.fromJson(json["building"]); - floor= json["floor"] == null ? null : Lookup.fromJson(json["floor"]); - department= json["department"] == null ? null : Lookup.fromJson(json["department"]); - room= json["room"] == null ? null : Lookup.fromJson(json["room"]); + building = json["building"] == null ? null : Lookup.fromJson(json["building"]); + floor = json["floor"] == null ? null : Lookup.fromJson(json["floor"]); + department = json["department"] == null ? null : Lookup.fromJson(json["department"]); + room = json["room"] == null ? null : Lookup.fromJson(json["room"]); if (json['planRecurrentMedicalTaskRooms'] != null) { planRecurrentMedicalTaskRooms = []; json['planRecurrentMedicalTaskRooms'].forEach((v) { - planRecurrentMedicalTaskRooms! - .add(PlanRecurrentMedicalTaskRooms.fromJson(v)); + planRecurrentMedicalTaskRooms!.add(PlanRecurrentMedicalTaskRooms.fromJson(v)); }); } if (json['planRecurrentTaskTimers'] != null) { - //TODO match with exact data and replace... - // planRecurrentTaskTimers = []; - // json['planRecurrentTaskTimers'].forEach((v) { - // planRecurrentTaskTimers!.add(new Null.fromJson(v)); - // }); + planRecurrentTaskTimers = []; + json['planRecurrentTaskTimers'].forEach((v) { + planRecurrentTaskTimers?.add(PlanRecurrentTaskTimers.fromJson(v)); + }); + totalWorkingHours = json['planRecurrentTaskTimers'].fold(0.0, (sum, item) => (sum ?? 0) + DateTime.parse(item.endTime!).difference(DateTime.parse(item.startTime!)).inSeconds) ?? 0; } } - Map toJson() { + Map toJson({int? status = 0}) { final Map data = {}; + List taskRoomTabAttributesJson = []; + if (planRecurrentMedicalTaskRooms != null) { + taskRoomTabAttributesJson = planRecurrentMedicalTaskRooms + ?.expand((room) => room.planRecurrentMedicalTaskRoomTabs ?? []) + .expand((tab) => tab.planRecurrentMedicalTaskRoomTabAttributes ?? []) + .map((attribute) => attribute.toJson()) + .toList() ?? + []; + } data['id'] = id; - if (engineer != null) { - data['engineer'] = engineer!.toJson(); + data['statusValue'] = status; + + if (planRecurrentTaskTimers != null) { + data['planRecurrentTaskTimers'] = planRecurrentTaskTimers!.map((v) => v.toJson()).toList(); } - data['scheduleDate'] = scheduleDate; - if (status != null) { - data['status'] = status!.toJson(); + if (taskRoomTabAttributesJson.isNotEmpty) { + data['attributes'] = taskRoomTabAttributesJson; } - if (site != null) { - data['site'] = site!.toJson(); + else{ + data['attributes'] = []; } - if (planRecurrentMedicalTaskRooms != null) { - data['planRecurrentMedicalTaskRooms'] = - planRecurrentMedicalTaskRooms!.map((v) => v.toJson()).toList(); - } - if (planRecurrentTaskTimers != null) { - //TODO match with exact data and replace... - // data['planRecurrentTaskTimers'] = - // this.planRecurrentTaskTimers!.map((v) => v.toJson()).toList(); - } return data; } } @@ -131,12 +126,7 @@ class Engineer { String? employeeId; int? languageId; - Engineer( - {this.userId, - this.userName, - this.email, - this.employeeId, - this.languageId}); + Engineer({this.userId, this.userName, this.email, this.employeeId, this.languageId}); Engineer.fromJson(Map json) { userId = json['userId']; @@ -147,12 +137,12 @@ class Engineer { } Map toJson() { - final Map data = new Map(); - data['userId'] = this.userId; - data['userName'] = this.userName; - data['email'] = this.email; - data['employeeId'] = this.employeeId; - data['languageId'] = this.languageId; + final Map data = {}; + data['userId'] = userId; + data['userName'] = userName; + data['email'] = email; + data['employeeId'] = employeeId; + data['languageId'] = languageId; return data; } } @@ -171,10 +161,10 @@ class Status { } Map toJson() { - final Map data = new Map(); - data['id'] = this.id; - data['name'] = this.name; - data['value'] = this.value; + final Map data = {}; + data['id'] = id; + data['name'] = name; + data['value'] = value; return data; } } @@ -191,9 +181,9 @@ class Site { } Map toJson() { - final Map data = new Map(); - data['id'] = this.id; - data['siteName'] = this.siteName; + final Map data = {}; + data['id'] =id; + data['siteName'] = siteName; return data; } } @@ -203,32 +193,27 @@ class PlanRecurrentMedicalTaskRooms { Room? room; List? planRecurrentMedicalTaskRoomTabs; - PlanRecurrentMedicalTaskRooms( - {this.id, this.room, this.planRecurrentMedicalTaskRoomTabs}); + PlanRecurrentMedicalTaskRooms({this.id, this.room, this.planRecurrentMedicalTaskRoomTabs}); PlanRecurrentMedicalTaskRooms.fromJson(Map json) { id = json['id']; - room = json['room'] != null ? new Room.fromJson(json['room']) : null; + room = json['room'] != null ? Room.fromJson(json['room']) : null; if (json['planRecurrentMedicalTaskRoomTabs'] != null) { planRecurrentMedicalTaskRoomTabs = []; json['planRecurrentMedicalTaskRoomTabs'].forEach((v) { - planRecurrentMedicalTaskRoomTabs! - .add(new PlanRecurrentMedicalTaskRoomTabs.fromJson(v)); + planRecurrentMedicalTaskRoomTabs!.add(PlanRecurrentMedicalTaskRoomTabs.fromJson(v)); }); } } Map toJson() { - final Map data = new Map(); - data['id'] = this.id; - if (this.room != null) { - data['room'] = this.room!.toJson(); + final Map data = {}; + data['id'] = id; + if (room != null) { + data['room'] = room!.toJson(); } - if (this.planRecurrentMedicalTaskRoomTabs != null) { - data['planRecurrentMedicalTaskRoomTabs'] = this - .planRecurrentMedicalTaskRoomTabs! - .map((v) => v.toJson()) - .toList(); + if (planRecurrentMedicalTaskRoomTabs != null) { + data['planRecurrentMedicalTaskRoomTabs'] = planRecurrentMedicalTaskRoomTabs!.map((v) => v.toJson()).toList(); } return data; } @@ -246,9 +231,9 @@ class Room { } Map toJson() { - final Map data = new Map(); - data['id'] = this.id; - data['roomId'] = this.roomId; + final Map data = {}; + data['id'] = id; + data['roomId'] = roomId; return data; } } @@ -257,39 +242,29 @@ class PlanRecurrentMedicalTaskRoomTabs { int? id; String? tabName; int? tabMedicalRoomId; - List? - planRecurrentMedicalTaskRoomTabAttributes; + List? planRecurrentMedicalTaskRoomTabAttributes; - PlanRecurrentMedicalTaskRoomTabs( - {this.id, - this.tabName, - this.tabMedicalRoomId, - this.planRecurrentMedicalTaskRoomTabAttributes}); + PlanRecurrentMedicalTaskRoomTabs({this.id, this.tabName, this.tabMedicalRoomId, this.planRecurrentMedicalTaskRoomTabAttributes}); PlanRecurrentMedicalTaskRoomTabs.fromJson(Map json) { id = json['id']; tabName = json['tabName']; tabMedicalRoomId = json['tabMedicalRoomId']; if (json['planRecurrentMedicalTaskRoomTabAttributes'] != null) { - planRecurrentMedicalTaskRoomTabAttributes = - []; + planRecurrentMedicalTaskRoomTabAttributes = []; json['planRecurrentMedicalTaskRoomTabAttributes'].forEach((v) { - planRecurrentMedicalTaskRoomTabAttributes! - .add(new PlanRecurrentMedicalTaskRoomTabAttributes.fromJson(v)); + planRecurrentMedicalTaskRoomTabAttributes!.add( PlanRecurrentMedicalTaskRoomTabAttributes.fromJson(v)); }); } } Map toJson() { - final Map data = new Map(); - data['id'] = this.id; - data['tabName'] = this.tabName; - data['tabMedicalRoomId'] = this.tabMedicalRoomId; - if (this.planRecurrentMedicalTaskRoomTabAttributes != null) { - data['planRecurrentMedicalTaskRoomTabAttributes'] = this - .planRecurrentMedicalTaskRoomTabAttributes! - .map((v) => v.toJson()) - .toList(); + final Map data = {}; + data['id'] = id; + data['tabName'] = tabName; + data['tabMedicalRoomId'] = tabMedicalRoomId; + if (planRecurrentMedicalTaskRoomTabAttributes != null) { + data['planRecurrentMedicalTaskRoomTabAttributes'] = planRecurrentMedicalTaskRoomTabAttributes!.map((v) => v.toJson()).toList(); } return data; } @@ -298,27 +273,20 @@ class PlanRecurrentMedicalTaskRoomTabs { class PlanRecurrentMedicalTaskRoomTabAttributes { int? id; Attribute? attribute; - Null? attributeValue; + dynamic attributeValue; - PlanRecurrentMedicalTaskRoomTabAttributes( - {this.id, this.attribute, this.attributeValue}); + PlanRecurrentMedicalTaskRoomTabAttributes({this.id, this.attribute, this.attributeValue}); - PlanRecurrentMedicalTaskRoomTabAttributes.fromJson( - Map json) { + PlanRecurrentMedicalTaskRoomTabAttributes.fromJson(Map json) { id = json['id']; - attribute = json['attribute'] != null - ? new Attribute.fromJson(json['attribute']) - : null; - attributeValue = json['attributeValue']; + attribute = json['attribute'] != null ? Attribute.fromJson(json['attribute']) : null; + attributeValue = json['attributeValue'] ?? (json['attribute']['type'] == 'bool' ? (json['attributeValue']?.toString() == 'true') : json['attributeValue']); } Map toJson() { - final Map data = new Map(); - data['id'] = this.id; - if (this.attribute != null) { - data['attribute'] = this.attribute!.toJson(); - } - data['attributeValue'] = this.attributeValue; + final Map data = {}; + data['id'] = id; + data['attributeValue'] =attributeValue!=null? attributeValue.toString():attributeValue; return data; } } @@ -327,20 +295,47 @@ class Attribute { String? name; String? type; String? key; + RecurrentTaskInspectionDataTypeEnum? dataTypeEnum; - Attribute({this.name, this.type, this.key}); + Attribute({this.name, this.type, this.key, this.dataTypeEnum}); Attribute.fromJson(Map json) { name = json['name']; type = json['type']; + dataTypeEnum = json['type'] == null ? null : (json['type'] as String).toRecurrentTaskInspectionDataTypeEnum(); key = json['key']; } Map toJson() { - final Map data = new Map(); - data['name'] = this.name; - data['type'] = this.type; - data['key'] = this.key; + final Map data = {}; + data['name'] = name; + data['type'] = type; + data['key'] = key; + return data; + } +} + +class PlanRecurrentTaskTimers { + int? id; + String? startTime; + String? endTime; + dynamic workingHours; + + PlanRecurrentTaskTimers({this.id, this.startTime, this.endTime, this.workingHours}); + + PlanRecurrentTaskTimers.fromJson(Map json) { + id = json['id']; + startTime = json['startTime']; + endTime = json['endTime']; + workingHours = json['workingHours']; + } + + Map toJson() { + final Map data = {}; + data['id'] = id; + data['startTime'] = startTime; + data['endTime'] = endTime; + data['workingHours'] = workingHours; return data; } -} \ No newline at end of file +} diff --git a/lib/new_views/app_style/app_color.dart b/lib/new_views/app_style/app_color.dart index 448d1950..8ccc5700 100644 --- a/lib/new_views/app_style/app_color.dart +++ b/lib/new_views/app_style/app_color.dart @@ -60,10 +60,12 @@ class AppColor { static const Color red50 = Color(0xffD02127); static const Color red60 = Color(0xff8C050A); static const Color red70 = Color(0xffF63939); + static const Color red80 = Color(0xfffdcdcd); //green static const Color green40 = Color(0xffBAFFE1); static const Color green50 = Color(0xff62BE96); + static const Color green30 = Color(0xffd8efe5); static const Color green60 = Color(0xff065E38); static const Color green70 = Color(0xff54C166); static const Color green15 = Color(0xff157D14); diff --git a/lib/new_views/pages/land_page/requests/recurrent_wo_item_view.dart b/lib/new_views/pages/land_page/requests/recurrent_wo_item_view.dart index 0f4abfdb..3d8b7c42 100644 --- a/lib/new_views/pages/land_page/requests/recurrent_wo_item_view.dart +++ b/lib/new_views/pages/land_page/requests/recurrent_wo_item_view.dart @@ -67,13 +67,9 @@ class RecurrentWoItemView extends StatelessWidget { ), ], ).toShadowContainer(context, withShadow: showShadow).onPress(() async { - print('data i got is ${requestDetails?.id}'); - - RecurrentWo recurrentWo = await Provider.of(context,listen:false).getRecurrentWoById(context, id: requestDetails!.id!); - Navigator.of(context).push(MaterialPageRoute(builder: (_) => RecurrentWorkOrderView( recurrentWo: recurrentWo))); - + Navigator.of(context).push(MaterialPageRoute(builder: (_) => RecurrentWorkOrderView(taskId: requestDetails!.id))); }); } - return SizedBox(); + return const SizedBox(); } } 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 e8043355..118fa3ce 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 @@ -101,6 +101,7 @@ class _InternalMaintenanceRequestState extends State print("timerProgress:$isRunning"); }, onChange: (timer) async { + requestDetailProvider.activityMaintenanceHelperModel?.activityMaintenanceTimerModel = timer; return true; }, 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 3cc8a907..ad7b8a3c 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 @@ -101,12 +101,6 @@ class _MaintenanceRequestFormState extends State with Si if (validate(model: requestDetailProvider.activityMaintenanceHelperModel!)) { - ActivityMaintenanceTimers model = ActivityMaintenanceTimers( - id: 0, - startTime: requestDetailProvider.activityMaintenanceHelperModel?.activityMaintenanceTimerModel?.startAt!.toIso8601String(), // Handle potential null - endTime: requestDetailProvider.activityMaintenanceHelperModel?.activityMaintenanceTimerModel?.endAt?.toIso8601String(), // Handle potential null - workingHours: ((requestDetailProvider.activityMaintenanceHelperModel?.activityMaintenanceTimerModel?.durationInSecond ?? 0) / 60 / 60), - ); requestDetailProvider.activityMaintenanceHelperModel?.activityMaintenanceTimers =requestDetailProvider.activityMaintenanceHelperModel?.activityMaintenanceTimers??[]; requestDetailProvider.activityMaintenanceHelperModel?.activityMaintenanceTimers?.add( ActivityMaintenanceTimers( diff --git a/lib/views/pages/user/ppm/ppm_work_order/recurrent_wo/components/asset_info_widget.dart b/lib/views/pages/user/ppm/ppm_work_order/recurrent_wo/components/asset_info_widget.dart index 1257bf88..343d5e31 100644 --- a/lib/views/pages/user/ppm/ppm_work_order/recurrent_wo/components/asset_info_widget.dart +++ b/lib/views/pages/user/ppm/ppm_work_order/recurrent_wo/components/asset_info_widget.dart @@ -1,4 +1,6 @@ import 'package:flutter/material.dart'; +import 'package:provider/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/int_extensions.dart'; import 'package:test_sa/extensions/string_extensions.dart'; @@ -13,15 +15,14 @@ import 'package:test_sa/service_request_latest/utilities/service_request_utils.d import 'package:test_sa/views/widgets/requests/request_status.dart'; import 'package:test_sa/views/widgets/timer/app_timer.dart'; -class AssetInfoWidget extends StatelessWidget { +class RecurrentTaskAssetInfoWidget extends StatelessWidget { + final RecurrentWoData? model; - final RecurrentWoData? model; // Use `final` since it's a StatelessWidget - - AssetInfoWidget({super.key, required this.model}); + RecurrentTaskAssetInfoWidget({super.key, required this.model}); @override Widget build(BuildContext context) { - double totalWorkingHours = 2.0; + return Column( mainAxisSize: MainAxisSize.min, children: [ @@ -32,54 +33,72 @@ class AssetInfoWidget extends StatelessWidget { if (model?.status != null) StatusLabel( label: model?.status?.name, - textColor: AppColor.getRequestStatusTextColorByName(context,model?.status?.name), - backgroundColor: AppColor.getRequestStatusColorByName(context,model?.status?.name), + textColor: AppColor.getRequestStatusTextColorByName(context, model?.status?.name), + backgroundColor: AppColor.getRequestStatusColorByName(context, model?.status?.name), ), 8.height, -// TODO need to replace this with correct data... - model!.site!.siteName!.bodyText(context).custom(color:AppColor.black10 ), + model!.site!.siteName!.bodyText(context).custom(color: AppColor.black10), 2.height, - '${context.translation.taskNo}: ${model!.site!.id!}'.bodyText2(context).custom(color: AppColor.neutral120), + '${context.translation.taskNo}: ${model!.id!}'.bodyText2(context).custom(color: AppColor.neutral120), '${context.translation.site}: ${model!.site!.siteName!}'.bodyText2(context).custom(color: AppColor.neutral120), - '${context.translation.assignEngineer}: ${model!.engineer!.userName ?? ""}'.bodyText2(context).custom(color: AppColor.neutral120), + '${context.translation.assignEngineer}: ${model!.engineer!.userName ?? ""}'.bodyText2(context).custom(color: AppColor.neutral120), '${context.translation.scheduledDate}: ${model!.scheduleDate!.toMonthYearFormat}'.bodyText2(context).custom(color: AppColor.neutral120), ], ).toShadowContainer(context), 12.height, - model!.planRecurrentMedicalTaskRooms!.isEmpty? Column( - mainAxisSize: MainAxisSize.min, - crossAxisAlignment: CrossAxisAlignment.start, + model!.planRecurrentMedicalTaskRooms!.isEmpty + ? Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + buildingInfoWidget(label: context.translation.department, value: model!.department!.name!.cleanupWhitespace.capitalizeFirstOfEach, context: context), + 8.height, + buildingInfoWidget(label: context.translation.floor, value: model!.floor!.name!.cleanupWhitespace.capitalizeFirstOfEach, context: context), + 8.height, + buildingInfoWidget(label: context.translation.room, value: model!.room!.name!.cleanupWhitespace.capitalizeFirstOfEach, context: context), + 8.height, + _timerWidget(context, model!.totalWorkingHours!) + ], + // ], + ).toShadowContainer(context, padding: 12) + : _timerWidget(context, model!.totalWorkingHours!).toShadowContainer(context, padding: 12), + ], + ); + } + + Widget _timerWidget(BuildContext context, double totalWorkingHours) { + return Consumer( + + builder: (context, snapshot,child) { + return Column( children: [ - buildingInfoWidget(label: context.translation.department, value: model!.department!.name!.cleanupWhitespace.capitalizeFirstOfEach,context: context), - 8.height, - buildingInfoWidget(label: context.translation.floor, value: model!.floor!.name!.cleanupWhitespace.capitalizeFirstOfEach,context: context), - 8.height, - buildingInfoWidget(label: context.translation.room, value: model!.room!.name!.cleanupWhitespace.capitalizeFirstOfEach,context: context), - 8.height, AppTimer( label: context.translation.timer, - timer: model!.recurrentWoTimerModel, - width:double.infinity, - enabled: model!.recurrentWoTimerModel?.endAt == null, + timer: snapshot.recurrentWoData?.recurrentWoTimerModel, + width: double.infinity, + enabled: snapshot.recurrentWoData?.recurrentWoTimerModel?.endAt == null, decoration: BoxDecoration( color: AppColor.neutral100, borderRadius: BorderRadius.circular(10), ), timerProgress: (isRunning) {}, onChange: (timer) async { - timer = timer; + snapshot.updateRecurrentWoTimer(timer: timer); return true; }, ), - // if (totalWorkingHours > 0.0) ...[ 11.height, + if (totalWorkingHours > 0.0) ...[ Row( crossAxisAlignment: CrossAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.start, children: [ Text( "Total Working Time: ", - style: Theme.of(context).textTheme.bodySmall?.copyWith(color: context.isDark ? null : AppColor.neutral20, fontWeight: FontWeight.w500), + style: Theme.of(context).textTheme.bodySmall?.copyWith( + color: context.isDark ? null : AppColor.neutral20, + fontWeight: FontWeight.w500, + ), ), Text( " ${ServiceRequestUtils.formatTimerDuration(totalWorkingHours.round())}", @@ -87,39 +106,39 @@ class AssetInfoWidget extends StatelessWidget { ), ], ), + ], 8.height, ], - // ], - ).toShadowContainer(context,padding: 12):const SizedBox(), - ], + ); + } ); } +} - Widget buildingInfoWidget({required String label, required String value, required BuildContext context}) { - return Column( - mainAxisAlignment: MainAxisAlignment.start, - crossAxisAlignment: CrossAxisAlignment.start, - mainAxisSize: MainAxisSize.min, - children: [ - Text( - label, - style: AppTextStyles.textFieldLabelStyle.copyWith(color: AppColor.neutral120), - ), - 3.height, - Text( - value, - style: AppTextStyles.bodyText2.copyWith(color: AppColor.black10), - ) - ], - ).toShadowContainer(context, backgroundColor: AppColor.neutral100, borderRadius: 10, paddingObject: EdgeInsets.all(12.toScreenHeight), showShadow: false); - } +Widget buildingInfoWidget({required String label, required String value, required BuildContext context}) { + return Column( + mainAxisAlignment: MainAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisSize: MainAxisSize.min, + children: [ + Text( + label, + style: AppTextStyles.textFieldLabelStyle.copyWith(color: AppColor.neutral120), + ), + 3.height, + Text( + value, + style: AppTextStyles.bodyText2.copyWith(color: AppColor.black10), + ) + ], + ).toShadowContainer(context, backgroundColor: AppColor.neutral100, borderRadius: 10, paddingObject: EdgeInsets.all(12.toScreenHeight), showShadow: false); } -class DummyModel{ - RequestsDetails? request; - Ppm? ppm; - TimerModel? timerModel = TimerModel(); - double totalWorkingHours = 2; +class DummyModel { + RequestsDetails? request; + Ppm? ppm; + TimerModel? timerModel = TimerModel(); + double totalWorkingHours = 2; - DummyModel(this.request,this.ppm,this.timerModel,this.totalWorkingHours); + DummyModel(this.request, this.ppm, this.timerModel, this.totalWorkingHours); } diff --git a/lib/views/pages/user/ppm/ppm_work_order/recurrent_wo/components/room_inspection_card.dart b/lib/views/pages/user/ppm/ppm_work_order/recurrent_wo/components/room_inspection_card.dart index 09334adb..56dd7470 100644 --- a/lib/views/pages/user/ppm/ppm_work_order/recurrent_wo/components/room_inspection_card.dart +++ b/lib/views/pages/user/ppm/ppm_work_order/recurrent_wo/components/room_inspection_card.dart @@ -1,10 +1,13 @@ import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; import 'package:test_sa/dashboard_latest/dashboard_view.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/recurrent_task_inspection_data_type.dart'; import 'package:test_sa/models/ppm/recurrent_wo.dart'; import 'package:test_sa/new_views/app_style/app_color.dart'; +import 'package:test_sa/new_views/common_widgets/app_text_form_field.dart'; class RoomInspectionCard extends StatefulWidget { final PlanRecurrentMedicalTaskRoomTabs? inspectionModel; @@ -16,14 +19,11 @@ class RoomInspectionCard extends StatefulWidget { } class _RoomInspectionCardState extends State { - late List inspectionValues; // Add a list to store the state of switches + late List inspectionValues; @override void initState() { super.initState(); - inspectionValues = widget.inspectionModel!.planRecurrentMedicalTaskRoomTabAttributes! - .map((inspectionType) => inspectionType.attributeValue != null) - .toList(); } @override @@ -31,20 +31,30 @@ class _RoomInspectionCardState extends State { return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - widget.inspectionModel!.tabName! - .bodyText(context) - .custom(color: AppColor.neutral50, fontWeight: FontWeight.w600), + widget.inspectionModel!.tabName!.bodyText(context).custom(color: AppColor.neutral50, fontWeight: FontWeight.w600), 8.height, Column( - children: widget.inspectionModel!.planRecurrentMedicalTaskRoomTabAttributes - ?.asMap() - .entries - .map((entry) => inspectionStatusRadioWidget( - index: entry.key, - label: entry.value.attribute!.name??'', - context: context, - )) - .toList() ?? + children: widget.inspectionModel!.planRecurrentMedicalTaskRoomTabAttributes?.asMap().entries.map((entry) { + final model = entry.value; + final attribute = model.attribute; + + switch (attribute?.dataTypeEnum) { + case RecurrentTaskInspectionDataTypeEnum.bool: + return inspectionStatusRadioWidget( + index: entry.key, + model: model, + context: context, + ); + case RecurrentTaskInspectionDataTypeEnum.number: + return inspectionStatusNumberWidget( + index: entry.key, + model: model, + context: context, + ); + default: + return const SizedBox.shrink(); // Handles any unexpected cases gracefully + } + }).toList() ?? [], ) ], @@ -53,39 +63,80 @@ class _RoomInspectionCardState extends State { Widget inspectionStatusRadioWidget({ required int index, - required String label, + required PlanRecurrentMedicalTaskRoomTabAttributes model, required BuildContext context, }) { - String status = inspectionValues[index] ? 'Pass' : 'Fail'; + bool status = model.attributeValue; + String statusString = status ? 'Pass' : 'Fail'; + return Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, + crossAxisAlignment: CrossAxisAlignment.center, children: [ Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - label - .bodyText2(context) - .custom(color: AppColor.white936, fontWeight: FontWeight.w500), - status - .bodyText2(context) - .custom(color: AppColor.neutral120, fontWeight: FontWeight.w500), + model.attribute!.name!.bodyText2(context).custom(color: AppColor.white936, fontWeight: FontWeight.w500), + statusString.bodyText2(context).custom(color: AppColor.neutral120, fontWeight: FontWeight.w500), ], ), - CupertinoSwitch( - thumbColor: - inspectionValues[index] ? AppColor.green50 : AppColor.red30, - activeColor: inspectionValues[index] - ? AppColor.green50.withOpacity(0.25) - : AppColor.red30.withOpacity(0.25), - value: inspectionValues[index], - onChanged: (state) { - setState(() { - inspectionValues[index] = state; - }); + SizedBox( + height: 24.toScreenHeight, + width: 41.toScreenWidth, + child: CupertinoSwitch( + thumbColor: status ? AppColor.green50 : AppColor.red30, + activeColor: AppColor.green30, + trackColor: AppColor.red80, + value: status, + onChanged: (state) { + setState(() { + model.attributeValue = state; + status = state; + }); + }, + ), + ) + ], + ).paddingOnly(bottom: 12); + } + + Widget inspectionStatusNumberWidget({ + required int index, + required PlanRecurrentMedicalTaskRoomTabAttributes model, + required BuildContext context, + }) { + final border = OutlineInputBorder( + borderRadius: BorderRadius.circular(4), // Optional: Slight rounding + borderSide: const BorderSide( + color: AppColor.white70, // Border color + width: 1, // 1px border + ), + ); + return Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + model.attribute!.name!.bodyText2(context).custom(color: AppColor.white936, fontWeight: FontWeight.w500), + TextFormField( + keyboardType: TextInputType.number, + initialValue: model.attributeValue??'', + decoration: InputDecoration( + contentPadding: EdgeInsets.symmetric(horizontal: 5.toScreenWidth), + filled: true, + fillColor: AppColor.neutral100, + constraints: const BoxConstraints( + maxHeight: 30, + maxWidth: 50, + ), + border: border, + enabledBorder: border, + focusedBorder: border, + ), + onChanged: (value){ + model.attributeValue=value; }, ), ], ).paddingOnly(bottom: 12); } } - diff --git a/lib/views/pages/user/ppm/ppm_work_order/recurrent_wo/components/room_tabs_widget.dart b/lib/views/pages/user/ppm/ppm_work_order/recurrent_wo/components/room_tabs_widget.dart index 25eea61a..decd93e1 100644 --- a/lib/views/pages/user/ppm/ppm_work_order/recurrent_wo/components/room_tabs_widget.dart +++ b/lib/views/pages/user/ppm/ppm_work_order/recurrent_wo/components/room_tabs_widget.dart @@ -5,7 +5,6 @@ import 'package:test_sa/extensions/text_extensions.dart'; import 'package:test_sa/extensions/widget_extensions.dart'; import 'package:test_sa/models/ppm/recurrent_wo.dart'; import 'package:test_sa/new_views/app_style/app_color.dart'; -import 'package:test_sa/views/pages/user/ppm/ppm_work_order/recurrent_wo/components/dummy_data.dart'; import 'package:test_sa/views/pages/user/ppm/ppm_work_order/recurrent_wo/components/room_inspection_card.dart'; import 'package:test_sa/views/widgets/loaders/app_loading.dart'; @@ -25,57 +24,54 @@ class _RoomTabsWidgetState extends State { Widget build(BuildContext context) { return Column( crossAxisAlignment: CrossAxisAlignment.start, - mainAxisSize: MainAxisSize.min, children: [ Container( - padding: EdgeInsets.all(12.toScreenHeight), + padding: EdgeInsets.all(8.toScreenHeight), + height: 57.toScreenHeight, + width: double.infinity, decoration: BoxDecoration( color: context.isDark ? AppColor.neutral50 : AppColor.white10, borderRadius: BorderRadius.circular(10), ), - child: SingleChildScrollView( + child: ListView( scrollDirection: Axis.horizontal, - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: widget.model!.planRecurrentMedicalTaskRooms!.asMap().entries.map((entry) { - final int index = entry.key; - final String label = entry.value.room!.roomId!; - return GestureDetector( - onTap: () { - setState(() { - isLoading = true; - selectedIndex = index; - //TODO replace with api response delay... - Future.delayed(const Duration(seconds: 1)).whenComplete(() { - setState(() { - isLoading = false; - }); + // mainAxisAlignment: MainAxisAlignment.spaceAround, + children: widget.model!.planRecurrentMedicalTaskRooms!.asMap().entries.map((entry) { + final int index = entry.key; + final String label = entry.value.room!.roomId!; + return GestureDetector( + onTap: () { + setState(() { + isLoading = true; + selectedIndex = index; + //TODO replace with api response delay... + Future.delayed(const Duration(seconds: 1)).whenComplete(() { + setState(() { + isLoading = false; }); }); - }, - child: Container( - margin: EdgeInsets.only(right: 8.toScreenWidth), - padding: EdgeInsets.symmetric( - vertical: 20.toScreenHeight, - horizontal: 30.toScreenWidth, - ), - alignment: Alignment.center, - decoration: BoxDecoration( - color: selectedIndex == index ? (context.isDark ? AppColor.neutral60 : AppColor.neutral110) : Colors.transparent, - borderRadius: BorderRadius.circular(7), - ), - child: label.bodyText(context).custom( - color: selectedIndex == index ? (context.isDark ? AppColor.white10 : AppColor.black20) : (context.isDark ? AppColor.neutral30 : AppColor.black20), - fontWeight: FontWeight.w600, - ), + }); + }, + child: Container( + // margin: EdgeInsets.only(right: 8.toScreenWidth), + height: 49.toScreenHeight, + padding: EdgeInsets.symmetric( + // vertical: 20.toScreenHeight, + horizontal: 30.toScreenWidth, ), - ); - }).toList(), - ), + alignment: Alignment.center, + decoration: BoxDecoration( + color: selectedIndex == index ? (context.isDark ? AppColor.neutral60 : AppColor.neutral110) : Colors.transparent, + borderRadius: BorderRadius.circular(7), + ), + child: label.bodyText(context).custom( + color:AppColor.white936, + ), + ), + ); + }).toList(), ), ), - 12.height, - // Display the Selected Tab Content isLoading ? SizedBox(height: 120.toScreenHeight, child: const ALoading().center) : ListView( diff --git a/lib/views/pages/user/ppm/ppm_work_order/recurrent_wo/recurrent_work_order_view.dart b/lib/views/pages/user/ppm/ppm_work_order/recurrent_wo/recurrent_work_order_view.dart index 5ae21521..fb7f268d 100644 --- a/lib/views/pages/user/ppm/ppm_work_order/recurrent_wo/recurrent_work_order_view.dart +++ b/lib/views/pages/user/ppm/ppm_work_order/recurrent_wo/recurrent_work_order_view.dart @@ -1,15 +1,12 @@ -import 'package:flutter/cupertino.dart'; +import 'dart:developer'; + import 'package:flutter/material.dart'; +import 'package:fluttertoast/fluttertoast.dart'; import 'package:provider/provider.dart'; -import 'package:test_sa/controllers/providers/api/ppm_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/widget_extensions.dart'; -import 'package:test_sa/models/all_requests_and_count_model.dart'; -import 'package:test_sa/models/ppm/ppm.dart'; import 'package:test_sa/models/ppm/recurrent_wo.dart'; -import 'package:test_sa/models/timer_model.dart'; import 'package:test_sa/new_views/app_style/app_color.dart'; import 'package:test_sa/new_views/common_widgets/app_filled_button.dart'; import 'package:test_sa/new_views/common_widgets/default_app_bar.dart'; @@ -18,13 +15,14 @@ import 'package:test_sa/views/pages/user/ppm/ppm_work_order/recurrent_wo/compone import 'package:test_sa/views/pages/user/ppm/ppm_work_order/recurrent_wo/components/dummy_data.dart'; import 'package:test_sa/views/widgets/loaders/app_loading.dart'; import 'package:test_sa/views/widgets/loaders/no_data_found.dart'; +import '../../../../../../controllers/providers/api/all_requests_provider.dart'; import 'components/room_tabs_widget.dart'; class RecurrentWorkOrderView extends StatefulWidget { static const String id = "/recurrent_wo"; - final RecurrentWo recurrentWo; + final int? taskId; - const RecurrentWorkOrderView({Key? key, required this.recurrentWo}) : super(key: key); + RecurrentWorkOrderView({Key? key, required this.taskId}) : super(key: key); @override _RecurrentWorkOrderViewState createState() { @@ -33,15 +31,12 @@ class RecurrentWorkOrderView extends StatefulWidget { } class _RecurrentWorkOrderViewState extends State { - UserProvider? userProvider; - TimerModel? timerModel = TimerModel(); - PpmProvider? ppmProvider; - - // double totalWorkingHours = _requestDetailProvider?.activityMaintenanceHelperModel?.activityMaintenanceTimers?.fold(0.0, (sum, item) => (sum ?? 0) + DateTime.parse(item.endTime!).difference(DateTime.parse(item.startTime!)).inSeconds) ?? 0; - double totalWorkingHours = 2.0; + AllRequestsProvider? allRequestsProvider; @override void initState() { + allRequestsProvider = Provider.of(context, listen: false); + Provider.of(context, listen: false).getRecurrentWoById(id: widget.taskId!); super.initState(); } @@ -52,75 +47,102 @@ class _RecurrentWorkOrderViewState extends State { @override Widget build(BuildContext context) { - userProvider ??= Provider.of(context, listen: false); - ppmProvider ??= Provider.of(context, listen: false); - print('data i got is ${widget.recurrentWo.recurrentWoData?.toJson()}'); - RoomTabs.getRoomTabs(); - return Scaffold( - appBar: DefaultAppBar(title: context.translation.recurrentWo), - //TODO refactor this after getting api... - body: widget.recurrentWo.recurrentWoData != null - ? Stack( - children: [ - SingleChildScrollView( - child: Column( - mainAxisSize: MainAxisSize.min, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - AssetInfoWidget(model: widget.recurrentWo.recurrentWoData), - 16.height, - widget.recurrentWo.recurrentWoData!.planRecurrentMedicalTaskRooms!.isNotEmpty - ? RoomTabsWidget( - model: widget.recurrentWo.recurrentWoData, - ) - : const SizedBox(), - ], - ).paddingAll(12), - ).paddingOnly(bottom: 85), - FooterActionButton.footerContainer( - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceAround, + return Consumer(builder: (context, requestProvider, child) { + return Scaffold( + appBar: DefaultAppBar(title: context.translation.recurrentWo), + body: allRequestsProvider!.isLoading + ? const ALoading() + : requestProvider.recurrentWoData != null + ? Stack( children: [ - AppFilledButton( - label: context.translation.save, - buttonColor: AppColor.white60, - textColor: AppColor.black10, - onPressed: () async { - print('save clicked...'); - }, - ).expanded, - 12.width, - AppFilledButton( - label: context.translation.complete, - buttonColor: AppColor.primary10, - onPressed: () async { - print('complete clicked...'); - }, - ).expanded, + SingleChildScrollView( + child: Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + RecurrentTaskAssetInfoWidget(model: requestProvider.recurrentWoData), + // 8.height, + requestProvider.recurrentWoData!.planRecurrentMedicalTaskRooms!.isNotEmpty + ? Column( + children: [ + 8.height, + RoomTabsWidget( + model: requestProvider.recurrentWoData, + ), + ], + ) + : const SizedBox(), + ], + ).paddingAll(12), + ).paddingOnly(bottom: 85), + FooterActionButton.footerContainer( + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceAround, + children: [ + AppFilledButton( + label: context.translation.save, + buttonColor: AppColor.white60, + textColor: AppColor.black10, + onPressed: () => _updateTask( + context: context, + status: 0, + ), + ).expanded, + 12.width, + AppFilledButton( + label: context.translation.complete, + buttonColor: AppColor.primary10, + onPressed: () => _updateTask( + context: context, + status: 1, + ), + ).expanded, + ], + ), + ), ], - ), - ), - ], - ) - : NoDataFound(message: context.translation.noDataFound).center, - ); + ) + : NoDataFound(message: context.translation.noDataFound).center, + ); + }); } } -class RoomTabs { - String label; - int tag; +void _updateTask({required BuildContext context, required int status}) async { + + AllRequestsProvider allRequestsProvider = Provider.of(context, listen: false); + + if(validate(model: allRequestsProvider.recurrentWoData!)){ + allRequestsProvider.recurrentWoData?.planRecurrentTaskTimers = allRequestsProvider.recurrentWoData?.planRecurrentTaskTimers ?? []; + + final workingHours = allRequestsProvider.recurrentWoData?.recurrentWoTimerModel?.startAt == null ? 0 : (allRequestsProvider.recurrentWoData?.recurrentWoTimerModel?.startAt ?? DateTime.now()).difference(allRequestsProvider.recurrentWoData!.recurrentWoTimerModel!.startAt!).inSeconds; + print('working hours is ${workingHours}'); + return; + allRequestsProvider.recurrentWoData?.planRecurrentTaskTimers?.add( + PlanRecurrentTaskTimers( + id: 0, + startTime: allRequestsProvider.recurrentWoData?.recurrentWoTimerModel?.startAt?.toIso8601String(), + endTime: allRequestsProvider.recurrentWoData?.recurrentWoTimerModel?.endAt?.toIso8601String(), + workingHours: ((allRequestsProvider.recurrentWoData?.recurrentWoTimerModel?.durationInSecond ?? 0) / 60 / 60), + ), + ); + await allRequestsProvider.updateRecurrentWo( + status: status, + ); + Navigator.pop(context); + } - RoomTabs({ - required this.label, - required this.tag, - }); - static List getRoomTabs() { - List roomTabs = []; - for (int i = 0; i < DummyData.roomData.length; i++) { - roomTabs.add(RoomTabs(label: DummyData.roomData[i]['name'], tag: i)); - } - return roomTabs; +} + +bool validate({required RecurrentWoData model}) { + if (model.recurrentWoTimerModel?.startAt == null) { + Fluttertoast.showToast(msg: "Working Hours Required"); + return false; + } + if (model.recurrentWoTimerModel?.endAt == null) { + Fluttertoast.showToast(msg: "Please Stop The Timer"); + return false; } + return true; }