From 6b62c02d52832dee54c923495ecfb7ab107519dd Mon Sep 17 00:00:00 2001 From: "saad.siddiq" Date: Thu, 10 Apr 2025 12:03:52 +0500 Subject: [PATCH] First Commit --- .gitignore | 15 + app/.gitignore | 1 + app/build.gradle | 47 +++ app/proguard-rules.pro | 21 ++ .../ExampleInstrumentedTest.java | 26 ++ app/src/main/AndroidManifest.xml | 50 +++ .../activities/DashboardActivity.java | 138 +++++++ .../activities/LoginActivity.java | 162 ++++++++ .../adapters/PagerAdapter.java | 71 ++++ .../apiservice/ApiService.java | 35 ++ .../apiservice/ApiServiceFactory.java | 17 + .../apiservice/RetrofitClient.java | 49 +++ .../fragments/DraftFragment.java | 27 ++ .../fragments/HomeFragment.java | 27 ++ .../hseobservationsapp/helper/Helper.java | 127 +++++++ .../hseobservationsapp/helper/Preference.java | 82 ++++ .../hseobservationsapp/models/Department.java | 177 +++++++++ .../hseobservationsapp/models/Item.java | 24 ++ .../hseobservationsapp/models/ItemModel.java | 93 +++++ .../models/LocationFloor.java | 69 ++++ .../models/LocationSite.java | 80 ++++ .../models/LocationUnit.java | 59 +++ .../models/QualityControl.java | 70 ++++ .../models/QualityControlProcess.java | 32 ++ .../models/QualityControlProcessStep.java | 43 +++ .../models/QualityControlResponse.java | 77 ++++ .../models/QualitySaveResponse.java | 117 ++++++ .../utils/NonSwipeableViewPager.java | 33 ++ .../utils/ProgressDialogFragment.java | 37 ++ .../viewmodels/LoginViewModel.java | 80 ++++ .../main/res/anim/bs_list_layout_fade_in.xml | 6 + app/src/main/res/anim/fade_in.xml | 11 + app/src/main/res/anim/fade_out.xml | 11 + app/src/main/res/anim/grow_from_bottom.xml | 14 + app/src/main/res/anim/grow_from_top.xml | 15 + app/src/main/res/anim/popup_hide.xml | 8 + app/src/main/res/anim/popup_show.xml | 8 + app/src/main/res/anim/slide_down.xml | 3 + app/src/main/res/anim/slide_in_bottom.xml | 9 + app/src/main/res/anim/slide_in_left.xml | 11 + app/src/main/res/anim/slide_in_left_menu.xml | 8 + app/src/main/res/anim/slide_in_right.xml | 11 + app/src/main/res/anim/slide_in_right_menu.xml | 8 + app/src/main/res/anim/slide_in_top.xml | 9 + app/src/main/res/anim/slide_out_bottom.xml | 9 + app/src/main/res/anim/slide_out_left.xml | 11 + app/src/main/res/anim/slide_out_right.xml | 11 + app/src/main/res/anim/slide_out_top.xml | 9 + app/src/main/res/anim/slide_up.xml | 5 + app/src/main/res/drawable/arrow_back.xml | 5 + app/src/main/res/drawable/curved_layout.xml | 18 + app/src/main/res/drawable/custom_button.xml | 9 + .../main/res/drawable/dropdown_item_bg.xml | 17 + app/src/main/res/drawable/et_border.xml | 8 + .../main/res/drawable/et_border_dropdown.xml | 8 + app/src/main/res/drawable/hse.png | Bin 0 -> 28631 bytes app/src/main/res/drawable/ic_delete.xml | 5 + app/src/main/res/drawable/ic_email.xml | 5 + .../res/drawable/ic_launcher_background.xml | 170 +++++++++ .../res/drawable/ic_launcher_foreground.xml | 30 ++ app/src/main/res/drawable/ic_logout.xml | 5 + app/src/main/res/drawable/ic_password.xml | 5 + app/src/main/res/drawable/icon_home.png | Bin 0 -> 215 bytes app/src/main/res/drawable/icon_hse.png | Bin 0 -> 2680 bytes app/src/main/res/drawable/icon_tab_drafts.xml | 5 + app/src/main/res/drawable/icon_tab_home.xml | 5 + app/src/main/res/drawable/image_picker.xml | 5 + app/src/main/res/drawable/img_load.xml | 12 + app/src/main/res/drawable/rounded_border.xml | 8 + .../main/res/drawable/rounded_btn_login.xml | 7 + app/src/main/res/drawable/rounded_white.xml | 13 + app/src/main/res/drawable/wave_4_.xml | 9 + .../main/res/layout/activity_dashboard.xml | 82 ++++ app/src/main/res/layout/activity_login.xml | 90 +++++ .../res/layout/custom_layout_for_logout.xml | 87 +++++ app/src/main/res/layout/custom_tab.xml | 28 ++ app/src/main/res/layout/dialog_progress.xml | 15 + app/src/main/res/layout/fragment_draft.xml | 33 ++ app/src/main/res/layout/fragment_home.xml | 24 ++ .../res/mipmap-anydpi-v26/ic_launcher.xml | 6 + .../mipmap-anydpi-v26/ic_launcher_round.xml | 6 + app/src/main/res/mipmap-hdpi/ic_launcher.webp | Bin 0 -> 1404 bytes .../res/mipmap-hdpi/ic_launcher_round.webp | Bin 0 -> 2898 bytes app/src/main/res/mipmap-mdpi/ic_launcher.webp | Bin 0 -> 982 bytes .../res/mipmap-mdpi/ic_launcher_round.webp | Bin 0 -> 1772 bytes .../main/res/mipmap-xhdpi/ic_launcher.webp | Bin 0 -> 1900 bytes .../res/mipmap-xhdpi/ic_launcher_round.webp | Bin 0 -> 3918 bytes .../main/res/mipmap-xxhdpi/ic_launcher.webp | Bin 0 -> 2884 bytes .../res/mipmap-xxhdpi/ic_launcher_round.webp | Bin 0 -> 5914 bytes .../main/res/mipmap-xxxhdpi/ic_launcher.webp | Bin 0 -> 3844 bytes .../res/mipmap-xxxhdpi/ic_launcher_round.webp | Bin 0 -> 7778 bytes app/src/main/res/values-hdpi/meta.xml | 5 + app/src/main/res/values-hdpi/sdp.xml | 303 +++++++++++++++ app/src/main/res/values-land/dimens.xml | 3 + app/src/main/res/values-mdpi/meta.xml | 5 + app/src/main/res/values-mdpi/sdp.xml | 303 +++++++++++++++ app/src/main/res/values-night/themes.xml | 7 + app/src/main/res/values-sw300dp/meta.xml | 5 + app/src/main/res/values-sw300dp/sdp.xml | 303 +++++++++++++++ app/src/main/res/values-sw330dp/meta.xml | 5 + app/src/main/res/values-sw330dp/sdp.xml | 303 +++++++++++++++ app/src/main/res/values-sw360dp/meta.xml | 5 + app/src/main/res/values-sw360dp/sdp.xml | 303 +++++++++++++++ app/src/main/res/values-sw390dp/meta.xml | 5 + app/src/main/res/values-sw390dp/sdp.xml | 303 +++++++++++++++ app/src/main/res/values-sw420dp/meta.xml | 5 + app/src/main/res/values-sw420dp/sdp.xml | 303 +++++++++++++++ app/src/main/res/values-sw450dp/meta.xml | 5 + app/src/main/res/values-sw450dp/sdp.xml | 303 +++++++++++++++ app/src/main/res/values-sw480dp/meta.xml | 5 + app/src/main/res/values-sw480dp/sdp.xml | 303 +++++++++++++++ app/src/main/res/values-sw510dp/meta.xml | 5 + app/src/main/res/values-sw510dp/sdp.xml | 303 +++++++++++++++ app/src/main/res/values-sw540dp/meta.xml | 5 + app/src/main/res/values-sw540dp/sdp.xml | 303 +++++++++++++++ app/src/main/res/values-sw570dp/meta.xml | 5 + app/src/main/res/values-sw570dp/sdp.xml | 303 +++++++++++++++ app/src/main/res/values-sw600dp/meta.xml | 5 + app/src/main/res/values-sw600dp/sdp.xml | 303 +++++++++++++++ app/src/main/res/values-sw630dp/meta.xml | 5 + app/src/main/res/values-sw630dp/sdp.xml | 303 +++++++++++++++ app/src/main/res/values-sw660dp/meta.xml | 5 + app/src/main/res/values-sw660dp/sdp.xml | 303 +++++++++++++++ app/src/main/res/values-sw690dp/meta.xml | 5 + app/src/main/res/values-sw690dp/sdp.xml | 303 +++++++++++++++ app/src/main/res/values-sw720dp/meta.xml | 5 + app/src/main/res/values-sw720dp/sdp.xml | 303 +++++++++++++++ app/src/main/res/values-sw750dp/meta.xml | 5 + app/src/main/res/values-sw750dp/sdp.xml | 303 +++++++++++++++ app/src/main/res/values-sw780dp/meta.xml | 5 + app/src/main/res/values-sw780dp/sdp.xml | 303 +++++++++++++++ app/src/main/res/values-w1240dp/dimens.xml | 3 + app/src/main/res/values-w600dp/dimens.xml | 3 + app/src/main/res/values-xhdpi/meta.xml | 2 + app/src/main/res/values-xhdpi/sdp.xml | 303 +++++++++++++++ app/src/main/res/values-xlarge/meta.xml | 5 + app/src/main/res/values-xlarge/sdp.xml | 303 +++++++++++++++ app/src/main/res/values-xxhdpi/meta.xml | 2 + app/src/main/res/values-xxhdpi/sdp.xml | 304 +++++++++++++++ app/src/main/res/values-xxxhdpi/meta.xml | 2 + app/src/main/res/values-xxxhdpi/sdp.xml | 304 +++++++++++++++ app/src/main/res/values/colors.xml | 357 ++++++++++++++++++ app/src/main/res/values/strings.xml | 5 + app/src/main/res/values/themes.xml | 21 ++ app/src/main/res/xml/backup_rules.xml | 13 + .../main/res/xml/data_extraction_rules.xml | 19 + app/src/main/res/xml/file_paths.xml | 4 + .../hseobservationsapp/ExampleUnitTest.java | 17 + build.gradle | 4 + gradle.properties | 21 ++ gradle/libs.versions.toml | 31 ++ gradle/wrapper/gradle-wrapper.jar | Bin 0 -> 59203 bytes gradle/wrapper/gradle-wrapper.properties | 6 + gradlew | 185 +++++++++ gradlew.bat | 89 +++++ settings.gradle | 23 ++ 156 files changed, 10671 insertions(+) create mode 100644 .gitignore create mode 100644 app/.gitignore create mode 100644 app/build.gradle create mode 100644 app/proguard-rules.pro create mode 100644 app/src/androidTest/java/com/utopiaindustries/hseobservationsapp/ExampleInstrumentedTest.java create mode 100644 app/src/main/AndroidManifest.xml create mode 100644 app/src/main/java/com/utopiaindustries/hseobservationsapp/activities/DashboardActivity.java create mode 100644 app/src/main/java/com/utopiaindustries/hseobservationsapp/activities/LoginActivity.java create mode 100644 app/src/main/java/com/utopiaindustries/hseobservationsapp/adapters/PagerAdapter.java create mode 100644 app/src/main/java/com/utopiaindustries/hseobservationsapp/apiservice/ApiService.java create mode 100644 app/src/main/java/com/utopiaindustries/hseobservationsapp/apiservice/ApiServiceFactory.java create mode 100644 app/src/main/java/com/utopiaindustries/hseobservationsapp/apiservice/RetrofitClient.java create mode 100644 app/src/main/java/com/utopiaindustries/hseobservationsapp/fragments/DraftFragment.java create mode 100644 app/src/main/java/com/utopiaindustries/hseobservationsapp/fragments/HomeFragment.java create mode 100644 app/src/main/java/com/utopiaindustries/hseobservationsapp/helper/Helper.java create mode 100644 app/src/main/java/com/utopiaindustries/hseobservationsapp/helper/Preference.java create mode 100644 app/src/main/java/com/utopiaindustries/hseobservationsapp/models/Department.java create mode 100644 app/src/main/java/com/utopiaindustries/hseobservationsapp/models/Item.java create mode 100644 app/src/main/java/com/utopiaindustries/hseobservationsapp/models/ItemModel.java create mode 100644 app/src/main/java/com/utopiaindustries/hseobservationsapp/models/LocationFloor.java create mode 100644 app/src/main/java/com/utopiaindustries/hseobservationsapp/models/LocationSite.java create mode 100644 app/src/main/java/com/utopiaindustries/hseobservationsapp/models/LocationUnit.java create mode 100644 app/src/main/java/com/utopiaindustries/hseobservationsapp/models/QualityControl.java create mode 100644 app/src/main/java/com/utopiaindustries/hseobservationsapp/models/QualityControlProcess.java create mode 100644 app/src/main/java/com/utopiaindustries/hseobservationsapp/models/QualityControlProcessStep.java create mode 100644 app/src/main/java/com/utopiaindustries/hseobservationsapp/models/QualityControlResponse.java create mode 100644 app/src/main/java/com/utopiaindustries/hseobservationsapp/models/QualitySaveResponse.java create mode 100644 app/src/main/java/com/utopiaindustries/hseobservationsapp/utils/NonSwipeableViewPager.java create mode 100644 app/src/main/java/com/utopiaindustries/hseobservationsapp/utils/ProgressDialogFragment.java create mode 100644 app/src/main/java/com/utopiaindustries/hseobservationsapp/viewmodels/LoginViewModel.java create mode 100644 app/src/main/res/anim/bs_list_layout_fade_in.xml create mode 100644 app/src/main/res/anim/fade_in.xml create mode 100644 app/src/main/res/anim/fade_out.xml create mode 100644 app/src/main/res/anim/grow_from_bottom.xml create mode 100644 app/src/main/res/anim/grow_from_top.xml create mode 100644 app/src/main/res/anim/popup_hide.xml create mode 100644 app/src/main/res/anim/popup_show.xml create mode 100644 app/src/main/res/anim/slide_down.xml create mode 100644 app/src/main/res/anim/slide_in_bottom.xml create mode 100644 app/src/main/res/anim/slide_in_left.xml create mode 100644 app/src/main/res/anim/slide_in_left_menu.xml create mode 100644 app/src/main/res/anim/slide_in_right.xml create mode 100644 app/src/main/res/anim/slide_in_right_menu.xml create mode 100644 app/src/main/res/anim/slide_in_top.xml create mode 100644 app/src/main/res/anim/slide_out_bottom.xml create mode 100644 app/src/main/res/anim/slide_out_left.xml create mode 100644 app/src/main/res/anim/slide_out_right.xml create mode 100644 app/src/main/res/anim/slide_out_top.xml create mode 100644 app/src/main/res/anim/slide_up.xml create mode 100644 app/src/main/res/drawable/arrow_back.xml create mode 100644 app/src/main/res/drawable/curved_layout.xml create mode 100644 app/src/main/res/drawable/custom_button.xml create mode 100644 app/src/main/res/drawable/dropdown_item_bg.xml create mode 100644 app/src/main/res/drawable/et_border.xml create mode 100644 app/src/main/res/drawable/et_border_dropdown.xml create mode 100644 app/src/main/res/drawable/hse.png create mode 100644 app/src/main/res/drawable/ic_delete.xml create mode 100644 app/src/main/res/drawable/ic_email.xml create mode 100644 app/src/main/res/drawable/ic_launcher_background.xml create mode 100644 app/src/main/res/drawable/ic_launcher_foreground.xml create mode 100644 app/src/main/res/drawable/ic_logout.xml create mode 100644 app/src/main/res/drawable/ic_password.xml create mode 100644 app/src/main/res/drawable/icon_home.png create mode 100644 app/src/main/res/drawable/icon_hse.png create mode 100644 app/src/main/res/drawable/icon_tab_drafts.xml create mode 100644 app/src/main/res/drawable/icon_tab_home.xml create mode 100644 app/src/main/res/drawable/image_picker.xml create mode 100644 app/src/main/res/drawable/img_load.xml create mode 100644 app/src/main/res/drawable/rounded_border.xml create mode 100644 app/src/main/res/drawable/rounded_btn_login.xml create mode 100644 app/src/main/res/drawable/rounded_white.xml create mode 100644 app/src/main/res/drawable/wave_4_.xml create mode 100644 app/src/main/res/layout/activity_dashboard.xml create mode 100644 app/src/main/res/layout/activity_login.xml create mode 100644 app/src/main/res/layout/custom_layout_for_logout.xml create mode 100644 app/src/main/res/layout/custom_tab.xml create mode 100644 app/src/main/res/layout/dialog_progress.xml create mode 100644 app/src/main/res/layout/fragment_draft.xml create mode 100644 app/src/main/res/layout/fragment_home.xml create mode 100644 app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml create mode 100644 app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml create mode 100644 app/src/main/res/mipmap-hdpi/ic_launcher.webp create mode 100644 app/src/main/res/mipmap-hdpi/ic_launcher_round.webp create mode 100644 app/src/main/res/mipmap-mdpi/ic_launcher.webp create mode 100644 app/src/main/res/mipmap-mdpi/ic_launcher_round.webp create mode 100644 app/src/main/res/mipmap-xhdpi/ic_launcher.webp create mode 100644 app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp create mode 100644 app/src/main/res/mipmap-xxhdpi/ic_launcher.webp create mode 100644 app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp create mode 100644 app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp create mode 100644 app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp create mode 100644 app/src/main/res/values-hdpi/meta.xml create mode 100644 app/src/main/res/values-hdpi/sdp.xml create mode 100644 app/src/main/res/values-land/dimens.xml create mode 100644 app/src/main/res/values-mdpi/meta.xml create mode 100644 app/src/main/res/values-mdpi/sdp.xml create mode 100644 app/src/main/res/values-night/themes.xml create mode 100644 app/src/main/res/values-sw300dp/meta.xml create mode 100644 app/src/main/res/values-sw300dp/sdp.xml create mode 100644 app/src/main/res/values-sw330dp/meta.xml create mode 100644 app/src/main/res/values-sw330dp/sdp.xml create mode 100644 app/src/main/res/values-sw360dp/meta.xml create mode 100644 app/src/main/res/values-sw360dp/sdp.xml create mode 100644 app/src/main/res/values-sw390dp/meta.xml create mode 100644 app/src/main/res/values-sw390dp/sdp.xml create mode 100644 app/src/main/res/values-sw420dp/meta.xml create mode 100644 app/src/main/res/values-sw420dp/sdp.xml create mode 100644 app/src/main/res/values-sw450dp/meta.xml create mode 100644 app/src/main/res/values-sw450dp/sdp.xml create mode 100644 app/src/main/res/values-sw480dp/meta.xml create mode 100644 app/src/main/res/values-sw480dp/sdp.xml create mode 100644 app/src/main/res/values-sw510dp/meta.xml create mode 100644 app/src/main/res/values-sw510dp/sdp.xml create mode 100644 app/src/main/res/values-sw540dp/meta.xml create mode 100644 app/src/main/res/values-sw540dp/sdp.xml create mode 100644 app/src/main/res/values-sw570dp/meta.xml create mode 100644 app/src/main/res/values-sw570dp/sdp.xml create mode 100644 app/src/main/res/values-sw600dp/meta.xml create mode 100644 app/src/main/res/values-sw600dp/sdp.xml create mode 100644 app/src/main/res/values-sw630dp/meta.xml create mode 100644 app/src/main/res/values-sw630dp/sdp.xml create mode 100644 app/src/main/res/values-sw660dp/meta.xml create mode 100644 app/src/main/res/values-sw660dp/sdp.xml create mode 100644 app/src/main/res/values-sw690dp/meta.xml create mode 100644 app/src/main/res/values-sw690dp/sdp.xml create mode 100644 app/src/main/res/values-sw720dp/meta.xml create mode 100644 app/src/main/res/values-sw720dp/sdp.xml create mode 100644 app/src/main/res/values-sw750dp/meta.xml create mode 100644 app/src/main/res/values-sw750dp/sdp.xml create mode 100644 app/src/main/res/values-sw780dp/meta.xml create mode 100644 app/src/main/res/values-sw780dp/sdp.xml create mode 100644 app/src/main/res/values-w1240dp/dimens.xml create mode 100644 app/src/main/res/values-w600dp/dimens.xml create mode 100644 app/src/main/res/values-xhdpi/meta.xml create mode 100644 app/src/main/res/values-xhdpi/sdp.xml create mode 100644 app/src/main/res/values-xlarge/meta.xml create mode 100644 app/src/main/res/values-xlarge/sdp.xml create mode 100644 app/src/main/res/values-xxhdpi/meta.xml create mode 100644 app/src/main/res/values-xxhdpi/sdp.xml create mode 100644 app/src/main/res/values-xxxhdpi/meta.xml create mode 100644 app/src/main/res/values-xxxhdpi/sdp.xml create mode 100644 app/src/main/res/values/colors.xml create mode 100644 app/src/main/res/values/strings.xml create mode 100644 app/src/main/res/values/themes.xml create mode 100644 app/src/main/res/xml/backup_rules.xml create mode 100644 app/src/main/res/xml/data_extraction_rules.xml create mode 100644 app/src/main/res/xml/file_paths.xml create mode 100644 app/src/test/java/com/utopiaindustries/hseobservationsapp/ExampleUnitTest.java create mode 100644 build.gradle create mode 100644 gradle.properties create mode 100644 gradle/libs.versions.toml create mode 100644 gradle/wrapper/gradle-wrapper.jar create mode 100644 gradle/wrapper/gradle-wrapper.properties create mode 100644 gradlew create mode 100644 gradlew.bat create mode 100644 settings.gradle diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..aa724b7 --- /dev/null +++ b/.gitignore @@ -0,0 +1,15 @@ +*.iml +.gradle +/local.properties +/.idea/caches +/.idea/libraries +/.idea/modules.xml +/.idea/workspace.xml +/.idea/navEditor.xml +/.idea/assetWizardSettings.xml +.DS_Store +/build +/captures +.externalNativeBuild +.cxx +local.properties diff --git a/app/.gitignore b/app/.gitignore new file mode 100644 index 0000000..42afabf --- /dev/null +++ b/app/.gitignore @@ -0,0 +1 @@ +/build \ No newline at end of file diff --git a/app/build.gradle b/app/build.gradle new file mode 100644 index 0000000..f3124be --- /dev/null +++ b/app/build.gradle @@ -0,0 +1,47 @@ +plugins { + alias(libs.plugins.android.application) +} + +android { + namespace 'com.utopiaindustries.hseobservationsapp' + compileSdk 34 + + defaultConfig { + applicationId "com.utopiaindustries.hseobservationsapp" + minSdk 24 + targetSdk 34 + versionCode 1 + versionName "1.0" + + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + } + + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + } + } + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } +} + +dependencies { + + implementation libs.appcompat + implementation libs.material + implementation libs.activity + implementation libs.constraintlayout + testImplementation libs.junit + androidTestImplementation libs.ext.junit + androidTestImplementation libs.espresso.core + + implementation libs.retrofit + implementation libs.converter.gson + implementation libs.glide + implementation libs.easypermissions + implementation libs.preference + +} \ No newline at end of file diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro new file mode 100644 index 0000000..481bb43 --- /dev/null +++ b/app/proguard-rules.pro @@ -0,0 +1,21 @@ +# Add project specific ProGuard rules here. +# You can control the set of applied configuration files using the +# proguardFiles setting in build.gradle. +# +# For more details, see +# http://developer.android.com/guide/developing/tools/proguard.html + +# If your project uses WebView with JS, uncomment the following +# and specify the fully qualified class name to the JavaScript interface +# class: +#-keepclassmembers class fqcn.of.javascript.interface.for.webview { +# public *; +#} + +# Uncomment this to preserve the line number information for +# debugging stack traces. +#-keepattributes SourceFile,LineNumberTable + +# If you keep the line number information, uncomment this to +# hide the original source file name. +#-renamesourcefileattribute SourceFile \ No newline at end of file diff --git a/app/src/androidTest/java/com/utopiaindustries/hseobservationsapp/ExampleInstrumentedTest.java b/app/src/androidTest/java/com/utopiaindustries/hseobservationsapp/ExampleInstrumentedTest.java new file mode 100644 index 0000000..539dff5 --- /dev/null +++ b/app/src/androidTest/java/com/utopiaindustries/hseobservationsapp/ExampleInstrumentedTest.java @@ -0,0 +1,26 @@ +package com.utopiaindustries.hseobservationsapp; + +import android.content.Context; + +import androidx.test.platform.app.InstrumentationRegistry; +import androidx.test.ext.junit.runners.AndroidJUnit4; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import static org.junit.Assert.*; + +/** + * Instrumented test, which will execute on an Android device. + * + * @see Testing documentation + */ +@RunWith(AndroidJUnit4.class) +public class ExampleInstrumentedTest { + @Test + public void useAppContext() { + // Context of the app under test. + Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext(); + assertEquals("com.utopiaindustries.hseobservationsapp", appContext.getPackageName()); + } +} \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000..87704c6 --- /dev/null +++ b/app/src/main/AndroidManifest.xml @@ -0,0 +1,50 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/java/com/utopiaindustries/hseobservationsapp/activities/DashboardActivity.java b/app/src/main/java/com/utopiaindustries/hseobservationsapp/activities/DashboardActivity.java new file mode 100644 index 0000000..1dcc305 --- /dev/null +++ b/app/src/main/java/com/utopiaindustries/hseobservationsapp/activities/DashboardActivity.java @@ -0,0 +1,138 @@ +package com.utopiaindustries.hseobservationsapp.activities; + +import android.content.Context; +import android.content.Intent; +import android.graphics.Color; +import android.graphics.drawable.ColorDrawable; +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ImageView; +import android.widget.TextView; + +import androidx.activity.EdgeToEdge; +import androidx.appcompat.app.AlertDialog; +import androidx.appcompat.app.AppCompatActivity; +import androidx.core.graphics.Insets; +import androidx.core.view.ViewCompat; +import androidx.core.view.WindowInsetsCompat; +import androidx.viewpager.widget.ViewPager; + +import com.google.android.material.tabs.TabLayout; +import com.utopiaindustries.hseobservationsapp.R; +import com.utopiaindustries.hseobservationsapp.adapters.PagerAdapter; + +public class DashboardActivity extends AppCompatActivity { + + TabLayout tabLayout; + ViewPager viewPager; + + PagerAdapter pagerAdapter; + + ImageView imgLogout; + ImageView img_back; + + public int[] tabIcons = { + R.drawable.icon_tab_home, + R.drawable.icon_tab_drafts + }; + + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + EdgeToEdge.enable(this); + setContentView(R.layout.activity_dashboard); + ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main), (v, insets) -> { + Insets systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars()); + v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom); + return insets; + }); + + initializeLayout(); + + imgLogout.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + alertLogOut(DashboardActivity.this); + } + }); + + img_back.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + if (getSupportFragmentManager().getBackStackEntryCount() > 0) { + getSupportFragmentManager().popBackStack(); // Go back to the previous fragment + } else { + finish(); + } + } + }); + + } + + public void initializeLayout() { + img_back = findViewById(R.id.img_back); + imgLogout = findViewById(R.id.img_logout); + + viewPager = (ViewPager) findViewById(R.id.viewpager); + pagerAdapter = new PagerAdapter(getSupportFragmentManager(), DashboardActivity.this); + viewPager.setAdapter(pagerAdapter); + + tabLayout = (TabLayout) findViewById(R.id.tab_layout); + tabLayout.setupWithViewPager(viewPager); + + tabLayout.getTabAt(0).setIcon(tabIcons[0]); + tabLayout.getTabAt(1).setIcon(tabIcons[1]); + + for (int i = 0; i < tabLayout.getTabCount(); i++) { + TabLayout.Tab tab = tabLayout.getTabAt(i); + tab.setCustomView(pagerAdapter.getTabView(i)); + } + } + + public void alertLogOut(Context con) { + ViewGroup viewGroup = findViewById(android.R.id.content); + + TextView dialogOkBtn, dialogCancelBtn; + + AlertDialog.Builder builder = new AlertDialog.Builder(con); + View view1 = LayoutInflater.from(con).inflate(R.layout.custom_layout_for_logout, viewGroup, false); + builder.setCancelable(false); + builder.setView(view1); + + dialogOkBtn = view1.findViewById(R.id.dialogOkBtn); + dialogCancelBtn = view1.findViewById(R.id.dialogCancelBtn); + + AlertDialog alertDialog = builder.create(); + alertDialog.getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT)); + + dialogOkBtn.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + + alertDialog.dismiss(); + + finish(); + Intent i = new Intent(DashboardActivity.this, LoginActivity.class); + i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK); + startActivity(i); + overridePendingTransition(R.anim.slide_in_right, R.anim.slide_out_left); + + } + }); + + dialogCancelBtn.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + + alertDialog.dismiss(); + //Toast.makeText(con, "Cancel", Toast.LENGTH_SHORT).show(); + + } + }); + + alertDialog.show(); + } +} \ No newline at end of file diff --git a/app/src/main/java/com/utopiaindustries/hseobservationsapp/activities/LoginActivity.java b/app/src/main/java/com/utopiaindustries/hseobservationsapp/activities/LoginActivity.java new file mode 100644 index 0000000..1988d11 --- /dev/null +++ b/app/src/main/java/com/utopiaindustries/hseobservationsapp/activities/LoginActivity.java @@ -0,0 +1,162 @@ +package com.utopiaindustries.hseobservationsapp.activities; + +import android.content.Intent; +import android.os.Bundle; +import android.widget.Button; +import android.widget.EditText; +import android.widget.Toast; + +import androidx.activity.EdgeToEdge; +import androidx.appcompat.app.AppCompatActivity; +import androidx.core.graphics.Insets; +import androidx.core.view.ViewCompat; +import androidx.core.view.WindowInsetsCompat; +import androidx.lifecycle.ViewModelProvider; + +import com.utopiaindustries.hseobservationsapp.R; +import com.utopiaindustries.hseobservationsapp.apiservice.ApiService; +import com.utopiaindustries.hseobservationsapp.apiservice.ApiServiceFactory; +import com.utopiaindustries.hseobservationsapp.helper.Helper; +import com.utopiaindustries.hseobservationsapp.helper.Preference; +import com.utopiaindustries.hseobservationsapp.utils.ProgressDialogFragment; +import com.utopiaindustries.hseobservationsapp.viewmodels.LoginViewModel; + +public class LoginActivity extends AppCompatActivity { + + EditText tfEmail, tfPassword; + Button btnLogin; + LoginViewModel loginViewModel; + ApiService apiService; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + EdgeToEdge.enable(this); + setContentView(R.layout.activity_login); + ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main), (v, insets) -> { + Insets systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars()); + v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom); + return insets; + }); + + if (!Helper.isNetworkConnected(this)) { + Toast.makeText(this, "No Internet Connection", Toast.LENGTH_LONG).show(); + } + + initializeLayout(); + + btnLogin.setOnClickListener(v -> { + if (isValidate()) { + /*loginViewModel.isUserAuthenticated(tfEmail.getText().toString().trim(), + tfPassword.getText().toString(), + new String[]{"ROLE_UIM_QC_APP_ACCESS_YES"});*/ + + Preference.setMyBooleanPref(Helper.project_file, "isLoggedIn", getApplicationContext(), true); + Preference.setMyStringPref(Helper.project_file,Helper.logInUser,this,tfEmail.getText().toString()); + + Intent intent = new Intent(this, DashboardActivity.class); + startActivity(intent); + overridePendingTransition(R.anim.slide_in_right, R.anim.slide_out_left); + finish(); + } + }); + } + + public void initializeLayout() { + tfEmail = findViewById(R.id.tf_email); + tfPassword = findViewById(R.id.tf_password); + btnLogin = findViewById(R.id.btn_login); + apiService = ApiServiceFactory.getApiService(); + + //tfEmail.setText("adnan.niaz"); + //tfPassword.setText("Utopia01"); + + loginViewModel = new ViewModelProvider(this).get(LoginViewModel.class); + + loginViewModel.getLoadingState().observe(this, isLoading -> { + if (isLoading != null && isLoading) { + showProgressDialog(); + } else { + dismissProgressDialog(); + } + }); + + loginViewModel.getErrorMessage().observe(this, errorResponse -> { + if (errorResponse.isEmpty()) { + Toast.makeText(this, "Something went wrong", Toast.LENGTH_SHORT).show(); + } else { + Toast.makeText(this, errorResponse, Toast.LENGTH_SHORT).show(); + } + + }); + + loginViewModel.getLoginUser().observe(this, loginUser -> { + if (loginUser) { + Preference.setMyBooleanPref(Helper.project_file, "isLoggedIn", getApplicationContext(), true); + Preference.setMyStringPref(Helper.project_file,Helper.logInUser,this,tfEmail.getText().toString()); + + Intent intent = new Intent(this, DashboardActivity.class); + startActivity(intent); + overridePendingTransition(R.anim.slide_in_right, R.anim.slide_out_left); + finish(); + } + else { + Toast.makeText(this, "Login Failed", Toast.LENGTH_SHORT).show(); + } + }); + + /*loginViewModel.getUserLiveData().observe(this, user -> { + if (user != null) { + Preference.setMyBooleanPref(Helper.project_file, "isLoggedIn", getApplicationContext(), true); + Helper.setPreferenceObject(getApplicationContext(), user, "DriverResponse"); + + //Toast.makeText(this, "Welcome " + user.getTruckerName(), Toast.LENGTH_SHORT).show(); + Intent intent = new Intent(this, HomeActivity.class); + startActivity(intent); + overridePendingTransition(R.anim.slide_in_right, R.anim.slide_out_left); + finish(); + } else { + Toast.makeText(this, "Login Failed", Toast.LENGTH_SHORT).show(); + } + });*/ + } + + public boolean isValidate() { + boolean returnValue = true; + String message = ""; + + if (tfPassword.getText().toString().isEmpty()) { + message = "Please enter password."; + returnValue = false; + } + + /*if (!Helper.isValidEmail(tfEmail.getText().toString())) { + message = "Please enter valid email."; + returnValue = false; + }*/ + + if (tfEmail.getText().toString().isEmpty()) { + message = "Please enter user name."; + returnValue = false; + } + + if (!returnValue) { + Toast.makeText(this, message, Toast.LENGTH_SHORT).show(); + } + + return returnValue; + } + + public void showProgressDialog() { + ProgressDialogFragment progressDialog = new ProgressDialogFragment(); + progressDialog.setCancelable(false); + progressDialog.show(getSupportFragmentManager(), "progressDialog"); + } + + public void dismissProgressDialog() { + ProgressDialogFragment progressDialog = (ProgressDialogFragment) getSupportFragmentManager().findFragmentByTag("progressDialog"); + if (progressDialog != null) { + progressDialog.dismiss(); + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/utopiaindustries/hseobservationsapp/adapters/PagerAdapter.java b/app/src/main/java/com/utopiaindustries/hseobservationsapp/adapters/PagerAdapter.java new file mode 100644 index 0000000..fd34374 --- /dev/null +++ b/app/src/main/java/com/utopiaindustries/hseobservationsapp/adapters/PagerAdapter.java @@ -0,0 +1,71 @@ +package com.utopiaindustries.hseobservationsapp.adapters; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.widget.ImageView; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; +import androidx.fragment.app.FragmentManager; +import androidx.fragment.app.FragmentStatePagerAdapter; + +import com.utopiaindustries.hseobservationsapp.R; +import com.utopiaindustries.hseobservationsapp.fragments.DraftFragment; +import com.utopiaindustries.hseobservationsapp.fragments.HomeFragment; + +@SuppressWarnings("deprecation") +public class PagerAdapter extends FragmentStatePagerAdapter { + + String tabTitles[] = new String[]{"Home", "Draft"}; + Context context; + + public PagerAdapter(FragmentManager fm, Context context) { + super(fm, BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT); + this.context = context; + } + + public int[] tabIcons = { + R.drawable.icon_tab_home, + R.drawable.icon_tab_drafts + }; + + @Override + public int getCount() { + return tabTitles.length; + } + + @NonNull + @Override + public Fragment getItem(int position) { + + switch (position) { + case 0: + return new HomeFragment(); + case 1: + return new DraftFragment(); + } + return null; + } + + @Override + public CharSequence getPageTitle(int position) { + // Generate title based on item position + // return tabTitles[position]; + return null; + } + + public View getTabView(int position) { + View tab = LayoutInflater.from(context).inflate(R.layout.custom_tab, null); + + TextView tv = (TextView) tab.findViewById(R.id.txt_name); + ImageView imgView = (ImageView) tab.findViewById(R.id.imgView); + tv.setText(tabTitles[position]); + imgView.setBackgroundResource(tabIcons[position]); + + // tv.setTextSize(TypedValue.COMPLEX_UNIT_SP, context.getResources().getDimension(R.dimen.tab_text_size)); + + return tab; + } +} diff --git a/app/src/main/java/com/utopiaindustries/hseobservationsapp/apiservice/ApiService.java b/app/src/main/java/com/utopiaindustries/hseobservationsapp/apiservice/ApiService.java new file mode 100644 index 0000000..9e1c32d --- /dev/null +++ b/app/src/main/java/com/utopiaindustries/hseobservationsapp/apiservice/ApiService.java @@ -0,0 +1,35 @@ +package com.utopiaindustries.hseobservationsapp.apiservice; + +import com.utopiaindustries.hseobservationsapp.models.QualityControl; +import com.utopiaindustries.hseobservationsapp.models.QualityControlResponse; +import com.utopiaindustries.hseobservationsapp.models.QualitySaveResponse; + +import retrofit2.Call; +import retrofit2.http.Body; +import retrofit2.http.GET; +import retrofit2.http.POST; +import retrofit2.http.Query; + +public interface ApiService { + + /*@GET("rest/uic/inspection-report") + Call> fetchAllReports( + @Query("username") String username + );*/ + + @GET("rest/uic/quality-control/get-quality-control-data") + Call getQualityControlData(); + + + @POST("rest/uic/quality-control/save-quality-control") + Call saveQualityControlReport( + @Body QualityControl request + ); + + @POST("rest/authentication/authenticate-user") + Call isUserAuthenticated( + @Query("username") String username, + @Query("password") String password, + @Query("roles") String[] roles + ); +} diff --git a/app/src/main/java/com/utopiaindustries/hseobservationsapp/apiservice/ApiServiceFactory.java b/app/src/main/java/com/utopiaindustries/hseobservationsapp/apiservice/ApiServiceFactory.java new file mode 100644 index 0000000..d5bbef2 --- /dev/null +++ b/app/src/main/java/com/utopiaindustries/hseobservationsapp/apiservice/ApiServiceFactory.java @@ -0,0 +1,17 @@ +package com.utopiaindustries.hseobservationsapp.apiservice; + +import retrofit2.Retrofit; + +public class ApiServiceFactory { + + private static ApiService apiService; + + public synchronized static ApiService getApiService() { + if ( apiService == null ) { + Retrofit retrofit = RetrofitClient.getClient(); + apiService = retrofit.create( ApiService.class ); + } + return apiService; + } + +} diff --git a/app/src/main/java/com/utopiaindustries/hseobservationsapp/apiservice/RetrofitClient.java b/app/src/main/java/com/utopiaindustries/hseobservationsapp/apiservice/RetrofitClient.java new file mode 100644 index 0000000..573d3d8 --- /dev/null +++ b/app/src/main/java/com/utopiaindustries/hseobservationsapp/apiservice/RetrofitClient.java @@ -0,0 +1,49 @@ +package com.utopiaindustries.hseobservationsapp.apiservice; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; + +import java.util.concurrent.TimeUnit; + +import okhttp3.OkHttpClient; +import retrofit2.Retrofit; +import retrofit2.converter.gson.GsonConverterFactory; + +public class RetrofitClient { + + //Live url + //private final static String BASE_URL = "https://portal.utopiaindustries.pk/uind/"; + + //Test Url + private final static String BASE_URL = "http://192.168.91.44:8081/uind/"; + + private static Retrofit retrofit; + + public synchronized static Retrofit getClient() { + + Gson gson = new GsonBuilder() + //.registerTypeAdapter(Boolean.class, new BooleanTypeAdapter()) + .create(); + + + if (retrofit == null) { + try { + + OkHttpClient okHttpClient = new OkHttpClient.Builder() + .connectTimeout(40, TimeUnit.SECONDS) + .readTimeout(40, TimeUnit.SECONDS) + .writeTimeout(40, TimeUnit.SECONDS) + .build(); + + retrofit = new Retrofit.Builder() + .baseUrl(BASE_URL) + .client(okHttpClient) + .addConverterFactory(GsonConverterFactory.create(gson)) + .build(); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + return retrofit; + } +} diff --git a/app/src/main/java/com/utopiaindustries/hseobservationsapp/fragments/DraftFragment.java b/app/src/main/java/com/utopiaindustries/hseobservationsapp/fragments/DraftFragment.java new file mode 100644 index 0000000..f886a5d --- /dev/null +++ b/app/src/main/java/com/utopiaindustries/hseobservationsapp/fragments/DraftFragment.java @@ -0,0 +1,27 @@ +package com.utopiaindustries.hseobservationsapp.fragments; + +import android.os.Bundle; + +import androidx.annotation.Nullable; +import androidx.fragment.app.Fragment; + +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import com.utopiaindustries.hseobservationsapp.R; + +public class DraftFragment extends Fragment { + + @Override + public void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + } + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + // Inflate the layout for this fragment + return inflater.inflate(R.layout.fragment_draft, container, false); + } +} \ No newline at end of file diff --git a/app/src/main/java/com/utopiaindustries/hseobservationsapp/fragments/HomeFragment.java b/app/src/main/java/com/utopiaindustries/hseobservationsapp/fragments/HomeFragment.java new file mode 100644 index 0000000..84dc442 --- /dev/null +++ b/app/src/main/java/com/utopiaindustries/hseobservationsapp/fragments/HomeFragment.java @@ -0,0 +1,27 @@ +package com.utopiaindustries.hseobservationsapp.fragments; + +import android.os.Bundle; + +import androidx.annotation.Nullable; +import androidx.fragment.app.Fragment; + +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import com.utopiaindustries.hseobservationsapp.R; + +public class HomeFragment extends Fragment { + + @Override + public void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + } + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + // Inflate the layout for this fragment + return inflater.inflate(R.layout.fragment_home, container, false); + } +} \ No newline at end of file diff --git a/app/src/main/java/com/utopiaindustries/hseobservationsapp/helper/Helper.java b/app/src/main/java/com/utopiaindustries/hseobservationsapp/helper/Helper.java new file mode 100644 index 0000000..a015470 --- /dev/null +++ b/app/src/main/java/com/utopiaindustries/hseobservationsapp/helper/Helper.java @@ -0,0 +1,127 @@ +package com.utopiaindustries.hseobservationsapp.helper; + +import android.content.Context; +import android.content.SharedPreferences; +import android.net.ConnectivityManager; +import android.net.NetworkInfo; +import android.text.TextUtils; +import android.util.Log; + +import androidx.preference.PreferenceManager; + +import com.google.gson.Gson; +import com.google.gson.reflect.TypeToken; + +import java.lang.reflect.Type; +import java.util.ArrayList; +import java.util.List; + +public class Helper { + + public static final String project_file = "Quality-Control"; + + public static final String departmentId = "departId"; + public static final String departmentName = "departName"; + public static final String locationSiteId = "locationSiteId"; + public static final String locationSiteName = "locationSiteName"; + public static final String unitId = "unitId"; + public static final String unitName = "unitName"; + public static final String floorId = "floorId"; + public static final String floorName = "floorName"; + + public static final String logInUser = "LogInUser"; + + public static boolean isValidEmail(CharSequence target) { + return !TextUtils.isEmpty(target) && android.util.Patterns.EMAIL_ADDRESS.matcher(target).matches(); + } + + public static boolean isNetworkConnected(Context context) { + ConnectivityManager connectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); + NetworkInfo activeNetwork = connectivityManager.getActiveNetworkInfo(); + return activeNetwork != null && activeNetwork.isConnectedOrConnecting(); + } + + static public void setPreferenceObject(Context c, Object modal, String key) { + + SharedPreferences appSharedPrefs = PreferenceManager.getDefaultSharedPreferences(c.getApplicationContext()); + SharedPreferences.Editor prefsEditor = appSharedPrefs.edit(); + + Gson gson = new Gson(); + String jsonObject = gson.toJson(modal); + prefsEditor.putString(key, jsonObject); + prefsEditor.commit(); + } + + /*static public QualityControlResponse getPreferenceObjectJson(Context c, String key) { + + SharedPreferences appSharedPrefs = PreferenceManager.getDefaultSharedPreferences(c.getApplicationContext()); + + String json = appSharedPrefs.getString(key, ""); + Gson gson = new Gson(); + QualityControlResponse selectedUser = gson.fromJson(json, QualityControlResponse.class); + return selectedUser; + }*/ + + /*static public void saveArrayList(List list, String key, Context context){ + SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context); + SharedPreferences.Editor editor = prefs.edit(); + Gson gson = new Gson(); + String json = gson.toJson(list); + editor.putString(key, json); + editor.apply(); + + }*/ + + /*static public List getArrayList(String key, Context context){ + SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context); + + // Check if the key exists + if (!prefs.contains(key)) { + return null; // Return null if the key doesn't exist + } + + Gson gson = new Gson(); + String json = prefs.getString(key, null); + Type type = new TypeToken>() {}.getType(); + return gson.fromJson(json, type); + }*/ + + static public void RemoveArrayList(String key, Context context) { + if (context != null) { + SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context); + if (prefs.contains(key)) { // Check if the key exists + SharedPreferences.Editor editor = prefs.edit(); + editor.remove(key); // Remove the key-value pair + editor.apply(); // Apply changes + ///Log.e("SharedPreferences", "Key '" + key + "' removed successfully."); + } else { + Log.e("SharedPreferences", "Key '" + key + "' does not exist."); + } + } + + } + + //for department, site, unit, floor + public static void saveList(List list, String key, Context context) { + SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context); + SharedPreferences.Editor editor = prefs.edit(); + Gson gson = new Gson(); + String json = gson.toJson(list); // Convert the list to JSON + editor.putString(key, json); + editor.apply(); // Save to SharedPreferences + } + + public static List getList(String key, Context context, Class clazz) { + SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context); + + // Check if the key exists + if (!prefs.contains(key)) { + return new ArrayList<>(); // Return an empty list if the key doesn't exist + } + + Gson gson = new Gson(); + String json = prefs.getString(key, null); + Type type = TypeToken.getParameterized(ArrayList.class, clazz).getType(); // Use the provided class type + return gson.fromJson(json, type); // Convert JSON back to the list + } +} diff --git a/app/src/main/java/com/utopiaindustries/hseobservationsapp/helper/Preference.java b/app/src/main/java/com/utopiaindustries/hseobservationsapp/helper/Preference.java new file mode 100644 index 0000000..45deab4 --- /dev/null +++ b/app/src/main/java/com/utopiaindustries/hseobservationsapp/helper/Preference.java @@ -0,0 +1,82 @@ +package com.utopiaindustries.hseobservationsapp.helper; + +import android.content.Context; +import android.content.SharedPreferences; + +public class Preference { + + private static final int PREFERENCE_MODE_PRIVATE = 0; + private static String MY_STRING_PREF = "mystringpref"; + public static String LOGIN_FILE = "login_prefs"; + public static String TEMP_FILE = "temp_prefs"; + + + public static String KEY_PIN_CODE = "pin_code"; + + public static String KEY_CUSTOMER_ID = "cus_id"; + public static String KEY_CUSTOMER_NAME = "cus_name"; + + public static String KEY_USER_IS_MASTER = "user_is_master"; + + public static SharedPreferences getPrefs(String nameOfFile, Context context) { + + return context.getSharedPreferences(nameOfFile, Context.MODE_PRIVATE); + } + + public static boolean containsKey(String fileName, String key, Context context) { + return getPrefs(fileName, context).contains(key); + } + + public static String getMyStringPref(String fileName, String key, Context context) { + + return getPrefs(fileName,context).getString(key, "default"); + } + public static boolean getMyBooleanPref(String fileName, String key, Context context) { + + return getPrefs(fileName,context).getBoolean(key,false); + } + public static int getMyIntPref(String fileName, String key, Context context) { + + return getPrefs(fileName,context).getInt(key, 0); + } + + public static long getMyLongPref(String fileName, String key, Context context) { + + return getPrefs(fileName,context).getLong(key, 0); + } + + public static void setMyLongPref(String fileName, String key, Context context, long value) { + // perform validation etc.. + getPrefs(fileName,context).edit().putLong(key, value).apply(); + } + + public static void setMyStringPref(String fileName, String key, Context context, String value) { + // perform validation etc.. + getPrefs(fileName,context).edit().putString(key, value).apply(); + } + + public static void setMyBooleanPref(String fileName, String key, Context context, boolean value) { + // perform validation etc.. + getPrefs(fileName,context).edit().putBoolean(key, value).apply(); + } + + public static void setMyIntPref(String fileName, String key, Context context, int value) { + // perform validation etc.. + getPrefs(fileName,context).edit().putInt(key, value).apply(); + } + + + public static void remove(String fileName, String key, Context context) { + // perform validation etc.. + if (context != null) { + if (getPrefs(fileName,context).contains(key)) { + getPrefs(fileName,context).edit().remove(key).apply(); + } + } + + } + public static void removeAll(String fileName, Context context) { + // perform validation etc.. + getPrefs(fileName,context).edit().clear().apply(); + } +} diff --git a/app/src/main/java/com/utopiaindustries/hseobservationsapp/models/Department.java b/app/src/main/java/com/utopiaindustries/hseobservationsapp/models/Department.java new file mode 100644 index 0000000..719521e --- /dev/null +++ b/app/src/main/java/com/utopiaindustries/hseobservationsapp/models/Department.java @@ -0,0 +1,177 @@ + +package com.utopiaindustries.hseobservationsapp.models; + +import com.google.gson.annotations.Expose; +import com.google.gson.annotations.SerializedName; + +import java.util.List; + +public class Department { + + @SerializedName("id") + @Expose + private Integer id; + @SerializedName("companyId") + @Expose + private Integer companyId; + @SerializedName("functionId") + @Expose + private Integer functionId; + @SerializedName("title") + @Expose + private String title; + @SerializedName("organization") + @Expose + private String organization; + @SerializedName("code") + @Expose + private Integer code; + @SerializedName("email") + @Expose + private Object email; + @SerializedName("isActive") + @Expose + private Boolean isActive; + @SerializedName("sections") + @Expose + private Object sections; + @SerializedName("hierarchyString") + @Expose + private Object hierarchyString; + @SerializedName("costCenters") + @Expose + private Object costCenters; + @SerializedName("locationSites") + @Expose + private Object locationSites; + @SerializedName("departmentLocationSites") + @Expose + private Object departmentLocationSites; + @SerializedName("utilitySubMeterDepartments") + @Expose + private List utilitySubMeterDepartments; + @SerializedName("capitalizedTitle") + @Expose + private String capitalizedTitle; + + public Integer getId() { + return id; + } + + public void setId(Integer id) { + this.id = id; + } + + public Integer getCompanyId() { + return companyId; + } + + public void setCompanyId(Integer companyId) { + this.companyId = companyId; + } + + public Integer getFunctionId() { + return functionId; + } + + public void setFunctionId(Integer functionId) { + this.functionId = functionId; + } + + public String getTitle() { + return title; + } + + public void setTitle(String title) { + this.title = title; + } + + public String getOrganization() { + return organization; + } + + public void setOrganization(String organization) { + this.organization = organization; + } + + public Integer getCode() { + return code; + } + + public void setCode(Integer code) { + this.code = code; + } + + public Object getEmail() { + return email; + } + + public void setEmail(Object email) { + this.email = email; + } + + public Boolean getIsActive() { + return isActive; + } + + public void setIsActive(Boolean isActive) { + this.isActive = isActive; + } + + public Object getSections() { + return sections; + } + + public void setSections(Object sections) { + this.sections = sections; + } + + public Object getHierarchyString() { + return hierarchyString; + } + + public void setHierarchyString(Object hierarchyString) { + this.hierarchyString = hierarchyString; + } + + public Object getCostCenters() { + return costCenters; + } + + public void setCostCenters(Object costCenters) { + this.costCenters = costCenters; + } + + public Object getLocationSites() { + return locationSites; + } + + public void setLocationSites(Object locationSites) { + this.locationSites = locationSites; + } + + public Object getDepartmentLocationSites() { + return departmentLocationSites; + } + + public void setDepartmentLocationSites(Object departmentLocationSites) { + this.departmentLocationSites = departmentLocationSites; + } + + public List getUtilitySubMeterDepartments() { + return utilitySubMeterDepartments; + } + + public void setUtilitySubMeterDepartments(List utilitySubMeterDepartments) { + this.utilitySubMeterDepartments = utilitySubMeterDepartments; + } + + public String getCapitalizedTitle() { + return capitalizedTitle; + } + + public void setCapitalizedTitle(String capitalizedTitle) { + this.capitalizedTitle = capitalizedTitle; + } + +} diff --git a/app/src/main/java/com/utopiaindustries/hseobservationsapp/models/Item.java b/app/src/main/java/com/utopiaindustries/hseobservationsapp/models/Item.java new file mode 100644 index 0000000..49002bd --- /dev/null +++ b/app/src/main/java/com/utopiaindustries/hseobservationsapp/models/Item.java @@ -0,0 +1,24 @@ +package com.utopiaindustries.hseobservationsapp.models; + +public class Item { + + private final String name; + private int selectedOption; // Index of the selected dropdown option + + public Item(String name, int selectedOption) { + this.name = name; + this.selectedOption = selectedOption; + } + + public String getName() { + return name; + } + + public int getSelectedOption() { + return selectedOption; + } + + public void setSelectedOption(int selectedOption) { + this.selectedOption = selectedOption; + } +} diff --git a/app/src/main/java/com/utopiaindustries/hseobservationsapp/models/ItemModel.java b/app/src/main/java/com/utopiaindustries/hseobservationsapp/models/ItemModel.java new file mode 100644 index 0000000..b1d7e39 --- /dev/null +++ b/app/src/main/java/com/utopiaindustries/hseobservationsapp/models/ItemModel.java @@ -0,0 +1,93 @@ +package com.utopiaindustries.hseobservationsapp.models; + +import java.util.List; + +public class ItemModel { + + private int processId; + private int stepId; + private double rating; + private String percentage; + private String remarks; + private int selectedOption; + private byte[] imageByteArray; + private List files; + + public ItemModel() { + } + + public ItemModel(int processId, int stepId, double rating, String percentage, String remarks, int selectedOption, byte[] imageByteArray, List imageArrayList) { + this.processId = processId; + this.stepId = stepId; + this.rating = rating; + this.percentage = percentage; + this.remarks = remarks; + this.selectedOption = selectedOption; + this.imageByteArray = imageByteArray; + this.files = imageArrayList; + } + + public int getProcessId() { + return processId; + } + + public void setProcessId(int processId) { + this.processId = processId; + } + + public int getStepId() { + return stepId; + } + + public void setStepId(int stepId) { + this.stepId = stepId; + } + + public String getPercentage() { + return percentage; + } + + public void setPercentage(String percentage) { + this.percentage = percentage; + } + + public String getRemarks() { + return remarks; + } + + public void setRemarks(String remarks) { + this.remarks = remarks; + } + + public int getSelectedOption() { + return selectedOption; + } + + public void setSelectedOption(int selectedOption) { + this.selectedOption = selectedOption; + } + + public double getRating() { + return rating; + } + + public void setRating(double rating) { + this.rating = rating; + } + + public byte[] getImageUri() { + return imageByteArray; + } + + public void setImageUri(byte[] imageUri) { + this.imageByteArray = imageUri; + } + + public List getImageArrayList() { + return files; + } + + public void setImageArrayList(List imageArrayList) { + this.files = imageArrayList; + } +} diff --git a/app/src/main/java/com/utopiaindustries/hseobservationsapp/models/LocationFloor.java b/app/src/main/java/com/utopiaindustries/hseobservationsapp/models/LocationFloor.java new file mode 100644 index 0000000..b642936 --- /dev/null +++ b/app/src/main/java/com/utopiaindustries/hseobservationsapp/models/LocationFloor.java @@ -0,0 +1,69 @@ + +package com.utopiaindustries.hseobservationsapp.models; + +import com.google.gson.annotations.Expose; +import com.google.gson.annotations.SerializedName; + +public class LocationFloor { + + @SerializedName("id") + @Expose + private Integer id; + @SerializedName("title") + @Expose + private String title; + @SerializedName("siteId") + @Expose + private Integer siteId; + @SerializedName("unitId") + @Expose + private Integer unitId; + @SerializedName("stores") + @Expose + private Object stores; + + public Integer getId() { + return id; + } + + public void setId(Integer id) { + this.id = id; + } + + public String getTitle() { + return title; + } + + public void setTitle(String title) { + this.title = title; + } + + public Integer getSiteId() { + return siteId; + } + + public void setSiteId(Integer siteId) { + this.siteId = siteId; + } + + public Integer getUnitId() { + return unitId; + } + + public void setUnitId(Integer unitId) { + this.unitId = unitId; + } + + public Object getStores() { + return stores; + } + + public void setStores(Object stores) { + this.stores = stores; + } + + @Override + public String toString() { + return title; + } +} diff --git a/app/src/main/java/com/utopiaindustries/hseobservationsapp/models/LocationSite.java b/app/src/main/java/com/utopiaindustries/hseobservationsapp/models/LocationSite.java new file mode 100644 index 0000000..79f2bce --- /dev/null +++ b/app/src/main/java/com/utopiaindustries/hseobservationsapp/models/LocationSite.java @@ -0,0 +1,80 @@ + +package com.utopiaindustries.hseobservationsapp.models; + +import com.google.gson.annotations.Expose; +import com.google.gson.annotations.SerializedName; + +public class LocationSite { + + @SerializedName("id") + @Expose + private Integer id; + @SerializedName("title") + @Expose + private String title; + @SerializedName("shortTitle") + @Expose + private String shortTitle; + @SerializedName("address") + @Expose + private String address; + @SerializedName("hasColony") + @Expose + private Boolean hasColony; + @SerializedName("units") + @Expose + private Object units; + + public Integer getId() { + return id; + } + + public void setId(Integer id) { + this.id = id; + } + + public String getTitle() { + return title; + } + + public void setTitle(String title) { + this.title = title; + } + + public String getShortTitle() { + return shortTitle; + } + + public void setShortTitle(String shortTitle) { + this.shortTitle = shortTitle; + } + + public String getAddress() { + return address; + } + + public void setAddress(String address) { + this.address = address; + } + + public Boolean getHasColony() { + return hasColony; + } + + public void setHasColony(Boolean hasColony) { + this.hasColony = hasColony; + } + + public Object getUnits() { + return units; + } + + public void setUnits(Object units) { + this.units = units; + } + + @Override + public String toString() { + return title; + } +} diff --git a/app/src/main/java/com/utopiaindustries/hseobservationsapp/models/LocationUnit.java b/app/src/main/java/com/utopiaindustries/hseobservationsapp/models/LocationUnit.java new file mode 100644 index 0000000..2c5542c --- /dev/null +++ b/app/src/main/java/com/utopiaindustries/hseobservationsapp/models/LocationUnit.java @@ -0,0 +1,59 @@ + +package com.utopiaindustries.hseobservationsapp.models; + +import com.google.gson.annotations.Expose; +import com.google.gson.annotations.SerializedName; + +public class LocationUnit { + + @SerializedName("id") + @Expose + private Integer id; + @SerializedName("title") + @Expose + private String title; + @SerializedName("siteId") + @Expose + private Integer siteId; + @SerializedName("floors") + @Expose + private Object floors; + + public Integer getId() { + return id; + } + + public void setId(Integer id) { + this.id = id; + } + + public String getTitle() { + return title; + } + + public void setTitle(String title) { + this.title = title; + } + + public Integer getSiteId() { + return siteId; + } + + public void setSiteId(Integer siteId) { + this.siteId = siteId; + } + + public Object getFloors() { + return floors; + } + + public void setFloors(Object floors) { + this.floors = floors; + } + + @Override + public String toString() { + return title; + } + +} diff --git a/app/src/main/java/com/utopiaindustries/hseobservationsapp/models/QualityControl.java b/app/src/main/java/com/utopiaindustries/hseobservationsapp/models/QualityControl.java new file mode 100644 index 0000000..a54b79f --- /dev/null +++ b/app/src/main/java/com/utopiaindustries/hseobservationsapp/models/QualityControl.java @@ -0,0 +1,70 @@ +package com.utopiaindustries.hseobservationsapp.models; + +import java.util.List; + +public class QualityControl { + + private String generatedBy; + private int siteId; + private int unitId; + private int departmentId; + private int floorId; + private List qualityControlItemList; + + public QualityControl(String generatedBy, int siteId, int unitId, int departmentId, int floorId, List qualityControlItemList) { + this.generatedBy = generatedBy; + this.siteId = siteId; + this.unitId = unitId; + this.departmentId = departmentId; + this.floorId = floorId; + this.qualityControlItemList = qualityControlItemList; + } + + public String getGeneratedBy() { + return generatedBy; + } + + public void setGeneratedBy(String generatedBy) { + this.generatedBy = generatedBy; + } + + public int getSiteId() { + return siteId; + } + + public void setSiteId(int siteId) { + this.siteId = siteId; + } + + public int getUnitId() { + return unitId; + } + + public void setUnitId(int unitId) { + this.unitId = unitId; + } + + public int getDepartmentId() { + return departmentId; + } + + public void setDepartmentId(int departmentId) { + this.departmentId = departmentId; + } + + public int getFloorId() { + return floorId; + } + + public void setFloorId(int floorId) { + this.floorId = floorId; + } + + public List getQualityControlItemList() { + return qualityControlItemList; + } + + public void setQualityControlItemList(List qualityControlItemList) { + this.qualityControlItemList = qualityControlItemList; + } +} diff --git a/app/src/main/java/com/utopiaindustries/hseobservationsapp/models/QualityControlProcess.java b/app/src/main/java/com/utopiaindustries/hseobservationsapp/models/QualityControlProcess.java new file mode 100644 index 0000000..d8ff836 --- /dev/null +++ b/app/src/main/java/com/utopiaindustries/hseobservationsapp/models/QualityControlProcess.java @@ -0,0 +1,32 @@ + +package com.utopiaindustries.hseobservationsapp.models; + +import com.google.gson.annotations.Expose; +import com.google.gson.annotations.SerializedName; + +public class QualityControlProcess { + + @SerializedName("id") + @Expose + private Integer id; + @SerializedName("name") + @Expose + private String name; + + public Integer getId() { + return id; + } + + public void setId(Integer id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + +} diff --git a/app/src/main/java/com/utopiaindustries/hseobservationsapp/models/QualityControlProcessStep.java b/app/src/main/java/com/utopiaindustries/hseobservationsapp/models/QualityControlProcessStep.java new file mode 100644 index 0000000..e116d3d --- /dev/null +++ b/app/src/main/java/com/utopiaindustries/hseobservationsapp/models/QualityControlProcessStep.java @@ -0,0 +1,43 @@ + +package com.utopiaindustries.hseobservationsapp.models; + +import com.google.gson.annotations.Expose; +import com.google.gson.annotations.SerializedName; + +public class QualityControlProcessStep { + + @SerializedName("id") + @Expose + private Integer id; + @SerializedName("title") + @Expose + private String title; + @SerializedName("description") + @Expose + private String description; + + public Integer getId() { + return id; + } + + public void setId(Integer id) { + this.id = id; + } + + public String getTitle() { + return title; + } + + public void setTitle(String title) { + this.title = title; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + +} diff --git a/app/src/main/java/com/utopiaindustries/hseobservationsapp/models/QualityControlResponse.java b/app/src/main/java/com/utopiaindustries/hseobservationsapp/models/QualityControlResponse.java new file mode 100644 index 0000000..f5d0aca --- /dev/null +++ b/app/src/main/java/com/utopiaindustries/hseobservationsapp/models/QualityControlResponse.java @@ -0,0 +1,77 @@ +package com.utopiaindustries.hseobservationsapp.models; + +import com.google.gson.annotations.Expose; +import com.google.gson.annotations.SerializedName; + +import java.util.List; + +public class QualityControlResponse { + + @SerializedName("locationUnits") + @Expose + private List locationUnits; + @SerializedName("locationFloors") + @Expose + private List locationFloors; + @SerializedName("qualityControlProcessSteps") + @Expose + private List qualityControlProcessSteps; + @SerializedName("locationSites") + @Expose + private List locationSites; + @SerializedName("departments") + @Expose + private List departments; + @SerializedName("qualityControlProcessList") + @Expose + private List qualityControlProcessList; + + public List getLocationUnits() { + return locationUnits; + } + + public void setLocationUnits(List locationUnits) { + this.locationUnits = locationUnits; + } + + + public List getLocationFloors() { + return locationFloors; + } + + public void setLocationFloors(List locationFloors) { + this.locationFloors = locationFloors; + } + + public List getQualityControlProcessSteps() { + return qualityControlProcessSteps; + } + + public void setQualityControlProcessSteps(List qualityControlProcessSteps) { + this.qualityControlProcessSteps = qualityControlProcessSteps; + } + + public List getLocationSites() { + return locationSites; + } + + public void setLocationSites(List locationSites) { + this.locationSites = locationSites; + } + + public List getDepartments() { + return departments; + } + + public void setDepartments(List departments) { + this.departments = departments; + } + + public List getQualityControlProcessList() { + return qualityControlProcessList; + } + + public void setQualityControlProcessList(List qualityControlProcessList) { + this.qualityControlProcessList = qualityControlProcessList; + } +} diff --git a/app/src/main/java/com/utopiaindustries/hseobservationsapp/models/QualitySaveResponse.java b/app/src/main/java/com/utopiaindustries/hseobservationsapp/models/QualitySaveResponse.java new file mode 100644 index 0000000..25f207f --- /dev/null +++ b/app/src/main/java/com/utopiaindustries/hseobservationsapp/models/QualitySaveResponse.java @@ -0,0 +1,117 @@ +package com.utopiaindustries.hseobservationsapp.models; + +import com.google.gson.annotations.Expose; +import com.google.gson.annotations.SerializedName; + +import java.io.Serializable; + +public class QualitySaveResponse implements Serializable { + + @SerializedName("overAllPercentage") + @Expose + private String overAllPercentage; + + @SerializedName("status") + @Expose + private String status; + + @SerializedName("message") + @Expose + private String message; + + @SerializedName("Cutting") + @Expose + private String Cutting; + + @SerializedName("Stiching") + @Expose + private String Stiching; + + @SerializedName("Checking") + @Expose + private String Checking; + + @SerializedName("Packing") + @Expose + private String Packing; + + @SerializedName("Sub Store") + @Expose + private String Sub_Store; + + @SerializedName("code") + @Expose + private String ReportId; + + public String getOverAllPercentage() { + return overAllPercentage; + } + + public void setOverAllPercentage(String overAllPercentage) { + this.overAllPercentage = overAllPercentage; + } + + public String getStatus() { + return status; + } + + public void setStatus(String status) { + this.status = status; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public String getCutting() { + return Cutting; + } + + public void setCutting(String cutting) { + Cutting = cutting; + } + + public String getStiching() { + return Stiching; + } + + public void setStiching(String stiching) { + Stiching = stiching; + } + + public String getChecking() { + return Checking; + } + + public void setChecking(String checking) { + Checking = checking; + } + + public String getPacking() { + return Packing; + } + + public void setPacking(String packing) { + Packing = packing; + } + + public String getSub_Store() { + return Sub_Store; + } + + public void setSub_Store(String sub_Store) { + Sub_Store = sub_Store; + } + + public String getReportId() { + return ReportId; + } + + public void setReportId(String reportId) { + ReportId = reportId; + } +} diff --git a/app/src/main/java/com/utopiaindustries/hseobservationsapp/utils/NonSwipeableViewPager.java b/app/src/main/java/com/utopiaindustries/hseobservationsapp/utils/NonSwipeableViewPager.java new file mode 100644 index 0000000..6bad83f --- /dev/null +++ b/app/src/main/java/com/utopiaindustries/hseobservationsapp/utils/NonSwipeableViewPager.java @@ -0,0 +1,33 @@ +package com.utopiaindustries.hseobservationsapp.utils; + +import android.content.Context; +import android.util.AttributeSet; +import android.view.MotionEvent; + +import androidx.viewpager.widget.ViewPager; + +/** + * Created by Development on 05-Oct-2021. + */ +public class NonSwipeableViewPager extends ViewPager +{ + public NonSwipeableViewPager(Context context) { + super(context); + } + + public NonSwipeableViewPager(Context context, AttributeSet attrs) { + super(context, attrs); + } + + @Override + public boolean onInterceptTouchEvent(MotionEvent event) { + // Never allow swiping to switch between pages + return false; + } + + @Override + public boolean onTouchEvent(MotionEvent event) { + // Never allow swiping to switch between pages + return false; + } +} diff --git a/app/src/main/java/com/utopiaindustries/hseobservationsapp/utils/ProgressDialogFragment.java b/app/src/main/java/com/utopiaindustries/hseobservationsapp/utils/ProgressDialogFragment.java new file mode 100644 index 0000000..286aebc --- /dev/null +++ b/app/src/main/java/com/utopiaindustries/hseobservationsapp/utils/ProgressDialogFragment.java @@ -0,0 +1,37 @@ +package com.utopiaindustries.hseobservationsapp.utils; + +import android.content.DialogInterface; +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.fragment.app.DialogFragment; + +import com.utopiaindustries.hseobservationsapp.R; + +public class ProgressDialogFragment extends DialogFragment { + + @Nullable + @Override + public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + return inflater.inflate(R.layout.dialog_progress, container, false); + } + + @Override + public void onStart() { + super.onStart(); + if (getDialog() != null && getDialog().getWindow() != null) { + getDialog().getWindow().setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT); + getDialog().getWindow().setBackgroundDrawableResource(android.R.color.transparent); + } + } + + @Override + public void onCancel(@NonNull DialogInterface dialog) { + // Prevent the dialog from being canceled when touched outside + setCancelable(false); + } +} diff --git a/app/src/main/java/com/utopiaindustries/hseobservationsapp/viewmodels/LoginViewModel.java b/app/src/main/java/com/utopiaindustries/hseobservationsapp/viewmodels/LoginViewModel.java new file mode 100644 index 0000000..13400ad --- /dev/null +++ b/app/src/main/java/com/utopiaindustries/hseobservationsapp/viewmodels/LoginViewModel.java @@ -0,0 +1,80 @@ +package com.utopiaindustries.hseobservationsapp.viewmodels; + +import androidx.annotation.NonNull; +import androidx.lifecycle.LiveData; +import androidx.lifecycle.MutableLiveData; +import androidx.lifecycle.ViewModel; + +import com.utopiaindustries.hseobservationsapp.apiservice.ApiService; +import com.utopiaindustries.hseobservationsapp.apiservice.ApiServiceFactory; +import com.utopiaindustries.hseobservationsapp.models.QualityControlResponse; + +import retrofit2.Call; +import retrofit2.Callback; +import retrofit2.Response; + +public class LoginViewModel extends ViewModel { + + private MutableLiveData userLiveData; + private MutableLiveData userLoginLiveData; + private MutableLiveData errorLiveData; + private MutableLiveData isLoading; + private ApiService apiService; + + public LoginViewModel() { + apiService = ApiServiceFactory.getApiService(); + userLiveData = new MutableLiveData<>(); + userLoginLiveData = new MutableLiveData<>(); + errorLiveData = new MutableLiveData<>(); + isLoading = new MutableLiveData<>(); + } + + public LiveData getUserLiveData() { + return userLiveData; + } + + public LiveData getLoadingState() { + + return isLoading; + } + + public LiveData getErrorMessage() { + return errorLiveData; + } + + public void isUserAuthenticated(String username, String password, String[] roles) { + isLoading.setValue(true); + apiService.isUserAuthenticated(username, password, roles).enqueue(new Callback() { + @Override + public void onResponse(@NonNull Call call, @NonNull Response response) { + isLoading.setValue(false); + //Log.e("onResponse-1: ", "Successful: "+response); + if (response.isSuccessful() && response.body() != null) { + //Log.e("onResponse-2: ", "Successful: "+response); + userLoginLiveData.setValue(response.body()); + } else { + userLoginLiveData.setValue(false); + } + } + + @Override + public void onFailure(@NonNull Call call, @NonNull Throwable t) { + //Log.e("onResponse-2: ", "failed"+t.getMessage()); + isLoading.setValue(false); + errorLiveData.setValue(t.getMessage()); + } + }); + } + + public LiveData getLoginUser() { + return userLoginLiveData; + } + + public LiveData getUser() { + return userLiveData; + } + + public LiveData getError() { + return errorLiveData; + } +} diff --git a/app/src/main/res/anim/bs_list_layout_fade_in.xml b/app/src/main/res/anim/bs_list_layout_fade_in.xml new file mode 100644 index 0000000..f967280 --- /dev/null +++ b/app/src/main/res/anim/bs_list_layout_fade_in.xml @@ -0,0 +1,6 @@ + + + \ No newline at end of file diff --git a/app/src/main/res/anim/fade_in.xml b/app/src/main/res/anim/fade_in.xml new file mode 100644 index 0000000..e27221b --- /dev/null +++ b/app/src/main/res/anim/fade_in.xml @@ -0,0 +1,11 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/anim/fade_out.xml b/app/src/main/res/anim/fade_out.xml new file mode 100644 index 0000000..4ebd4e2 --- /dev/null +++ b/app/src/main/res/anim/fade_out.xml @@ -0,0 +1,11 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/anim/grow_from_bottom.xml b/app/src/main/res/anim/grow_from_bottom.xml new file mode 100644 index 0000000..be9e03a --- /dev/null +++ b/app/src/main/res/anim/grow_from_bottom.xml @@ -0,0 +1,14 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/anim/grow_from_top.xml b/app/src/main/res/anim/grow_from_top.xml new file mode 100644 index 0000000..16c36e8 --- /dev/null +++ b/app/src/main/res/anim/grow_from_top.xml @@ -0,0 +1,15 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/anim/popup_hide.xml b/app/src/main/res/anim/popup_hide.xml new file mode 100644 index 0000000..e311d4b --- /dev/null +++ b/app/src/main/res/anim/popup_hide.xml @@ -0,0 +1,8 @@ + + + + diff --git a/app/src/main/res/anim/popup_show.xml b/app/src/main/res/anim/popup_show.xml new file mode 100644 index 0000000..d90ef50 --- /dev/null +++ b/app/src/main/res/anim/popup_show.xml @@ -0,0 +1,8 @@ + + + + diff --git a/app/src/main/res/anim/slide_down.xml b/app/src/main/res/anim/slide_down.xml new file mode 100644 index 0000000..be798a9 --- /dev/null +++ b/app/src/main/res/anim/slide_down.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/app/src/main/res/anim/slide_in_bottom.xml b/app/src/main/res/anim/slide_in_bottom.xml new file mode 100644 index 0000000..ae4e011 --- /dev/null +++ b/app/src/main/res/anim/slide_in_bottom.xml @@ -0,0 +1,9 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/anim/slide_in_left.xml b/app/src/main/res/anim/slide_in_left.xml new file mode 100644 index 0000000..44e6eb9 --- /dev/null +++ b/app/src/main/res/anim/slide_in_left.xml @@ -0,0 +1,11 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/anim/slide_in_left_menu.xml b/app/src/main/res/anim/slide_in_left_menu.xml new file mode 100644 index 0000000..bc4f72c --- /dev/null +++ b/app/src/main/res/anim/slide_in_left_menu.xml @@ -0,0 +1,8 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/anim/slide_in_right.xml b/app/src/main/res/anim/slide_in_right.xml new file mode 100644 index 0000000..740308b --- /dev/null +++ b/app/src/main/res/anim/slide_in_right.xml @@ -0,0 +1,11 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/anim/slide_in_right_menu.xml b/app/src/main/res/anim/slide_in_right_menu.xml new file mode 100644 index 0000000..bb153b3 --- /dev/null +++ b/app/src/main/res/anim/slide_in_right_menu.xml @@ -0,0 +1,8 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/anim/slide_in_top.xml b/app/src/main/res/anim/slide_in_top.xml new file mode 100644 index 0000000..a608380 --- /dev/null +++ b/app/src/main/res/anim/slide_in_top.xml @@ -0,0 +1,9 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/anim/slide_out_bottom.xml b/app/src/main/res/anim/slide_out_bottom.xml new file mode 100644 index 0000000..46b3bf1 --- /dev/null +++ b/app/src/main/res/anim/slide_out_bottom.xml @@ -0,0 +1,9 @@ + + + + + + diff --git a/app/src/main/res/anim/slide_out_left.xml b/app/src/main/res/anim/slide_out_left.xml new file mode 100644 index 0000000..4db9289 --- /dev/null +++ b/app/src/main/res/anim/slide_out_left.xml @@ -0,0 +1,11 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/anim/slide_out_right.xml b/app/src/main/res/anim/slide_out_right.xml new file mode 100644 index 0000000..73e7bfc --- /dev/null +++ b/app/src/main/res/anim/slide_out_right.xml @@ -0,0 +1,11 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/anim/slide_out_top.xml b/app/src/main/res/anim/slide_out_top.xml new file mode 100644 index 0000000..6d813cd --- /dev/null +++ b/app/src/main/res/anim/slide_out_top.xml @@ -0,0 +1,9 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/anim/slide_up.xml b/app/src/main/res/anim/slide_up.xml new file mode 100644 index 0000000..57f2be5 --- /dev/null +++ b/app/src/main/res/anim/slide_up.xml @@ -0,0 +1,5 @@ + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/arrow_back.xml b/app/src/main/res/drawable/arrow_back.xml new file mode 100644 index 0000000..7b7c7d0 --- /dev/null +++ b/app/src/main/res/drawable/arrow_back.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/app/src/main/res/drawable/curved_layout.xml b/app/src/main/res/drawable/curved_layout.xml new file mode 100644 index 0000000..0306638 --- /dev/null +++ b/app/src/main/res/drawable/curved_layout.xml @@ -0,0 +1,18 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/custom_button.xml b/app/src/main/res/drawable/custom_button.xml new file mode 100644 index 0000000..151887f --- /dev/null +++ b/app/src/main/res/drawable/custom_button.xml @@ -0,0 +1,9 @@ + + + + + diff --git a/app/src/main/res/drawable/dropdown_item_bg.xml b/app/src/main/res/drawable/dropdown_item_bg.xml new file mode 100644 index 0000000..16b011c --- /dev/null +++ b/app/src/main/res/drawable/dropdown_item_bg.xml @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/et_border.xml b/app/src/main/res/drawable/et_border.xml new file mode 100644 index 0000000..28504f7 --- /dev/null +++ b/app/src/main/res/drawable/et_border.xml @@ -0,0 +1,8 @@ + + + + + diff --git a/app/src/main/res/drawable/et_border_dropdown.xml b/app/src/main/res/drawable/et_border_dropdown.xml new file mode 100644 index 0000000..d8998b5 --- /dev/null +++ b/app/src/main/res/drawable/et_border_dropdown.xml @@ -0,0 +1,8 @@ + + + + + diff --git a/app/src/main/res/drawable/hse.png b/app/src/main/res/drawable/hse.png new file mode 100644 index 0000000000000000000000000000000000000000..10912a0b992720266884573c1f13dd917c023e45 GIT binary patch literal 28631 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 ak2YJ1wKap!_7#+P0I%g#Wl_?m!T$&1l6h + + + + diff --git a/app/src/main/res/drawable/ic_email.xml b/app/src/main/res/drawable/ic_email.xml new file mode 100644 index 0000000..4c104e9 --- /dev/null +++ b/app/src/main/res/drawable/ic_email.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/app/src/main/res/drawable/ic_launcher_background.xml b/app/src/main/res/drawable/ic_launcher_background.xml new file mode 100644 index 0000000..07d5da9 --- /dev/null +++ b/app/src/main/res/drawable/ic_launcher_background.xml @@ -0,0 +1,170 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/drawable/ic_launcher_foreground.xml b/app/src/main/res/drawable/ic_launcher_foreground.xml new file mode 100644 index 0000000..2b068d1 --- /dev/null +++ b/app/src/main/res/drawable/ic_launcher_foreground.xml @@ -0,0 +1,30 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_logout.xml b/app/src/main/res/drawable/ic_logout.xml new file mode 100644 index 0000000..bf421c2 --- /dev/null +++ b/app/src/main/res/drawable/ic_logout.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/app/src/main/res/drawable/ic_password.xml b/app/src/main/res/drawable/ic_password.xml new file mode 100644 index 0000000..1813549 --- /dev/null +++ b/app/src/main/res/drawable/ic_password.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/app/src/main/res/drawable/icon_home.png b/app/src/main/res/drawable/icon_home.png new file mode 100644 index 0000000000000000000000000000000000000000..c81b39a018ca05ff15f69eec482ec36ce997df16 GIT binary patch literal 215 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 mIJn + + + + diff --git a/app/src/main/res/drawable/icon_tab_home.xml b/app/src/main/res/drawable/icon_tab_home.xml new file mode 100644 index 0000000..a1cb4ef --- /dev/null +++ b/app/src/main/res/drawable/icon_tab_home.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/app/src/main/res/drawable/image_picker.xml b/app/src/main/res/drawable/image_picker.xml new file mode 100644 index 0000000..fd890ce --- /dev/null +++ b/app/src/main/res/drawable/image_picker.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/app/src/main/res/drawable/img_load.xml b/app/src/main/res/drawable/img_load.xml new file mode 100644 index 0000000..2102567 --- /dev/null +++ b/app/src/main/res/drawable/img_load.xml @@ -0,0 +1,12 @@ + + + + + diff --git a/app/src/main/res/drawable/rounded_border.xml b/app/src/main/res/drawable/rounded_border.xml new file mode 100644 index 0000000..db35694 --- /dev/null +++ b/app/src/main/res/drawable/rounded_border.xml @@ -0,0 +1,8 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/rounded_btn_login.xml b/app/src/main/res/drawable/rounded_btn_login.xml new file mode 100644 index 0000000..0e174d6 --- /dev/null +++ b/app/src/main/res/drawable/rounded_btn_login.xml @@ -0,0 +1,7 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/rounded_white.xml b/app/src/main/res/drawable/rounded_white.xml new file mode 100644 index 0000000..6072ca7 --- /dev/null +++ b/app/src/main/res/drawable/rounded_white.xml @@ -0,0 +1,13 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/wave_4_.xml b/app/src/main/res/drawable/wave_4_.xml new file mode 100644 index 0000000..01a16b0 --- /dev/null +++ b/app/src/main/res/drawable/wave_4_.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/layout/activity_dashboard.xml b/app/src/main/res/layout/activity_dashboard.xml new file mode 100644 index 0000000..d1ec7fd --- /dev/null +++ b/app/src/main/res/layout/activity_dashboard.xml @@ -0,0 +1,82 @@ + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_login.xml b/app/src/main/res/layout/activity_login.xml new file mode 100644 index 0000000..f91becd --- /dev/null +++ b/app/src/main/res/layout/activity_login.xml @@ -0,0 +1,90 @@ + + + + + + + + + + + + + + + + + + + + + +