From d7ab1c8dc269925f050f164028a9d470f1b6a78e Mon Sep 17 00:00:00 2001 From: haroon amjad Date: Thu, 13 Apr 2023 15:36:35 +0300 Subject: [PATCH 01/19] PageView added to PR Info page --- lib/ui/work_list/item_history_screen.dart | 119 ++++++++++++++++------ 1 file changed, 87 insertions(+), 32 deletions(-) diff --git a/lib/ui/work_list/item_history_screen.dart b/lib/ui/work_list/item_history_screen.dart index 88abf06..c53a68e 100644 --- a/lib/ui/work_list/item_history_screen.dart +++ b/lib/ui/work_list/item_history_screen.dart @@ -58,6 +58,7 @@ class _ItemHistoryScreenState extends State { List actionHistoryList = []; List getAttachmentList = []; int tabIndex = 0; + PageController controller = PageController(); @override void initState() { @@ -136,7 +137,7 @@ class _ItemHistoryScreenState extends State { backgroundColor: Colors.white, body: ListView( padding: _screenParams!.isPRInfo ? const EdgeInsets.all(0) : const EdgeInsets.all(21), - physics: const BouncingScrollPhysics(), + physics: const NeverScrollableScrollPhysics(), children: [ if (_screenParams!.isPRInfo) prLinesDataView(), if (moItemHistoryList.isNotEmpty) loadMoItemHistoryData(), @@ -150,6 +151,7 @@ class _ItemHistoryScreenState extends State { Widget prLinesDataView() { return Column( + mainAxisSize: MainAxisSize.min, children: [ Container( padding: const EdgeInsets.only(left: 21, right: 21, top: 16, bottom: 16), @@ -177,36 +179,88 @@ class _ItemHistoryScreenState extends State { ), ), if (tabIndex == 0) _screenParams!.getPRInformationList!.pRHeader![0].dESCRIPTION!.toText14().paddingOnly(top: 20, right: 21, left: 21), - if (tabIndex == 0) - ListView.separated( - padding: const EdgeInsets.all(21), - shrinkWrap: true, - physics: const NeverScrollableScrollPhysics(), - itemBuilder: (cxt, index) => Column( - children: [ - ItemDetailGrid( - ItemDetailViewCol("Cost Center", _screenParams!.getPRInformationList!.pRLines![index].cOSTCENTER ?? ""), - ItemDetailViewCol("Code", _screenParams!.getPRInformationList!.pRLines![index].iTEMCODE ?? ""), - ), - ItemDetailGrid( - ItemDetailViewCol("Unit", _screenParams!.getPRInformationList!.pRLines![index].uOM ?? ""), - ItemDetailViewCol("Price (SAR)", _screenParams!.getPRInformationList!.pRLines![index].uNITPRICE.toString() ?? ""), - ), - ItemDetailGrid( - ItemDetailViewCol("Amount (SAR)", _screenParams!.getPRInformationList!.pRLines![index].lINEAMOUNT.toString() ?? ""), - ItemDetailViewCol("Quantity", _screenParams!.getPRInformationList!.pRLines![index].qUANTITY.toString() ?? ""), - ), - ItemDetailGrid( - ItemDetailViewCol("AMU (Last 3 months)", _screenParams!.getPRInformationList!.pRLines![index].iTEMAMU.toString() ?? ""), - ItemDetailViewCol("PR Number", _screenParams!.getPRInformationList!.pRHeader![0].pRNUMBER!.toString() ?? ""), - isItLast: true, - ), - ], - ).objectContainerView(), - separatorBuilder: (cxt, index) => 12.height, - itemCount: _screenParams!.getPRInformationList!.pRLines!.length), - if (tabIndex == 1) getPRActionsHistory(), //"ACTIONS".toText14().paddingOnly(top: 20, right: 21, left: 21), - if (tabIndex == 2) getPRAttachments(), + // if (tabIndex == 0) + // ListView.separated( + // padding: const EdgeInsets.all(21), + // shrinkWrap: true, + // physics: const NeverScrollableScrollPhysics(), + // itemBuilder: (cxt, index) => Column( + // children: [ + // ItemDetailGrid( + // ItemDetailViewCol("Cost Center", _screenParams!.getPRInformationList!.pRLines![index].cOSTCENTER ?? ""), + // ItemDetailViewCol("Code", _screenParams!.getPRInformationList!.pRLines![index].iTEMCODE ?? ""), + // ), + // ItemDetailGrid( + // ItemDetailViewCol("Unit", _screenParams!.getPRInformationList!.pRLines![index].uOM ?? ""), + // ItemDetailViewCol("Price (SAR)", _screenParams!.getPRInformationList!.pRLines![index].uNITPRICE.toString() ?? ""), + // ), + // ItemDetailGrid( + // ItemDetailViewCol("Amount (SAR)", _screenParams!.getPRInformationList!.pRLines![index].lINEAMOUNT.toString() ?? ""), + // ItemDetailViewCol("Quantity", _screenParams!.getPRInformationList!.pRLines![index].qUANTITY.toString() ?? ""), + // ), + // ItemDetailGrid( + // ItemDetailViewCol("AMU (Last 3 months)", _screenParams!.getPRInformationList!.pRLines![index].iTEMAMU.toString() ?? ""), + // ItemDetailViewCol("PR Number", _screenParams!.getPRInformationList!.pRHeader![0].pRNUMBER!.toString() ?? ""), + // isItLast: true, + // ), + // ], + // ).objectContainerView(), + // separatorBuilder: (cxt, index) => 12.height, + // itemCount: _screenParams!.getPRInformationList!.pRLines!.length), + // if (tabIndex == 1) getPRActionsHistory(), //"ACTIONS".toText14().paddingOnly(top: 20, right: 21, left: 21), + // if (tabIndex == 2) getPRAttachments(), + + SizedBox( + height: MediaQuery.of(context).size.height, + child: PageView( + controller: controller, + onPageChanged: (pageIndex) { + setState(() { + tabIndex = pageIndex; + if (pageIndex == 1) { + getActionsDataFromApi(); + } + if (pageIndex == 2) { + getAttachmentsDataFromApi(); + } + }); + }, + children: [ + // if (tabIndex == 0) + ListView.separated( + padding: const EdgeInsets.all(21), + shrinkWrap: true, + physics: const NeverScrollableScrollPhysics(), + itemBuilder: (cxt, index) => Column( + children: [ + ItemDetailGrid( + ItemDetailViewCol("Cost Center", _screenParams!.getPRInformationList!.pRLines![index].cOSTCENTER ?? ""), + ItemDetailViewCol("Code", _screenParams!.getPRInformationList!.pRLines![index].iTEMCODE ?? ""), + ), + ItemDetailGrid( + ItemDetailViewCol("Unit", _screenParams!.getPRInformationList!.pRLines![index].uOM ?? ""), + ItemDetailViewCol("Price (SAR)", _screenParams!.getPRInformationList!.pRLines![index].uNITPRICE.toString() ?? ""), + ), + ItemDetailGrid( + ItemDetailViewCol("Amount (SAR)", _screenParams!.getPRInformationList!.pRLines![index].lINEAMOUNT.toString() ?? ""), + ItemDetailViewCol("Quantity", _screenParams!.getPRInformationList!.pRLines![index].qUANTITY.toString() ?? ""), + ), + ItemDetailGrid( + ItemDetailViewCol("AMU (Last 3 months)", _screenParams!.getPRInformationList!.pRLines![index].iTEMAMU.toString() ?? ""), + ItemDetailViewCol("PR Number", _screenParams!.getPRInformationList!.pRHeader![0].pRNUMBER!.toString() ?? ""), + isItLast: true, + ), + ], + ).objectContainerView(), + separatorBuilder: (cxt, index) => 12.height, + itemCount: _screenParams!.getPRInformationList!.pRLines!.length), + // if (tabIndex == 1) + getPRActionsHistory(), //"ACTIONS".toText14().paddingOnly(top: 20, right: 21, left: 21), + // if (tabIndex == 2) + getPRAttachments(), + ], + ), + ), ], ); } @@ -550,7 +604,8 @@ class _ItemHistoryScreenState extends State { if (index == 2) { getAttachmentsDataFromApi(); } - tabIndex = index; + // tabIndex = index; + controller.jumpToPage(index); }); }).expanded; } From f8c207d33f9ba4e881ab86274c1f38a2270bee40 Mon Sep 17 00:00:00 2001 From: haroon amjad Date: Thu, 25 May 2023 09:55:14 +0300 Subject: [PATCH 02/19] updates --- lib/ui/login/login_screen.dart | 29 +++++++++++-------- lib/ui/work_list/item_history_screen.dart | 34 ----------------------- 2 files changed, 18 insertions(+), 45 deletions(-) diff --git a/lib/ui/login/login_screen.dart b/lib/ui/login/login_screen.dart index 8d8e7c2..0eb7f4f 100644 --- a/lib/ui/login/login_screen.dart +++ b/lib/ui/login/login_screen.dart @@ -27,7 +27,6 @@ import 'package:mohem_flutter_app/models/member_information_list_model.dart'; import 'package:mohem_flutter_app/models/member_login_list_model.dart'; import 'package:mohem_flutter_app/models/privilege_list_model.dart'; import 'package:mohem_flutter_app/widgets/button/default_button.dart'; -import 'package:mohem_flutter_app/widgets/button/hmg_connectivity_button.dart'; import 'package:mohem_flutter_app/widgets/input_widget.dart'; // import 'package:safe_device/safe_device.dart'; @@ -98,6 +97,7 @@ class _LoginScreenState extends State { Future checkFirebaseToken() async { try { + await checkPrefs(); Utils.showLoading(context); if (Platform.isAndroid) { try { @@ -120,6 +120,9 @@ class _LoginScreenState extends State { await Firebase.initializeApp(); _firebaseMessaging = FirebaseMessaging.instance; firebaseToken = await _firebaseMessaging.getToken(); + String? firebaseAPNSToken = await _firebaseMessaging.getAPNSToken(); + print("Firebase Token: $firebaseToken"); + print("Firebase APNS Token: $firebaseAPNSToken"); AppNotifications().init(firebaseToken); checkLoginInfo(); await FirebaseCrashlytics.instance.setCrashlyticsCollectionEnabled(true); @@ -132,17 +135,21 @@ class _LoginScreenState extends State { } void checkLoginInfo() async { - loginInfo = await LoginApiClient().getMobileLoginInfoNEW(AppState().getIsHuawei ? AppState().getHuaweiPushToken : firebaseToken ?? "", Platform.isAndroid ? "android" : "ios"); - if (loginInfo == null) { - await checkPrefs(); - _autoLogin = false; - Utils.hideLoading(context); - return; - } else { - loginInfo!.deviceToken = firebaseToken; - await checkPrefs(); + try { + loginInfo = await LoginApiClient().getMobileLoginInfoNEW(AppState().getIsHuawei ? AppState().getHuaweiPushToken : firebaseToken ?? "", Platform.isAndroid ? "android" : "ios"); + if (loginInfo == null) { + await checkPrefs(); + _autoLogin = false; + Utils.hideLoading(context); + return; + } else { + loginInfo!.deviceToken = firebaseToken; + await checkPrefs(); + Utils.hideLoading(context); + performLogin(); + } + } catch (ex) { Utils.hideLoading(context); - performLogin(); } } diff --git a/lib/ui/work_list/item_history_screen.dart b/lib/ui/work_list/item_history_screen.dart index c53a68e..e88dcba 100644 --- a/lib/ui/work_list/item_history_screen.dart +++ b/lib/ui/work_list/item_history_screen.dart @@ -179,37 +179,6 @@ class _ItemHistoryScreenState extends State { ), ), if (tabIndex == 0) _screenParams!.getPRInformationList!.pRHeader![0].dESCRIPTION!.toText14().paddingOnly(top: 20, right: 21, left: 21), - // if (tabIndex == 0) - // ListView.separated( - // padding: const EdgeInsets.all(21), - // shrinkWrap: true, - // physics: const NeverScrollableScrollPhysics(), - // itemBuilder: (cxt, index) => Column( - // children: [ - // ItemDetailGrid( - // ItemDetailViewCol("Cost Center", _screenParams!.getPRInformationList!.pRLines![index].cOSTCENTER ?? ""), - // ItemDetailViewCol("Code", _screenParams!.getPRInformationList!.pRLines![index].iTEMCODE ?? ""), - // ), - // ItemDetailGrid( - // ItemDetailViewCol("Unit", _screenParams!.getPRInformationList!.pRLines![index].uOM ?? ""), - // ItemDetailViewCol("Price (SAR)", _screenParams!.getPRInformationList!.pRLines![index].uNITPRICE.toString() ?? ""), - // ), - // ItemDetailGrid( - // ItemDetailViewCol("Amount (SAR)", _screenParams!.getPRInformationList!.pRLines![index].lINEAMOUNT.toString() ?? ""), - // ItemDetailViewCol("Quantity", _screenParams!.getPRInformationList!.pRLines![index].qUANTITY.toString() ?? ""), - // ), - // ItemDetailGrid( - // ItemDetailViewCol("AMU (Last 3 months)", _screenParams!.getPRInformationList!.pRLines![index].iTEMAMU.toString() ?? ""), - // ItemDetailViewCol("PR Number", _screenParams!.getPRInformationList!.pRHeader![0].pRNUMBER!.toString() ?? ""), - // isItLast: true, - // ), - // ], - // ).objectContainerView(), - // separatorBuilder: (cxt, index) => 12.height, - // itemCount: _screenParams!.getPRInformationList!.pRLines!.length), - // if (tabIndex == 1) getPRActionsHistory(), //"ACTIONS".toText14().paddingOnly(top: 20, right: 21, left: 21), - // if (tabIndex == 2) getPRAttachments(), - SizedBox( height: MediaQuery.of(context).size.height, child: PageView( @@ -226,7 +195,6 @@ class _ItemHistoryScreenState extends State { }); }, children: [ - // if (tabIndex == 0) ListView.separated( padding: const EdgeInsets.all(21), shrinkWrap: true, @@ -254,9 +222,7 @@ class _ItemHistoryScreenState extends State { ).objectContainerView(), separatorBuilder: (cxt, index) => 12.height, itemCount: _screenParams!.getPRInformationList!.pRLines!.length), - // if (tabIndex == 1) getPRActionsHistory(), //"ACTIONS".toText14().paddingOnly(top: 20, right: 21, left: 21), - // if (tabIndex == 2) getPRAttachments(), ], ), From 9030b9bc817aa5f9ec74b6c3b0206208485848b3 Mon Sep 17 00:00:00 2001 From: haroon amjad Date: Mon, 29 May 2023 12:30:26 +0300 Subject: [PATCH 03/19] Notification details implemented --- lib/api/my_requests_api_client.dart | 4 +- lib/classes/notifications.dart | 45 +++++- .../get_notifications_response_model.dart | 96 +++++++++++++ lib/ui/login/login_screen.dart | 5 +- .../notification_details_page.dart | 74 ++++++++++ lib/ui/screens/my_requests/my_requests.dart | 132 +++++++++--------- lib/ui/screens/my_requests/new_request.dart | 22 +-- 7 files changed, 299 insertions(+), 79 deletions(-) create mode 100644 lib/models/get_notifications_response_model.dart create mode 100644 lib/ui/notifications/notification_details_page.dart diff --git a/lib/api/my_requests_api_client.dart b/lib/api/my_requests_api_client.dart index c9507b9..96eafa5 100644 --- a/lib/api/my_requests_api_client.dart +++ b/lib/api/my_requests_api_client.dart @@ -60,7 +60,7 @@ class MyRequestsApiClient { }, url, postParams); } - Future getSubmitNewRequest(List> list) async + Future getSubmitNewRequest(List> list) async { String url = "${ApiConsts.erpRest}SUBMIT_CCP_TRANSACTION"; Map postParams = { @@ -73,7 +73,7 @@ class MyRequestsApiClient { postParams["EITTransactionTBL"] = list; return await ApiClient().postJsonForObject((json) { GenericResponseModel? responseData = GenericResponseModel.fromJson(json); - return responseData.submitCcpTransactionList; + return responseData; }, url, postParams); } diff --git a/lib/classes/notifications.dart b/lib/classes/notifications.dart index 9528616..e29b29c 100644 --- a/lib/classes/notifications.dart +++ b/lib/classes/notifications.dart @@ -3,12 +3,16 @@ import 'dart:io'; import 'package:firebase_core/firebase_core.dart'; import 'package:firebase_messaging/firebase_messaging.dart'; import 'package:flutter/foundation.dart'; +import 'package:flutter/material.dart'; import 'package:flutter_local_notifications/flutter_local_notifications.dart'; // import 'package:huawei_hmsavailability/huawei_hmsavailability.dart'; import 'package:huawei_push/huawei_push.dart' as huawei_push; import 'package:mohem_flutter_app/app_state/app_state.dart'; +import 'package:mohem_flutter_app/classes/date_uitl.dart'; import 'package:mohem_flutter_app/classes/utils.dart'; +import 'package:mohem_flutter_app/models/get_notifications_response_model.dart'; +import 'package:mohem_flutter_app/ui/notifications/notification_details_page.dart'; import 'package:permission_handler/permission_handler.dart'; final FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin = FlutterLocalNotificationsPlugin(); @@ -24,6 +28,8 @@ class AppNotifications { String _huaweiToken = ''; + late BuildContext context; + Future requestPermissions() async { if (Platform.isIOS) { await flutterLocalNotificationsPlugin.resolvePlatformSpecificImplementation()?.requestPermissions(alert: true, badge: true, sound: true); @@ -40,11 +46,13 @@ class AppNotifications { } } - void init(String? firebaseToken) async { + void init(String? firebaseToken, BuildContext context) async { // if (Platform.isAndroid) { // hmsApiAvailability = HmsApiAvailability(); // } + this.context = context; + await requestPermissions(); AppState().setDeviceToken = firebaseToken; await Permission.notification.isDenied.then((bool value) { @@ -113,12 +121,47 @@ class AppNotifications { void _handleMessage(RemoteMessage message) { Utils.saveStringFromPrefs("isAppOpendByChat", "false"); + GetNotificationsResponseModel notification = GetNotificationsResponseModel(); + + notification.createdOn = DateUtil.getMonthDayYearDateFormatted(DateTime.now()); + notification.messageTypeData = message.data['picture']; + notification.message = message.data['message']; + notification.notificationType = message.data["NotificationType"].toString(); + if (message.data["NotificationType"] == "2") { + notification.videoURL = message.data["VideoUrl"]; + } + + Navigator.of(context).push( + MaterialPageRoute( + builder: (BuildContext context) => NotificationsDetailsPage( + notification: notification, + ), + ), + ); } void _handleOpenApp(RemoteMessage message) { if (message.data.isNotEmpty && message.data["type"] == 'chat') { Utils.saveStringFromPrefs("isAppOpendByChat", "true"); Utils.saveStringFromPrefs("notificationData", message.data["user_chat_history_response"].toString()); + } else { + GetNotificationsResponseModel notification = GetNotificationsResponseModel(); + + notification.createdOn = DateUtil.getMonthDayYearDateFormatted(DateTime.now()); + notification.messageTypeData = message.data['picture']; + notification.message = message.data['message']; + notification.notificationType = message.data["NotificationType"].toString(); + if (message.data["NotificationType"] == "2") { + notification.videoURL = message.data["VideoUrl"]; + } + + Navigator.of(context).push( + MaterialPageRoute( + builder: (BuildContext context) => NotificationsDetailsPage( + notification: notification, + ), + ), + ); } } } diff --git a/lib/models/get_notifications_response_model.dart b/lib/models/get_notifications_response_model.dart new file mode 100644 index 0000000..adf08ee --- /dev/null +++ b/lib/models/get_notifications_response_model.dart @@ -0,0 +1,96 @@ +class GetNotificationsResponseModel { + int? id; + int? recordId; + int? patientID; + bool? projectOutSA; + String? deviceType; + String? deviceToken; + String? message; + String? messageType; + String? messageTypeData; + dynamic videoURL; + bool? isQueue; + String? isQueueOn; + String? createdOn; + String? createdBy; + String? notificationType; + bool? isSent; + String? isSentOn; + bool? isRead; + String? isReadOn; + int? channelID; + int? projectID; + + GetNotificationsResponseModel( + {this.id, + this.recordId, + this.patientID, + this.projectOutSA, + this.deviceType, + this.deviceToken, + this.message, + this.messageType, + this.messageTypeData, + this.videoURL, + this.isQueue, + this.isQueueOn, + this.createdOn, + this.createdBy, + this.notificationType, + this.isSent, + this.isSentOn, + this.isRead, + this.isReadOn, + this.channelID, + this.projectID}); + + GetNotificationsResponseModel.fromJson(Map json) { + id = json['Id']; + recordId = json['RecordId']; + patientID = json['PatientID']; + projectOutSA = json['ProjectOutSA']; + deviceType = json['DeviceType']; + deviceToken = json['DeviceToken']; + message = json['Message']; + messageType = json['MessageType']; + messageTypeData = json['MessageTypeData']; + videoURL = json['VideoURL']; + isQueue = json['IsQueue']; + isQueueOn = json['IsQueueOn']; + createdOn = json['CreatedOn']; + createdBy = json['CreatedBy']; + notificationType = json['NotificationType']; + isSent = json['IsSent']; + isSentOn = json['IsSentOn']; + isRead = json['IsRead']; + isReadOn = json['IsReadOn']; + channelID = json['ChannelID']; + projectID = json['ProjectID']; + } + + Map toJson() { + Map data = new Map(); + data['Id'] = this.id; + data['RecordId'] = this.recordId; + data['PatientID'] = this.patientID; + data['ProjectOutSA'] = this.projectOutSA; + data['DeviceType'] = this.deviceType; + data['DeviceToken'] = this.deviceToken; + data['Message'] = this.message; + data['MessageType'] = this.messageType; + data['MessageTypeData'] = this.messageTypeData; + data['VideoURL'] = this.videoURL; + data['IsQueue'] = this.isQueue; + data['IsQueueOn'] = this.isQueueOn; + data['CreatedOn'] = this.createdOn; + data['CreatedBy'] = this.createdBy; + data['NotificationType'] = this.notificationType; + data['IsSent'] = this.isSent; + data['IsSentOn'] = this.isSentOn; + data['IsRead'] = this.isRead; + data['IsReadOn'] = this.isReadOn; + data['ChannelID'] = this.channelID; + data['ProjectID'] = this.projectID; + return data; + } +} diff --git a/lib/ui/login/login_screen.dart b/lib/ui/login/login_screen.dart index 0eb7f4f..3293e43 100644 --- a/lib/ui/login/login_screen.dart +++ b/lib/ui/login/login_screen.dart @@ -110,7 +110,8 @@ class _LoginScreenState extends State { await Firebase.initializeApp(); _firebaseMessaging = FirebaseMessaging.instance; firebaseToken = await _firebaseMessaging.getToken(); - AppNotifications().init(firebaseToken); + print(firebaseToken); + AppNotifications().init(firebaseToken, context); checkLoginInfo(); await FirebaseCrashlytics.instance.setCrashlyticsCollectionEnabled(true); } @@ -123,7 +124,7 @@ class _LoginScreenState extends State { String? firebaseAPNSToken = await _firebaseMessaging.getAPNSToken(); print("Firebase Token: $firebaseToken"); print("Firebase APNS Token: $firebaseAPNSToken"); - AppNotifications().init(firebaseToken); + AppNotifications().init(firebaseToken, context); checkLoginInfo(); await FirebaseCrashlytics.instance.setCrashlyticsCollectionEnabled(true); } diff --git a/lib/ui/notifications/notification_details_page.dart b/lib/ui/notifications/notification_details_page.dart new file mode 100644 index 0000000..67573dc --- /dev/null +++ b/lib/ui/notifications/notification_details_page.dart @@ -0,0 +1,74 @@ +import 'package:flutter/material.dart'; +import 'package:lottie/lottie.dart'; +import 'package:mohem_flutter_app/models/get_notifications_response_model.dart'; +import 'package:mohem_flutter_app/widgets/app_bar_widget.dart'; + +class NotificationsDetailsPage extends StatefulWidget { + final GetNotificationsResponseModel notification; + + NotificationsDetailsPage({required this.notification}); + + @override + State createState() => _NotificationsDetailsPageState(); +} + +class _NotificationsDetailsPageState extends State { + @override + Widget build(BuildContext context) { + return Scaffold( + backgroundColor: Colors.white, + appBar: AppBarWidget( + context, + title: "Notification Details", + ), + body: ListView( + physics: BouncingScrollPhysics(), + padding: EdgeInsets.all(21), + children: [ + Text( + widget.notification.createdOn!, + style: const TextStyle( + fontSize: 16, + fontWeight: FontWeight.w600, + color: Color(0xff2E303A), + letterSpacing: -0.64, + ), + ), + if (widget.notification.messageTypeData != null) + if (widget.notification.messageTypeData!.isNotEmpty && widget.notification.notificationType != "2") + Padding( + padding: const EdgeInsets.only(top: 18), + child: Image.network(widget.notification.messageTypeData!, loadingBuilder: (BuildContext context, Widget child, ImageChunkEvent? loadingProgress) { + if (loadingProgress == null) return child; + return Center( + child: SizedBox( + width: 40.0, + height: 40.0, + child: showLoadingAnimation(), + ), + ); + }, fit: BoxFit.fill), + ), + SizedBox(height: 18), + Text( + widget.notification.message!.trim(), + style: const TextStyle( + fontSize: 12, + fontWeight: FontWeight.w600, + color: Color(0xff575757), + letterSpacing: -0.48, + ), + ), + ], + ), + ); + } + + Widget showLoadingAnimation() { + return Lottie.asset( + 'assets/lottie/loading.json', + repeat: true, + reverse: false, + ); + } +} diff --git a/lib/ui/screens/my_requests/my_requests.dart b/lib/ui/screens/my_requests/my_requests.dart index dd6147f..4d16219 100644 --- a/lib/ui/screens/my_requests/my_requests.dart +++ b/lib/ui/screens/my_requests/my_requests.dart @@ -76,70 +76,72 @@ class _MyRequestsState extends State { }), ), 12.height, - getCCPTransactionsList.isNotEmpty ? Expanded( - child: ListView.separated( - physics: const BouncingScrollPhysics(), - shrinkWrap: true, - itemBuilder: (BuildContext context, int index) { - return Container( - width: double.infinity, - padding: const EdgeInsets.only(left: 12, right: 12, top: 10, bottom: 12), - margin: const EdgeInsets.only(left: 12, right: 12, top: 10, bottom: 0), - decoration: BoxDecoration( - color: Colors.white, - borderRadius: BorderRadius.circular(10), - boxShadow: [ - BoxShadow( - color: const Color(0xff000000).withOpacity(.05), - blurRadius: 26, - offset: const Offset(0, -3), - ), - ], - ), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Row( - crossAxisAlignment: CrossAxisAlignment.start, - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - ("Request ID: " + getCCPTransactionsList[index].rEQUESTID.toString()).toText12(color: MyColors.grey57Color), - DateUtil.formatDateToDate(DateUtil.convertStringToDate(getCCPTransactionsList[index].rEQUESTDATE!), false).toText12(color: MyColors.grey70Color), - ], - ), - Container( - padding: const EdgeInsets.only(top: 10.0), - child: ("Phase: " + getCCPTransactionsList[index].cCPPHASE!).toText12(color: MyColors.grey57Color, isBold: true), - ), - Container( - padding: const EdgeInsets.only(top: 10.0), - child: "Program Name: ".toText12(color: MyColors.grey57Color, isBold: true), - ), - getCCPTransactionsList[index].cONCURRENTPROGRAMNAME!.toText12(color: MyColors.gradiantEndColor), - Container( - padding: const EdgeInsets.only(top: 10.0), - child: InkWell( - onTap: () { - getCCPOutput(getCCPTransactionsList[index].rEQUESTID.toString()); - }, - child: Row( - children: [ - "Output: ".toText12(color: MyColors.grey57Color), - 8.width, - "Open PDF".toText12(color: MyColors.grey57Color), - 6.width, - const Icon(Icons.launch, size: 16.0), - ], - ), + getCCPTransactionsList.isNotEmpty + ? Expanded( + child: ListView.separated( + physics: const BouncingScrollPhysics(), + shrinkWrap: true, + itemBuilder: (BuildContext context, int index) { + return Container( + width: double.infinity, + padding: const EdgeInsets.only(left: 12, right: 12, top: 10, bottom: 12), + margin: const EdgeInsets.only(left: 12, right: 12, top: 10, bottom: 0), + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(10), + boxShadow: [ + BoxShadow( + color: const Color(0xff000000).withOpacity(.05), + blurRadius: 26, + offset: const Offset(0, -3), + ), + ], ), - ), - ], - ), - ); - }, - separatorBuilder: (BuildContext context, int index) => 12.height, - itemCount: getCCPTransactionsList.length), - ) : Container(), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + ("Request ID: " + getCCPTransactionsList[index].rEQUESTID.toString()).toText12(color: MyColors.grey57Color), + DateUtil.formatDateToDate(DateUtil.convertStringToDate(getCCPTransactionsList[index].rEQUESTDATE!), false).toText12(color: MyColors.grey70Color), + ], + ), + Container( + padding: const EdgeInsets.only(top: 10.0), + child: ("Phase: " + getCCPTransactionsList[index].cCPPHASE!).toText12(color: MyColors.grey57Color, isBold: true), + ), + Container( + padding: const EdgeInsets.only(top: 10.0), + child: "Program Name: ".toText12(color: MyColors.grey57Color, isBold: true), + ), + getCCPTransactionsList[index].cONCURRENTPROGRAMNAME!.toText12(color: MyColors.gradiantEndColor), + Container( + padding: const EdgeInsets.only(top: 10.0), + child: InkWell( + onTap: () { + getCCPOutput(getCCPTransactionsList[index].rEQUESTID.toString()); + }, + child: Row( + children: [ + "Output: ".toText12(color: MyColors.grey57Color), + 8.width, + "Open PDF".toText12(color: MyColors.grey57Color), + 6.width, + const Icon(Icons.launch, size: 16.0), + ], + ), + ), + ), + ], + ), + ); + }, + separatorBuilder: (BuildContext context, int index) => 12.height, + itemCount: getCCPTransactionsList.length), + ) + : Container(), ], ).expanded, 1.divider, @@ -153,7 +155,9 @@ class _MyRequestsState extends State { void openNewRequest() async { await Navigator.pushNamed(context, AppRoutes.newRequest).then((value) { - // getOpenTickets(); + if (value != null && value == "refresh") { + getCCPTransactions(selectedConcurrentProgramList?.cONCURRENTPROGRAMNAME); + } }); } diff --git a/lib/ui/screens/my_requests/new_request.dart b/lib/ui/screens/my_requests/new_request.dart index 670b18d..04d7cb4 100644 --- a/lib/ui/screens/my_requests/new_request.dart +++ b/lib/ui/screens/my_requests/new_request.dart @@ -5,12 +5,12 @@ import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:mohem_flutter_app/api/my_requests_api_client.dart'; import 'package:mohem_flutter_app/classes/utils.dart'; -import 'package:mohem_flutter_app/config/routes.dart'; import 'package:mohem_flutter_app/extensions/int_extensions.dart'; import 'package:mohem_flutter_app/extensions/string_extensions.dart'; import 'package:mohem_flutter_app/extensions/widget_extensions.dart'; import 'package:mohem_flutter_app/generated/locale_keys.g.dart'; import 'package:mohem_flutter_app/models/dyanmic_forms/validate_eit_transaction_model.dart'; +import 'package:mohem_flutter_app/models/generic_response_model.dart'; import 'package:mohem_flutter_app/models/get_eit_dff_structure_list_model.dart'; import 'package:mohem_flutter_app/models/my_requests/get_ccp_transactions_model.dart'; import 'package:mohem_flutter_app/models/my_requests/get_ccp_transations_list_model.dart'; @@ -118,14 +118,14 @@ class _NewRequestState extends State { return ValidateEitTransactionModel(dATEVALUE: dateVal, nAME: e.aPPLICATIONCOLUMNNAME, nUMBERVALUE: numberVal, tRANSACTIONNUMBER: 1, vARCHAR2VALUE: vatcherVal.toString()).toJson(); }).toList(); Utils.showLoading(context); - submitCcpTransactionList = await MyRequestsApiClient().getSubmitNewRequest(values); - getCCPTransactionsList = await MyRequestsApiClient().getCcpTransactions(values); + GenericResponseModel responseModel = await MyRequestsApiClient().getSubmitNewRequest(values); Utils.hideLoading(context); - Navigator.pushNamed( - context, - AppRoutes.myRequests, - ); - setState(() {}); + + if (responseModel.messageStatus == 1) { + Navigator.pop(context, "refresh"); + } else { + Utils.showToast(responseModel.errorEndUserMessage ?? ""); + } } catch (ex) { Utils.hideLoading(context); Utils.handleException(ex, context, null); @@ -214,13 +214,15 @@ class _NewRequestState extends State { pIDCOLUMNNAME: DateFormat('yyyy/MM/dd HH:MM:SS', "en_US").format(date1), pRETURNMSG: "null", pRETURNSTATUS: getCCPDFFStructureModelList![index].dEFAULTVALUE, - pVALUECOLUMNNAME: getCCPDFFStructureModelList![index].isDefaultTypeIsCDPS ? DateFormat('yyyy/MM/dd HH:MM:SS', "en_US").format(date) : DateFormat('yyyy-MM-ddThh:mm:ss.s').format(date)); + pVALUECOLUMNNAME: + getCCPDFFStructureModelList![index].isDefaultTypeIsCDPS ? DateFormat('yyyy/MM/dd HH:MM:SS', "en_US").format(date) : DateFormat('yyyy-MM-ddThh:mm:ss.s').format(date)); } else { eservicesdv = ESERVICESDV( pIDCOLUMNNAME: DateFormat('yyyy-MM-dd', "en_US").format(date1), pRETURNMSG: "null", pRETURNSTATUS: getCCPDFFStructureModelList![index].dEFAULTVALUE, - pVALUECOLUMNNAME: getCCPDFFStructureModelList![index].isDefaultTypeIsCDPS ? DateFormat('yyyy-MM-dd hh:mm:ss', "en_US").format(date) : DateFormat('yyyy-MM-ddThh:mm:ss.s').format(date)); + pVALUECOLUMNNAME: + getCCPDFFStructureModelList![index].isDefaultTypeIsCDPS ? DateFormat('yyyy-MM-dd hh:mm:ss', "en_US").format(date) : DateFormat('yyyy-MM-ddThh:mm:ss.s').format(date)); } getCCPDFFStructureModelList![index].eSERVICESDV = eservicesdv; setState(() {}); From ab1aa33ff3db863a8a612b1f432a726c58ccc563 Mon Sep 17 00:00:00 2001 From: haroon amjad Date: Wed, 7 Jun 2023 10:07:26 +0300 Subject: [PATCH 04/19] notifications update --- lib/classes/notifications.dart | 28 ++++++++++++++++------------ 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/lib/classes/notifications.dart b/lib/classes/notifications.dart index e29b29c..47d4acd 100644 --- a/lib/classes/notifications.dart +++ b/lib/classes/notifications.dart @@ -131,13 +131,15 @@ class AppNotifications { notification.videoURL = message.data["VideoUrl"]; } - Navigator.of(context).push( - MaterialPageRoute( - builder: (BuildContext context) => NotificationsDetailsPage( - notification: notification, + Future.delayed(Duration(seconds: 5), () { + Navigator.of(context).push( + MaterialPageRoute( + builder: (BuildContext context) => NotificationsDetailsPage( + notification: notification, + ), ), - ), - ); + ); + }); } void _handleOpenApp(RemoteMessage message) { @@ -155,13 +157,15 @@ class AppNotifications { notification.videoURL = message.data["VideoUrl"]; } - Navigator.of(context).push( - MaterialPageRoute( - builder: (BuildContext context) => NotificationsDetailsPage( - notification: notification, + Future.delayed(Duration(seconds: 5), () { + Navigator.of(context).push( + MaterialPageRoute( + builder: (BuildContext context) => NotificationsDetailsPage( + notification: notification, + ), ), - ), - ); + ); + }); } } } From c4dc3e941dbb5b7452f5c59796915ae2aa753c88 Mon Sep 17 00:00:00 2001 From: haroon amjad Date: Wed, 14 Jun 2023 14:52:52 +0300 Subject: [PATCH 05/19] auth key --- AuthKey_67L2G322GR.p8 | 6 ++++ ios/Runner.xcodeproj/project.pbxproj | 43 ++++++++++------------------ 2 files changed, 21 insertions(+), 28 deletions(-) create mode 100644 AuthKey_67L2G322GR.p8 diff --git a/AuthKey_67L2G322GR.p8 b/AuthKey_67L2G322GR.p8 new file mode 100644 index 0000000..eddd4c6 --- /dev/null +++ b/AuthKey_67L2G322GR.p8 @@ -0,0 +1,6 @@ +-----BEGIN PRIVATE KEY----- +MIGTAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBHkwdwIBAQQg+oBl9YdOiMRXfQZe +nIe6tR1tojoOvvcohNJmJtH+SsagCgYIKoZIzj0DAQehRANCAATDY9E82MAgMI/g +bKF1t4zLHJ1Yt9uoOnedNYsfyZLhh3l3ZyXRj02uDXz04AsNbNFjkLJXPc4xY9ad ++A4rY70x +-----END PRIVATE KEY----- \ No newline at end of file diff --git a/ios/Runner.xcodeproj/project.pbxproj b/ios/Runner.xcodeproj/project.pbxproj index 43841a1..073c15f 100644 --- a/ios/Runner.xcodeproj/project.pbxproj +++ b/ios/Runner.xcodeproj/project.pbxproj @@ -3,7 +3,7 @@ archiveVersion = 1; classes = { }; - objectVersion = 51; + objectVersion = 54; objects = { /* Begin PBXBuildFile section */ @@ -144,7 +144,6 @@ 9705A1C41CF9048500538489 /* Embed Frameworks */, 3B06AD1E1E4923F5004D2608 /* Thin Binary */, C4CFBC4C5CAC00182015ACD5 /* [CP] Embed Pods Frameworks */, - 1C704830960BB41251F31356 /* [CP] Copy Pods Resources */, ); buildRules = ( ); @@ -204,23 +203,6 @@ /* End PBXResourcesBuildPhase section */ /* Begin PBXShellScriptBuildPhase section */ - 1C704830960BB41251F31356 /* [CP] Copy Pods Resources */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputFileListPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources-${CONFIGURATION}-input-files.xcfilelist", - ); - name = "[CP] Copy Pods Resources"; - outputFileListPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources-${CONFIGURATION}-output-files.xcfilelist", - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources.sh\"\n"; - showEnvVarsInLog = 0; - }; 2D06B7AD3B87C9C9059E4168 /* [CP] Check Pods Manifest.lock */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; @@ -245,6 +227,7 @@ }; 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = { isa = PBXShellScriptBuildPhase; + alwaysOutOfDate = 1; buildActionMask = 2147483647; files = ( ); @@ -259,6 +242,7 @@ }; 9740EEB61CF901F6004384FC /* Run Script */ = { isa = PBXShellScriptBuildPhase; + alwaysOutOfDate = 1; buildActionMask = 2147483647; files = ( ); @@ -382,17 +366,18 @@ CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + CURRENT_PROJECT_VERSION = 1; DEVELOPMENT_TEAM = 99Z3UD3LJM; ENABLE_BITCODE = NO; INFOPLIST_FILE = Runner/Info.plist; INFOPLIST_KEY_CFBundleDisplayName = Mohemm; - IPHONEOS_DEPLOYMENT_TARGET = 12.0; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", ); - PRODUCT_BUNDLE_IDENTIFIER = com.cloudsolutions.mohemmtest; + MARKETING_VERSION = 3.7.2; + PRODUCT_BUNDLE_IDENTIFIER = com.cloudsolutions.mohemm; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; @@ -519,17 +504,18 @@ CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + CURRENT_PROJECT_VERSION = 1; DEVELOPMENT_TEAM = 99Z3UD3LJM; ENABLE_BITCODE = NO; INFOPLIST_FILE = Runner/Info.plist; INFOPLIST_KEY_CFBundleDisplayName = Mohemm; - IPHONEOS_DEPLOYMENT_TARGET = 12.0; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", ); - PRODUCT_BUNDLE_IDENTIFIER = com.cloudsolutions.mohemmtest; + MARKETING_VERSION = 3.7.2; + PRODUCT_BUNDLE_IDENTIFIER = com.cloudsolutions.mohemm; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; @@ -548,17 +534,18 @@ CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + CURRENT_PROJECT_VERSION = 1; DEVELOPMENT_TEAM = 99Z3UD3LJM; ENABLE_BITCODE = NO; INFOPLIST_FILE = Runner/Info.plist; INFOPLIST_KEY_CFBundleDisplayName = Mohemm; - IPHONEOS_DEPLOYMENT_TARGET = 12.0; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", ); - PRODUCT_BUNDLE_IDENTIFIER = com.cloudsolutions.mohemmtest; + MARKETING_VERSION = 3.7.2; + PRODUCT_BUNDLE_IDENTIFIER = com.cloudsolutions.mohemm; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; From 15c8e807994490e3e2973391d866a639892b5056 Mon Sep 17 00:00:00 2001 From: haroon amjad Date: Wed, 12 Jul 2023 17:00:43 +0300 Subject: [PATCH 06/19] ERM Video fixes --- ios/Runner/Info.plist | 2 + lib/classes/utils.dart | 11 +++ .../itg/its_add_screen_video_image.dart | 70 +++++++++++++------ .../dynamic_screens/dynamic_input_screen.dart | 13 ++-- 4 files changed, 72 insertions(+), 24 deletions(-) diff --git a/ios/Runner/Info.plist b/ios/Runner/Info.plist index 75c680b..8108c0a 100644 --- a/ios/Runner/Info.plist +++ b/ios/Runner/Info.plist @@ -91,5 +91,7 @@ TAG + UIApplicationSupportsIndirectInputEvents + diff --git a/lib/classes/utils.dart b/lib/classes/utils.dart index 34831c2..1838cb8 100644 --- a/lib/classes/utils.dart +++ b/lib/classes/utils.dart @@ -401,4 +401,15 @@ class Utils { } return false; } + + static bool isDate(String input, String format) { + try { + DateTime d = DateFormat(format).parseStrict(input); + //print(d); + return true; + } catch (e) { + //print(e); + return false; + } + } } diff --git a/lib/ui/landing/itg/its_add_screen_video_image.dart b/lib/ui/landing/itg/its_add_screen_video_image.dart index 61b2766..160f773 100644 --- a/lib/ui/landing/itg/its_add_screen_video_image.dart +++ b/lib/ui/landing/itg/its_add_screen_video_image.dart @@ -39,6 +39,12 @@ class _ITGAdsScreenState extends State { String? masterID; int videoDuration = 0; + bool hasTimerEndedBool = false; + + final ValueNotifier hasTimerEnded = ValueNotifier(false); + + late CountdownTimerController timerController; + void checkFileType() async { String? rFile = advertisementData!.viewAttachFileColl!.first.base64String; String? rFileExt = advertisementData!.viewAttachFileColl!.first.fileName; @@ -56,6 +62,17 @@ class _ITGAdsScreenState extends State { setState(() {}); } + void changeTimer(bool isTimerEnd) { + hasTimerEndedBool = isTimerEnd; + hasTimerEnded.value = !hasTimerEnded.value; + } + + void onTimerEnd() { + changeTimer(true); + timerController.disposeTimer(); + timerController.dispose(); + } + Future processImage(String encodedBytes) async { try { Uint8List decodedBytes = base64Decode(encodedBytes.split("base64,").last); @@ -69,18 +86,20 @@ class _ITGAdsScreenState extends State { Future createVideoPlayer(String encodedBytes) async { try { - Uint8List decodedBytes = base64Decode(encodedBytes.split("base64,").last); - Directory appDocumentsDirectory = await getApplicationDocumentsDirectory(); // 1 - File file = Io.File("${appDocumentsDirectory.path}/myAdsVideo.mp4"); - file.writeAsBytesSync(decodedBytes); - VideoPlayerController controller = VideoPlayerController.file(file); + // Uint8List decodedBytes = base64Decode(encodedBytes.split("base64,").last); + // Directory appDocumentsDirectory = await getApplicationDocumentsDirectory(); // 1 + // File file = Io.File("${appDocumentsDirectory.path}/myAdsVideo.mp4"); + // file.writeAsBytesSync(decodedBytes); + // VideoPlayerController controller = VideoPlayerController.file(file); + VideoPlayerController controller = VideoPlayerController.network(advertisementData!.viewAttachFileColl!.first.base64String!); await controller.initialize(); await controller.play(); await controller.setVolume(1.0); await controller.setLooping(false); return controller; } catch (e) { - return VideoPlayerController.asset("dataSource"); + print(e); + return VideoPlayerController.network("https://apimohemmweb.cloudsolutions.com.sa/ErmAttachment/compressedvideo.mp4"); } } @@ -107,6 +126,7 @@ class _ITGAdsScreenState extends State { if (advertisementData != null) { checkFileType(); videoDuration = advertisementData?.durationInSeconds ?? 0; + timerController = CountdownTimerController(endTime: DateTime.now().millisecondsSinceEpoch + 1000 * videoDuration, onEnd: onTimerEnd); } return Scaffold( backgroundColor: Colors.black, @@ -131,24 +151,34 @@ class _ITGAdsScreenState extends State { ), 30.height, CountdownTimer( + controller: timerController, endTime: DateTime.now().millisecondsSinceEpoch + 1000 * videoDuration, - onEnd: null, - endWidget: "00:00:00".toText14(color: Colors.white, isBold: true), + endWidget: "00:00:00".toText16(color: Colors.white, isBold: true), textStyle: const TextStyle(color: Colors.white, fontSize: 16, letterSpacing: -0.48, fontWeight: FontWeight.bold), ), 50.height, - Container(padding: const EdgeInsets.all(16), decoration: Utils.containerRadius(MyColors.white, 10), child: const Icon(Icons.thumb_up, color: MyColors.gradiantEndColor)) - .onPress(() { - try { - DashboardApiClient().setAdvertisementViewed(masterID!, advertisementData!.advertisementId!).then((value) { - logger.d(value); - Navigator.pop(context); - }); - } catch (ex) { - logger.wtf(ex); - Utils.handleException(ex, context, null); - } - }), + ValueListenableBuilder( + valueListenable: hasTimerEnded, + builder: (context, val, child) { + if (hasTimerEndedBool) { + return Container( + padding: const EdgeInsets.all(16), decoration: Utils.containerRadius(MyColors.white, 10), child: const Icon(Icons.thumb_up, color: MyColors.gradiantEndColor)) + .onPress(() { + try { + DashboardApiClient().setAdvertisementViewed(masterID!, advertisementData!.advertisementId!).then((value) { + logger.d(value); + Navigator.pop(context); + }); + } catch (ex) { + logger.wtf(ex); + Utils.handleException(ex, context, null); + } + }); + } else { + return Container(); + } + }), + // DefaultButton(LocaleKeys.home.tr(), () async { // DashboardApiClient().setAdvertisementViewed(masterID!, advertisementData!.advertisementId!).then((value) { // logger.d(value); diff --git a/lib/ui/my_attendance/dynamic_screens/dynamic_input_screen.dart b/lib/ui/my_attendance/dynamic_screens/dynamic_input_screen.dart index bd9305d..3e75813 100644 --- a/lib/ui/my_attendance/dynamic_screens/dynamic_input_screen.dart +++ b/lib/ui/my_attendance/dynamic_screens/dynamic_input_screen.dart @@ -340,10 +340,15 @@ class _DynamicInputScreenState extends State { idColName = val; if (getEitDffStructureList![j].fORMATTYPE == "X") { - idColName = Utils.formatDateDefault(idColName!); - // commenting to test - // DateTime date = DateFormat('yyyy-MM-dd').parse(idColName!); - // idColName = DateFormat('yyyy-MM-dd HH:mm:ss').format(date); + idColName = Utils.reverseFormatDate(idColName!); + if (Utils.isDate(Utils.reverseFormatDate(Utils.formatDateNew(idColName)), "yyyy-MM-dd")) { + idColName = Utils.formatStandardDate(Utils.formatStandardDate(Utils.formatDateNew(idColName))); + // idColName = DateFormat('yyyy/MM/dd HH:mm:ss').format(date); + } else if (Utils.isDate(Utils.reverseFormatDate(idColName), "dd-MM-yyyy")) { + // // change date format on 31/05/2023 + DateTime date = DateFormat('dd-MM-yyyy').parse(idColName); + idColName = DateFormat('yyyy-MM-dd HH:mm:ss').format(date); + } } } From 4aa35349e1bfa2a112a8d98e818cbe77209e0011 Mon Sep 17 00:00:00 2001 From: haroon amjad Date: Mon, 17 Jul 2023 09:49:07 +0300 Subject: [PATCH 07/19] VersionID Update --- lib/app_state/app_state.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/app_state/app_state.dart b/lib/app_state/app_state.dart index 7ccdd4f..f59994c 100644 --- a/lib/app_state/app_state.dart +++ b/lib/app_state/app_state.dart @@ -90,7 +90,7 @@ class AppState { String get getHuaweiPushToken => _huaweiPushToken; - final PostParamsModel _postParamsInitConfig = PostParamsModel(channel: 31, versionID: 4.8, mobileType: Platform.isAndroid ? "android" : "ios"); + final PostParamsModel _postParamsInitConfig = PostParamsModel(channel: 31, versionID: 4.9, mobileType: Platform.isAndroid ? "android" : "ios"); void setPostParamsInitConfig() { isAuthenticated = false; From 13c5b49fc2f9fe9136d6724357d0a5bf46fb45d6 Mon Sep 17 00:00:00 2001 From: haroon amjad Date: Mon, 17 Jul 2023 10:03:11 +0300 Subject: [PATCH 08/19] info plist --- ios/Runner/Info.plist | 35 ++++++++++++++++++----------------- 1 file changed, 18 insertions(+), 17 deletions(-) diff --git a/ios/Runner/Info.plist b/ios/Runner/Info.plist index 8108c0a..24ba08c 100644 --- a/ios/Runner/Info.plist +++ b/ios/Runner/Info.plist @@ -2,15 +2,6 @@ - NSAppTransportSecurity - - NSAllowsArbitraryLoads - - NSAllowsArbitraryLoadsForMedia - - NSAllowsArbitraryLoadsInWebContent - - CADisableMinimumFrameDurationOnPhone CFBundleDevelopmentRegion @@ -31,6 +22,10 @@ ???? CFBundleVersion $(FLUTTER_BUILD_NUMBER) + FirebaseAppDelegateProxyEnabled + + ITSAppUsesNonExemptEncryption + LSApplicationQueriesSchemes sms @@ -41,6 +36,15 @@ NFCReaderUsageDescription This App requires access to NFC to mark your attendance. + NSAppTransportSecurity + + NSAllowsArbitraryLoads + + NSAllowsArbitraryLoadsForMedia + + NSAllowsArbitraryLoadsInWebContent + + NSCameraUsageDescription This app requires camera access to capture & upload picture as profile image. NSFaceIDUsageDescription @@ -51,17 +55,18 @@ This App requires access to your location to mark your attendance. NSLocationWhenInUseUsageDescription This App requires access to your location to mark your attendance. - NSPhotoLibraryUsageDescription - This app requires photo library access to select image as document & upload it. NSMicrophoneUsageDescription This app requires microphone access to for call. + NSPhotoLibraryUsageDescription + This app requires photo library access to select image as document & upload it. + UIApplicationSupportsIndirectInputEvents + UIBackgroundModes fetch remote-notification + voip - FirebaseAppDelegateProxyEnabled - UILaunchStoryboardName LaunchScreen UIMainStoryboardFile @@ -85,13 +90,9 @@ 0000 - ITSAppUsesNonExemptEncryption - com.apple.developer.nfc.readersession.formats TAG - UIApplicationSupportsIndirectInputEvents - From 59116b700ab8d3138d5b0e6824bd698270b0847a Mon Sep 17 00:00:00 2001 From: haroon amjad Date: Tue, 18 Jul 2023 10:47:21 +0300 Subject: [PATCH 09/19] Location check added --- lib/classes/consts.dart | 4 +- lib/widgets/location/Location.dart | 2 +- lib/widgets/mark_attendance_widget.dart | 179 +++++++++++++++++------- 3 files changed, 134 insertions(+), 51 deletions(-) diff --git a/lib/classes/consts.dart b/lib/classes/consts.dart index 32b3fc7..45ef661 100644 --- a/lib/classes/consts.dart +++ b/lib/classes/consts.dart @@ -3,8 +3,8 @@ import 'package:mohem_flutter_app/ui/marathon/widgets/question_card.dart'; class ApiConsts { //static String baseUrl = "http://10.200.204.20:2801/"; // Local server // static String baseUrl = "https://erptstapp.srca.org.sa"; // SRCA server - static String baseUrl = "https://uat.hmgwebservices.com"; // UAT server - // static String baseUrl = "https://hmgwebservices.com"; // Live server + // static String baseUrl = "https://uat.hmgwebservices.com"; // UAT server + static String baseUrl = "https://hmgwebservices.com"; // Live server static String baseUrlServices = baseUrl + "/Services/"; // server // static String baseUrlServices = "https://api.cssynapses.com/tangheem/"; // Live server static String utilitiesRest = baseUrlServices + "Utilities.svc/REST/"; diff --git a/lib/widgets/location/Location.dart b/lib/widgets/location/Location.dart index 62bd016..e324618 100644 --- a/lib/widgets/location/Location.dart +++ b/lib/widgets/location/Location.dart @@ -8,7 +8,7 @@ import 'package:mohem_flutter_app/classes/utils.dart'; class Location { static void havePermission(Function(bool) callback) { Geolocator.checkPermission().then((value) async { - if (value == LocationPermission.denied) { + if (value == LocationPermission.denied || value == LocationPermission.deniedForever) { value = await Geolocator.requestPermission(); callback(![LocationPermission.denied, LocationPermission.deniedForever].contains(value)); } else { diff --git a/lib/widgets/mark_attendance_widget.dart b/lib/widgets/mark_attendance_widget.dart index f11fafe..dfb4357 100644 --- a/lib/widgets/mark_attendance_widget.dart +++ b/lib/widgets/mark_attendance_widget.dart @@ -54,8 +54,6 @@ class _MarkAttendanceWidgetState extends State { } void checkAttendanceAvailability() async { - String? deviceID = await PlatformDeviceId.getDeviceId; - print("Platform Device ID: $deviceID"); bool isAvailable = await NfcManager.instance.isAvailable(); setState(() { AppState().privilegeListModel!.forEach((PrivilegeListModel element) { @@ -124,7 +122,7 @@ class _MarkAttendanceWidgetState extends State { mainAxisSize: MainAxisSize.min, children: [ LocaleKeys.markAttendance.tr().toSectionHeading(), - LocaleKeys.selectMethodOfAttendance.tr().tr().toText11(color: const Color(0xff535353)), + LocaleKeys.selectMethodOfAttendance.tr().toText11(color: const Color(0xff535353)), GridView( physics: const NeverScrollableScrollPhysics(), shrinkWrap: true, @@ -132,60 +130,145 @@ class _MarkAttendanceWidgetState extends State { gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: (MediaQuery.of(context).size.width < 550) ? 3 : 5, childAspectRatio: 1 / 1, crossAxisSpacing: 8, mainAxisSpacing: 8), children: [ - // if (isNfcEnabled) attendanceMethod("NFC", "assets/images/nfc.svg", isNfcEnabled, () { - // if (isNfcLocationEnabled) { + if (AppState().getIsHuawei) { + checkHuaweiLocationPermission("NFC"); + } else { + Location.isEnabled((bool isEnabled) { + if (isEnabled) { + Location.havePermission((bool permission) { + if (permission) { + Location.getCurrentLocation( + (Position position, bool isMocked) { + if (isMocked) { + markFakeAttendance("NFC", position.latitude.toString() ?? "", position.longitude.toString() ?? ""); + } else { + performNfcAttendance(widget.model, lat: position.latitude.toString() ?? "", lng: position.longitude.toString() ?? ""); + } + }, + context, + ); + } else { + showDialog( + context: context, + builder: (BuildContext cxt) => ConfirmDialog( + message: "You need to give location permission to mark attendance", + onTap: () async { + Navigator.pop(context); + await Geolocator.openAppSettings(); + }, + ), + ); + } + }); + } else { + showDialog( + context: context, + builder: (BuildContext cxt) => ConfirmDialog( + message: "You need to enable location services to mark attendance", + onTap: () async { + Navigator.pop(context); + await Geolocator.openLocationSettings(); + }, + ), + ); + } + }); + } + }), + if (isWifiEnabled) + attendanceMethod("Wifi", "assets/images/wufu.svg", isWifiEnabled, () { if (AppState().getIsHuawei) { - checkHuaweiLocationPermission("NFC"); + checkHuaweiLocationPermission("WIFI"); } else { - Location.getCurrentLocation((Position position, bool isMocked) { - if (isMocked) { - markFakeAttendance("NFC", position.latitude.toString() ?? "", position.longitude.toString() ?? ""); + Location.isEnabled((bool isEnabled) { + if (isEnabled) { + Location.havePermission((bool permission) { + if (permission) { + Location.getCurrentLocation( + (Position position, bool isMocked) { + if (isMocked) { + markFakeAttendance("WIFI", position.latitude.toString() ?? "", position.longitude.toString() ?? ""); + } else { + performWifiAttendance(widget.model, lat: position.latitude.toString() ?? "", lng: position.longitude.toString() ?? ""); + } + }, + context, + ); + } else { + showDialog( + context: context, + builder: (BuildContext cxt) => ConfirmDialog( + message: "You need to give location permission to mark attendance", + onTap: () async { + Navigator.pop(context); + await Geolocator.openAppSettings(); + }, + ), + ); + } + }); } else { - performNfcAttendance(widget.model, lat: position.latitude.toString() ?? "", lng: position.longitude.toString() ?? ""); + showDialog( + context: context, + builder: (BuildContext cxt) => ConfirmDialog( + message: "You need to enable location services to mark attendance", + onTap: () async { + Navigator.pop(context); + await Geolocator.openLocationSettings(); + }, + ), + ); } - }, context); + }); } - // } else { - // performNfcAttendance(widget.model); - // } - }), - if (isWifiEnabled) - attendanceMethod("Wifi", "assets/images/wufu.svg", isWifiEnabled, () { - // if (isWifiLocationEnabled) { - if (AppState().getIsHuawei) { - checkHuaweiLocationPermission("WIFI"); - } else { - Location.getCurrentLocation((Position position, bool isMocked) { - if (isMocked) { - markFakeAttendance("WIFI", position.latitude.toString() ?? "", position.longitude.toString() ?? ""); - } else { - performWifiAttendance(widget.model, lat: position.latitude.toString() ?? "", lng: position.longitude.toString() ?? ""); - } - }, context); - } - // } else { - // performWifiAttendance(widget.model); - // } }), if (isQrEnabled) attendanceMethod("QR", "assets/images/ic_qr.svg", isQrEnabled, () async { - // if (isQrLocationEnabled) { - if (AppState().getIsHuawei) { - checkHuaweiLocationPermission("QR"); - } else { - Location.getCurrentLocation((Position position, bool isMocked) { - if (isMocked) { - markFakeAttendance("QR", position.latitude.toString() ?? "", position.longitude.toString() ?? ""); - } else { - performQrCodeAttendance(widget.model, lat: position.latitude.toString() ?? "", lng: position.longitude.toString() ?? ""); - } - }, context); - } - // } else { - // performQrCodeAttendance(widget.model); - // } - // performQrCodeAttendance(model); + if (AppState().getIsHuawei) { + checkHuaweiLocationPermission("QR"); + } else { + Location.isEnabled((bool isEnabled) { + if (isEnabled) { + Location.havePermission((bool permission) { + if (permission) { + Location.getCurrentLocation( + (Position position, bool isMocked) { + if (isMocked) { + markFakeAttendance("QR", position.latitude.toString() ?? "", position.longitude.toString() ?? ""); + } else { + performQrCodeAttendance(widget.model, lat: position.latitude.toString() ?? "", lng: position.longitude.toString() ?? ""); + } + }, + context, + ); + } else { + showDialog( + context: context, + builder: (BuildContext cxt) => ConfirmDialog( + message: "You need to give location permission to mark attendance", + onTap: () async { + Navigator.pop(context); + await Geolocator.openAppSettings(); + }, + ), + ); + } + }); + } else { + showDialog( + context: context, + builder: (BuildContext cxt) => ConfirmDialog( + message: "You need to enable location services to mark attendance", + onTap: () async { + Navigator.pop(context); + await Geolocator.openLocationSettings(); + }, + ), + ); + } + }); + } }), ], ) From 1a8db3b0eec0632a22f40a4145616f94a87cb92d Mon Sep 17 00:00:00 2001 From: haroon amjad Date: Thu, 27 Jul 2023 14:56:13 +0300 Subject: [PATCH 10/19] ERM Channel updates --- android/build.gradle | 2 +- lib/api/dashboard_api_client.dart | 6 +- lib/models/itg/advertisement.dart | 9 ++ .../itg/its_add_screen_video_image.dart | 94 ++++++++++--------- 4 files changed, 65 insertions(+), 46 deletions(-) diff --git a/android/build.gradle b/android/build.gradle index 7991b9d..dc67123 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -1,5 +1,5 @@ buildscript { - ext.kotlin_version = '1.6.0' + ext.kotlin_version = '1.7.20' repositories { google() mavenCentral() diff --git a/lib/api/dashboard_api_client.dart b/lib/api/dashboard_api_client.dart index dfa4801..544ba71 100644 --- a/lib/api/dashboard_api_client.dart +++ b/lib/api/dashboard_api_client.dart @@ -201,13 +201,15 @@ class DashboardApiClient { }, url, postParams); } - Future setAdvertisementViewed(String masterID, int advertisementId) async { + Future setAdvertisementViewed(String masterID, int advertisementId, String ackValue) async { String url = "${ApiConsts.cocRest}Mohemm_ITG_UpdateAdvertisementAsViewed"; Map postParams = { "ItgNotificationMasterId": masterID, "EmployeeNumber": AppState().memberInformationList!.eMPLOYEENUMBER.toString(), - "ItgAdvertisement": {"advertisementId": advertisementId, "acknowledgment": true} //Mobile Id + "ItgAdvertisementId": advertisementId, + "ItgAcknowledgment": ackValue, + // "ItgAdvertisement": {"ItgAdvertisementId": advertisementId, "ItgAcknowledgment": ackValue} //Mobile Id }; postParams.addAll(AppState().postParamsJson); return await ApiClient().postJsonForObject((json) { diff --git a/lib/models/itg/advertisement.dart b/lib/models/itg/advertisement.dart index 598a248..96f4037 100644 --- a/lib/models/itg/advertisement.dart +++ b/lib/models/itg/advertisement.dart @@ -10,6 +10,9 @@ class Advertisement { this.pageSize, this.pageNo, this.languageId, + this.isOptional, + this.skipButtonTextEn, + this.skipButtonTextAr, }); final int? advertisementId; @@ -22,6 +25,9 @@ class Advertisement { final dynamic pageSize; final dynamic pageNo; final dynamic languageId; + final bool? isOptional; + final String? skipButtonTextEn; + final String? skipButtonTextAr; factory Advertisement.fromJson(Map json) => Advertisement( advertisementId: json["advertisementId"] == null ? null : json["advertisementId"], @@ -34,6 +40,9 @@ class Advertisement { pageSize: json["pageSize"], pageNo: json["pageNo"], languageId: json["languageId"], + isOptional: json["isOptional"] == null ? null : json["isOptional"], + skipButtonTextEn: json["skipBtnTextEn"] == null ? null : json["skipBtnTextEn"], + skipButtonTextAr: json["skipBtnTextAr"] == null ? null : json["skipBtnTextAr"], ); Map toJson() => { diff --git a/lib/ui/landing/itg/its_add_screen_video_image.dart b/lib/ui/landing/itg/its_add_screen_video_image.dart index 160f773..1e280d8 100644 --- a/lib/ui/landing/itg/its_add_screen_video_image.dart +++ b/lib/ui/landing/itg/its_add_screen_video_image.dart @@ -7,6 +7,7 @@ import 'package:flutter/material.dart'; import 'package:flutter_countdown_timer/index.dart'; import 'package:lottie/lottie.dart'; import 'package:mohem_flutter_app/api/dashboard_api_client.dart'; +import 'package:mohem_flutter_app/app_state/app_state.dart'; import 'package:mohem_flutter_app/classes/colors.dart'; import 'package:mohem_flutter_app/classes/lottie_consts.dart'; import 'package:mohem_flutter_app/classes/utils.dart'; @@ -15,6 +16,7 @@ import 'package:mohem_flutter_app/extensions/string_extensions.dart'; import 'package:mohem_flutter_app/extensions/widget_extensions.dart'; import 'package:mohem_flutter_app/main.dart'; import 'package:mohem_flutter_app/models/itg/advertisement.dart' as ads; +import 'package:mohem_flutter_app/widgets/button/default_button.dart'; import 'package:path_provider/path_provider.dart'; import 'package:video_player/video_player.dart'; @@ -86,11 +88,6 @@ class _ITGAdsScreenState extends State { Future createVideoPlayer(String encodedBytes) async { try { - // Uint8List decodedBytes = base64Decode(encodedBytes.split("base64,").last); - // Directory appDocumentsDirectory = await getApplicationDocumentsDirectory(); // 1 - // File file = Io.File("${appDocumentsDirectory.path}/myAdsVideo.mp4"); - // file.writeAsBytesSync(decodedBytes); - // VideoPlayerController controller = VideoPlayerController.file(file); VideoPlayerController controller = VideoPlayerController.network(advertisementData!.viewAttachFileColl!.first.base64String!); await controller.initialize(); await controller.play(); @@ -113,8 +110,6 @@ class _ITGAdsScreenState extends State { @override void dispose() { if (_controller != null) _controller.dispose(); - // player.stop(); - // player.dispose(); super.dispose(); } @@ -158,41 +153,54 @@ class _ITGAdsScreenState extends State { ), 50.height, ValueListenableBuilder( - valueListenable: hasTimerEnded, - builder: (context, val, child) { - if (hasTimerEndedBool) { - return Container( - padding: const EdgeInsets.all(16), decoration: Utils.containerRadius(MyColors.white, 10), child: const Icon(Icons.thumb_up, color: MyColors.gradiantEndColor)) - .onPress(() { - try { - DashboardApiClient().setAdvertisementViewed(masterID!, advertisementData!.advertisementId!).then((value) { - logger.d(value); + valueListenable: hasTimerEnded, + builder: (context, val, child) { + if (hasTimerEndedBool) { + return Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Container( + padding: const EdgeInsets.all(16), decoration: Utils.containerRadius(MyColors.white, 10), child: const Icon(Icons.thumb_up, color: MyColors.gradiantEndColor)) + .onPress(() { + try { Navigator.pop(context); - }); - } catch (ex) { - logger.wtf(ex); - Utils.handleException(ex, context, null); - } - }); - } else { - return Container(); - } - }), - - // DefaultButton(LocaleKeys.home.tr(), () async { - // DashboardApiClient().setAdvertisementViewed(masterID!, advertisementData!.advertisementId!).then((value) { - // logger.d(value); - // }); - // }).paddingOnly(left: 50, right: 50) - - // ElevatedButton( - // onPressed: () async { - // // DashboardApiClient().setAdvertisementViewed(widget.addMasterId, widget.advertisement!.advertisementId!).then((value) { - // // logger.d(value); - // // }); - // }, - // child: const Text("Go To Dashboard"), - // ) + DashboardApiClient().setAdvertisementViewed(masterID!, advertisementData!.advertisementId!, "Like").then((value) { + logger.d(value); + }); + } catch (ex) { + logger.wtf(ex); + Utils.handleException(ex, context, null); + } + }), + 20.width, + Container( + padding: const EdgeInsets.all(16), decoration: Utils.containerRadius(MyColors.white, 10), child: const Icon(Icons.thumb_down, color: MyColors.gradiantEndColor)) + .onPress(() { + try { + Navigator.pop(context); + DashboardApiClient().setAdvertisementViewed(masterID!, advertisementData!.advertisementId!, "Dislike").then((value) { + logger.d(value); + }); + } catch (ex) { + logger.wtf(ex); + Utils.handleException(ex, context, null); + } + }), + ], + ); + } else { + return Container(); + } + }, + ), + 20.height, + if (advertisementData?.isOptional ?? false) + DefaultButton(AppState().isArabic(context) ? advertisementData?.skipButtonTextAr ?? "Skip" : advertisementData?.skipButtonTextEn ?? "Skip", () async { + Navigator.pop(context); + DashboardApiClient().setAdvertisementViewed(masterID!, advertisementData!.advertisementId!, "Skip").then((value) { + logger.d(value); + }); + }).paddingOnly(left: 100, right: 100) ], ); } else { @@ -212,9 +220,9 @@ class _ITGAdsScreenState extends State { Container(padding: const EdgeInsets.all(16), decoration: Utils.containerRadius(MyColors.white, 10), child: const Icon(Icons.thumb_up, color: MyColors.gradiantEndColor)).onPress( () { try { - DashboardApiClient().setAdvertisementViewed(masterID!, advertisementData!.advertisementId!).then((value) { + Navigator.pop(context); + DashboardApiClient().setAdvertisementViewed(masterID!, advertisementData!.advertisementId!, "Like").then((value) { logger.d(value); - Navigator.pop(context); }); } catch (ex) { logger.wtf(ex); From 23b4e8117070a8547e3f6b4161433106b729790f Mon Sep 17 00:00:00 2001 From: Sikander Saleem Date: Tue, 8 Aug 2023 15:14:17 +0300 Subject: [PATCH 11/19] my documents added. --- assets/images/cancel_button.svg | 9 + assets/images/document.svg | 4 + assets/langs/ar-SA.json | 9 +- assets/langs/en-US.json | 9 +- lib/api/profile_api_client.dart | 14 ++ lib/classes/colors.dart | 2 + lib/classes/utils.dart | 2 +- lib/config/routes.dart | 7 +- lib/generated/codegen_loader.g.dart | 18 +- lib/generated/locale_keys.g.dart | 7 + lib/models/generic_response_model.dart | 26 ++- .../employee_documents_list_model.dart | 29 +++ lib/provider/dashboard_provider_model.dart | 1 + lib/ui/landing/widget/services_widget.dart | 13 +- lib/ui/misc/request_submit_screen.dart | 12 +- .../dynamic_screens/dynamic_input_screen.dart | 13 +- .../dynamic_listview_screen.dart | 3 +- .../my_document_detail_screen.dart | 174 ++++++++++++++++++ .../my_documents/my_documents_fragment.dart | 157 ++++++++++++++++ .../my_documents/my_documents_screen.dart | 132 +++++++++++++ lib/widgets/my_document_item.dart | 76 ++++++++ pubspec.yaml | 3 + 22 files changed, 700 insertions(+), 20 deletions(-) create mode 100644 assets/images/cancel_button.svg create mode 100644 assets/images/document.svg create mode 100644 lib/models/my_documents/employee_documents_list_model.dart create mode 100644 lib/ui/screens/my_documents/my_document_detail_screen.dart create mode 100644 lib/ui/screens/my_documents/my_documents_fragment.dart create mode 100644 lib/ui/screens/my_documents/my_documents_screen.dart create mode 100644 lib/widgets/my_document_item.dart diff --git a/assets/images/cancel_button.svg b/assets/images/cancel_button.svg new file mode 100644 index 0000000..2aba62a --- /dev/null +++ b/assets/images/cancel_button.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/assets/images/document.svg b/assets/images/document.svg new file mode 100644 index 0000000..ca0e83f --- /dev/null +++ b/assets/images/document.svg @@ -0,0 +1,4 @@ + + + + diff --git a/assets/langs/ar-SA.json b/assets/langs/ar-SA.json index 4b7acc9..48f443e 100644 --- a/assets/langs/ar-SA.json +++ b/assets/langs/ar-SA.json @@ -530,5 +530,12 @@ "connectHmgWifi": "قم بتوصيل HMG WIFI", "connectedHmgWifi": "اتصال HMG WIFI", "itgForms": "نماذج (ITG)", - "resetAdPassword": "إعادة تعيين كلمة مرور AD" + "resetAdPassword": "إعادة تعيين كلمة مرور AD", + "myDocuments": "مستنداتي", + "requiredDocuments": "المستندات المطلوبة", + "optionalDocuments": "المستندات الاختيارية", + "allDocuments": "كافة المستندات", + "expiredDocuments": "المستندات منتهية الصلاحية", + "missingDocuments": "مستندات مفقودة", + "uploadedDocuments": "المستندات التي تم تحميلها" } \ No newline at end of file diff --git a/assets/langs/en-US.json b/assets/langs/en-US.json index 3f460a1..b005710 100644 --- a/assets/langs/en-US.json +++ b/assets/langs/en-US.json @@ -530,5 +530,12 @@ "connectHmgWifi": "Connect HMG WIFI", "connectedHmgWifi": "Connected HMG WIFI", "itgForms": "ITG Forms", - "resetAdPassword": "Reset AD Password" + "resetAdPassword": "Reset AD Password", + "myDocuments": "My Documents", + "requiredDocuments": "Required Documents", + "optionalDocuments": "Optional Documents", + "allDocuments": "All\nDocuments", + "expiredDocuments": "Expired\nDocuments", + "missingDocuments": "Missing\nDocuments", + "uploadedDocuments": "Uploaded\nDocuments" } \ No newline at end of file diff --git a/lib/api/profile_api_client.dart b/lib/api/profile_api_client.dart index 6a8cfb0..030a949 100644 --- a/lib/api/profile_api_client.dart +++ b/lib/api/profile_api_client.dart @@ -12,6 +12,7 @@ import 'package:mohem_flutter_app/models/get_employee_address_model.dart'; import 'package:mohem_flutter_app/models/get_employee_basic_details.model.dart'; import 'package:mohem_flutter_app/models/get_employee_contacts.model.dart'; import 'package:mohem_flutter_app/models/get_employee_phones_model.dart'; +import 'package:mohem_flutter_app/models/my_documents/employee_documents_list_model.dart'; import 'package:mohem_flutter_app/models/performance.dart'; import 'package:mohem_flutter_app/models/profile/basic_details_dff_structure.dart'; import 'package:mohem_flutter_app/models/profile/get_contact_clos_structure_list.dart'; @@ -84,6 +85,19 @@ class ProfileApiClient { }, url, postParams); } + Future> getEmployeeDocuments() async { + String url = "${ApiConsts.erpRest}GET_EMPLOYEE_DOCUMENTS"; + Map postParams = { + "P_MENU_TYPE": "E", + "P_SELECTED_RESP_ID": -999, + }; + postParams.addAll(AppState().postParamsJson); + return await ApiClient().postJsonForObject((json) { + GenericResponseModel? responseData = GenericResponseModel.fromJson(json); + return responseData.employeeDocumentsList ?? []; + }, url, postParams); + } + Future updateEmpImage(img) async { String url = "${ApiConsts.erpRest}UPDATE_EMPLOYEE_IMAGE"; Map postParams = {"P_MENU_TYPE": "E", "P_SELECTED_RESP_ID": -999, "P_IMAGE": img}; diff --git a/lib/classes/colors.dart b/lib/classes/colors.dart index 5c9b30e..915f35d 100644 --- a/lib/classes/colors.dart +++ b/lib/classes/colors.dart @@ -35,6 +35,7 @@ class MyColors { static const Color orange = Color(0xFFCC9B14); static const Color yellowFavColor = Color(0xffEAC321); static const Color yellowColorII = Color(0xffEAA118); + static const Color yellowColor00 = Color(0xffE6AA00); static const Color backgroundBlackColor = Color(0xff202529); static const Color black = Color(0xff000000); static const Color white = Color(0xffffffff); @@ -64,4 +65,5 @@ class MyColors { static const Color grey71Color = Color(0xff717171); static const Color darkGrey3BColor = Color(0xff3B3B3B); static const Color lightGreyIconColor = Color(0xff919191); + static const Color selectedBorderColor = Color(0xff37A4BE); } diff --git a/lib/classes/utils.dart b/lib/classes/utils.dart index 1838cb8..7885fad 100644 --- a/lib/classes/utils.dart +++ b/lib/classes/utils.dart @@ -349,7 +349,7 @@ class Utils { } static Future selectDate(BuildContext context, DateTime selectedDate) async { - if (!Platform.isIOS) { + if (Platform.isIOS) { await showCupertinoModalPopup( context: context, builder: (BuildContext cxt) => Container( diff --git a/lib/config/routes.dart b/lib/config/routes.dart index 7ccb6ce..705e40d 100644 --- a/lib/config/routes.dart +++ b/lib/config/routes.dart @@ -1,4 +1,5 @@ import 'package:flutter/material.dart'; +import 'package:mohem_flutter_app/models/my_documents/employee_documents_list_model.dart'; import 'package:mohem_flutter_app/ui/app_update_screen.dart'; import 'package:mohem_flutter_app/ui/attendance/add_vacation_rule_screen.dart'; import 'package:mohem_flutter_app/ui/attendance/monthly_attendance_screen.dart'; @@ -59,6 +60,8 @@ import 'package:mohem_flutter_app/ui/screens/items_for_sale/items_for_sale_home. import 'package:mohem_flutter_app/ui/screens/mowadhafhi/mowadhafhi_home.dart'; import 'package:mohem_flutter_app/ui/screens/mowadhafhi/mowadhafhi_hr_request.dart'; import 'package:mohem_flutter_app/ui/screens/mowadhafhi/request_details.dart'; +import 'package:mohem_flutter_app/ui/screens/my_documents/my_document_detail_screen.dart'; +import 'package:mohem_flutter_app/ui/screens/my_documents/my_documents_screen.dart'; import 'package:mohem_flutter_app/ui/screens/my_requests/my_requests.dart'; import 'package:mohem_flutter_app/ui/screens/my_requests/new_request.dart'; import 'package:mohem_flutter_app/ui/screens/offers_and_discounts/offers_and_discounts_details.dart'; @@ -149,6 +152,8 @@ class AppRoutes { // My Requests static const String myRequests = "/myRequests"; static const String newRequest = "/newRequests"; + static const String myDocuments = "/myDocuments"; + static const String myDocumentDetail = "/myDocumentDetail"; // Items For Sale static const String itemsForSale = "/itemsForSale"; @@ -265,7 +270,7 @@ class AppRoutes { //My Requests myRequests: (BuildContext context) => MyRequests(), newRequest: (BuildContext context) => NewRequest(), - + myDocuments: (BuildContext context) => MyDocumentsScreen(), // Items for sale itemsForSale: (BuildContext context) => ItemsForSale(), itemsForSaleDetail: (BuildContext context) => ItemForSaleDetailPage(), diff --git a/lib/generated/codegen_loader.g.dart b/lib/generated/codegen_loader.g.dart index ba21c29..c8bfdfa 100644 --- a/lib/generated/codegen_loader.g.dart +++ b/lib/generated/codegen_loader.g.dart @@ -546,7 +546,14 @@ class CodegenLoader extends AssetLoader{ "connectHmgWifi": "قم بتوصيل HMG WIFI", "connectedHmgWifi": "اتصال HMG WIFI", "itgForms": "نماذج (ITG)", - "resetAdPassword": "إعادة تعيين كلمة مرور AD" + "resetAdPassword": "إعادة تعيين كلمة مرور AD", + "myDocuments": "مستنداتي", + "requiredDocuments": "المستندات المطلوبة", + "optionalDocuments": "المستندات الاختيارية", + "allDocuments": "كافة المستندات", + "expiredDocuments": "المستندات منتهية الصلاحية", + "missingDocuments": "مستندات مفقودة", + "uploadedDocuments": "المستندات التي تم تحميلها" }; static const Map en_US = { "mohemm": "Mohemm", @@ -1080,7 +1087,14 @@ static const Map en_US = { "connectHmgWifi": "Connect HMG WIFI", "connectedHmgWifi": "Connected HMG WIFI", "itgForms": "ITG Forms", - "resetAdPassword": "Reset AD Password" + "resetAdPassword": "Reset AD Password", + "myDocuments": "My Documents", + "requiredDocuments": "Required Documents", + "optionalDocuments": "Optional Documents", + "allDocuments": "All\nDocuments", + "expiredDocuments": "Expired\nDocuments", + "missingDocuments": "Missing\nDocuments", + "uploadedDocuments": "Uploaded\nDocuments" }; static const Map> mapLocales = {"ar_SA": ar_SA, "en_US": en_US}; } diff --git a/lib/generated/locale_keys.g.dart b/lib/generated/locale_keys.g.dart index 343bf38..3a4921f 100644 --- a/lib/generated/locale_keys.g.dart +++ b/lib/generated/locale_keys.g.dart @@ -517,5 +517,12 @@ abstract class LocaleKeys { static const connectedHmgWifi = 'connectedHmgWifi'; static const itgForms = 'itgForms'; static const resetAdPassword = 'resetAdPassword'; + static const myDocuments = 'myDocuments'; + static const requiredDocuments = 'requiredDocuments'; + static const optionalDocuments = 'optionalDocuments'; + static const allDocuments = 'allDocuments'; + static const expiredDocuments = 'expiredDocuments'; + static const missingDocuments = 'missingDocuments'; + static const uploadedDocuments = 'uploadedDocuments'; } diff --git a/lib/models/generic_response_model.dart b/lib/models/generic_response_model.dart index a9006eb..5188b2c 100644 --- a/lib/models/generic_response_model.dart +++ b/lib/models/generic_response_model.dart @@ -60,6 +60,7 @@ import 'package:mohem_flutter_app/models/mowadhafhi/get_ticket_details.dart'; import 'package:mohem_flutter_app/models/mowadhafhi/get_ticket_transactions.dart'; import 'package:mohem_flutter_app/models/mowadhafhi/get_ticket_types.dart'; import 'package:mohem_flutter_app/models/mowadhafhi/get_tickets_list.dart'; +import 'package:mohem_flutter_app/models/my_documents/employee_documents_list_model.dart'; import 'package:mohem_flutter_app/models/my_requests/get_ccp_dff_structure_model.dart'; import 'package:mohem_flutter_app/models/my_requests/get_ccp_output_model.dart'; import 'package:mohem_flutter_app/models/my_requests/get_ccp_transactions_model.dart'; @@ -160,6 +161,7 @@ class GenericResponseModel { String? deleteVacationRuleList; String? disableSessionList; String? employeeQR; + List? employeeDocumentsList; String? forgetPasswordTokenID; List? getCcpTransactionsListNew; List? getConcurrentProgramsList; @@ -431,6 +433,7 @@ class GenericResponseModel { this.deleteVacationRuleList, this.disableSessionList, this.employeeQR, + this.employeeDocumentsList, this.forgetPasswordTokenID, this.getAbsenceAttachmentsList, this.getAbsenceAttendanceTypesList, @@ -709,6 +712,14 @@ class GenericResponseModel { deleteVacationRuleList = json['DeleteVacationRuleList']; disableSessionList = json['DisableSessionList']; employeeQR = json['EmployeeQR']; + + if (json['Employee_Documents_List'] != null) { + employeeDocumentsList = []; + json['Employee_Documents_List'].forEach((v) { + employeeDocumentsList!.add(EmployeeDocumentsList.fromJson(v)); + }); + } + forgetPasswordTokenID = json['ForgetPasswordTokenID']; getAbsenceAttachmentsList = json['GetAbsenceAttachmentsList']; @@ -1315,7 +1326,7 @@ class GenericResponseModel { if (json['RespondRolesList'] != null) { respondRolesList = []; json['RespondRolesList'].forEach((v) { - // respondRolesList!.add(v); + // respondRolesList!.add(v); }); } resubmitAbsenceTransactionList = json['ResubmitAbsenceTransactionList']; @@ -1341,10 +1352,7 @@ class GenericResponseModel { submitAddressTransactionList = json['SubmitAddressTransactionList'] != null ? SubmitAddressTransaction.fromJson(json['SubmitAddressTransactionList']) : null; submitBasicDetTransactionList = json['SubmitBasicDetTransactionList'] != null ? SubmitBasicDetailsTransactionList.fromJson(json['SubmitBasicDetTransactionList']) : null; submitCEITransactionList = json['SubmitCEITransactionList']; - submitCcpTransactionList = json['SubmitCcpTransactionList'] != null - ? new SubmitCcpTransactionList.fromJson( - json['SubmitCcpTransactionList']) - : null; + submitCcpTransactionList = json['SubmitCcpTransactionList'] != null ? new SubmitCcpTransactionList.fromJson(json['SubmitCcpTransactionList']) : null; submitContactTransactionList = json['SubmitContactTransactionList'] != null ? SubmitContactTransactionList.fromJson(json['SubmitContactTransactionList']) : null; submitEITTransactionList = json['SubmitEITTransactionList'] != null ? SubmitEITTransactionList.fromJson(json['SubmitEITTransactionList']) : null; @@ -1471,6 +1479,11 @@ class GenericResponseModel { data['DeleteVacationRuleList'] = this.deleteVacationRuleList; data['DisableSessionList'] = this.disableSessionList; data['EmployeeQR'] = this.employeeQR; + + if (this.employeeDocumentsList != null) { + data['Employee_Documents_List'] = this.employeeDocumentsList!.map((v) => v.toJson()).toList(); + } + data['ForgetPasswordTokenID'] = this.forgetPasswordTokenID; data['GetAbsenceAttachmentsList'] = this.getAbsenceAttachmentsList; @@ -1804,8 +1817,7 @@ class GenericResponseModel { data['SubmitCEITransactionList'] = this.submitCEITransactionList; if (this.submitCcpTransactionList != null) { - data['SubmitCcpTransactionList'] = - this.submitCcpTransactionList!.toJson(); + data['SubmitCcpTransactionList'] = this.submitCcpTransactionList!.toJson(); } data['SubmitContactTransactionList'] = this.submitContactTransactionList; diff --git a/lib/models/my_documents/employee_documents_list_model.dart b/lib/models/my_documents/employee_documents_list_model.dart new file mode 100644 index 0000000..97ef785 --- /dev/null +++ b/lib/models/my_documents/employee_documents_list_model.dart @@ -0,0 +1,29 @@ +class EmployeeDocumentsList { + String? dOCUMENTREQUIREDSTATUS; + String? dOCUMENTSTATUS; + String? dOCUMENTTYPE; + String? fUNCTIONNAME; + + EmployeeDocumentsList({ + this.dOCUMENTREQUIREDSTATUS, + this.dOCUMENTSTATUS, + this.dOCUMENTTYPE, + this.fUNCTIONNAME, + }); + + EmployeeDocumentsList.fromJson(Map json) { + dOCUMENTREQUIREDSTATUS = json['DOCUMENT_REQUIRED_STATUS']; + dOCUMENTSTATUS = json['DOCUMENT_STATUS']; + dOCUMENTTYPE = json['DOCUMENT_TYPE']; + fUNCTIONNAME = json['FUNCTION_NAME']; + } + + Map toJson() { + Map data = Map(); + data['DOCUMENT_REQUIRED_STATUS'] = dOCUMENTREQUIREDSTATUS; + data['DOCUMENT_STATUS'] = dOCUMENTSTATUS; + data['DOCUMENT_TYPE'] = dOCUMENTTYPE; + data['FUNCTION_NAME'] = fUNCTIONNAME; + return data; + } +} diff --git a/lib/provider/dashboard_provider_model.dart b/lib/provider/dashboard_provider_model.dart index 0e18544..5eac532 100644 --- a/lib/provider/dashboard_provider_model.dart +++ b/lib/provider/dashboard_provider_model.dart @@ -278,6 +278,7 @@ class DashboardProviderModel with ChangeNotifier, DiagnosticableTreeMixin { getMenuEntriesList.add(activeDirectoryEntry); list.add(GetMenuEntriesList(requestType: "ITG_FORMS", prompt: LocaleKeys.itgForms.tr(), menuName: 'ITG_FORMS')); + list.add(GetMenuEntriesList(requestType: "MY_DOCUMENTS", prompt: LocaleKeys.myDocuments.tr(), menuName: 'MY_DOCUMENTS')); } menus.add(Menus(getMenuEntriesList[i], list)); diff --git a/lib/ui/landing/widget/services_widget.dart b/lib/ui/landing/widget/services_widget.dart index 2333c18..7dabb0c 100644 --- a/lib/ui/landing/widget/services_widget.dart +++ b/lib/ui/landing/widget/services_widget.dart @@ -69,7 +69,9 @@ class ServicesWidget extends StatelessWidget { mainAxisAlignment: MainAxisAlignment.spaceBetween, crossAxisAlignment: CrossAxisAlignment.start, children: [ - SvgPicture.asset(AppState().isArabic(context) ? getMenuIconAr(data.homeMenus![parentIndex].menuEntiesList[index].prompt!) : getMenuIconEn(data.homeMenus![parentIndex].menuEntiesList[index].prompt!)), + SvgPicture.asset(AppState().isArabic(context) + ? getMenuIconAr(data.homeMenus![parentIndex].menuEntiesList[index].prompt!) + : getMenuIconEn(data.homeMenus![parentIndex].menuEntiesList[index].prompt!)), Row( crossAxisAlignment: CrossAxisAlignment.end, children: [ @@ -138,6 +140,9 @@ class ServicesWidget extends StatelessWidget { case "قاعدة الاجازات": returnImage = "assets/images/services_icons/vacation_rule.svg"; break; + case "مستنداتي": + returnImage = "assets/images/document.svg"; + break; default: returnImage = "assets/images/monthly_attendance.svg"; break; @@ -181,6 +186,9 @@ class ServicesWidget extends StatelessWidget { case "Vacation Rule": returnImage = "assets/images/services_icons/vacation_rule.svg"; break; + case "My Documents": + returnImage = "assets/images/document.svg"; + break; default: returnImage = "assets/images/monthly_attendance.svg"; break; @@ -199,6 +207,9 @@ class ServicesWidget extends StatelessWidget { } else if (menuEntry.menuName == "MBL_PERINFO_SS") { Navigator.of(context).pushNamed(AppRoutes.profile); return; + } else if (menuEntry.menuName == "MY_DOCUMENTS") { + Navigator.pushNamed(context, AppRoutes.myDocuments); + return; } List menuList = pro.getMenuEntriesList?.where((element) => element.parentMenuName == menuEntry.menuName && (element.menuEntryType == "FUNCTION")).toList() ?? []; menuEntry.icon = ""; diff --git a/lib/ui/misc/request_submit_screen.dart b/lib/ui/misc/request_submit_screen.dart index 3611241..6fa0ef8 100644 --- a/lib/ui/misc/request_submit_screen.dart +++ b/lib/ui/misc/request_submit_screen.dart @@ -31,8 +31,9 @@ class RequestSubmitScreenParams { String pItemId; String approvalFlag; String? selectedEmployeeID; + String? popNavigateToSpecificRoute; - RequestSubmitScreenParams(this.title, this.transactionId, this.pItemId, this.approvalFlag, {this.selectedEmployeeID}); + RequestSubmitScreenParams(this.title, this.transactionId, this.pItemId, this.approvalFlag, {this.selectedEmployeeID, this.popNavigateToSpecificRoute}); } class RequestSubmitScreen extends StatefulWidget { @@ -145,8 +146,13 @@ class _RequestSubmitScreenState extends State { Utils.hideLoading(context); Utils.showToast(LocaleKeys.yourRequestHasBeenSubmittedForApprovals.tr(), longDuration: true); AppState().cancelRequestTrancsection = false; - Navigator.of(context).popUntil((route) => route.settings.name == AppRoutes.dashboard); - Navigator.pushNamed(context, AppRoutes.workList); + + if (params?.popNavigateToSpecificRoute == null) { + Navigator.of(context).popUntil((route) => route.settings.name == AppRoutes.dashboard); + Navigator.pushNamed(context, AppRoutes.workList); + } else { + Navigator.of(context).popUntil((route) => route.settings.name == params!.popNavigateToSpecificRoute); + } } catch (ex) { Utils.hideLoading(context); Utils.handleException(ex, context, null); diff --git a/lib/ui/my_attendance/dynamic_screens/dynamic_input_screen.dart b/lib/ui/my_attendance/dynamic_screens/dynamic_input_screen.dart index 3e75813..8d595bf 100644 --- a/lib/ui/my_attendance/dynamic_screens/dynamic_input_screen.dart +++ b/lib/ui/my_attendance/dynamic_screens/dynamic_input_screen.dart @@ -94,8 +94,17 @@ class _DynamicInputScreenState extends State { genericResponseModel = await MyAttendanceApiClient().validateEitTransaction(dESCFLEXCONTEXTCODE, dynamicParams!.dynamicId, values, empID: dynamicParams!.selectedEmp); SubmitEITTransactionList submitEITTransactionList = await MyAttendanceApiClient().submitEitTransaction(dESCFLEXCONTEXTCODE, dynamicParams!.dynamicId, values, empID: dynamicParams!.selectedEmp); Utils.hideLoading(context); - await Navigator.pushNamed(context, AppRoutes.requestSubmitScreen, - arguments: RequestSubmitScreenParams(LocaleKeys.submit.tr(), submitEITTransactionList.pTRANSACTIONID!, submitEITTransactionList.pITEMKEY!, 'eit')); + await Navigator.pushNamed( + context, + AppRoutes.requestSubmitScreen, + arguments: RequestSubmitScreenParams( + LocaleKeys.submit.tr(), + submitEITTransactionList.pTRANSACTIONID!, + submitEITTransactionList.pITEMKEY!, + 'eit', + popNavigateToSpecificRoute: dynamicParams!.popUntilRoute, + ), + ); if (!AppState().cancelRequestTrancsection) { return; } diff --git a/lib/ui/my_attendance/dynamic_screens/dynamic_listview_screen.dart b/lib/ui/my_attendance/dynamic_screens/dynamic_listview_screen.dart index a9c9694..9294159 100644 --- a/lib/ui/my_attendance/dynamic_screens/dynamic_listview_screen.dart +++ b/lib/ui/my_attendance/dynamic_screens/dynamic_listview_screen.dart @@ -19,12 +19,13 @@ class DynamicListViewParams { String requestID; String colsURL; bool isUpdate; + String? popUntilRoute; List? collectionNotificationList; final String? selectedEmp; DynamicListViewParams(this.title, this.dynamicId, - {this.selectedEmp, this.uRL = 'GET_EIT_DFF_STRUCTURE', this.requestID = '', this.colsURL = '', this.isUpdate = false, this.collectionNotificationList}); + {this.selectedEmp, this.uRL = 'GET_EIT_DFF_STRUCTURE', this.requestID = '', this.colsURL = '', this.isUpdate = false, this.collectionNotificationList, this.popUntilRoute}); } class DynamicListViewScreen extends StatefulWidget { diff --git a/lib/ui/screens/my_documents/my_document_detail_screen.dart b/lib/ui/screens/my_documents/my_document_detail_screen.dart new file mode 100644 index 0000000..ec97586 --- /dev/null +++ b/lib/ui/screens/my_documents/my_document_detail_screen.dart @@ -0,0 +1,174 @@ +import 'dart:io'; + +import 'package:dotted_border/dotted_border.dart'; +import 'package:easy_localization/easy_localization.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_svg/svg.dart'; +import 'package:image_picker/image_picker.dart'; +import 'package:mohem_flutter_app/app_state/app_state.dart'; +import 'package:mohem_flutter_app/classes/colors.dart'; +import 'package:mohem_flutter_app/classes/utils.dart'; +import 'package:mohem_flutter_app/extensions/int_extensions.dart'; +import 'package:mohem_flutter_app/extensions/string_extensions.dart'; +import 'package:mohem_flutter_app/extensions/widget_extensions.dart'; +import 'package:mohem_flutter_app/generated/locale_keys.g.dart'; +import 'package:mohem_flutter_app/models/my_documents/employee_documents_list_model.dart'; +import 'package:mohem_flutter_app/widgets/app_bar_widget.dart'; +import 'package:mohem_flutter_app/widgets/button/default_button.dart'; +import 'package:mohem_flutter_app/widgets/dynamic_forms/dynamic_textfield_widget.dart'; +import 'package:mohem_flutter_app/widgets/my_document_item.dart'; +import 'package:sizer/sizer.dart'; + +class MyDocumentDetailScreen extends StatefulWidget { + EmployeeDocumentsList document; + final Color color; + + MyDocumentDetailScreen(this.document, this.color, {Key? key}) : super(key: key); + + @override + _MyDocumentDetailScreenState createState() { + return _MyDocumentDetailScreenState(); + } +} + +class _MyDocumentDetailScreenState extends State { + DateTime? expiryDate; + List imagesList = []; + + @override + void initState() { + super.initState(); + } + + @override + void dispose() { + super.dispose(); + } + + @override + Widget build(BuildContext context) { + return Scaffold( + backgroundColor: Colors.white, + appBar: AppBarWidget(context, title: widget.document.dOCUMENTTYPE!, showHomeButton: true), + body: Column( + children: [ + ListView( + padding: const EdgeInsets.all(21), + children: [ + MyDocumentItem(widget.document, widget.color,isNotInDetailView: false), + 20.height, + DynamicTextFieldWidget( + LocaleKeys.employeeNumber.tr(), + AppState().getUserName!, + isInputTypeNum: true, + isReadOnly: true, + ), + 12.height, + PopupMenuButton( + child: DynamicTextFieldWidget( + "Document Type*", + "National ID", + isEnable: false, + isPopup: true, + isInputTypeNum: true, + // isReadOnly: true, + ), + itemBuilder: (_) => >[], + onSelected: (int popipIndex) async {}), + 12.height, + DynamicTextFieldWidget( + "Expiry Date", + expiryDate == null ? LocaleKeys.dateRequired.tr() : Utils.getMonthNamedFormat(expiryDate!).replaceAll("-", " "), + suffixIconData: Icons.calendar_today, + isEnable: false, + onTap: () async { + DateTime date = await Utils.selectDate(context, expiryDate ?? DateTime.now()); + String dateString = date.toString().split(' ').first; + if (date != expiryDate) { + expiryDate = date; + setState(() {}); + } + }, + ), + 12.height, + DottedBorder( + borderType: BorderType.RRect, + radius: const Radius.circular(10), + padding: const EdgeInsets.all(12), + dashPattern: const [2, 1], + color: MyColors.selectedBorderColor, + child: Row( + mainAxisSize: MainAxisSize.min, + children: [ + Transform.rotate( + angle: 45, + child: const Icon(Icons.attach_file_rounded, size: 16, color: MyColors.selectedBorderColor), + ), + 4.width, + "Attach Image".toText14(color: MyColors.selectedBorderColor), + ], + ).center, + ).onPress(() async { + ImagePicker picker = ImagePicker(); + List list = await picker.pickMultiImage(); + if (list.isNotEmpty) { + imagesList.addAll(list); + var seen = {}; + imagesList = imagesList.where((image) => seen.add(image.name)).toList(); + setState(() {}); + } + }), + 12.height, + GridView.builder( + padding: EdgeInsets.zero, + itemCount: imagesList.length, + shrinkWrap: true, + physics: const NeverScrollableScrollPhysics(), + itemBuilder: (context, index) { + return Stack( + alignment: Alignment.topRight, + children: [ + AspectRatio( + aspectRatio: 1, + child: Image.file( + File(imagesList[index].path), + fit: BoxFit.cover, + errorBuilder: (BuildContext context, Object error, StackTrace? stackTrace) { + return const Center(child: Text('This image type is not supported')); + }, + ), + ).paddingOnly(top: 6, right: 6), + Container( + height: 16, + width: 16, + decoration: const BoxDecoration( + shape: BoxShape.circle, + color: Color(0xffd85323), + ), + child: const Icon(Icons.clear, color: Colors.white, size: 12), + ).onPress(() { + imagesList.removeAt(index); + setState(() {}); + }), + ], + ); + }, + gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount( + crossAxisCount: 4, + mainAxisSpacing: 8, + crossAxisSpacing: 8, + childAspectRatio: 1, + ), + ) + ], + ).expanded, + const Divider(height: 1, color: MyColors.lightGreyEFColor), + DefaultButton( + LocaleKeys.submit.tr(), + widget.document.dOCUMENTSTATUS == "Exist" ? null : () {}, + ).paddingOnly(left: 21, right: 21, bottom: 21, top: 14), + ], + ), + ); + } +} diff --git a/lib/ui/screens/my_documents/my_documents_fragment.dart b/lib/ui/screens/my_documents/my_documents_fragment.dart new file mode 100644 index 0000000..89ad69d --- /dev/null +++ b/lib/ui/screens/my_documents/my_documents_fragment.dart @@ -0,0 +1,157 @@ +import 'package:easy_localization/easy_localization.dart'; +import 'package:flutter/material.dart'; +import 'package:mohem_flutter_app/api/profile_api_client.dart'; +import 'package:mohem_flutter_app/app_state/app_state.dart'; +import 'package:mohem_flutter_app/classes/colors.dart'; +import 'package:mohem_flutter_app/classes/utils.dart'; +import 'package:mohem_flutter_app/config/routes.dart'; +import 'package:mohem_flutter_app/extensions/int_extensions.dart'; +import 'package:mohem_flutter_app/extensions/string_extensions.dart'; +import 'package:mohem_flutter_app/extensions/widget_extensions.dart'; +import 'package:mohem_flutter_app/generated/locale_keys.g.dart'; +import 'package:mohem_flutter_app/models/my_documents/employee_documents_list_model.dart'; +import 'package:mohem_flutter_app/ui/my_attendance/dynamic_screens/dynamic_listview_screen.dart'; +import 'package:mohem_flutter_app/ui/screens/my_documents/my_document_detail_screen.dart'; +import 'package:mohem_flutter_app/widgets/my_document_item.dart'; + +class MyDocumentsFragment extends StatefulWidget { + List? list; + + MyDocumentsFragment(this.list, {Key? key}) : super(key: key); + + @override + _MyDocumentsFragmentState createState() { + return _MyDocumentsFragmentState(); + } +} + +class _MyDocumentsFragmentState extends State { + int selectedIndex = 0; + List? documentsList; + + @override + void initState() { + super.initState(); + documentsList = widget.list; + } + + @override + void dispose() { + super.dispose(); + } + + @override + void didUpdateWidget(covariant MyDocumentsFragment oldWidget) { + super.didUpdateWidget(oldWidget); + if (oldWidget.list != widget.list) { + documentsList = widget.list; + } + } + + @override + Widget build(BuildContext context) { + List documentfilteredList = getTagBySelectedTab(selectedIndex); + return Column( + children: [ + GridView.count( + crossAxisSpacing: 6, + crossAxisCount: 4, + childAspectRatio: 79 / 79, + shrinkWrap: true, + physics: const NeverScrollableScrollPhysics(), + padding: const EdgeInsets.only(left: 21, right: 21, bottom: 11, top: 21), + children: [ + gridViewItem(LocaleKeys.allDocuments.tr(), getTagBySelectedTab(0).length.toString(), 0, MyColors.darkTextColor), + gridViewItem(LocaleKeys.expiredDocuments.tr(), getTagBySelectedTab(1).length.toString(), 1, MyColors.redA3Color), + gridViewItem(LocaleKeys.missingDocuments.tr(), getTagBySelectedTab(2).length.toString(), 2, MyColors.yellowColor00), + gridViewItem(LocaleKeys.uploadedDocuments.tr(), getTagBySelectedTab(3).length.toString(), 3, MyColors.greenColor), + ], + ), + documentsList == null + ? const SizedBox() + : (documentfilteredList.isNotEmpty + ? ListView.separated( + physics: const BouncingScrollPhysics(), + padding: const EdgeInsets.only(left: 21, right: 21, bottom: 21, top: 11), + itemBuilder: (cxt, index) { + return MyDocumentItem(documentfilteredList[index], getColorByDocumentStatus(documentfilteredList[index].dOCUMENTSTATUS!)).onPress(() { + Navigator.pushNamed(context, AppRoutes.addDynamicInput, + arguments: DynamicListViewParams(documentfilteredList[index].dOCUMENTTYPE!, documentfilteredList[index].fUNCTIONNAME!, selectedEmp: AppState().getUserName, popUntilRoute: AppRoutes.myDocuments)); + }); + }, + separatorBuilder: (cxt, index) => 12.height, + itemCount: documentfilteredList.length) + : Utils.getNoDataWidget(context).center) + .expanded, + ], + ); + } + + Widget gridViewItem(String title, String value, int index, Color color) { + return Container( + padding: const EdgeInsets.symmetric(vertical: 10, horizontal: 8), + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(15), + boxShadow: [ + BoxShadow( + color: const Color(0xff000000).withOpacity(.05), + blurRadius: 26, + offset: const Offset(0, 0), + ), + ], + border: Border.all(color: selectedIndex == index ? MyColors.selectedBorderColor : Colors.white, width: 2), + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + title.toText10(), + value.toText20(isBold: true, color: color), + ], + ), + ).onPress(() { + setState(() { + selectedIndex = index; + }); + }); + } + + Color getColorByDocumentStatus(String status) { + Color _color; + switch (status) { + case "Exist": + _color = MyColors.greenColor; + break; + case "Missing": + _color = MyColors.yellowColor00; + break; + case "Not Exist": + _color = MyColors.redA3Color; + break; + default: + _color = MyColors.darkTextColor; + break; + } + return _color; + } + + List getTagBySelectedTab(int index) { + List list = []; + switch (index) { + case 1: + list = documentsList?.where((element) => element.dOCUMENTSTATUS == "Not Exist").toList() ?? []; + break; + case 2: + list = documentsList?.where((element) => element.dOCUMENTSTATUS == "Missing").toList() ?? []; + break; + case 3: + list = documentsList?.where((element) => element.dOCUMENTSTATUS == "Exist").toList() ?? []; + break; + default: + list = documentsList ?? []; + break; + } + return list; + } +} diff --git a/lib/ui/screens/my_documents/my_documents_screen.dart b/lib/ui/screens/my_documents/my_documents_screen.dart new file mode 100644 index 0000000..ffddd36 --- /dev/null +++ b/lib/ui/screens/my_documents/my_documents_screen.dart @@ -0,0 +1,132 @@ +import 'package:easy_localization/easy_localization.dart'; +import 'package:flutter/material.dart'; +import 'package:mohem_flutter_app/api/profile_api_client.dart'; +import 'package:mohem_flutter_app/classes/colors.dart'; +import 'package:mohem_flutter_app/classes/utils.dart'; +import 'package:mohem_flutter_app/extensions/int_extensions.dart'; +import 'package:mohem_flutter_app/extensions/string_extensions.dart'; +import 'package:mohem_flutter_app/extensions/widget_extensions.dart'; +import 'package:mohem_flutter_app/generated/locale_keys.g.dart'; +import 'package:mohem_flutter_app/models/my_documents/employee_documents_list_model.dart'; +import 'package:mohem_flutter_app/ui/screens/my_documents/my_documents_fragment.dart'; +import 'package:mohem_flutter_app/widgets/app_bar_widget.dart'; + +class MyDocumentsScreen extends StatefulWidget { + MyDocumentsScreen({Key? key}) : super(key: key); + + @override + _MyDocumentsScreenState createState() { + return _MyDocumentsScreenState(); + } +} + +class _MyDocumentsScreenState extends State { + int tabIndex = 0; + PageController controller = PageController(); + + List? documentsList; + + @override + void initState() { + super.initState(); + getDocuments(); + } + + @override + void dispose() { + super.dispose(); + } + + void getDocuments() async { + try { + documentsList?.clear(); + Utils.showLoading(context); + documentsList = await ProfileApiClient().getEmployeeDocuments(); + Utils.hideLoading(context); + setState(() {}); + } catch (ex) { + Utils.hideLoading(context); + Utils.handleException(ex, context, null); + } + } + + @override + Widget build(BuildContext context) { + var requiredDocumentsList; + var optionalDocumentsList; + + if (documentsList?.isNotEmpty ?? false) { + requiredDocumentsList = []; + optionalDocumentsList = []; + documentsList!.forEach((element) { + if (element.dOCUMENTREQUIREDSTATUS == "Required") { + requiredDocumentsList.add(element); + } else { + optionalDocumentsList.add(element); + } + }); + } + + return Scaffold( + backgroundColor: Colors.white, + appBar: AppBarWidget(context, title: LocaleKeys.myDocuments.tr(), showHomeButton: true), + body: Column( + children: [ + Container( + padding: const EdgeInsets.only(left: 21, right: 21, top: 16, bottom: 16), + decoration: const BoxDecoration( + borderRadius: BorderRadius.only( + bottomLeft: Radius.circular(25), + bottomRight: Radius.circular(25), + ), + gradient: LinearGradient( + transform: GradientRotation(.83), + begin: Alignment.topRight, + end: Alignment.bottomLeft, + colors: [ + MyColors.gradiantEndColor, + MyColors.gradiantStartColor, + ], + ), + ), + child: Row( + children: [myTab(LocaleKeys.requiredDocuments.tr(), 0), myTab(LocaleKeys.optionalDocuments.tr(), 1)], + ), + ), + PageView( + controller: controller, + physics: const NeverScrollableScrollPhysics(), + onPageChanged: (int pageIndex) { + setState(() { + tabIndex = pageIndex; + }); + }, + children: [MyDocumentsFragment(requiredDocumentsList), MyDocumentsFragment(optionalDocumentsList)], + ).expanded, + ], + ), + ); + } + + Widget myTab(String title, int index) { + bool isSelected = (index == tabIndex); + return Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + title.toText12(color: isSelected ? Colors.white : Colors.white.withOpacity(.74), isCenter: true), + 4.height, + Container( + height: 8, + width: 8, + decoration: BoxDecoration( + shape: BoxShape.circle, + color: isSelected ? Colors.white : Colors.transparent, + ), + ), + ], + ).onPress(() { + controller.jumpToPage(index); + }).expanded; + } +} diff --git a/lib/widgets/my_document_item.dart b/lib/widgets/my_document_item.dart new file mode 100644 index 0000000..b0d4b51 --- /dev/null +++ b/lib/widgets/my_document_item.dart @@ -0,0 +1,76 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_svg/flutter_svg.dart'; +import 'package:mohem_flutter_app/extensions/int_extensions.dart'; +import 'package:mohem_flutter_app/extensions/string_extensions.dart'; +import 'package:mohem_flutter_app/extensions/widget_extensions.dart'; +import 'package:mohem_flutter_app/models/my_documents/employee_documents_list_model.dart'; +import 'package:sizer/sizer.dart'; + +class MyDocumentItem extends StatelessWidget { + EmployeeDocumentsList document; + final Color color; + final bool isNotInDetailView; + + MyDocumentItem(this.document, this.color, {Key? key,this.isNotInDetailView = true}) : super(key: key); + + @override + Widget build(BuildContext context) { + return Container( + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(10), + boxShadow: [ + BoxShadow( + color: const Color(0xff000000).withOpacity(.05), + blurRadius: 26, + offset: const Offset(0, -3), + ), + ], + ), + child: ClipRRect( + borderRadius: BorderRadius.circular(10.0), + child: Stack( + children: [ + Positioned( + top: -35, + child: Container( + width: 45, + height: 45, + transform: Matrix4.rotationZ(0.8), + color: color, + ), + ), + Row( + crossAxisAlignment: CrossAxisAlignment.end, + mainAxisSize: MainAxisSize.min, + children: [ + Row( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisSize: MainAxisSize.min, + children: [ + SvgPicture.asset('assets/images/document.svg').paddingOnly(top: 6), + 12.width, + Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisSize: MainAxisSize.min, + children: [ + document.dOCUMENTTYPE!.toText16(), + document.dOCUMENTSTATUS!.toText10(color: color), + ], + ).expanded, + ], + ).expanded, + if(isNotInDetailView) + const Icon( + Icons.arrow_forward, + size: 20, + color: Color(0xff2E303A), + ) + ], + ).paddingOnly(top: 14, bottom: 18, right: 14, left: 24), + ], + ), + ), + ); + } +} diff --git a/pubspec.yaml b/pubspec.yaml index bc70be9..aae7196 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -117,6 +117,9 @@ dependencies: # store_checker: ^1.1.0 google_api_availability: ^3.0.1 + #todo its for temporary purpose, later will remove this. + dotted_border: ^2.0.0+3 + dependency_overrides: firebase_core_platform_interface: 4.5.1 From e39526b5ebef81d61c70bf34cc9cc125c134b295 Mon Sep 17 00:00:00 2001 From: haroon amjad Date: Wed, 9 Aug 2023 11:41:48 +0300 Subject: [PATCH 12/19] Updates & fixes --- lib/app_state/app_state.dart | 2 +- lib/classes/notifications.dart | 5 +- lib/extensions/int_extensions.dart | 2 - lib/ui/login/login_screen.dart | 1 + lib/widgets/location/Location.dart | 9 -- lib/widgets/mark_attendance_widget.dart | 174 ++++++++++++++++-------- pubspec.yaml | 29 ++-- 7 files changed, 135 insertions(+), 87 deletions(-) diff --git a/lib/app_state/app_state.dart b/lib/app_state/app_state.dart index f59994c..b0c93ee 100644 --- a/lib/app_state/app_state.dart +++ b/lib/app_state/app_state.dart @@ -90,7 +90,7 @@ class AppState { String get getHuaweiPushToken => _huaweiPushToken; - final PostParamsModel _postParamsInitConfig = PostParamsModel(channel: 31, versionID: 4.9, mobileType: Platform.isAndroid ? "android" : "ios"); + final PostParamsModel _postParamsInitConfig = PostParamsModel(channel: 31, versionID: 5.0, mobileType: Platform.isAndroid ? "android" : "ios"); void setPostParamsInitConfig() { isAuthenticated = false; diff --git a/lib/classes/notifications.dart b/lib/classes/notifications.dart index 47d4acd..8f432d7 100644 --- a/lib/classes/notifications.dart +++ b/lib/classes/notifications.dart @@ -109,7 +109,10 @@ class AppNotifications { debugPrint("HUAWEI PUSH TOKEN: $_huaweiToken"); } - void _onTokenError(Object error) {} + void _onTokenError(Object error) { + debugPrint("HUAWEI PUSH TOKEN ERROR: $error"); + Utils.hideLoading(context); + } Future initTokenStream(Function loginCallback) async { huawei_push.Push.getTokenStream.listen(_onTokenEvent, onError: _onTokenError).onData((data) { diff --git a/lib/extensions/int_extensions.dart b/lib/extensions/int_extensions.dart index 16bdd29..f46d5bb 100644 --- a/lib/extensions/int_extensions.dart +++ b/lib/extensions/int_extensions.dart @@ -10,6 +10,4 @@ extension IntExtensions on int { Widget get divider => Divider(height: toDouble(), thickness: toDouble(), color: MyColors.lightGreyEFColor); Widget get makeItSquare => SizedBox(width: toDouble(), height: toDouble()); - - } diff --git a/lib/ui/login/login_screen.dart b/lib/ui/login/login_screen.dart index 3293e43..5d83fe9 100644 --- a/lib/ui/login/login_screen.dart +++ b/lib/ui/login/login_screen.dart @@ -103,6 +103,7 @@ class _LoginScreenState extends State { try { if (!(await Utils.isGoogleServicesAvailable())) { print("HUAWEI APPPP GALLERYYYY!!!!"); + AppNotifications().init(firebaseToken, context); AppState().setIsHuawei = true; AppNotifications().initHuaweiPush(checkLoginInfo); } else { diff --git a/lib/widgets/location/Location.dart b/lib/widgets/location/Location.dart index e324618..67d3cdd 100644 --- a/lib/widgets/location/Location.dart +++ b/lib/widgets/location/Location.dart @@ -47,15 +47,6 @@ class Location { Geolocator.getCurrentPosition(desiredAccuracy: LocationAccuracy.medium, timeLimit: const Duration(seconds: 5)).then((value) { done(value); }); - // Geolocator.getLastKnownPosition(forceAndroidLocationManager: true).then((value) { - // if (value == null) { - // Geolocator.getCurrentPosition().then((value) { - // done(value); - // }); - // } else { - // done(value); - // } - // }); } else { // AppPermissions } diff --git a/lib/widgets/mark_attendance_widget.dart b/lib/widgets/mark_attendance_widget.dart index dfb4357..982e316 100644 --- a/lib/widgets/mark_attendance_widget.dart +++ b/lib/widgets/mark_attendance_widget.dart @@ -1,13 +1,11 @@ +import 'dart:async'; import 'dart:io'; import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/material.dart'; import 'package:flutter_svg/flutter_svg.dart'; import 'package:geolocator/geolocator.dart'; -import 'package:huawei_location/location/fused_location_provider_client.dart'; -import 'package:huawei_location/location/location_request.dart'; -import 'package:huawei_location/location/location_settings_request.dart'; -import 'package:huawei_location/permission/permission_handler.dart'; +import 'package:huawei_location/huawei_location.dart'; import 'package:mohem_flutter_app/api/dashboard_api_client.dart'; import 'package:mohem_flutter_app/app_state/app_state.dart'; import 'package:mohem_flutter_app/classes/colors.dart'; @@ -21,7 +19,7 @@ import 'package:mohem_flutter_app/provider/dashboard_provider_model.dart'; import 'package:mohem_flutter_app/ui/dialogs/success_dialog.dart'; import 'package:mohem_flutter_app/widgets/dialogs/confirm_dialog.dart'; import 'package:mohem_flutter_app/widgets/dialogs/dialogs.dart'; -import 'package:mohem_flutter_app/widgets/location/Location.dart'; +import 'package:mohem_flutter_app/widgets/location/Location.dart' as location; import 'package:mohem_flutter_app/widgets/nfc/nfc_reader_sheet.dart'; import 'package:mohem_flutter_app/widgets/qr_scanner_dialog.dart'; import 'package:nfc_manager/nfc_manager.dart'; @@ -75,26 +73,61 @@ class _MarkAttendanceWidgetState extends State { } void checkHuaweiLocationPermission(String attendanceType) async { - PermissionHandler permissionHandler = PermissionHandler(); - - if (await permissionHandler.hasLocationPermission()) { - getHuaweiCurrentLocation(attendanceType); - } else { - bool has = await requestPermissions(); - if (has) { - getHuaweiCurrentLocation(attendanceType); + // Permission_Handler permissionHandler = PermissionHandler(); + location.Location.isEnabled((bool isEnabled) async { + if (isEnabled) { + location.Location.havePermission((bool permission) async { + if (permission) { + getHuaweiCurrentLocation(attendanceType); + } else { + bool has = await requestPermissions(); + if (has) { + getHuaweiCurrentLocation(attendanceType); + } else { + showDialog( + context: context, + builder: (BuildContext cxt) => ConfirmDialog( + message: "You need to give location permission to mark attendance", + onTap: () { + Navigator.pop(context); + }, + ), + ); + } + } + }); } else { showDialog( context: context, builder: (BuildContext cxt) => ConfirmDialog( - message: "You need to give location permission to mark attendance", - onTap: () { + message: "You need to enable location services to mark attendance", + onTap: () async { Navigator.pop(context); + await Geolocator.openLocationSettings(); }, ), ); } - } + }); + + // if (await permissionHandler.hasLocationPermission()) { + // getHuaweiCurrentLocation(attendanceType); + // } else { + // bool has = await requestPermissions(); + // if (has) { + // getHuaweiCurrentLocation(attendanceType); + // } else { + // showDialog( + // context: context, + // builder: (BuildContext cxt) => ConfirmDialog( + // message: "You need to give location permission to mark attendance", + // onTap: () { + // Navigator.pop(context); + // }, + // ), + // ); + // } + // } } Future requestPermissions() async { @@ -134,11 +167,11 @@ class _MarkAttendanceWidgetState extends State { if (AppState().getIsHuawei) { checkHuaweiLocationPermission("NFC"); } else { - Location.isEnabled((bool isEnabled) { + location.Location.isEnabled((bool isEnabled) { if (isEnabled) { - Location.havePermission((bool permission) { + location.Location.havePermission((bool permission) { if (permission) { - Location.getCurrentLocation( + location.Location.getCurrentLocation( (Position position, bool isMocked) { if (isMocked) { markFakeAttendance("NFC", position.latitude.toString() ?? "", position.longitude.toString() ?? ""); @@ -181,11 +214,11 @@ class _MarkAttendanceWidgetState extends State { if (AppState().getIsHuawei) { checkHuaweiLocationPermission("WIFI"); } else { - Location.isEnabled((bool isEnabled) { + location.Location.isEnabled((bool isEnabled) { if (isEnabled) { - Location.havePermission((bool permission) { + location.Location.havePermission((bool permission) { if (permission) { - Location.getCurrentLocation( + location.Location.getCurrentLocation( (Position position, bool isMocked) { if (isMocked) { markFakeAttendance("WIFI", position.latitude.toString() ?? "", position.longitude.toString() ?? ""); @@ -228,11 +261,11 @@ class _MarkAttendanceWidgetState extends State { if (AppState().getIsHuawei) { checkHuaweiLocationPermission("QR"); } else { - Location.isEnabled((bool isEnabled) { + location.Location.isEnabled((bool isEnabled) { if (isEnabled) { - Location.havePermission((bool permission) { + location.Location.havePermission((bool permission) { if (permission) { - Location.getCurrentLocation( + location.Location.getCurrentLocation( (Position position, bool isMocked) { if (isMocked) { markFakeAttendance("QR", position.latitude.toString() ?? "", position.longitude.toString() ?? ""); @@ -277,49 +310,70 @@ class _MarkAttendanceWidgetState extends State { ); } - void getHuaweiCurrentLocation(String attendanceType) { + void getHuaweiCurrentLocation(String attendanceType) async { try { + Utils.showLoading(context); FusedLocationProviderClient locationService = FusedLocationProviderClient(); LocationRequest locationRequest = LocationRequest(); locationRequest.priority = LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY; - locationRequest.interval = 1000; + locationRequest.interval = 500; List locationRequestList = [locationRequest]; LocationSettingsRequest locationSettingsRequest = LocationSettingsRequest(requests: locationRequestList); - locationService.checkLocationSettings(locationSettingsRequest).then((settings) async { - await locationService.getLastLocation().then((value) { - if (value.latitude == null || value.longitude == null) { - showDialog( - context: context, - builder: (BuildContext cxt) => ConfirmDialog( - message: "Unable to get your location, Please check your location settings & try again.", - onTap: () { - Navigator.pop(context); - }, - ), - ); - } else { - if (attendanceType == "QR") { - performQrCodeAttendance(widget.model, lat: value.latitude.toString() ?? "", lng: value.longitude.toString() ?? ""); - } - if (attendanceType == "WIFI") { - performWifiAttendance(widget.model, lat: value.latitude.toString() ?? "", lng: value.longitude.toString() ?? ""); - } - if (attendanceType == "NFC") { - performNfcAttendance(widget.model, lat: value.latitude.toString() ?? "", lng: value.longitude.toString() ?? ""); - } + late StreamSubscription _streamSubscription; + int requestCode = (await (locationService.requestLocationUpdates(locationRequest)))!; + + _streamSubscription = locationService.onLocationData!.listen( + (Location location) async { + Utils.hideLoading(context); + await locationService.removeLocationUpdates(requestCode); + if (attendanceType == "QR") { + performQrCodeAttendance(widget.model, lat: location.latitude.toString() ?? "", lng: location.longitude.toString() ?? ""); } - }).catchError((error) { - print("HUAWEI LOCATION getLastLocation ERROR!!!!!"); - print(error); - }); - }).catchError((error) { - print("HUAWEI LOCATION checkLocationSettings ERROR!!!!!"); - print(error); - if (error.code == "LOCATION_SETTINGS_NOT_AVAILABLE") { - // Location service not enabled. - } - }); + if (attendanceType == "WIFI") { + performWifiAttendance(widget.model, lat: location.latitude.toString() ?? "", lng: location.longitude.toString() ?? ""); + } + if (attendanceType == "NFC") { + performNfcAttendance(widget.model, lat: location.latitude.toString() ?? "", lng: location.longitude.toString() ?? ""); + } + requestCode = 0; + }, + ); + + // locationService.checkLocationSettings(locationSettingsRequest).then((settings) async { + // await locationService.getLastLocation().then((value) { + // if (value.latitude == null || value.longitude == null) { + // showDialog( + // context: context, + // builder: (BuildContext cxt) => ConfirmDialog( + // message: "Unable to get your location, Please check your location settings & try again.", + // onTap: () { + // Navigator.pop(context); + // }, + // ), + // ); + // } else { + // if (attendanceType == "QR") { + // performQrCodeAttendance(widget.model, lat: value.latitude.toString() ?? "", lng: value.longitude.toString() ?? ""); + // } + // if (attendanceType == "WIFI") { + // performWifiAttendance(widget.model, lat: value.latitude.toString() ?? "", lng: value.longitude.toString() ?? ""); + // } + // if (attendanceType == "NFC") { + // performNfcAttendance(widget.model, lat: value.latitude.toString() ?? "", lng: value.longitude.toString() ?? ""); + // } + // } + // }).catchError((error) { + // print("HUAWEI LOCATION getLastLocation ERROR!!!!!"); + // print(error); + // }); + // }).catchError((error) { + // print("HUAWEI LOCATION checkLocationSettings ERROR!!!!!"); + // print(error); + // if (error.code == "LOCATION_SETTINGS_NOT_AVAILABLE") { + // // Location service not enabled. + // } + // }); } catch (error) { print("HUAWEI LOCATION ERROR!!!!!"); print(error); diff --git a/pubspec.yaml b/pubspec.yaml index bc70be9..d154f9f 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -16,7 +16,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: 3.2.93+300032 +version: 3.2.991+300039 environment: sdk: ">=2.16.0 <3.0.0" @@ -46,7 +46,7 @@ dependencies: local_auth: ^1.1.9 fluttertoast: ^8.0.8 syncfusion_flutter_calendar: ^19.4.48 -# flutter_calendar_carousel: ^2.1.0 + # flutter_calendar_carousel: ^2.1.0 pie_chart: ^5.1.0 shared_preferences: ^2.0.12 firebase_messaging: ^13.0.4 @@ -54,9 +54,9 @@ dependencies: logger: ^1.1.0 flutter_countdown_timer: ^4.1.0 nfc_manager: ^3.2.0 -# uuid: ^3.0.6 -# device_info_plus: ^4.0.0 -# android_id: ^0.1.3+1 + # uuid: ^3.0.6 + # device_info_plus: ^4.0.0 + # android_id: ^0.1.3+1 platform_device_id: ^1.0.1 image_picker: ^0.8.5+3 file_picker: ^4.6.1 @@ -66,21 +66,21 @@ dependencies: open_file: ^3.2.1 wifi_iot: ^0.3.18 flutter_html: ^3.0.0-alpha.6 -# flutter_barcode_scanner: ^2.0.0 + # flutter_barcode_scanner: ^2.0.0 qr_code_scanner: ^1.0.1 -# qr_flutter: ^4.0.0 + # qr_flutter: ^4.0.0 url_launcher: ^6.0.15 share: 2.0.4 flutter_rating_bar: ^4.0.1 auto_size_text: ^3.0.0 pull_to_refresh: ^2.0.0 -# lottie json animations + # lottie json animations lottie: any -# Marathon Card Swipe + # Marathon Card Swipe appinio_swiper: ^1.1.1 expandable: ^5.0.1 -# networkImage + # networkImage cached_network_image: ^3.2.2 #Chat @@ -101,12 +101,13 @@ dependencies: video_player: ^2.5.1 just_audio: ^0.9.30 -# safe_device: ^1.1.2 + # safe_device: ^1.1.2 flutter_layout_grid: ^2.0.1 #Huawei Dependencies -# huawei_hmsavailability: ^6.6.0+300 - huawei_location: 6.0.0+302 + # huawei_hmsavailability: ^6.6.0+300 +# huawei_location: 6.0.0+302 + huawei_location: ^6.11.0+301 huawei_push: ^6.7.0+300 firebase_crashlytics: ^2.9.0 @@ -114,7 +115,7 @@ dependencies: carousel_slider: ^4.2.1 #Huawei Specified -# store_checker: ^1.1.0 + # store_checker: ^1.1.0 google_api_availability: ^3.0.1 From 5098aa7f901d3114b7ef5b602eabf0b6599759ae Mon Sep 17 00:00:00 2001 From: haroon amjad Date: Thu, 10 Aug 2023 14:20:47 +0300 Subject: [PATCH 13/19] my docs upload fix --- android/gradle/wrapper/gradle-wrapper.properties | 2 +- lib/ui/screens/my_documents/my_documents_fragment.dart | 9 ++++++--- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/android/gradle/wrapper/gradle-wrapper.properties b/android/gradle/wrapper/gradle-wrapper.properties index ed1a787..2f8758c 100644 --- a/android/gradle/wrapper/gradle-wrapper.properties +++ b/android/gradle/wrapper/gradle-wrapper.properties @@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.0.2-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-7.3.3-bin.zip \ No newline at end of file diff --git a/lib/ui/screens/my_documents/my_documents_fragment.dart b/lib/ui/screens/my_documents/my_documents_fragment.dart index 89ad69d..e1be0a4 100644 --- a/lib/ui/screens/my_documents/my_documents_fragment.dart +++ b/lib/ui/screens/my_documents/my_documents_fragment.dart @@ -75,8 +75,11 @@ class _MyDocumentsFragmentState extends State { padding: const EdgeInsets.only(left: 21, right: 21, bottom: 21, top: 11), itemBuilder: (cxt, index) { return MyDocumentItem(documentfilteredList[index], getColorByDocumentStatus(documentfilteredList[index].dOCUMENTSTATUS!)).onPress(() { - Navigator.pushNamed(context, AppRoutes.addDynamicInput, - arguments: DynamicListViewParams(documentfilteredList[index].dOCUMENTTYPE!, documentfilteredList[index].fUNCTIONNAME!, selectedEmp: AppState().getUserName, popUntilRoute: AppRoutes.myDocuments)); + Navigator.pushNamed( + context, + AppRoutes.addDynamicInput, + arguments: DynamicListViewParams(documentfilteredList[index].dOCUMENTTYPE!, documentfilteredList[index].fUNCTIONNAME!, selectedEmp: AppState().getUserName), + ); }); }, separatorBuilder: (cxt, index) => 12.height, @@ -107,7 +110,7 @@ class _MyDocumentsFragmentState extends State { mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ title.toText10(), - value.toText20(isBold: true, color: color), + value.toText18(isBold: true, color: color), ], ), ).onPress(() { From a48d70364296b63cffbaba2bc7a770ae0650ddf5 Mon Sep 17 00:00:00 2001 From: haroon amjad Date: Thu, 24 Aug 2023 18:19:46 +0300 Subject: [PATCH 14/19] ITG ADs update --- lib/api/dashboard_api_client.dart | 2 +- lib/classes/consts.dart | 4 +- lib/models/itg/advertisement.dart | 220 +++++++++++------- lib/models/itg/survey_model.dart | 30 +-- .../itg_forms_models/itg_request_model.dart | 2 +- lib/ui/landing/dashboard_screen.dart | 2 +- .../itg/its_add_screen_video_image.dart | 127 +++++++--- 7 files changed, 243 insertions(+), 144 deletions(-) diff --git a/lib/api/dashboard_api_client.dart b/lib/api/dashboard_api_client.dart index 544ba71..77cc37d 100644 --- a/lib/api/dashboard_api_client.dart +++ b/lib/api/dashboard_api_client.dart @@ -201,7 +201,7 @@ class DashboardApiClient { }, url, postParams); } - Future setAdvertisementViewed(String masterID, int advertisementId, String ackValue) async { + Future setAdvertisementViewed(String masterID, int advertisementId, String? ackValue) async { String url = "${ApiConsts.cocRest}Mohemm_ITG_UpdateAdvertisementAsViewed"; Map postParams = { diff --git a/lib/classes/consts.dart b/lib/classes/consts.dart index 45ef661..32b3fc7 100644 --- a/lib/classes/consts.dart +++ b/lib/classes/consts.dart @@ -3,8 +3,8 @@ import 'package:mohem_flutter_app/ui/marathon/widgets/question_card.dart'; class ApiConsts { //static String baseUrl = "http://10.200.204.20:2801/"; // Local server // static String baseUrl = "https://erptstapp.srca.org.sa"; // SRCA server - // static String baseUrl = "https://uat.hmgwebservices.com"; // UAT server - static String baseUrl = "https://hmgwebservices.com"; // Live server + static String baseUrl = "https://uat.hmgwebservices.com"; // UAT server + // static String baseUrl = "https://hmgwebservices.com"; // Live server static String baseUrlServices = baseUrl + "/Services/"; // server // static String baseUrlServices = "https://api.cssynapses.com/tangheem/"; // Live server static String utilitiesRest = baseUrlServices + "Utilities.svc/REST/"; diff --git a/lib/models/itg/advertisement.dart b/lib/models/itg/advertisement.dart index 96f4037..ebcf704 100644 --- a/lib/models/itg/advertisement.dart +++ b/lib/models/itg/advertisement.dart @@ -1,108 +1,156 @@ class Advertisement { + int? advertisementId; + String? advertisementTitle; + int? durationInSeconds; + bool? showDelete; + dynamic acknowledgment; + late bool isOptional; + List? viewAttachFileColl; + int? skipButtonId; + List? actionButtonsColl; + bool? isActive; + num? pageSize; + num? pageNo; + num? languageId; + Advertisement({ this.advertisementId, this.advertisementTitle, this.durationInSeconds, this.showDelete, this.acknowledgment, + required this.isOptional, + // this.skipBtnTextEn, + // this.skipBtnTextAr, this.viewAttachFileColl, + this.skipButtonId, + this.actionButtonsColl, this.isActive, this.pageSize, this.pageNo, this.languageId, - this.isOptional, - this.skipButtonTextEn, - this.skipButtonTextAr, }); - final int? advertisementId; - final String? advertisementTitle; - final int? durationInSeconds; - final bool? showDelete; - final dynamic acknowledgment; - final List? viewAttachFileColl; - final bool? isActive; - final dynamic pageSize; - final dynamic pageNo; - final dynamic languageId; - final bool? isOptional; - final String? skipButtonTextEn; - final String? skipButtonTextAr; - - factory Advertisement.fromJson(Map json) => Advertisement( - advertisementId: json["advertisementId"] == null ? null : json["advertisementId"], - advertisementTitle: json["advertisementTitle"] == null ? null : json["advertisementTitle"], - durationInSeconds: json["durationInSeconds"] == null ? null : json["durationInSeconds"], - showDelete: json["showDelete"] == null ? null : json["showDelete"], - acknowledgment: json["acknowledgment"], - viewAttachFileColl: json["viewAttachFileColl"] == null ? null : List.from(json["viewAttachFileColl"].map((x) => ViewAttachFileColl.fromJson(x))), - isActive: json["isActive"] == null ? null : json["isActive"], - pageSize: json["pageSize"], - pageNo: json["pageNo"], - languageId: json["languageId"], - isOptional: json["isOptional"] == null ? null : json["isOptional"], - skipButtonTextEn: json["skipBtnTextEn"] == null ? null : json["skipBtnTextEn"], - skipButtonTextAr: json["skipBtnTextAr"] == null ? null : json["skipBtnTextAr"], - ); + Advertisement.fromJson(Map json) { + advertisementId = json['advertisementId']; + advertisementTitle = json['advertisementTitle']; + durationInSeconds = json['durationInSeconds']; + showDelete = json['showDelete']; + acknowledgment = json['acknowledgment']; + isOptional = json['isOptional']; + // skipBtnTextEn = json['skipBtnTextEn']; + // skipBtnTextAr = json['skipBtnTextAr']; + if (json['viewAttachFileColl'] != null) { + viewAttachFileColl = []; + json['viewAttachFileColl'].forEach((v) { + viewAttachFileColl!.add(ViewAttachFileColl.fromJson(v)); + }); + } + skipButtonId = json['skipButtonId']; + if (json['actionButtonsColl'] != null) { + actionButtonsColl = []; + json['actionButtonsColl'].forEach((v) { + actionButtonsColl!.add(ActionButtonsColl.fromJson(v)); + }); + } + isActive = json['isActive']; + pageSize = json['pageSize']; + pageNo = json['pageNo']; + languageId = json['languageId']; + } - Map toJson() => { - "advertisementId": advertisementId == null ? null : advertisementId, - "advertisementTitle": advertisementTitle == null ? null : advertisementTitle, - "durationInSeconds": durationInSeconds == null ? null : durationInSeconds, - "showDelete": showDelete == null ? null : showDelete, - "acknowledgment": acknowledgment, - "viewAttachFileColl": viewAttachFileColl == null ? null : List.from(viewAttachFileColl!.map((x) => x.toJson())), - "isActive": isActive == null ? null : isActive, - "pageSize": pageSize, - "pageNo": pageNo, - "languageId": languageId, - }; + Map toJson() { + Map data = Map(); + data['advertisementId'] = this.advertisementId; + data['advertisementTitle'] = this.advertisementTitle; + data['durationInSeconds'] = this.durationInSeconds; + data['showDelete'] = this.showDelete; + data['acknowledgment'] = this.acknowledgment; + data['isOptional'] = this.isOptional; + // data['skipBtnTextEn'] = this.skipBtnTextEn; + // data['skipBtnTextAr'] = this.skipBtnTextAr; + if (this.viewAttachFileColl != null) { + data['viewAttachFileColl'] = this.viewAttachFileColl!.map((v) => v.toJson()).toList(); + } + data['skipButtonId'] = this.skipButtonId; + if (this.actionButtonsColl != null) { + data['actionButtonsColl'] = this.actionButtonsColl!.map((v) => v.toJson()).toList(); + } + data['isActive'] = this.isActive; + data['pageSize'] = this.pageSize; + data['pageNo'] = this.pageNo; + data['languageId'] = this.languageId; + return data; + } } class ViewAttachFileColl { - ViewAttachFileColl({ - this.attachmentId, - this.fileName, - this.contentType, - this.attachFileStream, - this.base64String, - this.isActive, - this.referenceItemId, - this.content, - this.filePath, - }); + dynamic attachmentId; + String? fileName; + String? contentType; + dynamic attachFileStream; + String? base64String; + dynamic isActive; + dynamic referenceItemId; + dynamic content; + dynamic filePath; + + ViewAttachFileColl({this.attachmentId, this.fileName, this.contentType, this.attachFileStream, this.base64String, this.isActive, this.referenceItemId, this.content, this.filePath}); + + ViewAttachFileColl.fromJson(Map json) { + attachmentId = json['attachmentId']; + fileName = json['fileName']; + contentType = json['contentType']; + attachFileStream = json['attachFileStream']; + base64String = json['base64String']; + isActive = json['isActive']; + referenceItemId = json['referenceItemId']; + content = json['content']; + filePath = json['filePath']; + } + + Map toJson() { + Map data = new Map(); + data['attachmentId'] = this.attachmentId; + data['fileName'] = this.fileName; + data['contentType'] = this.contentType; + data['attachFileStream'] = this.attachFileStream; + data['base64String'] = this.base64String; + data['isActive'] = this.isActive; + data['referenceItemId'] = this.referenceItemId; + data['content'] = this.content; + data['filePath'] = this.filePath; + return data; + } +} + +class ActionButtonsColl { + late int actionButtonId; + late String btnTextEn; + late String btnTextAr; + late String actionValue; + late dynamic iconOrImage; + late int orderNo; - final dynamic attachmentId; - final String? fileName; - final String? contentType; - final dynamic attachFileStream; - final String? base64String; - final dynamic isActive; - final dynamic referenceItemId; - final dynamic content; - final dynamic filePath; + ActionButtonsColl({required this.actionButtonId, required this.btnTextEn, required this.btnTextAr, required this.actionValue, required this.iconOrImage, required this.orderNo}); - factory ViewAttachFileColl.fromJson(Map json) => ViewAttachFileColl( - attachmentId: json["attachmentId"], - fileName: json["fileName"] == null ? null : json["fileName"], - contentType: json["contentType"] == null ? null : json["contentType"], - attachFileStream: json["attachFileStream"], - base64String: json["base64String"] == null ? null : json["base64String"], - isActive: json["isActive"], - referenceItemId: json["referenceItemId"], - content: json["content"], - filePath: json["filePath"], - ); + ActionButtonsColl.fromJson(Map json) { + actionButtonId = json['actionButtonId']; + btnTextEn = json['btnTextEn']; + btnTextAr = json['btnTextAr']; + actionValue = json['actionValue']; + iconOrImage = json['iconOrImage']; + orderNo = json['orderNo']; + } - Map toJson() => { - "attachmentId": attachmentId, - "fileName": fileName == null ? null : fileName, - "contentType": contentType == null ? null : contentType, - "attachFileStream": attachFileStream, - "base64String": base64String == null ? null : base64String, - "isActive": isActive, - "referenceItemId": referenceItemId, - "content": content, - "filePath": filePath, - }; + Map toJson() { + Map data = new Map(); + data['actionButtonId'] = this.actionButtonId; + data['btnTextEn'] = this.btnTextEn; + data['btnTextAr'] = this.btnTextAr; + data['actionValue'] = this.actionValue; + data['iconOrImage'] = this.iconOrImage; + data['orderNo'] = this.orderNo; + return data; + } } diff --git a/lib/models/itg/survey_model.dart b/lib/models/itg/survey_model.dart index 7cdbbdd..f9ac415 100644 --- a/lib/models/itg/survey_model.dart +++ b/lib/models/itg/survey_model.dart @@ -5,9 +5,9 @@ class SurveyModel { String? description; List? questions; bool? isActive; - Null? pageSize; - Null? pageNo; - Null? languageId; + dynamic pageSize; + dynamic pageNo; + dynamic languageId; SurveyModel({this.surveyId, this.referenceNo, this.title, this.description, this.questions, this.isActive, this.pageSize, this.pageNo, this.languageId}); @@ -51,13 +51,13 @@ class Questions { bool? isRequired; String? type; int? sequenceNo; - Null? surveyId; + dynamic surveyId; List? options; - Null? rspPercentage; - Null? isActive; - Null? pageSize; - Null? pageNo; - Null? languageId; + dynamic rspPercentage; + dynamic isActive; + dynamic pageSize; + dynamic pageNo; + dynamic languageId; Questions({this.questionId, this.title, this.isRequired, this.type, this.sequenceNo, this.surveyId, this.options, this.rspPercentage, this.isActive, this.pageSize, this.pageNo, this.languageId}); @@ -107,12 +107,12 @@ class Options { bool? isCommentsRequired; int? sequenceNo; int? questionId; - Null? rspPercentage; - Null? count; - Null? isActive; - Null? pageSize; - Null? pageNo; - Null? languageId; + dynamic rspPercentage; + dynamic count; + dynamic isActive; + dynamic pageSize; + dynamic pageNo; + dynamic languageId; Options({this.optionId, this.title, this.isCommentsRequired, this.sequenceNo, this.questionId, this.rspPercentage, this.count, this.isActive, this.pageSize, this.pageNo, this.languageId}); diff --git a/lib/models/itg_forms_models/itg_request_model.dart b/lib/models/itg_forms_models/itg_request_model.dart index ba10305..87d8280 100644 --- a/lib/models/itg_forms_models/itg_request_model.dart +++ b/lib/models/itg_forms_models/itg_request_model.dart @@ -6,7 +6,7 @@ class ITGRequest { List? allowedActions; List? attachments; List? fieldGoups; - Null? grantFields; + dynamic grantFields; List? wFHistory; ITGRequest({this.allowedActions, this.attachments, this.fieldGoups, this.grantFields, this.wFHistory}); diff --git a/lib/ui/landing/dashboard_screen.dart b/lib/ui/landing/dashboard_screen.dart index 2db09d0..4116594 100644 --- a/lib/ui/landing/dashboard_screen.dart +++ b/lib/ui/landing/dashboard_screen.dart @@ -163,7 +163,7 @@ class _DashboardScreenState extends State with WidgetsBindingOb print("-------------------- Survey ----------------------------"); if (val.result!.data!.notificationType == "Survey") { DashboardApiClient().getAdvertisementDetail(val.result!.data!.notificationMasterId ?? "").then( - (value) { + (value) { if (value!.mohemmItgResponseItem!.statusCode == 200) { if (value.mohemmItgResponseItem!.result!.data != null) { // Navigator.pushNamed(context, AppRoutes.survey, arguments: val.result!.data); diff --git a/lib/ui/landing/itg/its_add_screen_video_image.dart b/lib/ui/landing/itg/its_add_screen_video_image.dart index 1e280d8..8ce89d0 100644 --- a/lib/ui/landing/itg/its_add_screen_video_image.dart +++ b/lib/ui/landing/itg/its_add_screen_video_image.dart @@ -61,6 +61,11 @@ class _ITGAdsScreenState extends State { isVideo = true; _futureController = createVideoPlayer(rFile!); } + + advertisementData?.actionButtonsColl!.forEach((element) { + advertisementData?.actionButtonsColl!.removeWhere((element1) => element1.actionButtonId == advertisementData?.skipButtonId); + }); + setState(() {}); } @@ -152,55 +157,101 @@ class _ITGAdsScreenState extends State { textStyle: const TextStyle(color: Colors.white, fontSize: 16, letterSpacing: -0.48, fontWeight: FontWeight.bold), ), 50.height, + if (advertisementData?.isOptional ?? false) + DefaultButton(AppState().isArabic(context) ? "يتخطى" : "Skip", () async { + Navigator.pop(context); + DashboardApiClient().setAdvertisementViewed(masterID!, advertisementData!.advertisementId!, "Skip").then((value) { + logger.d(value); + }); + }).paddingOnly(left: 60.0, right: 60.0, top: 8, bottom: 8), ValueListenableBuilder( valueListenable: hasTimerEnded, builder: (context, val, child) { if (hasTimerEndedBool) { - return Row( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Container( - padding: const EdgeInsets.all(16), decoration: Utils.containerRadius(MyColors.white, 10), child: const Icon(Icons.thumb_up, color: MyColors.gradiantEndColor)) - .onPress(() { - try { - Navigator.pop(context); - DashboardApiClient().setAdvertisementViewed(masterID!, advertisementData!.advertisementId!, "Like").then((value) { - logger.d(value); - }); - } catch (ex) { - logger.wtf(ex); - Utils.handleException(ex, context, null); - } - }), - 20.width, - Container( - padding: const EdgeInsets.all(16), decoration: Utils.containerRadius(MyColors.white, 10), child: const Icon(Icons.thumb_down, color: MyColors.gradiantEndColor)) - .onPress(() { - try { - Navigator.pop(context); - DashboardApiClient().setAdvertisementViewed(masterID!, advertisementData!.advertisementId!, "Dislike").then((value) { - logger.d(value); - }); - } catch (ex) { - logger.wtf(ex); - Utils.handleException(ex, context, null); - } - }), - ], + return GridView.builder( + padding: EdgeInsets.zero, + itemCount: advertisementData?.actionButtonsColl!.length, + shrinkWrap: true, + physics: const NeverScrollableScrollPhysics(), + itemBuilder: (context, index) { + String? btnText = AppState().isArabic(context) ? advertisementData?.actionButtonsColl![index].btnTextAr : advertisementData?.actionButtonsColl![index].btnTextEn; + return DefaultButton(btnText!, () async { + Navigator.pop(context); + DashboardApiClient() + .setAdvertisementViewed(masterID!, advertisementData!.advertisementId!, advertisementData?.actionButtonsColl![index].actionValue) + .then((value) { + logger.d(value); + }); + }).paddingOnly(left: 60.0, right: 60.0, top: 8, bottom: 8); + }, + gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount( + crossAxisCount: 1, + childAspectRatio: (7.0), + ), ); + // Row( + // mainAxisAlignment: MainAxisAlignment.center, + // children: [ + // Container(padding: const EdgeInsets.all(16), decoration: Utils.containerRadius(MyColors.white, 10), child: const Icon(Icons.thumb_up, color: MyColors.gradiantEndColor)) + // .onPress(() { + // try { + // Navigator.pop(context); + // DashboardApiClient().setAdvertisementViewed(masterID!, advertisementData!.advertisementId!, "Like").then((value) { + // logger.d(value); + // }); + // } catch (ex) { + // logger.wtf(ex); + // Utils.handleException(ex, context, null); + // } + // }), + // 20.width, + // Container( + // padding: const EdgeInsets.all(16), decoration: Utils.containerRadius(MyColors.white, 10), child: const Icon(Icons.thumb_down, color: MyColors.gradiantEndColor)) + // .onPress(() { + // try { + // Navigator.pop(context); + // DashboardApiClient().setAdvertisementViewed(masterID!, advertisementData!.advertisementId!, "Dislike").then((value) { + // logger.d(value); + // }); + // } catch (ex) { + // logger.wtf(ex); + // Utils.handleException(ex, context, null); + // } + // }), + // ], + // ); } else { return Container(); } }, ), 20.height, - if (advertisementData?.isOptional ?? false) - DefaultButton(AppState().isArabic(context) ? advertisementData?.skipButtonTextAr ?? "Skip" : advertisementData?.skipButtonTextEn ?? "Skip", () async { - Navigator.pop(context); - DashboardApiClient().setAdvertisementViewed(masterID!, advertisementData!.advertisementId!, "Skip").then((value) { - logger.d(value); - }); - }).paddingOnly(left: 100, right: 100) + // if (advertisementData?.isOptional ?? false) + // GridView.builder( + // padding: EdgeInsets.zero, + // itemCount: advertisementData?.actionButtonsColl!.length, + // shrinkWrap: true, + // physics: const NeverScrollableScrollPhysics(), + // itemBuilder: (context, index) { + // String? btnText = AppState().isArabic(context) ? advertisementData?.actionButtonsColl![index].btnTextAr : advertisementData?.actionButtonsColl![index].btnTextEn; + // return DefaultButton(btnText!, () async { + // Navigator.pop(context); + // DashboardApiClient().setAdvertisementViewed(masterID!, advertisementData!.advertisementId!, advertisementData?.actionButtonsColl![index].actionValue).then((value) { + // logger.d(value); + // }); + // }).paddingAll(8); + // }, + // gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount( + // crossAxisCount: 2, + // childAspectRatio: (4.0), + // ), + // ) + // DefaultButton(AppState().isArabic(context) ? advertisementData?.skipButtonTextAr ?? "Skip" : advertisementData?.skipButtonTextEn ?? "Skip", () async { + // Navigator.pop(context); + // DashboardApiClient().setAdvertisementViewed(masterID!, advertisementData!.advertisementId!, "Skip").then((value) { + // logger.d(value); + // }); + // }).paddingOnly(left: 100, right: 100) ], ); } else { From ed9705f18f424f300eb1ca164d93cbc34a83b9af Mon Sep 17 00:00:00 2001 From: haroon amjad Date: Sun, 3 Sep 2023 09:56:24 +0300 Subject: [PATCH 15/19] fixes --- lib/generated/codegen_loader.g.dart | 3 +-- lib/ui/work_list/worklist_fragments/info_fragments.dart | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/lib/generated/codegen_loader.g.dart b/lib/generated/codegen_loader.g.dart index 1daf8f7..1e2d5af 100644 --- a/lib/generated/codegen_loader.g.dart +++ b/lib/generated/codegen_loader.g.dart @@ -1098,8 +1098,7 @@ static const Map en_US = { "allDocuments": "All\nDocuments", "expiredDocuments": "Expired\nDocuments", "missingDocuments": "Missing\nDocuments", - "uploadedDocuments": "Uploaded\nDocuments" - "resetAdPassword": "Reset AD Password", + "uploadedDocuments": "Uploaded\nDocuments", "manage": "Manage", "members": "Members", "areYouSureWantTodelete": "Are you sure want to delete?", diff --git a/lib/ui/work_list/worklist_fragments/info_fragments.dart b/lib/ui/work_list/worklist_fragments/info_fragments.dart index d2c64f3..5edb6f1 100644 --- a/lib/ui/work_list/worklist_fragments/info_fragments.dart +++ b/lib/ui/work_list/worklist_fragments/info_fragments.dart @@ -164,7 +164,7 @@ class InfoFragment extends StatelessWidget { ), ItemDetailGrid( ItemDetailViewCol(LocaleKeys.otherCharges.tr(), poHeaderList[index].oTHERCHARGES?.toString() ?? ""), - ItemDetailViewCol(LocaleKeys.totalPOAmountWithVAT.tr(), poHeaderList[index].tOTPOAMT.toString() ?? ""), + ItemDetailViewCol(LocaleKeys.totalPOAmountWithVAT.tr(), poHeaderList[index].lOCCURTOTPOAMT.toString() ?? ""), ), ItemDetailGrid( ItemDetailViewCol(LocaleKeys.totalPOAmountInWords.tr(), poHeaderList[index].tOTPOAMTWORD ?? ""), From 281f0bab7885f2f1e1c2a7c7fac04566878d0552 Mon Sep 17 00:00:00 2001 From: haroon amjad Date: Wed, 20 Sep 2023 09:27:08 +0300 Subject: [PATCH 16/19] updates --- ios/Runner/Info.plist | 1 - lib/provider/chat_provider_model.dart | 2 +- lib/ui/chat/chat_home.dart | 4 ++-- lib/ui/marathon/marathon_screen.dart | 4 ++-- 4 files changed, 5 insertions(+), 6 deletions(-) diff --git a/ios/Runner/Info.plist b/ios/Runner/Info.plist index 24ba08c..cb62b88 100644 --- a/ios/Runner/Info.plist +++ b/ios/Runner/Info.plist @@ -65,7 +65,6 @@ fetch remote-notification - voip UILaunchStoryboardName LaunchScreen diff --git a/lib/provider/chat_provider_model.dart b/lib/provider/chat_provider_model.dart index 824a19f..00545b2 100644 --- a/lib/provider/chat_provider_model.dart +++ b/lib/provider/chat_provider_model.dart @@ -168,7 +168,7 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { Future getUserRecentChats() async { ChatUserModel recentChat = await ChatApiClient().getRecentChats(); ChatUserModel favUList = await ChatApiClient().getFavUsers(); - userGroups = await ChatApiClient().getGroupsByUserId(); + // userGroups = await ChatApiClient().getGroupsByUserId(); if (favUList.response != null && recentChat.response != null) { favUsersList = favUList.response!; favUsersList.sort((ChatUser a, ChatUser b) => diff --git a/lib/ui/chat/chat_home.dart b/lib/ui/chat/chat_home.dart index dc4265f..426c9a2 100644 --- a/lib/ui/chat/chat_home.dart +++ b/lib/ui/chat/chat_home.dart @@ -91,7 +91,7 @@ class _ChatHomeState extends State { child: Row( children: [ myTab(LocaleKeys.mychats.tr(), 0), - myTab(LocaleKeys.group.tr(), 1), + // myTab(LocaleKeys.group.tr(), 1), myTab(LocaleKeys.favorite.tr(), 2), AppState().getempStatusIsManager ? myTab(LocaleKeys.myTeam.tr(), 3) : const SizedBox(), ], @@ -107,7 +107,7 @@ class _ChatHomeState extends State { }, children: [ ChatHomeScreen(), - GropChatHomeScreen(), + // GropChatHomeScreen(), ChatFavoriteUsersScreen(), AppState().getempStatusIsManager ? const MyTeamScreen() : const SizedBox(), ], diff --git a/lib/ui/marathon/marathon_screen.dart b/lib/ui/marathon/marathon_screen.dart index 6dbbd18..d5fc8c4 100644 --- a/lib/ui/marathon/marathon_screen.dart +++ b/lib/ui/marathon/marathon_screen.dart @@ -81,8 +81,8 @@ class MarathonScreen extends StatelessWidget { displayLocalizedContent( isPhoneLangArabic: AppState().isArabic(context), selectedLanguage: provider.demoMarathonDetailModel.selectedLanguage!, - arabicContent: AppState().memberInformationList!.eMPLOYEEDISPLAYNAMEAr!, - englishContent: AppState().memberInformationList!.eMPLOYEEDISPLAYNAMEEn!, + arabicContent: AppState().memberInformationList!.eMPLOYEEDISPLAYNAMEAr ?? "", + englishContent: AppState().memberInformationList!.eMPLOYEEDISPLAYNAMEEn ?? "", ).toText22( color: MyColors.grey3AColor, isCentered: true, From 58962ede0339bf1b1d3f567d2804200b3befda2b Mon Sep 17 00:00:00 2001 From: Sikander Saleem Date: Tue, 3 Oct 2023 16:49:39 +0300 Subject: [PATCH 17/19] CR-6273 implemented. --- assets/langs/ar-SA.json | 3 +- assets/langs/en-US.json | 3 +- lib/classes/consts.dart | 4 +-- lib/generated/locale_keys.g.dart | 1 + .../employee_documents_list_model.dart | 31 ++++++++++++------- lib/provider/dashboard_provider_model.dart | 1 - lib/ui/landing/widget/services_widget.dart | 2 +- lib/ui/misc/request_submit_screen.dart | 10 ++++-- .../dynamic_screens/dynamic_input_screen.dart | 2 +- .../dynamic_listview_screen.dart | 15 +++++++-- .../my_documents/my_documents_fragment.dart | 8 +++-- .../my_documents/my_documents_screen.dart | 1 + lib/widgets/my_document_item.dart | 2 +- 13 files changed, 57 insertions(+), 26 deletions(-) diff --git a/assets/langs/ar-SA.json b/assets/langs/ar-SA.json index 2ed5acc..3a4cd96 100644 --- a/assets/langs/ar-SA.json +++ b/assets/langs/ar-SA.json @@ -539,5 +539,6 @@ "allDocuments": "كافة المستندات", "expiredDocuments": "المستندات منتهية الصلاحية", "missingDocuments": "مستندات مفقودة", - "uploadedDocuments": "المستندات التي تم تحميلها" + "uploadedDocuments": "المستندات التي تم تحميلها", + "addAtLeastOneAttachment": "الرجاء إضافة مرفق واحد على الأقل." } \ No newline at end of file diff --git a/assets/langs/en-US.json b/assets/langs/en-US.json index 38aeaa7..02bcd94 100644 --- a/assets/langs/en-US.json +++ b/assets/langs/en-US.json @@ -559,5 +559,6 @@ "searchByUserName": "Search By Username", "userSearch": "User Search", "userName": "User Name", - "userId": "UserID" + "userId": "UserID", + "addAtLeastOneAttachment": "Please add at least one attachment." } \ No newline at end of file diff --git a/lib/classes/consts.dart b/lib/classes/consts.dart index 64047e5..9023f93 100644 --- a/lib/classes/consts.dart +++ b/lib/classes/consts.dart @@ -3,8 +3,8 @@ import 'package:mohem_flutter_app/ui/marathon/widgets/question_card.dart'; class ApiConsts { //static String baseUrl = "http://10.200.204.20:2801/"; // Local server // static String baseUrl = "https://erptstapp.srca.org.sa"; // SRCA server - // static String baseUrl = "https://uat.hmgwebservices.com"; // UAT server - static String baseUrl = "https://hmgwebservices.com"; // Live server + static String baseUrl = "https://uat.hmgwebservices.com"; // UAT server + // static String baseUrl = "https://hmgwebservices.com"; // Live server static String baseUrlServices = baseUrl + "/Services/"; // server // static String baseUrlServices = "https://api.cssynapses.com/tangheem/"; // Live server static String utilitiesRest = baseUrlServices + "Utilities.svc/REST/"; diff --git a/lib/generated/locale_keys.g.dart b/lib/generated/locale_keys.g.dart index c5ec04f..5455a92 100644 --- a/lib/generated/locale_keys.g.dart +++ b/lib/generated/locale_keys.g.dart @@ -546,4 +546,5 @@ abstract class LocaleKeys { static const userSearch ='userSearch'; static const userName ='userName'; static const userId ='userId'; + static const addAtLeastOneAttachment ='addAtLeastOneAttachment'; } diff --git a/lib/models/my_documents/employee_documents_list_model.dart b/lib/models/my_documents/employee_documents_list_model.dart index 97ef785..b91bc3d 100644 --- a/lib/models/my_documents/employee_documents_list_model.dart +++ b/lib/models/my_documents/employee_documents_list_model.dart @@ -2,28 +2,35 @@ class EmployeeDocumentsList { String? dOCUMENTREQUIREDSTATUS; String? dOCUMENTSTATUS; String? dOCUMENTTYPE; + String? dOCUMENTTYPENAME; + String? eNTITLEDTOAPPLYFLAG; String? fUNCTIONNAME; - EmployeeDocumentsList({ - this.dOCUMENTREQUIREDSTATUS, - this.dOCUMENTSTATUS, - this.dOCUMENTTYPE, - this.fUNCTIONNAME, - }); + EmployeeDocumentsList( + {this.dOCUMENTREQUIREDSTATUS, + this.dOCUMENTSTATUS, + this.dOCUMENTTYPE, + this.dOCUMENTTYPENAME, + this.eNTITLEDTOAPPLYFLAG, + this.fUNCTIONNAME}); EmployeeDocumentsList.fromJson(Map json) { dOCUMENTREQUIREDSTATUS = json['DOCUMENT_REQUIRED_STATUS']; dOCUMENTSTATUS = json['DOCUMENT_STATUS']; dOCUMENTTYPE = json['DOCUMENT_TYPE']; + dOCUMENTTYPENAME = json['DOCUMENT_TYPE_NAME']; + eNTITLEDTOAPPLYFLAG = json['ENTITLED_TO_APPLY_FLAG']; fUNCTIONNAME = json['FUNCTION_NAME']; } Map toJson() { - Map data = Map(); - data['DOCUMENT_REQUIRED_STATUS'] = dOCUMENTREQUIREDSTATUS; - data['DOCUMENT_STATUS'] = dOCUMENTSTATUS; - data['DOCUMENT_TYPE'] = dOCUMENTTYPE; - data['FUNCTION_NAME'] = fUNCTIONNAME; + Map data = new Map(); + data['DOCUMENT_REQUIRED_STATUS'] = this.dOCUMENTREQUIREDSTATUS; + data['DOCUMENT_STATUS'] = this.dOCUMENTSTATUS; + data['DOCUMENT_TYPE'] = this.dOCUMENTTYPE; + data['DOCUMENT_TYPE_NAME'] = this.dOCUMENTTYPENAME; + data['ENTITLED_TO_APPLY_FLAG'] = this.eNTITLEDTOAPPLYFLAG; + data['FUNCTION_NAME'] = this.fUNCTIONNAME; return data; } -} +} \ No newline at end of file diff --git a/lib/provider/dashboard_provider_model.dart b/lib/provider/dashboard_provider_model.dart index 5eac532..0e18544 100644 --- a/lib/provider/dashboard_provider_model.dart +++ b/lib/provider/dashboard_provider_model.dart @@ -278,7 +278,6 @@ class DashboardProviderModel with ChangeNotifier, DiagnosticableTreeMixin { getMenuEntriesList.add(activeDirectoryEntry); list.add(GetMenuEntriesList(requestType: "ITG_FORMS", prompt: LocaleKeys.itgForms.tr(), menuName: 'ITG_FORMS')); - list.add(GetMenuEntriesList(requestType: "MY_DOCUMENTS", prompt: LocaleKeys.myDocuments.tr(), menuName: 'MY_DOCUMENTS')); } menus.add(Menus(getMenuEntriesList[i], list)); diff --git a/lib/ui/landing/widget/services_widget.dart b/lib/ui/landing/widget/services_widget.dart index 7dabb0c..cc16fc5 100644 --- a/lib/ui/landing/widget/services_widget.dart +++ b/lib/ui/landing/widget/services_widget.dart @@ -207,7 +207,7 @@ class ServicesWidget extends StatelessWidget { } else if (menuEntry.menuName == "MBL_PERINFO_SS") { Navigator.of(context).pushNamed(AppRoutes.profile); return; - } else if (menuEntry.menuName == "MY_DOCUMENTS") { + } else if (menuEntry.menuName!.substring(4, menuEntry.menuName!.length) == "MBL_EMPLOYEE_DOCUMENTS") { Navigator.pushNamed(context, AppRoutes.myDocuments); return; } diff --git a/lib/ui/misc/request_submit_screen.dart b/lib/ui/misc/request_submit_screen.dart index 6fa0ef8..ceba8be 100644 --- a/lib/ui/misc/request_submit_screen.dart +++ b/lib/ui/misc/request_submit_screen.dart @@ -32,8 +32,9 @@ class RequestSubmitScreenParams { String approvalFlag; String? selectedEmployeeID; String? popNavigateToSpecificRoute; + bool isAttachmentMandatory; - RequestSubmitScreenParams(this.title, this.transactionId, this.pItemId, this.approvalFlag, {this.selectedEmployeeID, this.popNavigateToSpecificRoute}); + RequestSubmitScreenParams(this.title, this.transactionId, this.pItemId, this.approvalFlag, {this.selectedEmployeeID, this.popNavigateToSpecificRoute, this.isAttachmentMandatory = false}); } class RequestSubmitScreen extends StatefulWidget { @@ -180,7 +181,7 @@ class _RequestSubmitScreenState extends State { physics: const BouncingScrollPhysics(), children: [ attachmentView( - LocaleKeys.attachments.tr(), + LocaleKeys.attachments.tr() + (params!.isAttachmentMandatory ? "*" : ""), ), 14.height, InputWidget( @@ -210,6 +211,11 @@ class _RequestSubmitScreenState extends State { DefaultButton( LocaleKeys.submit.tr(), () { + if (params!.isAttachmentMandatory && attachmentFiles.isEmpty) { + Utils.showToast(LocaleKeys.addAtLeastOneAttachment.tr()); + return; + } + showDialog( context: context, builder: (cxt) => ConfirmDialog( diff --git a/lib/ui/my_attendance/dynamic_screens/dynamic_input_screen.dart b/lib/ui/my_attendance/dynamic_screens/dynamic_input_screen.dart index c1f5cfe..2f3f1be 100644 --- a/lib/ui/my_attendance/dynamic_screens/dynamic_input_screen.dart +++ b/lib/ui/my_attendance/dynamic_screens/dynamic_input_screen.dart @@ -95,7 +95,7 @@ class _DynamicInputScreenState extends State { SubmitEITTransactionList submitEITTransactionList = await MyAttendanceApiClient().submitEitTransaction(dESCFLEXCONTEXTCODE, dynamicParams!.dynamicId, values, empID: dynamicParams!.selectedEmp); Utils.hideLoading(context); await Navigator.pushNamed(context, AppRoutes.requestSubmitScreen, - arguments: RequestSubmitScreenParams(LocaleKeys.submit.tr(), submitEITTransactionList.pTRANSACTIONID!, submitEITTransactionList.pITEMKEY!, 'eit')); + arguments: RequestSubmitScreenParams(LocaleKeys.submit.tr(), submitEITTransactionList.pTRANSACTIONID!, submitEITTransactionList.pITEMKEY!, 'eit',isAttachmentMandatory: dynamicParams!.isAttachmentMandatory)); if (!AppState().cancelRequestTrancsection) { return; } diff --git a/lib/ui/my_attendance/dynamic_screens/dynamic_listview_screen.dart b/lib/ui/my_attendance/dynamic_screens/dynamic_listview_screen.dart index 9294159..94a201f 100644 --- a/lib/ui/my_attendance/dynamic_screens/dynamic_listview_screen.dart +++ b/lib/ui/my_attendance/dynamic_screens/dynamic_listview_screen.dart @@ -20,12 +20,23 @@ class DynamicListViewParams { String colsURL; bool isUpdate; String? popUntilRoute; + bool isAttachmentMandatory; List? collectionNotificationList; final String? selectedEmp; - DynamicListViewParams(this.title, this.dynamicId, - {this.selectedEmp, this.uRL = 'GET_EIT_DFF_STRUCTURE', this.requestID = '', this.colsURL = '', this.isUpdate = false, this.collectionNotificationList, this.popUntilRoute}); + DynamicListViewParams( + this.title, + this.dynamicId, { + this.selectedEmp, + this.uRL = 'GET_EIT_DFF_STRUCTURE', + this.requestID = '', + this.colsURL = '', + this.isUpdate = false, + this.collectionNotificationList, + this.popUntilRoute, + this.isAttachmentMandatory = false, + }); } class DynamicListViewScreen extends StatefulWidget { diff --git a/lib/ui/screens/my_documents/my_documents_fragment.dart b/lib/ui/screens/my_documents/my_documents_fragment.dart index e1be0a4..b385d15 100644 --- a/lib/ui/screens/my_documents/my_documents_fragment.dart +++ b/lib/ui/screens/my_documents/my_documents_fragment.dart @@ -78,7 +78,8 @@ class _MyDocumentsFragmentState extends State { Navigator.pushNamed( context, AppRoutes.addDynamicInput, - arguments: DynamicListViewParams(documentfilteredList[index].dOCUMENTTYPE!, documentfilteredList[index].fUNCTIONNAME!, selectedEmp: AppState().getUserName), + arguments: DynamicListViewParams(documentfilteredList[index].dOCUMENTTYPE!, documentfilteredList[index].fUNCTIONNAME!, + selectedEmp: AppState().getUserName, isAttachmentMandatory: true), ); }); }, @@ -123,6 +124,9 @@ class _MyDocumentsFragmentState extends State { Color getColorByDocumentStatus(String status) { Color _color; switch (status) { + case "Expired": + _color = MyColors.redA3Color; + break; case "Exist": _color = MyColors.greenColor; break; @@ -143,7 +147,7 @@ class _MyDocumentsFragmentState extends State { List list = []; switch (index) { case 1: - list = documentsList?.where((element) => element.dOCUMENTSTATUS == "Not Exist").toList() ?? []; + list = documentsList?.where((element) => element.dOCUMENTSTATUS == "Expired").toList() ?? []; break; case 2: list = documentsList?.where((element) => element.dOCUMENTSTATUS == "Missing").toList() ?? []; diff --git a/lib/ui/screens/my_documents/my_documents_screen.dart b/lib/ui/screens/my_documents/my_documents_screen.dart index ffddd36..703adeb 100644 --- a/lib/ui/screens/my_documents/my_documents_screen.dart +++ b/lib/ui/screens/my_documents/my_documents_screen.dart @@ -42,6 +42,7 @@ class _MyDocumentsScreenState extends State { documentsList?.clear(); Utils.showLoading(context); documentsList = await ProfileApiClient().getEmployeeDocuments(); + documentsList?.removeWhere((element) => element.eNTITLEDTOAPPLYFLAG!="Y"); Utils.hideLoading(context); setState(() {}); } catch (ex) { diff --git a/lib/widgets/my_document_item.dart b/lib/widgets/my_document_item.dart index b0d4b51..700d6fb 100644 --- a/lib/widgets/my_document_item.dart +++ b/lib/widgets/my_document_item.dart @@ -54,7 +54,7 @@ class MyDocumentItem extends StatelessWidget { crossAxisAlignment: CrossAxisAlignment.start, mainAxisSize: MainAxisSize.min, children: [ - document.dOCUMENTTYPE!.toText16(), + document.dOCUMENTTYPENAME!.toText16(), document.dOCUMENTSTATUS!.toText10(color: color), ], ).expanded, From 7f6f240590bbd88c78315cc6f9e77d1bf313b0b5 Mon Sep 17 00:00:00 2001 From: Sikander Saleem Date: Wed, 11 Oct 2023 11:53:45 +0300 Subject: [PATCH 18/19] CR-6273 improvement. --- .../my_documents/my_documents_fragment.dart | 1 + .../screens/my_documents/my_documents_screen.dart | 1 - lib/widgets/my_document_item.dart | 14 +++++++------- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/lib/ui/screens/my_documents/my_documents_fragment.dart b/lib/ui/screens/my_documents/my_documents_fragment.dart index b385d15..6bc46f7 100644 --- a/lib/ui/screens/my_documents/my_documents_fragment.dart +++ b/lib/ui/screens/my_documents/my_documents_fragment.dart @@ -75,6 +75,7 @@ class _MyDocumentsFragmentState extends State { padding: const EdgeInsets.only(left: 21, right: 21, bottom: 21, top: 11), itemBuilder: (cxt, index) { return MyDocumentItem(documentfilteredList[index], getColorByDocumentStatus(documentfilteredList[index].dOCUMENTSTATUS!)).onPress(() { + if (documentfilteredList[index].eNTITLEDTOAPPLYFLAG != 'Y') return; Navigator.pushNamed( context, AppRoutes.addDynamicInput, diff --git a/lib/ui/screens/my_documents/my_documents_screen.dart b/lib/ui/screens/my_documents/my_documents_screen.dart index 703adeb..ffddd36 100644 --- a/lib/ui/screens/my_documents/my_documents_screen.dart +++ b/lib/ui/screens/my_documents/my_documents_screen.dart @@ -42,7 +42,6 @@ class _MyDocumentsScreenState extends State { documentsList?.clear(); Utils.showLoading(context); documentsList = await ProfileApiClient().getEmployeeDocuments(); - documentsList?.removeWhere((element) => element.eNTITLEDTOAPPLYFLAG!="Y"); Utils.hideLoading(context); setState(() {}); } catch (ex) { diff --git a/lib/widgets/my_document_item.dart b/lib/widgets/my_document_item.dart index 700d6fb..4eb8051 100644 --- a/lib/widgets/my_document_item.dart +++ b/lib/widgets/my_document_item.dart @@ -17,7 +17,7 @@ class MyDocumentItem extends StatelessWidget { Widget build(BuildContext context) { return Container( decoration: BoxDecoration( - color: Colors.white, + color: document.eNTITLEDTOAPPLYFLAG != 'Y' ? Colors.grey.shade300 : Colors.white, borderRadius: BorderRadius.circular(10), boxShadow: [ BoxShadow( @@ -60,12 +60,12 @@ class MyDocumentItem extends StatelessWidget { ).expanded, ], ).expanded, - if(isNotInDetailView) - const Icon( - Icons.arrow_forward, - size: 20, - color: Color(0xff2E303A), - ) + if (isNotInDetailView) + const Icon( + Icons.arrow_forward, + size: 20, + color: Color(0xff2E303A), + ) ], ).paddingOnly(top: 14, bottom: 18, right: 14, left: 24), ], From 74b12391d2c09303b62b374ccf0fea3e8830c252 Mon Sep 17 00:00:00 2001 From: haroon amjad Date: Wed, 11 Oct 2023 13:36:19 +0300 Subject: [PATCH 19/19] update to store for document upload CR --- lib/app_state/app_state.dart | 2 +- lib/classes/consts.dart | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/app_state/app_state.dart b/lib/app_state/app_state.dart index b0c93ee..052ad10 100644 --- a/lib/app_state/app_state.dart +++ b/lib/app_state/app_state.dart @@ -90,7 +90,7 @@ class AppState { String get getHuaweiPushToken => _huaweiPushToken; - final PostParamsModel _postParamsInitConfig = PostParamsModel(channel: 31, versionID: 5.0, mobileType: Platform.isAndroid ? "android" : "ios"); + final PostParamsModel _postParamsInitConfig = PostParamsModel(channel: 31, versionID: 5.2, mobileType: Platform.isAndroid ? "android" : "ios"); void setPostParamsInitConfig() { isAuthenticated = false; diff --git a/lib/classes/consts.dart b/lib/classes/consts.dart index 9023f93..64047e5 100644 --- a/lib/classes/consts.dart +++ b/lib/classes/consts.dart @@ -3,8 +3,8 @@ import 'package:mohem_flutter_app/ui/marathon/widgets/question_card.dart'; class ApiConsts { //static String baseUrl = "http://10.200.204.20:2801/"; // Local server // static String baseUrl = "https://erptstapp.srca.org.sa"; // SRCA server - static String baseUrl = "https://uat.hmgwebservices.com"; // UAT server - // static String baseUrl = "https://hmgwebservices.com"; // Live server + // static String baseUrl = "https://uat.hmgwebservices.com"; // UAT server + static String baseUrl = "https://hmgwebservices.com"; // Live server static String baseUrlServices = baseUrl + "/Services/"; // server // static String baseUrlServices = "https://api.cssynapses.com/tangheem/"; // Live server static String utilitiesRest = baseUrlServices + "Utilities.svc/REST/";