Merge branch 'development_mirza' into 'main'

Development mirza

See merge request mirza.shafique/mohem_flutter_app!16
merge-requests/131/head
Mirza Shafique 4 years ago
commit d173da5b07

@ -23,6 +23,7 @@ if (flutterVersionName == null) {
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'com.google.gms.google-services'
apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"
android {
@ -43,8 +44,8 @@ android {
defaultConfig {
// TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
applicationId "com.mohem_flutter_app"
minSdkVersion 16
applicationId "hmg.cloudSolutions.mohem"
minSdkVersion 21
targetSdkVersion 30
versionCode flutterVersionCode.toInteger()
versionName flutterVersionName

@ -0,0 +1,40 @@
{
"project_info": {
"project_number": "679409052782",
"firebase_url": "https://mohemm-dce93.firebaseio.com",
"project_id": "mohemm-dce93",
"storage_bucket": "mohemm-dce93.appspot.com"
},
"client": [
{
"client_info": {
"mobilesdk_app_id": "1:679409052782:android:dba155ac0859d7fea78a7f",
"android_client_info": {
"package_name": "hmg.cloudSolutions.mohem"
}
},
"oauth_client": [
{
"client_id": "679409052782-mtd6d8rjltucnm9uatn6g7et08sm6lbv.apps.googleusercontent.com",
"client_type": 3
}
],
"api_key": [
{
"current_key": "AIzaSyDgWjuSBIKGghWxYg_KGBRIZTi-O_UA8mU"
}
],
"services": {
"appinvite_service": {
"other_platform_oauth_client": [
{
"client_id": "679409052782-mtd6d8rjltucnm9uatn6g7et08sm6lbv.apps.googleusercontent.com",
"client_type": 3
}
]
}
}
}
],
"configuration_version": "1"
}

@ -1,8 +1,12 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.mohem_flutter_app">
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.USE_BIOMETRIC"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.NFC"/>
<application
android:label="mohem_flutter_app"
android:label="Mohemm"
android:icon="@mipmap/ic_launcher">
<activity
android:name=".MainActivity"

@ -1,6 +1,17 @@
package com.mohem_flutter_app
import io.flutter.embedding.android.FlutterActivity
//import io.flutter.embedding.android.FlutterActivity
//
//class MainActivity: FlutterActivity() {
//}
class MainActivity: FlutterActivity() {
}
import io.flutter.embedding.android.FlutterFragmentActivity
import io.flutter.embedding.engine.FlutterEngine
import io.flutter.plugins.GeneratedPluginRegistrant
class MainActivity: FlutterFragmentActivity() {
override fun configureFlutterEngine(flutterEngine: FlutterEngine) {
GeneratedPluginRegistrant.registerWith(flutterEngine)
}
}

@ -8,6 +8,7 @@ buildscript {
dependencies {
classpath 'com.android.tools.build:gradle:7.0.3'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
classpath 'com.google.gms:google-services:4.3.8'
}
}

@ -0,0 +1,7 @@
<svg id="interview_3_" data-name="interview (3)" xmlns="http://www.w3.org/2000/svg" width="27.258" height="27.258" viewBox="0 0 27.258 27.258">
<path id="Path_4667" data-name="Path 4667" d="M7.663,248.55a4.22,4.22,0,1,0-5.175,0A5.07,5.07,0,0,0,0,252.918v1.711a.8.8,0,0,0,.8.8H9.352a.8.8,0,0,0,.8-.8v-1.711A5.07,5.07,0,0,0,7.663,248.55Zm-5.21-3.33a2.623,2.623,0,1,1,2.623,2.623A2.626,2.626,0,0,1,2.452,245.22Zm6.1,8.61H1.6v-.912a3.478,3.478,0,1,1,6.956,0v.912Zm0,0" transform="translate(0 -228.17)" fill="#989898"/>
<path id="Path_4668" data-name="Path 4668" d="M206.43,0H196.165A3.363,3.363,0,0,0,192.8,3.365v15.4a.8.8,0,0,0,1.278.639l3.208-2.406h9.143a3.363,3.363,0,0,0,3.365-3.365V3.365A3.363,3.363,0,0,0,206.43,0ZM208.2,13.629A1.766,1.766,0,0,1,206.43,15.4h-9.409a.8.8,0,0,0-.479.16L194.4,17.164V3.365A1.766,1.766,0,0,1,196.165,1.6H206.43A1.766,1.766,0,0,1,208.2,3.365Zm0,0" transform="translate(-182.536 0)" fill="#989898"/>
<path id="Path_4669" data-name="Path 4669" d="M266.419,80.332h-8.554a.8.8,0,1,0,0,1.6h8.554a.8.8,0,0,0,0-1.6Zm0,0" transform="translate(-243.381 -76.055)" fill="#989898"/>
<path id="Path_4670" data-name="Path 4670" d="M266.419,144.6h-8.554a.8.8,0,1,0,0,1.6h8.554a.8.8,0,0,0,0-1.6Zm0,0" transform="translate(-243.381 -136.903)" fill="#989898"/>
<path id="Path_4671" data-name="Path 4671" d="M262.142,208.867h-4.277a.8.8,0,1,0,0,1.6h4.277a.8.8,0,1,0,0-1.6Zm0,0" transform="translate(-243.381 -197.747)" fill="#989898"/>
</svg>

After

Width:  |  Height:  |  Size: 1.4 KiB

@ -0,0 +1,7 @@
<svg xmlns="http://www.w3.org/2000/svg" width="25.898" height="25.9" viewBox="0 0 25.898 25.9">
<g id="home_12_" data-name="home (12)" transform="translate(-0.022)">
<path id="Path_4683" data-name="Path 4683" d="M351.362.759A.759.759,0,0,0,350.6,0h-3.251a.759.759,0,0,0-.759.759v.687l4.769,4.769Z" transform="translate(-329.039 0)" fill="#2e303a"/>
<path id="Path_4684" data-name="Path 4684" d="M25.221,11.259,14.661.7A2.391,2.391,0,0,0,11.28.7L.721,11.26A2.391,2.391,0,1,0,4.1,14.641l8.869-8.869,8.869,8.869a2.375,2.375,0,0,0,1.69.7h0a2.391,2.391,0,0,0,1.691-4.081Z" fill="#2e303a"/>
<path id="Path_4685" data-name="Path 4685" d="M65.238,156.525l-7.8,7.8a3.878,3.878,0,0,1-2.369,1.125v6.271a2.794,2.794,0,0,0,2.791,2.791H62.8a.759.759,0,0,0,.759-.759v-5.743h3.359v5.743a.759.759,0,0,0,.759.759h4.935a2.794,2.794,0,0,0,2.791-2.791v-6.271a3.879,3.879,0,0,1-2.368-1.125Z" transform="translate(-52.267 -148.607)" fill="#2e303a"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 955 B

@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="25.974" height="24.23" viewBox="0 0 25.974 24.23">
<path id="shipping_2_" data-name="shipping (2)" d="M23.959,29.714V17.886a.764.764,0,0,0-.764-.764H2.724a.764.764,0,0,0-.764.764V30.657A2.294,2.294,0,0,0,.512,34.381l3.442,4.172c2.13,2.493,4.393,2.8,7.758,2.8a25.054,25.054,0,0,0,6.694-.561l2.45-.586a2.138,2.138,0,0,0,1.737.914H23.8a2.238,2.238,0,0,0,2.175-2.291V32A2.248,2.248,0,0,0,23.959,29.714Zm-3.434,1.572-1.018-.517a6.053,6.053,0,0,0-5.309-.086,7.3,7.3,0,0,1-2,.774H8.664a2.128,2.128,0,0,0-2.125,2.125v.557l-.02-.021L4,31.381a2.327,2.327,0,0,0-.508-.416v-7.58H9.741v2.8a.764.764,0,0,0,.764.764h4.821a.764.764,0,0,0,.764-.764v-2.8h6.341v6.329A2.2,2.2,0,0,0,20.525,31.286Zm-9.256-7.9h3.293v2.037H11.269Zm11.162-1.528H16.091V18.65h6.341v3.206ZM14.563,18.65v3.206H11.269V18.65Zm-4.821,0v3.206H3.488V18.65ZM18.05,39.3a24.308,24.308,0,0,1-6.312.511c-3.158,0-4.684-.051-6.606-2.235L1.691,33.408a.773.773,0,0,1,1.182-.993L5.4,35.154a3.469,3.469,0,0,0,2.54,1.113h6.994a.764.764,0,0,0,0-1.528H8.067V33.582a.6.6,0,0,1,.6-.6H12.2a6.994,6.994,0,0,0,2.645-.917,4.533,4.533,0,0,1,3.975.063l1.6.813v5.794Zm6.4-.477a.713.713,0,0,1-.647.763H22.592a.713.713,0,0,1-.647-.763V32a.713.713,0,0,1,.647-.763H23.8a.713.713,0,0,1,.647.763Z" transform="translate(0.001 -17.122)" fill="#989898"/>
</svg>

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

@ -0,0 +1,15 @@
<svg xmlns="http://www.w3.org/2000/svg" width="21.12" height="26.881" viewBox="0 0 21.12 26.881">
<g id="clipboard_5_" data-name="clipboard (5)" transform="translate(-47.037 0)">
<g id="Group_7687" data-name="Group 7687" transform="translate(47.037 0)">
<g id="Group_7686" data-name="Group 7686" transform="translate(0 0)">
<path id="Path_4672" data-name="Path 4672" d="M65.469,3.522H63.037V2.434c0-.352-.384-.512-.736-.512H60.413A2.862,2.862,0,0,0,57.565,0a2.912,2.912,0,0,0-2.848,1.92H52.861c-.352,0-.7.16-.7.512V3.522H49.725a2.72,2.72,0,0,0-2.688,2.592V24.45a2.575,2.575,0,0,0,2.688,2.432H65.469a2.575,2.575,0,0,0,2.688-2.432V6.114A2.72,2.72,0,0,0,65.469,3.522ZM53.437,3.2H55.2a.7.7,0,0,0,.608-.576,1.856,1.856,0,0,1,1.76-1.44,1.824,1.824,0,0,1,1.728,1.44.7.7,0,0,0,.64.576h1.824v2.56h-8.32ZM66.877,24.45A1.3,1.3,0,0,1,65.469,25.6H49.725a1.3,1.3,0,0,1-1.408-1.152V6.114A1.44,1.44,0,0,1,49.725,4.8h2.432V6.434a.672.672,0,0,0,.7.608H62.3a.7.7,0,0,0,.736-.608V4.8h2.432a1.44,1.44,0,0,1,1.408,1.312V24.45Z" transform="translate(-47.037 0)" fill="#989898"/>
<path id="Path_4673" data-name="Path 4673" d="M104.271,230.511a.64.64,0,0,0-.9-.032l-2.048,1.952-.864-.9a.64.64,0,0,0-.9-.032.672.672,0,0,0,0,.928l1.312,1.344a.576.576,0,0,0,.448.192.64.64,0,0,0,.448-.192l2.5-2.368a.608.608,0,0,0,.037-.859C104.3,230.535,104.283,230.523,104.271,230.511Z" transform="translate(-96.175 -216.205)" fill="#989898"/>
<path id="Path_4674" data-name="Path 4674" d="M206.548,256.034h-7.36a.64.64,0,0,0,0,1.28h7.36a.64.64,0,1,0,0-1.28Z" transform="translate(-189.268 -240.352)" fill="#989898"/>
<path id="Path_4675" data-name="Path 4675" d="M104.271,146.919a.64.64,0,0,0-.9-.032l-2.048,1.952-.864-.9a.64.64,0,0,0-.9-.032.672.672,0,0,0,0,.928l1.312,1.344a.576.576,0,0,0,.448.192.64.64,0,0,0,.448-.192l2.5-2.368a.608.608,0,0,0,.037-.859C104.3,146.943,104.283,146.931,104.271,146.919Z" transform="translate(-96.175 -137.733)" fill="#989898"/>
<path id="Path_4676" data-name="Path 4676" d="M206.548,172.442h-7.36a.64.64,0,0,0,0,1.28h7.36a.64.64,0,1,0,0-1.28Z" transform="translate(-189.268 -161.88)" fill="#989898"/>
<path id="Path_4677" data-name="Path 4677" d="M104.271,314.1a.64.64,0,0,0-.9-.032l-2.048,1.952-.864-.9a.64.64,0,0,0-.9-.032.672.672,0,0,0,0,.928l1.312,1.344a.576.576,0,0,0,.448.192.64.64,0,0,0,.448-.192l2.5-2.368a.608.608,0,0,0,.037-.859C104.3,314.126,104.283,314.114,104.271,314.1Z" transform="translate(-96.175 -294.677)" fill="#989898"/>
<path id="Path_4678" data-name="Path 4678" d="M206.548,339.626h-7.36a.64.64,0,0,0,0,1.28h7.36a.64.64,0,1,0,0-1.28Z" transform="translate(-189.268 -318.824)" fill="#989898"/>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.6 KiB

@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="21.655" height="24.033" viewBox="0 0 21.655 24.033">
<path id="Path_4726" data-name="Path 4726" d="M12.03.53C9.864-.713,8.107.305,8.107,2.8V21.229c0,2.5,1.757,3.516,3.923,2.275l16.106-9.237c2.167-1.243,2.167-3.258,0-4.5Z" transform="translate(-8.107 0)" fill="#fff"/>
</svg>

After

Width:  |  Height:  |  Size: 324 B

@ -0,0 +1,8 @@
<svg xmlns="http://www.w3.org/2000/svg" width="93.613" height="93.613" viewBox="0 0 93.613 93.613">
<g id="fingerprint-scan_1_" data-name="fingerprint-scan (1)" transform="translate(0 0)" opacity="0.049">
<path id="Path_4635" data-name="Path 4635" d="M243.282,223.494a2.743,2.743,0,0,0,2.743-2.742V207.5a2.743,2.743,0,1,0-5.485,0v13.255A2.743,2.743,0,0,0,243.282,223.494Z" transform="translate(-196.559 -167.317)" fill="#fff"/>
<path id="Path_4636" data-name="Path 4636" d="M167.739,215.135A2.743,2.743,0,0,0,165,217.877c0,11.945-8.538,21.664-19.032,21.664s-19.032-9.718-19.032-21.664V202.967a2.743,2.743,0,1,0-5.485,0v14.911c0,14.97,11,27.149,24.517,27.149s24.517-12.179,24.517-27.149A2.743,2.743,0,0,0,167.739,215.135Z" transform="translate(-99.243 -163.615)" fill="#fff"/>
<path id="Path_4637" data-name="Path 4637" d="M243.282,232.819c7.516,0,13.63-6.7,13.63-14.946V202.96a2.743,2.743,0,0,0-5.485,0v14.911c0,5.217-3.654,9.461-8.145,9.461a2.743,2.743,0,0,0,0,5.485Z" transform="translate(-196.559 -163.611)" fill="#fff"/>
<path id="Path_4638" data-name="Path 4638" d="M90.871,24.37H79.481a39.852,39.852,0,0,0-7.619-12.733A33.489,33.489,0,0,0,46.722,0,33.49,33.49,0,0,0,21.581,11.639a39.854,39.854,0,0,0-7.617,12.73H2.743a2.743,2.743,0,1,0,0,5.485h9.609a43.839,43.839,0,0,0-1.033,9.5V54.262A41.449,41.449,0,0,0,21.581,81.974,33.49,33.49,0,0,0,46.722,93.613,33.49,33.49,0,0,0,71.864,81.974,41.45,41.45,0,0,0,82.126,54.262V39.345a43.839,43.839,0,0,0-1.033-9.49h9.777a2.743,2.743,0,0,0,0-5.485ZM46.722,5.485c11.747,0,21.933,7.705,26.826,18.885H67.158C62.762,17.043,55.243,12.2,46.722,12.2a2.743,2.743,0,0,0,0,5.485A17.967,17.967,0,0,1,60.456,24.37H19.9C24.788,13.19,34.974,5.485,46.722,5.485ZM76.641,54.262c0,18.674-13.421,33.866-29.919,33.866S16.8,72.936,16.8,54.262V39.351a37.925,37.925,0,0,1,1.2-9.5H36.2a15.572,15.572,0,0,0-3.107,9.5V54.262a2.743,2.743,0,1,0,5.485,0V39.351c0-5.217,3.654-9.461,8.145-9.461l17.1-.035a24.013,24.013,0,0,1,1.929,9.493h0a2.743,2.743,0,0,0,5.485,0h0a29.615,29.615,0,0,0-1.549-9.492h5.752a37.927,37.927,0,0,1,1.2,9.491V54.262Z" fill="#fff"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.1 KiB

@ -48,12 +48,30 @@
"employeeId": "هوية الموظف",
"loginCodeWillSentToMobileNumber": "الرجاء إدخال معرف الموظف الخاص بك ، وسيتم إرسال رمز تسجيل الدخول إلى رقم هاتفك المحمول",
"changePassword": "تغيير كلمة المرور",
"ok": "موافق",
"confirm": "تؤكد",
"passwordChangedSuccessfully": "تم تغيير الرقم السري بنجاح",
"itemsForSale": "سلع للبيع",
"doNotUseRecentPassword": "لا تستخدم كلمة مرور حديثة",
"atLeastOneLowercase": "حرف صغير واحد على الأقل",
"atLeastOneUppercase": "حرف كبير واحد على الأقل",
"atLeastOneNumeric": "رقم واحد على الأقل",
"minimum8Characters": "8 أحرف على الأقل",
"doNotAddRepeatingLetters": "لا تقم بإضافة أحرف متكررة",
"itShouldContainSpecialCharacter": "يجب أن يحتوي على طابع خاص",
"confirmPasswordMustMatch": "يجب أن يتطابق تأكيد كلمة المرور",
"sms": "رسالة قصيرة",
"fingerPrint": "بصمة",
"face": "التعرف على الوجه",
"whatsapp": "واتس اب",
"reject": "يرفض",
"approve": "يوافق",
"msg": "Hello {} in the {} world ",
"msg_named": "{} are written in the {lang} language",
"clickMe": "Click me",
"human": "Human",
"resources": "Resources",
"human": "بشري",
"resources": "موارد",
"details": "تفاصيل",
"profile": {
"reset_password": {
"label": "Reset Password",

@ -48,12 +48,30 @@
"employeeId": "Employee ID",
"loginCodeWillSentToMobileNumber": "Please Enter your Employee ID, A login code will be sent to your mobile number",
"changePassword": "Change Password",
"ok": "OK",
"confirm": "Confirm",
"passwordChangedSuccessfully": "Password changed successfully",
"itemsForSale": "Items for Sale",
"doNotUseRecentPassword": "Do not use recent password",
"atLeastOneLowercase": "At least one lowercase",
"atLeastOneUppercase": "At least one uppercase",
"atLeastOneNumeric": "At least one numeric",
"minimum8Characters": "Minimum 8 characters",
"doNotAddRepeatingLetters": "Do not add repeating letters",
"itShouldContainSpecialCharacter": "It should contain special character",
"confirmPasswordMustMatch": "Confirm password must match",
"sms": "SMS",
"fingerPrint": "Fingerprint",
"face": "Face",
"whatsapp": "Whatsapp",
"reject": "Reject",
"approve": "Approve",
"msg": "Hello {} in the {} world ",
"msg_named": "{} are written in the {lang} language",
"clickMe": "Click me",
"human": "Human",
"resources": "Resources",
"details": "Details",
"profile": {
"reset_password": {
"label": "Reset Password",

@ -7,6 +7,8 @@ import 'package:http/http.dart';
import 'package:http/io_client.dart';
import 'package:mohem_flutter_app/exceptions/api_exception.dart';
import '../main.dart';
typedef FactoryConstructor<U> = U Function(dynamic);
class APIError {
@ -74,25 +76,25 @@ class ApiClient {
print("body:$jsonObject");
}
var response = await postJsonForResponse(url, jsonObject, token: token, queryParameters: queryParameters, headers: _headers, retryTimes: retryTimes);
try {
if (!kReleaseMode) {
print("res: " + response.body);
}
var jsonData = jsonDecode(response.body);
if (jsonData["ErrorMessage"] == null) {
return factoryConstructor(jsonData);
} else {
APIError? apiError;
apiError = APIError(jsonData['ErrorCode'], jsonData['ErrorMessage']);
throw APIException(APIException.BAD_REQUEST, error: apiError);
}
} catch (ex) {
if (ex is APIException) {
rethrow;
} else {
throw APIException(APIException.BAD_RESPONSE_FORMAT, arguments: ex);
}
// try {
if (!kReleaseMode) {
logger.i("res: " + response.body);
}
var jsonData = jsonDecode(response.body);
if (jsonData["ErrorMessage"] == null) {
return factoryConstructor(jsonData);
} else {
APIError? apiError;
apiError = APIError(jsonData['ErrorCode'], jsonData['ErrorMessage']);
throw APIException(APIException.BAD_REQUEST, error: apiError);
}
// } catch (ex) {
// if (ex is APIException) {
// rethrow;
// } else {
// throw APIException(APIException.BAD_RESPONSE_FORMAT, arguments: ex);
// }
// }
}
Future<Response> postJsonForResponse<T>(String url, T jsonObject, {String? token, Map<String, dynamic>? queryParameters, Map<String, String>? headers, int retryTimes = 0}) async {
@ -160,6 +162,68 @@ class ApiClient {
}
}
Future<Response> getJsonForResponse<T>(String url, {String? token, Map<String, dynamic>? queryParameters, Map<String, String>? headers, int retryTimes = 0}) async {
if (headers == null) {
headers = {'Content-Type': 'application/json'};
} else {
headers['Content-Type'] = 'application/json';
}
return await _getForResponse(url, token: token, queryParameters: queryParameters, headers: headers, retryTimes: retryTimes);
}
Future<Response> _getForResponse(String url, {String? token, Map<String, dynamic>? queryParameters, Map<String, String>? headers, int retryTimes = 0}) async {
try {
var _headers = <String, String>{};
if (token != null) {
_headers['Authorization'] = 'Bearer $token';
}
if (headers != null && headers.isNotEmpty) {
_headers.addAll(headers);
}
if (queryParameters != null) {
var queryString = new Uri(queryParameters: queryParameters).query;
url = url + '?' + queryString;
}
var response = await _get(Uri.parse(url), headers: _headers).timeout(Duration(seconds: 60));
if (response.statusCode >= 200 && response.statusCode < 300) {
return response;
} else {
throw _throwAPIException(response);
}
} on SocketException catch (e) {
if (retryTimes > 0) {
print('will retry after 3 seconds...');
await Future.delayed(Duration(seconds: 3));
return await _getForResponse(url, token: token, queryParameters: queryParameters, headers: headers, retryTimes: retryTimes - 1);
} else {
throw APIException(APIException.OTHER, arguments: e);
}
} on HttpException catch (e) {
if (retryTimes > 0) {
print('will retry after 3 seconds...');
await Future.delayed(Duration(seconds: 3));
return await _getForResponse(url, token: token, queryParameters: queryParameters, headers: headers, retryTimes: retryTimes - 1);
} else {
throw APIException(APIException.OTHER, arguments: e);
}
} on TimeoutException catch (e) {
throw APIException(APIException.TIMEOUT, arguments: e);
} on ClientException catch (e) {
if (retryTimes > 0) {
print('will retry after 3 seconds...');
await Future.delayed(Duration(seconds: 3));
return await _getForResponse(url, token: token, queryParameters: queryParameters, headers: headers, retryTimes: retryTimes - 1);
} else {
throw APIException(APIException.OTHER, arguments: e);
}
}
}
Future<Response> _get(url, {Map<String, String>? headers}) => _withClient((client) => client.get(url, headers: headers));
bool _certificateCheck(X509Certificate cert, String host, int port) => true;
Future<T> _withClient<T>(Future<T> Function(Client) fn) async {
@ -173,4 +237,4 @@ class ApiClient {
}
Future<Response> _post(url, {Map<String, String>? headers, body, Encoding? encoding}) => _withClient((client) => client.post(url, headers: headers, body: body, encoding: encoding));
}
}

@ -4,26 +4,28 @@ import 'package:mohem_flutter_app/app_state/app_state.dart';
import 'package:mohem_flutter_app/classes/consts.dart';
import 'package:mohem_flutter_app/models/basic_member_information_model.dart';
import 'package:mohem_flutter_app/models/check_mobile_app_version_model.dart';
import 'package:mohem_flutter_app/models/dashboard/get_attendance_tracking_list_model.dart';
import 'package:mohem_flutter_app/models/dashboard/itg_forms_model.dart';
import 'package:mohem_flutter_app/models/generic_response_model.dart';
import 'package:mohem_flutter_app/models/member_login_list_model.dart';
import 'package:uuid/uuid.dart';
import 'api_client.dart';
class DashbaordApiClient {
static final DashbaordApiClient _instance = DashbaordApiClient._internal();
class DashboardApiClient {
static final DashboardApiClient _instance = DashboardApiClient._internal();
DashbaordApiClient._internal();
DashboardApiClient._internal();
factory DashbaordApiClient() => _instance;
factory DashboardApiClient() => _instance;
Future<GenericResponseModel?> getAttendanceTracking() async {
Future<GetAttendanceTracking?> getAttendanceTracking() async {
String url = "${ApiConsts.erpRest}GET_Attendance_Tracking";
Map<String, dynamic> postParams = {};
postParams.addAll(AppState().postParamsJson);
return await ApiClient().postJsonForObject((json) {
GenericResponseModel responseData = GenericResponseModel.fromJson(json);
return responseData;
return responseData.getAttendanceTrackingList;
}, url, postParams);
}
@ -66,4 +68,49 @@ class DashbaordApiClient {
return responseData;
}, url, postParams);
}
//Menus List
Future<GenericResponseModel?> getListMenu() async {
String url = "${ApiConsts.erpRest}GET_MENU";
Map<String, dynamic> postParams = {};
postParams.addAll(AppState().postParamsJson);
return await ApiClient().postJsonForObject((json) {
GenericResponseModel responseData = GenericResponseModel.fromJson(json);
return responseData;
}, url, postParams);
}
//GET_MENU_ENTRIES
Future<GenericResponseModel?> getGetMenuEntries() async {
String url = "${ApiConsts.erpRest}GET_MENU_ENTRIES";
Map<String, dynamic> postParams = {"P_SELECTED_RESP_ID": -999, "P_MENU_TYPE": "E"};
postParams.addAll(AppState().postParamsJson);
return await ApiClient().postJsonForObject((json) {
GenericResponseModel responseData = GenericResponseModel.fromJson(json);
return responseData;
}, url, postParams);
}
//Mark Attendance
Future<GenericResponseModel?> markAttendance({String lat = "0", String? long = "0", required int pointType, String nfcValue = "", bool isGpsRequired = false}) async {
String url = "${ApiConsts.swpRest}AuthenticateAndSwipeUserSupportNFC";
var uuid = Uuid();
// Generate a v4 (random) id
Map<String, dynamic> postParams = {
"UID": uuid.v4(), //Mobile Id
"Latitude": lat,
"Longitude": long,
"QRValue": "",
"PointType": pointType, // NFC=2, Wifi = 3, QR= 1,
"NFCValue": nfcValue,
"WifiValue": "",
"IsGpsRequired": isGpsRequired
};
postParams.addAll(AppState().postParamsJson);
return await ApiClient().postJsonForObject((json) {
GenericResponseModel responseData = GenericResponseModel.fromJson(json);
return responseData;
}, url, postParams);
}
}

@ -5,6 +5,7 @@ import 'package:mohem_flutter_app/classes/consts.dart';
import 'package:mohem_flutter_app/models/basic_member_information_model.dart';
import 'package:mohem_flutter_app/models/check_mobile_app_version_model.dart';
import 'package:mohem_flutter_app/models/generic_response_model.dart';
import 'package:mohem_flutter_app/models/get_mobile_login_info_list_model.dart';
import 'package:mohem_flutter_app/models/member_login_list_model.dart';
import 'api_client.dart';
@ -16,6 +17,41 @@ class LoginApiClient {
factory LoginApiClient() => _instance;
Future<GetMobileLoginInfoListModel?> getMobileLoginInfoNEW(String deviceToken, String deviceType) async {
String url = "${ApiConsts.erpRest}Mohemm_GetMobileLoginInfo_NEW";
Map<String, dynamic> postParams = {};
postParams["DeviceToken"] = deviceToken;
postParams["DeviceType"] = deviceType;
return await ApiClient().postJsonForObject((json) {
GenericResponseModel? responseData = GenericResponseModel.fromJson(json);
return (responseData.mohemmGetMobileLoginInfoList?.length ?? 0) > 0 ? responseData.mohemmGetMobileLoginInfoList!.first : null;
}, url, postParams);
}
Future<GenericResponseModel?> insertMobileLoginInfoNEW(
String email, int sessionId, String employeeName, int loginType, String mobileNumber, String userName, String deviceToken, String deviceType) async {
String url = "${ApiConsts.erpRest}Mohemm_InsertMobileLoginInfo";
Map<String, dynamic> postParams = {
"MobileNumber": mobileNumber,
"P_USER_NAME": userName,
"UserName": userName,
"CompanyID": 1, // todo 'sikander' @discuss umer for companyID
"DeviceToken": deviceToken,
"LoginType": loginType,
"EmployeeName": employeeName,
"P_SESSION_ID": sessionId,
"P_EMAIL_ADDRESS": email
};
postParams["DeviceToken"] = deviceToken;
postParams["DeviceType"] = deviceType;
postParams.addAll(AppState().postParamsJson);
return await ApiClient().postJsonForObject((json) {
GenericResponseModel? responseData = GenericResponseModel.fromJson(json);
AppState().setLogged = true;
return responseData;
}, url, postParams);
}
Future<CheckMobileAppVersionModel> checkMobileAppVersion() async {
String url = "${ApiConsts.utilitiesRest}CheckMobileAppVersion";
Map<String, dynamic> postParams = {};
@ -47,7 +83,6 @@ class LoginApiClient {
postParams.addAll(AppState().postParamsJson);
return await ApiClient().postJsonForObject((json) {
GenericResponseModel responseData = GenericResponseModel.fromJson(json);
AppState().setLogged = true;
AppState().postParamsObject?.setTokenID = responseData.tokenID;
AppState().postParamsObject?.mobileNumber = responseData.basicMemberInformation!.pMOBILENUMBER;
AppState().postParamsObject?.userName = AppState().getUserName;
@ -55,6 +90,7 @@ class LoginApiClient {
AppState().postParamsObject?.pSessionId = responseData.pSESSIONID;
AppState().postParamsObject?.pUserName = AppState().getUserName;
AppState().postParamsObject?.pSelectedEmployeeNumber = AppState().getUserName;
return responseData;
}, url, postParams);
}
@ -83,7 +119,7 @@ class LoginApiClient {
postParams.addAll(AppState().postParamsJson);
return await ApiClient().postJsonForObject((json) {
GenericResponseModel responseData = GenericResponseModel.fromJson(json);
AppState().setForgetPasswordTokenID = responseData.tokenID;
AppState().setForgetPasswordTokenID = responseData.forgetPasswordTokenID;
return responseData;
}, url, postParams);
}

@ -0,0 +1,41 @@
import 'dart:async';
import 'package:mohem_flutter_app/api/api_client.dart';
import 'package:mohem_flutter_app/app_state/app_state.dart';
import 'package:mohem_flutter_app/classes/consts.dart';
import 'package:mohem_flutter_app/models/dashboard/itg_forms_model.dart';
import 'package:mohem_flutter_app/models/generic_response_model.dart';
import 'package:mohem_flutter_app/models/worklist_response_model.dart';
class WorkListApiClient {
static final WorkListApiClient _instance = WorkListApiClient._internal();
WorkListApiClient._internal();
factory WorkListApiClient() => _instance;
Future<List<WorkListResponseModel>?> getWorkList(int pPageNum, String pItemType) async {
String url = "${ApiConsts.erpRest}GET_WORKLIST";
Map<String, dynamic> postParams = {
"P_NOTIFICATION_TYPE": "1",
"P_PAGE_NUM": pPageNum,
"P_PAGE_LIMIT": 50,
"P_ITEM_TYPE": pItemType,
};
postParams.addAll(AppState().postParamsJson);
return await ApiClient().postJsonForObject((json) {
GenericResponseModel? responseData = GenericResponseModel.fromJson(json);
return responseData.getWorkList;
}, url, postParams);
}
Future<ItgFormsModel?> GetITGTaskCountRequestType() async {
String url = "${ApiConsts.cocRest}ITGGetTaskCountRequestType";
Map<String, dynamic> postParams = {};
postParams.addAll(AppState().postParamsJson);
return await ApiClient().postJsonForObject((json) {
ItgFormsModel responseData = ItgFormsModel.fromJson(json);
return responseData;
}, url, postParams);
}
}

@ -1,5 +1,8 @@
import 'package:easy_localization/easy_localization.dart';
import 'package:mohem_flutter_app/models/member_information_list_model.dart';
import 'package:mohem_flutter_app/models/member_login_list_model.dart';
import 'package:mohem_flutter_app/models/post_params_model.dart';
import 'package:mohem_flutter_app/models/privilege_list_model.dart';
class AppState {
static final AppState _instance = AppState._internal();
@ -30,15 +33,34 @@ class AppState {
this._postParams = _postParams;
}
bool isArabic(context) => EasyLocalization.of(context)?.locale.languageCode == "ar";
String? _username;
// todo ''sikander' added password for now, later will remove & improve
String? password;
set setUserName(v) => _username = v;
String? get getUserName => _username;
set setUserPassword(_password) => password = _password;
MemberLoginListModel? _memberLoginList;
MemberLoginListModel? get memberLoginList => _memberLoginList;
set setMemberLoginListModel(MemberLoginListModel? _memberLoginList) => this._memberLoginList = _memberLoginList;
MemberInformationListModel? _memberInformationList;
MemberInformationListModel? get memberInformationList => _memberInformationList;
set setMemberInformationListModel(MemberInformationListModel? _memberInformationList) => this._memberInformationList = _memberInformationList;
List<PrivilegeListModel>? _privilegeListModel;
List<PrivilegeListModel>? get privilegeListModel => _privilegeListModel;
set setPrivilegeListModel(List<PrivilegeListModel>? _privilegeListModel) => this._privilegeListModel = _privilegeListModel;
}

@ -0,0 +1,30 @@
import 'package:permission_handler/permission_handler.dart';
class AppPermissions{
static location(Function(bool) completion) {
Permission.location.isGranted.then((isGranted){
if(!isGranted){
Permission.location.request().then((granted){
completion(granted == PermissionStatus.granted);
});
}
completion(isGranted);
});
}
static checkAll(Function(bool) completion){
[
Permission.location
].request().then((value){
bool allGranted = false;
value.values.forEach((element) {
allGranted = allGranted && element == PermissionStatus.granted;
});
completion(allGranted);
});
}
}

@ -16,6 +16,7 @@ class MyColors {
static const Color grey98Color = Color(0xff989898);
static const Color lightGreyEFColor = Color(0xffEFEFEF);
static const Color lightGreyEDColor = Color(0xffEDEDED);
static const Color lightGreyE6Color = Color(0xffE6E6E6);
static const Color lightGreyEAColor = Color(0xffEAEAEA);
static const Color darkWhiteColor = Color(0xffE0E0E0);
static const Color redColor = Color(0xffD02127);

@ -1,22 +1,23 @@
class ApiConsts {
//static String baseUrl = "http://10.200.204.20:2801/"; // Local server
static String baseUrl = "https://uat.hmgwebservices.com"; // UAT server
static String baseUrlServices = baseUrl + "/services/"; // server
// static String baseUrl = "https://hmgwebservices.com"; // Live server
static String baseUrlServices = baseUrl + "/Services/"; // server
// static String baseUrlServices = "https://api.cssynapses.com/tangheem/"; // Live server
static String utilitiesRest = baseUrlServices + "Utilities.svc/REST/";
static String erpRest = baseUrlServices + "ERP.svc/REST/";
static String swpRest = baseUrlServices + "SWP.svc/REST/";
static String user = baseUrlServices + "api/User/";
static String cocRest = baseUrlServices + "COCWS.svc/REST/";
}
class GlobalConsts {
class SharedPrefsConsts {
static String isRememberMe = "remember_me";
static String email = "email";
static String username = "username";
static String password = "password";
static String bookmark = "bookmark";
static String fontZoomSize = "font_zoom_size";
static String privilegeList = "privilegeList";
static String firebaseToken = "firebaseToken";
static String memberInformation = "memberInformation";
static String welcomeVideoUrl = "welcomeVideoUrl";
static String doNotShowWelcomeVideo = "doNotShowWelcomeVideo";
}

@ -0,0 +1,444 @@
import 'package:intl/intl.dart';
class DateUtil {
/// convert String To Date function
/// [date] String we want to convert
static DateTime convertStringToDate(String date) {
// /Date(1585774800000+0300)/
if (date != null) {
const start = "/Date(";
const end = "+0300)";
final startIndex = date.indexOf(start);
final endIndex = date.indexOf(end, startIndex + start.length);
return DateTime.fromMillisecondsSinceEpoch(
int.parse(
date.substring(startIndex + start.length, endIndex),
),
);
} else
return DateTime.now();
}
static DateTime convertSimpleStringDateToDate(String date) {
return DateFormat("MM/dd/yyyy hh:mm:ss").parse(date);
}
static DateTime convertStringToDateNoTimeZone(String date) {
// /Date(1585774800000+0300)/
if (date != null) {
const start = "/Date(";
const end = ")";
final startIndex = date.indexOf(start);
final endIndex = date.indexOf(end, startIndex + start.length);
return DateTime.fromMillisecondsSinceEpoch(
int.parse(
date.substring(startIndex + start.length, endIndex),
),
);
} else
return DateTime.now();
}
static DateTime convertStringToDateTime(String date) {
if (date != null) {
try {
var dateT = date.split('/');
var year = dateT[2].substring(0, 4);
var dateP = DateTime(int.parse(year), int.parse(dateT[1]), int.parse(dateT[0]));
return dateP;
} catch (e) {
print(e);
}
return DateTime.now();
} else
return DateTime.now();
}
static String convertDateToString(DateTime date) {
const start = "/Date(";
const end = "+0300)";
int milliseconds = date.millisecondsSinceEpoch;
return start + "$milliseconds" + end;
}
static String convertDateToStringLocation(DateTime date) {
const start = "/Date(";
const end = ")/";
int milliseconds = date.millisecondsSinceEpoch;
return start + "$milliseconds" + end;
}
static String formatDateToDate(DateTime date, bool isArabic) {
return DateFormat('dd MMM yyy', isArabic ? "ar_SA" : "en_US").format(date);
}
static String formatDateToTime(DateTime date) {
return DateFormat('hh:mm a').format(date);
}
static String yearMonthDay(DateTime dateTime) {
String dateFormat = '${dateTime.year}-${dateTime.month}-${dateTime.day}';
return dateFormat;
}
static String time(DateTime dateTime) {
String dateFormat = '${dateTime.hour}:${dateTime.minute}:00';
return dateFormat;
}
static String convertDateMSToJsonDate(utc) {
var dt = new DateTime.fromMicrosecondsSinceEpoch(utc);
return "/Date(" + (dt.millisecondsSinceEpoch * 1000).toString() + '+0300' + ")/";
}
/// check Date
/// [dateString] String we want to convert
static String checkDate(DateTime checkedTime) {
DateTime currentTime = DateTime.now();
if ((currentTime.year == checkedTime.year) && (currentTime.month == checkedTime.month) && (currentTime.day == checkedTime.day)) {
return "Today";
} else if ((currentTime.year == checkedTime.year) && (currentTime.month == checkedTime.month)) {
if ((currentTime.day - checkedTime.day) == 1) {
return "YESTERDAY";
} else if ((currentTime.day - checkedTime.day) == -1) {
return "Tomorrow";
}
if ((currentTime.day - checkedTime.day) <= -2) {
return "Next Week";
} else {
return "Old Date";
}
}
return "Old Date";
}
static String getDateFormatted(String date) {
DateTime dateObj = DateUtil.convertStringToDate(date);
return DateUtil.getWeekDay(dateObj.weekday) + ", " + dateObj.day.toString() + " " + DateUtil.getMonth(dateObj.month) + " " + dateObj.year.toString();
}
static String getISODateFormat(DateTime dateTime) {
// 2020-04-30T00:00:00.000
return dateTime.toIso8601String();
}
/// get month by
/// [month] convert month number in to month name
static getMonth(int month) {
switch (month) {
case 1:
return "January";
case 2:
return "February";
case 3:
return "March";
case 4:
return "April";
case 5:
return "May";
case 6:
return "June";
case 7:
return "July";
case 8:
return "August";
case 9:
return "September";
case 10:
return "October";
case 11:
return "November";
case 12:
return "December";
}
}
/// get month by
/// [month] convert month number in to month name in Arabic
static getMonthArabic(int month) {
switch (month) {
case 1:
return "يناير";
case 2:
return " فبراير";
case 3:
return "مارس";
case 4:
return "أبريل";
case 5:
return "مايو";
case 6:
return "يونيو";
case 7:
return "يوليو";
case 8:
return "أغسطس";
case 9:
return "سبتمبر";
case 10:
return " اكتوبر";
case 11:
return " نوفمبر";
case 12:
return "ديسمبر";
}
}
static getMonthByName(String month) {
switch (month.toLowerCase()) {
case 'january':
return 1;
case 'february':
return 2;
case 'march':
return 3;
case 'april':
return 4;
case 'may':
return 5;
case 'june':
return 6;
case 'july':
return 7;
case 'august':
return 8;
case 'september':
return 9;
case 'october':
return 10;
case 'november':
return 11;
case 'december':
return 12;
}
}
static DateTime getMonthDateTime(String month, yearName) {
DateTime? date;
try {
date = DateTime(int.parse(yearName), getMonthByName(month));
} catch (e) {
print(e);
}
return date ?? DateTime.now();
}
/// get month by
/// [weekDay] convert week day in int to week day name
static getWeekDay(int weekDay) {
switch (weekDay) {
case 1:
return "Monday";
case 2:
return "Tuesday";
case 3:
return "Wednesday";
case 4:
return "Thursday";
case 5:
return "Friday";
case 6:
return "Saturday ";
case 7:
return "Sunday";
}
}
/// get month by
/// [weekDay] convert week day in int to week day name arabic
static getWeekDayArabic(int weekDay) {
switch (weekDay) {
case 1:
return "الاثنين";
case 2:
return "الثلاثاء";
case 3:
return "الاربعاء";
case 4:
return "الخميس";
case 5:
return "الجمعه";
case 6:
return "السبت ";
case 7:
return "الاحد";
}
}
static getWeekDayEnglish(int weekDay) {
switch (weekDay) {
case 1:
return "Monday";
case 2:
return "Tuesday";
case 3:
return "Wednesday";
case 4:
return "Thursday";
case 5:
return "Friday";
case 6:
return "Saturday ";
case 7:
return "Sunday";
}
}
/// get data formatted like Apr 26,2020
/// [dateTime] convert DateTime to data formatted
static String getMonthDayYearDateFormatted(DateTime dateTime) {
if (dateTime != null)
return getMonth(dateTime.month) + " " + dateTime.day.toString() + ", " + dateTime.year.toString();
else
return "";
}
/// get data formatted like Apr 26,2020
/// [dateTime] convert DateTime to data formatted Arabic
static String getMonthDayYearDateFormattedAr(DateTime dateTime) {
if (dateTime != null)
return getMonthArabic(dateTime.month) + " " + dateTime.day.toString() + ", " + dateTime.year.toString();
else
return "";
}
/// get data formatted like Thursday, Apr 26,2020
/// [dateTime] convert DateTime to date formatted
static String getWeekDayMonthDayYearDateFormatted(DateTime dateTime, String lang) {
// print(dateTime);
// print(dateTime.weekday);
// print(dateTime.weekday.getDayOfWeekEnumValue.value);
if (dateTime != null)
return lang == 'en'
? getWeekDayEnglish(dateTime.weekday) + ", " + getMonth(dateTime.month) + " " + dateTime.day.toString() + " " + dateTime.year.toString()
: getWeekDayArabic(dateTime.weekday) + ", " + dateTime.day.toString() + " " + getMonthArabic(dateTime.month) + " " + dateTime.year.toString();
else
return "";
}
static String getMonthDayYearLangDateFormatted(DateTime dateTime, String lang) {
if (dateTime != null)
return lang == 'en'
? getMonth(dateTime.month) + " " + dateTime.day.toString() + " " + dateTime.year.toString()
: dateTime.day.toString() + " " + getMonthArabic(dateTime.month) + " " + dateTime.year.toString();
else
return "";
}
/// get data formatted like 26/4/2020
static String getDayMonthYearLangDateFormatted(DateTime dateTime, String lang) {
if (dateTime != null)
return lang == 'en'
? dateTime.day.toString() + " " + getMonth(dateTime.month) + " " + dateTime.year.toString()
: dateTime.day.toString() + " " + getMonthArabic(dateTime.month) + " " + dateTime.year.toString();
else
return "";
}
static String getMonthYearLangDateFormatted(DateTime dateTime, String lang) {
if (dateTime != null)
return lang == 'en' ? getMonth(dateTime.month) + " " + dateTime.year.toString() : getMonthArabic(dateTime.month) + " " + dateTime.year.toString();
else
return "";
}
/// get data formatted like 26/4/2020
/// [dateTime] convert DateTime to data formatted
static String getDayMonthYearDateFormatted(DateTime dateTime) {
if (dateTime != null)
return dateTime.day.toString() + "/" + dateTime.month.toString() + "/" + dateTime.year.toString();
else
return "";
}
/// get data formatted like 26/4/2020
/// [dateTime] convert DateTime to data formatted
static String getDayMonthDateFormatted(DateTime dateTime) {
if (dateTime != null)
return DateFormat('dd/MM').format(dateTime);
else
return "";
}
/// get data formatted like 26/4/2020
/// [dateTime] convert DateTime to data formatted according to language
static String getDayMonthYearDateFormattedLang(DateTime dateTime, bool isArabic) {
if (dateTime != null)
return DateFormat('dd/MM/yyyy', isArabic ? "ar_SA" : "en_US").format(dateTime);
else
return "";
}
/// get data formatted like 10:30 according to lang
static String formatDateToTimeLang(DateTime date, bool isArabic) {
return DateFormat('HH:mm', isArabic ? "ar_SA" : "en_US").format(date);
}
/// get data formatted like 26/4/2020 10:30
/// [dateTime] convert DateTime to data formatted
static String getDayMonthYearHourMinuteDateFormatted(DateTime dateTime) {
if (dateTime != null)
return dateTime.day.toString() + "/" + dateTime.month.toString() + "/" + dateTime.year.toString() + " " + DateFormat('HH:mm').format(dateTime);
else
return "";
}
/// get data formatted like 2020-8-13 09:43:00
/// [dateTime] convert DateTime to data formatted
static String getYearMonthDayHourMinSecDateFormatted(DateTime dateTime) {
if (dateTime != null)
return dateTime.year.toString() +
"-" +
dateTime.month.toString() +
"-" +
dateTime.day.toString() +
" " +
dateTime.hour.toString() +
":" +
dateTime.minute.toString() +
":" +
dateTime.second.toString();
else
return "";
}
static String getFormattedDate(DateTime dateTime, String formattedString) {
return DateFormat(formattedString).format(dateTime);
}
static convertISODateToJsonDate(String isoDate) {
return "/Date(" + DateFormat('mm-dd-yyy').parse(isoDate).millisecondsSinceEpoch.toString() + ")/";
}
// static String getDay(DayOfWeek dayOfWeek) {
// switch (dayOfWeek) {
// case DayOfWeek.Monday:
// return "Monday";
// break;
// case DayOfWeek.Tuesday:
// return "Tuesday";
// break;
// case DayOfWeek.Wednesday:
// return "Wednesday";
// break;
// case DayOfWeek.Thursday:
// return "Thursday";
// break;
// case DayOfWeek.Friday:
// return "Friday";
// break;
// case DayOfWeek.Saturday:
// return "Saturday";
// break;
// case DayOfWeek.Sunday:
// return "Sunday";
// break;
// }
// return "";
// }
}

@ -3,7 +3,9 @@ import 'package:fluttertoast/fluttertoast.dart';
// import 'package:fluttertoast/fluttertoast.dart';
import 'package:mohem_flutter_app/exceptions/api_exception.dart';
import 'package:mohem_flutter_app/widgets/dialogs/confirm_dialog.dart';
import 'package:mohem_flutter_app/widgets/loading_dialog.dart';
import 'package:shared_preferences/shared_preferences.dart';
class Utils {
static bool _isLoadingVisible = false;
@ -44,6 +46,10 @@ class Utils {
});
}
static Future delay(int millis) async {
return await Future.delayed(Duration(milliseconds: millis));
}
static void hideLoading(BuildContext context) {
if (_isLoadingVisible) {
_isLoadingVisible = false;
@ -52,6 +58,16 @@ class Utils {
_isLoadingVisible = false;
}
static Future<String> getStringFromPrefs(String key) async {
SharedPreferences prefs = await SharedPreferences.getInstance();
return prefs.getString(key) ?? "";
}
static Future<bool> saveStringFromPrefs(String key, String value) async {
SharedPreferences prefs = await SharedPreferences.getInstance();
return await prefs.setString(key, value);
}
static void handleException(dynamic exception, Function(String)? onErrorMessage) {
String errorMessage;
if (exception is APIException) {
@ -69,4 +85,13 @@ class Utils {
showToast(errorMessage);
}
}
static void confirmDialog(cxt, String message) {
showDialog(
context: cxt,
builder: (cxt) => ConfirmDialog(
message: message,
),
);
}
}

@ -1,9 +1,10 @@
import 'package:flutter/material.dart';
import 'package:mohem_flutter_app/ui/landing/dashboard.dart';
import 'package:mohem_flutter_app/ui/landing/dashboard_screen.dart';
import 'package:mohem_flutter_app/ui/landing/today_attendance_screen.dart';
import 'package:mohem_flutter_app/ui/login/forgot_password_screen.dart';
import 'package:mohem_flutter_app/ui/login/login_screen.dart';
import 'package:mohem_flutter_app/ui/login/new_password_screen.dart';
import 'package:mohem_flutter_app/ui/login/verify_last_login_screen.dart';
import 'package:mohem_flutter_app/ui/login/verify_login_screen.dart';
import 'package:mohem_flutter_app/ui/work_list/missing_swipe/missing_swipe_screen.dart';
import 'package:mohem_flutter_app/ui/work_list/work_list_screen.dart';
@ -14,6 +15,7 @@ class AppRoutes {
static const String loginVerifyAccount = "/loginVerifyAccount";
static const String login = "/login";
static const String verifyLogin = "/verifyLogin";
static const String verifyLastLogin = "/verifyLastLogin";
static const String forgotPassword = "/forgotPassword";
static const String newPassword = "/newPassword";
static const String loginVerification = "/loginVerification";
@ -28,7 +30,8 @@ class AppRoutes {
static final Map<String, WidgetBuilder> routes = {
login: (context) => LoginScreen(),
verifyLogin: (context) => VerifyLoginScreen(),
dashboard: (context) => Dashboard(),
verifyLastLogin: (context) => VerifyLastLoginScreen(),
dashboard: (context) => DashboardScreen(),
newPassword: (context) => NewPasswordScreen(),
forgotPassword: (context) => ForgotPasswordScreen(),
todayAttendance: (context) => TodayAttendanceScreen(),

@ -1,6 +1,18 @@
import 'package:easy_localization/src/public_ext.dart';
import 'package:flutter/cupertino.dart';
import 'package:intl/intl.dart';
import 'package:mohem_flutter_app/classes/colors.dart';
import 'package:mohem_flutter_app/generated/locale_keys.g.dart';
extension CapExtension on String {
String get toCamelCase => "${this[0].toUpperCase()}${this.substring(1)}";
String get inCaps => '${this[0].toUpperCase()}${this.substring(1)}';
String get allInCaps => this.toUpperCase();
String get capitalizeFirstofEach => this.trim().length > 0 ? this.trim().toLowerCase().split(" ").map((str) => str.inCaps).join(" ") : "";
}
extension EmailValidator on String {
Widget get toWidget => Text(this);
@ -57,9 +69,9 @@ extension EmailValidator on String {
style: TextStyle(height: 1, color: color ?? MyColors.darkTextColor, fontSize: 22, letterSpacing: -1.44, fontWeight: isBold ? FontWeight.bold : FontWeight.w600),
);
Widget toText24({Color? color, bool isBold = false}) => Text(
Widget toText24({Color? color, bool isBold = false, bool considerHeight = true}) => Text(
this,
style: TextStyle(height: 23 / 24, color: color ?? MyColors.darkTextColor, fontSize: 24, letterSpacing: -1.44, fontWeight: isBold ? FontWeight.bold : FontWeight.w600),
style: TextStyle(height: considerHeight ? 23 / 24 : null, color: color ?? MyColors.darkTextColor, fontSize: 24, letterSpacing: -1.44, fontWeight: isBold ? FontWeight.bold : FontWeight.w600),
);
Widget toText32({Color? color, bool isBold = false}) => Text(
@ -67,6 +79,38 @@ extension EmailValidator on String {
style: TextStyle(height: 32 / 32, color: color ?? MyColors.darkTextColor, fontSize: 32, letterSpacing: -1.92, fontWeight: isBold ? FontWeight.bold : FontWeight.w600),
);
Widget toSectionHeading({String upperHeading = "", String lowerHeading = ""}) {
String upper = "";
String lower = "";
String heading = this;
if (heading.isNotEmpty) {
List<String> data = heading.split(" ");
if (data.length > 1) {
upper = data[0];
data.removeAt(0);
lower = data.join(" ");
} else {
lower = data[0];
}
}
if (upperHeading.isNotEmpty) {
upper = upperHeading;
}
if (lowerHeading.isNotEmpty) {
lower = lowerHeading;
}
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: [
if (upper.isNotEmpty) upper.toText12(),
lower.toText24(isBold: true),
],
);
}
bool isValidEmail() {
return RegExp(r'^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$').hasMatch(this);
}

@ -1,11 +1,39 @@
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
import 'package:shimmer/shimmer.dart';
extension WidgetExtensions on Widget {
Widget onPress(VoidCallback onTap) => InkWell(onTap: onTap, child: this);
Widget get expanded => Expanded(child: this);
Widget get center => Center(child: this);
Widget paddingAll(double _value) => Padding(padding: EdgeInsets.all(_value), child: this);
Widget paddingOnly({double left = 0.0, double right = 0.0, double top = 0.0, double bottom = 0.0}) =>
Padding(padding: EdgeInsets.only(left: left, right: right, top: top, bottom: bottom), child: this);
Widget toShimmer({bool isShow = true}) => isShow
? Shimmer.fromColors(
baseColor: Color(0xffe8eff0),
highlightColor: Colors.white,
child: Container(
child: this,
color: Colors.white,
),
)
: Container(
child: this,
);
Widget animatedSwither() => AnimatedSwitcher(
duration: const Duration(milliseconds: 500),
// transitionBuilder: (Widget child, Animation<double> animation) {
// return ScaleTransition(scale: animation, child: child);
// },
switchInCurve: Curves.linearToEaseOut,
switchOutCurve: Curves.linearToEaseOut,
child: this,
);
}

@ -6,191 +6,193 @@ import 'dart:ui';
import 'package:easy_localization/easy_localization.dart' show AssetLoader;
class CodegenLoader extends AssetLoader{
class CodegenLoader extends AssetLoader {
const CodegenLoader();
@override
Future<Map<String, dynamic>> load(String fullPath, Locale locale ) {
Future<Map<String, dynamic>> load(String fullPath, Locale locale) {
return Future.value(mapLocales[locale.toString()]);
}
static const Map<String,dynamic> ar_SA = {
"mohemm": "Mohemm",
"english": "English",
"arabic": "Arabic",
"login": "تسجيل الدخول",
"pleaseEnterLoginDetails": "الرجاء إدخال التفاصيل أدناه لتسجيل الدخول",
"username": "اسم المستخدم",
"password": "كلمة المرور",
"welcomeBack": "مرحبا بعودتك",
"wouldYouLikeToLoginWithCurrentUsername": "هل ترغب في تسجيل الدخول باسم المستخدم الحالي؟",
"lastLoginDetails": "تفاصيل تسجيل الدخول الأخير:",
"verificationType": "نوع التحقق:",
"pleaseVerify": "ارجوك تحقق",
"verifyThroughFace": "تحقق من خلال الوجه",
"verifyThroughFingerprint": "تحقق من خلال بصمة الإصبع",
"verifyThroughSMS": "تحقق من خلال الرسائل القصيرة",
"verifyThroughWhatsapp": "تحقق من خلال Whatsapp",
"useAnotherAccount": "استخدم حسابا آخر",
"pleaseEnterTheVerificationCodeSentTo": "الرجاء إدخال رمز التحقق المرسل إلى ",
"theVerificationCodeWillExpireIn": "ستنتهي صلاحية رمز التحقق في ",
"goodMorning": "صباح الخير",
"markAttendance": "علامة الحضور",
"timeLeftToday": "الوقت المتبقي اليوم",
"checkIn": "تحقق في",
"workList": "قائمة العمل",
"leaveBalance": "رصيد الاجازات",
"missingSwipes": "الضربات الشديدة في عداد المفقودين",
"ticketBalance": "رصيد التذكرة",
"other": "آخر",
"services": "خدمات",
"viewAllServices": "عرض جميع الخدمات",
"monthlyAttendance": "الحضور الشهري",
"workFromHome": "العمل من المنزل",
"ticketRequest": "طلب تذكرة",
"viewAllOffers": "مشاهدة جميع العروض",
"offers": "عروض & ",
"discounts": "الخصومات",
"newString": "جديد",
"setTheNewPassword": "قم بتعيين كلمة المرور الجديدة",
"typeYourNewPasswordBelow": "اكتب كلمة المرور الجديدة أدناه",
"confirmPassword": "تأكيد كلمة المرور",
"update": "تحديث",
"title": "عنوان",
"home": "مسكن",
"mySalary": "راتبي",
"createRequest": "إنشاء طلب",
"forgotPassword": "هل نسيت كلمة السر",
"employeeId": "هوية الموظف",
"loginCodeWillSentToMobileNumber": "الرجاء إدخال معرف الموظف الخاص بك ، وسيتم إرسال رمز تسجيل الدخول إلى رقم هاتفك المحمول",
"changePassword": "تغيير كلمة المرور",
"itemsForSale": "سلع للبيع",
"msg": "Hello {} in the {} world ",
"msg_named": "{} are written in the {lang} language",
"clickMe": "Click me",
"human": "Human",
"resources": "Resources",
"profile": {
"reset_password": {
"label": "Reset Password",
"username": "Username",
"password": "password"
}
},
"clicked": {
"zero": "You clicked {} times!",
"one": "You clicked {} time!",
"two": "You clicked {} times!",
"few": "You clicked {} times!",
"many": "You clicked {} times!",
"other": "You clicked {} times!"
},
"amount": {
"zero": "Your amount : {} ",
"one": "Your amount : {} ",
"two": "Your amount : {} ",
"few": "Your amount : {} ",
"many": "Your amount : {} ",
"other": "Your amount : {} "
},
"gender": {
"male": "Hi man ;) ",
"female": "Hello girl :)",
"with_arg": {
"male": "Hi man ;) {}",
"female": "Hello girl :) {}"
}
},
"reset_locale": "Reset Language"
};
static const Map<String,dynamic> en_US = {
"mohemm": "Mohemm",
"english": "English",
"arabic": "Arabic",
"login": "Login",
"pleaseEnterLoginDetails": "Please enter the detail below to login",
"username": "Username",
"password": "Password",
"welcomeBack": "Welcome back",
"wouldYouLikeToLoginWithCurrentUsername": "Would you like to login with current Username?",
"lastLoginDetails": "Last Login Details:",
"verificationType": "Verification Type:",
"pleaseVerify": "Please Verify",
"verifyThroughFace": "Verify Through Face",
"verifyThroughFingerprint": "Verify Through Fingerprint",
"verifyThroughSMS": "Verify Through SMS",
"verifyThroughWhatsapp": "Verify Through Whatsapp",
"useAnotherAccount": "Use Another Account",
"pleaseEnterTheVerificationCodeSentTo": "Please enter the verification code sent to ",
"theVerificationCodeWillExpireIn": "The verification code will expire in ",
"goodMorning": "Good Morning",
"markAttendance": "Mark Attendance",
"timeLeftToday": "Time Left Today",
"checkIn": "Check In",
"workList": "Work List",
"leaveBalance": "Leave Balance",
"missingSwipes": "Missing Swipes",
"ticketBalance": "Ticket Balance",
"other": "Other",
"services": "Services",
"viewAllServices": "View All Services",
"monthlyAttendance": "Monthly Attendance",
"workFromHome": "Work From Home",
"ticketRequest": "Ticket Request",
"viewAllOffers": "View All Offers",
"offers": "Offers & ",
"discounts": "Discounts",
"newString": "New",
"setTheNewPassword": "Set the new password",
"typeYourNewPasswordBelow": "Type your new password below",
"confirmPassword": "Confirm Password",
"update": "Update",
"title": "Title",
"home": "Home",
"mySalary": "My Salary",
"createRequest": "Create Request",
"forgotPassword": "Forgot Password",
"employeeId": "Employee ID",
"loginCodeWillSentToMobileNumber": "Please Enter your Employee ID, A login code will be sent to your mobile number",
"changePassword": "Change Password",
"itemsForSale": "Items for Sale",
"msg": "Hello {} in the {} world ",
"msg_named": "{} are written in the {lang} language",
"clickMe": "Click me",
"human": "Human",
"resources": "Resources",
"profile": {
"reset_password": {
"label": "Reset Password",
"username": "Username",
"password": "password"
}
},
"clicked": {
"zero": "You clicked {} times!",
"one": "You clicked {} time!",
"two": "You clicked {} times!",
"few": "You clicked {} times!",
"many": "You clicked {} times!",
"other": "You clicked {} times!"
},
"amount": {
"zero": "Your amount : {} ",
"one": "Your amount : {} ",
"two": "Your amount : {} ",
"few": "Your amount : {} ",
"many": "Your amount : {} ",
"other": "Your amount : {} "
},
"gender": {
"male": "Hi man ;) ",
"female": "Hello girl :)",
"with_arg": {
"male": "Hi man ;) {}",
"female": "Hello girl :) {}"
}
},
"reset_locale": "Reset Language"
};
static const Map<String, Map<String,dynamic>> mapLocales = {"ar_SA": ar_SA, "en_US": en_US};
static const Map<String, dynamic> ar_SA = {
"mohemm": "Mohemm",
"english": "English",
"arabic": "Arabic",
"login": "تسجيل الدخول",
"pleaseEnterLoginDetails": "الرجاء إدخال التفاصيل أدناه لتسجيل الدخول",
"username": "اسم المستخدم",
"password": "كلمة المرور",
"welcomeBack": "مرحبا بعودتك",
"wouldYouLikeToLoginWithCurrentUsername": "هل ترغب في تسجيل الدخول باسم المستخدم الحالي؟",
"lastLoginDetails": "تفاصيل تسجيل الدخول الأخير:",
"verificationType": "نوع التحقق:",
"pleaseVerify": "ارجوك تحقق",
"verifyThroughFace": "تحقق من خلال الوجه",
"verifyThroughFingerprint": "تحقق من خلال بصمة الإصبع",
"verifyThroughSMS": "تحقق من خلال الرسائل القصيرة",
"verifyThroughWhatsapp": "تحقق من خلال Whatsapp",
"useAnotherAccount": "استخدم حسابا آخر",
"pleaseEnterTheVerificationCodeSentTo": "الرجاء إدخال رمز التحقق المرسل إلى ",
"theVerificationCodeWillExpireIn": "ستنتهي صلاحية رمز التحقق في ",
"goodMorning": "صباح الخير",
"markAttendance": "علامة الحضور",
"timeLeftToday": "الوقت المتبقي اليوم",
"checkIn": "تحقق في",
"workList": "قائمة العمل",
"leaveBalance": "رصيد الاجازات",
"missingSwipes": "الضربات الشديدة في عداد المفقودين",
"ticketBalance": "رصيد التذكرة",
"other": "آخر",
"services": "خدمات",
"viewAllServices": "عرض جميع الخدمات",
"monthlyAttendance": "الحضور الشهري",
"workFromHome": "العمل من المنزل",
"ticketRequest": "طلب تذكرة",
"viewAllOffers": "مشاهدة جميع العروض",
"offers": "عروض & ",
"discounts": "الخصومات",
"newString": "جديد",
"setTheNewPassword": "قم بتعيين كلمة المرور الجديدة",
"typeYourNewPasswordBelow": "اكتب كلمة المرور الجديدة أدناه",
"confirmPassword": "تأكيد كلمة المرور",
"update": "تحديث",
"title": "عنوان",
"home": "مسكن",
"mySalary": "راتبي",
"createRequest": "إنشاء طلب",
"forgotPassword": "هل نسيت كلمة السر",
"employeeId": "هوية الموظف",
"loginCodeWillSentToMobileNumber": "الرجاء إدخال معرف الموظف الخاص بك ، وسيتم إرسال رمز تسجيل الدخول إلى رقم هاتفك المحمول",
"changePassword": "تغيير كلمة المرور",
"ok": "موافق",
"confirm": "تؤكد",
"passwordChangedSuccessfully": "تم تغيير الرقم السري بنجاح",
"itemsForSale": "سلع للبيع",
"doNotUseRecentPassword": "لا تستخدم كلمة مرور حديثة",
"atLeastOneLowercase": "حرف صغير واحد على الأقل",
"atLeastOneUppercase": "حرف كبير واحد على الأقل",
"atLeastOneNumeric": "رقم واحد على الأقل",
"minimum8Characters": "8 أحرف على الأقل",
"doNotAddRepeatingLetters": "لا تقم بإضافة أحرف متكررة",
"itShouldContainSpecialCharacter": "يجب أن يحتوي على طابع خاص",
"confirmPasswordMustMatch": "يجب أن يتطابق تأكيد كلمة المرور",
"sms": "رسالة قصيرة",
"fingerPrint": "بصمة",
"face": "التعرف على الوجه",
"whatsapp": "واتس اب",
"msg": "Hello {} in the {} world ",
"msg_named": "{} are written in the {lang} language",
"clickMe": "Click me",
"human": "Human",
"resources": "Resources",
"profile": {
"reset_password": {"label": "Reset Password", "username": "Username", "password": "password"}
},
"clicked": {
"zero": "You clicked {} times!",
"one": "You clicked {} time!",
"two": "You clicked {} times!",
"few": "You clicked {} times!",
"many": "You clicked {} times!",
"other": "You clicked {} times!"
},
"amount": {"zero": "Your amount : {} ", "one": "Your amount : {} ", "two": "Your amount : {} ", "few": "Your amount : {} ", "many": "Your amount : {} ", "other": "Your amount : {} "},
"gender": {
"male": "Hi man ;) ",
"female": "Hello girl :)",
"with_arg": {"male": "Hi man ;) {}", "female": "Hello girl :) {}"}
},
"reset_locale": "Reset Language"
};
static const Map<String, dynamic> en_US = {
"mohemm": "Mohemm",
"english": "English",
"arabic": "Arabic",
"login": "Login",
"pleaseEnterLoginDetails": "Please enter the detail below to login",
"username": "Username",
"password": "Password",
"welcomeBack": "Welcome back",
"wouldYouLikeToLoginWithCurrentUsername": "Would you like to login with current Username?",
"lastLoginDetails": "Last Login Details:",
"verificationType": "Verification Type:",
"pleaseVerify": "Please Verify",
"verifyThroughFace": "Verify Through Face",
"verifyThroughFingerprint": "Verify Through Fingerprint",
"verifyThroughSMS": "Verify Through SMS",
"verifyThroughWhatsapp": "Verify Through Whatsapp",
"useAnotherAccount": "Use Another Account",
"pleaseEnterTheVerificationCodeSentTo": "Please enter the verification code sent to ",
"theVerificationCodeWillExpireIn": "The verification code will expire in ",
"goodMorning": "Good Morning",
"markAttendance": "Mark Attendance",
"timeLeftToday": "Time Left Today",
"checkIn": "Check In",
"workList": "Work List",
"leaveBalance": "Leave Balance",
"missingSwipes": "Missing Swipes",
"ticketBalance": "Ticket Balance",
"other": "Other",
"services": "Services",
"viewAllServices": "View All Services",
"monthlyAttendance": "Monthly Attendance",
"workFromHome": "Work From Home",
"ticketRequest": "Ticket Request",
"viewAllOffers": "View All Offers",
"offers": "Offers & ",
"discounts": "Discounts",
"newString": "New",
"setTheNewPassword": "Set the new password",
"typeYourNewPasswordBelow": "Type your new password below",
"confirmPassword": "Confirm Password",
"update": "Update",
"title": "Title",
"home": "Home",
"mySalary": "My Salary",
"createRequest": "Create Request",
"forgotPassword": "Forgot Password",
"employeeId": "Employee ID",
"loginCodeWillSentToMobileNumber": "Please Enter your Employee ID, A login code will be sent to your mobile number",
"changePassword": "Change Password",
"ok": "OK",
"confirm": "Confirm",
"passwordChangedSuccessfully": "Password changed successfully",
"itemsForSale": "Items for Sale",
"doNotUseRecentPassword": "Do not use recent password",
"atLeastOneLowercase": "At least one lowercase",
"atLeastOneUppercase": "At least one uppercase",
"atLeastOneNumeric": "At least one numeric",
"minimum8Characters": "Minimum 8 characters",
"doNotAddRepeatingLetters": "Do not add repeating letters",
"itShouldContainSpecialCharacter": "It should contain special character",
"confirmPasswordMustMatch": "Confirm password must match",
"sms": "SMS",
"fingerPrint": "Fingerprint",
"face": "Face",
"whatsapp": "Whatsapp",
"msg": "Hello {} in the {} world ",
"msg_named": "{} are written in the {lang} language",
"clickMe": "Click me",
"human": "Human",
"resources": "Resources",
"profile": {
"reset_password": {"label": "Reset Password", "username": "Username", "password": "password"}
},
"clicked": {
"zero": "You clicked {} times!",
"one": "You clicked {} time!",
"two": "You clicked {} times!",
"few": "You clicked {} times!",
"many": "You clicked {} times!",
"other": "You clicked {} times!"
},
"amount": {"zero": "Your amount : {} ", "one": "Your amount : {} ", "two": "Your amount : {} ", "few": "Your amount : {} ", "many": "Your amount : {} ", "other": "Your amount : {} "},
"gender": {
"male": "Hi man ;) ",
"female": "Hello girl :)",
"with_arg": {"male": "Hi man ;) {}", "female": "Hello girl :) {}"}
},
"reset_locale": "Reset Language"
};
static const Map<String, Map<String, dynamic>> mapLocales = {"ar_SA": ar_SA, "en_US": en_US};
}

@ -1,6 +1,6 @@
// DO NOT EDIT. This is code generated via package:easy_localization/generate.dart
abstract class LocaleKeys {
abstract class LocaleKeys {
static const mohemm = 'mohemm';
static const english = 'english';
static const arabic = 'arabic';
@ -49,12 +49,30 @@ abstract class LocaleKeys {
static const employeeId = 'employeeId';
static const loginCodeWillSentToMobileNumber = 'loginCodeWillSentToMobileNumber';
static const changePassword = 'changePassword';
static const ok = 'ok';
static const confirm = 'confirm';
static const passwordChangedSuccessfully = 'passwordChangedSuccessfully';
static const itemsForSale = 'itemsForSale';
static const doNotUseRecentPassword = 'doNotUseRecentPassword';
static const atLeastOneLowercase = 'atLeastOneLowercase';
static const atLeastOneUppercase = 'atLeastOneUppercase';
static const atLeastOneNumeric = 'atLeastOneNumeric';
static const minimum8Characters = 'minimum8Characters';
static const doNotAddRepeatingLetters = 'doNotAddRepeatingLetters';
static const itShouldContainSpecialCharacter = 'itShouldContainSpecialCharacter';
static const confirmPasswordMustMatch = 'confirmPasswordMustMatch';
static const sms = 'sms';
static const fingerPrint = 'fingerPrint';
static const face = 'face';
static const whatsapp = 'whatsapp';
static const msg = 'msg';
static const msg_named = 'msg_named';
static const clickMe = 'clickMe';
static const human = 'human';
static const resources = 'resources';
static const details = 'details';
static const reject = 'reject';
static const approve = 'approve';
static const profile_reset_password_label = 'profile.reset_password.label';
static const profile_reset_password_username = 'profile.reset_password.username';
static const profile_reset_password_password = 'profile.reset_password.password';
@ -65,5 +83,4 @@ abstract class LocaleKeys {
static const gender_with_arg = 'gender.with_arg';
static const gender = 'gender';
static const reset_locale = 'reset_locale';
}

@ -1,4 +1,5 @@
import 'dart:io';
import 'dart:typed_data';
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
@ -6,14 +7,30 @@ import 'package:mohem_flutter_app/app_state/app_state.dart';
import 'package:mohem_flutter_app/config/app_provider.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/provider/dashboard_provider_model.dart';
import 'package:mohem_flutter_app/theme/app_theme.dart';
import 'package:mohem_flutter_app/widgets/nfc/nfc_reader_sheet.dart';
import 'package:nfc_manager/nfc_manager.dart';
import 'package:nfc_manager/platform_tags.dart';
import 'package:provider/provider.dart';
import 'package:sizer/sizer.dart';
import 'package:firebase_core/firebase_core.dart';
import 'config/routes.dart';
import 'package:logger/logger.dart';
var logger = Logger(
// filter: null, // Use the default LogFilter (-> only log in debug mode)
printer: PrettyPrinter(lineLength: 0), // Use the PrettyPrinter to format and print log
// output: null, // U
);
Future<void> main() async {
WidgetsFlutterBinding.ensureInitialized();
await EasyLocalization.ensureInitialized();
await Firebase.initializeApp();
AppState().setPostParamsModel(
PostParamsModel(channel: 31, versionID: 3.4, mobileType: Platform.isAndroid ? "android" : "ios"),
);
runApp(
EasyLocalization(
supportedLocales: const [
@ -22,7 +39,12 @@ Future<void> main() async {
],
path: 'assets/langs',
assetLoader: CodegenLoader(),
child: MyApp(),
child: MultiProvider(
providers: [
ChangeNotifierProvider(create: (_) => DashboardProviderModel()),
],
child: MyApp(),
),
),
);
}
@ -40,23 +62,159 @@ class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return AppProvider(
child: Sizer(
builder: (context, orientation, deviceType) {
AppState().setPostParamsModel(
PostParamsModel(languageID: EasyLocalization.of(context)?.locale.languageCode == "ar" ? 1 : 2, channel: 31, versionID: 3.2, mobileType: Platform.isAndroid ? "android" : "ios"),
);
return MaterialApp(
theme: AppTheme.getTheme(EasyLocalization.of(context)?.locale.languageCode == "ar"),
debugShowCheckedModeBanner: false,
localizationsDelegates: context.localizationDelegates,
supportedLocales: context.supportedLocales,
locale: context.locale,
initialRoute: AppRoutes.initialRoute,
routes: AppRoutes.routes,
);
},
),
return Sizer(
builder: (context, orientation, deviceType) {
print(AppState().postParamsObject?.toJson());
var obj = AppState().postParamsObject;
obj?.languageID = EasyLocalization.of(context)?.locale.languageCode == "ar" ? 1 : 2;
AppState().setPostParamsModel(obj!);
return MaterialApp(
theme: AppTheme.getTheme(EasyLocalization.of(context)?.locale.languageCode == "ar"),
debugShowCheckedModeBanner: false,
localizationsDelegates: context.localizationDelegates,
supportedLocales: context.supportedLocales,
locale: context.locale,
initialRoute: AppRoutes.initialRoute,
routes: AppRoutes.routes,
);
},
);
}
}
// class MyApp extends StatefulWidget {
// @override
// State<StatefulWidget> createState() => MyAppState();
// }
//
// class MyAppState extends State<MyApp> {
// ValueNotifier<dynamic> result = ValueNotifier(null);
//
// @override
// Widget build(BuildContext context) {
// return MaterialApp(
// home: Scaffold(
// appBar: AppBar(title: Text('NfcManager Plugin Example')),
// body: SafeArea(
// child: FutureBuilder<bool>(
// future: NfcManager.instance.isAvailable(),
// builder: (context, ss) => ss.data != true
// ? Center(child: Text('NfcManager.isAvailable(): ${ss.data}'))
// : Flex(
// mainAxisAlignment: MainAxisAlignment.spaceBetween,
// direction: Axis.vertical,
// children: [
// Flexible(
// flex: 2,
// child: Container(
// margin: EdgeInsets.all(4),
// constraints: BoxConstraints.expand(),
// decoration: BoxDecoration(border: Border.all()),
// child: SingleChildScrollView(
// child: ValueListenableBuilder<dynamic>(
// valueListenable: result,
// builder: (context, value, _) => Text('${value ?? ''}'),
// ),
// ),
// ),
// ),
// Flexible(
// flex: 3,
// child: GridView.count(
// padding: EdgeInsets.all(4),
// crossAxisCount: 2,
// childAspectRatio: 4,
// crossAxisSpacing: 4,
// mainAxisSpacing: 4,
// children: [
// ElevatedButton(child: Text('Tag Read'), onPressed: _tagRead),
// ElevatedButton(child: Text('Ndef Write'), onPressed: _ndefWrite),
// ElevatedButton(child: Text('Ndef Write Lock'), onPressed: _ndefWriteLock),
// ],
// ),
// ),
// ],
// ),
// ),
// ),
// ),
// );
// }
//
// void _tagRead() {
// showNfcReader(
// context,
// onNcfScan: (String? nfcId) {},
// );
// // NfcManager.instance.startSession(onDiscovered: (NfcTag tag) async {
// // result.value = tag.data;
// // print(tag.data);
// // var ndef = Ndef.from(tag);
// //
// // var f = MifareUltralight(tag: tag, identifier: tag.data["nfca"]["identifier"], type: 2, maxTransceiveLength: 252, timeout: 22);
// // final String identifier = f.identifier.map((e) => e.toRadixString(16).padLeft(2, '0')).join('');
// // print(identifier); // => 0428fcf2255e81
// // print(ndef!.additionalData);
// //
// // // onDiscovered callback
// // // final mifare = MiFare.from(tag);
// // // if (mifare == null) {
// // // print('Tag is not compatible with MiFare.');
// // // return;
// // // }
// // // print(mifare.identifier);
// // // final String identifier = mifare.identifier.map((e) => e.toRadixString(16).padLeft(2, '0')).join('');
// // // print(identifier); // => 0428fcf2255e81
// // NfcManager.instance.stopSession();
// // });
// }
//
// void _ndefWrite() {
// NfcManager.instance.startSession(onDiscovered: (NfcTag tag) async {
// var ndef = Ndef.from(tag);
// if (ndef == null || !ndef.isWritable) {
// result.value = 'Tag is not ndef writable';
// NfcManager.instance.stopSession(errorMessage: result.value);
// return;
// }
//
// NdefMessage message = NdefMessage([
// NdefRecord.createText('Hello World!'),
// NdefRecord.createUri(Uri.parse('https://flutter.dev')),
// NdefRecord.createMime('text/plain', Uint8List.fromList('Hello'.codeUnits)),
// NdefRecord.createExternal('com.example', 'mytype', Uint8List.fromList('mydata'.codeUnits)),
// ]);
//
// try {
// await ndef.write(message);
// result.value = 'Success to "Ndef Write"';
// NfcManager.instance.stopSession();
// } catch (e) {
// result.value = e;
// NfcManager.instance.stopSession(errorMessage: result.value.toString());
// return;
// }
// });
// }
//
// void _ndefWriteLock() {
// NfcManager.instance.startSession(onDiscovered: (NfcTag tag) async {
// var ndef = Ndef.from(tag);
// if (ndef == null) {
// result.value = 'Tag is not ndef';
// NfcManager.instance.stopSession(errorMessage: result.value.toString());
// return;
// }
//
// try {
// await ndef.writeLock();
// result.value = 'Success to "Ndef Write Lock"';
// NfcManager.instance.stopSession();
// } catch (e) {
// result.value = e;
// NfcManager.instance.stopSession(errorMessage: result.value.toString());
// return;
// }
// });
// }
// }

@ -1,5 +1,5 @@
class GetAttendanceTrackingList {
GetAttendanceTrackingList({
class GetAttendanceTracking {
GetAttendanceTracking({
this.pBreakHours,
this.pLateInHours,
this.pRemainingHours,
@ -25,7 +25,7 @@ class GetAttendanceTrackingList {
dynamic pSwipeIn;
dynamic pSwipeOut;
factory GetAttendanceTrackingList.fromMap(Map<String, dynamic> json) => GetAttendanceTrackingList(
factory GetAttendanceTracking.fromMap(Map<String, dynamic> json) => GetAttendanceTracking(
pBreakHours: json["P_BREAK_HOURS"] == null ? null : json["P_BREAK_HOURS"],
pLateInHours: json["P_LATE_IN_HOURS"] == null ? null : json["P_LATE_IN_HOURS"],
pRemainingHours: json["P_REMAINING_HOURS"] == null ? null : json["P_REMAINING_HOURS"],

@ -93,97 +93,163 @@ class ItgFormsModel {
dynamic mohemmItgProjectsList;
dynamic mohemmItgTicketTypesList;
DateTime? referenceNumber;
dynamic requestType;
List<RequestType>? requestType;
int? totalCount;
int? statuseCode;
factory ItgFormsModel.fromJson(Map<String, dynamic> json) => ItgFormsModel(
date: json["Date"],
languageId: json["LanguageID"] == null ? null : json["LanguageID"],
serviceName: json["ServiceName"] == null ? null : json["ServiceName"],
time: json["Time"],
androidLink: json["AndroidLink"],
authenticationTokenId: json["AuthenticationTokenID"],
data: json["Data"],
dataw: json["Dataw"] == null ? null : json["Dataw"],
dietType: json["DietType"] == null ? null : json["DietType"],
dietTypeId: json["DietTypeID"] == null ? null : json["DietTypeID"],
errorCode: json["ErrorCode"],
errorEndUserMessage: json["ErrorEndUserMessage"],
errorEndUserMessageN: json["ErrorEndUserMessageN"],
errorMessage: json["ErrorMessage"],
errorType: json["ErrorType"] == null ? null : json["ErrorType"],
foodCategory: json["FoodCategory"] == null ? null : json["FoodCategory"],
iosLink: json["IOSLink"],
isAuthenticated: json["IsAuthenticated"] == null ? null : json["IsAuthenticated"],
mealOrderStatus: json["MealOrderStatus"] == null ? null : json["MealOrderStatus"],
mealType: json["MealType"] == null ? null : json["MealType"],
messageStatus: json["MessageStatus"] == null ? null : json["MessageStatus"],
numberOfResultRecords: json["NumberOfResultRecords"] == null ? null : json["NumberOfResultRecords"],
patientBlodType: json["PatientBlodType"],
successMsg: json["SuccessMsg"] == null ? null : json["SuccessMsg"],
successMsgN: json["SuccessMsgN"],
vidaUpdatedResponse: json["VidaUpdatedResponse"],
itgRequest: json["ITGRequest"],
itgFormAttachmentsList: json["Itg_FormAttachmentsList"],
message: json["Message"] == null ? null : json["Message"],
mohemmItgDepartmentSectionsList: json["Mohemm_ITG_DepartmentSectionsList"],
mohemmItgProjectDepartmentsList: json["Mohemm_ITG_ProjectDepartmentsList"],
mohemmItgResponseItem: json["Mohemm_ITG_ResponseItem"],
mohemmItgSectionTopicsList: json["Mohemm_ITG_SectionTopicsList"],
mohemmItgTicketDetailsList: json["Mohemm_ITG_TicketDetailsList"],
mohemmItgTicketTransactionsList: json["Mohemm_ITG_TicketTransactionsList"],
mohemmItgTicketsByEmployeeList: json["Mohemm_ITG_TicketsByEmployeeList"],
mohemmItgProjectsList: json["Mohemm_Itg_ProjectsList"],
mohemmItgTicketTypesList: json["Mohemm_Itg_TicketTypesList"],
referenceNumber: json["ReferenceNumber"] == null ? null : DateTime.parse(json["ReferenceNumber"]),
requestType: json["RequestType"],
totalCount: json["TotalCount"] == null ? null : json["TotalCount"],
statuseCode: json["statuseCode"] == null ? null : json["statuseCode"],
);
date: json["Date"],
languageId: json["LanguageID"] == null ? null : json["LanguageID"],
serviceName: json["ServiceName"] == null ? null : json["ServiceName"],
time: json["Time"],
androidLink: json["AndroidLink"],
authenticationTokenId: json["AuthenticationTokenID"],
data: json["Data"],
dataw: json["Dataw"] == null ? null : json["Dataw"],
dietType: json["DietType"] == null ? null : json["DietType"],
dietTypeId: json["DietTypeID"] == null ? null : json["DietTypeID"],
errorCode: json["ErrorCode"],
errorEndUserMessage: json["ErrorEndUserMessage"],
errorEndUserMessageN: json["ErrorEndUserMessageN"],
errorMessage: json["ErrorMessage"],
errorType: json["ErrorType"] == null ? null : json["ErrorType"],
foodCategory: json["FoodCategory"] == null ? null : json["FoodCategory"],
iosLink: json["IOSLink"],
isAuthenticated: json["IsAuthenticated"] == null ? null : json["IsAuthenticated"],
mealOrderStatus: json["MealOrderStatus"] == null ? null : json["MealOrderStatus"],
mealType: json["MealType"] == null ? null : json["MealType"],
messageStatus: json["MessageStatus"] == null ? null : json["MessageStatus"],
numberOfResultRecords: json["NumberOfResultRecords"] == null ? null : json["NumberOfResultRecords"],
patientBlodType: json["PatientBlodType"],
successMsg: json["SuccessMsg"] == null ? null : json["SuccessMsg"],
successMsgN: json["SuccessMsgN"],
vidaUpdatedResponse: json["VidaUpdatedResponse"],
itgRequest: json["ITGRequest"],
itgFormAttachmentsList: json["Itg_FormAttachmentsList"],
message: json["Message"] == null ? null : json["Message"],
mohemmItgDepartmentSectionsList: json["Mohemm_ITG_DepartmentSectionsList"],
mohemmItgProjectDepartmentsList: json["Mohemm_ITG_ProjectDepartmentsList"],
mohemmItgResponseItem: json["Mohemm_ITG_ResponseItem"],
mohemmItgSectionTopicsList: json["Mohemm_ITG_SectionTopicsList"],
mohemmItgTicketDetailsList: json["Mohemm_ITG_TicketDetailsList"],
mohemmItgTicketTransactionsList: json["Mohemm_ITG_TicketTransactionsList"],
mohemmItgTicketsByEmployeeList: json["Mohemm_ITG_TicketsByEmployeeList"],
mohemmItgProjectsList: json["Mohemm_Itg_ProjectsList"],
mohemmItgTicketTypesList: json["Mohemm_Itg_TicketTypesList"],
referenceNumber: json["ReferenceNumber"] == null ? null : DateTime.parse(json["ReferenceNumber"]),
requestType: json["RequestType"] == null ? <RequestType>[] : json['RequestType']!.map<RequestType>((v) => RequestType.fromJson(v)).toList(),
totalCount: json["TotalCount"] == null ? null : json["TotalCount"],
statuseCode: json["statuseCode"] == null ? null : json["statuseCode"],
);
Map<String, dynamic> toMap() => {
"Date": date,
"LanguageID": languageId == null ? null : languageId,
"ServiceName": serviceName == null ? null : serviceName,
"Time": time,
"AndroidLink": androidLink,
"AuthenticationTokenID": authenticationTokenId,
"Data": data,
"Dataw": dataw == null ? null : dataw,
"DietType": dietType == null ? null : dietType,
"DietTypeID": dietTypeId == null ? null : dietTypeId,
"ErrorCode": errorCode,
"ErrorEndUserMessage": errorEndUserMessage,
"ErrorEndUserMessageN": errorEndUserMessageN,
"ErrorMessage": errorMessage,
"ErrorType": errorType == null ? null : errorType,
"FoodCategory": foodCategory == null ? null : foodCategory,
"IOSLink": iosLink,
"IsAuthenticated": isAuthenticated == null ? null : isAuthenticated,
"MealOrderStatus": mealOrderStatus == null ? null : mealOrderStatus,
"MealType": mealType == null ? null : mealType,
"MessageStatus": messageStatus == null ? null : messageStatus,
"NumberOfResultRecords": numberOfResultRecords == null ? null : numberOfResultRecords,
"PatientBlodType": patientBlodType,
"SuccessMsg": successMsg == null ? null : successMsg,
"SuccessMsgN": successMsgN,
"VidaUpdatedResponse": vidaUpdatedResponse,
"ITGRequest": itgRequest,
"Itg_FormAttachmentsList": itgFormAttachmentsList,
"Message": message == null ? null : message,
"Mohemm_ITG_DepartmentSectionsList": mohemmItgDepartmentSectionsList,
"Mohemm_ITG_ProjectDepartmentsList": mohemmItgProjectDepartmentsList,
"Mohemm_ITG_ResponseItem": mohemmItgResponseItem,
"Mohemm_ITG_SectionTopicsList": mohemmItgSectionTopicsList,
"Mohemm_ITG_TicketDetailsList": mohemmItgTicketDetailsList,
"Mohemm_ITG_TicketTransactionsList": mohemmItgTicketTransactionsList,
"Mohemm_ITG_TicketsByEmployeeList": mohemmItgTicketsByEmployeeList,
"Mohemm_Itg_ProjectsList": mohemmItgProjectsList,
"Mohemm_Itg_TicketTypesList": mohemmItgTicketTypesList,
"ReferenceNumber": referenceNumber == null ? null : referenceNumber!.toIso8601String(),
"RequestType": requestType,
"TotalCount": totalCount == null ? null : totalCount,
"statuseCode": statuseCode == null ? null : statuseCode,
};
"Date": date,
"LanguageID": languageId == null ? null : languageId,
"ServiceName": serviceName == null ? null : serviceName,
"Time": time,
"AndroidLink": androidLink,
"AuthenticationTokenID": authenticationTokenId,
"Data": data,
"Dataw": dataw == null ? null : dataw,
"DietType": dietType == null ? null : dietType,
"DietTypeID": dietTypeId == null ? null : dietTypeId,
"ErrorCode": errorCode,
"ErrorEndUserMessage": errorEndUserMessage,
"ErrorEndUserMessageN": errorEndUserMessageN,
"ErrorMessage": errorMessage,
"ErrorType": errorType == null ? null : errorType,
"FoodCategory": foodCategory == null ? null : foodCategory,
"IOSLink": iosLink,
"IsAuthenticated": isAuthenticated == null ? null : isAuthenticated,
"MealOrderStatus": mealOrderStatus == null ? null : mealOrderStatus,
"MealType": mealType == null ? null : mealType,
"MessageStatus": messageStatus == null ? null : messageStatus,
"NumberOfResultRecords": numberOfResultRecords == null ? null : numberOfResultRecords,
"PatientBlodType": patientBlodType,
"SuccessMsg": successMsg == null ? null : successMsg,
"SuccessMsgN": successMsgN,
"VidaUpdatedResponse": vidaUpdatedResponse,
"ITGRequest": itgRequest,
"Itg_FormAttachmentsList": itgFormAttachmentsList,
"Message": message == null ? null : message,
"Mohemm_ITG_DepartmentSectionsList": mohemmItgDepartmentSectionsList,
"Mohemm_ITG_ProjectDepartmentsList": mohemmItgProjectDepartmentsList,
"Mohemm_ITG_ResponseItem": mohemmItgResponseItem,
"Mohemm_ITG_SectionTopicsList": mohemmItgSectionTopicsList,
"Mohemm_ITG_TicketDetailsList": mohemmItgTicketDetailsList,
"Mohemm_ITG_TicketTransactionsList": mohemmItgTicketTransactionsList,
"Mohemm_ITG_TicketsByEmployeeList": mohemmItgTicketsByEmployeeList,
"Mohemm_Itg_ProjectsList": mohemmItgProjectsList,
"Mohemm_Itg_TicketTypesList": mohemmItgTicketTypesList,
"ReferenceNumber": referenceNumber == null ? null : referenceNumber!.toIso8601String(),
"RequestType": requestType == null ? null : requestType!.map((v) => v.toJson()).toList(),
"TotalCount": totalCount == null ? null : totalCount,
"statuseCode": statuseCode == null ? null : statuseCode,
};
}
class RequestType {
int? itemCount;
List<RequestDetails>? requestDetails;
String? requestTypeCode;
String? requestTypeName;
RequestType({this.itemCount, this.requestDetails, this.requestTypeCode, this.requestTypeName});
RequestType.fromJson(Map<String, dynamic> json) {
itemCount = json['ItemCount'];
if (json['RequestDetails'] != null) {
requestDetails = <RequestDetails>[];
json['RequestDetails'].forEach((v) {
requestDetails!.add(new RequestDetails.fromJson(v));
});
}
requestTypeCode = json['RequestTypeCode'];
requestTypeName = json['RequestTypeName'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['ItemCount'] = this.itemCount;
if (this.requestDetails != null) {
data['RequestDetails'] = this.requestDetails!.map((v) => v.toJson()).toList();
}
data['RequestTypeCode'] = this.requestTypeCode;
data['RequestTypeName'] = this.requestTypeName;
return data;
}
}
class RequestDetails {
int? iD;
int? itemID;
String? listID;
String? listName;
String? modifiedDate;
String? title;
String? uRL;
RequestDetails({this.iD, this.itemID, this.listID, this.listName, this.modifiedDate, this.title, this.uRL});
RequestDetails.fromJson(Map<String, dynamic> json) {
iD = json['ID'];
itemID = json['ItemID'];
listID = json['ListID'];
listName = json['ListName'];
modifiedDate = json['ModifiedDate'];
title = json['Title'];
uRL = json['URL'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['ID'] = this.iD;
data['ItemID'] = this.itemID;
data['ListID'] = this.listID;
data['ListName'] = this.listName;
data['ModifiedDate'] = this.modifiedDate;
data['Title'] = this.title;
data['URL'] = this.uRL;
return data;
}
}

@ -0,0 +1,39 @@
class ListMenu {
ListMenu({
this.menuId,
this.menuName,
this.menuType,
this.requestGroupId,
this.requestGroupName,
this.respId,
this.subMenuName,
});
int? menuId;
String? menuName;
String? menuType;
int? requestGroupId;
String? requestGroupName;
dynamic? respId;
String? subMenuName;
factory ListMenu.fromJson(Map<String, dynamic> json) => ListMenu(
menuId: json["MENU_ID"] == null ? null : json["MENU_ID"],
menuName: json["MENU_NAME"] == null ? null : json["MENU_NAME"],
menuType: json["MENU_TYPE"] == null ? null : json["MENU_TYPE"],
requestGroupId: json["REQUEST_GROUP_ID"] == null ? null : json["REQUEST_GROUP_ID"],
requestGroupName: json["REQUEST_GROUP_NAME"] == null ? null : json["REQUEST_GROUP_NAME"],
respId: json["RESP_ID"],
subMenuName: json["SUB_MENU_NAME"] == null ? null : json["SUB_MENU_NAME"],
);
Map<String, dynamic> toJson() => {
"MENU_ID": menuId == null ? null : menuId,
"MENU_NAME": menuName == null ? null : menuName,
"MENU_TYPE": menuType == null ? null : menuType,
"REQUEST_GROUP_ID": requestGroupId == null ? null : requestGroupId,
"REQUEST_GROUP_NAME": requestGroupName == null ? null : requestGroupName,
"RESP_ID": respId,
"SUB_MENU_NAME": subMenuName == null ? null : subMenuName,
};
}

@ -0,0 +1,60 @@
class GetMenuEntriesList {
GetMenuEntriesList({
this.addButton,
this.deleteButton,
this.entrySequence,
this.functionName,
this.icon,
this.lvl,
this.menuEntryType,
this.menuName,
this.parentMenuName,
this.prompt,
this.requestType,
this.updateButton,
});
String? addButton;
String? deleteButton;
int? entrySequence;
String? functionName;
String? icon;
int? lvl;
String? menuEntryType;
String? menuName;
String? parentMenuName;
String? prompt;
String? requestType;
String? updateButton;
factory GetMenuEntriesList.fromJson(Map<String, dynamic> json) => GetMenuEntriesList(
addButton: json["ADD_BUTTON"] == null ? null : json["ADD_BUTTON"],
deleteButton: json["DELETE_BUTTON"] == null ? null : json["DELETE_BUTTON"],
entrySequence: json["ENTRY_SEQUENCE"] == null ? null : json["ENTRY_SEQUENCE"],
functionName: json["FUNCTION_NAME"] == null ? null : json["FUNCTION_NAME"],
icon: json["ICON"] == null ? null : json["ICON"],
lvl: json["LVL"] == null ? null : json["LVL"],
menuEntryType: json["MENU_ENTRY_TYPE"] == null ? null : json["MENU_ENTRY_TYPE"],
menuName: json["MENU_NAME"] == null ? null : json["MENU_NAME"],
parentMenuName: json["PARENT_MENU_NAME"] == null ? null : json["PARENT_MENU_NAME"],
prompt: json["PROMPT"] == null ? null : json["PROMPT"],
requestType: json["REQUEST_TYPE"] == null ? null : json["REQUEST_TYPE"],
updateButton: json["UPDATE_BUTTON"] == null ? null :json["UPDATE_BUTTON"],
);
Map<String, dynamic> toJson() => {
"ADD_BUTTON": addButton == null ? null :addButton,
"DELETE_BUTTON": deleteButton == null ? null : deleteButton,
"ENTRY_SEQUENCE": entrySequence == null ? null : entrySequence,
"FUNCTION_NAME": functionName == null ? null : functionName,
"ICON": icon == null ? null : icon,
"LVL": lvl == null ? null : lvl,
"MENU_ENTRY_TYPE": menuEntryType == null ? null : menuEntryType,
"MENU_NAME": menuName == null ? null : menuName,
"PARENT_MENU_NAME": parentMenuName == null ? null : parentMenuName,
"PROMPT": prompt == null ? null : prompt,
"REQUEST_TYPE": requestType == null ? null : requestType,
"UPDATE_BUTTON": updateButton == null ? null : updateButton,
};
}

@ -0,0 +1,10 @@
import 'package:mohem_flutter_app/models/dashboard/menu_entries.dart';
class Menus {
GetMenuEntriesList menuEntry;
List<GetMenuEntriesList> menuEntiesList;
Menus(this.menuEntry, this.menuEntiesList);
}

@ -1,10 +1,14 @@
import 'package:mohem_flutter_app/models/member_login_list_model.dart';
import 'package:mohem_flutter_app/models/worklist_response_model.dart';
import 'basic_member_information_model.dart';
import 'get_mobile_login_info_list_model.dart';
import 'dashboard/get_accrual_balances_list_model.dart';
import 'dashboard/get_attendance_tracking_list_model.dart';
import 'dashboard/get_open_missing_swipes_list_model.dart';
import 'dashboard/get_open_notifications_list.dart';
import 'dashboard/list_menu.dart';
import 'dashboard/menu_entries.dart';
import 'member_information_list_model.dart';
import 'privilege_list_model.dart';
@ -67,7 +71,7 @@ class GenericResponseModel {
List<String>? getAddressNotificationBodyList;
List<String>? getApprovesList;
List<String>? getAttachementList;
GetAttendanceTrackingList? getAttendanceTrackingList;
GetAttendanceTracking? getAttendanceTrackingList;
List<String>? getBasicDetColsStructureList;
List<String>? getBasicDetDffStructureList;
List<String>? getBasicDetNtfBodyList;
@ -103,7 +107,7 @@ class GenericResponseModel {
List<String>? getItemTypeNotificationsList;
List<String>? getItemTypesList;
List<String>? getLookupValuesList;
List<String>? getMenuEntriesList;
List<GetMenuEntriesList>? getMenuEntriesList;
List<String>? getMoItemHistoryList;
List<String>? getMoNotificationBodyList;
List<String>? getNotificationButtonsList;
@ -147,7 +151,7 @@ class GenericResponseModel {
List<String>? getVaccinationOnHandList;
List<String>? getVaccinationsList;
List<String>? getValueSetValuesList;
List<String>? getWorkList;
List<WorkListResponseModel>? getWorkList;
String? hRCertificateTemplate;
String? imgURLsList;
String? insertApInv;
@ -169,7 +173,7 @@ class GenericResponseModel {
String? listItemImagesDetails;
String? listItemMaster;
String? listMedicineDetails;
String? listMenu;
List<ListMenu>? listMenu;
String? listNewEmployees;
String? listRadScreen;
String? logInTokenID;
@ -178,7 +182,7 @@ class GenericResponseModel {
String? mohemmGetBusinessCardEnabledList;
List? mohemmGetFavoriteReplacementsList;
String? mohemmGetMobileDeviceInfobyEmpInfoList;
String? mohemmGetMobileLoginInfoList;
List<GetMobileLoginInfoListModel>? mohemmGetMobileLoginInfoList;
String? mohemmGetPatientIDList;
String? mohemmITGResponseItem;
bool? mohemmIsChangeIsActiveBusinessCardEnable;
@ -198,7 +202,7 @@ class GenericResponseModel {
String? pINFORMATION;
int? pMBLID;
String? pNUMOFSUBORDINATES;
String? pOPENNTFNUMBER;
int? pOPENNTFNUMBER;
String? pQUESTION;
int? pSESSIONID;
String? pSchema;
@ -567,15 +571,13 @@ class GenericResponseModel {
getAbsenceCollectionNotificationBodyList = json['GetAbsenceCollectionNotificationBodyList'];
getAbsenceDffStructureList = json['GetAbsenceDffStructureList'];
getAbsenceTransactionList = json['GetAbsenceTransactionList'];
getAccrualBalancesList:
json["GetAccrualBalancesList"] == null ? null : List<GetAccrualBalancesList>.from(json["GetAccrualBalancesList"].map((x) => GetAccrualBalancesList.fromJson(x)));
getAccrualBalancesList = json["GetAccrualBalancesList"] == null ? null : List<GetAccrualBalancesList>.from(json["GetAccrualBalancesList"].map((x) => GetAccrualBalancesList.fromJson(x)));
getActionHistoryList = json['GetActionHistoryList'];
getAddressDffStructureList = json['GetAddressDffStructureList'];
getAddressNotificationBodyList = json['GetAddressNotificationBodyList'];
getApprovesList = json['GetApprovesList'];
getAttachementList = json['GetAttachementList'];
getAttendanceTrackingList:
json["GetAttendanceTrackingList"] == null ? null : GetAttendanceTrackingList.fromMap(json["GetAttendanceTrackingList"]);
getAttendanceTrackingList = json["GetAttendanceTrackingList"] == null ? null : GetAttendanceTracking.fromMap(json["GetAttendanceTrackingList"]);
getBasicDetColsStructureList = json['GetBasicDetColsStructureList'];
getBasicDetDffStructureList = json['GetBasicDetDffStructureList'];
getBasicDetNtfBodyList = json['GetBasicDetNtfBodyList'];
@ -611,15 +613,14 @@ class GenericResponseModel {
getItemTypeNotificationsList = json['GetItemTypeNotificationsList'];
getItemTypesList = json['GetItemTypesList'];
getLookupValuesList = json['GetLookupValuesList'];
getMenuEntriesList = json['GetMenuEntriesList'];
getMenuEntriesList = json["GetMenuEntriesList"] == null ? null : List<GetMenuEntriesList>.from(json["GetMenuEntriesList"].map((x) => GetMenuEntriesList.fromJson(x)));
getMoItemHistoryList = json['GetMoItemHistoryList'];
getMoNotificationBodyList = json['GetMoNotificationBodyList'];
getNotificationButtonsList = json['GetNotificationButtonsList'];
getNotificationReassignModeList = json['GetNotificationReassignModeList'];
getObjectValuesList = json['GetObjectValuesList'];
getOpenMissingSwipesList: json["GetOpenMissingSwipesList"] == null ? null : GetOpenMissingSwipesList.fromJson(json["GetOpenMissingSwipesList"]);
getOpenNotificationsList:
json["GetOpenNotificationsList"] == null ? null : List<GetOpenNotificationsList>.from(json["GetOpenNotificationsList"].map((x) => GetOpenNotificationsList.fromMap(x)));
getOpenMissingSwipesList = json["GetOpenMissingSwipesList"] == null ? null : GetOpenMissingSwipesList.fromJson(json["GetOpenMissingSwipesList"]);
getOpenNotificationsList = json["GetOpenNotificationsList"] == null ? null : List<GetOpenNotificationsList>.from(json["GetOpenNotificationsList"].map((x) => GetOpenNotificationsList.fromMap(x)));
getOpenNotificationsNumList = json['GetOpenNotificationsNumList'];
getOpenPeriodDatesList = json['GetOpenPeriodDatesList'];
getOrganizationsSalariesList = json['GetOrganizationsSalariesList'];
@ -656,7 +657,14 @@ class GenericResponseModel {
getVaccinationOnHandList = json['GetVaccinationOnHandList'];
getVaccinationsList = json['GetVaccinationsList'];
getValueSetValuesList = json['GetValueSetValuesList'];
getWorkList = json['GetWorkList'];
if (json['GetWorkList'] != null) {
getWorkList = <WorkListResponseModel>[];
json['GetWorkList'].forEach((v) {
getWorkList!.add(WorkListResponseModel.fromJson(v));
});
}
hRCertificateTemplate = json['HRCertificateTemplate'];
imgURLsList = json['ImgURLsList'];
insertApInv = json['InsertApInv'];
@ -678,7 +686,7 @@ class GenericResponseModel {
listItemImagesDetails = json['List_ItemImagesDetails'];
listItemMaster = json['List_ItemMaster'];
listMedicineDetails = json['List_MedicineDetails'];
listMenu = json['List_Menu'];
listMenu = json["List_Menu"] == null ? null : List<ListMenu>.from(json["List_Menu"].map((x) => ListMenu.fromJson(x)));
listNewEmployees = json['List_NewEmployees'];
listRadScreen = json['List_RadScreen'];
logInTokenID = json['LogInTokenID'];
@ -692,7 +700,12 @@ class GenericResponseModel {
mohemmGetBusinessCardEnabledList = json['Mohemm_GetBusinessCardEnabledList'];
mohemmGetFavoriteReplacementsList = json['Mohemm_GetFavoriteReplacementsList'];
mohemmGetMobileDeviceInfobyEmpInfoList = json['Mohemm_GetMobileDeviceInfobyEmpInfoList'];
mohemmGetMobileLoginInfoList = json['Mohemm_GetMobileLoginInfoList'];
if (json['Mohemm_GetMobileLoginInfoList'] != null) {
mohemmGetMobileLoginInfoList = <GetMobileLoginInfoListModel>[];
json['Mohemm_GetMobileLoginInfoList'].forEach((v) {
mohemmGetMobileLoginInfoList!.add(new GetMobileLoginInfoListModel.fromJson(v));
});
}
mohemmGetPatientIDList = json['Mohemm_GetPatientID_List'];
mohemmITGResponseItem = json['Mohemm_ITG_ResponseItem'];
mohemmIsChangeIsActiveBusinessCardEnable = json['Mohemm_IsChangeIsActiveBusinessCardEnable'];
@ -925,7 +938,11 @@ class GenericResponseModel {
data['GetVaccinationOnHandList'] = this.getVaccinationOnHandList;
data['GetVaccinationsList'] = this.getVaccinationsList;
data['GetValueSetValuesList'] = this.getValueSetValuesList;
data['GetWorkList'] = this.getWorkList;
if (getWorkList != null) {
data['GetWorkList'] = getWorkList!.map((v) => v.toJson()).toList();
}
data['HRCertificateTemplate'] = this.hRCertificateTemplate;
data['ImgURLsList'] = this.imgURLsList;
data['InsertApInv'] = this.insertApInv;
@ -958,7 +975,9 @@ class GenericResponseModel {
data['Mohemm_GetBusinessCardEnabledList'] = this.mohemmGetBusinessCardEnabledList;
data['Mohemm_GetFavoriteReplacementsList'] = this.mohemmGetFavoriteReplacementsList;
data['Mohemm_GetMobileDeviceInfobyEmpInfoList'] = this.mohemmGetMobileDeviceInfobyEmpInfoList;
data['Mohemm_GetMobileLoginInfoList'] = this.mohemmGetMobileLoginInfoList;
if (this.mohemmGetMobileLoginInfoList != null) {
data['Mohemm_GetMobileLoginInfoList'] = this.mohemmGetMobileLoginInfoList!.map((v) => v.toJson()).toList();
}
data['Mohemm_GetPatientID_List'] = this.mohemmGetPatientIDList;
data['Mohemm_ITG_ResponseItem'] = this.mohemmITGResponseItem;
data['Mohemm_IsChangeIsActiveBusinessCardEnable'] = this.mohemmIsChangeIsActiveBusinessCardEnable;

@ -0,0 +1,64 @@
class GetMobileLoginInfoListModel {
int? iD;
int? employeeID;
int? channelID;
int? companyID;
String? deviceType;
String? deviceToken;
int? language;
int? gender;
int? loginType;
String? createdOn;
String? editedOn;
String? employeeName;
bool? businessCardPrivilege;
GetMobileLoginInfoListModel(
{this.iD,
this.employeeID,
this.channelID,
this.companyID,
this.deviceType,
this.deviceToken,
this.language,
this.gender,
this.loginType,
this.createdOn,
this.editedOn,
this.employeeName,
this.businessCardPrivilege});
GetMobileLoginInfoListModel.fromJson(Map<String, dynamic> json) {
iD = json['ID'];
employeeID = json['EmployeeID'];
channelID = json['ChannelID'];
companyID = json['CompanyID'];
deviceType = json['DeviceType'];
deviceToken = json['DeviceToken'];
language = json['Language'];
gender = json['Gender'];
loginType = json['LoginType'];
createdOn = json['CreatedOn'];
editedOn = json['EditedOn'];
employeeName = json['EmployeeName'];
businessCardPrivilege = json['BusinessCardPrivilege'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = Map<String, dynamic>();
data['ID'] = iD;
data['EmployeeID'] = employeeID;
data['ChannelID'] = channelID;
data['CompanyID'] = companyID;
data['DeviceType'] = deviceType;
data['DeviceToken'] = deviceToken;
data['Language'] = language;
data['Gender'] = gender;
data['LoginType'] = loginType;
data['CreatedOn'] = createdOn;
data['EditedOn'] = editedOn;
data['EmployeeName'] = employeeName;
data['BusinessCardPrivilege'] = businessCardPrivilege;
return data;
}
}

@ -1,3 +1,8 @@
import 'dart:convert';
import 'package:mohem_flutter_app/classes/consts.dart';
import 'package:shared_preferences/shared_preferences.dart';
class MemberInformationListModel {
String? aCTUALTERMINATIONDATE;
String? aSSIGNMENTENDDATE;
@ -27,7 +32,7 @@ class MemberInformationListModel {
String? fREQUENCY;
String? fREQUENCYMEANING;
int? fROMROWNUM;
String? gRADEID;
int? gRADEID;
String? gRADENAME;
String? hIREDATE;
int? jOBID;
@ -333,4 +338,16 @@ class MemberInformationListModel {
data['USER_STATUS'] = this.uSERSTATUS;
return data;
}
static Future<List<MemberInformationListModel>> getFromPrefs() async {
SharedPreferences prefs = await SharedPreferences.getInstance();
List encodedList = prefs.getStringList(SharedPrefsConsts.memberInformation) ?? [];
return encodedList.map((e) => MemberInformationListModel.fromJson(jsonDecode(e))).toList();
}
static void saveToPrefs(List<MemberInformationListModel> list) async {
SharedPreferences prefs = await SharedPreferences.getInstance();
List<String> encodedList = list.map((e) => jsonEncode(e.toJson())).toList();
await prefs.setStringList(SharedPrefsConsts.memberInformation, encodedList);
}
}

@ -1,3 +1,8 @@
import 'dart:convert';
import 'package:mohem_flutter_app/classes/consts.dart';
import 'package:shared_preferences/shared_preferences.dart';
class PrivilegeListModel {
int? iD;
String? serviceName;
@ -18,4 +23,16 @@ class PrivilegeListModel {
data['Previlege'] = this.previlege;
return data;
}
static Future<List<PrivilegeListModel>> getFromPrefs() async {
SharedPreferences prefs = await SharedPreferences.getInstance();
List encodedList = prefs.getStringList(SharedPrefsConsts.privilegeList) ?? [];
return encodedList.map((e) => PrivilegeListModel.fromJson(jsonDecode(e))).toList();
}
static void saveToPrefs(List<PrivilegeListModel> list) async {
SharedPreferences prefs = await SharedPreferences.getInstance();
List<String> encodedList = list.map((e) => jsonEncode(e.toJson())).toList();
await prefs.setStringList(SharedPrefsConsts.privilegeList, encodedList);
}
}

@ -0,0 +1,38 @@
import 'dart:ui';
class WorkListItemTypeModelData {
late int value;
late String name;
late String fullName;
late bool active;
late List<Color> color;
late String icon;
late String key;
late bool disable;
WorkListItemTypeModelData({required this.value, required this.name, required this.fullName, required this.active, required this.color, required this.icon, required this.key, required this.disable});
WorkListItemTypeModelData.fromJson(Map<String, dynamic> json) {
value = json['value'];
name = json['name'];
fullName = json['fullName'];
active = json['active'];
color = json['color'];
icon = json['icon'];
key = json['key'];
disable = json['disable'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = <String, dynamic>{};
data['value'] = value;
data['name'] = name;
data['fullName'] = fullName;
data['active'] = active;
data['color'] = color;
data['icon'] = icon;
data['key'] = key;
data['disable'] = disable;
return data;
}
}

@ -0,0 +1,137 @@
class WorkListResponseModel {
String? bEGINDATE;
String? dUEDATE;
String? eNDDATE;
String? fROMROLE;
int? fROMROWNUM;
String? fROMUSER;
String? fUNCTIONNAME;
String? iTEMKEY;
String? iTEMTYPE;
String? iTEMTYPEDISPLAYNAME;
String? lANGUAGE;
String? mAILSTATUS;
String? mOREINFOROLE;
int? nOTIFICATIONID;
String? nOTIFICATIONNAME;
int? nOOFROWS;
String? oRIGINALRECIPIENT;
String? pONUMBER;
int? pRIORITY;
String? pRIORITYF;
String? pRNUMBER;
String? rECIPIENTROLE;
String? rEQUESTNUMBER;
String? rEQUESTTYPE;
String? rESPONDER;
int? rOWNUM;
String? sELECTEDEMPLOYEENUMBER;
String? sTATUS;
String? sUBJECT;
int? tOROWNUM;
String? tOUSER;
WorkListResponseModel(
{this.bEGINDATE,
this.dUEDATE,
this.eNDDATE,
this.fROMROLE,
this.fROMROWNUM,
this.fROMUSER,
this.fUNCTIONNAME,
this.iTEMKEY,
this.iTEMTYPE,
this.iTEMTYPEDISPLAYNAME,
this.lANGUAGE,
this.mAILSTATUS,
this.mOREINFOROLE,
this.nOTIFICATIONID,
this.nOTIFICATIONNAME,
this.nOOFROWS,
this.oRIGINALRECIPIENT,
this.pONUMBER,
this.pRIORITY,
this.pRIORITYF,
this.pRNUMBER,
this.rECIPIENTROLE,
this.rEQUESTNUMBER,
this.rEQUESTTYPE,
this.rESPONDER,
this.rOWNUM,
this.sELECTEDEMPLOYEENUMBER,
this.sTATUS,
this.sUBJECT,
this.tOROWNUM,
this.tOUSER});
WorkListResponseModel.fromJson(Map<String, dynamic> json) {
bEGINDATE = json['BEGIN_DATE'];
dUEDATE = json['DUE_DATE'];
eNDDATE = json['END_DATE'];
fROMROLE = json['FROM_ROLE'];
fROMROWNUM = json['FROM_ROW_NUM'];
fROMUSER = json['FROM_USER'];
fUNCTIONNAME = json['FUNCTION_NAME'];
iTEMKEY = json['ITEM_KEY'];
iTEMTYPE = json['ITEM_TYPE'];
iTEMTYPEDISPLAYNAME = json['ITEM_TYPE_DISPLAY_NAME'];
lANGUAGE = json['LANGUAGE'];
mAILSTATUS = json['MAIL_STATUS'];
mOREINFOROLE = json['MORE_INFO_ROLE'];
nOTIFICATIONID = json['NOTIFICATION_ID'];
nOTIFICATIONNAME = json['NOTIFICATION_NAME'];
nOOFROWS = json['NO_OF_ROWS'];
oRIGINALRECIPIENT = json['ORIGINAL_RECIPIENT'];
pONUMBER = json['PO_NUMBER'];
pRIORITY = json['PRIORITY'];
pRIORITYF = json['PRIORITY_F'];
pRNUMBER = json['PR_NUMBER'];
rECIPIENTROLE = json['RECIPIENT_ROLE'];
rEQUESTNUMBER = json['REQUEST_NUMBER'];
rEQUESTTYPE = json['REQUEST_TYPE'];
rESPONDER = json['RESPONDER'];
rOWNUM = json['ROW_NUM'];
sELECTEDEMPLOYEENUMBER = json['SELECTED_EMPLOYEE_NUMBER'];
sTATUS = json['STATUS'];
sUBJECT = json['SUBJECT'];
tOROWNUM = json['TO_ROW_NUM'];
tOUSER = json['TO_USER'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['BEGIN_DATE'] = this.bEGINDATE;
data['DUE_DATE'] = this.dUEDATE;
data['END_DATE'] = this.eNDDATE;
data['FROM_ROLE'] = this.fROMROLE;
data['FROM_ROW_NUM'] = this.fROMROWNUM;
data['FROM_USER'] = this.fROMUSER;
data['FUNCTION_NAME'] = this.fUNCTIONNAME;
data['ITEM_KEY'] = this.iTEMKEY;
data['ITEM_TYPE'] = this.iTEMTYPE;
data['ITEM_TYPE_DISPLAY_NAME'] = this.iTEMTYPEDISPLAYNAME;
data['LANGUAGE'] = this.lANGUAGE;
data['MAIL_STATUS'] = this.mAILSTATUS;
data['MORE_INFO_ROLE'] = this.mOREINFOROLE;
data['NOTIFICATION_ID'] = this.nOTIFICATIONID;
data['NOTIFICATION_NAME'] = this.nOTIFICATIONNAME;
data['NO_OF_ROWS'] = this.nOOFROWS;
data['ORIGINAL_RECIPIENT'] = this.oRIGINALRECIPIENT;
data['PO_NUMBER'] = this.pONUMBER;
data['PRIORITY'] = this.pRIORITY;
data['PRIORITY_F'] = this.pRIORITYF;
data['PR_NUMBER'] = this.pRNUMBER;
data['RECIPIENT_ROLE'] = this.rECIPIENTROLE;
data['REQUEST_NUMBER'] = this.rEQUESTNUMBER;
data['REQUEST_TYPE'] = this.rEQUESTTYPE;
data['RESPONDER'] = this.rESPONDER;
data['ROW_NUM'] = this.rOWNUM;
data['SELECTED_EMPLOYEE_NUMBER'] = this.sELECTEDEMPLOYEENUMBER;
data['STATUS'] = this.sTATUS;
data['SUBJECT'] = this.sUBJECT;
data['TO_ROW_NUM'] = this.tOROWNUM;
data['TO_USER'] = this.tOUSER;
return data;
}
}

@ -0,0 +1,190 @@
import 'dart:convert';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:mohem_flutter_app/api/dashboard_api_client.dart';
import 'package:mohem_flutter_app/classes/utils.dart';
import 'package:mohem_flutter_app/main.dart';
import 'package:mohem_flutter_app/models/dashboard/get_attendance_tracking_list_model.dart';
import 'package:mohem_flutter_app/models/dashboard/get_open_notifications_list.dart';
import 'package:mohem_flutter_app/models/dashboard/itg_forms_model.dart';
import 'package:mohem_flutter_app/models/dashboard/menu_entries.dart';
import 'package:mohem_flutter_app/models/dashboard/menus.dart';
import 'package:mohem_flutter_app/models/generic_response_model.dart';
import 'package:mohem_flutter_app/widgets/Updater.dart';
/// Mix-in [DiagnosticableTreeMixin] to have access to [debugFillProperties] for the devtool
// ignore: prefer_mixin
class DashboardProviderModel with ChangeNotifier, DiagnosticableTreeMixin {
//Attendance Tracking
bool isAttendanceTrackingLoading = true;
int endTime = 0, isTimeRemainingInSeconds = 0;
double progress = 0.0;
GetAttendanceTracking? attendanceTracking;
//Work List
bool isWorkListLoading = true;
int workListCounter = 0;
//Misssing Swipe
bool isMissingSwipeLoading = true;
int missingSwipeCounter = 0;
//Leave and Ticket Balance
bool isLeaveTicketBalanceLoading = true;
double leaveBalance = 0;
double ticketBalance = 0;
//Menu Entries
bool isServicesMenusLoading = true;
List<Menus>? homeMenus;
List<GetMenuEntriesList>? getMenuEntriesList;
//Attendance Tracking API's & Methods
Future<bool> fetchAttendanceTracking() async {
try {
attendanceTracking = await DashboardApiClient().getAttendanceTracking();
print("attendanceTracking:" + (attendanceTracking!.pRemainingHours).toString());
isAttendanceTrackingLoading = false;
// isTimeRemainingInSeconds = calculateSeconds( "00:00:00");
if (attendanceTracking?.pSwipeIn != null) {
isTimeRemainingInSeconds = calculateSeconds(attendanceTracking!.pRemainingHours ?? "00:00:00");
int totalShiftTimeInSeconds = calculateSeconds(attendanceTracking!.pScheduledHours ?? "00:00:00");
print("totalShiftTimeInSeconds: " + totalShiftTimeInSeconds.toString());
print("isTimeRemainingInSeconds: " + isTimeRemainingInSeconds.toString());
progress = (isTimeRemainingInSeconds / totalShiftTimeInSeconds);
endTime = DateTime.now().millisecondsSinceEpoch + Duration(seconds: isTimeRemainingInSeconds).inMilliseconds;
print("endTime " + endTime.toString());
}
notifyListeners();
} catch (ex) {
Utils.handleException(ex, null);
}
return true;
}
int calculateSeconds(String time) {
int hour = int.parse(time.split(":")[0]);
int mints = int.parse(time.split(":")[1]);
int seconds = int.parse(time.split(":")[2]);
return ((hour * 60 * 60) + (mints * 60) + seconds);
}
update() {
fetchAttendanceTracking();
// isAttendanceTrackingLoading = !isAttendanceTrackingLoading;
// isWorkListLoading = !isWorkListLoading;
// attendanceTracking?.pSwipeIn = "a";
// isTimeRemainingInSeconds = calculateSeconds("00:10:30");
// endTime = DateTime.now().millisecondsSinceEpoch + Duration(seconds: isTimeRemainingInSeconds).inMilliseconds;
// notifyListeners();
}
ItgFormsModel? itgFormsModel;
List<GetOpenNotificationsList>? getOpenNotificationsList;
//Work List API's & Methods
Future fetchWorkListCounter(context, {bool showLoading = false}) async {
try {
if (showLoading) Utils.showLoading(context);
GenericResponseModel? genericResponseModel = await DashboardApiClient().getOpenNotifications();
isWorkListLoading = false;
getOpenNotificationsList = genericResponseModel?.getOpenNotificationsList;
workListCounter = genericResponseModel?.pOPENNTFNUMBER ?? 0;
itgFormsModel = await DashboardApiClient().getItgFormsPendingTask();
workListCounter = workListCounter + (itgFormsModel?.totalCount ?? 0);
if (showLoading) Utils.hideLoading(context);
notifyListeners();
} catch (ex) {
isWorkListLoading = false;
logger.wtf(ex);
if (showLoading) Utils.hideLoading(context);
notifyListeners();
Utils.handleException(ex, null);
}
}
//Missing Siwpe API's & Methods
Future fetchMissingSwipe() async {
try {
GenericResponseModel? genericResponseModel = await DashboardApiClient().getOpenMissingSwipes();
isMissingSwipeLoading = false;
missingSwipeCounter = genericResponseModel!.getOpenMissingSwipesList!.pOpenMissingSwipes ?? 0;
notifyListeners();
} catch (ex) {
isMissingSwipeLoading = false;
logger.wtf(ex);
notifyListeners();
Utils.handleException(ex, null);
}
}
//Leave and Ticket Balance API's & Methods
Future fetchLeaveTicketBalance() async {
try {
GenericResponseModel? genericResponseModel = await DashboardApiClient().getAccrualBalances();
isLeaveTicketBalanceLoading = false;
leaveBalance = genericResponseModel?.getAccrualBalancesList![0].accrualNetEntitlement ?? 0.0;
ticketBalance = (genericResponseModel?.getAccrualBalancesList![1].accrualNetEntitlement ?? 0.0) + (genericResponseModel?.getAccrualBalancesList![2].accrualNetEntitlement ?? 0.0);
notifyListeners();
} catch (ex) {
isLeaveTicketBalanceLoading = false;
logger.wtf(ex);
notifyListeners();
Utils.handleException(ex, null);
}
}
//List Menu API's & Methods
fetchListMenu() async {
try {
GenericResponseModel? genericResponseModel = await DashboardApiClient().getListMenu();
Map<String, String> map = {};
print(jsonEncode(genericResponseModel!.listMenu));
for (int i = 0; i < genericResponseModel.listMenu!.length; i++) {
print(genericResponseModel.listMenu![i].menuName ?? "");
map[genericResponseModel.listMenu![i].menuName ?? ""] = i.toString();
}
logger.i(map);
notifyListeners();
} catch (ex) {
logger.wtf(ex);
notifyListeners();
Utils.handleException(ex, null);
}
}
//Menu Entries API's & Methods
fetchMenuEntries() async {
try {
GenericResponseModel? genericResponseModel = await DashboardApiClient().getGetMenuEntries();
getMenuEntriesList = genericResponseModel!.getMenuEntriesList;
homeMenus = parseMenues(getMenuEntriesList ?? []);
isServicesMenusLoading = false;
notifyListeners();
} catch (ex) {
logger.wtf(ex);
notifyListeners();
Utils.handleException(ex, null);
}
}
List<Menus> parseMenues(List<GetMenuEntriesList> getMenuEntriesList) {
List<Menus> menus = [];
for (int i = 0; i < getMenuEntriesList.length; i++) {
if (getMenuEntriesList[i].parentMenuName!.isEmpty) {
menus.add(Menus(getMenuEntriesList[i], getMenuEntriesList.where((element) => getMenuEntriesList[i].menuName == element.parentMenuName).toList()));
}
}
// Verify Menus by printing in log
// for(int i=0;i<menus.length;i++){
// logger.i(jsonEncode(menus[i].menuEntry.prompt));
// for(int j=0;j<menus[i].menuEntiesList.length;j++){
// logger.e(menus[i].menuEntiesList[j].prompt);
// }
// }
return menus;
}
}

@ -1,26 +0,0 @@
import 'package:easy_localization/src/public_ext.dart';
import 'package:flutter/material.dart';
import 'package:mohem_flutter_app/classes/colors.dart';
import 'package:mohem_flutter_app/generated/locale_keys.g.dart';
import 'package:mohem_flutter_app/extensions/string_extensions.dart';
AppBar appBar(BuildContext context, {required String title}) {
return AppBar(
title: title.toText24(color: MyColors.darkTextColor),
centerTitle: false,
automaticallyImplyLeading: false,
backgroundColor: Colors.white,
actions: [
IconButton(
onPressed: () {
Navigator.pop(context);
},
icon: Icon(
Icons.close,
color: MyColors.darkIconColor,
),
),
],
);
}

@ -1,379 +0,0 @@
import 'package:easy_localization/src/public_ext.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:mohem_flutter_app/api/dashboard_api_client.dart';
import 'package:mohem_flutter_app/classes/colors.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/theme/colors.dart';
import 'package:mohem_flutter_app/widgets/circular_avatar.dart';
import 'package:shimmer/shimmer.dart';
class Dashboard extends StatefulWidget {
Dashboard({Key? key}) : super(key: key);
@override
_DashboardState createState() {
return _DashboardState();
}
}
class _DashboardState extends State<Dashboard> {
@override
void initState() {
super.initState();
DashbaordApiClient().getAttendanceTracking();
}
@override
void dispose() {
super.dispose();
}
@override
Widget build(BuildContext context) {
List<String> names = [LocaleKeys.workList.tr(), LocaleKeys.missingSwipes.tr(), LocaleKeys.leaveBalance.tr(), LocaleKeys.ticketBalance.tr()];
List<double> namesInt = [118, 02, 18.5, 03];
List<int> namesColor = [0xff125765, 0xff239D8F, 0xff2BB8A8, 0xff1D92AA];
List<String> namesT = [LocaleKeys.monthlyAttendance.tr(), LocaleKeys.workFromHome.tr(), LocaleKeys.ticketRequest.tr(), LocaleKeys.monthlyAttendance.tr()];
List<String> iconT = ["assets/images/monthly_attendance.svg", "assets/images/work_from_home.svg", "assets/images/ticket_request.svg", "assets/images/work_from_home.svg"];
List<String> namesD = ["Nostalgia Perfume Perfume", "Al Nafoura", "AlJadi", "Nostalgia Perfume"];
// DashbaordApiClient().getOpenNotifications();
DashbaordApiClient().getOpenMissingSwipes();
return Scaffold(
body: Column(
children: [
Row(
children: [
Row(
mainAxisSize: MainAxisSize.min,
children: [
CircularAvatar(
width: 34,
height: 34,
url: "https://cdn4.iconfinder.com/data/icons/professions-2-2/151/89-512.png",
),
8.width,
SvgPicture.asset("assets/images/side_nav.svg"),
],
).onPress(() {}),
Expanded(
child: Row(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
mainAxisSize: MainAxisSize.min,
children: [
//AppLogo(),
8.width,
LocaleKeys.mohemm.tr().toText14()
],
),
),
SizedBox(
width: 36,
height: 36,
child: Stack(
alignment: Alignment.centerLeft,
children: [
SvgPicture.asset("assets/images/announcements.svg"),
Positioned(
right: 0,
top: 0,
child: Container(
padding: const EdgeInsets.only(left: 5, right: 5),
decoration: BoxDecoration(color: MyColors.redColor, borderRadius: BorderRadius.circular(17)),
child: "3".toText12(color: Colors.white),
),
)
],
),
)
],
).paddingOnly(left: 21, right: 21, top: 48, bottom: 7),
Expanded(
child: ListView(
padding: EdgeInsets.zero,
children: [
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
LocaleKeys.goodMorning.tr().toText14(color: MyColors.grey77Color),
"Mahmoud Shrouf".toText24(isBold: true),
16.height,
Row(
children: [
Expanded(
child: AspectRatio(
aspectRatio: 159 / 159,
child: Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(15),
gradient: const LinearGradient(transform: GradientRotation(.46), begin: Alignment.topRight, end: Alignment.bottomRight, colors: [
MyColors.gradiantEndColor,
MyColors.gradiantStartColor,
]),
),
child: Stack(
alignment: Alignment.center,
children: [
// SvgPicture.asset("assets/images/"),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Expanded(
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
LocaleKeys.markAttendance.tr().toText14(color: Colors.white, isBold: true),
9.height,
"07:55:12".toText14(color: Colors.white, isBold: true),
LocaleKeys.timeLeftToday.tr().toText12(color: Colors.white),
9.height,
const ClipRRect(
borderRadius: BorderRadius.all(
Radius.circular(20),
),
child: LinearProgressIndicator(
value: 0.7,
minHeight: 8,
valueColor: const AlwaysStoppedAnimation<Color>(Colors.white),
backgroundColor: const Color(0xff196D73),
),
),
],
).paddingOnly(top: 12, right: 15, left: 12),
),
Row(
children: [
Expanded(
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [LocaleKeys.checkIn.tr().toText12(color: Colors.white), "09:00".toText14(color: Colors.white, isBold: true), 4.height],
).paddingOnly(left: 12),
),
Container(
width: 45,
height: 45,
padding: const EdgeInsets.only(left: 14, right: 14),
decoration: const BoxDecoration(
color: Color(0xff259EA4),
borderRadius: BorderRadius.only(
bottomRight: Radius.circular(15),
),
),
child: SvgPicture.asset("assets/images/stop.svg"),
),
],
),
],
),
],
),
).onPress(() {
Navigator.pushNamed(context, AppRoutes.todayAttendance);
}),
),
),
9.width,
Expanded(
child: GridView.builder(
shrinkWrap: true,
primary: false,
physics: const NeverScrollableScrollPhysics(),
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 2, childAspectRatio: 2 / 2, crossAxisSpacing: 9, mainAxisSpacing: 9),
padding: EdgeInsets.zero,
itemCount: 4,
itemBuilder: (BuildContext context, int index) {
return Container(
decoration: BoxDecoration(
color: Color(namesColor[index]),
borderRadius: BorderRadius.circular(10),
),
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
names[index].toText12(color: Colors.white),
Row(
children: [
Expanded(
child: namesInt[index].toStringAsFixed(1).toText16(color: Colors.white, isBold: true),
),
SvgPicture.asset("assets/images/arrow_next.svg", color: Colors.white)
],
)
],
).paddingOnly(left: 10, right: 10, bottom: 6, top: 6),
).onPress(() {
Navigator.pushNamed(context, AppRoutes.workList);
});
},
),
),
],
),
20.height,
Row(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: [
"Other".tr().toText12(),
LocaleKeys.services.tr().toText24(isBold: true),
],
),
),
LocaleKeys.viewAllServices.tr().toText12(isUnderLine: true),
],
),
],
).paddingOnly(left: 21, right: 21, top: 7),
SizedBox(
height: 105 + 26,
child: ListView.separated(
shrinkWrap: true,
physics: const BouncingScrollPhysics(),
padding: const EdgeInsets.only(left: 21, right: 21, top: 13, bottom: 13),
scrollDirection: Axis.horizontal,
itemBuilder: (cxt, index) {
return AspectRatio(
aspectRatio: 105 / 105,
child: Container(
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(15),
boxShadow: [
BoxShadow(
color: const Color(0xff000000).withOpacity(.05),
blurRadius: 26,
offset: const Offset(0, -3),
),
],
),
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
SvgPicture.asset(iconT[index]),
Row(
crossAxisAlignment: CrossAxisAlignment.end,
children: [
Expanded(
child: namesT[index].toText11(isBold: true),
),
SvgPicture.asset("assets/images/arrow_next.svg").paddingOnly(bottom: 4)
],
)
],
).paddingOnly(left: 10, right: 10, bottom: 10, top: 12),
),
);
},
separatorBuilder: (cxt, index) => 9.width,
itemCount: 4),
),
8.height,
Container(
width: double.infinity,
padding: EdgeInsets.only(top: 31),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.only(topRight: Radius.circular(50), topLeft: Radius.circular(50)),
border: Border.all(color: MyColors.lightGreyEDColor, width: 1),
),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Row(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: [
LocaleKeys.offers.tr().toText12(),
Row(
children: [
LocaleKeys.discounts.tr().toText24(isBold: true),
6.width,
Container(
padding: const EdgeInsets.only(left: 8, right: 8),
decoration: BoxDecoration(
color: MyColors.yellowColor,
borderRadius: BorderRadius.circular(10),
),
child: LocaleKeys.newString.tr().toText10(isBold: true)),
],
),
],
),
),
LocaleKeys.viewAllOffers.tr().toText12(isUnderLine: true),
],
).paddingOnly(left: 21, right: 21),
SizedBox(
height: 103 + 33,
child: ListView.separated(
shrinkWrap: true,
physics: const BouncingScrollPhysics(),
padding: const EdgeInsets.only(left: 21, right: 21, top: 13),
scrollDirection: Axis.horizontal,
itemBuilder: (cxt, index) {
return SizedBox(
width: 73,
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Container(
width: 73,
height: 73,
decoration: BoxDecoration(
borderRadius: const BorderRadius.all(
Radius.circular(100),
),
border: Border.all(color: MyColors.lightGreyEDColor, width: 1),
),
child: ClipRRect(
borderRadius: const BorderRadius.all(
Radius.circular(50),
),
child: Image.network(
"https://play-lh.googleusercontent.com/NPo88ojmhah4HDiposucJmfQIop4z4xc8kqJK9ITO9o-yCab2zxIp7PPB_XPj2iUojo",
fit: BoxFit.cover,
),
),
),
4.height,
Expanded(
child: namesD[6 % (index + 1)].toText12(isCenter: true, maxLine: 2),
),
],
),
);
},
separatorBuilder: (cxt, index) => 8.width,
itemCount: 6),
),
],
),
)
],
),
)
],
),
);
}
}

@ -0,0 +1,390 @@
import 'package:easy_localization/src/public_ext.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_countdown_timer/flutter_countdown_timer.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:mohem_flutter_app/classes/colors.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/provider/dashboard_provider_model.dart';
import 'package:mohem_flutter_app/ui/landing/widget/menus_widget.dart';
import 'package:mohem_flutter_app/ui/landing/widget/services_widget.dart';
import 'package:mohem_flutter_app/widgets/circular_avatar.dart';
import 'package:mohem_flutter_app/widgets/shimmer/dashboard_shimmer_widget.dart';
import 'package:provider/provider.dart';
class DashboardScreen extends StatefulWidget {
DashboardScreen({Key? key}) : super(key: key);
@override
_DashboardScreenState createState() {
return _DashboardScreenState();
}
}
class _DashboardScreenState extends State<DashboardScreen> {
late DashboardProviderModel data;
@override
void initState() {
super.initState();
data = Provider.of<DashboardProviderModel>(context, listen: false);
data.fetchAttendanceTracking();
data.fetchWorkListCounter(context);
data.fetchMissingSwipe();
data.fetchLeaveTicketBalance();
data.fetchMenuEntries();
}
@override
void dispose() {
super.dispose();
}
@override
Widget build(BuildContext context) {
List<String> namesD = ["Nostalgia Perfume Perfume", "Al Nafoura", "AlJadi", "Nostalgia Perfume"];
return Scaffold(
body: Column(
children: [
Row(
children: [
Row(
mainAxisSize: MainAxisSize.min,
children: [
CircularAvatar(
width: 34,
height: 34,
url: "https://cdn4.iconfinder.com/data/icons/professions-2-2/151/89-512.png",
),
8.width,
SvgPicture.asset("assets/images/side_nav.svg"),
],
).onPress(() {}),
Expanded(
child: Row(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
mainAxisSize: MainAxisSize.min,
children: [
//AppLogo(),
8.width,
LocaleKeys.mohemm.tr().toText14()
],
),
),
SizedBox(
width: 36,
height: 36,
child: Stack(
alignment: Alignment.centerLeft,
children: [
SvgPicture.asset("assets/images/announcements.svg"),
Positioned(
right: 0,
top: 0,
child: Container(
padding: const EdgeInsets.only(left: 5, right: 5),
decoration: BoxDecoration(color: MyColors.redColor, borderRadius: BorderRadius.circular(17)),
child: "3".toText12(color: Colors.white),
),
)
],
),
).onPress(() {
data.update();
})
],
).paddingOnly(left: 21, right: 21, top: 48, bottom: 7),
Expanded(
child: Column(
// padding: EdgeInsets.zero,
// physics: NeverScrollableScrollPhysics(),
children: [
Expanded(
child: SingleChildScrollView(
child: Column(
children: [
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
LocaleKeys.goodMorning.tr().toText14(color: MyColors.grey77Color),
"Mahmoud Shrouf".toText24(isBold: true),
16.height,
Row(
children: [
Expanded(
child: AspectRatio(
aspectRatio: 159 / 159,
child: Consumer<DashboardProviderModel>(
builder: (context, model, child) {
return (model.isAttendanceTrackingLoading
? GetAttendanceTrackingShimmer()
: Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(15),
gradient: const LinearGradient(transform: GradientRotation(.46), begin: Alignment.topRight, end: Alignment.bottomLeft, colors: [
MyColors.gradiantEndColor,
MyColors.gradiantStartColor,
]),
),
child: Stack(
alignment: Alignment.center,
children: [
if (model.isTimeRemainingInSeconds == 0) SvgPicture.asset("assets/images/thumb.svg"),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Expanded(
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
LocaleKeys.markAttendance.tr().toText14(color: Colors.white, isBold: true),
if (model.isTimeRemainingInSeconds == 0) "01-02-2022".toText12(color: Colors.white),
if (model.isTimeRemainingInSeconds != 0)
Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
9.height,
CountdownTimer(
endTime: model.endTime,
onEnd: null,
endWidget: "00:00:00".toText14(color: Colors.white, isBold: true),
textStyle: TextStyle(color: Colors.white, fontSize: 14, letterSpacing: -0.48, fontWeight: FontWeight.bold),
),
LocaleKeys.timeLeftToday.tr().toText12(color: Colors.white),
9.height,
ClipRRect(
borderRadius: BorderRadius.all(
Radius.circular(20),
),
child: LinearProgressIndicator(
value: model.progress,
minHeight: 8,
valueColor: const AlwaysStoppedAnimation<Color>(Colors.white),
backgroundColor: const Color(0xff196D73),
),
),
],
),
],
).paddingOnly(top: 12, right: 15, left: 12),
),
Row(
children: [
Expanded(
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
LocaleKeys.checkIn.tr().toText12(color: Colors.white),
(model.attendanceTracking!.pSwipeIn == null ? "--:--" : model.attendanceTracking!.pSwipeIn)
.toString()
.toText14(color: Colors.white, isBold: true),
4.height,
],
).paddingOnly(left: 12),
),
Container(
width: 45,
height: 45,
padding: const EdgeInsets.only(left: 14, right: 14),
decoration: const BoxDecoration(
color: Color(0xff259EA4),
borderRadius: BorderRadius.only(
bottomRight: Radius.circular(15),
),
),
child: SvgPicture.asset(model.isTimeRemainingInSeconds == 0 ? "assets/images/play.svg" : "assets/images/stop.svg"),
),
],
),
],
),
],
),
).onPress(() {
Navigator.pushNamed(context, AppRoutes.todayAttendance);
}))
.animatedSwither();
},
),
),
),
9.width,
Expanded(
child: MenusWidget(),
),
],
),
20.height,
],
).paddingOnly(left: 21, right: 21, top: 7),
ServicesWidget(),
8.height,
],
),
),
),
Container(
width: double.infinity,
padding: EdgeInsets.only(top: 31),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.only(topRight: Radius.circular(50), topLeft: Radius.circular(50)),
border: Border.all(color: MyColors.lightGreyEDColor, width: 1),
),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Row(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: [
LocaleKeys.offers.tr().toText12(),
Row(
children: [
LocaleKeys.discounts.tr().toText24(isBold: true),
6.width,
Container(
padding: const EdgeInsets.only(left: 8, right: 8),
decoration: BoxDecoration(
color: MyColors.yellowColor,
borderRadius: BorderRadius.circular(10),
),
child: LocaleKeys.newString.tr().toText10(isBold: true)),
],
),
],
),
),
LocaleKeys.viewAllOffers.tr().toText12(isUnderLine: true),
],
).paddingOnly(left: 21, right: 21),
SizedBox(
height: 103 + 33,
child: ListView.separated(
shrinkWrap: true,
physics: const BouncingScrollPhysics(),
padding: const EdgeInsets.only(left: 21, right: 21, top: 13),
scrollDirection: Axis.horizontal,
itemBuilder: (cxt, index) {
return SizedBox(
width: 73,
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Container(
width: 73,
height: 73,
decoration: BoxDecoration(
borderRadius: const BorderRadius.all(
Radius.circular(100),
),
border: Border.all(color: MyColors.lightGreyEDColor, width: 1),
),
child: ClipRRect(
borderRadius: const BorderRadius.all(
Radius.circular(50),
),
child: Image.network(
"https://play-lh.googleusercontent.com/NPo88ojmhah4HDiposucJmfQIop4z4xc8kqJK9ITO9o-yCab2zxIp7PPB_XPj2iUojo",
fit: BoxFit.cover,
),
),
),
4.height,
Expanded(
child: namesD[6 % (index + 1)].toText12(isCenter: true, maxLine: 2),
),
],
),
);
},
separatorBuilder: (cxt, index) => 8.width,
itemCount: 6),
),
],
),
)
],
),
)
],
),
bottomNavigationBar: BottomNavigationBar(
items: <BottomNavigationBarItem>[
BottomNavigationBarItem(
icon: Padding(
padding: const EdgeInsets.all(4.0),
child: SvgPicture.asset(
"assets/icons/home.svg",
width: 20,
height: 20,
),
),
label: 'Home',
),
BottomNavigationBarItem(
icon: Padding(
padding: const EdgeInsets.all(4.0),
child: SvgPicture.asset(
"assets/icons/create_req.svg",
width: 20,
height: 20,
),
),
label: 'Create Request',
),
BottomNavigationBarItem(
icon: Padding(
padding: const EdgeInsets.all(4.0),
child: SvgPicture.asset(
"assets/icons/work_list.svg",
width: 20,
height: 20,
),
),
label: 'Work List',
),
BottomNavigationBarItem(
icon: Padding(
padding: const EdgeInsets.all(4.0),
child: SvgPicture.asset(
"assets/icons/item_for_sale.svg",
width: 20,
height: 20,
),
),
label: 'Items for Sale',
),
],
currentIndex: 0,
selectedLabelStyle: TextStyle(
fontSize: 8,
color: Color(0xff989898),
fontWeight: FontWeight.w600,
),
unselectedLabelStyle: TextStyle(
fontSize: 8,
color: Color(0xff989898),
fontWeight: FontWeight.w600,
),
type: BottomNavigationBarType.fixed,
selectedItemColor: Colors.black,
backgroundColor: Color(0xffF8F8F8),
onTap: (v) {},
),
);
}
}

@ -1,12 +1,25 @@
import 'package:easy_localization/src/public_ext.dart';
import 'package:flutter/material.dart';
import 'package:flutter_countdown_timer/flutter_countdown_timer.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:google_maps_flutter/google_maps_flutter.dart';
import 'package:mohem_flutter_app/api/dashboard_api_client.dart';
import 'package:mohem_flutter_app/app_state/app_state.dart';
import 'package:mohem_flutter_app/classes/colors.dart';
import 'package:mohem_flutter_app/classes/date_uitl.dart';
import 'package:mohem_flutter_app/classes/utils.dart';
import 'package:mohem_flutter_app/extensions/int_extensions.dart';
import 'package:mohem_flutter_app/extensions/string_extensions.dart';
import 'package:mohem_flutter_app/extensions/widget_extensions.dart';
import 'package:mohem_flutter_app/generated/locale_keys.g.dart';
import 'package:mohem_flutter_app/models/generic_response_model.dart';
import 'package:mohem_flutter_app/widgets/circular_step_progress_bar.dart';
import 'package:mohem_flutter_app/widgets/nfc/nfc_reader_sheet.dart';
import 'package:nfc_manager/nfc_manager.dart';
import 'package:provider/provider.dart';
import '../../provider/dashboard_provider_model.dart';
import '../../widgets/location/Location.dart';
class TodayAttendanceScreen extends StatefulWidget {
TodayAttendanceScreen({Key? key}) : super(key: key);
@ -18,14 +31,45 @@ class TodayAttendanceScreen extends StatefulWidget {
}
class _TodayAttendanceScreenState extends State<TodayAttendanceScreen> {
ValueNotifier<dynamic> result = ValueNotifier(null);
late DashboardProviderModel data;
bool isNfcEnabled = false, isNfcLocationEnabled = false, isQrEnabled = false, isQrLocationEnabled = false, isWifiEnabled = false, isWifiLocationEnabled = false;
@override
void initState() {
super.initState();
checkAttendanceAvailablity();
data = Provider.of<DashboardProviderModel>(context, listen: false);
}
checkAttendanceAvailablity() async {
bool isAvailable = await NfcManager.instance.isAvailable();
setState(() {
AppState().privilegeListModel!.forEach((element) {
// Check availability
if (isAvailable) if (element.serviceName == "enableNFC") {
// if (element.previlege ?? false)
isNfcEnabled = true;
} else if (element.serviceName == "enableQR") {
if (element.previlege ?? false) isQrEnabled = true;
} else if (element.serviceName == "enableWIFI") {
if (element.previlege ?? false) isWifiEnabled = true;
} else if (element.serviceName == "enableLocatoinNFC") {
if (element.previlege ?? false) isNfcLocationEnabled = true;
} else if (element.serviceName == "enableLocationQR") {
if (element.previlege ?? false) isQrLocationEnabled = true;
} else if (element.serviceName == "enableLocationWIFI") {
if (element.previlege ?? false) isWifiLocationEnabled = true;
}
});
});
}
@override
void dispose() {
super.dispose();
// Stop Session
NfcManager.instance.stopSession();
}
@override
@ -37,133 +81,197 @@ class _TodayAttendanceScreenState extends State<TodayAttendanceScreen> {
icon: const Icon(Icons.arrow_back_ios, color: Colors.white),
onPressed: () => Navigator.pop(context),
),
),
backgroundColor: Colors.white,
body: ListView(
children: [
Container(
color: MyColors.backgroundBlackColor,
padding: EdgeInsets.only(top: 4,left: 21, right: 21, bottom: 21),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
"June 13, 2021".toText24(isBold: true, color: Colors.white),
LocaleKeys.timeLeftToday.tr().toText16(color: Color(0xffACACAC)),
21.height,
Center(
child: CircularStepProgressBar(
totalSteps: 16 * 4,
currentStep: 16,
width: 216,
height: 216,
selectedColor: MyColors.gradiantEndColor,
unselectedColor: MyColors.grey70Color,
child: Center(
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
"08:58:15".toText32(color: Colors.white, isBold: true),
19.height,
"Shift Time".tr().toText12(color: MyColors.greyACColor),
"08:00 - 17:00".toText22(color: Colors.white, isBold: true),
],
),
),
),
),
],
),
),
Container(
color: MyColors.backgroundBlackColor,
child: Stack(
children: [
Container(
height: 187,
padding: EdgeInsets.only(left: 31, right: 31, top: 31, bottom: 16),
decoration: BoxDecoration(
borderRadius: BorderRadius.only(topLeft: Radius.circular(25), topRight: Radius.circular(25)),
gradient: const LinearGradient(transform: GradientRotation(.64), begin: Alignment.topRight, end: Alignment.bottomRight, colors: [
MyColors.gradiantEndColor,
MyColors.gradiantStartColor,
]),
),
child: Column(
children: [
Row(
children: [commonStatusView("Check In", "09:27"), commonStatusView("Check Out", "- - : - -")],
),
21.height,
Row(
children: [commonStatusView("Late In", "00:27"), commonStatusView("Regular", "08:00")],
),
],
),
),
Container(
width: double.infinity,
decoration: BoxDecoration(borderRadius: BorderRadius.only(topLeft: Radius.circular(25), topRight: Radius.circular(25)), color: Colors.white),
margin: EdgeInsets.only(top: 187 - 31),
padding: EdgeInsets.only(left: 21, right: 21, top: 24, bottom: 24),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: [
"Mark".tr().toText12(),
"Attendance".tr().toText24(),
"Select the method to mark the attendance".tr().toText12(color: Color(0xff535353)),
24.height,
GridView(
physics: const NeverScrollableScrollPhysics(),
shrinkWrap: true,
padding: EdgeInsets.zero,
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 3, childAspectRatio: 1 / 1, crossAxisSpacing: 8, mainAxisSpacing: 8),
children: <Widget>[
attendanceMethod("NFC", "assets/images/nfc.svg", () {}),
attendanceMethod("Wifi", "assets/images/wufu.svg", () {}),
],
)
],
),
),
// Positioned(
// top: 187 - 21,
// child: Container(
// padding: EdgeInsets.only(left: 31, right: 31, top: 31, bottom: 16),
// decoration: BoxDecoration(borderRadius: BorderRadius.only(topLeft: Radius.circular(25), topRight: Radius.circular(25)), color: Colors.white),
// child: Column(
// children: [
// Row(
// children: [commonStatusView("Check In", "09:27"), commonStatusView("Check Out", "- - : - -")],
// ),
// 21.height,
// Row(
// children: [commonStatusView("Late In", "00:27"), commonStatusView("Regular", "08:00")],
// ),
// ],
// ),
// ),
// ),
],
actions: [
IconButton(
onPressed: () {
data.fetchAttendanceTracking();
},
icon: Icon(
Icons.ac_unit,
color: Colors.white,
),
)
],
),
backgroundColor: MyColors.backgroundBlackColor,
body: Consumer<DashboardProviderModel>(
builder: (context, model, child) {
return (model.isAttendanceTrackingLoading
? Center(child: CircularProgressIndicator())
: ListView(
children: [
Container(
color: MyColors.backgroundBlackColor,
padding: EdgeInsets.only(top: 4, left: 21, right: 21, bottom: 21),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
DateUtil.getWeekDayMonthDayYearDateFormatted(DateTime.now(), "en").toText24(isBold: true, color: Colors.white),
LocaleKeys.timeLeftToday.tr().toText16(color: Color(0xffACACAC)),
21.height,
Center(
child: CircularStepProgressBar(
totalSteps: 16 * 4,
currentStep: (model.progress * 100).toInt(),
width: 216,
height: 216,
selectedColor: MyColors.gradiantEndColor,
unselectedColor: MyColors.grey70Color,
child: Center(
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
CountdownTimer(
endTime: model.endTime,
onEnd: null,
endWidget: "00:00:00".toText32(color: Colors.white, isBold: true),
textStyle: TextStyle(color: Colors.white, fontSize: 32, letterSpacing: -1.92, fontWeight: FontWeight.bold, height: 1),
),
19.height,
"Shift Time".tr().toText12(color: MyColors.greyACColor),
(model.attendanceTracking!.pShtName ?? "00:00:00").toString().toText22(color: Colors.white, isBold: true),
],
),
),
),
),
],
),
),
Container(
color: MyColors.backgroundBlackColor,
child: Stack(
children: [
Container(
height: 187,
padding: EdgeInsets.only(left: 31, right: 31, top: 31, bottom: 16),
decoration: BoxDecoration(
borderRadius: BorderRadius.only(topLeft: Radius.circular(25), topRight: Radius.circular(25)),
gradient: const LinearGradient(transform: GradientRotation(.64), begin: Alignment.topRight, end: Alignment.bottomLeft, colors: [
MyColors.gradiantEndColor,
MyColors.gradiantStartColor,
]),
),
child: Column(
children: [
Row(
children: [
commonStatusView("Check In", (model.attendanceTracking!.pSwipeIn) ?? "- - : - -"),
commonStatusView("Check Out", (model.attendanceTracking!.pSwipeOut) ?? "- - : - -")
],
),
21.height,
Row(
children: [
commonStatusView("Late In", (model.attendanceTracking!.pLateInHours) ?? "- - : - -"),
commonStatusView("Regular", (model.attendanceTracking!.pScheduledHours) ?? "- - : - -")
],
),
],
),
),
Container(
width: double.infinity,
decoration: BoxDecoration(borderRadius: BorderRadius.only(topLeft: Radius.circular(25), topRight: Radius.circular(25)), color: Colors.white),
margin: EdgeInsets.only(top: 187 - 31),
padding: EdgeInsets.only(left: 21, right: 21, top: 24, bottom: 24),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: [
"Mark".tr().toText12(),
"Attendance".tr().toText24(),
"Select the method to mark the attendance".tr().toText12(color: Color(0xff535353)),
24.height,
GridView(
physics: const NeverScrollableScrollPhysics(),
shrinkWrap: true,
padding: EdgeInsets.zero,
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 3, childAspectRatio: 1 / 1, crossAxisSpacing: 8, mainAxisSpacing: 8),
children: <Widget>[
attendanceMethod("NFC", "assets/images/nfc.svg", isNfcEnabled, () {
showNfcReader(context, onNcfScan: (String? nfcId) async {
print(nfcId);
Utils.showLoading(context);
try {
GenericResponseModel? g = await DashboardApiClient().markAttendance(pointType: 2, nfcValue: nfcId ?? "");
bool status = await model.fetchAttendanceTracking();
Utils.hideLoading(context);
} catch (ex) {
print(ex);
Utils.hideLoading(context);
Utils.handleException(ex, (msg) {
Utils.confirmDialog(context, msg);
});
}
});
// Location.getCurrentLocation((LatLng? latlng) {
// print(latlng!.longitude.toString());
// });
}),
attendanceMethod("Wifi", "assets/images/wufu.svg", isWifiEnabled, () {}),
],
)
],
),
),
// Positioned(
// top: 187 - 21,
// child: Container(
// padding: EdgeInsets.only(left: 31, right: 31, top: 31, bottom: 16),
// decoration: BoxDecoration(borderRadius: BorderRadius.only(topLeft: Radius.circular(25), topRight: Radius.circular(25)), color: Colors.white),
// child: Column(
// children: [
// Row(
// children: [commonStatusView("Check In", "09:27"), commonStatusView("Check Out", "- - : - -")],
// ),
// 21.height,
// Row(
// children: [commonStatusView("Late In", "00:27"), commonStatusView("Regular", "08:00")],
// ),
// ],
// ),
// ),
// ),
],
),
)
],
))
.animatedSwither();
},
),
);
}
Widget attendanceMethod(String title, String image, VoidCallback onPress) => Container(
padding: const EdgeInsets.only(left: 10, right: 10, top: 14, bottom: 14),
Widget attendanceMethod(String title, String image, bool isEnabled, VoidCallback onPress) => Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(15),
gradient: const LinearGradient(transform: GradientRotation(.64), begin: Alignment.topRight, end: Alignment.bottomRight, colors: [
gradient: const LinearGradient(transform: GradientRotation(.64), begin: Alignment.topRight, end: Alignment.bottomLeft, colors: [
MyColors.gradiantEndColor,
MyColors.gradiantStartColor,
]),
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [Expanded(child: SvgPicture.asset(image)), title.toText17(isBold: true, color: Colors.white)],
clipBehavior: Clip.antiAlias,
child: Stack(
children: [
Container(
padding: const EdgeInsets.only(left: 10, right: 10, top: 14, bottom: 14),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Expanded(child: SvgPicture.asset(image)),
title.toText17(isBold: true, color: Colors.white),
],
),
),
if (!isEnabled)
Container(
width: double.infinity,
height: double.infinity,
color: Colors.grey.withOpacity(0.7),
)
],
),
).onPress(onPress);

