Merge branch 'master' into faiz_cs

# Conflicts:
#	lib/generated/codegen_loader.g.dart
merge-requests/98/head
Faiz Hashmi 3 years ago
commit 8ae8f6d2fe

@ -11,6 +11,7 @@
<application
android:icon="@mipmap/ic_launcher"
android:label="Mohemm"
android:allowBackup="false"
android:networkSecurityConfig="@xml/network_security_config"
android:roundIcon="@mipmap/ic_launcher_round">
<activity

Binary file not shown.

@ -424,6 +424,9 @@
"typeCurrentPasswordBelow": "اكتب كلمة المرور الحاليه",
"currentPassword": "كلمة المرور الحاليه",
"concurrentReports": "التقارير المتزامنه",
"EnterNewAddressMoved" : "أدخل عنوان جديد إذا كنت قد انتقلت",
"CorrectAddress": "تصحيح أو تعديل هذا العنوان",
"SelectChangeWantToMake": " حدد نوع التغيير الذي تريد القيام به.",
"profile": {
"reset_password": {
"label": "Reset Password",

@ -424,6 +424,9 @@
"typeCurrentPasswordBelow": "Type Your Current password below",
"currentPassword": "Current password",
"concurrentReports": "Concurrent Reports",
"EnterNewAddressMoved" : "Enter a new address if you have moved",
"CorrectAddress": "Correct or amend this address",
"SelectChangeWantToMake": "Select the type of change you want to make",
"profile": {
"reset_password": {
"label": "Reset Password",

@ -45,7 +45,7 @@
<key>NSPhotoLibraryUsageDescription</key>
<string>This app requires photo library access to select image as document &amp; upload it.</string>
<key>NSMicrophoneUsageDescription</key>
<string>This app requires microphone access to for call.</string>
<string>This app requires microphone access to for call.</string>
<key>UIBackgroundModes</key>
<array>
<string>remote-notification</string>
@ -69,6 +69,10 @@
</array>
<key>UIViewControllerBasedStatusBarAppearance</key>
<false/>
<key>com.apple.developer.nfc.readersession.formats</key>
<array>
<string>TAG</string>
</array>
<key>com.apple.developer.nfc.readersession.felica.systemcodes</key>
<array>
<string>0000</string>

@ -65,10 +65,13 @@ class DashboardApiClient {
}, url, postParams);
}
Future<List<GetAccrualBalancesList>> getAccrualBalances(String effectiveDate) async {
Future<List<GetAccrualBalancesList>> getAccrualBalances(String effectiveDate, {String? empID}) async {
String url = "${ApiConsts.erpRest}GET_ACCRUAL_BALANCES";
Map<String, dynamic> postParams = {"P_EFFECTIVE_DATE": effectiveDate};
postParams.addAll(AppState().postParamsJson);
if (empID != null && empID.isNotEmpty) {
postParams['P_SELECTED_EMPLOYEE_NUMBER'] = empID;
}
return await ApiClient().postJsonForObject((json) {
GenericResponseModel responseData = GenericResponseModel.fromJson(json);
return responseData.getAccrualBalancesList ?? [];

@ -17,27 +17,33 @@ class LeaveBalanceApiClient {
factory LeaveBalanceApiClient() => _instance;
Future<List<GetAbsenceTransactionList>> getAbsenceTransactions(int pSelectedResopID) async {
Future<List<GetAbsenceTransactionList>> getAbsenceTransactions(int pSelectedResopID, {String? empID}) async {
String url = "${ApiConsts.erpRest}GET_ABSENCE_TRANSACTIONS";
Map<String, dynamic> postParams = {"P_PAGE_LIMIT": 50, "P_PAGE_NUM": 1, "P_MENU_TYPE": "E", "P_SELECTED_RESP_ID": pSelectedResopID};
postParams.addAll(AppState().postParamsJson);
if (empID!.isNotEmpty) {
postParams['P_SELECTED_EMPLOYEE_NUMBER'] = empID;
}
return await ApiClient().postJsonForObject((json) {
GenericResponseModel? responseData = GenericResponseModel.fromJson(json);
return responseData.getAbsenceTransactionList ?? [];
}, url, postParams);
}
Future<List<GetAbsenceAttendanceTypesList>> getAbsenceAttendanceTypes() async {
Future<List<GetAbsenceAttendanceTypesList>> getAbsenceAttendanceTypes({String? empID}) async {
String url = "${ApiConsts.erpRest}GET_ABSENCE_ATTENDANCE_TYPES";
Map<String, dynamic> postParams = {};
postParams.addAll(AppState().postParamsJson);
if (empID!.isNotEmpty) {
postParams['P_SELECTED_EMPLOYEE_NUMBER'] = empID;
}
return await ApiClient().postJsonForObject((json) {
GenericResponseModel? responseData = GenericResponseModel.fromJson(json);
return responseData.getAbsenceAttendanceTypesList ?? [];
}, url, postParams);
}
Future<CalculateAbsenceDuration> calculateAbsenceDuration(int pAbsenceAttendanceTypeID, String pDateStart, String pDateEnd, int pSelectedResopID) async {
Future<CalculateAbsenceDuration> calculateAbsenceDuration(int pAbsenceAttendanceTypeID, String pDateStart, String pDateEnd, int pSelectedResopID, {String? empID}) async {
String url = "${ApiConsts.erpRest}CALCULATE_ABSENCE_DURATION";
Map<String, dynamic> postParams = {
"P_ABSENCE_ATTENDANCE_TYPE_ID": pAbsenceAttendanceTypeID,
@ -49,16 +55,22 @@ class LeaveBalanceApiClient {
"P_TIME_START": null,
};
postParams.addAll(AppState().postParamsJson);
if (empID!.isNotEmpty) {
postParams['P_SELECTED_EMPLOYEE_NUMBER'] = empID;
}
return await ApiClient().postJsonForObject((json) {
GenericResponseModel? responseData = GenericResponseModel.fromJson(json);
return responseData.calculateAbsenceDuration!;
}, url, postParams);
}
Future<List<GetAbsenceDffStructureList>> getAbsenceDffStructure(String pDescFlexContextCode, String pFunctionName, int pSelectedResopID) async {
Future<List<GetAbsenceDffStructureList>> getAbsenceDffStructure(String pDescFlexContextCode, String pFunctionName, int pSelectedResopID, {String? empID}) async {
String url = "${ApiConsts.erpRest}GET_ABSENCE_DFF_STRUCTURE";
Map<String, dynamic> postParams = {"P_DESC_FLEX_CONTEXT_CODE": pDescFlexContextCode, "P_FUNCTION_NAME": pFunctionName, "P_MENU_TYPE": "E", "P_SELECTED_RESP_ID": pSelectedResopID};
postParams.addAll(AppState().postParamsJson);
if (empID!.isNotEmpty) {
postParams['P_SELECTED_EMPLOYEE_NUMBER'] = empID;
}
return await ApiClient().postJsonForObject((json) {
GenericResponseModel? responseData = GenericResponseModel.fromJson(json);
return responseData.getAbsenceDffStructureList ?? [];
@ -67,7 +79,7 @@ class LeaveBalanceApiClient {
Future<GenericResponseModel> validateAbsenceTransaction(
String pDescFlexContextCode, String pFunctionName, int pAbsenceAttendanceTypeID, String pReplacementUserName, String pDateStart, String pDateEnd, int pSelectedResopID, Map<String, String?> data,
{String comments = ""}) async {
{String comments = "", String? empID}) async {
String url = "${ApiConsts.erpRest}VALIDATE_ABSENCE_TRANSACTION";
Map<String, dynamic> postParams = {
"P_DESC_FLEX_CONTEXT_CODE": pDescFlexContextCode,
@ -86,6 +98,9 @@ class LeaveBalanceApiClient {
};
postParams.addAll(data);
postParams.addAll(AppState().postParamsJson);
if (empID!.isNotEmpty) {
postParams['P_SELECTED_EMPLOYEE_NUMBER'] = empID;
}
return await ApiClient().postJsonForObject((json) {
GenericResponseModel? responseData = GenericResponseModel.fromJson(json);
return responseData;
@ -94,7 +109,7 @@ class LeaveBalanceApiClient {
Future<SumbitAbsenceTransactionList> submitAbsenceTransaction(
String pDescFlexContextCode, String pFunctionName, int pAbsenceAttendanceTypeID, String pReplacementUserName, String pDateStart, String pDateEnd, int pSelectedResopID, Map<String, String?> data,
{String comments = ""}) async {
{String comments = "", String? empID}) async {
String url = "${ApiConsts.erpRest}SUBMIT_ABSENCE_TRANSACTION";
Map<String, dynamic> postParams = {
"P_DESC_FLEX_CONTEXT_CODE": pDescFlexContextCode,
@ -113,6 +128,9 @@ class LeaveBalanceApiClient {
};
postParams.addAll(data);
postParams.addAll(AppState().postParamsJson);
if (empID!.isNotEmpty) {
postParams['P_SELECTED_EMPLOYEE_NUMBER'] = empID;
}
return await ApiClient().postJsonForObject((json) {
GenericResponseModel? responseData = GenericResponseModel.fromJson(json);
return responseData.sumbitAbsenceTransactionList!;
@ -129,7 +147,7 @@ class LeaveBalanceApiClient {
}, url, postParams);
}
Future<StartAbsenceApprovalProccess> startAbsenceApprovalProcess(int pTransactionID, String comments, int pSelectedResopID) async {
Future<StartAbsenceApprovalProccess> startAbsenceApprovalProcess(int pTransactionID, String comments, int pSelectedResopID,{String? empID}) async {
String url = "${ApiConsts.erpRest}START_ABSENCE_APPROVAL_PROCESS";
Map<String, dynamic> postParams = {
"P_TRANSACTION_ID": pTransactionID,
@ -138,6 +156,9 @@ class LeaveBalanceApiClient {
"P_MENU_TYPE": "E",
};
postParams.addAll(AppState().postParamsJson);
if (empID!.isNotEmpty) {
postParams['P_SELECTED_EMPLOYEE_NUMBER'] = empID;
}
return await ApiClient().postJsonForObject((json) {
GenericResponseModel? responseData = GenericResponseModel.fromJson(json);
return responseData.startAbsenceApprovalProccess!;

@ -2,8 +2,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://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/";

@ -1,4 +1,5 @@
import 'dart:convert';
import 'dart:typed_data';
import 'package:flutter/services.dart';

@ -86,6 +86,11 @@ class Utils {
return prefs.getString(key) ?? "";
}
static Future<bool> removeStringFromPrefs(String key) async {
SharedPreferences prefs = await SharedPreferences.getInstance();
return prefs.remove(key);
}
static Future<bool> saveStringFromPrefs(String key, String value) async {
SharedPreferences prefs = await SharedPreferences.getInstance();
return await prefs.setString(key, value);
@ -116,7 +121,8 @@ class Utils {
),
);
} else {
showToast(errorMessage);
// showToast(errorMessage);
confirmDialog(cxt, errorMessage);
}
}
}

@ -66,6 +66,7 @@ import 'package:mohem_flutter_app/ui/screens/pending_transactions/pending_transa
import 'package:mohem_flutter_app/ui/screens/pending_transactions/pending_transactions_details.dart';
import 'package:mohem_flutter_app/ui/screens/submenu_screen.dart';
import 'package:mohem_flutter_app/ui/termination/end_employement.dart';
import 'package:mohem_flutter_app/ui/unsafe_device_screen.dart';
import 'package:mohem_flutter_app/ui/work_list/item_history_screen.dart';
import 'package:mohem_flutter_app/ui/work_list/itg_detail_screen.dart';
import 'package:mohem_flutter_app/ui/work_list/work_list_screen.dart';
@ -189,6 +190,8 @@ class AppRoutes {
static const String marathonSponsorVideoScreen = "/marathonSponsorVideoScreen";
static const String marathonWaitingScreen = "/marathonWaitingScreen";
static const String unsafeDeviceScreen = "/unsafeDeviceScreen";
static final Map<String, WidgetBuilder> routes = {
login: (BuildContext context) => LoginScreen(),
verifyLogin: (BuildContext context) => VerifyLoginScreen(),
@ -297,5 +300,7 @@ class AppRoutes {
marathonWinnerScreen: (BuildContext context) => WinnerScreen(),
marathonSponsorVideoScreen: (BuildContext context) => const SponsorVideoScreen(),
marathonWaitingScreen: (BuildContext context) => const MarathonWaitingScreen(),
unsafeDeviceScreen: (BuildContext context) => const UnsafeDeviceScreen(),
};
}

@ -90,8 +90,9 @@ extension EmailValidator on String {
style: TextStyle(fontSize: 13, fontWeight: FontWeight.w600, color: color ?? MyColors.darkTextColor, letterSpacing: -0.52, decoration: isUnderLine ? TextDecoration.underline : null),
);
Widget toText14({Color? color, bool isUnderLine = false, bool isBold = false, FontWeight? weight, int? maxlines}) => Text(
Widget toText14({Color? color, bool isUnderLine = false, bool isBold = false, FontWeight? weight, int? maxlines, bool isCenter = false}) => Text(
this,
textAlign: isCenter ? TextAlign.center : TextAlign.left,
maxLines: maxlines,
style: TextStyle(
color: color ?? MyColors.darkTextColor,

@ -440,6 +440,9 @@ class CodegenLoader extends AssetLoader{
"typeCurrentPasswordBelow": "اكتب كلمة المرور الحاليه",
"currentPassword": "كلمة المرور الحاليه",
"concurrentReports": "التقارير المتزامنه",
"EnterNewAddressMoved": "أدخل عنوان جديد إذا كنت قد انتقلت",
"CorrectAddress": "تصحيح أو تعديل هذا العنوان",
"SelectChangeWantToMake": " حدد نوع التغيير الذي تريد القيام به.",
"profile": {
"reset_password": {
"label": "Reset Password",
@ -953,6 +956,9 @@ static const Map<String,dynamic> en_US = {
"typeCurrentPasswordBelow": "Type Your Current password below",
"currentPassword": "Current password",
"concurrentReports": "Concurrent Reports",
"EnterNewAddressMoved": "Enter a new address if you have moved",
"CorrectAddress": "Correct or amend this address",
"SelectChangeWantToMake": "Select the type of change you want to make",
"profile": {
"reset_password": {
"label": "Reset Password",

@ -425,6 +425,9 @@ abstract class LocaleKeys {
static const typeCurrentPasswordBelow = 'typeCurrentPasswordBelow';
static const currentPassword = 'currentPassword';
static const concurrentReports = 'concurrentReports';
static const EnterNewAddressMoved = 'EnterNewAddressMoved';
static const CorrectAddress = 'CorrectAddress';
static const SelectChangeWantToMake = 'SelectChangeWantToMake';
static const profile_reset_password_label = 'profile.reset_password.label';
static const profile_reset_password_username = 'profile.reset_password.username';
static const profile_reset_password_password = 'profile.reset_password.password';

@ -1,4 +1,5 @@
import 'dart:convert';
import 'dart:typed_data';
import 'package:flutter/foundation.dart';

@ -210,10 +210,10 @@ class GetEITDFFStructureList {
}
class ESERVICESDV {
String? pIDCOLUMNNAME;
String? pRETURNMSG;
dynamic pIDCOLUMNNAME;
dynamic pRETURNMSG;
String? pRETURNSTATUS;
String? pVALUECOLUMNNAME;
dynamic pVALUECOLUMNNAME;
ESERVICESDV({this.pIDCOLUMNNAME, this.pRETURNMSG, this.pRETURNSTATUS, this.pVALUECOLUMNNAME});
@ -226,10 +226,10 @@ class ESERVICESDV {
Map<String, dynamic> toJson() {
Map<String, dynamic> data = new Map<String, dynamic>();
data['P_ID_COLUMN_NAME'] = this.pIDCOLUMNNAME;
data['P_RETURN_MSG'] = this.pRETURNMSG;
data['P_RETURN_STATUS'] = this.pRETURNSTATUS;
data['P_VALUE_COLUMN_NAME'] = this.pVALUECOLUMNNAME;
data['P_ID_COLUMN_NAME'] = pIDCOLUMNNAME;
data['P_RETURN_MSG'] = pRETURNMSG;
data['P_RETURN_STATUS'] = pRETURNSTATUS;
data['P_VALUE_COLUMN_NAME'] = pVALUECOLUMNNAME;
return data;
}
}

@ -1,10 +1,12 @@
import 'dart:async';
import 'dart:convert';
import 'dart:io';
import 'dart:typed_data';
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/foundation.dart';
import 'package:http/http.dart';
import 'package:just_audio/just_audio.dart';
import 'package:mohem_flutter_app/api/chat/chat_api_client.dart';
import 'package:mohem_flutter_app/app_state/app_state.dart';
import 'package:mohem_flutter_app/classes/consts.dart';
@ -53,6 +55,8 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin {
Future<void> buildHubConnection() async {
chatHubConnection = await getHubConnection();
await chatHubConnection.start();
print("Startedddddddd");
chatHubConnection.on("OnDeliveredChatUserAsync", onMsgReceived);
}
Future<HubConnection> getHubConnection() async {
@ -74,7 +78,7 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin {
void registerEvents() {
chatHubConnection.on("OnUpdateUserStatusAsync", changeStatus);
chatHubConnection.on("OnDeliveredChatUserAsync", onMsgReceived);
// chatHubConnection.on("OnDeliveredChatUserAsync", onMsgReceived);
// hubConnection.on("OnSeenChatUserAsync", onChatSeen);
//hubConnection.on("OnUserTypingAsync", onUserTyping);
chatHubConnection.on("OnUserCountAsync", userCountAsync);
@ -121,7 +125,9 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin {
),
);
notifyListeners();
getUserImages();
if (searchedChats!.isNotEmpty) {
getUserImages();
}
}
Future invokeUserChatHistoryNotDeliveredAsync({required int userId}) async {
@ -134,6 +140,13 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin {
if (isNewChat) userChatHistory = [];
if (!loadMore) paginationVal = 0;
isChatScreenActive = true;
// if (chatHubConnection.state != HubConnectionState.Connected) {
// getUserAutoLoginToken().whenComplete(() async {
// await buildHubConnection();
// getSingleUserChatHistory(senderUID: senderUID, receiverUID: receiverUID, loadMore: loadMore);
// });
// return;
// }
Response response = await ChatApiClient().getSingleUserChatHistory(senderUID: senderUID, receiverUID: receiverUID, loadMore: loadMore, paginationVal: paginationVal);
if (response.statusCode == 204) {
if (isNewChat) {
@ -313,8 +326,7 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin {
}
Future<void> onMsgReceived(List<Object?>? parameters) async {
List<SingleUserChatModel> data = [];
List<SingleUserChatModel> temp = [];
List<SingleUserChatModel> data = [], temp = [];
for (dynamic msg in parameters!) {
data = getSingleUserChatModel(jsonEncode(msg));
temp = getSingleUserChatModel(jsonEncode(msg));
@ -335,16 +347,22 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin {
}
}
}
dynamic contain = searchedChats!.where((ChatUser element) => element.id == data.first.currentUserId);
if (contain.isEmpty) {
searchedChats!.add(ChatUser(id: data.first.currentUserId, userName: data.first.currentUserName, unreadMessageCount: 0, isImageLoading: false, image: "", isImageLoaded: true, userStatus: 1));
}
setMsgTune();
userChatHistory.insert(0, data.first);
if (searchedChats != null && !isChatScreenActive) {
for (ChatUser user in searchedChats!) {
if (user.id == data.first.currentUserId) {
var tempCount = user.unreadMessageCount ?? 0;
int tempCount = user.unreadMessageCount ?? 0;
user.unreadMessageCount = tempCount + 1;
}
}
sort();
}
List list = [
@ -354,6 +372,14 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin {
notifyListeners();
}
void sort() {
searchedChats!.sort(
(ChatUser a, ChatUser b) => b.unreadMessageCount!.compareTo(
a.unreadMessageCount!,
),
);
}
void onUserTyping(List<Object?>? parameters) {
for (ChatUser user in searchedChats!) {
if (user.id == parameters![1] && parameters[0] == true) {
@ -447,34 +473,35 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin {
Uint8List? image,
required bool isImageLoaded}) async {
Uuid uuid = const Uuid();
var contentNo = uuid.v4();
String contentNo = uuid.v4();
var msg = message.text;
String msg = message.text;
SingleUserChatModel data = SingleUserChatModel(
chatEventId: chatEventId,
chatSource: 1,
contant: msg,
contantNo: contentNo,
conversationId: chatCID,
createdDate: DateTime.now(),
currentUserId: AppState().chatDetails!.response!.id,
currentUserName: AppState().chatDetails!.response!.userName,
targetUserId: targetUserId,
targetUserName: targetUserName,
isReplied: false,
fileTypeId: fileTypeId,
userChatReplyResponse: isReply ? UserChatReplyResponse.fromJson(repliedMsg.first.toJson()) : null,
fileTypeResponse: isAttachment
? FileTypeResponse(
fileTypeId: fileTypeId,
fileTypeName: getFileType(getFileExtension(selectedFile.path).toString()),
fileKind: getFileExtension(selectedFile.path),
fileName: selectedFile.path.split("/").last,
fileTypeDescription: getFileTypeDescription(getFileExtension(selectedFile.path).toString()),
)
: null,
image: image,
isImageLoaded: isImageLoaded);
chatEventId: chatEventId,
chatSource: 1,
contant: msg,
contantNo: contentNo,
conversationId: chatCID,
createdDate: DateTime.now(),
currentUserId: AppState().chatDetails!.response!.id,
currentUserName: AppState().chatDetails!.response!.userName,
targetUserId: targetUserId,
targetUserName: targetUserName,
isReplied: false,
fileTypeId: fileTypeId,
userChatReplyResponse: isReply ? UserChatReplyResponse.fromJson(repliedMsg.first.toJson()) : null,
fileTypeResponse: isAttachment
? FileTypeResponse(
fileTypeId: fileTypeId,
fileTypeName: getFileType(getFileExtension(selectedFile.path).toString()),
fileKind: getFileExtension(selectedFile.path),
fileName: selectedFile.path.split("/").last,
fileTypeDescription: getFileTypeDescription(getFileExtension(selectedFile.path).toString()),
)
: null,
image: image,
isImageLoaded: isImageLoaded,
);
userChatHistory.insert(0, data);
isFileSelected = false;
isMsgReply = false;
@ -491,7 +518,7 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin {
dynamic contain = searchedChats!.where((ChatUser element) => element.id == targetUserId);
if (contain.isEmpty) {
searchedChats!.add(
ChatUser(id: targetUserId, userName: targetUserName, unreadMessageCount: 0),
ChatUser(id: targetUserId, userName: targetUserName, unreadMessageCount: 0, isImageLoading: false, image: "", isImageLoaded: true),
);
notifyListeners();
}
@ -728,11 +755,25 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin {
}
}
}
notifyListeners();
}
///getUserAutoLoginToken().whenComplete(() {
// buildHubConnection();
// print("After Reconnect State: " + hubConnection.state.toString());
// });
void setMsgTune() async {
AudioPlayer player = AudioPlayer();
await player.setVolume(1.0);
String audioAsset = "";
if (Platform.isAndroid) {
audioAsset = "assets/audio/pulse_tone_android.mp3";
} else {
audioAsset = "assets/audio/pulse_tune_ios.caf";
}
try {
await player.setAsset(audioAsset);
await player.load();
player.play();
} catch (e) {
print("Error: $e");
}
}
}

@ -239,8 +239,7 @@ class ChatBubble extends StatelessWidget {
return SizedBox(
height: isReplyPreview ? 32 : 140,
width: isReplyPreview ? 32 : 227,
child: const Center(child: CircularProgressIndicator()),
);
).toShimmer();
}
},
);

@ -16,13 +16,11 @@ import 'package:mohem_flutter_app/models/chat/get_single_user_chat_list_model.da
import 'package:mohem_flutter_app/provider/chat_provider_model.dart';
import 'package:mohem_flutter_app/ui/chat/call/chat_outgoing_call_screen.dart';
import 'package:mohem_flutter_app/ui/chat/chat_bubble.dart';
import 'package:mohem_flutter_app/ui/landing/dashboard_screen.dart';
import 'package:mohem_flutter_app/widgets/app_bar_widget.dart';
import 'package:mohem_flutter_app/widgets/shimmer/dashboard_shimmer_widget.dart';
import 'package:provider/provider.dart';
import 'package:pull_to_refresh/pull_to_refresh.dart';
import 'package:signalr_netcore/signalr_client.dart';
import 'package:sizer/sizer.dart';
import 'package:swipe_to/swipe_to.dart';
class ChatDetailScreen extends StatefulWidget {
@ -34,9 +32,9 @@ class ChatDetailScreen extends StatefulWidget {
}
class _ChatDetailScreenState extends State<ChatDetailScreen> {
final RefreshController _rc = RefreshController(initialRefresh: false);
dynamic userDetails;
late ChatProviderModel data;
final RefreshController _rc = RefreshController(initialRefresh: false);
void getMoreChat() async {
if (userDetails != null) {
@ -165,6 +163,10 @@ class _ChatDetailScreenState extends State<ChatDetailScreen> {
),
if (m.isFileSelected && m.sFileType == ".png" || m.sFileType == ".jpeg" || m.sFileType == ".jpg")
SizedBox(height: 200, width: double.infinity, child: Image.file(m.selectedFile, fit: BoxFit.cover)).paddingOnly(left: 21, right: 21, top: 21),
const Divider(
height: 1,
color: MyColors.lightGreyEFColor,
),
TextField(
controller: m.message,
decoration: InputDecoration(

@ -85,6 +85,7 @@ class _ChatHomeState extends State<ChatHome> {
onPageChanged: (int pageIndex) {
setState(() {
tabIndex = pageIndex;
});
},
children: <Widget>[

@ -19,6 +19,7 @@ import 'package:mohem_flutter_app/widgets/bottom_sheets/search_employee_bottom_s
import 'package:mohem_flutter_app/widgets/circular_avatar.dart';
import 'package:mohem_flutter_app/widgets/shimmer/dashboard_shimmer_widget.dart';
import 'package:provider/provider.dart';
import 'package:pull_to_refresh/pull_to_refresh.dart';
class ChatHomeScreen extends StatefulWidget {
const ChatHomeScreen({Key? key}) : super(key: key);
@ -31,6 +32,8 @@ class _ChatHomeScreenState extends State<ChatHomeScreen> {
TextEditingController search = TextEditingController();
late ChatProviderModel data;
final RefreshController _rc = RefreshController(initialRefresh: false);
@override
void initState() {
super.initState();
@ -86,7 +89,7 @@ class _ChatHomeScreenState extends State<ChatHomeScreen> {
itemCount: m.searchedChats!.length,
shrinkWrap: true,
physics: const ClampingScrollPhysics(),
padding: const EdgeInsets.only(bottom: 80.0),
padding: const EdgeInsets.only(bottom: 80.0),
itemBuilder: (BuildContext context, int index) {
return SizedBox(
height: 55,
@ -99,7 +102,7 @@ class _ChatHomeScreenState extends State<ChatHomeScreen> {
height: 48,
width: 48,
).toShimmer().circle(30),
if (m.searchedChats![index].isImageLoaded! && m.searchedChats![index].image != null && m.searchedChats![index].image.isNotEmpty)
if (m.searchedChats![index].isImageLoaded! && m.searchedChats![index].image.isNotEmpty)
CircularAvatar(
radius: 20,
height: 48,
@ -125,7 +128,9 @@ class _ChatHomeScreenState extends State<ChatHomeScreen> {
).circle(10),
)
],
),
).onPress(() {
print(jsonEncode(m.searchedChats![index]));
}),
Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,

@ -23,13 +23,16 @@ class ChatFavoriteUsersScreen extends StatelessWidget {
body: Consumer<ChatProviderModel>(
builder: (BuildContext context, ChatProviderModel m, Widget? child) {
if (m.isLoading) {
return ChatHomeShimmer(isDetailedScreen: false,);
return ChatHomeShimmer(
isDetailedScreen: false,
);
} else {
return m.favUsersList != null && m.favUsersList.isNotEmpty
? ListView.separated(
itemCount: m.favUsersList!.length,
shrinkWrap: true,
physics: const NeverScrollableScrollPhysics(),
physics: const ClampingScrollPhysics(),
padding: const EdgeInsets.only(bottom: 80.0),
itemBuilder: (BuildContext context, int index) {
return SizedBox(
height: 55,

@ -4,6 +4,7 @@ import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:mohem_flutter_app/api/leave_balance_api_client.dart';
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/config/routes.dart';
@ -24,7 +25,8 @@ import 'package:mohem_flutter_app/widgets/button/default_button.dart';
import 'package:mohem_flutter_app/widgets/dynamic_forms/dynamic_textfield_widget.dart';
class AddLeaveBalanceScreen extends StatefulWidget {
AddLeaveBalanceScreen({Key? key}) : super(key: key);
final String selectedEmp;
AddLeaveBalanceScreen({this.selectedEmp = '', Key? key}) : super(key: key);
@override
_AddLeaveBalanceScreenState createState() {
@ -42,19 +44,21 @@ class _AddLeaveBalanceScreenState extends State<AddLeaveBalanceScreen> {
int? totalDays;
String comment = "";
ReplacementList? selectedReplacementEmployee;
dynamic dynamicParams;
String selectedEmp = "";
DateTime selectedDate = DateTime(DateTime.now().year, DateTime.now().month, DateTime.now().day);
@override
void initState() {
super.initState();
getAbsenceAttendanceTypes();
//getAbsenceAttendanceTypes();
}
void getAbsenceAttendanceTypes() async {
try {
Utils.showLoading(context);
absenceList = await LeaveBalanceApiClient().getAbsenceAttendanceTypes();
absenceList = await LeaveBalanceApiClient().getAbsenceAttendanceTypes(empID: selectedEmp);
Utils.hideLoading(context);
setState(() {});
} catch (ex) {
@ -67,7 +71,7 @@ class _AddLeaveBalanceScreenState extends State<AddLeaveBalanceScreen> {
try {
Utils.showLoading(context);
getabsenceDffStructureList.clear();
getabsenceDffStructureList = await LeaveBalanceApiClient().getAbsenceDffStructure(selectedAbsenceType!.dESCFLEXCONTEXTCODE!, "HR_LOA_SS", -999);
getabsenceDffStructureList = await LeaveBalanceApiClient().getAbsenceDffStructure(selectedAbsenceType!.dESCFLEXCONTEXTCODE!, "HR_LOA_SS", -999, empID: selectedEmp);
Utils.hideLoading(context);
setState(() {});
} catch (ex) {
@ -80,7 +84,7 @@ class _AddLeaveBalanceScreenState extends State<AddLeaveBalanceScreen> {
try {
Utils.showLoading(context);
CalculateAbsenceDuration duration = await LeaveBalanceApiClient()
.calculateAbsenceDuration(selectedAbsenceType!.aBSENCEATTENDANCETYPEID!, Utils.getMonthNamedFormat(startDateTime!), Utils.getMonthNamedFormat(endDateTime!), -999);
.calculateAbsenceDuration(selectedAbsenceType!.aBSENCEATTENDANCETYPEID!, Utils.getMonthNamedFormat(startDateTime!), Utils.getMonthNamedFormat(endDateTime!), -999, empID: selectedEmp);
totalDays = duration.pABSENCEDAYS?.toInt();
Utils.hideLoading(context);
@ -91,58 +95,60 @@ class _AddLeaveBalanceScreenState extends State<AddLeaveBalanceScreen> {
}
}
void validateAbsenceTransaction() async {
try {
Utils.showLoading(context);
Map<String, String?> dffDataMap = {};
for (int i = 1; i <= 20; i++) {
dffDataMap["P_ATTRIBUTE$i"] = null;
for (int dffIndex = 0; dffIndex < getabsenceDffStructureList.length; dffIndex++) {
if ("ATTRIBUTE$i" == getabsenceDffStructureList[dffIndex].aPPLICATIONCOLUMNNAME) {
if (getabsenceDffStructureList[dffIndex].fORMATTYPE == "X") {
dffDataMap["P_ATTRIBUTE$i"] =
getabsenceDffStructureList[dffIndex].eSERVICESDV!.pIDCOLUMNNAME != null ? Utils.formatDate(getabsenceDffStructureList[dffIndex].eSERVICESDV!.pIDCOLUMNNAME!) : "";
} else {
dffDataMap["P_ATTRIBUTE$i"] = getabsenceDffStructureList[dffIndex].eSERVICESDV?.pIDCOLUMNNAME;
}
break;
void validateAbsenceTransaction(selectedID) async {
//try {
Utils.showLoading(context);
Map<String, String?> dffDataMap = {};
for (int i = 1; i <= 20; i++) {
dffDataMap["P_ATTRIBUTE$i"] = null;
for (int dffIndex = 0; dffIndex < getabsenceDffStructureList.length; dffIndex++) {
if ("ATTRIBUTE$i" == getabsenceDffStructureList[dffIndex].aPPLICATIONCOLUMNNAME) {
if (getabsenceDffStructureList[dffIndex].fORMATTYPE == "X") {
dffDataMap["P_ATTRIBUTE$i"] =
getabsenceDffStructureList[dffIndex].eSERVICESDV!.pIDCOLUMNNAME != null ? Utils.formatDate(getabsenceDffStructureList[dffIndex].eSERVICESDV!.pIDCOLUMNNAME!) : "";
} else {
dffDataMap["P_ATTRIBUTE$i"] = getabsenceDffStructureList[dffIndex].eSERVICESDV?.pIDCOLUMNNAME;
}
break;
}
}
await LeaveBalanceApiClient().validateAbsenceTransaction(
selectedAbsenceType!.dESCFLEXCONTEXTCODE!,
"HR_LOA_SS",
selectedAbsenceType!.aBSENCEATTENDANCETYPEID!,
selectedReplacementEmployee != null ? selectedReplacementEmployee!.userName! : "",
DateUtil.getFormattedDate(startDateTime!, "MM/dd/yyyy"),
DateUtil.getFormattedDate(endDateTime!, "MM/dd/yyyy"),
-999,
dffDataMap,
comments: comment);
}
await LeaveBalanceApiClient().validateAbsenceTransaction(
selectedAbsenceType!.dESCFLEXCONTEXTCODE!,
"HR_LOA_SS",
selectedAbsenceType!.aBSENCEATTENDANCETYPEID!,
selectedReplacementEmployee != null ? selectedReplacementEmployee!.userName! : "",
DateUtil.getFormattedDate(startDateTime!, "MM/dd/yyyy"),
DateUtil.getFormattedDate(endDateTime!, "MM/dd/yyyy"),
-999,
dffDataMap,
comments: comment,
empID: selectedEmp);
SumbitAbsenceTransactionList submit = await LeaveBalanceApiClient().submitAbsenceTransaction(
selectedAbsenceType!.dESCFLEXCONTEXTCODE!,
"HR_LOA_SS",
selectedAbsenceType!.aBSENCEATTENDANCETYPEID!,
selectedReplacementEmployee != null ? selectedReplacementEmployee!.userName! : "",
DateUtil.getFormattedDate(startDateTime!, "MM/dd/yyyy"),
DateUtil.getFormattedDate(endDateTime!, "MM/dd/yyyy"),
-999,
dffDataMap,
comments: comment);
SumbitAbsenceTransactionList submit = await LeaveBalanceApiClient().submitAbsenceTransaction(
selectedAbsenceType!.dESCFLEXCONTEXTCODE!,
"HR_LOA_SS",
selectedAbsenceType!.aBSENCEATTENDANCETYPEID!,
selectedReplacementEmployee != null ? selectedReplacementEmployee!.userName! : "",
DateUtil.getFormattedDate(startDateTime!, "MM/dd/yyyy"),
DateUtil.getFormattedDate(endDateTime!, "MM/dd/yyyy"),
-999,
dffDataMap,
comments: comment,
empID: selectedEmp);
Utils.hideLoading(context);
Utils.hideLoading(context);
var res = await Navigator.pushNamed(context, AppRoutes.requestSubmitScreen, arguments: RequestSubmitScreenParams(LocaleKeys.submit.tr(), submit.pTRANSACTIONID!, "", "add_leave_balance"));
if (res != null && res == true) {
Utils.showLoading(context);
}
await LeaveBalanceApiClient().cancelHrTransaction(submit.pTRANSACTIONID!);
Utils.hideLoading(context);
} catch (ex) {
Utils.hideLoading(context);
Utils.handleException(ex, context, null);
var res = await Navigator.pushNamed(context, AppRoutes.requestSubmitScreen, arguments: RequestSubmitScreenParams(LocaleKeys.submit.tr(), submit.pTRANSACTIONID!, "", "add_leave_balance"));
if (res != null && res == true) {
Utils.showLoading(context);
}
await LeaveBalanceApiClient().cancelHrTransaction(submit.pTRANSACTIONID!);
Utils.hideLoading(context);
// } catch (ex) {
// Utils.hideLoading(context);
// Utils.handleException(ex, context, null);
// }
}
@override
@ -152,6 +158,16 @@ class _AddLeaveBalanceScreenState extends State<AddLeaveBalanceScreen> {
@override
Widget build(BuildContext context) {
if (dynamicParams == null) {
dynamicParams = ModalRoute.of(context)!.settings.arguments;
if (dynamicParams!= null && dynamicParams.isNotEmpty) {
AppState().postParamsJson['P_SELECTED_EMPLOYEE_NUMBER'] = dynamicParams;
selectedEmp = dynamicParams;
getAbsenceAttendanceTypes();
} else {
getAbsenceAttendanceTypes();
}
}
return Scaffold(
backgroundColor: Colors.white,
appBar: AppBarWidget(
@ -269,7 +285,7 @@ class _AddLeaveBalanceScreenState extends State<AddLeaveBalanceScreen> {
validateFieldData()
? null
: () {
validateAbsenceTransaction();
validateAbsenceTransaction(selectedEmp);
},
).insideContainer
],

@ -1,6 +1,7 @@
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:mohem_flutter_app/api/leave_balance_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';
@ -13,7 +14,8 @@ import 'package:mohem_flutter_app/widgets/balances_dashboard_widget.dart';
import 'package:mohem_flutter_app/widgets/item_detail_view_widget.dart';
class LeaveBalance extends StatefulWidget {
LeaveBalance({Key? key}) : super(key: key);
final String selectedEmp;
LeaveBalance({this.selectedEmp = '', Key? key}) : super(key: key);
@override
_LeaveBalanceState createState() {
@ -25,12 +27,13 @@ class _LeaveBalanceState extends State<LeaveBalance> {
List<GetAbsenceTransactionList>? absenceTransList;
DateTime accrualDateTime = DateTime.now();
dynamic dynamicParams;
String selectedEmp = "";
@override
void initState() {
super.initState();
getAbsenceTransactions();
absenceTransList = [];
}
@override
@ -40,9 +43,9 @@ class _LeaveBalanceState extends State<LeaveBalance> {
void getAbsenceTransactions() async {
try {
Utils.showLoading(context);
absenceTransList = await LeaveBalanceApiClient().getAbsenceTransactions(-999);
Utils.hideLoading(context);
// Utils.showLoading(context);
absenceTransList = await LeaveBalanceApiClient().getAbsenceTransactions(-999, empID: selectedEmp);
//Utils.hideLoading(context);
setState(() {});
} catch (ex) {
Utils.hideLoading(context);
@ -52,6 +55,16 @@ class _LeaveBalanceState extends State<LeaveBalance> {
@override
Widget build(BuildContext context) {
if (dynamicParams == null) {
dynamicParams = ModalRoute.of(context)!.settings.arguments;
if (dynamicParams!= null && dynamicParams.isNotEmpty) {
AppState().postParamsJson['P_SELECTED_EMPLOYEE_NUMBER'] = dynamicParams;
selectedEmp = dynamicParams;
getAbsenceTransactions();
} else {
getAbsenceTransactions();
}
}
return Scaffold(
backgroundColor: Colors.white,
appBar: AppBarWidget(
@ -62,7 +75,7 @@ class _LeaveBalanceState extends State<LeaveBalance> {
physics: const BouncingScrollPhysics(),
padding: const EdgeInsets.all(21),
children: [
BalancesDashboardWidget(LocaleKeys.currentLeaveBalance.tr(), true),
BalancesDashboardWidget(LocaleKeys.currentLeaveBalance.tr(), true, selectedEmp),
12.height,
absenceTransList == null
? const SizedBox()
@ -111,7 +124,7 @@ class _LeaveBalanceState extends State<LeaveBalance> {
),
child: const Icon(Icons.add, color: Colors.white, size: 30),
).onPress(() {
Navigator.pushNamed(context, AppRoutes.addLeaveBalance);
Navigator.pushNamed(context, AppRoutes.addLeaveBalance, arguments: selectedEmp ?? '');
}),
);
}

@ -25,6 +25,7 @@ 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/input_widget.dart';
import 'package:safe_device/safe_device.dart';
class LoginScreen extends StatefulWidget {
LoginScreen({Key? key}) : super(key: key);
@ -48,10 +49,34 @@ class _LoginScreenState extends State<LoginScreen> {
bool? isAppOpenBySystem;
bool isJailBroken = false;
bool isRealDevice = false;
bool isOnExternalStorage = false;
bool isDevelopmentModeEnable = false;
@override
void initState() {
super.initState();
// checkFirebaseToken();
// checkFirebaseToken();
if (kReleaseMode) {
checkDeviceSafety();
}
}
void checkDeviceSafety() async {
try {
isJailBroken = await SafeDevice.isJailBroken;
isRealDevice = await SafeDevice.isRealDevice;
if (Platform.isAndroid) {
isOnExternalStorage = await SafeDevice.isOnExternalStorage;
isDevelopmentModeEnable = await SafeDevice.isDevelopmentModeEnable;
}
if (isJailBroken || !isRealDevice || isOnExternalStorage || isDevelopmentModeEnable) {
Navigator.pushNamedAndRemoveUntil(context, AppRoutes.unsafeDeviceScreen, (_) => false);
}
} catch (error) {
print(error);
}
}
@override
@ -68,8 +93,7 @@ class _LoginScreenState extends State<LoginScreen> {
await Firebase.initializeApp();
_firebaseMessaging = FirebaseMessaging.instance;
firebaseToken = await _firebaseMessaging.getToken();
loginInfo = await LoginApiClient().getMobileLoginInfoNEW(
firebaseToken ?? "", Platform.isAndroid ? "android" : "ios");
loginInfo = await LoginApiClient().getMobileLoginInfoNEW(firebaseToken ?? "", Platform.isAndroid ? "android" : "ios");
if (loginInfo == null) {
Utils.hideLoading(context);
return;
@ -86,11 +110,9 @@ class _LoginScreenState extends State<LoginScreen> {
}
Future<void> checkPrefs() async {
String username =
await Utils.getStringFromPrefs(SharedPrefsConsts.username);
String username = await Utils.getStringFromPrefs(SharedPrefsConsts.username);
if (username.isNotEmpty) {
String password =
await Utils.getStringFromPrefs(SharedPrefsConsts.password);
String password = await Utils.getStringFromPrefs(SharedPrefsConsts.password);
// String firebaseToken = await Utils.getStringFromPrefs(SharedPrefsConsts.firebaseToken);
// print("firebaseToken:$firebaseToken");
this.username.text = username;
@ -103,30 +125,23 @@ class _LoginScreenState extends State<LoginScreen> {
Utils.showLoading(context);
try {
_checkMobileAppVersion = await LoginApiClient().checkMobileAppVersion();
_memberLoginList =
await LoginApiClient().memberLogin(username.text, password.text);
_memberLoginList = await LoginApiClient().memberLogin(username.text, password.text);
AppState().setMemberLoginListModel = _memberLoginList;
AppState().setUserName = username.text;
AppState().password = password.text;
if (_autoLogin) {
AppState().setMemberInformationListModel =
(await MemberInformationListModel.getFromPrefs()).first;
AppState().setPrivilegeListModel =
await PrivilegeListModel.getFromPrefs();
String mohemmWifiSSID =
await Utils.getStringFromPrefs(SharedPrefsConsts.mohemmWifiSSID);
String mohemmWifiPassword = await Utils.getStringFromPrefs(
SharedPrefsConsts.mohemmWifiPassword);
AppState().setMemberInformationListModel = (await MemberInformationListModel.getFromPrefs()).first;
AppState().setPrivilegeListModel = await PrivilegeListModel.getFromPrefs();
String mohemmWifiSSID = await Utils.getStringFromPrefs(SharedPrefsConsts.mohemmWifiSSID);
String mohemmWifiPassword = await Utils.getStringFromPrefs(SharedPrefsConsts.mohemmWifiPassword);
AppState().setMohemmWifiSSID = mohemmWifiSSID;
AppState().setMohemmWifiPassword = mohemmWifiPassword;
}
Utils.hideLoading(context);
if (_autoLogin) {
Navigator.pushReplacementNamed(context, AppRoutes.verifyLastLogin,
arguments: loginInfo);
Navigator.pushReplacementNamed(context, AppRoutes.verifyLastLogin, arguments: loginInfo);
} else {
Navigator.pushNamed(context, AppRoutes.verifyLogin,
arguments: "$firebaseToken");
Navigator.pushNamed(context, AppRoutes.verifyLogin, arguments: "$firebaseToken");
}
Utils.saveStringFromPrefs(SharedPrefsConsts.password, password.text);
} catch (ex) {
@ -169,13 +184,7 @@ class _LoginScreenState extends State<LoginScreen> {
Expanded(child: SizedBox()),
Row(
children: [
LocaleKeys.english
.tr()
.toText14(
color: AppState().isArabic(context)
? null
: MyColors.textMixColor)
.onPress(() {
LocaleKeys.english.tr().toText14(color: AppState().isArabic(context) ? null : MyColors.textMixColor).onPress(() {
context.setLocale(const Locale("en", "US"));
}),
Container(
@ -184,13 +193,7 @@ class _LoginScreenState extends State<LoginScreen> {
height: 16,
margin: const EdgeInsets.only(left: 10, right: 10),
),
LocaleKeys.arabic
.tr()
.toText14(
color: !AppState().isArabic(context)
? null
: MyColors.textMixColor)
.onPress(() {
LocaleKeys.arabic.tr().toText14(color: !AppState().isArabic(context) ? null : MyColors.textMixColor).onPress(() {
context.setLocale(const Locale("ar", "SA"));
}),
],
@ -206,23 +209,14 @@ class _LoginScreenState extends State<LoginScreen> {
LocaleKeys.login.tr().toText24(isBold: true),
LocaleKeys.pleaseEnterLoginDetails.tr().toText16(),
16.height,
InputWidget(
LocaleKeys.username.tr(), "123456", username),
InputWidget(LocaleKeys.username.tr(), "123456", username),
12.height,
InputWidget(
LocaleKeys.password.tr(), "xxxxxx", password,
isTextIsPassword: true),
InputWidget(LocaleKeys.password.tr(), "xxxxxx", password, isTextIsPassword: true),
9.height,
Align(
alignment: Alignment.centerRight,
child: LocaleKeys.forgotPassword
.tr()
.toText12(
isUnderLine: true,
color: MyColors.textMixColor)
.onPress(() {
Navigator.pushNamed(
context, AppRoutes.forgotPassword);
child: LocaleKeys.forgotPassword.tr().toText12(isUnderLine: true, color: MyColors.textMixColor).onPress(() {
Navigator.pushNamed(context, AppRoutes.forgotPassword);
}),
),
],

@ -8,6 +8,7 @@ import 'package:mohem_flutter_app/api/leave_balance_api_client.dart';
import 'package:mohem_flutter_app/api/my_attendance_api_client.dart';
import 'package:mohem_flutter_app/api/profile_api_client.dart';
import 'package:mohem_flutter_app/api/termination_dff_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';
@ -35,7 +36,8 @@ class RequestSubmitScreenParams {
}
class RequestSubmitScreen extends StatefulWidget {
RequestSubmitScreen({Key? key}) : super(key: key);
final String selectedEmp;
RequestSubmitScreen({this.selectedEmp ='',Key? key}) : super(key: key);
@override
_RequestSubmitScreenState createState() {
@ -50,6 +52,8 @@ class _RequestSubmitScreenState extends State<RequestSubmitScreen> {
List<GetApprovesList> approverList = [];
List<File> attachmentFiles = [];
List<String> attachments = [];
dynamic dynamicParams;
String selectedEmp ="";
@override
void initState() {
@ -123,6 +127,7 @@ class _RequestSubmitScreenState extends State<RequestSubmitScreen> {
params!.transactionId,
comments.text,
-999,
empID: widget.selectedEmp
);
} else if (params!.approvalFlag == 'eit') {
await MyAttendanceApiClient().startEitApprovalProcess(

@ -50,18 +50,6 @@ class _DynamicInputScreenState extends State<DynamicInputScreen> {
descFlexConTextTitle = genericResponseModel!.pDESCFLEXCONTEXTNAME ?? "";
getEitDffStructureList = genericResponseModel?.getEITDFFStructureList ?? [];
//getEitDffStructureList = getEitDffStructureList!.where((element) => element.dISPLAYFLAG != "N").toList();
if (dynamicParams!.collectionNotificationList != null && dynamicParams!.collectionNotificationList!.isNotEmpty) {
getEitDffStructureList!.forEach((element) {
dynamicParams!.collectionNotificationList!.forEach((element2) {
if (element.sEGMENTNAME == element2.segmentName) {
element.fieldAnswer = element2.varchar2Value;
element.eSERVICESDV ??= ESERVICESDV();
element.eSERVICESDV!.pIDCOLUMNNAME = element2.varchar2Value;
}
});
});
}
Utils.hideLoading(context);
setState(() {});
} catch (ex) {
@ -108,11 +96,9 @@ class _DynamicInputScreenState extends State<DynamicInputScreen> {
SubmitEITTransactionList submitEITTransactionList =
await MyAttendanceApiClient().submitEitTransaction(dESCFLEXCONTEXTCODE, dynamicParams!.dynamicId, values, empID: dynamicParams!.selectedEmp ?? '');
Utils.hideLoading(context);
var res = await Navigator.pushNamed(context, AppRoutes.requestSubmitScreen,
await Navigator.pushNamed(context, AppRoutes.requestSubmitScreen,
arguments: RequestSubmitScreenParams(LocaleKeys.submit.tr(), submitEITTransactionList.pTRANSACTIONID!, submitEITTransactionList.pITEMKEY!, 'eit'));
if (res != null && res == true) {
Utils.showLoading(context);
}
Utils.showLoading(context);
await LeaveBalanceApiClient().cancelHrTransaction(submitEITTransactionList.pTRANSACTIONID!);
Utils.hideLoading(context);
} catch (ex) {
@ -345,7 +331,7 @@ class _DynamicInputScreenState extends State<DynamicInputScreen> {
idColName = val;
if (getEitDffStructureList![j].fORMATTYPE == "X") {
idColName = Utils.formatDateDefault(idColName!);
idColName = Utils.formatDateNew(idColName!);
// commenting to test
// DateTime date = DateFormat('yyyy-MM-dd').parse(idColName!);
// idColName = DateFormat('yyyy-MM-dd HH:mm:ss').format(date);
@ -498,7 +484,7 @@ class _DynamicInputScreenState extends State<DynamicInputScreen> {
return DynamicTextFieldWidget(
(model.sEGMENTPROMPT ?? "") + (model.rEQUIREDFLAG == "Y" ? "*" : ""),
model.eSERVICESDV?.pIDCOLUMNNAME ?? "",
// isReadOnly: model.rEADONLY == "Y",
isReadOnly: model.rEADONLY == "Y",
isInputTypeNum: true,
onChange: (text) {
model.fieldAnswer = text;
@ -635,7 +621,12 @@ class _DynamicInputScreenState extends State<DynamicInputScreen> {
).paddingOnly(bottom: 12),
itemBuilder: (_) => <PopupMenuItem<int>>[
if (model.rEADONLY != "Y")
for (int i = 0; i < model.eSERVICESVS!.length; i++) PopupMenuItem<int>(child: Text(model.eSERVICESVS![i].vALUECOLUMNNAME!), value: i),
for (int i = 0; i < model.eSERVICESVS!.length; i++) PopupMenuItem<int>(value: i, child: Column(
children: [
Text(model.eSERVICESVS![i].vALUECOLUMNNAME!),
const PopupMenuDivider(),
],
)),
],
onSelected: (int popipIndex) async {
ESERVICESDV eservicesdv = ESERVICESDV(

@ -91,7 +91,7 @@ class _DynamicListViewScreenState extends State<DynamicListViewScreen> {
padding: const EdgeInsets.all(21),
children: [
// HMG_TKT_NEW_EIT_SS Id used for ticket balance dashboard
if (isTicketRequest) ...[const BalancesDashboardWidget("Current Ticket Balance", false), 12.height],
if (isTicketRequest) ...[const BalancesDashboardWidget("Current Ticket Balance", false, ""), 12.height],
getEITTransactionList == null
? const SizedBox()
: (getEITTransactionList!.isEmpty
@ -102,8 +102,8 @@ class _DynamicListViewScreenState extends State<DynamicListViewScreen> {
itemBuilder: (cxt, int parentIndex) => getEITTransactionList![parentIndex].collectionTransaction!.isEmpty
? const SizedBox()
: GridView(
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 2, childAspectRatio: 1.9 / 0.75),
padding: const EdgeInsets.all(12.0),
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 2, childAspectRatio: 1.0 / 0.75),
padding: const EdgeInsets.only(left: 12,right: 21,top: 12),
shrinkWrap: true,
primary: false,
physics: const ScrollPhysics(),

@ -54,7 +54,7 @@ class ServicesMenuListScreen extends StatelessWidget {
}
return;
} else if (servicesMenuData.list[index].requestType == "ABSENCE") {
Navigator.pushNamed(context, AppRoutes.leaveBalance);
Navigator.pushNamed(context, AppRoutes.leaveBalance, arguments: servicesMenuData?.selectedEmp ??'');
return;
}
if (servicesMenuData.list[index].requestType == "EIT") {

@ -65,14 +65,14 @@ class _CreateRequestState extends State<CreateRequest> {
return menus;
}
void handleOnPress(context, Menus menu) {
void handleOnPress(context, Menus menu) {
if (menu.menuEntry.menuEntryType == "FUNCTION") {
if (menu.menuEntry.requestType == "EIT") {
Navigator.pushNamed(context, AppRoutes.dynamicScreen, arguments: DynamicListViewParams(menu.menuEntry.prompt!, menu.menuEntry.functionName!));
Navigator.pushNamed(context, AppRoutes.dynamicScreen, arguments: DynamicListViewParams(menu.menuEntry.prompt!, menu.menuEntry.functionName!, selectedEmp: getEmployeeSubordinates?.eMPLOYEENUMBER ?? ''));
} else {}
} else {
Navigator.pushNamed(context, AppRoutes.servicesMenuListScreen, arguments: ServicesMenuListScreenParams(menu.menuEntry.prompt!, menu.menuEntiesList, selectedEmp: getEmployeeSubordinates?.eMPLOYEENUMBER??''));
Navigator.pushNamed(context, AppRoutes.servicesMenuListScreen,
arguments: ServicesMenuListScreenParams(menu.menuEntry.prompt!, menu.menuEntiesList, selectedEmp: getEmployeeSubordinates?.eMPLOYEENUMBER ?? ''));
}
return;
}

@ -1,3 +1,4 @@
import 'package:auto_size_text/auto_size_text.dart';
import 'package:easy_localization/src/public_ext.dart';
import 'package:flutter/material.dart';
import 'package:mohem_flutter_app/api/profile_api_client.dart';
@ -14,6 +15,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_phones_model.dart';
import 'package:mohem_flutter_app/provider/dashboard_provider_model.dart';
import 'package:mohem_flutter_app/ui/misc/no_data_ui.dart';
import 'package:mohem_flutter_app/ui/profile/dynamic_screens/dynamic_input_address_screen.dart';
import 'package:mohem_flutter_app/ui/profile/phone_numbers.dart';
import 'package:mohem_flutter_app/widgets/app_bar_widget.dart';
@ -33,7 +35,7 @@ class _ContactDetailsState extends State<ContactDetails> {
String? civilIdentityNumber = "";
String? emailAddress = "";
String? employeeNo = "";
int? correctOrNew = 1;
int? correctOrNew = 2;
List<GetEmployeePhonesList> getEmployeePhonesList = [];
List<GetEmployeeAddressList> getEmployeeAddressList = [];
List<GetEmployeeBasicDetailsList> getEmployeeBasicDetailsList = [];
@ -99,16 +101,17 @@ class _ContactDetailsState extends State<ContactDetails> {
separatorBuilder: (cxt, index) => 12.height,
itemCount: getEmployeePhonesList.length),
if (menuEntriesPhone.updateButton == 'Y')
AppState().isArabic(context)? Positioned(
top: 1,
left: 1,
child: const Icon(Icons.edit_location_alt_outlined, size: 20).onPress(updatePhone),
)
:Positioned(
top: 1,
right: 1,
child: const Icon(Icons.edit_location_alt_outlined, size: 20).onPress(updatePhone),
),
AppState().isArabic(context)
? Positioned(
top: 1,
left: 1,
child: const Icon(Icons.edit_location_alt_outlined, size: 20).onPress(updatePhone),
)
: Positioned(
top: 1,
right: 1,
child: const Icon(Icons.edit_location_alt_outlined, size: 20).onPress(updatePhone),
),
],
).objectContainerView(),
12.height,
@ -129,16 +132,35 @@ class _ContactDetailsState extends State<ContactDetails> {
separatorBuilder: (cxt, index) => 12.height,
itemCount: getEmployeeAddressList.length),
if (menuEntriesAddress.updateButton == 'Y')
AppState().isArabic(context)? Positioned(
top: 1,
left: 1,
child: const Icon(Icons.edit_location_alt_outlined, size: 20).onPress(addUpdateAddress),
)
:Positioned(
top: 1,
right: 1,
child: const Icon(Icons.edit_location_alt_outlined, size: 20).onPress(addUpdateAddress),
),
AppState().isArabic(context)
? Positioned(
top: 1,
left: 1,
child: const Icon(Icons.edit_location_alt_outlined, size: 20).onPress(addUpdateAddress),
)
: Positioned(
top: 1,
right: 1,
child: const Icon(Icons.edit_location_alt_outlined, size: 20).onPress(addUpdateAddress),
),
],
).objectContainerView()
else
Stack(
children: [
if (menuEntriesAddress.addButton == 'Y')
AppState().isArabic(context)
? Positioned(
top: 1,
left: 1,
child: const Icon(Icons.add_location_alt_outlined, size: 20).onPress(continueDynamicForms),
)
: Positioned(
top: 1,
right: 1,
child: const Icon(Icons.add_location_alt_outlined, size: 20).onPress(continueDynamicForms),
),
Utils.getNoDataWidget(context).expanded,
],
).objectContainerView()
],
@ -155,13 +177,13 @@ class _ContactDetailsState extends State<ContactDetails> {
void addUpdateAddress() {
Widget cancelButton = TextButton(
child: Text("Cancel"),
child: Text(LocaleKeys.cancel.tr()),
onPressed: () {
Navigator.pop(context);
},
);
Widget continueButton = TextButton(
child: Text("Next"),
child: Text(LocaleKeys.next.tr()),
onPressed: () {
continueDynamicForms();
},
@ -169,7 +191,7 @@ class _ContactDetailsState extends State<ContactDetails> {
StatefulBuilder alert = StatefulBuilder(builder: (context, setState) {
return AlertDialog(
shape: RoundedRectangleBorder(borderRadius: BorderRadius.all(Radius.circular(10.0))),
title: Text("Confirm"),
title: Text(LocaleKeys.confirm.tr()),
content: Builder(builder: (context) {
// Get available height and width of the build area of this widget. Make a choice depending on the size.
var height = MediaQuery.of(context).size.height * .5;
@ -177,14 +199,14 @@ class _ContactDetailsState extends State<ContactDetails> {
height: height,
child: Column(children: [
Text(
"Select the type of change you want to make.",
LocaleKeys.SelectChangeWantToMake.tr(),
style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold),
),
Divider(),
Column(
children: [
ListTile(
title: Text("Correct or amend this address"),
title: Text(LocaleKeys.CorrectAddress.tr()),
leading: Radio(
value: 1,
groupValue: correctOrNew,
@ -197,7 +219,7 @@ class _ContactDetailsState extends State<ContactDetails> {
),
),
ListTile(
title: Text("Enter a new address if you have moved"),
title: Text(LocaleKeys.EnterNewAddressMoved.tr()),
leading: Radio(
value: 2,
groupValue: correctOrNew,

@ -191,7 +191,8 @@ class _DynamicInputScreenState extends State<DynamicInputScreenAddress> {
],
onSelected: (int popupIndex) {
model?.getEmployeeAddressList!.sEGMENTVALUEDSP = model.eSERVICESVS![popupIndex].vALUECOLUMNNAME;
model?.getEmployeeAddressList!.vARCHAR2VALUE = model.eSERVICESVS![popupIndex].dESCRIPTION;
model?.getEmployeeAddressList!.vARCHAR2VALUE =
model.eSERVICESVS![popupIndex].dESCRIPTION != "" ? model.eSERVICESVS![popupIndex].dESCRIPTION : model.eSERVICESVS![popupIndex].iDCOLUMNNAME;
setState(() {});
});
}
@ -282,7 +283,7 @@ class _DynamicInputScreenState extends State<DynamicInputScreenAddress> {
tempVar = e.getEmployeeAddressList!.sEGMENTVALUEDSP ?? "";
}
return ValidateEitTransactionModel(dATEVALUE: null, nAME: e.aPPLICATIONCOLUMNNAME, nUMBERVALUE: null, tRANSACTIONNUMBER: 0, vARCHAR2VALUE: tempVar.toString()).toJson();
return ValidateEitTransactionModel(dATEVALUE: null, nAME: e.aPPLICATIONCOLUMNNAME, nUMBERVALUE: 0, tRANSACTIONNUMBER: 0, vARCHAR2VALUE: tempVar.toString()).toJson();
}).toList();
submitPhoneNumbers = await ProfileApiClient().submitAddressTransaction(
@ -291,7 +292,7 @@ class _DynamicInputScreenState extends State<DynamicInputScreenAddress> {
values,
dynamicParams!.correctOrNew,
countryCode,
effectiveDate.isEmpty ? DateFormat('dd-MMM-yyy').format(DateTime.now().add(Duration(days: 35))) : effectiveDate,
effectiveDate.isEmpty ? DateFormat('dd-MMM-yyy').format(DateTime.now()) : effectiveDate,
);
print(values);
Utils.hideLoading(context);

@ -34,12 +34,12 @@ class _FamilyMembersState extends State<FamilyMembers> {
@override
void initState() {
super.initState();
List<GetMenuEntriesList> menuData = Provider.of<DashboardProviderModel>(context, listen: false).getMenuEntriesList!;
List<GetMenuEntriesList> menuData = Provider.of<DashboardProviderModel>(context, listen: false).getMenuEntriesList!;
List<GetMenuEntriesList> arr = menuData.where((GetMenuEntriesList e) => e.requestType == 'CONTACT').toList();
if(arr.isNotEmpty){
List<GetMenuEntriesList> arr = menuData.where((GetMenuEntriesList e) => e.requestType == 'CONTACT').toList();
if (arr.isNotEmpty) {
menuEntries = arr[0];
}else{
} else {
menuEntries = new GetMenuEntriesList();
}
@ -66,9 +66,10 @@ class _FamilyMembersState extends State<FamilyMembers> {
),
backgroundColor: MyColors.backgroundColor,
body: Column(
children: [
children: [
Expanded(
child: getEmployeeContactsList.isEmpty ? Utils.getNoDataWidget(context)
child: getEmployeeContactsList.isEmpty
? Utils.getNoDataWidget(context)
: ListView.separated(
padding: const EdgeInsets.all(21),
separatorBuilder: (cxt, index) => 12.height,
@ -87,57 +88,68 @@ class _FamilyMembersState extends State<FamilyMembers> {
children: <Widget>[
// todo @faitma clean below logic and write clean code.
RichText(
text: TextSpan(
children: [
WidgetSpan(
child: Icon(Icons.edit, size: 14, color: menuEntries.updateButton == 'Y' ? MyColors.grey67Color : MyColors.lightGreyColor,)
),
TextSpan(
text: LocaleKeys.update.tr(),
style:TextStyle(color: menuEntries.updateButton == 'Y' ? MyColors.grey67Color : MyColors.lightGreyColor, fontSize: 12, letterSpacing: -0.36, fontWeight: FontWeight.w600),
recognizer: TapGestureRecognizer()
..onTap = () async {
relationId = getEmployeeContactsList[index]!.cONTACTRELATIONSHIPID;
menuEntries.updateButton == 'Y'? showUpdateAlertDialog(context, relationId, 2, "UPDATE"):null;
}
)
],
),
),
Container(height: 35, width: 1, color: const Color(0xffEFEFEF)),
RichText(
text: TextSpan(
children: [
const WidgetSpan(
text: TextSpan(
children: [
WidgetSpan(
child: Icon(
Icons.delete, size: 15, color: MyColors.redColor,),
),
TextSpan(
text: LocaleKeys.remove.tr(),
style: const TextStyle(color: MyColors.redColor, fontSize: 12, letterSpacing: -0.36, fontWeight: FontWeight.w600),
Icons.edit,
size: 14,
color: menuEntries.updateButton == 'Y' ? MyColors.grey67Color : MyColors.lightGreyColor,
)),
TextSpan(
text: LocaleKeys.update.tr(),
style: TextStyle(
color: menuEntries.updateButton == 'Y' ? MyColors.grey67Color : MyColors.lightGreyColor, fontSize: 12, letterSpacing: -0.36, fontWeight: FontWeight.w600),
recognizer: TapGestureRecognizer()
..onTap = () async {
relationId = getEmployeeContactsList[index]!.cONTACTRELATIONSHIPID;
menuEntries.updateButton == 'Y' ? showUpdateAlertDialog(context, relationId, 2, "UPDATE") : null;
})
],
),
),
Container(height: 35, width: 1, color: const Color(0xffEFEFEF)),
RichText(
text: TextSpan(
children: [
WidgetSpan(
child: Icon(
Icons.delete,
size: 15,
color: menuEntries.updateButton == 'Y' ? MyColors.redColor : MyColors.lightGreyColor,
),
],
),
).onPress(() { relationId = getEmployeeContactsList[index]!.cONTACTRELATIONSHIPID;
showRemoveAlertDialog(context, relationId);}),
),
TextSpan(
text: LocaleKeys.remove.tr(),
style: TextStyle(
color: menuEntries.updateButton == 'Y' ? MyColors.redColor : MyColors.lightGreyColor, fontSize: 12, letterSpacing: -0.36, fontWeight: FontWeight.w600),
),
],
),
).onPress(() {
relationId = getEmployeeContactsList[index]!.cONTACTRELATIONSHIPID;
menuEntries.updateButton == 'Y' ? showRemoveAlertDialog(context, relationId) : null;
}),
],
),
],
).objectContainerView(disablePadding: true);
}),
),
DefaultButton(LocaleKeys.addNewFamilyMember.tr(),
menuEntries.updateButton == 'Y'
?
() async {
Navigator.pushNamed(context, AppRoutes.addUpdateFamilyMember, arguments: {"relationID": relationId, "flag": 1, "actionType": "ADD"});
// ProfileScreen();
} : null).insideContainer,
DefaultButton(
LocaleKeys.addNewFamilyMember.tr(),
menuEntries.updateButton == 'Y'
? () async {
Navigator.pushNamed(context, AppRoutes.addUpdateFamilyMember, arguments: {"relationID": relationId, "flag": 1, "actionType": "ADD"});
// ProfileScreen();
}
: null)
.insideContainer,
],
));
}
void showUpdateAlertDialog(BuildContext context, relationId, int flag, String actionType) {
void showUpdateAlertDialog(BuildContext context, relationId, int flag, String actionType) {
Widget cancelButton = TextButton(
child: Text(
LocaleKeys.cancel.tr(),
@ -176,7 +188,7 @@ class _FamilyMembersState extends State<FamilyMembers> {
);
}
void showRemoveAlertDialog(BuildContext context, relationId) {
void showRemoveAlertDialog(BuildContext context, relationId) {
Widget cancelButton = TextButton(
child: Text(
LocaleKeys.cancel.tr(),

@ -60,7 +60,7 @@ class _AnnouncementDetailsState extends State<AnnouncementDetails> {
),
),
Html(
data: getAnnouncementDetailsObj?.bodyEN,
data: AppState().isArabic(context) ? getAnnouncementDetailsObj?.bodyAR : getAnnouncementDetailsObj?.bodyEN,
).paddingOnly(top: 12),
],
).objectContainerView().paddingAll(21),

@ -127,6 +127,7 @@ class _AddItemDetailsFragmentState extends State<AddItemDetailsFragment> {
isPopup: false,
lines: 1,
isInputTypeNum: true,
isInputTypeNumSigned: false,
isReadOnly: false,
onChange: (String value) {
itemPrice = num.parse(value);

@ -1,6 +1,8 @@
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:mohem_flutter_app/classes/colors.dart';
import 'package:mohem_flutter_app/classes/consts.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';
@ -74,6 +76,7 @@ class _ItemsForSaleState extends State<ItemsForSale> {
child: const Icon(Icons.add, color: Colors.white, size: 30),
).onPress(
() {
Utils.removeStringFromPrefs(SharedPrefsConsts.editItemForSale);
Navigator.pushNamed(context, AppRoutes.addNewItemForSale);
},
),

@ -143,7 +143,7 @@ class _OffersAndDiscountsDetailsState extends State<OffersAndDiscountsDetails> {
List<Widget> getItemsForSaleWidgets() {
List<Widget> itemsList = [];
for (int i = 1; i < 5; i++) {
for (int i = 1; i < getOffersList.length; i++) {
itemsList.add(getItemCard(getOffersList[i]));
}
return itemsList;

@ -80,39 +80,26 @@ class _OffersAndDiscountsHomeState extends State<OffersAndDiscountsHome> {
// getItemsForSale(currentPageNo, currentCategoryID);
});
},
child: Container(
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(15),
boxShadow: [
BoxShadow(
color: const Color(0xff000000).withOpacity(.05),
blurRadius: 26,
offset: const Offset(0, -3),
),
],
),
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
SvgPicture.string(
getCategoriesList[index].content!,
fit: BoxFit.contain,
width: 25,
height: 25,
),
currentCategoryID == getCategoriesList[index].id ? const Icon(Icons.check_circle_rounded, color: MyColors.greenColor, size: 16.0) : Container(),
],
).expanded,
AppState().isArabic(context) ? getCategoriesList[index].categoryNameAr!.toText10(maxlines: 1) : getCategoriesList[index].categoryNameEn!.toText10(maxlines: 1)
],
).paddingOnly(left: 10, right: 10, bottom: 10, top: 12),
),
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
SvgPicture.string(
getCategoriesList[index].content!,
fit: BoxFit.contain,
width: 25,
height: 25,
),
currentCategoryID == getCategoriesList[index].id ? const Icon(Icons.check_circle_rounded, color: MyColors.greenColor, size: 16.0) : Container(),
],
).expanded,
AppState().isArabic(context) ? getCategoriesList[index].categoryNameAr!.toText10() : getCategoriesList[index].categoryNameEn!.toText10()
],
).paddingOnly(left: 10, right: 10, bottom: 10, top: 12).expanded.objectContainerView(disablePadding: true),
),
);
},

@ -0,0 +1,72 @@
import 'dart:io';
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:mohem_flutter_app/classes/colors.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/widgets/button/default_button.dart';
class UnsafeDeviceScreen extends StatefulWidget {
const UnsafeDeviceScreen({Key? key}) : super(key: key);
@override
State<UnsafeDeviceScreen> createState() => _UnsafeDeviceScreenState();
}
class _UnsafeDeviceScreenState extends State<UnsafeDeviceScreen> {
@override
Widget build(BuildContext context) {
return Scaffold(
body: SafeArea(
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
children: [
21.height,
Center(child: Image.asset("assets/images/logos/main_mohemm_logo.png", width: 200, height: 50)),
50.height,
"Sorry".toText24(isBold: true),
21.height,
"You are using Mohemm app on an unsafe device. To be able to use the app with all it's features, Please make sure that the below points are considered: "
.toText14(isCenter: true)
.paddingOnly(left: 20.0, right: 20.0),
48.height,
passwordConstraintsUI("The device is not jailbroken or rooted.", true).paddingOnly(left: 24.0, right: 5.0),
8.height,
passwordConstraintsUI("The app is not installed on external storage.", true).paddingOnly(left: 24.0, right: 5.0),
8.height,
passwordConstraintsUI("Development mode is disabled.", true).paddingOnly(left: 24.0, right: 5.0),
21.height,
DefaultButton(LocaleKeys.ok.tr(), () async {
if (Platform.isAndroid) {
SystemChannels.platform.invokeMethod('SystemNavigator.pop');
} else {
// MinimizeApp.minimizeApp();
}
}).paddingAll(24)
],
),
),
);
}
Widget passwordConstraintsUI(String description, bool check) {
return Row(
children: [
4.width,
SizedBox(
width: 12,
height: 12,
child: Checkbox(fillColor: MaterialStateProperty.all(MyColors.gradiantEndColor), shape: const CircleBorder(), value: check, onChanged: null),
),
8.width,
description.toText14()
],
);
}
}

@ -233,9 +233,9 @@ class _WorkListDetailScreenState extends State<WorkListDetailScreen> {
),
child: Row(
children: [
(workListData!.iTEMTYPE == "HRSSA" || workListData!.iTEMTYPE == "STAMP") ? myTab(LocaleKeys.details.tr(), 0) : myTab(LocaleKeys.request.tr(), 0),
myTab(LocaleKeys.actions.tr(), 1),
myTab(LocaleKeys.info.tr(), 2),
myTab(LocaleKeys.info.tr(), 0),
(workListData!.iTEMTYPE == "HRSSA" || workListData!.iTEMTYPE == "STAMP") ? myTab(LocaleKeys.details.tr(), 1) : myTab(LocaleKeys.request.tr(), 1),
myTab(LocaleKeys.actions.tr(), 2),
myTab(LocaleKeys.attachments.tr(), 3),
],
),
@ -249,6 +249,19 @@ class _WorkListDetailScreenState extends State<WorkListDetailScreen> {
});
},
children: [
InfoFragment(
poHeaderList: getPoNotificationBody?.pOHeader ?? [],
workListData: workListData,
itemCreationHeader: getItemCreationNtfBody?.itemCreationHeader ?? [],
getStampMsNotifications: getStampMsNotifications,
getStampNsNotifications: getStampNsNotifications,
getEitCollectionNotificationBodyList: getEitCollectionNotificationBodyList,
getPhonesNotificationBodyList: getPhonesNotificationBodyList,
getBasicDetNtfBodyList: getBasicDetNtfBodyList,
getAbsenceCollectionNotificationBodyList: getAbsenceCollectionNotificationBodyList,
getContactNotificationBodyList: getContactNotificationBodyList,
getPrNotificationBodyList: getPrNotificationBody,
),
(workListData!.iTEMTYPE == "HRSSA" || workListData!.iTEMTYPE == "STAMP")
? DetailFragment(workListData, memberInformationListModel)
: RequestFragment(
@ -266,19 +279,6 @@ class _WorkListDetailScreenState extends State<WorkListDetailScreen> {
voidCallback: reloadWorkList,
)
: showLoadingAnimation(),
InfoFragment(
poHeaderList: getPoNotificationBody?.pOHeader ?? [],
workListData: workListData,
itemCreationHeader: getItemCreationNtfBody?.itemCreationHeader ?? [],
getStampMsNotifications: getStampMsNotifications,
getStampNsNotifications: getStampNsNotifications,
getEitCollectionNotificationBodyList: getEitCollectionNotificationBodyList,
getPhonesNotificationBodyList: getPhonesNotificationBodyList,
getBasicDetNtfBodyList: getBasicDetNtfBodyList,
getAbsenceCollectionNotificationBodyList: getAbsenceCollectionNotificationBodyList,
getContactNotificationBodyList: getContactNotificationBodyList,
getPrNotificationBodyList: getPrNotificationBody,
),
isAttachmentLoaded
? getAttachmentList.isEmpty
? Utils.getNoDataWidget(context)

@ -31,8 +31,9 @@ class BalancesDashboardWidget extends StatefulWidget {
final String title;
final List<PieChartModel> chartModelList;
final bool isLeaveBalance;
final String selectedEmp;
const BalancesDashboardWidget(this.title, this.isLeaveBalance, {Key? key, this.chartModelList = const []}) : super(key: key);
const BalancesDashboardWidget(this.title, this.isLeaveBalance, this.selectedEmp, {Key? key, this.chartModelList = const []}) : super(key: key);
@override
_BalancesDashboardWidgetState createState() {
@ -45,11 +46,14 @@ class _BalancesDashboardWidgetState extends State<BalancesDashboardWidget> {
late DateTime accrualDateTime;
GetAccrualBalancesList? leaveBalanceAccrual;
List<GetAccrualBalancesList>? ticketBalanceAccrualList;
dynamic dynamicParams;
String selectedEmp = "";
@override
void initState() {
super.initState();
accrualDateTime = DateTime.now();
changeAccrualDate();
}
@override
@ -59,8 +63,8 @@ class _BalancesDashboardWidgetState extends State<BalancesDashboardWidget> {
void changeAccrualDate() async {
try {
Utils.showLoading(context);
List<GetAccrualBalancesList> accrualList = await DashboardApiClient().getAccrualBalances(DateFormat("MM/dd/yyyy").format(accrualDateTime));
// Utils.showLoading(context);
List<GetAccrualBalancesList> accrualList = await DashboardApiClient().getAccrualBalances(DateFormat("MM/dd/yyyy").format(accrualDateTime), empID: widget.selectedEmp);
if (accrualList.isNotEmpty) {
if (widget.isLeaveBalance) {
leaveBalanceAccrual = accrualList[0];
@ -76,7 +80,7 @@ class _BalancesDashboardWidgetState extends State<BalancesDashboardWidget> {
];
}
}
Utils.hideLoading(context);
// Utils.hideLoading(context);
setState(() {});
} catch (ex) {
Utils.hideLoading(context);

@ -15,6 +15,7 @@ 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/main.dart';
import 'package:mohem_flutter_app/models/chat/get_search_user_chat_model.dart';
import 'package:mohem_flutter_app/models/get_action_history_list_model.dart';
import 'package:mohem_flutter_app/models/worklist/get_favorite_replacements_model.dart';
@ -90,10 +91,9 @@ class _SearchEmployeeBottomSheetState extends State<SearchEmployeeBottomSheet> {
Utils.showLoading(context);
chatUsersList = await ChatApiClient().getChatMemberFromSearch(
searchText,
int.parse(
AppState().chatDetails!.response!.id.toString(),
),
int.parse(AppState().chatDetails!.response!.id.toString()),
);
chatUsersList!.removeWhere((element) => element.id == AppState().chatDetails!.response!.id);
Utils.hideLoading(context);
setState(() {});
} catch (e) {

@ -4,6 +4,7 @@ import 'package:mohem_flutter_app/classes/colors.dart';
class DynamicTextFieldWidget extends StatelessWidget {
final String labelText;
final String hintText;
// final TextEditingController controller;
final VoidCallback? onTap;
final IconData? suffixIconData;
@ -13,6 +14,7 @@ class DynamicTextFieldWidget extends StatelessWidget {
final bool isPopup;
final int? lines;
final bool isInputTypeNum;
final bool isInputTypeNumSigned;
final bool isObscureText;
final bool isBackgroundEnable;
final void Function(String)? onChange;
@ -28,6 +30,7 @@ class DynamicTextFieldWidget extends StatelessWidget {
this.inputAction,
this.onChange,
this.isInputTypeNum = false,
this.isInputTypeNumSigned = true,
this.isBackgroundEnable = false});
@override
@ -63,8 +66,13 @@ class DynamicTextFieldWidget extends StatelessWidget {
),
TextField(
enabled: isEnable,
scrollPadding: EdgeInsets.zero, readOnly: isReadOnly,
keyboardType: isInputTypeNum ? const TextInputType.numberWithOptions(signed: true) : TextInputType.text,
scrollPadding: EdgeInsets.zero,
readOnly: isReadOnly,
keyboardType: (isInputTypeNum)
? isInputTypeNumSigned
? const TextInputType.numberWithOptions(signed: true)
: TextInputType.number
: TextInputType.text,
textInputAction: TextInputAction.done,
//controller: controller,
maxLines: lines,

@ -37,9 +37,9 @@ class ItemDetailViewCol extends StatelessWidget {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
"$title:".toText12(isBold: true, color: const Color(0xff2BB8A6)),
"$title:".toText12(isBold: true, color: const Color(0xff2BB8A6), maxLine: 2),
4.width,
(value.isEmpty ? "--" : value).toText12(color: MyColors.normalTextColor),
(value.isEmpty ? "--" : value).toText12(color: MyColors.normalTextColor, maxLine: 2),
],
);
}

@ -98,6 +98,7 @@ dependencies:
video_player: ^2.4.7
just_audio: ^0.9.30
safe_device: ^1.1.2
dev_dependencies:
flutter_test:

Loading…
Cancel
Save