diff --git a/.vscode/settings.json b/.vscode/settings.json index af7c712..6558ca6 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,5 +1,6 @@ { "cSpell.words": [ "MPLOYEEIMAGE" - ] + ], + "java.configuration.updateBuildConfiguration": "disabled" } \ No newline at end of file diff --git a/android/agconnect-services.json b/android/agconnect-services.json new file mode 100644 index 0000000..20a7546 --- /dev/null +++ b/android/agconnect-services.json @@ -0,0 +1,57 @@ +{ + "agcgw_all":{ + "CN":"connect-drcn.dbankcloud.cn", + "CN_back":"connect-drcn.hispace.hicloud.com", + "DE":"connect-dre.dbankcloud.cn", + "DE_back":"connect-dre.hispace.hicloud.com", + "RU":"connect-drru.hispace.dbankcloud.ru", + "RU_back":"connect-drru.hispace.dbankcloud.cn", + "SG":"connect-dra.dbankcloud.cn", + "SG_back":"connect-dra.hispace.hicloud.com" + }, + "websocketgw_all":{ + "CN":"connect-ws-drcn.hispace.dbankcloud.cn", + "CN_back":"connect-ws-drcn.hispace.dbankcloud.com", + "DE":"connect-ws-dre.hispace.dbankcloud.cn", + "DE_back":"connect-ws-dre.hispace.dbankcloud.com", + "RU":"connect-ws-drru.hispace.dbankcloud.ru", + "RU_back":"connect-ws-drru.hispace.dbankcloud.cn", + "SG":"connect-ws-dra.hispace.dbankcloud.cn", + "SG_back":"connect-ws-dra.hispace.dbankcloud.com" + }, + "client":{ + "cp_id":"2640966000002322881", + "product_id":"737518067793559971", + "client_id":"715996003571874624", + "client_secret":"B5B89A56A53847C6BB9D216A8747E75952760DF9A8232239D8744CD847A8FFDA", + "project_id":"737518067793559971", + "app_id":"104737117", + "api_key":"DAEDACKDrYgyco9mjPV9ZUjCSh1kCr/GBV0nseHH0z2mnxlZ41RksOKmyTi+PUTwmGEPK+VxCup4F9oUf4VbDnCsjB7aNBShYcjR+g==", + "package_name":"hmg.cloudSolutions.mohem" + }, + "oauth_client":{ + "client_id":"104737117", + "client_type":1 + }, + "app_info":{ + "app_id":"104737117", + "package_name":"hmg.cloudSolutions.mohem" + }, + "configuration_version":"3.0", + "appInfos":[ + { + "package_name":"hmg.cloudSolutions.mohem", + "client":{ + "app_id":"104737117" + }, + "app_info":{ + "package_name":"hmg.cloudSolutions.mohem", + "app_id":"104737117" + }, + "oauth_client":{ + "client_type":1, + "client_id":"104737117" + } + } + ] +} \ No newline at end of file diff --git a/android/app/build.gradle b/android/app/build.gradle index e760f43..255ebd4 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -1,25 +1,12 @@ -def localProperties = new Properties() -def localPropertiesFile = rootProject.file('local.properties') -if (localPropertiesFile.exists()) { - localPropertiesFile.withReader('UTF-8') { reader -> - localProperties.load(reader) - } -} - -def flutterRoot = localProperties.getProperty('flutter.sdk') -if (flutterRoot == null) { - throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.") +plugins { + id "com.android.application" + id "kotlin-android" + id "com.google.gms.google-services" + id "dev.flutter.flutter-gradle-plugin" + id "com.google.firebase.crashlytics" + id "com.huawei.agconnect" } -def flutterVersionCode = localProperties.getProperty('flutter.versionCode') -if (flutterVersionCode == null) { - flutterVersionCode = '1' -} - -def flutterVersionName = localProperties.getProperty('flutter.versionName') -if (flutterVersionName == null) { - flutterVersionName = '1.0' -} def keystoreProperties = new Properties() def keystorePropertiesFile = rootProject.file('key.properties') @@ -27,18 +14,17 @@ if (keystorePropertiesFile.exists()) { keystoreProperties.load(new FileInputStream(keystorePropertiesFile)) } -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" -apply plugin: 'com.huawei.agconnect' + android { - compileSdkVersion 34 + namespace 'hmg.cloudSolutions.mohem' + compileSdk 36 // Changed from 36 to a supported version + ndkVersion '28.2.13676358' compileOptions { sourceCompatibility JavaVersion.VERSION_1_8 targetCompatibility JavaVersion.VERSION_1_8 + coreLibraryDesugaringEnabled true } kotlinOptions { @@ -53,9 +39,15 @@ android { // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). applicationId "com.cloudsolutions.alhabibmohemm" minSdkVersion 28 - targetSdkVersion 34 - versionCode flutterVersionCode.toInteger() - versionName flutterVersionName +// targetSdk = flutter.targetSdkVersion + targetSdk 35 + versionCode flutter.versionCode + versionName flutter.versionName + multiDexEnabled true + } + + buildFeatures{ + buildConfig true } signingConfigs { @@ -84,5 +76,9 @@ flutter { } dependencies { - implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" + implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:2.1.20" + coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:2.1.5' + implementation 'com.huawei.hms:push:6.11.0.300' + + } diff --git a/android/app/src/debug/AndroidManifest.xml b/android/app/src/debug/AndroidManifest.xml index 50ab38d..443c7bf 100644 --- a/android/app/src/debug/AndroidManifest.xml +++ b/android/app/src/debug/AndroidManifest.xml @@ -1,5 +1,5 @@ + > diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml index 1518147..563251c 100644 --- a/android/app/src/main/AndroidManifest.xml +++ b/android/app/src/main/AndroidManifest.xml @@ -1,6 +1,6 @@ + > diff --git a/android/app/src/main/kotlin/com/mohem_flutter_app/MainActivity.kt b/android/app/src/main/kotlin/hmg/cloudSolutions/mohem/MainActivity.kt similarity index 93% rename from android/app/src/main/kotlin/com/mohem_flutter_app/MainActivity.kt rename to android/app/src/main/kotlin/hmg/cloudSolutions/mohem/MainActivity.kt index 0023ec9..15133a2 100644 --- a/android/app/src/main/kotlin/com/mohem_flutter_app/MainActivity.kt +++ b/android/app/src/main/kotlin/hmg/cloudSolutions/mohem/MainActivity.kt @@ -1,4 +1,4 @@ -package com.mohem_flutter_app +package hmg.cloudSolutions.mohem //import io.flutter.embedding.android.FlutterActivity // diff --git a/android/app/src/profile/AndroidManifest.xml b/android/app/src/profile/AndroidManifest.xml index 50ab38d..443c7bf 100644 --- a/android/app/src/profile/AndroidManifest.xml +++ b/android/app/src/profile/AndroidManifest.xml @@ -1,5 +1,5 @@ + > diff --git a/android/build.gradle b/android/build.gradle index 2c90dbd..8a97f51 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -1,5 +1,4 @@ buildscript { - ext.kotlin_version = '1.9.10' repositories { google() mavenCentral() @@ -7,11 +6,10 @@ buildscript { } dependencies { - classpath 'com.android.tools.build:gradle:7.1.3' - classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" - classpath 'com.google.gms:google-services:4.3.8' - classpath 'com.huawei.agconnect:agcp:1.8.0.300' - classpath "com.android.tools:r8:8.2.33" + classpath 'com.android.tools.build:gradle:7.3.0' + classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.7.10" + classpath 'com.google.gms:google-services:4.3.15' + classpath 'com.huawei.agconnect:agcp:1.9.1.304' } } @@ -21,14 +19,66 @@ allprojects { mavenCentral() maven { url 'https://developer.huawei.com/repo/' } } + + // Exclude old BouncyCastle globally to avoid duplicate classes + configurations.all { + exclude group: 'org.bouncycastle', module: 'bcprov-jdk16' + } + + tasks.withType(JavaCompile).configureEach { + sourceCompatibility = JavaVersion.VERSION_21 + targetCompatibility = JavaVersion.VERSION_21 + } + + tasks.withType(org.jetbrains.kotlin.gradle.tasks.KotlinCompile).configureEach { + kotlinOptions { + jvmTarget = "21" + } + } + + subprojects { + afterEvaluate { project -> + if (project.hasProperty('android')) { + project.android { + if (namespace == null) { + namespace project.group + } + + buildFeatures { + if (buildConfig == null) { + buildConfig true + } + } + compileOptions { + sourceCompatibility JavaVersion.VERSION_21 + targetCompatibility JavaVersion.VERSION_21 + } + } + } + // Force Java 17 for all JavaCompile tasks in all subprojects (including plugins) + project.tasks.withType(JavaCompile).configureEach { + sourceCompatibility = JavaVersion.VERSION_21 + targetCompatibility = JavaVersion.VERSION_21 + } + // Force Kotlin JVM target for all subprojects + project.tasks.withType(org.jetbrains.kotlin.gradle.tasks.KotlinCompile).configureEach { + kotlinOptions { + jvmTarget = "21" + } + } + } + } } + rootProject.buildDir = '../build' subprojects { project.buildDir = "${rootProject.buildDir}/${project.name}" +} +subprojects { project.evaluationDependsOn(':app') } tasks.register("clean", Delete) { - delete rootProject.buildDir + delete rootProject.layout.buildDirectory } diff --git a/android/gradle.properties b/android/gradle.properties index 54e1a43..fbdc0de 100644 --- a/android/gradle.properties +++ b/android/gradle.properties @@ -1,4 +1,6 @@ org.gradle.jvmargs=-Xmx2048M android.useAndroidX=true android.enableJetifier=true -org.gradle.java.home=/Users/user/Library/Java/JavaVirtualMachines/jbr-17.0.12/Contents/Home/ \ No newline at end of file +apmsInstrumentationEnabled=false + +#org.gradle.java.home=/Users/amirs/Library/Java/JavaVirtualMachines/jbr-17.0.12/Contents/Home/ \ No newline at end of file diff --git a/android/gradle/wrapper/gradle-wrapper.properties b/android/gradle/wrapper/gradle-wrapper.properties index 1e830b7..941ceb1 100644 --- a/android/gradle/wrapper/gradle-wrapper.properties +++ b/android/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ -#Thu Mar 06 11:40:30 AST 2025 +#Tue Jul 08 11:08:34 AST 2025 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.3.3-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.13-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/android/settings.gradle b/android/settings.gradle index 44e62bc..10a4a8d 100644 --- a/android/settings.gradle +++ b/android/settings.gradle @@ -1,11 +1,56 @@ -include ':app' +pluginManagement { + def flutterSdkPath = { + def properties = new Properties() + file("local.properties").withInputStream { properties.load(it) } + def flutterSdkPath = properties.getProperty("flutter.sdk") + assert flutterSdkPath != null, "flutter.sdk not set in local.properties" + return flutterSdkPath + }() -def localPropertiesFile = new File(rootProject.projectDir, "local.properties") -def properties = new Properties() -assert localPropertiesFile.exists() -localPropertiesFile.withReader("UTF-8") { reader -> properties.load(reader) } + includeBuild("$flutterSdkPath/packages/flutter_tools/gradle") -def flutterSdkPath = properties.getProperty("flutter.sdk") -assert flutterSdkPath != null, "flutter.sdk not set in local.properties" -apply from: "$flutterSdkPath/packages/flutter_tools/gradle/app_plugin_loader.gradle" + repositories { + google() + mavenCentral() + gradlePluginPortal() + maven { url 'https://developer.huawei.com/repo/' } + } + + resolutionStrategy { + eachPlugin { + if (requested.id.id == "com.huawei.agconnect") { + useModule("com.huawei.agconnect:agcp:1.9.1.304") + } + } + } + +} + + +plugins { + id "dev.flutter.flutter-plugin-loader" version "1.0.0" + id "com.android.application" version '8.11.0' apply false + id("org.jetbrains.kotlin.android") version "2.2.0" apply false + id("com.google.gms.google-services") version "4.4.3" apply false + id("com.google.firebase.crashlytics") version "3.0.4" apply false + id('org.gradle.toolchains.foojay-resolver-convention') version '0.9.0' apply false + id "com.huawei.agconnect" version "1.9.1.304" apply false +} + + +dependencyResolutionManagement { + repositories { + google() + mavenCentral() + gradlePluginPortal() + maven { url 'https://developer.huawei.com/repo/' } + maven { + url "https://artifactory.ess-dev.com/artifactory/gradle-dev-local" + } + } +} + + + +include ":app" diff --git a/assets/icons/mazaya_brand.svg b/assets/icons/mazaya_brand.svg new file mode 100755 index 0000000..52fb265 --- /dev/null +++ b/assets/icons/mazaya_brand.svg @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + diff --git a/assets/langs/ar-SA.json b/assets/langs/ar-SA.json index bc53ac7..2bf458a 100644 --- a/assets/langs/ar-SA.json +++ b/assets/langs/ar-SA.json @@ -612,5 +612,10 @@ "searchByUserName": "البحث بواسطة اسم المستخدم", "shareScreen": "مشاركة الشاشة", "start":"يبدأ", - "about":"عن" + "about":"عن", + "explore": "يستكشف", + "mazaya": "مازيا", + "benefits": "فوائد", + "mazayaDesc": "اكتشف الخصومات والعروض الخاصة المتاحة للموظفين", + "viewallofferMazaya" : "أعرض كل المزايا" } \ No newline at end of file diff --git a/assets/langs/en-US.json b/assets/langs/en-US.json index 2405127..1012d5a 100644 --- a/assets/langs/en-US.json +++ b/assets/langs/en-US.json @@ -612,5 +612,11 @@ "bonusQty": "Bonus Qty.", "balQty": "Bal. Qty.", "start":"Start", - "about":"About" + "about":"About", + "explore": "Explore", + "mazaya": "MAZAYA", + "benefits": "Benefits", + "mazayaDesc": "Discover special Discounts and offers available to Employees", + "viewallofferMazaya" : "View All Offers" + } \ No newline at end of file diff --git a/ios/Runner.xcodeproj/project.pbxproj b/ios/Runner.xcodeproj/project.pbxproj index a1fa803..3df58f1 100644 --- a/ios/Runner.xcodeproj/project.pbxproj +++ b/ios/Runner.xcodeproj/project.pbxproj @@ -242,6 +242,23 @@ shellPath = /bin/sh; shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin"; }; + 6C6E76E4FB19FAF11C24005D /* [CP] Copy Pods Resources */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources-${CONFIGURATION}-input-files.xcfilelist", + ); + name = "[CP] Copy Pods Resources"; + outputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources-${CONFIGURATION}-output-files.xcfilelist", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources.sh\"\n"; + showEnvVarsInLog = 0; + }; 9740EEB61CF901F6004384FC /* Run Script */ = { isa = PBXShellScriptBuildPhase; alwaysOutOfDate = 1; @@ -274,23 +291,6 @@ shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n"; showEnvVarsInLog = 0; }; - EF29CE25BB57F5AA48CE1136 /* [CP] Copy Pods Resources */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputFileListPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources-${CONFIGURATION}-input-files.xcfilelist", - ); - name = "[CP] Copy Pods Resources"; - outputFileListPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources-${CONFIGURATION}-output-files.xcfilelist", - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources.sh\"\n"; - showEnvVarsInLog = 0; - }; /* End PBXShellScriptBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ diff --git a/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme index 5e31d3d..9c12df5 100644 --- a/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme +++ b/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme @@ -26,6 +26,7 @@ buildConfiguration = "Debug" selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" + customLLDBInitFile = "$(SRCROOT)/Flutter/ephemeral/flutter_lldbinit" shouldUseLaunchSchemeArgsEnv = "YES"> diff --git a/lib/api/chat/chat_api_client.dart b/lib/api/chat/chat_api_client.dart index 510f6fa..a9667ec 100644 --- a/lib/api/chat/chat_api_client.dart +++ b/lib/api/chat/chat_api_client.dart @@ -28,7 +28,7 @@ class ChatApiClient { factory ChatApiClient() => _instance; Future getUserLoginToken() async { - user.UserAutoLoginModel userLoginResponse = user.UserAutoLoginModel(); + user.UserAutoLoginModel userLoginResponse = user.UserAutoLoginModel(); String? deviceToken = AppState().getIsHuawei ? AppState().getHuaweiPushToken : AppState().getDeviceToken; Response response = await ApiClient().postJsonForResponse( "${ApiConsts.chatLoginTokenUrl}externaluserlogin", diff --git a/lib/api/dashboard_api_client.dart b/lib/api/dashboard_api_client.dart index 145b039..b2ee4c2 100644 --- a/lib/api/dashboard_api_client.dart +++ b/lib/api/dashboard_api_client.dart @@ -1,6 +1,10 @@ import 'dart:async'; import 'dart:convert'; +import 'dart:io'; +import 'package:easy_localization/easy_localization.dart'; +import 'package:http/http.dart' as http; +import 'package:device_info_plus/device_info_plus.dart'; 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'; @@ -12,7 +16,9 @@ import 'package:mohem_flutter_app/models/dashboard/list_menu.dart'; import 'package:mohem_flutter_app/models/generic_response_model.dart'; import 'package:mohem_flutter_app/models/itg/itg_main_response.dart'; import 'package:mohem_flutter_app/models/itg/itg_response_model.dart'; -import 'package:platform_device_id/platform_device_id.dart'; +import 'package:mohem_flutter_app/models/sso_auth_model.dart'; +import 'package:platform_device_id_plus/platform_device_id.dart'; +// import 'package:platform_device_id/platform_device_id.dart'; // import 'package:platform_device_id/platform_device_id.dart'; import 'package:uuid/uuid.dart'; @@ -153,6 +159,59 @@ class DashboardApiClient { ); } + Future getTicketBookingRedirection() async { + String url = "${ApiConsts.erpRest}GET_PORTAL_REDIRECTION"; + Map postParams = {"P_USER_NAME": AppState().memberInformationList?.eMPLOYEENUMBER}; + postParams.addAll(AppState().postParamsJson); + return await ApiClient().postJsonForObject( + (json) { + GenericResponseModel responseData = GenericResponseModel.fromJson(json); + return responseData; + }, + url, + postParams, + ); + } + + Future getBookingSSOAuthRedirection({required String clientID}) async { + String url = "${ApiConsts.ssoAuthRedirection}?grantType=mohemm"; + //https://sso-uat.hmg.com/api/auth/connect?grantType=mohemm' + // Map postParams = {"P_USER_NAME": AppState().memberInformationList?.eMPLOYEENUMBER}; + Map postParams = { + "ClientId": clientID, + // "ClientId": "a9f4d1a0596d4aea8f830992ec4bdac1", + "PersonId": AppState().memberInformationList?.eMPLOYEENUMBER, + "Username": AppState().memberInformationList?.eMPLOYEENUMBER, + "Language": "US", + }; + postParams.addAll(AppState().postParamsJson); + return await ApiClient().postJsonForObject( + (json) { + SSOAuthModel responseData = SSOAuthModel.fromJson(json); + return responseData; + }, + url, + postParams, + ); + } + + Future getBookingSSOFinalRedirection({required String token}) async { + token = "eyJhbGciOiJSUzI1NiIsImtpZCI6IjhjZTE2OWM0YjIwYjQ2ZWM5YTQyOTU3Y2ZhODUzNzQ1IiwidHlwIjoiSldUIn0.eyJ0ZW5hbnRfaWQiOiJhOWY0ZDFhMDU5NmQ0YWVhOGY4MzA5OTJlYzRiZGFjMSIsImVpZCI6IjExNzkzMCIsImh0dHA6Ly9zY2hlbWFzLnhtbHNvYXAub3JnL3dzLzIwMDUvMDUvaWRlbnRpdHkvY2xhaW1zL3NpZCI6Ijk2MDI0OGM1NzA3YzQ3MmFhYTEzM2I1N2ZhODE1ZmVhIiwibGFuZ3VhZ2UiOiJVUyIsImh0dHA6Ly9zY2hlbWFzLnhtbHNvYXAub3JnL3dzLzIwMDUvMDUvaWRlbnRpdHkvY2xhaW1zL2VtYWlsYWRkcmVzcyI6IjExNzkzMEBobWcuY29tIiwiZXhwIjoxNzgyNDc1NzY5LCJpc3MiOiJodHRwczovL3Nzby11YXQuaG1nLmNvbSIsImF1ZCI6ImE5ZjRkMWEwNTk2ZDRhZWE4ZjgzMDk5MmVjNGJkYWMxIn0.rJcLVsG8D0XECyLERCTD2uqGeWyvp-OBVGE9uL2qKrX4etFUHgdFt_5kYF6edFTtGy-0PIZadHDmv7e-IOhVWHm5HVMClaukiXoRXR8cDN8XA1wfme3Kd-U5PXN-IRh49AyRTzLO0rYNPvH81ScosWGlsFSkOvA-0hJNa2adHdtvgNvB8wJshSU5p7sAmF8mjdDY6aInG19etu2iEuUDwHHA4ZY_ts4hboHo8fE392hFaYGonExoD7bpW5RMx5xKWeRCmWpG_PK8Aw_z1jGzdB9PANus4pteRGuln1J-kmo2lQC9pVrSyZATAKp1HfgfyZ_vUhaHEfM69cMWaCslJQ"; + var request = http.MultipartRequest('POST', Uri.parse('https://ek.techmaster.in/SSO/HMG')); + request.fields.addAll({'JWTToken': token}); + + // request.headers.addAll(headers); + + http.StreamedResponse response = await request.send(); + if (response.statusCode == 302) { + print("================== post =========="); + var res = await response.stream.bytesToString(); + return response.headers["location"]; + } else { + print(response.reasonPhrase); + } + } + //Mark Attendance Future markAttendance({ String lat = "0", @@ -165,10 +224,17 @@ class DashboardApiClient { }) async { String url = "${ApiConsts.swpRest}AuthenticateAndSwipeUserSupportNFC"; var uuid = Uuid(); + String? deviceId = ""; // Generate a v4 (random) id - + if (Platform.isAndroid) { + AndroidDeviceInfo androidInfo = await DeviceInfoPlugin().androidInfo; + deviceId = androidInfo.id; + } else if (Platform.isIOS) { + IosDeviceInfo iosInfo = await DeviceInfoPlugin().iosInfo; + deviceId = iosInfo.identifierForVendor; + } Map postParams = { - "UID": await PlatformDeviceId.getDeviceId, //uuid.v4(), //Mobile Id + "UID": deviceId, //uuid.v4(), //Mobile Id // "UID": uuid.v4(), //Mobile Id "Latitude": lat, "Longitude": long, diff --git a/lib/app_state/app_state.dart b/lib/app_state/app_state.dart index 66c21a5..1f045f4 100644 --- a/lib/app_state/app_state.dart +++ b/lib/app_state/app_state.dart @@ -90,7 +90,7 @@ class AppState { String get getHuaweiPushToken => _huaweiPushToken; - final PostParamsModel _postParamsInitConfig = PostParamsModel(channel: 33, versionID: 9.0, mobileType: Platform.isAndroid ? "android" : "ios"); + final PostParamsModel _postParamsInitConfig = PostParamsModel(channel: 33, versionID: 9.2, mobileType: Platform.isAndroid ? "android" : "ios"); void setPostParamsInitConfig() { isAuthenticated = false; diff --git a/lib/classes/colors.dart b/lib/classes/colors.dart index 915f35d..1b0dd06 100644 --- a/lib/classes/colors.dart +++ b/lib/classes/colors.dart @@ -66,4 +66,5 @@ class MyColors { static const Color darkGrey3BColor = Color(0xff3B3B3B); static const Color lightGreyIconColor = Color(0xff919191); static const Color selectedBorderColor = Color(0xff37A4BE); + static const Color mazayaRedColor = Color(0xffED1C2B); } diff --git a/lib/classes/consts.dart b/lib/classes/consts.dart index fea9b75..12635a6 100644 --- a/lib/classes/consts.dart +++ b/lib/classes/consts.dart @@ -11,10 +11,10 @@ class ApiConsts { static String baseUrl = "https://mohemm.hmg.com"; // New Live server // - // static String baseUrl = "https://uat.hmgwebservices.com"; // UAT ser343622ver + // static String baseUrl = "https://uat.hmgwebservices.com"; // UAT ser343622ver // static String baseUrl = "http://10.20.200.111:1010/"; - // static String baseUrl = "https://webservices.hmg.com"; // PreProd + // static String baseUrl = "https://webservices.hmg.com"; // PreProd // static String baseUrl = "https://mohemm.hmg.com"; // static String baseUrl = "https://hmgwebservices.com"; // Live server @@ -27,6 +27,8 @@ class ApiConsts { static String user = baseUrlServices + "api/User/"; static String cocRest = baseUrlServices + "COCWS.svc/REST/"; + static String ssoAuthRedirection = "https://sso-uat.hmg.com/api/auth/connect"; + //Chat static String chatServerBaseUrl = "https://apiderichat.hmg.com/"; static String chatServerBaseApiUrl = chatServerBaseUrl + "api/"; diff --git a/lib/classes/inAppWebView.dart b/lib/classes/inAppWebView.dart new file mode 100644 index 0000000..ccb24fd --- /dev/null +++ b/lib/classes/inAppWebView.dart @@ -0,0 +1,33 @@ +import 'dart:developer'; + +import 'package:flutter_inappwebview/flutter_inappwebview.dart'; + +class MyInAppBrowser extends InAppBrowser { + final Function onExitCallback; + final Function(String) onLoadStartCallback; + + MyInAppBrowser({ + required this.onExitCallback, + required this.onLoadStartCallback, + }); + + @override + Future onBrowserCreated() async { + log("\n\nBrowser Created!\n\n"); + } + + @override + Future onLoadStart(Uri? url) async { + onLoadStartCallback(url.toString()); + } + + @override + Future onLoadStop(Uri? url) async { + log("\n\nStopped $url\n\n"); + } + + @override + void onLoadError(Uri? url, int code, String message) { + log("Can't load $url.. Error: $message"); + } +} diff --git a/lib/classes/notifications.dart b/lib/classes/notifications.dart index 8f432d7..058606c 100644 --- a/lib/classes/notifications.dart +++ b/lib/classes/notifications.dart @@ -34,8 +34,8 @@ class AppNotifications { if (Platform.isIOS) { await flutterLocalNotificationsPlugin.resolvePlatformSpecificImplementation()?.requestPermissions(alert: true, badge: true, sound: true); } else if (Platform.isAndroid) { - AndroidFlutterLocalNotificationsPlugin? androidImplementation = flutterLocalNotificationsPlugin.resolvePlatformSpecificImplementation(); - bool? granted = await androidImplementation?.requestPermission(); + AndroidFlutterLocalNotificationsPlugin? androidImplementation = flutterLocalNotificationsPlugin.resolvePlatformSpecificImplementation(); + bool? granted = await androidImplementation?.requestNotificationsPermission(); if (granted == false) { if (kDebugMode) { print("-------------------- Permission Granted ------------------------"); diff --git a/lib/classes/utils.dart b/lib/classes/utils.dart index 1838cb8..0245bbf 100644 --- a/lib/classes/utils.dart +++ b/lib/classes/utils.dart @@ -31,13 +31,14 @@ class Utils { static void showToast(String message, {bool longDuration = true}) { Fluttertoast.showToast( - msg: message, - toastLength: longDuration ? Toast.LENGTH_LONG : Toast.LENGTH_SHORT, - gravity: ToastGravity.BOTTOM, - timeInSecForIosWeb: 1, - backgroundColor: Colors.black54, - textColor: Colors.white, - fontSize: 13.0); + msg: message, + toastLength: longDuration ? Toast.LENGTH_LONG : Toast.LENGTH_SHORT, + gravity: ToastGravity.BOTTOM, + timeInSecForIosWeb: 1, + backgroundColor: Colors.black54, + textColor: Colors.white, + fontSize: 13.0, + ); } static dynamic getNotNullValue(List list, int index) { @@ -63,12 +64,7 @@ class Utils { static void showLoading(BuildContext context) { WidgetsBinding.instance.addPostFrameCallback((_) { _isLoadingVisible = true; - showDialog( - context: context, - barrierColor: Colors.black.withOpacity(0.5), - useRootNavigator: false, - builder: (BuildContext context) => LoadingDialog(), - ).then((value) { + showDialog(context: context, barrierColor: Colors.black.withOpacity(0.5), useRootNavigator: false, builder: (BuildContext context) => LoadingDialog()).then((value) { _isLoadingVisible = false; }); }); @@ -118,13 +114,14 @@ class Utils { showDialog( barrierDismissible: false, context: cxt, - builder: (cxt) => ConfirmDialog( - message: errorMessage, - onTap: () { - Navigator.pushNamedAndRemoveUntil(cxt, AppRoutes.login, (Route route) => false); - }, - onCloseTap: () {}, - ), + builder: + (cxt) => ConfirmDialog( + message: errorMessage, + onTap: () { + Navigator.pushNamedAndRemoveUntil(cxt, AppRoutes.login, (Route route) => false); + }, + onCloseTap: () {}, + ), ); } else { if (cxt != null) { @@ -138,33 +135,18 @@ class Utils { } static Future showErrorDialog({required BuildContext context, required VoidCallback onOkTapped, required String message}) async { - return showDialog( - context: context, - builder: (BuildContext context) => ConfirmDialog( - message: message, - onTap: onOkTapped, - ), - ); + return showDialog(context: context, builder: (BuildContext context) => ConfirmDialog(message: message, onTap: onOkTapped)); } static void confirmDialog(cxt, String message, {VoidCallback? onTap}) { - showDialog( - context: cxt, - builder: (BuildContext cxt) => ConfirmDialog( - message: message, - onTap: onTap, - ), - ); + showDialog(context: cxt, builder: (BuildContext cxt) => ConfirmDialog(message: message, onTap: onTap)); } static Widget getNoDataWidget(BuildContext context) { return Column( mainAxisAlignment: MainAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.center, - children: [ - SvgPicture.asset('assets/images/not_found.svg', width: 110.0, height: 110.0), - LocaleKeys.noDataAvailable.tr().toText16().paddingOnly(top: 15), - ], + children: [SvgPicture.asset('assets/images/not_found.svg', width: 110.0, height: 110.0), LocaleKeys.noDataAvailable.tr().toText16().paddingOnly(top: 15)], ).center; } @@ -172,10 +154,7 @@ class Utils { return Column( mainAxisAlignment: MainAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.center, - children: [ - SvgPicture.asset('assets/images/not_found.svg', width: 110.0, height: 110.0), - LocaleKeys.noDataAvailable.tr().toText16().paddingOnly(top: 15), - ], + children: [SvgPicture.asset('assets/images/not_found.svg', width: 110.0, height: 110.0), LocaleKeys.noDataAvailable.tr().toText16().paddingOnly(top: 15)], ).center; } @@ -209,17 +188,7 @@ class Utils { return Column( crossAxisAlignment: CrossAxisAlignment.start, mainAxisSize: MainAxisSize.min, - children: [ - 6.height, - alignCenter ? text.toText12().center : text.toText12(), - 5.height, - if (showDivider) - const Divider( - height: 1, - color: Color(0xff2E303A), - thickness: 1, - ) - ], + children: [6.height, alignCenter ? text.toText12().center : text.toText12(), 5.height, if (showDivider) const Divider(height: 1, color: Color(0xff2E303A), thickness: 1)], ); } @@ -227,17 +196,15 @@ class Utils { return BoxDecoration( color: background, border: Border.all( - width: 1, // - color: background // <--- border width here - ), + width: 1, // + color: background, // <--- border width here + ), borderRadius: BorderRadius.circular(radius), ); } static Widget mHeight(double h) { - return Container( - height: h, - ); + return Container(height: h); } static Widget mDivider(Color color) { @@ -352,20 +319,21 @@ class Utils { if (!Platform.isIOS) { await showCupertinoModalPopup( context: context, - builder: (BuildContext cxt) => Container( - height: 250, - color: Colors.white, - child: CupertinoDatePicker( - backgroundColor: Colors.white, - mode: CupertinoDatePickerMode.date, - onDateTimeChanged: (DateTime value) { - if (value != null && value != selectedDate) { - selectedDate = value; - } - }, - initialDateTime: selectedDate, - ), - ), + builder: + (BuildContext cxt) => Container( + height: 250, + color: Colors.white, + child: CupertinoDatePicker( + backgroundColor: Colors.white, + mode: CupertinoDatePickerMode.date, + onDateTimeChanged: (DateTime value) { + if (value != null && value != selectedDate) { + selectedDate = value; + } + }, + initialDateTime: selectedDate, + ), + ), ); } else { DateTime? picked = await showDatePicker(context: context, initialDate: selectedDate, initialEntryMode: DatePickerEntryMode.calendarOnly, firstDate: DateTime(2015, 8), lastDate: DateTime(2101)); @@ -377,19 +345,25 @@ class Utils { } static void readNFc({required Function(String) onRead}) { - NfcManager.instance.startSession(onDiscovered: (NfcTag tag) async { - MifareUltralight f; - if (Platform.isAndroid) { - f = MifareUltralight(tag: tag, identifier: tag.data["nfca"]["identifier"], type: 2, maxTransceiveLength: 252, timeout: 22); - } else { - f = MifareUltralight(tag: tag, identifier: tag.data["mifare"]["identifier"], type: 2, maxTransceiveLength: 252, timeout: 22); - } - String identifier = f.identifier.map((e) => e.toRadixString(16).padLeft(2, '0')).join(''); - NfcManager.instance.stopSession(); - onRead(identifier); - }).catchError((err) { - print(err); - }); + NfcManager.instance + .startSession( + onDiscovered: (NfcTag tag) async { + MifareUltralight f; + if (Platform.isAndroid) { + print(tag); + f = MifareUltralight(tag: tag, identifier: tag.data["nfca"]["identifier"], type: 2, maxTransceiveLength: 252, timeout: 22); + } else { + f = MifareUltralight(tag: tag, identifier: tag.data["mifare"]["identifier"], type: 2, maxTransceiveLength: 252, timeout: 22); + } + String identifier = f.identifier.map((e) => e.toRadixString(16).padLeft(2, '0')).join(''); + NfcManager.instance.stopSession(); + onRead(identifier); + }, + pollingOptions: {NfcPollingOption.iso14443}, + ) + .catchError((err) { + print(err); + }); } //HUAWEI DECISION MAKING diff --git a/lib/dialogs/otp_dialog.dart b/lib/dialogs/otp_dialog.dart index 7265d97..da2611e 100644 --- a/lib/dialogs/otp_dialog.dart +++ b/lib/dialogs/otp_dialog.dart @@ -67,6 +67,7 @@ class OtpDialog { // projectProvider = Provider.of(context); return Dialog( backgroundColor: Colors.white, + surfaceTintColor: Colors.transparent, shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(20)), insetPadding: const EdgeInsets.only(left: 21, right: 21), child: StatefulBuilder(builder: (context, setState) { @@ -202,8 +203,13 @@ class OtpDialog { ), errorBorder: OutlineInputBorder( borderRadius: const BorderRadius.all(Radius.circular(10.0)), - borderSide: BorderSide(color: Theme.of(context).colorScheme.error), + borderSide: BorderSide(color: Colors.red), ), + // focusedErrorBorder: OutlineInputBorder( + // borderRadius: const BorderRadius.all(Radius.circular(10.0)), + // borderSide: BorderSide(color: Colors.red), + // // borderSide: BorderSide(color: Theme.of(context).colorScheme.error), + // ), focusedErrorBorder: OutlineInputBorder( borderRadius: const BorderRadius.all(Radius.circular(10.0)), borderSide: BorderSide(color: Theme.of(context).colorScheme.error), diff --git a/lib/generated/codegen_loader.g.dart b/lib/generated/codegen_loader.g.dart index 0e2cfbf..f3fda6a 100644 --- a/lib/generated/codegen_loader.g.dart +++ b/lib/generated/codegen_loader.g.dart @@ -1,6 +1,6 @@ // DO NOT EDIT. This is code generated via package:easy_localization/generate.dart -// ignore_for_file: prefer_single_quotes, avoid_renaming_method_parameters +// ignore_for_file: prefer_single_quotes, avoid_renaming_method_parameters, constant_identifier_names import 'dart:ui'; @@ -14,7 +14,7 @@ class CodegenLoader extends AssetLoader{ return Future.value(mapLocales[locale.toString()]); } - static const Map ar_SA = { + static const Map _ar_SA = { "mohemm": "Mohemm", "english": "English", "arabic": "عربي", @@ -116,6 +116,7 @@ class CodegenLoader extends AssetLoader{ "reject": "يرفض", "approve": "يوافق", "cancel": "إلغاء", + "generate": "يولد", "requestedItems": "العناصر المطلوبة", "request": "طلب", "myRequest": "طلبي", @@ -560,10 +561,9 @@ class CodegenLoader extends AssetLoader{ "missingDocuments": "مستندات مفقودة", "uploadedDocuments": "المستندات التي تم تحميلها", "addAtLeastOneAttachment": "الرجاء إضافة مرفق واحد على الأقل.", - "open": "يفتح", - "youCannotJoinTheMarathon": "لا يمكنك الانضمام إلى الماراثون لأنك تجاوزت الحد الزمني", "pleaseClickButtonToJoinMarathon": "الرجاء الضغط على الزر أدناه للانضمام إلى الماراثون", - "generate": "يولد", + "youCannotJoinTheMarathon": "لا يمكنك الانضمام إلى الماراثون لأنك تجاوزت الحد الزمني", + "open": "يفتح", "paymentRequest": "طلب الدفع", "paymentDetails": "تفاصيل الدفع", "requestNo": "رقم الطلب", @@ -627,10 +627,15 @@ class CodegenLoader extends AssetLoader{ "members": "الأعضاء", "searchByUserName": "البحث بواسطة اسم المستخدم", "shareScreen": "مشاركة الشاشة", - "start":"يبدأ", - "about":"عن" + "start": "يبدأ", + "about": "عن", + "explore": "يستكشف", + "mazaya": "مازيا", + "benefits": "فوائد", + "mazayaDesc": "اكتشف الخصومات والعروض الخاصة المتاحة للموظفين", + "viewallofferMazaya": "أعرض كل المزايا" }; -static const Map en_US = { +static const Map _en_US = { "mohemm": "Mohemm", "english": "English", "arabic": "عربي", @@ -725,6 +730,7 @@ static const Map en_US = { "whatsapp": "Whatsapp", "reject": "Reject", "approve": "Approve", + "generate": "Generate", "cancel": "Cancel", "requestedItems": "Requested Items", "request": "Request", @@ -1197,7 +1203,6 @@ static const Map en_US = { "pleaseClickButtonToJoinMarathon": "Press the button below to join the Marathon.", "youCannotJoinTheMarathon": "You cannot join the Marathon because you have exceeded the time limit.", "requesterOperatingUnit": "Requester Operating Unit", - "generate": "Generate", "paymentRequest": "Pay Request", "paymentDetails": "Payment Details", "requestNo": "Request No", @@ -1243,8 +1248,13 @@ static const Map en_US = { "qtyReceived": "Qty. Received", "bonusQty": "Bonus Qty.", "balQty": "Bal. Qty.", - "start":"Start", - "about":"About" + "start": "Start", + "about": "About", + "explore": "Explore", + "mazaya": "MAZAYA", + "benefits": "Benefits", + "mazayaDesc": "Discover special Discounts and offers available to Employees", + "viewallofferMazaya": "View All Offers" }; -static const Map> mapLocales = {"ar_SA": ar_SA, "en_US": en_US}; +static const Map> mapLocales = {"ar_SA": _ar_SA, "en_US": _en_US}; } diff --git a/lib/generated/locale_keys.g.dart b/lib/generated/locale_keys.g.dart index f8bc858..b748380 100644 --- a/lib/generated/locale_keys.g.dart +++ b/lib/generated/locale_keys.g.dart @@ -1,5 +1,7 @@ // DO NOT EDIT. This is code generated via package:easy_localization/generate.dart +// ignore_for_file: constant_identifier_names + abstract class LocaleKeys { static const mohemm = 'mohemm'; static const english = 'english'; @@ -101,6 +103,7 @@ abstract class LocaleKeys { static const reject = 'reject'; static const approve = 'approve'; static const cancel = 'cancel'; + static const generate = 'generate'; static const requestedItems = 'requestedItems'; static const request = 'request'; static const myRequest = 'myRequest'; @@ -530,10 +533,9 @@ abstract class LocaleKeys { static const missingDocuments = 'missingDocuments'; static const uploadedDocuments = 'uploadedDocuments'; static const addAtLeastOneAttachment = 'addAtLeastOneAttachment'; - static const open = 'open'; - static const youCannotJoinTheMarathon = 'youCannotJoinTheMarathon'; static const pleaseClickButtonToJoinMarathon = 'pleaseClickButtonToJoinMarathon'; - static const generate = 'generate'; + static const youCannotJoinTheMarathon = 'youCannotJoinTheMarathon'; + static const open = 'open'; static const paymentRequest = 'paymentRequest'; static const paymentDetails = 'paymentDetails'; static const requestNo = 'requestNo'; @@ -598,5 +600,11 @@ abstract class LocaleKeys { static const searchByUserName = 'searchByUserName'; static const shareScreen = 'shareScreen'; static const start = 'start'; - static const about ='about'; + static const about = 'about'; + static const explore = 'explore'; + static const mazaya = 'mazaya'; + static const benefits = 'benefits'; + static const mazayaDesc = 'mazayaDesc'; + static const viewallofferMazaya = 'viewallofferMazaya'; + } diff --git a/lib/models/chat/get_user_login_token_model.dart b/lib/models/chat/get_user_login_token_model.dart index 8d55461..f0620c3 100644 --- a/lib/models/chat/get_user_login_token_model.dart +++ b/lib/models/chat/get_user_login_token_model.dart @@ -5,21 +5,21 @@ UserAutoLoginModel userAutoLoginModelFromJson(String str) => UserAutoLoginModel. String userAutoLoginModelToJson(UserAutoLoginModel data) => json.encode(data.toJson()); class UserAutoLoginModel { - UserAutoLoginModel({ - this.response, - this.errorResponses, - }); + UserAutoLoginModel({this.response, this.errorResponses, this.StatusCode}); Response? response; List? errorResponses; + int? StatusCode; factory UserAutoLoginModel.fromJson(Map json) => UserAutoLoginModel( response: json["response"] == null ? null : Response.fromJson(json["response"]), + StatusCode: json["StatusCode"], errorResponses: json["errorResponses"] == null ? null : List.from(json["errorResponses"].map((x) => ErrorResponse.fromJson(x))), ); Map toJson() => { "response": response == null ? null : response!.toJson(), + "StatusCode": StatusCode, "errorResponses": errorResponses == null ? null : List.from(errorResponses!.map((x) => x.toJson())), }; } diff --git a/lib/models/generic_response_model.dart b/lib/models/generic_response_model.dart index ba48836..74cef13 100644 --- a/lib/models/generic_response_model.dart +++ b/lib/models/generic_response_model.dart @@ -1,3 +1,5 @@ +import 'dart:convert'; + import 'package:mohem_flutter_app/models/add_att_success_list_model.dart'; import 'package:mohem_flutter_app/models/add_attachment_list_model.dart'; import 'package:mohem_flutter_app/models/basic_member_information_model.dart'; @@ -391,275 +393,278 @@ class GenericResponseModel { String? ePharmacyGetItemOnHandList; bool? isActiveCode; bool? isSMSSent; - - GenericResponseModel( - {this.date, - this.languageID, - this.serviceName, - this.time, - this.androidLink, - this.authenticationTokenID, - this.data, - this.dataw, - this.dietType, - this.dietTypeID, - this.errorCode, - this.errorEndUserMessage, - this.errorEndUserMessageN, - this.errorMessage, - this.errorType, - this.foodCategory, - this.iOSLink, - this.isAuthenticated, - this.mealOrderStatus, - this.mealType, - this.messageStatus, - this.numberOfResultRecords, - this.patientBlodType, - this.successMsg, - this.successMsgN, - this.vidaUpdatedResponse, - this.addAttSuccessList, - this.addAttachmentList, - this.bCDomain, - this.bCLogo, - this.basicMemberInformation, - this.businessCardPrivilege, - this.calculateAbsenceDuration, - this.cancelHRTransactionLIst, - this.chatEmployeeLoginList, - this.companyBadge, - this.companyImage, - this.companyImageDescription, - this.companyImageURL, - this.companyMainCompany, - this.countryList, - this.createVacationRuleList, - this.deleteAttachmentList, - this.deleteVacationRuleList, - this.disableSessionList, - this.employeeQR, - this.employeeDocumentsList, - this.forgetPasswordTokenID, - this.getAbsenceAttachmentsList, - this.getAbsenceAttendanceTypesList, - this.getAbsenceCollectionNotificationBodyList, - this.getAbsenceDffStructureList, - this.getAbsenceTransactionList, - this.getAccrualBalancesList, - this.getActionHistoryList, - this.getPRActionHistoryList, - this.getAddressDffStructureList, - this.getAddressNotificationBodyList, - this.getApprovesList, - this.getAttachementList, - this.getPRAttachmentList, - this.getAttendanceTrackingList, - this.getBasicDetColsStructureList, - this.getBasicDetDffStructureList, - this.getBasicDetNtfBodyList, - this.getCEICollectionNotificationBodyList, - this.getCEIDFFStructureList, - this.getCEITransactionList, - this.getCcpTransactionsList, - this.getCcpTransactionsListNew, - this.getConcurrentProgramsList, - this.getContactColsStructureList, - this.getContactDetailsList, - this.getContactDffStructureList, - this.getContactNotificationBodyList, - this.getCountriesList, - this.getDayHoursTypeDetailsList, - this.getDeductionsList, - this.getDefaultValueList, - this.getEITCollectionNotificationBodyList, - this.getEITDFFStructureList, - this.getEITTransactionList, - this.getEarningsList, - this.getEmployeeAddressList, - this.getEmployeeBasicDetailsList, - this.getEmployeeContactsList, - this.getEmployeePhonesList, - this.getEmployeeSubordinatesList, - this.getFliexfieldStructureList, - this.getHrCollectionNotificationBodyList, - this.getHrTransactionList, - this.getItemCreationNtfBodyList, - this.getItemTypeNotificationsList, - this.getItemTypesList, - this.getLookupValuesList, - this.getMenuEntriesList, - this.getEventActivityList, - this.getMoItemHistoryList, - this.getMoNotificationBodyList, - this.getNotificationButtonsList, - this.getNotificationReassignModeList, - this.getObjectValuesList, - this.getOpenMissingSwipesList, - this.getOpenNotificationsList, - this.getOpenNotificationsNumList, - this.getOpenPeriodDatesList, - this.getOrganizationsSalariesList, - this.getPaymentInformationList, - this.getPayslipList, - this.getPerformanceAppraisalList, - this.getPhonesNotificationBodyList, - this.getPoItemHistoryList, - this.getPoNotificationBodyList, - this.getPrNotificationBodyList, - this.getPaymentNotificationBodyList, - this.getPRInformationList, - this.getQuotationAnalysisList, - this.getRFCEmployeeListList, - this.getRespondAttributeValueList, - this.getSITCollectionNotificationBodyList, - this.getSITDFFStructureList, - this.getSITTransactionList, - this.getScheduleShiftsDetailsList, - this.getShiftTypesList, - this.getStampMsNotificationBodyList, - this.getStampNsNotificationBodyList, - this.getSubordinatesAttdStatusList, - this.getSubordinatesLeavesList, - this.getSubordinatesLeavesTotalVacationsList, - this.getSummaryOfPaymentList, - this.getSwipesList, - this.getTermColsStructureList, - this.getTermDffStructureList, - this.getTermNotificationBodyList, - this.getTimeCardSummaryList, - this.getTicketsByEmployeeList, - this.getTicketDetailsByEmployee, - this.getTicketTransactions, - this.getTicketTypes, - this.getSectionTopics, - this.getMowadhafhiProjects, - this.getProjectDepartments, - this.getDepartmentSections, - this.getPendingTransactionsFunctions, - this.getPendingTransactionsDetails, - this.getConcurrentProgramsModel, - this.getCCPTransactionsModel, - this.getCCPOutputModel, - this.getCCPDFFStructureModel, - this.getUserItemTypesList, - this.getVacationRulesList, - this.getVaccinationOnHandList, - this.getVaccinationsList, - this.getValueSetValuesList, - this.getWorkList, - this.hRCertificateTemplate, - this.imgURLsList, - this.insertApInv, - this.insertBooked, - this.insertEmpSwipesList, - this.insertJournal, - this.insertOrders, - this.intPortalGetEmployeeList, - this.isDeviceTokenEmpty, - this.isPasswordExpired, - this.isRegisterAllowed, - this.isRequriedValueSetEmpty, - this.isUserSMSExcluded, - this.itemOnHand, - this.languageAvailable, - this.listSupplier, - this.listUserAgreement, - this.listEITStrucrure, - this.listItemImagesDetails, - this.listItemMaster, - this.listMedicineDetails, - this.listMenu, - this.listNewEmployees, - this.listRadScreen, - this.logInTokenID, - this.memberInformationList, - this.memberLoginList, - this.mohemmGetBusinessCardEnabledList, - this.mohemmGetFavoriteReplacementsList, - this.mohemmGetMobileDeviceInfobyEmpInfoList, - this.mohemmGetMobileLoginInfoList, - this.mohemmGetPatientIDList, - this.mohemmITGResponseItem, - this.mohemmIsChangeIsActiveBusinessCardEnable, - this.mohemmIsInsertBusinessCardEnable, - this.mohemmWifiPassword, - this.mohemmWifiSSID, - this.notificationAction, - this.notificationGetRespondAttributesList, - this.notificationRespondRolesList, - this.oracleOutPutNumber, - this.pASSWORDEXPIREDMSG, - this.pCOUNTRYCODE, - this.pCOUNTRYNAME, - this.pDESCFLEXCONTEXTCODE, - this.pDESCFLEXCONTEXTNAME, - this.pForm, - this.pINFORMATION, - this.pMBLID, - this.pNUMOFSUBORDINATES, - this.pOPENNTFNUMBER, - this.pQUESTION, - this.pSESSIONID, - this.pSchema, - this.pharmacyStockAddPharmacyStockList, - this.pharmacyStockGetOnHandList, - this.privilegeList, - this.processTransactions, - this.registerUserNameList, - this.replacementList, - this.respondAttributesList, - this.respondRolesList, - this.resubmitAbsenceTransactionList, - this.resubmitEITTransactionList, - this.resubmitHrTransactionList, - this.sFHGetPoNotificationBodyList, - this.sFHGetPrNotificationBodyList, - this.startAbsenceApprovalProccess, - this.startAddressApprovalProcessList, - this.startBasicDetApprProcessList, - this.startCeiApprovalProcess, - this.startContactApprovalProcessList, - this.startEitApprovalProcess, - this.startHrApprovalProcessList, - this.startPhonesApprovalProcessList, - this.startSitApprovalProcess, - this.startTermApprovalProcessList, - this.submitAddressTransactionList, - this.submitBasicDetTransactionList, - this.submitCEITransactionList, - this.submitCcpTransactionList, - this.submitContactTransactionList, - this.submitEITTransactionList, - this.submitHrTransactionList, - this.submitPhonesTransactionList, - this.submitSITTransactionList, - this.submitTermTransactionList, - this.subordinatesOnLeavesList, - this.sumbitAbsenceTransactionList, - this.tokenID, - this.updateAttachmentList, - this.updateEmployeeImageList, - this.updateItemTypeSuccessList, - this.updateUserItemTypesList, - this.updateVacationRuleList, - this.vHREmployeeLoginList, - this.vHRGetEmployeeDetailsList, - this.vHRGetManagersDetailsList, - this.vHRGetProjectByCodeList, - this.vHRIsVerificationCodeValid, - this.validateAbsenceTransactionList, - this.validateEITTransactionList, - this.validatePhonesTransactionList, - this.vrItemTypesList, - this.wFLookUpList, - this.eLearningGETEMPLOYEEPROFILEList, - this.eLearningLOGINList, - this.eLearningValidateLoginList, - this.eLearningValidate_LoginList, - this.ePharmacyGetItemOnHandList, - this.isActiveCode, - this.isSMSSent}); + PortalDirectionData? portalDirectionData; + + GenericResponseModel({ + this.date, + this.languageID, + this.portalDirectionData, + this.serviceName, + this.time, + this.androidLink, + this.authenticationTokenID, + this.data, + this.dataw, + this.dietType, + this.dietTypeID, + this.errorCode, + this.errorEndUserMessage, + this.errorEndUserMessageN, + this.errorMessage, + this.errorType, + this.foodCategory, + this.iOSLink, + this.isAuthenticated, + this.mealOrderStatus, + this.mealType, + this.messageStatus, + this.numberOfResultRecords, + this.patientBlodType, + this.successMsg, + this.successMsgN, + this.vidaUpdatedResponse, + this.addAttSuccessList, + this.addAttachmentList, + this.bCDomain, + this.bCLogo, + this.basicMemberInformation, + this.businessCardPrivilege, + this.calculateAbsenceDuration, + this.cancelHRTransactionLIst, + this.chatEmployeeLoginList, + this.companyBadge, + this.companyImage, + this.companyImageDescription, + this.companyImageURL, + this.companyMainCompany, + this.countryList, + this.createVacationRuleList, + this.deleteAttachmentList, + this.deleteVacationRuleList, + this.disableSessionList, + this.employeeQR, + this.employeeDocumentsList, + this.forgetPasswordTokenID, + this.getAbsenceAttachmentsList, + this.getAbsenceAttendanceTypesList, + this.getAbsenceCollectionNotificationBodyList, + this.getAbsenceDffStructureList, + this.getAbsenceTransactionList, + this.getAccrualBalancesList, + this.getActionHistoryList, + this.getPRActionHistoryList, + this.getAddressDffStructureList, + this.getAddressNotificationBodyList, + this.getApprovesList, + this.getAttachementList, + this.getPRAttachmentList, + this.getAttendanceTrackingList, + this.getBasicDetColsStructureList, + this.getBasicDetDffStructureList, + this.getBasicDetNtfBodyList, + this.getCEICollectionNotificationBodyList, + this.getCEIDFFStructureList, + this.getCEITransactionList, + this.getCcpTransactionsList, + this.getCcpTransactionsListNew, + this.getConcurrentProgramsList, + this.getContactColsStructureList, + this.getContactDetailsList, + this.getContactDffStructureList, + this.getContactNotificationBodyList, + this.getCountriesList, + this.getDayHoursTypeDetailsList, + this.getDeductionsList, + this.getDefaultValueList, + this.getEITCollectionNotificationBodyList, + this.getEITDFFStructureList, + this.getEITTransactionList, + this.getEarningsList, + this.getEmployeeAddressList, + this.getEmployeeBasicDetailsList, + this.getEmployeeContactsList, + this.getEmployeePhonesList, + this.getEmployeeSubordinatesList, + this.getFliexfieldStructureList, + this.getHrCollectionNotificationBodyList, + this.getHrTransactionList, + this.getItemCreationNtfBodyList, + this.getItemTypeNotificationsList, + this.getItemTypesList, + this.getLookupValuesList, + this.getMenuEntriesList, + this.getEventActivityList, + this.getMoItemHistoryList, + this.getMoNotificationBodyList, + this.getNotificationButtonsList, + this.getNotificationReassignModeList, + this.getObjectValuesList, + this.getOpenMissingSwipesList, + this.getOpenNotificationsList, + this.getOpenNotificationsNumList, + this.getOpenPeriodDatesList, + this.getOrganizationsSalariesList, + this.getPaymentInformationList, + this.getPayslipList, + this.getPerformanceAppraisalList, + this.getPhonesNotificationBodyList, + this.getPoItemHistoryList, + this.getPoNotificationBodyList, + this.getPrNotificationBodyList, + this.getPaymentNotificationBodyList, + this.getPRInformationList, + this.getQuotationAnalysisList, + this.getRFCEmployeeListList, + this.getRespondAttributeValueList, + this.getSITCollectionNotificationBodyList, + this.getSITDFFStructureList, + this.getSITTransactionList, + this.getScheduleShiftsDetailsList, + this.getShiftTypesList, + this.getStampMsNotificationBodyList, + this.getStampNsNotificationBodyList, + this.getSubordinatesAttdStatusList, + this.getSubordinatesLeavesList, + this.getSubordinatesLeavesTotalVacationsList, + this.getSummaryOfPaymentList, + this.getSwipesList, + this.getTermColsStructureList, + this.getTermDffStructureList, + this.getTermNotificationBodyList, + this.getTimeCardSummaryList, + this.getTicketsByEmployeeList, + this.getTicketDetailsByEmployee, + this.getTicketTransactions, + this.getTicketTypes, + this.getSectionTopics, + this.getMowadhafhiProjects, + this.getProjectDepartments, + this.getDepartmentSections, + this.getPendingTransactionsFunctions, + this.getPendingTransactionsDetails, + this.getConcurrentProgramsModel, + this.getCCPTransactionsModel, + this.getCCPOutputModel, + this.getCCPDFFStructureModel, + this.getUserItemTypesList, + this.getVacationRulesList, + this.getVaccinationOnHandList, + this.getVaccinationsList, + this.getValueSetValuesList, + this.getWorkList, + this.hRCertificateTemplate, + this.imgURLsList, + this.insertApInv, + this.insertBooked, + this.insertEmpSwipesList, + this.insertJournal, + this.insertOrders, + this.intPortalGetEmployeeList, + this.isDeviceTokenEmpty, + this.isPasswordExpired, + this.isRegisterAllowed, + this.isRequriedValueSetEmpty, + this.isUserSMSExcluded, + this.itemOnHand, + this.languageAvailable, + this.listSupplier, + this.listUserAgreement, + this.listEITStrucrure, + this.listItemImagesDetails, + this.listItemMaster, + this.listMedicineDetails, + this.listMenu, + this.listNewEmployees, + this.listRadScreen, + this.logInTokenID, + this.memberInformationList, + this.memberLoginList, + this.mohemmGetBusinessCardEnabledList, + this.mohemmGetFavoriteReplacementsList, + this.mohemmGetMobileDeviceInfobyEmpInfoList, + this.mohemmGetMobileLoginInfoList, + this.mohemmGetPatientIDList, + this.mohemmITGResponseItem, + this.mohemmIsChangeIsActiveBusinessCardEnable, + this.mohemmIsInsertBusinessCardEnable, + this.mohemmWifiPassword, + this.mohemmWifiSSID, + this.notificationAction, + this.notificationGetRespondAttributesList, + this.notificationRespondRolesList, + this.oracleOutPutNumber, + this.pASSWORDEXPIREDMSG, + this.pCOUNTRYCODE, + this.pCOUNTRYNAME, + this.pDESCFLEXCONTEXTCODE, + this.pDESCFLEXCONTEXTNAME, + this.pForm, + this.pINFORMATION, + this.pMBLID, + this.pNUMOFSUBORDINATES, + this.pOPENNTFNUMBER, + this.pQUESTION, + this.pSESSIONID, + this.pSchema, + this.pharmacyStockAddPharmacyStockList, + this.pharmacyStockGetOnHandList, + this.privilegeList, + this.processTransactions, + this.registerUserNameList, + this.replacementList, + this.respondAttributesList, + this.respondRolesList, + this.resubmitAbsenceTransactionList, + this.resubmitEITTransactionList, + this.resubmitHrTransactionList, + this.sFHGetPoNotificationBodyList, + this.sFHGetPrNotificationBodyList, + this.startAbsenceApprovalProccess, + this.startAddressApprovalProcessList, + this.startBasicDetApprProcessList, + this.startCeiApprovalProcess, + this.startContactApprovalProcessList, + this.startEitApprovalProcess, + this.startHrApprovalProcessList, + this.startPhonesApprovalProcessList, + this.startSitApprovalProcess, + this.startTermApprovalProcessList, + this.submitAddressTransactionList, + this.submitBasicDetTransactionList, + this.submitCEITransactionList, + this.submitCcpTransactionList, + this.submitContactTransactionList, + this.submitEITTransactionList, + this.submitHrTransactionList, + this.submitPhonesTransactionList, + this.submitSITTransactionList, + this.submitTermTransactionList, + this.subordinatesOnLeavesList, + this.sumbitAbsenceTransactionList, + this.tokenID, + this.updateAttachmentList, + this.updateEmployeeImageList, + this.updateItemTypeSuccessList, + this.updateUserItemTypesList, + this.updateVacationRuleList, + this.vHREmployeeLoginList, + this.vHRGetEmployeeDetailsList, + this.vHRGetManagersDetailsList, + this.vHRGetProjectByCodeList, + this.vHRIsVerificationCodeValid, + this.validateAbsenceTransactionList, + this.validateEITTransactionList, + this.validatePhonesTransactionList, + this.vrItemTypesList, + this.wFLookUpList, + this.eLearningGETEMPLOYEEPROFILEList, + this.eLearningLOGINList, + this.eLearningValidateLoginList, + this.eLearningValidate_LoginList, + this.ePharmacyGetItemOnHandList, + this.isActiveCode, + this.isSMSSent, + }); GenericResponseModel.fromJson(Map json) { date = json['Date']; @@ -688,6 +693,7 @@ class GenericResponseModel { successMsg = json['SuccessMsg']; successMsgN = json['SuccessMsgN']; vidaUpdatedResponse = json['VidaUpdatedResponse']; + portalDirectionData = json["PortalDirectionData"] == null ? null : PortalDirectionData.fromJson(json["PortalDirectionData"]); if (json['AddAttSuccessList'] != null) { addAttSuccessList = []; @@ -848,9 +854,10 @@ class GenericResponseModel { }); } - getCEICollectionNotificationBodyList = json["GetCEICollectionNotificationBodyList"] == null - ? null - : List.from(json["GetCEICollectionNotificationBodyList"].map((x) => GetEitCollectionNotificationBodyList.fromJson(x))); + getCEICollectionNotificationBodyList = + json["GetCEICollectionNotificationBodyList"] == null + ? null + : List.from(json["GetCEICollectionNotificationBodyList"].map((x) => GetEitCollectionNotificationBodyList.fromJson(x))); if (json['GetCEIDFFStructureList'] != null) { getCEIDFFStructureList = []; @@ -909,9 +916,10 @@ class GenericResponseModel { }); } getDefaultValueList = json['GetDefaultValueList'] != null ? GetDefaultValueList.fromJson(json['GetDefaultValueList']) : null; - getEITCollectionNotificationBodyList = json["GetEITCollectionNotificationBodyList"] == null - ? null - : List.from(json["GetEITCollectionNotificationBodyList"].map((x) => GetEitCollectionNotificationBodyList.fromJson(x))); + getEITCollectionNotificationBodyList = + json["GetEITCollectionNotificationBodyList"] == null + ? null + : List.from(json["GetEITCollectionNotificationBodyList"].map((x) => GetEitCollectionNotificationBodyList.fromJson(x))); if (json['GetEITDFFStructureList'] != null) { getEITDFFStructureList = []; json['GetEITDFFStructureList'].forEach((v) { @@ -1475,6 +1483,7 @@ class GenericResponseModel { data['SuccessMsg'] = this.successMsg; data['SuccessMsgN'] = this.successMsgN; data['VidaUpdatedResponse'] = this.vidaUpdatedResponse; + data['PortalDirectionData'] = portalDirectionData?.toJson(); if (this.addAttSuccessList != null) { data['AddAttSuccessList'] = this.addAttSuccessList!.map((v) => v.toJson()).toList(); @@ -1930,3 +1939,25 @@ class GenericResponseModel { return data; } } + +class PortalDirectionData { + String? pRedirection; + String? clientID; + + PortalDirectionData({this.pRedirection, this.clientID}); + + factory PortalDirectionData.fromRawJson(String str) => PortalDirectionData.fromJson(json.decode(str)); + + String toRawJson() => json.encode(toJson()); + + factory PortalDirectionData.fromJson(Map json) => PortalDirectionData(pRedirection: json["P_REDIRECTION"], clientID: json["ClientID"]); + + Map toJson() => {"P_REDIRECTION": pRedirection, "ClientID": clientID}; +} + + +class TicketBookingResult { + final bool success; + final String? clientId; + TicketBookingResult(this.success, this.clientId); +} \ No newline at end of file diff --git a/lib/models/sso_auth_model.dart b/lib/models/sso_auth_model.dart new file mode 100644 index 0000000..0ee9b98 --- /dev/null +++ b/lib/models/sso_auth_model.dart @@ -0,0 +1,65 @@ +import 'dart:convert'; + +class SSOAuthModel { + String? status; + List? message; + Data? data; + + SSOAuthModel({ + this.status, + this.message, + this.data, + }); + + factory SSOAuthModel.fromRawJson(String str) => SSOAuthModel.fromJson(json.decode(str)); + + String toRawJson() => json.encode(toJson()); + + factory SSOAuthModel.fromJson(Map json) => SSOAuthModel( + status: json["status"], + message: json["message"] == null ? [] : List.from(json["message"]!.map((x) => x)), + data: json["data"] == null ? null : Data.fromJson(json["data"]), + ); + + Map toJson() => { + "status": status, + "message": message == null ? [] : List.from(message!.map((x) => x)), + "data": data?.toJson(), + }; +} + +class Data { + String? accessToken; + String? idToken; + int? expiresIn; + String? refreshToken; + String? postBackUrl; + + Data({ + this.accessToken, + this.idToken, + this.expiresIn, + this.refreshToken, + this.postBackUrl, + }); + + factory Data.fromRawJson(String str) => Data.fromJson(json.decode(str)); + + String toRawJson() => json.encode(toJson()); + + factory Data.fromJson(Map json) => Data( + accessToken: json["accessToken"], + idToken: json["idToken"], + expiresIn: json["expiresIn"], + refreshToken: json["refreshToken"], + postBackUrl: json["postBackUrl"], + ); + + Map toJson() => { + "accessToken": accessToken, + "idToken": idToken, + "expiresIn": expiresIn, + "refreshToken": refreshToken, + "postBackUrl": postBackUrl, + }; +} diff --git a/lib/provider/chat_provider_model.dart b/lib/provider/chat_provider_model.dart index df0600a..43315ab 100644 --- a/lib/provider/chat_provider_model.dart +++ b/lib/provider/chat_provider_model.dart @@ -93,6 +93,12 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { Future getUserAutoLoginToken() async { userLoginToken.UserAutoLoginModel userLoginResponse = await ChatApiClient().getUserLoginToken(); + + if (userLoginResponse.StatusCode == 500) { + disbaleChatForThisUser = true; + notifyListeners(); + } + if (userLoginResponse.response != null) { AppState().setchatUserDetails = userLoginResponse; } else { @@ -399,8 +405,8 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { if (data.first.userChatReplyResponse != null) { if (data.first.fileTypeResponse != null) { if (data.first.userChatReplyResponse!.fileTypeId == 12 || data.first.userChatReplyResponse!.fileTypeId == 4 || data.first.userChatReplyResponse!.fileTypeId == 3) { - data.first.userChatReplyResponse!.image = - await ChatApiClient().downloadURL(fileName: data.first.userChatReplyResponse!.contant!, fileTypeDescription: data.first.fileTypeResponse!.fileTypeDescription ?? "image/jpg", fileSource: 1); + data.first.userChatReplyResponse!.image = await ChatApiClient() + .downloadURL(fileName: data.first.userChatReplyResponse!.contant!, fileTypeDescription: data.first.fileTypeResponse!.fileTypeDescription ?? "image/jpg", fileSource: 1); data.first.userChatReplyResponse!.isImageLoaded = true; } } @@ -476,8 +482,8 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { if (data.first.groupChatReplyResponse != null) { if (data.first.fileTypeResponse != null) { if (data.first.groupChatReplyResponse!.fileTypeId == 12 || data.first.groupChatReplyResponse!.fileTypeId == 4 || data.first.groupChatReplyResponse!.fileTypeId == 3) { - data.first.groupChatReplyResponse!.image = - await ChatApiClient().downloadURL(fileName: data.first.groupChatReplyResponse!.contant!, fileTypeDescription: data.first.fileTypeResponse!.fileTypeDescription ?? "image/jpg", fileSource: 2); + data.first.groupChatReplyResponse!.image = await ChatApiClient() + .downloadURL(fileName: data.first.groupChatReplyResponse!.contant!, fileTypeDescription: data.first.fileTypeResponse!.fileTypeDescription ?? "image/jpg", fileSource: 2); data.first.groupChatReplyResponse!.isImageLoaded = true; } } @@ -1653,7 +1659,7 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { void sRecoding() async { isVoiceMsg = true; recorderController.reset(); - await recorderController.record(path); + await recorderController.record(path: path); _recodeDuration = 0; _startTimer(); isRecoding = !isRecoding; @@ -1685,7 +1691,7 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin { File file = File(path!); file.readAsBytesSync(); path = file.path; - await playerController.preparePlayer(file.path, 1.0); + await playerController.preparePlayer(path:file.path, volume: 1.0); _timer?.cancel(); notifyListeners(); } diff --git a/lib/provider/dashboard_provider_model.dart b/lib/provider/dashboard_provider_model.dart index e644aa0..fc53773 100644 --- a/lib/provider/dashboard_provider_model.dart +++ b/lib/provider/dashboard_provider_model.dart @@ -21,6 +21,7 @@ import 'package:mohem_flutter_app/models/dashboard/mohemm_itg_pending_task_respo import 'package:mohem_flutter_app/models/generic_response_model.dart'; import 'package:mohem_flutter_app/models/itg/itg_response_model.dart'; import 'package:mohem_flutter_app/models/offers_and_discounts/get_offers_list.dart'; +import 'package:mohem_flutter_app/models/sso_auth_model.dart'; import 'package:mohem_flutter_app/widgets/dialogs/confirm_dialog.dart'; /// Mix-in [DiagnosticableTreeMixin] to have access to [debugFillProperties] for the devtool @@ -239,6 +240,7 @@ class DashboardProviderModel with ChangeNotifier, DiagnosticableTreeMixin { homeMenus = parseMenus(getMenuEntriesList ?? []); if (homeMenus!.isNotEmpty) { homeMenus!.first.menuEntiesList.insert(0, GetMenuEntriesList(requestType: "MONTHLY_ATTENDANCE", prompt: LocaleKeys.monthlyAttendance.tr())); + // homeMenus!.first.menuEntiesList.insert(1, GetMenuEntriesList(requestType: "TICKET_BOOKING", prompt: "Ticket Booking")); homeMenus!.first.menuEntiesList.add(GetMenuEntriesList(requestType: "VACATION_RULE", prompt: LocaleKeys.vacationRule.tr())); } isServicesMenusLoading = false; @@ -283,6 +285,61 @@ class DashboardProviderModel with ChangeNotifier, DiagnosticableTreeMixin { } } + Future fetchTicketBooking() async { + try { + GenericResponseModel? genericResponseModel = await DashboardApiClient().getTicketBookingRedirection(); + if (genericResponseModel?.portalDirectionData?.pRedirection!.toLowerCase() == "alma") { + return TicketBookingResult(true, genericResponseModel?.portalDirectionData?.clientID); + } + return TicketBookingResult(false, null); + } catch (ex) { + logger.wtf(ex); + isEventLoadingLoading = false; + notifyListeners(); + Utils.handleException(ex, null, null); + return TicketBookingResult(false, null); // Ensure a return value in case of an exception + } + } + + Future fetchSSOAuthRedirection({String? clientID}) async { + try { + SSOAuthModel? ssoResponse = await DashboardApiClient().getBookingSSOAuthRedirection(clientID: clientID!); + logger.d("SSO Response: ${ssoResponse!.toJson()}"); + if (ssoResponse.status == "Success") { + return ssoResponse; + } else { + Utils.showToast(ssoResponse.message!.first ?? "Failed to fetch SSO Auth Token"); + return null; + } + } catch (ex) { + logger.wtf(ex); + isEventLoadingLoading = false; + notifyListeners(); + Utils.handleException(ex, null, null); + return null; // Ensure a return value in case of an exception + } + } + + Future fetchURLRedirection({required String token}) async { + try { + dynamic res = await DashboardApiClient().getBookingSSOFinalRedirection(token: token); + logger.d("SSO URL: $res"); + return res; + // if (ssoResponse.status == "Success") { + // return ssoResponse; + // } else { + // Utils.showToast(ssoResponse.message!.first ?? "Failed to fetch SSO Auth Token"); + // return null; + // } + } catch (ex) { + logger.wtf(ex); + isEventLoadingLoading = false; + notifyListeners(); + Utils.handleException(ex, null, null); + return null; // Ensure a return value in case of an exception + } + } + List parseMenus(List getMenuEntriesList) { List menus = []; for (int i = 0; i < getMenuEntriesList.length; i++) { @@ -316,8 +373,6 @@ class DashboardProviderModel with ChangeNotifier, DiagnosticableTreeMixin { return res; } - - void notify() { notifyListeners(); } diff --git a/lib/theme/app_theme.dart b/lib/theme/app_theme.dart index b1a5570..f228600 100644 --- a/lib/theme/app_theme.dart +++ b/lib/theme/app_theme.dart @@ -16,84 +16,36 @@ class AppTheme { }, ), hintColor: Colors.grey[400], - colorScheme: ColorScheme.fromSwatch( - accentColor: MyColors.backgroundColor, - errorColor: const Color.fromRGBO(235, 80, 60, 1.0), - ), + colorScheme: ColorScheme.fromSwatch(accentColor: MyColors.backgroundColor).copyWith(surfaceTint : Colors.transparent), disabledColor: Colors.grey[300], + // errorColor: const Color.fromRGBO(235, 80, 60, 1.0), + applyElevationOverlayColor: false, scaffoldBackgroundColor: MyColors.backgroundColor, textSelectionTheme: const TextSelectionThemeData(cursorColor: Colors.grey, selectionColor: Color.fromRGBO(80, 100, 253, 0.5), selectionHandleColor: Colors.grey), canvasColor: Colors.white, + // backgroundColor: const Color.fromRGBO(255, 255, 255, 1), highlightColor: Colors.grey[100]!.withOpacity(0.4), splashColor: Colors.transparent, primaryColor: primaryColor, primaryColorDark: primaryColor, - buttonTheme: ButtonThemeData( - buttonColor: Colors.black, - ), - switchTheme: SwitchThemeData( - thumbColor: MaterialStateProperty.resolveWith( - (Set states) { - if (states.contains(MaterialState.disabled)) { - return null; - } - if (states.contains(MaterialState.selected)) { - return secondaryColor; - } - return null; - }), - trackColor: MaterialStateProperty.resolveWith( - (Set states) { - if (states.contains(MaterialState.disabled)) { - return null; - } - if (states.contains(MaterialState.selected)) { - return secondaryColor; - } - return null; - }), - ), - radioTheme: RadioThemeData( - fillColor: MaterialStateProperty.resolveWith( - (Set states) { - if (states.contains(MaterialState.disabled)) { - return null; - } - if (states.contains(MaterialState.selected)) { - return secondaryColor; - } - return null; - }), - ), - checkboxTheme: CheckboxThemeData( - fillColor: MaterialStateProperty.resolveWith( - (Set states) { - if (states.contains(MaterialState.disabled)) { - return null; - } - if (states.contains(MaterialState.selected)) { - return secondaryColor; - } - return null; - }), - ), + // toggleableActiveColor: secondaryColor, indicatorColor: secondaryColor, bottomSheetTheme: const BottomSheetThemeData( backgroundColor: Color(0xFFE0E0E0), ), + primaryTextTheme: const TextTheme( + // bodyText2: TextStyle(color: Colors.white), + ), iconTheme: const IconThemeData(color: MyColors.darkIconColor), textTheme: const TextTheme( - bodyMedium: TextStyle(color: Colors.black, letterSpacing: 0.6), - headlineSmall: TextStyle(color: Colors.white, letterSpacing: 0.6), - headlineMedium: TextStyle(color: Colors.white, letterSpacing: 0.6), + // bodyText1: TextStyle(color: Colors.black, letterSpacing: 0.6), + // headline1: TextStyle(color: Colors.white, letterSpacing: 0.6), + // headline2: TextStyle(color: Colors.white, letterSpacing: 0.6), ), floatingActionButtonTheme: const FloatingActionButtonThemeData(highlightElevation: 2, disabledElevation: 0, elevation: 2), - - appBarTheme: AppBarTheme( - systemOverlayStyle: const SystemUiOverlayStyle( - statusBarBrightness: Brightness.light, - ), + appBarTheme: AppBarTheme( color: const Color(0xff515A5D), + systemOverlayStyle: const SystemUiOverlayStyle(statusBarBrightness: Brightness.light), elevation: 0.0, actionsIconTheme: IconThemeData( color: Colors.grey[800], diff --git a/lib/ui/attendance/monthly_attendance_screen.dart b/lib/ui/attendance/monthly_attendance_screen.dart index a4374c3..cce9d3b 100644 --- a/lib/ui/attendance/monthly_attendance_screen.dart +++ b/lib/ui/attendance/monthly_attendance_screen.dart @@ -16,7 +16,7 @@ import 'package:mohem_flutter_app/models/get_schedule_shifts_details_list_model. import 'package:mohem_flutter_app/models/get_time_card_summary_list_model.dart'; import 'package:mohem_flutter_app/widgets/app_bar_widget.dart'; import 'package:mohem_flutter_app/widgets/circular_step_progress_bar.dart'; -import 'package:month_picker_dialog_2/month_picker_dialog_2.dart'; +import 'package:month_picker_dialog/month_picker_dialog.dart'; import 'package:pie_chart/pie_chart.dart'; import 'package:syncfusion_flutter_calendar/calendar.dart'; @@ -301,6 +301,7 @@ class _MonthlyAttendanceScreenState extends State { monthCellBuilder: (build, details) { if (details.date.month == formattedDate.month && details.date.year == formattedDate.year) { int val = details.date.day; + int index = val-1; //check day is off // if (getDayHoursTypeDetailsList.isNotEmpty) { // bool isDayIsOff = getDayHoursTypeDetailsList[val - 1].aTTENDEDFLAG == 'N' && getDayHoursTypeDetailsList[val - 1].dAYTYPE == 'OFF'; @@ -310,9 +311,9 @@ class _MonthlyAttendanceScreenState extends State { getDayHoursTypeDetailsList.where((GetDayHoursTypeDetailsList element) => DateFormat("MM/dd/yyyy", "en_US").parse(element.sCHEDULEDATE!).day == details.date.day).toList(); if (getDayHours.isNotEmpty) { - bool isDayIsOff = getDayHoursTypeDetailsList[0].aTTENDEDFLAG == 'N' && getDayHoursTypeDetailsList[0].dAYTYPE == 'OFF'; - bool isDayIsPresent = getDayHoursTypeDetailsList[0].aTTENDEDFLAG == 'Y'; - bool isDayIsAbsent = getDayHoursTypeDetailsList[0].aTTENDEDFLAG == 'N' && getDayHoursTypeDetailsList[0].aBSENTFLAG == 'Y'; + bool isDayIsOff = getDayHoursTypeDetailsList[index].aTTENDEDFLAG == 'N' && getDayHoursTypeDetailsList[index].dAYTYPE == 'OFF'; + bool isDayIsPresent = getDayHoursTypeDetailsList[index].aTTENDEDFLAG == 'Y'; + bool isDayIsAbsent = getDayHoursTypeDetailsList[index].aTTENDEDFLAG == 'N' && getDayHoursTypeDetailsList[index].aBSENTFLAG == 'Y'; if (isDayIsOff) { return Container( diff --git a/lib/ui/chat/chat_home.dart b/lib/ui/chat/chat_home.dart index 426c9a2..c522475 100644 --- a/lib/ui/chat/chat_home.dart +++ b/lib/ui/chat/chat_home.dart @@ -32,8 +32,11 @@ class _ChatHomeState extends State { @override void initState() { super.initState(); - data = Provider.of(context, listen: false); - data.registerEvents(); + + if (chatHubConnection.state == HubConnectionState.Connected) { + data = Provider.of(context, listen: false); + data.registerEvents(); + } } @override @@ -47,7 +50,6 @@ class _ChatHomeState extends State { data.getUserAutoLoginToken().whenComplete(() async { await data.buildHubConnection(); data.getUserRecentChats(); - }); return; } @@ -57,7 +59,7 @@ class _ChatHomeState extends State { // String isAppOpendByChat = await Utils.getStringFromPrefs("isAppOpendByChat"); // String notificationData = await Utils.getStringFromPrefs("notificationData"); // if (isAppOpendByChat != "null" || isAppOpendByChat == "true" && notificationData != "null") { - // data.openChatByNoti(context); + // data.openChatByNoti(context); // } }); } diff --git a/lib/ui/chat/chat_home_screen.dart b/lib/ui/chat/chat_home_screen.dart index 2f392f3..846f19d 100644 --- a/lib/ui/chat/chat_home_screen.dart +++ b/lib/ui/chat/chat_home_screen.dart @@ -214,8 +214,13 @@ class _ChatHomeScreenState extends State { }, ), floatingActionButton: FloatingActionButton( +// <<<<<<< HEAD +// elevation: 0, +// backgroundColor : Colors.transparent, +// ======= backgroundColor: Colors.transparent, elevation: 0, + child: Container( width: 60, height: 60, diff --git a/lib/ui/landing/dashboard_screen.dart b/lib/ui/landing/dashboard_screen.dart index 05cc2bf..d3ecb9f 100644 --- a/lib/ui/landing/dashboard_screen.dart +++ b/lib/ui/landing/dashboard_screen.dart @@ -60,10 +60,10 @@ class _DashboardScreenState extends State with WidgetsBindingOb void initState() { WidgetsBinding.instance.addObserver(this); super.initState(); + cProvider = Provider.of(context, listen: false); scheduleMicrotask(() { data = Provider.of(context, listen: false); marathonProvider = Provider.of(context, listen: false); - cProvider = Provider.of(context, listen: false); if (checkIfPrivilegedForChat()) { _bHubCon(); } @@ -117,6 +117,7 @@ class _DashboardScreenState extends State with WidgetsBindingOb } Future checkHubCon() async { + // chatHubConnection = await context.read().getHubConnection(); if (chatHubConnection.state == HubConnectionState.Connected) { await chatHubConnection.stop(); await chatHubConnection.start(); @@ -151,7 +152,7 @@ class _DashboardScreenState extends State with WidgetsBindingOb data.fetchLeaveTicketBalance(context, DateTime.now()); data.fetchMenuEntries(); data.fetchEventActivity(); - data.getCategoryOffersListAPI(context); + // data.getCategoryOffersListAPI(context); marathonProvider.getMarathonDetailsFromApi(); marathonProvider.getMarathonTutorial(); if (isFromInit) { @@ -175,10 +176,11 @@ class _DashboardScreenState extends State with WidgetsBindingOb if (list[ermIndex].notificationType == "Survey") { await Navigator.pushNamed(context, AppRoutes.survey, arguments: response.mohemmItgResponseItem!.result!.data!.first); } else { - await Navigator.pushNamed(context, AppRoutes.advertisement, arguments: { - "masterId": list[ermIndex].notificationMasterId, - "advertisement": response.mohemmItgResponseItem!.result!.data!.first.advertisement, - }); + await Navigator.pushNamed( + context, + AppRoutes.advertisement, + arguments: {"masterId": list[ermIndex].notificationMasterId, "advertisement": response.mohemmItgResponseItem!.result!.data!.first.advertisement}, + ); } } ermIndex++; @@ -235,88 +237,84 @@ class _DashboardScreenState extends State with WidgetsBindingOb @override Widget build(BuildContext context) { - return Scaffold( - key: _scaffoldState, - body: Column( - children: [ - Row( - children: [ - Builder(builder: (BuildContext context) { - return Row( - mainAxisSize: MainAxisSize.min, - children: [ - Image.memory( - Utils.dataFromBase64String( - AppState().memberInformationList!.eMPLOYEEIMAGE ?? "", - ), - errorBuilder: (BuildContext context, Object error, StackTrace? stackTrace) { - return SvgPicture.asset( - "assets/images/user.svg", - height: 34, + return SafeArea( + bottom: Platform.isAndroid ? true : false, + top: false, + child: Scaffold( + key: _scaffoldState, + body: Column( + children: [ + Row( + children: [ + Builder( + builder: (BuildContext context) { + return Row( + mainAxisSize: MainAxisSize.min, + children: [ + Image.memory( + Utils.dataFromBase64String(AppState().memberInformationList!.eMPLOYEEIMAGE ?? ""), + errorBuilder: (BuildContext context, Object error, StackTrace? stackTrace) { + return SvgPicture.asset("assets/images/user.svg", height: 34, width: 34); + }, width: 34, - ); - }, - width: 34, - height: 34, - fit: BoxFit.cover, - ).circle(50), - // 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(() { - _scaffoldState.currentState!.openDrawer(); - }); - }), - Image.asset("assets/images/logos/main_mohemm_logo.png", width: 134, height: 28).expanded, - SvgPicture.asset( - "assets/images/announcements.svg", - matchTextDirection: true, - ).onPress(() async { - await Navigator.pushNamed(context, AppRoutes.announcements); - }) - ], - ).paddingOnly(left: 21, right: 21, top: 48, bottom: 7), - Expanded( - child: SmartRefresher( - enablePullDown: true, - enablePullUp: false, - header: const MaterialClassicHeader( - color: MyColors.gradiantEndColor, - ), - controller: _refreshController, - onRefresh: () { - _onRefresh(false); - }, - child: SingleChildScrollView( - child: Column( - children: [ - Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - LocaleKeys.welcomeBack.tr().toText14(color: MyColors.grey77Color), - (AppState().memberInformationList!.eMPLOYEENAME ?? "").toText24(isBold: true), - 16.height, - Row( - children: [ - Expanded( - child: AspectRatio( - aspectRatio: 159 / 159, - child: Consumer( - builder: (BuildContext context, DashboardProviderModel model, Widget? child) { - return (model.isAttendanceTrackingLoading - ? GetAttendanceTrackingShimmer() - : Container( + height: 34, + fit: BoxFit.cover, + ).circle(50), + // 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(() { + _scaffoldState.currentState!.openDrawer(); + }); + }, + ), + Image.asset("assets/images/logos/main_mohemm_logo.png", width: 134, height: 28).expanded, + SvgPicture.asset("assets/images/announcements.svg", matchTextDirection: true).onPress(() async { + await Navigator.pushNamed(context, AppRoutes.announcements); + }), + ], + ).paddingOnly(left: 21, right: 21, top: 48, bottom: 7), + Expanded( + child: SmartRefresher( + enablePullDown: true, + enablePullUp: false, + header: const MaterialClassicHeader(color: MyColors.gradiantEndColor), + controller: _refreshController, + onRefresh: () { + _onRefresh(false); + }, + child: SingleChildScrollView( + child: Column( + children: [ + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + LocaleKeys.welcomeBack.tr().toText14(color: MyColors.grey77Color), + (AppState().memberInformationList!.eMPLOYEENAME ?? "").toText24(isBold: true), + 16.height, + Row( + children: [ + Expanded( + child: AspectRatio( + aspectRatio: 159 / 159, + child: Consumer( + builder: (BuildContext context, DashboardProviderModel model, Widget? 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, - ]), + gradient: const LinearGradient( + transform: GradientRotation(.46), + begin: Alignment.topRight, + end: Alignment.bottomLeft, + colors: [MyColors.gradiantEndColor, MyColors.gradiantStartColor], + ), ), child: Stack( alignment: Alignment.center, @@ -371,9 +369,10 @@ class _DashboardScreenState extends State with WidgetsBindingOb 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), + (model.attendanceTracking!.pSwipeIn == null ? "--:--" : model.attendanceTracking!.pSwipeIn).toString().toText14( + color: Colors.white, + isBold: true, + ), 4.height, ], ).paddingOnly(left: 12, right: 12), @@ -384,19 +383,15 @@ class _DashboardScreenState extends State with WidgetsBindingOb height: 45, padding: const EdgeInsets.only(left: 10, right: 10), decoration: BoxDecoration( - color: Color(0xff259EA4), + color: const Color(0xff259EA4), borderRadius: BorderRadius.only( - bottomRight: AppState().isArabic(context) ? Radius.circular(0) : Radius.circular(15), - bottomLeft: AppState().isArabic(context) ? Radius.circular(15) : Radius.circular(0), + bottomRight: AppState().isArabic(context) ? const Radius.circular(0) : const Radius.circular(15), + bottomLeft: AppState().isArabic(context) ? const Radius.circular(15) : const Radius.circular(0), ), ), child: SvgPicture.asset(model.isTimeRemainingInSeconds == 0 ? "assets/images/biometrics.svg" : "assets/images/biometrics.svg"), ).onPress(() { - showMyBottomSheet( - context, - callBackFunc: () {}, - child: MarkAttendanceWidget(model, isFromDashboard: true), - ); + showMyBottomSheet(context, callBackFunc: () {}, child: MarkAttendanceWidget(model, isFromDashboard: true)); }), ], ), @@ -404,324 +399,306 @@ class _DashboardScreenState extends State with WidgetsBindingOb ), ], ), - ).onPress( - () { - Navigator.pushNamed(context, AppRoutes.todayAttendance); - }, - )) - .animatedSwither(); - }, + ).onPress(() { + Navigator.pushNamed(context, AppRoutes.todayAttendance); + })) + .animatedSwither(); + }, + ), ), ), - ), - 9.width, - Expanded( - child: MenusWidget(), - ), - ], - ), - ], - ).paddingOnly(left: 21, right: 21, top: 7, bottom: 21), - eventActivityWidget(context), - Consumer(builder: (BuildContext context, DashboardProviderModel model, Widget? child) { - if (!model.isOffersLoading && model.getOffersList.isEmpty) { - return const SizedBox(); - } - return Column( + 9.width, + Expanded(child: MenusWidget()), + ], + ), + ], + ).paddingOnly(left: 21, right: 21, top: 7, bottom: 21), + eventActivityWidget(context), + Column( mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.start, 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), + Directionality( + textDirection: AppState().isArabic(context) ? ui.TextDirection.rtl : ui.TextDirection.ltr, + child: Container( + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(20), + gradient: const LinearGradient(colors: [Color(0xFF91C481), Color(0xFF7CCED7)], begin: Alignment.centerLeft, end: Alignment.centerRight), + ), + child: Padding( + padding: const EdgeInsets.all(3.0), // This creates the border width + child: Container( + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(17), // Slightly less than outer radius + ), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Expanded( + flex: 4, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.start, + children: [ + Row( + children: [ + Expanded( + flex: 2, + child: RichText( + text: + AppState().isArabic(context) + ? TextSpan( + children: [ + TextSpan( + text: 'اطلع على مميزات', + style: TextStyle(fontSize: 16, letterSpacing: -0.2, fontFamily: AppState().isArabic(context) ? 'Cairo' : 'Poppins', fontWeight: FontWeight.w700, height: 24 / 16, color: Color(0xFF5D5E5E)), + ), + TextSpan( + text: ' مزايا', + style: TextStyle( + fontSize: 16, + fontFamily: AppState().isArabic(context) ? 'Cairo' : 'Poppins', + fontWeight: FontWeight.w700, + letterSpacing: -0.2, + height: 24 / 16, + color: MyColors.mazayaRedColor, // Use your MAZAYA red color here if defined, e.g. MyColors.mazayaRed + ), + ), + ], + ) + : TextSpan( + children: [ + TextSpan( + text: LocaleKeys.explore.tr() + ' ', + style: const TextStyle(fontSize: 16, letterSpacing: -0.2, fontFamily: 'Poppins', fontWeight: FontWeight.w700, height: 24 / 16, color: Color(0xFF5D5E5E)), + ), + TextSpan( + text: LocaleKeys.mazaya.tr(), + style: const TextStyle( + fontSize: 16, + fontWeight: FontWeight.w700, + fontFamily: 'Poppins', + letterSpacing: -0.2, + height: 24 / 16, + color: MyColors.mazayaRedColor, // Use your MAZAYA red color here if defined, e.g. MyColors.mazayaRed + ), + ), + TextSpan( + text: ' ' + LocaleKeys.benefits.tr(), + style: const TextStyle(fontSize: 16, letterSpacing: -0.2, + fontFamily: 'Poppins',fontWeight: FontWeight.w700, height: 24 / 16, color: Color(0xFF5D5E5E)), + ), + ], + ), + ), + ), + const Expanded(flex: 1, child: SizedBox()), + ], ), - child: LocaleKeys.newString.tr().toText10(isBold: true)), - ], - ), - ], + const SizedBox(height: 8), + LocaleKeys.mazayaDesc.tr().toText11(color: const Color(0xFF5D5E5E)), + ], + ), + ), + Expanded( + flex: 2, + child: Column( + crossAxisAlignment: CrossAxisAlignment.end, + mainAxisAlignment: MainAxisAlignment.end, + children: [ + SvgPicture.asset("assets/icons/mazaya_brand.svg", width: 90, height: 47), + const SizedBox(height: 28), + LocaleKeys.viewallofferMazaya.tr().toText12(isUnderLine: true, color: const Color(0xFF3B3D4A)).onPress(() { + Navigator.pushNamed(context, AppRoutes.offersAndDiscounts); + }), + ], + ), + ), + ], + ).paddingOnly(left: 21, right: 21, top: 14, bottom: 14), ), ), - LocaleKeys.viewAllOffers.tr().toText12(isUnderLine: true).onPress(() { - Navigator.pushNamed(context, AppRoutes.offersAndDiscounts); - }) - ], - ).paddingOnly(left: 21, right: 21), - Consumer( - builder: (BuildContext context, DashboardProviderModel model, Widget? child) { - return 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: (BuildContext cxt, int index) { - return model.isOffersLoading - ? const OffersShimmerWidget() - : InkWell( - onTap: () { - navigateToDetails(data.getOffersList[index]); - }, - child: SizedBox( - width: 73, - child: Column( - crossAxisAlignment: CrossAxisAlignment.center, - children: [ - Container( - width: 73, - height: 73, - decoration: BoxDecoration( - color: Colors.white, - borderRadius: const BorderRadius.all( - Radius.circular(100), - ), - border: Border.all(color: MyColors.lightGreyE3Color, width: 1), - ), - child: ClipRRect( - borderRadius: const BorderRadius.all( - Radius.circular(50), - ), - child: Hero( - tag: "ItemImage" + data.getOffersList[index].offersDiscountId.toString()!, - transitionOnUserGestures: true, - child: Image.network( - data.getOffersList[index].logo ?? "", - fit: BoxFit.contain, - ), - ), - ), - ), - 4.height, - Expanded( - child: AppState().isArabic(context) - ? data.getOffersList[index].titleAr!.toText12(isCenter: true, maxLine: 1) - : data.getOffersList[index].titleEn!.toText12(isCenter: true, maxLine: 1), - ), - ], - ), - ), - ); - }, - separatorBuilder: (BuildContext cxt, int index) => 8.width, - itemCount: 9), - ); - }, + ).paddingOnly(left: 21, right: 21, top: 0, bottom: 21), ), ], - ); - }), - Container( - width: double.infinity, - padding: const EdgeInsets.only(top: 31), - decoration: BoxDecoration( - color: Colors.white, - borderRadius: const BorderRadius.only(topRight: Radius.circular(50), topLeft: Radius.circular(50)), - border: Border.all(color: MyColors.lightGreyEDColor, width: 1), ), - child: Column( - mainAxisSize: MainAxisSize.min, - children: [ - ServicesWidget(), - context.watch().isLoading ? const MarathonBannerShimmer().paddingAll(20) : const MarathonBanner().paddingOnly(left: 21, right: 21, bottom: 8, top: 8), - // context.watch().isTutorialLoading - // ? const MarathonBannerShimmer().paddingAll(20) - // : Container( - // padding: EdgeInsets.only(bottom: 12, top: 12), - // margin: EdgeInsets.only(left: 21, right: 21, bottom: 21, top: 8), - // width: double.infinity, - // alignment: Alignment.center, - // decoration: BoxDecoration( - // color: MyColors.backgroundBlackColor, - // borderRadius: BorderRadius.circular(20), - // border: Border.all(color: MyColors.lightGreyEDColor, width: 1), - // ), - // child: Column( - // crossAxisAlignment: CrossAxisAlignment.start, - // mainAxisSize: MainAxisSize.min, - // children: [ - // Text( - // "Tutorial:", - // style: TextStyle( - // fontSize: 11, - // fontStyle: FontStyle.italic, - // fontWeight: FontWeight.w600, - // color: MyColors.white.withOpacity(0.83), - // letterSpacing: -0.4, - // ), - // ), - // Text( - // context.read().tutorial?.tutorialName ?? "", - // overflow: TextOverflow.ellipsis, - // style: TextStyle( - // fontStyle: FontStyle.italic, - // fontSize: 19, - // fontWeight: FontWeight.bold, - // color: MyColors.white, - // height: 32 / 22, - // ), - // ), - // ], - // ), - // ).onPress(() { - // checkERMChannel(); - // // Navigator.pushNamed(context, AppRoutes.marathonTutorialScreen); - // }), - ], + Container( + width: double.infinity, + padding: const EdgeInsets.only(top: 31), + decoration: BoxDecoration( + color: Colors.white, + borderRadius: const BorderRadius.only(topRight: Radius.circular(50), topLeft: Radius.circular(50)), + border: Border.all(color: MyColors.lightGreyEDColor, width: 1), + ), + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + ServicesWidget(), + context.watch().isLoading ? const MarathonBannerShimmer().paddingAll(20) : const MarathonBanner().paddingOnly(left: 21, right: 21, bottom: 8, top: 8), + // context.watch().isTutorialLoading + // ? const MarathonBannerShimmer().paddingAll(20) + // : Container( + // padding: EdgeInsets.only(bottom: 12, top: 12), + // margin: EdgeInsets.only(left: 21, right: 21, bottom: 21, top: 8), + // width: double.infinity, + // alignment: Alignment.center, + // decoration: BoxDecoration( + // color: MyColors.backgroundBlackColor, + // borderRadius: BorderRadius.circular(20), + // border: Border.all(color: MyColors.lightGreyEDColor, width: 1), + // ), + // child: Column( + // crossAxisAlignment: CrossAxisAlignment.start, + // mainAxisSize: MainAxisSize.min, + // children: [ + // Text( + // "Tutorial:", + // style: TextStyle( + // fontSize: 11, + // fontStyle: FontStyle.italic, + // fontWeight: FontWeight.w600, + // color: MyColors.white.withOpacity(0.83), + // letterSpacing: -0.4, + // ), + // ), + // Text( + // context.read().tutorial?.tutorialName ?? "", + // overflow: TextOverflow.ellipsis, + // style: TextStyle( + // fontStyle: FontStyle.italic, + // fontSize: 19, + // fontWeight: FontWeight.bold, + // color: MyColors.white, + // height: 32 / 22, + // ), + // ), + // ], + // ), + // ).onPress(() { + // checkERMChannel(); + // // Navigator.pushNamed(context, AppRoutes.marathonTutorialScreen); + // }), + ], + ), ), + ], + ), + ), + ), + ), + ], + ), + drawer: AppDrawer(onLanguageChange: _onRefresh), + bottomNavigationBar: SizedBox( + height: Platform.isAndroid ? 70 : 100, + child: BottomNavigationBar( + items: [ + BottomNavigationBarItem(icon: SvgPicture.asset("assets/icons/home.svg", color: currentIndex == 0 ? MyColors.grey3AColor : MyColors.grey98Color).paddingAll(4), label: LocaleKeys.home.tr()), + BottomNavigationBarItem( + icon: SvgPicture.asset("assets/icons/create_req.svg", color: currentIndex == 1 ? MyColors.grey3AColor : MyColors.grey98Color).paddingAll(4), + label: LocaleKeys.mowadhafhiRequest.tr(), + ), + BottomNavigationBarItem( + icon: Stack( + alignment: Alignment.centerLeft, + children: [ + SvgPicture.asset("assets/icons/work_list.svg", color: currentIndex == 2 ? MyColors.grey3AColor : MyColors.grey98Color).paddingAll(4), + Consumer( + builder: (BuildContext cxt, DashboardProviderModel data, Widget? child) { + if (data.workListCounter == 0) { + return const SizedBox(); + } + return Positioned( + right: 0, + top: 0, + child: Container( + padding: const EdgeInsets.only(left: 4, right: 4), + alignment: Alignment.center, + decoration: BoxDecoration(color: MyColors.redColor, borderRadius: BorderRadius.circular(17)), + child: data.workListCounter.toString().toText10(color: Colors.white), + ), + ); + }, ), ], ), + label: LocaleKeys.workList.tr(), ), - ), - ) - ], - ), - drawer: SafeArea( - child: AppDrawer(onLanguageChange: _onRefresh), - ), - bottomNavigationBar: SizedBox( - height: Platform.isAndroid ? 70 : 100, - child: BottomNavigationBar( - items: [ - BottomNavigationBarItem( - icon: SvgPicture.asset( - "assets/icons/home.svg", - color: currentIndex == 0 ? MyColors.grey3AColor : MyColors.grey98Color, - ).paddingAll(4), - label: LocaleKeys.home.tr(), - ), - BottomNavigationBarItem( - icon: SvgPicture.asset( - "assets/icons/create_req.svg", - color: currentIndex == 1 ? MyColors.grey3AColor : MyColors.grey98Color, - ).paddingAll(4), - label: LocaleKeys.mowadhafhiRequest.tr(), - ), - BottomNavigationBarItem( - icon: Stack( - alignment: Alignment.centerLeft, - children: [ - SvgPicture.asset( - "assets/icons/work_list.svg", - color: currentIndex == 2 ? MyColors.grey3AColor : MyColors.grey98Color, - ).paddingAll(4), - Consumer( - builder: (BuildContext cxt, DashboardProviderModel data, Widget? child) { - if (data.workListCounter == 0) { - return const SizedBox(); - } - return Positioned( - right: 0, - top: 0, - child: Container( - padding: const EdgeInsets.only(left: 4, right: 4), - alignment: Alignment.center, - decoration: BoxDecoration(color: MyColors.redColor, borderRadius: BorderRadius.circular(17)), - child: data.workListCounter.toString().toText10(color: Colors.white), - ), - ); - }, - ), - ], + BottomNavigationBarItem( + icon: SvgPicture.asset("assets/icons/item_for_sale.svg", color: currentIndex == 3 ? MyColors.grey3AColor : MyColors.grey98Color).paddingAll(4), + label: LocaleKeys.itemsForSale.tr(), ), - label: LocaleKeys.workList.tr(), - ), - BottomNavigationBarItem( - icon: SvgPicture.asset( - "assets/icons/item_for_sale.svg", - color: currentIndex == 3 ? MyColors.grey3AColor : MyColors.grey98Color, - ).paddingAll(4), - label: LocaleKeys.itemsForSale.tr(), - ), - BottomNavigationBarItem( - icon: Stack( - alignment: Alignment.centerLeft, - children: [ - SvgPicture.asset( - "assets/icons/chat/chat.svg", - color: !checkIfPrivilegedForChat() ? MyColors.lightGreyE3Color : currentIndex == 4 - ? MyColors.grey3AColor - : cProvider.disbaleChatForThisUser - ? MyColors.lightGreyE3Color - : MyColors.grey98Color, - ).paddingAll(4), - Consumer( - builder: (BuildContext cxt, ChatProviderModel data, Widget? child) { - return !checkIfPrivilegedForChat() ? const SizedBox() : Positioned( - right: 0, - top: 0, - child: Container( - padding: const EdgeInsets.only(left: 4, right: 4), - alignment: Alignment.center, - decoration: BoxDecoration(color: cProvider.disbaleChatForThisUser ? MyColors.pinkDarkColor : MyColors.redColor, borderRadius: BorderRadius.circular(17)), - child: data.chatUConvCounter.toString().toText10(color: Colors.white), - ), - ); - }, - ), - ], + BottomNavigationBarItem( + icon: Stack( + alignment: Alignment.centerLeft, + children: [ + SvgPicture.asset( + "assets/icons/chat/chat.svg", + color: + !checkIfPrivilegedForChat() + ? MyColors.lightGreyE3Color + : currentIndex == 4 + ? MyColors.grey3AColor + : cProvider.disbaleChatForThisUser + ? MyColors.lightGreyE3Color + : MyColors.grey98Color, + ).paddingAll(4), + Consumer( + builder: (BuildContext cxt, ChatProviderModel data, Widget? child) { + return !checkIfPrivilegedForChat() + ? const SizedBox() + : Positioned( + right: 0, + top: 0, + child: Container( + padding: const EdgeInsets.only(left: 4, right: 4), + alignment: Alignment.center, + decoration: BoxDecoration(color: cProvider.disbaleChatForThisUser ? MyColors.pinkDarkColor : MyColors.redColor, borderRadius: BorderRadius.circular(17)), + child: data.chatUConvCounter.toString().toText10(color: Colors.white), + ), + ); + }, + ), + ], + ), + label: LocaleKeys.chat.tr(), ), - label: LocaleKeys.chat.tr(), - ), - ], - currentIndex: currentIndex, - selectedLabelStyle: const TextStyle(fontSize: 10, color: MyColors.grey3AColor, fontWeight: FontWeight.w600), - unselectedLabelStyle: const TextStyle(fontSize: 10, color: MyColors.grey98Color, fontWeight: FontWeight.w600), - type: BottomNavigationBarType.fixed, - selectedItemColor: MyColors.grey3AColor, - backgroundColor: MyColors.backgroundColor, - selectedIconTheme: const IconThemeData(color: MyColors.grey3AColor, size: 28), - unselectedIconTheme: const IconThemeData(color: MyColors.grey98Color, size: 28), - onTap: (int index) { - if (index == 1) { - Navigator.pushNamed(context, AppRoutes.mowadhafhi); - } else if (index == 2) { - Navigator.pushNamed(context, AppRoutes.workList); - } else if (index == 3) { - Navigator.pushNamed(context, AppRoutes.itemsForSale); - } else if (index == 4) { - if (!cProvider.disbaleChatForThisUser && checkIfPrivilegedForChat()) { - Navigator.pushNamed(context, AppRoutes.chat); + ], + currentIndex: currentIndex, + selectedLabelStyle: const TextStyle(fontSize: 10, color: MyColors.grey3AColor, fontWeight: FontWeight.w600), + unselectedLabelStyle: const TextStyle(fontSize: 10, color: MyColors.grey98Color, fontWeight: FontWeight.w600), + type: BottomNavigationBarType.fixed, + selectedItemColor: MyColors.grey3AColor, + backgroundColor: MyColors.backgroundColor, + selectedIconTheme: const IconThemeData(color: MyColors.grey3AColor, size: 28), + unselectedIconTheme: const IconThemeData(color: MyColors.grey98Color, size: 28), + onTap: (int index) { + if (index == 1) { + Navigator.pushNamed(context, AppRoutes.mowadhafhi); + } else if (index == 2) { + Navigator.pushNamed(context, AppRoutes.workList); + } else if (index == 3) { + Navigator.pushNamed(context, AppRoutes.itemsForSale); + } else if (index == 4) { + if (!cProvider.disbaleChatForThisUser && checkIfPrivilegedForChat()) { + Navigator.pushNamed(context, AppRoutes.chat); + } } - } - }, + }, + ), ), ), ); } - bool checkIfPrivilegedForChat() { - for (PrivilegeListModel element in AppState().privilegeListModel!) { - if (element.serviceName?.toLowerCase() == "chat") { - if (element.previlege != null) { - return element.previlege!; - } - } - } - return false; - } - Widget eventActivityWidget(BuildContext context) { return (context.watch().isEventLoadingLoading) ? const MarathonBannerShimmer().paddingOnly(left: 21, right: 21, bottom: 21, top: 0) : (context.watch().eventActivity != null && context.watch().eventActivity!.isActive == true) - ? const EventActivityBanner().paddingOnly(left: 21, right: 21, bottom: 21, top: 0) - : const SizedBox(); + ? const EventActivityBanner().paddingOnly(left: 21, right: 21, bottom: 21, top: 0) + : const SizedBox(); } void navigateToDetails(OffersListModel offersListModelObj) { @@ -741,4 +718,15 @@ class _DashboardScreenState extends State with WidgetsBindingOb }); Navigator.pushNamed(context, AppRoutes.offersAndDiscountsDetails, arguments: getOffersDetailList); } + + bool checkIfPrivilegedForChat() { + for (PrivilegeListModel element in AppState().privilegeListModel!) { + if (element.serviceName?.toLowerCase() == "chat") { + if (element.previlege != null) { + return element.previlege!; + } + } + } + return false; + } } diff --git a/lib/ui/landing/widget/services_widget.dart b/lib/ui/landing/widget/services_widget.dart index 7c19b58..7d2c2b2 100644 --- a/lib/ui/landing/widget/services_widget.dart +++ b/lib/ui/landing/widget/services_widget.dart @@ -1,20 +1,56 @@ +import 'dart:convert'; +import 'dart:developer'; + import 'package:easy_localization/src/public_ext.dart'; import 'package:flutter/material.dart'; +import 'package:flutter_inappwebview/flutter_inappwebview.dart'; import 'package:flutter_svg/svg.dart'; import 'package:mohem_flutter_app/app_state/app_state.dart'; +import 'package:mohem_flutter_app/classes/inAppWebView.dart'; +import 'package:mohem_flutter_app/classes/utils.dart'; import 'package:mohem_flutter_app/config/routes.dart'; import 'package:mohem_flutter_app/extensions/int_extensions.dart'; import 'package:mohem_flutter_app/extensions/string_extensions.dart'; import 'package:mohem_flutter_app/extensions/widget_extensions.dart'; import 'package:mohem_flutter_app/generated/locale_keys.g.dart'; +import 'package:mohem_flutter_app/main.dart'; import 'package:mohem_flutter_app/models/dashboard/menu_entries.dart'; +import 'package:mohem_flutter_app/models/generic_response_model.dart'; +import 'package:mohem_flutter_app/models/sso_auth_model.dart'; import 'package:mohem_flutter_app/provider/dashboard_provider_model.dart'; import 'package:mohem_flutter_app/ui/my_attendance/dynamic_screens/dynamic_listview_screen.dart'; import 'package:mohem_flutter_app/ui/my_attendance/services_menu_list_screen.dart'; import 'package:mohem_flutter_app/widgets/shimmer/dashboard_shimmer_widget.dart'; +import 'package:mohem_flutter_app/widgets/sso_webview_widget.dart'; import 'package:provider/provider.dart'; +import 'package:url_launcher/url_launcher.dart'; class ServicesWidget extends StatelessWidget { + MyInAppBrowser? myInAppBrowser; + var inAppBrowserOptions = InAppBrowserClassSettings( + webViewSettings: InAppWebViewSettings( + useShouldOverrideUrlLoading: false, + transparentBackground: false, + isInspectable: false, + applePayAPIEnabled: true, + cacheEnabled: false, + allowsBackForwardNavigationGestures: false, + ), + browserSettings: InAppBrowserSettings( + hideUrlBar: true, + hideTitleBar: true, + hideDefaultMenuItems: true, + hideToolbarBottom: true, + hideToolbarTop: false, + hideCloseButton: false, + allowGoBackWithBackButton: false, + toolbarBottomBackgroundColor: Colors.black, + closeButtonColor: Colors.white, + presentationStyle: ModalPresentationStyle.FULL_SCREEN, + // toolbarTopBackgroundColor: Colors.black + ), + ); + @override Widget build(BuildContext context) { List namesT = [LocaleKeys.monthlyAttendance.tr(), LocaleKeys.workFromHome.tr(), LocaleKeys.ticketRequest.tr(), LocaleKeys.monthlyAttendance.tr()]; @@ -26,7 +62,7 @@ class ServicesWidget extends StatelessWidget { "assets/images/vacation_rule.svg", "assets/images/ticket_request.svg", "assets/images/ticket_request.svg", - "assets/images/ticket_request.svg" + "assets/images/ticket_request.svg", ]; return Consumer( @@ -34,72 +70,69 @@ class ServicesWidget extends StatelessWidget { return data.isServicesMenusLoading ? whileLoading() : ListView.separated( - padding: const EdgeInsets.only(top: 0), - itemBuilder: (context, parentIndex) { - return Column( - crossAxisAlignment: CrossAxisAlignment.start, - mainAxisSize: MainAxisSize.min, - children: [ - data.homeMenus![parentIndex].menuEntry.prompt!.toSectionHeading().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 + padding: const EdgeInsets.only(top: 0), + itemBuilder: (context, parentIndex) { + return Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisSize: MainAxisSize.min, + children: [ + data.homeMenus![parentIndex].menuEntry.prompt!.toSectionHeading().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(AppState().isArabic(context) + 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( + AppState().isArabic(context) ? getMenuIconAr(data.homeMenus![parentIndex].menuEntiesList[index].prompt!) - : getMenuIconEn(data.homeMenus![parentIndex].menuEntiesList[index].prompt!)), - Row( - crossAxisAlignment: CrossAxisAlignment.end, - children: [ - Expanded( - child: data.homeMenus![parentIndex].menuEntiesList[index].prompt!.toText11(isBold: true), - ), - RotatedBox(quarterTurns: AppState().isArabic(context) ? 2 : 4, child: SvgPicture.asset("assets/images/arrow_next.svg").paddingOnly(bottom: 4)), - ], - ) - ], - ).paddingOnly(left: 10, right: 10, bottom: 10, top: 12), - ).onPress(() { - handleOnPress(context, data.homeMenus![parentIndex].menuEntiesList[index]); - }), - ); - }, - separatorBuilder: (cxt, index) => 9.width, - itemCount: data.homeMenus![parentIndex].menuEntiesList.length), + : getMenuIconEn(data.homeMenus![parentIndex].menuEntiesList[index].prompt!), + ), + Row( + crossAxisAlignment: CrossAxisAlignment.end, + children: [ + Expanded(child: data.homeMenus![parentIndex].menuEntiesList[index].prompt!.toText11(isBold: true)), + RotatedBox(quarterTurns: AppState().isArabic(context) ? 2 : 4, child: SvgPicture.asset("assets/images/arrow_next.svg").paddingOnly(bottom: 4)), + ], + ), + ], + ).paddingOnly(left: 10, right: 10, bottom: 10, top: 12), + ).onPress(() { + handleOnPress(context, data.homeMenus![parentIndex].menuEntiesList[index]); + }), + ); + }, + separatorBuilder: (cxt, index) => 9.width, + itemCount: data.homeMenus![parentIndex].menuEntiesList.length, ), - ], - ); - }, - separatorBuilder: (context, index) { - return 12.height; - }, - shrinkWrap: true, - physics: const NeverScrollableScrollPhysics(), - itemCount: data.homeMenus!.length); + ), + ], + ); + }, + separatorBuilder: (context, index) { + return 12.height; + }, + shrinkWrap: true, + physics: const NeverScrollableScrollPhysics(), + itemCount: data.homeMenus!.length, + ); }, ); } @@ -196,7 +229,7 @@ class ServicesWidget extends StatelessWidget { return returnImage; } - void handleOnPress(context, GetMenuEntriesList menuEntry) { + Future handleOnPress(context, GetMenuEntriesList menuEntry) async { var pro = Provider.of(context, listen: false); if (menuEntry.requestType == "MONTHLY_ATTENDANCE") { Navigator.pushNamed(context, AppRoutes.monthlyAttendance); @@ -220,9 +253,28 @@ class ServicesWidget extends StatelessWidget { Navigator.pushNamed(context, AppRoutes.monthlyPaySlip); } } else { - List _menuList = - pro.getMenuEntriesList?.where((element) => element.parentMenuName == menuEntry.menuName && (element.menuEntryType == "FUNCTION" || element.menuEntryType == "MENU")).toList() ?? []; - Navigator.pushNamed(context, AppRoutes.servicesMenuListScreen, arguments: ServicesMenuListScreenParams(menuEntry.prompt!, _menuList.isEmpty ? menuList : _menuList)); + if (menuEntry.menuName == "HMG_TICKET_REQUESTS") { + Utils.showLoading(context); + TicketBookingResult response = await pro.fetchTicketBooking(); + Utils.hideLoading(context); + if (response.success) { + SSOAuthModel? ssoToken = await pro.fetchSSOAuthRedirection(clientID: response.clientId); + if (ssoToken != null) { + logger.d(ssoToken.data!.toJson()); + logger.d(ssoToken.data!.accessToken); + dynamic url = await pro.fetchURLRedirection(token: ssoToken.data!.accessToken!); + Navigator.push(context, MaterialPageRoute(builder: (context) => SsoLoginWebView(url: url ?? "", jwtToken: ssoToken.data!.accessToken!))); + } + } else { + List _menuList = + pro.getMenuEntriesList?.where((element) => element.parentMenuName == menuEntry.menuName && (element.menuEntryType == "FUNCTION" || element.menuEntryType == "MENU")).toList() ?? []; + Navigator.pushNamed(context, AppRoutes.servicesMenuListScreen, arguments: ServicesMenuListScreenParams(menuEntry.prompt!, _menuList.isEmpty ? menuList : _menuList)); + } + } else { + List _menuList = + pro.getMenuEntriesList?.where((element) => element.parentMenuName == menuEntry.menuName && (element.menuEntryType == "FUNCTION" || element.menuEntryType == "MENU")).toList() ?? []; + Navigator.pushNamed(context, AppRoutes.servicesMenuListScreen, arguments: ServicesMenuListScreenParams(menuEntry.prompt!, _menuList.isEmpty ? menuList : _menuList)); + } } return; } @@ -253,10 +305,7 @@ class ServicesWidget extends StatelessWidget { 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(), - ); + return AspectRatio(aspectRatio: 105 / 105, child: ServicesMenuShimmer()); }, separatorBuilder: (cxt, index) => 9.width, itemCount: 4, diff --git a/lib/ui/login/verify_last_login_screen.dart b/lib/ui/login/verify_last_login_screen.dart index 05b5c35..5c76092 100644 --- a/lib/ui/login/verify_last_login_screen.dart +++ b/lib/ui/login/verify_last_login_screen.dart @@ -4,8 +4,9 @@ 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:local_auth_darwin/local_auth_darwin.dart'; +import 'package:local_auth_android/local_auth_android.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'; @@ -65,6 +66,7 @@ class _VerifyLastLoginScreenState extends State { return Scaffold( appBar: AppBar( + surfaceTintColor: Colors.transparent, backgroundColor: Colors.transparent, automaticallyImplyLeading: false, title: (mobileLoginInfoListModel?.businessCardPrivilege ?? false) @@ -74,6 +76,7 @@ class _VerifyLastLoginScreenState extends State { : Container(), actions: [ Center( + child: LocaleKeys.employeeDigitalID.tr().toText12(color: MyColors.textMixColor, isUnderLine: true).onPress(() { showMDialog(context, child: EmployeeDigitialIdDialog()); }), @@ -204,15 +207,26 @@ class _VerifyLastLoginScreenState extends State { } Future loginWithFaceIDAndBiometrics() async { - IOSAuthMessages iosStrings = const IOSAuthMessages( - cancelButton: 'cancel', - goToSettingsButton: 'settings', - goToSettingsDescription: 'Please set up your Touch ID.', - lockOut: 'Please reenable your Touch ID', - ); + + IOSAuthMessages iosStrings = const IOSAuthMessages(cancelButton: 'cancel', goToSettingsButton: 'settings', goToSettingsDescription: 'Please set up your Touch ID.', lockOut: 'Please reenable your Touch ID'); + + // 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, biometricOnly: true, iOSAuthStrings: iosStrings); + authenticated = await auth.authenticate(localizedReason: 'Scan your fingerprint to authenticate', options: const AuthenticationOptions( + useErrorDialogs: true, stickyAuth: true, biometricOnly: true, + ), + authMessages: [ + iosStrings, + const AndroidAuthMessages(), + ], + ); } on PlatformException catch (e) { print(e); Utils.hideLoading(context); @@ -222,8 +236,22 @@ class _VerifyLastLoginScreenState extends State { } Widget _loginOptionButton(String _title, String _icon, int _flag, int? _loginIndex) { - bool isDisable = (_flag == 3 && !checkBiometricIsAvailable(BiometricType.face) || - _flag == 4 && !checkBiometricIsAvailable(BiometricType.fingerprint) && _flag == 4 && !checkBiometricIsAvailable(BiometricType.face)); +// <<<<<<< HEAD + bool isDisable = false; + if(_flag >= 3 && _flag <= 4) { + bool isFaceEnabled = (_flag == 3 && (checkBiometricIsAvailable(BiometricType.face) || + checkBiometricIsAvailable(BiometricType.weak))); + + bool isThumbEnabled = + (_flag == 4 && (checkBiometricIsAvailable(BiometricType.fingerprint) || + checkBiometricIsAvailable(BiometricType.strong))); + + isDisable = !(isFaceEnabled || isThumbEnabled); + } +// ======= +// bool isDisable = (_flag == 3 && !checkBiometricIsAvailable(BiometricType.face) || +// _flag == 4 && !checkBiometricIsAvailable(BiometricType.fingerprint) && _flag == 4 && !checkBiometricIsAvailable(BiometricType.face)); +// // >>>>>>> master return InkWell( onTap: isDisable ? null diff --git a/lib/ui/login/verify_login_screen.dart b/lib/ui/login/verify_login_screen.dart index 0c9bdc0..e0015e0 100644 --- a/lib/ui/login/verify_login_screen.dart +++ b/lib/ui/login/verify_login_screen.dart @@ -4,7 +4,8 @@ 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_darwin/local_auth_darwin.dart'; +import 'package:local_auth_android/local_auth_android.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'; @@ -517,7 +518,11 @@ class _VerifyLoginScreenState extends State { 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, biometricOnly: true, iOSAuthStrings: iosStrings); + authenticated = await auth.authenticate(localizedReason: 'Scan your fingerprint to authenticate', + options: const AuthenticationOptions(useErrorDialogs: true, stickyAuth: true, biometricOnly: true,), authMessages: [ + iosStrings, + const AndroidAuthMessages(), + ],); } on PlatformException catch (e) { print(e); Utils.hideLoading(context); @@ -527,25 +532,17 @@ class _VerifyLoginScreenState extends State { } Widget _loginOptionButton(String _title, String _icon, int _flag, int? _loginIndex) { - bool isDisable = (_flag == 3 && !checkBiometricIsAvailable(BiometricType.face) || - _flag == 4 && !checkBiometricIsAvailable(BiometricType.fingerprint) && _flag == 4 && !checkBiometricIsAvailable(BiometricType.face)); - // bool isDisable = false; - // switch (_flag) { - // case 3: - // isDisable = !(checkBiometricIsAvailable(BiometricType.face) || - // checkBiometricIsAvailable(BiometricType.weak)); - // break; - // case 4: - // isDisable = !(checkBiometricIsAvailable(BiometricType.fingerprint) || - // checkBiometricIsAvailable(BiometricType.strong)); - // break; - // } - // // bool isDisable = ((_flag == 3 && - // // (!checkBiometricIsAvailable(BiometricType.face) || - // // !checkBiometricIsAvailable(BiometricType.weak))) || - // // (_flag == 4 && - // // (!checkBiometricIsAvailable(BiometricType.fingerprint) || - // // !checkBiometricIsAvailable(BiometricType.strong)))); + bool isDisable = false; + if(_flag >= 3 && _flag <= 4) { + bool isFaceEnabled = (_flag == 3 && (checkBiometricIsAvailable(BiometricType.face) || + checkBiometricIsAvailable(BiometricType.weak))); + + bool isThumbEnabled = + (_flag == 4 && (checkBiometricIsAvailable(BiometricType.fingerprint) || + checkBiometricIsAvailable(BiometricType.strong))); + + isDisable = !(isFaceEnabled || isThumbEnabled); + } return InkWell( onTap: isDisable ? null diff --git a/lib/ui/my_team/view_attendance.dart b/lib/ui/my_team/view_attendance.dart index 1a5ebe1..96e673d 100644 --- a/lib/ui/my_team/view_attendance.dart +++ b/lib/ui/my_team/view_attendance.dart @@ -15,7 +15,7 @@ import 'package:mohem_flutter_app/models/get_time_card_summary_list_model.dart'; import 'package:mohem_flutter_app/models/my_team/get_employee_subordinates_list.dart'; import 'package:mohem_flutter_app/widgets/app_bar_widget.dart'; import 'package:mohem_flutter_app/widgets/circular_step_progress_bar.dart'; -import 'package:month_picker_dialog_2/month_picker_dialog_2.dart'; +import 'package:month_picker_dialog/month_picker_dialog.dart'; import 'package:pie_chart/pie_chart.dart'; import 'package:syncfusion_flutter_calendar/calendar.dart'; diff --git a/lib/ui/screens/offers_and_discounts/offers_and_discounts_details.dart b/lib/ui/screens/offers_and_discounts/offers_and_discounts_details.dart index 37680f0..846c52f 100644 --- a/lib/ui/screens/offers_and_discounts/offers_and_discounts_details.dart +++ b/lib/ui/screens/offers_and_discounts/offers_and_discounts_details.dart @@ -16,7 +16,7 @@ import 'package:mohem_flutter_app/extensions/widget_extensions.dart'; import 'package:mohem_flutter_app/models/offers_and_discounts/get_offers_list.dart'; import 'package:mohem_flutter_app/widgets/app_bar_widget.dart'; import 'package:path_provider/path_provider.dart'; -import 'package:share/share.dart'; +import 'package:share_plus/share_plus.dart'; import 'package:url_launcher/url_launcher.dart'; class OffersAndDiscountsDetails extends StatefulWidget { @@ -61,13 +61,7 @@ class _OffersAndDiscountsDetailsState extends State { // transitionOnUserGestures: true, child: RepaintBoundary( key: _globalKey, - child: ClipRRect( - borderRadius: BorderRadius.circular(6), - child: Image.network( - getOffersList[0].bannerImage ?? "", - fit: BoxFit.contain, - ), - ).paddingAll(12), + child: ClipRRect(borderRadius: BorderRadius.circular(6), child: Image.network(getOffersList[0].bannerImage ?? "", fit: BoxFit.contain)).paddingAll(12), ), ), 8.height, @@ -87,19 +81,20 @@ class _OffersAndDiscountsDetailsState extends State { children: [ getOffersList[0].discountDescription!.toText16(isBold: true), InkWell( - onTap: () { - _shareOfferAsImage(); - }, - child: const Icon(Icons.share, color: MyColors.darkIconColor).paddingOnly(bottom: 4)) + onTap: () { + _shareOfferAsImage(); + }, + child: const Icon(Icons.share, color: MyColors.darkIconColor).paddingOnly(bottom: 4), + ), ], ).paddingOnly(left: 8, right: 8), getOffersList[0].isHasLocation == "true" ? InkWell( - onTap: () {}, - child: Row( - children: [const Icon(Icons.map_sharp, color: MyColors.darkIconColor).paddingOnly(bottom: 4), "Offer Location".toText16(isUnderLine: true).paddingOnly(left: 8)], - ).paddingOnly(left: 8, right: 8, top: 8), - ) + onTap: () {}, + child: Row( + children: [const Icon(Icons.map_sharp, color: MyColors.darkIconColor).paddingOnly(bottom: 4), "Offer Location".toText16(isUnderLine: true).paddingOnly(left: 8)], + ).paddingOnly(left: 8, right: 8, top: 8), + ) : 12.height, ], ).objectContainerView().paddingOnly(left: 21, right: 21, top: 21), @@ -127,18 +122,14 @@ class _OffersAndDiscountsDetailsState extends State { Directory tempDir = await getTemporaryDirectory(); File file = await File('${tempDir.path}/${DateTime.now().toString()}.png').create(); await file.writeAsBytes(pngBytes); - await Share.shareFiles([(file.path)], text: AppState().isArabic(context) ? getOffersList[0].titleAr : getOffersList[0].titleEn); + await SharePlus.instance.share(ShareParams(files: [(XFile(file.path))], text: AppState().isArabic(context) ? getOffersList[0].titleAr : getOffersList[0].titleEn)); } catch (ex) { debugPrint(ex.toString()); } } void _scrollToTop() { - _scrollController.animateTo( - 0, - duration: const Duration(milliseconds: 500), - curve: Curves.linear, - ); + _scrollController.animateTo(0, duration: const Duration(milliseconds: 500), curve: Curves.linear); } List getItemsForSaleWidgets() { @@ -155,18 +146,9 @@ class _OffersAndDiscountsDetailsState extends State { mainAxisSize: MainAxisSize.min, children: [ Hero( - tag: "ItemImage" + getOffersList.offersDiscountId.toString()!, + tag: "ItemImage" + getOffersList.offersDiscountId.toString(), transitionOnUserGestures: true, - child: AspectRatio( - aspectRatio: 148 / 127, - child: ClipRRect( - borderRadius: BorderRadius.circular(6), - child: Image.network( - getOffersList.bannerImage ?? "", - fit: BoxFit.contain, - ), - ), - ), + child: AspectRatio(aspectRatio: 148 / 127, child: ClipRRect(borderRadius: BorderRadius.circular(6), child: Image.network(getOffersList.bannerImage ?? "", fit: BoxFit.contain))), ), 5.height, getOffersList.titleEn!.toText16(isBold: true, color: const Color(0xff2B353E), maxlines: 1), @@ -180,10 +162,7 @@ class _OffersAndDiscountsDetailsState extends State { // 16.height, getOffersList.discountDescription!.toText14(isBold: true, maxlines: 1), 8.height, - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [checkDate(getOffersList.endDate!), SvgPicture.asset("assets/images/arrow_next.svg").paddingOnly(bottom: 4)], - ), + Row(mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [checkDate(getOffersList.endDate!), SvgPicture.asset("assets/images/arrow_next.svg").paddingOnly(bottom: 4)]), ], ).objectContainerView().onPress(() { this.getOffersList[0] = getOffersList; diff --git a/lib/ui/screens/offers_and_discounts/offers_and_discounts_home.dart b/lib/ui/screens/offers_and_discounts/offers_and_discounts_home.dart index fd2c19e..f67a835 100644 --- a/lib/ui/screens/offers_and_discounts/offers_and_discounts_home.dart +++ b/lib/ui/screens/offers_and_discounts/offers_and_discounts_home.dart @@ -39,7 +39,7 @@ class _OffersAndDiscountsHomeState extends State { Widget build(BuildContext context) { return Scaffold( backgroundColor: Colors.white, - appBar: AppBarWidget(context, title: LocaleKeys.offerAndDiscounts.tr(), showHomeButton: true), + appBar: AppBarWidget(context, title: LocaleKeys.offerAndDiscounts.tr(), showHomeButton: true, showLogo: true, logoPath: "assets/icons/mazaya_brand.svg"), body: SingleChildScrollView( child: Column( crossAxisAlignment: CrossAxisAlignment.start, diff --git a/lib/ui/work_list/itg_detail_screen.dart b/lib/ui/work_list/itg_detail_screen.dart index bbe4c3e..fdfe19c 100644 --- a/lib/ui/work_list/itg_detail_screen.dart +++ b/lib/ui/work_list/itg_detail_screen.dart @@ -97,14 +97,20 @@ class _ItgDetailScreenState extends State { // "{\"returN_STATUS\":\"S\",\"returN_MSG\":\"null\",\"summeries\":[{\"employeE_NUMBER\":\"410123\",\"assignmenT_NUMBER\":\"410123\",\"employeE_NAME\":\"Samiullah Abdulqadir\",\"hirE_DATE\":\"2024-07-21T00:00:00\",\"actuaL_TERMINATION_DATE\":null,\"perioD_DAYS\":31,\"schedulE_DAYS\":20,\"ofF_DAYS\":9,\"noN_SCHEDULED_DAYS\":0,\"noT_ANALAYZED_DAYS\":0,\"attendeD_DAYS\":20,\"absenT_DAYS\":0,\"missinG_SWIPES_DAYS\":0,\"scheduleD_HRS\":\"120\",\"actuaL_HRS\":\"121.96\",\"excesS_HRS\":\"2.61\",\"comP_OFF_W_HRS\":\"0\",\"comP_OFF_H_HRS\":\"0\",\"comP_OFF_N_HRS\":\"0\",\"timebacK_HRS\":\"2.61\",\"shortagE_HRS\":\".65\",\"latE_IN_HRS\":\".1\",\"earlY_OUT_HRS\":\".65\",\"uncovereD_SHORTAGE_HRS\":0.65,\"halF_DAY_LEAVES\":0,\"sicK_LEAVES\":0,\"publiC_HOLIDAYS\":2,\"worK_FROM_HOME_DAYS\":0,\"businesS_TRIPS\":0,\"unauthorizeD_LEAVES\":0,\"unpaiD_LEAVES\":0,\"paiD_LEAVES\":0}],\"details\":[{\"schedulE_DATE\":\"2025-03-01T00:00:00\",\"shifT_NAME\":\"00:00 - 00:00\",\"shifT_TYPE\":\"Regular\",\"breaK_NAME\":\"00:00 - 00:00\",\"actuaL_WOB_HRS\":\"00:00\",\"shT_ACTUAL_START_DATETIME\":null,\"shT_ACTUAL_END_DATETIME\":null,\"approveD_START_DATETIME\":null,\"approveD_END_DATETIME\":null,\"scheduleD_HRS\":\"00:00\",\"actuaL_HRS\":\"00:00\",\"excesS_HRS\":\"00:00\",\"comP_OFF_N_HRS\":\"00:00\",\"comP_OFF_W_HRS\":\"00:00\",\"comP_OFF_H_HRS\":\"00:00\",\"timebacK_HRS\":null,\"shortagE_HRS\":\"00:00\",\"latE_IN_HRS\":\"00:00\",\"earlY_OUT_HRS\":\"00:00\",\"remarks\":\"Off Shift\",\"excesS_FLAG\":\"N\",\"comP_OFF_FLAG\":\"N\",\"timebacK_FLAG\":\"N\",\"shortagE_FLAG\":\"N\",\"latE_IN_FLAG\":\"N\",\"earlY_OUT_FLAG\":\"N\",\"missinG_SWIPES_FLAG\":\"N\"},{\"schedulE_DATE\":\"2025-03-02T00:00:00\",\"shifT_NAME\":\"10:00 - 16:00\",\"shifT_TYPE\":\"Regular\",\"breaK_NAME\":\"00:00 - 00:00\",\"actuaL_WOB_HRS\":\"00:00\",\"shT_ACTUAL_START_DATETIME\":\"09:58\",\"shT_ACTUAL_END_DATETIME\":\"16:01\",\"approveD_START_DATETIME\":null,\"approveD_END_DATETIME\":null,\"scheduleD_HRS\":\"06:00\",\"actuaL_HRS\":\"06:03\",\"excesS_HRS\":\"00:03\",\"comP_OFF_N_HRS\":\"00:00\",\"comP_OFF_W_HRS\":\"00:00\",\"comP_OFF_H_HRS\":\"00:00\",\"timebacK_HRS\":null,\"shortagE_HRS\":\"00:00\",\"latE_IN_HRS\":\"00:00\",\"earlY_OUT_HRS\":\"00:00\",\"remarks\":null,\"excesS_FLAG\":\"Y\",\"comP_OFF_FLAG\":\"N\",\"timebacK_FLAG\":\"Y\",\"shortagE_FLAG\":\"N\",\"latE_IN_FLAG\":\"N\",\"earlY_OUT_FLAG\":\"N\",\"missinG_SWIPES_FLAG\":\"N\"},{\"schedulE_DATE\":\"2025-03-03T00:00:00\",\"shifT_NAME\":\"10:00 - 16:00\",\"shifT_TYPE\":\"Regular\",\"breaK_NAME\":\"00:00 - 00:00\",\"actuaL_WOB_HRS\":\"00:00\",\"shT_ACTUAL_START_DATETIME\":\"10:11\",\"shT_ACTUAL_END_DATETIME\":\"16:11\",\"approveD_START_DATETIME\":null,\"approveD_END_DATETIME\":null,\"scheduleD_HRS\":\"06:00\",\"actuaL_HRS\":\"06:00\",\"excesS_HRS\":\"00:00\",\"comP_OFF_N_HRS\":\"00:00\",\"comP_OFF_W_HRS\":\"00:00\",\"comP_OFF_H_HRS\":\"00:00\",\"timebacK_HRS\":null,\"shortagE_HRS\":\"00:00\",\"latE_IN_HRS\":\"00:00\",\"earlY_OUT_HRS\":\"00:00\",\"remarks\":null,\"excesS_FLAG\":\"N\",\"comP_OFF_FLAG\":\"N\",\"timebacK_FLAG\":\"N\",\"shortagE_FLAG\":\"N\",\"latE_IN_FLAG\":\"N\",\"earlY_OUT_FLAG\":\"N\",\"missinG_SWIPES_FLAG\":\"N\"},{\"schedulE_DATE\":\"2025-03-04T00:00:00\",\"shifT_NAME\":\"10:00 - 16:00\",\"shifT_TYPE\":\"Regular\",\"breaK_NAME\":\"00:00 - 00:00\",\"actuaL_WOB_HRS\":\"00:00\",\"shT_ACTUAL_START_DATETIME\":\"10:08\",\"shT_ACTUAL_END_DATETIME\":\"16:12\",\"approveD_START_DATETIME\":null,\"approveD_END_DATETIME\":null,\"scheduleD_HRS\":\"06:00\",\"actuaL_HRS\":\"06:04\",\"excesS_HRS\":\"00:04\",\"comP_OFF_N_HRS\":\"00:00\",\"comP_OFF_W_HRS\":\"00:00\",\"comP_OFF_H_HRS\":\"00:00\",\"timebacK_HRS\":null,\"shortagE_HRS\":\"00:00\",\"latE_IN_HRS\":\"00:00\",\"earlY_OUT_HRS\":\"00:00\",\"remarks\":null,\"excesS_FLAG\":\"Y\",\"comP_OFF_FLAG\":\"N\",\"timebacK_FLAG\":\"Y\",\"shortagE_FLAG\":\"N\",\"latE_IN_FLAG\":\"N\",\"earlY_OUT_FLAG\":\"N\",\"missinG_SWIPES_FLAG\":\"N\"},{\"schedulE_DATE\":\"2025-03-05T00:00:00\",\"shifT_NAME\":\"10:00 - 16:00\",\"shifT_TYPE\":\"Regular\",\"breaK_NAME\":\"00:00 - 00:00\",\"actuaL_WOB_HRS\":\"00:00\",\"shT_ACTUAL_START_DATETIME\":\"10:09\",\"shT_ACTUAL_END_DATETIME\":\"16:12\",\"approveD_START_DATETIME\":null,\"approveD_END_DATETIME\":null,\"scheduleD_HRS\":\"06:00\",\"actuaL_HRS\":\"06:03\",\"excesS_HRS\":\"00:03\",\"comP_OFF_N_HRS\":\"00:00\",\"comP_OFF_W_HRS\":\"00:00\",\"comP_OFF_H_HRS\":\"00:00\",\"timebacK_HRS\":null,\"shortagE_HRS\":\"00:00\",\"latE_IN_HRS\":\"00:00\",\"earlY_OUT_HRS\":\"00:00\",\"remarks\":null,\"excesS_FLAG\":\"Y\",\"comP_OFF_FLAG\":\"N\",\"timebacK_FLAG\":\"Y\",\"shortagE_FLAG\":\"N\",\"latE_IN_FLAG\":\"N\",\"earlY_OUT_FLAG\":\"N\",\"missinG_SWIPES_FLAG\":\"N\"},{\"schedulE_DATE\":\"2025-03-06T00:00:00\",\"shifT_NAME\":\"10:00 - 16:00\",\"shifT_TYPE\":\"Regular\",\"breaK_NAME\":\"00:00 - 00:00\",\"actuaL_WOB_HRS\":\"00:00\",\"shT_ACTUAL_START_DATETIME\":\"09:53\",\"shT_ACTUAL_END_DATETIME\":\"15:54\",\"approveD_START_DATETIME\":null,\"approveD_END_DATETIME\":null,\"scheduleD_HRS\":\"06:00\",\"actuaL_HRS\":\"06:01\",\"excesS_HRS\":\"00:01\",\"comP_OFF_N_HRS\":\"00:00\",\"comP_OFF_W_HRS\":\"00:00\",\"comP_OFF_H_HRS\":\"00:00\",\"timebacK_HRS\":null,\"shortagE_HRS\":\"00:00\",\"latE_IN_HRS\":\"00:00\",\"earlY_OUT_HRS\":\"00:00\",\"remarks\":null,\"excesS_FLAG\":\"Y\",\"comP_OFF_FLAG\":\"N\",\"timebacK_FLAG\":\"Y\",\"shortagE_FLAG\":\"N\",\"latE_IN_FLAG\":\"N\",\"earlY_OUT_FLAG\":\"N\",\"missinG_SWIPES_FLAG\":\"N\"},{\"schedulE_DATE\":\"2025-03-07T00:00:00\",\"shifT_NAME\":\"00:00 - 00:00\",\"shifT_TYPE\":\"Regular\",\"breaK_NAME\":\"00:00 - 00:00\",\"actuaL_WOB_HRS\":\"00:00\",\"shT_ACTUAL_START_DATETIME\":null,\"shT_ACTUAL_END_DATETIME\":null,\"approveD_START_DATETIME\":null,\"approveD_END_DATETIME\":null,\"scheduleD_HRS\":\"00:00\",\"actuaL_HRS\":\"00:00\",\"excesS_HRS\":\"00:00\",\"comP_OFF_N_HRS\":\"00:00\",\"comP_OFF_W_HRS\":\"00:00\",\"comP_OFF_H_HRS\":\"00:00\",\"timebacK_HRS\":null,\"shortagE_HRS\":\"00:00\",\"latE_IN_HRS\":\"00:00\",\"earlY_OUT_HRS\":\"00:00\",\"remarks\":\"Off Shift\",\"excesS_FLAG\":\"N\",\"comP_OFF_FLAG\":\"N\",\"timebacK_FLAG\":\"N\",\"shortagE_FLAG\":\"N\",\"latE_IN_FLAG\":\"N\",\"earlY_OUT_FLAG\":\"N\",\"missinG_SWIPES_FLAG\":\"N\"},{\"schedulE_DATE\":\"2025-03-08T00:00:00\",\"shifT_NAME\":\"00:00 - 00:00\",\"shifT_TYPE\":\"Regular\",\"breaK_NAME\":\"00:00 - 00:00\",\"actuaL_WOB_HRS\":\"00:00\",\"shT_ACTUAL_START_DATETIME\":null,\"shT_ACTUAL_END_DATETIME\":null,\"approveD_START_DATETIME\":null,\"approveD_END_DATETIME\":null,\"scheduleD_HRS\":\"00:00\",\"actuaL_HRS\":\"00:00\",\"excesS_HRS\":\"00:00\",\"comP_OFF_N_HRS\":\"00:00\",\"comP_OFF_W_HRS\":\"00:00\",\"comP_OFF_H_HRS\":\"00:00\",\"timebacK_HRS\":null,\"shortagE_HRS\":\"00:00\",\"latE_IN_HRS\":\"00:00\",\"earlY_OUT_HRS\":\"00:00\",\"remarks\":\"Off Shift\",\"excesS_FLAG\":\"N\",\"comP_OFF_FLAG\":\"N\",\"timebacK_FLAG\":\"N\",\"shortagE_FLAG\":\"N\",\"latE_IN_FLAG\":\"N\",\"earlY_OUT_FLAG\":\"N\",\"missinG_SWIPES_FLAG\":\"N\"},{\"schedulE_DATE\":\"2025-03-09T00:00:00\",\"shifT_NAME\":\"10:00 - 16:00\",\"shifT_TYPE\":\"Regular\",\"breaK_NAME\":\"00:00 - 00:00\",\"actuaL_WOB_HRS\":\"00:00\",\"shT_ACTUAL_START_DATETIME\":\"10:06\",\"shT_ACTUAL_END_DATETIME\":\"16:08\",\"approveD_START_DATETIME\":null,\"approveD_END_DATETIME\":null,\"scheduleD_HRS\":\"06:00\",\"actuaL_HRS\":\"06:02\",\"excesS_HRS\":\"00:02\",\"comP_OFF_N_HRS\":\"00:00\",\"comP_OFF_W_HRS\":\"00:00\",\"comP_OFF_H_HRS\":\"00:00\",\"timebacK_HRS\":null,\"shortagE_HRS\":\"00:00\",\"latE_IN_HRS\":\"00:00\",\"earlY_OUT_HRS\":\"00:00\",\"remarks\":null,\"excesS_FLAG\":\"Y\",\"comP_OFF_FLAG\":\"N\",\"timebacK_FLAG\":\"Y\",\"shortagE_FLAG\":\"N\",\"latE_IN_FLAG\":\"N\",\"earlY_OUT_FLAG\":\"N\",\"missinG_SWIPES_FLAG\":\"N\"},{\"schedulE_DATE\":\"2025-03-10T00:00:00\",\"shifT_NAME\":\"10:00 - 16:00\",\"shifT_TYPE\":\"Regular\",\"breaK_NAME\":\"00:00 - 00:00\",\"actuaL_WOB_HRS\":\"00:00\",\"shT_ACTUAL_START_DATETIME\":\"11:06\",\"shT_ACTUAL_END_DATETIME\":\"17:06\",\"approveD_START_DATETIME\":null,\"approveD_END_DATETIME\":null,\"scheduleD_HRS\":\"06:00\",\"actuaL_HRS\":\"06:00\",\"excesS_HRS\":\"00:00\",\"comP_OFF_N_HRS\":\"00:00\",\"comP_OFF_W_HRS\":\"00:00\",\"comP_OFF_H_HRS\":\"00:00\",\"timebacK_HRS\":null,\"shortagE_HRS\":\"00:00\",\"latE_IN_HRS\":\"00:06\",\"earlY_OUT_HRS\":\"00:00\",\"remarks\":null,\"excesS_FLAG\":\"N\",\"comP_OFF_FLAG\":\"N\",\"timebacK_FLAG\":\"N\",\"shortagE_FLAG\":\"N\",\"latE_IN_FLAG\":\"Y\",\"earlY_OUT_FLAG\":\"N\",\"missinG_SWIPES_FLAG\":\"N\"},{\"schedulE_DATE\":\"2025-03-11T00:00:00\",\"shifT_NAME\":\"10:00 - 16:00\",\"shifT_TYPE\":\"Regular\",\"breaK_NAME\":\"00:00 - 00:00\",\"actuaL_WOB_HRS\":\"00:00\",\"shT_ACTUAL_START_DATETIME\":\"10:09\",\"shT_ACTUAL_END_DATETIME\":\"16:12\",\"approveD_START_DATETIME\":null,\"approveD_END_DATETIME\":null,\"scheduleD_HRS\":\"06:00\",\"actuaL_HRS\":\"06:03\",\"excesS_HRS\":\"00:03\",\"comP_OFF_N_HRS\":\"00:00\",\"comP_OFF_W_HRS\":\"00:00\",\"comP_OFF_H_HRS\":\"00:00\",\"timebacK_HRS\":null,\"shortagE_HRS\":\"00:00\",\"latE_IN_HRS\":\"00:00\",\"earlY_OUT_HRS\":\"00:00\",\"remarks\":null,\"excesS_FLAG\":\"Y\",\"comP_OFF_FLAG\":\"N\",\"timebacK_FLAG\":\"Y\",\"shortagE_FLAG\":\"N\",\"latE_IN_FLAG\":\"N\",\"earlY_OUT_FLAG\":\"N\",\"missinG_SWIPES_FLAG\":\"N\"},{\"schedulE_DATE\":\"2025-03-12T00:00:00\",\"shifT_NAME\":\"10:00 - 16:00\",\"shifT_TYPE\":\"Regular\",\"breaK_NAME\":\"00:00 - 00:00\",\"actuaL_WOB_HRS\":\"00:00\",\"shT_ACTUAL_START_DATETIME\":\"10:37\",\"shT_ACTUAL_END_DATETIME\":\"16:38\",\"approveD_START_DATETIME\":null,\"approveD_END_DATETIME\":null,\"scheduleD_HRS\":\"06:00\",\"actuaL_HRS\":\"06:01\",\"excesS_HRS\":\"00:01\",\"comP_OFF_N_HRS\":\"00:00\",\"comP_OFF_W_HRS\":\"00:00\",\"comP_OFF_H_HRS\":\"00:00\",\"timebacK_HRS\":null,\"shortagE_HRS\":\"00:00\",\"latE_IN_HRS\":\"00:00\",\"earlY_OUT_HRS\":\"00:00\",\"remarks\":null,\"excesS_FLAG\":\"Y\",\"comP_OFF_FLAG\":\"N\",\"timebacK_FLAG\":\"Y\",\"shortagE_FLAG\":\"N\",\"latE_IN_FLAG\":\"N\",\"earlY_OUT_FLAG\":\"N\",\"missinG_SWIPES_FLAG\":\"N\"},{\"schedulE_DATE\":\"2025-03-13T00:00:00\",\"shifT_NAME\":\"10:00 - 16:00\",\"shifT_TYPE\":\"Regular\",\"breaK_NAME\":\"00:00 - 00:00\",\"actuaL_WOB_HRS\":\"00:00\",\"shT_ACTUAL_START_DATETIME\":\"09:53\",\"shT_ACTUAL_END_DATETIME\":\"16:08\",\"approveD_START_DATETIME\":null,\"approveD_END_DATETIME\":null,\"scheduleD_HRS\":\"06:00\",\"actuaL_HRS\":\"06:15\",\"excesS_HRS\":\"00:15\",\"comP_OFF_N_HRS\":\"00:00\",\"comP_OFF_W_HRS\":\"00:00\",\"comP_OFF_H_HRS\":\"00:00\",\"timebacK_HRS\":null,\"shortagE_HRS\":\"00:00\",\"latE_IN_HRS\":\"00:00\",\"earlY_OUT_HRS\":\"00:00\",\"remarks\":null,\"excesS_FLAG\":\"Y\",\"comP_OFF_FLAG\":\"N\",\"timebacK_FLAG\":\"Y\",\"shortagE_FLAG\":\"N\",\"latE_IN_FLAG\":\"N\",\"earlY_OUT_FLAG\":\"N\",\"missinG_SWIPES_FLAG\":\"N\"},{\"schedulE_DATE\":\"2025-03-14T00:00:00\",\"shifT_NAME\":\"00:00 - 00:00\",\"shifT_TYPE\":\"Regular\",\"breaK_NAME\":\"00:00 - 00:00\",\"actuaL_WOB_HRS\":\"00:00\",\"shT_ACTUAL_START_DATETIME\":null,\"shT_ACTUAL_END_DATETIME\":null,\"approveD_START_DATETIME\":null,\"approveD_END_DATETIME\":null,\"scheduleD_HRS\":\"00:00\",\"actuaL_HRS\":\"00:00\",\"excesS_HRS\":\"00:00\",\"comP_OFF_N_HRS\":\"00:00\",\"comP_OFF_W_HRS\":\"00:00\",\"comP_OFF_H_HRS\":\"00:00\",\"timebacK_HRS\":null,\"shortagE_HRS\":\"00:00\",\"latE_IN_HRS\":\"00:00\",\"earlY_OUT_HRS\":\"00:00\",\"remarks\":\"Off Shift\",\"excesS_FLAG\":\"N\",\"comP_OFF_FLAG\":\"N\",\"timebacK_FLAG\":\"N\",\"shortagE_FLAG\":\"N\",\"latE_IN_FLAG\":\"N\",\"earlY_OUT_FLAG\":\"N\",\"missinG_SWIPES_FLAG\":\"N\"},{\"schedulE_DATE\":\"2025-03-15T00:00:00\",\"shifT_NAME\":\"00:00 - 00:00\",\"shifT_TYPE\":\"Regular\",\"breaK_NAME\":\"00:00 - 00:00\",\"actuaL_WOB_HRS\":\"00:00\",\"shT_ACTUAL_START_DATETIME\":null,\"shT_ACTUAL_END_DATETIME\":null,\"approveD_START_DATETIME\":null,\"approveD_END_DATETIME\":null,\"scheduleD_HRS\":\"00:00\",\"actuaL_HRS\":\"00:00\",\"excesS_HRS\":\"00:00\",\"comP_OFF_N_HRS\":\"00:00\",\"comP_OFF_W_HRS\":\"00:00\",\"comP_OFF_H_HRS\":\"00:00\",\"timebacK_HRS\":null,\"shortagE_HRS\":\"00:00\",\"latE_IN_HRS\":\"00:00\",\"earlY_OUT_HRS\":\"00:00\",\"remarks\":\"Off Shift\",\"excesS_FLAG\":\"N\",\"comP_OFF_FLAG\":\"N\",\"timebacK_FLAG\":\"N\",\"shortagE_FLAG\":\"N\",\"latE_IN_FLAG\":\"N\",\"earlY_OUT_FLAG\":\"N\",\"missinG_SWIPES_FLAG\":\"N\"},{\"schedulE_DATE\":\"2025-03-16T00:00:00\",\"shifT_NAME\":\"10:00 - 16:00\",\"shifT_TYPE\":\"Regular\",\"breaK_NAME\":\"00:00 - 00:00\",\"actuaL_WOB_HRS\":\"00:00\",\"shT_ACTUAL_START_DATETIME\":\"10:52\",\"shT_ACTUAL_END_DATETIME\":\"16:54\",\"approveD_START_DATETIME\":null,\"approveD_END_DATETIME\":null,\"scheduleD_HRS\":\"06:00\",\"actuaL_HRS\":\"06:02\",\"excesS_HRS\":\"00:02\",\"comP_OFF_N_HRS\":\"00:00\",\"comP_OFF_W_HRS\":\"00:00\",\"comP_OFF_H_HRS\":\"00:00\",\"timebacK_HRS\":null,\"shortagE_HRS\":\"00:00\",\"latE_IN_HRS\":\"00:00\",\"earlY_OUT_HRS\":\"00:00\",\"remarks\":null,\"excesS_FLAG\":\"Y\",\"comP_OFF_FLAG\":\"N\",\"timebacK_FLAG\":\"Y\",\"shortagE_FLAG\":\"N\",\"latE_IN_FLAG\":\"N\",\"earlY_OUT_FLAG\":\"N\",\"missinG_SWIPES_FLAG\":\"N\"},{\"schedulE_DATE\":\"2025-03-17T00:00:00\",\"shifT_NAME\":\"10:00 - 16:00\",\"shifT_TYPE\":\"Regular\",\"breaK_NAME\":\"00:00 - 00:00\",\"actuaL_WOB_HRS\":\"00:00\",\"shT_ACTUAL_START_DATETIME\":\"10:49\",\"shT_ACTUAL_END_DATETIME\":\"17:00\",\"approveD_START_DATETIME\":null,\"approveD_END_DATETIME\":null,\"scheduleD_HRS\":\"06:00\",\"actuaL_HRS\":\"06:11\",\"excesS_HRS\":\"00:11\",\"comP_OFF_N_HRS\":\"00:00\",\"comP_OFF_W_HRS\":\"00:00\",\"comP_OFF_H_HRS\":\"00:00\",\"timebacK_HRS\":null,\"shortagE_HRS\":\"00:00\",\"latE_IN_HRS\":\"00:00\",\"earlY_OUT_HRS\":\"00:00\",\"remarks\":null,\"excesS_FLAG\":\"Y\",\"comP_OFF_FLAG\":\"N\",\"timebacK_FLAG\":\"Y\",\"shortagE_FLAG\":\"N\",\"latE_IN_FLAG\":\"N\",\"earlY_OUT_FLAG\":\"N\",\"missinG_SWIPES_FLAG\":\"N\"},{\"schedulE_DATE\":\"2025-03-18T00:00:00\",\"shifT_NAME\":\"10:00 - 16:00\",\"shifT_TYPE\":\"Regular\",\"breaK_NAME\":\"00:00 - 00:00\",\"actuaL_WOB_HRS\":\"00:00\",\"shT_ACTUAL_START_DATETIME\":\"10:40\",\"shT_ACTUAL_END_DATETIME\":\"16:59\",\"approveD_START_DATETIME\":null,\"approveD_END_DATETIME\":null,\"scheduleD_HRS\":\"06:00\",\"actuaL_HRS\":\"06:19\",\"excesS_HRS\":\"00:19\",\"comP_OFF_N_HRS\":\"00:00\",\"comP_OFF_W_HRS\":\"00:00\",\"comP_OFF_H_HRS\":\"00:00\",\"timebacK_HRS\":null,\"shortagE_HRS\":\"00:00\",\"latE_IN_HRS\":\"00:00\",\"earlY_OUT_HRS\":\"00:00\",\"remarks\":null,\"excesS_FLAG\":\"Y\",\"comP_OFF_FLAG\":\"N\",\"timebacK_FLAG\":\"Y\",\"shortagE_FLAG\":\"N\",\"latE_IN_FLAG\":\"N\",\"earlY_OUT_FLAG\":\"N\",\"missinG_SWIPES_FLAG\":\"N\"},{\"schedulE_DATE\":\"2025-03-19T00:00:00\",\"shifT_NAME\":\"10:00 - 16:00\",\"shifT_TYPE\":\"Regular\",\"breaK_NAME\":\"00:00 - 00:00\",\"actuaL_WOB_HRS\":\"00:00\",\"shT_ACTUAL_START_DATETIME\":\"10:46\",\"shT_ACTUAL_END_DATETIME\":\"17:03\",\"approveD_START_DATETIME\":null,\"approveD_END_DATETIME\":null,\"scheduleD_HRS\":\"06:00\",\"actuaL_HRS\":\"06:17\",\"excesS_HRS\":\"00:17\",\"comP_OFF_N_HRS\":\"00:00\",\"comP_OFF_W_HRS\":\"00:00\",\"comP_OFF_H_HRS\":\"00:00\",\"timebacK_HRS\":null,\"shortagE_HRS\":\"00:00\",\"latE_IN_HRS\":\"00:00\",\"earlY_OUT_HRS\":\"00:00\",\"remarks\":null,\"excesS_FLAG\":\"Y\",\"comP_OFF_FLAG\":\"N\",\"timebacK_FLAG\":\"Y\",\"shortagE_FLAG\":\"N\",\"latE_IN_FLAG\":\"N\",\"earlY_OUT_FLAG\":\"N\",\"missinG_SWIPES_FLAG\":\"N\"},{\"schedulE_DATE\":\"2025-03-20T00:00:00\",\"shifT_NAME\":\"10:00 - 16:00\",\"shifT_TYPE\":\"Regular\",\"breaK_NAME\":\"00:00 - 00:00\",\"actuaL_WOB_HRS\":\"00:00\",\"shT_ACTUAL_START_DATETIME\":\"10:52\",\"shT_ACTUAL_END_DATETIME\":\"16:55\",\"approveD_START_DATETIME\":null,\"approveD_END_DATETIME\":null,\"scheduleD_HRS\":\"06:00\",\"actuaL_HRS\":\"06:03\",\"excesS_HRS\":\"00:03\",\"comP_OFF_N_HRS\":\"00:00\",\"comP_OFF_W_HRS\":\"00:00\",\"comP_OFF_H_HRS\":\"00:00\",\"timebacK_HRS\":null,\"shortagE_HRS\":\"00:00\",\"latE_IN_HRS\":\"00:00\",\"earlY_OUT_HRS\":\"00:00\",\"remarks\":null,\"excesS_FLAG\":\"Y\",\"comP_OFF_FLAG\":\"N\",\"timebacK_FLAG\":\"Y\",\"shortagE_FLAG\":\"N\",\"latE_IN_FLAG\":\"N\",\"earlY_OUT_FLAG\":\"N\",\"missinG_SWIPES_FLAG\":\"N\"},{\"schedulE_DATE\":\"2025-03-21T00:00:00\",\"shifT_NAME\":\"00:00 - 00:00\",\"shifT_TYPE\":\"Regular\",\"breaK_NAME\":\"00:00 - 00:00\",\"actuaL_WOB_HRS\":\"00:00\",\"shT_ACTUAL_START_DATETIME\":null,\"shT_ACTUAL_END_DATETIME\":null,\"approveD_START_DATETIME\":null,\"approveD_END_DATETIME\":null,\"scheduleD_HRS\":\"00:00\",\"actuaL_HRS\":\"00:00\",\"excesS_HRS\":\"00:00\",\"comP_OFF_N_HRS\":\"00:00\",\"comP_OFF_W_HRS\":\"00:00\",\"comP_OFF_H_HRS\":\"00:00\",\"timebacK_HRS\":null,\"shortagE_HRS\":\"00:00\",\"latE_IN_HRS\":\"00:00\",\"earlY_OUT_HRS\":\"00:00\",\"remarks\":\"Off Shift\",\"excesS_FLAG\":\"N\",\"comP_OFF_FLAG\":\"N\",\"timebacK_FLAG\":\"N\",\"shortagE_FLAG\":\"N\",\"latE_IN_FLAG\":\"N\",\"earlY_OUT_FLAG\":\"N\",\"missinG_SWIPES_FLAG\":\"N\"},{\"schedulE_DATE\":\"2025-03-22T00:00:00\",\"shifT_NAME\":\"00:00 - 00:00\",\"shifT_TYPE\":\"Regular\",\"breaK_NAME\":\"00:00 - 00:00\",\"actuaL_WOB_HRS\":\"00:00\",\"shT_ACTUAL_START_DATETIME\":null,\"shT_ACTUAL_END_DATETIME\":null,\"approveD_START_DATETIME\":null,\"approveD_END_DATETIME\":null,\"scheduleD_HRS\":\"00:00\",\"actuaL_HRS\":\"00:00\",\"excesS_HRS\":\"00:00\",\"comP_OFF_N_HRS\":\"00:00\",\"comP_OFF_W_HRS\":\"00:00\",\"comP_OFF_H_HRS\":\"00:00\",\"timebacK_HRS\":null,\"shortagE_HRS\":\"00:00\",\"latE_IN_HRS\":\"00:00\",\"earlY_OUT_HRS\":\"00:00\",\"remarks\":\"Off Shift\",\"excesS_FLAG\":\"N\",\"comP_OFF_FLAG\":\"N\",\"timebacK_FLAG\":\"N\",\"shortagE_FLAG\":\"N\",\"latE_IN_FLAG\":\"N\",\"earlY_OUT_FLAG\":\"N\",\"missinG_SWIPES_FLAG\":\"N\"},{\"schedulE_DATE\":\"2025-03-23T00:00:00\",\"shifT_NAME\":\"10:00 - 16:00\",\"shifT_TYPE\":\"Regular\",\"breaK_NAME\":\"00:00 - 00:00\",\"actuaL_WOB_HRS\":\"00:00\",\"shT_ACTUAL_START_DATETIME\":\"10:54\",\"shT_ACTUAL_END_DATETIME\":\"17:13\",\"approveD_START_DATETIME\":null,\"approveD_END_DATETIME\":null,\"scheduleD_HRS\":\"06:00\",\"actuaL_HRS\":\"06:19\",\"excesS_HRS\":\"00:19\",\"comP_OFF_N_HRS\":\"00:00\",\"comP_OFF_W_HRS\":\"00:00\",\"comP_OFF_H_HRS\":\"00:00\",\"timebacK_HRS\":null,\"shortagE_HRS\":\"00:00\",\"latE_IN_HRS\":\"00:00\",\"earlY_OUT_HRS\":\"00:00\",\"remarks\":null,\"excesS_FLAG\":\"Y\",\"comP_OFF_FLAG\":\"N\",\"timebacK_FLAG\":\"Y\",\"shortagE_FLAG\":\"N\",\"latE_IN_FLAG\":\"N\",\"earlY_OUT_FLAG\":\"N\",\"missinG_SWIPES_FLAG\":\"N\"},{\"schedulE_DATE\":\"2025-03-24T00:00:00\",\"shifT_NAME\":\"10:00 - 16:00\",\"shifT_TYPE\":\"Regular\",\"breaK_NAME\":\"00:00 - 00:00\",\"actuaL_WOB_HRS\":\"00:00\",\"shT_ACTUAL_START_DATETIME\":\"10:40\",\"shT_ACTUAL_END_DATETIME\":\"16:51\",\"approveD_START_DATETIME\":null,\"approveD_END_DATETIME\":null,\"scheduleD_HRS\":\"06:00\",\"actuaL_HRS\":\"06:11\",\"excesS_HRS\":\"00:11\",\"comP_OFF_N_HRS\":\"00:00\",\"comP_OFF_W_HRS\":\"00:00\",\"comP_OFF_H_HRS\":\"00:00\",\"timebacK_HRS\":null,\"shortagE_HRS\":\"00:00\",\"latE_IN_HRS\":\"00:00\",\"earlY_OUT_HRS\":\"00:00\",\"remarks\":null,\"excesS_FLAG\":\"Y\",\"comP_OFF_FLAG\":\"N\",\"timebacK_FLAG\":\"Y\",\"shortagE_FLAG\":\"N\",\"latE_IN_FLAG\":\"N\",\"earlY_OUT_FLAG\":\"N\",\"missinG_SWIPES_FLAG\":\"N\"},{\"schedulE_DATE\":\"2025-03-25T00:00:00\",\"shifT_NAME\":\"10:00 - 16:00\",\"shifT_TYPE\":\"Regular\",\"breaK_NAME\":\"00:00 - 00:00\",\"actuaL_WOB_HRS\":\"00:00\",\"shT_ACTUAL_START_DATETIME\":\"10:49\",\"shT_ACTUAL_END_DATETIME\":\"17:04\",\"approveD_START_DATETIME\":null,\"approveD_END_DATETIME\":null,\"scheduleD_HRS\":\"06:00\",\"actuaL_HRS\":\"06:15\",\"excesS_HRS\":\"00:15\",\"comP_OFF_N_HRS\":\"00:00\",\"comP_OFF_W_HRS\":\"00:00\",\"comP_OFF_H_HRS\":\"00:00\",\"timebacK_HRS\":null,\"shortagE_HRS\":\"00:00\",\"latE_IN_HRS\":\"00:00\",\"earlY_OUT_HRS\":\"00:00\",\"remarks\":null,\"excesS_FLAG\":\"Y\",\"comP_OFF_FLAG\":\"N\",\"timebacK_FLAG\":\"Y\",\"shortagE_FLAG\":\"N\",\"latE_IN_FLAG\":\"N\",\"earlY_OUT_FLAG\":\"N\",\"missinG_SWIPES_FLAG\":\"N\"},{\"schedulE_DATE\":\"2025-03-26T00:00:00\",\"shifT_NAME\":\"10:00 - 16:00\",\"shifT_TYPE\":\"Regular\",\"breaK_NAME\":\"00:00 - 00:00\",\"actuaL_WOB_HRS\":\"00:00\",\"shT_ACTUAL_START_DATETIME\":\"10:55\",\"shT_ACTUAL_END_DATETIME\":\"17:23\",\"approveD_START_DATETIME\":null,\"approveD_END_DATETIME\":null,\"scheduleD_HRS\":\"06:00\",\"actuaL_HRS\":\"06:28\",\"excesS_HRS\":\"00:28\",\"comP_OFF_N_HRS\":\"00:00\",\"comP_OFF_W_HRS\":\"00:00\",\"comP_OFF_H_HRS\":\"00:00\",\"timebacK_HRS\":null,\"shortagE_HRS\":\"00:00\",\"latE_IN_HRS\":\"00:00\",\"earlY_OUT_HRS\":\"00:00\",\"remarks\":null,\"excesS_FLAG\":\"Y\",\"comP_OFF_FLAG\":\"N\",\"timebacK_FLAG\":\"Y\",\"shortagE_FLAG\":\"N\",\"latE_IN_FLAG\":\"N\",\"earlY_OUT_FLAG\":\"N\",\"missinG_SWIPES_FLAG\":\"N\"},{\"schedulE_DATE\":\"2025-03-27T00:00:00\",\"shifT_NAME\":\"10:00 - 16:00\",\"shifT_TYPE\":\"Regular\",\"breaK_NAME\":\"00:00 - 00:00\",\"actuaL_WOB_HRS\":\"00:00\",\"shT_ACTUAL_START_DATETIME\":\"10:56\",\"shT_ACTUAL_END_DATETIME\":\"16:17\",\"approveD_START_DATETIME\":null,\"approveD_END_DATETIME\":null,\"scheduleD_HRS\":\"06:00\",\"actuaL_HRS\":\"05:21\",\"excesS_HRS\":\"00:00\",\"comP_OFF_N_HRS\":\"00:00\",\"comP_OFF_W_HRS\":\"00:00\",\"comP_OFF_H_HRS\":\"00:00\",\"timebacK_HRS\":null,\"shortagE_HRS\":\"00:39\",\"latE_IN_HRS\":\"00:00\",\"earlY_OUT_HRS\":\"00:39\",\"remarks\":null,\"excesS_FLAG\":\"N\",\"comP_OFF_FLAG\":\"N\",\"timebacK_FLAG\":\"N\",\"shortagE_FLAG\":\"Y\",\"latE_IN_FLAG\":\"N\",\"earlY_OUT_FLAG\":\"Y\",\"missinG_SWIPES_FLAG\":\"N\"},{\"schedulE_DATE\":\"2025-03-28T00:00:00\",\"shifT_NAME\":\"00:00 - 00:00\",\"shifT_TYPE\":\"Regular\",\"breaK_NAME\":\"00:00 - 00:00\",\"actuaL_WOB_HRS\":\"00:00\",\"shT_ACTUAL_START_DATETIME\":null,\"shT_ACTUAL_END_DATETIME\":null,\"approveD_START_DATETIME\":null,\"approveD_END_DATETIME\":null,\"scheduleD_HRS\":\"00:00\",\"actuaL_HRS\":\"00:00\",\"excesS_HRS\":\"00:00\",\"comP_OFF_N_HRS\":\"00:00\",\"comP_OFF_W_HRS\":\"00:00\",\"comP_OFF_H_HRS\":\"00:00\",\"timebacK_HRS\":null,\"shortagE_HRS\":\"00:00\",\"latE_IN_HRS\":\"00:00\",\"earlY_OUT_HRS\":\"00:00\",\"remarks\":\"Off Shift\",\"excesS_FLAG\":\"N\",\"comP_OFF_FLAG\":\"N\",\"timebacK_FLAG\":\"N\",\"shortagE_FLAG\":\"N\",\"latE_IN_FLAG\":\"N\",\"earlY_OUT_FLAG\":\"N\",\"missinG_SWIPES_FLAG\":\"N\"},{\"schedulE_DATE\":\"2025-03-29T00:00:00\",\"shifT_NAME\":\"00:00 - 00:00\",\"shifT_TYPE\":\"Regular\",\"breaK_NAME\":\"00:00 - 00:00\",\"actuaL_WOB_HRS\":\"00:00\",\"shT_ACTUAL_START_DATETIME\":null,\"shT_ACTUAL_END_DATETIME\":null,\"approveD_START_DATETIME\":null,\"approveD_END_DATETIME\":null,\"scheduleD_HRS\":\"00:00\",\"actuaL_HRS\":\"00:00\",\"excesS_HRS\":\"00:00\",\"comP_OFF_N_HRS\":\"00:00\",\"comP_OFF_W_HRS\":\"00:00\",\"comP_OFF_H_HRS\":\"00:00\",\"timebacK_HRS\":null,\"shortagE_HRS\":\"00:00\",\"latE_IN_HRS\":\"00:00\",\"earlY_OUT_HRS\":\"00:00\",\"remarks\":\"Off Shift\",\"excesS_FLAG\":\"N\",\"comP_OFF_FLAG\":\"N\",\"timebacK_FLAG\":\"N\",\"shortagE_FLAG\":\"N\",\"latE_IN_FLAG\":\"N\",\"earlY_OUT_FLAG\":\"N\",\"missinG_SWIPES_FLAG\":\"N\"},{\"schedulE_DATE\":\"2025-03-30T00:00:00\",\"shifT_NAME\":\"08:00 - 17:00\",\"shifT_TYPE\":\"Regular\",\"breaK_NAME\":\"13:00 - 14:00\",\"actuaL_WOB_HRS\":\"00:00\",\"shT_ACTUAL_START_DATETIME\":null,\"shT_ACTUAL_END_DATETIME\":null,\"approveD_START_DATETIME\":null,\"approveD_END_DATETIME\":null,\"scheduleD_HRS\":\"00:00\",\"actuaL_HRS\":\"00:00\",\"excesS_HRS\":\"00:00\",\"comP_OFF_N_HRS\":\"00:00\",\"comP_OFF_W_HRS\":\"00:00\",\"comP_OFF_H_HRS\":\"00:00\",\"timebacK_HRS\":null,\"shortagE_HRS\":\"00:00\",\"latE_IN_HRS\":\"00:00\",\"earlY_OUT_HRS\":\"00:00\",\"remarks\":\" From: 30-03-2025 To : 02-04-2025\\n\",\"excesS_FLAG\":\"N\",\"comP_OFF_FLAG\":\"N\",\"timebacK_FLAG\":\"N\",\"shortagE_FLAG\":\"N\",\"latE_IN_FLAG\":\"N\",\"earlY_OUT_FLAG\":\"N\",\"missinG_SWIPES_FLAG\":\"N\"},{\"schedulE_DATE\":\"2025-03-31T00:00:00\",\"shifT_NAME\":\"08:00 - 17:00\",\"shifT_TYPE\":\"Regular\",\"breaK_NAME\":\"13:00 - 14:00\",\"actuaL_WOB_HRS\":\"00:00\",\"shT_ACTUAL_START_DATETIME\":null,\"shT_ACTUAL_END_DATETIME\":null,\"approveD_START_DATETIME\":null,\"approveD_END_DATETIME\":null,\"scheduleD_HRS\":\"00:00\",\"actuaL_HRS\":\"00:00\",\"excesS_HRS\":\"00:00\",\"comP_OFF_N_HRS\":\"00:00\",\"comP_OFF_W_HRS\":\"00:00\",\"comP_OFF_H_HRS\":\"00:00\",\"timebacK_HRS\":null,\"shortagE_HRS\":\"00:00\",\"latE_IN_HRS\":\"00:00\",\"earlY_OUT_HRS\":\"00:00\",\"remarks\":\" From: 30-03-2025 To : 02-04-2025\\n\",\"excesS_FLAG\":\"N\",\"comP_OFF_FLAG\":\"N\",\"timebacK_FLAG\":\"N\",\"shortagE_FLAG\":\"N\",\"latE_IN_FLAG\":\"N\",\"earlY_OUT_FLAG\":\"N\",\"missinG_SWIPES_FLAG\":\"N\"}]}", // ); timeCardSummaryData = ItgTimeCardSummaryData.fromJson(decodedDta); + Future.delayed(Duration.zero); + setState(() { + controller.jumpToPage(0); + }); + Utils.hideLoading(context); } } else { timeCardSummaryData = ItgTimeCardSummaryData(); + Utils.hideLoading(context); + setState(() { + controller.jumpToPage(0); + }); } - Utils.hideLoading(context); - setState(() { - controller.jumpToPage(0); - }); + } catch (ex) { setState(() {}); Utils.hideLoading(context); diff --git a/lib/ui/work_list/worklist_detail_screen.dart b/lib/ui/work_list/worklist_detail_screen.dart index 45ecd4d..f1a7a3e 100644 --- a/lib/ui/work_list/worklist_detail_screen.dart +++ b/lib/ui/work_list/worklist_detail_screen.dart @@ -61,6 +61,7 @@ class _WorkListDetailScreenState extends State { int animationIndex = 0; PageController controller = PageController(); bool showFabOptions = false; + bool isShowActions = false; WorkListResponseModel? workListData; MemberInformationListModel? memberInformationListModel; @@ -286,6 +287,7 @@ class _WorkListDetailScreenState extends State { : ActionsFragment( workListData!.nOTIFICATIONID, actionHistoryList, + isShowActions, voidCallback: reloadWorkList, ) : showLoadingAnimation(), @@ -713,7 +715,6 @@ class _WorkListDetailScreenState extends State { "P_NOTIFICATION_ID": workListData!.nOTIFICATIONID, "RespondAttributeList": responseAttribute, }; - if (actionMode == "APPROVED" || actionMode == "APPROVE" || actionMode == "CLOSE" || @@ -1078,6 +1079,14 @@ class _WorkListDetailScreenState extends State { } return false; }); + + if(notificationButtonsList.any((GetNotificationButtonsList element) => element.bUTTONACTION == "DELEGATE" || element.bUTTONACTION == "REQUEST_INFO" )) { + isShowActions = true; + } else { + isShowActions = false; + } + + } apiCallCount--; if (apiCallCount == 0) { diff --git a/lib/ui/work_list/worklist_fragments/actions_fragment.dart b/lib/ui/work_list/worklist_fragments/actions_fragment.dart index 29d5328..97e540c 100644 --- a/lib/ui/work_list/worklist_fragments/actions_fragment.dart +++ b/lib/ui/work_list/worklist_fragments/actions_fragment.dart @@ -17,8 +17,9 @@ class ActionsFragment extends StatelessWidget { int? notificationID; List actionHistoryList; VoidCallback voidCallback; + bool isShowActions = false; - ActionsFragment(this.notificationID, this.actionHistoryList, {Key? key, required this.voidCallback}) : super(key: key); + ActionsFragment(this.notificationID, this.actionHistoryList, this.isShowActions, {Key? key, required this.voidCallback}) : super(key: key); @override Widget build(BuildContext context) { @@ -113,42 +114,41 @@ class ActionsFragment extends StatelessWidget { ], ).paddingOnly(top: 19, left: 16, right: 16, bottom: 12), Container(width: double.infinity, height: 1, color: MyColors.lightGreyEFColor), - Row( - children: [ - LocaleKeys.request_info.tr().toText12(color: MyColors.grey67Color).center.paddingOnly(top: 6, bottom: 6).onPress(() { - showMyBottomSheet( - context, - callBackFunc: voidCallback, - child: SelectedItemSheet(LocaleKeys.request_info.tr(), apiMode: "REQUEST_INFO", notificationID: notificationID, actionHistoryList: actionHistory), - ); - }).expanded, - Container(width: 1, height: 30, color: MyColors.lightGreyEFColor), - LocaleKeys.delegate.tr().toText12(color: MyColors.gradiantEndColor).center.paddingOnly(top: 6, bottom: 6).onPress(() { - if (actionHistory.uSERNAME == AppState().memberInformationList?.eMPLOYEENUMBER) { - showMyBottomSheet(context, + isShowActions + ? Row( + children: [ + LocaleKeys.request_info.tr().toText12(color: MyColors.grey67Color).center.paddingOnly(top: 6, bottom: 6).onPress(() { + showMyBottomSheet( + context, callBackFunc: voidCallback, - child: DelegateSheet( - title: LocaleKeys.delegate.tr(), - apiMode: "DELEGATE", - notificationID: notificationID, - actionHistoryList: actionHistoryList, + child: SelectedItemSheet(LocaleKeys.request_info.tr(), apiMode: "REQUEST_INFO", notificationID: notificationID, actionHistoryList: actionHistory), + ); + }).expanded, + Container(width: 1, height: 30, color: MyColors.lightGreyEFColor), + LocaleKeys.delegate.tr().toText12(color: MyColors.gradiantEndColor).center.paddingOnly(top: 6, bottom: 6).onPress(() { + if (actionHistory.uSERNAME == AppState().memberInformationList?.eMPLOYEENUMBER) { + showMyBottomSheet( + context, callBackFunc: voidCallback, - )); - return; - } - showMyBottomSheet( - context, - callBackFunc: voidCallback, - child: SelectedItemSheet( - LocaleKeys.comments.tr(), - apiMode: "DELEGATE", - actionHistoryList: actionHistory, - notificationID: notificationID, - ), - ); - }).expanded, - ], - ), + child: DelegateSheet( + title: LocaleKeys.delegate.tr(), + apiMode: "DELEGATE", + notificationID: notificationID, + actionHistoryList: actionHistoryList, + callBackFunc: voidCallback, + ), + ); + return; + } + showMyBottomSheet( + context, + callBackFunc: voidCallback, + child: SelectedItemSheet(LocaleKeys.comments.tr(), apiMode: "DELEGATE", actionHistoryList: actionHistory, notificationID: notificationID), + ); + }).expanded, + ], + ) + : const SizedBox(), ], ), ], diff --git a/lib/ui/work_list/worklist_fragments/info_fragments.dart b/lib/ui/work_list/worklist_fragments/info_fragments.dart index 76f2ace..73a87f7 100644 --- a/lib/ui/work_list/worklist_fragments/info_fragments.dart +++ b/lib/ui/work_list/worklist_fragments/info_fragments.dart @@ -760,6 +760,18 @@ class InfoFragment extends StatelessWidget { ItemDetailViewCol( LocaleKeys.requesterPayrollName.tr(), data.paymentDetailsList![0].requesterPayrollName ?? ""), ), + ItemDetailGrid( + ItemDetailViewCol( LocaleKeys.preparePositionName.tr(), + data.paymentDetailsList![0].preparePositionName ?? ""), + ItemDetailViewCol( + LocaleKeys.requesterPositionName.tr(), data.paymentDetailsList![0].requesterPositionName ?? ""), + ), + ItemDetailGrid( + ItemDetailViewCol( LocaleKeys.prepareEmpName.tr(), + data.paymentDetailsList![0].prepareEmployeeName ?? ""), + ItemDetailViewCol( + LocaleKeys.requesterPayrollName.tr(), data.paymentDetailsList![0].requesterPayrollName ?? ""), + ), ItemDetailGrid( ItemDetailViewCol( LocaleKeys.preparePositionName.tr(), data.paymentDetailsList![0].preparePositionName ?? ""), @@ -897,15 +909,18 @@ class InfoFragment extends StatelessWidget { ), ItemDetailGrid( ItemDetailViewCol(LocaleKeys.invoiceDate.tr(), - DateUtil.formatDateToDate( - DateUtil.convertStringToDate( data.refundInvoiceList![0].invoicedDate), false)?? ""), + DateUtil.formatDateToDate( + DateUtil.convertStringToDate( data.refundInvoiceList![0].invoicedDate), false)?? ""), + ItemDetailViewCol( LocaleKeys.refundInvoice.tr(), data.refundInvoiceList![0].invoiceNumber ?? "" ), ), ], ).objectContainerView(), - ], + + ], + ); } } diff --git a/lib/widgets/app_bar_widget.dart b/lib/widgets/app_bar_widget.dart index 744b7eb..277a414 100644 --- a/lib/widgets/app_bar_widget.dart +++ b/lib/widgets/app_bar_widget.dart @@ -1,22 +1,27 @@ import 'package:flutter/material.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'; -AppBar AppBarWidget(BuildContext context, - {required String title, - bool showHomeButton = true, - bool showWorkListSettingButton = false, - bool showMemberButton = false, - List? actions, - void Function()? onHomeTapped, - void Function()? onBackTapped}) { +AppBar AppBarWidget( + BuildContext context, { + required String title, + bool showHomeButton = true, + bool showLogo = false, + String? logoPath, + bool showWorkListSettingButton = false, + bool showMemberButton = false, + List? actions, + void Function()? onHomeTapped, + void Function()? onBackTapped, +}) { return AppBar( leadingWidth: 0, - automaticallyImplyLeading: false, + surfaceTintColor: Colors.transparent, title: Row( children: [ GestureDetector( @@ -26,8 +31,10 @@ AppBar AppBarWidget(BuildContext context, }, context), child: const Icon(Icons.arrow_back_ios, color: MyColors.darkIconColor), ), + if (showLogo) 4.width, + if (showLogo) SvgPicture.asset(logoPath!), 4.width, - title.toText24(color: MyColors.darkTextColor, isBold: true).expanded, + if (!showLogo)title.toText24(color: MyColors.darkTextColor, isBold: true).expanded, ], ), centerTitle: false, @@ -55,7 +62,7 @@ AppBar AppBarWidget(BuildContext context, }, icon: const Icon(Icons.people, color: MyColors.textMixColor), ), - ...actions ?? [] + ...actions ?? [], ], ); } diff --git a/lib/widgets/chat_app_bar_widge.dart b/lib/widgets/chat_app_bar_widge.dart index cc252ec..1291f9f 100644 --- a/lib/widgets/chat_app_bar_widge.dart +++ b/lib/widgets/chat_app_bar_widge.dart @@ -13,6 +13,8 @@ AppBar ChatAppBarWidget(BuildContext context, {required String title, bool showHomeButton = true, ChatUser? chatUser, bool showTyping = false, List? actions, void Function()? onHomeTapped, void Function()? onBackTapped}) { return AppBar( leadingWidth: 0, + automaticallyImplyLeading: false, + surfaceTintColor: Colors.transparent, title: Consumer(builder: (BuildContext cxt, ChatProviderModel data, Widget? child) { return Row( children: [ diff --git a/lib/widgets/image_picker.dart b/lib/widgets/image_picker.dart index f808d6e..a5d346f 100644 --- a/lib/widgets/image_picker.dart +++ b/lib/widgets/image_picker.dart @@ -159,7 +159,7 @@ class _BottomSheet extends StatelessWidget { Widget build(BuildContext context) { return Container( padding: const EdgeInsets.symmetric(vertical: 12.0), - decoration: BoxDecoration(color: Theme.of(context).scaffoldBackgroundColor, borderRadius: const BorderRadius.only(topLeft: Radius.circular(16.0), topRight: Radius.circular(16.0))), + decoration: BoxDecoration( borderRadius: const BorderRadius.only(topLeft: Radius.circular(16.0), topRight: Radius.circular(16.0))), child: SafeArea( top: false, child: Column( diff --git a/lib/widgets/mark_attendance_widget.dart b/lib/widgets/mark_attendance_widget.dart index 508ed00..ee258e1 100644 --- a/lib/widgets/mark_attendance_widget.dart +++ b/lib/widgets/mark_attendance_widget.dart @@ -24,7 +24,6 @@ import 'package:mohem_flutter_app/widgets/nfc/nfc_reader_sheet.dart'; import 'package:mohem_flutter_app/widgets/qr_scanner_dialog.dart'; import 'package:nfc_manager/nfc_manager.dart'; import 'package:permission_handler/permission_handler.dart'; -import 'package:platform_device_id/platform_device_id.dart'; import 'package:wifi_iot/wifi_iot.dart'; class MarkAttendanceWidget extends StatefulWidget { diff --git a/lib/widgets/nfc/nfc_reader_sheet.dart b/lib/widgets/nfc/nfc_reader_sheet.dart index de4c2f8..5e0b62d 100644 --- a/lib/widgets/nfc/nfc_reader_sheet.dart +++ b/lib/widgets/nfc/nfc_reader_sheet.dart @@ -78,10 +78,10 @@ class _NfcLayoutState extends State { } Widget scanNfc() { - return SizedBox( - width: MediaQuery.of(context).size.width, + return Container( + key: ValueKey(1), + width: double.infinity, child: Column( - key: ValueKey(1), mainAxisSize: MainAxisSize.min, children: [ SizedBox( @@ -139,9 +139,8 @@ class _NfcLayoutState extends State { Widget doneNfc() { return Container( - width: MediaQuery.of(context).size.width, + key: ValueKey(2), child: Column( - key: ValueKey(2), mainAxisSize: MainAxisSize.min, children: [ SizedBox( diff --git a/lib/widgets/qr_scanner_dialog.dart b/lib/widgets/qr_scanner_dialog.dart index 11e2601..01a92de 100644 --- a/lib/widgets/qr_scanner_dialog.dart +++ b/lib/widgets/qr_scanner_dialog.dart @@ -1,8 +1,8 @@ import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/material.dart'; +import 'package:mobile_scanner/mobile_scanner.dart'; import 'package:mohem_flutter_app/generated/locale_keys.g.dart'; import 'package:mohem_flutter_app/widgets/button/default_button.dart'; -import 'package:qr_code_scanner/qr_code_scanner.dart'; class QrScannerDialog extends StatefulWidget { @override @@ -11,8 +11,9 @@ class QrScannerDialog extends StatefulWidget { class _QrScannerDialogState extends State { final GlobalKey qrKey = GlobalKey(debugLabel: 'QR'); - Barcode? result; - QRViewController? controller; + // Barcode? result; + // QRViewController? controller; + Barcode? _barcode; bool isPicked = false; @override @@ -26,10 +27,7 @@ class _QrScannerDialogState extends State { children: [ Expanded( flex: 1, - child: QRView( - key: qrKey, - onQRViewCreated: _onQRViewCreated, - ), + child: MobileScanner(key : qrKey,onDetect: _handleBarcode), ), // Expanded( // flex: 1, @@ -55,25 +53,25 @@ class _QrScannerDialogState extends State { ); } - void _onQRViewCreated(QRViewController controller) { - this.controller = controller; - - controller.scannedDataStream.listen((scanData) { + void _handleBarcode(BarcodeCapture barcodes) { + // this.controller = controller; + Barcode? data = barcodes.barcodes.firstOrNull; + if(data == null || isPicked) { + return; + } + // controller.scannedDataStream.listen((scanData) { setState(() { - result = scanData; - if (!isPicked) { + // result = scanData; isPicked = true; - Navigator.pop(context, result!.code); - } + Navigator.pop(context, data.displayValue); }); - }); - controller.pauseCamera(); - controller.resumeCamera(); + // }); + // controller.pauseCamera(); + // controller.resumeCamera(); } @override void dispose() { - controller?.dispose(); super.dispose(); } } diff --git a/lib/widgets/sso_webview_widget.dart b/lib/widgets/sso_webview_widget.dart new file mode 100644 index 0000000..e5f2759 --- /dev/null +++ b/lib/widgets/sso_webview_widget.dart @@ -0,0 +1,61 @@ +import 'dart:convert'; + +import 'package:flutter/material.dart'; +import 'package:webview_flutter/webview_flutter.dart'; + +class SsoLoginWebView extends StatefulWidget { + final String url; + final String jwtToken; + + SsoLoginWebView({required this.url, required this.jwtToken}); + + @override + State createState() => _SsoLoginWebViewState(); +} + +class _SsoLoginWebViewState extends State { + late final WebViewController _controller; + + @override + void initState() { + // TODO: implement initState + super.initState(); + _controller = + WebViewController() + ..setJavaScriptMode(JavaScriptMode.unrestricted) + ..setNavigationDelegate( + NavigationDelegate( + onProgress: (int progress) { + print("WebView is loading (progress: $progress%)"); + }, + onPageStarted: (String url) { + print("Page started loading: $url"); + }, + onPageFinished: (String url) { + print("Page finished loading: $url"); + }, + onHttpError: (HttpResponseError error) { + print("HTTP error: ${error.toString()} for URL: ${error.response!.statusCode}"); + }, + onWebResourceError: (WebResourceError error) { + print("Web resource error: ${error.description} for URL: ${error.errorType}"); + }, + ), + ) + ..loadHtmlString(''' + + + +
+ +
+

Redirecting...

+ +'''); + } + + @override + Widget build(BuildContext context) { + return Scaffold(appBar: AppBar(title: Text('Logging in...')), body: WebViewWidget(controller: _controller)); + } +} diff --git a/pubspec.yaml b/pubspec.yaml index 20d34ac..31d5682 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -16,11 +16,12 @@ publish_to: 'none' # Remove this line if you wish to publish to pub.dev # In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion. # Read more about iOS versioning at # https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html -#version: 3.3.01+300040 -version: 4.5.3+4000035 + +version: 3.6.7+300077 +#version: 3.9.0+1 environment: - sdk: ">=2.16.0 <3.0.0" + sdk: ^3.7.0 # Dependencies specify other packages that your package needs in order to work. # To automatically upgrade your package dependencies to the latest versions @@ -36,102 +37,118 @@ dependencies: # The following adds the Cupertino Icons font to your application. # Use with the CupertinoIcons class for iOS style icons. cupertino_icons: ^1.0.4 - path_provider: ^2.0.8 +# path_provider: ^2.0.8 + path_provider: ^2.1.5 injector: ^2.0.0 provider: ^6.0.1 easy_localization: ^3.0.0 - http: ^0.13.4 - permission_handler: ^10.2.0 + http: ^1.4.0 + permission_handler: ^12.0.1 flutter_svg: any sizer: ^2.0.15 - local_auth: ^1.1.9 - fluttertoast: ^8.0.8 - syncfusion_flutter_calendar: ^19.4.48 + local_auth: ^2.3.0 + fluttertoast: ^8.2.12 + syncfusion_flutter_calendar: ^29.1.38 # flutter_calendar_carousel: ^2.1.0 pie_chart: ^5.1.0 - shared_preferences: ^2.0.12 - firebase_messaging: ^13.0.4 +# shared_preferences: ^2.0.12 + shared_preferences: ^2.5.3 + firebase_messaging: ^15.2.9 shimmer: ^2.0.0 logger: ^1.1.0 flutter_countdown_timer: ^4.1.0 - nfc_manager: ^3.2.0 - # uuid: ^3.0.6 - # device_info_plus: ^4.0.0 - # android_id: ^0.1.3+1 - platform_device_id: ^1.0.1 - image_picker: ^0.8.5+3 - file_picker: 5.2.5 - geolocator: ^11.1.0 - month_year_picker: ^0.2.0+1 - month_picker_dialog_2: ^0.5.5 - # open_file: ^3.2.1 - open_filex: ^4.4.0 - wifi_iot: ^0.3.19+1 + + platform_device_id_plus: ^1.0.7 + device_info_plus: ^11.5.0 + image_picker: ^1.1.2 + file_picker: ^8.3.1 + geolocator: ^9.0.2 + month_year_picker: ^0.5.0+1 + month_picker_dialog: ^6.0.3 +# open_file: ^3.2.1 + open_filex: ^4.6.0 + wifi_iot: ^0.3.19+2 flutter_html: ^3.0.0-alpha.6 + mobile_scanner: ^6.0.10 # flutter_barcode_scanner: ^2.0.0 - qr_code_scanner: ^1.0.1 +# qr_code_scanner: ^1.0.1 # qr_flutter: ^4.0.0 - url_launcher: ^6.0.15 - share: 2.0.4 + url_launcher: ^6.3.2 + share_plus: ^11.0.0 flutter_rating_bar: ^4.0.1 auto_size_text: ^3.0.0 pull_to_refresh: ^2.0.0 - fl_chart: ^0.62.0 + fl_chart: ^0.66.0 # lottie json animations - lottie: any + lottie: ^3.3.1 # Marathon Card Swipe appinio_swiper: ^1.1.1 expandable: ^5.0.1 safe_device: ^1.1.9 # networkImage - cached_network_image: ^3.2.2 +# cached_network_image: ^3.2.2 + cached_network_image: ^3.4.1 #Chat signalr_netcore: ^1.3.3 logging: ^1.0.1 swipe_to: ^1.0.2 - flutter_webrtc: ^0.9.17 - camera: ^0.10.3 - flutter_local_notifications: ^10.0.0 + flutter_webrtc: ^0.12.11 + camera: ^0.11.2 +# camera: ^0.10.3 + flutter_local_notifications: ^18.0.1 #firebase_analytics: any #Chat Voice Message Recoding & Play - audio_waveforms: ^0.1.5+1 + audio_waveforms: ^1.3.0 rxdart: ^0.27.7 #Encryption flutter_des: ^2.1.0 - video_player: 2.7.0 + video_player: ^2.10.0 just_audio: ^0.9.30 # safe_device: ^1.1.2 flutter_layout_grid: ^2.0.1 #Huawei Dependencies # huawei_hmsavailability: ^6.6.0+300 - # huawei_location: 6.0.0+302 - huawei_location: ^6.11.0+301 - huawei_push: ^6.7.0+300 - firebase_crashlytics: ^2.9.0 +# huawei_location: 6.0.0+302 + huawei_location: ^6.14.2+301 +# huawei_push: ^6.7.0+300 + + huawei_map: + git: + url: https://github.com/fleoparra/hms-flutter-plugin.git + path: flutter-hms-map + huawei_push: + git: + url: https://github.com/crasowas/hms-flutter-plugin.git + path: flutter-hms-push + firebase_crashlytics: ^4.3.9 #Items for sale Image Carousel Slider - carousel_slider: ^4.2.1 + carousel_slider: ^5.1.1 #Huawei Specified # store_checker: ^1.1.0 - google_api_availability: ^3.0.1 - + google_api_availability: ^5.0.1 + google_maps_flutter_web: ^0.5.4 in_app_update: 4.1.0 + flutter_inappwebview: ^6.1.5 + flutter_blurhash: ^0.8.0 #todo its for temporary purpose, later will remove this. dotted_border: ^2.0.0+3 + webview_flutter: ^4.13.0 # saf: ^1.0.3+4 dependency_overrides: - firebase_core_platform_interface: 4.5.1 + nfc_manager: ^3.2.0 +# firebase_core_platform_interface: 4.5.1 dev_dependencies: @@ -228,4 +245,4 @@ flutter: # see https://flutter.dev/custom-fonts/#from-packages -# Adding this to test the push from iMac \ No newline at end of file +# Adding this to test the push from iMac