@ -0,0 +1,138 @@
import 'package:easy_localization/src/public_ext.dart';
import 'package:flutter/material.dart';
import 'package:flutter_svg/svg.dart';
import 'package:mohem_flutter_app/config/routes.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/provider/dashboard_provider_model.dart';
import 'package:mohem_flutter_app/widgets/shimmer/dashboard_shimmer_widget.dart';
import 'package:provider/provider.dart';
class MenusWidget extends StatelessWidget {
@override
Widget build(BuildContext context) {
List<int> namesColor = [0xff125765, 0xff239D8F, 0xff2BB8A8, 0xff1D92AA];
return Consumer<DashboardProviderModel>(builder: (cxt, data, child) {
return GridView(
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 2, childAspectRatio: 2 / 2, crossAxisSpacing: 9, mainAxisSpacing: 9),
padding: EdgeInsets.zero,
shrinkWrap: true,
primary: false,
physics: const NeverScrollableScrollPhysics(),
children: [
data.isWorkListLoading
? MenuShimmer().onPress(() {
data.fetchWorkListCounter(context, showLoading: true);
})
: Container(
decoration: BoxDecoration(
color: Color(namesColor[0]),
borderRadius: BorderRadius.circular(10),
),
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
LocaleKeys.workList.tr().toText12(color: Colors.white),
Row(
children: [
Expanded(
child: data.workListCounter.toString().toText16(color: Colors.white, isBold: true),
),
SvgPicture.asset("assets/images/arrow_next.svg", color: Colors.white)
],
)
],
).paddingOnly(left: 10, right: 10, bottom: 6, top: 6),
).onPress(() async {
//await data.fetchWorkListCounter(context, showLoading: true);
Navigator.pushNamed(context, AppRoutes.workList);
}),
data.isMissingSwipeLoading
? MenuShimmer().onPress(() {
data.fetchWorkListCounter(context);
})
: Container(
decoration: BoxDecoration(
color: Color(namesColor[1]),
borderRadius: BorderRadius.circular(10),
),
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
LocaleKeys.missingSwipes.tr().toText12(color: Colors.white),
Row(
children: [
Expanded(
child: data.missingSwipeCounter.toString().toText16(color: Colors.white, isBold: true),
),
SvgPicture.asset("assets/images/arrow_next.svg", color: Colors.white)
],
)
],
).paddingOnly(left: 10, right: 10, bottom: 6, top: 6),
).onPress(() {
Navigator.pushNamed(context, AppRoutes.workList);
}),
data.isLeaveTicketBalanceLoading
? MenuShimmer().onPress(() {
data.fetchWorkListCounter(context);
})
: Container(
decoration: BoxDecoration(
color: Color(namesColor[2]),
borderRadius: BorderRadius.circular(10),
),
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
LocaleKeys.leaveBalance.tr().toText12(color: Colors.white),
Row(
children: [
Expanded(
child: data.leaveBalance.toString().toText16(color: Colors.white, isBold: true),
),
SvgPicture.asset("assets/images/arrow_next.svg", color: Colors.white)
],
)
],
).paddingOnly(left: 10, right: 10, bottom: 6, top: 6),
).onPress(() {
Navigator.pushNamed(context, AppRoutes.workList);
}),
data.isLeaveTicketBalanceLoading
? MenuShimmer().onPress(() {
data.fetchWorkListCounter(context);
})
: Container(
decoration: BoxDecoration(
color: Color(namesColor[3]),
borderRadius: BorderRadius.circular(10),
),
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
LocaleKeys.ticketBalance.tr().toText12(color: Colors.white),
Row(
children: [
Expanded(
child: data.ticketBalance.toString().toText16(color: Colors.white, isBold: true),
),
SvgPicture.asset("assets/images/arrow_next.svg", color: Colors.white)
],
)
],
).paddingOnly(left: 10, right: 10, bottom: 6, top: 6),
).onPress(() {
Navigator.pushNamed(context, AppRoutes.workList);
})
],
);
});
}
}

