diff --git a/lib/controllers/api_routes/urls.dart b/lib/controllers/api_routes/urls.dart index fc41f648..2e0857a9 100644 --- a/lib/controllers/api_routes/urls.dart +++ b/lib/controllers/api_routes/urls.dart @@ -1,12 +1,11 @@ class URLs { URLs._(); - static const String appReleaseBuildNumber = "31"; + static const String appReleaseBuildNumber = "32"; // static const host1 = "https://atomsm.hmg.com"; // production url // static const host1 = "https://atomsmdev.hmg.com"; // local DEV url static const host1 = "https://atomsmuat.hmg.com"; // local UAT url - // static const host1 = "http://10.201.111.125:9495"; // temporary Server UAT url // static String _baseUrl = "$_host/mobile"; @@ -20,6 +19,7 @@ class URLs { static const String chatHubUrlApi = "$chatHubUrl/api"; // new V2 apis static const String chatHubUrlChat = "$chatHubUrl/hubs/chat"; // new V2 apis + static const String resetMessageCount = "$chatHubUrlApi/userChatHistory/AckMessages"; // new V2 apis static const String chatApiKey = "f53a98286f82798d588f67a7f0db19f7aebc839e"; // new V2 apis static String _host = host1; diff --git a/lib/controllers/notification/firebase_notification_manger.dart b/lib/controllers/notification/firebase_notification_manger.dart index bc011827..243e8a57 100644 --- a/lib/controllers/notification/firebase_notification_manger.dart +++ b/lib/controllers/notification/firebase_notification_manger.dart @@ -1,4 +1,5 @@ import 'dart:convert'; +import 'dart:developer'; import 'dart:io'; import 'package:firebase_messaging/firebase_messaging.dart'; @@ -13,6 +14,7 @@ import 'package:test_sa/modules/cx_module/survey/survey_page.dart'; import 'package:test_sa/modules/pm_module/ppm_wo/ppm_details_page.dart'; import 'package:test_sa/modules/pm_module/recurrent_wo/recurrent_work_order_view.dart'; import 'package:test_sa/modules/tm_module/device_transfer/device_transfer_details.dart'; +import 'package:test_sa/modules/tm_module/tasks/task_request_detail_view.dart'; import 'package:test_sa/modules/tm_module/gas_refill/gas_refill_details.dart'; import 'package:test_sa/views/widgets/loaders/no_data_found.dart'; @@ -88,6 +90,44 @@ class FirebaseNotificationManger { String? transactionType = messageData["transactionType"]?.toString(); + if (transactionType == null) { + return; + } else if (transactionType == "17" && messageData["requestType"] == "chat") { + int moduleId = int.parse(messageData["moduleId"].toString()); + int requestNumber = int.parse(messageData["requestNumber"].toString()); + + switch (moduleId) { + case 1: // cm + serviceClass = CMDetailPage(requestId: requestNumber, moduleId: moduleId); + break; + case 2: // gas refill + serviceClass = GasRefillDetailsPage( + priority: messageData["priority"], + date: messageData["createdOn"], + moduleId: moduleId, + model: GasRefillModel(id: requestNumber), + ); + break; + case 3: //transfer + serviceClass = DeviceTransferDetails(model: DeviceTransfer(id: requestNumber), moduleId: moduleId); + break; + case 6: // task + serviceClass = TaskRequestDetailsView( + taskId: requestNumber, + moduleId: moduleId, + // requestDetails: RequestsDetails(nameOfType: requestData?.nameOfType, status: requestData?.statusName, priority: requestData?.priorityName, date: requestData?.transactionDate, ), + ); + // ServiceRequestDetailMain(requestId: int.parse(messageData["requestNumber"].toString()), moduleId: 1); + break; + + default: + serviceClass = const Scaffold(body: Center(child: NoDataFound())); + } + + Navigator.of(context).push(MaterialPageRoute(builder: (_) => serviceClass!)); + return; + } + // PPM=1, // ServiceRequestEngineer = 3, // AssetTransfer=7, @@ -101,13 +141,13 @@ class FirebaseNotificationManger { break; //these three request are same corrective maintenance.... case "3": - serviceClass = CMDetailPage(requestId: int.parse(messageData["requestNumber"].toString())); + serviceClass = CMDetailPage(requestId: int.parse(messageData["requestNumber"].toString()), moduleId: 1); break; case "8": - serviceClass = CMDetailPage(requestId: int.parse(messageData["requestNumber"].toString())); + serviceClass = CMDetailPage(requestId: int.parse(messageData["requestNumber"].toString()), moduleId: 1); break; case "11": - serviceClass = CMDetailPage(requestId: int.parse(messageData["requestNumber"].toString())); + serviceClass = CMDetailPage(requestId: int.parse(messageData["requestNumber"].toString()), moduleId: 1); break; case "7": serviceClass = DeviceTransferDetails(model: DeviceTransfer(id: int.parse(messageData["requestNumber"].toString())), moduleId: 3); diff --git a/lib/dashboard_latest/dashboard_view.dart b/lib/dashboard_latest/dashboard_view.dart index 987e76cd..bf9b5a71 100644 --- a/lib/dashboard_latest/dashboard_view.dart +++ b/lib/dashboard_latest/dashboard_view.dart @@ -73,14 +73,14 @@ class _DashboardViewState extends State { // await requestDetailProvider.engineerRejectWorkOrder(id: '3', feedBack: 'Abcdef'); // await dashBoardProvider.getDashBoardCount(usersType: user.type!); // await getAllRequests(); - if (isFCM) { - FirebaseNotificationManger.initialized(context); - NotificationManger.initialisation((notificationDetails) { - FirebaseNotificationManger.handleMessage(context, json.decode(notificationDetails.payload!)); - }, (id, title, body, payload) async {}); - - isFCM = false; - } + // if (isFCM) { + // FirebaseNotificationManger.initialized(context); + // NotificationManger.initialisation((notificationDetails) { + // FirebaseNotificationManger.handleMessage(context, json.decode(notificationDetails.payload!)); + // }, (id, title, body, payload) async {}); + // + // isFCM = false; + // } }); } diff --git a/lib/main.dart b/lib/main.dart index ed84e486..8e8bdbe6 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -136,6 +136,7 @@ import 'providers/service_request_providers/reject_reason_provider.dart'; void main() async { WidgetsFlutterBinding.ensureInitialized(); + SystemChrome.setEnabledSystemUIMode(SystemUiMode.edgeToEdge); // HttpOverrides.global = MyHttpOverrides(); // for later use. _configureLocalTimeZone(); NotificationManger.initialisation((notificationDetails) {}, (id, title, body, payload) async {}); diff --git a/lib/models/user.dart b/lib/models/user.dart index a18b67c5..17da87c9 100644 --- a/lib/models/user.dart +++ b/lib/models/user.dart @@ -12,6 +12,7 @@ class User { List? departmentName; String? message; String? username; + String? employeeId; String? userID; String? email; String? password; @@ -53,6 +54,7 @@ class User { this.departmentName, this.message, this.username, + this.employeeId, this.userID, this.email, this.password, @@ -151,6 +153,7 @@ class User { map['message'] = message; map['username'] = username; map['userID'] = userID; + map['employeeId'] = employeeId; map['email'] = email; map['password'] = password; map['token'] = token; @@ -212,6 +215,7 @@ class User { message = json['message']; username = json['username']; userID = json['userID']; + employeeId = json['employeeId']; email = json['email']; password = json['password']; token = json['token']; diff --git a/lib/modules/cm_module/cm_detail_page.dart b/lib/modules/cm_module/cm_detail_page.dart index d396e598..15b1b503 100644 --- a/lib/modules/cm_module/cm_detail_page.dart +++ b/lib/modules/cm_module/cm_detail_page.dart @@ -13,6 +13,7 @@ import 'package:test_sa/modules/cm_module/cm_detail_provider.dart'; import 'package:test_sa/modules/cm_module/views/components/bottom_sheets/service_request_bottomsheet.dart'; import 'package:test_sa/modules/cx_module/chat/chat_page.dart'; import 'package:test_sa/modules/cx_module/chat/chat_provider.dart'; +import 'package:test_sa/modules/cx_module/chat/chat_widget.dart'; import 'package:test_sa/modules/cx_module/survey/survey_page.dart'; import 'package:test_sa/modules/loan_module/pages/create_loan_request_page.dart'; import 'package:test_sa/new_views/app_style/app_color.dart'; @@ -23,8 +24,9 @@ import 'views/components/service_request_detail_view.dart'; class CMDetailPage extends StatefulWidget { final int requestId; + final int moduleId; - CMDetailPage({Key? key, required this.requestId}) : super(key: key); + CMDetailPage({Key? key, required this.requestId, required this.moduleId}) : super(key: key); @override _CMDetailPageState createState() { @@ -40,6 +42,7 @@ class _CMDetailPageState extends State { @override void initState() { super.initState(); + _requestProvider = Provider.of(context, listen: false); WidgetsBinding.instance.addPostFrameCallback((_) { Provider.of(context, listen: false).reset(); getInitialData(); @@ -89,85 +92,46 @@ class _CMDetailPageState extends State { Navigator.pop(context); }, actions: [ - if (context.userProvider.isEngineer || context.userProvider.isNurse) - Selector( - selector: (_, myModel) => myModel.isLoading, // Selects only the userName - builder: (_, isLoading, __) { - if (isLoading) { - return const SizedBox(); - } else { - CMDetailProvider provider = Provider.of(context, listen: false); - int? statusValue = provider.currentWorkOrder?.data?.status?.value; - if (statusValue == 2 || statusValue == 3 || statusValue == 5 || statusValue == 6) { - getChatToken(moduleId, provider.currentWorkOrder?.data?.workOrderNo ?? ""); - return Consumer(builder: (pContext, requestProvider, _) { - return IconButton( - icon: const Icon(Icons.chat_bubble), - onPressed: () { - Navigator.push( - context, - CupertinoPageRoute( - builder: (context) => ChatPage( - moduleId: moduleId, - requestId: widget.requestId, - title: _requestProvider.currentWorkOrder?.data?.workOrderNo ?? "", - readOnly: _requestProvider.isReadOnlyRequest, - ))); - }, - ).toShimmer(context: context, isShow: requestProvider.chatLoginTokenLoading, radius: 30, height: 30, width: 30); - }); - } - return const SizedBox(); - } - }), - if (isNurse) - IconButton( - icon: 'qr'.toSvgAsset(height: 24, width: 24), - onPressed: () { - ServiceRequestBottomSheet.getQRCodeBottomSheet(context: context); - }, - ) - else ...[ - Selector( - selector: (_, myModel) => myModel.isLoading, // Selects only the userName - builder: (_, isLoading, __) { - if (isLoading) { - return const SizedBox(); - } else { - CMDetailProvider provider = Provider.of(context, listen: false); - int? statusValue = provider.currentWorkOrder?.data?.status?.value; - if (statusValue == 2) { - return Container( - padding: const EdgeInsets.symmetric(vertical: 4, horizontal: 6), - margin: const EdgeInsets.only(left: 2), - decoration: BoxDecoration(color: context.isDark ? AppColor.neutral50 : AppColor.neutral30, borderRadius: BorderRadius.circular(16)), - child: Row( - mainAxisSize: MainAxisSize.min, - children: [ - const Icon(Icons.add, size: 20, color: AppColor.black1E), - Text( - "Loan", - style: AppTextStyles.bodyText2.copyWith(color: AppColor.black1E), - ), - 4.width, - ], - ), - ).onPress(() { - CMDetailProvider provider = Provider.of(context, listen: false); - Navigator.push(context, MaterialPageRoute(builder: (context) => CreateLoanRequestPage(workOrderId: widget.requestId, workOrder: provider.currentWorkOrder!.data))); - }); - } - return const SizedBox(); + Selector( + selector: (_, myModel) => myModel.isLoading, // Selects only the userName + builder: (_, isLoading, __) { + if (isLoading) { + return const SizedBox(); + } else { + CMDetailProvider provider = Provider.of(context, listen: false); + if ((context.userProvider.isEngineer || context.userProvider.isNurse) && + provider.currentWorkOrder?.data?.assignedEmployee != null && + (provider.currentWorkOrder?.data?.workOrderContactPerson?.isNotEmpty ?? false)) { + return ChatWidget( + moduleId: widget.moduleId, + isShow: context.settingProvider.isUserFlowMedical && (context.userProvider.isEngineer || context.userProvider.isNurse) && provider.currentWorkOrder?.data?.assignedEmployee != null, + isReadOnly: _requestProvider.isReadOnlyRequest, + requestId: widget.requestId.toInt(), + assigneeEmployeeNumber: provider.currentWorkOrder?.data?.assignedEmployee!.employeeId!, + myLoginUserID: context.userProvider.user!.employeeId ?? context.userProvider.user!.username!, + contactEmployeeINumber: provider.currentWorkOrder?.data?.workOrderContactPerson.first.employeeId, + ); } - }), - IconButton( - icon: const Icon(Icons.home), - onPressed: () { - // stopTimer(); - Navigator.pop(context); - }, - ) - ], + return const SizedBox(); + } + }), + isNurse + ? IconButton( + icon: 'qr'.toSvgAsset( + height: 24, + width: 24, + ), + onPressed: () { + ServiceRequestBottomSheet.getQRCodeBottomSheet(context: context); + }, + ) + : IconButton( + icon: const Icon(Icons.home), + onPressed: () { + // stopTimer(); + Navigator.pop(context); + }, + ), ], ), body: DefaultTabController( diff --git a/lib/modules/cm_module/create_cm_request.dart b/lib/modules/cm_module/create_cm_request.dart index 1ae1d862..95c74d29 100644 --- a/lib/modules/cm_module/create_cm_request.dart +++ b/lib/modules/cm_module/create_cm_request.dart @@ -300,7 +300,7 @@ class _CreateCMRequestState extends State with TickerProviderSt bool checkPendingRequest = false; void showPendingRequests() { - Navigator.of(context).push(MaterialPageRoute(builder: (_) => PendingServiceRequestScreen(pendingAssetServiceRequest!))); + Navigator.of(context).push(MaterialPageRoute(builder: (_) => PendingServiceRequestScreen(pendingAssetServiceRequest!, 1))); } void showPendingRequestBottomSheet() async { diff --git a/lib/modules/cx_module/chat/chat_api_client.dart b/lib/modules/cx_module/chat/chat_api_client.dart index b209db79..5fdc5b52 100644 --- a/lib/modules/cx_module/chat/chat_api_client.dart +++ b/lib/modules/cx_module/chat/chat_api_client.dart @@ -35,6 +35,7 @@ import 'model/user_chat_history_model.dart'; // import 'package:mohem_flutter_app/models/chat/get_user_login_token_model.dart' as user; // import 'package:mohem_flutter_app/models/chat/make_user_favotire_unfavorite_chat_model.dart' as fav; +//Need to refector this remove unused code. class ChatApiClient { static final ChatApiClient _instance = ChatApiClient._internal(); @@ -81,8 +82,9 @@ class ChatApiClient { } Future loadParticipants(int moduleId, int referenceId, String? assigneeEmployeeNumber) async { - Response response = - await ApiClient().getJsonForResponse("${URLs.chatHubUrlApi}/chat/context/$moduleId/$referenceId?assigneeEmployeeNumber=$assigneeEmployeeNumber", token: chatLoginResponse!.token); + Response response = await ApiClient().getJsonForResponse( + "${URLs.chatHubUrlApi}/chat/context/$moduleId/$referenceId?assigneeEmployeeNumber=$assigneeEmployeeNumber&requestType=chat&transactionType=17", + token: chatLoginResponse!.token); if (!kReleaseMode) { // logger.i("login-res: " + response.body); @@ -94,6 +96,20 @@ class ChatApiClient { } } + Future resetCountApi(int moduleCode, int referenceNumber, String? employeeNumber) async { + final Map payload = { + 'moduleCode': "$moduleCode", + 'ReferenceNumber': "$referenceNumber", + }; + final Response response = await ApiClient().postJsonForResponse( + URLs.resetMessageCount, + payload, + token: chatLoginResponse!.token, + ); + return response.statusCode == 200; + } + + Future> viewAllDocuments(int moduleId, int referenceId) async { Response response = await ApiClient().getJsonForResponse("${URLs.chatHubUrlApi}/attachments/conversation?referenceId=$referenceId&moduleCode=$moduleId", token: chatLoginResponse!.token); diff --git a/lib/modules/cx_module/chat/chat_page.dart b/lib/modules/cx_module/chat/chat_page.dart index 8b8e05c9..fdd96dba 100644 --- a/lib/modules/cx_module/chat/chat_page.dart +++ b/lib/modules/cx_module/chat/chat_page.dart @@ -1,4 +1,5 @@ import 'dart:convert'; +import 'dart:developer'; import 'dart:io'; import 'package:audio_waveforms/audio_waveforms.dart'; @@ -29,6 +30,7 @@ import 'helper/chat_file_viewer.dart'; import 'model/get_single_user_chat_list_model.dart'; import 'model/user_chat_history_model.dart'; +//Need to refactor this ... enum ChatState { idle, voiceRecordingStarted, voiceRecordingCompleted } class ChatPage extends StatefulWidget { @@ -66,7 +68,10 @@ class _ChatPageState extends State { @override void initState() { super.initState(); - loadChatHistory(); + WidgetsBinding.instance.addPostFrameCallback((_) { + loadChatHistory(); + }); + playerController.addListener(() async { // if (playerController.playerState == PlayerState.playing && playerController.maxDuration == await playerController.getDuration()) { // await playerController.stopPlayer(); @@ -75,7 +80,7 @@ class _ChatPageState extends State { }); } - void loadChatHistory() { + void loadChatHistory() async { // // String assigneeEmployeeNumber = Provider.of(context, listen: false).currentWorkOrder?.data?.assignedEmployee?.employeeId ?? ""; // // String myEmployeeId = context.userProvider.user!.username!; // // @@ -99,7 +104,14 @@ class _ChatPageState extends State { ? Provider.of(context, listen: false).currentWorkOrder!.data!.workOrderCreatedBy!.employeeId! : Provider.of(context, listen: false).currentWorkOrder!.data!.workOrderContactPerson.first.employeeId!)) : ""); - Provider.of(context, listen: false).connectToHub(widget.moduleId, widget.requestId, myEmployeeId, receiver, widget.readOnly, isMounted: mounted); + final chatProvider = context.read(); + // final chatProvider = Provider.of { } return Column(mainAxisSize: MainAxisSize.min, children: [ if (showDateHeader) dateCard(currentMessage.createdDate?.toString().chatMsgDateWithYear ?? ""), - isSender ? senderMsgCard(showSenderName, chatProvider.chatResponseList[index]) : recipientMsgCard(showSenderName, chatProvider.chatResponseList[index]) + isSender + ? senderMsgCard(showSenderName, chatProvider.chatResponseList[index], index: index) + : recipientMsgCard(showSenderName, chatProvider.chatResponseList[index]) ]); }, itemCount: chatProvider.chatResponseList.length)) @@ -607,7 +621,7 @@ class _ChatPageState extends State { .center; } - Widget senderMsgCard(bool showHeader, SingleUserChatModel? chatResponse, {bool loading = false, String msg = ""}) { + Widget senderMsgCard(bool showHeader, SingleUserChatModel? chatResponse, {bool loading = false, String msg = "", int index = 0}) { Widget senderHeader = Row( mainAxisSize: MainAxisSize.min, children: [ diff --git a/lib/modules/cx_module/chat/chat_provider.dart b/lib/modules/cx_module/chat/chat_provider.dart index 136dd28b..8d56bcf2 100644 --- a/lib/modules/cx_module/chat/chat_provider.dart +++ b/lib/modules/cx_module/chat/chat_provider.dart @@ -1,5 +1,6 @@ import 'dart:async'; import 'dart:convert'; +import 'dart:developer'; import 'dart:io'; import 'dart:typed_data'; import 'package:audio_waveforms/audio_waveforms.dart'; @@ -40,6 +41,7 @@ import 'package:path_provider/path_provider.dart'; import 'package:permission_handler/permission_handler.dart'; import 'package:signalr_netcore/hub_connection.dart'; import 'package:signalr_netcore/signalr_client.dart'; +import 'package:test_sa/controllers/api_routes/api_manager.dart'; import 'package:test_sa/controllers/api_routes/urls.dart'; import 'package:test_sa/extensions/string_extensions.dart'; import 'package:test_sa/modules/cx_module/chat/model/chat_login_response_model.dart'; @@ -54,6 +56,8 @@ import 'model/get_single_user_chat_list_model.dart'; import 'model/user_chat_history_model.dart'; // import 'get_single_user_chat_list_model.dart'; +//Need to refactor this remove unused code. + HubConnection? chatHubConnection; class ChatProvider with ChangeNotifier, DiagnosticableTreeMixin { @@ -248,6 +252,9 @@ class ChatProvider with ChangeNotifier, DiagnosticableTreeMixin { chatHubConnection!.on("OnSubmitChatAsync", OnSubmitChatAsync); chatHubConnection!.on("OnTypingAsync", OnTypingAsync); chatHubConnection!.on("OnStopTypingAsync", OnStopTypingAsync); + //Need by Chat Backend for seen and un seen. + chatHubConnection!.on("OnSeenChatUserAsync", onSeenUserChatAsync); + chatHubConnection!.on("OnAckSeenAsync", onAckSeenAsync); //group On message @@ -370,7 +377,19 @@ class ChatProvider with ChangeNotifier, DiagnosticableTreeMixin { // } } } - // notifyListeners(); + } + + Future resetCount({ + required int moduleId, + required int referenceNo, + String? userId, + }) async { + try { + return await ChatApiClient().resetCountApi(moduleId, referenceNo, userId); + } catch (e, stack) { + debugPrint('resetCount error: $e'); + rethrow; + } } void updateUserChatHistoryStatusAsync(List data) { @@ -453,6 +472,15 @@ class ChatProvider with ChangeNotifier, DiagnosticableTreeMixin { print(args); } + Future markMessageAsRead(int messageId) async { + final senderId = sender?.userId; + if (senderId == null) return; + chatHubConnection?.invoke( + "SendMessageReadAsync", + args: [messageId, senderId], + ); + } + void onChatSeen(List? args) { dynamic items = args!.toList(); // for (var user in searchedChats!) { @@ -559,6 +587,57 @@ class ChatProvider with ChangeNotifier, DiagnosticableTreeMixin { notifyListeners(); } + Future onSeenUserChatAsync(List? parameters) async { + try { + if (parameters == null || parameters.isEmpty) { + log('onSeenUserChatAsync: parameters are null or empty'); + return; + } + final parm = parameters.first; + if (parm is! List || parm.isEmpty) { + log('onSeenUserChatAsync: parm is not a valid list'); + return; + } + final firstItem = parm.first; + if (firstItem is! Map) { + log('onSeenUserChatAsync: firstItem is not a Map'); + return; + } + await chatHubConnection!.invoke( + "AckSeenAsync", + args: [ + firstItem['currentUserId'], + [firstItem['userChatHistoryId']], + ], + ); + } catch (e, stackTrace) { + log('onSeenUserChatAsync error: $e'); + log('StackTrace: $stackTrace'); + } + } + + + Future onAckSeenAsync(List? parameters) async { + try { + if (parameters == null || parameters.isEmpty) { + log('onAckSeenAsync: parameters are null or empty'); + return; + } + final parm = parameters.first; + log('parm onAckSeenAsync $parm'); + if (chatResponseList.isEmpty) { + log('onAckSeenAsync: chatResponseList is empty'); + return; + } + log('last list item id ${chatResponseList.first.toJson()}'); + chatResponseList.first.isSeen = true; + notifyListeners(); + } catch (e, stackTrace) { + log('onAckSeenAsync error: $e'); + log('StackTrace: $stackTrace'); + } + } + // Future OnSubmitChatAsync(List? parameters) async { // // List data = jsonDecode(parameters!.first!.toString()); // diff --git a/lib/modules/cx_module/chat/chat_widget.dart b/lib/modules/cx_module/chat/chat_widget.dart index 4d28bd1b..8d5011e8 100644 --- a/lib/modules/cx_module/chat/chat_widget.dart +++ b/lib/modules/cx_module/chat/chat_widget.dart @@ -1,9 +1,12 @@ + + import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; import 'package:test_sa/extensions/context_extension.dart'; import 'package:test_sa/extensions/widget_extensions.dart'; import 'package:test_sa/modules/cm_module/cm_detail_provider.dart'; +import 'package:test_sa/new_views/common_widgets/custom_badge.dart'; import 'chat_page.dart'; import 'chat_provider.dart'; @@ -40,8 +43,10 @@ class _ChatWidgetState extends State { @override void initState() { super.initState(); - Provider.of(context, listen: false).reset(); - getChatToken(); + WidgetsBinding.instance.addPostFrameCallback((_) { + Provider.of(context, listen: false).reset(); + getChatToken(); + }); } void getChatToken() { @@ -74,24 +79,31 @@ class _ChatWidgetState extends State { @override Widget build(BuildContext context) { return widget.isShow - ? Consumer(builder: (pContext, requestProvider, _) { - return IconButton( - icon: const Icon(Icons.chat_bubble), - onPressed: () { - Navigator.push( - context, - CupertinoPageRoute( - builder: (context) => ChatPage( - moduleId: widget.moduleId, - requestId: widget.requestId, - title: widget.title, - readOnly: widget.isReadOnly, - assigneeEmployeeNumber: widget.assigneeEmployeeNumber, - contactEmployeeINumber: widget.contactEmployeeINumber, - myLoginUserID: widget.myLoginUserID, - ))); - }, - ).toShimmer(context: context, isShow: requestProvider.chatLoginTokenLoading, radius: 30, height: 30, width: 30); + ? Consumer(builder: (pContext, chatProvider, _) { + final int unreadCount = (!chatProvider.chatLoginTokenLoading && (chatProvider.chatParticipantModel?.unreadCount ?? 0) > 0) ? chatProvider.chatParticipantModel!.unreadCount! : 0; + return CustomBadge2( + value: unreadCount, + top: 2, + right: 2, + minSize: 18, + child: IconButton( + icon: const Icon(Icons.chat_bubble), + onPressed: () { + Navigator.push( + context, + CupertinoPageRoute( + builder: (context) => ChatPage( + moduleId: widget.moduleId, + requestId: widget.requestId, + title: widget.title, + readOnly: widget.isReadOnly, + assigneeEmployeeNumber: widget.assigneeEmployeeNumber, + contactEmployeeINumber: widget.contactEmployeeINumber, + myLoginUserID: widget.myLoginUserID, + ))); + }, + ).toShimmer(context: context, isShow: chatProvider.chatLoginTokenLoading, radius: 30, height: 30, width: 30), + ); }) : const SizedBox(); } diff --git a/lib/modules/cx_module/chat/helper/chat_file_picker.dart b/lib/modules/cx_module/chat/helper/chat_file_picker.dart index 1070e3db..f080cd20 100644 --- a/lib/modules/cx_module/chat/helper/chat_file_picker.dart +++ b/lib/modules/cx_module/chat/helper/chat_file_picker.dart @@ -46,6 +46,7 @@ class ChatFilePicker extends StatelessWidget { fromMediaPicker(BuildContext context, ImageSource imageSource) async { XFile? pickedFile = await ImagePicker().pickImage(source: imageSource, imageQuality: 70, maxWidth: 800, maxHeight: 800); if (pickedFile != null) { + //Has UI issues here top buttons not clickable smoothly CroppedFile? croppedFile = await ImageCropper().cropImage( sourcePath: pickedFile.path, // aspectRatio: CropAspectRatio(ratioX: 1, ratioY: 1), diff --git a/lib/modules/cx_module/chat/helper/chat_file_viewer.dart b/lib/modules/cx_module/chat/helper/chat_file_viewer.dart index 04fba4a1..6d9c99d9 100644 --- a/lib/modules/cx_module/chat/helper/chat_file_viewer.dart +++ b/lib/modules/cx_module/chat/helper/chat_file_viewer.dart @@ -24,6 +24,7 @@ class ChatFileViewer extends StatelessWidget { @override Widget build(BuildContext context) { + return FutureBuilder( future: checkFileInLocalStorage(), builder: (BuildContext context, AsyncSnapshot snapshot) { diff --git a/lib/modules/cx_module/chat/model/chat_participant_model.dart b/lib/modules/cx_module/chat/model/chat_participant_model.dart index 6ef1d4e4..80c6bfc4 100644 --- a/lib/modules/cx_module/chat/model/chat_participant_model.dart +++ b/lib/modules/cx_module/chat/model/chat_participant_model.dart @@ -1,12 +1,15 @@ +import 'dart:developer'; + class ChatParticipantModel { int? id; String? title; String? conversationType; List? participants; - String? lastMessage; + dynamic lastMessage; String? createdAt; + int? unreadCount; - ChatParticipantModel({this.id, this.title, this.conversationType, this.participants, this.lastMessage, this.createdAt}); + ChatParticipantModel({this.id, this.title, this.conversationType, this.participants, this.createdAt, this.unreadCount}); ChatParticipantModel.fromJson(Map json) { id = json['id']; @@ -20,18 +23,20 @@ class ChatParticipantModel { } lastMessage = json['lastMessage']; createdAt = json['createdAt']; + unreadCount = json['unreadCount']; } Map toJson() { - final Map data = new Map(); - data['id'] = this.id; - data['title'] = this.title; - data['conversationType'] = this.conversationType; - if (this.participants != null) { - data['participants'] = this.participants!.map((v) => v.toJson()).toList(); + final Map data = {}; + data['id'] = id; + data['title'] = title; + data['conversationType'] = conversationType; + if (participants != null) { + data['participants'] = participants!.map((v) => v.toJson()).toList(); } - data['lastMessage'] = this.lastMessage; - data['createdAt'] = this.createdAt; + data['lastMessage'] = lastMessage; + data['createdAt'] = createdAt; + data['unreadCount'] = unreadCount; return data; } } @@ -54,12 +59,12 @@ class Participants { } Map toJson() { - final Map data = new Map(); - data['userId'] = this.userId; - data['userName'] = this.userName; - data['employeeNumber'] = this.employeeNumber; - data['role'] = this.role; - data['userStatus'] = this.userStatus; + final Map data = {}; + data['userId'] = userId; + data['userName'] = userName; + data['employeeNumber'] = employeeNumber; + data['role'] = role; + data['userStatus'] = userStatus; return data; } } diff --git a/lib/modules/loan_module/models/loan_form_model.dart b/lib/modules/loan_module/models/loan_form_model.dart index b31df2e6..79d459ca 100644 --- a/lib/modules/loan_module/models/loan_form_model.dart +++ b/lib/modules/loan_module/models/loan_form_model.dart @@ -1,8 +1,7 @@ import 'package:test_sa/models/lookup.dart'; -import 'package:test_sa/models/new_models/building.dart'; -import 'package:test_sa/models/new_models/department.dart'; -import 'package:test_sa/models/new_models/floor.dart'; +import 'package:test_sa/models/new_models/mapped_sites.dart'; import 'package:test_sa/models/new_models/site.dart'; +import 'package:test_sa/models/new_models/traf_department.dart'; import 'package:test_sa/modules/loan_module/models/medical_department_model.dart'; class LoanFormModel { @@ -21,6 +20,8 @@ class LoanFormModel { Site? site; MedicalDepartmentModel? department; List? loanAttachment; + MappedSite? mappedSite; + TrafDepartment? mappedDepartment; LoanFormModel({ this.docName, @@ -38,6 +39,8 @@ class LoanFormModel { this.loanAttachment, this.site, this.department, + this.mappedSite, + this.mappedDepartment, }); //{ @@ -91,8 +94,10 @@ class LoanFormModel { "vendorNumber": vendorNumber, "vendorContact": vendorNumber, "vendorEmail": vendorEmail, - 'siteId': site?.id, - 'departmentId': department?.id, + // 'siteId': site?.id, + 'siteId': mappedSite?.id, + // 'departmentId': department?.id, + 'departmentId': mappedDepartment?.id, "loanAttachments": loanAttachment != null ? loanAttachment!.map((v) => v.toJson()).toList() : [], }; } diff --git a/lib/modules/loan_module/pages/create_loan_request_page.dart b/lib/modules/loan_module/pages/create_loan_request_page.dart index fe76e39b..32616761 100644 --- a/lib/modules/loan_module/pages/create_loan_request_page.dart +++ b/lib/modules/loan_module/pages/create_loan_request_page.dart @@ -1,39 +1,33 @@ import 'dart:convert'; import 'dart:io'; - import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; -import 'package:test_sa/controllers/providers/api/device_transfer_provider.dart'; import 'package:test_sa/controllers/validator/validator.dart'; -import 'package:test_sa/dashboard_latest/dashboard_provider.dart'; import 'package:test_sa/extensions/context_extension.dart'; import 'package:test_sa/extensions/int_extensions.dart'; import 'package:test_sa/extensions/string_extensions.dart'; import 'package:test_sa/extensions/text_extensions.dart'; import 'package:test_sa/extensions/widget_extensions.dart'; import 'package:test_sa/helper/utils.dart'; -import 'package:test_sa/models/device/asset.dart'; -import 'package:test_sa/models/enums/user_types.dart'; import 'package:test_sa/models/generic_attachment_model.dart'; import 'package:test_sa/models/lookup.dart'; -import 'package:test_sa/models/new_models/site.dart'; +import 'package:test_sa/models/new_models/mapped_sites.dart'; import 'package:test_sa/models/new_models/task_request/task_type_model.dart'; +import 'package:test_sa/models/new_models/traf_department.dart'; import 'package:test_sa/models/new_models/work_order_detail_model.dart'; import 'package:test_sa/modules/cm_module/cm_request_utils.dart'; import 'package:test_sa/modules/cm_module/views/components/action_button/footer_action_button.dart'; import 'package:test_sa/modules/loan_module/models/loan_form_model.dart'; -import 'package:test_sa/modules/loan_module/models/medical_department_model.dart'; import 'package:test_sa/modules/loan_module/provider/loan_period_provider.dart'; import 'package:test_sa/modules/loan_module/provider/loan_provider.dart'; -import 'package:test_sa/modules/loan_module/provider/loan_provider.dart'; import 'package:test_sa/modules/loan_module/provider/medical_department_provider.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/new_views/common_widgets/single_item_drop_down_menu.dart'; -import 'package:test_sa/providers/department_provider.dart'; import 'package:test_sa/providers/gas_request_providers/site_provider.dart'; import 'package:test_sa/providers/loading_list_notifier.dart'; +import 'package:test_sa/providers/lookups/department_lookup_provider.dart'; import 'package:test_sa/views/widgets/images/multi_image_picker.dart'; import '../../../../../../new_views/common_widgets/default_app_bar.dart'; @@ -275,10 +269,10 @@ class _CreateLoanRequestPageState extends State with Tick return [ 'Item Details'.addTranslation.bodyText(context).custom(color: AppColor.black10), 8.height, - SingleItemDropDownMenu( + SingleItemDropDownMenu( context: context, title: context.translation.site, - initialValue: _loanFormModel.site, + initialValue: _loanFormModel.mappedSite, showShadow: false, validator: (value) { if (value == null) return "Please select a site"; @@ -287,12 +281,17 @@ class _CreateLoanRequestPageState extends State with Tick backgroundColor: AppColor.fieldBgColor(context), showAsBottomSheet: true, onSelect: (value) { - _loanFormModel.site = value; - setState(() {}); + if(value!=null){ + _loanFormModel.mappedSite = value; + _loanFormModel.mappedDepartment = null; + Provider.of(context,listen:false).getData(id:_loanFormModel.mappedSite?.id); + setState(() {}); + } + }, ), 8.height, - SingleItemDropDownMenu( + SingleItemDropDownMenu( context: context, title: context.translation.department, showShadow: false, @@ -301,11 +300,11 @@ class _CreateLoanRequestPageState extends State with Tick return null; }, showAsBottomSheet: true, - initialValue: _loanFormModel.department, + initialValue: _loanFormModel.mappedDepartment, requestById: context.userProvider.user?.clientId, backgroundColor: AppColor.fieldBgColor(context), onSelect: (value) { - _loanFormModel.department = value; + _loanFormModel.mappedDepartment = value; setState(() {}); }, ), diff --git a/lib/modules/tm_module/device_transfer/create_device_transfer_request.dart b/lib/modules/tm_module/device_transfer/create_device_transfer_request.dart index 26a9c10f..6b9ed8aa 100644 --- a/lib/modules/tm_module/device_transfer/create_device_transfer_request.dart +++ b/lib/modules/tm_module/device_transfer/create_device_transfer_request.dart @@ -62,10 +62,6 @@ class _CreateDeviceTransferRequestState extends State PendingServiceRequestScreen(pendingAssetServiceRequest!))); - } - void _onSubmit() async { _transferModel.assetId = _pickedAsset?.id; _transferModel.destSiteId = _assetDestination.site?.id; diff --git a/lib/modules/tm_module/device_transfer/device_transfer_details.dart b/lib/modules/tm_module/device_transfer/device_transfer_details.dart index e249bd35..6e843398 100644 --- a/lib/modules/tm_module/device_transfer/device_transfer_details.dart +++ b/lib/modules/tm_module/device_transfer/device_transfer_details.dart @@ -223,11 +223,11 @@ class _DeviceTransferDetailsState extends State { if (context.userProvider.isEngineer || context.userProvider.isNurse) ChatWidget( moduleId: widget.moduleId, - isShow: _model!.senderMachineStatusValue! != 4, + isShow: context.settingProvider.isUserFlowMedical && _model!.senderMachineStatusValue! != 4, isReadOnly: _model!.senderMachineStatusValue! != 1, requestId: widget.model.id!.toInt(), assigneeEmployeeNumber: _model!.senderAssignedEmployeeNumber, - myLoginUserID: context.userProvider.user!.username!, + myLoginUserID: context.userProvider.user!.employeeId ?? context.userProvider.user!.username!, contactEmployeeINumber: _model!.assetTransferContactPersons!.first.employeeNumber, ), if ((_userProvider!.user?.type == UsersTypes.engineer)) @@ -284,11 +284,11 @@ class _DeviceTransferDetailsState extends State { if (context.userProvider.isEngineer || context.userProvider.isNurse) ChatWidget( moduleId: widget.moduleId, - isShow: (isSender ? _deviceTransfer.senderMachineStatusValue! : _deviceTransfer.receiverMachineStatusValue!) != 0, + isShow: context.settingProvider.isUserFlowMedical && (isSender ? _deviceTransfer.senderMachineStatusValue! : _deviceTransfer.receiverMachineStatusValue!) != 0, isReadOnly: (isSender ? _deviceTransfer.senderMachineStatusValue! : _deviceTransfer.receiverMachineStatusValue) != 1, requestId: widget.model.id!.toInt(), assigneeEmployeeNumber: isSender ? _deviceTransfer.senderAssignedEmployeeNumber! : _deviceTransfer.receiverAssignedEmployeeNumber!, - myLoginUserID: context.userProvider.user!.username!, + myLoginUserID: context.userProvider.user!.employeeId ?? context.userProvider.user!.username!, contactEmployeeINumber: _deviceTransfer.assetTransferContactPersons!.first.employeeNumber, ), if ((_userProvider!.user?.type == UsersTypes.engineer)) diff --git a/lib/modules/tm_module/gas_refill/gas_refill_details.dart b/lib/modules/tm_module/gas_refill/gas_refill_details.dart index 00ac17aa..c785a6a1 100644 --- a/lib/modules/tm_module/gas_refill/gas_refill_details.dart +++ b/lib/modules/tm_module/gas_refill/gas_refill_details.dart @@ -68,11 +68,11 @@ class _GasRefillDetailsPageState extends State { return ChatWidget( moduleId: widget.moduleId, - isShow: _gasRefillModel.status!.value! != 0, + isShow: context.settingProvider.isUserFlowMedical && _gasRefillModel.status!.value! != 0, isReadOnly: _gasRefillModel.status!.value! != 1, requestId: widget.model.id!.toInt(), assigneeEmployeeNumber: _gasRefillModel.assignedEmployee?.employeeId!, - myLoginUserID: context.userProvider.user!.username!, + myLoginUserID: context.userProvider.user!.employeeId ?? context.userProvider.user!.username!, contactEmployeeINumber: _gasRefillModel.gasRefillContactPerson!.first.employeeCode!, ); }) diff --git a/lib/modules/tm_module/tasks/task_request_detail_view.dart b/lib/modules/tm_module/tasks/task_request_detail_view.dart index 91a75fc7..1a60c0b9 100644 --- a/lib/modules/tm_module/tasks/task_request_detail_view.dart +++ b/lib/modules/tm_module/tasks/task_request_detail_view.dart @@ -75,16 +75,20 @@ class _TaskRequestDetailsViewState extends State { selector: (_, myModel) => myModel.taskRequestModel, // Selects only the userName builder: (_, _taskReqModel, __) { if (_taskReqModel == null) return const SizedBox(); - - return ChatWidget( - moduleId: widget.moduleId, - isShow: _taskReqModel.taskJobStatus!.value! != 1, - isReadOnly: _taskReqModel.taskJobStatus!.value! != 2, - requestId: widget.taskId.toInt(), - assigneeEmployeeNumber: _taskReqModel.assignedEngineer?.employeeId!, - myLoginUserID: context.userProvider.user!.username!, - contactEmployeeINumber: _taskReqModel.taskJobContactPersons!.first.user?.employeeId, - ); + if ((context.userProvider.isEngineer || context.userProvider.isNurse) && + _taskReqModel.assignedEngineer?.employeeId != null && + (_taskReqModel.taskJobContactPersons?.isNotEmpty ?? false)) { + return ChatWidget( + moduleId: widget.moduleId, + isShow: context.settingProvider.isUserFlowMedical && _taskReqModel.taskJobStatus!.value! != 1, + isReadOnly: _taskReqModel.taskJobStatus!.value! != 2, + requestId: widget.taskId.toInt(), + assigneeEmployeeNumber: _taskReqModel.assignedEngineer?.employeeId!, + myLoginUserID: context.userProvider.user!.employeeId ?? context.userProvider.user!.username!, + contactEmployeeINumber: _taskReqModel.taskJobContactPersons!.first.user?.employeeId, + ); + } else + return const SizedBox(); }) ], ), diff --git a/lib/new_views/common_widgets/custom_badge.dart b/lib/new_views/common_widgets/custom_badge.dart index 654304ec..a048877f 100644 --- a/lib/new_views/common_widgets/custom_badge.dart +++ b/lib/new_views/common_widgets/custom_badge.dart @@ -5,12 +5,20 @@ import 'package:test_sa/new_views/app_style/app_color.dart'; class CustomBadge extends StatelessWidget { final Widget child; // The widget that the badge will be overlaid on. final int value; // The value or text to be displayed in the badge. - final Color color; // The background color of the badge. + final Color color; + final double? positionR; + final double? positionT; + final double? height; + final double? width; - const CustomBadge({ + CustomBadge({ Key? key, required this.child, required this.value, + this.height, + this.width, + this.positionR, + this.positionT, this.color = AppColor.red30, // Default color is red }) : super(key: key); @@ -22,13 +30,14 @@ class CustomBadge extends StatelessWidget { child, // The main widget // if (value > 0) Positioned( - right: -6, - top: -6, + right: positionR ?? -6, + top: positionT ?? -6, + //Need to check why opacity he used here this is not correct need to make this total dynamic and responsive child: Opacity( opacity: value > 0 ? 1 : 0, child: Container( - height: 23, - constraints: const BoxConstraints(minWidth: 23), + height: height ?? 23, + constraints: BoxConstraints(minWidth: width ?? 23), padding: const EdgeInsets.all(3), alignment: Alignment.center, decoration: BoxDecoration(color: color, borderRadius: BorderRadius.circular(30)), @@ -43,3 +52,139 @@ class CustomBadge extends StatelessWidget { ); } } + +//Need to use this badge every where.. +class CustomBadge2 extends StatelessWidget { + final Widget child; + final int value; + final double top; + final double right; + final double left; + final double bottom; + final double minSize; + final Color backgroundColor; + final Color textColor; + final TextStyle? textStyle; + final int maxValue; + final Duration animationDuration; + + const CustomBadge2({ + super.key, + required this.child, + required this.value, + this.top = -6, + this.right = -6, + this.left = double.nan, + this.bottom = double.nan, + this.minSize = 18, + this.backgroundColor = AppColor.red30, + this.textColor = AppColor.white10, + this.textStyle, + this.maxValue = 99, + this.animationDuration = const Duration(milliseconds: 200), + }); + + bool get _isVisible => value > 0; + + @override + Widget build(BuildContext context) { + return Stack( + clipBehavior: Clip.none, + children: [ + child, + if (_isVisible) + Positioned( + top: top.isNaN ? null : top, + right: right.isNaN ? null : right, + left: left.isNaN ? null : left, + bottom: bottom.isNaN ? null : bottom, + child: AnimatedScale( + scale: _isVisible ? 1 : 0, + duration: animationDuration, + curve: Curves.easeOutBack, + child: AnimatedOpacity( + opacity: _isVisible ? 1 : 0, + duration: animationDuration, + child: _Badge( + value: value, + maxValue: maxValue, + minSize: minSize, + backgroundColor: backgroundColor, + textColor: textColor, + textStyle: textStyle ?? + Theme.of(context).textTheme.labelSmall?.copyWith( + fontWeight: FontWeight.w700, + ), + ), + ), + ), + ), + ], + ); + } +} + +class _Badge extends StatelessWidget { + final int value; + final int maxValue; + final double minSize; + final Color backgroundColor; + final Color textColor; + final TextStyle? textStyle; + + const _Badge({ + required this.value, + required this.maxValue, + required this.minSize, + required this.backgroundColor, + required this.textColor, + this.textStyle, + }); + + bool get _isOverflow => value > maxValue; + + @override + Widget build(BuildContext context) { + final TextStyle baseStyle = (textStyle ?? Theme.of(context).textTheme.labelMedium)!.copyWith( + color: textColor, + fontWeight: FontWeight.w700, + ); + + final double badgeSize = minSize; + + return IgnorePointer( + child: SizedBox( + width: badgeSize, + height: badgeSize, + child: DecoratedBox( + decoration: const BoxDecoration( + shape: BoxShape.circle, + ), + child: DecoratedBox( + decoration: BoxDecoration( + color: backgroundColor, + shape: BoxShape.circle, + ), + child: Center( + child: _isOverflow + ? FittedBox( + child: Text( + '$maxValue+', + style: baseStyle.copyWith( + fontSize: badgeSize * 0.45, + ), + ), + ) + : CounterAnimatedText( + value: value, + style: baseStyle.copyWith( + fontSize: badgeSize * 0.6, + ), + ), + ), + ), + ), + ), + ); + } +} diff --git a/lib/new_views/pages/land_page/create_request_type_bottom_sheet.dart b/lib/new_views/pages/land_page/create_request_type_bottom_sheet.dart index 030b2895..81e96409 100644 --- a/lib/new_views/pages/land_page/create_request_type_bottom_sheet.dart +++ b/lib/new_views/pages/land_page/create_request_type_bottom_sheet.dart @@ -112,12 +112,14 @@ class CreateRequestModel { // list.add(CreateRequestModel(module.module!.name!, "add_icon", CreateTaskView.id)); // } // }); - if (context.userProvider.isQualityUser) { + if (context.userProvider.isQualityUser && context.settingProvider.isUserFlowMedical) { list.add(CreateRequestModel("Equipment Internal Audit Checklist".addTranslation, "add_icon", CreateEquipmentInternalAuditForm.id)); list.add(CreateRequestModel("System Internal Audit Checklist".addTranslation, "add_icon", CreateSystemInternalAuditForm.id)); - } else if (context.userProvider.isAssessor) { - list.add(CreateRequestModel("TRAF".addTranslation, "add_icon", CreateTRAFRequestPage.id)); - } else if (context.userProvider.isEngineer) { + } + // else if (context.userProvider.isAssessor) { + // list.add(CreateRequestModel("TRAF".addTranslation, "add_icon", CreateTRAFRequestPage.id)); + // } + else if (context.userProvider.isEngineer) { if (Provider.of(context, listen: false).engineerCanCreateCM) { list.add(CreateRequestModel(context.translation.correctiveMaintenance, "add_icon", CreateCMRequest.id)); } @@ -129,7 +131,7 @@ class CreateRequestModel { list.add(CreateRequestModel(context.translation.transferAsset, "add_icon", CreateDeviceTransferRequest.id)); //TODO uncommit this to enable task. list.add(CreateRequestModel(context.translation.task, "add_icon", CreateTaskView.id)); - list.add(CreateRequestModel("TRAF".addTranslation, "add_icon", CreateTRAFRequestPage.id)); + // list.add(CreateRequestModel("TRAF".addTranslation, "add_icon", CreateTRAFRequestPage.id)); list.add(CreateRequestModel('Loan Equipment Request'.addTranslation, "add_icon", CreateLoanRequestPage.id)); } return list; diff --git a/lib/new_views/pages/land_page/land_page.dart b/lib/new_views/pages/land_page/land_page.dart index 437a87dc..b024e501 100644 --- a/lib/new_views/pages/land_page/land_page.dart +++ b/lib/new_views/pages/land_page/land_page.dart @@ -1,8 +1,11 @@ +import 'dart:convert'; import 'dart:io'; import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; import 'package:shared_preferences/shared_preferences.dart'; +import 'package:test_sa/controllers/notification/firebase_notification_manger.dart'; +import 'package:test_sa/controllers/notification/notification_manger.dart'; import 'package:test_sa/controllers/providers/api/user_provider.dart'; import 'package:test_sa/controllers/providers/settings/app_settings.dart'; import 'package:test_sa/dashboard_latest/dashboard_view.dart'; @@ -42,7 +45,7 @@ class _LandPageState extends State { bool showAppbar = true; late List _pages; UserProvider? _userProvider; - + bool isFCM = true; @override void initState() { _pages = []; @@ -123,7 +126,14 @@ class _LandPageState extends State { // if (_userProvider!.user!.type != UsersTypes.engineer) const CalendarPage(), const MyAssetsPage(fromBottomBar: true), ]; + if (isFCM) { + FirebaseNotificationManger.initialized(context); + NotificationManger.initialisation((notificationDetails) { + FirebaseNotificationManger.handleMessage(context, json.decode(notificationDetails.payload!)); + }, (id, title, body, payload) async {}); + isFCM = false; + } checkLocalAuth(); } diff --git a/lib/new_views/pages/land_page/my_request/all_requests_filter_page.dart b/lib/new_views/pages/land_page/my_request/all_requests_filter_page.dart index 06482a0f..d0375646 100644 --- a/lib/new_views/pages/land_page/my_request/all_requests_filter_page.dart +++ b/lib/new_views/pages/land_page/my_request/all_requests_filter_page.dart @@ -79,8 +79,8 @@ class _AllRequestsFilterPageState extends State { if (isEngineer) { types[context.translation.recurrentWo] = 5; - types["Equipment Internal Audit".addTranslation] = 10; - types["System Internal Audit".addTranslation] = 11; + if (context.settingProvider.isUserFlowMedical) types["Equipment Internal Audit".addTranslation] = 10; + if (context.settingProvider.isUserFlowMedical) types["System Internal Audit".addTranslation] = 11; } if (context.settingProvider.isUserFlowMedical && isEngineer) { @@ -93,18 +93,18 @@ class _AllRequestsFilterPageState extends State { types[module.module!.name!] = module.module!.value!; } }); +//Hide traf + // if (!isEngineer) { + // types['TRAF'] = 9; + // } - if (!isEngineer) { - types['TRAF'] = 9; - } - - if (context.userProvider.isAssessor) { - types = {"TRAF": 9}; - } + // if (context.userProvider.isAssessor) { + // types = {"TRAF": 9}; + // } if (context.userProvider.isQualityUser) { if (context.settingProvider.isUserFlowMedical) types = {'Recall and Alert': 7}; - types['Equipment Internal Audit'] = 10; - types['System Internal Audit'] = 11; + if (context.settingProvider.isUserFlowMedical) types['Equipment Internal Audit'] = 10; + if (context.settingProvider.isUserFlowMedical) types['System Internal Audit'] = 11; } if (context.userProvider.isCommissioningEngineer) { ///TODO need to check what other requests type needed here. diff --git a/lib/new_views/pages/land_page/my_request/my_requests_page.dart b/lib/new_views/pages/land_page/my_request/my_requests_page.dart index 52c35338..79cb4e15 100644 --- a/lib/new_views/pages/land_page/my_request/my_requests_page.dart +++ b/lib/new_views/pages/land_page/my_request/my_requests_page.dart @@ -62,10 +62,11 @@ class _MyRequestsPageState extends State { requestsList.add(Request(module.module!.value!, module.module!.name!.addTranslation)); } }); - if (context.userProvider.user!.type == UsersTypes.normal_user) { - requestsList.add(Request(9, 'TRAF')); - } - if (context.userProvider.isEngineer) { + //Hide TRAF. + // if (context.userProvider.user!.type == UsersTypes.normal_user) { + // requestsList.add(Request(9, 'TRAF')); + // } + if (context.userProvider.isEngineer &&context.settingProvider.isUserFlowMedical) { requestsList.add(Request(10, 'Equipment Internal Audit')); requestsList.add(Request(11, 'System Internal Audit')); //Need to be added for new user role commissioning engineer @@ -77,7 +78,7 @@ class _MyRequestsPageState extends State { if (context.userProvider.isAssessor) { requestsList = [ Request(null, context.translation.allWorkOrder), - Request(9, 'TRAF'), + // Request(9, 'TRAF'), ]; } if (context.userProvider.isCommissioningEngineer) { @@ -91,8 +92,8 @@ class _MyRequestsPageState extends State { requestsList = [ Request(null, context.translation.allWorkOrder), if (context.settingProvider.isUserFlowMedical) Request(7, 'Recall and Alert'), - Request(10, 'Equipment Internal Audit'), - Request(11, 'System Internal Audit'), + if (context.settingProvider.isUserFlowMedical) Request(10, 'Equipment Internal Audit'), + if (context.settingProvider.isUserFlowMedical) Request(11, 'System Internal Audit'), ]; } diff --git a/lib/new_views/pages/land_page/requests/service_request_item_view.dart b/lib/new_views/pages/land_page/requests/service_request_item_view.dart index f11d784c..b24a01cc 100644 --- a/lib/new_views/pages/land_page/requests/service_request_item_view.dart +++ b/lib/new_views/pages/land_page/requests/service_request_item_view.dart @@ -81,7 +81,7 @@ class ServiceRequestItemView extends StatelessWidget { ), ], ).toShadowContainer(context, withShadow: showShadow).onPress(() async { - await Navigator.of(context).push(MaterialPageRoute(builder: (_) => CMDetailPage(requestId: requestData!.id!))); + await Navigator.of(context).push(MaterialPageRoute(builder: (_) => CMDetailPage(requestId: requestData!.id!, moduleId: requestData!.transactionNo!))); if (refreshData) { Provider.of(context, listen: false).refreshDashboard(userType: Provider.of(context, listen: false).user!.type!, context: context); } @@ -140,7 +140,7 @@ class ServiceRequestItemView extends StatelessWidget { ), ], ).toShadowContainer(context, withShadow: showShadow).onPress(() { - Navigator.of(context).push(MaterialPageRoute(builder: (_) => CMDetailPage(requestId: requestDetails!.id!))); + Navigator.of(context).push(MaterialPageRoute(builder: (_) => CMDetailPage(requestId: requestDetails!.id!, moduleId: requestDetails!.transactionType!))); }); } diff --git a/lib/views/pages/user/requests/pending_requests_screen.dart b/lib/views/pages/user/requests/pending_requests_screen.dart index b87af0d9..acacc179 100644 --- a/lib/views/pages/user/requests/pending_requests_screen.dart +++ b/lib/views/pages/user/requests/pending_requests_screen.dart @@ -9,9 +9,10 @@ import 'package:test_sa/new_views/common_widgets/default_app_bar.dart'; import 'package:test_sa/views/widgets/sound/sound_player.dart'; class PendingServiceRequestScreen extends StatelessWidget { + final int moduleId; final PendingAssetServiceRequest pendingAssetServiceRequest; - const PendingServiceRequestScreen(this.pendingAssetServiceRequest, {Key? key}) : super(key: key); + const PendingServiceRequestScreen(this.pendingAssetServiceRequest, this.moduleId, {Key? key}) : super(key: key); @override Widget build(BuildContext context) { @@ -63,7 +64,7 @@ class PendingServiceRequestScreen extends StatelessWidget { ], ), ).onPress(() { - Navigator.of(context).push(MaterialPageRoute(builder: (_) => CMDetailPage(requestId: pendingAssetServiceRequest.details![index].id ?? 0))); + Navigator.of(context).push(MaterialPageRoute(builder: (_) => CMDetailPage(requestId: pendingAssetServiceRequest.details![index].id ?? 0, moduleId: moduleId))); }))); } } diff --git a/lib/views/widgets/equipment/asset_detail_page.dart b/lib/views/widgets/equipment/asset_detail_page.dart index f34f834c..f0b095fb 100644 --- a/lib/views/widgets/equipment/asset_detail_page.dart +++ b/lib/views/widgets/equipment/asset_detail_page.dart @@ -122,7 +122,7 @@ class _AssetDetailPageState extends State { "${context.translation.building}: ${assetModel.building?.name?.cleanupWhitespace.capitalizeFirstOfEach ?? "-"}".bodyText(context), "${context.translation.floor}: ${assetModel.floor?.name?.cleanupWhitespace.capitalizeFirstOfEach ?? "-"}".bodyText(context), "${context.translation.md}: ${assetModel.department?.departmentName?.cleanupWhitespace.capitalizeFirstOfEach ?? "-"}".bodyText(context), - "${context.translation.room}: ${assetModel.room?.value ?? "-"}".bodyText(context), + "${context.translation.room}: ${assetModel.room?.name?.cleanupWhitespace.capitalizeFirstOfEach ?? "-"}".bodyText(context), ], ).expanded, ], diff --git a/pubspec.yaml b/pubspec.yaml index a7edc369..678fdb0f 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -15,7 +15,7 @@ publish_to: 'none' # Remove this line if you wish to publish to pub.dev # In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion. # Read more about iOS versioning at # https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html -version: 1.4.0+31 +version: 1.5.0+32 environment: sdk: ">=3.5.0 <4.0.0"