Merge branch 'master' into development_aamir

merge-requests/99/head
Aamir Muhammad 3 years ago
commit 30c7f5738d

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

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

@ -424,6 +424,9 @@
"typeCurrentPasswordBelow": "Type Your Current password below", "typeCurrentPasswordBelow": "Type Your Current password below",
"currentPassword": "Current password", "currentPassword": "Current password",
"concurrentReports": "Concurrent Reports", "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": { "profile": {
"reset_password": { "reset_password": {
"label": "Reset Password", "label": "Reset Password",

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

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

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

@ -8,6 +8,7 @@ import 'package:mohem_flutter_app/classes/consts.dart';
import 'package:mohem_flutter_app/models/marathon/marathon_generic_model.dart'; import 'package:mohem_flutter_app/models/marathon/marathon_generic_model.dart';
import 'package:mohem_flutter_app/models/marathon/marathon_model.dart'; import 'package:mohem_flutter_app/models/marathon/marathon_model.dart';
import 'package:mohem_flutter_app/models/marathon/question_model.dart'; import 'package:mohem_flutter_app/models/marathon/question_model.dart';
import 'package:mohem_flutter_app/models/marathon/winner_model.dart';
import 'package:signalr_netcore/hub_connection.dart'; import 'package:signalr_netcore/hub_connection.dart';
class MarathonApiClient { class MarathonApiClient {
@ -19,6 +20,7 @@ class MarathonApiClient {
String employeeSession = AppState().postParamsObject?.pSessionId.toString() ?? ""; String employeeSession = AppState().postParamsObject?.pSessionId.toString() ?? "";
Map<String, String> jsonObject = <String, String>{"userName": employeeUserName, "password": employeeSession}; Map<String, String> jsonObject = <String, String>{"userName": employeeUserName, "password": employeeSession};
Response response = await ApiClient().postJsonForResponse(ApiConsts.marathonParticipantLoginUrl, jsonObject); Response response = await ApiClient().postJsonForResponse(ApiConsts.marathonParticipantLoginUrl, jsonObject);
var json = jsonDecode(response.body); var json = jsonDecode(response.body);
@ -80,10 +82,11 @@ class MarathonApiClient {
return marathonDetailModel; return marathonDetailModel;
} }
Future<bool> joinMarathonAsParticipant() async { Future<int?> joinMarathonAsParticipant() async {
Map<String, String> jsonObject = <String, String>{ Map<String, String> jsonObject = <String, String>{
"employeeNumber": AppState().memberInformationList!.eMPLOYEENUMBER ?? "", "employeeNumber": AppState().memberInformationList!.eMPLOYEENUMBER ?? "",
"employeeName": AppState().memberInformationList!.eMPLOYEENAME ?? "", "employeeNameAr": AppState().memberInformationList!.eMPLOYEEDISPLAYNAMEAr ?? "",
"employeeNameEn": AppState().memberInformationList!.eMPLOYEEDISPLAYNAMEEn ?? "",
"marathonId": AppState().getMarathonProjectId!, "marathonId": AppState().getMarathonProjectId!,
}; };
@ -95,31 +98,33 @@ class MarathonApiClient {
if (marathonModel.statusCode == 208) { if (marathonModel.statusCode == 208) {
// means participant is already in the marathon i.e already joined // means participant is already in the marathon i.e already joined
return true; return marathonModel.data["remainingTime"];
} }
if (marathonModel.statusCode == 200) { if (marathonModel.statusCode == 200) {
if (marathonModel.data != null && marathonModel.isSuccessful == true) { if (marathonModel.data != null && marathonModel.isSuccessful == true) {
logger.i("joinMarathonAsParticipant: ${marathonModel.data}"); logger.i("joinMarathonAsParticipant: ${marathonModel.data}");
return true; return marathonModel.data["remainingTime"];
} else { } else {
return false; return null;
} }
} else { } else {
return false; return null;
} }
} }
Future<QuestionModel?> getNextQuestion({required String? questionId, required String marathonId}) async { Future<QuestionModel?> getNextQuestion({required String? questionId, required String marathonId}) async {
Map<String, String?> jsonObject = <String, String?>{ Map<String, String?> jsonObject = <String, String?>{
"questionId": questionId, "previousQuestionId": questionId,
"marathonId": marathonId, "marathonId": marathonId,
}; };
Response response = await ApiClient().postJsonForResponse(ApiConsts.marathonNextQuestionUrl, jsonObject, token: AppState().getMarathonToken ?? await getMarathonToken()); Response response = await ApiClient().postJsonForResponse(ApiConsts.marathonNextQuestionUrl, jsonObject, token: AppState().getMarathonToken ?? await getMarathonToken());
var json = jsonDecode(response.body); var json = jsonDecode(response.body);
logger.i("json in NextQuestion: $json");
var data = json["data"]; var data = json["data"];
if (data != null) { if (data != null) {
@ -130,13 +135,13 @@ class MarathonApiClient {
} }
} }
Future<bool> submitSelectedOption({required String? selectedAnswerId}) async { Future<bool> submitSelectedOption({required String marathonId, required String? questionId, required String? selectedAnswerId}) async {
Map<String, String?> jsonObject = <String, String?>{"selectedOptionId": selectedAnswerId}; Map<String, String?> jsonObject = <String, String?>{"marathonId": marathonId, "questionId": questionId, "selectedOptionId" : selectedAnswerId};
Response response = await ApiClient().postJsonForResponse(ApiConsts.marathonSubmitAnswerUrl, jsonObject, token: AppState().getMarathonToken ?? await getMarathonToken()); Response response = await ApiClient().postJsonForResponse(ApiConsts.marathonSubmitAnswerUrl, jsonObject, token: AppState().getMarathonToken ?? await getMarathonToken());
var json = jsonDecode(response.body); var json = jsonDecode(response.body);
logger.i("json: $json"); logger.i("json in submitSelectedOption : $json");
MarathonGenericModel marathonModel = MarathonGenericModel.fromJson(json); MarathonGenericModel marathonModel = MarathonGenericModel.fromJson(json);
@ -147,6 +152,42 @@ class MarathonApiClient {
return marathonModel.isSuccessful!; return marathonModel.isSuccessful!;
} }
Future<int?> getQualifiers({required String marathonId}) async {
Map<String, String> params = <String, String>{"marathonId": marathonId};
Response response = await ApiClient().getJsonForResponse(ApiConsts.marathonQualifiersUrl, queryParameters: params, token: AppState().getMarathonToken ?? await getMarathonToken());
var json = jsonDecode(response.body);
logger.i("json in getQualifiers: $json");
MarathonGenericModel marathonGenericModel = MarathonGenericModel.fromJson(json);
if (marathonGenericModel.isSuccessful == true && marathonGenericModel.statusCode == 200 && marathonGenericModel.data != null) {
return marathonGenericModel.data["winnerCount"];
}
return null;
}
Future<List<WinnerModel>?> getSelectedWinner({required String marathonId}) async {
Map<String, String> params = <String, String>{"marathonId": marathonId};
Response response = await ApiClient().getJsonForResponse(ApiConsts.marathonSelectedWinner, queryParameters: params, token: AppState().getMarathonToken ?? await getMarathonToken());
var json = jsonDecode(response.body);
logger.i("json in getSelectedWinner: $json");
MarathonGenericModel marathonGenericModel = MarathonGenericModel.fromJson(json);
if (marathonGenericModel.isSuccessful == true && marathonGenericModel.statusCode == 200 && marathonGenericModel.data != null) {
List<WinnerModel> winners = <WinnerModel>[];
List data = marathonGenericModel.data as List;
for (Map<String, dynamic> winner in data) {
winners.add(WinnerModel.fromJson(winner));
}
return winners;
}
return null;
}
// Future<void> buildHubConnection(BuildContext context, String prizeId) async { // Future<void> buildHubConnection(BuildContext context, String prizeId) async {
// HttpConnectionOptions httpOptions = HttpConnectionOptions(skipNegotiation: false, logMessageContent: true); // HttpConnectionOptions httpOptions = HttpConnectionOptions(skipNegotiation: false, logMessageContent: true);
// hubConnection = HubConnectionBuilder() // hubConnection = HubConnectionBuilder()

@ -2,8 +2,8 @@ import 'package:mohem_flutter_app/ui/marathon/widgets/question_card.dart';
class ApiConsts { class ApiConsts {
//static String baseUrl = "http://10.200.204.20:2801/"; // Local server //static String baseUrl = "http://10.200.204.20:2801/"; // Local server
//static String baseUrl = "https://uat.hmgwebservices.com"; // UAT server // static String baseUrl = "https://uat.hmgwebservices.com"; // UAT server
static String baseUrl = "https://hmgwebservices.com"; // Live server static String baseUrl = "https://hmgwebservices.com"; // Live server
static String baseUrlServices = baseUrl + "/Services/"; // server static String baseUrlServices = baseUrl + "/Services/"; // server
// static String baseUrlServices = "https://api.cssynapses.com/tangheem/"; // Live server // static String baseUrlServices = "https://api.cssynapses.com/tangheem/"; // Live server
static String utilitiesRest = baseUrlServices + "Utilities.svc/REST/"; static String utilitiesRest = baseUrlServices + "Utilities.svc/REST/";
@ -25,21 +25,21 @@ class ApiConsts {
static String chatFavUser = chatServerBaseApiUrl + "FavUser/"; static String chatFavUser = chatServerBaseApiUrl + "FavUser/";
static String chatUserImages = chatServerBaseUrl + "empservice/api/employee/"; static String chatUserImages = chatServerBaseUrl + "empservice/api/employee/";
//Brain Marathon Constants //Brain Marathon Constants
static String marathonBaseUrl = "https://marathoon.com/service/api/"; static String marathonBaseUrl = "https://marathoon.com/service/api/";
static String marathonParticipantLoginUrl = marathonBaseUrl + "auth/participantlogin"; static String marathonParticipantLoginUrl = marathonBaseUrl + "auth/participantlogin";
static String marathonProjectGetUrl = marathonBaseUrl + "Project/Project_Get"; static String marathonProjectGetUrl = marathonBaseUrl + "Project/Project_Get";
static String marathonUpcomingUrl = marathonBaseUrl + "marathon/upcoming/"; static String marathonUpcomingUrl = marathonBaseUrl + "marathon/upcoming/";
static String marathonJoinParticipantUrl = marathonBaseUrl + "participant/participant_join"; static String marathonJoinParticipantUrl = marathonBaseUrl + "participant/join";
static String marathonNextQuestionUrl = marathonBaseUrl + "question/next"; static String marathonNextQuestionUrl = marathonBaseUrl + "question/next";
static String marathonSubmitAnswerUrl = marathonBaseUrl + "question/submit"; static String marathonSubmitAnswerUrl = marathonBaseUrl + "question/submit";
static String marathonQualifiersUrl = marathonBaseUrl + "winner/getWinner/"; static String marathonQualifiersUrl = marathonBaseUrl + "winner/getWinner/";
static String marathonSelectedWinner = marathonBaseUrl + "winner/getSelectedWinner/"; static String marathonSelectedWinner = marathonBaseUrl + "winner/getSelectedWinner/";
//DummyCards for the UI //DummyCards for the UI
static CardContent dummyQuestion = const CardContent(); static CardContent dummyQuestion = const CardContent();
static int tabletMinLength = 500;
} }
class SharedPrefsConsts { class SharedPrefsConsts {

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

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

@ -22,7 +22,6 @@ import 'package:mohem_flutter_app/ui/marathon/marathon_intro_screen.dart';
import 'package:mohem_flutter_app/ui/marathon/marathon_screen.dart'; import 'package:mohem_flutter_app/ui/marathon/marathon_screen.dart';
import 'package:mohem_flutter_app/ui/marathon/marathon_sponsor_video_screen.dart'; import 'package:mohem_flutter_app/ui/marathon/marathon_sponsor_video_screen.dart';
import 'package:mohem_flutter_app/ui/marathon/marathon_waiting_screen.dart'; import 'package:mohem_flutter_app/ui/marathon/marathon_waiting_screen.dart';
import 'package:mohem_flutter_app/ui/marathon/marathon_winner_selection.dart';
import 'package:mohem_flutter_app/ui/marathon/winner_screen.dart'; import 'package:mohem_flutter_app/ui/marathon/winner_screen.dart';
import 'package:mohem_flutter_app/ui/misc/request_submit_screen.dart'; import 'package:mohem_flutter_app/ui/misc/request_submit_screen.dart';
import 'package:mohem_flutter_app/ui/my_attendance/dynamic_screens/dynamic_input_screen.dart'; import 'package:mohem_flutter_app/ui/my_attendance/dynamic_screens/dynamic_input_screen.dart';
@ -67,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/pending_transactions/pending_transactions_details.dart';
import 'package:mohem_flutter_app/ui/screens/submenu_screen.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/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/item_history_screen.dart';
import 'package:mohem_flutter_app/ui/work_list/itg_detail_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'; import 'package:mohem_flutter_app/ui/work_list/work_list_screen.dart';
@ -186,11 +186,12 @@ class AppRoutes {
//Marathon //Marathon
static const String marathonIntroScreen = "/marathonIntroScreen"; static const String marathonIntroScreen = "/marathonIntroScreen";
static const String marathonScreen = "/marathonScreen"; static const String marathonScreen = "/marathonScreen";
static const String marathonWinnerSelection = "/marathonWinnerSelection";
static const String marathonWinnerScreen = "/marathonWinnerScreen"; static const String marathonWinnerScreen = "/marathonWinnerScreen";
static const String marathonSponsorVideoScreen = "/marathonSponsorVideoScreen"; static const String marathonSponsorVideoScreen = "/marathonSponsorVideoScreen";
static const String marathonWaitingScreen = "/marathonWaitingScreen"; static const String marathonWaitingScreen = "/marathonWaitingScreen";
static const String unsafeDeviceScreen = "/unsafeDeviceScreen";
static final Map<String, WidgetBuilder> routes = { static final Map<String, WidgetBuilder> routes = {
login: (BuildContext context) => LoginScreen(), login: (BuildContext context) => LoginScreen(),
verifyLogin: (BuildContext context) => VerifyLoginScreen(), verifyLogin: (BuildContext context) => VerifyLoginScreen(),
@ -296,9 +297,10 @@ class AppRoutes {
// Marathon // Marathon
marathonIntroScreen: (BuildContext context) => MarathonIntroScreen(), marathonIntroScreen: (BuildContext context) => MarathonIntroScreen(),
marathonScreen: (BuildContext context) => MarathonScreen(), marathonScreen: (BuildContext context) => MarathonScreen(),
marathonWinnerSelection: (BuildContext context) => MarathonWinnerSelection(),
marathonWinnerScreen: (BuildContext context) => WinnerScreen(), marathonWinnerScreen: (BuildContext context) => WinnerScreen(),
marathonSponsorVideoScreen: (BuildContext context) => const SponsorVideoScreen(), marathonSponsorVideoScreen: (BuildContext context) => const SponsorVideoScreen(),
marathonWaitingScreen: (BuildContext context) => const MarathonWaitingScreen(), 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), 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, this,
textAlign: isCenter ? TextAlign.center : TextAlign.left,
maxLines: maxlines, maxLines: maxlines,
style: TextStyle( style: TextStyle(
color: color ?? MyColors.darkTextColor, color: color ?? MyColors.darkTextColor,
@ -140,8 +141,9 @@ extension EmailValidator on String {
style: TextStyle(color: color ?? MyColors.grey3AColor, fontSize: 21, letterSpacing: -0.84, fontWeight: weight ?? (isBold ? FontWeight.bold : FontWeight.w600)), style: TextStyle(color: color ?? MyColors.grey3AColor, fontSize: 21, letterSpacing: -0.84, fontWeight: weight ?? (isBold ? FontWeight.bold : FontWeight.w600)),
); );
Widget toText22({Color? color, bool isBold = false}) => Text( Widget toText22({Color? color, bool isBold = false, bool isCentered = false}) => Text(
this, this,
textAlign: isCentered ? TextAlign.center : null,
style: TextStyle(height: 1, color: color ?? MyColors.darkTextColor, fontSize: 22, letterSpacing: -1.44, fontWeight: isBold ? FontWeight.bold : FontWeight.w600), style: TextStyle(height: 1, color: color ?? MyColors.darkTextColor, fontSize: 22, letterSpacing: -1.44, fontWeight: isBold ? FontWeight.bold : FontWeight.w600),
); );
@ -151,12 +153,13 @@ extension EmailValidator on String {
); );
Widget toText30({Color? color, bool isBold = false}) => Text( Widget toText30({Color? color, bool isBold = false}) => Text(
this, this,
style: TextStyle(height: 20 / 32, color: color ?? MyColors.darkTextColor, fontSize: 32, letterSpacing: -1.2, fontWeight: isBold ? FontWeight.bold : FontWeight.w600), style: TextStyle(height: 20 / 32, color: color ?? MyColors.darkTextColor, fontSize: 32, letterSpacing: -1.2, fontWeight: isBold ? FontWeight.bold : FontWeight.w600),
); );
Widget toText32({Color? color, bool isBold = false}) => Text( Widget toText32({Color? color, bool isBold = false, bool isCentered = false}) => Text(
this, this,
textAlign: isCentered ? TextAlign.center : null,
style: TextStyle(height: 32 / 32, color: color ?? MyColors.darkTextColor, fontSize: 32, letterSpacing: -1.92, fontWeight: isBold ? FontWeight.bold : FontWeight.w600), style: TextStyle(height: 32 / 32, color: color ?? MyColors.darkTextColor, fontSize: 32, letterSpacing: -1.92, fontWeight: isBold ? FontWeight.bold : FontWeight.w600),
); );

@ -440,6 +440,9 @@ class CodegenLoader extends AssetLoader{
"typeCurrentPasswordBelow": "اكتب كلمة المرور الحاليه", "typeCurrentPasswordBelow": "اكتب كلمة المرور الحاليه",
"currentPassword": "كلمة المرور الحاليه", "currentPassword": "كلمة المرور الحاليه",
"concurrentReports": "التقارير المتزامنه", "concurrentReports": "التقارير المتزامنه",
"EnterNewAddressMoved": "أدخل عنوان جديد إذا كنت قد انتقلت",
"CorrectAddress": "تصحيح أو تعديل هذا العنوان",
"SelectChangeWantToMake": " حدد نوع التغيير الذي تريد القيام به.",
"profile": { "profile": {
"reset_password": { "reset_password": {
"label": "Reset Password", "label": "Reset Password",
@ -516,7 +519,16 @@ class CodegenLoader extends AssetLoader{
"codeExpire": "انتهت صلاحية رمز التحقق", "codeExpire": "انتهت صلاحية رمز التحقق",
"typeheretoreply": "اكتب هنا للرد", "typeheretoreply": "اكتب هنا للرد",
"favorite": "مفضلتي", "favorite": "مفضلتي",
"searchfromchat": "البحث من الدردشة" "searchfromchat": "البحث من الدردشة",
"yourAnswerCorrect": "إجابتك صحيحة",
"youMissedTheQuestion": "نفد منك الوقت. أنت خارج اللعبة. لكن يمكنك الاستمرار وكمشاهد.",
"wrongAnswer": "إجابتك غير صحيحة. أنت خارج اللعبة. لكن يمكنك الاستمرار وكمشاهد.",
"oops": "أوه!!!",
"winner": "الفائز",
"youWantToLeaveMarathon": "هل أنت متأكد أنك تريد العودة؟ سوف تخرج من المسابقة.",
"ourSponsor": "راعينا:",
"startingIn": "يبدأ في",
"youAreOutOfContest": "أنت خارج المسابقة."
}; };
static const Map<String,dynamic> en_US = { static const Map<String,dynamic> en_US = {
"mohemm": "Mohemm", "mohemm": "Mohemm",
@ -944,6 +956,9 @@ static const Map<String,dynamic> en_US = {
"typeCurrentPasswordBelow": "Type Your Current password below", "typeCurrentPasswordBelow": "Type Your Current password below",
"currentPassword": "Current password", "currentPassword": "Current password",
"concurrentReports": "Concurrent Reports", "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": { "profile": {
"reset_password": { "reset_password": {
"label": "Reset Password", "label": "Reset Password",
@ -1020,7 +1035,16 @@ static const Map<String,dynamic> en_US = {
"allQuestionsCorrect": "You have answered all questions correct", "allQuestionsCorrect": "You have answered all questions correct",
"typeheretoreply": "Type here to reply", "typeheretoreply": "Type here to reply",
"favorite": "My Favorites", "favorite": "My Favorites",
"searchfromchat": "Search from chat" "searchfromchat": "Search from chat",
"yourAnswerCorrect": "Your answer is correct",
"youMissedTheQuestion": "You ran out of time. You are out of the game. But you can continue and as a viewer.",
"wrongAnswer": "Your answer is Incorrect. You are out of the game. But you can continue and as a viewer.",
"oops": "Ooopsss!!!!",
"winner": "WINNER",
"youWantToLeaveMarathon": "Are you sure you want to go back? You will be out of the contest.",
"ourSponsor": "Our Sponsor:",
"startingIn": "Starting in",
"youAreOutOfContest": "You are out of the contest."
}; };
static const Map<String, Map<String,dynamic>> mapLocales = {"ar_SA": ar_SA, "en_US": en_US}; static const Map<String, Map<String,dynamic>> mapLocales = {"ar_SA": ar_SA, "en_US": en_US};
} }

@ -425,6 +425,9 @@ abstract class LocaleKeys {
static const typeCurrentPasswordBelow = 'typeCurrentPasswordBelow'; static const typeCurrentPasswordBelow = 'typeCurrentPasswordBelow';
static const currentPassword = 'currentPassword'; static const currentPassword = 'currentPassword';
static const concurrentReports = 'concurrentReports'; 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_label = 'profile.reset_password.label';
static const profile_reset_password_username = 'profile.reset_password.username'; static const profile_reset_password_username = 'profile.reset_password.username';
static const profile_reset_password_password = 'profile.reset_password.password'; static const profile_reset_password_password = 'profile.reset_password.password';

@ -4,6 +4,7 @@ import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:logger/logger.dart'; import 'package:logger/logger.dart';
import 'package:mohem_flutter_app/app_state/app_state.dart'; import 'package:mohem_flutter_app/app_state/app_state.dart';
import 'package:mohem_flutter_app/classes/consts.dart';
import 'package:mohem_flutter_app/config/routes.dart'; import 'package:mohem_flutter_app/config/routes.dart';
import 'package:mohem_flutter_app/generated/codegen_loader.g.dart'; import 'package:mohem_flutter_app/generated/codegen_loader.g.dart';
import 'package:mohem_flutter_app/models/post_params_model.dart'; import 'package:mohem_flutter_app/models/post_params_model.dart';
@ -32,11 +33,15 @@ class MyHttpOverrides extends HttpOverrides {
} }
} }
bool isTablet = false;
Future<void> main() async { Future<void> main() async {
WidgetsFlutterBinding.ensureInitialized(); WidgetsFlutterBinding.ensureInitialized();
await EasyLocalization.ensureInitialized(); await EasyLocalization.ensureInitialized();
AppState().setPostParamsInitConfig(); AppState().setPostParamsInitConfig();
HttpOverrides.global = MyHttpOverrides(); HttpOverrides.global = MyHttpOverrides();
isTablet = MediaQueryData.fromWindow(WidgetsBinding.instance.window).size.shortestSide >= ApiConsts.tabletMinLength;
runApp( runApp(
EasyLocalization( EasyLocalization(
supportedLocales: const <Locale>[ supportedLocales: const <Locale>[

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

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

@ -0,0 +1,17 @@
class WinnerModel {
String? id;
String? marathoneId;
String? employeeId;
String? nameEn;
String? nameAr;
WinnerModel({id, marathoneId, employeeId, nameEn, nameAr});
WinnerModel.fromJson(Map<String, dynamic> json) {
id = json['id'];
marathoneId = json['marathoneId'];
employeeId = json['employeeId'];
nameEn = json['nameEn'];
nameAr = json['nameAr'];
}
}

@ -1,6 +1,7 @@
import 'dart:async'; import 'dart:async';
import 'dart:convert'; import 'dart:convert';
import 'dart:io'; import 'dart:io';
import 'dart:typed_data';
import 'package:easy_localization/easy_localization.dart'; import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/cupertino.dart'; import 'package:flutter/cupertino.dart';
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';

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

@ -1,6 +1,7 @@
import 'package:easy_localization/easy_localization.dart'; import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:mohem_flutter_app/api/leave_balance_api_client.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/colors.dart';
import 'package:mohem_flutter_app/classes/utils.dart'; import 'package:mohem_flutter_app/classes/utils.dart';
import 'package:mohem_flutter_app/config/routes.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'; import 'package:mohem_flutter_app/widgets/item_detail_view_widget.dart';
class LeaveBalance extends StatefulWidget { class LeaveBalance extends StatefulWidget {
LeaveBalance({Key? key}) : super(key: key); final String selectedEmp;
LeaveBalance({this.selectedEmp = '', Key? key}) : super(key: key);
@override @override
_LeaveBalanceState createState() { _LeaveBalanceState createState() {
@ -25,12 +27,13 @@ class _LeaveBalanceState extends State<LeaveBalance> {
List<GetAbsenceTransactionList>? absenceTransList; List<GetAbsenceTransactionList>? absenceTransList;
DateTime accrualDateTime = DateTime.now(); DateTime accrualDateTime = DateTime.now();
dynamic dynamicParams;
String selectedEmp = "";
@override @override
void initState() { void initState() {
super.initState(); super.initState();
absenceTransList = [];
getAbsenceTransactions();
} }
@override @override
@ -40,9 +43,9 @@ class _LeaveBalanceState extends State<LeaveBalance> {
void getAbsenceTransactions() async { void getAbsenceTransactions() async {
try { try {
Utils.showLoading(context); // Utils.showLoading(context);
absenceTransList = await LeaveBalanceApiClient().getAbsenceTransactions(-999); absenceTransList = await LeaveBalanceApiClient().getAbsenceTransactions(-999, empID: selectedEmp);
Utils.hideLoading(context); //Utils.hideLoading(context);
setState(() {}); setState(() {});
} catch (ex) { } catch (ex) {
Utils.hideLoading(context); Utils.hideLoading(context);
@ -52,6 +55,16 @@ class _LeaveBalanceState extends State<LeaveBalance> {
@override @override
Widget build(BuildContext context) { 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( return Scaffold(
backgroundColor: Colors.white, backgroundColor: Colors.white,
appBar: AppBarWidget( appBar: AppBarWidget(
@ -62,7 +75,7 @@ class _LeaveBalanceState extends State<LeaveBalance> {
physics: const BouncingScrollPhysics(), physics: const BouncingScrollPhysics(),
padding: const EdgeInsets.all(21), padding: const EdgeInsets.all(21),
children: [ children: [
BalancesDashboardWidget(LocaleKeys.currentLeaveBalance.tr(), true), BalancesDashboardWidget(LocaleKeys.currentLeaveBalance.tr(), true, selectedEmp),
12.height, 12.height,
absenceTransList == null absenceTransList == null
? const SizedBox() ? const SizedBox()
@ -111,7 +124,7 @@ class _LeaveBalanceState extends State<LeaveBalance> {
), ),
child: const Icon(Icons.add, color: Colors.white, size: 30), child: const Icon(Icons.add, color: Colors.white, size: 30),
).onPress(() { ).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/models/privilege_list_model.dart';
import 'package:mohem_flutter_app/widgets/button/default_button.dart'; import 'package:mohem_flutter_app/widgets/button/default_button.dart';
import 'package:mohem_flutter_app/widgets/input_widget.dart'; import 'package:mohem_flutter_app/widgets/input_widget.dart';
import 'package:safe_device/safe_device.dart';
class LoginScreen extends StatefulWidget { class LoginScreen extends StatefulWidget {
LoginScreen({Key? key}) : super(key: key); LoginScreen({Key? key}) : super(key: key);
@ -48,10 +49,34 @@ class _LoginScreenState extends State<LoginScreen> {
bool? isAppOpenBySystem; bool? isAppOpenBySystem;
bool isJailBroken = false;
bool isRealDevice = false;
bool isOnExternalStorage = false;
bool isDevelopmentModeEnable = false;
@override @override
void initState() { void initState() {
super.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 @override
@ -68,8 +93,7 @@ class _LoginScreenState extends State<LoginScreen> {
await Firebase.initializeApp(); await Firebase.initializeApp();
_firebaseMessaging = FirebaseMessaging.instance; _firebaseMessaging = FirebaseMessaging.instance;
firebaseToken = await _firebaseMessaging.getToken(); firebaseToken = await _firebaseMessaging.getToken();
loginInfo = await LoginApiClient().getMobileLoginInfoNEW( loginInfo = await LoginApiClient().getMobileLoginInfoNEW(firebaseToken ?? "", Platform.isAndroid ? "android" : "ios");
firebaseToken ?? "", Platform.isAndroid ? "android" : "ios");
if (loginInfo == null) { if (loginInfo == null) {
Utils.hideLoading(context); Utils.hideLoading(context);
return; return;
@ -86,11 +110,9 @@ class _LoginScreenState extends State<LoginScreen> {
} }
Future<void> checkPrefs() async { Future<void> checkPrefs() async {
String username = String username = await Utils.getStringFromPrefs(SharedPrefsConsts.username);
await Utils.getStringFromPrefs(SharedPrefsConsts.username);
if (username.isNotEmpty) { if (username.isNotEmpty) {
String password = String password = await Utils.getStringFromPrefs(SharedPrefsConsts.password);
await Utils.getStringFromPrefs(SharedPrefsConsts.password);
// String firebaseToken = await Utils.getStringFromPrefs(SharedPrefsConsts.firebaseToken); // String firebaseToken = await Utils.getStringFromPrefs(SharedPrefsConsts.firebaseToken);
// print("firebaseToken:$firebaseToken"); // print("firebaseToken:$firebaseToken");
this.username.text = username; this.username.text = username;
@ -103,30 +125,23 @@ class _LoginScreenState extends State<LoginScreen> {
Utils.showLoading(context); Utils.showLoading(context);
try { try {
_checkMobileAppVersion = await LoginApiClient().checkMobileAppVersion(); _checkMobileAppVersion = await LoginApiClient().checkMobileAppVersion();
_memberLoginList = _memberLoginList = await LoginApiClient().memberLogin(username.text, password.text);
await LoginApiClient().memberLogin(username.text, password.text);
AppState().setMemberLoginListModel = _memberLoginList; AppState().setMemberLoginListModel = _memberLoginList;
AppState().setUserName = username.text; AppState().setUserName = username.text;
AppState().password = password.text; AppState().password = password.text;
if (_autoLogin) { if (_autoLogin) {
AppState().setMemberInformationListModel = AppState().setMemberInformationListModel = (await MemberInformationListModel.getFromPrefs()).first;
(await MemberInformationListModel.getFromPrefs()).first; AppState().setPrivilegeListModel = await PrivilegeListModel.getFromPrefs();
AppState().setPrivilegeListModel = String mohemmWifiSSID = await Utils.getStringFromPrefs(SharedPrefsConsts.mohemmWifiSSID);
await PrivilegeListModel.getFromPrefs(); String mohemmWifiPassword = await Utils.getStringFromPrefs(SharedPrefsConsts.mohemmWifiPassword);
String mohemmWifiSSID =
await Utils.getStringFromPrefs(SharedPrefsConsts.mohemmWifiSSID);
String mohemmWifiPassword = await Utils.getStringFromPrefs(
SharedPrefsConsts.mohemmWifiPassword);
AppState().setMohemmWifiSSID = mohemmWifiSSID; AppState().setMohemmWifiSSID = mohemmWifiSSID;
AppState().setMohemmWifiPassword = mohemmWifiPassword; AppState().setMohemmWifiPassword = mohemmWifiPassword;
} }
Utils.hideLoading(context); Utils.hideLoading(context);
if (_autoLogin) { if (_autoLogin) {
Navigator.pushReplacementNamed(context, AppRoutes.verifyLastLogin, Navigator.pushReplacementNamed(context, AppRoutes.verifyLastLogin, arguments: loginInfo);
arguments: loginInfo);
} else { } else {
Navigator.pushNamed(context, AppRoutes.verifyLogin, Navigator.pushNamed(context, AppRoutes.verifyLogin, arguments: "$firebaseToken");
arguments: "$firebaseToken");
} }
Utils.saveStringFromPrefs(SharedPrefsConsts.password, password.text); Utils.saveStringFromPrefs(SharedPrefsConsts.password, password.text);
} catch (ex) { } catch (ex) {
@ -169,13 +184,7 @@ class _LoginScreenState extends State<LoginScreen> {
Expanded(child: SizedBox()), Expanded(child: SizedBox()),
Row( Row(
children: [ children: [
LocaleKeys.english LocaleKeys.english.tr().toText14(color: AppState().isArabic(context) ? null : MyColors.textMixColor).onPress(() {
.tr()
.toText14(
color: AppState().isArabic(context)
? null
: MyColors.textMixColor)
.onPress(() {
context.setLocale(const Locale("en", "US")); context.setLocale(const Locale("en", "US"));
}), }),
Container( Container(
@ -184,13 +193,7 @@ class _LoginScreenState extends State<LoginScreen> {
height: 16, height: 16,
margin: const EdgeInsets.only(left: 10, right: 10), margin: const EdgeInsets.only(left: 10, right: 10),
), ),
LocaleKeys.arabic LocaleKeys.arabic.tr().toText14(color: !AppState().isArabic(context) ? null : MyColors.textMixColor).onPress(() {
.tr()
.toText14(
color: !AppState().isArabic(context)
? null
: MyColors.textMixColor)
.onPress(() {
context.setLocale(const Locale("ar", "SA")); context.setLocale(const Locale("ar", "SA"));
}), }),
], ],
@ -206,23 +209,14 @@ class _LoginScreenState extends State<LoginScreen> {
LocaleKeys.login.tr().toText24(isBold: true), LocaleKeys.login.tr().toText24(isBold: true),
LocaleKeys.pleaseEnterLoginDetails.tr().toText16(), LocaleKeys.pleaseEnterLoginDetails.tr().toText16(),
16.height, 16.height,
InputWidget( InputWidget(LocaleKeys.username.tr(), "123456", username),
LocaleKeys.username.tr(), "123456", username),
12.height, 12.height,
InputWidget( InputWidget(LocaleKeys.password.tr(), "xxxxxx", password, isTextIsPassword: true),
LocaleKeys.password.tr(), "xxxxxx", password,
isTextIsPassword: true),
9.height, 9.height,
Align( Align(
alignment: Alignment.centerRight, alignment: Alignment.centerRight,
child: LocaleKeys.forgotPassword child: LocaleKeys.forgotPassword.tr().toText12(isUnderLine: true, color: MyColors.textMixColor).onPress(() {
.tr() Navigator.pushNamed(context, AppRoutes.forgotPassword);
.toText12(
isUnderLine: true,
color: MyColors.textMixColor)
.onPress(() {
Navigator.pushNamed(
context, AppRoutes.forgotPassword);
}), }),
), ),
], ],

@ -9,6 +9,7 @@ import 'package:mohem_flutter_app/classes/utils.dart';
import 'package:mohem_flutter_app/config/routes.dart'; import 'package:mohem_flutter_app/config/routes.dart';
import 'package:mohem_flutter_app/models/marathon/marathon_model.dart'; import 'package:mohem_flutter_app/models/marathon/marathon_model.dart';
import 'package:mohem_flutter_app/models/marathon/question_model.dart'; import 'package:mohem_flutter_app/models/marathon/question_model.dart';
import 'package:mohem_flutter_app/models/marathon/winner_model.dart';
import 'package:mohem_flutter_app/ui/marathon/widgets/question_card.dart'; import 'package:mohem_flutter_app/ui/marathon/widgets/question_card.dart';
import 'package:video_player/video_player.dart'; import 'package:video_player/video_player.dart';
@ -22,10 +23,10 @@ class MarathonProvider extends ChangeNotifier {
QuestionModel currentQuestion = QuestionModel(); QuestionModel currentQuestion = QuestionModel();
List<QuestionCardStatus> answerStatusesList = <QuestionCardStatus>[]; List<QuestionCardStatus> answerStatusesList = <QuestionCardStatus>[];
QuestionCardStatus questionCardStatus = QuestionCardStatus.question; QuestionCardStatus questionCardStatus = QuestionCardStatus.question;
List<WinnerModel>? selectedWinners;
int? selectedOptionIndex; int? selectedOptionIndex;
String? selectedOptionId; String? selectedOptionId;
int totalQualifiers = 0; int? totalQualifiers;
bool _isLoading = false; bool _isLoading = false;
@ -110,6 +111,7 @@ class MarathonProvider extends ChangeNotifier {
//****************TIMERS********** //****************TIMERS**********
int sponsorsSecondsCounter = 0;
int totalSponsorVideoSeconds = 0; int totalSponsorVideoSeconds = 0;
Timer timerForSponsorVideo = Timer.periodic(const Duration(seconds: 1), (Timer timer) {}); Timer timerForSponsorVideo = Timer.periodic(const Duration(seconds: 1), (Timer timer) {});
@ -118,6 +120,7 @@ class MarathonProvider extends ChangeNotifier {
timerForSponsorVideo = Timer.periodic( timerForSponsorVideo = Timer.periodic(
oneSec, oneSec,
(Timer timer) async { (Timer timer) async {
sponsorsSecondsCounter++;
if (totalSponsorVideoSeconds == 0) { if (totalSponsorVideoSeconds == 0) {
timer.cancel(); timer.cancel();
notifyListeners(); notifyListeners();
@ -134,12 +137,15 @@ class MarathonProvider extends ChangeNotifier {
int totalSecondsToWaitForMarathon = 20; int totalSecondsToWaitForMarathon = 20;
Timer timerToWaitForMarathon = Timer.periodic(const Duration(seconds: 1), (Timer timer) {}); Timer timerToWaitForMarathon = Timer.periodic(const Duration(seconds: 1), (Timer timer) {});
void startTimerToMarathon(BuildContext context) { void startTimerToWaitForMarathon() {
const Duration oneSec = Duration(seconds: 1); const Duration oneSec = Duration(seconds: 1);
timerToWaitForMarathon = Timer.periodic( timerToWaitForMarathon = Timer.periodic(
oneSec, oneSec,
(Timer timer) async { (Timer timer) async {
if (totalSecondsToWaitForMarathon == 0) { if (totalSecondsToWaitForMarathon == 0) {
callNextQuestionApi();
timer.cancel();
return;
} else { } else {
totalSecondsToWaitForMarathon--; totalSecondsToWaitForMarathon--;
} }
@ -163,6 +169,8 @@ class MarathonProvider extends ChangeNotifier {
} }
if (totalCurrentQuestionTime == currentGapTime) { if (totalCurrentQuestionTime == currentGapTime) {
totalCurrentQuestionTime--;
updateCardStatusToAnswer(); updateCardStatusToAnswer();
await callSubmitOptionApi().then((bool value) async { await callSubmitOptionApi().then((bool value) async {
@ -175,6 +183,7 @@ class MarathonProvider extends ChangeNotifier {
if (totalCurrentQuestionTime == 0) { if (totalCurrentQuestionTime == 0) {
updateCardData(); updateCardData();
if (currentQuestionNumber == marathonDetailModel.totalQuestions! - 1) { if (currentQuestionNumber == marathonDetailModel.totalQuestions! - 1) {
callGetQualifiersApi();
updateQuestionCardStatus(QuestionCardStatus.findingWinner); updateQuestionCardStatus(QuestionCardStatus.findingWinner);
timer.cancel(); timer.cancel();
cancelTimer(); cancelTimer();
@ -182,7 +191,9 @@ class MarathonProvider extends ChangeNotifier {
} }
return; return;
} else { } else {
totalCurrentQuestionTime--; if (totalCurrentQuestionTime != currentGapTime) {
totalCurrentQuestionTime--;
}
} }
notifyListeners(); notifyListeners();
@ -214,7 +225,17 @@ class MarathonProvider extends ChangeNotifier {
//****************FUNCTIONS********* //****************FUNCTIONS*********
Future<bool> callSubmitOptionApi() async { Future<bool> callSubmitOptionApi() async {
return await MarathonApiClient().submitSelectedOption(selectedAnswerId: selectedOptionId); return await MarathonApiClient().submitSelectedOption(marathonId: marathonDetailModel.id!, questionId: currentQuestion.id, selectedAnswerId: selectedOptionId);
}
Future<void> callGetQualifiersApi() async {
totalQualifiers = await MarathonApiClient().getQualifiers(marathonId: marathonDetailModel.id!);
notifyListeners();
}
Future<void> callGetSelectedWinnersApi() async {
selectedWinners = await MarathonApiClient().getSelectedWinner(marathonId: marathonDetailModel.id!);
notifyListeners();
} }
// TODO: here I need to add a logic where I should call this function for Api but for the 1st question it should behave differently // TODO: here I need to add a logic where I should call this function for Api but for the 1st question it should behave differently
@ -222,6 +243,7 @@ class MarathonProvider extends ChangeNotifier {
Future<void> callNextQuestionApi() async { Future<void> callNextQuestionApi() async {
if (currentQuestionNumber < marathonDetailModel.totalQuestions!) { if (currentQuestionNumber < marathonDetailModel.totalQuestions!) {
if (currentQuestionNumber == 0) { if (currentQuestionNumber == 0) {
Utils.showLoading(AppRoutes.navigatorKey.currentContext!);
currentQuestion = (await MarathonApiClient().getNextQuestion(questionId: null, marathonId: marathonDetailModel.id!))!; currentQuestion = (await MarathonApiClient().getNextQuestion(questionId: null, marathonId: marathonDetailModel.id!))!;
if (Utils.isLoading) { if (Utils.isLoading) {
Utils.hideLoading(AppRoutes.navigatorKey.currentContext!); Utils.hideLoading(AppRoutes.navigatorKey.currentContext!);
@ -239,8 +261,7 @@ class MarathonProvider extends ChangeNotifier {
void updateCardData() { void updateCardData() {
if (currentQuestionNumber > 0) { if (currentQuestionNumber > 0) {
print("swiped it away!!"); swiperController.swipeLeft();
swipeCardLeft();
} }
selectedOptionIndex = null; selectedOptionIndex = null;
currentQuestionNumber++; currentQuestionNumber++;
@ -249,6 +270,7 @@ class MarathonProvider extends ChangeNotifier {
currentGapTime = currentQuestion.nextQuestGap!; currentGapTime = currentQuestion.nextQuestGap!;
totalMarathoners = currentQuestion.remainingParticipantCount!; totalMarathoners = currentQuestion.remainingParticipantCount!;
questionCardStatus = QuestionCardStatus.question; questionCardStatus = QuestionCardStatus.question;
notifyListeners();
} }
void populateQuestionStatusesList() { void populateQuestionStatusesList() {
@ -316,20 +338,21 @@ class MarathonProvider extends ChangeNotifier {
} }
} }
void swipeCardLeft() {
swiperController.swipeLeft();
notifyListeners();
}
void resetValues() async { void resetValues() async {
_currentQuestionNumber = 0; _currentQuestionNumber = 0;
cardContentList.clear(); cardContentList.clear();
timerForWinnerSelection.cancel(); timerForWinnerSelection.cancel();
timerForSponsorVideo.cancel();
timerToWaitForMarathon.cancel();
timerForQuestion.cancel(); timerForQuestion.cancel();
_isMarathonCompleted = false; _isMarathonCompleted = false;
isUserOutOfGame = false;
totalCurrentQuestionTime = 0; totalCurrentQuestionTime = 0;
sponsorsSecondsCounter = 0;
totalSponsorVideoSeconds = 0;
totalSecondsToWaitForMarathon = 20;
currentGapTime = 0;
currentQuestion = QuestionModel(); currentQuestion = QuestionModel();
notifyListeners(); notifyListeners();
} }
@ -354,40 +377,23 @@ class MarathonProvider extends ChangeNotifier {
}); });
} }
Future<void> buildConnectionWithSignalR(BuildContext context) async { Future<void> onJoinMarathonPressed(BuildContext context) async {
Utils.showLoading(context);
try { try {
Utils.showLoading(context);
resetValues(); resetValues();
// await MarathonApiClient().buildHubConnection(context, marathonDetailModel.sponsors!.first.sponsorPrizes!.first.id!); int? remainingTime = await MarathonApiClient().joinMarathonAsParticipant();
if (remainingTime != null) {
totalSecondsToWaitForMarathon = remainingTime;
notifyListeners();
startTimerToWaitForMarathon();
Navigator.pushReplacementNamed(context, AppRoutes.marathonWaitingScreen);
}
} catch (e) { } catch (e) {
if (kDebugMode) { if (kDebugMode) {
print("error in buildConnectionWithSignalR: ${e.toString()}"); print("error in onJoinMarathonPressed: ${e.toString()}");
} }
Utils.hideLoading(context); Utils.hideLoading(context);
Utils.confirmDialog(context, e.toString()); Utils.confirmDialog(context, e.toString());
} }
} }
Future<void> onJoinMarathonPressed(BuildContext context) async {
//TODO: here we need to put a check to make sure we should not display sponsor when remaining time to marathon is less than 30 seconds plus video duration e.g. 30 seconds + video duration time
// if (marathonDetailModel.sponsors!.first.video != null && marathonDetailModel.sponsors!.first.video != "") {
if (false) {
await initializeVideoPlayer().then((_) {
startTimerForSponsorVideo();
Navigator.pushNamed(context, AppRoutes.marathonSponsorVideoScreen);
});
} else {
try {
Utils.showLoading(context);
bool isJoined = await MarathonApiClient().joinMarathonAsParticipant();
if (isJoined) {
print("joined");
callNextQuestionApi();
}
} catch (e, s) {
Utils.hideLoading(context);
Utils.confirmDialog(context, e.toString());
}
}
}
} }

@ -8,7 +8,7 @@ import 'package:mohem_flutter_app/app_state/app_state.dart';
import 'package:mohem_flutter_app/classes/colors.dart'; import 'package:mohem_flutter_app/classes/colors.dart';
import 'package:mohem_flutter_app/classes/decorations_helper.dart'; import 'package:mohem_flutter_app/classes/decorations_helper.dart';
import 'package:mohem_flutter_app/classes/lottie_consts.dart'; import 'package:mohem_flutter_app/classes/lottie_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/int_extensions.dart';
import 'package:mohem_flutter_app/extensions/string_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/extensions/widget_extensions.dart';
@ -21,6 +21,7 @@ import 'package:mohem_flutter_app/ui/marathon/widgets/marathon_qualifiers_contai
import 'package:mohem_flutter_app/ui/marathon/widgets/question_card.dart'; import 'package:mohem_flutter_app/ui/marathon/widgets/question_card.dart';
import 'package:mohem_flutter_app/ui/marathon/widgets/question_card_builder.dart'; import 'package:mohem_flutter_app/ui/marathon/widgets/question_card_builder.dart';
import 'package:mohem_flutter_app/widgets/app_bar_widget.dart'; import 'package:mohem_flutter_app/widgets/app_bar_widget.dart';
import 'package:mohem_flutter_app/widgets/dialogs/confirm_dialog.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
class MarathonScreen extends StatelessWidget { class MarathonScreen extends StatelessWidget {
@ -63,22 +64,28 @@ class MarathonScreen extends StatelessWidget {
SizedBox( SizedBox(
height: 50, height: 50,
child: Stack( child: Stack(
children: [ children: <Widget>[
Align( Align(
alignment: Alignment.center, alignment: Alignment.center,
child: SvgPicture.asset("assets/images/winner_ribbon.svg", height: 50), child: SvgPicture.asset("assets/images/winner_ribbon.svg", height: 50),
), ),
Align( Align(
alignment: Alignment.center, alignment: Alignment.center,
child: LocaleKeys.winner.tr().toText32(color: MyColors.white, isBold: true).paddingOnly(top: 07), child: LocaleKeys.winner.tr().toText32(color: MyColors.white, isBold: true, isCentered: true).paddingOnly(top: 07),
) )
], ],
), ),
), ),
12.height, 12.height,
"Muhammad Shrouff".toText22(color: MyColors.grey3AColor), if (provider.selectedWinners != null) ...<Widget>[
"837436".toText22(color: MyColors.grey57Color), (AppState().isArabic(context) ? provider.selectedWinners!.first.nameEn : provider.selectedWinners!.first.nameEn)!.toText22(
80.height, color: MyColors.grey3AColor,
isCentered: true,
),
8.height,
provider.selectedWinners!.first.employeeId!.toText22(color: MyColors.grey57Color),
],
60.height,
if (provider.marathonDetailModel.sponsors != null && provider.marathonDetailModel.sponsors!.isNotEmpty) ...<Widget>[ if (provider.marathonDetailModel.sponsors != null && provider.marathonDetailModel.sponsors!.isNotEmpty) ...<Widget>[
Row( Row(
mainAxisAlignment: MainAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center,
@ -118,12 +125,12 @@ class MarathonScreen extends StatelessWidget {
child: Row( child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween, mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[ children: <Widget>[
(AppState().isArabic(context) ? AppState().memberInformationList!.eMPLOYEEDISPLAYNAMEEn! : AppState().memberInformationList!.eMPLOYEEDISPLAYNAMEAr!) (AppState().isArabic(context) ? AppState().memberInformationList!.eMPLOYEEDISPLAYNAMEAr! : AppState().memberInformationList!.eMPLOYEEDISPLAYNAMEEn!)
.toText17(isBold: true, color: MyColors.white), .toText17(isBold: true, color: MyColors.white),
AppState().memberInformationList!.eMPLOYEENUMBER!.toText17(isBold: true, color: MyColors.white), AppState().memberInformationList!.eMPLOYEENUMBER!.toText17(isBold: true, color: MyColors.white),
], ],
), ),
).paddingOnly(left: 20, right: 20, top: 12, bottom: 20); ).paddingOnly(left: 20, right: 20, top: 12, bottom: 10);
} }
@override @override
@ -135,10 +142,38 @@ class MarathonScreen extends StatelessWidget {
context, context,
title: LocaleKeys.brainMarathon.tr(), title: LocaleKeys.brainMarathon.tr(),
onHomeTapped: () { onHomeTapped: () {
Utils.confirmDialog(context, LocaleKeys.youWantToLeaveMarathon.tr()); if (provider.questionCardStatus == QuestionCardStatus.winnerFound) {
provider.resetValues();
Navigator.of(context).popUntil(ModalRoute.withName(AppRoutes.dashboard));
} else {
showDialog(
context: context,
builder: (BuildContext context) => ConfirmDialog(
message: LocaleKeys.youWantToLeaveMarathon.tr(),
onTap: () {
provider.resetValues();
Navigator.of(context).popUntil(ModalRoute.withName(AppRoutes.dashboard));
},
),
);
}
}, },
onBackTapped: () { onBackTapped: () {
Utils.confirmDialog(context, LocaleKeys.youWantToLeaveMarathon.tr()); if (provider.questionCardStatus == QuestionCardStatus.winnerFound) {
provider.resetValues();
Navigator.of(context).popUntil(ModalRoute.withName(AppRoutes.dashboard));
} else {
showDialog(
context: context,
builder: (BuildContext context) => ConfirmDialog(
message: LocaleKeys.youWantToLeaveMarathon.tr(),
onTap: () {
provider.resetValues();
Navigator.of(context).popUntil(ModalRoute.withName(AppRoutes.dashboard));
},
),
);
}
}, },
), ),
body: SingleChildScrollView( body: SingleChildScrollView(
@ -156,7 +191,7 @@ class MarathonScreen extends StatelessWidget {
getNameContainer(context), getNameContainer(context),
], ],
QuestionCardBuilder( QuestionCardBuilder(
onQuestion: (BuildContext context) => QuestionCard(provider: provider), onQuestion: (BuildContext context) => const QuestionCard(),
onCompleted: (BuildContext context) => CustomStatusWidget( onCompleted: (BuildContext context) => CustomStatusWidget(
asset: Lottie.asset(MyLottieConsts.allQuestions, height: 200), asset: Lottie.asset(MyLottieConsts.allQuestions, height: 200),
title: LocaleKeys.congrats.tr().toText22(color: MyColors.greenColor), title: LocaleKeys.congrats.tr().toText22(color: MyColors.greenColor),

@ -25,6 +25,9 @@ class SponsorVideoScreen extends StatelessWidget {
return WillPopScope( return WillPopScope(
onWillPop: () { onWillPop: () {
provider.videoController.dispose(); provider.videoController.dispose();
provider.sponsorsSecondsCounter = 0;
provider.totalSponsorVideoSeconds = 0;
provider.timerForSponsorVideo.cancel();
return Future<bool>.value(true); return Future<bool>.value(true);
}, },
child: Scaffold( child: Scaffold(
@ -52,9 +55,11 @@ class SponsorVideoScreen extends StatelessWidget {
child: provider.totalSponsorVideoSeconds == 0 child: provider.totalSponsorVideoSeconds == 0
? InkWell( ? InkWell(
onTap: () { onTap: () {
Navigator.pop(context);
provider.videoController.dispose(); provider.videoController.dispose();
provider.buildConnectionWithSignalR(AppRoutes.navigatorKey.currentState!.overlay!.context); provider.sponsorsSecondsCounter = 0;
provider.totalSponsorVideoSeconds = 0;
provider.timerForSponsorVideo.cancel();
Navigator.pushReplacementNamed(context, AppRoutes.marathonIntroScreen);
}, },
child: const Icon(Icons.close, size: 12), child: const Icon(Icons.close, size: 12),
) )
@ -64,24 +69,30 @@ class SponsorVideoScreen extends StatelessWidget {
), ),
), ),
).paddingOnly(top: 20, right: 18), ).paddingOnly(top: 20, right: 18),
Align(
alignment: Alignment.topLeft, //TODO: WE WILL INCREASE THIS 2 BEFORE GOING LIVE
child: InkWell( provider.sponsorsSecondsCounter >= 2
onTap: () { ? Align(
Navigator.pop(context); alignment: Alignment.topLeft,
provider.videoController.dispose(); child: InkWell(
provider.buildConnectionWithSignalR(AppRoutes.navigatorKey.currentState!.overlay!.context); onTap: () {
}, provider.videoController.dispose();
child: Container( provider.sponsorsSecondsCounter = 0;
decoration: BoxDecoration(color: MyColors.white, borderRadius: BorderRadius.circular(15)), provider.totalSponsorVideoSeconds = 0;
padding: const EdgeInsets.symmetric(vertical: 3, horizontal: 6), provider.timerForSponsorVideo.cancel();
child: Directionality( Navigator.pushReplacementNamed(context, AppRoutes.marathonIntroScreen);
textDirection: ui.TextDirection.ltr, },
child: LocaleKeys.skip.tr().toText11(color: MyColors.darkTextColor), child: Container(
), decoration: BoxDecoration(color: MyColors.white, borderRadius: BorderRadius.circular(15)),
), padding: const EdgeInsets.symmetric(vertical: 3, horizontal: 6),
), child: Directionality(
).paddingOnly(top: 20, left: 18), textDirection: ui.TextDirection.ltr,
child: LocaleKeys.skip.tr().toText11(color: MyColors.darkTextColor),
),
),
),
).paddingOnly(top: 20, left: 18)
: const SizedBox(),
], ],
), ),
), ),

@ -4,12 +4,13 @@ import 'package:lottie/lottie.dart';
import 'package:mohem_flutter_app/classes/colors.dart'; import 'package:mohem_flutter_app/classes/colors.dart';
import 'package:mohem_flutter_app/classes/decorations_helper.dart'; import 'package:mohem_flutter_app/classes/decorations_helper.dart';
import 'package:mohem_flutter_app/classes/lottie_consts.dart'; import 'package:mohem_flutter_app/classes/lottie_consts.dart';
import 'package:mohem_flutter_app/classes/utils.dart'; import 'package:mohem_flutter_app/config/routes.dart';
import 'package:mohem_flutter_app/extensions/string_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/extensions/widget_extensions.dart';
import 'package:mohem_flutter_app/generated/locale_keys.g.dart'; import 'package:mohem_flutter_app/generated/locale_keys.g.dart';
import 'package:mohem_flutter_app/ui/marathon/marathon_provider.dart'; import 'package:mohem_flutter_app/ui/marathon/marathon_provider.dart';
import 'package:mohem_flutter_app/widgets/app_bar_widget.dart'; import 'package:mohem_flutter_app/widgets/app_bar_widget.dart';
import 'package:mohem_flutter_app/widgets/dialogs/confirm_dialog.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
class MarathonWaitingScreen extends StatelessWidget { class MarathonWaitingScreen extends StatelessWidget {
@ -18,44 +19,90 @@ class MarathonWaitingScreen extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
MarathonProvider provider = context.watch<MarathonProvider>(); MarathonProvider provider = context.watch<MarathonProvider>();
return Scaffold( return WillPopScope(
appBar: AppBarWidget( onWillPop: () {
context, showDialog(
title: LocaleKeys.brainMarathon.tr(), context: context,
onHomeTapped: () { builder: (BuildContext context) => ConfirmDialog(
Utils.confirmDialog(context, LocaleKeys.youWantToLeaveMarathon.tr()); message: LocaleKeys.youWantToLeaveMarathon.tr(),
}, onTap: () {
onBackTapped: () { provider.resetValues();
Utils.confirmDialog(context, LocaleKeys.youWantToLeaveMarathon.tr()); Navigator.of(context).popUntil(ModalRoute.withName(AppRoutes.dashboard));
}, },
), ),
body: Column( );
crossAxisAlignment: CrossAxisAlignment.center, return Future<bool>.value(false);
mainAxisAlignment: MainAxisAlignment.center, },
children: <Widget>[ child: Scaffold(
Container( appBar: AppBarWidget(
width: double.infinity, context,
margin: const EdgeInsets.all(21), title: LocaleKeys.brainMarathon.tr(),
decoration: MyDecorations.shadowDecoration, onHomeTapped: () {
child: Stack( showDialog(
children: <Widget>[ context: context,
Align( builder: (BuildContext context) => ConfirmDialog(
child: Lottie.asset(MyLottieConsts.marathonWaiting, height: 200), message: LocaleKeys.youWantToLeaveMarathon.tr(),
), onTap: () {
Align( provider.resetValues();
child: Column( Navigator.of(context).popUntil(ModalRoute.withName(AppRoutes.dashboard));
mainAxisAlignment: MainAxisAlignment.center, },
children: <Widget>[ ),
LocaleKeys.startingIn.tr().toText16(), );
"00:${provider.totalSecondsToWaitForMarathon < 10 ? "0${provider.totalSecondsToWaitForMarathon}" : provider.totalSecondsToWaitForMarathon}" },
.toText18(color: provider.totalSecondsToWaitForMarathon < 5 ? MyColors.redColor : MyColors.black), onBackTapped: () {
], showDialog(
context: context,
builder: (BuildContext context) => ConfirmDialog(
message: LocaleKeys.youWantToLeaveMarathon.tr(),
onTap: () {
provider.resetValues();
Navigator.of(context).popUntil(ModalRoute.withName(AppRoutes.dashboard));
},
),
);
},
),
body: Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Container(
width: double.infinity,
margin: const EdgeInsets.all(21),
decoration: MyDecorations.shadowDecoration,
child: Stack(
children: <Widget>[
Align(
child: Lottie.asset(MyLottieConsts.marathonWaiting, height: 200),
),
Align(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
LocaleKeys.startingIn.tr().toText16(),
provider.totalSecondsToWaitForMarathon.toString().toText18(color: provider.totalSecondsToWaitForMarathon < 5 ? MyColors.redColor : MyColors.black),
],
),
),
Align(
child: Column(
mainAxisAlignment: MainAxisAlignment.end,
children: <Widget>[
InkWell(
onTap: () {
provider.callNextQuestionApi();
provider.timerToWaitForMarathon.cancel();
},
child: "Join Now".toText16(),
).paddingOnly(bottom: 20),
],
),
), ),
), ],
], ),
), ).expanded,
).expanded, ],
], ),
), ),
); );
} }

@ -1,90 +0,0 @@
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:lottie/lottie.dart';
import 'package:mohem_flutter_app/classes/colors.dart';
import 'package:mohem_flutter_app/classes/lottie_consts.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/ui/marathon/marathon_provider.dart';
import 'package:mohem_flutter_app/ui/marathon/widgets/custom_status_widget.dart';
import 'package:mohem_flutter_app/ui/marathon/widgets/marathon_qualifiers_container.dart';
import 'package:mohem_flutter_app/widgets/app_bar_widget.dart';
import 'package:provider/provider.dart';
class MarathonWinnerSelection extends StatelessWidget {
const MarathonWinnerSelection({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
MarathonProvider provider = context.read<MarathonProvider>();
return Scaffold(
appBar: AppBarWidget(context, title: LocaleKeys.brainMarathon.tr()),
body: SingleChildScrollView(
child: Column(
children: [
20.height,
QualifiersContainer(provider: provider,).paddingOnly(left: 21, right: 21),
12.height,
InkWell(
onTap: () {
Navigator.pushNamed(context, AppRoutes.marathonWinnerScreen);
},
child: Container(
height: 50,
decoration: BoxDecoration(
color: MyColors.greenColor,
borderRadius: BorderRadius.circular(15),
boxShadow: [
BoxShadow(
color: const Color(0xff000000).withOpacity(.05),
blurRadius: 26,
offset: const Offset(0, -3),
),
],
),
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 20),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
"Muhammad Shrouff".toText17(isBold: true, color: MyColors.white),
"837436".toText17(isBold: true, color: MyColors.white),
],
),
),
).paddingOnly(left: 20, right: 20),
),
CustomStatusWidget(
asset: Lottie.asset(
MyLottieConsts.winnerLottie,
height: 168,
),
title: Text(
LocaleKeys.fingersCrossed.tr(),
style: const TextStyle(
height: 27 / 27,
color: MyColors.greenColor,
fontSize: 27,
letterSpacing: -1.08,
fontWeight: FontWeight.w600,
),
),
subTitle: Text(
LocaleKeys.winnerSelectedRandomly.tr(),
textAlign: TextAlign.center,
style: const TextStyle(
color: MyColors.darkTextColor,
fontSize: 18,
letterSpacing: -0.72,
fontWeight: FontWeight.w600,
),
)).paddingOnly(left: 21, right: 21, top: 20, bottom: 20),
],
),
),
);
}
}

@ -8,6 +8,7 @@ import 'package:flutter_countdown_timer/current_remaining_time.dart';
import 'package:flutter_countdown_timer/flutter_countdown_timer.dart'; import 'package:flutter_countdown_timer/flutter_countdown_timer.dart';
import 'package:mohem_flutter_app/classes/colors.dart'; import 'package:mohem_flutter_app/classes/colors.dart';
import 'package:mohem_flutter_app/generated/locale_keys.g.dart'; import 'package:mohem_flutter_app/generated/locale_keys.g.dart';
import 'package:mohem_flutter_app/main.dart';
import 'package:mohem_flutter_app/ui/marathon/marathon_provider.dart'; import 'package:mohem_flutter_app/ui/marathon/marathon_provider.dart';
class BuildCountdownTimer extends StatelessWidget { class BuildCountdownTimer extends StatelessWidget {
@ -29,9 +30,10 @@ class BuildCountdownTimer extends StatelessWidget {
letterSpacing: -0.4, letterSpacing: -0.4,
); );
final TextStyle styleDigitHome = const TextStyle( final TextStyle styleDigitHome = TextStyle(
height: 22 / 27, height: 22 / 27,
color: MyColors.white, color: MyColors.white,
fontSize: isTablet ? 30 : 15,
fontStyle: FontStyle.italic, fontStyle: FontStyle.italic,
letterSpacing: -1.44, letterSpacing: -1.44,
fontWeight: FontWeight.bold, fontWeight: FontWeight.bold,
@ -53,6 +55,33 @@ class BuildCountdownTimer extends StatelessWidget {
fontWeight: FontWeight.bold, fontWeight: FontWeight.bold,
); );
Widget buildSeparator() {
return AutoSizeText(
" : ",
maxFontSize: 24,
minFontSize: 20,
style: screenFlag == 0 ? styleDigitHome : styleDigitMarathon,
);
}
Widget getTimeDigit(String text) {
return AutoSizeText(
text,
maxFontSize: 24,
minFontSize: 20,
style: screenFlag == 0 ? styleDigitHome : styleDigitMarathon,
);
}
Widget getTimeText(String text) {
return AutoSizeText(
text,
minFontSize: 7,
maxFontSize: 8,
style: screenFlag == 0 ? styleTextHome : styleTextMarathon,
);
}
Widget buildEmptyWidget() { Widget buildEmptyWidget() {
return Directionality( return Directionality(
textDirection: ui.TextDirection.ltr, textDirection: ui.TextDirection.ltr,
@ -63,70 +92,29 @@ class BuildCountdownTimer extends StatelessWidget {
children: <Widget>[ children: <Widget>[
Column( Column(
children: <Widget>[ children: <Widget>[
// todo @faiz: Make a separate method and pass string , so we can minimize code replication getTimeDigit("00"),
AutoSizeText( getTimeText(LocaleKeys.days.tr()),
"00",
maxFontSize: 24,
minFontSize: 20,
style: screenFlag == 0 ? styleDigitHome : styleDigitMarathon,
),
AutoSizeText(
LocaleKeys.days.tr(),
minFontSize: 7,
maxFontSize: 8,
style: screenFlag == 0 ? styleTextHome : styleTextMarathon,
),
], ],
), ),
buildSeparator(), buildSeparator(),
Column( Column(
children: <Widget>[ children: <Widget>[
AutoSizeText( getTimeDigit("00"),
"00", getTimeText(LocaleKeys.hours.tr()),
maxFontSize: 24,
minFontSize: 20,
style: screenFlag == 0 ? styleDigitHome : styleDigitMarathon,
),
AutoSizeText(
LocaleKeys.hours.tr(),
minFontSize: 7,
maxFontSize: 8,
style: screenFlag == 0 ? styleTextHome : styleTextMarathon,
),
], ],
), ),
buildSeparator(), buildSeparator(),
Column( Column(
children: <Widget>[ children: <Widget>[
AutoSizeText( getTimeDigit("00"),
"00", getTimeText(LocaleKeys.minutes.tr()),
maxFontSize: 24,
minFontSize: 20,
style: screenFlag == 0 ? styleDigitHome : styleDigitMarathon,
),
AutoSizeText(
LocaleKeys.minutes.tr(),
minFontSize: 7,
maxFontSize: 8,
style: screenFlag == 0 ? styleTextHome : styleTextMarathon,
),
], ],
), ),
buildSeparator(), buildSeparator(),
Column( Column(
children: <Widget>[ children: <Widget>[
AutoSizeText( getTimeDigit("00"),
"00", getTimeText(LocaleKeys.seconds.tr()),
maxFontSize: 24,
minFontSize: 20,
style: screenFlag == 0 ? styleDigitHome : styleDigitMarathon,
),
AutoSizeText(
LocaleKeys.seconds.tr(),
minFontSize: 7,
maxFontSize: 8,
style: screenFlag == 0 ? styleTextHome : styleTextMarathon,
),
], ],
), ),
], ],
@ -134,15 +122,6 @@ class BuildCountdownTimer extends StatelessWidget {
); );
} }
Widget buildSeparator() {
return AutoSizeText(
" : ",
maxFontSize: 24,
minFontSize: 20,
style: screenFlag == 0 ? styleDigitHome : styleDigitMarathon,
);
}
Widget buildCountdownTimer(CurrentRemainingTime? time) { Widget buildCountdownTimer(CurrentRemainingTime? time) {
if (time == null) { if (time == null) {
if (!provider.itsMarathonTime) { if (!provider.itsMarathonTime) {
@ -162,98 +141,29 @@ class BuildCountdownTimer extends StatelessWidget {
children: <Widget>[ children: <Widget>[
Column( Column(
children: <Widget>[ children: <Widget>[
// todo @faiz: Make a separate method and pass value and string , so we can minimize code replication time.days == null ? getTimeDigit("00") : getTimeDigit(time.days! < 10 ? "0${time.days.toString()}" : time.days.toString()),
time.days == null getTimeText(LocaleKeys.days.tr()),
? AutoSizeText(
"00",
maxFontSize: 24,
minFontSize: 20,
style: screenFlag == 0 ? styleDigitHome : styleDigitMarathon,
)
: AutoSizeText(
time.days! < 10 ? "0${time.days.toString()}" : time.days.toString(),
maxFontSize: 24,
minFontSize: 20,
style: screenFlag == 0 ? styleDigitHome : styleDigitMarathon,
),
AutoSizeText(
LocaleKeys.days.tr(),
minFontSize: 7,
maxFontSize: 8,
style: screenFlag == 0 ? styleTextHome : styleTextMarathon,
),
], ],
), ),
buildSeparator(), buildSeparator(),
Column( Column(
children: <Widget>[ children: <Widget>[
time.hours == null time.hours == null ? getTimeDigit("00") : getTimeDigit(time.hours! < 10 ? "0${time.hours.toString()}" : time.hours.toString()),
? AutoSizeText( getTimeText(LocaleKeys.hours.tr()),
"00",
maxFontSize: 24,
minFontSize: 20,
style: screenFlag == 0 ? styleDigitHome : styleDigitMarathon,
)
: AutoSizeText(
time.hours! < 10 ? "0${time.hours.toString()}" : time.hours.toString(),
maxFontSize: 24,
minFontSize: 20,
style: screenFlag == 0 ? styleDigitHome : styleDigitMarathon,
),
AutoSizeText(
LocaleKeys.hours.tr(),
minFontSize: 7,
maxFontSize: 8,
style: screenFlag == 0 ? styleTextHome : styleTextMarathon,
),
], ],
), ),
buildSeparator(), buildSeparator(),
Column( Column(
children: <Widget>[ children: <Widget>[
time.min == null time.min == null ? getTimeDigit("00") : getTimeDigit(time.min! < 10 ? "0${time.min.toString()}" : time.min.toString()),
? AutoSizeText( getTimeText(LocaleKeys.minutes.tr()),
"00",
maxFontSize: 24,
minFontSize: 20,
style: screenFlag == 0 ? styleDigitHome : styleDigitMarathon,
)
: AutoSizeText(
time.min! < 10 ? "0${time.min.toString()}" : time.min.toString(),
maxFontSize: 24,
minFontSize: 20,
style: screenFlag == 0 ? styleDigitHome : styleDigitMarathon,
),
AutoSizeText(
LocaleKeys.minutes.tr(),
minFontSize: 7,
maxFontSize: 8,
style: screenFlag == 0 ? styleTextHome : styleTextMarathon,
),
], ],
), ),
buildSeparator(), buildSeparator(),
Column( Column(
children: <Widget>[ children: <Widget>[
time.sec == null time.sec == null ? getTimeDigit("00") : getTimeDigit(time.sec! < 10 ? "0${time.sec.toString()}" : time.sec.toString()),
? AutoSizeText( getTimeText(LocaleKeys.seconds.tr()),
"00",
maxFontSize: 24,
minFontSize: 20,
style: screenFlag == 0 ? styleDigitHome : styleDigitMarathon,
)
: AutoSizeText(
time.sec! < 10 ? "0${time.sec.toString()}" : time.sec.toString(),
maxFontSize: 24,
minFontSize: 20,
style: screenFlag == 0 ? styleDigitHome : styleDigitMarathon,
),
AutoSizeText(
LocaleKeys.seconds.tr(),
minFontSize: 7,
maxFontSize: 8,
style: screenFlag == 0 ? styleTextHome : styleTextMarathon,
),
], ],
), ),
], ],

@ -1,16 +1,18 @@
import 'dart:math' as math; import 'dart:math' as math;
import 'package:auto_size_text/auto_size_text.dart';
import 'package:easy_localization/easy_localization.dart'; import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart'; import 'package:flutter_svg/flutter_svg.dart';
import 'package:mohem_flutter_app/app_state/app_state.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/colors.dart';
import 'package:mohem_flutter_app/classes/decorations_helper.dart'; import 'package:mohem_flutter_app/classes/decorations_helper.dart';
import 'package:mohem_flutter_app/classes/utils.dart';
import 'package:mohem_flutter_app/config/routes.dart'; import 'package:mohem_flutter_app/config/routes.dart';
import 'package:mohem_flutter_app/extensions/int_extensions.dart'; import 'package:mohem_flutter_app/extensions/int_extensions.dart';
import 'package:mohem_flutter_app/extensions/widget_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/generated/locale_keys.g.dart';
import 'package:mohem_flutter_app/main.dart';
import 'package:mohem_flutter_app/ui/marathon/marathon_provider.dart'; import 'package:mohem_flutter_app/ui/marathon/marathon_provider.dart';
import 'package:mohem_flutter_app/ui/marathon/widgets/countdown_timer.dart'; import 'package:mohem_flutter_app/ui/marathon/widgets/countdown_timer.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
@ -26,10 +28,10 @@ class MarathonBanner extends StatelessWidget {
return provider.marathonDetailModel.startTime != null return provider.marathonDetailModel.startTime != null
? Container( ? Container(
decoration: MyDecorations.shadowDecoration, decoration: MyDecorations.shadowDecoration,
height: MediaQuery.of(context).size.height * 0.11, height: isTablet ? MediaQuery.of(context).size.height * 0.17 : MediaQuery.of(context).size.height * 0.11,
clipBehavior: Clip.antiAlias, clipBehavior: Clip.antiAlias,
child: Stack( child: Stack(
children: [ children: <Widget>[
Transform( Transform(
alignment: Alignment.center, alignment: Alignment.center,
transform: Matrix4.rotationY( transform: Matrix4.rotationY(
@ -48,8 +50,8 @@ class MarathonBanner extends StatelessWidget {
child: Transform.rotate( child: Transform.rotate(
angle: 10, angle: 10,
child: Container( child: Container(
width: 65, width: isTablet ? 70 : 65,
height: 32, height: isTablet ? 40 : 32,
color: MyColors.darkDigitColor, color: MyColors.darkDigitColor,
), ),
), ),
@ -60,8 +62,8 @@ class MarathonBanner extends StatelessWidget {
child: Transform.rotate( child: Transform.rotate(
angle: 15, angle: 15,
child: Container( child: Container(
width: 65, width: isTablet ? 70 : 65,
height: 32, height: isTablet ? 40 : 32,
color: MyColors.darkDigitColor, color: MyColors.darkDigitColor,
), ),
), ),
@ -70,7 +72,7 @@ class MarathonBanner extends StatelessWidget {
width: double.infinity, width: double.infinity,
height: double.infinity, height: double.infinity,
child: Row( child: Row(
children: [ children: <Widget>[
const Expanded( const Expanded(
flex: 3, flex: 3,
child: SizedBox( child: SizedBox(
@ -92,28 +94,27 @@ class MarathonBanner extends StatelessWidget {
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
children: <Widget>[ children: <Widget>[
AppState().isArabic(context) ? 0.height : 5.height, AppState().isArabic(context) ? 0.height : 5.height,
AutoSizeText( Text(
LocaleKeys.getReadyForContest.tr(), LocaleKeys.getReadyForContest.tr(),
minFontSize: 08,
maxFontSize: 11,
style: TextStyle( style: TextStyle(
fontSize: isTablet ? 20 : 11,
fontStyle: FontStyle.italic, fontStyle: FontStyle.italic,
fontWeight: FontWeight.w600, fontWeight: FontWeight.w600,
color: MyColors.white.withOpacity(0.83), color: MyColors.white.withOpacity(0.83),
letterSpacing: -0.4, letterSpacing: -0.4,
), ),
), ),
AutoSizeText( Text(
AppState().isArabic(context) ? provider.marathonDetailModel.titleAr ?? "" : provider.marathonDetailModel.titleEn ?? "", AppState().isArabic(context) ? provider.marathonDetailModel.titleAr ?? "" : provider.marathonDetailModel.titleEn ?? "",
style: TextStyle( style: TextStyle(
fontStyle: FontStyle.italic, fontStyle: FontStyle.italic,
fontSize: 19, fontSize: isTablet ? 30 : 19,
fontWeight: FontWeight.bold, fontWeight: FontWeight.bold,
color: MyColors.white.withOpacity(0.83), color: MyColors.white.withOpacity(0.83),
height: 32 / 22, height: 32 / 22,
), ),
), ),
3.height, isTablet ? 10.height : 3.height,
BuildCountdownTimer( BuildCountdownTimer(
timeToMarathon: DateTime.parse(provider.marathonDetailModel.startTime!).millisecondsSinceEpoch, timeToMarathon: DateTime.parse(provider.marathonDetailModel.startTime!).millisecondsSinceEpoch,
provider: provider, provider: provider,
@ -135,18 +136,18 @@ class MarathonBanner extends StatelessWidget {
? Align( ? Align(
alignment: Alignment.topRight, alignment: Alignment.topRight,
child: SizedBox( child: SizedBox(
height: 20, height: isTablet ? 30 : 20,
width: 35, width: isTablet ? 45 : 35,
child: Transform.rotate( child: Transform.rotate(
angle: math.pi / 4.5, angle: math.pi / 4.5,
child: Text( child: Text(
LocaleKeys.brainMarathon.tr(), LocaleKeys.brainMarathon.tr(),
textAlign: TextAlign.center, textAlign: TextAlign.center,
maxLines: 2, maxLines: 2,
style: const TextStyle( style: TextStyle(
color: MyColors.white, color: MyColors.white,
fontWeight: FontWeight.bold, fontWeight: FontWeight.bold,
fontSize: 6, fontSize: isTablet ? 8 : 6,
height: 1.2, height: 1.2,
), ),
), ),
@ -156,18 +157,18 @@ class MarathonBanner extends StatelessWidget {
: Align( : Align(
alignment: Alignment.topLeft, alignment: Alignment.topLeft,
child: SizedBox( child: SizedBox(
height: 20, height: isTablet ? 30 : 20,
width: 35, width: isTablet ? 45 : 35,
child: Transform.rotate( child: Transform.rotate(
angle: -math.pi / 4.5, angle: -math.pi / 4.5,
child: Text( child: Text(
LocaleKeys.brainMarathon.tr(), LocaleKeys.brainMarathon.tr(),
textAlign: TextAlign.center, textAlign: TextAlign.center,
maxLines: 2, maxLines: 2,
style: const TextStyle( style: TextStyle(
color: MyColors.kWhiteColor, color: MyColors.kWhiteColor,
fontWeight: FontWeight.bold, fontWeight: FontWeight.bold,
fontSize: 6, fontSize: isTablet ? 8 : 6,
height: 1.2, height: 1.2,
), ),
), ),
@ -181,7 +182,7 @@ class MarathonBanner extends StatelessWidget {
child: RotatedBox( child: RotatedBox(
quarterTurns: 4, quarterTurns: 4,
child: SvgPicture.asset("assets/images/arrow_next.svg", color: MyColors.whiteColor), child: SvgPicture.asset("assets/images/arrow_next.svg", color: MyColors.whiteColor),
).paddingAll(15), ).paddingAll(isTablet ? 20 : 15),
) )
: Positioned( : Positioned(
bottom: 0, bottom: 0,
@ -189,12 +190,31 @@ class MarathonBanner extends StatelessWidget {
child: RotatedBox( child: RotatedBox(
quarterTurns: 2, quarterTurns: 2,
child: SvgPicture.asset("assets/images/arrow_next.svg", color: MyColors.whiteColor), child: SvgPicture.asset("assets/images/arrow_next.svg", color: MyColors.whiteColor),
).paddingAll(15), ).paddingAll(isTablet ? 20 : 15),
), ),
], ],
).onPress( ).onPress(() async {
() => Navigator.pushNamed(context, AppRoutes.marathonIntroScreen), int remainingTimeInMinutes = DateTime.parse(provider.marathonDetailModel.startTime!).difference(DateTime.now()).inMinutes;
),
if (remainingTimeInMinutes > 2) {
Utils.showLoading(context);
try {
await provider.initializeVideoPlayer().then((_) {
Utils.hideLoading(context);
provider.startTimerForSponsorVideo();
Navigator.pushNamed(context, AppRoutes.marathonSponsorVideoScreen);
});
} catch (e, s) {
if (kDebugMode) {
print("Error in VideoPlayer: ${e.toString()}");
}
Utils.hideLoading(context);
Navigator.pushNamed(context, AppRoutes.marathonIntroScreen);
}
} else {
Navigator.pushNamed(context, AppRoutes.marathonIntroScreen);
}
}),
) )
: const SizedBox(); : const SizedBox();
} }

@ -20,6 +20,7 @@ class _QualifiersContainerState extends State<QualifiersContainer> {
@override @override
void initState() { void initState() {
widget.provider.startTimerForWinnerSelection(); widget.provider.startTimerForWinnerSelection();
widget.provider.callGetSelectedWinnersApi();
super.initState(); super.initState();
} }
@ -36,13 +37,14 @@ class _QualifiersContainerState extends State<QualifiersContainer> {
mainAxisAlignment: MainAxisAlignment.spaceBetween, mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[ children: <Widget>[
LocaleKeys.winnerSelection.tr().toText21(color: MyColors.grey3AColor), LocaleKeys.winnerSelection.tr().toText21(color: MyColors.grey3AColor),
"00:${widget.provider.totalSecondsToWaitForWinner < 10 ? "0${widget.provider.totalSecondsToWaitForWinner}" : widget.provider.totalSecondsToWaitForWinner}".toText18(color: MyColors.redColor), "00:${widget.provider.totalSecondsToWaitForWinner < 10 ? "0${widget.provider.totalSecondsToWaitForWinner}" : widget.provider.totalSecondsToWaitForWinner}"
.toText18(color: MyColors.redColor),
], ],
), ),
10.height, 10.height,
Row( Row(
children: <Widget>[ children: <Widget>[
widget.provider.totalQualifiers.toString().toText30(color: MyColors.greenColor, isBold: true), widget.provider.totalQualifiers != null ? widget.provider.totalQualifiers.toString().toText30(color: MyColors.greenColor, isBold: true) : const SizedBox(),
2.width, 2.width,
LocaleKeys.qualifiers.tr().toText16(color: MyColors.greenColor), LocaleKeys.qualifiers.tr().toText16(color: MyColors.greenColor),
], ],

@ -1,4 +1,5 @@
import 'package:appinio_swiper/appinio_swiper.dart'; import 'package:appinio_swiper/appinio_swiper.dart';
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/cupertino.dart'; import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:lottie/lottie.dart'; import 'package:lottie/lottie.dart';
@ -6,38 +7,35 @@ import 'package:mohem_flutter_app/app_state/app_state.dart';
import 'package:mohem_flutter_app/classes/colors.dart'; import 'package:mohem_flutter_app/classes/colors.dart';
import 'package:mohem_flutter_app/classes/decorations_helper.dart'; import 'package:mohem_flutter_app/classes/decorations_helper.dart';
import 'package:mohem_flutter_app/classes/lottie_consts.dart'; import 'package:mohem_flutter_app/classes/lottie_consts.dart';
import 'package:mohem_flutter_app/classes/utils.dart';
import 'package:mohem_flutter_app/extensions/int_extensions.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/string_extensions.dart';
import 'package:mohem_flutter_app/extensions/widget_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/marathon/question_model.dart'; import 'package:mohem_flutter_app/models/marathon/question_model.dart';
import 'package:mohem_flutter_app/ui/marathon/marathon_provider.dart'; import 'package:mohem_flutter_app/ui/marathon/marathon_provider.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
class QuestionCard extends StatelessWidget { class QuestionCard extends StatelessWidget {
final MarathonProvider provider; const QuestionCard({Key? key}) : super(key: key);
const QuestionCard({Key? key, required this.provider}) : super(key: key);
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
MarathonProvider provider = context.read<MarathonProvider>();
return CupertinoPageScaffold( return CupertinoPageScaffold(
child: provider.cardContentList.isEmpty child: provider.cardContentList.isEmpty
? Lottie.asset(MyLottieConsts.hourGlassLottie, height: 250).paddingOnly(top: 50) ? Lottie.asset(MyLottieConsts.hourGlassLottie, height: 250).paddingOnly(top: 50)
: SizedBox( : SizedBox(
height: 440, height: 440,
width: double.infinity, width: double.infinity,
child: Consumer<MarathonProvider>( child: AppinioSwiper(
builder: (BuildContext context, MarathonProvider provider, _) { duration: const Duration(milliseconds: 400),
return AppinioSwiper( padding: EdgeInsets.zero,
duration: const Duration(milliseconds: 400), isDisabled: true,
padding: EdgeInsets.zero, controller: provider.swiperController,
isDisabled: true, unswipe: (int index, AppinioSwiperDirection direction) {},
controller: provider.swiperController, onSwipe: (int index, AppinioSwiperDirection direction) {},
unswipe: (int index, AppinioSwiperDirection direction) {}, cards: provider.cardContentList,
onSwipe: (int index, AppinioSwiperDirection direction) {},
cards: provider.cardContentList,
);
},
), ),
), ),
); );
@ -163,7 +161,7 @@ class AnswerTileForText extends StatelessWidget {
MarathonProvider provider = context.watch<MarathonProvider>(); MarathonProvider provider = context.watch<MarathonProvider>();
return InkWell( return InkWell(
onTap: () { onTap: () {
provider.isUserOutOfGame ? null : onAnswerTapped() ; provider.isUserOutOfGame ? Utils.showToast(LocaleKeys.youAreOutOfContest.tr()) : onAnswerTapped();
}, },
child: Container( child: Container(
alignment: Alignment.centerLeft, alignment: Alignment.centerLeft,

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

@ -50,18 +50,6 @@ class _DynamicInputScreenState extends State<DynamicInputScreen> {
descFlexConTextTitle = genericResponseModel!.pDESCFLEXCONTEXTNAME ?? ""; descFlexConTextTitle = genericResponseModel!.pDESCFLEXCONTEXTNAME ?? "";
getEitDffStructureList = genericResponseModel?.getEITDFFStructureList ?? []; getEitDffStructureList = genericResponseModel?.getEITDFFStructureList ?? [];
//getEitDffStructureList = getEitDffStructureList!.where((element) => element.dISPLAYFLAG != "N").toList(); //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); Utils.hideLoading(context);
setState(() {}); setState(() {});
} catch (ex) { } catch (ex) {
@ -108,11 +96,9 @@ class _DynamicInputScreenState extends State<DynamicInputScreen> {
SubmitEITTransactionList submitEITTransactionList = SubmitEITTransactionList submitEITTransactionList =
await MyAttendanceApiClient().submitEitTransaction(dESCFLEXCONTEXTCODE, dynamicParams!.dynamicId, values, empID: dynamicParams!.selectedEmp ?? ''); await MyAttendanceApiClient().submitEitTransaction(dESCFLEXCONTEXTCODE, dynamicParams!.dynamicId, values, empID: dynamicParams!.selectedEmp ?? '');
Utils.hideLoading(context); 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')); 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!); await LeaveBalanceApiClient().cancelHrTransaction(submitEITTransactionList.pTRANSACTIONID!);
Utils.hideLoading(context); Utils.hideLoading(context);
} catch (ex) { } catch (ex) {
@ -345,7 +331,7 @@ class _DynamicInputScreenState extends State<DynamicInputScreen> {
idColName = val; idColName = val;
if (getEitDffStructureList![j].fORMATTYPE == "X") { if (getEitDffStructureList![j].fORMATTYPE == "X") {
idColName = Utils.formatDateDefault(idColName!); idColName = Utils.formatDateNew(idColName!);
// commenting to test // commenting to test
// DateTime date = DateFormat('yyyy-MM-dd').parse(idColName!); // DateTime date = DateFormat('yyyy-MM-dd').parse(idColName!);
// idColName = DateFormat('yyyy-MM-dd HH:mm:ss').format(date); // idColName = DateFormat('yyyy-MM-dd HH:mm:ss').format(date);
@ -498,7 +484,7 @@ class _DynamicInputScreenState extends State<DynamicInputScreen> {
return DynamicTextFieldWidget( return DynamicTextFieldWidget(
(model.sEGMENTPROMPT ?? "") + (model.rEQUIREDFLAG == "Y" ? "*" : ""), (model.sEGMENTPROMPT ?? "") + (model.rEQUIREDFLAG == "Y" ? "*" : ""),
model.eSERVICESDV?.pIDCOLUMNNAME ?? "", model.eSERVICESDV?.pIDCOLUMNNAME ?? "",
// isReadOnly: model.rEADONLY == "Y", isReadOnly: model.rEADONLY == "Y",
isInputTypeNum: true, isInputTypeNum: true,
onChange: (text) { onChange: (text) {
model.fieldAnswer = text; model.fieldAnswer = text;
@ -635,7 +621,12 @@ class _DynamicInputScreenState extends State<DynamicInputScreen> {
).paddingOnly(bottom: 12), ).paddingOnly(bottom: 12),
itemBuilder: (_) => <PopupMenuItem<int>>[ itemBuilder: (_) => <PopupMenuItem<int>>[
if (model.rEADONLY != "Y") 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 { onSelected: (int popipIndex) async {
ESERVICESDV eservicesdv = ESERVICESDV( ESERVICESDV eservicesdv = ESERVICESDV(

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

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

@ -65,14 +65,14 @@ class _CreateRequestState extends State<CreateRequest> {
return menus; return menus;
} }
void handleOnPress(context, Menus menu) { void handleOnPress(context, Menus menu) {
if (menu.menuEntry.menuEntryType == "FUNCTION") { if (menu.menuEntry.menuEntryType == "FUNCTION") {
if (menu.menuEntry.requestType == "EIT") { 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 {}
} 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; return;
} }

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

@ -191,7 +191,8 @@ class _DynamicInputScreenState extends State<DynamicInputScreenAddress> {
], ],
onSelected: (int popupIndex) { onSelected: (int popupIndex) {
model?.getEmployeeAddressList!.sEGMENTVALUEDSP = model.eSERVICESVS![popupIndex].vALUECOLUMNNAME; 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(() {}); setState(() {});
}); });
} }
@ -282,7 +283,7 @@ class _DynamicInputScreenState extends State<DynamicInputScreenAddress> {
tempVar = e.getEmployeeAddressList!.sEGMENTVALUEDSP ?? ""; 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(); }).toList();
submitPhoneNumbers = await ProfileApiClient().submitAddressTransaction( submitPhoneNumbers = await ProfileApiClient().submitAddressTransaction(
@ -291,7 +292,7 @@ class _DynamicInputScreenState extends State<DynamicInputScreenAddress> {
values, values,
dynamicParams!.correctOrNew, dynamicParams!.correctOrNew,
countryCode, 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); print(values);
Utils.hideLoading(context); Utils.hideLoading(context);

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

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

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

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

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

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

@ -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( child: Row(
children: [ children: [
(workListData!.iTEMTYPE == "HRSSA" || workListData!.iTEMTYPE == "STAMP") ? myTab(LocaleKeys.details.tr(), 0) : myTab(LocaleKeys.request.tr(), 0), myTab(LocaleKeys.info.tr(), 0),
myTab(LocaleKeys.actions.tr(), 1), (workListData!.iTEMTYPE == "HRSSA" || workListData!.iTEMTYPE == "STAMP") ? myTab(LocaleKeys.details.tr(), 1) : myTab(LocaleKeys.request.tr(), 1),
myTab(LocaleKeys.info.tr(), 2), myTab(LocaleKeys.actions.tr(), 2),
myTab(LocaleKeys.attachments.tr(), 3), myTab(LocaleKeys.attachments.tr(), 3),
], ],
), ),
@ -249,6 +249,19 @@ class _WorkListDetailScreenState extends State<WorkListDetailScreen> {
}); });
}, },
children: [ 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") (workListData!.iTEMTYPE == "HRSSA" || workListData!.iTEMTYPE == "STAMP")
? DetailFragment(workListData, memberInformationListModel) ? DetailFragment(workListData, memberInformationListModel)
: RequestFragment( : RequestFragment(
@ -266,19 +279,6 @@ class _WorkListDetailScreenState extends State<WorkListDetailScreen> {
voidCallback: reloadWorkList, voidCallback: reloadWorkList,
) )
: showLoadingAnimation(), : 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 isAttachmentLoaded
? getAttachmentList.isEmpty ? getAttachmentList.isEmpty
? Utils.getNoDataWidget(context) ? Utils.getNoDataWidget(context)

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

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

@ -37,9 +37,9 @@ class ItemDetailViewCol extends StatelessWidget {
return Column( return Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
"$title:".toText12(isBold: true, color: const Color(0xff2BB8A6)), "$title:".toText12(isBold: true, color: const Color(0xff2BB8A6), maxLine: 2),
4.width, 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 video_player: ^2.4.7
just_audio: ^0.9.30 just_audio: ^0.9.30
safe_device: ^1.1.2
dev_dependencies: dev_dependencies:
flutter_test: flutter_test:

Loading…
Cancel
Save