@ -0,0 +1,148 @@
import 'package:easy_localization/src/public_ext.dart';
import 'package:flutter/material.dart';
import 'package:flutter_svg/svg.dart';
import 'package:mohem_flutter_app/extensions/int_extensions.dart';
import 'package:mohem_flutter_app/extensions/string_extensions.dart';
import 'package:mohem_flutter_app/extensions/widget_extensions.dart';
import 'package:mohem_flutter_app/generated/locale_keys.g.dart';
import 'package:mohem_flutter_app/provider/dashboard_provider_model.dart';
import 'package:mohem_flutter_app/widgets/shimmer/dashboard_shimmer_widget.dart';
import 'package:provider/provider.dart';
class ServicesWidget extends StatelessWidget {
@override
Widget build(BuildContext context) {
List<String> namesT = [LocaleKeys.monthlyAttendance.tr(), LocaleKeys.workFromHome.tr(), LocaleKeys.ticketRequest.tr(), LocaleKeys.monthlyAttendance.tr()];
List<String> iconT = [
"assets/images/monthly_attendance.svg",
"assets/images/work_from_home.svg",
"assets/images/ticket_request.svg",
"assets/images/work_from_home.svg",
"assets/images/work_from_home.svg",
"assets/images/work_from_home.svg",
"assets/images/work_from_home.svg",
"assets/images/work_from_home.svg"
];
return Consumer<DashboardProviderModel>(
builder: (context, data, child) {
return data.isServicesMenusLoading
? whileLoading()
: ListView.separated(
itemBuilder: (context, parentIndex) {
return Column(
children: [
Row(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: [
firstWord(data.homeMenus![parentIndex].menuEntry.prompt!).toText12(),
lastWord(data.homeMenus![parentIndex].menuEntry.prompt!).toText24(isBold: true),
],
),
),
LocaleKeys.viewAllServices.tr().toText12(isUnderLine: true),
],
).paddingOnly(left: 21, right: 21),
SizedBox(
height: 105 + 26,
child: ListView.separated(
shrinkWrap: true,
physics: const BouncingScrollPhysics(),
padding: const EdgeInsets.only(left: 21, right: 21, top: 13, bottom: 13),
scrollDirection: Axis.horizontal,
itemBuilder: (cxt, index) {
return AspectRatio(
aspectRatio: 105 / 105,
child: data.isServicesMenusLoading
? ServicesMenuShimmer()
: Container(
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(15),
boxShadow: [
BoxShadow(
color: const Color(0xff000000).withOpacity(.05),
blurRadius: 26,
offset: const Offset(0, -3),
),
],
),
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
SvgPicture.asset(iconT[index]),
Row(
crossAxisAlignment: CrossAxisAlignment.end,
children: [
Expanded(
child: data.homeMenus![parentIndex].menuEntiesList[index].prompt!.toText11(isBold: true),
),
SvgPicture.asset("assets/images/arrow_next.svg").paddingOnly(bottom: 4)
],
)
],
).paddingOnly(left: 10, right: 10, bottom: 10, top: 12),
),
);
},
separatorBuilder: (cxt, index) => 9.width,
itemCount: data.homeMenus![parentIndex].menuEntiesList.length),
),
],
);
},
separatorBuilder: (context, index) {
return 12.height;
},
shrinkWrap: true,
physics: NeverScrollableScrollPhysics(),
itemCount: data.homeMenus!.length);
},
);
}
String firstWord(String value) {
return value.split(" ").length > 1 ? value.split(" ")[0] : "";
}
String lastWord(String value) {
var parts = value.split(" ");
if (parts.length == 1) {
return value;
} else {
int i = value.indexOf(" ");
return value.substring(i + 1).toCamelCase;
}
}
Widget whileLoading() {
return Column(
children: [
ServicesHeaderShimmer().paddingOnly(left: 21, right: 21),
SizedBox(
height: 105 + 26,
child: ListView.separated(
shrinkWrap: true,
physics: const BouncingScrollPhysics(),
padding: const EdgeInsets.only(left: 21, right: 21, top: 13, bottom: 13),
scrollDirection: Axis.horizontal,
itemBuilder: (cxt, index) {
return AspectRatio(
aspectRatio: 105 / 105,
child: ServicesMenuShimmer(),
);
},
separatorBuilder: (cxt, index) => 9.width,
itemCount: 4,
),
),
],
);
}
}

