diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..034a5be --- /dev/null +++ b/.gitignore @@ -0,0 +1,48 @@ +# Miscellaneous +*.class +*.log +*.pyc +*.swp +*.lock +.DS_Store +pubspec.lock +.atom/ +.buildlog/ +.history +.svn/ + +# IntelliJ related +*.iml +*.ipr +*.iws +.idea/ + +# The .vscode folder contains launch configuration and tasks you configure in +# VS Code which you may wish to be included in version control, so this line +# is commented out by default. +#.vscode/ + +# Flutter/Dart/Pub related +**/doc/api/ +**/ios/Flutter/.last_build_id +.dart_tool/ +.flutter-plugins +.flutter-plugins-dependencies +.packages +.pub-cache/ +.pub/ +/build/ + +# Web related +lib/generated_plugin_registrant.dart + +# Symbolication related +app.*.symbols + +# Obfuscation related +app.*.map.json + +# Android Studio will place build artifacts here +/android/app/debug +/android/app/profile +/android/app/release diff --git a/.metadata b/.metadata new file mode 100644 index 0000000..0f055bf --- /dev/null +++ b/.metadata @@ -0,0 +1,10 @@ +# This file tracks properties of this Flutter project. +# Used by Flutter tool to assess capabilities and perform upgrades etc. +# +# This file should be version controlled and should not be manually edited. + +version: + revision: ffb2ecea5223acdd139a5039be2f9c796962833d + channel: stable + +project_type: app diff --git a/analysis_options.yaml b/analysis_options.yaml new file mode 100644 index 0000000..90c25c1 --- /dev/null +++ b/analysis_options.yaml @@ -0,0 +1,34 @@ +# This file configures the analyzer, which statically analyzes Dart code to +# check for errors, warnings, and lints. +# +# The issues identified by the analyzer are surfaced in the UI of Dart-enabled +# IDEs (https://dart.dev/tools#ides-and-editors). The analyzer can also be +# invoked from the command line by running `flutter analyze`. + +# The following line activates a set of recommended lints for Flutter apps, +# packages, and plugins designed to encourage good coding practices. +include: package:flutter_lints/flutter.yaml + +linter: + # The lint rules applied to this project can be customized in the + # section below to disable rules from the `package:flutter_lints/flutter.yaml` + # included above or to enable additional rules. A list of all available lints + # and their documentation is published at + # https://dart-lang.github.io/linter/lints/index.html. + # + # Instead of disabling a lint rule for the entire project in the + # section below, it can also be suppressed for a single line of code + # or a specific dart file by using the `// ignore: name_of_lint` and + # `// ignore_for_file: name_of_lint` syntax on the line or in the file + # producing the lint. + rules: + always_specify_types: true + always_declare_return_types: true + always_use_package_imports: true + avoid_empty_else: true + avoid_annotating_with_dynamic: true + # avoid_print: false # Uncomment to disable the `avoid_print` rule + # prefer_single_quotes: true # Uncomment to enable the `prefer_single_quotes` rule + +# Additional information about this file can be found at +# https://dart.dev/guides/language/analysis-options diff --git a/android/.gitignore b/android/.gitignore new file mode 100644 index 0000000..6f56801 --- /dev/null +++ b/android/.gitignore @@ -0,0 +1,13 @@ +gradle-wrapper.jar +/.gradle +/captures/ +/gradlew +/gradlew.bat +/local.properties +GeneratedPluginRegistrant.java + +# Remember to never publicly share your keystore. +# See https://flutter.dev/docs/deployment/android#reference-the-keystore-from-the-app +key.properties +**/*.keystore +**/*.jks diff --git a/android/app/build.gradle b/android/app/build.gradle new file mode 100644 index 0000000..4e4b395 --- /dev/null +++ b/android/app/build.gradle @@ -0,0 +1,68 @@ +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.") +} + +def flutterVersionCode = localProperties.getProperty('flutter.versionCode') +if (flutterVersionCode == null) { + flutterVersionCode = '1' +} + +def flutterVersionName = localProperties.getProperty('flutter.versionName') +if (flutterVersionName == null) { + flutterVersionName = '1.0' +} + +apply plugin: 'com.android.application' +apply plugin: 'kotlin-android' +apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" + +android { + compileSdkVersion 31 + + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } + + kotlinOptions { + jvmTarget = '1.8' + } + + sourceSets { + main.java.srcDirs += 'src/main/kotlin' + } + + defaultConfig { + // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). + applicationId "com.mohem_flutter_app" + minSdkVersion 16 + targetSdkVersion 30 + versionCode flutterVersionCode.toInteger() + versionName flutterVersionName + } + + buildTypes { + release { + // TODO: Add your own signing config for the release build. + // Signing with the debug keys for now, so `flutter run --release` works. + signingConfig signingConfigs.debug + } + } +} + +flutter { + source '../..' +} + +dependencies { + implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" +} diff --git a/android/app/src/debug/AndroidManifest.xml b/android/app/src/debug/AndroidManifest.xml new file mode 100644 index 0000000..50ab38d --- /dev/null +++ b/android/app/src/debug/AndroidManifest.xml @@ -0,0 +1,7 @@ + + + + diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000..472e794 --- /dev/null +++ b/android/app/src/main/AndroidManifest.xml @@ -0,0 +1,42 @@ + + + + + + + + + + + + + + + + + diff --git a/android/app/src/main/kotlin/com/mohem_flutter_app/MainActivity.kt b/android/app/src/main/kotlin/com/mohem_flutter_app/MainActivity.kt new file mode 100644 index 0000000..ec84fc4 --- /dev/null +++ b/android/app/src/main/kotlin/com/mohem_flutter_app/MainActivity.kt @@ -0,0 +1,6 @@ +package com.mohem_flutter_app + +import io.flutter.embedding.android.FlutterActivity + +class MainActivity: FlutterActivity() { +} diff --git a/android/app/src/main/res/drawable-v21/launch_background.xml b/android/app/src/main/res/drawable-v21/launch_background.xml new file mode 100644 index 0000000..f74085f --- /dev/null +++ b/android/app/src/main/res/drawable-v21/launch_background.xml @@ -0,0 +1,12 @@ + + + + + + + + diff --git a/android/app/src/main/res/drawable/launch_background.xml b/android/app/src/main/res/drawable/launch_background.xml new file mode 100644 index 0000000..304732f --- /dev/null +++ b/android/app/src/main/res/drawable/launch_background.xml @@ -0,0 +1,12 @@ + + + + + + + + diff --git a/android/app/src/main/res/mipmap-hdpi/ic_launcher.png b/android/app/src/main/res/mipmap-hdpi/ic_launcher.png new file mode 100644 index 0000000..db77bb4 Binary files /dev/null and b/android/app/src/main/res/mipmap-hdpi/ic_launcher.png differ diff --git a/android/app/src/main/res/mipmap-mdpi/ic_launcher.png b/android/app/src/main/res/mipmap-mdpi/ic_launcher.png new file mode 100644 index 0000000..17987b7 Binary files /dev/null and b/android/app/src/main/res/mipmap-mdpi/ic_launcher.png differ diff --git a/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png new file mode 100644 index 0000000..09d4391 Binary files /dev/null and b/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png differ diff --git a/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png new file mode 100644 index 0000000..d5f1c8d Binary files /dev/null and b/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png differ diff --git a/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png new file mode 100644 index 0000000..4d6372e Binary files /dev/null and b/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png differ diff --git a/android/app/src/main/res/values-night/styles.xml b/android/app/src/main/res/values-night/styles.xml new file mode 100644 index 0000000..449a9f9 --- /dev/null +++ b/android/app/src/main/res/values-night/styles.xml @@ -0,0 +1,18 @@ + + + + + + + diff --git a/android/app/src/main/res/values/styles.xml b/android/app/src/main/res/values/styles.xml new file mode 100644 index 0000000..d74aa35 --- /dev/null +++ b/android/app/src/main/res/values/styles.xml @@ -0,0 +1,18 @@ + + + + + + + diff --git a/android/app/src/profile/AndroidManifest.xml b/android/app/src/profile/AndroidManifest.xml new file mode 100644 index 0000000..50ab38d --- /dev/null +++ b/android/app/src/profile/AndroidManifest.xml @@ -0,0 +1,7 @@ + + + + diff --git a/android/build.gradle b/android/build.gradle new file mode 100644 index 0000000..66edc25 --- /dev/null +++ b/android/build.gradle @@ -0,0 +1,29 @@ +buildscript { + ext.kotlin_version = '1.6.0' + repositories { + google() + mavenCentral() + } + + dependencies { + classpath 'com.android.tools.build:gradle:7.0.3' + classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" + } +} + +allprojects { + repositories { + google() + mavenCentral() + } +} + +rootProject.buildDir = '../build' +subprojects { + project.buildDir = "${rootProject.buildDir}/${project.name}" + project.evaluationDependsOn(':app') +} + +task clean(type: Delete) { + delete rootProject.buildDir +} diff --git a/android/gradle.properties b/android/gradle.properties new file mode 100644 index 0000000..94adc3a --- /dev/null +++ b/android/gradle.properties @@ -0,0 +1,3 @@ +org.gradle.jvmargs=-Xmx1536M +android.useAndroidX=true +android.enableJetifier=true diff --git a/android/gradle/wrapper/gradle-wrapper.properties b/android/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 0000000..ed1a787 --- /dev/null +++ b/android/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,6 @@ +#Fri Jun 23 08:50:38 CEST 2017 +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-7.0.2-bin.zip diff --git a/android/settings.gradle b/android/settings.gradle new file mode 100644 index 0000000..44e62bc --- /dev/null +++ b/android/settings.gradle @@ -0,0 +1,11 @@ +include ':app' + +def localPropertiesFile = new File(rootProject.projectDir, "local.properties") +def properties = new Properties() + +assert localPropertiesFile.exists() +localPropertiesFile.withReader("UTF-8") { reader -> properties.load(reader) } + +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" diff --git a/assets/fonts/ar/Cairo-Bold/Cairo-Bold.eot b/assets/fonts/ar/Cairo-Bold/Cairo-Bold.eot new file mode 100644 index 0000000..ed5f0c3 Binary files /dev/null and b/assets/fonts/ar/Cairo-Bold/Cairo-Bold.eot differ diff --git a/assets/fonts/ar/Cairo-Bold/Cairo-Bold.otf b/assets/fonts/ar/Cairo-Bold/Cairo-Bold.otf new file mode 100644 index 0000000..8bc25fb Binary files /dev/null and b/assets/fonts/ar/Cairo-Bold/Cairo-Bold.otf differ diff --git a/assets/fonts/ar/Cairo-Bold/Cairo-Bold.ttf b/assets/fonts/ar/Cairo-Bold/Cairo-Bold.ttf new file mode 100644 index 0000000..4f02689 Binary files /dev/null and b/assets/fonts/ar/Cairo-Bold/Cairo-Bold.ttf differ diff --git a/assets/fonts/ar/Cairo-Bold/Cairo-Bold.woff b/assets/fonts/ar/Cairo-Bold/Cairo-Bold.woff new file mode 100644 index 0000000..91e3d06 Binary files /dev/null and b/assets/fonts/ar/Cairo-Bold/Cairo-Bold.woff differ diff --git a/assets/fonts/ar/Cairo-Light/Cairo-Light.eot b/assets/fonts/ar/Cairo-Light/Cairo-Light.eot new file mode 100644 index 0000000..d76c539 Binary files /dev/null and b/assets/fonts/ar/Cairo-Light/Cairo-Light.eot differ diff --git a/assets/fonts/ar/Cairo-Light/Cairo-Light.otf b/assets/fonts/ar/Cairo-Light/Cairo-Light.otf new file mode 100644 index 0000000..f8812a9 Binary files /dev/null and b/assets/fonts/ar/Cairo-Light/Cairo-Light.otf differ diff --git a/assets/fonts/ar/Cairo-Light/Cairo-Light.ttf b/assets/fonts/ar/Cairo-Light/Cairo-Light.ttf new file mode 100644 index 0000000..840cbc3 Binary files /dev/null and b/assets/fonts/ar/Cairo-Light/Cairo-Light.ttf differ diff --git a/assets/fonts/ar/Cairo-Light/Cairo-Light.woff b/assets/fonts/ar/Cairo-Light/Cairo-Light.woff new file mode 100644 index 0000000..9534bb4 Binary files /dev/null and b/assets/fonts/ar/Cairo-Light/Cairo-Light.woff differ diff --git a/assets/fonts/en/WorkSans-Bold/WorkSans-Bold.eot b/assets/fonts/en/WorkSans-Bold/WorkSans-Bold.eot new file mode 100644 index 0000000..98bc246 Binary files /dev/null and b/assets/fonts/en/WorkSans-Bold/WorkSans-Bold.eot differ diff --git a/assets/fonts/en/WorkSans-Bold/WorkSans-Bold.otf b/assets/fonts/en/WorkSans-Bold/WorkSans-Bold.otf new file mode 100644 index 0000000..73f8bf0 Binary files /dev/null and b/assets/fonts/en/WorkSans-Bold/WorkSans-Bold.otf differ diff --git a/assets/fonts/en/WorkSans-Bold/WorkSans-Bold.ttf b/assets/fonts/en/WorkSans-Bold/WorkSans-Bold.ttf new file mode 100644 index 0000000..177a3b6 Binary files /dev/null and b/assets/fonts/en/WorkSans-Bold/WorkSans-Bold.ttf differ diff --git a/assets/fonts/en/WorkSans-Bold/WorkSans-Bold.woff b/assets/fonts/en/WorkSans-Bold/WorkSans-Bold.woff new file mode 100644 index 0000000..8d7013c Binary files /dev/null and b/assets/fonts/en/WorkSans-Bold/WorkSans-Bold.woff differ diff --git a/assets/fonts/en/WorkSans-Light/WorkSans-Light_0.eot b/assets/fonts/en/WorkSans-Light/WorkSans-Light_0.eot new file mode 100644 index 0000000..9541e41 Binary files /dev/null and b/assets/fonts/en/WorkSans-Light/WorkSans-Light_0.eot differ diff --git a/assets/fonts/en/WorkSans-Light/WorkSans-Light_0.otf b/assets/fonts/en/WorkSans-Light/WorkSans-Light_0.otf new file mode 100644 index 0000000..be5e0ac Binary files /dev/null and b/assets/fonts/en/WorkSans-Light/WorkSans-Light_0.otf differ diff --git a/assets/fonts/en/WorkSans-Light/WorkSans-Light_0.ttf b/assets/fonts/en/WorkSans-Light/WorkSans-Light_0.ttf new file mode 100644 index 0000000..0b010ad Binary files /dev/null and b/assets/fonts/en/WorkSans-Light/WorkSans-Light_0.ttf differ diff --git a/assets/fonts/en/WorkSans-Light/WorkSans-Light_0.woff b/assets/fonts/en/WorkSans-Light/WorkSans-Light_0.woff new file mode 100644 index 0000000..12226d7 Binary files /dev/null and b/assets/fonts/en/WorkSans-Light/WorkSans-Light_0.woff differ diff --git a/assets/fonts/en/WorkSans-Light/WorkSans-Regular.otf b/assets/fonts/en/WorkSans-Light/WorkSans-Regular.otf new file mode 100644 index 0000000..be88832 Binary files /dev/null and b/assets/fonts/en/WorkSans-Light/WorkSans-Regular.otf differ diff --git a/assets/fonts/en/WorkSans-Light/WorkSans-Regular.ttf b/assets/fonts/en/WorkSans-Light/WorkSans-Regular.ttf new file mode 100644 index 0000000..0ac4520 Binary files /dev/null and b/assets/fonts/en/WorkSans-Light/WorkSans-Regular.ttf differ diff --git a/assets/fonts/en/WorkSans-Light/WorkSans-Regular.woff b/assets/fonts/en/WorkSans-Light/WorkSans-Regular.woff new file mode 100644 index 0000000..89af38b Binary files /dev/null and b/assets/fonts/en/WorkSans-Light/WorkSans-Regular.woff differ diff --git a/assets/fonts/poppins/Poppins-Black.ttf b/assets/fonts/poppins/Poppins-Black.ttf new file mode 100644 index 0000000..a9520b7 Binary files /dev/null and b/assets/fonts/poppins/Poppins-Black.ttf differ diff --git a/assets/fonts/poppins/Poppins-Bold.ttf b/assets/fonts/poppins/Poppins-Bold.ttf new file mode 100644 index 0000000..b94d47f Binary files /dev/null and b/assets/fonts/poppins/Poppins-Bold.ttf differ diff --git a/assets/fonts/poppins/Poppins-ExtraBold.ttf b/assets/fonts/poppins/Poppins-ExtraBold.ttf new file mode 100644 index 0000000..8f008c3 Binary files /dev/null and b/assets/fonts/poppins/Poppins-ExtraBold.ttf differ diff --git a/assets/fonts/poppins/Poppins-ExtraLight.ttf b/assets/fonts/poppins/Poppins-ExtraLight.ttf new file mode 100644 index 0000000..ee62382 Binary files /dev/null and b/assets/fonts/poppins/Poppins-ExtraLight.ttf differ diff --git a/assets/fonts/poppins/Poppins-Light.ttf b/assets/fonts/poppins/Poppins-Light.ttf new file mode 100644 index 0000000..2ab0221 Binary files /dev/null and b/assets/fonts/poppins/Poppins-Light.ttf differ diff --git a/assets/fonts/poppins/Poppins-Medium.ttf b/assets/fonts/poppins/Poppins-Medium.ttf new file mode 100644 index 0000000..e90e87e Binary files /dev/null and b/assets/fonts/poppins/Poppins-Medium.ttf differ diff --git a/assets/fonts/poppins/Poppins-Regular.ttf b/assets/fonts/poppins/Poppins-Regular.ttf new file mode 100644 index 0000000..be06e7f Binary files /dev/null and b/assets/fonts/poppins/Poppins-Regular.ttf differ diff --git a/assets/fonts/poppins/Poppins-SemiBold.ttf b/assets/fonts/poppins/Poppins-SemiBold.ttf new file mode 100644 index 0000000..dabf7c2 Binary files /dev/null and b/assets/fonts/poppins/Poppins-SemiBold.ttf differ diff --git a/assets/fonts/poppins/Poppins-Thin.ttf b/assets/fonts/poppins/Poppins-Thin.ttf new file mode 100644 index 0000000..f5c0fdd Binary files /dev/null and b/assets/fonts/poppins/Poppins-Thin.ttf differ diff --git a/assets/icons/ic_face_id.png b/assets/icons/ic_face_id.png new file mode 100644 index 0000000..913e850 Binary files /dev/null and b/assets/icons/ic_face_id.png differ diff --git a/assets/icons/ic_fingerprint.png b/assets/icons/ic_fingerprint.png new file mode 100644 index 0000000..bf73197 Binary files /dev/null and b/assets/icons/ic_fingerprint.png differ diff --git a/assets/icons/ic_sms.png b/assets/icons/ic_sms.png new file mode 100644 index 0000000..aa72e0e Binary files /dev/null and b/assets/icons/ic_sms.png differ diff --git a/assets/icons/ic_whatsapp.png b/assets/icons/ic_whatsapp.png new file mode 100644 index 0000000..3f36403 Binary files /dev/null and b/assets/icons/ic_whatsapp.png differ diff --git a/assets/images/add.svg b/assets/images/add.svg new file mode 100644 index 0000000..0230942 --- /dev/null +++ b/assets/images/add.svg @@ -0,0 +1,3 @@ + + + diff --git a/assets/images/announcements.svg b/assets/images/announcements.svg new file mode 100644 index 0000000..d204e60 --- /dev/null +++ b/assets/images/announcements.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/assets/images/arrow_next.svg b/assets/images/arrow_next.svg new file mode 100644 index 0000000..76de3b9 --- /dev/null +++ b/assets/images/arrow_next.svg @@ -0,0 +1,3 @@ + + + diff --git a/assets/images/clear_field.svg b/assets/images/clear_field.svg new file mode 100644 index 0000000..618ed79 --- /dev/null +++ b/assets/images/clear_field.svg @@ -0,0 +1,3 @@ + + + diff --git a/assets/images/clock.svg b/assets/images/clock.svg new file mode 100644 index 0000000..bc9faed --- /dev/null +++ b/assets/images/clock.svg @@ -0,0 +1,3 @@ + + + diff --git a/assets/images/close.svg b/assets/images/close.svg new file mode 100644 index 0000000..7ef696b --- /dev/null +++ b/assets/images/close.svg @@ -0,0 +1,3 @@ + + + diff --git a/assets/images/delegate.svg b/assets/images/delegate.svg new file mode 100644 index 0000000..aa2bd7a --- /dev/null +++ b/assets/images/delegate.svg @@ -0,0 +1,3 @@ + + + diff --git a/assets/images/dot_circle.svg b/assets/images/dot_circle.svg new file mode 100644 index 0000000..b3ac566 --- /dev/null +++ b/assets/images/dot_circle.svg @@ -0,0 +1,3 @@ + + + diff --git a/assets/images/fav.svg b/assets/images/fav.svg new file mode 100644 index 0000000..ebbaf1c --- /dev/null +++ b/assets/images/fav.svg @@ -0,0 +1,3 @@ + + + diff --git a/assets/images/jpg.svg b/assets/images/jpg.svg new file mode 100644 index 0000000..cfda5a7 --- /dev/null +++ b/assets/images/jpg.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/assets/images/login/verify_face.svg b/assets/images/login/verify_face.svg new file mode 100644 index 0000000..e50d1a6 --- /dev/null +++ b/assets/images/login/verify_face.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/assets/images/login/verify_sms.svg b/assets/images/login/verify_sms.svg new file mode 100644 index 0000000..ae5fa9f --- /dev/null +++ b/assets/images/login/verify_sms.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/assets/images/login/verify_thumb.svg b/assets/images/login/verify_thumb.svg new file mode 100644 index 0000000..e626baf --- /dev/null +++ b/assets/images/login/verify_thumb.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/assets/images/login/verify_whatsapp.svg b/assets/images/login/verify_whatsapp.svg new file mode 100644 index 0000000..09ac85c --- /dev/null +++ b/assets/images/login/verify_whatsapp.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/assets/images/logos/loading_mohemm_logo.gif b/assets/images/logos/loading_mohemm_logo.gif new file mode 100644 index 0000000..ffefdb0 Binary files /dev/null and b/assets/images/logos/loading_mohemm_logo.gif differ diff --git a/assets/images/logos/mohemm_logo.svg b/assets/images/logos/mohemm_logo.svg new file mode 100644 index 0000000..1cb9a0b --- /dev/null +++ b/assets/images/logos/mohemm_logo.svg @@ -0,0 +1,62 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/images/miss_swipe.svg b/assets/images/miss_swipe.svg new file mode 100644 index 0000000..05d32f2 --- /dev/null +++ b/assets/images/miss_swipe.svg @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/assets/images/monthly_attendance.svg b/assets/images/monthly_attendance.svg new file mode 100644 index 0000000..c84a9a1 --- /dev/null +++ b/assets/images/monthly_attendance.svg @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/assets/images/more_dotted.svg b/assets/images/more_dotted.svg new file mode 100644 index 0000000..add7848 --- /dev/null +++ b/assets/images/more_dotted.svg @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + + + + + diff --git a/assets/images/nfc.svg b/assets/images/nfc.svg new file mode 100644 index 0000000..aff027e --- /dev/null +++ b/assets/images/nfc.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/assets/images/pdf.svg b/assets/images/pdf.svg new file mode 100644 index 0000000..fc59aea --- /dev/null +++ b/assets/images/pdf.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/assets/images/png.svg b/assets/images/png.svg new file mode 100644 index 0000000..2a0091d --- /dev/null +++ b/assets/images/png.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/assets/images/request_info.svg b/assets/images/request_info.svg new file mode 100644 index 0000000..43ac9c1 --- /dev/null +++ b/assets/images/request_info.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/assets/images/side_nav.svg b/assets/images/side_nav.svg new file mode 100644 index 0000000..a53378f --- /dev/null +++ b/assets/images/side_nav.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/assets/images/skip.svg b/assets/images/skip.svg new file mode 100644 index 0000000..01831e0 --- /dev/null +++ b/assets/images/skip.svg @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/assets/images/stop.svg b/assets/images/stop.svg new file mode 100644 index 0000000..5f658a8 --- /dev/null +++ b/assets/images/stop.svg @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/assets/images/ticket_request.svg b/assets/images/ticket_request.svg new file mode 100644 index 0000000..f489a8e --- /dev/null +++ b/assets/images/ticket_request.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/assets/images/un_fav.svg b/assets/images/un_fav.svg new file mode 100644 index 0000000..de1b852 --- /dev/null +++ b/assets/images/un_fav.svg @@ -0,0 +1,3 @@ + + + diff --git a/assets/images/work_from_home.svg b/assets/images/work_from_home.svg new file mode 100644 index 0000000..cf9a8d7 --- /dev/null +++ b/assets/images/work_from_home.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/assets/images/wufu.svg b/assets/images/wufu.svg new file mode 100644 index 0000000..dd3ebab --- /dev/null +++ b/assets/images/wufu.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/assets/images/xls.svg b/assets/images/xls.svg new file mode 100644 index 0000000..658ba92 --- /dev/null +++ b/assets/images/xls.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/assets/langs/ar-SA.json b/assets/langs/ar-SA.json new file mode 100644 index 0000000..1d9e8bc --- /dev/null +++ b/assets/langs/ar-SA.json @@ -0,0 +1,89 @@ +{ + "mohemm": "Mohemm", + "english": "English", + "arabic": "Arabic", + "login": "تسجيل الدخول", + "pleaseEnterLoginDetails": "الرجاء إدخال التفاصيل أدناه لتسجيل الدخول", + "username": "اسم المستخدم", + "password": "كلمة المرور", + "welcomeBack": "مرحبا بعودتك", + "wouldYouLikeToLoginWithCurrentUsername": "هل ترغب في تسجيل الدخول باسم المستخدم الحالي؟", + "lastLoginDetails": "تفاصيل تسجيل الدخول الأخير:", + "verificationType": "نوع التحقق:", + "pleaseVerify": "ارجوك تحقق", + "verifyThroughFace": "تحقق من خلال الوجه", + "verifyThroughFingerprint": "تحقق من خلال بصمة الإصبع", + "verifyThroughSMS": "تحقق من خلال الرسائل القصيرة", + "verifyThroughWhatsapp": "تحقق من خلال Whatsapp", + "useAnotherAccount": "استخدم حسابا آخر", + "pleaseEnterTheVerificationCodeSentTo": "الرجاء إدخال رمز التحقق المرسل إلى ", + "theVerificationCodeWillExpireIn": "ستنتهي صلاحية رمز التحقق في ", + "goodMorning": "صباح الخير", + "markAttendance": "علامة الحضور", + "timeLeftToday": "الوقت المتبقي اليوم", + "checkIn": "تحقق في", + "workList": "قائمة العمل", + "leaveBalance": "رصيد الاجازات", + "missingSwipes": "الضربات الشديدة في عداد المفقودين", + "ticketBalance": "رصيد التذكرة", + "other": "آخر", + "services": "خدمات", + "viewAllServices": "عرض جميع الخدمات", + "monthlyAttendance": "الحضور الشهري", + "workFromHome": "العمل من المنزل", + "ticketRequest": "طلب تذكرة", + "viewAllOffers": "مشاهدة جميع العروض", + "offers": "عروض & ", + "discounts": "الخصومات", + "newString": "جديد", + "setTheNewPassword": "قم بتعيين كلمة المرور الجديدة", + "typeYourNewPasswordBelow": "اكتب كلمة المرور الجديدة أدناه", + "confirmPassword": "تأكيد كلمة المرور", + "update": "تحديث", + "title": "عنوان", + "home": "مسكن", + "mySalary": "راتبي", + "createRequest": "إنشاء طلب", + "forgotPassword": "هل نسيت كلمة السر", + "employeeId": "هوية الموظف", + "loginCodeWillSentToMobileNumber": "الرجاء إدخال معرف الموظف الخاص بك ، وسيتم إرسال رمز تسجيل الدخول إلى رقم هاتفك المحمول", + "changePassword": "تغيير كلمة المرور", + "itemsForSale": "سلع للبيع", + "msg": "Hello {} in the {} world ", + "msg_named": "{} are written in the {lang} language", + "clickMe": "Click me", + "human": "Human", + "resources": "Resources", + "profile": { + "reset_password": { + "label": "Reset Password", + "username": "Username", + "password": "password" + } + }, + "clicked": { + "zero": "You clicked {} times!", + "one": "You clicked {} time!", + "two": "You clicked {} times!", + "few": "You clicked {} times!", + "many": "You clicked {} times!", + "other": "You clicked {} times!" + }, + "amount": { + "zero": "Your amount : {} ", + "one": "Your amount : {} ", + "two": "Your amount : {} ", + "few": "Your amount : {} ", + "many": "Your amount : {} ", + "other": "Your amount : {} " + }, + "gender": { + "male": "Hi man ;) ", + "female": "Hello girl :)", + "with_arg": { + "male": "Hi man ;) {}", + "female": "Hello girl :) {}" + } + }, + "reset_locale": "Reset Language" +} \ No newline at end of file diff --git a/assets/langs/en-US.json b/assets/langs/en-US.json new file mode 100644 index 0000000..9c812ce --- /dev/null +++ b/assets/langs/en-US.json @@ -0,0 +1,89 @@ +{ + "mohemm": "Mohemm", + "english": "English", + "arabic": "Arabic", + "login": "Login", + "pleaseEnterLoginDetails": "Please enter the detail below to login", + "username": "Username", + "password": "Password", + "welcomeBack": "Welcome back", + "wouldYouLikeToLoginWithCurrentUsername": "Would you like to login with current Username?", + "lastLoginDetails": "Last Login Details:", + "verificationType": "Verification Type:", + "pleaseVerify": "Please Verify", + "verifyThroughFace": "Verify Through Face", + "verifyThroughFingerprint": "Verify Through Fingerprint", + "verifyThroughSMS": "Verify Through SMS", + "verifyThroughWhatsapp": "Verify Through Whatsapp", + "useAnotherAccount": "Use Another Account", + "pleaseEnterTheVerificationCodeSentTo": "Please enter the verification code sent to ", + "theVerificationCodeWillExpireIn": "The verification code will expire in ", + "goodMorning": "Good Morning", + "markAttendance": "Mark Attendance", + "timeLeftToday": "Time Left Today", + "checkIn": "Check In", + "workList": "Work List", + "leaveBalance": "Leave Balance", + "missingSwipes": "Missing Swipes", + "ticketBalance": "Ticket Balance", + "other": "Other", + "services": "Services", + "viewAllServices": "View All Services", + "monthlyAttendance": "Monthly Attendance", + "workFromHome": "Work From Home", + "ticketRequest": "Ticket Request", + "viewAllOffers": "View All Offers", + "offers": "Offers & ", + "discounts": "Discounts", + "newString": "New", + "setTheNewPassword": "Set the new password", + "typeYourNewPasswordBelow": "Type your new password below", + "confirmPassword": "Confirm Password", + "update": "Update", + "title": "Title", + "home": "Home", + "mySalary": "My Salary", + "createRequest": "Create Request", + "forgotPassword": "Forgot Password", + "employeeId": "Employee ID", + "loginCodeWillSentToMobileNumber": "Please Enter your Employee ID, A login code will be sent to your mobile number", + "changePassword": "Change Password", + "itemsForSale": "Items for Sale", + "msg": "Hello {} in the {} world ", + "msg_named": "{} are written in the {lang} language", + "clickMe": "Click me", + "human": "Human", + "resources": "Resources", + "profile": { + "reset_password": { + "label": "Reset Password", + "username": "Username", + "password": "password" + } + }, + "clicked": { + "zero": "You clicked {} times!", + "one": "You clicked {} time!", + "two": "You clicked {} times!", + "few": "You clicked {} times!", + "many": "You clicked {} times!", + "other": "You clicked {} times!" + }, + "amount": { + "zero": "Your amount : {} ", + "one": "Your amount : {} ", + "two": "Your amount : {} ", + "few": "Your amount : {} ", + "many": "Your amount : {} ", + "other": "Your amount : {} " + }, + "gender": { + "male": "Hi man ;) ", + "female": "Hello girl :)", + "with_arg": { + "male": "Hi man ;) {}", + "female": "Hello girl :) {}" + } + }, + "reset_locale": "Reset Language" +} \ No newline at end of file diff --git a/ios/.gitignore b/ios/.gitignore new file mode 100644 index 0000000..151026b --- /dev/null +++ b/ios/.gitignore @@ -0,0 +1,33 @@ +*.mode1v3 +*.mode2v3 +*.moved-aside +*.pbxuser +*.perspectivev3 +**/*sync/ +.sconsign.dblite +.tags* +**/.vagrant/ +**/DerivedData/ +Icon? +**/Pods/ +**/.symlinks/ +profile +xcuserdata +**/.generated/ +Flutter/App.framework +Flutter/Flutter.framework +Flutter/Flutter.podspec +Flutter/Generated.xcconfig +Flutter/ephemeral/ +Flutter/app.flx +Flutter/app.zip +Flutter/flutter_assets/ +Flutter/flutter_export_environment.sh +ServiceDefinitions.json +Runner/GeneratedPluginRegistrant.* + +# Exceptions to above rules. +!default.mode1v3 +!default.mode2v3 +!default.pbxuser +!default.perspectivev3 diff --git a/ios/Flutter/AppFrameworkInfo.plist b/ios/Flutter/AppFrameworkInfo.plist new file mode 100644 index 0000000..8d4492f --- /dev/null +++ b/ios/Flutter/AppFrameworkInfo.plist @@ -0,0 +1,26 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + App + CFBundleIdentifier + io.flutter.flutter.app + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + App + CFBundlePackageType + FMWK + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + 1.0 + MinimumOSVersion + 9.0 + + diff --git a/ios/Flutter/Debug.xcconfig b/ios/Flutter/Debug.xcconfig new file mode 100644 index 0000000..ec97fc6 --- /dev/null +++ b/ios/Flutter/Debug.xcconfig @@ -0,0 +1,2 @@ +#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig" +#include "Generated.xcconfig" diff --git a/ios/Flutter/Release.xcconfig b/ios/Flutter/Release.xcconfig new file mode 100644 index 0000000..c4855bf --- /dev/null +++ b/ios/Flutter/Release.xcconfig @@ -0,0 +1,2 @@ +#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig" +#include "Generated.xcconfig" diff --git a/ios/Runner.xcodeproj/project.pbxproj b/ios/Runner.xcodeproj/project.pbxproj new file mode 100644 index 0000000..7ca764b --- /dev/null +++ b/ios/Runner.xcodeproj/project.pbxproj @@ -0,0 +1,539 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXBuildFile section */ + 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; }; + 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; }; + 6BB994F47479089301AC9232 /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6CBD2B2B1A504A0E0BA52E83 /* Pods_Runner.framework */; }; + 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; }; + 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; }; + 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; }; + 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; }; +/* End PBXBuildFile section */ + +/* Begin PBXCopyFilesBuildPhase section */ + 9705A1C41CF9048500538489 /* Embed Frameworks */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + ); + name = "Embed Frameworks"; + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXCopyFilesBuildPhase section */ + +/* Begin PBXFileReference section */ + 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = ""; }; + 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = ""; }; + 3085328F552329DC897B71DD /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = ""; }; + 3A5ABA8306DCFDB9E71D453A /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = ""; }; + 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; }; + 3B4D9CAD3B112CCF7FEE1F91 /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = ""; }; + 6CBD2B2B1A504A0E0BA52E83 /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = ""; }; + 74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; + 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; }; + 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = ""; }; + 9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = ""; }; + 97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; + 97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + 97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; + 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 97C146EB1CF9000F007C117D /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 6BB994F47479089301AC9232 /* Pods_Runner.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 6BD33033650F08D3E79761E4 /* Frameworks */ = { + isa = PBXGroup; + children = ( + 6CBD2B2B1A504A0E0BA52E83 /* Pods_Runner.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; + 969F82F1FCE09135D9CB4C64 /* Pods */ = { + isa = PBXGroup; + children = ( + 3085328F552329DC897B71DD /* Pods-Runner.debug.xcconfig */, + 3B4D9CAD3B112CCF7FEE1F91 /* Pods-Runner.release.xcconfig */, + 3A5ABA8306DCFDB9E71D453A /* Pods-Runner.profile.xcconfig */, + ); + name = Pods; + path = Pods; + sourceTree = ""; + }; + 9740EEB11CF90186004384FC /* Flutter */ = { + isa = PBXGroup; + children = ( + 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */, + 9740EEB21CF90195004384FC /* Debug.xcconfig */, + 7AFA3C8E1D35360C0083082E /* Release.xcconfig */, + 9740EEB31CF90195004384FC /* Generated.xcconfig */, + ); + name = Flutter; + sourceTree = ""; + }; + 97C146E51CF9000F007C117D = { + isa = PBXGroup; + children = ( + 9740EEB11CF90186004384FC /* Flutter */, + 97C146F01CF9000F007C117D /* Runner */, + 97C146EF1CF9000F007C117D /* Products */, + 969F82F1FCE09135D9CB4C64 /* Pods */, + 6BD33033650F08D3E79761E4 /* Frameworks */, + ); + sourceTree = ""; + }; + 97C146EF1CF9000F007C117D /* Products */ = { + isa = PBXGroup; + children = ( + 97C146EE1CF9000F007C117D /* Runner.app */, + ); + name = Products; + sourceTree = ""; + }; + 97C146F01CF9000F007C117D /* Runner */ = { + isa = PBXGroup; + children = ( + 97C146FA1CF9000F007C117D /* Main.storyboard */, + 97C146FD1CF9000F007C117D /* Assets.xcassets */, + 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */, + 97C147021CF9000F007C117D /* Info.plist */, + 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */, + 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */, + 74858FAE1ED2DC5600515810 /* AppDelegate.swift */, + 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */, + ); + path = Runner; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 97C146ED1CF9000F007C117D /* Runner */ = { + isa = PBXNativeTarget; + buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */; + buildPhases = ( + 7D19CFF3DFB977EA83F4C733 /* [CP] Check Pods Manifest.lock */, + 9740EEB61CF901F6004384FC /* Run Script */, + 97C146EA1CF9000F007C117D /* Sources */, + 97C146EB1CF9000F007C117D /* Frameworks */, + 97C146EC1CF9000F007C117D /* Resources */, + 9705A1C41CF9048500538489 /* Embed Frameworks */, + 3B06AD1E1E4923F5004D2608 /* Thin Binary */, + AAF25E5FC427CABFCDCC628C /* [CP] Embed Pods Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = Runner; + productName = Runner; + productReference = 97C146EE1CF9000F007C117D /* Runner.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 97C146E61CF9000F007C117D /* Project object */ = { + isa = PBXProject; + attributes = { + LastUpgradeCheck = 1020; + ORGANIZATIONNAME = ""; + TargetAttributes = { + 97C146ED1CF9000F007C117D = { + CreatedOnToolsVersion = 7.3.1; + LastSwiftMigration = 1100; + }; + }; + }; + buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */; + compatibilityVersion = "Xcode 9.3"; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 97C146E51CF9000F007C117D; + productRefGroup = 97C146EF1CF9000F007C117D /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 97C146ED1CF9000F007C117D /* Runner */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 97C146EC1CF9000F007C117D /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */, + 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */, + 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */, + 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXShellScriptBuildPhase section */ + 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "Thin Binary"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin"; + }; + 7D19CFF3DFB977EA83F4C733 /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; + outputFileListPaths = ( + ); + outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-Runner-checkManifestLockResult.txt", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; + showEnvVarsInLog = 0; + }; + 9740EEB61CF901F6004384FC /* Run Script */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "Run Script"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build"; + }; + AAF25E5FC427CABFCDCC628C /* [CP] Embed Pods Frameworks */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-input-files.xcfilelist", + ); + name = "[CP] Embed Pods Frameworks"; + outputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-output-files.xcfilelist", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n"; + showEnvVarsInLog = 0; + }; +/* End PBXShellScriptBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 97C146EA1CF9000F007C117D /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */, + 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + 97C146FA1CF9000F007C117D /* Main.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 97C146FB1CF9000F007C117D /* Base */, + ); + name = Main.storyboard; + sourceTree = ""; + }; + 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 97C147001CF9000F007C117D /* Base */, + ); + name = LaunchScreen.storyboard; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 249021D3217E4FDB00AE95B9 /* Profile */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 9.0; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = iphoneos; + SUPPORTED_PLATFORMS = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + }; + name = Profile; + }; + 249021D4217E4FDB00AE95B9 /* Profile */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ENABLE_MODULES = YES; + CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + ENABLE_BITCODE = NO; + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = com.mohemFlutterApp; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; + SWIFT_VERSION = 5.0; + VERSIONING_SYSTEM = "apple-generic"; + }; + name = Profile; + }; + 97C147031CF9000F007C117D /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 9.0; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 97C147041CF9000F007C117D /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 9.0; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = iphoneos; + SUPPORTED_PLATFORMS = iphoneos; + SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 97C147061CF9000F007C117D /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ENABLE_MODULES = YES; + CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + ENABLE_BITCODE = NO; + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = com.mohemFlutterApp; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 5.0; + VERSIONING_SYSTEM = "apple-generic"; + }; + name = Debug; + }; + 97C147071CF9000F007C117D /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ENABLE_MODULES = YES; + CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + ENABLE_BITCODE = NO; + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = com.mohemFlutterApp; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; + SWIFT_VERSION = 5.0; + VERSIONING_SYSTEM = "apple-generic"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 97C147031CF9000F007C117D /* Debug */, + 97C147041CF9000F007C117D /* Release */, + 249021D3217E4FDB00AE95B9 /* Profile */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 97C147061CF9000F007C117D /* Debug */, + 97C147071CF9000F007C117D /* Release */, + 249021D4217E4FDB00AE95B9 /* Profile */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 97C146E61CF9000F007C117D /* Project object */; +} diff --git a/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000..919434a --- /dev/null +++ b/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 0000000..18d9810 --- /dev/null +++ b/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings b/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings new file mode 100644 index 0000000..f9b0d7c --- /dev/null +++ b/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings @@ -0,0 +1,8 @@ + + + + + PreviewsEnabled + + + diff --git a/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme new file mode 100644 index 0000000..a28140c --- /dev/null +++ b/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme @@ -0,0 +1,91 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/ios/Runner.xcworkspace/contents.xcworkspacedata b/ios/Runner.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000..21a3cc1 --- /dev/null +++ b/ios/Runner.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,10 @@ + + + + + + + diff --git a/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 0000000..18d9810 --- /dev/null +++ b/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings b/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings new file mode 100644 index 0000000..f9b0d7c --- /dev/null +++ b/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings @@ -0,0 +1,8 @@ + + + + + PreviewsEnabled + + + diff --git a/ios/Runner/AppDelegate.swift b/ios/Runner/AppDelegate.swift new file mode 100644 index 0000000..70693e4 --- /dev/null +++ b/ios/Runner/AppDelegate.swift @@ -0,0 +1,13 @@ +import UIKit +import Flutter + +@UIApplicationMain +@objc class AppDelegate: FlutterAppDelegate { + override func application( + _ application: UIApplication, + didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? + ) -> Bool { + GeneratedPluginRegistrant.register(with: self) + return super.application(application, didFinishLaunchingWithOptions: launchOptions) + } +} diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..d36b1fa --- /dev/null +++ b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,122 @@ +{ + "images" : [ + { + "size" : "20x20", + "idiom" : "iphone", + "filename" : "Icon-App-20x20@2x.png", + "scale" : "2x" + }, + { + "size" : "20x20", + "idiom" : "iphone", + "filename" : "Icon-App-20x20@3x.png", + "scale" : "3x" + }, + { + "size" : "29x29", + "idiom" : "iphone", + "filename" : "Icon-App-29x29@1x.png", + "scale" : "1x" + }, + { + "size" : "29x29", + "idiom" : "iphone", + "filename" : "Icon-App-29x29@2x.png", + "scale" : "2x" + }, + { + "size" : "29x29", + "idiom" : "iphone", + "filename" : "Icon-App-29x29@3x.png", + "scale" : "3x" + }, + { + "size" : "40x40", + "idiom" : "iphone", + "filename" : "Icon-App-40x40@2x.png", + "scale" : "2x" + }, + { + "size" : "40x40", + "idiom" : "iphone", + "filename" : "Icon-App-40x40@3x.png", + "scale" : "3x" + }, + { + "size" : "60x60", + "idiom" : "iphone", + "filename" : "Icon-App-60x60@2x.png", + "scale" : "2x" + }, + { + "size" : "60x60", + "idiom" : "iphone", + "filename" : "Icon-App-60x60@3x.png", + "scale" : "3x" + }, + { + "size" : "20x20", + "idiom" : "ipad", + "filename" : "Icon-App-20x20@1x.png", + "scale" : "1x" + }, + { + "size" : "20x20", + "idiom" : "ipad", + "filename" : "Icon-App-20x20@2x.png", + "scale" : "2x" + }, + { + "size" : "29x29", + "idiom" : "ipad", + "filename" : "Icon-App-29x29@1x.png", + "scale" : "1x" + }, + { + "size" : "29x29", + "idiom" : "ipad", + "filename" : "Icon-App-29x29@2x.png", + "scale" : "2x" + }, + { + "size" : "40x40", + "idiom" : "ipad", + "filename" : "Icon-App-40x40@1x.png", + "scale" : "1x" + }, + { + "size" : "40x40", + "idiom" : "ipad", + "filename" : "Icon-App-40x40@2x.png", + "scale" : "2x" + }, + { + "size" : "76x76", + "idiom" : "ipad", + "filename" : "Icon-App-76x76@1x.png", + "scale" : "1x" + }, + { + "size" : "76x76", + "idiom" : "ipad", + "filename" : "Icon-App-76x76@2x.png", + "scale" : "2x" + }, + { + "size" : "83.5x83.5", + "idiom" : "ipad", + "filename" : "Icon-App-83.5x83.5@2x.png", + "scale" : "2x" + }, + { + "size" : "1024x1024", + "idiom" : "ios-marketing", + "filename" : "Icon-App-1024x1024@1x.png", + "scale" : "1x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png new file mode 100644 index 0000000..dc9ada4 Binary files /dev/null and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png new file mode 100644 index 0000000..28c6bf0 Binary files /dev/null and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png new file mode 100644 index 0000000..2ccbfd9 Binary files /dev/null and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png new file mode 100644 index 0000000..f091b6b Binary files /dev/null and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png new file mode 100644 index 0000000..4cde121 Binary files /dev/null and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png new file mode 100644 index 0000000..d0ef06e Binary files /dev/null and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png new file mode 100644 index 0000000..dcdc230 Binary files /dev/null and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png new file mode 100644 index 0000000..2ccbfd9 Binary files /dev/null and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png new file mode 100644 index 0000000..c8f9ed8 Binary files /dev/null and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png new file mode 100644 index 0000000..a6d6b86 Binary files /dev/null and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png new file mode 100644 index 0000000..a6d6b86 Binary files /dev/null and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png new file mode 100644 index 0000000..75b2d16 Binary files /dev/null and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png new file mode 100644 index 0000000..c4df70d Binary files /dev/null and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png new file mode 100644 index 0000000..6a84f41 Binary files /dev/null and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png new file mode 100644 index 0000000..d0e1f58 Binary files /dev/null and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png differ diff --git a/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json b/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json new file mode 100644 index 0000000..0bedcf2 --- /dev/null +++ b/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "LaunchImage.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "LaunchImage@2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "LaunchImage@3x.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} diff --git a/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png b/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png new file mode 100644 index 0000000..9da19ea Binary files /dev/null and b/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png differ diff --git a/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png b/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png new file mode 100644 index 0000000..9da19ea Binary files /dev/null and b/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png differ diff --git a/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png b/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png new file mode 100644 index 0000000..9da19ea Binary files /dev/null and b/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png differ diff --git a/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md b/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md new file mode 100644 index 0000000..89c2725 --- /dev/null +++ b/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md @@ -0,0 +1,5 @@ +# Launch Screen Assets + +You can customize the launch screen with your own desired assets by replacing the image files in this directory. + +You can also do it by opening your Flutter project's Xcode project with `open ios/Runner.xcworkspace`, selecting `Runner/Assets.xcassets` in the Project Navigator and dropping in the desired images. \ No newline at end of file diff --git a/ios/Runner/Base.lproj/LaunchScreen.storyboard b/ios/Runner/Base.lproj/LaunchScreen.storyboard new file mode 100644 index 0000000..f2e259c --- /dev/null +++ b/ios/Runner/Base.lproj/LaunchScreen.storyboard @@ -0,0 +1,37 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/ios/Runner/Base.lproj/Main.storyboard b/ios/Runner/Base.lproj/Main.storyboard new file mode 100644 index 0000000..f3c2851 --- /dev/null +++ b/ios/Runner/Base.lproj/Main.storyboard @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/ios/Runner/Info.plist b/ios/Runner/Info.plist new file mode 100644 index 0000000..bf06aab --- /dev/null +++ b/ios/Runner/Info.plist @@ -0,0 +1,45 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + mohem_flutter_app + CFBundlePackageType + APPL + CFBundleShortVersionString + $(FLUTTER_BUILD_NAME) + CFBundleSignature + ???? + CFBundleVersion + $(FLUTTER_BUILD_NUMBER) + LSRequiresIPhoneOS + + UILaunchStoryboardName + LaunchScreen + UIMainStoryboardFile + Main + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UIViewControllerBasedStatusBarAppearance + + + diff --git a/ios/Runner/Runner-Bridging-Header.h b/ios/Runner/Runner-Bridging-Header.h new file mode 100644 index 0000000..308a2a5 --- /dev/null +++ b/ios/Runner/Runner-Bridging-Header.h @@ -0,0 +1 @@ +#import "GeneratedPluginRegistrant.h" diff --git a/lib/api/api_client.dart b/lib/api/api_client.dart new file mode 100644 index 0000000..a08ed01 --- /dev/null +++ b/lib/api/api_client.dart @@ -0,0 +1,176 @@ +import 'dart:async'; +import 'dart:convert'; +import 'dart:io'; + +import 'package:flutter/foundation.dart'; +import 'package:http/http.dart'; +import 'package:http/io_client.dart'; +import 'package:mohem_flutter_app/exceptions/api_exception.dart'; + +typedef FactoryConstructor = U Function(dynamic); + +class APIError { + int? errorCode; + String? errorMessage; + + APIError(this.errorCode, this.errorMessage); + + Map toJson() => {'errorCode': errorCode, 'errorMessage': errorMessage}; + + @override + String toString() { + return jsonEncode(this); + } +} + +APIException _throwAPIException(Response response) { + switch (response.statusCode) { + case 200: + APIError? apiError; + if (response.body != null && response.body.isNotEmpty) { + var jsonError = jsonDecode(response.body); + print(jsonError); + apiError = APIError(jsonError['ErrorCode'], jsonError['ErrorMessage']); + } + return APIException(APIException.BAD_REQUEST, error: apiError); + case 400: + APIError? apiError; + if (response.body != null && response.body.isNotEmpty) { + var jsonError = jsonDecode(response.body); + apiError = APIError(jsonError['ErrorCode'], jsonError['ErrorMessage']); + } + return APIException(APIException.BAD_REQUEST, error: apiError); + case 401: + return APIException(APIException.UNAUTHORIZED); + case 403: + return APIException(APIException.FORBIDDEN); + case 404: + return APIException(APIException.NOT_FOUND); + case 500: + return APIException(APIException.INTERNAL_SERVER_ERROR); + case 444: + var downloadUrl = response.headers["location"]; + return APIException(APIException.UPGRADE_REQUIRED, arguments: downloadUrl); + default: + return APIException(APIException.OTHER); + } +} + +class ApiClient { + static final ApiClient _instance = ApiClient._internal(); + + ApiClient._internal(); + + factory ApiClient() => _instance; + + Future postJsonForObject(FactoryConstructor factoryConstructor, String url, T jsonObject, + {String? token, Map? queryParameters, Map? headers, int retryTimes = 0}) async { + var _headers = {'Accept': 'application/json'}; + if (headers != null && headers.isNotEmpty) { + _headers.addAll(headers); + } + if (!kReleaseMode) { + print("Url:$url"); + print("body:$jsonObject"); + } + var response = await postJsonForResponse(url, jsonObject, token: token, queryParameters: queryParameters, headers: _headers, retryTimes: retryTimes); + try { + if (!kReleaseMode) { + print("res: " + response.body); + } + var jsonData = jsonDecode(response.body); + if (jsonData["ErrorMessage"] == null) { + return factoryConstructor(jsonData); + } else { + APIError? apiError; + apiError = APIError(jsonData['ErrorCode'], jsonData['ErrorMessage']); + throw APIException(APIException.BAD_REQUEST, error: apiError); + } + } catch (ex) { + if (ex is APIException) { + rethrow; + } else { + throw APIException(APIException.BAD_RESPONSE_FORMAT, arguments: ex); + } + } + } + + Future postJsonForResponse(String url, T jsonObject, {String? token, Map? queryParameters, Map? headers, int retryTimes = 0}) async { + String? requestBody; + if (jsonObject != null) { + requestBody = jsonEncode(jsonObject); + if (headers == null) { + headers = {'Content-Type': 'application/json'}; + } else { + headers['Content-Type'] = 'application/json'; + } + } + + return await _postForResponse(url, requestBody, token: token, queryParameters: queryParameters, headers: headers, retryTimes: retryTimes); + } + + Future _postForResponse(String url, requestBody, {String? token, Map? queryParameters, Map? headers, int retryTimes = 0}) async { + try { + var _headers = {}; + if (token != null) { + _headers['Authorization'] = 'Bearer $token'; + } + + if (headers != null && headers.isNotEmpty) { + _headers.addAll(headers); + } + + if (queryParameters != null) { + var queryString = new Uri(queryParameters: queryParameters).query; + url = url + '?' + queryString; + } + var response = await _post(Uri.parse(url), body: requestBody, headers: _headers).timeout(Duration(seconds: 60)); + + if (response.statusCode >= 200 && response.statusCode < 300) { + return response; + } else { + throw _throwAPIException(response); + } + } on SocketException catch (e) { + if (retryTimes > 0) { + print('will retry after 3 seconds...'); + await Future.delayed(Duration(seconds: 3)); + return await _postForResponse(url, requestBody, token: token, queryParameters: queryParameters, headers: headers, retryTimes: retryTimes - 1); + } else { + throw APIException(APIException.OTHER, arguments: e); + } + } on HttpException catch (e) { + if (retryTimes > 0) { + print('will retry after 3 seconds...'); + await Future.delayed(Duration(seconds: 3)); + return await _postForResponse(url, requestBody, token: token, queryParameters: queryParameters, headers: headers, retryTimes: retryTimes - 1); + } else { + throw APIException(APIException.OTHER, arguments: e); + } + } on TimeoutException catch (e) { + throw APIException(APIException.TIMEOUT, arguments: e); + } on ClientException catch (e) { + if (retryTimes > 0) { + print('will retry after 3 seconds...'); + await Future.delayed(Duration(seconds: 3)); + return await _postForResponse(url, requestBody, token: token, queryParameters: queryParameters, headers: headers, retryTimes: retryTimes - 1); + } else { + throw APIException(APIException.OTHER, arguments: e); + } + } + } + + bool _certificateCheck(X509Certificate cert, String host, int port) => true; + + Future _withClient(Future Function(Client) fn) async { + var httpClient = HttpClient()..badCertificateCallback = _certificateCheck; + var client = IOClient(httpClient); + try { + return await fn(client); + } finally { + client.close(); + } + } + + Future _post(url, {Map? headers, body, Encoding? encoding}) => _withClient((client) => client.post(url, headers: headers, body: body, encoding: encoding)); +} diff --git a/lib/api/dashboard_api_client.dart b/lib/api/dashboard_api_client.dart new file mode 100644 index 0000000..5b6f961 --- /dev/null +++ b/lib/api/dashboard_api_client.dart @@ -0,0 +1,69 @@ +import 'dart:async'; + +import 'package:mohem_flutter_app/app_state/app_state.dart'; +import 'package:mohem_flutter_app/classes/consts.dart'; +import 'package:mohem_flutter_app/models/basic_member_information_model.dart'; +import 'package:mohem_flutter_app/models/check_mobile_app_version_model.dart'; +import 'package:mohem_flutter_app/models/dashboard/itg_forms_model.dart'; +import 'package:mohem_flutter_app/models/generic_response_model.dart'; +import 'package:mohem_flutter_app/models/member_login_list_model.dart'; + +import 'api_client.dart'; + +class DashbaordApiClient { + static final DashbaordApiClient _instance = DashbaordApiClient._internal(); + + DashbaordApiClient._internal(); + + factory DashbaordApiClient() => _instance; + + Future getAttendanceTracking() async { + String url = "${ApiConsts.erpRest}GET_Attendance_Tracking"; + Map postParams = {}; + postParams.addAll(AppState().postParamsJson); + return await ApiClient().postJsonForObject((json) { + GenericResponseModel responseData = GenericResponseModel.fromJson(json); + return responseData; + }, url, postParams); + } + + Future getOpenNotifications() async { + String url = "${ApiConsts.erpRest}GET_OPEN_NOTIFICATIONS"; + Map postParams = {}; + postParams.addAll(AppState().postParamsJson); + return await ApiClient().postJsonForObject((json) { + GenericResponseModel responseData = GenericResponseModel.fromJson(json); + return responseData; + }, url, postParams); + } + + Future getItgFormsPendingTask() async { + String url = "${ApiConsts.cocRest}ITGFormsPendingTasks"; + Map postParams = {}; + postParams.addAll(AppState().postParamsJson); + return await ApiClient().postJsonForObject((json) { + ItgFormsModel responseData = ItgFormsModel.fromJson(json); + return responseData; + }, url, postParams); + } + + Future getAccrualBalances() async { + String url = "${ApiConsts.erpRest}GET_ACCRUAL_BALANCES"; + Map postParams = {"P_EFFECTIVE_DATE": "1/30/2022"}; + postParams.addAll(AppState().postParamsJson); + return await ApiClient().postJsonForObject((json) { + GenericResponseModel responseData = GenericResponseModel.fromJson(json); + return responseData; + }, url, postParams); + } + + Future getOpenMissingSwipes() async { + String url = "${ApiConsts.erpRest}GET_OPEN_MISSING_SWIPES"; + Map postParams = {}; + postParams.addAll(AppState().postParamsJson); + return await ApiClient().postJsonForObject((json) { + GenericResponseModel responseData = GenericResponseModel.fromJson(json); + return responseData; + }, url, postParams); + } +} diff --git a/lib/api/login_api_client.dart b/lib/api/login_api_client.dart new file mode 100644 index 0000000..fb6bb80 --- /dev/null +++ b/lib/api/login_api_client.dart @@ -0,0 +1,101 @@ +import 'dart:async'; + +import 'package:mohem_flutter_app/app_state/app_state.dart'; +import 'package:mohem_flutter_app/classes/consts.dart'; +import 'package:mohem_flutter_app/models/basic_member_information_model.dart'; +import 'package:mohem_flutter_app/models/check_mobile_app_version_model.dart'; +import 'package:mohem_flutter_app/models/generic_response_model.dart'; +import 'package:mohem_flutter_app/models/member_login_list_model.dart'; + +import 'api_client.dart'; + +class LoginApiClient { + static final LoginApiClient _instance = LoginApiClient._internal(); + + LoginApiClient._internal(); + + factory LoginApiClient() => _instance; + + Future checkMobileAppVersion() async { + String url = "${ApiConsts.utilitiesRest}CheckMobileAppVersion"; + Map postParams = {}; + postParams.addAll(AppState().postParamsJson); + return await ApiClient().postJsonForObject((json) => CheckMobileAppVersionModel.fromJson(json), url, postParams); + } + + Future memberLogin(String username, String password) async { + String url = "${ApiConsts.erpRest}MemberLogin"; + Map postParams = {"P_APP_VERSION": "CS", "P_LANGUAGE": "US", "P_PASSWORD": password, "P_USER_NAME": username}; + postParams.addAll(AppState().postParamsJson); + return await ApiClient().postJsonForObject((json) { + GenericResponseModel responseData = GenericResponseModel.fromJson(json); + AppState().postParamsObject?.setLogInTokenID = responseData.logInTokenID; + return responseData.memberLoginList; + }, url, postParams); + } + + Future mohemmSendActivationCodeByOTPNotificationType(int isMobileFingerPrint, String? mobileNumber, int optSendType, String? pUserName) async { + String url = "${ApiConsts.erpRest}Mohemm_SendActivationCodebyOTPNotificationType"; + Map postParams = {"IsMobileFingerPrint": isMobileFingerPrint, "MobileNumber": mobileNumber, "OTP_SendType": optSendType, "P_USER_NAME": pUserName}; + postParams.addAll(AppState().postParamsJson); + return await ApiClient().postJsonForObject((json) => GenericResponseModel.fromJson(json).basicMemberInformation, url, postParams); + } + + Future checkActivationCode(bool isDeviceNFC, String? mobileNumber, String activationCode, String? pUserName) async { + String url = "${ApiConsts.erpRest}CheckActivationCode"; + Map postParams = {"isDeviceNFC": isDeviceNFC, "MobileNumber": mobileNumber, "activationCode": activationCode, "P_USER_NAME": pUserName}; + postParams.addAll(AppState().postParamsJson); + return await ApiClient().postJsonForObject((json) { + GenericResponseModel responseData = GenericResponseModel.fromJson(json); + AppState().setLogged = true; + AppState().postParamsObject?.setTokenID = responseData.tokenID; + AppState().postParamsObject?.mobileNumber = responseData.basicMemberInformation!.pMOBILENUMBER; + AppState().postParamsObject?.userName = AppState().getUserName; + AppState().postParamsObject?.pEmailAddress = responseData.basicMemberInformation!.pEMAILADDRESS; + AppState().postParamsObject?.pSessionId = responseData.pSESSIONID; + AppState().postParamsObject?.pUserName = AppState().getUserName; + AppState().postParamsObject?.pSelectedEmployeeNumber = AppState().getUserName; + return responseData; + }, url, postParams); + } + + Future getBasicUserInformation(String pAppVersion, String pUsername) async { + String url = "${ApiConsts.erpRest}Get_BasicUserInformation"; + Map postParams = {"P_APP_VERSION": pAppVersion, "P_USER_NAME": pUsername}; + postParams.addAll(AppState().postParamsJson); + return await ApiClient().postJsonForObject((json) => GenericResponseModel.fromJson(json).basicMemberInformation, url, postParams); + } + + Future sendPublicActivationCode(String? mobileNumber, String? pUsername) async { + String url = "${ApiConsts.erpRest}SendPublicActivationCode"; + Map postParams = {"MobileNumber": mobileNumber, "P_MOBILE_NUMBER": mobileNumber, "P_USER_NAME": pUsername}; + postParams.addAll(AppState().postParamsJson); + return await ApiClient().postJsonForObject((json) { + GenericResponseModel responseData = GenericResponseModel.fromJson(json); + AppState().postParamsObject?.setLogInTokenID = responseData.logInTokenID; + return responseData; + }, url, postParams); + } + + Future checkPublicActivationCode(String activationCode, String? pUserName) async { + String url = "${ApiConsts.erpRest}checkPublicActivationCode"; + Map postParams = {"activationCode": activationCode, "P_USER_NAME": pUserName}; + postParams.addAll(AppState().postParamsJson); + return await ApiClient().postJsonForObject((json) { + GenericResponseModel responseData = GenericResponseModel.fromJson(json); + AppState().setForgetPasswordTokenID = responseData.tokenID; + return responseData; + }, url, postParams); + } + + Future changePasswordForget(String forgetPasswordTokenID, String pNewPassword, String pConfirmNewPassword, String? pUserName) async { + String url = "${ApiConsts.erpRest}ChangePassword_Forget"; + Map postParams = {"P_USER_NAME": pUserName, "ForgetPasswordTokenID": forgetPasswordTokenID, "P_Confirm_NEW_PASSWORD": pConfirmNewPassword, "P_NEW_PASSWORD": pNewPassword}; + postParams.addAll(AppState().postParamsJson); + return await ApiClient().postJsonForObject((json) { + GenericResponseModel responseData = GenericResponseModel.fromJson(json); + + return responseData; + }, url, postParams); + } +} diff --git a/lib/api/tangheem_user_api_client.dart b/lib/api/tangheem_user_api_client.dart new file mode 100644 index 0000000..32a5a82 --- /dev/null +++ b/lib/api/tangheem_user_api_client.dart @@ -0,0 +1,34 @@ +import 'dart:async'; + +import 'package:mohem_flutter_app/classes/consts.dart'; +import 'package:mohem_flutter_app/models/content_info_model.dart'; +import 'package:mohem_flutter_app/models/member_login_list_model.dart'; +import 'package:mohem_flutter_app/models/surah_model.dart'; + +import 'api_client.dart'; + +class TangheemUserApiClient { + static final TangheemUserApiClient _instance = TangheemUserApiClient._internal(); + + TangheemUserApiClient._internal(); + + factory TangheemUserApiClient() => _instance; + + // Future getSurahs() async { + // String url = "${ApiConsts.tangheemUsers}AlSuar_Get"; + // var postParams = {}; + // return await ApiClient().postJsonForObject((json) => SurahModel.fromJson(json), url, postParams); + // } + // + // Future getMembers() async { + // String url = "${ApiConsts.tangheemUsers}Committee_Get"; + // var postParams = {}; + // return await ApiClient().postJsonForObject((json) => MemberModel.fromJson(json), url, postParams); + // } + // + // Future getContentInfo(int contentId) async { + // String url = "${ApiConsts.tangheemUsers}ContentInfo_Get"; + // var postParams = {"contentTypeId": contentId}; + // return await ApiClient().postJsonForObject((json) => ContentInfoModel.fromJson(json), url, postParams); + // } +} diff --git a/lib/app_state/app_state.dart b/lib/app_state/app_state.dart new file mode 100644 index 0000000..65d5184 --- /dev/null +++ b/lib/app_state/app_state.dart @@ -0,0 +1,44 @@ +import 'package:mohem_flutter_app/models/member_login_list_model.dart'; +import 'package:mohem_flutter_app/models/post_params_model.dart'; + +class AppState { + static final AppState _instance = AppState._internal(); + + AppState._internal(); + + factory AppState() => _instance; + + bool isLogged = false; + + set setLogged(v) => isLogged = v; + + bool? get getIsLogged => isLogged; + + String? forgetPasswordTokenID; + + set setForgetPasswordTokenID(token) => forgetPasswordTokenID = token; + + String? get getForgetPasswordTokenID => forgetPasswordTokenID; + + PostParamsModel? _postParams; + + PostParamsModel? get postParamsObject => _postParams; + + Map get postParamsJson => isLogged ? (_postParams?.toJsonAfterLogin() ?? {}) : (_postParams?.toJson() ?? {}); + + void setPostParamsModel(PostParamsModel _postParams) { + this._postParams = _postParams; + } + + String? _username; + + set setUserName(v) => _username = v; + + String? get getUserName => _username; + + MemberLoginListModel? _memberLoginList; + + MemberLoginListModel? get memberLoginList => _memberLoginList; + + set setMemberLoginListModel(MemberLoginListModel? _memberLoginList) => this._memberLoginList = _memberLoginList; +} diff --git a/lib/classes/colors.dart b/lib/classes/colors.dart new file mode 100644 index 0000000..2e5eaef --- /dev/null +++ b/lib/classes/colors.dart @@ -0,0 +1,28 @@ +import 'package:flutter/cupertino.dart'; + +class MyColors { + static const Color darkIconColor = Color(0xff28323A); + static const Color darkTextColor = Color(0xff2B353E); + static const Color normalTextColor = Color(0xff5A5A5A); + static const Color lightTextColor = Color(0xffBFBFBF); + static const Color gradiantStartColor = Color(0xff33c0a5); + static const Color gradiantEndColor = Color(0xff259db7 ); + static const Color textMixColor = Color(0xff2BB8A6); + static const Color backgroundColor = Color(0xffF8F8F8); + static const Color grey57Color = Color(0xff575757); + static const Color grey77Color = Color(0xff777777); + static const Color grey70Color = Color(0xff707070); + static const Color greyACColor = Color(0xffACACAC); + static const Color grey98Color = Color(0xff989898); + static const Color lightGreyEFColor = Color(0xffEFEFEF); + static const Color lightGreyEDColor = Color(0xffEDEDED); + static const Color lightGreyEAColor = Color(0xffEAEAEA); + static const Color darkWhiteColor = Color(0xffE0E0E0); + static const Color redColor = Color(0xffD02127); + static const Color yellowColor = Color(0xffF4E31C); + static const Color backgroundBlackColor = Color(0xff202529); + static const Color black = Color(0xff000000); + static const Color white = Color(0xffffffff); + static const Color green = Color(0xffffffff); + static const Color borderColor = Color(0xffE8E8E8); +} diff --git a/lib/classes/consts.dart b/lib/classes/consts.dart new file mode 100644 index 0000000..4bad83c --- /dev/null +++ b/lib/classes/consts.dart @@ -0,0 +1,22 @@ +class ApiConsts { + //static String baseUrl = "http://10.200.204.20:2801/"; // Local server + static String baseUrl = "https://uat.hmgwebservices.com"; // UAT server + static String baseUrlServices = baseUrl + "/services/"; // server + // static String baseUrlServices = "https://api.cssynapses.com/tangheem/"; // Live server + static String utilitiesRest = baseUrlServices + "Utilities.svc/REST/"; + static String erpRest = baseUrlServices + "ERP.svc/REST/"; + static String user = baseUrlServices + "api/User/"; + static String cocRest = baseUrlServices + "COCWS.svc/REST/"; +} + + + +class GlobalConsts { + static String isRememberMe = "remember_me"; + static String email = "email"; + static String password = "password"; + static String bookmark = "bookmark"; + static String fontZoomSize = "font_zoom_size"; + static String welcomeVideoUrl = "welcomeVideoUrl"; + static String doNotShowWelcomeVideo = "doNotShowWelcomeVideo"; +} diff --git a/lib/classes/utils.dart b/lib/classes/utils.dart new file mode 100644 index 0000000..d80fdf5 --- /dev/null +++ b/lib/classes/utils.dart @@ -0,0 +1,72 @@ +import 'package:flutter/material.dart'; +import 'package:fluttertoast/fluttertoast.dart'; + +// import 'package:fluttertoast/fluttertoast.dart'; +import 'package:mohem_flutter_app/exceptions/api_exception.dart'; +import 'package:mohem_flutter_app/widgets/loading_dialog.dart'; + +class Utils { + static bool _isLoadingVisible = false; + + static bool get isLoading => _isLoadingVisible; + + static void showToast(String message) { + Fluttertoast.showToast( + msg: message, toastLength: Toast.LENGTH_SHORT, gravity: ToastGravity.BOTTOM, timeInSecForIosWeb: 1, backgroundColor: Colors.black54, textColor: Colors.white, fontSize: 16.0); + } + + static dynamic getNotNullValue(List list, int index) { + try { + return list[index]; + } catch (ex) { + return null; + } + } + + static int stringToHex(String colorCode) { + try { + return int.parse(colorCode.replaceAll("#", "0xff")); + } catch (ex) { + return (0xff000000); + } + } + + static void showLoading(BuildContext context) { + WidgetsBinding.instance?.addPostFrameCallback((_) { + _isLoadingVisible = true; + showDialog( + context: context, + barrierColor: Colors.black.withOpacity(0.5), + builder: (BuildContext context) => LoadingDialog(), + ).then((value) { + _isLoadingVisible = false; + }); + }); + } + + static void hideLoading(BuildContext context) { + if (_isLoadingVisible) { + _isLoadingVisible = false; + Navigator.of(context).pop(); + } + _isLoadingVisible = false; + } + + static void handleException(dynamic exception, Function(String)? onErrorMessage) { + String errorMessage; + if (exception is APIException) { + if (exception.message == APIException.UNAUTHORIZED) { + return; + } else { + errorMessage = exception.error?.errorMessage ?? exception.message; + } + } else { + errorMessage = APIException.UNKNOWN; + } + if (onErrorMessage != null) { + onErrorMessage(errorMessage); + } else { + showToast(errorMessage); + } + } +} diff --git a/lib/config/app_provider.dart b/lib/config/app_provider.dart new file mode 100644 index 0000000..9ccf065 --- /dev/null +++ b/lib/config/app_provider.dart @@ -0,0 +1,19 @@ +import 'package:flutter/material.dart'; +import 'package:provider/provider.dart'; + +class AppProvider extends StatelessWidget { + final Widget child; + + AppProvider({required this.child}); + + @override + Widget build(BuildContext context) { + return child; + return MultiProvider( + providers: [ + // ChangeNotifierProvider(create: (_) => Counter()), + ], + child: child, + ); + } +} diff --git a/lib/config/routes.dart b/lib/config/routes.dart new file mode 100644 index 0000000..39a4ebc --- /dev/null +++ b/lib/config/routes.dart @@ -0,0 +1,40 @@ +import 'package:flutter/material.dart'; +import 'package:mohem_flutter_app/ui/landing/dashboard.dart'; +import 'package:mohem_flutter_app/ui/landing/today_attendance_screen.dart'; +import 'package:mohem_flutter_app/ui/login/forgot_password_screen.dart'; +import 'package:mohem_flutter_app/ui/login/login_screen.dart'; +import 'package:mohem_flutter_app/ui/login/new_password_screen.dart'; +import 'package:mohem_flutter_app/ui/login/verify_login_screen.dart'; +import 'package:mohem_flutter_app/ui/work_list/missing_swipe/missing_swipe_screen.dart'; +import 'package:mohem_flutter_app/ui/work_list/work_list_screen.dart'; + +class AppRoutes { + static const String splash = "/splash"; + static const String registerSelection = "/registerSelection"; + static const String loginVerifyAccount = "/loginVerifyAccount"; + static const String login = "/login"; + static const String verifyLogin = "/verifyLogin"; + static const String forgotPassword = "/forgotPassword"; + static const String newPassword = "/newPassword"; + static const String loginVerification = "/loginVerification"; + static const String dashboard = "/dashboard"; + static const String todayAttendance = "/todayAttendance"; + static const String initialRoute = login; + + //Work List + static const String workList = "/workList"; + static const String missingSwipe = "/missingSwipe"; + + static final Map routes = { + login: (context) => LoginScreen(), + verifyLogin: (context) => VerifyLoginScreen(), + dashboard: (context) => Dashboard(), + newPassword: (context) => NewPasswordScreen(), + forgotPassword: (context) => ForgotPasswordScreen(), + todayAttendance: (context) => TodayAttendanceScreen(), + + //Work List + workList: (context) => WorkListScreen(), + missingSwipe: (context) => MissingSwipeScreen(), + }; +} diff --git a/lib/dialogs/otp_dialog.dart b/lib/dialogs/otp_dialog.dart new file mode 100644 index 0000000..d82cf9c --- /dev/null +++ b/lib/dialogs/otp_dialog.dart @@ -0,0 +1,228 @@ +import 'dart:async'; + +import 'package:easy_localization/src/public_ext.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_svg/svg.dart'; +import 'package:mohem_flutter_app/classes/colors.dart'; +import 'package:mohem_flutter_app/extensions/int_extensions.dart'; +import 'package:mohem_flutter_app/extensions/string_extensions.dart'; +import 'package:mohem_flutter_app/generated/locale_keys.g.dart'; +import 'package:mohem_flutter_app/widgets/otp_widget.dart'; + +class OtpDialog { + final int type; + final int? mobileNo; + final Function(String) onSuccess; + final Function onFailure; + final BuildContext context; + + int remainingTime = 120; + + Future? timer; + + static BuildContext? _context; + + static bool? _loading; + + OtpDialog( + this.context, + this.type, + this.mobileNo, + this.onSuccess, + this.onFailure, + ); + + GlobalKey? verifyAccountForm = GlobalKey(); + + final TextEditingController _pinPutController = TextEditingController(); + + TextEditingController digit1 = TextEditingController(text: ""); + TextEditingController digit2 = TextEditingController(text: ""); + TextEditingController digit3 = TextEditingController(text: ""); + TextEditingController digit4 = TextEditingController(text: ""); + + Map verifyAccountFormValue = { + 'digit1': '', + 'digit2': '', + 'digit3': '', + 'digit4': '', + }; + final focusD1 = FocusNode(); + final focusD2 = FocusNode(); + final focusD3 = FocusNode(); + final focusD4 = FocusNode(); + String? errorMsg; + + // ProjectViewModel projectProvider; + String displayTime = ''; + String? _code; + dynamic setState; + bool stopTimer = false; + + // static String signature; + + void displayDialog(BuildContext context) async { + return showDialog( + context: context, + barrierColor: Colors.black.withOpacity(0.63), + builder: (context) { + // projectProvider = Provider.of(context); + return Dialog( + backgroundColor: Colors.white, + shape: const RoundedRectangleBorder(), + insetPadding: const EdgeInsets.only(left: 21, right: 21), + child: StatefulBuilder(builder: (context, setState) { + if (displayTime == '') { + startTimer(setState); + } + + return Container( + padding: EdgeInsets.only(left: 21, right: 18, top: 39, bottom: 59), + child: Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + SvgPicture.asset( + type == 1 ? "assets/images/login/verify_sms.svg" : "assets/images/login/verify_whatsapp.svg", + height: 50, + width: 50, + ), + IconButton( + padding: EdgeInsets.zero, + icon: const Icon(Icons.close), + constraints: const BoxConstraints(), + onPressed: () { + stopTimer = true; + onFailure(); + }) + ], + ), + 22.height, + (LocaleKeys.pleaseEnterTheVerificationCodeSentTo.tr() + ' xxxxxxxx' + mobileNo.toString().substring(mobileNo.toString().length - 3)).toText16(), + 18.height, + Directionality( + textDirection: TextDirection.ltr, + child: Center( + child: OTPWidget( + autoFocus: true, + controller: _pinPutController, + defaultBorderColor: const Color(0xffD8D8D8), + maxLength: 4, + onTextChanged: (text) {}, + pinBoxColor: Colors.white, + onDone: (code) => _onOtpCallBack(code, null), + textBorderColor: const Color(0xffD8D8D8), + pinBoxWidth: 60, + pinBoxHeight: 60, + pinTextStyle: const TextStyle(fontSize: 24.0, color: MyColors.darkTextColor), + pinTextAnimatedSwitcherTransition: ProvidedPinBoxTextAnimation.scalingTransition, + pinTextAnimatedSwitcherDuration: const Duration(milliseconds: 300), + pinBoxRadius: 10, + keyboardType: TextInputType.number, + ), + ), + ), + 30.height, + RichText( + text: TextSpan( + text: LocaleKeys.theVerificationCodeWillExpireIn.tr() + '\n', + style: const TextStyle(fontSize: 16, fontWeight: FontWeight.w600, color: MyColors.darkTextColor, letterSpacing: -0.48), + children: [ + TextSpan( + text: displayTime, + style: const TextStyle(fontSize: 16, fontWeight: FontWeight.w600, color: MyColors.textMixColor, letterSpacing: -0.48), + ), + ], + ), + ), + ], + ), + ); + }), + ); + }); + } + + InputDecoration buildInputDecoration(BuildContext context) { + return InputDecoration( + counterText: " ", + enabledBorder: const OutlineInputBorder( + borderRadius: BorderRadius.all(Radius.circular(10)), + borderSide: BorderSide(color: Colors.black), + ), + focusedBorder: OutlineInputBorder( + borderRadius: const BorderRadius.all(Radius.circular(10.0)), + borderSide: BorderSide(color: Theme.of(context).primaryColor), + ), + errorBorder: OutlineInputBorder( + borderRadius: const BorderRadius.all(Radius.circular(10.0)), + borderSide: BorderSide(color: Theme.of(context).errorColor), + ), + focusedErrorBorder: OutlineInputBorder( + borderRadius: const BorderRadius.all(Radius.circular(10.0)), + borderSide: BorderSide(color: Theme.of(context).errorColor), + ), + ); + } + + // String validateCodeDigit(value) { + // if (value.isEmpty) { + // return ' '; + // } else if (value.length == 3) { + // print(value); + // } else { + // return null; + // } + // } + + String getSecondsAsDigitalClock(int inputSeconds) { + int secNum = int.parse(inputSeconds.toString()); // don't forget the second param + int hours = (secNum / 3600).floor(); + int minutes = ((secNum - hours * 3600) / 60).floor(); + double seconds = secNum - hours * 3600 - minutes * 60; + String minutesString = ""; + String secondsString = ""; + minutesString = minutes < 10 ? "0" + minutes.toString() : minutes.toString(); + secondsString = seconds < 10 ? "0" + seconds.toStringAsFixed(0) : seconds.toStringAsFixed(0); + return minutesString + ":" + secondsString; + } + + void startTimer(setState) { + remainingTime--; + if (stopTimer) return; + setState(() { + displayTime = getSecondsAsDigitalClock(remainingTime); + }); + + timer = Future.delayed(const Duration(seconds: 1), () { + if (remainingTime > 0) { + startTimer(setState); + } else { + Navigator.pop(context); + } + }); + } + + static void hideSMSBox(context) { + Navigator.pop(context); + } + + void _onOtpCallBack(String otpCode, bool? isAutofill) { + if (otpCode.length == 4) { + stopTimer = true; + onSuccess(otpCode); + } + } + + static getSignature() async { + // if (Platform.isAndroid) { + // return await SmsRetriever.getAppSignature(); + // } else { + // return null; + // } + } +} diff --git a/lib/exceptions/api_exception.dart b/lib/exceptions/api_exception.dart new file mode 100644 index 0000000..e3046ca --- /dev/null +++ b/lib/exceptions/api_exception.dart @@ -0,0 +1,29 @@ +import 'dart:convert'; + +import 'package:mohem_flutter_app/api/api_client.dart'; + +class APIException implements Exception { + static const String BAD_REQUEST = 'api_common_bad_request'; + static const String UNAUTHORIZED = 'api_common_unauthorized'; + static const String FORBIDDEN = 'api_common_forbidden'; + static const String NOT_FOUND = 'api_common_not_found'; + static const String INTERNAL_SERVER_ERROR = 'api_common_internal_server_error'; + static const String UPGRADE_REQUIRED = 'api_common_upgrade_required'; + static const String BAD_RESPONSE_FORMAT = 'api_common_bad_response_format'; + static const String OTHER = 'api_common_http_error'; + static const String TIMEOUT = 'api_common_http_timeout'; + static const String UNKNOWN = 'unexpected_error'; + + final String message; + final APIError? error; + final arguments; + + const APIException(this.message, {this.arguments, this.error}); + + Map toJson() => {'message': message, 'error': error, 'arguments': '$arguments'}; + + @override + String toString() { + return jsonEncode(this); + } +} diff --git a/lib/extensions/int_extensions.dart b/lib/extensions/int_extensions.dart new file mode 100644 index 0000000..9b90b2f --- /dev/null +++ b/lib/extensions/int_extensions.dart @@ -0,0 +1,7 @@ +import 'package:flutter/cupertino.dart'; + +extension IntExtensions on int { + Widget get height => SizedBox(height: toDouble()); + + Widget get width => SizedBox(width: toDouble()); +} diff --git a/lib/extensions/string_extensions.dart b/lib/extensions/string_extensions.dart new file mode 100644 index 0000000..9db4829 --- /dev/null +++ b/lib/extensions/string_extensions.dart @@ -0,0 +1,109 @@ +import 'package:flutter/cupertino.dart'; +import 'package:intl/intl.dart'; +import 'package:mohem_flutter_app/classes/colors.dart'; + +extension EmailValidator on String { + Widget get toWidget => Text(this); + + Widget toText10({Color? color, bool isBold = false}) => Text( + this, + style: TextStyle(fontSize: 10, fontWeight: isBold ? FontWeight.bold : FontWeight.w600, color: color ?? MyColors.darkTextColor, letterSpacing: -0.4), + ); + + Widget toText11({Color? color, bool isUnderLine = false, bool isBold = false}) => Text( + this, + style: TextStyle( + fontSize: 11, + fontWeight: isBold ? FontWeight.bold : FontWeight.w600, + color: color ?? MyColors.darkTextColor, + letterSpacing: -0.33, + decoration: isUnderLine ? TextDecoration.underline : null), + ); + + Widget toText12({Color? color, bool isUnderLine = false, bool isBold = false, bool isCenter = false, int maxLine = 0}) => Text( + this, + textAlign: isCenter ? TextAlign.center : null, + maxLines: (maxLine > 0) ? maxLine : null, + style: TextStyle( + fontSize: 12, + fontWeight: isBold ? FontWeight.bold : FontWeight.w600, + color: color ?? MyColors.darkTextColor, + letterSpacing: -0.72, + decoration: isUnderLine ? TextDecoration.underline : null), + ); + + Widget toText13({Color? color, bool isUnderLine = false}) => Text( + this, + style: TextStyle(fontSize: 13, fontWeight: FontWeight.w600, color: color ?? MyColors.darkTextColor, letterSpacing: -0.52, decoration: isUnderLine ? TextDecoration.underline : null), + ); + + Widget toText14({Color? color, bool isBold = false}) => Text( + this, + style: TextStyle(color: color ?? MyColors.darkTextColor, fontSize: 14, letterSpacing: -0.48, fontWeight: isBold ? FontWeight.bold : FontWeight.w600), + ); + + Widget toText16({Color? color, bool isBold = false}) => Text( + this, + style: TextStyle(color: color ?? MyColors.darkTextColor, fontSize: 16, letterSpacing: -0.64, fontWeight: isBold ? FontWeight.bold : FontWeight.w600), + ); + + Widget toText17({Color? color, bool isBold = false}) => Text( + this, + style: TextStyle(color: color ?? MyColors.darkTextColor, fontSize: 17, letterSpacing: -0.68, fontWeight: isBold ? FontWeight.bold : FontWeight.w600), + ); + + Widget toText22({Color? color, bool isBold = false}) => Text( + this, + style: TextStyle(height: 1, color: color ?? MyColors.darkTextColor, fontSize: 22, letterSpacing: -1.44, fontWeight: isBold ? FontWeight.bold : FontWeight.w600), + ); + + Widget toText24({Color? color, bool isBold = false}) => Text( + this, + style: TextStyle(height: 23 / 24, color: color ?? MyColors.darkTextColor, fontSize: 24, letterSpacing: -1.44, fontWeight: isBold ? FontWeight.bold : FontWeight.w600), + ); + + Widget toText32({Color? color, bool isBold = false}) => Text( + this, + style: TextStyle(height: 32 / 32, color: color ?? MyColors.darkTextColor, fontSize: 32, letterSpacing: -1.92, fontWeight: isBold ? FontWeight.bold : FontWeight.w600), + ); + + bool isValidEmail() { + return RegExp(r'^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$').hasMatch(this); + } + + String toFormattedDate() { + String date = this.split("T")[0]; + String time = this.split("T")[1]; + var dates = date.split("-"); + return "${dates[2]} ${getMonth(int.parse(dates[1]))} ${dates[0]} ${DateFormat('hh:mm a').format(DateFormat('hh:mm:ss').parse(time))}"; + } + + getMonth(int month) { + switch (month) { + case 1: + return "January"; + case 2: + return "February"; + case 3: + return "March"; + case 4: + return "April"; + case 5: + return "May"; + case 6: + return "June"; + case 7: + return "July"; + case 8: + return "August"; + case 9: + return "September"; + case 10: + return "October"; + case 11: + return "November"; + case 12: + return "December"; + } + } +} diff --git a/lib/extensions/widget_extensions.dart b/lib/extensions/widget_extensions.dart new file mode 100644 index 0000000..787894d --- /dev/null +++ b/lib/extensions/widget_extensions.dart @@ -0,0 +1,11 @@ +import 'package:flutter/material.dart'; +import 'package:flutter/widgets.dart'; + +extension WidgetExtensions on Widget { + Widget onPress(VoidCallback onTap) => InkWell(onTap: onTap, child: this); + + Widget paddingAll(double _value) => Padding(padding: EdgeInsets.all(_value), child: this); + + Widget paddingOnly({double left = 0.0, double right = 0.0, double top = 0.0, double bottom = 0.0}) => + Padding(padding: EdgeInsets.only(left: left, right: right, top: top, bottom: bottom), child: this); +} diff --git a/lib/generated/codegen_loader.g.dart b/lib/generated/codegen_loader.g.dart new file mode 100644 index 0000000..b43f3bd --- /dev/null +++ b/lib/generated/codegen_loader.g.dart @@ -0,0 +1,196 @@ +// DO NOT EDIT. This is code generated via package:easy_localization/generate.dart + +// ignore_for_file: prefer_single_quotes + +import 'dart:ui'; + +import 'package:easy_localization/easy_localization.dart' show AssetLoader; + +class CodegenLoader extends AssetLoader{ + const CodegenLoader(); + + @override + Future> load(String fullPath, Locale locale ) { + return Future.value(mapLocales[locale.toString()]); + } + + static const Map ar_SA = { + "mohemm": "Mohemm", + "english": "English", + "arabic": "Arabic", + "login": "تسجيل الدخول", + "pleaseEnterLoginDetails": "الرجاء إدخال التفاصيل أدناه لتسجيل الدخول", + "username": "اسم المستخدم", + "password": "كلمة المرور", + "welcomeBack": "مرحبا بعودتك", + "wouldYouLikeToLoginWithCurrentUsername": "هل ترغب في تسجيل الدخول باسم المستخدم الحالي؟", + "lastLoginDetails": "تفاصيل تسجيل الدخول الأخير:", + "verificationType": "نوع التحقق:", + "pleaseVerify": "ارجوك تحقق", + "verifyThroughFace": "تحقق من خلال الوجه", + "verifyThroughFingerprint": "تحقق من خلال بصمة الإصبع", + "verifyThroughSMS": "تحقق من خلال الرسائل القصيرة", + "verifyThroughWhatsapp": "تحقق من خلال Whatsapp", + "useAnotherAccount": "استخدم حسابا آخر", + "pleaseEnterTheVerificationCodeSentTo": "الرجاء إدخال رمز التحقق المرسل إلى ", + "theVerificationCodeWillExpireIn": "ستنتهي صلاحية رمز التحقق في ", + "goodMorning": "صباح الخير", + "markAttendance": "علامة الحضور", + "timeLeftToday": "الوقت المتبقي اليوم", + "checkIn": "تحقق في", + "workList": "قائمة العمل", + "leaveBalance": "رصيد الاجازات", + "missingSwipes": "الضربات الشديدة في عداد المفقودين", + "ticketBalance": "رصيد التذكرة", + "other": "آخر", + "services": "خدمات", + "viewAllServices": "عرض جميع الخدمات", + "monthlyAttendance": "الحضور الشهري", + "workFromHome": "العمل من المنزل", + "ticketRequest": "طلب تذكرة", + "viewAllOffers": "مشاهدة جميع العروض", + "offers": "عروض & ", + "discounts": "الخصومات", + "newString": "جديد", + "setTheNewPassword": "قم بتعيين كلمة المرور الجديدة", + "typeYourNewPasswordBelow": "اكتب كلمة المرور الجديدة أدناه", + "confirmPassword": "تأكيد كلمة المرور", + "update": "تحديث", + "title": "عنوان", + "home": "مسكن", + "mySalary": "راتبي", + "createRequest": "إنشاء طلب", + "forgotPassword": "هل نسيت كلمة السر", + "employeeId": "هوية الموظف", + "loginCodeWillSentToMobileNumber": "الرجاء إدخال معرف الموظف الخاص بك ، وسيتم إرسال رمز تسجيل الدخول إلى رقم هاتفك المحمول", + "changePassword": "تغيير كلمة المرور", + "itemsForSale": "سلع للبيع", + "msg": "Hello {} in the {} world ", + "msg_named": "{} are written in the {lang} language", + "clickMe": "Click me", + "human": "Human", + "resources": "Resources", + "profile": { + "reset_password": { + "label": "Reset Password", + "username": "Username", + "password": "password" + } + }, + "clicked": { + "zero": "You clicked {} times!", + "one": "You clicked {} time!", + "two": "You clicked {} times!", + "few": "You clicked {} times!", + "many": "You clicked {} times!", + "other": "You clicked {} times!" + }, + "amount": { + "zero": "Your amount : {} ", + "one": "Your amount : {} ", + "two": "Your amount : {} ", + "few": "Your amount : {} ", + "many": "Your amount : {} ", + "other": "Your amount : {} " + }, + "gender": { + "male": "Hi man ;) ", + "female": "Hello girl :)", + "with_arg": { + "male": "Hi man ;) {}", + "female": "Hello girl :) {}" + } + }, + "reset_locale": "Reset Language" +}; +static const Map en_US = { + "mohemm": "Mohemm", + "english": "English", + "arabic": "Arabic", + "login": "Login", + "pleaseEnterLoginDetails": "Please enter the detail below to login", + "username": "Username", + "password": "Password", + "welcomeBack": "Welcome back", + "wouldYouLikeToLoginWithCurrentUsername": "Would you like to login with current Username?", + "lastLoginDetails": "Last Login Details:", + "verificationType": "Verification Type:", + "pleaseVerify": "Please Verify", + "verifyThroughFace": "Verify Through Face", + "verifyThroughFingerprint": "Verify Through Fingerprint", + "verifyThroughSMS": "Verify Through SMS", + "verifyThroughWhatsapp": "Verify Through Whatsapp", + "useAnotherAccount": "Use Another Account", + "pleaseEnterTheVerificationCodeSentTo": "Please enter the verification code sent to ", + "theVerificationCodeWillExpireIn": "The verification code will expire in ", + "goodMorning": "Good Morning", + "markAttendance": "Mark Attendance", + "timeLeftToday": "Time Left Today", + "checkIn": "Check In", + "workList": "Work List", + "leaveBalance": "Leave Balance", + "missingSwipes": "Missing Swipes", + "ticketBalance": "Ticket Balance", + "other": "Other", + "services": "Services", + "viewAllServices": "View All Services", + "monthlyAttendance": "Monthly Attendance", + "workFromHome": "Work From Home", + "ticketRequest": "Ticket Request", + "viewAllOffers": "View All Offers", + "offers": "Offers & ", + "discounts": "Discounts", + "newString": "New", + "setTheNewPassword": "Set the new password", + "typeYourNewPasswordBelow": "Type your new password below", + "confirmPassword": "Confirm Password", + "update": "Update", + "title": "Title", + "home": "Home", + "mySalary": "My Salary", + "createRequest": "Create Request", + "forgotPassword": "Forgot Password", + "employeeId": "Employee ID", + "loginCodeWillSentToMobileNumber": "Please Enter your Employee ID, A login code will be sent to your mobile number", + "changePassword": "Change Password", + "itemsForSale": "Items for Sale", + "msg": "Hello {} in the {} world ", + "msg_named": "{} are written in the {lang} language", + "clickMe": "Click me", + "human": "Human", + "resources": "Resources", + "profile": { + "reset_password": { + "label": "Reset Password", + "username": "Username", + "password": "password" + } + }, + "clicked": { + "zero": "You clicked {} times!", + "one": "You clicked {} time!", + "two": "You clicked {} times!", + "few": "You clicked {} times!", + "many": "You clicked {} times!", + "other": "You clicked {} times!" + }, + "amount": { + "zero": "Your amount : {} ", + "one": "Your amount : {} ", + "two": "Your amount : {} ", + "few": "Your amount : {} ", + "many": "Your amount : {} ", + "other": "Your amount : {} " + }, + "gender": { + "male": "Hi man ;) ", + "female": "Hello girl :)", + "with_arg": { + "male": "Hi man ;) {}", + "female": "Hello girl :) {}" + } + }, + "reset_locale": "Reset Language" +}; +static const Map> 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 new file mode 100644 index 0000000..24d7171 --- /dev/null +++ b/lib/generated/locale_keys.g.dart @@ -0,0 +1,69 @@ +// DO NOT EDIT. This is code generated via package:easy_localization/generate.dart + +abstract class LocaleKeys { + static const mohemm = 'mohemm'; + static const english = 'english'; + static const arabic = 'arabic'; + static const login = 'login'; + static const pleaseEnterLoginDetails = 'pleaseEnterLoginDetails'; + static const username = 'username'; + static const password = 'password'; + static const welcomeBack = 'welcomeBack'; + static const wouldYouLikeToLoginWithCurrentUsername = 'wouldYouLikeToLoginWithCurrentUsername'; + static const lastLoginDetails = 'lastLoginDetails'; + static const verificationType = 'verificationType'; + static const pleaseVerify = 'pleaseVerify'; + static const verifyThroughFace = 'verifyThroughFace'; + static const verifyThroughFingerprint = 'verifyThroughFingerprint'; + static const verifyThroughSMS = 'verifyThroughSMS'; + static const verifyThroughWhatsapp = 'verifyThroughWhatsapp'; + static const useAnotherAccount = 'useAnotherAccount'; + static const pleaseEnterTheVerificationCodeSentTo = 'pleaseEnterTheVerificationCodeSentTo'; + static const theVerificationCodeWillExpireIn = 'theVerificationCodeWillExpireIn'; + static const goodMorning = 'goodMorning'; + static const markAttendance = 'markAttendance'; + static const timeLeftToday = 'timeLeftToday'; + static const checkIn = 'checkIn'; + static const workList = 'workList'; + static const leaveBalance = 'leaveBalance'; + static const missingSwipes = 'missingSwipes'; + static const ticketBalance = 'ticketBalance'; + static const services = 'services'; + static const viewAllServices = 'viewAllServices'; + static const monthlyAttendance = 'monthlyAttendance'; + static const workFromHome = 'workFromHome'; + static const ticketRequest = 'ticketRequest'; + static const viewAllOffers = 'viewAllOffers'; + static const offers = 'offers'; + static const discounts = 'discounts'; + static const newString = 'newString'; + static const setTheNewPassword = 'setTheNewPassword'; + static const typeYourNewPasswordBelow = 'typeYourNewPasswordBelow'; + static const confirmPassword = 'confirmPassword'; + static const update = 'update'; + static const title = 'title'; + static const home = 'home'; + static const mySalary = 'mySalary'; + static const createRequest = 'createRequest'; + static const forgotPassword = 'forgotPassword'; + static const employeeId = 'employeeId'; + static const loginCodeWillSentToMobileNumber = 'loginCodeWillSentToMobileNumber'; + static const changePassword = 'changePassword'; + static const itemsForSale = 'itemsForSale'; + static const msg = 'msg'; + static const msg_named = 'msg_named'; + static const clickMe = 'clickMe'; + static const human = 'human'; + static const resources = 'resources'; + static const profile_reset_password_label = 'profile.reset_password.label'; + static const profile_reset_password_username = 'profile.reset_password.username'; + static const profile_reset_password_password = 'profile.reset_password.password'; + static const profile_reset_password = 'profile.reset_password'; + static const profile = 'profile'; + static const clicked = 'clicked'; + static const amount = 'amount'; + static const gender_with_arg = 'gender.with_arg'; + static const gender = 'gender'; + static const reset_locale = 'reset_locale'; + +} diff --git a/lib/main.dart b/lib/main.dart new file mode 100644 index 0000000..99cff95 --- /dev/null +++ b/lib/main.dart @@ -0,0 +1,62 @@ +import 'dart:io'; + +import 'package:easy_localization/easy_localization.dart'; +import 'package:flutter/material.dart'; +import 'package:mohem_flutter_app/app_state/app_state.dart'; +import 'package:mohem_flutter_app/config/app_provider.dart'; +import 'package:mohem_flutter_app/generated/codegen_loader.g.dart'; +import 'package:mohem_flutter_app/models/post_params_model.dart'; +import 'package:mohem_flutter_app/theme/app_theme.dart'; +import 'package:sizer/sizer.dart'; + +import 'config/routes.dart'; + +Future main() async { + WidgetsFlutterBinding.ensureInitialized(); + await EasyLocalization.ensureInitialized(); + runApp( + EasyLocalization( + supportedLocales: const [ + Locale('en', 'US'), + Locale('ar', 'SA'), + ], + path: 'assets/langs', + assetLoader: CodegenLoader(), + child: MyApp(), + ), + ); +} + +// todo terminal command to genertate translation files +// flutter pub run easy_localization:generate --source-dir ./assets/langs +// todo terminal command to genertate translation keys +// flutter pub run easy_localization:generate --source-dir ./assets/langs -f keys -o locale_keys.g.dart +// command to generate languages data from json + +class MyApp extends StatelessWidget { + MyApp() { +// AppDependencies.addDependencies(); + } + + @override + Widget build(BuildContext context) { + return AppProvider( + child: Sizer( + builder: (context, orientation, deviceType) { + AppState().setPostParamsModel( + PostParamsModel(languageID: EasyLocalization.of(context)?.locale.languageCode == "ar" ? 1 : 2, channel: 31, versionID: 3.2, mobileType: Platform.isAndroid ? "android" : "ios"), + ); + return MaterialApp( + theme: AppTheme.getTheme(EasyLocalization.of(context)?.locale.languageCode == "ar"), + debugShowCheckedModeBanner: false, + localizationsDelegates: context.localizationDelegates, + supportedLocales: context.supportedLocales, + locale: context.locale, + initialRoute: AppRoutes.initialRoute, + routes: AppRoutes.routes, + ); + }, + ), + ); + } +} diff --git a/lib/models/basic_member_information_model.dart b/lib/models/basic_member_information_model.dart new file mode 100644 index 0000000..33b55fa --- /dev/null +++ b/lib/models/basic_member_information_model.dart @@ -0,0 +1,32 @@ +class BasicMemberInformationModel { + String? pEMAILADDRESS; + String? pLEGISLATIONCODE; + String? pMOBILENUMBER; + String? pRETURNMSG; + String? pRETURNSTATUS; + + BasicMemberInformationModel( + {this.pEMAILADDRESS, + this.pLEGISLATIONCODE, + this.pMOBILENUMBER, + this.pRETURNMSG, + this.pRETURNSTATUS}); + + BasicMemberInformationModel.fromJson(Map json) { + pEMAILADDRESS = json['P_EMAIL_ADDRESS']; + pLEGISLATIONCODE = json['P_LEGISLATION_CODE']; + pMOBILENUMBER = json['P_MOBILE_NUMBER']; + pRETURNMSG = json['P_RETURN_MSG']; + pRETURNSTATUS = json['P_RETURN_STATUS']; + } + + Map toJson() { + final Map data = new Map(); + data['P_EMAIL_ADDRESS'] = this.pEMAILADDRESS; + data['P_LEGISLATION_CODE'] = this.pLEGISLATIONCODE; + data['P_MOBILE_NUMBER'] = this.pMOBILENUMBER; + data['P_RETURN_MSG'] = this.pRETURNMSG; + data['P_RETURN_STATUS'] = this.pRETURNSTATUS; + return data; + } +} diff --git a/lib/models/check_mobile_app_version_model.dart b/lib/models/check_mobile_app_version_model.dart new file mode 100644 index 0000000..cd301d3 --- /dev/null +++ b/lib/models/check_mobile_app_version_model.dart @@ -0,0 +1,191 @@ +class CheckMobileAppVersionModel { + String? date; + int? languageID; + int? serviceName; + String? time; + String? androidLink; + String? authenticationTokenID; + String? data; + bool? dataw; + int? dietType; + int? dietTypeID; + int? errorCode; + String? errorEndUserMessage; + String? errorEndUserMessageN; + String? errorMessage; + int? errorType; + int? foodCategory; + String? iOSLink; + bool? isAuthenticated; + int? mealOrderStatus; + int? mealType; + int? messageStatus; + int? numberOfResultRecords; + String? patientBlodType; + String? successMsg; + String? successMsgN; + String? vidaUpdatedResponse; + String? encryprURL; + bool? kioskHelp; + List? listRssItems; + List? listKioskFingerPrint; + List? listKioskFingerPrintGetByID; + List? listKioskGetLastTransaction; + List? listRegKioskFingerPrint; + String? message; + String? ramadanTimeObj; + String? habibTwitterList; + + CheckMobileAppVersionModel( + {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.encryprURL, + this.kioskHelp, + this.listRssItems, + this.listKioskFingerPrint, + this.listKioskFingerPrintGetByID, + this.listKioskGetLastTransaction, + this.listRegKioskFingerPrint, + this.message, + this.ramadanTimeObj, + this.habibTwitterList}); + + CheckMobileAppVersionModel.fromJson(Map json) { + date = json['Date']; + languageID = json['LanguageID']; + serviceName = json['ServiceName']; + time = json['Time']; + androidLink = json['AndroidLink']; + authenticationTokenID = json['AuthenticationTokenID']; + data = json['Data']; + dataw = json['Dataw']; + dietType = json['DietType']; + dietTypeID = json['DietTypeID']; + errorCode = json['ErrorCode']; + errorEndUserMessage = json['ErrorEndUserMessage']; + errorEndUserMessageN = json['ErrorEndUserMessageN']; + errorMessage = json['ErrorMessage']; + errorType = json['ErrorType']; + foodCategory = json['FoodCategory']; + iOSLink = json['IOSLink']; + isAuthenticated = json['IsAuthenticated']; + mealOrderStatus = json['MealOrderStatus']; + mealType = json['MealType']; + messageStatus = json['MessageStatus']; + numberOfResultRecords = json['NumberOfResultRecords']; + patientBlodType = json['PatientBlodType']; + successMsg = json['SuccessMsg']; + successMsgN = json['SuccessMsgN']; + vidaUpdatedResponse = json['VidaUpdatedResponse']; + encryprURL = json['EncryprURL']; + kioskHelp = json['KioskHelp']; + if (json['ListRssItems'] != null) { + listRssItems = []; + json['ListRssItems'].forEach((v) { + //listRssItems!.add(new Null.fromJson(v)); + }); + } + if (json['List_Kiosk_FingerPrint'] != null) { + listKioskFingerPrint = []; + json['List_Kiosk_FingerPrint'].forEach((v) { + // listKioskFingerPrint!.add(new Null.fromJson(v)); + }); + } + if (json['List_Kiosk_FingerPrintGetByID'] != null) { + listKioskFingerPrintGetByID = []; + json['List_Kiosk_FingerPrintGetByID'].forEach((v) { + // listKioskFingerPrintGetByID!.add(new Null.fromJson(v)); + }); + } + if (json['List_Kiosk_GetLastTransaction'] != null) { + listKioskGetLastTransaction = []; + json['List_Kiosk_GetLastTransaction'].forEach((v) { + // listKioskGetLastTransaction!.add(new Null.fromJson(v)); + }); + } + if (json['List_RegKiosk_FingerPrint'] != null) { + listRegKioskFingerPrint = []; + json['List_RegKiosk_FingerPrint'].forEach((v) { + // listRegKioskFingerPrint!.add(new Null.fromJson(v)); + }); + } + message = json['Message']; + ramadanTimeObj = json['RamadanTimeObj']; + habibTwitterList = json['habibTwitterList']; + } + + Map toJson() { + final Map data = new Map(); + data['Date'] = this.date; + data['LanguageID'] = this.languageID; + data['ServiceName'] = this.serviceName; + data['Time'] = this.time; + data['AndroidLink'] = this.androidLink; + data['AuthenticationTokenID'] = this.authenticationTokenID; + data['Data'] = this.data; + data['Dataw'] = this.dataw; + data['DietType'] = this.dietType; + data['DietTypeID'] = this.dietTypeID; + data['ErrorCode'] = this.errorCode; + data['ErrorEndUserMessage'] = this.errorEndUserMessage; + data['ErrorEndUserMessageN'] = this.errorEndUserMessageN; + data['ErrorMessage'] = this.errorMessage; + data['ErrorType'] = this.errorType; + data['FoodCategory'] = this.foodCategory; + data['IOSLink'] = this.iOSLink; + data['IsAuthenticated'] = this.isAuthenticated; + data['MealOrderStatus'] = this.mealOrderStatus; + data['MealType'] = this.mealType; + data['MessageStatus'] = this.messageStatus; + data['NumberOfResultRecords'] = this.numberOfResultRecords; + data['PatientBlodType'] = this.patientBlodType; + data['SuccessMsg'] = this.successMsg; + data['SuccessMsgN'] = this.successMsgN; + data['VidaUpdatedResponse'] = this.vidaUpdatedResponse; + data['EncryprURL'] = this.encryprURL; + data['KioskHelp'] = this.kioskHelp; + if (this.listRssItems != null) { + //data['ListRssItems'] = this.listRssItems!.map((v) => v.toJson()).toList(); + } + if (this.listKioskFingerPrint != null) { + // data['List_Kiosk_FingerPrint'] = this.listKioskFingerPrint!.map((v) => v.toJson()).toList(); + } + if (this.listKioskFingerPrintGetByID != null) { + //data['List_Kiosk_FingerPrintGetByID'] = this.listKioskFingerPrintGetByID!.map((v) => v.toJson()).toList(); + } + if (this.listKioskGetLastTransaction != null) { + //data['List_Kiosk_GetLastTransaction'] = this.listKioskGetLastTransaction!.map((v) => v.toJson()).toList(); + } + if (this.listRegKioskFingerPrint != null) { + //data['List_RegKiosk_FingerPrint'] = this.listRegKioskFingerPrint!.map((v) => v.toJson()).toList(); + } + data['Message'] = this.message; + data['RamadanTimeObj'] = this.ramadanTimeObj; + data['habibTwitterList'] = this.habibTwitterList; + return data; + } +} diff --git a/lib/models/content_info_model.dart b/lib/models/content_info_model.dart new file mode 100644 index 0000000..4eec746 --- /dev/null +++ b/lib/models/content_info_model.dart @@ -0,0 +1,65 @@ +class ContentInfoModel { + int? totalItemsCount; + int? statusCode; + String? message; + List? data; + + ContentInfoModel({this.totalItemsCount, this.statusCode, this.message, this.data}); + + ContentInfoModel.fromJson(Map json) { + totalItemsCount = json['totalItemsCount']; + statusCode = json['statusCode']; + message = json['message']; + if (json['data'] != null) { + data = []; + json['data'].forEach((v) { + data?.add(new ContentInfoDataModel.fromJson(v)); + }); + } + } + + Map toJson() { + final Map data = new Map(); + data['totalItemsCount'] = this.totalItemsCount; + data['statusCode'] = this.statusCode; + data['message'] = this.message; + if (this.data != null) { + data['data'] = this.data?.map((v) => v.toJson()).toList(); + } + return data; + } +} + +class ContentInfoDataModel { + int? contentInfoId; + int? contentTypeId; + String? content; + String? contentTypeNameEn; + String? contentTypeNameAr; + String? fileName; + String? exposeFilePath; + + ContentInfoDataModel({this.contentInfoId, this.contentTypeId, this.content, this.contentTypeNameEn, this.contentTypeNameAr, this.fileName, this.exposeFilePath}); + + ContentInfoDataModel.fromJson(Map json) { + contentInfoId = json['contentInfoId']; + contentTypeId = json['contentTypeId']; + content = json['content']; + contentTypeNameEn = json['contentTypeNameEn']; + contentTypeNameAr = json['contentTypeNameAr']; + fileName = json['fileName']; + exposeFilePath = json['exposeFilePath']; + } + + Map toJson() { + final Map data = new Map(); + data['contentInfoId'] = this.contentInfoId; + data['contentTypeId'] = this.contentTypeId; + data['content'] = this.content; + data['contentTypeNameEn'] = this.contentTypeNameEn; + data['contentTypeNameAr'] = this.contentTypeNameAr; + data['fileName'] = this.fileName; + data['exposeFilePath'] = this.exposeFilePath; + return data; + } +} diff --git a/lib/models/dashboard/get_accrual_balances_list_model.dart b/lib/models/dashboard/get_accrual_balances_list_model.dart new file mode 100644 index 0000000..a53133e --- /dev/null +++ b/lib/models/dashboard/get_accrual_balances_list_model.dart @@ -0,0 +1,39 @@ +class GetAccrualBalancesList { + GetAccrualBalancesList({ + this.accrualNetEntitlement, + this.accrualUsedEntitlement, + this.accrualYearlyEntitlement, + this.accuralPlanName, + this.endDate, + this.lastAccrualDate, + this.startDate, + }); + + double? accrualNetEntitlement; + int? accrualUsedEntitlement; + dynamic accrualYearlyEntitlement; + String? accuralPlanName; + String? endDate; + String? lastAccrualDate; + String? startDate; + + factory GetAccrualBalancesList.fromJson(Map json) => GetAccrualBalancesList( + accrualNetEntitlement: json["ACCRUAL_NET_ENTITLEMENT"] == null ? null : json["ACCRUAL_NET_ENTITLEMENT"].toDouble(), + accrualUsedEntitlement: json["ACCRUAL_USED_ENTITLEMENT"] == null ? null : json["ACCRUAL_USED_ENTITLEMENT"], + accrualYearlyEntitlement: json["ACCRUAL_YEARLY_ENTITLEMENT"], + accuralPlanName: json["ACCURAL_PLAN_NAME"] == null ? null : json["ACCURAL_PLAN_NAME"], + endDate: json["END_DATE"] == null ? null : json["END_DATE"], + lastAccrualDate: json["LAST_ACCRUAL_DATE"] == null ? null : json["LAST_ACCRUAL_DATE"], + startDate: json["START_DATE"] == null ? null : json["START_DATE"], + ); + + Map toJson() => { + "ACCRUAL_NET_ENTITLEMENT": accrualNetEntitlement == null ? null : accrualNetEntitlement, + "ACCRUAL_USED_ENTITLEMENT": accrualUsedEntitlement == null ? null : accrualUsedEntitlement, + "ACCRUAL_YEARLY_ENTITLEMENT": accrualYearlyEntitlement, + "ACCURAL_PLAN_NAME": accuralPlanName == null ? null : accuralPlanName, + "END_DATE": endDate == null ? null : endDate, + "LAST_ACCRUAL_DATE": lastAccrualDate == null ? null : lastAccrualDate, + "START_DATE": startDate == null ? null : startDate, + }; +} diff --git a/lib/models/dashboard/get_attendance_tracking_list_model.dart b/lib/models/dashboard/get_attendance_tracking_list_model.dart new file mode 100644 index 0000000..66b9ed8 --- /dev/null +++ b/lib/models/dashboard/get_attendance_tracking_list_model.dart @@ -0,0 +1,55 @@ +class GetAttendanceTrackingList { + GetAttendanceTrackingList({ + this.pBreakHours, + this.pLateInHours, + this.pRemainingHours, + this.pReturnMsg, + this.pReturnStatus, + this.pScheduledHours, + this.pShtName, + this.pSpentHours, + this.pSwipesExemptedFlag, + this.pSwipeIn, + this.pSwipeOut, + }); + + String? pBreakHours; + String? pLateInHours; + String? pRemainingHours; + String? pReturnMsg; + String? pReturnStatus; + String? pScheduledHours; + String? pShtName; + String? pSpentHours; + String? pSwipesExemptedFlag; + dynamic pSwipeIn; + dynamic pSwipeOut; + + factory GetAttendanceTrackingList.fromMap(Map json) => GetAttendanceTrackingList( + pBreakHours: json["P_BREAK_HOURS"] == null ? null : json["P_BREAK_HOURS"], + pLateInHours: json["P_LATE_IN_HOURS"] == null ? null : json["P_LATE_IN_HOURS"], + pRemainingHours: json["P_REMAINING_HOURS"] == null ? null : json["P_REMAINING_HOURS"], + pReturnMsg: json["P_RETURN_MSG"] == null ? null : json["P_RETURN_MSG"], + pReturnStatus: json["P_RETURN_STATUS"] == null ? null : json["P_RETURN_STATUS"], + pScheduledHours: json["P_SCHEDULED_HOURS"] == null ? null : json["P_SCHEDULED_HOURS"], + pShtName: json["P_SHT_NAME"] == null ? null : json["P_SHT_NAME"], + pSpentHours: json["P_SPENT_HOURS"] == null ? null : json["P_SPENT_HOURS"], + pSwipesExemptedFlag: json["P_SWIPES_EXEMPTED_FLAG"] == null ? null : json["P_SWIPES_EXEMPTED_FLAG"], + pSwipeIn: json["P_SWIPE_IN"], + pSwipeOut: json["P_SWIPE_OUT"], + ); + + Map toMap() => { + "P_BREAK_HOURS": pBreakHours == null ? null : pBreakHours, + "P_LATE_IN_HOURS": pLateInHours == null ? null : pLateInHours, + "P_REMAINING_HOURS": pRemainingHours == null ? null : pRemainingHours, + "P_RETURN_MSG": pReturnMsg == null ? null : pReturnMsg, + "P_RETURN_STATUS": pReturnStatus == null ? null : pReturnStatus, + "P_SCHEDULED_HOURS": pScheduledHours == null ? null : pScheduledHours, + "P_SHT_NAME": pShtName == null ? null : pShtName, + "P_SPENT_HOURS": pSpentHours == null ? null : pSpentHours, + "P_SWIPES_EXEMPTED_FLAG": pSwipesExemptedFlag == null ? null : pSwipesExemptedFlag, + "P_SWIPE_IN": pSwipeIn, + "P_SWIPE_OUT": pSwipeOut, + }; +} diff --git a/lib/models/dashboard/get_open_missing_swipes_list_model.dart b/lib/models/dashboard/get_open_missing_swipes_list_model.dart new file mode 100644 index 0000000..86ac6a9 --- /dev/null +++ b/lib/models/dashboard/get_open_missing_swipes_list_model.dart @@ -0,0 +1,24 @@ + +class GetOpenMissingSwipesList { + GetOpenMissingSwipesList({ + this.pOpenMissingSwipes, + this.pReturnMsg, + this.pReturnStatus, + }); + + int? pOpenMissingSwipes; + String? pReturnMsg; + String? pReturnStatus; + + factory GetOpenMissingSwipesList.fromJson(Map json) => GetOpenMissingSwipesList( + pOpenMissingSwipes: json["P_OPEN_MISSING_SWIPES"] == null ? null : json["P_OPEN_MISSING_SWIPES"], + pReturnMsg: json["P_RETURN_MSG"] == null ? null : json["P_RETURN_MSG"], + pReturnStatus: json["P_RETURN_STATUS"] == null ? null : json["P_RETURN_STATUS"], + ); + + Map toJson() => { + "P_OPEN_MISSING_SWIPES": pOpenMissingSwipes == null ? null : pOpenMissingSwipes, + "P_RETURN_MSG": pReturnMsg == null ? null : pReturnMsg, + "P_RETURN_STATUS": pReturnStatus == null ? null : pReturnStatus, + }; +} diff --git a/lib/models/dashboard/get_open_notifications_list.dart b/lib/models/dashboard/get_open_notifications_list.dart new file mode 100644 index 0000000..854b62a --- /dev/null +++ b/lib/models/dashboard/get_open_notifications_list.dart @@ -0,0 +1,23 @@ +class GetOpenNotificationsList { + GetOpenNotificationsList({ + this.itemType, + this.itemTypeDisplayName, + this.openNtfNumber, + }); + + String? itemType; + String? itemTypeDisplayName; + int? openNtfNumber; + + factory GetOpenNotificationsList.fromMap(Map json) => GetOpenNotificationsList( + itemType: json["ITEM_TYPE"] == null ? null : json["ITEM_TYPE"], + itemTypeDisplayName: json["ITEM_TYPE_DISPLAY_NAME"] == null ? null : json["ITEM_TYPE_DISPLAY_NAME"], + openNtfNumber: json["OPEN_NTF_NUMBER"] == null ? null : json["OPEN_NTF_NUMBER"], + ); + + Map toMap() => { + "ITEM_TYPE": itemType == null ? null : itemType, + "ITEM_TYPE_DISPLAY_NAME": itemTypeDisplayName == null ? null : itemTypeDisplayName, + "OPEN_NTF_NUMBER": openNtfNumber == null ? null : openNtfNumber, + }; +} diff --git a/lib/models/dashboard/itg_forms_model.dart b/lib/models/dashboard/itg_forms_model.dart new file mode 100644 index 0000000..c5a0145 --- /dev/null +++ b/lib/models/dashboard/itg_forms_model.dart @@ -0,0 +1,189 @@ +// To parse this JSON data, do +// +// final itgFormsModel = itgFormsModelFromMap(jsonString); + +import 'dart:convert'; + +ItgFormsModel itgFormsModelFromMap(String str) => ItgFormsModel.fromJson(json.decode(str)); + +String itgFormsModelToMap(ItgFormsModel data) => json.encode(data.toMap()); + +class ItgFormsModel { + ItgFormsModel({ + 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.itgRequest, + this.itgFormAttachmentsList, + this.message, + this.mohemmItgDepartmentSectionsList, + this.mohemmItgProjectDepartmentsList, + this.mohemmItgResponseItem, + this.mohemmItgSectionTopicsList, + this.mohemmItgTicketDetailsList, + this.mohemmItgTicketTransactionsList, + this.mohemmItgTicketsByEmployeeList, + this.mohemmItgProjectsList, + this.mohemmItgTicketTypesList, + this.referenceNumber, + this.requestType, + this.totalCount, + this.statuseCode, + }); + + dynamic date; + int? languageId; + int? serviceName; + dynamic time; + dynamic androidLink; + dynamic authenticationTokenId; + dynamic data; + bool? dataw; + int? dietType; + int? dietTypeId; + dynamic errorCode; + dynamic errorEndUserMessage; + dynamic errorEndUserMessageN; + dynamic errorMessage; + int? errorType; + int? foodCategory; + dynamic iosLink; + bool? isAuthenticated; + int? mealOrderStatus; + int? mealType; + int? messageStatus; + int? numberOfResultRecords; + dynamic patientBlodType; + String? successMsg; + dynamic successMsgN; + dynamic vidaUpdatedResponse; + dynamic itgRequest; + dynamic itgFormAttachmentsList; + String? message; + dynamic mohemmItgDepartmentSectionsList; + dynamic mohemmItgProjectDepartmentsList; + dynamic mohemmItgResponseItem; + dynamic mohemmItgSectionTopicsList; + dynamic mohemmItgTicketDetailsList; + dynamic mohemmItgTicketTransactionsList; + dynamic mohemmItgTicketsByEmployeeList; + dynamic mohemmItgProjectsList; + dynamic mohemmItgTicketTypesList; + DateTime? referenceNumber; + dynamic requestType; + int? totalCount; + int? statuseCode; + + factory ItgFormsModel.fromJson(Map json) => ItgFormsModel( + date: json["Date"], + languageId: json["LanguageID"] == null ? null : json["LanguageID"], + serviceName: json["ServiceName"] == null ? null : json["ServiceName"], + time: json["Time"], + androidLink: json["AndroidLink"], + authenticationTokenId: json["AuthenticationTokenID"], + data: json["Data"], + dataw: json["Dataw"] == null ? null : json["Dataw"], + dietType: json["DietType"] == null ? null : json["DietType"], + dietTypeId: json["DietTypeID"] == null ? null : json["DietTypeID"], + errorCode: json["ErrorCode"], + errorEndUserMessage: json["ErrorEndUserMessage"], + errorEndUserMessageN: json["ErrorEndUserMessageN"], + errorMessage: json["ErrorMessage"], + errorType: json["ErrorType"] == null ? null : json["ErrorType"], + foodCategory: json["FoodCategory"] == null ? null : json["FoodCategory"], + iosLink: json["IOSLink"], + isAuthenticated: json["IsAuthenticated"] == null ? null : json["IsAuthenticated"], + mealOrderStatus: json["MealOrderStatus"] == null ? null : json["MealOrderStatus"], + mealType: json["MealType"] == null ? null : json["MealType"], + messageStatus: json["MessageStatus"] == null ? null : json["MessageStatus"], + numberOfResultRecords: json["NumberOfResultRecords"] == null ? null : json["NumberOfResultRecords"], + patientBlodType: json["PatientBlodType"], + successMsg: json["SuccessMsg"] == null ? null : json["SuccessMsg"], + successMsgN: json["SuccessMsgN"], + vidaUpdatedResponse: json["VidaUpdatedResponse"], + itgRequest: json["ITGRequest"], + itgFormAttachmentsList: json["Itg_FormAttachmentsList"], + message: json["Message"] == null ? null : json["Message"], + mohemmItgDepartmentSectionsList: json["Mohemm_ITG_DepartmentSectionsList"], + mohemmItgProjectDepartmentsList: json["Mohemm_ITG_ProjectDepartmentsList"], + mohemmItgResponseItem: json["Mohemm_ITG_ResponseItem"], + mohemmItgSectionTopicsList: json["Mohemm_ITG_SectionTopicsList"], + mohemmItgTicketDetailsList: json["Mohemm_ITG_TicketDetailsList"], + mohemmItgTicketTransactionsList: json["Mohemm_ITG_TicketTransactionsList"], + mohemmItgTicketsByEmployeeList: json["Mohemm_ITG_TicketsByEmployeeList"], + mohemmItgProjectsList: json["Mohemm_Itg_ProjectsList"], + mohemmItgTicketTypesList: json["Mohemm_Itg_TicketTypesList"], + referenceNumber: json["ReferenceNumber"] == null ? null : DateTime.parse(json["ReferenceNumber"]), + requestType: json["RequestType"], + totalCount: json["TotalCount"] == null ? null : json["TotalCount"], + statuseCode: json["statuseCode"] == null ? null : json["statuseCode"], + ); + + Map toMap() => { + "Date": date, + "LanguageID": languageId == null ? null : languageId, + "ServiceName": serviceName == null ? null : serviceName, + "Time": time, + "AndroidLink": androidLink, + "AuthenticationTokenID": authenticationTokenId, + "Data": data, + "Dataw": dataw == null ? null : dataw, + "DietType": dietType == null ? null : dietType, + "DietTypeID": dietTypeId == null ? null : dietTypeId, + "ErrorCode": errorCode, + "ErrorEndUserMessage": errorEndUserMessage, + "ErrorEndUserMessageN": errorEndUserMessageN, + "ErrorMessage": errorMessage, + "ErrorType": errorType == null ? null : errorType, + "FoodCategory": foodCategory == null ? null : foodCategory, + "IOSLink": iosLink, + "IsAuthenticated": isAuthenticated == null ? null : isAuthenticated, + "MealOrderStatus": mealOrderStatus == null ? null : mealOrderStatus, + "MealType": mealType == null ? null : mealType, + "MessageStatus": messageStatus == null ? null : messageStatus, + "NumberOfResultRecords": numberOfResultRecords == null ? null : numberOfResultRecords, + "PatientBlodType": patientBlodType, + "SuccessMsg": successMsg == null ? null : successMsg, + "SuccessMsgN": successMsgN, + "VidaUpdatedResponse": vidaUpdatedResponse, + "ITGRequest": itgRequest, + "Itg_FormAttachmentsList": itgFormAttachmentsList, + "Message": message == null ? null : message, + "Mohemm_ITG_DepartmentSectionsList": mohemmItgDepartmentSectionsList, + "Mohemm_ITG_ProjectDepartmentsList": mohemmItgProjectDepartmentsList, + "Mohemm_ITG_ResponseItem": mohemmItgResponseItem, + "Mohemm_ITG_SectionTopicsList": mohemmItgSectionTopicsList, + "Mohemm_ITG_TicketDetailsList": mohemmItgTicketDetailsList, + "Mohemm_ITG_TicketTransactionsList": mohemmItgTicketTransactionsList, + "Mohemm_ITG_TicketsByEmployeeList": mohemmItgTicketsByEmployeeList, + "Mohemm_Itg_ProjectsList": mohemmItgProjectsList, + "Mohemm_Itg_TicketTypesList": mohemmItgTicketTypesList, + "ReferenceNumber": referenceNumber == null ? null : referenceNumber!.toIso8601String(), + "RequestType": requestType, + "TotalCount": totalCount == null ? null : totalCount, + "statuseCode": statuseCode == null ? null : statuseCode, + }; +} diff --git a/lib/models/generic_response_model.dart b/lib/models/generic_response_model.dart new file mode 100644 index 0000000..fad6e51 --- /dev/null +++ b/lib/models/generic_response_model.dart @@ -0,0 +1,1047 @@ +import 'package:mohem_flutter_app/models/member_login_list_model.dart'; + +import 'basic_member_information_model.dart'; +import 'dashboard/get_accrual_balances_list_model.dart'; +import 'dashboard/get_attendance_tracking_list_model.dart'; +import 'dashboard/get_open_missing_swipes_list_model.dart'; +import 'dashboard/get_open_notifications_list.dart'; +import 'member_information_list_model.dart'; +import 'privilege_list_model.dart'; + +class GenericResponseModel { + String? date; + int? languageID; + int? serviceName; + String? time; + String? androidLink; + String? authenticationTokenID; + String? data; + bool? dataw; + int? dietType; + int? dietTypeID; + String? errorCode; + String? errorEndUserMessage; + String? errorEndUserMessageN; + String? errorMessage; + int? errorType; + int? foodCategory; + String? iOSLink; + bool? isAuthenticated; + int? mealOrderStatus; + int? mealType; + int? messageStatus; + int? numberOfResultRecords; + String? patientBlodType; + String? successMsg; + String? successMsgN; + String? vidaUpdatedResponse; + String? addAttSuccessList; + String? addAttachmentList; + String? bCDomain; + String? bCLogo; + BasicMemberInformationModel? basicMemberInformation; + bool? businessCardPrivilege; + String? calculateAbsenceDuration; + String? cancelHRTransactionLIst; + String? chatEmployeeLoginList; + String? companyBadge; + String? companyImage; + String? companyImageDescription; + String? companyImageURL; + String? companyMainCompany; + String? countryList; + String? createVacationRuleList; + String? deleteAttachmentList; + String? deleteVacationRuleList; + String? disableSessionList; + String? employeeQR; + String? forgetPasswordTokenID; + List? getAbsenceAttachmentsList; + List? getAbsenceAttendanceTypesList; + List? getAbsenceCollectionNotificationBodyList; + List? getAbsenceDffStructureList; + List? getAbsenceTransactionList; + List? getAccrualBalancesList; + List? getActionHistoryList; + List? getAddressDffStructureList; + List? getAddressNotificationBodyList; + List? getApprovesList; + List? getAttachementList; + GetAttendanceTrackingList? getAttendanceTrackingList; + List? getBasicDetColsStructureList; + List? getBasicDetDffStructureList; + List? getBasicDetNtfBodyList; + List? getCEICollectionNotificationBodyList; + List? getCEIDFFStructureList; + List? getCEITransactionList; + List? getCcpDffStructureList; + List? getCcpOutputList; + List? getCcpTransactionsList; + List? getCcpTransactionsListNew; + List? getConcurrentProgramsList; + List? getContactColsStructureList; + List? getContactDetailsList; + List? getContactDffStructureList; + List? getContactNotificationBodyList; + List? getCountriesList; + List? getDayHoursTypeDetailsList; + List? getDeductionsList; + List? getDefaultValueList; + List? getEITCollectionNotificationBodyList; + List? getEITDFFStructureList; + List? getEITTransactionList; + List? getEarningsList; + List? getEmployeeAddressList; + List? getEmployeeBasicDetailsList; + List? getEmployeeContactsList; + List? getEmployeePhonesList; + List? getEmployeeSubordinatesList; + List? getFliexfieldStructureList; + List? getHrCollectionNotificationBodyList; + List? getHrTransactionList; + List? getItemCreationNtfBodyList; + List? getItemTypeNotificationsList; + List? getItemTypesList; + List? getLookupValuesList; + List? getMenuEntriesList; + List? getMoItemHistoryList; + List? getMoNotificationBodyList; + List? getNotificationButtonsList; + List? getNotificationReassignModeList; + List? getObjectValuesList; + GetOpenMissingSwipesList? getOpenMissingSwipesList; + List? getOpenNotificationsList; + List? getOpenNotificationsNumList; + List? getOpenPeriodDatesList; + List? getOrganizationsSalariesList; + List? getPaymentInformationList; + List? getPayslipList; + List? getPendingReqDetailsList; + List? getPendingReqFunctionsList; + List? getPerformanceAppraisalList; + List? getPhonesNotificationBodyList; + List? getPoItemHistoryList; + List? getPoNotificationBodyList; + List? getPrNotificationBodyList; + List? getQuotationAnalysisList; + List? getRFCEmployeeListList; + List? getRespondAttributeValueList; + List? getSITCollectionNotificationBodyList; + List? getSITDFFStructureList; + List? getSITTransactionList; + List? getScheduleShiftsDetailsList; + List? getShiftTypesList; + List? getStampMsNotificationBodyList; + List? getStampNsNotificationBodyList; + List? getSubordinatesAttdStatusList; + List? getSubordinatesLeavesList; + List? getSubordinatesLeavesTotalVacationsList; + List? getSummaryOfPaymentList; + List? getSwipesList; + List? getTermColsStructureList; + List? getTermDffStructureList; + List? getTermNotificationBodyList; + List? getTimeCardSummaryList; + List? getUserItemTypesList; + List? getVacationRulesList; + List? getVaccinationOnHandList; + List? getVaccinationsList; + List? getValueSetValuesList; + List? getWorkList; + String? hRCertificateTemplate; + String? imgURLsList; + String? insertApInv; + String? insertBooked; + String? insertEmpSwipesList; + String? insertJournal; + String? insertOrders; + String? intPortalGetEmployeeList; + bool? isDeviceTokenEmpty; + bool? isPasswordExpired; + bool? isRegisterAllowed; + bool? isRequriedValueSetEmpty; + bool? isUserSMSExcluded; + String? itemOnHand; + String? languageAvailable; + String? listSupplier; + String? listUserAgreement; + String? listEITStrucrure; + String? listItemImagesDetails; + String? listItemMaster; + String? listMedicineDetails; + String? listMenu; + String? listNewEmployees; + String? listRadScreen; + String? logInTokenID; + List? memberInformationList; + MemberLoginListModel? memberLoginList; + String? mohemmGetBusinessCardEnabledList; + List? mohemmGetFavoriteReplacementsList; + String? mohemmGetMobileDeviceInfobyEmpInfoList; + String? mohemmGetMobileLoginInfoList; + String? mohemmGetPatientIDList; + String? mohemmITGResponseItem; + bool? mohemmIsChangeIsActiveBusinessCardEnable; + bool? mohemmIsInsertBusinessCardEnable; + String? mohemmWifiPassword; + String? mohemmWifiSSID; + String? notificationAction; + String? notificationGetRespondAttributesList; + String? notificationRespondRolesList; + int? oracleOutPutNumber; + String? pASSWORDEXPIREDMSG; + String? pCOUNTRYCODE; + String? pCOUNTRYNAME; + String? pDESCFLEXCONTEXTCODE; + String? pDESCFLEXCONTEXTNAME; + Null? pForm; + String? pINFORMATION; + int? pMBLID; + String? pNUMOFSUBORDINATES; + String? pOPENNTFNUMBER; + String? pQUESTION; + int? pSESSIONID; + String? pSchema; + String? pharmacyStockAddPharmacyStockList; + String? pharmacyStockGetOnHandList; + List? privilegeList; + String? processTransactions; + String? registerUserNameList; + String? replacementList; + String? respondAttributesList; + String? respondRolesList; + String? resubmitAbsenceTransactionList; + String? resubmitEITTransactionList; + String? resubmitHrTransactionList; + String? sFHGetPoNotificationBodyList; + String? sFHGetPrNotificationBodyList; + String? startAbsenceApprovalProccess; + String? startAddressApprovalProcessList; + String? startBasicDetApprProcessList; + String? startCeiApprovalProcess; + String? startContactApprovalProcessList; + String? startEitApprovalProcess; + String? startHrApprovalProcessList; + String? startPhonesApprovalProcessList; + String? startSitApprovalProcess; + String? startTermApprovalProcessList; + String? submitAddressTransactionList; + String? submitBasicDetTransactionList; + String? submitCEITransactionList; + String? submitCcpTransactionList; + String? submitContactTransactionList; + String? submitEITTransactionList; + String? submitHrTransactionList; + String? submitPhonesTransactionList; + String? submitSITTransactionList; + String? submitTermTransactionList; + String? subordinatesOnLeavesList; + String? sumbitAbsenceTransactionList; + String? tokenID; + String? updateAttachmentList; + String? updateEmployeeImageList; + String? updateItemTypeSuccessList; + String? updateUserItemTypesList; + String? updateVacationRuleList; + String? vHREmployeeLoginList; + String? vHRGetEmployeeDetailsList; + String? vHRGetManagersDetailsList; + String? vHRGetProjectByCodeList; + bool? vHRIsVerificationCodeValid; + String? validateAbsenceTransactionList; + String? validateEITTransactionList; + String? validatePhonesTransactionList; + String? vrItemTypesList; + String? wFLookUpList; + String? eLearningGETEMPLOYEEPROFILEList; + String? eLearningLOGINList; + String? eLearningValidateLoginList; + String? eLearningValidate_LoginList; + 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.forgetPasswordTokenID, + this.getAbsenceAttachmentsList, + this.getAbsenceAttendanceTypesList, + this.getAbsenceCollectionNotificationBodyList, + this.getAbsenceDffStructureList, + this.getAbsenceTransactionList, + this.getAccrualBalancesList, + this.getActionHistoryList, + this.getAddressDffStructureList, + this.getAddressNotificationBodyList, + this.getApprovesList, + this.getAttachementList, + this.getAttendanceTrackingList, + this.getBasicDetColsStructureList, + this.getBasicDetDffStructureList, + this.getBasicDetNtfBodyList, + this.getCEICollectionNotificationBodyList, + this.getCEIDFFStructureList, + this.getCEITransactionList, + this.getCcpDffStructureList, + this.getCcpOutputList, + 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.getMoItemHistoryList, + this.getMoNotificationBodyList, + this.getNotificationButtonsList, + this.getNotificationReassignModeList, + this.getObjectValuesList, + this.getOpenMissingSwipesList, + this.getOpenNotificationsList, + this.getOpenNotificationsNumList, + this.getOpenPeriodDatesList, + this.getOrganizationsSalariesList, + this.getPaymentInformationList, + this.getPayslipList, + this.getPendingReqDetailsList, + this.getPendingReqFunctionsList, + this.getPerformanceAppraisalList, + this.getPhonesNotificationBodyList, + this.getPoItemHistoryList, + this.getPoNotificationBodyList, + this.getPrNotificationBodyList, + 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.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']; + languageID = json['LanguageID']; + serviceName = json['ServiceName']; + time = json['Time']; + androidLink = json['AndroidLink']; + authenticationTokenID = json['AuthenticationTokenID']; + data = json['Data']; + dataw = json['Dataw']; + dietType = json['DietType']; + dietTypeID = json['DietTypeID']; + errorCode = json['ErrorCode']; + errorEndUserMessage = json['ErrorEndUserMessage']; + errorEndUserMessageN = json['ErrorEndUserMessageN']; + errorMessage = json['ErrorMessage']; + errorType = json['ErrorType']; + foodCategory = json['FoodCategory']; + iOSLink = json['IOSLink']; + isAuthenticated = json['IsAuthenticated']; + mealOrderStatus = json['MealOrderStatus']; + mealType = json['MealType']; + messageStatus = json['MessageStatus']; + numberOfResultRecords = json['NumberOfResultRecords']; + patientBlodType = json['PatientBlodType']; + successMsg = json['SuccessMsg']; + successMsgN = json['SuccessMsgN']; + vidaUpdatedResponse = json['VidaUpdatedResponse']; + addAttSuccessList = json['AddAttSuccessList']; + addAttachmentList = json['AddAttachment_List']; + bCDomain = json['BC_Domain']; + bCLogo = json['BC_Logo']; + basicMemberInformation = json['BasicMemberInformation'] != null ? new BasicMemberInformationModel.fromJson(json['BasicMemberInformation']) : null; + businessCardPrivilege = json['BusinessCardPrivilege']; + calculateAbsenceDuration = json['CalculateAbsenceDuration']; + cancelHRTransactionLIst = json['CancelHRTransactionLIst']; + chatEmployeeLoginList = json['Chat_EmployeeLoginList']; + companyBadge = json['CompanyBadge']; + companyImage = json['CompanyImage']; + companyImageDescription = json['CompanyImageDescription']; + companyImageURL = json['CompanyImageURL']; + companyMainCompany = json['CompanyMainCompany']; + countryList = json['CountryList']; + createVacationRuleList = json['CreateVacationRuleList']; + deleteAttachmentList = json['DeleteAttachmentList']; + deleteVacationRuleList = json['DeleteVacationRuleList']; + disableSessionList = json['DisableSessionList']; + employeeQR = json['EmployeeQR']; + forgetPasswordTokenID = json['ForgetPasswordTokenID']; + getAbsenceAttachmentsList = json['GetAbsenceAttachmentsList']; + getAbsenceAttendanceTypesList = json['GetAbsenceAttendanceTypesList']; + getAbsenceCollectionNotificationBodyList = json['GetAbsenceCollectionNotificationBodyList']; + getAbsenceDffStructureList = json['GetAbsenceDffStructureList']; + getAbsenceTransactionList = json['GetAbsenceTransactionList']; + getAccrualBalancesList: + json["GetAccrualBalancesList"] == null ? null : List.from(json["GetAccrualBalancesList"].map((x) => GetAccrualBalancesList.fromJson(x))); + getActionHistoryList = json['GetActionHistoryList']; + getAddressDffStructureList = json['GetAddressDffStructureList']; + getAddressNotificationBodyList = json['GetAddressNotificationBodyList']; + getApprovesList = json['GetApprovesList']; + getAttachementList = json['GetAttachementList']; + getAttendanceTrackingList: + json["GetAttendanceTrackingList"] == null ? null : GetAttendanceTrackingList.fromMap(json["GetAttendanceTrackingList"]); + getBasicDetColsStructureList = json['GetBasicDetColsStructureList']; + getBasicDetDffStructureList = json['GetBasicDetDffStructureList']; + getBasicDetNtfBodyList = json['GetBasicDetNtfBodyList']; + getCEICollectionNotificationBodyList = json['GetCEICollectionNotificationBodyList']; + getCEIDFFStructureList = json['GetCEIDFFStructureList']; + getCEITransactionList = json['GetCEITransactionList']; + getCcpDffStructureList = json['GetCcpDffStructureList']; + getCcpOutputList = json['GetCcpOutputList']; + getCcpTransactionsList = json['GetCcpTransactionsList']; + getCcpTransactionsListNew = json['GetCcpTransactionsList_New']; + getConcurrentProgramsList = json['GetConcurrentProgramsList']; + getContactColsStructureList = json['GetContactColsStructureList']; + getContactDetailsList = json['GetContactDetailsList']; + getContactDffStructureList = json['GetContactDffStructureList']; + getContactNotificationBodyList = json['GetContactNotificationBodyList']; + getCountriesList = json['GetCountriesList']; + getDayHoursTypeDetailsList = json['GetDayHoursTypeDetailsList']; + getDeductionsList = json['GetDeductionsList']; + getDefaultValueList = json['GetDefaultValueList']; + getEITCollectionNotificationBodyList = json['GetEITCollectionNotificationBodyList']; + getEITDFFStructureList = json['GetEITDFFStructureList']; + getEITTransactionList = json['GetEITTransactionList']; + getEarningsList = json['GetEarningsList']; + getEmployeeAddressList = json['GetEmployeeAddressList']; + getEmployeeBasicDetailsList = json['GetEmployeeBasicDetailsList']; + getEmployeeContactsList = json['GetEmployeeContactsList']; + getEmployeePhonesList = json['GetEmployeePhonesList']; + getEmployeeSubordinatesList = json['GetEmployeeSubordinatesList']; + getFliexfieldStructureList = json['GetFliexfieldStructureList']; + getHrCollectionNotificationBodyList = json['GetHrCollectionNotificationBodyList']; + getHrTransactionList = json['GetHrTransactionList']; + getItemCreationNtfBodyList = json['GetItemCreationNtfBodyList']; + getItemTypeNotificationsList = json['GetItemTypeNotificationsList']; + getItemTypesList = json['GetItemTypesList']; + getLookupValuesList = json['GetLookupValuesList']; + getMenuEntriesList = json['GetMenuEntriesList']; + getMoItemHistoryList = json['GetMoItemHistoryList']; + getMoNotificationBodyList = json['GetMoNotificationBodyList']; + getNotificationButtonsList = json['GetNotificationButtonsList']; + getNotificationReassignModeList = json['GetNotificationReassignModeList']; + getObjectValuesList = json['GetObjectValuesList']; + getOpenMissingSwipesList: json["GetOpenMissingSwipesList"] == null ? null : GetOpenMissingSwipesList.fromJson(json["GetOpenMissingSwipesList"]); + getOpenNotificationsList: + json["GetOpenNotificationsList"] == null ? null : List.from(json["GetOpenNotificationsList"].map((x) => GetOpenNotificationsList.fromMap(x))); + getOpenNotificationsNumList = json['GetOpenNotificationsNumList']; + getOpenPeriodDatesList = json['GetOpenPeriodDatesList']; + getOrganizationsSalariesList = json['GetOrganizationsSalariesList']; + getPaymentInformationList = json['GetPaymentInformationList']; + getPayslipList = json['GetPayslipList']; + getPendingReqDetailsList = json['GetPendingReqDetailsList']; + getPendingReqFunctionsList = json['GetPendingReqFunctionsList']; + getPerformanceAppraisalList = json['GetPerformanceAppraisalList']; + getPhonesNotificationBodyList = json['GetPhonesNotificationBodyList']; + getPoItemHistoryList = json['GetPoItemHistoryList']; + getPoNotificationBodyList = json['GetPoNotificationBodyList']; + getPrNotificationBodyList = json['GetPrNotificationBodyList']; + getQuotationAnalysisList = json['GetQuotationAnalysisList']; + getRFCEmployeeListList = json['GetRFCEmployeeListList']; + getRespondAttributeValueList = json['GetRespondAttributeValueList']; + getSITCollectionNotificationBodyList = json['GetSITCollectionNotificationBodyList']; + getSITDFFStructureList = json['GetSITDFFStructureList']; + getSITTransactionList = json['GetSITTransactionList']; + getScheduleShiftsDetailsList = json['GetScheduleShiftsDetailsList']; + getShiftTypesList = json['GetShiftTypesList']; + getStampMsNotificationBodyList = json['GetStampMsNotificationBodyList']; + getStampNsNotificationBodyList = json['GetStampNsNotificationBodyList']; + getSubordinatesAttdStatusList = json['GetSubordinatesAttdStatusList']; + getSubordinatesLeavesList = json['GetSubordinatesLeavesList']; + getSubordinatesLeavesTotalVacationsList = json['GetSubordinatesLeavesTotalVacationsList']; + getSummaryOfPaymentList = json['GetSummaryOfPaymentList']; + getSwipesList = json['GetSwipesList']; + getTermColsStructureList = json['GetTermColsStructureList']; + getTermDffStructureList = json['GetTermDffStructureList']; + getTermNotificationBodyList = json['GetTermNotificationBodyList']; + getTimeCardSummaryList = json['GetTimeCardSummaryList']; + getUserItemTypesList = json['GetUserItemTypesList']; + getVacationRulesList = json['GetVacationRulesList']; + getVaccinationOnHandList = json['GetVaccinationOnHandList']; + getVaccinationsList = json['GetVaccinationsList']; + getValueSetValuesList = json['GetValueSetValuesList']; + getWorkList = json['GetWorkList']; + hRCertificateTemplate = json['HRCertificateTemplate']; + imgURLsList = json['ImgURLsList']; + insertApInv = json['InsertApInv']; + insertBooked = json['InsertBooked']; + insertEmpSwipesList = json['InsertEmpSwipesList']; + insertJournal = json['InsertJournal']; + insertOrders = json['InsertOrders']; + intPortalGetEmployeeList = json['IntPortalGetEmployeeList']; + isDeviceTokenEmpty = json['IsDeviceTokenEmpty']; + isPasswordExpired = json['IsPasswordExpired']; + isRegisterAllowed = json['IsRegisterAllowed']; + isRequriedValueSetEmpty = json['IsRequriedValueSetEmpty']; + isUserSMSExcluded = json['IsUserSMSExcluded']; + itemOnHand = json['ItemOnHand']; + languageAvailable = json['LanguageAvailable']; + listSupplier = json['ListSupplier']; + listUserAgreement = json['ListUserAgreement']; + listEITStrucrure = json['List_EITStrucrure']; + listItemImagesDetails = json['List_ItemImagesDetails']; + listItemMaster = json['List_ItemMaster']; + listMedicineDetails = json['List_MedicineDetails']; + listMenu = json['List_Menu']; + listNewEmployees = json['List_NewEmployees']; + listRadScreen = json['List_RadScreen']; + logInTokenID = json['LogInTokenID']; + if (json['MemberInformationList'] != null) { + memberInformationList = []; + json['MemberInformationList'].forEach((v) { + memberInformationList!.add(MemberInformationListModel.fromJson(v)); + }); + } + memberLoginList = json['MemberLoginList'] != null ? MemberLoginListModel.fromJson(json['MemberLoginList']) : null; + mohemmGetBusinessCardEnabledList = json['Mohemm_GetBusinessCardEnabledList']; + mohemmGetFavoriteReplacementsList = json['Mohemm_GetFavoriteReplacementsList']; + mohemmGetMobileDeviceInfobyEmpInfoList = json['Mohemm_GetMobileDeviceInfobyEmpInfoList']; + mohemmGetMobileLoginInfoList = json['Mohemm_GetMobileLoginInfoList']; + mohemmGetPatientIDList = json['Mohemm_GetPatientID_List']; + mohemmITGResponseItem = json['Mohemm_ITG_ResponseItem']; + mohemmIsChangeIsActiveBusinessCardEnable = json['Mohemm_IsChangeIsActiveBusinessCardEnable']; + mohemmIsInsertBusinessCardEnable = json['Mohemm_IsInsertBusinessCardEnable']; + mohemmWifiPassword = json['Mohemm_Wifi_Password']; + mohemmWifiSSID = json['Mohemm_Wifi_SSID']; + notificationAction = json['NotificationAction']; + notificationGetRespondAttributesList = json['NotificationGetRespondAttributesList']; + notificationRespondRolesList = json['NotificationRespondRolesList']; + oracleOutPutNumber = json['OracleOutPutNumber']; + pASSWORDEXPIREDMSG = json['PASSWORD_EXPIRED_MSG']; + pCOUNTRYCODE = json['P_COUNTRY_CODE']; + pCOUNTRYNAME = json['P_COUNTRY_NAME']; + pDESCFLEXCONTEXTCODE = json['P_DESC_FLEX_CONTEXT_CODE']; + pDESCFLEXCONTEXTNAME = json['P_DESC_FLEX_CONTEXT_NAME']; + pForm = json['P_Form']; + pINFORMATION = json['P_INFORMATION']; + pMBLID = json['P_MBL_ID']; + pNUMOFSUBORDINATES = json['P_NUM_OF_SUBORDINATES']; + pOPENNTFNUMBER = json['P_OPEN_NTF_NUMBER']; + pQUESTION = json['P_QUESTION']; + pSESSIONID = json['P_SESSION_ID']; + pSchema = json['P_Schema']; + pharmacyStockAddPharmacyStockList = json['PharmacyStock_AddPharmacyStockList']; + pharmacyStockGetOnHandList = json['PharmacyStock_GetOnHandList']; + + if (json['Privilege_List'] != null) { + privilegeList = []; + json['Privilege_List'].forEach((v) { + privilegeList!.add(PrivilegeListModel.fromJson(v)); + }); + } + + processTransactions = json['ProcessTransactions']; + registerUserNameList = json['RegisterUserNameList']; + replacementList = json['ReplacementList']; + respondAttributesList = json['RespondAttributesList']; + respondRolesList = json['RespondRolesList']; + resubmitAbsenceTransactionList = json['ResubmitAbsenceTransactionList']; + resubmitEITTransactionList = json['ResubmitEITTransactionList']; + resubmitHrTransactionList = json['ResubmitHrTransactionList']; + sFHGetPoNotificationBodyList = json['SFH_GetPoNotificationBodyList']; + sFHGetPrNotificationBodyList = json['SFH_GetPrNotificationBodyList']; + startAbsenceApprovalProccess = json['StartAbsenceApprovalProccess']; + startAddressApprovalProcessList = json['StartAddressApprovalProcessList']; + startBasicDetApprProcessList = json['StartBasicDetApprProcessList']; + startCeiApprovalProcess = json['StartCeiApprovalProcess']; + startContactApprovalProcessList = json['StartContactApprovalProcessList']; + startEitApprovalProcess = json['StartEitApprovalProcess']; + startHrApprovalProcessList = json['StartHrApprovalProcessList']; + startPhonesApprovalProcessList = json['StartPhonesApprovalProcessList']; + startSitApprovalProcess = json['StartSitApprovalProcess']; + startTermApprovalProcessList = json['StartTermApprovalProcessList']; + submitAddressTransactionList = json['SubmitAddressTransactionList']; + submitBasicDetTransactionList = json['SubmitBasicDetTransactionList']; + submitCEITransactionList = json['SubmitCEITransactionList']; + submitCcpTransactionList = json['SubmitCcpTransactionList']; + submitContactTransactionList = json['SubmitContactTransactionList']; + submitEITTransactionList = json['SubmitEITTransactionList']; + submitHrTransactionList = json['SubmitHrTransactionList']; + submitPhonesTransactionList = json['SubmitPhonesTransactionList']; + submitSITTransactionList = json['SubmitSITTransactionList']; + submitTermTransactionList = json['SubmitTermTransactionList']; + subordinatesOnLeavesList = json['SubordinatesOnLeavesList']; + sumbitAbsenceTransactionList = json['SumbitAbsenceTransactionList']; + tokenID = json['TokenID']; + updateAttachmentList = json['UpdateAttachmentList']; + updateEmployeeImageList = json['UpdateEmployeeImageList']; + updateItemTypeSuccessList = json['UpdateItemTypeSuccessList']; + updateUserItemTypesList = json['UpdateUserItemTypesList']; + updateVacationRuleList = json['UpdateVacationRuleList']; + vHREmployeeLoginList = json['VHR_EmployeeLoginList']; + vHRGetEmployeeDetailsList = json['VHR_GetEmployeeDetailsList']; + vHRGetManagersDetailsList = json['VHR_GetManagersDetailsList']; + vHRGetProjectByCodeList = json['VHR_GetProjectByCodeList']; + vHRIsVerificationCodeValid = json['VHR_IsVerificationCodeValid']; + validateAbsenceTransactionList = json['ValidateAbsenceTransactionList']; + validateEITTransactionList = json['ValidateEITTransactionList']; + validatePhonesTransactionList = json['ValidatePhonesTransactionList']; + vrItemTypesList = json['VrItemTypesList']; + wFLookUpList = json['WFLookUpList']; + eLearningGETEMPLOYEEPROFILEList = json['eLearning_GET_EMPLOYEE_PROFILEList']; + eLearningLOGINList = json['eLearning_LOGINList']; + eLearningValidateLoginList = json['eLearning_ValidateLoginList']; + eLearningValidate_LoginList = json['eLearning_Validate_LoginList']; + ePharmacyGetItemOnHandList = json['ePharmacy_GetItemOnHandList']; + isActiveCode = json['isActiveCode']; + isSMSSent = json['isSMSSent']; + } + + Map toJson() { + final Map data = new Map(); + data['Date'] = this.date; + data['LanguageID'] = this.languageID; + data['ServiceName'] = this.serviceName; + data['Time'] = this.time; + data['AndroidLink'] = this.androidLink; + data['AuthenticationTokenID'] = this.authenticationTokenID; + data['Data'] = this.data; + data['Dataw'] = this.dataw; + data['DietType'] = this.dietType; + data['DietTypeID'] = this.dietTypeID; + data['ErrorCode'] = this.errorCode; + data['ErrorEndUserMessage'] = this.errorEndUserMessage; + data['ErrorEndUserMessageN'] = this.errorEndUserMessageN; + data['ErrorMessage'] = this.errorMessage; + data['ErrorType'] = this.errorType; + data['FoodCategory'] = this.foodCategory; + data['IOSLink'] = this.iOSLink; + data['IsAuthenticated'] = this.isAuthenticated; + data['MealOrderStatus'] = this.mealOrderStatus; + data['MealType'] = this.mealType; + data['MessageStatus'] = this.messageStatus; + data['NumberOfResultRecords'] = this.numberOfResultRecords; + data['PatientBlodType'] = this.patientBlodType; + data['SuccessMsg'] = this.successMsg; + data['SuccessMsgN'] = this.successMsgN; + data['VidaUpdatedResponse'] = this.vidaUpdatedResponse; + data['AddAttSuccessList'] = this.addAttSuccessList; + data['AddAttachment_List'] = this.addAttachmentList; + data['BC_Domain'] = this.bCDomain; + data['BC_Logo'] = this.bCLogo; + if (this.basicMemberInformation != null) { + data['BasicMemberInformation'] = this.basicMemberInformation!.toJson(); + } + data['BusinessCardPrivilege'] = this.businessCardPrivilege; + data['CalculateAbsenceDuration'] = this.calculateAbsenceDuration; + data['CancelHRTransactionLIst'] = this.cancelHRTransactionLIst; + data['Chat_EmployeeLoginList'] = this.chatEmployeeLoginList; + data['CompanyBadge'] = this.companyBadge; + data['CompanyImage'] = this.companyImage; + data['CompanyImageDescription'] = this.companyImageDescription; + data['CompanyImageURL'] = this.companyImageURL; + data['CompanyMainCompany'] = this.companyMainCompany; + data['CountryList'] = this.countryList; + data['CreateVacationRuleList'] = this.createVacationRuleList; + data['DeleteAttachmentList'] = this.deleteAttachmentList; + data['DeleteVacationRuleList'] = this.deleteVacationRuleList; + data['DisableSessionList'] = this.disableSessionList; + data['EmployeeQR'] = this.employeeQR; + data['ForgetPasswordTokenID'] = this.forgetPasswordTokenID; + data['GetAbsenceAttachmentsList'] = this.getAbsenceAttachmentsList; + data['GetAbsenceAttendanceTypesList'] = this.getAbsenceAttendanceTypesList; + data['GetAbsenceCollectionNotificationBodyList'] = this.getAbsenceCollectionNotificationBodyList; + data['GetAbsenceDffStructureList'] = this.getAbsenceDffStructureList; + data['GetAbsenceTransactionList'] = this.getAbsenceTransactionList; + data['GetAccrualBalancesList'] = this.getAccrualBalancesList; + data['GetActionHistoryList'] = this.getActionHistoryList; + data['GetAddressDffStructureList'] = this.getAddressDffStructureList; + data['GetAddressNotificationBodyList'] = this.getAddressNotificationBodyList; + data['GetApprovesList'] = this.getApprovesList; + data['GetAttachementList'] = this.getAttachementList; + data['GetAttendanceTrackingList'] = this.getAttendanceTrackingList; + data['GetBasicDetColsStructureList'] = this.getBasicDetColsStructureList; + data['GetBasicDetDffStructureList'] = this.getBasicDetDffStructureList; + data['GetBasicDetNtfBodyList'] = this.getBasicDetNtfBodyList; + data['GetCEICollectionNotificationBodyList'] = this.getCEICollectionNotificationBodyList; + data['GetCEIDFFStructureList'] = this.getCEIDFFStructureList; + data['GetCEITransactionList'] = this.getCEITransactionList; + data['GetCcpDffStructureList'] = this.getCcpDffStructureList; + data['GetCcpOutputList'] = this.getCcpOutputList; + data['GetCcpTransactionsList'] = this.getCcpTransactionsList; + data['GetCcpTransactionsList_New'] = this.getCcpTransactionsListNew; + data['GetConcurrentProgramsList'] = this.getConcurrentProgramsList; + data['GetContactColsStructureList'] = this.getContactColsStructureList; + data['GetContactDetailsList'] = this.getContactDetailsList; + data['GetContactDffStructureList'] = this.getContactDffStructureList; + data['GetContactNotificationBodyList'] = this.getContactNotificationBodyList; + data['GetCountriesList'] = this.getCountriesList; + data['GetDayHoursTypeDetailsList'] = this.getDayHoursTypeDetailsList; + data['GetDeductionsList'] = this.getDeductionsList; + data['GetDefaultValueList'] = this.getDefaultValueList; + data['GetEITCollectionNotificationBodyList'] = this.getEITCollectionNotificationBodyList; + data['GetEITDFFStructureList'] = this.getEITDFFStructureList; + data['GetEITTransactionList'] = this.getEITTransactionList; + data['GetEarningsList'] = this.getEarningsList; + data['GetEmployeeAddressList'] = this.getEmployeeAddressList; + data['GetEmployeeBasicDetailsList'] = this.getEmployeeBasicDetailsList; + data['GetEmployeeContactsList'] = this.getEmployeeContactsList; + data['GetEmployeePhonesList'] = this.getEmployeePhonesList; + data['GetEmployeeSubordinatesList'] = this.getEmployeeSubordinatesList; + data['GetFliexfieldStructureList'] = this.getFliexfieldStructureList; + data['GetHrCollectionNotificationBodyList'] = this.getHrCollectionNotificationBodyList; + data['GetHrTransactionList'] = this.getHrTransactionList; + data['GetItemCreationNtfBodyList'] = this.getItemCreationNtfBodyList; + data['GetItemTypeNotificationsList'] = this.getItemTypeNotificationsList; + data['GetItemTypesList'] = this.getItemTypesList; + data['GetLookupValuesList'] = this.getLookupValuesList; + data['GetMenuEntriesList'] = this.getMenuEntriesList; + data['GetMoItemHistoryList'] = this.getMoItemHistoryList; + data['GetMoNotificationBodyList'] = this.getMoNotificationBodyList; + data['GetNotificationButtonsList'] = this.getNotificationButtonsList; + data['GetNotificationReassignModeList'] = this.getNotificationReassignModeList; + data['GetObjectValuesList'] = this.getObjectValuesList; + data['GetOpenMissingSwipesList'] = this.getOpenMissingSwipesList; + data['GetOpenNotificationsList'] = this.getOpenNotificationsList; + data['GetOpenNotificationsNumList'] = this.getOpenNotificationsNumList; + data['GetOpenPeriodDatesList'] = this.getOpenPeriodDatesList; + data['GetOrganizationsSalariesList'] = this.getOrganizationsSalariesList; + data['GetPaymentInformationList'] = this.getPaymentInformationList; + data['GetPayslipList'] = this.getPayslipList; + data['GetPendingReqDetailsList'] = this.getPendingReqDetailsList; + data['GetPendingReqFunctionsList'] = this.getPendingReqFunctionsList; + data['GetPerformanceAppraisalList'] = this.getPerformanceAppraisalList; + data['GetPhonesNotificationBodyList'] = this.getPhonesNotificationBodyList; + data['GetPoItemHistoryList'] = this.getPoItemHistoryList; + data['GetPoNotificationBodyList'] = this.getPoNotificationBodyList; + data['GetPrNotificationBodyList'] = this.getPrNotificationBodyList; + data['GetQuotationAnalysisList'] = this.getQuotationAnalysisList; + data['GetRFCEmployeeListList'] = this.getRFCEmployeeListList; + data['GetRespondAttributeValueList'] = this.getRespondAttributeValueList; + data['GetSITCollectionNotificationBodyList'] = this.getSITCollectionNotificationBodyList; + data['GetSITDFFStructureList'] = this.getSITDFFStructureList; + data['GetSITTransactionList'] = this.getSITTransactionList; + data['GetScheduleShiftsDetailsList'] = this.getScheduleShiftsDetailsList; + data['GetShiftTypesList'] = this.getShiftTypesList; + data['GetStampMsNotificationBodyList'] = this.getStampMsNotificationBodyList; + data['GetStampNsNotificationBodyList'] = this.getStampNsNotificationBodyList; + data['GetSubordinatesAttdStatusList'] = this.getSubordinatesAttdStatusList; + data['GetSubordinatesLeavesList'] = this.getSubordinatesLeavesList; + data['GetSubordinatesLeavesTotalVacationsList'] = this.getSubordinatesLeavesTotalVacationsList; + data['GetSummaryOfPaymentList'] = this.getSummaryOfPaymentList; + data['GetSwipesList'] = this.getSwipesList; + data['GetTermColsStructureList'] = this.getTermColsStructureList; + data['GetTermDffStructureList'] = this.getTermDffStructureList; + data['GetTermNotificationBodyList'] = this.getTermNotificationBodyList; + data['GetTimeCardSummaryList'] = this.getTimeCardSummaryList; + data['GetUserItemTypesList'] = this.getUserItemTypesList; + data['GetVacationRulesList'] = this.getVacationRulesList; + data['GetVaccinationOnHandList'] = this.getVaccinationOnHandList; + data['GetVaccinationsList'] = this.getVaccinationsList; + data['GetValueSetValuesList'] = this.getValueSetValuesList; + data['GetWorkList'] = this.getWorkList; + data['HRCertificateTemplate'] = this.hRCertificateTemplate; + data['ImgURLsList'] = this.imgURLsList; + data['InsertApInv'] = this.insertApInv; + data['InsertBooked'] = this.insertBooked; + data['InsertEmpSwipesList'] = this.insertEmpSwipesList; + data['InsertJournal'] = this.insertJournal; + data['InsertOrders'] = this.insertOrders; + data['IntPortalGetEmployeeList'] = this.intPortalGetEmployeeList; + data['IsDeviceTokenEmpty'] = this.isDeviceTokenEmpty; + data['IsPasswordExpired'] = this.isPasswordExpired; + data['IsRegisterAllowed'] = this.isRegisterAllowed; + data['IsRequriedValueSetEmpty'] = this.isRequriedValueSetEmpty; + data['IsUserSMSExcluded'] = this.isUserSMSExcluded; + data['ItemOnHand'] = this.itemOnHand; + data['LanguageAvailable'] = this.languageAvailable; + data['ListSupplier'] = this.listSupplier; + data['ListUserAgreement'] = this.listUserAgreement; + data['List_EITStrucrure'] = this.listEITStrucrure; + data['List_ItemImagesDetails'] = this.listItemImagesDetails; + data['List_ItemMaster'] = this.listItemMaster; + data['List_MedicineDetails'] = this.listMedicineDetails; + data['List_Menu'] = this.listMenu; + data['List_NewEmployees'] = this.listNewEmployees; + data['List_RadScreen'] = this.listRadScreen; + data['LogInTokenID'] = this.logInTokenID; + if (this.memberInformationList != null) { + data['MemberInformationList'] = this.memberInformationList!.map((v) => v.toJson()).toList(); + } + data['MemberLoginList'] = this.memberLoginList; + data['Mohemm_GetBusinessCardEnabledList'] = this.mohemmGetBusinessCardEnabledList; + data['Mohemm_GetFavoriteReplacementsList'] = this.mohemmGetFavoriteReplacementsList; + data['Mohemm_GetMobileDeviceInfobyEmpInfoList'] = this.mohemmGetMobileDeviceInfobyEmpInfoList; + data['Mohemm_GetMobileLoginInfoList'] = this.mohemmGetMobileLoginInfoList; + data['Mohemm_GetPatientID_List'] = this.mohemmGetPatientIDList; + data['Mohemm_ITG_ResponseItem'] = this.mohemmITGResponseItem; + data['Mohemm_IsChangeIsActiveBusinessCardEnable'] = this.mohemmIsChangeIsActiveBusinessCardEnable; + data['Mohemm_IsInsertBusinessCardEnable'] = this.mohemmIsInsertBusinessCardEnable; + data['Mohemm_Wifi_Password'] = this.mohemmWifiPassword; + data['Mohemm_Wifi_SSID'] = this.mohemmWifiSSID; + data['NotificationAction'] = this.notificationAction; + data['NotificationGetRespondAttributesList'] = this.notificationGetRespondAttributesList; + data['NotificationRespondRolesList'] = this.notificationRespondRolesList; + data['OracleOutPutNumber'] = this.oracleOutPutNumber; + data['PASSWORD_EXPIRED_MSG'] = this.pASSWORDEXPIREDMSG; + data['P_COUNTRY_CODE'] = this.pCOUNTRYCODE; + data['P_COUNTRY_NAME'] = this.pCOUNTRYNAME; + data['P_DESC_FLEX_CONTEXT_CODE'] = this.pDESCFLEXCONTEXTCODE; + data['P_DESC_FLEX_CONTEXT_NAME'] = this.pDESCFLEXCONTEXTNAME; + data['P_Form'] = this.pForm; + data['P_INFORMATION'] = this.pINFORMATION; + data['P_MBL_ID'] = this.pMBLID; + data['P_NUM_OF_SUBORDINATES'] = this.pNUMOFSUBORDINATES; + data['P_OPEN_NTF_NUMBER'] = this.pOPENNTFNUMBER; + data['P_QUESTION'] = this.pQUESTION; + data['P_SESSION_ID'] = this.pSESSIONID; + data['P_Schema'] = this.pSchema; + data['PharmacyStock_AddPharmacyStockList'] = this.pharmacyStockAddPharmacyStockList; + data['PharmacyStock_GetOnHandList'] = this.pharmacyStockGetOnHandList; + if (this.privilegeList != null) { + data['Privilege_List'] = this.privilegeList!.map((v) => v.toJson()).toList(); + } + data['ProcessTransactions'] = this.processTransactions; + data['RegisterUserNameList'] = this.registerUserNameList; + data['ReplacementList'] = this.replacementList; + data['RespondAttributesList'] = this.respondAttributesList; + data['RespondRolesList'] = this.respondRolesList; + data['ResubmitAbsenceTransactionList'] = this.resubmitAbsenceTransactionList; + data['ResubmitEITTransactionList'] = this.resubmitEITTransactionList; + data['ResubmitHrTransactionList'] = this.resubmitHrTransactionList; + data['SFH_GetPoNotificationBodyList'] = this.sFHGetPoNotificationBodyList; + data['SFH_GetPrNotificationBodyList'] = this.sFHGetPrNotificationBodyList; + data['StartAbsenceApprovalProccess'] = this.startAbsenceApprovalProccess; + data['StartAddressApprovalProcessList'] = this.startAddressApprovalProcessList; + data['StartBasicDetApprProcessList'] = this.startBasicDetApprProcessList; + data['StartCeiApprovalProcess'] = this.startCeiApprovalProcess; + data['StartContactApprovalProcessList'] = this.startContactApprovalProcessList; + data['StartEitApprovalProcess'] = this.startEitApprovalProcess; + data['StartHrApprovalProcessList'] = this.startHrApprovalProcessList; + data['StartPhonesApprovalProcessList'] = this.startPhonesApprovalProcessList; + data['StartSitApprovalProcess'] = this.startSitApprovalProcess; + data['StartTermApprovalProcessList'] = this.startTermApprovalProcessList; + data['SubmitAddressTransactionList'] = this.submitAddressTransactionList; + data['SubmitBasicDetTransactionList'] = this.submitBasicDetTransactionList; + data['SubmitCEITransactionList'] = this.submitCEITransactionList; + data['SubmitCcpTransactionList'] = this.submitCcpTransactionList; + data['SubmitContactTransactionList'] = this.submitContactTransactionList; + data['SubmitEITTransactionList'] = this.submitEITTransactionList; + data['SubmitHrTransactionList'] = this.submitHrTransactionList; + data['SubmitPhonesTransactionList'] = this.submitPhonesTransactionList; + data['SubmitSITTransactionList'] = this.submitSITTransactionList; + data['SubmitTermTransactionList'] = this.submitTermTransactionList; + data['SubordinatesOnLeavesList'] = this.subordinatesOnLeavesList; + data['SumbitAbsenceTransactionList'] = this.sumbitAbsenceTransactionList; + data['TokenID'] = this.tokenID; + data['UpdateAttachmentList'] = this.updateAttachmentList; + data['UpdateEmployeeImageList'] = this.updateEmployeeImageList; + data['UpdateItemTypeSuccessList'] = this.updateItemTypeSuccessList; + data['UpdateUserItemTypesList'] = this.updateUserItemTypesList; + data['UpdateVacationRuleList'] = this.updateVacationRuleList; + data['VHR_EmployeeLoginList'] = this.vHREmployeeLoginList; + data['VHR_GetEmployeeDetailsList'] = this.vHRGetEmployeeDetailsList; + data['VHR_GetManagersDetailsList'] = this.vHRGetManagersDetailsList; + data['VHR_GetProjectByCodeList'] = this.vHRGetProjectByCodeList; + data['VHR_IsVerificationCodeValid'] = this.vHRIsVerificationCodeValid; + data['ValidateAbsenceTransactionList'] = this.validateAbsenceTransactionList; + data['ValidateEITTransactionList'] = this.validateEITTransactionList; + data['ValidatePhonesTransactionList'] = this.validatePhonesTransactionList; + data['VrItemTypesList'] = this.vrItemTypesList; + data['WFLookUpList'] = this.wFLookUpList; + data['eLearning_GET_EMPLOYEE_PROFILEList'] = this.eLearningGETEMPLOYEEPROFILEList; + data['eLearning_LOGINList'] = this.eLearningLOGINList; + data['eLearning_ValidateLoginList'] = this.eLearningValidateLoginList; + data['eLearning_Validate_LoginList'] = this.eLearningValidateLoginList; + data['ePharmacy_GetItemOnHandList'] = this.ePharmacyGetItemOnHandList; + data['isActiveCode'] = this.isActiveCode; + data['isSMSSent'] = this.isSMSSent; + return data; + } +} diff --git a/lib/models/member_information_list_model.dart b/lib/models/member_information_list_model.dart new file mode 100644 index 0000000..a3bc05f --- /dev/null +++ b/lib/models/member_information_list_model.dart @@ -0,0 +1,336 @@ +class MemberInformationListModel { + String? aCTUALTERMINATIONDATE; + String? aSSIGNMENTENDDATE; + int? aSSIGNMENTID; + String? aSSIGNMENTNUMBER; + String? aSSIGNMENTSTARTDATE; + int? aSSIGNMENTSTATUSTYPEID; + String? aSSIGNMENTTYPE; + int? bUSINESSGROUPID; + String? bUSINESSGROUPNAME; + String? businessCardQR; + String? cURRENTEMPLOYEEFLAG; + String? eMPLOYEEDISPLAYNAME; + String? eMPLOYEEDISPLAYNAMEAr; + String? eMPLOYEEDISPLAYNAMEEn; + String? eMPLOYEEEMAILADDRESS; + String? eMPLOYEEIMAGE; + String? eMPLOYEEMOBILENUMBER; + String? eMPLOYEENAME; + String? eMPLOYEENAMEAr; + String? eMPLOYEENAMEEn; + String? eMPLOYEENUMBER; + String? eMPLOYEEWORKNUMBER; + String? eMPLOYMENTCATEGORY; + String? eMPLOYMENTCATEGORYMEANING; + String? employeeQR; + String? fREQUENCY; + String? fREQUENCYMEANING; + int? fROMROWNUM; + String? gRADEID; + String? gRADENAME; + String? hIREDATE; + int? jOBID; + String? jOBNAME; + String? jOBNAMEAr; + String? jOBNAMEEn; + int? lEDGERID; + int? lOCATIONID; + String? lOCATIONNAME; + String? mANUALTIMECARDFLAG; + String? mANUALTIMECARDMEANING; + String? mobileNumberWithZipCode; + String? nATIONALITYCODE; + String? nATIONALITYMEANING; + String? nATIONALIDENTIFIER; + String? nORMALHOURS; + int? nOOFROWS; + int? oRGANIZATIONID; + String? oRGANIZATIONNAME; + String? pAYROLLCODE; + int? pAYROLLID; + String? pAYROLLNAME; + int? pERSONID; + String? pERSONTYPE; + int? pERSONTYPEID; + String? pERINFORMATIONCATEGORY; + int? pOSITIONID; + String? pOSITIONNAME; + String? pRIMARYFLAG; + int? rOWNUM; + int? sERVICEDAYS; + int? sERVICEMONTHS; + int? sERVICEYEARS; + String? sUPERVISORASSIGNMENTID; + String? sUPERVISORDISPLAYNAME; + String? sUPERVISOREMAILADDRESS; + int? sUPERVISORID; + String? sUPERVISORMOBILENUMBER; + String? sUPERVISORNAME; + String? sUPERVISORNUMBER; + String? sUPERVISORWORKNUMBER; + String? sWIPESEXEMPTEDFLAG; + String? sWIPESEXEMPTEDMEANING; + String? sYSTEMPERSONTYPE; + String? tKEMAILADDRESS; + String? tKEMPLOYEEDISPLAYNAME; + String? tKEMPLOYEENAME; + String? tKEMPLOYEENUMBER; + int? tKPERSONID; + int? tOROWNUM; + String? uNITNUMBER; + String? uSERSTATUS; + + MemberInformationListModel( + {this.aCTUALTERMINATIONDATE, + this.aSSIGNMENTENDDATE, + this.aSSIGNMENTID, + this.aSSIGNMENTNUMBER, + this.aSSIGNMENTSTARTDATE, + this.aSSIGNMENTSTATUSTYPEID, + this.aSSIGNMENTTYPE, + this.bUSINESSGROUPID, + this.bUSINESSGROUPNAME, + this.businessCardQR, + this.cURRENTEMPLOYEEFLAG, + this.eMPLOYEEDISPLAYNAME, + this.eMPLOYEEDISPLAYNAMEAr, + this.eMPLOYEEDISPLAYNAMEEn, + this.eMPLOYEEEMAILADDRESS, + this.eMPLOYEEIMAGE, + this.eMPLOYEEMOBILENUMBER, + this.eMPLOYEENAME, + this.eMPLOYEENAMEAr, + this.eMPLOYEENAMEEn, + this.eMPLOYEENUMBER, + this.eMPLOYEEWORKNUMBER, + this.eMPLOYMENTCATEGORY, + this.eMPLOYMENTCATEGORYMEANING, + this.employeeQR, + this.fREQUENCY, + this.fREQUENCYMEANING, + this.fROMROWNUM, + this.gRADEID, + this.gRADENAME, + this.hIREDATE, + this.jOBID, + this.jOBNAME, + this.jOBNAMEAr, + this.jOBNAMEEn, + this.lEDGERID, + this.lOCATIONID, + this.lOCATIONNAME, + this.mANUALTIMECARDFLAG, + this.mANUALTIMECARDMEANING, + this.mobileNumberWithZipCode, + this.nATIONALITYCODE, + this.nATIONALITYMEANING, + this.nATIONALIDENTIFIER, + this.nORMALHOURS, + this.nOOFROWS, + this.oRGANIZATIONID, + this.oRGANIZATIONNAME, + this.pAYROLLCODE, + this.pAYROLLID, + this.pAYROLLNAME, + this.pERSONID, + this.pERSONTYPE, + this.pERSONTYPEID, + this.pERINFORMATIONCATEGORY, + this.pOSITIONID, + this.pOSITIONNAME, + this.pRIMARYFLAG, + this.rOWNUM, + this.sERVICEDAYS, + this.sERVICEMONTHS, + this.sERVICEYEARS, + this.sUPERVISORASSIGNMENTID, + this.sUPERVISORDISPLAYNAME, + this.sUPERVISOREMAILADDRESS, + this.sUPERVISORID, + this.sUPERVISORMOBILENUMBER, + this.sUPERVISORNAME, + this.sUPERVISORNUMBER, + this.sUPERVISORWORKNUMBER, + this.sWIPESEXEMPTEDFLAG, + this.sWIPESEXEMPTEDMEANING, + this.sYSTEMPERSONTYPE, + this.tKEMAILADDRESS, + this.tKEMPLOYEEDISPLAYNAME, + this.tKEMPLOYEENAME, + this.tKEMPLOYEENUMBER, + this.tKPERSONID, + this.tOROWNUM, + this.uNITNUMBER, + this.uSERSTATUS}); + + MemberInformationListModel.fromJson(Map json) { + aCTUALTERMINATIONDATE = json['ACTUAL_TERMINATION_DATE']; + aSSIGNMENTENDDATE = json['ASSIGNMENT_END_DATE']; + aSSIGNMENTID = json['ASSIGNMENT_ID']; + aSSIGNMENTNUMBER = json['ASSIGNMENT_NUMBER']; + aSSIGNMENTSTARTDATE = json['ASSIGNMENT_START_DATE']; + aSSIGNMENTSTATUSTYPEID = json['ASSIGNMENT_STATUS_TYPE_ID']; + aSSIGNMENTTYPE = json['ASSIGNMENT_TYPE']; + bUSINESSGROUPID = json['BUSINESS_GROUP_ID']; + bUSINESSGROUPNAME = json['BUSINESS_GROUP_NAME']; + businessCardQR = json['BusinessCardQR']; + cURRENTEMPLOYEEFLAG = json['CURRENT_EMPLOYEE_FLAG']; + eMPLOYEEDISPLAYNAME = json['EMPLOYEE_DISPLAY_NAME']; + eMPLOYEEDISPLAYNAMEAr = json['EMPLOYEE_DISPLAY_NAME_Ar']; + eMPLOYEEDISPLAYNAMEEn = json['EMPLOYEE_DISPLAY_NAME_En']; + eMPLOYEEEMAILADDRESS = json['EMPLOYEE_EMAIL_ADDRESS']; + eMPLOYEEIMAGE = json['EMPLOYEE_IMAGE']; + eMPLOYEEMOBILENUMBER = json['EMPLOYEE_MOBILE_NUMBER']; + eMPLOYEENAME = json['EMPLOYEE_NAME']; + eMPLOYEENAMEAr = json['EMPLOYEE_NAME_Ar']; + eMPLOYEENAMEEn = json['EMPLOYEE_NAME_En']; + eMPLOYEENUMBER = json['EMPLOYEE_NUMBER']; + eMPLOYEEWORKNUMBER = json['EMPLOYEE_WORK_NUMBER']; + eMPLOYMENTCATEGORY = json['EMPLOYMENT_CATEGORY']; + eMPLOYMENTCATEGORYMEANING = json['EMPLOYMENT_CATEGORY_MEANING']; + employeeQR = json['EmployeeQR']; + fREQUENCY = json['FREQUENCY']; + fREQUENCYMEANING = json['FREQUENCY_MEANING']; + fROMROWNUM = json['FROM_ROW_NUM']; + gRADEID = json['GRADE_ID']; + gRADENAME = json['GRADE_NAME']; + hIREDATE = json['HIRE_DATE']; + jOBID = json['JOB_ID']; + jOBNAME = json['JOB_NAME']; + jOBNAMEAr = json['JOB_NAME_Ar']; + jOBNAMEEn = json['JOB_NAME_En']; + lEDGERID = json['LEDGER_ID']; + lOCATIONID = json['LOCATION_ID']; + lOCATIONNAME = json['LOCATION_NAME']; + mANUALTIMECARDFLAG = json['MANUAL_TIMECARD_FLAG']; + mANUALTIMECARDMEANING = json['MANUAL_TIMECARD_MEANING']; + mobileNumberWithZipCode = json['MobileNumberWithZipCode']; + nATIONALITYCODE = json['NATIONALITY_CODE']; + nATIONALITYMEANING = json['NATIONALITY_MEANING']; + nATIONALIDENTIFIER = json['NATIONAL_IDENTIFIER']; + nORMALHOURS = json['NORMAL_HOURS']; + nOOFROWS = json['NO_OF_ROWS']; + oRGANIZATIONID = json['ORGANIZATION_ID']; + oRGANIZATIONNAME = json['ORGANIZATION_NAME']; + pAYROLLCODE = json['PAYROLL_CODE']; + pAYROLLID = json['PAYROLL_ID']; + pAYROLLNAME = json['PAYROLL_NAME']; + pERSONID = json['PERSON_ID']; + pERSONTYPE = json['PERSON_TYPE']; + pERSONTYPEID = json['PERSON_TYPE_ID']; + pERINFORMATIONCATEGORY = json['PER_INFORMATION_CATEGORY']; + pOSITIONID = json['POSITION_ID']; + pOSITIONNAME = json['POSITION_NAME']; + pRIMARYFLAG = json['PRIMARY_FLAG']; + rOWNUM = json['ROW_NUM']; + sERVICEDAYS = json['SERVICE_DAYS']; + sERVICEMONTHS = json['SERVICE_MONTHS']; + sERVICEYEARS = json['SERVICE_YEARS']; + sUPERVISORASSIGNMENTID = json['SUPERVISOR_ASSIGNMENT_ID']; + sUPERVISORDISPLAYNAME = json['SUPERVISOR_DISPLAY_NAME']; + sUPERVISOREMAILADDRESS = json['SUPERVISOR_EMAIL_ADDRESS']; + sUPERVISORID = json['SUPERVISOR_ID']; + sUPERVISORMOBILENUMBER = json['SUPERVISOR_MOBILE_NUMBER']; + sUPERVISORNAME = json['SUPERVISOR_NAME']; + sUPERVISORNUMBER = json['SUPERVISOR_NUMBER']; + sUPERVISORWORKNUMBER = json['SUPERVISOR_WORK_NUMBER']; + sWIPESEXEMPTEDFLAG = json['SWIPES_EXEMPTED_FLAG']; + sWIPESEXEMPTEDMEANING = json['SWIPES_EXEMPTED_MEANING']; + sYSTEMPERSONTYPE = json['SYSTEM_PERSON_TYPE']; + tKEMAILADDRESS = json['TK_EMAIL_ADDRESS']; + tKEMPLOYEEDISPLAYNAME = json['TK_EMPLOYEE_DISPLAY_NAME']; + tKEMPLOYEENAME = json['TK_EMPLOYEE_NAME']; + tKEMPLOYEENUMBER = json['TK_EMPLOYEE_NUMBER']; + tKPERSONID = json['TK_PERSON_ID']; + tOROWNUM = json['TO_ROW_NUM']; + uNITNUMBER = json['UNIT_NUMBER']; + uSERSTATUS = json['USER_STATUS']; + } + + Map toJson() { + final Map data = new Map(); + data['ACTUAL_TERMINATION_DATE'] = this.aCTUALTERMINATIONDATE; + data['ASSIGNMENT_END_DATE'] = this.aSSIGNMENTENDDATE; + data['ASSIGNMENT_ID'] = this.aSSIGNMENTID; + data['ASSIGNMENT_NUMBER'] = this.aSSIGNMENTNUMBER; + data['ASSIGNMENT_START_DATE'] = this.aSSIGNMENTSTARTDATE; + data['ASSIGNMENT_STATUS_TYPE_ID'] = this.aSSIGNMENTSTATUSTYPEID; + data['ASSIGNMENT_TYPE'] = this.aSSIGNMENTTYPE; + data['BUSINESS_GROUP_ID'] = this.bUSINESSGROUPID; + data['BUSINESS_GROUP_NAME'] = this.bUSINESSGROUPNAME; + data['BusinessCardQR'] = this.businessCardQR; + data['CURRENT_EMPLOYEE_FLAG'] = this.cURRENTEMPLOYEEFLAG; + data['EMPLOYEE_DISPLAY_NAME'] = this.eMPLOYEEDISPLAYNAME; + data['EMPLOYEE_DISPLAY_NAME_Ar'] = this.eMPLOYEEDISPLAYNAMEAr; + data['EMPLOYEE_DISPLAY_NAME_En'] = this.eMPLOYEEDISPLAYNAMEEn; + data['EMPLOYEE_EMAIL_ADDRESS'] = this.eMPLOYEEEMAILADDRESS; + data['EMPLOYEE_IMAGE'] = this.eMPLOYEEIMAGE; + data['EMPLOYEE_MOBILE_NUMBER'] = this.eMPLOYEEMOBILENUMBER; + data['EMPLOYEE_NAME'] = this.eMPLOYEENAME; + data['EMPLOYEE_NAME_Ar'] = this.eMPLOYEENAMEAr; + data['EMPLOYEE_NAME_En'] = this.eMPLOYEENAMEEn; + data['EMPLOYEE_NUMBER'] = this.eMPLOYEENUMBER; + data['EMPLOYEE_WORK_NUMBER'] = this.eMPLOYEEWORKNUMBER; + data['EMPLOYMENT_CATEGORY'] = this.eMPLOYMENTCATEGORY; + data['EMPLOYMENT_CATEGORY_MEANING'] = this.eMPLOYMENTCATEGORYMEANING; + data['EmployeeQR'] = this.employeeQR; + data['FREQUENCY'] = this.fREQUENCY; + data['FREQUENCY_MEANING'] = this.fREQUENCYMEANING; + data['FROM_ROW_NUM'] = this.fROMROWNUM; + data['GRADE_ID'] = this.gRADEID; + data['GRADE_NAME'] = this.gRADENAME; + data['HIRE_DATE'] = this.hIREDATE; + data['JOB_ID'] = this.jOBID; + data['JOB_NAME'] = this.jOBNAME; + data['JOB_NAME_Ar'] = this.jOBNAMEAr; + data['JOB_NAME_En'] = this.jOBNAMEEn; + data['LEDGER_ID'] = this.lEDGERID; + data['LOCATION_ID'] = this.lOCATIONID; + data['LOCATION_NAME'] = this.lOCATIONNAME; + data['MANUAL_TIMECARD_FLAG'] = this.mANUALTIMECARDFLAG; + data['MANUAL_TIMECARD_MEANING'] = this.mANUALTIMECARDMEANING; + data['MobileNumberWithZipCode'] = this.mobileNumberWithZipCode; + data['NATIONALITY_CODE'] = this.nATIONALITYCODE; + data['NATIONALITY_MEANING'] = this.nATIONALITYMEANING; + data['NATIONAL_IDENTIFIER'] = this.nATIONALIDENTIFIER; + data['NORMAL_HOURS'] = this.nORMALHOURS; + data['NO_OF_ROWS'] = this.nOOFROWS; + data['ORGANIZATION_ID'] = this.oRGANIZATIONID; + data['ORGANIZATION_NAME'] = this.oRGANIZATIONNAME; + data['PAYROLL_CODE'] = this.pAYROLLCODE; + data['PAYROLL_ID'] = this.pAYROLLID; + data['PAYROLL_NAME'] = this.pAYROLLNAME; + data['PERSON_ID'] = this.pERSONID; + data['PERSON_TYPE'] = this.pERSONTYPE; + data['PERSON_TYPE_ID'] = this.pERSONTYPEID; + data['PER_INFORMATION_CATEGORY'] = this.pERINFORMATIONCATEGORY; + data['POSITION_ID'] = this.pOSITIONID; + data['POSITION_NAME'] = this.pOSITIONNAME; + data['PRIMARY_FLAG'] = this.pRIMARYFLAG; + data['ROW_NUM'] = this.rOWNUM; + data['SERVICE_DAYS'] = this.sERVICEDAYS; + data['SERVICE_MONTHS'] = this.sERVICEMONTHS; + data['SERVICE_YEARS'] = this.sERVICEYEARS; + data['SUPERVISOR_ASSIGNMENT_ID'] = this.sUPERVISORASSIGNMENTID; + data['SUPERVISOR_DISPLAY_NAME'] = this.sUPERVISORDISPLAYNAME; + data['SUPERVISOR_EMAIL_ADDRESS'] = this.sUPERVISOREMAILADDRESS; + data['SUPERVISOR_ID'] = this.sUPERVISORID; + data['SUPERVISOR_MOBILE_NUMBER'] = this.sUPERVISORMOBILENUMBER; + data['SUPERVISOR_NAME'] = this.sUPERVISORNAME; + data['SUPERVISOR_NUMBER'] = this.sUPERVISORNUMBER; + data['SUPERVISOR_WORK_NUMBER'] = this.sUPERVISORWORKNUMBER; + data['SWIPES_EXEMPTED_FLAG'] = this.sWIPESEXEMPTEDFLAG; + data['SWIPES_EXEMPTED_MEANING'] = this.sWIPESEXEMPTEDMEANING; + data['SYSTEM_PERSON_TYPE'] = this.sYSTEMPERSONTYPE; + data['TK_EMAIL_ADDRESS'] = this.tKEMAILADDRESS; + data['TK_EMPLOYEE_DISPLAY_NAME'] = this.tKEMPLOYEEDISPLAYNAME; + data['TK_EMPLOYEE_NAME'] = this.tKEMPLOYEENAME; + data['TK_EMPLOYEE_NUMBER'] = this.tKEMPLOYEENUMBER; + data['TK_PERSON_ID'] = this.tKPERSONID; + data['TO_ROW_NUM'] = this.tOROWNUM; + data['UNIT_NUMBER'] = this.uNITNUMBER; + data['USER_STATUS'] = this.uSERSTATUS; + return data; + } +} \ No newline at end of file diff --git a/lib/models/member_login_list_model.dart b/lib/models/member_login_list_model.dart new file mode 100644 index 0000000..ffbc942 --- /dev/null +++ b/lib/models/member_login_list_model.dart @@ -0,0 +1,48 @@ +class MemberLoginListModel { + String? pEMAILADDRESS; + String? pINVALIDLOGINMSG; + String? pLEGISLATIONCODE; + String? pMOBILENUMBER; + String? pPASSOWRDEXPIRED; + String? pPASSWORDEXPIREDMSG; + String? pRETURNMSG; + String? pRETURNSTATUS; + int? pSESSIONID; + + MemberLoginListModel( + {this.pEMAILADDRESS, + this.pINVALIDLOGINMSG, + this.pLEGISLATIONCODE, + this.pMOBILENUMBER, + this.pPASSOWRDEXPIRED, + this.pPASSWORDEXPIREDMSG, + this.pRETURNMSG, + this.pRETURNSTATUS, + this.pSESSIONID}); + + MemberLoginListModel.fromJson(Map json) { + pEMAILADDRESS = json['P_EMAIL_ADDRESS']; + pINVALIDLOGINMSG = json['P_INVALID_LOGIN_MSG']; + pLEGISLATIONCODE = json['P_LEGISLATION_CODE']; + pMOBILENUMBER = json['P_MOBILE_NUMBER']; + pPASSOWRDEXPIRED = json['P_PASSOWRD_EXPIRED']; + pPASSWORDEXPIREDMSG = json['P_PASSWORD_EXPIRED_MSG']; + pRETURNMSG = json['P_RETURN_MSG']; + pRETURNSTATUS = json['P_RETURN_STATUS']; + pSESSIONID = json['P_SESSION_ID']; + } + + Map toJson() { + final Map data = new Map(); + data['P_EMAIL_ADDRESS'] = this.pEMAILADDRESS; + data['P_INVALID_LOGIN_MSG'] = this.pINVALIDLOGINMSG; + data['P_LEGISLATION_CODE'] = this.pLEGISLATIONCODE; + data['P_MOBILE_NUMBER'] = this.pMOBILENUMBER; + data['P_PASSOWRD_EXPIRED'] = this.pPASSOWRDEXPIRED; + data['P_PASSWORD_EXPIRED_MSG'] = this.pPASSWORDEXPIREDMSG; + data['P_RETURN_MSG'] = this.pRETURNMSG; + data['P_RETURN_STATUS'] = this.pRETURNSTATUS; + data['P_SESSION_ID'] = this.pSESSIONID; + return data; + } +} diff --git a/lib/models/post_params_model.dart b/lib/models/post_params_model.dart new file mode 100644 index 0000000..1ab86f7 --- /dev/null +++ b/lib/models/post_params_model.dart @@ -0,0 +1,83 @@ +class PostParamsModel { + double? versionID; + int? channel; + int? languageID; + String? mobileType; + String? logInTokenID; + String? tokenID; + String? mobileNumber; + String? pEmailAddress; + String? pUserName; + String? pSelectedEmployeeNumber; + int? pSessionId; + String? userName; + + PostParamsModel({ + this.versionID, + this.channel, + this.languageID, + this.mobileType, + this.logInTokenID, + this.tokenID, + this.mobileNumber, + this.userName, + this.pEmailAddress, + this.pSessionId, + this.pUserName, + this.pSelectedEmployeeNumber, + }); + + PostParamsModel.fromJson(Map json) { + versionID = json['VersionID']; + channel = json['Channel']; + languageID = json['LanguageID']; + mobileType = json['MobileType']; + logInTokenID = json['LogInTokenID']; + tokenID = json['TokenID']; + } + + Map toJson() { + final Map data = new Map(); + data['VersionID'] = this.versionID; + data['Channel'] = this.channel; + data['LanguageID'] = this.languageID; + data['MobileType'] = this.mobileType; + data['LogInTokenID'] = this.logInTokenID; + data['TokenID'] = this.tokenID; + return data; + } + + Map toJsonAfterLogin() { + final Map data = new Map(); + data['VersionID'] = this.versionID; + data['Channel'] = this.channel; + data['LanguageID'] = this.languageID; + data['MobileType'] = this.mobileType; + data['LogInTokenID'] = this.logInTokenID; + data['TokenID'] = this.tokenID; + data['MobileNumber'] = this.mobileNumber; + data['UserName'] = this.userName; + data['P_EMAIL_ADDRESS'] = this.pEmailAddress; + data['P_SESSION_ID'] = this.pSessionId; + data['P_SELECTED_EMPLOYEE_NUMBER'] = this.pSelectedEmployeeNumber; + data['P_USER_NAME'] = this.pUserName; + + return data; + } + + set setLogInTokenID(String? token) => logInTokenID = token; + + set setTokenID(String? token) => tokenID = token; + + set setMobileNumer(String? v) => mobileNumber = v; + + set setUserName(String? v) => userName = v; + + set setPEmailAddress(String? v) => pEmailAddress = v; + + set setPSessionId(int? v) => pSessionId = v; + + set setPUserName(String? v) => pUserName = v; + + set setPSelectedEmployeeNumber(String? v) => pSelectedEmployeeNumber = v; +} diff --git a/lib/models/privilege_list_model.dart b/lib/models/privilege_list_model.dart new file mode 100644 index 0000000..3ef3954 --- /dev/null +++ b/lib/models/privilege_list_model.dart @@ -0,0 +1,21 @@ +class PrivilegeListModel { + int? iD; + String? serviceName; + bool? previlege; + + PrivilegeListModel({this.iD, this.serviceName, this.previlege}); + + PrivilegeListModel.fromJson(Map json) { + iD = json['ID']; + serviceName = json['ServiceName']; + previlege = json['Previlege']; + } + + Map toJson() { + final Map data = new Map(); + data['ID'] = this.iD; + data['ServiceName'] = this.serviceName; + data['Previlege'] = this.previlege; + return data; + } +} diff --git a/lib/models/surah_model.dart b/lib/models/surah_model.dart new file mode 100644 index 0000000..acc171a --- /dev/null +++ b/lib/models/surah_model.dart @@ -0,0 +1,74 @@ +class SurahModel { + int? totalItemsCount; + int? statusCode; + String? message; + List? data; + + SurahModel({this.totalItemsCount, this.statusCode, this.message, this.data}); + + SurahModel.fromJson(Map json) { + totalItemsCount = json['totalItemsCount']; + statusCode = json['statusCode']; + message = json['message']; + if (json['data'] != null) { + data = []; + json['data'].forEach((v) { + data?.add(SurahModelData.fromJson(v)); + }); + } + } + + Map toJson() { + final Map data = new Map(); + data['totalItemsCount'] = totalItemsCount; + data['statusCode'] = statusCode; + data['message'] = message; + if (this.data != null) { + data['data'] = this.data?.map((v) => v.toJson()).toList(); + } + return data; + } +} + +class SurahModelData { + int? id; + int? surahID; + String? nameAR; + String? nameEN; + int? numberOfAyahs; + String? englishNameTranslation; + int? revelationID; + String? revelationType; + int? startPageNo; + int? endPageNo; + + SurahModelData({this.id, this.surahID, this.nameAR, this.nameEN, this.numberOfAyahs, this.englishNameTranslation, this.revelationID, this.revelationType, this.startPageNo, this.endPageNo}); + + SurahModelData.fromJson(Map json) { + id = json['id']; + surahID = json['surahID']; + nameAR = json['nameAR']; + nameEN = json['nameEN']; + numberOfAyahs = json['numberOfAyahs']; + englishNameTranslation = json['englishNameTranslation']; + revelationID = json['revelation_ID']; + revelationType = json['revelationType']; + startPageNo = json['startPageNo']; + endPageNo = json['endPageNo']; + } + + Map toJson() { + final Map data = new Map(); + data['id'] = this.id; + data['surahID'] = this.surahID; + data['nameAR'] = this.nameAR; + data['nameEN'] = this.nameEN; + data['numberOfAyahs'] = this.numberOfAyahs; + data['englishNameTranslation'] = this.englishNameTranslation; + data['revelation_ID'] = this.revelationID; + data['revelationType'] = this.revelationType; + data['startPageNo'] = this.startPageNo; + data['endPageNo'] = this.endPageNo; + return data; + } +} diff --git a/lib/theme/app_theme.dart b/lib/theme/app_theme.dart new file mode 100644 index 0000000..51987cd --- /dev/null +++ b/lib/theme/app_theme.dart @@ -0,0 +1,60 @@ +import 'package:flutter/material.dart'; +import 'package:mohem_flutter_app/classes/colors.dart'; +import 'package:mohem_flutter_app/theme/colors.dart'; + +class AppTheme { + static getTheme(isArabic) => ThemeData( + fontFamily: isArabic ? 'Cairo' : 'Poppins', + primarySwatch: Colors.red, + visualDensity: VisualDensity.adaptivePlatformDensity, + brightness: Brightness.light, + pageTransitionsTheme: const PageTransitionsTheme( + builders: { + TargetPlatform.android: ZoomPageTransitionsBuilder(), + TargetPlatform.iOS: CupertinoPageTransitionsBuilder(), + }, + ), + hintColor: Colors.grey[400], + colorScheme: ColorScheme.fromSwatch(accentColor: MyColors.backgroundColor), + disabledColor: Colors.grey[300], + errorColor: const Color.fromRGBO(235, 80, 60, 1.0), + 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, + buttonColor: Colors.black, + 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( + 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( + color: const Color(0xff515A5D), + brightness: Brightness.light, + elevation: 0.0, + actionsIconTheme: IconThemeData( + color: Colors.grey[800], + ), + ), + ); +} + +extension ExtendedRevoCheckTheme on TextTheme { + //add custom styles and colors here + //taken from https://medium.com/@crizantlai/flutter-how-to-extend-themedata-b5b987a95bb5 + TextStyle get price => const TextStyle(color: Colors.redAccent); +} diff --git a/lib/theme/colors.dart b/lib/theme/colors.dart new file mode 100644 index 0000000..67b5a6f --- /dev/null +++ b/lib/theme/colors.dart @@ -0,0 +1,13 @@ +import 'package:flutter/material.dart'; + +const Color primaryColor = Color(0xffF8F8F8); +const Color secondaryColor = Color(0xff2BB8A6); +const Color accentColor = Colors.blue; +const Color appBackgroundColor = Colors.white; +Color? accentColorDark = Colors.green[800]; +const Color borderColor = Color(0xffE8E8E8); +Color? borderLightColor = Colors.blueGrey[50]; +Color backgroudColor = Colors.blueGrey[50]!.withOpacity(0.5); +const Color iconColor = Colors.blueGrey; +Color? headingColor = Colors.blueGrey[800]; +Color? txtColor = Colors.blueGrey[500]; diff --git a/lib/ui/app_bar.dart b/lib/ui/app_bar.dart new file mode 100644 index 0000000..c39e249 --- /dev/null +++ b/lib/ui/app_bar.dart @@ -0,0 +1,26 @@ +import 'package:easy_localization/src/public_ext.dart'; +import 'package:flutter/material.dart'; +import 'package:mohem_flutter_app/classes/colors.dart'; +import 'package:mohem_flutter_app/generated/locale_keys.g.dart'; +import 'package:mohem_flutter_app/extensions/string_extensions.dart'; + +AppBar appBar(BuildContext context, {required String title}) { + return AppBar( + title: title.toText24(color: MyColors.darkTextColor), + centerTitle: false, + automaticallyImplyLeading: false, + backgroundColor: Colors.white, + + actions: [ + IconButton( + onPressed: () { + Navigator.pop(context); + }, + icon: Icon( + Icons.close, + color: MyColors.darkIconColor, + ), + ), + ], + ); +} diff --git a/lib/ui/bottom_sheets/country_selection_bottom_sheet.dart b/lib/ui/bottom_sheets/country_selection_bottom_sheet.dart new file mode 100644 index 0000000..905c5ce --- /dev/null +++ b/lib/ui/bottom_sheets/country_selection_bottom_sheet.dart @@ -0,0 +1,103 @@ +// import 'package:flutter/material.dart'; +// import 'package:tangheem/classes/colors.dart'; +// import 'package:tangheem/models/country_model.dart'; +// import 'package:tangheem/widgets/common_textfield_widget.dart'; +// +// class CountrySelectionBottomSheet extends StatefulWidget { +// final List countryList; +// final Function(CountryModelData) onSelectCountry; +// +// CountrySelectionBottomSheet({Key key, this.countryList, this.onSelectCountry}) : super(key: key); +// +// @override +// _CountrySelectionBottomSheetState createState() { +// return _CountrySelectionBottomSheetState(); +// } +// } +// +// class _CountrySelectionBottomSheetState extends State { +// TextEditingController _searchCountryController = TextEditingController(); +// List _filteredCountryList = []; +// +// @override +// void initState() { +// super.initState(); +// _searchCountryController.addListener(_onTextChange); +// _filterList(""); +// } +// +// void _filterList(String _query) { +// _filteredCountryList = []; +// if (_query.isEmpty) { +// _filteredCountryList = widget.countryList; +// } else { +// _filteredCountryList = widget.countryList.where((element) => element.countryNameAr.contains(_query) || element.countryNameEn.toLowerCase().contains(_query.toLowerCase()))?.toList() ?? []; +// } +// setState(() {}); +// } +// +// void _onTextChange() { +// var _searchText = _searchCountryController.text; +// _filterList(_searchText); +// } +// +// @override +// void dispose() { +// super.dispose(); +// } +// +// @override +// Widget build(BuildContext context) { +// return Directionality( +// textDirection: TextDirection.rtl, +// child: Container( +// height: MediaQuery.of(context).size.height * 0.75, +// padding: EdgeInsets.all(16), +// decoration: BoxDecoration( +// color: Colors.white, +// borderRadius: BorderRadius.only( +// topLeft: Radius.circular(16), +// topRight: Radius.circular(16), +// ), +// ), +// child: Column( +// children: [ +// Container( +// padding: EdgeInsets.all(8), +// height: 54, +// decoration: BoxDecoration( +// color: ColorConsts.primaryBlue, +// borderRadius: BorderRadius.only( +// topLeft: Radius.circular(12), +// topRight: Radius.circular(12), +// bottomRight: Radius.circular(12), +// bottomLeft: Radius.circular(12), +// ), +// ), +// child: CommonTextFieldWidget(hint: "البحث في البلد", controller: _searchCountryController), +// ), +// Expanded( +// child: ListView.separated( +// padding: EdgeInsets.only(left: 8, right: 8), +// itemCount: _filteredCountryList.length, +// physics: BouncingScrollPhysics(), +// separatorBuilder: (context, index) => Divider( +// height: 1, +// color: Colors.black87.withOpacity(0.3), +// ), +// itemBuilder: (context, index) => ListTile( +// title: Text(_filteredCountryList[index].countryNameAr + " (" + _filteredCountryList[index].countryCode + ")"), +// dense: true, +// onTap: () { +// Navigator.pop(context); +// widget.onSelectCountry(_filteredCountryList[index]); +// }, +// ), +// ), +// ) +// ], +// ), +// ), +// ); +// } +// } diff --git a/lib/ui/common_appbar.dart b/lib/ui/common_appbar.dart new file mode 100644 index 0000000..ae1e782 --- /dev/null +++ b/lib/ui/common_appbar.dart @@ -0,0 +1,364 @@ +// import 'package:flutter/material.dart'; +// import 'package:flutter_svg/flutter_svg.dart'; +// import 'package:shared_preferences/shared_preferences.dart'; +// import 'package:tangheem/api/tangheem_user_api_client.dart'; +// import 'package:tangheem/app_state/app_state.dart'; +// import 'package:tangheem/classes/colors.dart'; +// import 'package:tangheem/classes/consts.dart'; +// import 'package:tangheem/classes/utils.dart'; +// import 'package:tangheem/models/navigation_model.dart'; +// import 'package:tangheem/models/quick_links_model.dart'; +// import 'package:tangheem/ui/screens/bookmark_screen.dart'; +// import 'package:tangheem/ui/screens/content_info_screen.dart'; +// import 'package:tangheem/ui/screens/login_screen.dart'; +// import 'package:tangheem/ui/screens/pdf_viewer_screen.dart'; +// import 'package:url_launcher/url_launcher.dart'; +// +// class CommonAppbar extends StatefulWidget { +// final bool showDrawer; +// final Widget child; +// final bool isFirst; +// +// CommonAppbar({Key key, this.showDrawer = false, @required this.child, this.isFirst = false}) : super(key: key); +// +// @override +// _CommonAppbarState createState() { +// return _CommonAppbarState(); +// } +// } +// +// class _CommonAppbarState extends State { +// final GlobalKey _scaffoldKey = new GlobalKey(); +// List quickLinks = []; +// List navigationList = []; +// +// @override +// void initState() { +// super.initState(); +// getPrefs(); +// getNavigation(); +// getQuickLinks(); +// //getCopyRight(); +// } +// +// // void getCopyRight() async { +// // if (AppState().getContentInfoModel == null) { +// // try { +// // var model = await TangheemUserApiClient().getContentInfo(3); +// // var contentList = model?.data ?? []; +// // if (contentList.length > 0) { +// // _copyRight = contentList.first; +// // AppState().setContentInfoModel(_copyRight); +// // } +// // } catch (ex) {} +// // } else { +// // _copyRight = AppState().getContentInfoModel; +// // } +// // setState(() {}); +// // } +// +// void getNavigation() async { +// if (AppState().getNavigationModel?.data == null) { +// try { +// var model = await TangheemUserApiClient().getNavigation(); +// navigationList = model?.data ?? []; +// navigationList.sort((a, b) => a.orderNo.compareTo(b.orderNo)); +// AppState().setNavigationModel(model); +// } catch (ex) {} +// } else { +// navigationList = AppState().getNavigationModel.data; +// } +// setState(() {}); +// } +// +// void getQuickLinks() async { +// if (widget.showDrawer) { +// try { +// quickLinks = (await TangheemUserApiClient().quickLinks())?.data ?? []; +// quickLinks = quickLinks.where((element) => element.position == "down").toList(); +// quickLinks.sort((a, b) => a.orderNo.compareTo(b.orderNo)); +// } catch (ex) {} +// setState(() {}); +// } +// } +// +// int fontSize; +// SharedPreferences prefs; +// +// void getPrefs() async { +// prefs = await SharedPreferences.getInstance(); +// fontSize = prefs.getInt(GlobalConsts.fontZoomSize) ?? 18; +// } +// +// @override +// void dispose() { +// super.dispose(); +// } +// +// @override +// Widget build(BuildContext context) { +// return Scaffold( +// key: widget.showDrawer ? _scaffoldKey : null, +// drawer: widget.showDrawer ? drawerView() : null, +// resizeToAvoidBottomInset: true, +// drawerScrimColor: Colors.black.withOpacity(.3), +// body: SafeArea( +// child: Column( +// children: [ +// Container( +// color: Colors.white, +// height: 100, +// padding: EdgeInsets.only(top: 8, bottom: 8, right: 16), +// child: Row( +// crossAxisAlignment: CrossAxisAlignment.center, +// children: [ +// if (!widget.isFirst) +// IconButton( +// icon: Icon(widget.showDrawer ? Icons.menu : Icons.arrow_back_ios, color: ColorConsts.textGrey), +// padding: EdgeInsets.only(left: 16), +// onPressed: () { +// if (widget.showDrawer) { +// _scaffoldKey.currentState.openDrawer(); +// } else { +// Navigator.pop(context); +// } +// }, +// ), +// Expanded(child: SizedBox()), +// Hero( +// tag: "logo", +// child: SvgPicture.asset( +// "assets/logos/tangheem_logo.svg", +// height: 100, +// width: 100, +// alignment: Alignment.centerRight, +// ), +// ) +// ], +// ), +// ), +// Expanded( +// child: Directionality(textDirection: TextDirection.rtl, child: widget.child), +// ), +// ], +// ), +// ), +// ); +// } +// +// Widget drawerView() { +// var height = MediaQuery.of(context).padding.top; +// return Drawer( +// elevation: 0, +// child: Container( +// color: Colors.white, +// child: SafeArea( +// bottom: true, +// top: false, +// right: false, +// left: false, +// maintainBottomViewPadding: true, +// child: Builder( +// builder: (context) { +// bool isPortrait = MediaQuery.of(context).orientation == Orientation.portrait; +// Widget listContents = ListView.builder( +// shrinkWrap: true, +// physics: BouncingScrollPhysics(), +// padding: EdgeInsets.only(left: 24, right: 24), +// itemCount: navigationList.length, +// itemBuilder: (context, index) { +// String icon = "assets/icons/${navigationList[index].mobileFontIcon}.svg"; +// var subList = navigationList.where((element) => element.parentId == navigationList[index].navigationId).toList(); +// return Column( +// mainAxisSize: MainAxisSize.min, +// children: [ +// if (navigationList[index].parentId == 1) +// myListItem(icon, navigationList[index].navigationText, navigationList[index].orderNo == 1 ? true : false, onTap: () { +// String url = navigationList[index]?.mobileNavigationUrl ?? ""; +// if (url.isEmpty || url.length < 2) { +// return; +// } +// Navigator.pushNamed(context, url, arguments: null); +// }), +// for (var subItem in subList) +// Container( +// width: double.infinity, +// child: Row( +// children: [ +// Expanded( +// child: myListItem("assets/icons/${subItem.mobileFontIcon}.svg", subItem.navigationText, false, onTap: () { +// String url = subItem.mobileNavigationUrl ?? ""; +// if (url.isEmpty) { +// return; +// } +// var contentId; +// if (subItem.mobileNavigationUrl == "/introduction") { +// url = ContentInfoScreen.routeName; +// contentId = 2; +// } else if (subItem.mobileNavigationUrl == "/encyclopedia") { +// url = ContentInfoScreen.routeName; +// contentId = 1; +// } else if (subItem.mobileNavigationUrl == "/tangheempdf") { +// url = PdfListScreen.routeName; +// contentId = 8; +// } +// Navigator.pushNamed(context, url, arguments: contentId); +// }), +// ), +// Container( +// height: 40, +// margin: EdgeInsets.only(right: 17, left: 10), +// child: VerticalDivider(color: ColorConsts.primaryBlack, thickness: .7, width: 1), +// ), +// ], +// ), +// ) +// ], +// ); +// }); +// if (isPortrait) { +// listContents = Expanded(child: listContents); +// } +// List list = [ +// Container( +// height: 100 + height, +// padding: EdgeInsets.only(left: 0, top: height), +// alignment: Alignment.centerLeft, +// child: IconButton( +// icon: Icon(Icons.clear, color: ColorConsts.textGrey), +// onPressed: () { +// if (_scaffoldKey.currentState.isDrawerOpen) { +// Navigator.pop(context); +// } +// }, +// ), +// ), +// Container( +// margin: EdgeInsets.only(top: 8, bottom: 16), +// padding: EdgeInsets.only(left: 16, right: 16), +// child: Row( +// mainAxisAlignment: MainAxisAlignment.spaceEvenly, +// children: [ +// commonIconButton("assets/icons/bookmark.svg", () { +// Navigator.pushNamed(context, BookmarkScreen.routeName); +// }), +// commonIconButton("assets/icons/increase_size.svg", () { +// if (fontSize >= 36) { +// Utils.showToast("وصل حجم الخط إلى الحد الأقصى للحجم"); +// return; +// } +// fontSize += 2; +// prefs.setInt(GlobalConsts.fontZoomSize, fontSize); +// Utils.showToast("زيادة حجم الخط"); +// }), +// commonIconButton("assets/icons/reduce_size.svg", () { +// if (fontSize <= 12) { +// Utils.showToast("وصل حجم الخط إلى الحد الأدنى للحجم"); +// return; +// } +// fontSize -= 2; +// prefs.setInt(GlobalConsts.fontZoomSize, fontSize); +// Utils.showToast("تم تقليل حجم الخط"); +// }), +// commonIconButton("assets/icons/user_logged.svg", () { +// if (AppState().isUserLogin) { +// Utils.showToast("أنت بالفعل تسجيل الدخول"); +// return; +// } +// Navigator.pushNamed(context, LoginScreen.routeName); +// }), +// ], +// ), +// ), +// listContents, +// Container( +// margin: EdgeInsets.only(top: 16, bottom: 12), +// padding: EdgeInsets.only(left: 32, right: 32), +// child: Row( +// children: [ +// for (QuickLinksData _quickLink in quickLinks) +// commonIconButton(ApiConsts.baseUrl + _quickLink.exposeFilePath, () { //for live production server +// // commonIconButton( _quickLink.exposeFilePath, () { +// _launchURL(_quickLink.imageUrl); +// }, size: 35, isAsset: false), +// ], +// ), +// ), +// Padding( +// padding: EdgeInsets.only(left: 32, right: 32, bottom: 8), +// child: Row( +// crossAxisAlignment: CrossAxisAlignment.center, +// mainAxisAlignment: MainAxisAlignment.center, +// children: [ +// Text( +// "Powered by Cloud Solutions", +// maxLines: 1, +// textAlign: TextAlign.right, +// style: TextStyle(fontSize: 14, color: Colors.black87), +// ), +// SizedBox(width: 8), +// SvgPicture.asset("assets/logos/cloud_logo.svg", width: 30, height: 30) +// ], +// ), +// ) +// ]; +// return isPortrait ? Column(children: list) : ListView(children: list); +// }, +// ), +// ), +// ), +// ); +// } +// +// void _launchURL(String _url) async => await canLaunch(_url) ? await launch(_url) : throw 'Could not launch $_url'; +// +// Widget commonIconButton(String icon, VoidCallback onPressed, {double size, bool isAsset = true}) { +// return Expanded( +// child: IconButton( +// padding: EdgeInsets.zero, +// icon: isAsset ? SvgPicture.asset(icon, height: size ?? 25, width: size ?? 30) : Image.network(icon, height: size ?? 25, width: size ?? 30), +// onPressed: () { +// Navigator.pop(context); +// Future.delayed(Duration(milliseconds: 200), () => onPressed()); +// }), +// ); +// } +// +// Widget myListItem(String icon, String title, bool isSelected, {VoidCallback onTap}) { +// return InkWell( +// onTap: () { +// Navigator.pop(context); +// if (onTap != null) { +// Future.delayed(Duration(milliseconds: 200), () => onTap()); +// } +// }, +// child: Container( +// height: 40, +// padding: EdgeInsets.only(left: 8, right: 8), +// alignment: Alignment.centerRight, +// decoration: BoxDecoration( +// borderRadius: BorderRadius.circular(6), +// gradient: isSelected +// ? LinearGradient( +// stops: [0.0, 0.5], +// begin: Alignment.topCenter, +// end: Alignment.bottomCenter, +// colors: [ColorConsts.gradientPink, ColorConsts.gradientOrange], +// ) +// : null, +// ), +// child: Row( +// mainAxisSize: MainAxisSize.min, +// children: [ +// Text( +// title, +// style: TextStyle(fontSize: 14, color: isSelected ? Colors.white : ColorConsts.textGrey), +// ), +// SizedBox(width: 8), +// SvgPicture.asset(icon, height: 20, width: 20, color: isSelected ? Colors.white : ColorConsts.textGrey), +// ], +// ), +// ), +// ); +// } +// } diff --git a/lib/ui/dialogs/change_password_dialog.dart b/lib/ui/dialogs/change_password_dialog.dart new file mode 100644 index 0000000..d856b9c --- /dev/null +++ b/lib/ui/dialogs/change_password_dialog.dart @@ -0,0 +1,101 @@ +// import 'package:flutter/cupertino.dart'; +// import 'package:flutter/material.dart'; +// import 'package:flutter/rendering.dart'; +// import 'package:tangheem/classes/colors.dart'; +// import 'package:tangheem/classes/utils.dart'; +// import 'package:tangheem/widgets/common_textfield_widget.dart'; +// +// class ChangePasswordDialog extends StatefulWidget { +// final Function(String) onPassword; +// +// ChangePasswordDialog({Key key, this.onPassword}) : super(key: key); +// +// @override +// _ChangePasswordDialogState createState() { +// return _ChangePasswordDialogState(); +// } +// } +// +// class _ChangePasswordDialogState extends State { +// final TextEditingController _passwordController = TextEditingController(); +// final TextEditingController _confirmPasswordController = TextEditingController(); +// +// @override +// void initState() { +// super.initState(); +// } +// +// @override +// void dispose() { +// super.dispose(); +// } +// +// @override +// Widget build(BuildContext context) { +// return Dialog( +// insetPadding: EdgeInsets.symmetric(horizontal: 60.0, vertical: 24.0), +// shape: RoundedRectangleBorder( +// borderRadius: BorderRadius.circular(12), +// ), +// elevation: 0, +// backgroundColor: Colors.transparent, +// child: Directionality( +// textDirection: TextDirection.rtl, +// child: Container( +// width: double.infinity, +// decoration: BoxDecoration( +// color: ColorConsts.primaryBlue, +// borderRadius: BorderRadius.circular(16), +// ), +// padding: EdgeInsets.symmetric(vertical: 32, horizontal: 16), +// child: Column( +// mainAxisSize: MainAxisSize.min, +// children: [ +// Text( +// "تغيير كلمة المرور", +// textAlign: TextAlign.center, +// style: TextStyle(color: Colors.white, fontSize: 22), +// ), +// SizedBox(height: 16), +// CommonTextFieldWidget(hint: "كلمة المرور الجديدة", controller: _passwordController, prefixIcon: "assets/icons/password.svg"), +// SizedBox(height: 8), +// CommonTextFieldWidget(hint: "تأكيد كلمة المرور الجديدة", controller: _confirmPasswordController, prefixIcon: "assets/icons/password.svg"), +// SizedBox(height: 16), +// SizedBox( +// width: double.infinity, +// height: 40, +// child: TextButton( +// onPressed: () { +// if (_passwordController.text.length < 1) { +// Utils.showToast("يرجى إاخال كلمة المرور"); +// return; +// } +// if (_confirmPasswordController.text.length < 1) { +// Utils.showToast("يرجى تأكيد كلمة المرور"); +// return; +// } +// if (_passwordController.text != _confirmPasswordController.text) { +// Utils.showToast("خطأ في تطابق كلمات المرور"); +// return; +// } +// widget.onPassword(_passwordController.text); +// }, +// style: TextButton.styleFrom( +// primary: Colors.white, +// padding: EdgeInsets.all(2), +// backgroundColor: ColorConsts.secondaryPink, +// textStyle: TextStyle(fontSize: 14, fontFamily: "DroidKufi"), +// shape: RoundedRectangleBorder( +// borderRadius: BorderRadius.circular(6.0), +// ), +// ), +// child: Text("إعادة تعيين كلمة المرور"), +// ), +// ), +// ], +// ), +// ), +// ), +// ); +// } +// } diff --git a/lib/ui/dialogs/general_dialog.dart b/lib/ui/dialogs/general_dialog.dart new file mode 100644 index 0000000..22255eb --- /dev/null +++ b/lib/ui/dialogs/general_dialog.dart @@ -0,0 +1,55 @@ +// import 'package:flutter/material.dart'; +// import 'package:tangheem/classes/colors.dart'; +// +// class GeneralDialog extends StatelessWidget { +// final String message; +// GeneralDialog({Key key, this.message}) : super(key: key); +// +// @override +// Widget build(BuildContext context) { +// return Dialog( +// insetPadding: EdgeInsets.symmetric(horizontal: 60.0, vertical: 24.0), +// shape: RoundedRectangleBorder( +// borderRadius: BorderRadius.circular(12), +// ), +// elevation: 0, +// backgroundColor: Colors.transparent, +// child: Container( +// width: double.infinity, +// decoration: BoxDecoration( +// color: ColorConsts.primaryBlue, +// borderRadius: BorderRadius.circular(16), +// ), +// padding: EdgeInsets.symmetric(vertical: 32, horizontal: 16), +// child: Column( +// mainAxisSize: MainAxisSize.min, +// children: [ +// Text( +// message ?? "للحصول على تجربة أفضل ، يرجى إمالة هاتفك واستخدام التطبيق في الوضع الأفقي", +// textAlign: TextAlign.center, +// style: TextStyle(color: Colors.white), +// ), +// SizedBox(height: 32), +// SizedBox( +// width: double.infinity, +// height: 40, +// child: TextButton( +// onPressed: () => Navigator.pop(context), +// style: TextButton.styleFrom( +// primary: Colors.white, +// padding: EdgeInsets.all(2), +// backgroundColor: ColorConsts.secondaryPink, +// textStyle: TextStyle(fontSize: 14, fontFamily: "DroidKufi"), +// shape: RoundedRectangleBorder( +// borderRadius: BorderRadius.circular(6.0), +// ), +// ), +// child: Text("نعم"), +// ), +// ), +// ], +// ), +// ), +// ); +// } +// } diff --git a/lib/ui/dialogs/loading_dialog.dart b/lib/ui/dialogs/loading_dialog.dart new file mode 100644 index 0000000..371b9fa --- /dev/null +++ b/lib/ui/dialogs/loading_dialog.dart @@ -0,0 +1,58 @@ +// import 'package:flutter/cupertino.dart'; +// import 'package:flutter/foundation.dart'; +// import 'package:flutter/material.dart'; +// import 'package:flutter/rendering.dart'; +// import 'package:tangheem/classes/colors.dart'; +// +// class LoadingDialog extends StatefulWidget { +// LoadingDialog({Key key}) : super(key: key); +// +// @override +// _LoadingDialogState createState() { +// return _LoadingDialogState(); +// } +// } +// +// class _LoadingDialogState extends State { +// @override +// void initState() { +// super.initState(); +// } +// +// @override +// void dispose() { +// super.dispose(); +// } +// +// @override +// Widget build(BuildContext context) { +// return Dialog( +// insetPadding: EdgeInsets.symmetric(horizontal: 60.0, vertical: 24.0), +// shape: RoundedRectangleBorder( +// borderRadius: BorderRadius.circular(16), +// ), +// elevation: 0, +// backgroundColor: Colors.transparent, +// child: Directionality( +// textDirection: TextDirection.rtl, +// child: Center( +// child: Container( +// decoration: BoxDecoration( +// color: Colors.white, +// borderRadius: BorderRadius.circular(16), +// ), +// padding: EdgeInsets.symmetric(vertical: 12, horizontal: 12), +// child: SizedBox( +// height: 32, +// width: 32, +// child: CircularProgressIndicator( +// strokeWidth: 2, +// valueColor: AlwaysStoppedAnimation(ColorConsts.textGrey), +// ), +// ), +// ), +// ), +// ), +// ); +// } +// } diff --git a/lib/ui/dialogs/otp_dialog.dart b/lib/ui/dialogs/otp_dialog.dart new file mode 100644 index 0000000..6b0238b --- /dev/null +++ b/lib/ui/dialogs/otp_dialog.dart @@ -0,0 +1,116 @@ +// import 'package:flutter/cupertino.dart'; +// import 'package:flutter/material.dart'; +// import 'package:flutter/rendering.dart'; +// import 'package:tangheem/classes/colors.dart'; +// import 'package:tangheem/classes/utils.dart'; +// import 'package:tangheem/widgets/otp_widget.dart'; +// +// class OTPDialog extends StatefulWidget { +// final Function(int) onOTP; +// +// OTPDialog({Key key, this.onOTP}) : super(key: key); +// +// @override +// _OTPDialogState createState() { +// return _OTPDialogState(); +// } +// } +// +// class _OTPDialogState extends State { +// final TextEditingController _pinPutController = TextEditingController(); +// +// bool hasError = false; +// String errorMessage; +// String otpMessage = ""; +// +// @override +// void initState() { +// super.initState(); +// } +// +// @override +// void dispose() { +// super.dispose(); +// } +// +// @override +// Widget build(BuildContext context) { +// return Dialog( +// insetPadding: EdgeInsets.symmetric(horizontal: 60.0, vertical: 24.0), +// shape: RoundedRectangleBorder( +// borderRadius: BorderRadius.circular(12), +// ), +// elevation: 0, +// backgroundColor: Colors.transparent, +// child: Container( +// width: double.infinity, +// decoration: BoxDecoration( +// color: ColorConsts.primaryBlue, +// borderRadius: BorderRadius.circular(16), +// ), +// padding: EdgeInsets.symmetric(vertical: 32, horizontal: 16), +// child: Column( +// mainAxisSize: MainAxisSize.min, +// children: [ +// Text( +// "الرجاء إدخال الرقم المرسل إلى جوالك", +// textAlign: TextAlign.center, +// style: TextStyle(color: Colors.white), +// ), +// Container( +// margin: EdgeInsets.only(top: 8, bottom: 8), +// padding: EdgeInsets.all(6), +// decoration: BoxDecoration( +// border: Border.all(width: 1, color: Colors.white), +// ), +// child: OTPWidget( +// autoFocus: true, +// controller: _pinPutController, +// defaultBorderColor: Colors.transparent, +// maxLength: 4, +// hasError: hasError, +// onTextChanged: (text) { +// setState(() { +// hasError = false; +// }); +// }, +// pinBoxColor: ColorConsts.secondaryWhite.withOpacity(0.2), +// onDone: (text) => otpMessage = text, +// textBorderColor: Colors.transparent, +// pinBoxWidth: 40, +// pinBoxHeight: 40, +// pinTextStyle: TextStyle(fontSize: 20.0, color: Colors.white), +// pinTextAnimatedSwitcherTransition: ProvidedPinBoxTextAnimation.scalingTransition, +// pinTextAnimatedSwitcherDuration: Duration(milliseconds: 300), +// keyboardType: TextInputType.number, +// ), +// ), +// SizedBox( +// width: double.infinity, +// height: 40, +// child: TextButton( +// onPressed: () { +// if (otpMessage.length < 4) { +// Utils.showToast("الرقم الذي قمت بإدخاله غير صحيح"); +// return; +// } +// widget.onOTP(int.parse(otpMessage)); +// }, +// style: TextButton.styleFrom( +// primary: Colors.white, +// padding: EdgeInsets.all(2), +// backgroundColor: ColorConsts.secondaryPink, +// textStyle: TextStyle(fontSize: 14, fontFamily: "DroidKufi"), +// shape: RoundedRectangleBorder( +// borderRadius: BorderRadius.circular(6.0), +// ), +// ), +// child: Text("تحقق من الرقم"), +// ), +// ), +// ], +// ), +// ), +// ); +// } +// } diff --git a/lib/ui/landing/dashboard.dart b/lib/ui/landing/dashboard.dart new file mode 100644 index 0000000..e8c2157 --- /dev/null +++ b/lib/ui/landing/dashboard.dart @@ -0,0 +1,379 @@ +import 'package:easy_localization/src/public_ext.dart'; +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_svg/flutter_svg.dart'; +import 'package:mohem_flutter_app/api/dashboard_api_client.dart'; +import 'package:mohem_flutter_app/classes/colors.dart'; +import 'package:mohem_flutter_app/config/routes.dart'; +import 'package:mohem_flutter_app/extensions/int_extensions.dart'; +import 'package:mohem_flutter_app/extensions/string_extensions.dart'; +import 'package:mohem_flutter_app/extensions/widget_extensions.dart'; +import 'package:mohem_flutter_app/generated/locale_keys.g.dart'; +import 'package:mohem_flutter_app/theme/colors.dart'; +import 'package:mohem_flutter_app/widgets/circular_avatar.dart'; +import 'package:shimmer/shimmer.dart'; + +class Dashboard extends StatefulWidget { + Dashboard({Key? key}) : super(key: key); + + @override + _DashboardState createState() { + return _DashboardState(); + } +} + +class _DashboardState extends State { + @override + void initState() { + super.initState(); + DashbaordApiClient().getAttendanceTracking(); + } + + @override + void dispose() { + super.dispose(); + } + + @override + Widget build(BuildContext context) { + List names = [LocaleKeys.workList.tr(), LocaleKeys.missingSwipes.tr(), LocaleKeys.leaveBalance.tr(), LocaleKeys.ticketBalance.tr()]; + List namesInt = [118, 02, 18.5, 03]; + List namesColor = [0xff125765, 0xff239D8F, 0xff2BB8A8, 0xff1D92AA]; + + List namesT = [LocaleKeys.monthlyAttendance.tr(), LocaleKeys.workFromHome.tr(), LocaleKeys.ticketRequest.tr(), LocaleKeys.monthlyAttendance.tr()]; + List iconT = ["assets/images/monthly_attendance.svg", "assets/images/work_from_home.svg", "assets/images/ticket_request.svg", "assets/images/work_from_home.svg"]; + + List namesD = ["Nostalgia Perfume Perfume", "Al Nafoura", "AlJadi", "Nostalgia Perfume"]; + // DashbaordApiClient().getOpenNotifications(); + DashbaordApiClient().getOpenMissingSwipes(); + return Scaffold( + body: Column( + children: [ + Row( + children: [ + Row( + mainAxisSize: MainAxisSize.min, + children: [ + CircularAvatar( + width: 34, + height: 34, + url: "https://cdn4.iconfinder.com/data/icons/professions-2-2/151/89-512.png", + ), + 8.width, + SvgPicture.asset("assets/images/side_nav.svg"), + ], + ).onPress(() {}), + Expanded( + child: Row( + crossAxisAlignment: CrossAxisAlignment.center, + mainAxisAlignment: MainAxisAlignment.center, + mainAxisSize: MainAxisSize.min, + children: [ + //AppLogo(), + 8.width, + LocaleKeys.mohemm.tr().toText14() + ], + ), + ), + SizedBox( + width: 36, + height: 36, + child: Stack( + alignment: Alignment.centerLeft, + children: [ + SvgPicture.asset("assets/images/announcements.svg"), + Positioned( + right: 0, + top: 0, + child: Container( + padding: const EdgeInsets.only(left: 5, right: 5), + decoration: BoxDecoration(color: MyColors.redColor, borderRadius: BorderRadius.circular(17)), + child: "3".toText12(color: Colors.white), + ), + ) + ], + ), + ) + ], + ).paddingOnly(left: 21, right: 21, top: 48, bottom: 7), + Expanded( + child: ListView( + padding: EdgeInsets.zero, + children: [ + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + LocaleKeys.goodMorning.tr().toText14(color: MyColors.grey77Color), + "Mahmoud Shrouf".toText24(isBold: true), + 16.height, + Row( + children: [ + Expanded( + child: AspectRatio( + aspectRatio: 159 / 159, + child: Container( + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(15), + gradient: const LinearGradient(transform: GradientRotation(.46), begin: Alignment.topRight, end: Alignment.bottomRight, colors: [ + MyColors.gradiantEndColor, + MyColors.gradiantStartColor, + ]), + ), + child: Stack( + alignment: Alignment.center, + children: [ + // SvgPicture.asset("assets/images/"), + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Expanded( + child: Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + LocaleKeys.markAttendance.tr().toText14(color: Colors.white, isBold: true), + 9.height, + "07:55:12".toText14(color: Colors.white, isBold: true), + LocaleKeys.timeLeftToday.tr().toText12(color: Colors.white), + 9.height, + const ClipRRect( + borderRadius: BorderRadius.all( + Radius.circular(20), + ), + child: LinearProgressIndicator( + value: 0.7, + minHeight: 8, + valueColor: const AlwaysStoppedAnimation(Colors.white), + backgroundColor: const Color(0xff196D73), + ), + ), + ], + ).paddingOnly(top: 12, right: 15, left: 12), + ), + Row( + children: [ + Expanded( + child: Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, + children: [LocaleKeys.checkIn.tr().toText12(color: Colors.white), "09:00".toText14(color: Colors.white, isBold: true), 4.height], + ).paddingOnly(left: 12), + ), + Container( + width: 45, + height: 45, + padding: const EdgeInsets.only(left: 14, right: 14), + decoration: const BoxDecoration( + color: Color(0xff259EA4), + borderRadius: BorderRadius.only( + bottomRight: Radius.circular(15), + ), + ), + child: SvgPicture.asset("assets/images/stop.svg"), + ), + ], + ), + ], + ), + ], + ), + ).onPress(() { + Navigator.pushNamed(context, AppRoutes.todayAttendance); + }), + ), + ), + 9.width, + Expanded( + child: GridView.builder( + shrinkWrap: true, + primary: false, + physics: const NeverScrollableScrollPhysics(), + gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 2, childAspectRatio: 2 / 2, crossAxisSpacing: 9, mainAxisSpacing: 9), + padding: EdgeInsets.zero, + itemCount: 4, + itemBuilder: (BuildContext context, int index) { + return Container( + decoration: BoxDecoration( + color: Color(namesColor[index]), + borderRadius: BorderRadius.circular(10), + ), + child: Column( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + names[index].toText12(color: Colors.white), + Row( + children: [ + Expanded( + child: namesInt[index].toStringAsFixed(1).toText16(color: Colors.white, isBold: true), + ), + SvgPicture.asset("assets/images/arrow_next.svg", color: Colors.white) + ], + ) + ], + ).paddingOnly(left: 10, right: 10, bottom: 6, top: 6), + ).onPress(() { + Navigator.pushNamed(context, AppRoutes.workList); + }); + }, + ), + ), + ], + ), + 20.height, + Row( + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisSize: MainAxisSize.min, + children: [ + "Other".tr().toText12(), + LocaleKeys.services.tr().toText24(isBold: true), + ], + ), + ), + LocaleKeys.viewAllServices.tr().toText12(isUnderLine: true), + ], + ), + ], + ).paddingOnly(left: 21, right: 21, top: 7), + SizedBox( + height: 105 + 26, + child: ListView.separated( + shrinkWrap: true, + physics: const BouncingScrollPhysics(), + padding: const EdgeInsets.only(left: 21, right: 21, top: 13, bottom: 13), + scrollDirection: Axis.horizontal, + itemBuilder: (cxt, index) { + return AspectRatio( + aspectRatio: 105 / 105, + child: Container( + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(15), + boxShadow: [ + BoxShadow( + color: const Color(0xff000000).withOpacity(.05), + blurRadius: 26, + offset: const Offset(0, -3), + ), + ], + ), + child: Column( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + SvgPicture.asset(iconT[index]), + Row( + crossAxisAlignment: CrossAxisAlignment.end, + children: [ + Expanded( + child: namesT[index].toText11(isBold: true), + ), + SvgPicture.asset("assets/images/arrow_next.svg").paddingOnly(bottom: 4) + ], + ) + ], + ).paddingOnly(left: 10, right: 10, bottom: 10, top: 12), + ), + ); + }, + separatorBuilder: (cxt, index) => 9.width, + itemCount: 4), + ), + 8.height, + Container( + width: double.infinity, + padding: EdgeInsets.only(top: 31), + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.only(topRight: Radius.circular(50), topLeft: Radius.circular(50)), + border: Border.all(color: MyColors.lightGreyEDColor, width: 1), + ), + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + Row( + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisSize: MainAxisSize.min, + children: [ + LocaleKeys.offers.tr().toText12(), + Row( + children: [ + LocaleKeys.discounts.tr().toText24(isBold: true), + 6.width, + Container( + padding: const EdgeInsets.only(left: 8, right: 8), + decoration: BoxDecoration( + color: MyColors.yellowColor, + borderRadius: BorderRadius.circular(10), + ), + child: LocaleKeys.newString.tr().toText10(isBold: true)), + ], + ), + ], + ), + ), + LocaleKeys.viewAllOffers.tr().toText12(isUnderLine: true), + ], + ).paddingOnly(left: 21, right: 21), + SizedBox( + height: 103 + 33, + child: ListView.separated( + shrinkWrap: true, + physics: const BouncingScrollPhysics(), + padding: const EdgeInsets.only(left: 21, right: 21, top: 13), + scrollDirection: Axis.horizontal, + itemBuilder: (cxt, index) { + return SizedBox( + width: 73, + child: Column( + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Container( + width: 73, + height: 73, + decoration: BoxDecoration( + borderRadius: const BorderRadius.all( + Radius.circular(100), + ), + border: Border.all(color: MyColors.lightGreyEDColor, width: 1), + ), + child: ClipRRect( + borderRadius: const BorderRadius.all( + Radius.circular(50), + ), + child: Image.network( + "https://play-lh.googleusercontent.com/NPo88ojmhah4HDiposucJmfQIop4z4xc8kqJK9ITO9o-yCab2zxIp7PPB_XPj2iUojo", + fit: BoxFit.cover, + ), + ), + ), + 4.height, + Expanded( + child: namesD[6 % (index + 1)].toText12(isCenter: true, maxLine: 2), + ), + ], + ), + ); + }, + separatorBuilder: (cxt, index) => 8.width, + itemCount: 6), + ), + ], + ), + ) + ], + ), + ) + ], + ), + ); + } +} diff --git a/lib/ui/landing/today_attendance_screen.dart b/lib/ui/landing/today_attendance_screen.dart new file mode 100644 index 0000000..ac42dd1 --- /dev/null +++ b/lib/ui/landing/today_attendance_screen.dart @@ -0,0 +1,176 @@ +import 'package:easy_localization/src/public_ext.dart'; +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/extensions/int_extensions.dart'; +import 'package:mohem_flutter_app/extensions/string_extensions.dart'; +import 'package:mohem_flutter_app/extensions/widget_extensions.dart'; +import 'package:mohem_flutter_app/generated/locale_keys.g.dart'; +import 'package:mohem_flutter_app/widgets/circular_step_progress_bar.dart'; + +class TodayAttendanceScreen extends StatefulWidget { + TodayAttendanceScreen({Key? key}) : super(key: key); + + @override + _TodayAttendanceScreenState createState() { + return _TodayAttendanceScreenState(); + } +} + +class _TodayAttendanceScreenState extends State { + @override + void initState() { + super.initState(); + } + + @override + void dispose() { + super.dispose(); + } + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + backgroundColor: MyColors.backgroundBlackColor, + leading: IconButton( + icon: const Icon(Icons.arrow_back_ios, color: Colors.white), + onPressed: () => Navigator.pop(context), + ), + ), + backgroundColor: Colors.white, + body: ListView( + children: [ + Container( + color: MyColors.backgroundBlackColor, + padding: EdgeInsets.only(top: 4,left: 21, right: 21, bottom: 21), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + "June 13, 2021".toText24(isBold: true, color: Colors.white), + LocaleKeys.timeLeftToday.tr().toText16(color: Color(0xffACACAC)), + 21.height, + Center( + child: CircularStepProgressBar( + totalSteps: 16 * 4, + currentStep: 16, + width: 216, + height: 216, + selectedColor: MyColors.gradiantEndColor, + unselectedColor: MyColors.grey70Color, + child: Center( + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + "08:58:15".toText32(color: Colors.white, isBold: true), + 19.height, + "Shift Time".tr().toText12(color: MyColors.greyACColor), + "08:00 - 17:00".toText22(color: Colors.white, isBold: true), + ], + ), + ), + ), + ), + ], + ), + ), + Container( + color: MyColors.backgroundBlackColor, + child: Stack( + children: [ + Container( + height: 187, + padding: EdgeInsets.only(left: 31, right: 31, top: 31, bottom: 16), + decoration: BoxDecoration( + borderRadius: BorderRadius.only(topLeft: Radius.circular(25), topRight: Radius.circular(25)), + gradient: const LinearGradient(transform: GradientRotation(.64), begin: Alignment.topRight, end: Alignment.bottomRight, colors: [ + MyColors.gradiantEndColor, + MyColors.gradiantStartColor, + ]), + ), + child: Column( + children: [ + Row( + children: [commonStatusView("Check In", "09:27"), commonStatusView("Check Out", "- - : - -")], + ), + 21.height, + Row( + children: [commonStatusView("Late In", "00:27"), commonStatusView("Regular", "08:00")], + ), + ], + ), + ), + Container( + width: double.infinity, + decoration: BoxDecoration(borderRadius: BorderRadius.only(topLeft: Radius.circular(25), topRight: Radius.circular(25)), color: Colors.white), + margin: EdgeInsets.only(top: 187 - 31), + padding: EdgeInsets.only(left: 21, right: 21, top: 24, bottom: 24), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisSize: MainAxisSize.min, + children: [ + "Mark".tr().toText12(), + "Attendance".tr().toText24(), + "Select the method to mark the attendance".tr().toText12(color: Color(0xff535353)), + 24.height, + GridView( + physics: const NeverScrollableScrollPhysics(), + shrinkWrap: true, + padding: EdgeInsets.zero, + gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 3, childAspectRatio: 1 / 1, crossAxisSpacing: 8, mainAxisSpacing: 8), + children: [ + attendanceMethod("NFC", "assets/images/nfc.svg", () {}), + attendanceMethod("Wifi", "assets/images/wufu.svg", () {}), + ], + ) + ], + ), + ), + // Positioned( + // top: 187 - 21, + // child: Container( + // padding: EdgeInsets.only(left: 31, right: 31, top: 31, bottom: 16), + // decoration: BoxDecoration(borderRadius: BorderRadius.only(topLeft: Radius.circular(25), topRight: Radius.circular(25)), color: Colors.white), + // child: Column( + // children: [ + // Row( + // children: [commonStatusView("Check In", "09:27"), commonStatusView("Check Out", "- - : - -")], + // ), + // 21.height, + // Row( + // children: [commonStatusView("Late In", "00:27"), commonStatusView("Regular", "08:00")], + // ), + // ], + // ), + // ), + // ), + ], + ), + ) + ], + ), + ); + } + + Widget attendanceMethod(String title, String image, VoidCallback onPress) => Container( + padding: const EdgeInsets.only(left: 10, right: 10, top: 14, bottom: 14), + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(15), + gradient: const LinearGradient(transform: GradientRotation(.64), begin: Alignment.topRight, end: Alignment.bottomRight, colors: [ + MyColors.gradiantEndColor, + MyColors.gradiantStartColor, + ]), + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [Expanded(child: SvgPicture.asset(image)), title.toText17(isBold: true, color: Colors.white)], + ), + ).onPress(onPress); + + Widget commonStatusView(String title, String time) => Expanded( + child: Column(mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.start, children: [ + title.toText12(color: Colors.white), + time.toText22(color: Colors.white, isBold: true), + ]), + ); +} diff --git a/lib/ui/login/forgot_password_screen.dart b/lib/ui/login/forgot_password_screen.dart new file mode 100644 index 0000000..89bd66e --- /dev/null +++ b/lib/ui/login/forgot_password_screen.dart @@ -0,0 +1,114 @@ +import 'package:easy_localization/src/public_ext.dart'; +import 'package:flutter/material.dart'; +import 'package:mohem_flutter_app/api/login_api_client.dart'; +import 'package:mohem_flutter_app/classes/colors.dart'; +import 'package:mohem_flutter_app/classes/utils.dart'; +import 'package:mohem_flutter_app/config/routes.dart'; +import 'package:mohem_flutter_app/dialogs/otp_dialog.dart'; +import 'package:mohem_flutter_app/extensions/int_extensions.dart'; +import 'package:mohem_flutter_app/extensions/string_extensions.dart'; +import 'package:mohem_flutter_app/generated/locale_keys.g.dart'; +import 'package:mohem_flutter_app/models/basic_member_information_model.dart'; +import 'package:mohem_flutter_app/models/generic_response_model.dart'; +import 'package:mohem_flutter_app/widgets/button/default_button.dart'; +import 'package:mohem_flutter_app/widgets/input_widget.dart'; + +class ForgotPasswordScreen extends StatefulWidget { + ForgotPasswordScreen({Key? key}) : super(key: key); + + @override + _ForgotPasswordScreenState createState() { + return _ForgotPasswordScreenState(); + } +} + +class _ForgotPasswordScreenState extends State { + TextEditingController employeeId = TextEditingController(); + BasicMemberInformationModel? _basicMemberInformation; + GenericResponseModel? genericResponseModel; + + @override + void initState() { + super.initState(); + } + + @override + void dispose() { + super.dispose(); + } + + void performLogin() async { + // Utils.showLoading(context); + try { + _basicMemberInformation = await LoginApiClient().getBasicUserInformation("CS", employeeId.text); + genericResponseModel = await LoginApiClient().sendPublicActivationCode(_basicMemberInformation?.pMOBILENUMBER, employeeId.text); + OtpDialog( + context, + 1, + int.tryParse(_basicMemberInformation?.pMOBILENUMBER ?? ""), + (value) async { + GenericResponseModel? genericResponseModel = await LoginApiClient().checkPublicActivationCode(value, employeeId.text); + if (genericResponseModel?.errorMessage != null) { + Utils.showToast(genericResponseModel?.errorMessage ?? ""); + return; + } + + Navigator.pushNamed(context, AppRoutes.newPassword); + // this.checkActivationCode(value: value); + }, + () => { + Navigator.pop(context), + }, + ).displayDialog(context); + } catch (ex) { + print(ex); + Utils.handleException(ex, null); + // Utils.hideLoading(context); + } + } + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + backgroundColor: Colors.transparent, + leading: IconButton( + icon: const Icon(Icons.arrow_back_ios, color: MyColors.darkIconColor), + onPressed: () => Navigator.pop(context), + ), + ), + body: Column( + children: [ + //const SizedBox(height: 23), + Expanded( + child: Padding( + padding: const EdgeInsets.all(21.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Expanded( + child: Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.center, + children: [ + LocaleKeys.forgotPassword.tr().toText24(isBold: true), + LocaleKeys.loginCodeWillSentToMobileNumber.tr().toText16(), + 16.height, + InputWidget(LocaleKeys.employeeId.tr(), "123456", employeeId), + ], + ), + ) + ], + ), + ), + ), + DefaultButton(LocaleKeys.changePassword.tr(), () async { + //Navigator.pushNamed(context, AppRoutes.verifyLogin); + }) + .insideContainer + ], + ), + ); + } +} diff --git a/lib/ui/login/login_screen.dart b/lib/ui/login/login_screen.dart new file mode 100644 index 0000000..2353f99 --- /dev/null +++ b/lib/ui/login/login_screen.dart @@ -0,0 +1,134 @@ +import 'package:easy_localization/easy_localization.dart'; +import 'package:easy_localization/src/public_ext.dart'; +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; +import 'package:mohem_flutter_app/api/login_api_client.dart'; +import 'package:mohem_flutter_app/app_state/app_state.dart'; +import 'package:mohem_flutter_app/classes/colors.dart'; +import 'package:mohem_flutter_app/classes/utils.dart'; +import 'package:mohem_flutter_app/config/routes.dart'; +import 'package:mohem_flutter_app/extensions/int_extensions.dart'; +import 'package:mohem_flutter_app/extensions/string_extensions.dart'; +import 'package:mohem_flutter_app/extensions/widget_extensions.dart'; +import 'package:mohem_flutter_app/generated/locale_keys.g.dart'; +import 'package:mohem_flutter_app/models/check_mobile_app_version_model.dart'; +import 'package:mohem_flutter_app/models/member_login_list_model.dart'; +import 'package:mohem_flutter_app/widgets/button/default_button.dart'; +import 'package:mohem_flutter_app/widgets/input_widget.dart'; + +class LoginScreen extends StatefulWidget { + LoginScreen({Key? key}) : super(key: key); + + @override + _LoginScreenState createState() { + return _LoginScreenState(); + } +} + +class _LoginScreenState extends State { + TextEditingController username = TextEditingController(); + TextEditingController password = TextEditingController(); + + CheckMobileAppVersionModel? _checkMobileAppVersion; + MemberLoginListModel? _memberLoginList; + + @override + void initState() { + super.initState(); + } + + @override + void dispose() { + super.dispose(); + } + + void performLogin() async { + Utils.showLoading(context); + try { + _checkMobileAppVersion = await LoginApiClient().checkMobileAppVersion(); + _memberLoginList = await LoginApiClient().memberLogin(username.text, password.text); + AppState().setMemberLoginListModel = _memberLoginList; + AppState().setUserName = username.text; + print(_memberLoginList?.toJson()); + Utils.hideLoading(context); + Navigator.pushNamed(context, AppRoutes.verifyLogin); + } catch (ex) { + print(ex); + Utils.handleException(ex, null); + Utils.hideLoading(context); + } + } + + @override + Widget build(BuildContext context) { + username.text="15153"; + password.text="e123e123e123"; + return Scaffold( + body: Column( + children: [ + const SizedBox(height: 23), + Expanded( + child: Padding( + padding: const EdgeInsets.all(21.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + children: [ + Expanded(child: SizedBox()), + Row( + children: [ + LocaleKeys.english.tr().toText14(color: MyColors.textMixColor).onPress(() { + context.setLocale(const Locale("en", "US")); + }), + Container( + width: 1, + color: MyColors.darkWhiteColor, + height: 16, + margin: const EdgeInsets.only(left: 10, right: 10), + ), + LocaleKeys.arabic.tr().toText14().onPress(() { + context.setLocale(const Locale("ar", "SA")); + }), + ], + ), + ], + ), + Expanded( + child: Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.center, + children: [ + LocaleKeys.login.tr().toText24(isBold: true), + LocaleKeys.pleaseEnterLoginDetails.tr().toText16(), + 16.height, + InputWidget(LocaleKeys.username.tr(), "123456", username), + 12.height, + InputWidget(LocaleKeys.password.tr(), "xxxxxx", password, isObscureText: true), + 9.height, + Align( + alignment: Alignment.centerRight, + child: LocaleKeys.forgotPassword.tr().toText12(isUnderLine: true, color: MyColors.textMixColor).onPress(() { + Navigator.pushNamed(context, AppRoutes.forgotPassword); + }), + ), + ], + ), + ) + ], + ), + ), + ), + DefaultButton(LocaleKeys.login.tr(), () async { + // context.setLocale(const Locale("en", "US")); // to change Loacle + + SystemChannels.textInput.invokeMethod('TextInput.hide'); + performLogin(); + }).insideContainer + ], + ), + ); + } +} diff --git a/lib/ui/login/new_password_screen.dart b/lib/ui/login/new_password_screen.dart new file mode 100644 index 0000000..3fc37f1 --- /dev/null +++ b/lib/ui/login/new_password_screen.dart @@ -0,0 +1,98 @@ +import 'package:easy_localization/src/public_ext.dart'; +import 'package:flutter/material.dart'; +import 'package:mohem_flutter_app/classes/colors.dart'; +import 'package:mohem_flutter_app/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/widgets/button/default_button.dart'; +import 'package:mohem_flutter_app/widgets/input_widget.dart'; + +class NewPasswordScreen extends StatefulWidget { + NewPasswordScreen({Key? key}) : super(key: key); + + @override + _NewPasswordScreenState createState() { + return _NewPasswordScreenState(); + } +} + +class _NewPasswordScreenState extends State { + TextEditingController password = TextEditingController(); + TextEditingController confirmPassword = TextEditingController(); + + @override + void initState() { + super.initState(); + } + + @override + void dispose() { + super.dispose(); + } + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + backgroundColor: Colors.transparent, + leading: IconButton( + icon: const Icon(Icons.arrow_back_ios, color: MyColors.darkIconColor), + onPressed: () => Navigator.pop(context), + ), + ), + body: Column( + children: [ + //const SizedBox(height: 23), + Expanded( + child: Padding( + padding: const EdgeInsets.all(21.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + // Row( + // children: [ + // Expanded(child: SizedBox()), + // Row( + // children: [ + // LocaleKeys.english.tr().toText14(color: MyColors.textMixColor).onPress(() {}), + // Container( + // width: 1, + // color: MyColors.darkWhiteColor, + // height: 16, + // margin: const EdgeInsets.only(left: 10, right: 10), + // ), + // LocaleKeys.arabic.tr().toText14().onPress(() {}), + // ], + // ), + // ], + // ), + Expanded( + child: Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.center, + children: [ + LocaleKeys.setTheNewPassword.tr().toText24(isBold: true), + LocaleKeys.typeYourNewPasswordBelow.tr().toText16(), + 16.height, + InputWidget(LocaleKeys.password.tr(), "**********", password), + 12.height, + InputWidget(LocaleKeys.confirmPassword.tr(), "**********", confirmPassword, isObscureText: true) + ], + ), + ) + ], + ), + ), + ), + DefaultButton(LocaleKeys.update.tr(), () async { + + // Navigator.pushNamed(context, AppRoutes.verifyLogin); + }).insideContainer + ], + ), + ); + } +} diff --git a/lib/ui/login/verify_login_screen.dart b/lib/ui/login/verify_login_screen.dart new file mode 100644 index 0000000..ba0eb98 --- /dev/null +++ b/lib/ui/login/verify_login_screen.dart @@ -0,0 +1,721 @@ +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/local_auth.dart'; +import 'package:mohem_flutter_app/api/login_api_client.dart'; +import 'package:mohem_flutter_app/app_state/app_state.dart'; +import 'package:mohem_flutter_app/classes/colors.dart'; +import 'package:mohem_flutter_app/classes/utils.dart'; +import 'package:mohem_flutter_app/config/routes.dart'; +import 'package:mohem_flutter_app/dialogs/otp_dialog.dart'; +import 'package:mohem_flutter_app/extensions/int_extensions.dart'; +import 'package:mohem_flutter_app/extensions/string_extensions.dart'; +import 'package:mohem_flutter_app/extensions/widget_extensions.dart'; +import 'package:mohem_flutter_app/generated/locale_keys.g.dart'; +import 'package:mohem_flutter_app/models/basic_member_information_model.dart'; +import 'package:mohem_flutter_app/models/generic_response_model.dart'; +import 'package:mohem_flutter_app/widgets/button/default_button.dart'; + +class VerifyLoginScreen extends StatefulWidget { + VerifyLoginScreen({Key? key}) : super(key: key); + + @override + _VerifyLoginScreenState createState() { + return _VerifyLoginScreenState(); + } +} + +class _VerifyLoginScreenState extends State { + final LocalAuthentication auth = LocalAuthentication(); + List _availableBioMetricType = []; + + @override + void initState() { + _getAvailableBiometrics(); + // setDefault(); + super.initState(); + } + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + backgroundColor: Colors.transparent, + leading: IconButton( + icon: const Icon(Icons.arrow_back_ios, color: MyColors.darkIconColor), + onPressed: () => Navigator.pop(context), + ), + actions: [Center(child: "Employee Digital ID".toText12(color: MyColors.textMixColor, isUnderLine: true).onPress(() {})), 21.width], + ), + body: Column( + children: [ + Expanded( + child: ListView( + padding: const EdgeInsets.all(21), + physics: const BouncingScrollPhysics(), + children: [ + //12.height, + if (true) + Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + LocaleKeys.welcomeBack.tr().toText12(), + "Mohammad Hussain".toText24(isBold: true), + 10.height, + LocaleKeys.wouldYouLikeToLoginWithCurrentUsername.tr().toText16(), + Container( + height: 72, + margin: const EdgeInsets.only(top: 23, bottom: 23), + alignment: Alignment.center, + padding: EdgeInsets.only(left: 17, right: 12), + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(10), + color: Colors.white, + border: Border.all( + color: Color(0xffefefef), + width: 1, + ), + ), + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + LocaleKeys.lastLoginDetails.tr().toText16(), + // Text( + // user.editedOn != null + // ? DateUtil.getDayMonthYearDateFormatted(DateUtil.convertStringToDate(user.editedOn)) + // : user.createdOn != null + // ? DateUtil.getDayMonthYearDateFormatted(DateUtil.convertStringToDate(user.createdOn)) + // : '--', + // style: TextStyle(fontSize: 12, fontWeight: FontWeight.w600, color: Color(0xff2B353E), letterSpacing: -0.48), + // ), + ], + ), + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + LocaleKeys.verificationType.tr().toText10(color: MyColors.grey57Color), + Text( + "SMS", + // " " + getType(user.logInType, context), + style: TextStyle( + fontSize: 12, + fontWeight: FontWeight.w600, + color: Color(0xff2B353E), + ), + ), + Expanded(child: SizedBox()), + // Text( + // user.editedOn != null + // ? DateUtil.formatDateToTimeLang(DateUtil.convertStringToDate(user.editedOn), false) + // : user.createdOn != null + // ? DateUtil.formatDateToTimeLang(DateUtil.convertStringToDate(user.createdOn), false) + // : '--', + // style: TextStyle(fontSize: 12, fontWeight: FontWeight.w600, color: Color(0xff575757), letterSpacing: -0.48), + // ), + ], + ) + ], + ), + ), + LocaleKeys.pleaseVerify.tr().toText16(), + GridView( + gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 2, crossAxisSpacing: 13, mainAxisSpacing: 9), + physics: const NeverScrollableScrollPhysics(), + padding: const EdgeInsets.only(top: 9), + shrinkWrap: true, + children: [ + getButton(3), + getButton(2), + getButton(1), + getButton(4), + ], + ) + ], + ) + // else + // Column(mainAxisAlignment: MainAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start, children: [ + // Image.asset( + // 'assets/images/habib-logo.png', + // height: 90, + // width: 90, + // ), + // SizedBox(height: 23), + // this.onlySMSBox == false + // ? Text( + // TranslationBase.of(context).verifyLoginWith, + // style: TextStyle(fontSize: 16, fontWeight: FontWeight.w600, color: Color(0xff2B353E), letterSpacing: -0.64, height: 25 / 16), + // ) + // : Text( + // TranslationBase.of(context).verifyFingerprint2, + // style: TextStyle(fontSize: 16, fontWeight: FontWeight.w600, color: Color(0xff2B353E), letterSpacing: -0.64, height: 25 / 16), + // ), + // SizedBox(height: 23), + // Text( + // TranslationBase.of(context).pleaseVerify, + // style: TextStyle(fontSize: 16, fontWeight: FontWeight.w600, color: Color(0xff2E303A), letterSpacing: -0.64), + // ), + // GridView( + // gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 2, crossAxisSpacing: 13, mainAxisSpacing: 9), + // physics: NeverScrollableScrollPhysics(), + // padding: EdgeInsets.only(top: 9), + // shrinkWrap: true, + // children: [ + // if (onlySMSBox == false) getButton(3), + // if (onlySMSBox == false) getButton(2), + // getButton(1), + // getButton(4), + // ], + // ), + // ]), + ], + ), + ), + 12.height, + DefaultButton( + LocaleKeys.useAnotherAccount.tr(), + () => { + //Navigator.of(context).pushNamed(LOGIN_TYPE) + }, + ).insideContainer, + ], + ), + ); + } + + Future _getAvailableBiometrics() async { + try { + _availableBioMetricType = await auth.getAvailableBiometrics(); + } on PlatformException catch (e) { + // AppToast.showErrorToast(message: e.message); + print(e); + } + if (mounted) setState(() {}); + } + + // authenticateUser(int type, {int isActive}) { + // GifLoaderDialogUtils.showMyDialog(context); + // if (type == 2 || type == 3) { + // fingrePrintBefore = type; + // } + // this.selectedOption = fingrePrintBefore != null ? fingrePrintBefore : type; + // + // switch (type) { + // case 1: + // this.loginWithSMS(type); + // break; + // case 2: + // this.loginWithFingurePrintFace(type, isActive); + // break; + // case 3: + // this.loginWithFingurePrintFace(type, isActive); + // break; + // case 4: + // this.loginWithSMS(type); + // break; + // default: + // break; + // } + // sharedPref.setInt(LAST_LOGIN, this.selectedOption); //this.cs.sharedService.setStorage(this.selectedOption, AuthenticationService.LAST_LOGIN); + // } +// +// loginWithSMS(type) { +// //if (!el.disabled) { +// if (this.user != null && this.registerd_data == null) { +// this.checkUserAuthentication(type); +// } else { +// if (this.loginTokenID != null) { +// // Future.delayed(Duration(seconds: 1), () { +// this.sendActivationCode(type); +// // }); +// } else { +// this.checkUserAuthentication(type); +// } +// } +// } +// +// checkUserAuthentication(type) { +// showLoader(true); +// var req = getCommonRequest(type: type); +// req.logInTokenID = ""; +// +// var request = CheckPatientAuthenticationReq.fromJson(req.toJson()); +// +// sharedPref.setObject(REGISTER_DATA_FOR_REGISTER, request); +// authService +// .checkPatientAuthentication(request) +// .then((value) => { +// GifLoaderDialogUtils.hideDialog(context), +// if (value['isSMSSent']) +// { +// sharedPref.setString(LOGIN_TOKEN_ID, value['LogInTokenID']), +// this.loginTokenID = value['LogInTokenID'], +// sharedPref.setObject(REGISTER_DATA_FOR_LOGIIN, request), +// // Future.delayed(Duration(seconds: 1), () { +// this.sendActivationCode(type) +// // }) +// } +// else +// { +// if (value['IsAuthenticated']) {this.checkActivationCode()} +// } +// }) +// .catchError((err) { +// print(err); +// GifLoaderDialogUtils.hideDialog(context); +// }); +// } +// +// sendActivationCode(type) async { +// var request = this.getCommonRequest(type: type); +// request.sMSSignature = await SMSOTP.getSignature(); +// GifLoaderDialogUtils.showMyDialog(context); +// if (healthId != null) { +// // final DateFormat dateFormat = DateFormat('MM/dd/yyyy'); +// // final DateFormat dateFormat2 = DateFormat('dd/MM/yyyy'); +// request.dob = dob; //isHijri == 1 ? dob : dateFormat2.format(dateFormat.parse(dob)); +// request.healthId = healthId; +// request.isHijri = isHijri; +// await this.authService.sendActivationCodeRegister(request).then((result) { +// GifLoaderDialogUtils.hideDialog(context); +// if (result != null && result['isSMSSent'] == true) { +// this.startSMSService(type); +// } +// }).catchError((r) { +// GifLoaderDialogUtils.hideDialog(context); +// }); +// } else { +// request.dob = ""; +// request.healthId = ""; +// request.isHijri = 0; +// await this.authService.sendActivationCode(request).then((result) { +// GifLoaderDialogUtils.hideDialog(context); +// if (result != null && result['isSMSSent'] == true) { +// this.startSMSService(type); +// } +// }).catchError((r) { +// GifLoaderDialogUtils.hideDialog(context); +// }); +// } +// } +// +// var tempType; +// +// startSMSService(type) { +// tempType = type; +// new SMSOTP( +// context, +// type, +// this.mobileNumber, +// (value) { +// this.checkActivationCode(value: value); +// }, +// () => { +// Navigator.pop(context), +// }, +// ).displayDialog(context); +// } +// +// loginWithFingurePrintFace(type, int isActive) async { +// if (isActive == 1 || isActive == 0) { +// const iosStrings = +// const IOSAuthMessages(cancelButton: 'cancel', goToSettingsButton: 'settings', goToSettingsDescription: 'Please set up your Touch ID.', lockOut: 'Please reenable your Touch ID'); +// +// try { +// authenticated = await auth.authenticateWithBiometrics(localizedReason: 'Scan your fingerprint to authenticate', useErrorDialogs: true, stickyAuth: true, iOSAuthStrings: iosStrings); +// } on PlatformException catch (e) { +// GifLoaderDialogUtils.hideDialog(context); +// AppToast.showErrorToast(message: 'Please enable your Touch or Face ID'); +// } +// +// if (authenticated == true) { +// // if (user != null && (user.logInType == 2 || user.logInType == 3)) { +// // this.checkActivationCode(); +// // } else { +// +// var request = this.getCommonRequest(type: type); +// this.getMobileInfo(request); +// //} +// } +// } +// } +// +// getMobileInfo(request) { +// // GifLoaderDialogUtils.showMyDialog(context); +// this.authService.getLoginInfo(request).then((result) { +// GifLoaderDialogUtils.hideDialog(context); +// if (result['SMSLoginRequired'] == false) { +// this.loginTokenID = result['LogInTokenID']; +// this.patientOutSA = result['PatientOutSA']; +// // sms for register the biometric +// if (result['isSMSSent']) { +// setState(() { +// isMoreOption = true; +// this.onlySMSBox = true; +// // this.fingrePrintBefore = true; +// }); +// //this.button(); +// } else { +// setDefault(); +// checkActivationCode(); +// } +// } else { +// if (result['IsAuthenticated'] == true) { +// setState(() { +// isMoreOption = true; +// this.onlySMSBox = true; +// // this.fingrePrintBefore = true; +// }); +// } +// } +// }).catchError((err) { +// GifLoaderDialogUtils.hideDialog(context); +// print(err); +// }); +// } +// +// setDefault() async { +// if (await sharedPref.getObject(IMEI_USER_DATA) != null) user = SelectDeviceIMEIRES.fromJson(await sharedPref.getObject(IMEI_USER_DATA)); +// +// if (await sharedPref.getObject(REGISTER_DATA_FOR_LOGIIN) != null) { +// isMoreOption = true; +// this.registerd_data = CheckPatientAuthenticationReq.fromJson(await sharedPref.getObject(REGISTER_DATA_FOR_LOGIIN)); +// } +// +// this.mobileNumber = this.registerd_data != null ? this.registerd_data.patientMobileNumber : int.parse(this.user.mobile); +// this.zipCode = this.registerd_data != null +// ? this.registerd_data.zipCode +// : this.user.outSA == true +// ? "971" +// : "966"; +// this.patientOutSA = this.registerd_data != null +// ? this.registerd_data.zipCode == "966" +// ? 0 +// : 1 +// : this.user.outSA; +// if (this.registerd_data != null) { +// this.loginTokenID = await sharedPref.getString(LOGIN_TOKEN_ID); +// this.loginType = this.registerd_data.searchType; +// } +// var nhic = await sharedPref.getObject(NHIC_DATA); +// if (nhic != null) { +// final DateFormat dateFormat = DateFormat('MM/dd/yyyy'); +// final DateFormat dateFormat2 = DateFormat('dd/MM/yyyy'); +// dob = nhic['IsHijri'] ? nhic['DateOfBirth'] : dateFormat2.format(dateFormat.parse(nhic['DateOfBirth'])); +// +// isHijri = nhic['IsHijri'] ? 1 : 0; +// healthId = nhic['HealthId']; +// } +// this.deviceToken = await sharedPref.getString(PUSH_TOKEN); +// this.lastLogin = await sharedPref.getInt(LAST_LOGIN) != null +// ? await sharedPref.getInt(LAST_LOGIN) +// : user != null +// ? user.logInType +// : null; +// +// //this.cs.sharedService.getStorage(AuthenticationService.LAST_LOGIN); +// } +// +// getCommonRequest({type}) { +// var request = SendActivationRequest(); +// request.patientMobileNumber = this.mobileNumber; +// request.mobileNo = '0' + this.mobileNumber.toString(); +// request.deviceToken = this.deviceToken; +// request.projectOutSA = this.patientOutSA == true ? true : false; +// request.loginType = this.selectedOption; +// request.oTPSendType = type == 1 ? type : 2; //this.selectedOption == 1 ? 1 : 2; +// request.zipCode = this.zipCode; +// +// request.logInTokenID = this.loginTokenID ?? ""; +// +// if (this.registerd_data != null) { +// request.searchType = this.registerd_data.searchType != null ? this.registerd_data.searchType : 1; +// request.patientID = this.registerd_data.patientID != null ? this.registerd_data.patientID : 0; +// request.patientIdentificationID = request.nationalID = this.registerd_data.patientIdentificationID != null ? this.registerd_data.patientIdentificationID : '0'; +// +// request.isRegister = this.registerd_data.isRegister; +// } else { +// request.searchType = request.searchType != null ? request.searchType : 2; +// request.patientID = this.user.patientID != null ? this.user.patientID : 0; +// request.nationalID = request.nationalID != null ? request.nationalID : '0'; +// request.patientIdentificationID = request.patientIdentificationID != null ? request.patientIdentificationID : '0'; +// request.isRegister = false; +// } +// request.deviceTypeID = request.searchType; +// return request; +// } +// +// // checkActivationCode({value}) async { +// // // Navigator.pop(context); +// // GifLoaderDialogUtils.showMyDialog(context); +// // var request = this.getCommonRequest().toJson(); +// // dynamic res; +// // if (healthId != null) { +// // request['DOB'] = dob; +// // request['HealthId'] = healthId; +// // request['IsHijri'] = isHijri; +// // +// // authService +// // .checkActivationCodeRegister(request, value) +// // .then((result) => { +// // res = result, +// // if (result is Map) +// // { +// // result = CheckActivationCode.fromJson(result), +// // if (this.registerd_data != null && this.registerd_data.isRegister == true) +// // { +// // widget.changePageViewIndex(1), +// // Navigator.popUntil(context, (route) => Utils.route(route, equalsTo: RegisterNew)), +// // } +// // } +// // else +// // { +// // // Navigator.of(context).pop(), +// // GifLoaderDialogUtils.hideDialog(context), +// // Future.delayed(Duration(seconds: 1), () { +// // AppToast.showErrorToast(message: result); +// // }), +// // } +// // }) +// // .catchError((err) { +// // print(err); +// // GifLoaderDialogUtils.hideDialog(context); +// // Future.delayed(Duration(seconds: 1), () { +// // AppToast.showErrorToast(message: err); +// // startSMSService(tempType); +// // }); +// // }); +// // } else { +// // authService +// // .checkActivationCode(request, value) +// // .then((result) => { +// // res = result, +// // if (result is Map) +// // { +// // result = CheckActivationCode.fromJson(result), +// // if (this.registerd_data != null && this.registerd_data.isRegister == true) +// // { +// // widget.changePageViewIndex(1), +// // Navigator.popUntil(context, (route) => Utils.route(route, equalsTo: RegisterNew)), +// // } +// // else +// // { +// // sharedPref.remove(FAMILY_FILE), +// // result.list.isFamily = false, +// // userData = result.list, +// // sharedPref.setString(BLOOD_TYPE, result.patientBloodType), +// // authenticatedUserObject.user = result.list, +// // projectViewModel.setPrivilege(privilegeList: res), +// // sharedPref.setObject(MAIN_USER, result.list), +// // sharedPref.setObject(USER_PROFILE, result.list), +// // loginTokenID = result.logInTokenID, +// // sharedPref.setObject(LOGIN_TOKEN_ID, result.logInTokenID), +// // sharedPref.setString(TOKEN, result.authenticationTokenID), +// // checkIfUserAgreedBefore(result), +// // } +// // } +// // else +// // { +// // // // Navigator.of(context).pop(), +// // // GifLoaderDialogUtils.hideDialog(context), +// // // Future.delayed(Duration(seconds: 1), () { +// // // AppToast.showErrorToast(message: result); +// // // startSMSService(tempType); +// // // }), +// // } +// // }) +// // .catchError((err) { +// // // print(err); +// // // GifLoaderDialogUtils.hideDialog(context); +// // // Future.delayed(Duration(seconds: 1), () { +// // // AppToast.showErrorToast(message: err); +// // // startSMSService(tempType); +// // // }); +// // }); +// // } +// // } +// +// // checkIfUserAgreedBefore(CheckActivationCode result) { +// // if (result.isNeedUserAgreement == true) { +// // //move to agreement page. +// // } else { +// // goToHome(); +// // } +// // } +// +// insertIMEI() { +// authService.insertDeviceImei(selectedOption).then((value) => {}).catchError((err) { +// print(err); +// }); +// } +// +// // getToDoCount() { +// // toDoProvider.setState(0, true, "0"); +// // ClinicListService service = new ClinicListService(); +// // service.getActiveAppointmentNo(context).then((res) { +// // if (res['MessageStatus'] == 1) { +// // toDoProvider.setState(res['AppointmentActiveNumber'], true, "0"); +// // } else {} +// // }).catchError((err) { +// // print(err); +// // }); +// // } +// +// // goToHome() async { +// // authenticatedUserObject.isLogin = true; +// // appointmentRateViewModel.isLogin = true; +// // projectViewModel.isLogin = true; +// // projectViewModel.user = authenticatedUserObject.user; +// // await authenticatedUserObject.getUser(getUser: true); +// // +// // // getToDoCount(); +// // +// // appointmentRateViewModel +// // .getIsLastAppointmentRatedList() +// // .then((value) => { +// // getToDoCount(), +// // GifLoaderDialogUtils.hideDialog(AppGlobal.context), +// // if (appointmentRateViewModel.isHaveAppointmentNotRate) +// // { +// // Navigator.pushAndRemoveUntil( +// // context, +// // FadePage( +// // page: RateAppointmentDoctor(), +// // ), +// // (r) => false) +// // } +// // else +// // { +// // Navigator.pushAndRemoveUntil( +// // context, +// // FadePage( +// // page: LandingPage(), +// // ), +// // (r) => false) +// // }, +// // insertIMEI() +// // }) +// // .catchError((err) { +// // print(err); +// // }); +// // } +// +// loading(flag) { +// // setState(() { +// // isLoading = flag; +// // }); +// } +// + Widget _loginOptionButton(String _title, String _icon, int _flag, int? _loginIndex) { + bool isDisable = ((_flag == 3 && !checkBiometricIsAvailable(BiometricType.face)) || (_flag == 2 && !checkBiometricIsAvailable(BiometricType.fingerprint))); + print("$_title:$isDisable"); + return InkWell( + onTap: isDisable + ? null + : () async { + if (_flag == 0) { + setState(() { + // isMoreOption = true; + }); + } else { + Utils.showLoading(context); + BasicMemberInformationModel? memberInformationModel = await LoginApiClient() + .mohemmSendActivationCodeByOTPNotificationType(checkBiometricIsAvailable(BiometricType.fingerprint) ? 1 : 0, AppState().memberLoginList?.pMOBILENUMBER, _flag, AppState().getUserName); + Utils.hideLoading(context); + OtpDialog( + context, + _flag, + int.tryParse(AppState().memberLoginList?.pMOBILENUMBER ?? ""), + (value) async { + Utils.showLoading(context); + try { + GenericResponseModel? genericResponseModel = await LoginApiClient().checkActivationCode(false, AppState().memberLoginList?.pMOBILENUMBER, value, AppState().getUserName); + if (genericResponseModel?.errorMessage != null) { + Utils.showToast(genericResponseModel?.errorMessage ?? ""); + // Navigator.pop(context); + } + Utils.hideLoading(context); + Navigator.pop(context); + Navigator.pushNamedAndRemoveUntil(context, AppRoutes.dashboard, (Route route) => false); + } catch (ex) { + print(ex); + Utils.hideLoading(context); + Utils.handleException(ex, null); + } + }, + () => { + Navigator.pop(context), + }, + ).displayDialog(context); + + // authenticateUser(_flag, isActive: _loginIndex); + } + }, + child: Container( + padding: const EdgeInsets.only(left: 20, right: 20, bottom: 15, top: 28), + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(15), + color: isDisable ? Colors.grey.withOpacity(0.3) : Colors.white, + border: Border.all(color: MyColors.lightGreyEFColor, width: 1), + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + SvgPicture.asset( + _icon, + height: 38, + width: 38, + color: isDisable ? MyColors.darkTextColor.withOpacity(0.7) : null, + ), + _title.toText16() + ], + ), + ), + ); + } + + Widget getButton(int flag) { + switch (flag) { + case 4: + return _loginOptionButton(LocaleKeys.verifyThroughWhatsapp.tr(), 'assets/images/login/verify_whatsapp.svg', flag, null); + case 1: + return _loginOptionButton(LocaleKeys.verifyThroughSMS.tr(), 'assets/images/login/verify_sms.svg', flag, null); + case 2: + return _loginOptionButton(LocaleKeys.verifyThroughFingerprint.tr(), 'assets/images/login/verify_thumb.svg', flag, BiometricType.fingerprint.index); + case 3: + return _loginOptionButton(LocaleKeys.verifyThroughFace.tr(), 'assets/images/login/verify_face.svg', flag, BiometricType.face.index); + default: + return const SizedBox(); + } + } + + bool checkBiometricIsAvailable(BiometricType biometricType) { + bool isAvailable = false; + for (int i = 0; i < _availableBioMetricType.length; i++) { + if (biometricType == _availableBioMetricType[i]) { + isAvailable = true; + break; + } + } + return isAvailable; + } +// +// formatDate(date) { +// return date; +// return DateFormat('MMM dd, yyy, kk:mm').format(date); +// } +// +// showLoader(bool isTrue) { +// setState(() { +// // isLoading = isTrue; +// }); +// } + +} diff --git a/lib/ui/misc/no_data_ui.dart b/lib/ui/misc/no_data_ui.dart new file mode 100644 index 0000000..5af6af7 --- /dev/null +++ b/lib/ui/misc/no_data_ui.dart @@ -0,0 +1,26 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_svg/svg.dart'; +import 'package:mohem_flutter_app/classes/colors.dart'; + +class NoDataUI extends StatelessWidget { + NoDataUI({Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + return Container( + alignment: Alignment.center, + padding: const EdgeInsets.only(top: 100), + child: Column( + children: [ + SvgPicture.asset("assets/icons/no_data.svg", width: 75, height: 75), + const SizedBox(height: 8), + Text( + "لا توجد بيانات", + style: TextStyle(fontSize: 16, color: MyColors.darkTextColor.withOpacity(0.7), fontWeight: FontWeight.w600), + ), + const SizedBox(height: 16), + ], + ), + ); + } +} diff --git a/lib/ui/screens/tangheem_detail_screen.dart b/lib/ui/screens/tangheem_detail_screen.dart new file mode 100644 index 0000000..b4ca256 --- /dev/null +++ b/lib/ui/screens/tangheem_detail_screen.dart @@ -0,0 +1,819 @@ +// import 'package:flutter/cupertino.dart'; +// import 'package:flutter/material.dart'; +// import 'package:flutter_html/flutter_html.dart'; +// import 'package:flutter_svg/flutter_svg.dart'; +// import 'package:shared_preferences/shared_preferences.dart'; +// import 'package:tangheem/api/admin_configuration_api_client.dart'; +// import 'package:tangheem/api/tangheem_user_api_client.dart'; +// import 'package:tangheem/app_state/app_state.dart'; +// import 'package:tangheem/classes/colors.dart'; +// import 'package:tangheem/classes/consts.dart'; +// import 'package:tangheem/classes/utils.dart'; +// import 'package:tangheem/extensions/string_extensions.dart'; +// import 'package:tangheem/models/aya_tangheem_type_mapped.dart'; +// import 'package:tangheem/models/discussion_model.dart'; +// import 'package:tangheem/ui/dialogs/discussion_input_dialog.dart'; +// import 'package:tangheem/widgets/aya_player_widget.dart'; +// import 'package:tangheem/widgets/aya_record_widget.dart'; +// import 'package:tangheem/widgets/text_highlight_widget.dart'; +// +// import 'login_screen.dart'; +// +// class TangheemDetailParams { +// final String selectedTangheemTypeId; +// final List ayatTangheemTypeMappedDataList; +// +// TangheemDetailParams({@required this.selectedTangheemTypeId, @required this.ayatTangheemTypeMappedDataList}); +// } +// +// class TangheemDetailScreen extends StatefulWidget { +// static const String routeName = "/tangheem_detail"; +// final TangheemDetailParams tangheemDetailParams; +// +// TangheemDetailScreen({Key key, this.tangheemDetailParams}) : super(key: key); +// +// @override +// _TangheemDetailScreenState createState() { +// return _TangheemDetailScreenState(); +// } +// } +// +// class _TangheemDetailScreenState extends State { +// GlobalKey _globalKey = GlobalKey(); +// +// List voiceNoteList = []; +// +// List ayatTangheemTypeMappedDataList = []; +// +// List _dataList = []; +// +// int _discussionPage = -1; +// AyatTangheemTypeMappedData _ayatTangheemTypeMappedFirstData; +// DiscussionModel _discussionModel; +// +// bool showAyaPlayer = false; +// +// @override +// void initState() { +// super.initState(); +// ayatTangheemTypeMappedDataList = widget.tangheemDetailParams.ayatTangheemTypeMappedDataList; +// _ayatTangheemTypeMappedFirstData = ayatTangheemTypeMappedDataList.first; +// filterVoiceListData(); +// getPrefs(); +// getTangheemDiscussionAndRelatedData(); +// } +// +// double fontSize = 18; +// +// SharedPreferences prefs; +// +// void getPrefs() async { +// prefs = await SharedPreferences.getInstance(); +// fontSize = (prefs.getInt(GlobalConsts.fontZoomSize) ?? 18) + 0.0; +// setState(() {}); +// } +// +// String getArabicIndexWord(int index) { +// if (index == 0) { +// return 'الأولى'; +// } else if (index == 1) { +// return 'الثانية'; +// } else if (index == 2) { +// return 'الثالثة'; +// } else if (index == 3) { +// return 'الرابعة'; +// } else if (index == 4) { +// return 'الخامسة'; +// } +// return ""; +// } +// +// void getTangheemDiscussionAndRelatedData() async { +// Utils.showLoading(context); +// try { +// _discussionModel = await TangheemUserApiClient().getDiscussionByTangheemID(_discussionPage, widget.tangheemDetailParams.selectedTangheemTypeId); +// if (!_ayatTangheemTypeMappedFirstData.ayatNumberInSurahs.contains(",")) { +// _dataList = await getTangheemRelatedData(); +// } +// Utils.hideLoading(context); +// setState(() {}); +// } catch (ex) { +// print(ex); +// Utils.handleException(ex, null); +// Utils.hideLoading(context); +// } +// } +// +// Future> getTangheemRelatedData() async { +// _dataList = []; +// AyatTangheemTypeMapped _ayatTangheemTypeMapped = +// await TangheemUserApiClient().getAyaTangheemTypeMappedRelated(_ayatTangheemTypeMappedFirstData.surahNo, _ayatTangheemTypeMappedFirstData.ayatNumberInSurahs); +// _dataList = _ayatTangheemTypeMapped?.data ?? []; +// if (_dataList.isNotEmpty) { +// _dataList = _dataList.where((element) => element.tangheemTypeId != _ayatTangheemTypeMappedFirstData.tangheemTypeId)?.toList() ?? []; +// var _tempList = _dataList.map((e) => e.tangheemTypeId).toList().toSet().toList(); +// var _dataTempList = []; +// _tempList.forEach((_tempElement) { +// _dataTempList.add(_dataList.firstWhere((element) { +// return !element.ayatNumberInSurahs.contains(",") && (element.tangheemTypeId == _tempElement); +// }, orElse: null)); +// }); +// _dataList = _dataTempList; +// } +// +// return _dataList; +// } +// +// void sendComment(String discussionText) async { +// Utils.showLoading(context); +// try { +// await AdminConfigurationApiClient().addDiscussion(discussionText, _ayatTangheemTypeMappedFirstData.ayaTangheemTypeId); +// Utils.showToast("تم إرسال التعليق ، سيكون مرئيًا بمجرد موافقة المسؤول عليه"); +// Utils.hideLoading(context); +// Navigator.pop(context); +// } catch (ex) { +// Utils.handleException(ex, null); +// Utils.hideLoading(context); +// } +// } +// +// void filterVoiceListData() { +// ayatTangheemTypeMappedDataList.forEach((element) { +// voiceNoteList.addAll(element.voiceNote); +// }); +// } +// +// @override +// void dispose() { +// super.dispose(); +// } +// +// @override +// Widget build(BuildContext context) { +// return Container( +// padding: EdgeInsets.fromLTRB(16, 0, 16, 0), +// width: double.infinity, +// child: _ayatTangheemTypeMappedFirstData == null +// ? SizedBox() +// : Column( +// crossAxisAlignment: CrossAxisAlignment.start, +// children: [ +// Expanded( +// child: ListView( +// physics: BouncingScrollPhysics(), +// padding: EdgeInsets.only(bottom: 16, top: 16), +// children: [ +// Text( +// _ayatTangheemTypeMappedFirstData.tangheemTypeName ?? "", +// style: TextStyle(fontWeight: FontWeight.bold, fontSize: 20, color: ColorConsts.primaryBlue, height: 1.5), +// ), +// SizedBox(height: 8), +// Text( +// _ayatTangheemTypeMappedFirstData.tangheemTypeDescription ?? "", +// style: TextStyle(fontSize: 14, color: ColorConsts.textGrey, height: 1), +// ), +// SizedBox(height: 8), +// Container( +// margin: EdgeInsets.only(top: 4, bottom: 4), +// padding: EdgeInsets.only(top: 8, bottom: 8, right: 4, left: 4), +// decoration: BoxDecoration( +// color: Colors.white, +// borderRadius: BorderRadius.circular(8), +// ), +// child: SingleChildScrollView( +// physics: NeverScrollableScrollPhysics(), +// child: RepaintBoundary( +// key: _globalKey, +// child: Material( +// color: Colors.white, +// child: ListView.builder( +// physics: NeverScrollableScrollPhysics(), +// shrinkWrap: true, +// itemCount: ayatTangheemTypeMappedDataList.length > 5 ? 5 : ayatTangheemTypeMappedDataList.length, +// itemBuilder: (context, index) { +// var _ayatTangheemTypeMappedData = ayatTangheemTypeMappedDataList[index]; +// List _tangheemInsideTableList = []; +// List _tangheemAboveTableList = []; +// List _tangheemBelowTableList = []; +// List _tangheemWords = []; +// +// List _tempPropertyList = List() + _ayatTangheemTypeMappedData?.property ?? []; +// int firstIndex = _tempPropertyList.indexWhere((element) => element.isInsideTable); +// if (firstIndex >= 0) { +// var _tempPropertyListTop = _tempPropertyList.take(firstIndex); +// _tempPropertyListTop = _tempPropertyListTop.where((element) => (element.propertyValue ?? "").isNotEmpty)?.toList() ?? []; +// _tangheemAboveTableList = _tempPropertyListTop; +// _tempPropertyListTop.forEach((element) { +// _tempPropertyList.remove(element); +// }); +// var _tempPropertyListInside = _tempPropertyList?.where((element) => (element.isInsideTable))?.toList() ?? []; +// _tempPropertyListInside.forEach((element) { +// _tempPropertyList.remove(element); +// }); +// _tempPropertyListInside = _tempPropertyListInside.where((element) => (element.propertyValue ?? "").isNotEmpty)?.toList() ?? []; +// _tangheemInsideTableList = _tempPropertyListInside; +// var _tempPropertyListBelow = _tempPropertyList; +// _tempPropertyListBelow = _tempPropertyListBelow.where((element) => (element.propertyValue ?? "").isNotEmpty)?.toList() ?? []; +// _tangheemBelowTableList = _tempPropertyListBelow; +// } +// +// _tangheemWords.add(_ayatTangheemTypeMappedData.highlightText ?? ""); +// // _tangheemInsideTableList = +// // _ayatTangheemTypeMappedData?.property?.where((element) => (element.isInsideTable) && (element.propertyValue ?? "").isNotEmpty)?.toList() ?? []; +// // _tangheemAboveTableList = +// // _ayatTangheemTypeMappedData?.property?.where((element) => (!element.isInsideTable) && (element.propertyValue ?? "").isNotEmpty)?.toList() ?? []; +// // +// // +// +// var _tempTangheemIndexWord = ""; +// if (ayatTangheemTypeMappedDataList.length == 1) { +// _tempTangheemIndexWord = ""; +// } else { +// _tempTangheemIndexWord = getArabicIndexWord(index) + " "; +// } +// +// return ListView( +// physics: NeverScrollableScrollPhysics(), +// shrinkWrap: true, +// padding: EdgeInsets.all(4), +// children: [ +// Row( +// children: [ +// Text( +// " جملة ${_ayatTangheemTypeMappedData.tangheemTypeName} $_tempTangheemIndexWord", +// style: TextStyle(fontWeight: FontWeight.bold, color: Colors.white, backgroundColor: ColorConsts.primaryBlue), +// ), +// Expanded( +// child: Container(height: 2, color: ColorConsts.primaryBlue), +// ), +// ], +// ), +// SizedBox(height: 8), +// TextHighLightWidget( +// text: _ayatTangheemTypeMappedData.reverseAyatNumber() ?? "", +// valueColor: ColorConsts.primaryBlue, +// highlights: _tangheemWords, +// highLightFontSize: fontSize, +// style: TextStyle( +// fontFamily: "UthmanicHafs", +// fontSize: fontSize, +// fontWeight: FontWeight.bold, +// ), +// ), +// SizedBox(height: 16), +// ListView.separated( +// itemCount: _tangheemAboveTableList.length, +// physics: NeverScrollableScrollPhysics(), +// shrinkWrap: true, +// separatorBuilder: (context, index) { +// return Divider( +// color: Colors.white, +// height: 4, +// thickness: 0, +// ); +// }, +// itemBuilder: (context, index) { +// return Row( +// children: [ +// Expanded( +// child: Container( +// height: 40, +// padding: EdgeInsets.only(left: 4, right: 8), +// alignment: Alignment.centerRight, +// child: Text( +// _tangheemAboveTableList[index].propertyText, +// maxLines: 1, +// style: TextStyle(fontWeight: FontWeight.bold, color: ColorConsts.secondaryOrange), +// ), +// color: ColorConsts.secondaryWhite, +// ), +// ), +// SizedBox(width: 4), +// Expanded( +// child: Container( +// color: ColorConsts.secondaryWhite, +// padding: EdgeInsets.all(4), +// child: Container( +// color: Colors.white, +// padding: EdgeInsets.only(left: 4, right: 8), +// // alignment: Alignment.centerRight, +// child: Html( +// data: _tangheemAboveTableList[index]?.propertyValue ?? "", +// style: { +// 'html': Style(textAlign: TextAlign.left), +// }, +// ), +// +// // Text( +// // _tangheemAboveTableList[index].propertyValue, +// // maxLines: 1, +// // style: TextStyle( +// // color: Color( +// // Utils.stringToHex(_tangheemAboveTableList[index].textColor), +// // ), +// // ), +// // ), +// ), +// ), +// ) +// ], +// ); +// }), +// if (_tangheemInsideTableList.isNotEmpty) +// Container( +// color: ColorConsts.primaryBlue, +// margin: EdgeInsets.only(top: 8, bottom: 8), +// padding: EdgeInsets.all(8), +// child: Column( +// children: [ +// Text( +// "خط النبر و التنغيم ل${_ayatTangheemTypeMappedData.tangheemTypeName ?? ""}", +// style: TextStyle(fontWeight: FontWeight.bold, color: Colors.white), +// ), +// SizedBox(height: 8), +// tangheemInsideTablePropertyView(_tangheemInsideTableList) +// ], +// ), +// ), +// tangheemOutSideTablePropertyView(_tangheemBelowTableList) +// ], +// ); +// }), +// ), +// ), +// ), +// ), +// SizedBox(height: 8), +// discussionView(_discussionModel?.data ?? []), +// if (_dataList.isNotEmpty) +// Container( +// margin: EdgeInsets.only(top: 8), +// padding: EdgeInsets.only(bottom: 20), +// width: double.infinity, +// decoration: BoxDecoration( +// color: Colors.white, +// borderRadius: BorderRadius.circular(8), +// ), +// child: Column( +// children: [ +// Container( +// height: 60, +// width: double.infinity, +// margin: EdgeInsets.only(bottom: 8), +// alignment: Alignment.center, +// decoration: BoxDecoration( +// color: ColorConsts.primaryBlue, +// borderRadius: BorderRadius.only( +// topLeft: Radius.circular(8), +// topRight: Radius.circular(8), +// ), +// ), +// child: Text( +// "قائمة الأساليب اللغوية في هذه الآية", +// style: TextStyle(fontSize: 16, color: Colors.white), +// ), +// ), +// ListView.separated( +// padding: EdgeInsets.fromLTRB(4, 8, 4, 4), +// shrinkWrap: true, +// physics: NeverScrollableScrollPhysics(), +// itemCount: _dataList.length, +// separatorBuilder: (context, index) => SizedBox(height: 16), +// itemBuilder: (context, index) { +// return InkWell( +// onTap: () { +// List list = _dataList; +// var removedData = list[index]; +// list.remove(removedData); +// list.insert(0, removedData); +// TangheemDetailParams tangheem = TangheemDetailParams(selectedTangheemTypeId: _dataList[index].ayaTangheemTypeId, ayatTangheemTypeMappedDataList: list); +// Navigator.pushNamed(context, TangheemDetailScreen.routeName, arguments: tangheem); +// }, +// child: Text( +// _dataList[index].tangheemTypeName, +// style: TextStyle(fontWeight: FontWeight.bold, fontSize: 16, color: ColorConsts.secondaryOrange, height: 1.5), +// ), +// ); +// }, +// ), +// ], +// ), +// ), +// SizedBox(height: 16), +// AyaRecordWidget() +// ], +// ), +// ), +// if (MediaQuery.of(context).orientation == Orientation.portrait) +// AyaPlayerWidget( +// surahName: _ayatTangheemTypeMappedFirstData?.surahNameAr ?? "", +// ayaTangheemTypeId: _ayatTangheemTypeMappedFirstData?.ayaTangheemTypeId ?? "", +// globalKey: _globalKey, +// ayaNo: _ayatTangheemTypeMappedFirstData?.ayahNo, +// surahNo: _ayatTangheemTypeMappedFirstData?.surahNo, +// voiceNoteList: voiceNoteList), +// if (MediaQuery.of(context).orientation == Orientation.landscape) +// Column( +// mainAxisSize: MainAxisSize.min, +// crossAxisAlignment: CrossAxisAlignment.start, +// children: [ +// Container( +// height: 24, +// margin: EdgeInsets.only(bottom: 8, top: 8), +// // color: Colors.transparent, +// child: TextButton( +// onPressed: () { +// setState(() { +// showAyaPlayer = !showAyaPlayer; +// }); +// }, +// child: Text( +// showAyaPlayer ? "إخفاء التسجيلات" : "إظهار التسجيلات", +// style: TextStyle(color: Colors.black87, fontSize: 12), +// ), +// style: TextButton.styleFrom( +// backgroundColor: ColorConsts.gradientOrange, +// primary: ColorConsts.primaryBlue, +// padding: EdgeInsets.only(top: 4, bottom: 4, right: 8, left: 8), +// textStyle: TextStyle(color: Colors.white, fontSize: 12), +// ), +// ), +// ), +// if (showAyaPlayer) +// AyaPlayerWidget( +// surahName: _ayatTangheemTypeMappedFirstData?.surahNameAr ?? "", +// ayaTangheemTypeId: _ayatTangheemTypeMappedFirstData?.ayaTangheemTypeId ?? "", +// ayaNo: _ayatTangheemTypeMappedFirstData?.ayahNo, +// surahNo: _ayatTangheemTypeMappedFirstData?.surahNo, +// globalKey: _globalKey, +// voiceNoteList: voiceNoteList), +// ], +// ) +// ], +// ), +// ); +// } +// +// Widget nextOptionButton(String icon, String text, VoidCallback onPressed) { +// return InkWell( +// onTap: onPressed, +// child: onPressed == null +// ? SizedBox() +// : Row( +// crossAxisAlignment: CrossAxisAlignment.center, +// mainAxisSize: MainAxisSize.min, +// children: [ +// SvgPicture.asset(icon, height: 12, width: 12), +// SizedBox(width: 4), +// Text( +// text, +// style: TextStyle(color: ColorConsts.textGrey), +// ), +// ], +// ), +// ); +// } +// +// Widget previousOptionButton(String icon, String text, VoidCallback onPressed) { +// return InkWell( +// onTap: onPressed, +// child: onPressed == null +// ? SizedBox() +// : Row( +// crossAxisAlignment: CrossAxisAlignment.center, +// mainAxisSize: MainAxisSize.min, +// children: [ +// Text( +// text, +// style: TextStyle(color: ColorConsts.textGrey), +// ), +// SizedBox(width: 4), +// SvgPicture.asset(icon, height: 12, width: 12), +// ], +// ), +// ); +// } +// +// Widget tangheemOutSideTablePropertyView(List tangheemPropertyList) { +// return ListView.separated( +// itemCount: tangheemPropertyList.length, +// physics: NeverScrollableScrollPhysics(), +// shrinkWrap: true, +// separatorBuilder: (context, index) { +// return Divider( +// color: Colors.white, +// height: 4, +// thickness: 0, +// ); +// }, +// itemBuilder: (context, index) { +// return Row( +// children: [ +// Expanded( +// child: Container( +// height: 40, +// padding: EdgeInsets.only(left: 4, right: 8), +// alignment: Alignment.centerRight, +// child: Text( +// tangheemPropertyList[index].propertyText, +// maxLines: 1, +// style: TextStyle(fontWeight: FontWeight.bold, color: ColorConsts.secondaryOrange), +// ), +// color: ColorConsts.secondaryWhite, +// ), +// ), +// SizedBox(width: 4), +// Expanded( +// child: Container( +// color: ColorConsts.secondaryWhite, +// padding: EdgeInsets.all(4), +// child: Container( +// color: Colors.white, +// padding: EdgeInsets.only(left: 4, right: 8), +// // alignment: Alignment.centerRight, +// child: Html( +// data: tangheemPropertyList[index]?.propertyValue ?? "", +// style: { +// 'html': Style(textAlign: TextAlign.left), +// }, +// ), +// // Text( +// // tangheemPropertyList[index].propertyValue, +// // maxLines: 1, +// // style: TextStyle( +// // color: Color( +// // Utils.stringToHex(tangheemPropertyList[index].textColor), +// // ), +// // ), +// // ), +// ), +// ), +// ) +// ], +// ); +// }); +// } +// +// Widget tangheemInsideTablePropertyView(List tangheemPropertyList) { +// return Container( +// color: Colors.white, +// padding: EdgeInsets.all(2), +// child: Row( +// children: [ +// for (var property in tangheemPropertyList) +// Expanded( +// child: Container( +// // color: ColorConsts.secondaryWhite, +// // padding: EdgeInsets.all(8), +// margin: EdgeInsets.only(left: 2, right: 2), +// child: Column( +// mainAxisSize: MainAxisSize.min, +// crossAxisAlignment: CrossAxisAlignment.start, +// mainAxisAlignment: MainAxisAlignment.center, +// children: [ +// Container( +// color: ColorConsts.secondaryWhite, +// //height: 30, +// alignment: Alignment.center, +// padding: EdgeInsets.only(left: 2, right: 4), +// width: double.infinity, +// child: Text( +// property.propertyText ?? "", +// // maxLines: 1, +// style: TextStyle(fontWeight: FontWeight.bold, fontSize: 12, color: ColorConsts.secondaryOrange), +// ), +// ), +// Container(width: double.infinity, height: 4, color: Colors.white), +// Container( +// color: ColorConsts.secondaryWhite, +// padding: EdgeInsets.all(4), +// child: Container( +// color: Colors.white, +// padding: EdgeInsets.only(left: 2, right: 4), +// width: double.infinity, +// child: Html( +// data: property.propertyValue ?? "", +// style: { +// 'html': Style(textAlign: TextAlign.left), +// }, +// ), +// +// // Text( +// // property.propertyValue ?? "", +// // maxLines: 1, +// // style: TextStyle( +// // fontSize: 12, +// // color: Color( +// // Utils.stringToHex(property.textColor), +// // ), +// // ), +// // ), +// ), +// ), +// ], +// ), +// ), +// ) +// ], +// ) +// +// //@todo sikander :commented these line for later discussion +// // ListView.separated( +// // itemCount: tangheemPropertyList.length, +// // physics: NeverScrollableScrollPhysics(), +// // padding: EdgeInsets.zero, +// // shrinkWrap: true, +// // separatorBuilder: (context, index) { +// // return Divider( +// // color: Colors.white, +// // height: 1, +// // thickness: 0, +// // ); +// // }, +// // itemBuilder: (context, index) { +// // return Container( +// // color: ColorConsts.secondaryWhite, +// // padding: EdgeInsets.all(8), +// // child: Column( +// // mainAxisSize: MainAxisSize.min, +// // crossAxisAlignment: CrossAxisAlignment.start, +// // mainAxisAlignment: MainAxisAlignment.center, +// // children: [ +// // Text( +// // tangheemPropertyList[index].propertyText ?? "", +// // style: TextStyle(fontWeight: FontWeight.bold, fontSize: 12, color: ColorConsts.secondaryOrange), +// // ), +// // SizedBox(height: 4), +// // Text( +// // tangheemPropertyList[index].propertyValue ?? "", +// // style: TextStyle( +// // fontSize: 12, +// // color: Color( +// // Utils.stringToHex(tangheemPropertyList[index].textColor), +// // ), +// // ), +// // ), +// // ], +// // ), +// // ); +// // }, +// // ), +// ); +// } +// +// Widget discussionView(List _discussionList) { +// _discussionList = _discussionList.where((element) => element.status.toLowerCase() == "Accept".toLowerCase()).toList(); +// return Stack( +// alignment: Alignment.bottomCenter, +// children: [ +// Container( +// margin: EdgeInsets.only(top: 4, bottom: 25), +// padding: EdgeInsets.all(8), +// width: double.infinity, +// decoration: BoxDecoration( +// color: Colors.white, +// borderRadius: BorderRadius.circular(8), +// ), +// child: _discussionList.length > 0 +// ? ListView.separated( +// padding: EdgeInsets.only(top: 4, bottom: 24), +// shrinkWrap: true, +// physics: NeverScrollableScrollPhysics(), +// itemCount: _discussionList.length, +// separatorBuilder: (context, index) => SizedBox(height: 16), +// itemBuilder: (context, index) { +// return Column( +// crossAxisAlignment: CrossAxisAlignment.start, +// mainAxisSize: MainAxisSize.min, +// children: [ +// Row( +// children: [ +// SvgPicture.asset( +// "assets/icons/chat_user.svg", +// width: 60, +// height: 60, +// ), +// SizedBox(width: 8), +// Column( +// crossAxisAlignment: CrossAxisAlignment.start, +// mainAxisAlignment: MainAxisAlignment.center, +// children: [ +// Text( +// "تعليق على الآية ${_ayatTangheemTypeMappedFirstData.ayatNumberInSurahs}", +// style: TextStyle(fontWeight: FontWeight.bold, fontSize: 16, color: ColorConsts.primaryBlue, height: 1.5), +// ), +// SizedBox(height: 4), +// Directionality( +// textDirection: TextDirection.ltr, +// child: Text( +// _discussionList[index].date.toFormattedDate(), +// style: TextStyle(fontSize: 12, color: ColorConsts.textGrey, height: 1), +// ), +// ), +// ], +// ) +// ], +// ), +// SizedBox(height: 4), +// Column( +// crossAxisAlignment: CrossAxisAlignment.start, +// children: [ +// Text( +// "تعليق من: " + _discussionList[index].userName, +// style: TextStyle(fontWeight: FontWeight.bold, fontSize: 14, color: ColorConsts.primaryBlue, height: 1.5), +// ), +// Text( +// _discussionList[index].discussionText, +// style: TextStyle(fontSize: 14, color: ColorConsts.textGrey, height: 1.4), +// ), +// if ((_discussionList[index]?.adminResponse ?? "").isNotEmpty) SizedBox(height: 4), +// if ((_discussionList[index]?.adminResponse ?? "").isNotEmpty) +// Text( +// "رد من المسؤول: " + _discussionList[index].adminResponse, +// style: TextStyle(fontSize: 14, color: ColorConsts.textGrey, height: 1.4), +// ), +// ], +// ) +// ], +// ); +// }, +// ) +// : Text( +// "لا يوجد تعليقات", +// style: TextStyle(fontSize: 12, color: ColorConsts.primaryBlue, height: 1.5), +// ), +// ), +// Positioned( +// bottom: 0, +// child: InkWell( +// borderRadius: BorderRadius.circular(30), +// onTap: () async { +// if (!AppState().isUserLogin) { +// Widget cancelButton = FlatButton( +// child: Text("أرغب بالتسجيل"), +// onPressed: () async { +// Navigator.pop(context); +// await Navigator.pushNamed(context, LoginScreen.routeName); +// if (!AppState().isUserLogin) { +// return; +// } +// }, +// ); +// Widget continueButton = FlatButton( +// child: Text("استمرار كضيف"), +// onPressed: () { +// Navigator.pop(context); +// return; +// }, +// ); +// +// AlertDialog alert = AlertDialog( +// content: Text("هذه الخاصية متاحه فقط للأعضاء المسجلين"), +// actions: [ +// cancelButton, +// continueButton, +// ], +// ); +// +// showDialog( +// context: context, +// builder: (BuildContext context) { +// return alert; +// }, +// ); +// +// return; +// } +// showDialog( +// context: context, +// barrierColor: ColorConsts.secondaryWhite.withOpacity(0.8), +// builder: (BuildContext context) => DiscussionInputDialog(onCommentPress: (comment) { +// sendComment(comment); +// }), +// ); +// }, +// child: Container( +// height: 40, +// padding: EdgeInsets.only(left: 24, right: 24), +// alignment: Alignment.centerRight, +// decoration: BoxDecoration( +// borderRadius: BorderRadius.circular(30), +// color: ColorConsts.gradientPink, +// gradient: LinearGradient( +// stops: [0.0, 0.5], +// begin: Alignment.topCenter, +// end: Alignment.bottomCenter, +// colors: [ColorConsts.gradientPink, ColorConsts.gradientOrange], +// ), +// ), +// child: Text( +// "إضافة تعليق", +// style: TextStyle(fontWeight: FontWeight.bold, fontSize: 14, color: Colors.white, height: 1.5), +// ), +// ), +// ), +// ), +// ], +// ); +// } +// } diff --git a/lib/ui/work_list/missing_swipe/fragments/actions_fragment.dart b/lib/ui/work_list/missing_swipe/fragments/actions_fragment.dart new file mode 100644 index 0000000..9c2de89 --- /dev/null +++ b/lib/ui/work_list/missing_swipe/fragments/actions_fragment.dart @@ -0,0 +1,152 @@ +import 'package:flutter/material.dart'; +import 'package:mohem_flutter_app/classes/colors.dart'; +import 'package:mohem_flutter_app/ui/work_list/sheets/delegate_sheet.dart'; +import 'package:mohem_flutter_app/ui/work_list/sheets/request_more_info_sheet.dart'; +import 'package:mohem_flutter_app/widgets/bottom_sheet.dart'; +import 'package:mohem_flutter_app/widgets/circular_avatar.dart'; +import 'package:mohem_flutter_app/extensions/string_extensions.dart'; +import 'package:mohem_flutter_app/extensions/int_extensions.dart'; +import 'package:mohem_flutter_app/extensions/widget_extensions.dart'; +import 'dart:math' as math; + +class ActionsFragment extends StatelessWidget { + @override + Widget build(BuildContext context) { + return Container( + width: double.infinity, + height: double.infinity, + child: ListView.separated( + itemCount: actionsList.length, + padding: EdgeInsets.all(21), + itemBuilder: (context, index) { + return showItem(context, actionsList[index]); + }, + separatorBuilder: (BuildContext context, int index) { + return 16.height; + }, + ), + ); + } + + Widget showItem(BuildContext context, Color color) { + return Container( + width: double.infinity, + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(15), + boxShadow: [ + BoxShadow( + color: const Color(0xff000000).withOpacity(.05), + blurRadius: 26, + offset: const Offset(0, -3), + ), + ], + ), + clipBehavior: Clip.antiAlias, + child: Stack( + clipBehavior: Clip.antiAlias, + children: [ + Positioned( + left: -21, + child: Transform.rotate( + angle: 125, + child: Container( + width: 60, + height: 20, + color: color, + ), + ), + ), + Column( + children: [ + Padding( + padding: const EdgeInsets.only(left: 12, right: 12, top: 12), + child: Column( + children: [ + Row( + children: [ + CircularAvatar(), + 12.width, + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + "Mahmoud Shrouf".toText16(), + 6.height, + "Missing Swipe Request for Hussain, Mohammad has been approved" + .toText12(), + 3.height, + Row( + children: [ + "Submitted".toText10(), + 12.width, + "On 07 Jan 2021" + .toText12(color: MyColors.lightTextColor) + ], + ) + ], + ), + ) + ], + ), + ], + ), + ), + 12.height, + Container( + width: double.infinity, + height: 1, + color: MyColors.lightTextColor, + ), + Row( + children: [ + Expanded( + child: InkWell( + onTap: () { + showMyBottomSheet(context, + child: RequestMoreInfoSheet()); + }, + child: Center( + child: "Request Info" + .toText12(isBold: true) + .paddingOnly( + left: 21, right: 21, top: 8, bottom: 8), + ), + ), + ), + Center( + child: Container( + width: 1, + height: 45, + color: MyColors.lightTextColor, + ), + ), + Expanded( + child: InkWell( + onTap: () { + showMyBottomSheet(context, child: DelegateSheet()); + }, + child: Center( + child: "Delegate" + .toText12( + color: MyColors.gradiantEndColor, isBold: true) + .paddingOnly( + left: 21, right: 21, top: 8, bottom: 8), + ), + ), + ), + ], + ), + ], + ), + ], + ), + ); + } +} + +List actionsList = [ + Colors.black, + Colors.red, + Colors.green, +]; diff --git a/lib/ui/work_list/missing_swipe/fragments/attachments_fragment.dart b/lib/ui/work_list/missing_swipe/fragments/attachments_fragment.dart new file mode 100644 index 0000000..652eba8 --- /dev/null +++ b/lib/ui/work_list/missing_swipe/fragments/attachments_fragment.dart @@ -0,0 +1,61 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_svg/flutter_svg.dart'; +import 'package:mohem_flutter_app/extensions/string_extensions.dart'; +import 'package:mohem_flutter_app/extensions/int_extensions.dart'; + +class AttachmentsFragment extends StatelessWidget { + @override + Widget build(BuildContext context) { + return Container( + width: double.infinity, + height: double.infinity, + child: ListView.separated( + itemCount: 2, + padding: EdgeInsets.all(21), + itemBuilder: (context, index) { + return showItem(attachmentsList[index]); + }, + separatorBuilder: (BuildContext context, int index) { + return 21.height; + }, + ), + ); + } + + Widget showItem(Attachments attachments) { + return Container( + width: double.infinity, + padding: EdgeInsets.all(21), + 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: Row( + children: [ + SvgPicture.asset(attachments.icon), + 12.width, + attachments.title.toText16() + ], + ), + ); + } +} + +class Attachments { + String title; + String icon; + + Attachments(this.title, this.icon); +} + +List attachmentsList = [ + Attachments("Attachment File Name.png", "assets/images/png.svg"), + Attachments("Attachment File Name.pdf", "assets/images/pdf.svg"), +]; diff --git a/lib/ui/work_list/missing_swipe/fragments/info_fragments.dart b/lib/ui/work_list/missing_swipe/fragments/info_fragments.dart new file mode 100644 index 0000000..b115df9 --- /dev/null +++ b/lib/ui/work_list/missing_swipe/fragments/info_fragments.dart @@ -0,0 +1,69 @@ +import 'package:flutter/material.dart'; +import 'package:mohem_flutter_app/classes/colors.dart'; +import 'package:mohem_flutter_app/extensions/int_extensions.dart'; +import 'package:mohem_flutter_app/extensions/string_extensions.dart'; + +class InfoFragment extends StatelessWidget { + @override + Widget build(BuildContext context) { + return Container( + width: double.infinity, + height: double.infinity, + child: Column( + children: [ + Container( + width: double.infinity, + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(15), + boxShadow: [ + BoxShadow( + color: const Color(0xff000000).withOpacity(.05), + blurRadius: 26, + offset: const Offset(0, -3), + ), + ], + ), + margin: EdgeInsets.all(21), + padding: EdgeInsets.only(top: 21, bottom: 21, right: 16, left: 16), + child: Column( + children: [ + Row( + children: [ + Expanded( + child: "Info Details".toText16(), + ), + // Icon(Icons.keyboard_arrow_down_rounded), + ], + ), + Column( + children: [ + 12.height, + showItem("From:", "Alma Linde Mendoza"), + showItem("To:", "Al Yabis, Norah"), + showItem("Sent:", "1/26/2020 10:41:07 AM"), + showItem("ID:", "30581045"), + showItem("Closed:", "-"), + ], + ), + ], + ), + ), + ], + ), + ); + } + + Widget showItem(String title, String value) { + return Padding( + padding: const EdgeInsets.only(top: 2, bottom: 2), + child: Row( + children: [ + title.toText12(isBold: true), + 6.width, + title.toText12(isBold: false, color: MyColors.normalTextColor), + ], + ), + ); + } +} diff --git a/lib/ui/work_list/missing_swipe/fragments/request_fragment.dart b/lib/ui/work_list/missing_swipe/fragments/request_fragment.dart new file mode 100644 index 0000000..f87995a --- /dev/null +++ b/lib/ui/work_list/missing_swipe/fragments/request_fragment.dart @@ -0,0 +1,87 @@ +import 'package:flutter/material.dart'; +import 'package:mohem_flutter_app/classes/colors.dart'; +import 'package:mohem_flutter_app/extensions/string_extensions.dart'; +import 'package:mohem_flutter_app/extensions/int_extensions.dart'; + +class RequestFragment extends StatefulWidget { + @override + State createState() => _RequestFragmentState(); +} + +class _RequestFragmentState extends State { + bool isOpened = false; + + @override + Widget build(BuildContext context) { + return Container( + width: double.infinity, + height: double.infinity, + child: Column( + children: [ + Container( + width: double.infinity, + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(15), + boxShadow: [ + BoxShadow( + color: const Color(0xff000000).withOpacity(.05), + blurRadius: 26, + offset: const Offset(0, -3), + ), + ], + ), + margin: EdgeInsets.all(21), + padding: EdgeInsets.only(top: 21, bottom: 21, right: 16, left: 16), + child: Column( + children: [ + Row( + children: [ + Expanded( + child: "Hardware Mobility 161 Messenger".toText16(), + ), + Icon(Icons.keyboard_arrow_down_rounded), + ], + ), + Column( + children: [ + 12.height, + showItem("Code:", "3188000067"), + showItem("Quantity:", "1"), + showItem("Line Status:", "Pending Approval"), + showItem("Transection Type:", "Move Order Issue:"), + showItem("Organization Code:", "SWD"), + showItem("From Subinventory:", "SWD_MSPS"), + showItem("To Subinventory:", "SWD_MSPS"), + showItem("Ship To Location :", + "SWD 11206-E.R. (Emergency Room)"), + showItem("Unit:", "Each"), + showItem("Date Required:", "12/23/2019 4:54:04 PM"), + showItem("Status Date:", "12/23/2019 4:54:04 PM"), + showItem("Operation Unit:", "Sehat Al Sewedi"), + showItem("Organization:", "Sehat Al Sewedi"), + showItem("From Locator:", "-"), + showItem("To Locator :", "-"), + ], + ), + ], + ), + ), + ], + ), + ); + } + + Widget showItem(String title, String value) { + return Padding( + padding: const EdgeInsets.only(top: 2, bottom: 2), + child: Row( + children: [ + title.toText12(isBold: true), + 6.width, + title.toText12(isBold: false, color: MyColors.normalTextColor), + ], + ), + ); + } +} diff --git a/lib/ui/work_list/missing_swipe/missing_swipe_screen.dart b/lib/ui/work_list/missing_swipe/missing_swipe_screen.dart new file mode 100644 index 0000000..4af620e --- /dev/null +++ b/lib/ui/work_list/missing_swipe/missing_swipe_screen.dart @@ -0,0 +1,98 @@ +import 'package:flutter/material.dart'; +import 'package:mohem_flutter_app/classes/colors.dart'; +import 'package:mohem_flutter_app/ui/app_bar.dart'; +import 'package:mohem_flutter_app/extensions/string_extensions.dart'; +import 'package:mohem_flutter_app/ui/work_list/missing_swipe/fragments/actions_fragment.dart'; +import 'package:mohem_flutter_app/ui/work_list/missing_swipe/fragments/attachments_fragment.dart'; +import 'package:mohem_flutter_app/ui/work_list/missing_swipe/fragments/info_fragments.dart'; +import 'package:mohem_flutter_app/ui/work_list/missing_swipe/fragments/request_fragment.dart'; +import 'package:mohem_flutter_app/widgets/button/default_button.dart'; +import 'package:mohem_flutter_app/extensions/int_extensions.dart'; + +class MissingSwipeScreen extends StatelessWidget { + @override + Widget build(BuildContext context) { + return DefaultTabController( + length: 4, + child: Scaffold( + appBar: appBar(context, title: "Missing Swipe Request"), + body: Container( + width: double.infinity, + height: double.infinity, + child: Column( + children: [ + Container( + decoration: BoxDecoration( + borderRadius: BorderRadius.only(bottomLeft: Radius.circular(20), bottomRight: Radius.circular(20)), + gradient: LinearGradient(transform: GradientRotation(.46), begin: Alignment.topRight, end: Alignment.bottomRight, colors: [ + MyColors.gradiantEndColor, + MyColors.gradiantStartColor, + ]), + ), + clipBehavior: Clip.antiAlias, + child: TabBar( + indicatorColor: Colors.white, + labelColor: Colors.white, + tabs: [ + Tab( + text: "Request", + ), + Tab( + text: "Actions", + ), + Tab( + text: "Attachments", + ), + Tab( + text: "Info.", + ), + ], + ), + ), + Expanded( + child: TabBarView( + children: [ + RequestFragment(), + ActionsFragment(), + AttachmentsFragment(), + InfoFragment(), + ], + ), + ), + Container( + width: double.infinity, + height: 60, + padding: EdgeInsets.only(left: 21, right: 21), + child: Row( + children: [ + Expanded( + child: DefaultButton( + "Reject", + () {}, + colors: [ + Color(0xffEB8C90), + Color(0xffDE6C70), + ], + ), + ), + 12.width, + Expanded( + child: DefaultButton( + "Approve", + () {}, + colors: [ + Color(0xff32D892), + Color(0xff1AB170), + ], + ), + ), + ], + ), + ) + ], + ), + ), + ), + ); + } +} diff --git a/lib/ui/work_list/sheets/delegate_sheet.dart b/lib/ui/work_list/sheets/delegate_sheet.dart new file mode 100644 index 0000000..ba0e6a4 --- /dev/null +++ b/lib/ui/work_list/sheets/delegate_sheet.dart @@ -0,0 +1,165 @@ +import 'package:flutter/material.dart'; +import 'package:mohem_flutter_app/classes/colors.dart'; +import 'package:mohem_flutter_app/extensions/string_extensions.dart'; +import 'package:mohem_flutter_app/extensions/int_extensions.dart'; +import 'package:mohem_flutter_app/ui/work_list/sheets/selected_item_sheet.dart'; +import 'package:mohem_flutter_app/widgets/bottom_sheet.dart'; +import 'package:mohem_flutter_app/widgets/button/default_button.dart'; +import 'package:mohem_flutter_app/widgets/circular_avatar.dart'; +import 'package:mohem_flutter_app/widgets/input_widget.dart'; +import 'package:mohem_flutter_app/widgets/radio/show_radio.dart'; +import 'package:mohem_flutter_app/extensions/widget_extensions.dart'; + +class DelegateSheet extends StatelessWidget { + TextEditingController username = TextEditingController(); + + @override + Widget build(BuildContext context) { + List related = [ + "Amjad Khan", + "Munahi Nasser", + ]; + List favorites = [ + "Amjad Khan", + "Muhammad Ahmed", + "Majid Ali", + "Faris Mahmoud", + ]; + return Container( + width: double.infinity, + height: MediaQuery.of(context).size.height - 80, + child: Column( + children: [ + Expanded( + child: SingleChildScrollView( + child: Padding( + padding: EdgeInsets.all(21), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + "Delegate".toText24(), + 24.height, + "Search".toText16(), + 12.height, + Row( + children: [ + Expanded( + flex: 2, + child: ShowRadio( + title: "Name", value: "Name", groupValue: "Name"), + ), + Expanded( + flex: 3, + child: ShowRadio( + title: "User Name", + value: "User Name", + groupValue: "Name"), + ), + Expanded( + flex: 2, + child: ShowRadio( + title: "Email", + value: "Email", + groupValue: "Name"), + ), + ], + ), + 20.height, + InputWidget( + "Search By Username", + "", + username, + isBackgroundEnable: true, + ), + 24.height, + "Related".toText16(), + 12.height, + ListView.separated( + itemBuilder: (context, index) { + return showItem(context, related[index]); + }, + separatorBuilder: (context, index) { + return Container( + color: MyColors.borderColor, + width: double.infinity, + height: 1, + margin: EdgeInsets.only(top: 8, bottom: 8), + ); + }, + physics: NeverScrollableScrollPhysics(), + shrinkWrap: true, + itemCount: related.length, + padding: EdgeInsets.only(top: 8, bottom: 8), + ), + 24.height, + "Favorites".toText16(), + 12.height, + ListView.separated( + itemBuilder: (context, index) { + return showItem(context, favorites[index], + isEnabled: true); + }, + separatorBuilder: (context, index) { + return Container( + color: MyColors.borderColor, + width: double.infinity, + height: 1, + margin: EdgeInsets.only(top: 8, bottom: 8), + ); + }, + physics: NeverScrollableScrollPhysics(), + shrinkWrap: true, + itemCount: favorites.length, + padding: EdgeInsets.only(top: 8, bottom: 8), + ), + ], + ), + ), + ), + ), + Container( + width: double.infinity, + height: 1, + color: MyColors.borderColor, + ), + DefaultButton( + "Cancel", + () { + Navigator.pop(context); + }, + textColor: Colors.black, + colors: [ + Color(0xffE6E6E6), + Color(0xffE6E6E6), + ], + ).insideContainer + ], + ), + ); + } + + Widget showItem(BuildContext context, String name, {bool isEnabled = false}) { + return InkWell( + onTap: () { + showMyBottomSheet(context, child: SelectedItemSheet("Delegate")); + }, + child: Row( + children: [ + CircularAvatar( + height: 30, + width: 30, + ), + 16.width, + Expanded( + child: name.toText12(), + ), + Icon( + Icons.star, + size: 16, + color: isEnabled ? MyColors.yellowColor : MyColors.borderColor, + ), + ], + ), + ); + } +} diff --git a/lib/ui/work_list/sheets/request_more_info_sheet.dart b/lib/ui/work_list/sheets/request_more_info_sheet.dart new file mode 100644 index 0000000..e2840ca --- /dev/null +++ b/lib/ui/work_list/sheets/request_more_info_sheet.dart @@ -0,0 +1,165 @@ +import 'package:flutter/material.dart'; +import 'package:mohem_flutter_app/classes/colors.dart'; +import 'package:mohem_flutter_app/extensions/string_extensions.dart'; +import 'package:mohem_flutter_app/extensions/int_extensions.dart'; +import 'package:mohem_flutter_app/ui/work_list/sheets/selected_item_sheet.dart'; +import 'package:mohem_flutter_app/widgets/bottom_sheet.dart'; +import 'package:mohem_flutter_app/widgets/button/default_button.dart'; +import 'package:mohem_flutter_app/widgets/circular_avatar.dart'; +import 'package:mohem_flutter_app/widgets/input_widget.dart'; +import 'package:mohem_flutter_app/widgets/radio/show_radio.dart'; +import 'package:mohem_flutter_app/extensions/widget_extensions.dart'; + +class RequestMoreInfoSheet extends StatelessWidget { + TextEditingController username = TextEditingController(); + + @override + Widget build(BuildContext context) { + List related = [ + "Amjad Khan", + "Munahi Nasser", + ]; + List favorites = [ + "Amjad Khan", + "Muhammad Ahmed", + "Majid Ali", + "Faris Mahmoud", + ]; + return Container( + width: double.infinity, + height: MediaQuery.of(context).size.height - 80, + child: Column( + children: [ + Expanded( + child: SingleChildScrollView( + child: Padding( + padding: EdgeInsets.all(21), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + "Request more info".toText24(), + 24.height, + "Search".toText16(), + 12.height, + Row( + children: [ + Expanded( + flex: 2, + child: ShowRadio( + title: "Name", value: "Name", groupValue: "Name"), + ), + Expanded( + flex: 3, + child: ShowRadio( + title: "User Name", + value: "User Name", + groupValue: "Name"), + ), + Expanded( + flex: 2, + child: ShowRadio( + title: "Email", + value: "Email", + groupValue: "Name"), + ), + ], + ), + 20.height, + InputWidget( + "Search By Username", + "", + username, + isBackgroundEnable: true, + ), + 24.height, + "Related".toText16(), + 12.height, + ListView.separated( + itemBuilder: (context, index) { + return showItem(context, related[index]); + }, + separatorBuilder: (context, index) { + return Container( + color: MyColors.borderColor, + width: double.infinity, + height: 1, + margin: EdgeInsets.only(top: 8, bottom: 8), + ); + }, + physics: NeverScrollableScrollPhysics(), + shrinkWrap: true, + itemCount: related.length, + padding: EdgeInsets.only(top: 8, bottom: 8), + ), + 24.height, + "Favorites".toText16(), + 12.height, + ListView.separated( + itemBuilder: (context, index) { + return showItem(context, favorites[index], + isEnabled: true); + }, + separatorBuilder: (context, index) { + return Container( + color: MyColors.borderColor, + width: double.infinity, + height: 1, + margin: EdgeInsets.only(top: 8, bottom: 8), + ); + }, + physics: NeverScrollableScrollPhysics(), + shrinkWrap: true, + itemCount: favorites.length, + padding: EdgeInsets.only(top: 8, bottom: 8), + ), + ], + ), + ), + ), + ), + Container( + width: double.infinity, + height: 1, + color: MyColors.borderColor, + ), + DefaultButton( + "Cancel", + () { + Navigator.pop(context); + }, + textColor: Colors.black, + colors: [ + Color(0xffE6E6E6), + Color(0xffE6E6E6), + ], + ).insideContainer + ], + ), + ); + } + + Widget showItem(BuildContext context, String name, {bool isEnabled = false}) { + return InkWell( + onTap: () { + showMyBottomSheet(context, child: SelectedItemSheet("Request more info")); + }, + child: Row( + children: [ + CircularAvatar( + height: 30, + width: 30, + ), + 16.width, + Expanded( + child: name.toText12(), + ), + Icon( + Icons.star, + size: 16, + color: isEnabled ? MyColors.yellowColor : MyColors.borderColor, + ), + ], + ), + ); + } +} diff --git a/lib/ui/work_list/sheets/selected_item_sheet.dart b/lib/ui/work_list/sheets/selected_item_sheet.dart new file mode 100644 index 0000000..50fcae4 --- /dev/null +++ b/lib/ui/work_list/sheets/selected_item_sheet.dart @@ -0,0 +1,151 @@ +import 'package:flutter/material.dart'; +import 'package:mohem_flutter_app/classes/colors.dart'; +import 'package:mohem_flutter_app/extensions/string_extensions.dart'; +import 'package:mohem_flutter_app/extensions/int_extensions.dart'; +import 'package:mohem_flutter_app/widgets/button/default_button.dart'; +import 'package:mohem_flutter_app/widgets/circular_avatar.dart'; +import 'package:mohem_flutter_app/widgets/input_widget.dart'; +import 'package:mohem_flutter_app/widgets/radio/show_radio.dart'; +import 'package:mohem_flutter_app/extensions/widget_extensions.dart'; + +class SelectedItemSheet extends StatelessWidget { + String title; + + SelectedItemSheet(this.title); + + TextEditingController username = TextEditingController(); + + @override + Widget build(BuildContext context) { + return Container( + width: double.infinity, + height: MediaQuery.of(context).size.height - 80, + child: Column( + children: [ + Expanded( + child: SingleChildScrollView( + child: Padding( + padding: EdgeInsets.all(21), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + title.toText24(), + 24.height, + "Search".toText16(), + 12.height, + Row( + children: [ + Expanded( + flex: 2, + child: ShowRadio( + title: "Name", value: "Name", groupValue: "Name"), + ), + Expanded( + flex: 3, + child: ShowRadio( + title: "User Name", + value: "User Name", + groupValue: "Name"), + ), + Expanded( + flex: 2, + child: ShowRadio( + title: "Email", + value: "Email", + groupValue: "Name"), + ), + ], + ), + 20.height, + showItem("name"), + 20.height, + InputWidget( + "Enter a note", + "This is simple note", + username, + isBackgroundEnable: true, + lines: 5, + ), + ], + ), + ), + ), + ), + Container( + width: double.infinity, + height: 1, + color: MyColors.borderColor, + ), + Row( + children: [ + Expanded( + child: DefaultButton( + "Cancel", + () { + Navigator.pop(context); + }, + textColor: Colors.black, + colors: [ + Color(0xffE6E6E6), + Color(0xffE6E6E6), + ], + ), + ), + 16.width, + Expanded( + child: DefaultButton( + "Submit", + () { + Navigator.pop(context); + }, + colors: [ + Color(0xff32D892), + Color(0xff1AB170), + ], + ), + ), + ], + ).insideContainer + ], + ), + ); + } + + Widget showItem(String name) { + return Container( + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(15), + color: Color(0xffF7F7F7), + border: Border.all( + color: Color(0xffefefef), + width: 1, + ), + ), + padding: EdgeInsets.only(top: 16, bottom: 16, left: 21, right: 21), + child: Row( + children: [ + CircularAvatar( + height: 30, + width: 30, + ), + 16.width, + Expanded( + child: name.toText12(), + ), + Container( + decoration: BoxDecoration( + color: MyColors.redColor, + borderRadius: BorderRadius.all(Radius.circular(100)), + ), + padding: EdgeInsets.all(3), + child: Icon( + Icons.star, + size: 12, + color: Colors.white, + ), + ), + ], + ), + ); + } +} diff --git a/lib/ui/work_list/work_list_screen.dart b/lib/ui/work_list/work_list_screen.dart new file mode 100644 index 0000000..06a545c --- /dev/null +++ b/lib/ui/work_list/work_list_screen.dart @@ -0,0 +1,206 @@ +import 'package:easy_localization/src/public_ext.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_svg/svg.dart'; +import 'package:mohem_flutter_app/classes/colors.dart'; +import 'package:mohem_flutter_app/config/routes.dart'; +import 'package:mohem_flutter_app/generated/locale_keys.g.dart'; +import 'package:mohem_flutter_app/ui/app_bar.dart'; +import 'package:mohem_flutter_app/extensions/string_extensions.dart'; +import 'package:mohem_flutter_app/extensions/int_extensions.dart'; +import 'package:mohem_flutter_app/extensions/widget_extensions.dart'; + +class WorkListScreen extends StatefulWidget { + @override + State createState() => _WorkListScreenState(); +} + +class _WorkListScreenState extends State { + @override + Widget build(BuildContext context) { + return Scaffold( + backgroundColor: Colors.white, + appBar: appBar( + context, + title: LocaleKeys.workList.tr(), + ), + body: Container( + width: double.infinity, + height: double.infinity, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Container( + width: double.infinity, + height: 2, + color: MyColors.darkWhiteColor, + ), + Container( + width: double.infinity, + height: 40, + margin: EdgeInsets.only( + top: 21, + ), + child: ListView.separated( + itemBuilder: (context, index) { + return Container( + padding: EdgeInsets.only( + left: 30, + right: 30, + ), + alignment: Alignment.center, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(6), + color: tabList[index].isSelected + ? MyColors.darkIconColor + : MyColors.lightGreyEAColor, + ), + child: tabList[index].title.toText12( + color: tabList[index].isSelected + ? MyColors.white + : MyColors.black, + ), + ); + }, + separatorBuilder: (context, index) { + return 8.width; + }, + shrinkWrap: true, + itemCount: tabList.length, + scrollDirection: Axis.horizontal, + padding: const EdgeInsets.only( + left: 21, + right: 21, + ), + ), + ), + Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisSize: MainAxisSize.min, + children: [ + LocaleKeys.human.toText12(), + LocaleKeys.resources.tr().toText24(isBold: true), + ], + ).paddingOnly(top: 24, left: 21, right: 21), + 24.height, + Expanded( + child: ListView.separated( + itemBuilder: (context, index) { + return rowItem(typesList[index]); + }, + separatorBuilder: (context, index) { + return 12.height; + }, + itemCount: typesList.length, + padding: EdgeInsets.only(left: 21, right: 21), + ), + ), + ], + ), + ), + ); + } + + Widget rowItem(Types types) { + return InkWell( + onTap: (){ + Navigator.pushNamed(context, AppRoutes.missingSwipe); + }, + child: Container( + width: double.infinity, + padding: EdgeInsets.all(12), + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(10), + boxShadow: [ + BoxShadow( + color: const Color(0xff000000).withOpacity(.05), + blurRadius: 26, + offset: const Offset(0, -3), + ), + ], + ), + child: Row( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.start, + children: [ + Container( + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(4), + gradient: LinearGradient( + transform: GradientRotation(.46), + begin: Alignment.topRight, + end: Alignment.bottomRight, + colors: types.colors), + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + SvgPicture.asset( + "assets/images/miss_swipe.svg", + color: Colors.white, + ), + 2.height, + types.title.toText10(color: Colors.white) + ], + ).paddingAll(6), + ), + 12.width, + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.start, + children: [ + "Missing Swipe Request".toText16(), + "Missing Swipe Request for Hussain, Mohammad has been approved" + .toText10(), + 12.height, + Row( + children: [ + Expanded( + child: "07 Jan 2021" + .toText10(color: MyColors.lightTextColor)), + SvgPicture.asset( + "assets/images/arrow_next.svg", + color: MyColors.darkIconColor, + ) + ], + ), + ], + ), + ), + ], + ), + ), + ); + } +} + +class Tabs { + String title; + bool isSelected; + + Tabs(this.title, this.isSelected); +} + +List tabList = [ + Tabs("All", true), + Tabs("HR", false), + Tabs("MO", false), + Tabs("PR", false), + Tabs("PO", false), +]; + +class Types { + String title; + List colors; + + Types(this.title, this.colors); +} + +List typesList = [ + Types("HR", [Color(0xff32D892), Color(0xff1AB170)]), + Types("ITG", [Color(0xffEB8C90), Color(0xffDE6C70)]), + Types("PO", [Color(0xff5099E3), Color(0xff3670AA)]), + Types("PR", [Color(0xff48EACF), Color(0xff3DCAB3)]), + Types("MO", [Color(0xff58DCFA), Color(0xff3CB9D5)]), +]; diff --git a/lib/widgets/app_logo.dart b/lib/widgets/app_logo.dart new file mode 100644 index 0000000..1c0bc37 --- /dev/null +++ b/lib/widgets/app_logo.dart @@ -0,0 +1,19 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_svg/svg.dart'; + +class AppLogo extends StatelessWidget { + AppLogo({Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + // TODO: implement build + return Row(children: [ + SvgPicture.asset( + "assets/mohemm_logo.svg", + height: 100, + width: 100, + alignment: Alignment.centerRight, + ), + ],); + } +} diff --git a/lib/widgets/bottom_sheet.dart b/lib/widgets/bottom_sheet.dart new file mode 100644 index 0000000..a44fd7b --- /dev/null +++ b/lib/widgets/bottom_sheet.dart @@ -0,0 +1,41 @@ +import 'package:flutter/material.dart'; +import 'package:mohem_flutter_app/extensions/int_extensions.dart'; + +showMyBottomSheet(BuildContext context, {required Widget child}) { + showModalBottomSheet( + context: context, + isScrollControlled: true, + backgroundColor: Colors.transparent, + builder: (BuildContext context) { + return Container( + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.only( + topRight: Radius.circular(24), + topLeft: Radius.circular(24), + ), + ), + clipBehavior: Clip.antiAlias, + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + mainAxisSize: MainAxisSize.min, + children: [ + 8.height, + Container( + height: 6, + width: 60, + decoration: BoxDecoration( + color: Colors.grey[200], + borderRadius: BorderRadius.all( + Radius.circular(20), + ), + ), + ), + 8.height, + child, + ], + ), + ); + }, + ); +} diff --git a/lib/widgets/button/default_button.dart b/lib/widgets/button/default_button.dart new file mode 100644 index 0000000..77d1c61 --- /dev/null +++ b/lib/widgets/button/default_button.dart @@ -0,0 +1,116 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_svg/svg.dart'; +import 'package:mohem_flutter_app/classes/colors.dart'; + +extension WithContainer on Widget { + Widget get insideContainer => Container( + color: Colors.white, + padding: const EdgeInsets.only(top: 16, bottom: 16, right: 21, left: 21), + child: this); +} + +class DefaultButton extends StatelessWidget { + final String text; + final VoidCallback? onPress; + final Color textColor; + final Color? color; + final Color? disabledColor; + final IconData? iconData; + final String? svgIcon; + final double? fontSize; + final bool isTextExpanded; + final int count; + final List? colors; + + DefaultButton(this.text, this.onPress, + {this.color, + this.isTextExpanded = true, + this.svgIcon, + this.disabledColor, + this.count = 0, + this.textColor = Colors.white, + this.iconData, + this.fontSize, + this.colors}); + + @override + Widget build(BuildContext context) { + return InkWell( + onTap: onPress, + child: Container( + height: 43, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(6.0), + gradient: onPress == null + ? const LinearGradient( + colors: [Color(0xffEAEAEA), Color(0xffEAEAEA)]) + : LinearGradient( + transform: GradientRotation(.83), + begin: Alignment.topRight, + end: Alignment.bottomLeft, + colors: colors ?? + [ + MyColors.gradiantEndColor, + MyColors.gradiantStartColor, + ]), + ), + child: Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + if (iconData != null) Icon(iconData, color: textColor), + if (svgIcon != null) + SvgPicture.asset(svgIcon ?? "", color: textColor), + if (!isTextExpanded) + Padding( + padding: EdgeInsets.only( + left: (iconData ?? svgIcon) != null ? 6 : 0), + child: Text( + text, + textAlign: TextAlign.center, + style: TextStyle( + fontSize: fontSize ?? 16, + fontWeight: FontWeight.w600, + color: textColor, + letterSpacing: -0.48), + ), + ), + if (isTextExpanded) + Expanded( + child: Text( + text, + textAlign: TextAlign.center, + style: TextStyle( + fontSize: fontSize ?? 16, + fontWeight: FontWeight.w600, + color: textColor, + letterSpacing: -0.48), + ), + ), + if (count > 0) + Align( + alignment: Alignment.topCenter, + child: Container( + margin: const EdgeInsets.only(top: 6, bottom: 6), + padding: const EdgeInsets.only(left: 5, right: 5), + alignment: Alignment.center, + height: 16, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(10.0), + color: Colors.white), + child: Text( + "$count", + textAlign: TextAlign.center, + style: const TextStyle( + fontSize: 12, + fontWeight: FontWeight.w700, + color: Color(0xffD02127), + letterSpacing: -0.6), + ), + ), + ) + ], + ), + ), + ); + } +} diff --git a/lib/widgets/circular_avatar.dart b/lib/widgets/circular_avatar.dart new file mode 100644 index 0000000..cd60e06 --- /dev/null +++ b/lib/widgets/circular_avatar.dart @@ -0,0 +1,25 @@ +import 'package:flutter/material.dart'; + +class CircularAvatar extends StatelessWidget { + final String? url; + final double radius; + final double width; + final double height; + + CircularAvatar({Key? key, this.radius = 70.0, this.width = 70, this.height = 60, this.url}) : super(key: key); + + @override + Widget build(BuildContext context) { + return Container( + width: width, + height: height, + decoration: BoxDecoration( + shape: BoxShape.circle, + image: DecorationImage( + fit: BoxFit.cover, + image: NetworkImage(url ?? "https://cdn4.iconfinder.com/data/icons/professions-2-2/151/89-512.png"), + ), + ), + ); + } +} diff --git a/lib/widgets/circular_step_progress_bar.dart b/lib/widgets/circular_step_progress_bar.dart new file mode 100644 index 0000000..75724c8 --- /dev/null +++ b/lib/widgets/circular_step_progress_bar.dart @@ -0,0 +1,515 @@ +import 'dart:math' as math; + +import 'package:flutter/material.dart'; + +class CircularStepProgressBar extends StatelessWidget { + /// Defines if steps grow from + /// clockwise [CircularDirection.clockwise] or + /// counterclockwise [CircularDirection.counterclockwise] + final CircularDirection circularDirection; + + /// Number of steps to underline, all the steps with + /// index <= [currentStep] will have [Color] equal to + /// [selectedColor] + /// + /// Only used when [customColor] is [null] + /// + /// Default value: 0 + final int currentStep; + + /// Total number of step of the complete indicator + final int totalSteps; + + /// Radial spacing between each step. Remember to + /// define the value in radiant units + /// + /// Default value: math.pi / 20 + final double padding; + + /// Height of the indicator's box container + final double? height; + + /// Width of the indicator's box container + final double? width; + + /// Assign a custom [Color] for each step + /// + /// Takes a [int], index of the current step starting from 0, and + /// must return a [Color] + /// + /// **NOTE**: If provided, it overrides + /// [selectedColor] and [unselectedColor] + final Color Function(int)? customColor; + + /// [Color] of the selected steps + /// + /// All the steps with index <= [currentStep] + /// + /// Default value: [Colors.blue] + final Color? selectedColor; + + /// [Color] of the unselected steps + /// + /// All the steps with index between + /// [currentStep] and [totalSteps] + /// + /// Default value: [Colors.grey] + final Color? unselectedColor; + + /// The size of a single step in the indicator + /// + /// Default value: 6.0 + final double stepSize; + + /// Specify a custom size for selected steps + /// + /// Only applicable when not custom setting (customColor, customStepSize) is defined + /// + /// This value will replace the [stepSize] only for selected steps + final double? selectedStepSize; + + /// Specify a custom size for unselected steps + /// + /// Only applicable when not custom setting (customColor, customStepSize) is defined + /// + /// This value will replace the [stepSize] only for unselected steps + final double? unselectedStepSize; + + /// Assign a custom size [double] for each step + /// + /// Function takes a [int], index of the current step starting from 0, and + /// a [bool], which tells if the step is selected based on [currentStep], + /// and must return a [double] size of the step + /// + /// **NOTE**: If provided, it overrides [stepSize] + final double Function(int, bool)? customStepSize; + + /// [Widget] contained inside the circular indicator + final Widget? child; + + /// Height of the indicator container in case no [height] parameter + /// given and parent height is [double.infinity] + /// + /// Default value: 100.0 + final double fallbackHeight; + + /// Height of the indicator container in case no [width] parameter + /// given and parent height is [double.infinity] + /// + /// Default value: 100.0 + final double fallbackWidth; + + /// Angle in radiants in which the first step of the indicator is placed. + /// The initial value is on the top of the indicator (- math.pi / 2) + /// - 0 => TOP + /// - math.pi / 2 => LEFT + /// - math.pi => BOTTOM + /// - math.pi / 2 * 3 => RIGHT + /// - math.pi / 2 => TOP (again) + final double startingAngle; + + /// Angle in radiants which represents the size of the arc used to display the indicator. + /// It allows you to draw a semi-circle instead of a full 360° (math.pi * 2) circle. + final double arcSize; + + /// Adds rounded edges at the beginning and at the end of the circular indicator + /// given a [int], index of each step, and a [bool], + /// which tells if the step is selected based on [currentStep], and must return a + /// [bool] that tells if the edges are rounded or not + /// + /// **NOTE**: For continuous circular indicators (`padding: 0`), to check if to apply + /// the rounded edges the packages uses index 0 (for the first arc painted) and + /// 1 (for the second arc painted) + /// + /// ```dart + /// // Example: Add rounded edges for all the steps + /// roundedCap: (index, _) => true + /// ``` + /// + /// ```dart + /// // Example: Add rounded edges for the selected arc of the indicator + /// roundedCap: (index, _) => index == 0, + /// padding: 0 + /// ``` + final bool Function(int, bool)? roundedCap; + + /// Adds a gradient color to the circular indicator + /// + /// **NOTE**: If provided, it overrides [selectedColor], [unselectedColor], and [customColor] + final Gradient? gradientColor; + + /// Removes the extra angle caused by [StrokeCap.round] when [roundedCap] is applied + final bool removeRoundedCapExtraAngle; + + const CircularStepProgressBar({ + required this.totalSteps, + this.child, + this.height, + this.width, + this.customColor, + this.customStepSize, + this.selectedStepSize, + this.unselectedStepSize, + this.roundedCap, + this.gradientColor, + this.circularDirection = CircularDirection.clockwise, + this.fallbackHeight = 100.0, + this.fallbackWidth = 100.0, + this.currentStep = 0, + this.selectedColor = Colors.blue, + this.unselectedColor = Colors.grey, + this.padding = math.pi / 20, + this.stepSize = 6.0, + this.startingAngle = 0, + this.arcSize = math.pi * 2, + this.removeRoundedCapExtraAngle = false, + Key? key, + }) : assert(totalSteps > 0, "Number of total steps (totalSteps) of the CircularStepProgressBar must be greater than 0"), + assert(currentStep >= 0, "Current step (currentStep) of the CircularStepProgressBar must be greater than or equal to 0"), + assert(padding >= 0.0, "Padding (padding) of the CircularStepProgressBar must be greater or equal to 0"), + super(key: key); + + @override + Widget build(BuildContext context) { + // Print warning when arcSize greater than math.pi * 2 which causes steps to overlap + if (arcSize > math.pi * 2) print("WARNING (step_progress_indicator): arcSize of CircularStepProgressBar is greater than 360° (math.pi * 2), this will cause some steps to overlap!"); + final TextDirection textDirection = Directionality.of(context); + + return LayoutBuilder( + builder: (context, constraints) => SizedBox( + // Apply fallback for both height and width + // if their value is null and no parent size limit + height: height != null + ? height + : constraints.maxHeight != double.infinity + ? constraints.maxHeight + : fallbackHeight, + width: width != null + ? width + : constraints.maxWidth != double.infinity + ? constraints.maxWidth + : fallbackWidth, + child: CustomPaint( + painter: _CircularIndicatorPainter( + totalSteps: totalSteps, + currentStep: currentStep, + customColor: customColor, + padding: padding, + circularDirection: circularDirection, + selectedColor: selectedColor, + unselectedColor: unselectedColor, + arcSize: arcSize, + stepSize: stepSize, + customStepSize: customStepSize, + maxDefinedSize: maxDefinedSize, + selectedStepSize: selectedStepSize, + unselectedStepSize: unselectedStepSize, + startingAngle: startingAngleTopOfIndicator, + roundedCap: roundedCap, + gradientColor: gradientColor, + textDirection: textDirection, + removeRoundedCapExtraAngle: removeRoundedCapExtraAngle, + ), + // Padding needed to show the indicator when child is placed on top of it + child: Padding( + padding: EdgeInsets.all(maxDefinedSize), + child: child, + ), + ), + ), + ); + } + + /// Compute the maximum possible size of the indicator between + /// [stepSize] and [customStepSize] + double get maxDefinedSize { + if (customStepSize == null) { + return math.max(stepSize, math.max(selectedStepSize ?? 0, unselectedStepSize ?? 0)); + } + + // When customSize defined, compute and return max possible size + double currentMaxSize = 0; + + for (int step = 0; step < totalSteps; ++step) { + // Consider max between selected and unselected case + final customSizeValue = math.max(customStepSize!(step, false), customStepSize!(step, true)); + if (customSizeValue > currentMaxSize) { + currentMaxSize = customSizeValue; + } + } + + return currentMaxSize; + } + + /// Make [startingAngle] to top-center of indicator (0°) by default + double get startingAngleTopOfIndicator => startingAngle - math.pi / 2; +} + +class _CircularIndicatorPainter implements CustomPainter { + final int totalSteps; + final int currentStep; + final double padding; + final Color? selectedColor; + final Color? unselectedColor; + final double stepSize; + final double? selectedStepSize; + final double? unselectedStepSize; + final double Function(int, bool)? customStepSize; + final double maxDefinedSize; + final Color Function(int)? customColor; + final CircularDirection circularDirection; + final double startingAngle; + final double arcSize; + final bool Function(int, bool)? roundedCap; + final Gradient? gradientColor; + final TextDirection textDirection; + final bool removeRoundedCapExtraAngle; + + _CircularIndicatorPainter({ + required this.totalSteps, + required this.circularDirection, + required this.customColor, + required this.currentStep, + required this.selectedColor, + required this.unselectedColor, + required this.padding, + required this.stepSize, + required this.selectedStepSize, + required this.unselectedStepSize, + required this.customStepSize, + required this.startingAngle, + required this.arcSize, + required this.maxDefinedSize, + required this.roundedCap, + required this.gradientColor, + required this.textDirection, + required this.removeRoundedCapExtraAngle, + }); + + @override + void paint(Canvas canvas, Size size) { + final w = size.width; + final h = size.height; + + // Step length is user-defined arcSize + // divided by the total number of steps (each step same size) + final stepLength = arcSize / totalSteps; + + // Define general arc paint + Paint paint = Paint() + ..style = PaintingStyle.stroke + ..strokeWidth = maxDefinedSize; + + final rect = Rect.fromCenter( + // Rect created from the center of the widget + center: Offset(w / 2, h / 2), + // For both height and width, subtract maxDefinedSize to fit indicator inside the parent container + height: h - maxDefinedSize, + width: w - maxDefinedSize, + ); + + if (gradientColor != null) { + paint.shader = gradientColor!.createShader(rect, textDirection: textDirection); + } + + // Change color selected or unselected based on the circularDirection + final isClockwise = circularDirection == CircularDirection.clockwise; + + // Make a continuous arc without rendering all the steps when possible + if (padding == 0 && customColor == null && customStepSize == null && roundedCap == null) { + _drawContinuousArc(canvas, paint, rect, isClockwise); + } else { + _drawStepArc(canvas, paint, rect, isClockwise, stepLength); + } + } + + /// Draw a series of arcs, each composing the full steps of the indicator + void _drawStepArc(Canvas canvas, Paint paint, Rect rect, bool isClockwise, double stepLength) { + // Draw a series of circular arcs to compose the indicator + // Starting based on startingAngle attribute + // + // When clockwise: + // - Start drawing counterclockwise so to have the selected steps on top of the unselected + int step = isClockwise ? totalSteps - 1 : 0; + double stepAngle = isClockwise ? startingAngle - stepLength : startingAngle; + for (; isClockwise ? step >= 0 : step < totalSteps; isClockwise ? stepAngle -= stepLength : stepAngle += stepLength, isClockwise ? --step : ++step) { + // Check if the current step is selected or unselected + final isSelectedColor = _isSelectedColor(step, isClockwise); + + // Size of the step + final indexStepSize = customStepSize != null + // Consider step index inverted when counterclockwise + ? customStepSize!(_indexOfStep(step, isClockwise), isSelectedColor) + : isSelectedColor + ? selectedStepSize ?? stepSize + : unselectedStepSize ?? stepSize; + + // Use customColor if defined + final stepColor = customColor != null + // Consider step index inverted when counterclockwise + ? customColor!(_indexOfStep(step, isClockwise)) + : isSelectedColor + ? selectedColor! + : unselectedColor!; + + // Apply stroke cap to each step + final hasStrokeCap = roundedCap != null ? roundedCap!(_indexOfStep(step, isClockwise), isSelectedColor) : false; + final strokeCap = hasStrokeCap ? StrokeCap.round : StrokeCap.butt; + + // Remove extra size caused by rounded stroke cap + // https://github.com/SandroMaglione/step-progress-indicator/issues/20#issue-786114745 + final extraCapSize = indexStepSize / 2; + final extraCapAngle = extraCapSize / (rect.width / 2); + final extraCapRemove = hasStrokeCap && removeRoundedCapExtraAngle; + + // Draw arc steps of the indicator + _drawArcOnCanvas( + canvas: canvas, + rect: rect, + startingAngle: stepAngle + (extraCapRemove ? extraCapAngle : 0), + sweepAngle: stepLength - padding - (extraCapRemove ? extraCapAngle * 2 : 0), + paint: paint, + color: stepColor, + strokeWidth: indexStepSize, + strokeCap: strokeCap, + ); + } + } + + /// Draw optimized continuous indicator instead of multiple steps + void _drawContinuousArc(Canvas canvas, Paint paint, Rect rect, bool isClockwise) { + // Compute color of the selected and unselected bars + final firstStepColor = isClockwise ? selectedColor : unselectedColor; + final secondStepColor = !isClockwise ? selectedColor : unselectedColor; + + // Selected and unselected step sizes if defined, otherwise use stepSize + final firstStepSize = isClockwise ? selectedStepSize ?? stepSize : unselectedStepSize ?? stepSize; + final secondStepSize = !isClockwise ? selectedStepSize ?? stepSize : unselectedStepSize ?? stepSize; + + // Compute length and starting angle of the selected and unselected bars + final firstArcLength = arcSize * (currentStep / totalSteps); + final secondArcLength = arcSize - firstArcLength; + + // firstArcStartingAngle = startingAngle + final secondArcStartingAngle = startingAngle + firstArcLength; + + // Apply stroke cap to both arcs + // NOTE: For continuous circular indicator, it uses 0 and 1 as index to + // apply the rounded cap + final firstArcStrokeCap = roundedCap != null + ? isClockwise + ? roundedCap!(0, true) + : roundedCap!(1, false) + : false; + final secondArcStrokeCap = roundedCap != null + ? isClockwise + ? roundedCap!(1, false) + : roundedCap!(0, true) + : false; + final firstCap = firstArcStrokeCap ? StrokeCap.round : StrokeCap.butt; + final secondCap = secondArcStrokeCap ? StrokeCap.round : StrokeCap.butt; + + // When clockwise, draw the second arc first and the first on top of it + // Required when stroke cap is rounded to make the selected step on top of the unselected + if (circularDirection == CircularDirection.clockwise) { + // Second arc, selected when counterclockwise, unselected otherwise + _drawArcOnCanvas( + canvas: canvas, + rect: rect, + paint: paint, + startingAngle: secondArcStartingAngle, + sweepAngle: secondArcLength, + strokeWidth: secondStepSize, + color: secondStepColor!, + strokeCap: secondCap, + ); + + // First arc, selected when clockwise, unselected otherwise + _drawArcOnCanvas( + canvas: canvas, + rect: rect, + paint: paint, + startingAngle: startingAngle, + sweepAngle: firstArcLength, + strokeWidth: firstStepSize, + color: firstStepColor!, + strokeCap: firstCap, + ); + } else { + // First arc, selected when clockwise, unselected otherwise + _drawArcOnCanvas( + canvas: canvas, + rect: rect, + paint: paint, + startingAngle: startingAngle, + sweepAngle: firstArcLength, + strokeWidth: firstStepSize, + color: firstStepColor!, + strokeCap: firstCap, + ); + + // Second arc, selected when counterclockwise, unselected otherwise + _drawArcOnCanvas( + canvas: canvas, + rect: rect, + paint: paint, + startingAngle: secondArcStartingAngle, + sweepAngle: secondArcLength, + strokeWidth: secondStepSize, + color: secondStepColor!, + strokeCap: secondCap, + ); + } + } + + /// Draw the actual arc for a continuous indicator + void _drawArcOnCanvas({ + required Canvas canvas, + required Rect rect, + required double startingAngle, + required double sweepAngle, + required Paint paint, + required Color color, + required double strokeWidth, + required StrokeCap strokeCap, + }) => + canvas.drawArc( + rect, + startingAngle, + sweepAngle, + false /*isRadial*/, + paint + ..color = color + ..strokeWidth = strokeWidth + ..strokeCap = strokeCap, + ); + + bool _isSelectedColor(int step, bool isClockwise) => isClockwise ? step < currentStep : (step + 1) > (totalSteps - currentStep); + + /// Start counting indexes from the right if clockwise and on the left if counterclockwise + int _indexOfStep(int step, bool isClockwise) => isClockwise ? step : totalSteps - step - 1; + + @override + bool shouldRepaint(CustomPainter oldDelegate) => oldDelegate != this; + + @override + bool hitTest(Offset position) => false; + + @override + void addListener(listener) {} + + @override + void removeListener(listener) {} + + @override + get semanticsBuilder => null; + + @override + bool shouldRebuildSemantics(CustomPainter oldDelegate) => false; +} + +/// Used to define the [circularDirection] attribute of the [CircularStepProgressBar] +enum CircularDirection { + clockwise, + counterclockwise, +} diff --git a/lib/widgets/input_widget.dart b/lib/widgets/input_widget.dart new file mode 100644 index 0000000..8b248e4 --- /dev/null +++ b/lib/widgets/input_widget.dart @@ -0,0 +1,106 @@ +import 'package:flutter/material.dart'; +import 'package:mohem_flutter_app/classes/colors.dart'; + +class InputWidget extends StatelessWidget { + final String labelText; + final String hintText; + final TextEditingController controller; + final VoidCallback? suffixTap; + final bool isEnable; + final bool hasSelection; + final int? lines; + final bool isInputTypeNum; + final bool isObscureText; + final bool isBackgroundEnable; + + InputWidget(this.labelText, this.hintText, this.controller, + {this.isObscureText = false, + this.suffixTap, + this.isEnable = true, + this.hasSelection = false, + this.lines = 1, + this.isInputTypeNum = false, + this.isBackgroundEnable = false}); + + @override + Widget build(BuildContext context) { + return Container( + padding: const EdgeInsets.only(left: 16, right: 16, bottom: 15, top: 15), + alignment: Alignment.center, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(15), + color: isBackgroundEnable ? Color(0xffF7F7F7) : Colors.white, + border: Border.all( + color: Color(0xffefefef), + width: 1, + ), + ), + child: InkWell( + onTap: hasSelection ? () {} : null, + child: Row( + children: [ + Expanded( + child: Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + labelText, + style: const TextStyle( + fontSize: 11, + fontWeight: FontWeight.w600, + color: Color(0xff2B353E), + letterSpacing: -0.44, + ), + ), + TextField( + enabled: isEnable, + scrollPadding: EdgeInsets.zero, + keyboardType: isInputTypeNum + ? TextInputType.number + : TextInputType.text, + controller: controller, + maxLines: lines, + obscuringCharacter: "*", + obscureText: isObscureText, + onChanged: (value) => {}, + style: const TextStyle( + fontSize: 14, + height: 21 / 14, + fontWeight: FontWeight.w400, + color: Color(0xff2B353E), + letterSpacing: -0.44, + ), + decoration: InputDecoration( + isDense: true, + hintText: hintText, + hintStyle: const TextStyle( + fontSize: 14, + height: 21 / 14, + fontWeight: FontWeight.w400, + color: Color(0xff575757), + letterSpacing: -0.56, + ), + suffixIconConstraints: const BoxConstraints(minWidth: 50), + suffixIcon: suffixTap == null + ? null + : IconButton( + icon: const Icon(Icons.mic, + color: MyColors.darkTextColor), + onPressed: suffixTap), + contentPadding: EdgeInsets.zero, + border: InputBorder.none, + focusedBorder: InputBorder.none, + enabledBorder: InputBorder.none, + ), + ), + ], + ), + ), + if (hasSelection) Icon(Icons.keyboard_arrow_down_outlined), + ], + ), + ), + ); + } +} diff --git a/lib/widgets/loading_dialog.dart b/lib/widgets/loading_dialog.dart new file mode 100644 index 0000000..9c88a39 --- /dev/null +++ b/lib/widgets/loading_dialog.dart @@ -0,0 +1,47 @@ +import 'package:flutter/cupertino.dart'; +import 'package:flutter/foundation.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter/rendering.dart'; + +class LoadingDialog extends StatefulWidget { + LoadingDialog({Key? key}) : super(key: key); + + @override + _LoadingDialogState createState() { + return _LoadingDialogState(); + } +} + +class _LoadingDialogState extends State { + @override + void initState() { + super.initState(); + } + + @override + void dispose() { + super.dispose(); + } + + @override + Widget build(BuildContext context) { + return Dialog( + insetPadding: const EdgeInsets.symmetric(horizontal: 60.0, vertical: 24.0), + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(16), + ), + elevation: 0, + backgroundColor: Colors.transparent, + child: Directionality( + textDirection: TextDirection.rtl, + child: Center( + child: Image.asset( + "assets/images/logos/loading_mohemm_logo.gif", + height: 96.0, + width: 96.0, + ), + ), + ), + ); + } +} diff --git a/lib/widgets/otp_widget.dart b/lib/widgets/otp_widget.dart new file mode 100644 index 0000000..a489e61 --- /dev/null +++ b/lib/widgets/otp_widget.dart @@ -0,0 +1,373 @@ +import 'dart:async'; + +import 'package:flutter/animation.dart'; +import 'package:flutter/foundation.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter/rendering.dart'; +import 'package:flutter/services.dart'; + +typedef OnDone = void Function(String text); + +class ProvidedPinBoxTextAnimation { + static AnimatedSwitcherTransitionBuilder scalingTransition = (child, animation) { + return ScaleTransition( + child: child, + scale: animation, + ); + }; + + static AnimatedSwitcherTransitionBuilder defaultNoTransition = (Widget child, Animation animation) { + return child; + }; +} + +class OTPWidget extends StatefulWidget { + final int maxLength; + final TextEditingController? controller; + + final Color defaultBorderColor; + final Color pinBoxColor; + final double pinBoxBorderWidth; + final double pinBoxRadius; + final bool hideDefaultKeyboard; + + final TextStyle? pinTextStyle; + final double pinBoxHeight; + final double pinBoxWidth; + final OnDone? onDone; + final bool hasError; + final Color errorBorderColor; + final Color textBorderColor; + final Function(String)? onTextChanged; + final bool autoFocus; + final FocusNode? focusNode; + final AnimatedSwitcherTransitionBuilder? pinTextAnimatedSwitcherTransition; + final Duration pinTextAnimatedSwitcherDuration; + final TextDirection textDirection; + final TextInputType keyboardType; + final EdgeInsets pinBoxOuterPadding; + + const OTPWidget({ + Key? key, + this.maxLength: 4, + this.controller, + this.pinBoxWidth: 70.0, + this.pinBoxHeight: 70.0, + this.pinTextStyle, + this.onDone, + this.defaultBorderColor: Colors.black, + this.textBorderColor: Colors.black, + this.pinTextAnimatedSwitcherTransition, + this.pinTextAnimatedSwitcherDuration: const Duration(), + this.hasError: false, + this.errorBorderColor: Colors.red, + this.onTextChanged, + this.autoFocus: false, + this.focusNode, + this.textDirection: TextDirection.ltr, + this.keyboardType: TextInputType.number, + this.pinBoxOuterPadding = const EdgeInsets.symmetric(horizontal: 4.0), + this.pinBoxColor = Colors.white, + this.pinBoxBorderWidth = 2.0, + this.pinBoxRadius = 0, + this.hideDefaultKeyboard = false, + }) : super(key: key); + + @override + State createState() { + return OTPWidgetState(); + } +} + +class OTPWidgetState extends State with SingleTickerProviderStateMixin { + AnimationController? _highlightAnimationController; + FocusNode? focusNode; + String text = ""; + int currentIndex = 0; + List strList = []; + bool hasFocus = false; + + @override + void didUpdateWidget(OTPWidget oldWidget) { + super.didUpdateWidget(oldWidget); + focusNode = widget.focusNode ?? focusNode; + + if (oldWidget.maxLength < widget.maxLength) { + setState(() { + currentIndex = text.length; + }); + widget.controller?.text = text; + widget.controller?.selection = TextSelection.collapsed(offset: text.length); + } else if (oldWidget.maxLength > widget.maxLength && widget.maxLength > 0 && text.length > 0 && text.length > widget.maxLength) { + setState(() { + text = text.substring(0, widget.maxLength); + currentIndex = text.length; + }); + widget.controller?.text = text; + widget.controller?.selection = TextSelection.collapsed(offset: text.length); + } + } + + _calculateStrList() { + if (strList.length > widget.maxLength) { + strList.length = widget.maxLength; + } + while (strList.length < widget.maxLength) { + strList.add(""); + } + } + + @override + void initState() { + super.initState(); + focusNode = widget.focusNode ?? FocusNode(); + + _initTextController(); + _calculateStrList(); + widget.controller?.addListener(_controllerListener); + focusNode?.addListener(_focusListener); + } + + void _controllerListener() { + if (mounted == true) { + setState(() { + _initTextController(); + }); + var onTextChanged = widget.onTextChanged; + if (onTextChanged != null) { + onTextChanged(widget.controller?.text ?? ""); + } + } + } + + void _focusListener() { + if (mounted == true) { + setState(() { + hasFocus = focusNode?.hasFocus ?? false; + }); + } + } + + void _initTextController() { + if (widget.controller == null) { + return; + } + strList.clear(); + var text = widget.controller?.text ?? ""; + if (text.isNotEmpty) { + if (text.length > widget.maxLength) { + throw Exception("TextEditingController length exceeded maxLength!"); + } + } + for (var i = 0; i < text.length; i++) { + strList.add(text[i]); + } + } + + double get _width { + var width = 0.0; + for (var i = 0; i < widget.maxLength; i++) { + width += widget.pinBoxWidth; + if (i == 0) { + width += widget.pinBoxOuterPadding.left; + } else if (i + 1 == widget.maxLength) { + width += widget.pinBoxOuterPadding.right; + } else { + width += widget.pinBoxOuterPadding.left; + } + } + return width; + } + + @override + void dispose() { + if (widget.focusNode == null) { + focusNode?.dispose(); + } else { + focusNode?.removeListener(_focusListener); + } + _highlightAnimationController?.dispose(); + widget.controller?.removeListener(_controllerListener); + + super.dispose(); + } + + @override + Widget build(BuildContext context) { + return Stack( + children: [ + _otpTextInput(), + _touchPinBoxRow(), + ], + ); + } + + Widget _touchPinBoxRow() { + return widget.hideDefaultKeyboard + ? _pinBoxRow(context) + : GestureDetector( + behavior: HitTestBehavior.opaque, + onTap: () { + if (hasFocus) { + FocusScope.of(context).requestFocus(FocusNode()); + Future.delayed(Duration(milliseconds: 100), () { + FocusScope.of(context).requestFocus(focusNode); + }); + } else { + FocusScope.of(context).requestFocus(focusNode); + } + }, + child: _pinBoxRow(context), + ); + } + + Widget _otpTextInput() { + var transparentBorder = OutlineInputBorder( + borderSide: BorderSide( + color: Colors.transparent, + width: 0.0, + ), + ); + return Container( + width: _width, + height: widget.pinBoxHeight, + child: TextField( + autofocus: !kIsWeb ? widget.autoFocus : false, + enableInteractiveSelection: false, + focusNode: focusNode, + controller: widget.controller, + keyboardType: widget.keyboardType, + inputFormatters: widget.keyboardType == TextInputType.number ? [FilteringTextInputFormatter.digitsOnly] : null, + style: TextStyle( + height: 0.1, + color: Colors.transparent, + ), + decoration: InputDecoration( + contentPadding: EdgeInsets.all(0), + focusedErrorBorder: transparentBorder, + errorBorder: transparentBorder, + disabledBorder: transparentBorder, + enabledBorder: transparentBorder, + focusedBorder: transparentBorder, + counterText: null, + counterStyle: null, + helperStyle: TextStyle( + height: 0.0, + color: Colors.transparent, + ), + labelStyle: TextStyle(height: 0.1), + fillColor: Colors.transparent, + border: InputBorder.none, + ), + cursorColor: Colors.transparent, + showCursor: false, + maxLength: widget.maxLength, + onChanged: _onTextChanged, + ), + ); + } + + void _onTextChanged(text) { + var onTextChanged = widget.onTextChanged; + if (onTextChanged != null) { + onTextChanged(text); + } + setState(() { + this.text = text; + if (text.length >= currentIndex) { + for (int i = currentIndex; i < text.length; i++) { + strList[i] = text[i]; + } + } + currentIndex = text.length; + }); + if (text.length == widget.maxLength) { + FocusScope.of(context).requestFocus(FocusNode()); + var onDone = widget.onDone; + if (onDone != null) { + onDone(text); + } + } + } + + Widget _pinBoxRow(BuildContext context) { + _calculateStrList(); + List pinCodes = List.generate(widget.maxLength, (int i) { + return _buildPinCode(i, context); + }); + return Row(children: pinCodes, mainAxisSize: MainAxisSize.min); + } + + Widget _buildPinCode(int i, BuildContext context) { + Color borderColor; + Color pinBoxColor = widget.pinBoxColor; + + if (widget.hasError) { + borderColor = widget.errorBorderColor; + } else if (i < text.length) { + borderColor = widget.textBorderColor; + } else { + borderColor = widget.defaultBorderColor; + pinBoxColor = widget.pinBoxColor; + } + + EdgeInsets insets; + if (i == 0) { + insets = EdgeInsets.only( + left: 0, + top: widget.pinBoxOuterPadding.top, + right: widget.pinBoxOuterPadding.right, + bottom: widget.pinBoxOuterPadding.bottom, + ); + } else if (i == strList.length - 1) { + insets = EdgeInsets.only( + left: widget.pinBoxOuterPadding.left, + top: widget.pinBoxOuterPadding.top, + right: 0, + bottom: widget.pinBoxOuterPadding.bottom, + ); + } else { + insets = widget.pinBoxOuterPadding; + } + return Container( + key: ValueKey("container$i"), + alignment: Alignment.center, + padding: EdgeInsets.symmetric(vertical: 4.0, horizontal: 1.0), + margin: insets, + child: _animatedTextBox(strList[i], i), + decoration: BoxDecoration( + border: Border.all( + color: borderColor, + width: widget.pinBoxBorderWidth, + ), + color: pinBoxColor, + borderRadius: BorderRadius.circular(widget.pinBoxRadius), + ), + width: widget.pinBoxWidth, + height: widget.pinBoxHeight, + ); + } + + Widget _animatedTextBox(String text, int i) { + if (widget.pinTextAnimatedSwitcherTransition != null) { + return AnimatedSwitcher( + duration: widget.pinTextAnimatedSwitcherDuration, + transitionBuilder: widget.pinTextAnimatedSwitcherTransition ?? + (Widget child, Animation animation) { + return child; + }, + child: Text( + text, + key: ValueKey("$text$i"), + style: widget.pinTextStyle, + ), + ); + } else { + return Text( + text, + key: ValueKey("${strList[i]}$i"), + style: widget.pinTextStyle, + ); + } + } +} diff --git a/lib/widgets/radio/show_radio.dart b/lib/widgets/radio/show_radio.dart new file mode 100644 index 0000000..fda5bf9 --- /dev/null +++ b/lib/widgets/radio/show_radio.dart @@ -0,0 +1,41 @@ +import 'package:flutter/material.dart'; +import 'package:mohem_flutter_app/classes/colors.dart'; +import 'package:mohem_flutter_app/extensions/int_extensions.dart'; +import 'package:mohem_flutter_app/extensions/string_extensions.dart'; +import 'package:mohem_flutter_app/extensions/int_extensions.dart'; + +class ShowRadio extends StatelessWidget { + String title, value, groupValue; + + ShowRadio( + {required this.title, required this.value, required this.groupValue}); + + @override + Widget build(BuildContext context) { + return Row( + mainAxisSize: MainAxisSize.min, + children: [ + Container( + width: 24, + height: 24, + decoration: BoxDecoration( + color: Colors.transparent, + border: Border.all(color: MyColors.grey98Color, width: 0.5), + borderRadius: BorderRadius.all(Radius.circular(100)), + ), + padding: EdgeInsets.all(4), + child: Container( + width: double.infinity, + height: double.infinity, + decoration: BoxDecoration( + color: value == groupValue ? Colors.black : Colors.transparent, + borderRadius: BorderRadius.all(Radius.circular(100)), + ), + ), + ), + 12.width, + title.toText12(isBold: true) + ], + ); + } +} diff --git a/pubspec.lock b/pubspec.lock new file mode 100644 index 0000000..1ae9d08 --- /dev/null +++ b/pubspec.lock @@ -0,0 +1,500 @@ +# Generated by pub +# See https://dart.dev/tools/pub/glossary#lockfile +packages: + args: + dependency: transitive + description: + name: args + url: "https://pub.dartlang.org" + source: hosted + version: "2.3.0" + async: + dependency: transitive + description: + name: async + url: "https://pub.dartlang.org" + source: hosted + version: "2.8.2" + boolean_selector: + dependency: transitive + description: + name: boolean_selector + url: "https://pub.dartlang.org" + source: hosted + version: "2.1.0" + characters: + dependency: transitive + description: + name: characters + url: "https://pub.dartlang.org" + source: hosted + version: "1.2.0" + charcode: + dependency: transitive + description: + name: charcode + url: "https://pub.dartlang.org" + source: hosted + version: "1.3.1" + clock: + dependency: transitive + description: + name: clock + url: "https://pub.dartlang.org" + source: hosted + version: "1.1.0" + collection: + dependency: transitive + description: + name: collection + url: "https://pub.dartlang.org" + source: hosted + version: "1.15.0" + crypto: + dependency: transitive + description: + name: crypto + url: "https://pub.dartlang.org" + source: hosted + version: "3.0.1" + cupertino_icons: + dependency: "direct main" + description: + name: cupertino_icons + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.4" + easy_localization: + dependency: "direct main" + description: + name: easy_localization + url: "https://pub.dartlang.org" + source: hosted + version: "3.0.0" + easy_logger: + dependency: transitive + description: + name: easy_logger + url: "https://pub.dartlang.org" + source: hosted + version: "0.0.2" + fake_async: + dependency: transitive + description: + name: fake_async + url: "https://pub.dartlang.org" + source: hosted + version: "1.2.0" + ffi: + dependency: transitive + description: + name: ffi + url: "https://pub.dartlang.org" + source: hosted + version: "1.1.2" + file: + dependency: transitive + description: + name: file + url: "https://pub.dartlang.org" + source: hosted + version: "6.1.2" + flutter: + dependency: "direct main" + description: flutter + source: sdk + version: "0.0.0" + flutter_lints: + dependency: "direct dev" + description: + name: flutter_lints + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.4" + flutter_localizations: + dependency: transitive + description: flutter + source: sdk + version: "0.0.0" + flutter_plugin_android_lifecycle: + dependency: transitive + description: + name: flutter_plugin_android_lifecycle + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.5" + flutter_svg: + dependency: "direct main" + description: + name: flutter_svg + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.0" + flutter_test: + dependency: "direct dev" + description: flutter + source: sdk + version: "0.0.0" + flutter_web_plugins: + dependency: transitive + description: flutter + source: sdk + version: "0.0.0" + fluttertoast: + dependency: "direct main" + description: + name: fluttertoast + url: "https://pub.dartlang.org" + source: hosted + version: "8.0.8" + http: + dependency: "direct main" + description: + name: http + url: "https://pub.dartlang.org" + source: hosted + version: "0.13.4" + http_parser: + dependency: transitive + description: + name: http_parser + url: "https://pub.dartlang.org" + source: hosted + version: "4.0.0" + injector: + dependency: "direct main" + description: + name: injector + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.0" + intl: + dependency: transitive + description: + name: intl + url: "https://pub.dartlang.org" + source: hosted + version: "0.17.0" + js: + dependency: transitive + description: + name: js + url: "https://pub.dartlang.org" + source: hosted + version: "0.6.3" + lints: + dependency: transitive + description: + name: lints + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.1" + local_auth: + dependency: "direct main" + description: + name: local_auth + url: "https://pub.dartlang.org" + source: hosted + version: "1.1.9" + matcher: + dependency: transitive + description: + name: matcher + url: "https://pub.dartlang.org" + source: hosted + version: "0.12.11" + meta: + dependency: transitive + description: + name: meta + url: "https://pub.dartlang.org" + source: hosted + version: "1.7.0" + nested: + dependency: transitive + description: + name: nested + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.0" + path: + dependency: transitive + description: + name: path + url: "https://pub.dartlang.org" + source: hosted + version: "1.8.0" + path_drawing: + dependency: transitive + description: + name: path_drawing + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.0" + path_parsing: + dependency: transitive + description: + name: path_parsing + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.0" + path_provider: + dependency: "direct main" + description: + name: path_provider + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.8" + path_provider_android: + dependency: transitive + description: + name: path_provider_android + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.9" + path_provider_ios: + dependency: transitive + description: + name: path_provider_ios + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.7" + path_provider_linux: + dependency: transitive + description: + name: path_provider_linux + url: "https://pub.dartlang.org" + source: hosted + version: "2.1.4" + path_provider_macos: + dependency: transitive + description: + name: path_provider_macos + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.4" + path_provider_platform_interface: + dependency: transitive + description: + name: path_provider_platform_interface + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.1" + path_provider_windows: + dependency: transitive + description: + name: path_provider_windows + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.4" + permission_handler: + dependency: "direct main" + description: + name: permission_handler + url: "https://pub.dartlang.org" + source: hosted + version: "8.3.0" + permission_handler_platform_interface: + dependency: transitive + description: + name: permission_handler_platform_interface + url: "https://pub.dartlang.org" + source: hosted + version: "3.7.0" + petitparser: + dependency: transitive + description: + name: petitparser + url: "https://pub.dartlang.org" + source: hosted + version: "4.4.0" + platform: + dependency: transitive + description: + name: platform + url: "https://pub.dartlang.org" + source: hosted + version: "3.1.0" + plugin_platform_interface: + dependency: transitive + description: + name: plugin_platform_interface + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.2" + process: + dependency: transitive + description: + name: process + url: "https://pub.dartlang.org" + source: hosted + version: "4.2.4" + provider: + dependency: "direct main" + description: + name: provider + url: "https://pub.dartlang.org" + source: hosted + version: "6.0.1" + shared_preferences: + dependency: transitive + description: + name: shared_preferences + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.11" + shared_preferences_android: + dependency: transitive + description: + name: shared_preferences_android + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.9" + shared_preferences_ios: + dependency: transitive + description: + name: shared_preferences_ios + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.8" + shared_preferences_linux: + dependency: transitive + description: + name: shared_preferences_linux + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.3" + shared_preferences_macos: + dependency: transitive + description: + name: shared_preferences_macos + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.2" + shared_preferences_platform_interface: + dependency: transitive + description: + name: shared_preferences_platform_interface + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.0" + shared_preferences_web: + dependency: transitive + description: + name: shared_preferences_web + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.2" + shared_preferences_windows: + dependency: transitive + description: + name: shared_preferences_windows + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.3" + shimmer: + dependency: "direct main" + description: + name: shimmer + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.0" + sizer: + dependency: "direct main" + description: + name: sizer + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.15" + sky_engine: + dependency: transitive + description: flutter + source: sdk + version: "0.0.99" + source_span: + dependency: transitive + description: + name: source_span + url: "https://pub.dartlang.org" + source: hosted + version: "1.8.1" + stack_trace: + dependency: transitive + description: + name: stack_trace + url: "https://pub.dartlang.org" + source: hosted + version: "1.10.0" + stream_channel: + dependency: transitive + description: + name: stream_channel + url: "https://pub.dartlang.org" + source: hosted + version: "2.1.0" + string_scanner: + dependency: transitive + description: + name: string_scanner + url: "https://pub.dartlang.org" + source: hosted + version: "1.1.0" + term_glyph: + dependency: transitive + description: + name: term_glyph + url: "https://pub.dartlang.org" + source: hosted + version: "1.2.0" + test_api: + dependency: transitive + description: + name: test_api + url: "https://pub.dartlang.org" + source: hosted + version: "0.4.3" + typed_data: + dependency: transitive + description: + name: typed_data + url: "https://pub.dartlang.org" + source: hosted + version: "1.3.0" + universal_io: + dependency: transitive + description: + name: universal_io + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.4" + vector_math: + dependency: transitive + description: + name: vector_math + url: "https://pub.dartlang.org" + source: hosted + version: "2.1.1" + win32: + dependency: transitive + description: + name: win32 + url: "https://pub.dartlang.org" + source: hosted + version: "2.3.1" + xdg_directories: + dependency: transitive + description: + name: xdg_directories + url: "https://pub.dartlang.org" + source: hosted + version: "0.2.0" + xml: + dependency: transitive + description: + name: xml + url: "https://pub.dartlang.org" + source: hosted + version: "5.3.1" +sdks: + dart: ">=2.14.0 <3.0.0" + flutter: ">=2.5.0" diff --git a/pubspec.yaml b/pubspec.yaml new file mode 100644 index 0000000..868012d --- /dev/null +++ b/pubspec.yaml @@ -0,0 +1,131 @@ +name: mohem_flutter_app +description: A new Flutter application. + +# The following line prevents the package from being accidentally published to +# pub.dev using `flutter pub publish`. This is preferred for private packages. +publish_to: 'none' # Remove this line if you wish to publish to pub.dev + +# The following defines the version and build number for your application. +# A version number is three numbers separated by dots, like 1.2.43 +# followed by an optional build number separated by a +. +# Both the version and the builder number may be overridden in flutter +# build by specifying --build-name and --build-number, respectively. +# In Android, build-name is used as versionName while build-number used as versionCode. +# Read more about Android versioning at https://developer.android.com/studio/publish/versioning +# 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: 1.0.0+1 + +environment: + sdk: ">=2.12.0 <3.0.0" + +# Dependencies specify other packages that your package needs in order to work. +# To automatically upgrade your package dependencies to the latest versions +# consider running `flutter pub upgrade --major-versions`. Alternatively, +# dependencies can be manually updated by changing the version numbers below to +# the latest version available on pub.dev. To see which dependencies have newer +# versions available, run `flutter pub outdated`. +dependencies: + flutter: + sdk: flutter + + + # 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 + injector: ^2.0.0 + provider: ^6.0.1 + easy_localization: ^3.0.0 + http: ^0.13.4 + permission_handler: ^8.3.0 + flutter_svg: ^1.0.0 + sizer: ^2.0.15 + local_auth: ^1.1.9 + fluttertoast: ^8.0.8 + shimmer: ^2.0.0 + + +dev_dependencies: + flutter_test: + sdk: flutter + + # The "flutter_lints" package below contains a set of recommended lints to + # encourage good coding practices. The lint set provided by the package is + # activated in the `analysis_options.yaml` file located at the root of your + # package. See that file for information about deactivating specific lint + # rules and activating additional ones. + flutter_lints: ^1.0.4 + +# For information on the generic Dart part of this file, see the +# following page: https://dart.dev/tools/pub/pubspec + +# The following section is specific to Flutter. +flutter: + + # The following line ensures that the Material Icons font is + # included with your application, so that you can use the icons in + # the material Icons class. + uses-material-design: true + + # To add assets to your application, add an assets section, like this: + # assets: + # - images/a_dot_burr.jpeg + # - images/a_dot_ham.jpeg + assets: + - assets/ + - assets/langs/ + - assets/icons/ + - assets/images/ + - assets/images/login/ + - assets/images/logos/ + + # An image asset can refer to one or more resolution-specific "variants", see + # https://flutter.dev/assets-and-images/#resolution-aware. + + # For details regarding adding assets from package dependencies, see + # https://flutter.dev/assets-and-images/#from-packages + + # To add custom fonts to your application, add a fonts section here, + # in this "flutter" section. Each entry in this list should have a + # "family" key with the font family name, and a "fonts" key with a + # list giving the asset and other descriptors for the font. For + # example: + fonts: + - family: Cairo + fonts: + - asset: assets/fonts/ar/Cairo-Light/Cairo-Light.eot + - asset: assets/fonts/ar/Cairo-Light/Cairo-Light.otf + - asset: assets/fonts/ar/Cairo-Light/Cairo-Light.ttf + - asset: assets/fonts/ar/Cairo-Light/Cairo-Light.woff + weight: 300 + + - asset: assets/fonts/ar/Cairo-Bold/Cairo-Bold.eot + - asset: assets/fonts/ar/Cairo-Bold/Cairo-Bold.otf + - asset: assets/fonts/ar/Cairo-Bold/Cairo-Bold.ttf + - asset: assets/fonts/ar/Cairo-Bold/Cairo-Bold.woff + weight: 700 + - family: Poppins + fonts: + - asset: assets/fonts/poppins/Poppins-Black.ttf + weight: 900 + - asset: assets/fonts/poppins/Poppins-ExtraBold.ttf + weight: 800 + - asset: assets/fonts/poppins/Poppins-Bold.ttf + weight: 700 + - asset: assets/fonts/poppins/Poppins-SemiBold.ttf + weight: 600 + - asset: assets/fonts/poppins/Poppins-Medium.ttf + weight: 500 + - asset: assets/fonts/poppins/Poppins-Regular.ttf + weight: 400 + - asset: assets/fonts/poppins/Poppins-Light.ttf + weight: 300 + - asset: assets/fonts/poppins/Poppins-ExtraLight.ttf + weight: 200 + - asset: assets/fonts/poppins/Poppins-Thin.ttf + weight: 100 + # + # For details regarding fonts from package dependencies, + # see https://flutter.dev/custom-fonts/#from-packages diff --git a/test/widget_test.dart b/test/widget_test.dart new file mode 100644 index 0000000..a360c7e --- /dev/null +++ b/test/widget_test.dart @@ -0,0 +1,30 @@ +// This is a basic Flutter widget test. +// +// To perform an interaction with a widget in your test, use the WidgetTester +// utility that Flutter provides. For example, you can send tap and scroll +// gestures. You can also use WidgetTester to find child widgets in the widget +// tree, read text, and verify that the values of widget properties are correct. + +import 'package:flutter/material.dart'; +import 'package:flutter_test/flutter_test.dart'; + +import 'package:mohem_flutter_app/main.dart'; + +void main() { + testWidgets('Counter increments smoke test', (WidgetTester tester) async { + // Build our app and trigger a frame. + await tester.pumpWidget( MyApp()); + + // Verify that our counter starts at 0. + expect(find.text('0'), findsOneWidget); + expect(find.text('1'), findsNothing); + + // Tap the '+' icon and trigger a frame. + await tester.tap(find.byIcon(Icons.add)); + await tester.pump(); + + // Verify that our counter has incremented. + expect(find.text('0'), findsNothing); + expect(find.text('1'), findsOneWidget); + }); +} diff --git a/web/favicon.png b/web/favicon.png new file mode 100644 index 0000000..8aaa46a Binary files /dev/null and b/web/favicon.png differ diff --git a/web/icons/Icon-192.png b/web/icons/Icon-192.png new file mode 100644 index 0000000..b749bfe Binary files /dev/null and b/web/icons/Icon-192.png differ diff --git a/web/icons/Icon-512.png b/web/icons/Icon-512.png new file mode 100644 index 0000000..88cfd48 Binary files /dev/null and b/web/icons/Icon-512.png differ diff --git a/web/icons/Icon-maskable-192.png b/web/icons/Icon-maskable-192.png new file mode 100644 index 0000000..eb9b4d7 Binary files /dev/null and b/web/icons/Icon-maskable-192.png differ diff --git a/web/icons/Icon-maskable-512.png b/web/icons/Icon-maskable-512.png new file mode 100644 index 0000000..d69c566 Binary files /dev/null and b/web/icons/Icon-maskable-512.png differ diff --git a/web/index.html b/web/index.html new file mode 100644 index 0000000..0da60b3 --- /dev/null +++ b/web/index.html @@ -0,0 +1,101 @@ + + + + + + + + + + + + + + + + + mohem_flutter_app + + + + + + + diff --git a/web/manifest.json b/web/manifest.json new file mode 100644 index 0000000..32285bd --- /dev/null +++ b/web/manifest.json @@ -0,0 +1,35 @@ +{ + "name": "mohem_flutter_app", + "short_name": "mohem_flutter_app", + "start_url": ".", + "display": "standalone", + "background_color": "#0175C2", + "theme_color": "#0175C2", + "description": "A new Flutter application.", + "orientation": "portrait-primary", + "prefer_related_applications": false, + "icons": [ + { + "src": "icons/Icon-192.png", + "sizes": "192x192", + "type": "image/png" + }, + { + "src": "icons/Icon-512.png", + "sizes": "512x512", + "type": "image/png" + }, + { + "src": "icons/Icon-maskable-192.png", + "sizes": "192x192", + "type": "image/png", + "purpose": "maskable" + }, + { + "src": "icons/Icon-maskable-512.png", + "sizes": "512x512", + "type": "image/png", + "purpose": "maskable" + } + ] +}