@ -37,24 +37,30 @@ class _ForgotPasswordScreenState extends State<ForgotPasswordScreen> {
super.dispose();
}
void performLogin() async {
// Utils.showLoading(context);
void performForgotPassword() async {
if (employeeId.text.isEmpty) {
return;
}
Utils.showLoading(context);
try {
_basicMemberInformation = await LoginApiClient().getBasicUserInformation("CS", employeeId.text);
genericResponseModel = await LoginApiClient().sendPublicActivationCode(_basicMemberInformation?.pMOBILENUMBER, employeeId.text);
Utils.hideLoading(context);
OtpDialog(
context,
1,
int.tryParse(_basicMemberInformation?.pMOBILENUMBER ?? ""),
(value) async {
Utils.showLoading(context);
GenericResponseModel? genericResponseModel = await LoginApiClient().checkPublicActivationCode(value, employeeId.text);
if (genericResponseModel?.errorMessage != null) {
Utils.showToast(genericResponseModel?.errorMessage ?? "");
return;
}
Navigator.pushNamed(context, AppRoutes.newPassword);
// this.checkActivationCode(value: value);
Utils.hideLoading(context);
await Navigator.pushNamed(context, AppRoutes.newPassword, arguments: employeeId.text);
Navigator.pop(context);
Navigator.pop(context);
},
() => {
Navigator.pop(context),
@ -62,8 +68,8 @@ class _ForgotPasswordScreenState extends State<ForgotPasswordScreen> {
).displayDialog(context);
} catch (ex) {
print(ex);
Utils.hideLoading(context);
Utils.handleException(ex, null);
// Utils.hideLoading(context);
}
}
@ -95,7 +101,14 @@ class _ForgotPasswordScreenState extends State<ForgotPasswordScreen> {
LocaleKeys.forgotPassword.tr().toText24(isBold: true),
LocaleKeys.loginCodeWillSentToMobileNumber.tr().toText16(),
16.height,
InputWidget(LocaleKeys.employeeId.tr(), "123456", employeeId),
InputWidget(
LocaleKeys.employeeId.tr(),
"123456",
employeeId,
onChange: (value) {
setState(() {});
},
),
],
),
)
@ -103,9 +116,13 @@ class _ForgotPasswordScreenState extends State<ForgotPasswordScreen> {
),
),
),
DefaultButton(LocaleKeys.changePassword.tr(), () async {
//Navigator.pushNamed(context, AppRoutes.verifyLogin);
})
DefaultButton(
LocaleKeys.changePassword.tr(),
employeeId.text.isEmpty
? null
: () async {
performForgotPassword();
})
.insideContainer
],
),

@ -1,11 +1,15 @@
import 'dart:io';
import 'package:easy_localization/easy_localization.dart';
import 'package:easy_localization/src/public_ext.dart';
import 'package:firebase_messaging/firebase_messaging.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:mohem_flutter_app/api/login_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/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';
@ -13,7 +17,10 @@ import 'package:mohem_flutter_app/extensions/string_extensions.dart';
import 'package:mohem_flutter_app/extensions/widget_extensions.dart';
import 'package:mohem_flutter_app/generated/locale_keys.g.dart';
import 'package:mohem_flutter_app/models/check_mobile_app_version_model.dart';
import 'package:mohem_flutter_app/models/get_mobile_login_info_list_model.dart';
import 'package:mohem_flutter_app/models/member_information_list_model.dart';
import 'package:mohem_flutter_app/models/member_login_list_model.dart';
import 'package:mohem_flutter_app/models/privilege_list_model.dart';
import 'package:mohem_flutter_app/widgets/button/default_button.dart';
import 'package:mohem_flutter_app/widgets/input_widget.dart';
@ -33,9 +40,15 @@ class _LoginScreenState extends State<LoginScreen> {
CheckMobileAppVersionModel? _checkMobileAppVersion;
MemberLoginListModel? _memberLoginList;
final FirebaseMessaging _firebaseMessaging = FirebaseMessaging.instance;
bool _autoLogin = false;
@override
void initState() {
super.initState();
checkFirebaseToken();
//checkPrefs();
}
@override
@ -43,6 +56,48 @@ class _LoginScreenState extends State<LoginScreen> {
super.dispose();
}
Future<void> checkPrefs() async {
String username = await Utils.getStringFromPrefs(SharedPrefsConsts.username);
if (username.isNotEmpty) {
String password = await Utils.getStringFromPrefs(SharedPrefsConsts.password);
// String firebaseToken = await Utils.getStringFromPrefs(SharedPrefsConsts.firebaseToken);
// print("firebaseToken:$firebaseToken");
this.username.text = username;
this.password.text = password;
_autoLogin = true;
}
}
String? firebaseToken;
Future<void> checkFirebaseToken() async {
try {
Utils.showLoading(context);
firebaseToken = await _firebaseMessaging.getToken();
GetMobileLoginInfoListModel? loginInfo = await LoginApiClient().getMobileLoginInfoNEW(firebaseToken ?? "", Platform.isAndroid ? "android" : "ios");
if (loginInfo == null) {
Utils.hideLoading(context);
print("Device token not found");
return;
} else {
await checkPrefs();
Utils.hideLoading(context);
performLogin();
}
} catch (ex) {
print(ex);
Utils.hideLoading(context);
Utils.handleException(ex, null);
}
}
// Future<void> getFirebaseToken() async {
// String? firebaseToken = await _firebaseMessaging.getToken();
// if (firebaseToken != null) {
// await Utils.saveStringFromPrefs(SharedPrefsConsts.firebaseToken, firebaseToken);
// }
// }
void performLogin() async {
Utils.showLoading(context);
try {
@ -50,20 +105,30 @@ class _LoginScreenState extends State<LoginScreen> {
_memberLoginList = await LoginApiClient().memberLogin(username.text, password.text);
AppState().setMemberLoginListModel = _memberLoginList;
AppState().setUserName = username.text;
print(_memberLoginList?.toJson());
AppState().password = password.text;
if (_autoLogin) {
AppState().setMemberInformationListModel = (await MemberInformationListModel.getFromPrefs()).first;
AppState().setPrivilegeListModel = await PrivilegeListModel.getFromPrefs();
}
Utils.hideLoading(context);
Navigator.pushNamed(context, AppRoutes.verifyLogin);
if (_autoLogin) {
Navigator.pushNamed(context, AppRoutes.verifyLastLogin);
} else {
Navigator.pushNamed(context, AppRoutes.verifyLogin, arguments: "$firebaseToken");
}
} catch (ex) {
print(ex);
Utils.handleException(ex, null);
Utils.hideLoading(context);
Utils.handleException(ex, (msg) {
Utils.confirmDialog(context, msg);
});
}
}
@override
Widget build(BuildContext context) {
username.text="15153";
password.text="e123e123e123";
password.text="Xy12345@";
return Scaffold(
body: Column(
children: [
@ -79,7 +144,7 @@ class _LoginScreenState extends State<LoginScreen> {
Expanded(child: SizedBox()),
Row(
children: [
LocaleKeys.english.tr().toText14(color: MyColors.textMixColor).onPress(() {
LocaleKeys.english.tr().toText14(color: AppState().isArabic(context) ? null : MyColors.textMixColor).onPress(() {
context.setLocale(const Locale("en", "US"));
}),
Container(
@ -88,7 +153,7 @@ class _LoginScreenState extends State<LoginScreen> {
height: 16,
margin: const EdgeInsets.only(left: 10, right: 10),
),
LocaleKeys.arabic.tr().toText14().onPress(() {
LocaleKeys.arabic.tr().toText14(color: !AppState().isArabic(context) ? null : MyColors.textMixColor).onPress(() {
context.setLocale(const Locale("ar", "SA"));
}),
],

@ -1,7 +1,9 @@
import 'package:easy_localization/src/public_ext.dart';
import 'package:flutter/material.dart';
import 'package:mohem_flutter_app/api/login_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/config/routes.dart';
import 'package:mohem_flutter_app/classes/utils.dart';
import 'package:mohem_flutter_app/extensions/int_extensions.dart';
import 'package:mohem_flutter_app/extensions/string_extensions.dart';
import 'package:mohem_flutter_app/extensions/widget_extensions.dart';
@ -22,6 +24,8 @@ class _NewPasswordScreenState extends State<NewPasswordScreen> {
TextEditingController password = TextEditingController();
TextEditingController confirmPassword = TextEditingController();
String? userName;
@override
void initState() {
super.initState();
@ -32,8 +36,26 @@ class _NewPasswordScreenState extends State<NewPasswordScreen> {
super.dispose();
}
void setNewPassword() async {
Utils.showLoading(context);
try {
var genericResponseModel = await LoginApiClient().changePasswordForget(AppState().getForgetPasswordTokenID ?? "", password.text, confirmPassword.text, userName);
Utils.hideLoading(context);
Utils.showToast(LocaleKeys.passwordChangedSuccessfully.tr());
Navigator.pop(context);
} catch (ex) {
print(ex);
Utils.hideLoading(context);
Utils.handleException(ex, (msg) {
Utils.confirmDialog(context, msg);
});
}
}
@override
Widget build(BuildContext context) {
userName ??= ModalRoute.of(context)!.settings.arguments as String;
return Scaffold(
appBar: AppBar(
backgroundColor: Colors.transparent,
@ -46,53 +68,125 @@ class _NewPasswordScreenState extends State<NewPasswordScreen> {
children: [
//const SizedBox(height: 23),
Expanded(
child: Padding(
padding: const EdgeInsets.all(21.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
// Row(
// children: [
// Expanded(child: SizedBox()),
// Row(
// children: [
// LocaleKeys.english.tr().toText14(color: MyColors.textMixColor).onPress(() {}),
// Container(
// width: 1,
// color: MyColors.darkWhiteColor,
// height: 16,
// margin: const EdgeInsets.only(left: 10, right: 10),
// ),
// LocaleKeys.arabic.tr().toText14().onPress(() {}),
// ],
// ),
// ],
// ),
Expanded(
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.center,
children: [
LocaleKeys.setTheNewPassword.tr().toText24(isBold: true),
LocaleKeys.typeYourNewPasswordBelow.tr().toText16(),
16.height,
InputWidget(LocaleKeys.password.tr(), "**********", password),
12.height,
InputWidget(LocaleKeys.confirmPassword.tr(), "**********", confirmPassword, isObscureText: true)
],
),
)
],
),
),
child: ListView(
// mainAxisSize: MainAxisSize.min,
// crossAxisAlignment: CrossAxisAlignment.start,
// mainAxisAlignment: MainAxisAlignment.center,
children: [
LocaleKeys.setTheNewPassword.tr().toText24(isBold: true),
LocaleKeys.typeYourNewPasswordBelow.tr().toText16(),
16.height,
InputWidget(
LocaleKeys.password.tr(),
"**********",
password,
onChange: (value) {
setState(() {});
},
),
12.height,
InputWidget(
LocaleKeys.confirmPassword.tr(),
"**********",
confirmPassword,
isObscureText: true,
onChange: (value) {
setState(() {});
},
),
12.height,
passwordConstraintsUI(LocaleKeys.doNotUseRecentPassword.tr(), true),
8.height,
passwordConstraintsUI(LocaleKeys.atLeastOneLowercase.tr(), checkRegEx(r'[a-z]')),
8.height,
passwordConstraintsUI(LocaleKeys.atLeastOneUppercase.tr(), checkRegEx(r'[A-Z]')),
8.height,
passwordConstraintsUI(LocaleKeys.atLeastOneNumeric.tr(), checkRegEx(r'[0-9]')),
8.height,
passwordConstraintsUI(LocaleKeys.minimum8Characters.tr(), password.text.length >= 8),
8.height,
passwordConstraintsUI(LocaleKeys.doNotAddRepeatingLetters.tr(), checkRepeatedChars(password.text)),
8.height,
passwordConstraintsUI(LocaleKeys.itShouldContainSpecialCharacter.tr(), checkRegEx(r'[!@#$%^&*(),.?":{}|<>]')),
8.height,
passwordConstraintsUI(LocaleKeys.confirmPasswordMustMatch.tr(), password.text.isNotEmpty && password.text == confirmPassword.text),
12.height,
],
).paddingAll(21),
),
DefaultButton(LocaleKeys.update.tr(), () async {
// Navigator.pushNamed(context, AppRoutes.verifyLogin);
}).insideContainer
DefaultButton(
LocaleKeys.update.tr(),
(!isPasswordCompliant(password.text, 8))
? null
: () async {
setNewPassword();
})
.insideContainer
],
),
);
}
bool checkRegEx(String pattern) {
return RegExp(pattern).hasMatch(password.text);
}
String recentPassword = "";
bool checkRepeatedCharacters(String value) {
if (value.isEmpty) {
return false;
}
for (int i = 0; i < value.length; i++) {
//if(i)
}
return true;
}
bool isPasswordCompliant(String? password, int minLength) {
if (password == null || password.isEmpty) {
return false;
}
bool hasUppercase = password.contains(RegExp(r'[A-Z]'));
bool hasDigits = password.contains(RegExp(r'[0-9]'));
bool hasLowercase = password.contains(RegExp(r'[a-z]'));
bool hasSpecialCharacters = password.contains(RegExp(r'[!@#$%^&*(),.?":{}|<>]'));
bool hasMinLength = password.length >= minLength;
bool isMatched = password == confirmPassword.text;
return hasDigits && hasUppercase && hasLowercase && hasSpecialCharacters && hasMinLength && isMatched && checkRepeatedChars(password);
}
bool checkRepeatedChars(String password) {
bool isNonRepeatedLetters = true;
if (password.length > 2) {
for (int i = 0; i < password.length; i++) {
String char = password[i];
try {
if (char == password[i + 1]) {
isNonRepeatedLetters = false;
break;
}
} catch (ex) {}
}
}
return isNonRepeatedLetters;
}
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()
],
);
}
}

@ -0,0 +1,331 @@
import 'package:easy_localization/src/public_ext.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_svg/svg.dart';
import 'package:local_auth/auth_strings.dart';
import 'package:local_auth/local_auth.dart';
import 'package:mohem_flutter_app/api/login_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/date_uitl.dart';
import 'package:mohem_flutter_app/classes/utils.dart';
import 'package:mohem_flutter_app/config/routes.dart';
import 'package:mohem_flutter_app/dialogs/otp_dialog.dart';
import 'package:mohem_flutter_app/extensions/int_extensions.dart';
import 'package:mohem_flutter_app/extensions/string_extensions.dart';
import 'package:mohem_flutter_app/extensions/widget_extensions.dart';
import 'package:mohem_flutter_app/generated/locale_keys.g.dart';
import 'package:mohem_flutter_app/models/basic_member_information_model.dart';
import 'package:mohem_flutter_app/models/generic_response_model.dart';
import 'package:mohem_flutter_app/models/get_mobile_login_info_list_model.dart';
import 'package:mohem_flutter_app/widgets/button/default_button.dart';
class VerifyLastLoginScreen extends StatefulWidget {
VerifyLastLoginScreen({Key? key}) : super(key: key);
@override
_VerifyLastLoginScreenState createState() {
return _VerifyLastLoginScreenState();
}
}
class _VerifyLastLoginScreenState extends State<VerifyLastLoginScreen> {
final LocalAuthentication auth = LocalAuthentication();
List<BiometricType> _availableBioMetricType = [];
GetMobileLoginInfoListModel? mobileLoginInfoListModel;
@override
void initState() {
_getAvailableBiometrics();
// setDefault();
super.initState();
}
@override
Widget build(BuildContext context) {
mobileLoginInfoListModel ??= ModalRoute.of(context)!.settings.arguments as GetMobileLoginInfoListModel;
String empName = AppState().isArabic(context) ? AppState().memberInformationList!.eMPLOYEEDISPLAYNAMEAr! : AppState().memberInformationList!.eMPLOYEEDISPLAYNAMEEn!;
return Scaffold(
appBar: AppBar(
backgroundColor: Colors.transparent,
leading: IconButton(
icon: const Icon(Icons.arrow_back_ios, color: MyColors.darkIconColor),
onPressed: () => Navigator.pop(context),
),
actions: [Center(child: "Employee Digital ID".toText12(color: MyColors.textMixColor, isUnderLine: true).onPress(() {})), 21.width],
),
body: Column(
children: [
Expanded(
child: ListView(
padding: const EdgeInsets.all(21),
physics: const BouncingScrollPhysics(),
children: [
//12.height,
if (true)
Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
LocaleKeys.welcomeBack.tr().toText12(),
mobileLoginInfoListModel!.employeeName!.toText24(isBold: true),
10.height,
LocaleKeys.wouldYouLikeToLoginWithCurrentUsername.tr().toText16(),
Container(
height: 72,
margin: const EdgeInsets.only(top: 23, bottom: 23),
alignment: Alignment.center,
padding: const EdgeInsets.only(left: 17, right: 12),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10),
color: Colors.white,
border: Border.all(
color: const Color(0xffefefef),
width: 1,
),
),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
LocaleKeys.lastLoginDetails.tr().toText16(),
DateUtil.formatDateToDate(DateUtil.convertStringToDate(mobileLoginInfoListModel!.editedOn!), false).toText12(),
],
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
LocaleKeys.verificationType.tr().toText10(color: MyColors.grey57Color),
getVerificationType(mobileLoginInfoListModel!.loginType!).toText12(),
Expanded(child: SizedBox()),
DateUtil.formatDateToTime(DateUtil.convertStringToDate(mobileLoginInfoListModel!.editedOn!)).toText12(),
],
)
],
),
),
LocaleKeys.pleaseVerify.tr().toText16(),
GridView(
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 2, crossAxisSpacing: 13, mainAxisSpacing: 9),
physics: const NeverScrollableScrollPhysics(),
padding: const EdgeInsets.only(top: 9),
shrinkWrap: true,
children: [
getButton(3),
getButton(2),
getButton(1),
getButton(4),
],
)
],
)
// else
// Column(mainAxisAlignment: MainAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start, children: <Widget>[
// Image.asset(
// 'assets/images/habib-logo.png',
// height: 90,
// width: 90,
// ),
// SizedBox(height: 23),
// this.onlySMSBox == false
// ? Text(
// TranslationBase.of(context).verifyLoginWith,
// style: TextStyle(fontSize: 16, fontWeight: FontWeight.w600, color: Color(0xff2B353E), letterSpacing: -0.64, height: 25 / 16),
// )
// : Text(
// TranslationBase.of(context).verifyFingerprint2,
// style: TextStyle(fontSize: 16, fontWeight: FontWeight.w600, color: Color(0xff2B353E), letterSpacing: -0.64, height: 25 / 16),
// ),
// SizedBox(height: 23),
// Text(
// TranslationBase.of(context).pleaseVerify,
// style: TextStyle(fontSize: 16, fontWeight: FontWeight.w600, color: Color(0xff2E303A), letterSpacing: -0.64),
// ),
// GridView(
// gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 2, crossAxisSpacing: 13, mainAxisSpacing: 9),
// physics: NeverScrollableScrollPhysics(),
// padding: EdgeInsets.only(top: 9),
// shrinkWrap: true,
// children: [
// if (onlySMSBox == false) getButton(3),
// if (onlySMSBox == false) getButton(2),
// getButton(1),
// getButton(4),
// ],
// ),
// ]),
],
),
),
12.height,
DefaultButton(
LocaleKeys.useAnotherAccount.tr(),
() => {
//Navigator.of(context).pushNamed(LOGIN_TYPE)
},
).insideContainer,
],
),
);
}
Future<void> _getAvailableBiometrics() async {
try {
_availableBioMetricType = await auth.getAvailableBiometrics();
} on PlatformException catch (e) {
// AppToast.showErrorToast(message: e.message);
print(e);
}
if (mounted) setState(() {});
}
String getVerificationType(int type) {
if (type == 1) {
LocaleKeys.sms.tr();
} else if (type == 2) {
return LocaleKeys.fingerPrint.tr();
} else if (type == 3) {
return LocaleKeys.face.tr();
} else if (type == 4) {
return LocaleKeys.whatsapp.tr();
}
return "";
}
Future<bool> loginWithFaceIDAndBiometrics() async {
IOSAuthMessages iosStrings =
const IOSAuthMessages(cancelButton: 'cancel', goToSettingsButton: 'settings', goToSettingsDescription: 'Please set up your Touch ID.', lockOut: 'Please reenable your Touch ID');
bool authenticated = false;
try {
authenticated = await auth.authenticate(localizedReason: 'Scan your fingerprint to authenticate', useErrorDialogs: true, stickyAuth: true, iOSAuthStrings: iosStrings);
} on PlatformException catch (e) {
print(e);
Utils.hideLoading(context);
Utils.showToast("Please enable your Touch or Face ID");
}
return authenticated;
}
Widget _loginOptionButton(String _title, String _icon, int _flag, int? _loginIndex) {
bool isDisable = ((_flag == 3 && !checkBiometricIsAvailable(BiometricType.face)) || (_flag == 2 && !checkBiometricIsAvailable(BiometricType.fingerprint)));
print("$_title:$isDisable");
return InkWell(
onTap: isDisable
? null
: () async {
if (_flag == 0) {
setState(() {
// isMoreOption = true;
});
} else {
Utils.showLoading(context);
if (_flag == 2 || _flag == 3) {
bool authenticateWithFaceAndTouchID = await loginWithFaceIDAndBiometrics();
if (authenticateWithFaceAndTouchID) {
Navigator.pushNamedAndRemoveUntil(context, AppRoutes.dashboard, (Route<dynamic> route) => false);
return;
} else {
Utils.hideLoading(context);
return;
}
}
await LoginApiClient().checkMobileAppVersion();
await LoginApiClient().memberLogin(AppState().getUserName!, AppState().password!);
BasicMemberInformationModel? memberInformationModel = await LoginApiClient().mohemmSendActivationCodeByOTPNotificationType(
checkBiometricIsAvailable(BiometricType.fingerprint) ? 1 : 0, AppState().memberLoginList?.pMOBILENUMBER, _flag, AppState().getUserName);
Utils.hideLoading(context);
OtpDialog(
context,
_flag,
int.tryParse(AppState().memberLoginList?.pMOBILENUMBER ?? ""),
(value) async {
Utils.showLoading(context);
try {
GenericResponseModel? genericResponseModel = await LoginApiClient().checkActivationCode(false, AppState().memberLoginList?.pMOBILENUMBER, value, AppState().getUserName);
if (genericResponseModel?.errorMessage != null) {
Utils.showToast(genericResponseModel?.errorMessage ?? "");
// Navigator.pop(context);
}
Utils.hideLoading(context);
Navigator.pop(context);
Navigator.pushNamedAndRemoveUntil(context, AppRoutes.dashboard, (Route<dynamic> route) => false);
} catch (ex) {
print(ex);
Utils.hideLoading(context);
Utils.handleException(ex, null);
}
},
() => {
Navigator.pop(context),
},
).displayDialog(context);
// authenticateUser(_flag, isActive: _loginIndex);
}
},
child: Container(
padding: const EdgeInsets.only(left: 20, right: 20, bottom: 15, top: 28),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(15),
color: isDisable ? Colors.grey.withOpacity(0.3) : Colors.white,
border: Border.all(color: MyColors.lightGreyEFColor, width: 1),
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
SvgPicture.asset(
_icon,
height: 38,
width: 38,
color: isDisable ? MyColors.darkTextColor.withOpacity(0.7) : null,
),
_title.toText16()
],
),
),
);
}
Widget getButton(int flag) {
switch (flag) {
case 4:
return _loginOptionButton(LocaleKeys.verifyThroughWhatsapp.tr(), 'assets/images/login/verify_whatsapp.svg', flag, null);
case 1:
return _loginOptionButton(LocaleKeys.verifyThroughSMS.tr(), 'assets/images/login/verify_sms.svg', flag, null);
case 2:
return _loginOptionButton(LocaleKeys.verifyThroughFingerprint.tr(), 'assets/images/login/verify_thumb.svg', flag, BiometricType.fingerprint.index);
case 3:
return _loginOptionButton(LocaleKeys.verifyThroughFace.tr(), 'assets/images/login/verify_face.svg', flag, BiometricType.face.index);
default:
return const SizedBox();
}
}
bool checkBiometricIsAvailable(BiometricType biometricType) {
bool isAvailable = false;
for (int i = 0; i < _availableBioMetricType.length; i++) {
if (biometricType == _availableBioMetricType[i]) {
isAvailable = true;
break;
}
}
return isAvailable;
}
//
// formatDate(date) {
// return date;
// return DateFormat('MMM dd, yyy, kk:mm').format(date);
// }
//
// showLoader(bool isTrue) {
// setState(() {
// // isLoading = isTrue;
// });
// }
}

@ -1,20 +1,25 @@
import 'dart:io';
import 'package:easy_localization/src/public_ext.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_svg/svg.dart';
import 'package:local_auth/auth_strings.dart';
import 'package:local_auth/local_auth.dart';
import 'package:mohem_flutter_app/api/login_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/consts.dart';
import 'package:mohem_flutter_app/classes/utils.dart';
import 'package:mohem_flutter_app/config/routes.dart';
import 'package:mohem_flutter_app/dialogs/otp_dialog.dart';
import 'package:mohem_flutter_app/extensions/int_extensions.dart';
import 'package:mohem_flutter_app/extensions/string_extensions.dart';
import 'package:mohem_flutter_app/extensions/widget_extensions.dart';
import 'package:mohem_flutter_app/generated/locale_keys.g.dart';
import 'package:mohem_flutter_app/models/basic_member_information_model.dart';
import 'package:mohem_flutter_app/models/generic_response_model.dart';
import 'package:mohem_flutter_app/models/member_information_list_model.dart';
import 'package:mohem_flutter_app/models/privilege_list_model.dart';
import 'package:mohem_flutter_app/widgets/button/default_button.dart';
class VerifyLoginScreen extends StatefulWidget {
@ -30,6 +35,8 @@ class _VerifyLoginScreenState extends State<VerifyLoginScreen> {
final LocalAuthentication auth = LocalAuthentication();
List<BiometricType> _availableBioMetricType = [];
String? firebaseToken;
@override
void initState() {
_getAvailableBiometrics();
@ -39,6 +46,7 @@ class _VerifyLoginScreenState extends State<VerifyLoginScreen> {
@override
Widget build(BuildContext context) {
firebaseToken ??= ModalRoute.of(context)!.settings.arguments as String;
return Scaffold(
appBar: AppBar(
backgroundColor: Colors.transparent,
@ -46,7 +54,7 @@ class _VerifyLoginScreenState extends State<VerifyLoginScreen> {
icon: const Icon(Icons.arrow_back_ios, color: MyColors.darkIconColor),
onPressed: () => Navigator.pop(context),
),
actions: [Center(child: "Employee Digital ID".toText12(color: MyColors.textMixColor, isUnderLine: true).onPress(() {})), 21.width],
// actions: [Center(child: "Employee Digital ID".toText12(color: MyColors.textMixColor, isUnderLine: true).onPress(() {})), 21.width],
),
body: Column(
children: [
@ -61,69 +69,69 @@ class _VerifyLoginScreenState extends State<VerifyLoginScreen> {
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
LocaleKeys.welcomeBack.tr().toText12(),
"Mohammad Hussain".toText24(isBold: true),
10.height,
LocaleKeys.wouldYouLikeToLoginWithCurrentUsername.tr().toText16(),
Container(
height: 72,
margin: const EdgeInsets.only(top: 23, bottom: 23),
alignment: Alignment.center,
padding: EdgeInsets.only(left: 17, right: 12),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10),
color: Colors.white,
border: Border.all(
color: Color(0xffefefef),
width: 1,
),
),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
LocaleKeys.lastLoginDetails.tr().toText16(),
// Text(
// user.editedOn != null
// ? DateUtil.getDayMonthYearDateFormatted(DateUtil.convertStringToDate(user.editedOn))
// : user.createdOn != null
// ? DateUtil.getDayMonthYearDateFormatted(DateUtil.convertStringToDate(user.createdOn))
// : '--',
// style: TextStyle(fontSize: 12, fontWeight: FontWeight.w600, color: Color(0xff2B353E), letterSpacing: -0.48),
// ),
],
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
LocaleKeys.verificationType.tr().toText10(color: MyColors.grey57Color),
Text(
"SMS",
// " " + getType(user.logInType, context),
style: TextStyle(
fontSize: 12,
fontWeight: FontWeight.w600,
color: Color(0xff2B353E),
),
),
Expanded(child: SizedBox()),
// Text(
// user.editedOn != null
// ? DateUtil.formatDateToTimeLang(DateUtil.convertStringToDate(user.editedOn), false)
// : user.createdOn != null
// ? DateUtil.formatDateToTimeLang(DateUtil.convertStringToDate(user.createdOn), false)
// : '--',
// style: TextStyle(fontSize: 12, fontWeight: FontWeight.w600, color: Color(0xff575757), letterSpacing: -0.48),
// ),
],
)
],
),
),
// LocaleKeys.welcomeBack.tr().toText12(),
// "Mohammad Hussain".toText24(isBold: true),
// 10.height,
// LocaleKeys.wouldYouLikeToLoginWithCurrentUsername.tr().toText16(),
// Container(
// height: 72,
// margin: const EdgeInsets.only(top: 23, bottom: 23),
// alignment: Alignment.center,
// padding: EdgeInsets.only(left: 17, right: 12),
// decoration: BoxDecoration(
// borderRadius: BorderRadius.circular(10),
// color: Colors.white,
// border: Border.all(
// color: Color(0xffefefef),
// width: 1,
// ),
// ),
// child: Column(
// mainAxisSize: MainAxisSize.min,
// children: [
// Row(
// mainAxisAlignment: MainAxisAlignment.spaceBetween,
// crossAxisAlignment: CrossAxisAlignment.center,
// children: [
// LocaleKeys.lastLoginDetails.tr().toText16(),
// // Text(
// // user.editedOn != null
// // ? DateUtil.getDayMonthYearDateFormatted(DateUtil.convertStringToDate(user.editedOn))
// // : user.createdOn != null
// // ? DateUtil.getDayMonthYearDateFormatted(DateUtil.convertStringToDate(user.createdOn))
// // : '--',
// // style: TextStyle(fontSize: 12, fontWeight: FontWeight.w600, color: Color(0xff2B353E), letterSpacing: -0.48),
// // ),
// ],
// ),
// Row(
// mainAxisAlignment: MainAxisAlignment.spaceBetween,
// crossAxisAlignment: CrossAxisAlignment.center,
// children: [
// LocaleKeys.verificationType.tr().toText10(color: MyColors.grey57Color),
// Text(
// "SMS",
// // " " + getType(user.logInType, context),
// style: TextStyle(
// fontSize: 12,
// fontWeight: FontWeight.w600,
// color: Color(0xff2B353E),
// ),
// ),
// Expanded(child: SizedBox()),
// // Text(
// // user.editedOn != null
// // ? DateUtil.formatDateToTimeLang(DateUtil.convertStringToDate(user.editedOn), false)
// // : user.createdOn != null
// // ? DateUtil.formatDateToTimeLang(DateUtil.convertStringToDate(user.createdOn), false)
// // : '--',
// // style: TextStyle(fontSize: 12, fontWeight: FontWeight.w600, color: Color(0xff575757), letterSpacing: -0.48),
// // ),
// ],
// )
// ],
// ),
// ),
LocaleKeys.pleaseVerify.tr().toText16(),
GridView(
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 2, crossAxisSpacing: 13, mainAxisSpacing: 9),
@ -612,9 +620,23 @@ class _VerifyLoginScreenState extends State<VerifyLoginScreen> {
// // });
// }
//
Future<bool> loginWithFaceIDAndBiometrics() async {
IOSAuthMessages iosStrings =
const IOSAuthMessages(cancelButton: 'cancel', goToSettingsButton: 'settings', goToSettingsDescription: 'Please set up your Touch ID.', lockOut: 'Please reenable your Touch ID');
bool authenticated = false;
try {
authenticated = await auth.authenticate(localizedReason: 'Scan your fingerprint to authenticate', useErrorDialogs: true, stickyAuth: true, iOSAuthStrings: iosStrings);
} on PlatformException catch (e) {
print(e);
Utils.hideLoading(context);
Utils.showToast("Please enable your Touch or Face ID");
}
return authenticated;
}
Widget _loginOptionButton(String _title, String _icon, int _flag, int? _loginIndex) {
bool isDisable = ((_flag == 3 && !checkBiometricIsAvailable(BiometricType.face)) || (_flag == 2 && !checkBiometricIsAvailable(BiometricType.fingerprint)));
print("$_title:$isDisable");
return InkWell(
onTap: isDisable
? null
@ -624,37 +646,64 @@ class _VerifyLoginScreenState extends State<VerifyLoginScreen> {
// isMoreOption = true;
});
} else {
Utils.showLoading(context);
BasicMemberInformationModel? memberInformationModel = await LoginApiClient()
.mohemmSendActivationCodeByOTPNotificationType(checkBiometricIsAvailable(BiometricType.fingerprint) ? 1 : 0, AppState().memberLoginList?.pMOBILENUMBER, _flag, AppState().getUserName);
Utils.hideLoading(context);
OtpDialog(
context,
_flag,
int.tryParse(AppState().memberLoginList?.pMOBILENUMBER ?? ""),
(value) async {
Utils.showLoading(context);
try {
GenericResponseModel? genericResponseModel = await LoginApiClient().checkActivationCode(false, AppState().memberLoginList?.pMOBILENUMBER, value, AppState().getUserName);
if (genericResponseModel?.errorMessage != null) {
Utils.showToast(genericResponseModel?.errorMessage ?? "");
// Navigator.pop(context);
}
Utils.hideLoading(context);
Navigator.pop(context);
Navigator.pushNamedAndRemoveUntil(context, AppRoutes.dashboard, (Route<dynamic> route) => false);
} catch (ex) {
print(ex);
Utils.hideLoading(context);
Utils.handleException(ex, null);
try {
Utils.showLoading(context);
if (_flag == 2 || _flag == 3) {
bool authenticateWithFaceAndTouchID = await loginWithFaceIDAndBiometrics();
if (!authenticateWithFaceAndTouchID) {
return;
}
},
() => {
Navigator.pop(context),
},
).displayDialog(context);
// authenticateUser(_flag, isActive: _loginIndex);
}
await LoginApiClient().checkMobileAppVersion();
await LoginApiClient().memberLogin(AppState().getUserName!, AppState().password!);
BasicMemberInformationModel? memberInformationModel = await LoginApiClient().mohemmSendActivationCodeByOTPNotificationType(
checkBiometricIsAvailable(BiometricType.fingerprint) ? 1 : 0, AppState().memberLoginList?.pMOBILENUMBER, _flag, AppState().getUserName);
Utils.hideLoading(context);
OtpDialog(
context,
_flag,
int.tryParse(AppState().memberLoginList?.pMOBILENUMBER ?? ""),
(value) async {
Utils.showLoading(context);
try {
GenericResponseModel? genericResponseModel = await LoginApiClient().checkActivationCode(false, AppState().memberLoginList?.pMOBILENUMBER, value, AppState().getUserName);
GenericResponseModel? genericResponseModel1 = await LoginApiClient().insertMobileLoginInfoNEW(
AppState().memberLoginList?.pEMAILADDRESS ?? "",
genericResponseModel?.pSESSIONID ?? 0,
genericResponseModel?.memberInformationList![0].eMPLOYEENAME ?? "",
_flag,
AppState().memberLoginList?.pMOBILENUMBER ?? "",
AppState().getUserName!,
firebaseToken!,
Platform.isAndroid ? "android" : "ios");
if (genericResponseModel?.errorMessage != null) {
Utils.showToast(genericResponseModel?.errorMessage ?? "");
} else {
AppState().setPrivilegeListModel = genericResponseModel!.privilegeList ?? [];
AppState().setMemberInformationListModel = genericResponseModel.memberInformationList?.first;
MemberInformationListModel.saveToPrefs(genericResponseModel.memberInformationList ?? []);
PrivilegeListModel.saveToPrefs(genericResponseModel.privilegeList ?? []);
Utils.saveStringFromPrefs(SharedPrefsConsts.username, AppState().getUserName!);
Utils.saveStringFromPrefs(SharedPrefsConsts.password, AppState().password!);
}
Utils.hideLoading(context);
Navigator.pop(context);
Navigator.pushNamedAndRemoveUntil(context, AppRoutes.dashboard, (Route<dynamic> route) => false);
} catch (ex) {
print(ex);
Utils.hideLoading(context);
Utils.handleException(ex, null);
}
},
() => {
Navigator.pop(context),
},
).displayDialog(context);
} catch (ex) {
print(ex);
Utils.hideLoading(context);
Utils.handleException(ex, null);
}
}
},
child: Container(

@ -1,56 +1,85 @@
import 'package:easy_localization/src/public_ext.dart';
import 'package:flutter/material.dart';
import 'package:flutter_svg/svg.dart';
import 'package:mohem_flutter_app/classes/colors.dart';
import 'package:mohem_flutter_app/ui/app_bar.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/work_list/missing_swipe/fragments/actions_fragment.dart';
import 'package:mohem_flutter_app/ui/work_list/missing_swipe/fragments/attachments_fragment.dart';
import 'package:mohem_flutter_app/ui/work_list/missing_swipe/fragments/info_fragments.dart';
import 'package:mohem_flutter_app/ui/work_list/missing_swipe/fragments/request_fragment.dart';
import 'package:mohem_flutter_app/widgets/app_bar_widget.dart';
import 'package:mohem_flutter_app/widgets/button/default_button.dart';
import 'package:mohem_flutter_app/extensions/int_extensions.dart';
class MissingSwipeScreen extends StatelessWidget {
class MissingSwipeScreen extends StatefulWidget {
MissingSwipeScreen({Key? key}) : super(key: key);
@override
_MissingSwipeScreenState createState() {
return _MissingSwipeScreenState();
}
}
class _MissingSwipeScreenState extends State<MissingSwipeScreen> {
int tabIndex = 0;
PageController controller = PageController();
bool showFabOptions = false;
@override
void initState() {
super.initState();
}
@override
void dispose() {
super.dispose();
}
@override
Widget build(BuildContext context) {
return DefaultTabController(
length: 4,
child: Scaffold(
appBar: appBar(context, title: "Missing Swipe Request"),
body: Container(
width: double.infinity,
height: double.infinity,
child: Column(
return Scaffold(
appBar: AppBarWidget(context, title: LocaleKeys.details.tr()),
backgroundColor: Colors.white,
body: Stack(
children: [
Column(
children: [
Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.only(bottomLeft: Radius.circular(20), bottomRight: Radius.circular(20)),
gradient: LinearGradient(transform: GradientRotation(.46), begin: Alignment.topRight, end: Alignment.bottomRight, colors: [
MyColors.gradiantEndColor,
MyColors.gradiantStartColor,
]),
padding: const EdgeInsets.only(left: 21, right: 21, top: 16, bottom: 16),
decoration: const BoxDecoration(
borderRadius: BorderRadius.only(
bottomLeft: Radius.circular(25),
bottomRight: Radius.circular(25),
),
gradient: LinearGradient(
transform: GradientRotation(.83),
begin: Alignment.topRight,
end: Alignment.bottomLeft,
colors: [
MyColors.gradiantEndColor,
MyColors.gradiantStartColor,
],
),
),
clipBehavior: Clip.antiAlias,
child: TabBar(
indicatorColor: Colors.white,
labelColor: Colors.white,
tabs: [
Tab(
text: "Request",
),
Tab(
text: "Actions",
),
Tab(
text: "Attachments",
),
Tab(
text: "Info.",
),
child: Row(
children: [
myTab("Request", 0),
myTab("Actions", 1),
myTab("Attachments", 2),
myTab("Info.", 3),
],
),
),
Expanded(
child: TabBarView(
child: PageView(
controller: controller,
onPageChanged: (pageIndex) {
setState(() {
tabIndex = pageIndex;
});
},
children: [
RequestFragment(),
ActionsFragment(),
@ -60,39 +89,140 @@ class MissingSwipeScreen extends StatelessWidget {
),
),
Container(
width: double.infinity,
height: 60,
padding: EdgeInsets.only(left: 21, right: 21),
padding: const EdgeInsets.only(top: 14, bottom: 14, left: 21, right: 21),
decoration: const BoxDecoration(
color: Colors.white,
border: Border(
top: BorderSide(
color: MyColors.lightGreyEFColor,
width: 1.0,
),
),
),
child: Row(
children: [
Expanded(
child: DefaultButton(
"Reject",
() {},
colors: [
Color(0xffEB8C90),
Color(0xffDE6C70),
],
),
),
12.width,
Expanded(
child: DefaultButton(
"Approve",
() {},
colors: [
Color(0xff32D892),
Color(0xff1AB170),
],
DefaultButton(
LocaleKeys.reject.tr(),
() {},
colors: const [
Color(0xffEB8C90),
Color(0xffDE6C70),
],
).expanded,
8.width,
DefaultButton(
LocaleKeys.approve.tr(),
() {},
colors: const [
Color(0xff32D892),
Color(0xff1AB170),
],
).expanded,
8.width,
Container(
height: 43,
width: 43,
decoration: const BoxDecoration(
shape: BoxShape.circle,
color: MyColors.lightGreyE6Color,
),
),
child: Icon(showFabOptions ? Icons.more_vert_rounded : Icons.more_horiz_rounded, color: MyColors.darkIconColor),
).onPress(() {
setState(() {
showFabOptions = true;
});
})
],
),
)
],
),
),
IgnorePointer(
ignoring: !showFabOptions,
child: AnimatedOpacity(
opacity: showFabOptions ? 1 : 0,
duration: const Duration(milliseconds: 250),
child: Container(
padding: const EdgeInsets.only(left: 21, right: 21, bottom: 75),
width: double.infinity,
height: double.infinity,
color: Colors.white.withOpacity(.67),
alignment: Alignment.bottomRight,
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.end,
children: [
myFab("Skip", "assets/images/skip.svg"),
12.height,
myFab("Request Info", "assets/images/request_info.svg"),
12.height,
myFab("Delegate", "assets/images/delegate.svg"),
],
),
),
).onPress(() {
setState(() {
showFabOptions = false;
});
}),
),
],
),
);
}
Widget myTab(String title, int index) {
bool isSelected = (index == tabIndex);
return Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
title.toText12(color: isSelected ? Colors.white : Colors.white.withOpacity(.74), isCenter: true),
4.height,
Container(
height: 8,
width: 8,
decoration: BoxDecoration(
shape: BoxShape.circle,
color: isSelected ? Colors.white : Colors.transparent,
),
).onPress(() {
setState(() {
showFabOptions = true;
});
})
],
).onPress(() {
controller.jumpToPage(index);
}).expanded;
}
Widget myFab(String title, String icon) {
return Row(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
title.toText16(),
14.width,
Container(
height: 43,
width: 43,
padding: const EdgeInsets.all(12),
decoration: const BoxDecoration(
shape: BoxShape.circle,
gradient: LinearGradient(
transform: GradientRotation(.46),
begin: Alignment.topRight,
end: Alignment.bottomLeft,
colors: [
MyColors.gradiantEndColor,
MyColors.gradiantStartColor,
],
),
),
child: SvgPicture.asset(icon),
)
],
);
}
}

@ -1,29 +1,116 @@
import 'package:easy_localization/src/public_ext.dart';
import 'package:flutter/material.dart';
import 'package:flutter_svg/svg.dart';
import 'package:mohem_flutter_app/api/worklist/worklist_api_client.dart';
import 'package:mohem_flutter_app/classes/colors.dart';
import 'package:mohem_flutter_app/classes/date_uitl.dart';
import 'package:mohem_flutter_app/classes/utils.dart';
import 'package:mohem_flutter_app/config/routes.dart';
import 'package:mohem_flutter_app/generated/locale_keys.g.dart';
import 'package:mohem_flutter_app/ui/app_bar.dart';
import 'package:mohem_flutter_app/extensions/string_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/widget_extensions.dart';
import 'package:mohem_flutter_app/generated/locale_keys.g.dart';
import 'package:mohem_flutter_app/models/dashboard/itg_forms_model.dart';
import 'package:mohem_flutter_app/models/worklist_item_type_model.dart';
import 'package:mohem_flutter_app/models/worklist_response_model.dart';
import 'package:mohem_flutter_app/provider/dashboard_provider_model.dart';
import 'package:mohem_flutter_app/widgets/app_bar_widget.dart';
import 'package:provider/provider.dart';
class WorkListScreen extends StatefulWidget {
WorkListScreen({Key? key}) : super(key: key);
@override
State<WorkListScreen> createState() => _WorkListScreenState();
_WorkListScreenState createState() {
return _WorkListScreenState();
}
}
class _WorkListScreenState extends State<WorkListScreen> {
List<WorkListItemTypeModelData> workListItemTypes = [
WorkListItemTypeModelData(
value: 0, name: 'HR', fullName: 'Human Resource', active: false, color: [Color(0xff32D892), Color(0xff1AB170)], icon: "assets/images/miss_swipe.svg", key: 'HRSSA', disable: false),
WorkListItemTypeModelData(
value: 0, name: 'MO', fullName: 'Move Order', active: false, color: [Color(0xff58DCFA), Color(0xff3CB9D5)], icon: "assets/images/miss_swipe.svg", key: 'INVMOA', disable: false),
WorkListItemTypeModelData(
value: 0, name: 'PR', fullName: 'Purchase Requisition', active: false, color: [Color(0xff48EACF), Color(0xff3DCAB3)], icon: "assets/images/miss_swipe.svg", key: 'REQAPPRV', disable: false),
WorkListItemTypeModelData(
value: 0, name: 'PO', fullName: 'Purchase Order', active: false, color: [Color(0xff5099E3), Color(0xff3670AA)], icon: "assets/images/miss_swipe.svg", key: 'POAPPRV', disable: false),
WorkListItemTypeModelData(
value: 0, name: 'ITG', fullName: 'ITG Forms', active: false, color: [Color(0xffEB8C90), Color(0xffDE6C70)], icon: "assets/images/miss_swipe.svg", key: 'ITG', disable: false),
WorkListItemTypeModelData(
value: 0, name: 'IC', fullName: 'Item Creation', active: false, color: [Color(0xff32D892), Color(0xff1AB170)], icon: "assets/images/miss_swipe.svg", key: 'INVITEM', disable: false),
WorkListItemTypeModelData(
value: 0, name: 'STAMP', fullName: 'Stamp', active: false, color: [Color(0xff32D892), Color(0xff1AB170)], icon: "assets/images/miss_swipe.svg", key: 'STAMP', disable: false),
];
int workListItemIndex = 0;
List<WorkListResponseModel>? workList;
int pageNumber = 1;
late DashboardProviderModel providerData;
@override
void initState() {
super.initState();
providerData = Provider.of<DashboardProviderModel>(context, listen: false);
workListItemTypes.forEach((workListElement) {
if (workListElement.key == "ITG") {
workListElement.value = providerData.itgFormsModel?.totalCount ?? 0;
} else {
var tempList = providerData.getOpenNotificationsList?.where((notificationElement) => notificationElement.itemType == workListElement.key).toList();
if (tempList!.isNotEmpty) {
workListElement.value = tempList.first.openNtfNumber ?? 0;
}
}
});
getWorkList();
}
ItgFormsModel? itgFormsModel;
int? itgRequestTypeIndex;
void getWorkList() async {
try {
Utils.showLoading(context);
if (workListItemTypes[workListItemIndex].key == "ITG") {
itgFormsModel = await WorkListApiClient().GetITGTaskCountRequestType();
List<RequestDetails> requestAllList = [];
for (int i = 0; i < (itgFormsModel?.requestType!.length ?? 0); i++) {
requestAllList = requestAllList + (itgFormsModel?.requestType![i].requestDetails ?? []);
}
itgFormsModel?.requestType!.insert(0, RequestType(requestDetails: requestAllList, requestTypeCode: "all", requestTypeName: "All"));
if ((itgFormsModel?.requestType?.length ?? 0) > 0) {
itgRequestTypeIndex = 0;
}
} else {
itgRequestTypeIndex = null;
workList = await WorkListApiClient().getWorkList(pageNumber, workListItemTypes[workListItemIndex].key);
}
Utils.hideLoading(context);
setState(() {});
} catch (ex) {
Utils.hideLoading(context);
Utils.handleException(ex, null);
}
}
@override
void dispose() {
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.white,
appBar: appBar(
appBar: AppBarWidget(
context,
title: LocaleKeys.workList.tr(),
),
body: Container(
body: SizedBox(
width: double.infinity,
height: double.infinity,
child: Column(
@ -31,67 +118,151 @@ class _WorkListScreenState extends State<WorkListScreen> {
children: [
Container(
width: double.infinity,
height: 2,
color: MyColors.darkWhiteColor,
height: 1,
color: MyColors.lightGreyEFColor,
),
Container(
width: double.infinity,
SizedBox(
height: 40,
margin: EdgeInsets.only(
top: 21,
),
child: ListView.separated(
itemBuilder: (context, index) {
return Container(
padding: EdgeInsets.only(
left: 30,
right: 30,
),
padding: const EdgeInsets.only(left: 21, right: 21, top: 8, bottom: 8),
alignment: Alignment.center,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(6),
color: tabList[index].isSelected
? MyColors.darkIconColor
: MyColors.lightGreyEAColor,
),
child: tabList[index].title.toText12(
color: tabList[index].isSelected
? MyColors.white
: MyColors.black,
),
);
},
separatorBuilder: (context, index) {
return 8.width;
decoration: BoxDecoration(borderRadius: BorderRadius.circular(6), color: workListItemIndex == index ? MyColors.darkIconColor : MyColors.lightGreyEAColor),
child: ("${workListItemTypes[index].name} ${workListItemTypes[index].value > 0 ? "(${workListItemTypes[index].value})" : ""}")
.toText12(color: workListItemIndex == index ? MyColors.white : MyColors.black),
).onPress(() {
if (workListItemIndex != index) {
workListItemIndex = index;
if (workListItemTypes[index].value == 0) {
workList = [];
} else {
workList = null;
}
setState(() {});
if (workListItemTypes[index].value > 0) {
getWorkList();
}
}
});
},
separatorBuilder: (context, index) => 8.width,
shrinkWrap: true,
itemCount: tabList.length,
itemCount: workListItemTypes.length,
scrollDirection: Axis.horizontal,
padding: const EdgeInsets.only(
left: 21,
right: 21,
padding: const EdgeInsets.only(left: 21, right: 21),
),
).paddingOnly(top: 21, bottom: 21),
workListItemTypes[workListItemIndex].fullName.toSectionHeading().paddingOnly(left: 21, right: 21),
if (itgRequestTypeIndex != null)
SizedBox(
height: 40,
child: ListView.separated(
itemBuilder: (context, index) {
RequestType type = itgFormsModel!.requestType![index];
return Container(
padding: const EdgeInsets.only(left: 21, right: 21, top: 8, bottom: 8),
alignment: Alignment.center,
decoration: BoxDecoration(borderRadius: BorderRadius.circular(30), color: itgRequestTypeIndex == index ? MyColors.darkIconColor : MyColors.lightGreyEAColor),
child: ("${type.requestTypeName}").toText12(color: itgRequestTypeIndex == index ? MyColors.white : MyColors.black),
).onPress(() {
if (itgRequestTypeIndex != index) {
itgRequestTypeIndex = index;
setState(() {});
}
});
},
separatorBuilder: (context, index) => 8.width,
shrinkWrap: true,
itemCount: itgFormsModel?.requestType?.length ?? 0,
scrollDirection: Axis.horizontal,
padding: const EdgeInsets.only(left: 21, right: 21),
),
).paddingOnly(top: 16, bottom: 16),
itgRequestTypeIndex != null
? Expanded(
child: ListView.separated(
physics: BouncingScrollPhysics(),
itemBuilder: (context, index) {
return itgRowItem(workListItemTypes[workListItemIndex], itgFormsModel!.requestType![itgRequestTypeIndex!].requestDetails![index]);
},
separatorBuilder: (context, index) => 12.height,
itemCount: itgFormsModel!.requestType![itgRequestTypeIndex!].requestDetails?.length ?? 0,
padding: EdgeInsets.only(top: 16, left: 21, right: 21),
),
)
: Expanded(
child: workList != null
? ((workList!).isEmpty
? "No History Available".toText16().center
: ListView.separated(
physics: BouncingScrollPhysics(),
itemBuilder: (context, index) {
return rowItem(workListItemTypes[workListItemIndex], workList![index]);
},
separatorBuilder: (context, index) => 12.height,
itemCount: workList?.length ?? 0,
padding: EdgeInsets.only(top: 21, left: 21, right: 21),
))
: const SizedBox(),
),
],
),
),
);
}
Widget itgRowItem(WorkListItemTypeModelData data, RequestDetails requestDetails) {
return InkWell(
onTap: () {
Navigator.pushNamed(context, AppRoutes.missingSwipe);
},
child: Container(
width: double.infinity,
padding: const EdgeInsets.only(left: 12, right: 12, top: 10, bottom: 10),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(10),
boxShadow: [
BoxShadow(
color: const Color(0xff000000).withOpacity(.05),
blurRadius: 26,
offset: const Offset(0, -3),
),
],
),
child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start,
children: [
Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(4),
gradient: LinearGradient(transform: GradientRotation(.218), begin: Alignment.topRight, end: Alignment.bottomRight, colors: data.color),
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: [SvgPicture.asset("assets/images/miss_swipe.svg", width: 20, height: 20, color: Colors.white), 2.height, data.name.toText10(color: Colors.white)],
).paddingAll(6),
),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: [
LocaleKeys.human.toText12(),
LocaleKeys.resources.tr().toText24(isBold: true),
],
).paddingOnly(top: 24, left: 21, right: 21),
24.height,
8.width,
Expanded(
child: ListView.separated(
itemBuilder: (context, index) {
return rowItem(typesList[index]);
},
separatorBuilder: (context, index) {
return 12.height;
},
itemCount: typesList.length,
padding: EdgeInsets.only(left: 21, right: 21),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start,
children: [
requestDetails.title!.toText12(color: MyColors.grey57Color),
10.height,
Row(
children: [
DateUtil.formatDateToDate(DateUtil.convertStringToDate(requestDetails.modifiedDate!), false).toText10(color: MyColors.lightTextColor).expanded,
SvgPicture.asset(
"assets/images/arrow_next.svg",
color: MyColors.darkIconColor,
)
],
),
],
),
),
],
@ -100,14 +271,14 @@ class _WorkListScreenState extends State<WorkListScreen> {
);
}
Widget rowItem(Types types) {
Widget rowItem(WorkListItemTypeModelData data, WorkListResponseModel workData) {
return InkWell(
onTap: (){
onTap: () {
Navigator.pushNamed(context, AppRoutes.missingSwipe);
},
child: Container(
width: double.infinity,
padding: EdgeInsets.all(12),
padding: const EdgeInsets.only(left: 12, right: 12, top: 10, bottom: 10),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(10),
@ -126,39 +297,24 @@ class _WorkListScreenState extends State<WorkListScreen> {
Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(4),
gradient: LinearGradient(
transform: GradientRotation(.46),
begin: Alignment.topRight,
end: Alignment.bottomRight,
colors: types.colors),
gradient: LinearGradient(transform: GradientRotation(.218), begin: Alignment.topRight, end: Alignment.bottomRight, colors: data.color),
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
SvgPicture.asset(
"assets/images/miss_swipe.svg",
color: Colors.white,
),
2.height,
types.title.toText10(color: Colors.white)
],
children: [SvgPicture.asset("assets/images/miss_swipe.svg", width: 20, height: 20, color: Colors.white), 2.height, data.name.toText10(color: Colors.white)],
).paddingAll(6),
),
12.width,
8.width,
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start,
children: [
"Missing Swipe Request".toText16(),
"Missing Swipe Request for Hussain, Mohammad has been approved"
.toText10(),
12.height,
workData.sUBJECT!.toText12(color: MyColors.grey57Color),
10.height,
Row(
children: [
Expanded(
child: "07 Jan 2021"
.toText10(color: MyColors.lightTextColor)),
DateUtil.formatDateToDate(DateUtil.convertSimpleStringDateToDate(workData.bEGINDATE!), false).toText10(color: MyColors.lightTextColor).expanded,
SvgPicture.asset(
"assets/images/arrow_next.svg",
color: MyColors.darkIconColor,
@ -174,33 +330,3 @@ class _WorkListScreenState extends State<WorkListScreen> {
);
}
}
class Tabs {
String title;
bool isSelected;
Tabs(this.title, this.isSelected);
}
List<Tabs> tabList = [
Tabs("All", true),
Tabs("HR", false),
Tabs("MO", false),
Tabs("PR", false),
Tabs("PO", false),
];
class Types {
String title;
List<Color> colors;
Types(this.title, this.colors);
}
List<Types> typesList = [
Types("HR", [Color(0xff32D892), Color(0xff1AB170)]),
Types("ITG", [Color(0xffEB8C90), Color(0xffDE6C70)]),
Types("PO", [Color(0xff5099E3), Color(0xff3670AA)]),
Types("PR", [Color(0xff48EACF), Color(0xff3DCAB3)]),
Types("MO", [Color(0xff58DCFA), Color(0xff3CB9D5)]),
];

@ -0,0 +1,39 @@
/* ZiK */
import 'dart:async';
import 'package:flutter/cupertino.dart';
typedef ChildProvider<E> = Widget Function(BuildContext context, E? data);
class Updater<T> extends StatelessWidget{
final ChildProvider<T> childProvider;
StreamController<T?>? sink;
T? initialData;
List<T?> _history = [];
Stream<T?>? _stream;
Updater({T? initialData, required this.childProvider}){
this.sink = StreamController<T?>();
this.initialData = initialData;
_stream = this.sink?.stream;
}
@override
Widget build(BuildContext context) {
return StreamBuilder<T?>(
initialData: this.initialData,
stream: _stream,
builder: (ctx, snapshot){
return childProvider(context, snapshot.data);
});
}
pushData(T? data) {
_history.add(data);
sink?.sink.add(data);
}
List<T?> getDataHistory() => _history;
T? getLatestData() => _history.last;
}

@ -0,0 +1,44 @@
import 'package:flutter/material.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';
AppBar AppBarWidget(BuildContext context, {required String title, bool showHomeButton = false}) {
return AppBar(
leadingWidth: 0,
// leading: GestureDetector(
// behavior: HitTestBehavior.opaque,
// onTap: Feedback.wrapForTap(() => Navigator.maybePop(context), context),
// child: const Icon(Icons.arrow_back_ios, color: MyColors.darkIconColor),
// ),
//titleSpacing: -1.44,
title: Row(
children: [
GestureDetector(
behavior: HitTestBehavior.opaque,
onTap: Feedback.wrapForTap(() => Navigator.maybePop(context), context),
child: const Icon(Icons.arrow_back_ios, color: MyColors.darkIconColor),
),
4.width,
title.toText24(color: MyColors.darkTextColor, isBold: true, considerHeight: false).expanded,
],
),
centerTitle: false,
elevation: 0,
backgroundColor: Colors.white,
actions: [
if (showHomeButton)
IconButton(
onPressed: () {
// Navigator.pushAndRemoveUntil(
// context,
// MaterialPageRoute(builder: (context) => LandingPage()),
// (Route<dynamic> route) => false,
// );
},
icon: const Icon(Icons.home, color: MyColors.darkIconColor),
),
],
);
}

@ -0,0 +1,66 @@
import 'package:easy_localization/src/public_ext.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:mohem_flutter_app/generated/locale_keys.g.dart';
import 'package:mohem_flutter_app/widgets/button/default_button.dart';
class ConfirmDialog extends StatelessWidget {
final String? title;
final String? message;
final String? okTitle;
final VoidCallback? onTap;
const ConfirmDialog({Key? key, this.title, @required this.message, this.okTitle, this.onTap}) : super(key: key);
@override
Widget build(BuildContext context) {
return Dialog(
backgroundColor: Colors.white,
shape: RoundedRectangleBorder(),
insetPadding: EdgeInsets.only(left: 21, right: 21),
child: Padding(
padding: EdgeInsets.only(left: 20, right: 20, top: 18, bottom: 28),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: [
Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Expanded(
child: Padding(
padding: const EdgeInsets.only(top: 16.0),
child: Text(
title ?? LocaleKeys.confirm.tr(),
style: TextStyle(fontSize: 24, fontWeight: FontWeight.w600, color: Color(0xff2B353E), height: 35 / 24, letterSpacing: -0.96),
),
),
),
IconButton(
padding: EdgeInsets.zero,
icon: Icon(Icons.close),
color: Color(0xff2B353E),
constraints: BoxConstraints(),
onPressed: () {
Navigator.pop(context);
},
)
],
),
Text(
message ?? "",
style: TextStyle(fontSize: 16, fontWeight: FontWeight.w600, color: Color(0xff808080), letterSpacing: -0.48),
),
SizedBox(height: 28),
DefaultButton(
okTitle ?? LocaleKeys.ok.tr(),
onTap == null ? () => Navigator.pop(context) : onTap,
textColor: Colors.white,
//color: Ap.green,
),
],
),
),
);
}
}

@ -12,15 +12,10 @@ class InputWidget extends StatelessWidget {
final bool isInputTypeNum;
final bool isObscureText;
final bool isBackgroundEnable;
final Function(String)? onChange;
InputWidget(this.labelText, this.hintText, this.controller,
{this.isObscureText = false,
this.suffixTap,
this.isEnable = true,
this.hasSelection = false,
this.lines = 1,
this.isInputTypeNum = false,
this.isBackgroundEnable = false});
{this.isObscureText = false, this.suffixTap, this.isEnable = true, this.hasSelection = false, this.lines = 1, this.onChange, this.isInputTypeNum = false, this.isBackgroundEnable = false});
@override
Widget build(BuildContext context) {
@ -56,14 +51,12 @@ class InputWidget extends StatelessWidget {
TextField(
enabled: isEnable,
scrollPadding: EdgeInsets.zero,
keyboardType: isInputTypeNum
? TextInputType.number
: TextInputType.text,
keyboardType: isInputTypeNum ? TextInputType.number : TextInputType.text,
controller: controller,
maxLines: lines,
obscuringCharacter: "*",
obscureText: isObscureText,
onChanged: (value) => {},
onChanged: onChange,
style: const TextStyle(
fontSize: 14,
height: 21 / 14,
@ -82,12 +75,7 @@ class InputWidget extends StatelessWidget {
letterSpacing: -0.56,
),
suffixIconConstraints: const BoxConstraints(minWidth: 50),
suffixIcon: suffixTap == null
? null
: IconButton(
icon: const Icon(Icons.mic,
color: MyColors.darkTextColor),
onPressed: suffixTap),
suffixIcon: suffixTap == null ? null : IconButton(icon: const Icon(Icons.mic, color: MyColors.darkTextColor), onPressed: suffixTap),
contentPadding: EdgeInsets.zero,
border: InputBorder.none,
focusedBorder: InputBorder.none,

@ -0,0 +1,249 @@
import 'dart:async';
import 'dart:math';
import 'dart:ui';
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
import 'package:geolocator/geolocator.dart';
import 'package:google_directions_api/google_directions_api.dart';
import 'package:google_maps_flutter/google_maps_flutter.dart';
import 'package:mohem_flutter_app/classes/utils.dart';
// import 'package:geodesy/geodesy.dart' as geodesy;
import '../../classes/app_permissions.dart';
import '../../theme/colors.dart';
//Created By Mr.Zohaib
class Location {
static _Map map = _Map();
static havePermission(Function(bool) callback) {
Geolocator.checkPermission().then((value) async {
if (value == LocationPermission.denied) {
value = await Geolocator.requestPermission();
callback(![LocationPermission.denied, LocationPermission.deniedForever].contains(value));
} else {
callback(true);
}
});
}
static isEnabled(Function(bool) callback) {
Geolocator.isLocationServiceEnabled().then((value) => callback(value));
}
static bool _listeningSettingChange = true;
static listenGPS({bool change = true, Function(bool)? onChange}) async {
_listeningSettingChange = change;
if (change == false) return;
Future.doWhile(() async {
await Utils.delay(1000);
var enable = await Geolocator.isLocationServiceEnabled();
onChange!(enable);
return _listeningSettingChange;
});
}
static getCurrentLocation(Function(LatLng?) callback) {
done(Position position) {
//AppStorage.sp.saveLocation(position);
LatLng? myCurrentLocation = LatLng(position.latitude, position.longitude);
callback(myCurrentLocation);
}
AppPermissions.location((granted) {
if (granted)
Geolocator.getLastKnownPosition(forceAndroidLocationManager: true).then((value) {
if (value == null) {
Geolocator.getCurrentPosition().then((value) {
done(value);
});
} else {
done(value);
}
});
});
}
// static LatLng locationAwayFrom(
// {required LatLng loc1, num distanceMeters = 200.0, num bearing = 270.0}) {
// geodesy.LatLng l1 = geodesy.LatLng(loc1.latitude, loc1.longitude);
// geodesy.LatLng destinationPoint = geodesy.Geodesy()
// .destinationPointByDistanceAndBearing(l1, distanceMeters, bearing);
// return LatLng(destinationPoint.latitude, destinationPoint.longitude);
// }
static Future<double> distanceTo(LatLng destination) async {
var myLoc = await Geolocator.getLastKnownPosition();
var distance = 0.0;
if (myLoc != null) {
distance = Geolocator.distanceBetween(destination.latitude, destination.longitude, myLoc.latitude, myLoc.longitude);
}
return distance;
}
}
class _Map {
Marker createMarker(
String id, {
required LatLng coordinates,
BitmapDescriptor? icon,
VoidCallback? onTap,
}) {
final MarkerId markerId = MarkerId(id);
return Marker(
icon: icon ?? BitmapDescriptor.defaultMarker,
markerId: markerId,
position: coordinates,
flat: false,
// infoWindow: InfoWindow(title: id, snippet: '*'),
onTap: onTap,
);
}
CameraPosition initialCamera({required Completer<GoogleMapController> mapController, LatLng? position, double zoom = 12}) {
position = position ?? LatLng(24.7249303, 46.5416656);
CameraPosition riyadhEye = CameraPosition(
target: position,
zoom: zoom,
);
mapController.future.then((controller) {
controller.animateCamera(CameraUpdate.newCameraPosition(riyadhEye));
});
return riyadhEye;
}
CameraPosition moveTo(LatLng location, {double zoom = 12, double direction = 0.0, required Completer<GoogleMapController> mapController, bool? animation}) {
var camera = CameraPosition(target: location, zoom: zoom, bearing: direction);
mapController.future.then((controller) {
animation ?? false ? controller.animateCamera(CameraUpdate.newCameraPosition(camera)) : controller.moveCamera(CameraUpdate.newCameraPosition(camera));
});
return camera;
}
moveCamera(CameraPosition camera, @required Completer<GoogleMapController> mapController, bool animation) {
mapController.future.then((controller) {
animation ? controller.animateCamera(CameraUpdate.newCameraPosition(camera)) : controller.moveCamera(CameraUpdate.newCameraPosition(camera));
});
}
scrollBy({double x = 0, double y = 0, required Completer<GoogleMapController> mapController, bool animation = true}) {
var camera = CameraUpdate.scrollBy(x, y);
mapController.future.then((controller) {
animation ? controller.animateCamera(camera) : controller.moveCamera(camera);
});
}
goToCurrentLocation({Completer<GoogleMapController>? mapController, double? direction = 0.0, bool? animation}) {
Location.getCurrentLocation((location) {
moveTo(location!, zoom: 17, mapController: mapController!, animation: animation, direction: direction!);
});
}
var routes = Map<String, DirectionsRoute>();
setRoutePolylines(LatLng? source, LatLng? destination, Set<Polyline> polylines, Completer<GoogleMapController> mapController, Function(DirectionsRoute?) completion) {
if (source == null || destination == null) {
completion(null);
return;
}
var origin = '${source.latitude},${source.longitude}';
var destin = '${destination.latitude},${destination.longitude}';
var routeId = '$origin->$destination';
createPolyline(DirectionsRoute results) {
List<LatLng> polylineCoordinates = results.overviewPath!.map((e) => LatLng(e.latitude, e.longitude)).toList();
PolylineId id = PolylineId("route");
Polyline polyline = Polyline(
polylineId: id,
color: accentColor,
width: 5,
jointType: JointType.round,
startCap: Cap.roundCap,
endCap: Cap.roundCap,
points: polylineCoordinates,
);
polylines.removeWhere((element) => true);
polylines.add(polyline);
LatLngBounds bound = getBounds(coordinates: polylineCoordinates);
focusCameraToLatLngBounds(bound: bound, mapController: mapController, padding: 100);
completion(routes[routeId]);
}
var availableRoute = routes[routeId];
if (availableRoute == null) {
var request = DirectionsRequest(origin: origin, destination: destin);
DirectionsService().route(request, (response, status) {
if (status == DirectionsStatus.ok && response.routes!.isNotEmpty) {
routes[routeId] = response.routes!.first;
createPolyline(response.routes!.first);
}
});
} else {
createPolyline(availableRoute);
}
}
LatLngBounds getBounds({required List<LatLng> coordinates}) {
var lngs = coordinates.map<double>((c) => c.longitude).toList();
var lats = coordinates.map<double>((c) => c.latitude).toList();
double bottomMost = lngs.reduce(min);
double topMost = lngs.reduce(max);
double leftMost = lats.reduce(min);
double rightMost = lats.reduce(max);
LatLngBounds bounds = LatLngBounds(
northeast: LatLng(rightMost, topMost),
southwest: LatLng(leftMost, bottomMost),
);
return bounds;
double? x0, x1, y0, y1;
for (LatLng latLng in coordinates) {
if (x0 == null) {
x0 = x1 = latLng.latitude;
y0 = y1 = latLng.longitude;
} else {
if (latLng.latitude > x1!) x1 = latLng.latitude;
if (latLng.latitude < x0) x0 = latLng.latitude;
if (latLng.longitude > y1!) y1 = latLng.longitude;
if (latLng.longitude < y0!) y0 = latLng.longitude;
}
}
return LatLngBounds(northeast: LatLng(x1!, y1!), southwest: LatLng(x0!, y0!));
}
focusCameraToLatLngBounds({LatLngBounds? bound, Completer<GoogleMapController>? mapController, double? padding}) async {
if (bound == null) return;
CameraUpdate camera = CameraUpdate.newLatLngBounds(bound, padding!);
final GoogleMapController controller = await mapController!.future;
controller.animateCamera(camera);
}
focusCameraTo2Points({LatLng? point1, LatLng? point2, Completer<GoogleMapController>? mapController, double? padding}) async {
var source = point1;
var destination = point2;
if (source != null && destination != null) {
// 'package:google_maps_flutter_platform_interface/src/types/location.dart': Failed assertion: line 72 pos 16: 'southwest.latitude <= northeast.latitude': is not true.
LatLngBounds bound;
if (source.latitude <= destination.latitude) {
bound = LatLngBounds(southwest: source, northeast: destination);
} else {
bound = LatLngBounds(southwest: destination, northeast: source);
}
if (bound == null) return;
focusCameraToLatLngBounds(bound: bound, mapController: mapController, padding: padding);
}
}
}

@ -0,0 +1,187 @@
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:nfc_manager/nfc_manager.dart';
import 'package:nfc_manager/platform_tags.dart';
void showNfcReader(BuildContext context, {required Function(String? nfcId) onNcfScan}) {
showModalBottomSheet(
context: context,
enableDrag: false,
isDismissible: false,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.only(topLeft: Radius.circular(12), topRight: Radius.circular(12)),
),
backgroundColor: Colors.white,
builder: (context) {
return NfcLayout(
onNcfScan: onNcfScan,
);
},
);
}
class NfcLayout extends StatefulWidget {
Function(String? nfcId) onNcfScan;
NfcLayout({required this.onNcfScan});
@override
_NfcLayoutState createState() => _NfcLayoutState();
}
class _NfcLayoutState extends State<NfcLayout> {
bool _reading = false;
Widget? mainWidget;
String? nfcId;
@override
void initState() {
super.initState();
NfcManager.instance.startSession(onDiscovered: (NfcTag tag) async {
print(tag.data);
var f = MifareUltralight(tag: tag, identifier: tag.data["nfca"]["identifier"], type: 2, maxTransceiveLength: 252, timeout: 22);
final String identifier = f.identifier.map((e) => e.toRadixString(16).padLeft(2, '0')).join('');
// print(identifier); // => 0428fcf2255e81
nfcId = identifier;
setState(() {
_reading = true;
mainWidget = doneNfc();
});
Future.delayed(const Duration(seconds: 1), () {
NfcManager.instance.stopSession();
Navigator.pop(context);
widget.onNcfScan(nfcId);
});
});
}
@override
Widget build(BuildContext context) {
(mainWidget == null && !_reading) ? mainWidget = scanNfc() : mainWidget = doneNfc();
return AnimatedSwitcher(duration: Duration(milliseconds: 500), child: mainWidget);
}
Widget scanNfc() {
return Container(
key: ValueKey(1),
child: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
SizedBox(
height: 30,
),
Text(
"Ready To Scan",
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 24,
),
),
SizedBox(
height: 30,
),
Image.asset(
"assets/icons/nfc/ic_nfc.png",
height: MediaQuery.of(context).size.width / 3,
),
SizedBox(
height: 30,
),
Text(
"Approach an NFC Tag",
style: TextStyle(
fontSize: 18,
),
),
SizedBox(
height: 30,
),
ButtonTheme(
minWidth: MediaQuery.of(context).size.width / 1.2,
height: 45.0,
buttonColor: Colors.grey[300],
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(6),
),
child: RaisedButton(
onPressed: () {
NfcManager.instance.stopSession();
Navigator.pop(context);
},
elevation: 0,
child: Text("CANCEL"),
),
),
SizedBox(
height: 30,
),
],
),
);
}
Widget doneNfc() {
return Container(
key: ValueKey(2),
child: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
SizedBox(
height: 30,
),
Text(
"Successfully Scanned",
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 24,
),
),
SizedBox(
height: 30,
),
Image.asset(
"assets/icons/nfc/ic_done.png",
height: MediaQuery.of(context).size.width / 3,
),
SizedBox(
height: 30,
),
Text(
"Approach an NFC Tag",
style: TextStyle(
fontSize: 18,
),
),
SizedBox(
height: 30,
),
ButtonTheme(
minWidth: MediaQuery.of(context).size.width / 1.2,
height: 45.0,
buttonColor: Colors.grey[300],
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(6),
),
child: RaisedButton(
// onPressed: () {
// _stream?.cancel();
// widget.onNcfScan(nfcId);
// Navigator.pop(context);
// },
onPressed: null,
elevation: 0,
child: Text("DONE"),
),
),
SizedBox(
height: 30,
),
],
),
);
}
}

@ -0,0 +1,189 @@
import 'package:easy_localization/src/public_ext.dart';
import 'package:flutter/material.dart';
import 'package:flutter_svg/svg.dart';
import 'package:mohem_flutter_app/extensions/int_extensions.dart';
import 'package:mohem_flutter_app/extensions/string_extensions.dart';
import 'package:mohem_flutter_app/extensions/widget_extensions.dart';
import 'package:mohem_flutter_app/generated/locale_keys.g.dart';
import 'package:shimmer/shimmer.dart';
class GetAttendanceTrackingShimmer extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Container(
width: double.infinity,
height: double.infinity,
clipBehavior: Clip.antiAlias,
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(15),
boxShadow: [
BoxShadow(
color: const Color(0xff000000).withOpacity(.05),
blurRadius: 26,
offset: const Offset(0, -3),
),
],
),
child: Stack(
alignment: Alignment.center,
children: [
// SvgPicture.asset("assets/images/"),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Expanded(
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
LocaleKeys.markAttendance.tr().toText14(color: Colors.white, isBold: true).toShimmer(),
16.height,
"07:55:12".toText10(color: Colors.white, isBold: true).toShimmer(),
3.height,
LocaleKeys.timeLeftToday.tr().toText10(color: Colors.white).toShimmer(),
9.height,
const ClipRRect(
borderRadius: BorderRadius.all(
Radius.circular(20),
),
child: LinearProgressIndicator(
value: 0.7,
minHeight: 8,
valueColor: const AlwaysStoppedAnimation<Color>(Colors.white),
backgroundColor: const Color(0xff196D73),
),
).toShimmer(),
],
).paddingOnly(top: 12, right: 15, left: 12),
),
Row(
children: [
Expanded(
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
LocaleKeys.checkIn.tr().toText12(color: Colors.white).toShimmer(),
],
).paddingOnly(left: 12),
),
Container(
width: 45,
height: 45,
// color: Colors.blue,
padding: const EdgeInsets.only(left: 14, right: 14),
).toShimmer(),
],
),
],
),
],
),
);
}
}
class MenuShimmer extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Container(
clipBehavior: Clip.antiAlias,
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(15),
boxShadow: [
BoxShadow(
color: const Color(0xff000000).withOpacity(.05),
blurRadius: 26,
offset: const Offset(0, -3),
),
],
),
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
LocaleKeys.workList.tr().toText12(color: Colors.white).toShimmer(),
Row(
children: [
Expanded(
flex: 3,
child: 123.toString().toText10(color: Colors.white, isBold: true).toShimmer(),
),
12.width,
SvgPicture.asset("assets/images/arrow_next.svg", color: Colors.white).toShimmer()
],
)
],
).paddingOnly(left: 10, right: 10, bottom: 6, top: 6),
);
}
}
class ServicesHeaderShimmer extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Row(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: [
"Other".tr().toText10().toShimmer(),
6.height,
LocaleKeys.services.tr().toText12(isBold: true).toShimmer(),
],
),
),
LocaleKeys.viewAllServices.tr().toText12(isUnderLine: true).toShimmer(),
],
);
}
}
class ServicesMenuShimmer extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Container(
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(15),
boxShadow: [
BoxShadow(
color: const Color(0xff000000).withOpacity(.05),
blurRadius: 26,
offset: const Offset(0, -3),
),
],
),
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
SvgPicture.asset("assets/images/monthly_attendance.svg").toShimmer(),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start,
children: [
"Attendan".toText11(isBold: false).toShimmer(),
5.height,
Row(
crossAxisAlignment: CrossAxisAlignment.end,
children: [
Expanded(
child: "Attendance".toText11(isBold: false).toShimmer(),
),
6.width,
SvgPicture.asset("assets/images/arrow_next.svg").paddingOnly(bottom: 4).toShimmer()
],
),
],
)
],
).paddingOnly(left: 10, right: 10, bottom: 10, top: 12),
);
}
}

@ -0,0 +1,194 @@
// import 'dart:async';
//
// import 'package:flutter/material.dart';
//
//
// void showNfcReader(BuildContext context, {Function onNcfScan}) {
// showModalBottomSheet(
// context: context,
// enableDrag: false,
// isDismissible: false,
// shape: RoundedRectangleBorder(
// borderRadius: BorderRadius.only(topLeft: Radius.circular(12), topRight: Radius.circular(12)),
// ),
// backgroundColor: Colors.white,
// builder: (context) {
// return NfcLayout(
// onNcfScan: onNcfScan,
// );
// });
// }
//
// class NfcLayout extends StatefulWidget {
// Function onNcfScan;
//
// NfcLayout({this.onNcfScan});
//
// @override
// _NfcLayoutState createState() => _NfcLayoutState();
// }
//
// class _NfcLayoutState extends State<NfcLayout> {
// StreamSubscription<NDEFMessage> _stream;
// bool _reading = false;
// Widget mainWidget;
// String nfcId;
//
// @override
// void initState() {
// super.initState();
//
// setState(() {
// // _reading = true;
// // Start reading using NFC.readNDEF()
// _stream = NFC.readNDEF(once: false, throwOnUserCancel: false, readerMode: NFCDispatchReaderMode()).listen((NDEFMessage message) {
// setState(() {
// _reading = true;
// mainWidget = doneNfc();
// });
// Future.delayed(const Duration(milliseconds: 500), () {
// _stream?.cancel();
// widget.onNcfScan(nfcId);
// Navigator.pop(context);
// });
// print("read NDEF id: ${message.id}");
// print("NFC Record " + message.payload);
// print("NFC Record Lenght " + message.records.length.toString());
// print("NFC Record " + message.records.first.id);
// print("NFC Record " + message.records.first.payload);
// print("NFC Record " + message.records.first.data);
// print("NFC Record " + message.records.first.type);
// // widget.onNcfScan(message.id);
// nfcId = message.id;
// }, onError: (e) {
// // Check error handling guide below
// });
// });
// }
//
// @override
// Widget build(BuildContext context) {
// (mainWidget == null && !_reading) ? mainWidget = scanNfc() : mainWidget = doneNfc();
// return AnimatedSwitcher(duration: Duration(milliseconds: 500), child: mainWidget);
// }
//
// Widget scanNfc() {
// return Container(
// key: ValueKey(1),
// child: Column(
// mainAxisSize: MainAxisSize.min,
// children: <Widget>[
// SizedBox(
// height: 30,
// ),
// Text(
// "Ready To Scan",
// style: TextStyle(
// fontWeight: FontWeight.bold,
// fontSize: 24,
// ),
// ),
// SizedBox(
// height: 30,
// ),
// Image.asset(
// "assets/images/nfc/ic_nfc.png",
// height: MediaQuery.of(context).size.width / 3,
// ),
// SizedBox(
// height: 30,
// ),
// Text(
// "Approach an NFC Tag",
// style: TextStyle(
// fontSize: 18,
// ),
// ),
// SizedBox(
// height: 30,
// ),
// ButtonTheme(
// minWidth: MediaQuery.of(context).size.width / 1.2,
// height: 45.0,
// buttonColor: Colors.grey[300],
// shape: RoundedRectangleBorder(
// borderRadius: BorderRadius.circular(6),
// ),
// child: RaisedButton(
// onPressed: () {
// _stream?.cancel();
// Navigator.pop(context);
// },
// elevation: 0,
// child: Text("CANCEL"),
// ),
// ),
// SizedBox(
// height: 30,
// ),
// ],
// ),
// );
// }
//
// Widget doneNfc() {
// return Container(
// key: ValueKey(2),
// child: Column(
// mainAxisSize: MainAxisSize.min,
// children: <Widget>[
// SizedBox(
// height: 30,
// ),
// Text(
// "Successfully Scanned",
// style: TextStyle(
// fontWeight: FontWeight.bold,
// fontSize: 24,
// ),
// ),
// SizedBox(
// height: 30,
// ),
// Image.asset(
// "assets/images/nfc/ic_done.png",
// height: MediaQuery.of(context).size.width / 3,
// ),
// SizedBox(
// height: 30,
// ),
// Text(
// "Approach an NFC Tag",
// style: TextStyle(
// fontSize: 18,
// ),
// ),
// SizedBox(
// height: 30,
// ),
// ButtonTheme(
// minWidth: MediaQuery.of(context).size.width / 1.2,
// height: 45.0,
// buttonColor: Colors.grey[300],
// shape: RoundedRectangleBorder(
// borderRadius: BorderRadius.circular(6),
// ),
// child: RaisedButton(
// // onPressed: () {
// // _stream?.cancel();
// // widget.onNcfScan(nfcId);
// // Navigator.pop(context);
// // },
// onPressed: null,
// elevation: 0,
// child: Text("DONE"),
// ),
// ),
// SizedBox(
// height: 30,
// ),
// ],
// ),
// );
// }
// }

@ -1,500 +0,0 @@
# Generated by pub
# See https://dart.dev/tools/pub/glossary#lockfile
packages:
args:
dependency: transitive
description:
name: args
url: "https://pub.dartlang.org"
source: hosted
version: "2.3.0"
async:
dependency: transitive
description:
name: async
url: "https://pub.dartlang.org"
source: hosted
version: "2.8.2"
boolean_selector:
dependency: transitive
description:
name: boolean_selector
url: "https://pub.dartlang.org"
source: hosted
version: "2.1.0"
characters:
dependency: transitive
description:
name: characters
url: "https://pub.dartlang.org"
source: hosted
version: "1.2.0"
charcode:
dependency: transitive
description:
name: charcode
url: "https://pub.dartlang.org"
source: hosted
version: "1.3.1"
clock:
dependency: transitive
description:
name: clock
url: "https://pub.dartlang.org"
source: hosted
version: "1.1.0"
collection:
dependency: transitive
description:
name: collection
url: "https://pub.dartlang.org"
source: hosted
version: "1.15.0"
crypto:
dependency: transitive
description:
name: crypto
url: "https://pub.dartlang.org"
source: hosted
version: "3.0.1"
cupertino_icons:
dependency: "direct main"
description:
name: cupertino_icons
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.4"
easy_localization:
dependency: "direct main"
description:
name: easy_localization
url: "https://pub.dartlang.org"
source: hosted
version: "3.0.0"
easy_logger:
dependency: transitive
description:
name: easy_logger
url: "https://pub.dartlang.org"
source: hosted
version: "0.0.2"
fake_async:
dependency: transitive
description:
name: fake_async
url: "https://pub.dartlang.org"
source: hosted
version: "1.2.0"
ffi:
dependency: transitive
description:
name: ffi
url: "https://pub.dartlang.org"
source: hosted
version: "1.1.2"
file:
dependency: transitive
description:
name: file
url: "https://pub.dartlang.org"
source: hosted
version: "6.1.2"
flutter:
dependency: "direct main"
description: flutter
source: sdk
version: "0.0.0"
flutter_lints:
dependency: "direct dev"
description:
name: flutter_lints
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.4"
flutter_localizations:
dependency: transitive
description: flutter
source: sdk
version: "0.0.0"
flutter_plugin_android_lifecycle:
dependency: transitive
description:
name: flutter_plugin_android_lifecycle
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.5"
flutter_svg:
dependency: "direct main"
description:
name: flutter_svg
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.0"
flutter_test:
dependency: "direct dev"
description: flutter
source: sdk
version: "0.0.0"
flutter_web_plugins:
dependency: transitive
description: flutter
source: sdk
version: "0.0.0"
fluttertoast:
dependency: "direct main"
description:
name: fluttertoast
url: "https://pub.dartlang.org"
source: hosted
version: "8.0.8"
http:
dependency: "direct main"
description:
name: http
url: "https://pub.dartlang.org"
source: hosted
version: "0.13.4"
http_parser:
dependency: transitive
description:
name: http_parser
url: "https://pub.dartlang.org"
source: hosted
version: "4.0.0"
injector:
dependency: "direct main"
description:
name: injector
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.0"
intl:
dependency: transitive
description:
name: intl
url: "https://pub.dartlang.org"
source: hosted
version: "0.17.0"
js:
dependency: transitive
description:
name: js
url: "https://pub.dartlang.org"
source: hosted
version: "0.6.3"
lints:
dependency: transitive
description:
name: lints
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.1"
local_auth:
dependency: "direct main"
description:
name: local_auth
url: "https://pub.dartlang.org"
source: hosted
version: "1.1.9"
matcher:
dependency: transitive
description:
name: matcher
url: "https://pub.dartlang.org"
source: hosted
version: "0.12.11"
meta:
dependency: transitive
description:
name: meta
url: "https://pub.dartlang.org"
source: hosted
version: "1.7.0"
nested:
dependency: transitive
description:
name: nested
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.0"
path:
dependency: transitive
description:
name: path
url: "https://pub.dartlang.org"
source: hosted
version: "1.8.0"
path_drawing:
dependency: transitive
description:
name: path_drawing
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.0"
path_parsing:
dependency: transitive
description:
name: path_parsing
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.0"
path_provider:
dependency: "direct main"
description:
name: path_provider
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.8"
path_provider_android:
dependency: transitive
description:
name: path_provider_android
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.9"
path_provider_ios:
dependency: transitive
description:
name: path_provider_ios
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.7"
path_provider_linux:
dependency: transitive
description:
name: path_provider_linux
url: "https://pub.dartlang.org"
source: hosted
version: "2.1.4"
path_provider_macos:
dependency: transitive
description:
name: path_provider_macos
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.4"
path_provider_platform_interface:
dependency: transitive
description:
name: path_provider_platform_interface
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.1"
path_provider_windows:
dependency: transitive
description:
name: path_provider_windows
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.4"
permission_handler:
dependency: "direct main"
description:
name: permission_handler
url: "https://pub.dartlang.org"
source: hosted
version: "8.3.0"
permission_handler_platform_interface:
dependency: transitive
description:
name: permission_handler_platform_interface
url: "https://pub.dartlang.org"
source: hosted
version: "3.7.0"
petitparser:
dependency: transitive
description:
name: petitparser
url: "https://pub.dartlang.org"
source: hosted
version: "4.4.0"
platform:
dependency: transitive
description:
name: platform
url: "https://pub.dartlang.org"
source: hosted
version: "3.1.0"
plugin_platform_interface:
dependency: transitive
description:
name: plugin_platform_interface
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.2"
process:
dependency: transitive
description:
name: process
url: "https://pub.dartlang.org"
source: hosted
version: "4.2.4"
provider:
dependency: "direct main"
description:
name: provider
url: "https://pub.dartlang.org"
source: hosted
version: "6.0.1"
shared_preferences:
dependency: transitive
description:
name: shared_preferences
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.11"
shared_preferences_android:
dependency: transitive
description:
name: shared_preferences_android
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.9"
shared_preferences_ios:
dependency: transitive
description:
name: shared_preferences_ios
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.8"
shared_preferences_linux:
dependency: transitive
description:
name: shared_preferences_linux
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.3"
shared_preferences_macos:
dependency: transitive
description:
name: shared_preferences_macos
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.2"
shared_preferences_platform_interface:
dependency: transitive
description:
name: shared_preferences_platform_interface
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.0"
shared_preferences_web:
dependency: transitive
description:
name: shared_preferences_web
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.2"
shared_preferences_windows:
dependency: transitive
description:
name: shared_preferences_windows
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.3"
shimmer:
dependency: "direct main"
description:
name: shimmer
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.0"
sizer:
dependency: "direct main"
description:
name: sizer
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.15"
sky_engine:
dependency: transitive
description: flutter
source: sdk
version: "0.0.99"
source_span:
dependency: transitive
description:
name: source_span
url: "https://pub.dartlang.org"
source: hosted
version: "1.8.1"
stack_trace:
dependency: transitive
description:
name: stack_trace
url: "https://pub.dartlang.org"
source: hosted
version: "1.10.0"
stream_channel:
dependency: transitive
description:
name: stream_channel
url: "https://pub.dartlang.org"
source: hosted
version: "2.1.0"
string_scanner:
dependency: transitive
description:
name: string_scanner
url: "https://pub.dartlang.org"
source: hosted
version: "1.1.0"
term_glyph:
dependency: transitive
description:
name: term_glyph
url: "https://pub.dartlang.org"
source: hosted
version: "1.2.0"
test_api:
dependency: transitive
description:
name: test_api
url: "https://pub.dartlang.org"
source: hosted
version: "0.4.3"
typed_data:
dependency: transitive
description:
name: typed_data
url: "https://pub.dartlang.org"
source: hosted
version: "1.3.0"
universal_io:
dependency: transitive
description:
name: universal_io
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.4"
vector_math:
dependency: transitive
description:
name: vector_math
url: "https://pub.dartlang.org"
source: hosted
version: "2.1.1"
win32:
dependency: transitive
description:
name: win32
url: "https://pub.dartlang.org"
source: hosted
version: "2.3.1"
xdg_directories:
dependency: transitive
description:
name: xdg_directories
url: "https://pub.dartlang.org"
source: hosted
version: "0.2.0"
xml:
dependency: transitive
description:
name: xml
url: "https://pub.dartlang.org"
source: hosted
version: "5.3.1"
sdks:
dart: ">=2.14.0 <3.0.0"
flutter: ">=2.5.0"

@ -18,7 +18,7 @@ publish_to: 'none' # Remove this line if you wish to publish to pub.dev
version: 1.0.0+1
environment:
sdk: ">=2.12.0 <3.0.0"
sdk: ">=2.16.0 <3.0.0"
# Dependencies specify other packages that your package needs in order to work.
# To automatically upgrade your package dependencies to the latest versions
@ -39,12 +39,26 @@ dependencies:
provider: ^6.0.1
easy_localization: ^3.0.0
http: ^0.13.4
permission_handler: ^8.3.0
permission_handler: ^9.2.0
flutter_svg: ^1.0.0
sizer: ^2.0.15
local_auth: ^1.1.9
fluttertoast: ^8.0.8
shared_preferences: ^2.0.12
firebase_messaging: ^11.2.8
shimmer: ^2.0.0
logger: ^1.1.0
flutter_countdown_timer: ^4.1.0
nfc_manager: ^3.1.1
uuid: ^3.0.6
# maps
google_maps_flutter: ^2.0.2
google_maps_utils: ^1.4.0+1
google_directions_api: ^0.9.0
geolocator: any
# flutter_compass: ^0.6.1
google_maps_flutter_web: ^0.3.2
dev_dependencies:
@ -80,6 +94,8 @@ flutter:
- assets/images/
- assets/images/login/
- assets/images/logos/
- assets/icons/nfc/ic_nfc.png
- assets/icons/nfc/ic_done.png
# An image asset can refer to one or more resolution-specific "variants", see
# https://flutter.dev/assets-and-images/#resolution-aware.

Loading…
Cancel
Save