From 7db48a7fb26cafbddbf0c91c35487f2e612b0b8e Mon Sep 17 00:00:00 2001 From: SurendarSuri30 Date: Thu, 24 Jul 2025 11:10:07 +0530 Subject: [PATCH] dark/light added --- .../arm64-v8a/configure_fingerprint.bin | 24 +- .../armeabi-v7a/configure_fingerprint.bin | 24 +- .../4y161to1/x86/configure_fingerprint.bin | 24 +- .../4y161to1/x86_64/configure_fingerprint.bin | 24 +- .../arm64-v8a/configure_fingerprint.bin | 24 +- .../armeabi-v7a/configure_fingerprint.bin | 24 +- .../574gs2w4/x86/configure_fingerprint.bin | 24 +- .../574gs2w4/x86_64/configure_fingerprint.bin | 24 +- android/app/build.gradle | 4 +- assets/banners/FCSCLogo_dark.png | Bin 11480 -> 7787 bytes assets/banners/FCSCLogo_dark1.png | Bin 0 -> 11480 bytes assets/banners/FCSCLogo_light.png | Bin 19097 -> 11028 bytes assets/banners/FCSCLogo_light1.png | Bin 0 -> 19097 bytes assets/icons/misc/lock.png | Bin 0 -> 509 bytes assets/icons/misc/person.png | Bin 0 -> 764 bytes assets/icons/misc/signInWithApple.png | Bin 0 -> 319 bytes assets/icons/misc/signInWithGoogle.png | Bin 0 -> 801 bytes assets/icons/misc/signInWithUAEPass.png | Bin 0 -> 1473 bytes assets/icons/misc/vector.png | Bin 557 -> 679 bytes assets/icons/misc/vector1.png | Bin 0 -> 557 bytes ios/Runner.xcodeproj/project.pbxproj | 12 +- .../icons/misc_icon_asset_path.dart | 5 + .../Country_Profile/country_profile.dart | 8 + .../UAE_Numbers/uae_numbers.dart | 27 +- .../auth_verification/create_new_pw.dart | 23 +- .../auth_verification/registration.dart | 90 +- .../Screens/charts/screens/chart_screen.dart | 708 ++++--- lib/presentation/Screens/profilepage.dart | 107 +- .../components/themed_text_field.dart | 14 +- .../routes/auth_routes/login_route.dart | 172 +- .../tab_routes/home_route.dart | 23 +- .../drawer_routes/Drawer Items/bookmark.dart | 422 +++-- .../drawer_routes/Drawer Items/contactUs.dart | 585 +++--- .../Drawer Items/edit_profile.dart | 1665 +++++++++-------- .../drawer_routes/Drawer Items/feedback.dart | 288 ++- .../Drawer Items/manage_users.dart | 137 +- .../notification/notification.dart | 176 +- .../notification/notification_details.dart | 122 +- .../user_guide/AboutTheApp/AboutFCSC.dart | 248 ++- .../user_guide/AboutTheApp/getStarted.dart | 184 +- .../user_guide/KeyFeatures/AppFeatures.dart | 349 +++- .../KeyFeatures/ChangeMyPassword.dart | 698 ++++--- .../user_guide/KeyFeatures/EditMyProfile.dart | 1431 ++++++++------ .../user_guide/KeyFeatures/howUseTheApp.dart | 210 ++- .../user_guide/KeyFeatures/purpose.dart | 181 +- .../user_guide/KeyFeatures/stayUpdate.dart | 134 +- .../user_guide/KeyFeatures/useTheApp.dart | 175 +- .../Drawer Items/user_guide/aboutApp.dart | 150 +- .../Drawer Items/user_guide/faq_page.dart | 929 +++++---- .../Drawer Items/user_guide/features.dart | 193 +- .../Drawer Items/user_guide/userguide.dart | 174 +- .../drawer_routes/custom_drawer_routes.dart | 530 +++--- pubspec.yaml | 4 +- 53 files changed, 6721 insertions(+), 3649 deletions(-) create mode 100644 assets/banners/FCSCLogo_dark1.png create mode 100644 assets/banners/FCSCLogo_light1.png create mode 100644 assets/icons/misc/lock.png create mode 100644 assets/icons/misc/person.png create mode 100644 assets/icons/misc/signInWithApple.png create mode 100644 assets/icons/misc/signInWithGoogle.png create mode 100644 assets/icons/misc/signInWithUAEPass.png create mode 100644 assets/icons/misc/vector1.png diff --git a/android/app/.cxx/Debug/4y161to1/arm64-v8a/configure_fingerprint.bin b/android/app/.cxx/Debug/4y161to1/arm64-v8a/configure_fingerprint.bin index 7888f3a4..58c725fc 100644 --- a/android/app/.cxx/Debug/4y161to1/arm64-v8a/configure_fingerprint.bin +++ b/android/app/.cxx/Debug/4y161to1/arm64-v8a/configure_fingerprint.bin @@ -2,27 +2,27 @@ C/C++ Structured Log} { y/Users/venbateam/Documents/UAE_Stats/FCSC/frontend/android/app/.cxx/Debug/4y161to1/arm64-v8a/additional_project_files.txtC A -?com.android.build.gradle.internal.cxx.io.EncodedFileFingerPrint  2  2z +?com.android.build.gradle.internal.cxx.io.EncodedFileFingerPrint  Ĺ3  2z x -v/Users/venbateam/Documents/UAE_Stats/FCSC/frontend/android/app/.cxx/Debug/4y161to1/arm64-v8a/android_gradle_build.json  2 2 +v/Users/venbateam/Documents/UAE_Stats/FCSC/frontend/android/app/.cxx/Debug/4y161to1/arm64-v8a/android_gradle_build.json  Ĺ3 2 } -{/Users/venbateam/Documents/UAE_Stats/FCSC/frontend/android/app/.cxx/Debug/4y161to1/arm64-v8a/android_gradle_build_mini.json  2 2l +{/Users/venbateam/Documents/UAE_Stats/FCSC/frontend/android/app/.cxx/Debug/4y161to1/arm64-v8a/android_gradle_build_mini.json  Ĺ3 2l j -h/Users/venbateam/Documents/UAE_Stats/FCSC/frontend/android/app/.cxx/Debug/4y161to1/arm64-v8a/build.ninja  2 2p +h/Users/venbateam/Documents/UAE_Stats/FCSC/frontend/android/app/.cxx/Debug/4y161to1/arm64-v8a/build.ninja  Ĺ3 2p n -l/Users/venbateam/Documents/UAE_Stats/FCSC/frontend/android/app/.cxx/Debug/4y161to1/arm64-v8a/build.ninja.txt  2u +l/Users/venbateam/Documents/UAE_Stats/FCSC/frontend/android/app/.cxx/Debug/4y161to1/arm64-v8a/build.ninja.txt  Ĺ3u s -q/Users/venbateam/Documents/UAE_Stats/FCSC/frontend/android/app/.cxx/Debug/4y161to1/arm64-v8a/build_file_index.txt  2 _ 2v +q/Users/venbateam/Documents/UAE_Stats/FCSC/frontend/android/app/.cxx/Debug/4y161to1/arm64-v8a/build_file_index.txt  Ĺ3 _ 2v t -r/Users/venbateam/Documents/UAE_Stats/FCSC/frontend/android/app/.cxx/Debug/4y161to1/arm64-v8a/compile_commands.json  2z +r/Users/venbateam/Documents/UAE_Stats/FCSC/frontend/android/app/.cxx/Debug/4y161to1/arm64-v8a/compile_commands.json  Ĺ3z x -v/Users/venbateam/Documents/UAE_Stats/FCSC/frontend/android/app/.cxx/Debug/4y161to1/arm64-v8a/compile_commands.json.bin  2  +v/Users/venbateam/Documents/UAE_Stats/FCSC/frontend/android/app/.cxx/Debug/4y161to1/arm64-v8a/compile_commands.json.bin  Ĺ3  ~ -|/Users/venbateam/Documents/UAE_Stats/FCSC/frontend/android/app/.cxx/Debug/4y161to1/arm64-v8a/metadata_generation_command.txt  2 +|/Users/venbateam/Documents/UAE_Stats/FCSC/frontend/android/app/.cxx/Debug/4y161to1/arm64-v8a/metadata_generation_command.txt  Ĺ3  2s q -o/Users/venbateam/Documents/UAE_Stats/FCSC/frontend/android/app/.cxx/Debug/4y161to1/arm64-v8a/prefab_config.json  2  ( 2x +o/Users/venbateam/Documents/UAE_Stats/FCSC/frontend/android/app/.cxx/Debug/4y161to1/arm64-v8a/prefab_config.json  Ĺ3  ( 2x v -t/Users/venbateam/Documents/UAE_Stats/FCSC/frontend/android/app/.cxx/Debug/4y161to1/arm64-v8a/symbol_folder_index.txt  2  k 2c +t/Users/venbateam/Documents/UAE_Stats/FCSC/frontend/android/app/.cxx/Debug/4y161to1/arm64-v8a/symbol_folder_index.txt  Ĺ3  k 2c a -_/Users/venbateam/Documents/flutter/packages/flutter_tools/gradle/src/main/groovy/CMakeLists.txt  2  ހ2 \ No newline at end of file +_/Users/venbateam/Documents/flutter/packages/flutter_tools/gradle/src/main/groovy/CMakeLists.txt  Ĺ3  ހ2 \ No newline at end of file diff --git a/android/app/.cxx/Debug/4y161to1/armeabi-v7a/configure_fingerprint.bin b/android/app/.cxx/Debug/4y161to1/armeabi-v7a/configure_fingerprint.bin index 88f59953..63f5ab87 100644 --- a/android/app/.cxx/Debug/4y161to1/armeabi-v7a/configure_fingerprint.bin +++ b/android/app/.cxx/Debug/4y161to1/armeabi-v7a/configure_fingerprint.bin @@ -2,27 +2,27 @@ C/C++ Structured Log } {/Users/venbateam/Documents/UAE_Stats/FCSC/frontend/android/app/.cxx/Debug/4y161to1/armeabi-v7a/additional_project_files.txtC A -?com.android.build.gradle.internal.cxx.io.EncodedFileFingerPrint  2  2| +?com.android.build.gradle.internal.cxx.io.EncodedFileFingerPrint  Ź3  2| z -x/Users/venbateam/Documents/UAE_Stats/FCSC/frontend/android/app/.cxx/Debug/4y161to1/armeabi-v7a/android_gradle_build.json  2 2 +x/Users/venbateam/Documents/UAE_Stats/FCSC/frontend/android/app/.cxx/Debug/4y161to1/armeabi-v7a/android_gradle_build.json  Ź3 2  -}/Users/venbateam/Documents/UAE_Stats/FCSC/frontend/android/app/.cxx/Debug/4y161to1/armeabi-v7a/android_gradle_build_mini.json  2 2n +}/Users/venbateam/Documents/UAE_Stats/FCSC/frontend/android/app/.cxx/Debug/4y161to1/armeabi-v7a/android_gradle_build_mini.json  Ź3 2n l -j/Users/venbateam/Documents/UAE_Stats/FCSC/frontend/android/app/.cxx/Debug/4y161to1/armeabi-v7a/build.ninja  2 2r +j/Users/venbateam/Documents/UAE_Stats/FCSC/frontend/android/app/.cxx/Debug/4y161to1/armeabi-v7a/build.ninja  Ź3 2r p -n/Users/venbateam/Documents/UAE_Stats/FCSC/frontend/android/app/.cxx/Debug/4y161to1/armeabi-v7a/build.ninja.txt  2w +n/Users/venbateam/Documents/UAE_Stats/FCSC/frontend/android/app/.cxx/Debug/4y161to1/armeabi-v7a/build.ninja.txt  Ź3w u -s/Users/venbateam/Documents/UAE_Stats/FCSC/frontend/android/app/.cxx/Debug/4y161to1/armeabi-v7a/build_file_index.txt  2 _ 2x +s/Users/venbateam/Documents/UAE_Stats/FCSC/frontend/android/app/.cxx/Debug/4y161to1/armeabi-v7a/build_file_index.txt  Ź3 _ 2x v -t/Users/venbateam/Documents/UAE_Stats/FCSC/frontend/android/app/.cxx/Debug/4y161to1/armeabi-v7a/compile_commands.json  2| +t/Users/venbateam/Documents/UAE_Stats/FCSC/frontend/android/app/.cxx/Debug/4y161to1/armeabi-v7a/compile_commands.json  Ź3| z -x/Users/venbateam/Documents/UAE_Stats/FCSC/frontend/android/app/.cxx/Debug/4y161to1/armeabi-v7a/compile_commands.json.bin  2  +x/Users/venbateam/Documents/UAE_Stats/FCSC/frontend/android/app/.cxx/Debug/4y161to1/armeabi-v7a/compile_commands.json.bin  Ź3   -~/Users/venbateam/Documents/UAE_Stats/FCSC/frontend/android/app/.cxx/Debug/4y161to1/armeabi-v7a/metadata_generation_command.txt  2 +~/Users/venbateam/Documents/UAE_Stats/FCSC/frontend/android/app/.cxx/Debug/4y161to1/armeabi-v7a/metadata_generation_command.txt  Ź3  2u s -q/Users/venbateam/Documents/UAE_Stats/FCSC/frontend/android/app/.cxx/Debug/4y161to1/armeabi-v7a/prefab_config.json  2  ( 2z +q/Users/venbateam/Documents/UAE_Stats/FCSC/frontend/android/app/.cxx/Debug/4y161to1/armeabi-v7a/prefab_config.json  Ź3  ( 2z x -v/Users/venbateam/Documents/UAE_Stats/FCSC/frontend/android/app/.cxx/Debug/4y161to1/armeabi-v7a/symbol_folder_index.txt  2  m 2c +v/Users/venbateam/Documents/UAE_Stats/FCSC/frontend/android/app/.cxx/Debug/4y161to1/armeabi-v7a/symbol_folder_index.txt  Ź3  m 2c a -_/Users/venbateam/Documents/flutter/packages/flutter_tools/gradle/src/main/groovy/CMakeLists.txt  2  ހ2 \ No newline at end of file +_/Users/venbateam/Documents/flutter/packages/flutter_tools/gradle/src/main/groovy/CMakeLists.txt  Ź3  ހ2 \ No newline at end of file diff --git a/android/app/.cxx/Debug/4y161to1/x86/configure_fingerprint.bin b/android/app/.cxx/Debug/4y161to1/x86/configure_fingerprint.bin index 0854c404..3b0dce56 100644 --- a/android/app/.cxx/Debug/4y161to1/x86/configure_fingerprint.bin +++ b/android/app/.cxx/Debug/4y161to1/x86/configure_fingerprint.bin @@ -2,27 +2,27 @@ C/C++ Structured Logw u s/Users/venbateam/Documents/UAE_Stats/FCSC/frontend/android/app/.cxx/Debug/4y161to1/x86/additional_project_files.txtC A -?com.android.build.gradle.internal.cxx.io.EncodedFileFingerPrint  2  2t +?com.android.build.gradle.internal.cxx.io.EncodedFileFingerPrint  Ź3  2t r -p/Users/venbateam/Documents/UAE_Stats/FCSC/frontend/android/app/.cxx/Debug/4y161to1/x86/android_gradle_build.json  2 2y +p/Users/venbateam/Documents/UAE_Stats/FCSC/frontend/android/app/.cxx/Debug/4y161to1/x86/android_gradle_build.json  Ź3 2y w -u/Users/venbateam/Documents/UAE_Stats/FCSC/frontend/android/app/.cxx/Debug/4y161to1/x86/android_gradle_build_mini.json  2 2f +u/Users/venbateam/Documents/UAE_Stats/FCSC/frontend/android/app/.cxx/Debug/4y161to1/x86/android_gradle_build_mini.json  Ź3 2f d -b/Users/venbateam/Documents/UAE_Stats/FCSC/frontend/android/app/.cxx/Debug/4y161to1/x86/build.ninja  2 2j +b/Users/venbateam/Documents/UAE_Stats/FCSC/frontend/android/app/.cxx/Debug/4y161to1/x86/build.ninja  Ź3 2j h -f/Users/venbateam/Documents/UAE_Stats/FCSC/frontend/android/app/.cxx/Debug/4y161to1/x86/build.ninja.txt  2o +f/Users/venbateam/Documents/UAE_Stats/FCSC/frontend/android/app/.cxx/Debug/4y161to1/x86/build.ninja.txt  Ź3o m -k/Users/venbateam/Documents/UAE_Stats/FCSC/frontend/android/app/.cxx/Debug/4y161to1/x86/build_file_index.txt  2 _ 2p +k/Users/venbateam/Documents/UAE_Stats/FCSC/frontend/android/app/.cxx/Debug/4y161to1/x86/build_file_index.txt  Ź3 _ 2p n -l/Users/venbateam/Documents/UAE_Stats/FCSC/frontend/android/app/.cxx/Debug/4y161to1/x86/compile_commands.json  2t +l/Users/venbateam/Documents/UAE_Stats/FCSC/frontend/android/app/.cxx/Debug/4y161to1/x86/compile_commands.json  Ź3t r -p/Users/venbateam/Documents/UAE_Stats/FCSC/frontend/android/app/.cxx/Debug/4y161to1/x86/compile_commands.json.bin  2 z +p/Users/venbateam/Documents/UAE_Stats/FCSC/frontend/android/app/.cxx/Debug/4y161to1/x86/compile_commands.json.bin  Ź3 z x -v/Users/venbateam/Documents/UAE_Stats/FCSC/frontend/android/app/.cxx/Debug/4y161to1/x86/metadata_generation_command.txt  2 +v/Users/venbateam/Documents/UAE_Stats/FCSC/frontend/android/app/.cxx/Debug/4y161to1/x86/metadata_generation_command.txt  Ź3  2m k -i/Users/venbateam/Documents/UAE_Stats/FCSC/frontend/android/app/.cxx/Debug/4y161to1/x86/prefab_config.json  2  ( 2r +i/Users/venbateam/Documents/UAE_Stats/FCSC/frontend/android/app/.cxx/Debug/4y161to1/x86/prefab_config.json  Ź3  ( 2r p -n/Users/venbateam/Documents/UAE_Stats/FCSC/frontend/android/app/.cxx/Debug/4y161to1/x86/symbol_folder_index.txt  2  e 2c +n/Users/venbateam/Documents/UAE_Stats/FCSC/frontend/android/app/.cxx/Debug/4y161to1/x86/symbol_folder_index.txt  Ź3  e 2c a -_/Users/venbateam/Documents/flutter/packages/flutter_tools/gradle/src/main/groovy/CMakeLists.txt  2  ހ2 \ No newline at end of file +_/Users/venbateam/Documents/flutter/packages/flutter_tools/gradle/src/main/groovy/CMakeLists.txt  Ź3  ހ2 \ No newline at end of file diff --git a/android/app/.cxx/Debug/4y161to1/x86_64/configure_fingerprint.bin b/android/app/.cxx/Debug/4y161to1/x86_64/configure_fingerprint.bin index 6967c255..0f0a9ad9 100644 --- a/android/app/.cxx/Debug/4y161to1/x86_64/configure_fingerprint.bin +++ b/android/app/.cxx/Debug/4y161to1/x86_64/configure_fingerprint.bin @@ -2,27 +2,27 @@ C/C++ Structured Logz x v/Users/venbateam/Documents/UAE_Stats/FCSC/frontend/android/app/.cxx/Debug/4y161to1/x86_64/additional_project_files.txtC A -?com.android.build.gradle.internal.cxx.io.EncodedFileFingerPrint  2  2w +?com.android.build.gradle.internal.cxx.io.EncodedFileFingerPrint  Ź3  2w u -s/Users/venbateam/Documents/UAE_Stats/FCSC/frontend/android/app/.cxx/Debug/4y161to1/x86_64/android_gradle_build.json  2 2| +s/Users/venbateam/Documents/UAE_Stats/FCSC/frontend/android/app/.cxx/Debug/4y161to1/x86_64/android_gradle_build.json  Ź3 2| z -x/Users/venbateam/Documents/UAE_Stats/FCSC/frontend/android/app/.cxx/Debug/4y161to1/x86_64/android_gradle_build_mini.json  2 2i +x/Users/venbateam/Documents/UAE_Stats/FCSC/frontend/android/app/.cxx/Debug/4y161to1/x86_64/android_gradle_build_mini.json  Ź3 2i g -e/Users/venbateam/Documents/UAE_Stats/FCSC/frontend/android/app/.cxx/Debug/4y161to1/x86_64/build.ninja  2 2m +e/Users/venbateam/Documents/UAE_Stats/FCSC/frontend/android/app/.cxx/Debug/4y161to1/x86_64/build.ninja  Ź3 2m k -i/Users/venbateam/Documents/UAE_Stats/FCSC/frontend/android/app/.cxx/Debug/4y161to1/x86_64/build.ninja.txt  2r +i/Users/venbateam/Documents/UAE_Stats/FCSC/frontend/android/app/.cxx/Debug/4y161to1/x86_64/build.ninja.txt  Ź3r p -n/Users/venbateam/Documents/UAE_Stats/FCSC/frontend/android/app/.cxx/Debug/4y161to1/x86_64/build_file_index.txt  2 _ 2s +n/Users/venbateam/Documents/UAE_Stats/FCSC/frontend/android/app/.cxx/Debug/4y161to1/x86_64/build_file_index.txt  Ź3 _ 2s q -o/Users/venbateam/Documents/UAE_Stats/FCSC/frontend/android/app/.cxx/Debug/4y161to1/x86_64/compile_commands.json  2w +o/Users/venbateam/Documents/UAE_Stats/FCSC/frontend/android/app/.cxx/Debug/4y161to1/x86_64/compile_commands.json  Ź3w u -s/Users/venbateam/Documents/UAE_Stats/FCSC/frontend/android/app/.cxx/Debug/4y161to1/x86_64/compile_commands.json.bin  2 } +s/Users/venbateam/Documents/UAE_Stats/FCSC/frontend/android/app/.cxx/Debug/4y161to1/x86_64/compile_commands.json.bin  Ź3 } { -y/Users/venbateam/Documents/UAE_Stats/FCSC/frontend/android/app/.cxx/Debug/4y161to1/x86_64/metadata_generation_command.txt  2 +y/Users/venbateam/Documents/UAE_Stats/FCSC/frontend/android/app/.cxx/Debug/4y161to1/x86_64/metadata_generation_command.txt  Ź3  2p n -l/Users/venbateam/Documents/UAE_Stats/FCSC/frontend/android/app/.cxx/Debug/4y161to1/x86_64/prefab_config.json  2  ( 2u +l/Users/venbateam/Documents/UAE_Stats/FCSC/frontend/android/app/.cxx/Debug/4y161to1/x86_64/prefab_config.json  Ź3  ( 2u s -q/Users/venbateam/Documents/UAE_Stats/FCSC/frontend/android/app/.cxx/Debug/4y161to1/x86_64/symbol_folder_index.txt  2  h 2c +q/Users/venbateam/Documents/UAE_Stats/FCSC/frontend/android/app/.cxx/Debug/4y161to1/x86_64/symbol_folder_index.txt  Ź3  h 2c a -_/Users/venbateam/Documents/flutter/packages/flutter_tools/gradle/src/main/groovy/CMakeLists.txt  2  ހ2 \ No newline at end of file +_/Users/venbateam/Documents/flutter/packages/flutter_tools/gradle/src/main/groovy/CMakeLists.txt  Ź3  ހ2 \ No newline at end of file diff --git a/android/app/.cxx/RelWithDebInfo/574gs2w4/arm64-v8a/configure_fingerprint.bin b/android/app/.cxx/RelWithDebInfo/574gs2w4/arm64-v8a/configure_fingerprint.bin index 60f372c0..fb068f44 100644 --- a/android/app/.cxx/RelWithDebInfo/574gs2w4/arm64-v8a/configure_fingerprint.bin +++ b/android/app/.cxx/RelWithDebInfo/574gs2w4/arm64-v8a/configure_fingerprint.bin @@ -2,27 +2,27 @@ C/C++ Structured Log  /Users/venbateam/Documents/UAE_Stats/FCSC/frontend/android/app/.cxx/RelWithDebInfo/574gs2w4/arm64-v8a/additional_project_files.txtC A -?com.android.build.gradle.internal.cxx.io.EncodedFileFingerPrint  Ă2  ǟ2 +?com.android.build.gradle.internal.cxx.io.EncodedFileFingerPrint  2  ǟ2  -/Users/venbateam/Documents/UAE_Stats/FCSC/frontend/android/app/.cxx/RelWithDebInfo/574gs2w4/arm64-v8a/android_gradle_build.json  Ă2 ǟ2 +/Users/venbateam/Documents/UAE_Stats/FCSC/frontend/android/app/.cxx/RelWithDebInfo/574gs2w4/arm64-v8a/android_gradle_build.json  2 ǟ2  -/Users/venbateam/Documents/UAE_Stats/FCSC/frontend/android/app/.cxx/RelWithDebInfo/574gs2w4/arm64-v8a/android_gradle_build_mini.json  Ă2 ǟ2u +/Users/venbateam/Documents/UAE_Stats/FCSC/frontend/android/app/.cxx/RelWithDebInfo/574gs2w4/arm64-v8a/android_gradle_build_mini.json  2 ǟ2u s -q/Users/venbateam/Documents/UAE_Stats/FCSC/frontend/android/app/.cxx/RelWithDebInfo/574gs2w4/arm64-v8a/build.ninja  Ă2 ǟ2y +q/Users/venbateam/Documents/UAE_Stats/FCSC/frontend/android/app/.cxx/RelWithDebInfo/574gs2w4/arm64-v8a/build.ninja  2 ǟ2y w -u/Users/venbateam/Documents/UAE_Stats/FCSC/frontend/android/app/.cxx/RelWithDebInfo/574gs2w4/arm64-v8a/build.ninja.txt  Ă2~ +u/Users/venbateam/Documents/UAE_Stats/FCSC/frontend/android/app/.cxx/RelWithDebInfo/574gs2w4/arm64-v8a/build.ninja.txt  2~ | -z/Users/venbateam/Documents/UAE_Stats/FCSC/frontend/android/app/.cxx/RelWithDebInfo/574gs2w4/arm64-v8a/build_file_index.txt  Ă2 _ ǟ2 +z/Users/venbateam/Documents/UAE_Stats/FCSC/frontend/android/app/.cxx/RelWithDebInfo/574gs2w4/arm64-v8a/build_file_index.txt  2 _ ǟ2 } -{/Users/venbateam/Documents/UAE_Stats/FCSC/frontend/android/app/.cxx/RelWithDebInfo/574gs2w4/arm64-v8a/compile_commands.json  Ă2 +{/Users/venbateam/Documents/UAE_Stats/FCSC/frontend/android/app/.cxx/RelWithDebInfo/574gs2w4/arm64-v8a/compile_commands.json  2  -/Users/venbateam/Documents/UAE_Stats/FCSC/frontend/android/app/.cxx/RelWithDebInfo/574gs2w4/arm64-v8a/compile_commands.json.bin  Ă2  +/Users/venbateam/Documents/UAE_Stats/FCSC/frontend/android/app/.cxx/RelWithDebInfo/574gs2w4/arm64-v8a/compile_commands.json.bin  2   -/Users/venbateam/Documents/UAE_Stats/FCSC/frontend/android/app/.cxx/RelWithDebInfo/574gs2w4/arm64-v8a/metadata_generation_command.txt  Ă2 +/Users/venbateam/Documents/UAE_Stats/FCSC/frontend/android/app/.cxx/RelWithDebInfo/574gs2w4/arm64-v8a/metadata_generation_command.txt  2  ǟ2| z -x/Users/venbateam/Documents/UAE_Stats/FCSC/frontend/android/app/.cxx/RelWithDebInfo/574gs2w4/arm64-v8a/prefab_config.json  Ă2  ( ǟ2 +x/Users/venbateam/Documents/UAE_Stats/FCSC/frontend/android/app/.cxx/RelWithDebInfo/574gs2w4/arm64-v8a/prefab_config.json  2  ( ǟ2  -}/Users/venbateam/Documents/UAE_Stats/FCSC/frontend/android/app/.cxx/RelWithDebInfo/574gs2w4/arm64-v8a/symbol_folder_index.txt  Ă2  t ǟ2c +}/Users/venbateam/Documents/UAE_Stats/FCSC/frontend/android/app/.cxx/RelWithDebInfo/574gs2w4/arm64-v8a/symbol_folder_index.txt  2  t ǟ2c a -_/Users/venbateam/Documents/flutter/packages/flutter_tools/gradle/src/main/groovy/CMakeLists.txt  Ă2  ހ2 \ No newline at end of file +_/Users/venbateam/Documents/flutter/packages/flutter_tools/gradle/src/main/groovy/CMakeLists.txt  2  ހ2 \ No newline at end of file diff --git a/android/app/.cxx/RelWithDebInfo/574gs2w4/armeabi-v7a/configure_fingerprint.bin b/android/app/.cxx/RelWithDebInfo/574gs2w4/armeabi-v7a/configure_fingerprint.bin index 3ecd5db8..b921d132 100644 --- a/android/app/.cxx/RelWithDebInfo/574gs2w4/armeabi-v7a/configure_fingerprint.bin +++ b/android/app/.cxx/RelWithDebInfo/574gs2w4/armeabi-v7a/configure_fingerprint.bin @@ -2,27 +2,27 @@ C/C++ Structured Log  /Users/venbateam/Documents/UAE_Stats/FCSC/frontend/android/app/.cxx/RelWithDebInfo/574gs2w4/armeabi-v7a/additional_project_files.txtC A -?com.android.build.gradle.internal.cxx.io.EncodedFileFingerPrint  էĂ2  ǟ2 +?com.android.build.gradle.internal.cxx.io.EncodedFileFingerPrint  2  ǟ2  -/Users/venbateam/Documents/UAE_Stats/FCSC/frontend/android/app/.cxx/RelWithDebInfo/574gs2w4/armeabi-v7a/android_gradle_build.json  էĂ2 ǟ2 +/Users/venbateam/Documents/UAE_Stats/FCSC/frontend/android/app/.cxx/RelWithDebInfo/574gs2w4/armeabi-v7a/android_gradle_build.json  2 ǟ2  -/Users/venbateam/Documents/UAE_Stats/FCSC/frontend/android/app/.cxx/RelWithDebInfo/574gs2w4/armeabi-v7a/android_gradle_build_mini.json  էĂ2 ǟ2w +/Users/venbateam/Documents/UAE_Stats/FCSC/frontend/android/app/.cxx/RelWithDebInfo/574gs2w4/armeabi-v7a/android_gradle_build_mini.json  2 ǟ2w u -s/Users/venbateam/Documents/UAE_Stats/FCSC/frontend/android/app/.cxx/RelWithDebInfo/574gs2w4/armeabi-v7a/build.ninja  էĂ2 ǟ2{ +s/Users/venbateam/Documents/UAE_Stats/FCSC/frontend/android/app/.cxx/RelWithDebInfo/574gs2w4/armeabi-v7a/build.ninja  2 ǟ2{ y -w/Users/venbateam/Documents/UAE_Stats/FCSC/frontend/android/app/.cxx/RelWithDebInfo/574gs2w4/armeabi-v7a/build.ninja.txt  էĂ2 +w/Users/venbateam/Documents/UAE_Stats/FCSC/frontend/android/app/.cxx/RelWithDebInfo/574gs2w4/armeabi-v7a/build.ninja.txt  2 ~ -|/Users/venbateam/Documents/UAE_Stats/FCSC/frontend/android/app/.cxx/RelWithDebInfo/574gs2w4/armeabi-v7a/build_file_index.txt  էĂ2 _ ǟ2 +|/Users/venbateam/Documents/UAE_Stats/FCSC/frontend/android/app/.cxx/RelWithDebInfo/574gs2w4/armeabi-v7a/build_file_index.txt  2 _ ǟ2  -}/Users/venbateam/Documents/UAE_Stats/FCSC/frontend/android/app/.cxx/RelWithDebInfo/574gs2w4/armeabi-v7a/compile_commands.json  էĂ2 +}/Users/venbateam/Documents/UAE_Stats/FCSC/frontend/android/app/.cxx/RelWithDebInfo/574gs2w4/armeabi-v7a/compile_commands.json  2  -/Users/venbateam/Documents/UAE_Stats/FCSC/frontend/android/app/.cxx/RelWithDebInfo/574gs2w4/armeabi-v7a/compile_commands.json.bin  էĂ2  +/Users/venbateam/Documents/UAE_Stats/FCSC/frontend/android/app/.cxx/RelWithDebInfo/574gs2w4/armeabi-v7a/compile_commands.json.bin  2   -/Users/venbateam/Documents/UAE_Stats/FCSC/frontend/android/app/.cxx/RelWithDebInfo/574gs2w4/armeabi-v7a/metadata_generation_command.txt  էĂ2 +/Users/venbateam/Documents/UAE_Stats/FCSC/frontend/android/app/.cxx/RelWithDebInfo/574gs2w4/armeabi-v7a/metadata_generation_command.txt  2  ǟ2~ | -z/Users/venbateam/Documents/UAE_Stats/FCSC/frontend/android/app/.cxx/RelWithDebInfo/574gs2w4/armeabi-v7a/prefab_config.json  էĂ2  ( ǟ2 +z/Users/venbateam/Documents/UAE_Stats/FCSC/frontend/android/app/.cxx/RelWithDebInfo/574gs2w4/armeabi-v7a/prefab_config.json  2  ( ǟ2  -/Users/venbateam/Documents/UAE_Stats/FCSC/frontend/android/app/.cxx/RelWithDebInfo/574gs2w4/armeabi-v7a/symbol_folder_index.txt  էĂ2  v ǟ2c +/Users/venbateam/Documents/UAE_Stats/FCSC/frontend/android/app/.cxx/RelWithDebInfo/574gs2w4/armeabi-v7a/symbol_folder_index.txt  2  v ǟ2c a -_/Users/venbateam/Documents/flutter/packages/flutter_tools/gradle/src/main/groovy/CMakeLists.txt  էĂ2  ހ2 \ No newline at end of file +_/Users/venbateam/Documents/flutter/packages/flutter_tools/gradle/src/main/groovy/CMakeLists.txt  2  ހ2 \ No newline at end of file diff --git a/android/app/.cxx/RelWithDebInfo/574gs2w4/x86/configure_fingerprint.bin b/android/app/.cxx/RelWithDebInfo/574gs2w4/x86/configure_fingerprint.bin index 0630bb48..f0625e4b 100644 --- a/android/app/.cxx/RelWithDebInfo/574gs2w4/x86/configure_fingerprint.bin +++ b/android/app/.cxx/RelWithDebInfo/574gs2w4/x86/configure_fingerprint.bin @@ -2,27 +2,27 @@ C/C++ Structured Log ~ |/Users/venbateam/Documents/UAE_Stats/FCSC/frontend/android/app/.cxx/RelWithDebInfo/574gs2w4/x86/additional_project_files.txtC A -?com.android.build.gradle.internal.cxx.io.EncodedFileFingerPrint  ާĂ2  ǟ2} +?com.android.build.gradle.internal.cxx.io.EncodedFileFingerPrint  å2  ǟ2} { -y/Users/venbateam/Documents/UAE_Stats/FCSC/frontend/android/app/.cxx/RelWithDebInfo/574gs2w4/x86/android_gradle_build.json  ާĂ2 ǟ2 +y/Users/venbateam/Documents/UAE_Stats/FCSC/frontend/android/app/.cxx/RelWithDebInfo/574gs2w4/x86/android_gradle_build.json  å2 ǟ2  -~/Users/venbateam/Documents/UAE_Stats/FCSC/frontend/android/app/.cxx/RelWithDebInfo/574gs2w4/x86/android_gradle_build_mini.json  ާĂ2 ǟ2o +~/Users/venbateam/Documents/UAE_Stats/FCSC/frontend/android/app/.cxx/RelWithDebInfo/574gs2w4/x86/android_gradle_build_mini.json  å2 ǟ2o m -k/Users/venbateam/Documents/UAE_Stats/FCSC/frontend/android/app/.cxx/RelWithDebInfo/574gs2w4/x86/build.ninja  ާĂ2 ǟ2s +k/Users/venbateam/Documents/UAE_Stats/FCSC/frontend/android/app/.cxx/RelWithDebInfo/574gs2w4/x86/build.ninja  å2 ǟ2s q -o/Users/venbateam/Documents/UAE_Stats/FCSC/frontend/android/app/.cxx/RelWithDebInfo/574gs2w4/x86/build.ninja.txt  ާĂ2x +o/Users/venbateam/Documents/UAE_Stats/FCSC/frontend/android/app/.cxx/RelWithDebInfo/574gs2w4/x86/build.ninja.txt  å2x v -t/Users/venbateam/Documents/UAE_Stats/FCSC/frontend/android/app/.cxx/RelWithDebInfo/574gs2w4/x86/build_file_index.txt  ާĂ2 _ ǟ2y +t/Users/venbateam/Documents/UAE_Stats/FCSC/frontend/android/app/.cxx/RelWithDebInfo/574gs2w4/x86/build_file_index.txt  å2 _ ǟ2y w -u/Users/venbateam/Documents/UAE_Stats/FCSC/frontend/android/app/.cxx/RelWithDebInfo/574gs2w4/x86/compile_commands.json  ާĂ2} +u/Users/venbateam/Documents/UAE_Stats/FCSC/frontend/android/app/.cxx/RelWithDebInfo/574gs2w4/x86/compile_commands.json  å2} { -y/Users/venbateam/Documents/UAE_Stats/FCSC/frontend/android/app/.cxx/RelWithDebInfo/574gs2w4/x86/compile_commands.json.bin  ާĂ2  +y/Users/venbateam/Documents/UAE_Stats/FCSC/frontend/android/app/.cxx/RelWithDebInfo/574gs2w4/x86/compile_commands.json.bin  å2   -/Users/venbateam/Documents/UAE_Stats/FCSC/frontend/android/app/.cxx/RelWithDebInfo/574gs2w4/x86/metadata_generation_command.txt  ާĂ2 +/Users/venbateam/Documents/UAE_Stats/FCSC/frontend/android/app/.cxx/RelWithDebInfo/574gs2w4/x86/metadata_generation_command.txt  å2  ǟ2v t -r/Users/venbateam/Documents/UAE_Stats/FCSC/frontend/android/app/.cxx/RelWithDebInfo/574gs2w4/x86/prefab_config.json  ާĂ2  ( ǟ2{ +r/Users/venbateam/Documents/UAE_Stats/FCSC/frontend/android/app/.cxx/RelWithDebInfo/574gs2w4/x86/prefab_config.json  å2  ( ǟ2{ y -w/Users/venbateam/Documents/UAE_Stats/FCSC/frontend/android/app/.cxx/RelWithDebInfo/574gs2w4/x86/symbol_folder_index.txt  ާĂ2  n ǟ2c +w/Users/venbateam/Documents/UAE_Stats/FCSC/frontend/android/app/.cxx/RelWithDebInfo/574gs2w4/x86/symbol_folder_index.txt  å2  n ǟ2c a -_/Users/venbateam/Documents/flutter/packages/flutter_tools/gradle/src/main/groovy/CMakeLists.txt  ާĂ2  ހ2 \ No newline at end of file +_/Users/venbateam/Documents/flutter/packages/flutter_tools/gradle/src/main/groovy/CMakeLists.txt  å2  ހ2 \ No newline at end of file diff --git a/android/app/.cxx/RelWithDebInfo/574gs2w4/x86_64/configure_fingerprint.bin b/android/app/.cxx/RelWithDebInfo/574gs2w4/x86_64/configure_fingerprint.bin index ad995a25..4d90eeae 100644 --- a/android/app/.cxx/RelWithDebInfo/574gs2w4/x86_64/configure_fingerprint.bin +++ b/android/app/.cxx/RelWithDebInfo/574gs2w4/x86_64/configure_fingerprint.bin @@ -2,27 +2,27 @@ C/C++ Structured Log  /Users/venbateam/Documents/UAE_Stats/FCSC/frontend/android/app/.cxx/RelWithDebInfo/574gs2w4/x86_64/additional_project_files.txtC A -?com.android.build.gradle.internal.cxx.io.EncodedFileFingerPrint  Ă2  ǟ2 +?com.android.build.gradle.internal.cxx.io.EncodedFileFingerPrint  ʥ2  ǟ2 ~ -|/Users/venbateam/Documents/UAE_Stats/FCSC/frontend/android/app/.cxx/RelWithDebInfo/574gs2w4/x86_64/android_gradle_build.json  Ă2 ǟ2 +|/Users/venbateam/Documents/UAE_Stats/FCSC/frontend/android/app/.cxx/RelWithDebInfo/574gs2w4/x86_64/android_gradle_build.json  ʥ2 ǟ2  -/Users/venbateam/Documents/UAE_Stats/FCSC/frontend/android/app/.cxx/RelWithDebInfo/574gs2w4/x86_64/android_gradle_build_mini.json  Ă2 ǟ2r +/Users/venbateam/Documents/UAE_Stats/FCSC/frontend/android/app/.cxx/RelWithDebInfo/574gs2w4/x86_64/android_gradle_build_mini.json  ʥ2 ǟ2r p -n/Users/venbateam/Documents/UAE_Stats/FCSC/frontend/android/app/.cxx/RelWithDebInfo/574gs2w4/x86_64/build.ninja  Ă2 ǟ2v +n/Users/venbateam/Documents/UAE_Stats/FCSC/frontend/android/app/.cxx/RelWithDebInfo/574gs2w4/x86_64/build.ninja  ʥ2 ǟ2v t -r/Users/venbateam/Documents/UAE_Stats/FCSC/frontend/android/app/.cxx/RelWithDebInfo/574gs2w4/x86_64/build.ninja.txt  Ă2{ +r/Users/venbateam/Documents/UAE_Stats/FCSC/frontend/android/app/.cxx/RelWithDebInfo/574gs2w4/x86_64/build.ninja.txt  ʥ2{ y -w/Users/venbateam/Documents/UAE_Stats/FCSC/frontend/android/app/.cxx/RelWithDebInfo/574gs2w4/x86_64/build_file_index.txt  Ă2 _ ǟ2| +w/Users/venbateam/Documents/UAE_Stats/FCSC/frontend/android/app/.cxx/RelWithDebInfo/574gs2w4/x86_64/build_file_index.txt  ʥ2 _ ǟ2| z -x/Users/venbateam/Documents/UAE_Stats/FCSC/frontend/android/app/.cxx/RelWithDebInfo/574gs2w4/x86_64/compile_commands.json  Ă2 +x/Users/venbateam/Documents/UAE_Stats/FCSC/frontend/android/app/.cxx/RelWithDebInfo/574gs2w4/x86_64/compile_commands.json  ʥ2 ~ -|/Users/venbateam/Documents/UAE_Stats/FCSC/frontend/android/app/.cxx/RelWithDebInfo/574gs2w4/x86_64/compile_commands.json.bin  Ă2  +|/Users/venbateam/Documents/UAE_Stats/FCSC/frontend/android/app/.cxx/RelWithDebInfo/574gs2w4/x86_64/compile_commands.json.bin  ʥ2   -/Users/venbateam/Documents/UAE_Stats/FCSC/frontend/android/app/.cxx/RelWithDebInfo/574gs2w4/x86_64/metadata_generation_command.txt  Ă2 +/Users/venbateam/Documents/UAE_Stats/FCSC/frontend/android/app/.cxx/RelWithDebInfo/574gs2w4/x86_64/metadata_generation_command.txt  ʥ2  ǟ2y w -u/Users/venbateam/Documents/UAE_Stats/FCSC/frontend/android/app/.cxx/RelWithDebInfo/574gs2w4/x86_64/prefab_config.json  Ă2  ( ǟ2~ +u/Users/venbateam/Documents/UAE_Stats/FCSC/frontend/android/app/.cxx/RelWithDebInfo/574gs2w4/x86_64/prefab_config.json  ʥ2  ( ǟ2~ | -z/Users/venbateam/Documents/UAE_Stats/FCSC/frontend/android/app/.cxx/RelWithDebInfo/574gs2w4/x86_64/symbol_folder_index.txt  Ă2  q ǟ2c +z/Users/venbateam/Documents/UAE_Stats/FCSC/frontend/android/app/.cxx/RelWithDebInfo/574gs2w4/x86_64/symbol_folder_index.txt  ʥ2  q ǟ2c a -_/Users/venbateam/Documents/flutter/packages/flutter_tools/gradle/src/main/groovy/CMakeLists.txt  Ă2  ހ2 \ No newline at end of file +_/Users/venbateam/Documents/flutter/packages/flutter_tools/gradle/src/main/groovy/CMakeLists.txt  ʥ2  ހ2 \ No newline at end of file diff --git a/android/app/build.gradle b/android/app/build.gradle index 59a83dd5..fc4f1720 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -20,12 +20,12 @@ if (project.hasProperty('google-services.json')) { def flutterVersionCode = localProperties.getProperty("flutter.versionCode") if (flutterVersionCode == null) { - flutterVersionCode = "61" + flutterVersionCode = "62" } def flutterVersionName = localProperties.getProperty("flutter.versionName") if (flutterVersionName == null) { - flutterVersionName = "1.0.60" + flutterVersionName = "1.0.61" } def keystorePropertiesFile = rootProject.file("key.properties") diff --git a/assets/banners/FCSCLogo_dark.png b/assets/banners/FCSCLogo_dark.png index 8f693c5e21844b9534378539c1b297208d945fd3..94419aa616fe4cd5619414666a113d06e6b3291e 100644 GIT binary patch literal 7787 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 literal 11480 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 literal 0 HcmV?d00001 diff --git a/assets/icons/misc/signInWithUAEPass.png b/assets/icons/misc/signInWithUAEPass.png new file mode 100644 index 0000000000000000000000000000000000000000..176fbf11bffa9e951b46d0d98a2a397fa9f9089c GIT binary patch literal 1473 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 Hu0mjf6A103 diff --git a/assets/icons/misc/vector1.png b/assets/icons/misc/vector1.png new file mode 100644 index 0000000000000000000000000000000000000000..d3783e75655e5e06d23e3f015bb9579f97dccb26 GIT binary patch literal 557 zcmV+|0@D47P)ZlHai=;sq#OCQBj8Vk=J9NOL(?O>Tj^u1>=DP<&O zvA}*tRIIz$Qa39)Ncrn{_UlIZa+64|g^*?&Te@ad0F3&~N{FYxv!9RGLB9eb!^ai@ z1we;!4X}$z)Llj0n0ED=W;F&-f~~3E1B}Sk4C#m>%%Oq9b%Lh*XqEeIV9_dbRY3%FC)=|} zbH=z#S#bGrVG8F4jU0q&mT)!Cta1})YcLA&bc;;hJo_cBV)QPf>r|(xUdR%Fi3M4- zw>bR*&_nRBfqe7msU9=lwH(YK)+;Twsxt3n$oinM1J+XMQ%^~?2>Dv)!2K93s(xK% zfkPukdMLk~C=JPJtF)ey@@|T|9^~L&^mSv?1_xusN@9dYjrv>zpQnUJmIG8Lg>9?X v9mcavlk#7WzjHbY+gPtV?Eiyx1XlD1{<|5N|I58000000NkvXXu0mjfm9O+S literal 0 HcmV?d00001 diff --git a/ios/Runner.xcodeproj/project.pbxproj b/ios/Runner.xcodeproj/project.pbxproj index 44733890..71b2ac31 100644 --- a/ios/Runner.xcodeproj/project.pbxproj +++ b/ios/Runner.xcodeproj/project.pbxproj @@ -506,7 +506,7 @@ CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 7; + CURRENT_PROJECT_VERSION = 8; DEVELOPMENT_ASSET_PATHS = Runner/Assets.xcassets; DEVELOPMENT_TEAM = 9N5SRFUGK2; ENABLE_BITCODE = NO; @@ -517,7 +517,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 1.0.6; + MARKETING_VERSION = 1.0.7; PRODUCT_BUNDLE_IDENTIFIER = ae.gov.fcsc.frontend.ios; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; @@ -705,7 +705,7 @@ CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 7; + CURRENT_PROJECT_VERSION = 8; DEVELOPMENT_ASSET_PATHS = Runner/Assets.xcassets; DEVELOPMENT_TEAM = 9N5SRFUGK2; ENABLE_BITCODE = NO; @@ -716,7 +716,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 1.0.6; + MARKETING_VERSION = 1.0.7; PRODUCT_BUNDLE_IDENTIFIER = ae.gov.fcsc.frontend.ios; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; @@ -742,7 +742,7 @@ CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 7; + CURRENT_PROJECT_VERSION = 8; DEVELOPMENT_ASSET_PATHS = Runner/Assets.xcassets; DEVELOPMENT_TEAM = 9N5SRFUGK2; ENABLE_BITCODE = NO; @@ -753,7 +753,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 1.0.6; + MARKETING_VERSION = 1.0.7; PRODUCT_BUNDLE_IDENTIFIER = ae.gov.fcsc.frontend.ios; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; diff --git a/lib/infrastructure/services/img_asset_paths/icons/misc_icon_asset_path.dart b/lib/infrastructure/services/img_asset_paths/icons/misc_icon_asset_path.dart index b81891fc..dcdc2260 100644 --- a/lib/infrastructure/services/img_asset_paths/icons/misc_icon_asset_path.dart +++ b/lib/infrastructure/services/img_asset_paths/icons/misc_icon_asset_path.dart @@ -2,9 +2,14 @@ abstract class MiscIconAssetPath { static const _basePath = 'assets/icons/misc'; static const rightChevronInSemiCircle = '$_basePath/right_chevron_in_semicircle.png'; + static const signInWithGoogle = '$_basePath/signInWithGoogle.png'; + static const signInWithApple = '$_basePath/signInWithApple.png'; + static const signInWithUAEPass = '$_basePath/signInWithUAEPass.png'; + static const lock = '$_basePath/lock.png'; static const lockDark = '$_basePath/lockDark.png'; static const lockLight = '$_basePath/lockLight.png'; static const menu = '$_basePath/menu.png'; + static const person = '$_basePath/person.png'; static const personDark = '$_basePath/personDark.png'; static const personLight = '$_basePath/personLight.png'; static const back = '$_basePath/back.png'; diff --git a/lib/presentation/Screens/Bottom Navigation Pages/Country_Profile/country_profile.dart b/lib/presentation/Screens/Bottom Navigation Pages/Country_Profile/country_profile.dart index f56e4c02..cc6306f9 100644 --- a/lib/presentation/Screens/Bottom Navigation Pages/Country_Profile/country_profile.dart +++ b/lib/presentation/Screens/Bottom Navigation Pages/Country_Profile/country_profile.dart @@ -4,6 +4,7 @@ import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:shared_preferences/shared_preferences.dart'; import 'package:go_router/go_router.dart'; import 'package:flutter_svg/flutter_svg.dart'; +import 'package:uae_stat/config/theme/theme_provider.dart'; import 'package:uae_stat/domain/use_cases/language.dart'; import 'package:uae_stat/infrastructure/services/img_asset_paths/icons/misc_icon_asset_path.dart'; import 'package:uae_stat/presentation/routes/drawer_routes/custom_drawer_routes.dart'; @@ -47,6 +48,13 @@ class _CountryProfilePageState extends ConsumerState { setState(() => _searchTerm = value); } + @override + void initState() { + super.initState(); + final currentTheme = ref.read(themeProvider); // should return ThemeMode + print(currentTheme); // ThemeMode.dark, ThemeMode.light, etc. + } + @override Widget build(BuildContext context) { final locale = AppLocalizations.of(context)!; diff --git a/lib/presentation/Screens/Bottom Navigation Pages/UAE_Numbers/uae_numbers.dart b/lib/presentation/Screens/Bottom Navigation Pages/UAE_Numbers/uae_numbers.dart index 28929176..50a8d1e5 100644 --- a/lib/presentation/Screens/Bottom Navigation Pages/UAE_Numbers/uae_numbers.dart +++ b/lib/presentation/Screens/Bottom Navigation Pages/UAE_Numbers/uae_numbers.dart @@ -265,7 +265,7 @@ class _UaenumberWidgetState extends ConsumerState { } return Container( - color: isDarkTheme ? Color(0xFF333333) : Color(0xFFFFFFFF), // Set background here + color: isDarkTheme ? Color(0xFF000000) : Color(0xFFFFFFFF), // Set background here child: Padding( padding: const EdgeInsets.only(left: 16.0, right: 16.0, top: 5.0, bottom: 5.0), child: Column( @@ -274,11 +274,11 @@ class _UaenumberWidgetState extends ConsumerState { height: 40, decoration: BoxDecoration( color: isDarkTheme ? Color(0xFF000000) : Colors.white, - borderRadius: BorderRadius.circular(30.0), - border: Border.all(width: 1, color: Color(0xFFAA8E83)), + borderRadius: BorderRadius.circular(5.0), + border: Border.all(width: 2, color: Color(0xFFA0A0A0)), ), child: Padding( - padding: EdgeInsets.only(left: 12.0), + padding: EdgeInsets.only(left: 5.0), child: TextField( controller: _searchController, onChanged: (value) { @@ -287,9 +287,9 @@ class _UaenumberWidgetState extends ConsumerState { decoration: InputDecoration( hintText: AppLocalizations.of(context)!.search, hintStyle: TextStyle( - color: isDarkTheme ? Color(0xFFBBBBBB) : Color(0xFFAA8E83), + color: isDarkTheme ? Color(0xFF898C81) : Color(0xFF898C81), fontFamily: context.translate('Roboto', 'NotoKufi'), - fontSize: 14, + fontSize: 18, // height: 1.8, ), prefixIconConstraints: BoxConstraints( @@ -320,7 +320,7 @@ class _UaenumberWidgetState extends ConsumerState { }, ) : null, - contentPadding: EdgeInsets.symmetric(vertical: 15, horizontal: 18.0), + contentPadding: EdgeInsets.symmetric(vertical: 12, horizontal: 18.0), border: InputBorder.none, // contentPadding: // EdgeInsets.symmetric(vertical: 9, horizontal: 18.0), @@ -502,9 +502,9 @@ class _UaenumberWidgetState extends ConsumerState { color: isDarkTheme ? Color(0xFF111111) : Colors.white, border: Border.all( color: bordercolor, - width: 1, + width: 2, ), - borderRadius: BorderRadius.circular(12), + borderRadius: BorderRadius.circular(5), ), padding: const EdgeInsets.only( top: 3.0, bottom: 3.0, left: 5.0, right: 5.0), @@ -605,12 +605,13 @@ class _CustomExpandableTileState extends ConsumerState { onTap: () => widget.onTap(widget.index), child: Container( decoration: BoxDecoration( - color: isDarkTheme ? Color(0xFF333333) : Colors.white, + color: isDarkTheme ? Color(0xFF000000) : Color(0xFFFFFFFF), ), child: Container( decoration: BoxDecoration( color: widget.titleBackgroundColor, - borderRadius: BorderRadius.all(Radius.circular(35))), + borderRadius: BorderRadius.only(topLeft: Radius.circular(20),topRight: Radius.circular(20)) + ), padding: const EdgeInsets.only( left: 16, bottom: 5, top: 5, right: 10), child: Row( @@ -645,13 +646,13 @@ class _CustomExpandableTileState extends ConsumerState { duration: Duration(milliseconds: 300), curve: Curves.easeInOut, width: double.infinity, - color: isDarkTheme ? Color(0xFF333333) : Colors.white, + color: isDarkTheme ? Color(0xFF000000) : Color(0xFFFFFFFF), height: widget.isExpanded ? myheight * 0.52 : 0, child: widget.isExpanded ? SingleChildScrollView( child: Container( decoration: BoxDecoration( - color: isDarkTheme ? Color(0xFF333333) : Colors.white, + color: isDarkTheme ? Color(0xFF000000) : Color(0xFFFFFFFF), // borderRadius: BorderRadius.all(Radius.circular(20)) ), padding: const EdgeInsets.all(1), diff --git a/lib/presentation/Screens/auth_verification/create_new_pw.dart b/lib/presentation/Screens/auth_verification/create_new_pw.dart index e69213d8..65633182 100644 --- a/lib/presentation/Screens/auth_verification/create_new_pw.dart +++ b/lib/presentation/Screens/auth_verification/create_new_pw.dart @@ -7,6 +7,7 @@ import 'package:shared_preferences/shared_preferences.dart'; import 'package:uae_stat/config/api_config.dart'; import 'package:uae_stat/config/connectivity_provider.dart'; import 'package:uae_stat/config/my_router.dart'; +import 'package:uae_stat/config/theme/theme_provider.dart'; import 'package:uae_stat/domain/use_cases/language.dart'; import 'package:uae_stat/infrastructure/data/p_auth_repo.dart'; import 'package:uae_stat/infrastructure/services/img_asset_paths/banner_asset_path.dart'; @@ -253,6 +254,13 @@ class _CreateNewPwState extends ConsumerState { context.push('/internetcheck'); } }); + + // final themeMode = ref.read(themeProvider); + final themeMode = ThemeMode.dark; + final isDarkTheme = themeMode == ThemeMode.dark || + (themeMode == ThemeMode.system && + MediaQuery.of(context).platformBrightness == Brightness.dark); + return PopScope( canPop: false, // Allow back navigation only if not login screen onPopInvokedWithResult: (didPop, result) { @@ -260,7 +268,7 @@ class _CreateNewPwState extends ConsumerState { logout(context);// Show exit confirmation dialog }, child: Scaffold( - backgroundColor: Colors.white, + backgroundColor: isDarkTheme ? Color(0xFF111111) : Colors.white, body: Stack(children: [ SingleChildScrollView( child: SafeArea( @@ -298,6 +306,10 @@ class _CreateNewPwState extends ConsumerState { Widget _buildPasswordForm( WidgetRef ref, double screenHeight, double screenWidth) { final passwordLocale = ref.watch(localeProvider); + final themeMode = ref.read(themeProvider); + final isDarkTheme = themeMode == ThemeMode.dark || + (themeMode == ThemeMode.system && + MediaQuery.of(context).platformBrightness == Brightness.dark); return Form( key: _formKey, child: Padding( @@ -322,7 +334,7 @@ class _CreateNewPwState extends ConsumerState { // Icons.close, Icons.arrow_back_ios, size: 24, // Icon size - color: Colors.black, // Icon color + color: isDarkTheme ? Colors.white : Colors.black, // Icon color ), ), ), // Left icon @@ -363,6 +375,7 @@ class _CreateNewPwState extends ConsumerState { ), fontSize: passwordLocale?.languageCode == 'ar' ? 24 : 26, fontWeight: FontWeight.w300, + color: isDarkTheme ? Colors.white : null, ), ), SizedBox(height: 10), @@ -410,7 +423,7 @@ class _CreateNewPwState extends ConsumerState { hintText: AppLocalizations.of(context)!.old_password, // prefixIcon: Icon(Icons.lock, color: Colors.blue), hintStyle: TextStyle( - color: Color(0xFFC3C6CB), + color: isDarkTheme ? Colors.white : Color(0xFFC3C6CB), fontWeight: FontWeight.w400, fontFamily: context.translate( 'Roboto', @@ -426,11 +439,11 @@ class _CreateNewPwState extends ConsumerState { end: 10, ), child: Image.asset( - MiscIconAssetPath.lockLight, + isDarkTheme ? MiscIconAssetPath.lockDark : MiscIconAssetPath.lockLight, fit: BoxFit.fitHeight, height: 25, width: 25, - color: MyTheme.topicColor(IndicatorTopic.economy).shade300, + color: isDarkTheme ? Colors.white : MyTheme.topicColor(IndicatorTopic.economy).shade300, ), ), suffixIcon: IconButton( diff --git a/lib/presentation/Screens/auth_verification/registration.dart b/lib/presentation/Screens/auth_verification/registration.dart index 91b6a911..2ffb6ab2 100644 --- a/lib/presentation/Screens/auth_verification/registration.dart +++ b/lib/presentation/Screens/auth_verification/registration.dart @@ -635,7 +635,7 @@ class _RegisterScreenState extends ConsumerState { ), fontSize: 32, fontWeight: FontWeight.w400, - color: isDarkTheme ? Color(0xFFFFFFFF) : null, + color: isDarkTheme ? Color(0xFFFFFFFF) : Color(0xFF000000), ), ), SizedBox(height: 10), @@ -649,7 +649,7 @@ class _RegisterScreenState extends ConsumerState { ), fontSize: context.translate(18.0, 14.0), - color: isDarkTheme ? Color(0xFFFFFFFF) : Color(0xff898C81), + color: isDarkTheme ? Color(0xFFFFFFFF) : Color(0xFF898C81), fontWeight: FontWeight.w600, ), ), @@ -694,14 +694,10 @@ class _RegisterScreenState extends ConsumerState { end: 10, ), child: Image.asset( - MiscIconAssetPath.personLight, + MiscIconAssetPath.person, fit: BoxFit.fitHeight, height: 25, width: 25, - color: MyTheme.topicColor( - IndicatorTopic - .economy) - .shade300, ), ), @@ -715,7 +711,7 @@ class _RegisterScreenState extends ConsumerState { borderRadius: BorderRadius.circular(10), borderSide: BorderSide( - color: isDarkTheme ? Colors.white : MyTheme.topicColor(IndicatorTopic.economy).shade400, // ✅ border + color: Color(0xFFB68A34), // ✅ border width: 1), // Enabled border ), focusedBorder: OutlineInputBorder( @@ -729,7 +725,7 @@ class _RegisterScreenState extends ConsumerState { borderRadius: BorderRadius.circular(10), borderSide: BorderSide( - color: isDarkTheme ? Color(0xFFFFA100) : Color(0xFFb22222), + color: Color(0xFFD83731), width: 1), // Error border ), focusedErrorBorder: @@ -737,7 +733,7 @@ class _RegisterScreenState extends ConsumerState { borderRadius: BorderRadius.circular(10), borderSide: BorderSide( - color: isDarkTheme ? Color(0xFFFFA100) : Color(0xFFb22222), + color: Color(0xFFD83731), width: 1), // Match the error color ), @@ -747,7 +743,7 @@ class _RegisterScreenState extends ConsumerState { 'Roboto', 'NotoKufi', ), - color: isDarkTheme ? const Color(0xFFEEEEEE) : const Color(0xFFC3C6CB), + color: const Color(0xFFC3C6CB), fontSize: registerLocale ?.languageCode == 'ar' @@ -804,12 +800,8 @@ class _RegisterScreenState extends ConsumerState { child: Image.asset( MiscIconAssetPath.vector, fit: BoxFit.fitHeight, - height: 20, + height: 25, width: 25, - color: MyTheme.topicColor( - IndicatorTopic - .economy) - .shade100, ), ), @@ -818,7 +810,7 @@ class _RegisterScreenState extends ConsumerState { borderRadius: BorderRadius.circular(10), borderSide: BorderSide( - color: isDarkTheme ? Colors.white : MyTheme.topicColor(IndicatorTopic.economy).shade400, + color: Color(0xFFB68A34), width: 1), ), focusedBorder: OutlineInputBorder( @@ -832,7 +824,7 @@ class _RegisterScreenState extends ConsumerState { borderRadius: BorderRadius.circular(10), borderSide: BorderSide( - color: isDarkTheme ? Color(0xFFFFA100) : Color(0xFFb22222), + color: Color(0xFFD83731), width: 1), // Error border ), focusedErrorBorder: @@ -840,7 +832,7 @@ class _RegisterScreenState extends ConsumerState { borderRadius: BorderRadius.circular(10), borderSide: BorderSide( - color: isDarkTheme ? Color(0xFFFFA100) : Color(0xFFb22222), + color: Color(0xFFD83731), width: 1), // Match the error color ), @@ -850,7 +842,7 @@ class _RegisterScreenState extends ConsumerState { 'Roboto', 'NotoKufi', ), - color: isDarkTheme ? const Color(0xFFEEEEEE) : const Color(0xFFC3C6CB), + color: const Color(0xFFC3C6CB), fontSize: registerLocale ?.languageCode == 'ar' @@ -908,14 +900,10 @@ class _RegisterScreenState extends ConsumerState { end: 10, ), child: Image.asset( - MiscIconAssetPath.lockLight, + MiscIconAssetPath.lock, fit: BoxFit.fitHeight, height: 25, width: 25, - color: MyTheme.topicColor( - IndicatorTopic - .economy) - .shade300, ), ), @@ -956,7 +944,7 @@ class _RegisterScreenState extends ConsumerState { borderRadius: BorderRadius.circular(10), borderSide: BorderSide( - color: isDarkTheme ? Colors.white : MyTheme.topicColor(IndicatorTopic.economy).shade400, + color: Color(0xFFB68A34), width: 1), ), focusedBorder: OutlineInputBorder( @@ -970,7 +958,7 @@ class _RegisterScreenState extends ConsumerState { borderRadius: BorderRadius.circular(10), borderSide: BorderSide( - color: isDarkTheme ? Color(0xFFFFA100) : Color(0xFFb22222), + color: Color(0xFFD83731), width: 1), // Error border ), focusedErrorBorder: @@ -978,7 +966,7 @@ class _RegisterScreenState extends ConsumerState { borderRadius: BorderRadius.circular(10), borderSide: BorderSide( - color: isDarkTheme ? Color(0xFFFFA100) : Color(0xFFb22222), + color: Color(0xFFD83731), width: 1), // Match the error color ), @@ -989,7 +977,7 @@ class _RegisterScreenState extends ConsumerState { 'Roboto', 'NotoKufi', ), - color: isDarkTheme ? const Color(0xFFEEEEEE) : const Color(0xFFC3C6CB), + color: const Color(0xFFC3C6CB), fontSize: registerLocale ?.languageCode == 'ar' @@ -1045,14 +1033,10 @@ class _RegisterScreenState extends ConsumerState { end: 10, ), child: Image.asset( - MiscIconAssetPath.lockLight, + MiscIconAssetPath.lock, fit: BoxFit.fitHeight, height: 25, width: 25, - color: MyTheme.topicColor( - IndicatorTopic - .economy) - .shade300, ), ), @@ -1083,7 +1067,7 @@ class _RegisterScreenState extends ConsumerState { borderRadius: BorderRadius.circular(10), borderSide: BorderSide( - color: isDarkTheme ? Colors.white : MyTheme.topicColor(IndicatorTopic.economy).shade400, + color: Color(0xFFB68A34), width: 1), ), focusedBorder: OutlineInputBorder( @@ -1097,7 +1081,7 @@ class _RegisterScreenState extends ConsumerState { borderRadius: BorderRadius.circular(10), borderSide: BorderSide( - color: isDarkTheme ? Color(0xFFFFA100) : Color(0xFFb22222), + color: Color(0xFFD83731), width: 1), // Error border ), focusedErrorBorder: @@ -1105,7 +1089,7 @@ class _RegisterScreenState extends ConsumerState { borderRadius: BorderRadius.circular(10), borderSide: BorderSide( - color: isDarkTheme ? Color(0xFFFFA100) : Color(0xFFb22222), + color: Color(0xFFD83731), width: 1), // Match the error color ), @@ -1115,7 +1099,7 @@ class _RegisterScreenState extends ConsumerState { 'Roboto', 'NotoKufi', ), - color: isDarkTheme ? const Color(0xFFEEEEEE) : const Color(0xFFC3C6CB), + color: const Color(0xFFC3C6CB), fontSize: registerLocale ?.languageCode == 'ar' @@ -1156,8 +1140,8 @@ class _RegisterScreenState extends ConsumerState { }, side: BorderSide( color: showError - ? isDarkTheme ? Color(0xFFFFA200) : Color(0xFFb22222) - : isDarkTheme ? Colors.white : MyTheme.topicColor(IndicatorTopic.economy).shade400, + ? Color(0xFFD83731) + : Color(0xFFB68A34), width: 1, ), ), @@ -1186,7 +1170,7 @@ class _RegisterScreenState extends ConsumerState { 'ar' ? 12 : 14, - color: isDarkTheme ? Color(0xFFEEEEEE) : Color(0xFF898C81), // Change to your desired color + color: isDarkTheme ? Color(0xFFFFFFFF) : Color(0xFF898C81), // Change to your desired color ), children: [ TextSpan( @@ -1213,7 +1197,7 @@ class _RegisterScreenState extends ConsumerState { fontWeight: FontWeight .bold, - color:isDarkTheme ? Color(0xFF9EB3E4) : Color(0xFF985400), + color:isDarkTheme ? Color(0xFFB68A35) : Color(0xFF985400), // Makes the text bold // decoration: // TextDecoration.underline, @@ -1232,7 +1216,7 @@ class _RegisterScreenState extends ConsumerState { 'Roboto', 'NotoKufi', ), - color: isDarkTheme ? Color(0xFFEEEEEE) : Color(0xFF898C81), + color: isDarkTheme ? Color(0xFFFFFFFF) : Color(0xFF898C81), ), ), TextSpan( @@ -1258,7 +1242,7 @@ class _RegisterScreenState extends ConsumerState { 'ar' ? 12 : 14, - color: isDarkTheme ? Color(0xFF9EB3E4) : Color(0xFF985400), + color: isDarkTheme ? Color(0xFFB68A35) : Color(0xFF985400), // decoration: // TextDecoration.underline, decorationColor: @@ -1283,7 +1267,7 @@ class _RegisterScreenState extends ConsumerState { 'ar' ? 12 : 14, - color: isDarkTheme ? Color(0xFFEEEEEE) : Color( 0xFF898C81), // Change to your desired color + color: isDarkTheme ? Color(0xFFFFFFFF) : Color( 0xFF898C81), // Change to your desired color ), ), ], @@ -1320,7 +1304,7 @@ class _RegisterScreenState extends ConsumerState { 'Roboto', 'NotoKufi', ), - color: isDarkTheme ? Color(0xFFFFA200) : Color(0xFFb22222), + color: Color(0xFFD83731), fontSize: registerLocale ?.languageCode == 'ar' @@ -1345,7 +1329,7 @@ class _RegisterScreenState extends ConsumerState { ? null : _registerUser, style: ElevatedButton.styleFrom( - backgroundColor: isDarkTheme ? Color(0xFF9EB3E4) : Color(0xFFA7887A), // Brownish color for Register + backgroundColor: Color(0xFFB68A34), // Brownish color for Register shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(10), @@ -1369,14 +1353,14 @@ class _RegisterScreenState extends ConsumerState { 'ar' ? 14 : 16, - color: isDarkTheme ? Color(0xFF000000) : Colors.white + color: Colors.white ), ), SizedBox(width: 8), Icon( Icons .chevron_right_outlined, - color: isDarkTheme ? Color(0xFF000000) : Colors.white, // Set your desired color here + color: Colors.white, // Set your desired color here ) ], ), @@ -1398,7 +1382,7 @@ class _RegisterScreenState extends ConsumerState { 'ar' ? 12 : 14, - color: isDarkTheme ? Color(0xFFEEEEEE) : Color(0xFF898C81), + color: isDarkTheme ? Color(0xFFFFFFFF) : Color(0xFF898C81), ), ), SizedBox(height: 15), @@ -1415,7 +1399,7 @@ class _RegisterScreenState extends ConsumerState { context.pop(); }, style: ElevatedButton.styleFrom( - backgroundColor: isDarkTheme ? Color(0xFF24B4FB) : Color(0xFF82AFCB), // Blueish color for Login + backgroundColor: Color(0xFFB68A34), // Blueish color for Login shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(10), @@ -1438,13 +1422,13 @@ class _RegisterScreenState extends ConsumerState { 'ar' ? 14 : 16, - color: isDarkTheme ? Color(0xFF000000) : Colors.white), + color: Colors.white), ), SizedBox(width: 8), Icon( Icons .chevron_right_outlined, - color: isDarkTheme ? Color(0xFF000000) : Colors.white, // Set your desired color here + color: Colors.white, // Set your desired color here ) ], ), diff --git a/lib/presentation/Screens/charts/screens/chart_screen.dart b/lib/presentation/Screens/charts/screens/chart_screen.dart index 072b0762..22bccc2e 100644 --- a/lib/presentation/Screens/charts/screens/chart_screen.dart +++ b/lib/presentation/Screens/charts/screens/chart_screen.dart @@ -22,6 +22,7 @@ import 'package:uae_stat/presentation/Screens/charts/services/api_service.dart'; import 'package:uae_stat/presentation/Screens/charts/widgets/chart_widget.dart'; import 'package:uae_stat/presentation/components/indicators/locale_provider.dart'; import 'package:uae_stat/presentation/components/my_toggle.dart'; +// import 'package:uae_stat/l10n/app_localizations.dart'; import 'package:flutter_gen/gen_l10n/app_localizations.dart'; import 'package:uae_stat/presentation/routes/drawer_routes/custom_drawer_routes.dart'; import 'package:uae_stat/presentation/Screens/app_tour/Target_content.dart'; @@ -123,7 +124,7 @@ class _ChartScreen1State extends ConsumerState { final themeMode = (isDark ? 'dark' : 'light'); fetchChartData(widget.dataSets, locale?.languageCode ?? 'en', widget.kpi, - widget.filter_data,themeMode) + widget.filter_data, themeMode) .then((_) { if (_tabsData.isNotEmpty) { // Call onTabSelected for the first tab @@ -199,8 +200,7 @@ class _ChartScreen1State extends ConsumerState { fontFamily: context.translate( 'Roboto', 'NotoKufi', - ) - ), + )), ), duration: Duration(seconds: 2), ), @@ -216,8 +216,7 @@ class _ChartScreen1State extends ConsumerState { fontFamily: context.translate( 'Roboto', 'NotoKufi', - ) - ), + )), ), // backgroundColor: Color(0xFFEB5F24), duration: Duration(seconds: 2), @@ -252,8 +251,7 @@ class _ChartScreen1State extends ConsumerState { fontFamily: context.translate( 'Roboto', 'NotoKufi', - ) - ), + )), ), duration: Duration(seconds: 2), ), @@ -269,8 +267,7 @@ class _ChartScreen1State extends ConsumerState { fontFamily: context.translate( 'Roboto', 'NotoKufi', - ) - ), + )), ), // backgroundColor: Color(0xFFEB5F24), duration: Duration(seconds: 2), @@ -366,15 +363,19 @@ class _ChartScreen1State extends ConsumerState { foregroundColor: Colors.white, shape: RoundedRectangleBorder( borderRadius: - BorderRadius.circular(10.0), // Set text color + BorderRadius.circular(10.0), // Set text color ), ), child: Text( context.translate('Yes', 'نعم'), - style: TextStyle(color: Colors.white, fontSize: 16, fontFamily: context.translate( - 'Roboto', - 'NotoKufi', - ),), + style: TextStyle( + color: Colors.white, + fontSize: 16, + fontFamily: context.translate( + 'Roboto', + 'NotoKufi', + ), + ), ), ), ), @@ -470,15 +471,19 @@ class _ChartScreen1State extends ConsumerState { foregroundColor: Colors.white, shape: RoundedRectangleBorder( borderRadius: - BorderRadius.circular(10.0), // Set text color + BorderRadius.circular(10.0), // Set text color ), ), child: Text( context.translate('Yes', 'نعم'), - style: TextStyle(color: Colors.white, fontSize: 16, fontFamily: context.translate( - 'Roboto', - 'NotoKufi', - ),), + style: TextStyle( + color: Colors.white, + fontSize: 16, + fontFamily: context.translate( + 'Roboto', + 'NotoKufi', + ), + ), ), ), ), @@ -505,7 +510,7 @@ class _ChartScreen1State extends ConsumerState { Future _getWidget() async { await Future.delayed(Duration(milliseconds: 50)); // Ensures widget is built final RenderBox? box = - cardKey.currentContext?.findRenderObject() as RenderBox?; + cardKey.currentContext?.findRenderObject() as RenderBox?; if (box != null) { final Offset position = box.localToGlobal(Offset.zero); @@ -696,7 +701,7 @@ class _ChartScreen1State extends ConsumerState { .state = true; ref .read(previousHomeTourProvider - .notifier) + .notifier) .state = false; tutorialCoachMark.finish(); } @@ -727,7 +732,7 @@ class _ChartScreen1State extends ConsumerState { .state = true; ref .read(previousHomeTourProvider - .notifier) + .notifier) .state = false; tutorialCoachMark.finish(); } else { @@ -831,7 +836,7 @@ class _ChartScreen1State extends ConsumerState { ), child: Text( AppLocalizations.of(context)!.skip, - style: TextStyle( + style: TextStyle( fontFamily: context.translate( 'Roboto', 'NotoKufi', @@ -1214,11 +1219,11 @@ class _ChartScreen1State extends ConsumerState { } else { ref .read(previousChartsTourProvider - .notifier) + .notifier) .state = true; ref .read(previousHomeTourProvider - .notifier) + .notifier) .state = false; tutorialCoachMark.finish(); } @@ -1248,11 +1253,11 @@ class _ChartScreen1State extends ConsumerState { if (locale.languageCode == 'ar') { ref .read(previousChartsTourProvider - .notifier) + .notifier) .state = true; ref .read(previousHomeTourProvider - .notifier) + .notifier) .state = false; tutorialCoachMark.finish(); } else { @@ -1387,8 +1392,8 @@ class _ChartScreen1State extends ConsumerState { String formattedKpi = kpi .split('_') // Split by underscore .map((word) => word.isNotEmpty - ? word[0].toUpperCase() + word.substring(1) - : '') // Capitalize + ? word[0].toUpperCase() + word.substring(1) + : '') // Capitalize .join(' '); // Join words with space return {'id': kpi, 'name': tabHeading, 'order': tabOrder.toString()}; }).toList(); @@ -1410,13 +1415,14 @@ class _ChartScreen1State extends ConsumerState { }); } - Future fetchChartData(String dataSets, locale, kpi, filter_data,themeMode) async { - var data = - await apiService.fetchChartData(dataSets, locale, kpi, filter_data,themeMode); + Future fetchChartData( + String dataSets, locale, kpi, filter_data, themeMode) async { + var data = await apiService.fetchChartData( + dataSets, locale, kpi, filter_data, themeMode); tabFilteredKpi = kpi; print('FETCH KPI- $kpi'); - print('FETCH KFilter- $filter_data'); + print('FETCH KFilter- $filter_data'); print('locale1 - $locale'); // print('locale11 - $loacleData'); @@ -1425,7 +1431,7 @@ class _ChartScreen1State extends ConsumerState { selectedFiltersApi = filter_data.map>((entry) { if (entry is Map) { return entry.map( - (key, value) => MapEntry(key.toString(), value)); + (key, value) => MapEntry(key.toString(), value)); } return {}; }).toList(); @@ -1493,12 +1499,12 @@ class _ChartScreen1State extends ConsumerState { // Transform the selectedFilters list into the required format formattedFilters = selectedFilters - // .where((filter) => filter['filter_data'] != null && filter['filter_data'].isNotEmpty) + // .where((filter) => filter['filter_data'] != null && filter['filter_data'].isNotEmpty) .map((filter) { return { 'filter_key': filter['filter_key'], 'filter_data': - filter['filter_data'].map((item) => item.toString()).toList() + filter['filter_data'].map((item) => item.toString()).toList() }; }).toList(); @@ -1506,7 +1512,7 @@ class _ChartScreen1State extends ConsumerState { // Convert to JSON format String selectedFormatFilters = - jsonEncode({'kpi': tabWiseKpi, 'filter_data': formattedFilters}); + jsonEncode({'kpi': tabWiseKpi, 'filter_data': formattedFilters}); print('Formatted Filters2: $selectedFormatFilters'); final locale = ref.watch(localeProvider)?.languageCode ?? 'en'; @@ -1525,8 +1531,7 @@ class _ChartScreen1State extends ConsumerState { locale, tabWiseKpi, // Ensure you are passing the correct KPI here formattedFilters, // Pass the formatted filter data here - themeMode - ); + themeMode); // Navigator.pop(context); selectedFiltersStorage = List.from(selectedFilters); @@ -1590,8 +1595,8 @@ class _ChartScreen1State extends ConsumerState { if (kDebugMode) { print( "Selected year: ${selectedFilters.firstWhere((f) => f['filter_key'] == 'TIME_PERIOD', orElse: () => { - 'filter_data': ['Unknown'] - })['filter_data']} - No data for chart: : $chartHeading"); + 'filter_data': ['Unknown'] + })['filter_data']} - No data for chart: : $chartHeading"); } // Add the complete chart data to the filteredData list @@ -1677,11 +1682,11 @@ class _ChartScreen1State extends ConsumerState { // Initialize selected filters structure from the stored value, if exists List> selectedFilters = - selectedFiltersStorage.isNotEmpty - ? List.from(selectedFiltersStorage) // Use stored filters - : filters.map((filter) { - return {"filter_key": filter["filter_key"], "filter_data": []}; - }).toList(); // Or initialize empty filters + selectedFiltersStorage.isNotEmpty + ? List.from(selectedFiltersStorage) // Use stored filters + : filters.map((filter) { + return {"filter_key": filter["filter_key"], "filter_data": []}; + }).toList(); // Or initialize empty filters print('selectedFiltersStoragedrgt- $selectedFiltersStorage'); @@ -1711,7 +1716,10 @@ class _ChartScreen1State extends ConsumerState { UaeNumbersAssetPath.filterCharts, semanticsLabel: 'Filter', colorFilter: ColorFilter.mode( - isDarkTheme ? Color(0xFFFFFFFF) : Color(0xFF8E8E8E), BlendMode.srcIn), + isDarkTheme + ? Color(0xFFFFFFFF) + : Color(0xFF8E8E8E), + BlendMode.srcIn), width: 25, height: 25, ), @@ -1722,7 +1730,9 @@ class _ChartScreen1State extends ConsumerState { 'المرشحات', ), style: TextStyle( - color: isDarkTheme ? Color(0xFFFFFFFF) : Color(0xFF8E8E8E), + color: isDarkTheme + ? Color(0xFFFFFFFF) + : Color(0xFF8E8E8E), fontSize: 20, fontWeight: FontWeight.w500, fontFamily: context.translate( @@ -1755,7 +1765,7 @@ class _ChartScreen1State extends ConsumerState { final filterKey = filter["filter_key"]; final filterData = filter["filter_data"]; final filter_text_and_order = - filter["filter_text_and_order"]; + filter["filter_text_and_order"]; final fieldOrder = filter_text_and_order['order']; return StatefulBuilder( @@ -1781,7 +1791,9 @@ class _ChartScreen1State extends ConsumerState { 'Roboto', 'NotoKufi', ), - color: isDarkTheme ? Color(0xFFFFFFFF) : Color(0xFF8E8E8E), + color: isDarkTheme + ? Color(0xFFFFFFFF) + : Color(0xFF8E8E8E), ), ), InkWell( @@ -1792,34 +1804,36 @@ class _ChartScreen1State extends ConsumerState { return StatefulBuilder( builder: (context, dialogSetState) { final locale = - ref.watch(localeProvider); + ref.watch(localeProvider); print('localelocale $locale'); return AlertDialog( title: Text( - // "${locale == 'ar' ? 'يختار ' : 'Select '}" - "${context.translate(filter_text_and_order['en'], filter_text_and_order['ar'])}", - style: TextStyle( - fontFamily: context.translate( - 'Roboto', - 'NotoKufi', - ) - ),), + // "${locale == 'ar' ? 'يختار ' : 'Select '}" + "${context.translate(filter_text_and_order['en'], filter_text_and_order['ar'])}", + style: TextStyle( + fontFamily: + context.translate( + 'Roboto', + 'NotoKufi', + )), + ), content: SingleChildScrollView( child: ListBody( children: filterData .map((value) { return CheckboxListTile( title: Text( - value.toString(), - style: TextStyle( - fontFamily: context.translate( - 'Roboto', - 'NotoKufi', - ) - ),), + value.toString(), + style: TextStyle( + fontFamily: context + .translate( + 'Roboto', + 'NotoKufi', + )), + ), value: selectedFilter[ - "filter_data"] + "filter_data"] .contains(value), onChanged: (bool? isChecked) { @@ -1827,11 +1841,11 @@ class _ChartScreen1State extends ConsumerState { if (isChecked == true) { selectedFilter[ - "filter_data"] + "filter_data"] .add(value); } else { selectedFilter[ - "filter_data"] + "filter_data"] .remove(value); } }); @@ -1853,12 +1867,14 @@ class _ChartScreen1State extends ConsumerState { 'نعم', ), style: TextStyle( - fontFamily: context.translate( - 'Roboto', - 'NotoKufi', - ), - color: isDarkTheme ? Color(0xFFFFFFFF) : null, - + fontFamily: + context.translate( + 'Roboto', + 'NotoKufi', + ), + color: isDarkTheme + ? Color(0xFFFFFFFF) + : null, ), ), ), @@ -1875,46 +1891,51 @@ class _ChartScreen1State extends ConsumerState { horizontal: 16.0, vertical: 12.0), decoration: BoxDecoration( border: - Border.all(color: Color(0xFF7296BE)), + Border.all(color: Color(0xFF7296BE)), borderRadius: BorderRadius.circular(8.0), ), child: Wrap( spacing: 8.0, runSpacing: 4.0, - children: - selectedFilter["filter_data"].isEmpty - ? [ - Text( - // "${locale == 'ar' ? 'يختار ' : 'Select '}" - "${context.translate(filter_text_and_order['en'], filter_text_and_order['ar'])}", - style: TextStyle( - color: isDarkTheme ? Color(0xFFFFFFFF) : Colors.grey, - fontFamily: context.translate( - 'Roboto', - 'NotoKufi', - ),), - ) - ] - : selectedFilter["filter_data"] - .map((value) { - return Chip( - label: Text(value, - style: TextStyle( - fontFamily: context.translate( - 'Roboto', - 'NotoKufi', - ) - ),), - // backgroundColor: Colors.white, // Default background color - onDeleted: () { - setState(() { - selectedFilter[ - "filter_data"] - .remove(value); - }); - }, - ); - }).toList(), + children: selectedFilter["filter_data"] + .isEmpty + ? [ + Text( + // "${locale == 'ar' ? 'يختار ' : 'Select '}" + "${context.translate(filter_text_and_order['en'], filter_text_and_order['ar'])}", + style: TextStyle( + color: isDarkTheme + ? Color(0xFFFFFFFF) + : Colors.grey, + fontFamily: context.translate( + 'Roboto', + 'NotoKufi', + ), + ), + ) + ] + : selectedFilter["filter_data"] + .map((value) { + return Chip( + label: Text( + value, + style: TextStyle( + fontFamily: + context.translate( + 'Roboto', + 'NotoKufi', + )), + ), + // backgroundColor: Colors.white, // Default background color + onDeleted: () { + setState(() { + selectedFilter[ + "filter_data"] + .remove(value); + }); + }, + ); + }).toList(), ), ), ), @@ -1953,7 +1974,8 @@ class _ChartScreen1State extends ConsumerState { print('locale22- $locale'); final isDark = currentTheme == ThemeMode.dark || (currentTheme == ThemeMode.system && - MediaQuery.of(context).platformBrightness == Brightness.dark); + MediaQuery.of(context).platformBrightness == + Brightness.dark); final themeMode = (isDark ? 'dark' : 'light'); @@ -1962,8 +1984,7 @@ class _ChartScreen1State extends ConsumerState { locale, tabWiseKpi, // Ensure you are passing the correct KPI here formattedFilters, // Pass the formatted filter data here - themeMode - ); + themeMode); Navigator.pop(context); }, style: ElevatedButton.styleFrom( @@ -1988,7 +2009,7 @@ class _ChartScreen1State extends ConsumerState { fontWeight: FontWeight.bold, ), overflow: - TextOverflow.ellipsis, // Prevents wrapping + TextOverflow.ellipsis, // Prevents wrapping maxLines: 1, // Ensures single line ), ), @@ -2001,7 +2022,8 @@ class _ChartScreen1State extends ConsumerState { print( "Selected Filters before applying: $selectedFilters"); - if (selectedFilters.every((filter) => filter['filter_data'].isEmpty)) { + if (selectedFilters.every( + (filter) => filter['filter_data'].isEmpty)) { setState(() { isLoading = true; }); @@ -2016,12 +2038,15 @@ class _ChartScreen1State extends ConsumerState { formattedFilters = []; final locale = - ref.watch(localeProvider)?.languageCode ?? 'en'; + ref.watch(localeProvider)?.languageCode ?? + 'en'; print('locale22- $locale'); final isDark = currentTheme == ThemeMode.dark || (currentTheme == ThemeMode.system && - MediaQuery.of(context).platformBrightness == Brightness.dark); + MediaQuery.of(context) + .platformBrightness == + Brightness.dark); final themeMode = (isDark ? 'dark' : 'light'); fetchChartData( @@ -2029,8 +2054,7 @@ class _ChartScreen1State extends ConsumerState { locale, tabWiseKpi, // Ensure you are passing the correct KPI here formattedFilters, // Pass the formatted filter data here - themeMode - ); + themeMode); Navigator.pop(context); } else { setState(() { @@ -2039,8 +2063,8 @@ class _ChartScreen1State extends ConsumerState { cardData = originalTabCardData; }); - applyFilters(context, filters, chartsData, cardData, - selectedFilters); + applyFilters(context, filters, chartsData, + cardData, selectedFilters); // selectedFiltersStorage = List.from(selectedFilters); } }, @@ -2069,7 +2093,7 @@ class _ChartScreen1State extends ConsumerState { fontWeight: FontWeight.bold, ), overflow: - TextOverflow.ellipsis, // Prevents wrapping + TextOverflow.ellipsis, // Prevents wrapping maxLines: 1, // Ensures single line ), ), @@ -2245,7 +2269,7 @@ class _ChartScreen1State extends ConsumerState { double calculateAspectRatio(int crossAxisCount, List cardData) { // Determine a default aspect ratio based on the most common chart type in the list if (cardData.any((item) => - item['chart_type'] == 'total' || item['chart_type'] == 'average')) { + item['chart_type'] == 'total' || item['chart_type'] == 'average')) { // return crossAxisCount == 1 ? 0.2 : (crossAxisCount > 2 ? 0.9 : 0.7); return crossAxisCount == 2 ? 1.0 : 0.7; // Larger Content // return crossAxisCount == 2 ? 1.5 : 0.9; @@ -2341,12 +2365,11 @@ class _ChartScreen1State extends ConsumerState { // return 1.0; // Default fallback (should never be reached) // } - @override Widget build(BuildContext context) { final locale = ref.watch(localeProvider); final localeNotifier = ref.read(localeProvider.notifier); - String url=GoRouterState.of(context).uri.toString(); + String url = GoRouterState.of(context).uri.toString(); final uri = Uri.parse(url); final pageTitle = uri.queryParameters['key'] ?? ''; @@ -2384,7 +2407,8 @@ class _ChartScreen1State extends ConsumerState { final List> safeFilterData = widget.filter_data ?? []; final String safeKpi = widget.kpi ?? ''; - fetchChartData(widget.dataSets, localeCode, safeKpi, safeFilterData,themeString) + fetchChartData( + widget.dataSets, localeCode, safeKpi, safeFilterData, themeString) .then((_) { print('DEBUG KPI: $safeKpi'); @@ -2430,7 +2454,8 @@ class _ChartScreen1State extends ConsumerState { final String safeKpi = widget.kpi ?? ''; /// 🔥 Call your API - fetchChartData(widget.dataSets, localeCode, safeKpi, safeFilterData, themeString) + fetchChartData( + widget.dataSets, localeCode, safeKpi, safeFilterData, themeString) .then((_) { print('DEBUG KPI: $safeKpi'); print('TAB11: $currentTab'); @@ -2455,10 +2480,10 @@ class _ChartScreen1State extends ConsumerState { mainTopic = chartScreenData['main_topic'] ?? ''; int crossAxisCount = - cardData.isNotEmpty ? (cardData.length / 2).ceil().clamp(1, 2) : 1; + cardData.isNotEmpty ? (cardData.length / 2).ceil().clamp(1, 2) : 1; final color = - Color(int.parse(widget.bgColor.replaceFirst('0x', ''), radix: 16)); + Color(int.parse(widget.bgColor.replaceFirst('0x', ''), radix: 16)); // Color bodyColor = Color( // int.parse( // (chartScreenData['body_color'] ?? '#898C81') @@ -2494,13 +2519,14 @@ class _ChartScreen1State extends ConsumerState { child: BaseScaffold( key: _scaffoldKey, title: (pageTitle == 'home') - ? Text(AppLocalizations.of(context)!.nav_home, - style: TextStyle( - fontFamily: context.translate( - 'Roboto', - 'NotoKufi', - ) - ),) + ? Text( + AppLocalizations.of(context)!.nav_home, + style: TextStyle( + fontFamily: context.translate( + 'Roboto', + 'NotoKufi', + )), + ) : Text( context.translate( 'UAE Numbers', @@ -2510,13 +2536,14 @@ class _ChartScreen1State extends ConsumerState { fontFamily: context.translate( 'Roboto', 'NotoKufi', - ) - ), + )), ), // appbarColor: Color(int.parse(widget.bgColor)), // Example color - appbarColor: Color(int.parse( - (chartScreenData['header_color'] ?? '#ffffff') - .replaceFirst('#', '0xff'))), + appbarColor: + isDarkTheme ? Colors.black : Colors.white, // Example color + // appbarColor: Color(int.parse( + // (chartScreenData['header_color'] ?? '#ffffff') + // .replaceFirst('#', '0xff'))), // Example color showBackButton: true, colorChange: true, @@ -2524,63 +2551,87 @@ class _ChartScreen1State extends ConsumerState { body: Stack(children: [ if (!isLoading) Container( - color: color, + // color: color, + color: isDarkTheme ? Colors.black54 : Colors.white, child: Column( children: [ Container( - // height: myheight / 5, + // height: myheight / 5, width: double.infinity, // color: color, - color: Color(int.parse( - (chartScreenData['header_color'] ?? '#898C81') - .replaceFirst('#', '0xff'))), + + color: isDarkTheme ? Colors.black : Colors.white, + // color: Color(int.parse( + // (chartScreenData['header_color'] ?? '#898C81') + // .replaceFirst('#', '0xff'))), child: Padding( padding: EdgeInsets.only( left: 30, right: 30, top: 8, bottom: 5), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - Text( - // widget.mainTopic ?? '', - // chartScreenData['main_topic'] ?? '', - mainTopic, - style: TextStyle( - color: Colors.white, - fontSize: 28, - fontWeight: FontWeight.w600, - fontFamily: context.translate( - 'Roboto', - 'NotoKufi', - ), - ), - ), Container( - width: mywidth / 7, - height: 1.5, - child: Divider( - thickness: 4, - color: Colors.white, - )), - Text( - // widget.title, - chartScreenData['data_set_tile_heading'] ?? '', - style: TextStyle( - color: Colors.white, + decoration: BoxDecoration( + color: Color(int.parse( + (chartScreenData['header_color'] ?? + '#898C81') + .replaceFirst('#', '0xff'))), + borderRadius: BorderRadius.only( + topLeft: Radius.circular(12.0), + topRight: Radius.circular(12.0), + ), + ), + width: double.infinity, + child: Center( + child: Text( + // widget.mainTopic ?? '', + // chartScreenData['main_topic'] ?? '', + mainTopic, + style: TextStyle( + color: Colors.white, + fontSize: 28, + fontWeight: FontWeight.w600, + fontFamily: context.translate( + 'Roboto', + 'NotoKufi', + ), + ), + ), + ), + ), + // Container( + // width: mywidth / 7, + // height: 1.5, + // child: Divider( + // thickness: 4, + // color: Colors.white, + // )), + Center( + child: Text( + // widget.title, + chartScreenData['data_set_tile_heading'] ?? + '', + style: TextStyle( + color: isDarkTheme + ? Colors.white + : Colors.black, fontSize: 20, fontWeight: FontWeight.w500, fontFamily: context.translate( - 'Roboto', - 'NotoKufi', - ), + 'Roboto', + 'NotoKufi', ), + ), + ), ), ], ), )), Container( - color: Color(int.parse( - (chartScreenData['header_color'] ?? '#898C81') - .replaceFirst('#', '0xff'))), + color: isDarkTheme ? Color(0xFF000000) : Colors.white, + // color: Color(int.parse( + // (chartScreenData['header_color'] ?? '#898C81') + // .replaceFirst('#', '0xff'))), child: Column( crossAxisAlignment: CrossAxisAlignment.end, children: [ @@ -2611,38 +2662,45 @@ class _ChartScreen1State extends ConsumerState { children: [ isBookmarked ? Text( - context.translate( - 'Bookmarked', - 'إشارة مرجعية', - ), - style: TextStyle( - fontFamily: context.translate( - 'Roboto', - 'NotoKufi', - ), - fontSize: 16, - color: Color(int.parse( - (chartScreenData[ - 'body_color'] ?? - '#898C81') - .replaceFirst( - '#', '0xff'))), - ), - ) + context.translate( + 'Bookmarked', + 'إشارة مرجعية', + ), + style: TextStyle( + fontFamily: + context.translate( + 'Roboto', + 'NotoKufi', + ), + fontSize: 16, + color: isDarkTheme + ? Colors.grey + : Color(0xFF416587), + // color: Color(int.parse( + // (chartScreenData[ + // 'body_color'] ?? + // '#898C81') + // .replaceFirst( + // '#', '0xff'))), + ), + ) : Text( - context.translate( - 'Bookmark', - 'إشارة مرجعية', - ), - style: TextStyle( - fontFamily: context.translate( - 'Roboto', - 'NotoKufi', - ), - fontSize: 16, - color: Colors.white, - ), - ), + context.translate( + 'Bookmark', + 'إشارة مرجعية', + ), + style: TextStyle( + fontFamily: + context.translate( + 'Roboto', + 'NotoKufi', + ), + fontSize: 16, + color: isDarkTheme + ? Colors.grey + : Color(0xFF416587), + ), + ), SizedBox(width: 5), // Text( @@ -2667,11 +2725,11 @@ class _ChartScreen1State extends ConsumerState { Icons.bookmarks_rounded, color: isBookmarked ? Color(int.parse( - (chartScreenData[ - 'body_color'] ?? - '#898C81') - .replaceFirst( - '#', '0xff'))) + (chartScreenData[ + 'body_color'] ?? + '#898C81') + .replaceFirst( + '#', '0xff'))) : Colors.white, ), ], @@ -2690,32 +2748,35 @@ class _ChartScreen1State extends ConsumerState { children: [ Text( context.translate('Share', 'يشارك'), - style:TextStyle( + style: TextStyle( fontFamily: context.translate( 'Roboto', 'NotoKufi', ), fontSize: 16, - color: Colors.white, + // color: Colors.white, + color: isDarkTheme + ? Colors.grey + : Color(0xFF416587), ), ), SizedBox(width: 5), _isSharing ? SizedBox( - width: 24, - height: 24, - child: - CircularProgressIndicator( - color: Colors.white, - strokeWidth: 2, - ), - ) // Show loading spinner + width: 24, + height: 24, + child: + CircularProgressIndicator( + color: Colors.white, + strokeWidth: 2, + ), + ) // Show loading spinner : SvgPicture.asset( - UaeNumbersAssetPath.share, - semanticsLabel: 'share', - width: 24, - height: 24, - ), + UaeNumbersAssetPath.share, + semanticsLabel: 'share', + width: 24, + height: 24, + ), ], ), ), @@ -2743,7 +2804,10 @@ class _ChartScreen1State extends ConsumerState { 'NotoKufi', ), fontSize: 16, - color: Colors.white, + // color: Colors.white, + color: isDarkTheme + ? Colors.grey + : Color(0xFF416587), ), ), SizedBox(width: 10), @@ -2774,9 +2838,19 @@ class _ChartScreen1State extends ConsumerState { ), Expanded( child: Container( - color: Color(int.parse( + // color: isDarkTheme ? Colors.black : Colors.white, + + color: isDarkTheme + ? Color(int.parse( + (chartScreenData['body_color'] ?? '#898C81') + .replaceFirst('#', '0xff'))) + : Color(int.parse( (chartScreenData['body_color'] ?? '#898C81') .replaceFirst('#', '0xff'))), + + // color: Color(int.parse( + // (chartScreenData['body_color'] ?? '#898C81') + // .replaceFirst('#', '0xff'))), child: Padding( padding: const EdgeInsets.all(10.0), child: ListView( @@ -2804,7 +2878,7 @@ class _ChartScreen1State extends ConsumerState { return _buildTab( _tabsData[index], isActive: - index == _activeTabIndex, + index == _activeTabIndex, ); }), ), @@ -2814,9 +2888,9 @@ class _ChartScreen1State extends ConsumerState { if (_tabsData.length > 1) _buildArrowButton( onPressed: - _activeTabIndex < _tabsData.length - 1 - ? _scrollRight - : null, + _activeTabIndex < _tabsData.length - 1 + ? _scrollRight + : null, icon: Icons.arrow_forward_ios, ), ], @@ -2851,7 +2925,7 @@ class _ChartScreen1State extends ConsumerState { child: CardWidget( card: card, chartScreenData: - chartScreenData, + chartScreenData, themeMode: themeMode)), ], )); @@ -2860,7 +2934,8 @@ class _ChartScreen1State extends ConsumerState { child: CardWidget( card: card, chartScreenData: - chartScreenData,themeMode: themeMode))); + chartScreenData, + themeMode: themeMode))); if (tempRow.length == 2) { rows.add(Row(children: tempRow)); tempRow = []; @@ -2885,20 +2960,32 @@ class _ChartScreen1State extends ConsumerState { shrinkWrap: true, physics: const NeverScrollableScrollPhysics(), itemBuilder: (context, index) { - final isDarkTheme = themeMode == ThemeMode.dark || - (themeMode == ThemeMode.system && - MediaQuery.of(context).platformBrightness == Brightness.dark); + final isDarkTheme = + themeMode == ThemeMode.dark || + (themeMode == ThemeMode.system && + MediaQuery.of(context) + .platformBrightness == + Brightness.dark); - final Map mainTopicColors = { - 'ECONOMY': Color(0xFF071F3B), - 'SOCIAL': Color(0xFF4F241B), - 'ENVIRONMENT': Color(0xFF16523C), - }; + // final Map mainTopicColors = { + // 'ECONOMY': Color(0xFF071F3B), + // 'SOCIAL': Color(0xFF4F241B), + // 'ENVIRONMENT': Color(0xFF16523C), + // }; - final String mainTopic = chartScreenData['main_topic']; - final Color backgroundColor = isDarkTheme - ? (mainTopicColors[mainTopic] ?? Colors.white) // fallback if key not found - : Colors.white; + final String mainTopic = + chartScreenData['main_topic']; + + final Color backgroundColor = Color(int.parse( + (chartScreenData['body_color'] ?? + '#898C81') + .replaceFirst('#', '0xff'))); + + // final Color backgroundColor = isDarkTheme + // ? (mainTopicColors[mainTopic] ?? + // Colors + // .white) // fallback if key not found + // : Colors.white; return Card( margin: const EdgeInsets.all(10), @@ -2908,8 +2995,8 @@ class _ChartScreen1State extends ConsumerState { color: Color( int.parse( (chartScreenData[ - 'border_color'] ?? - '#898C81') + 'border_color'] ?? + '#898C81') .replaceFirst('#', '0xff'), ), ), // Border color @@ -2923,21 +3010,21 @@ class _ChartScreen1State extends ConsumerState { padding: const EdgeInsets.all(16.0), child: Column( crossAxisAlignment: - CrossAxisAlignment.start, + CrossAxisAlignment.start, children: [ // ConstrainedBox Container( height: (chartsData[index][ - 'chart_height'] == - null || - chartsData[index][ - 'chart_height'] == - 0) + 'chart_height'] == + null || + chartsData[index][ + 'chart_height'] == + 0) ? 350 : double.tryParse( - chartsData[index] - ['chart_height'] - .toString()), + chartsData[index] + ['chart_height'] + .toString()), // height: (chartsData[index] // ['chart_type'] == // 'pie_chart') @@ -2960,9 +3047,10 @@ class _ChartScreen1State extends ConsumerState { // child: buildChart(chartsData[index]), child: ChartWidget( chartData: - chartsData[index], + chartsData[index], bodyColor: bodyColor, - chartHeader: chartHeader,isDarkTheme: isDarkTheme), + chartHeader: chartHeader, + isDarkTheme: isDarkTheme), ) ], ), @@ -2980,7 +3068,16 @@ class _ChartScreen1State extends ConsumerState { ), if (isLoading) Container( - color: isDarkTheme ? Colors.transparent : Color(0x98FFFCE5), // Semi-transparent background + // color: isDarkTheme + // ? Colors.transparent + // : Color(0x98FFFCE5), + + color: isDarkTheme + ? Colors.transparent + : Color(int.parse( + (chartScreenData['header_color'] ?? '#898C81') + .replaceFirst( + '#', '0xff'))), // Semi-transparent background child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ @@ -2989,7 +3086,9 @@ class _ChartScreen1State extends ConsumerState { horizontal: 40), // Left & Right space child: LinearProgressIndicator( minHeight: 5, // Adjust thickness - backgroundColor: isDarkTheme ? Colors.transparent : Colors.grey[100], // Optional: Background color + backgroundColor: isDarkTheme + ? Colors.transparent + : Colors.grey[100], // Optional: Background color valueColor: AlwaysStoppedAnimation( Color(0xFFAA8E83)), // Loader color ), @@ -3004,14 +3103,19 @@ class _ChartScreen1State extends ConsumerState { Widget _buildArrowButton( {required VoidCallback? onPressed, required IconData icon}) { final color = - Color(int.parse(widget.bgColor.replaceFirst('0x', ''), radix: 16)); + Color(int.parse(widget.bgColor.replaceFirst('0x', ''), radix: 16)); return Container( margin: EdgeInsets.symmetric(horizontal: 5.0), width: 30.0, // Set the width of the circle - height: 30.0, + height: 25.0, decoration: BoxDecoration( - color: onPressed == null ? Colors.grey[400] : Colors.white, - shape: BoxShape.circle, + // color: onPressed == null ? Colors.grey[400] : Colors.white, + color: onPressed == null + ? Color(int.parse((chartScreenData['header_color'] ?? '#898C81') + .replaceFirst('#', '0xff'))) + : Colors.grey[400], + shape: BoxShape.rectangle, + borderRadius: BorderRadius.circular(5.0), // boxShadow: [ // BoxShadow( // color: Colors.black26, @@ -3022,8 +3126,8 @@ class _ChartScreen1State extends ConsumerState { ), child: IconButton( onPressed: onPressed, - icon: Icon(icon, color: onPressed == null ? Colors.grey : color), - iconSize: 15.0, + icon: Icon(icon, color: onPressed == null ? Colors.white : Colors.grey), + iconSize: 12.5, ), ); } @@ -3039,10 +3143,14 @@ class _ChartScreen1State extends ConsumerState { }, child: Container( margin: EdgeInsets.symmetric(horizontal: 8.0), - padding: EdgeInsets.symmetric(vertical: 5.0, horizontal: 16.0), + padding: EdgeInsets.symmetric(vertical: 3.0, horizontal: 16.0), decoration: BoxDecoration( - color: isActive ? Colors.white : Colors.grey[400], - borderRadius: BorderRadius.circular(20.0), + // color: isActive ? Colors.white : Colors.grey[400], + color: isActive + ? Color(int.parse((chartScreenData['header_color'] ?? '#898C81') + .replaceFirst('#', '0xff'))) + : Colors.grey[400], + borderRadius: BorderRadius.circular(5.0), ), child: Text( tab['name']!, @@ -3061,8 +3169,6 @@ class _ChartScreen1State extends ConsumerState { } } - - // Function to convert hex color string to Color Color _getColorFromHex(String hexColor) { hexColor = hexColor.replaceFirst('#', ''); @@ -3078,7 +3184,10 @@ class CardWidget extends StatelessWidget { final themeMode; const CardWidget( - {Key? key, required this.card, required this.chartScreenData,required this.themeMode}) + {Key? key, + required this.card, + required this.chartScreenData, + required this.themeMode}) : super(key: key); @override @@ -3090,7 +3199,7 @@ class CardWidget extends StatelessWidget { final response = card['response'] as List? ?? []; final card_logo = card['card_logo']; double cardHeight = - (chart_type == 'totals' || chart_type == 'averages') ? 180.0 : 130.0; + (chart_type == 'totals' || chart_type == 'averages') ? 180.0 : 130.0; final bodyColor = Color( int.parse( @@ -3110,11 +3219,14 @@ class CardWidget extends StatelessWidget { }; final String mainTopic = chartScreenData['main_topic']; - final Color backgroundColor = isDarkTheme - ? (mainTopicColors[mainTopic] ?? Colors.white) // fallback if key not found - : Colors.white; + // final Color backgroundColor = isDarkTheme + // ? (mainTopicColors[mainTopic] ?? + // Colors.white) + final Color backgroundColor = Color(int.parse( + (chartScreenData['body_color'] ?? '#898C81') + .replaceFirst('#', '0xff'))); if (response.isEmpty) { return SizedBox.shrink(); @@ -3131,7 +3243,6 @@ class CardWidget extends StatelessWidget { // Dynamic border color width: 1, // Adjust border thickness ), - ), child: Card( margin: const EdgeInsets.all(0), @@ -3141,7 +3252,7 @@ class CardWidget extends StatelessWidget { elevation: 2, child: Container( // height: cardHeight, - height: 158 , + height: 158, padding: const EdgeInsets.only( left: 16.0, right: 16.0, bottom: 2.0, top: 1.0), decoration: BoxDecoration( @@ -3186,9 +3297,10 @@ class CardWidget extends StatelessWidget { style: TextStyle( color: Colors.white, fontFamily: context.translate( - 'Roboto', - 'NotoKufi', - ),), + 'Roboto', + 'NotoKufi', + ), + ), ), ), ), @@ -3203,7 +3315,7 @@ class CardWidget extends StatelessWidget { textAlign: TextAlign.center, maxLines: 2, overflow: - TextOverflow.ellipsis, // Truncate text with '...' + TextOverflow.ellipsis, // Truncate text with '...' style: TextStyle( fontFamily: context.translate( 'Roboto', @@ -3228,7 +3340,7 @@ class CardWidget extends StatelessWidget { fontSize: 11, color: Colors.grey, overflow: - TextOverflow.ellipsis, // Truncate if text overflows + TextOverflow.ellipsis, // Truncate if text overflows ), maxLines: 1, // Limit to one line to prevent overflow textAlign: TextAlign.center, // Ensure proper alignment @@ -3296,11 +3408,11 @@ class CardWidget extends StatelessWidget { decoration: BoxDecoration( color: backgroundColor, // Move color inside BoxDecoration borderRadius: - BorderRadius.circular(12), // Ensure border radius is applied + BorderRadius.circular(12), // Ensure border radius is applied ), child: Column( mainAxisSize: - MainAxisSize.min, // Adjust card height based on content + MainAxisSize.min, // Adjust card height based on content mainAxisAlignment: MainAxisAlignment.center, children: [ // const Icon(Icons.public, @@ -3332,14 +3444,14 @@ class CardWidget extends StatelessWidget { ), child: Text( chart_heading ?? 'NA', - style: - TextStyle( - color: Colors.white, - fontSize: 10, - fontFamily: context.translate( - 'Roboto', - 'NotoKufi', - ),), + style: TextStyle( + color: Colors.white, + fontSize: 10, + fontFamily: context.translate( + 'Roboto', + 'NotoKufi', + ), + ), ), ), ), @@ -3447,7 +3559,7 @@ class CardWidget extends StatelessWidget { ), textAlign: TextAlign.center, // Ensure proper alignment overflow: - TextOverflow.ellipsis, // Truncate if text overflows + TextOverflow.ellipsis, // Truncate if text overflows ), const SizedBox(width: 1), // Space between text and icon if (response[1]['font_color'] != '') ...[ @@ -3518,4 +3630,4 @@ class CardWidget extends StatelessWidget { // ), // ); } -} +} \ No newline at end of file diff --git a/lib/presentation/Screens/profilepage.dart b/lib/presentation/Screens/profilepage.dart index 183c3380..97cd1f2b 100644 --- a/lib/presentation/Screens/profilepage.dart +++ b/lib/presentation/Screens/profilepage.dart @@ -15,6 +15,7 @@ import 'package:shared_preferences/shared_preferences.dart'; import 'package:uae_stat/config/api_config.dart'; import 'package:uae_stat/config/connectivity_provider.dart'; import 'package:uae_stat/config/my_theme.dart'; +import 'package:uae_stat/config/theme/theme_provider.dart'; import 'package:uae_stat/domain/use_cases/language.dart'; import 'package:uae_stat/infrastructure/data/p_auth_repo.dart'; import 'package:uae_stat/infrastructure/services/img_asset_paths/icons/misc_icon_asset_path.dart'; @@ -83,6 +84,7 @@ class _ProfileScreenState extends ConsumerState { bool showError = false; final _picker = ImagePicker(); File? _profileImage; + late bool isDarkTheme; // Regular expression to validate Full Name (no special characters) final RegExp _nameRegExp = RegExp(r"^[a-zA-Z\s]+$"); @@ -96,6 +98,11 @@ class _ProfileScreenState extends ConsumerState { super.initState(); // print(widget.userId); + final themeMode = ref.read(themeProvider); + isDarkTheme = themeMode == ThemeMode.dark || + (themeMode == ThemeMode.system && + MediaQuery.of(context).platformBrightness == Brightness.dark); + // Add listeners for focus nodes for (int i = 0; i < _focusNodes.length; i++) { _focusNodes[i].addListener(() { @@ -515,6 +522,12 @@ class _ProfileScreenState extends ConsumerState { } }); final profileLocale = ref.watch(localeProvider); + + final themeMode = ref.read(themeProvider); + final isDarkTheme = themeMode == ThemeMode.dark || + (themeMode == ThemeMode.system && + MediaQuery.of(context).platformBrightness == Brightness.dark); + return PopScope( canPop: false, // Allow back navigation only if not login screen onPopInvokedWithResult: (didPop, result) { @@ -580,7 +593,7 @@ class _ProfileScreenState extends ConsumerState { ), body: SingleChildScrollView( child: Container( - color: Colors.white, + color: isDarkTheme ? Color(0xFF111111) : null, child: Form( key: _formKey, child: Padding( @@ -716,7 +729,7 @@ class _ProfileScreenState extends ConsumerState { 'Roboto', 'NotoKufi', ), - color: Color(0xFFC3C6CB), + color: isDarkTheme ? Colors.white : Color(0xFFC3C6CB), fontSize: 14, ), border: OutlineInputBorder( @@ -763,7 +776,7 @@ class _ProfileScreenState extends ConsumerState { enabledBorder: OutlineInputBorder( borderRadius: BorderRadius.circular(10), borderSide: BorderSide( - color: MyTheme.topicColor(IndicatorTopic.economy) + color: isDarkTheme ? Colors.white : MyTheme.topicColor(IndicatorTopic.economy) .shade400, width: 1), // Enabled border ), @@ -773,12 +786,12 @@ class _ProfileScreenState extends ConsumerState { 'Roboto', 'NotoKufi', ), - color: Color(0xFFC3C6CB), + color: isDarkTheme ? Colors.white : Color(0xFFC3C6CB), fontSize: 14, ), border: OutlineInputBorder( borderSide: BorderSide( - color: Color(0xFF7296BE), + color: isDarkTheme ? Colors.white : Color(0xFF7296BE), ), borderRadius: BorderRadius.circular(8), ), @@ -798,7 +811,9 @@ class _ProfileScreenState extends ConsumerState { 'Roboto', 'NotoKufi', ), - fontSize: 16, fontWeight: FontWeight.w500), + fontSize: 16, fontWeight: FontWeight.w500, + color:isDarkTheme ? Colors.white : null, + ), ), ], ), @@ -813,14 +828,14 @@ class _ProfileScreenState extends ConsumerState { enabledBorder: OutlineInputBorder( borderRadius: BorderRadius.circular(10), borderSide: BorderSide( - color: + color:isDarkTheme ? Colors.white : MyTheme.topicColor(IndicatorTopic.economy) .shade400, width: 1), // Enabled border ), border: OutlineInputBorder( borderSide: BorderSide( - color: Color(0xFF7296BE), + color:isDarkTheme ? Colors.white : Color(0xFF7296BE), ), borderRadius: BorderRadius.circular(8), ), @@ -831,7 +846,7 @@ class _ProfileScreenState extends ConsumerState { 'Roboto', 'NotoKufi', ), - color: Color(0xFFC3C6CB), + color: isDarkTheme ? Colors.white : Color(0xFFC3C6CB), fontSize: 14, ), @@ -863,7 +878,9 @@ class _ProfileScreenState extends ConsumerState { 'Roboto', 'NotoKufi', ), - fontSize: 16, fontWeight: FontWeight.w500), + fontSize: 16, fontWeight: FontWeight.w500, + color: isDarkTheme ? Colors.white : null + ), ), ], ), @@ -879,14 +896,14 @@ class _ProfileScreenState extends ConsumerState { enabledBorder: OutlineInputBorder( borderRadius: BorderRadius.circular(10), borderSide: BorderSide( - color: + color: isDarkTheme ? Colors.white : MyTheme.topicColor(IndicatorTopic.economy) .shade400, width: 1), // Enabled border ), border: OutlineInputBorder( borderSide: BorderSide( - color: Color(0xFF7296BE), + color: isDarkTheme ? Colors.white : Color(0xFF7296BE), ), borderRadius: BorderRadius.circular(8), ), @@ -903,7 +920,8 @@ class _ProfileScreenState extends ConsumerState { fontFamily: context.translate( 'Roboto', 'NotoKufi', - ) + ), + color: isDarkTheme ? Colors.white : null, ),), )) .toList(), @@ -926,7 +944,9 @@ class _ProfileScreenState extends ConsumerState { 'Roboto', 'NotoKufi', ), - fontSize: 16, fontWeight: FontWeight.w500), + fontSize: 16, fontWeight: FontWeight.w500, + color: isDarkTheme ? Colors.white : null, + ), ), ], ), @@ -942,14 +962,14 @@ class _ProfileScreenState extends ConsumerState { enabledBorder: OutlineInputBorder( borderRadius: BorderRadius.circular(10), borderSide: BorderSide( - color: + color: isDarkTheme ? Colors.white : MyTheme.topicColor(IndicatorTopic.economy) .shade400, width: 1), // Enabled border ), border: OutlineInputBorder( borderSide: BorderSide( - color: Color(0xFF7296BE), + color: isDarkTheme ? Colors.white : Color(0xFF7296BE), ), borderRadius: BorderRadius.circular(8), ), @@ -966,7 +986,8 @@ class _ProfileScreenState extends ConsumerState { fontFamily: context.translate( 'Roboto', 'NotoKufi', - ) + ), + color: isDarkTheme ? Colors.white : null, ),), )) .toList(), @@ -991,8 +1012,9 @@ class _ProfileScreenState extends ConsumerState { }, side: BorderSide( color: showError - ? Color(0xFFb22222) - : Color(0xFF7296BE), + ? isDarkTheme ? Color(0xFFFFA200) : Color(0xFFb22222) + : isDarkTheme ? Colors.white : Color(0xFF7296BE), + width: 1, ), ), @@ -1012,9 +1034,7 @@ class _ProfileScreenState extends ConsumerState { ), fontWeight: FontWeight.w500, fontSize: 14, - color: Color( - 0xFF898C81, - ), // Change to your desired color + color: isDarkTheme ? Colors.white : Color(0xFF898C81), // Change to your desired color ), children: [ TextSpan( @@ -1031,7 +1051,7 @@ class _ProfileScreenState extends ConsumerState { ), fontSize: 14, fontWeight: FontWeight.bold, - color: Color(0xFF985400), + color: isDarkTheme ? Color(0xFF9EB3E4) : Color(0xFF985400), // Makes the text bold // decoration: // TextDecoration.underline, @@ -1045,7 +1065,7 @@ class _ProfileScreenState extends ConsumerState { 'Roboto', 'NotoKufi', ), - color: Color( + color: isDarkTheme ? Colors.white : Color( 0xFF898C81), // Change to your desired color ), ), @@ -1062,7 +1082,7 @@ class _ProfileScreenState extends ConsumerState { 'Roboto', 'NotoKufi', ), - color: Color(0xFF985400), + color: isDarkTheme ? Color(0xFF9EB3E4) : Color(0xFF985400), // decoration: // TextDecoration.underline, decorationColor: Color(0xFF648CBA), @@ -1078,7 +1098,7 @@ class _ProfileScreenState extends ConsumerState { ), fontWeight: FontWeight.w500, fontSize: 14, - color: Color( + color: isDarkTheme ? Colors.white : Color( 0xFF898C81), // Change to your desired color ), ), @@ -1127,7 +1147,7 @@ class _ProfileScreenState extends ConsumerState { AppLocalizations.of(context)!.change_password, style: TextStyle( // color: Color(0xFF648CBA), - color: Color(0xFF985400), + color: isDarkTheme ? Color(0xFF9EB3E4) : Color(0xFF985400), fontSize: 14, fontWeight: FontWeight.w700, fontFamily: context.translate( @@ -1158,7 +1178,7 @@ class _ProfileScreenState extends ConsumerState { } }, style: ElevatedButton.styleFrom( - backgroundColor: Color(0xFF92722A), + backgroundColor: isDarkTheme ? Color(0xFF7296BE) :Color(0xFF92722A), minimumSize: Size(double.infinity, 50), shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(8), @@ -1196,10 +1216,15 @@ class _ProfileScreenState extends ConsumerState { } } -class ConfirmationDialog extends StatelessWidget { +class ConfirmationDialog extends ConsumerWidget { const ConfirmationDialog({Key? key}) : super(key: key); @override - Widget build(BuildContext context) { + Widget build(BuildContext context, WidgetRef ref) { + final themeMode = ref.read(themeProvider); + final isDarkTheme = themeMode == ThemeMode.dark || + (themeMode == ThemeMode.system && + MediaQuery.of(context).platformBrightness == Brightness.dark); + return AlertDialog( content: Column( mainAxisSize: MainAxisSize.min, @@ -1208,7 +1233,7 @@ class ConfirmationDialog extends StatelessWidget { AppLocalizations.of(context)!.sure_save_page, style: TextStyle( fontSize: 14, - color: Color(0xFF898C81), + color: isDarkTheme ? Colors.white : Color(0xFF898C81), fontFamily: context.translate( 'Roboto', 'NotoKufi', @@ -1223,7 +1248,7 @@ class ConfirmationDialog extends StatelessWidget { text: AppLocalizations.of(context)!.not_able_to_change, style: TextStyle( fontSize: 14, - color: Color(0xFF898C81), + color: isDarkTheme ? Colors.white : Color(0xFF898C81), fontFamily: context.translate( 'Roboto', 'NotoKufi', @@ -1237,10 +1262,13 @@ class ConfirmationDialog extends StatelessWidget { TextStyle(fontWeight: FontWeight.w700,fontFamily: context.translate( 'Roboto', 'NotoKufi', - ),), // Bold for "name" + ),color: isDarkTheme ? Colors.white : null), // Bold for "name" ), TextSpan( text: context.translate(' or ', 'أو'), + style: TextStyle( + color: isDarkTheme ? Colors.white : null, + ) ), TextSpan( text: AppLocalizations.of(context)!.dob, @@ -1249,10 +1277,15 @@ class ConfirmationDialog extends StatelessWidget { 'Roboto', 'NotoKufi', ), - fontWeight: FontWeight.w700), // Bold for "date of birth" + fontWeight: FontWeight.w700, + color: isDarkTheme ? Colors.white : null, + ), // Bold for "date of birth" ), TextSpan( text: ".", + style: TextStyle( + color: isDarkTheme ? Colors.white : null, + ) ), ], ), @@ -1276,14 +1309,14 @@ class ConfirmationDialog extends StatelessWidget { Navigator.of(context).pop(false); }, style: OutlinedButton.styleFrom( - side: BorderSide(color: Color(0xFF92722A)), + side: BorderSide(color: isDarkTheme ? Color(0xFF7296BE) : Color(0xFF92722A)), shape: RoundedRectangleBorder( borderRadius: BorderRadius.all(Radius.circular(7)), ), // Set the border color here ), child: Text( "Cancel", - style: TextStyle(color: Color(0xFF92722A),fontFamily: context.translate( + style: TextStyle(color: isDarkTheme ? Color(0xFF7296BE) : Color(0xFF92722A),fontFamily: context.translate( 'Roboto', 'NotoKufi', ),), @@ -1292,7 +1325,7 @@ class ConfirmationDialog extends StatelessWidget { ElevatedButton( onPressed: () => Navigator.of(context).pop(true), style: ElevatedButton.styleFrom( - backgroundColor: const Color(0xFF92722A), // Brown color + backgroundColor: isDarkTheme ? Color(0xFF7296BE) : Color(0xFF92722A), // Brown color foregroundColor: Colors.white, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(8), diff --git a/lib/presentation/components/themed_text_field.dart b/lib/presentation/components/themed_text_field.dart index a6feb982..7440e56c 100644 --- a/lib/presentation/components/themed_text_field.dart +++ b/lib/presentation/components/themed_text_field.dart @@ -59,19 +59,19 @@ class ThemedFormField extends HookWidget { 'Roboto', 'NotoKufi', ), - color: errorTextColor ?? const Color(0xFFB22222), + color: const Color(0xFFD83731), ), errorBorder: OutlineInputBorder( borderRadius: BorderRadius.circular(10), borderSide: BorderSide( - color: errorBorderColor ?? const Color(0xFFB22222), + color: const Color(0xFFD83731), width: 1, ), ), focusedErrorBorder: OutlineInputBorder( borderRadius: BorderRadius.circular(10), borderSide: BorderSide( - color: errorBorderColor ?? const Color(0xFFB22222), + color: const Color(0xFFD83731), width: 1, ), ), @@ -81,18 +81,18 @@ class ThemedFormField extends HookWidget { border: OutlineInputBorder( borderRadius: BorderRadius.circular(10), borderSide: BorderSide( - color: borderColor ?? MyTheme.topicColor(IndicatorTopic.economy).shade300, + color: Color(0xFFB68A34), ), ), enabledBorder: OutlineInputBorder( borderRadius: BorderRadius.circular(10), borderSide: BorderSide( - color: borderColor ?? MyTheme.topicColor(IndicatorTopic.economy).shade300, + color: Color(0xFFB68A34), ), ), hintText: hintText, hintStyle: TextStyle( // ✅ dynamic hint color - color: hintColor ?? const Color(0xffC3C6CB), + color: const Color(0xFFC3C6CB), ), prefixIconConstraints: const BoxConstraints( maxWidth: 25 + 16 + 10, @@ -108,7 +108,7 @@ class ThemedFormField extends HookWidget { fit: BoxFit.fitHeight, height: 25, width: 25, - color: MyTheme.topicColor(IndicatorTopic.economy).shade300, + // color: MyTheme.topicColor(IndicatorTopic.economy).shade300, ), ), suffixIcon: isObscurable ? obscureBtn : null, diff --git a/lib/presentation/routes/auth_routes/login_route.dart b/lib/presentation/routes/auth_routes/login_route.dart index 3f549795..004117d3 100644 --- a/lib/presentation/routes/auth_routes/login_route.dart +++ b/lib/presentation/routes/auth_routes/login_route.dart @@ -553,7 +553,7 @@ class LoginRoute extends HookConsumerWidget { ), fontWeight: FontWeight.bold, fontSize: locale?.languageCode == 'ar' ? 12 : 14, - color: isDarkTheme ? Color(0xFF9EB3E4) : Color(0xFF985400), + color: Color(0xFF8A8C81), ), ), ); @@ -735,7 +735,8 @@ class LoginRoute extends HookConsumerWidget { ), ), backgroundColor: WidgetStatePropertyAll( - isDarkTheme ? Color(0xFF24B4FB) : Color(0xFFAA8E83), + // isDarkTheme ? Color(0xFFB68A34) : Color(0xFFB68A34), + Color(0xFFB68A34), // MyTheme.topicColor(IndicatorTopic.social), ), // surfaceTintColor: MaterialStatePropertyAll( @@ -781,11 +782,11 @@ class LoginRoute extends HookConsumerWidget { 'Email', 'بريد إلكتروني', ), - hintColor: isDarkTheme ? Color(0XFFEEEEEE) : Color(0xFFC3C6CB), + // hintColor: isDarkTheme ? Color(0XFFEEEEEE) : Color(0xFFC3C6CB), backgroundColor: isDarkTheme ? Color(0xFF000000) : Colors.white, - borderColor: isDarkTheme ? Colors.white : MyTheme.topicColor(IndicatorTopic.economy).shade300, - errorBorderColor: isDarkTheme ? const Color(0xFFFFA100) : const Color(0xFFB22222), - errorTextColor: isDarkTheme ? const Color(0xFFFFA100) : const Color(0xFFB22222), + // borderColor: Color(0xFFB68A34), + // errorBorderColor: isDarkTheme ? const Color(0xFFFFA100) : const Color(0xFFB22222), + // errorTextColor: isDarkTheme ? const Color(0xFFFFA100) : const Color(0xFFB22222), validator: (value) { final emailRegex = r'^[a-zA-Z0-9àèìòùÀÈÌÒÙéàç~!#$%^&*()_+=-{}|;,.?<>]+@[a-zA-Z0-9àèìòùÀÈÌÒÙéàç~!#$%^&*()_+=-{}|;,.?<>]+\.[a-zA-Z]{2,}$'; @@ -796,7 +797,8 @@ class LoginRoute extends HookConsumerWidget { } return null; }, - imgPath: isDarkTheme ? MiscIconAssetPath.personDark : MiscIconAssetPath.personLight, + // imgPath: isDarkTheme ? MiscIconAssetPath.personDark : MiscIconAssetPath.personLight, + imgPath: MiscIconAssetPath.person, controller: emailCtl, ), 15.verticalSpace, @@ -813,12 +815,13 @@ class LoginRoute extends HookConsumerWidget { 'Password', 'كلمة المرور', ), - hintColor: isDarkTheme ? Color(0XFFEEEEEE) : Color(0xFFC3C6CB), + // hintColor: isDarkTheme ? Color(0XFFEEEEEE) : Color(0xFFC3C6CB), backgroundColor: isDarkTheme ? Color(0xFF000000) : Colors.white, - borderColor: isDarkTheme ? Colors.white : MyTheme.topicColor(IndicatorTopic.economy).shade300, - errorBorderColor: isDarkTheme ? const Color(0xFFFFA100) : const Color(0xFFB22222), - errorTextColor: isDarkTheme ? const Color(0xFFFFA100) : const Color(0xFFB22222), - imgPath: isDarkTheme ? MiscIconAssetPath.lockDark : MiscIconAssetPath.lockLight, + // borderColor: isDarkTheme ? Colors.white : MyTheme.topicColor(IndicatorTopic.economy).shade300, + // errorBorderColor: isDarkTheme ? const Color(0xFFFFA100) : const Color(0xFFB22222), + // errorTextColor: isDarkTheme ? const Color(0xFFFFA100) : const Color(0xFFB22222), + // imgPath: isDarkTheme ? MiscIconAssetPath.lockDark : MiscIconAssetPath.lockLight, + imgPath: MiscIconAssetPath.lock, controller: pwCtl, isObscurable: true, ), @@ -865,7 +868,7 @@ class LoginRoute extends HookConsumerWidget { 'NotoKufi', ), fontSize: context.translate(18.0, 14.0), - color: isDarkTheme ? Color(0xFFEEEEEE) : Color(0xff898C81), + color: isDarkTheme ? Color(0xFFFFFFFF) : Color(0xFF898C81), fontWeight: FontWeight.w600, ), ), @@ -894,7 +897,7 @@ class LoginRoute extends HookConsumerWidget { ), style: TextStyle( fontSize: locale?.languageCode == 'ar' ? 12 : 14, - color: isDarkTheme ? Color(0xFFCCCCCC) : Color(0xff898C81), + color: isDarkTheme ? Color(0xFFFFFFFF) : Color(0xFF898C81), ), ), const TextSpan( @@ -907,7 +910,7 @@ class LoginRoute extends HookConsumerWidget { ), style: TextStyle( fontSize: locale?.languageCode == 'ar' ? 12 : 14, - color: isDarkTheme ? Color(0xFF9EB3E4) : Color(0xFF985400), + color: isDarkTheme ? Color(0xFFB68A35) : Color(0xFF985400), ), ), ], @@ -918,13 +921,13 @@ class LoginRoute extends HookConsumerWidget { // width: double.infinity, // child: ElevatedButton( // onPressed: () async { - // final prefs = await SharedPreferences.getInstance(); - // prefs.clear(); - // final userId = 'guest'; - // if (userId.isNotEmpty) { - // await saveUserId(userId); - // } - // context.go('/myhomepage'); + // // final prefs = await SharedPreferences.getInstance(); + // // prefs.clear(); + // // final userId = 'guest'; + // // if (userId.isNotEmpty) { + // // await saveUserId(userId); + // // } + // // context.go('/myhomepage'); // //context.go('/${context.language}/${BottomNavBarItem.home.routePath}'), // }, // //context.go('/${context.language}/${BottomNavBarItem.home.routePath}'), @@ -969,6 +972,120 @@ class LoginRoute extends HookConsumerWidget { // ), // ), // ); + final signInWithGoogleBtn = SizedBox( + width: double.infinity, + child: OutlinedButton( + onPressed: () async {}, + style: OutlinedButton.styleFrom( + side: const BorderSide(color: Color(0xFF000000)), + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(8), + ), + padding: const EdgeInsets.symmetric(vertical: 12), + backgroundColor: Colors.white, + foregroundColor: Colors.black, + textStyle: TextStyle( + fontFamily: context.translate('Roboto', 'NotoKufi'), + fontSize: 16, + fontWeight: FontWeight.w500, + ), + ), + child: Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Image.asset( + MiscIconAssetPath.signInWithGoogle, // replace with your Google icon asset + height: 20, + ), + const SizedBox(width: 10), + Text( + 'Sign in with Google', + textAlign: TextAlign.center, + style: TextStyle( + color: Color(0xFF000000), + fontWeight: FontWeight.w600, + ), + ), + ], + ), + ), + ); + final signInWithAppleBtn = SizedBox( + width: double.infinity, + child: OutlinedButton( + onPressed: () async {}, + style: OutlinedButton.styleFrom( + side: const BorderSide(color: Color(0xFF000000)), + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(8), + ), + padding: const EdgeInsets.symmetric(vertical: 12), + backgroundColor: Colors.white, + foregroundColor: Colors.black, + textStyle: TextStyle( + fontFamily: context.translate('Roboto', 'NotoKufi'), + fontSize: 16, + fontWeight: FontWeight.w500, + ), + ), + child: Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Image.asset( + MiscIconAssetPath.signInWithApple, // replace with your Google icon asset + height: 20, + ), + const SizedBox(width: 10), + Text( + 'Sign in with Apple', + textAlign: TextAlign.center, + style: TextStyle( + color: Color(0xFF000000), + fontWeight: FontWeight.w600, + ), + ), + ], + ), + ), + ); + final signInWithUAEPassBtn = SizedBox( + width: double.infinity, + child: OutlinedButton( + onPressed: () async {}, + style: OutlinedButton.styleFrom( + side: const BorderSide(color: Color(0xFF000000)), + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(8), + ), + padding: const EdgeInsets.symmetric(vertical: 12), + backgroundColor: Colors.white, + foregroundColor: Colors.black, + textStyle: TextStyle( + fontFamily: context.translate('Roboto', 'NotoKufi'), + fontSize: 16, + fontWeight: FontWeight.w500, + ), + ), + child: Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Image.asset( + MiscIconAssetPath.signInWithUAEPass, // replace with your Google icon asset + height: 20, + ), + const SizedBox(width: 10), + Text( + 'Sign in with UAE PASS', + textAlign: TextAlign.center, + style: TextStyle( + color: Color(0xFF000000), + fontWeight: FontWeight.w600, + ), + ), + ], + ), + ), + ); final fcscBanner = Image.asset( isDarkTheme ? BannerAssetPath.fcscLogoDark @@ -1010,11 +1127,16 @@ class LoginRoute extends HookConsumerWidget { helloAndPleaseLoginTexts, 40.verticalSpace, form, - 15.verticalSpace, + 25.verticalSpace, dontHaveAnAccountRegisterBtn, // continueAsGuestBtn, - // Spacer(), + 25.verticalSpace, + signInWithGoogleBtn, 15.verticalSpace, + signInWithAppleBtn, + 15.verticalSpace, + signInWithUAEPassBtn, + 25.verticalSpace, fcscBanner, ], ), @@ -1034,7 +1156,7 @@ class LoginRoute extends HookConsumerWidget { // _showExitConfirmation(context); // Show exit confirmation dialog }, child: Scaffold( - backgroundColor: isDarkTheme ? Color(0xFF111111) : Colors.white, + backgroundColor: isDarkTheme ? Color(0xFF000000) : Colors.white, body: SafeArea(child: scaffoldBody), ), ); diff --git a/lib/presentation/routes/bottom_bar_routes/tab_routes/home_route.dart b/lib/presentation/routes/bottom_bar_routes/tab_routes/home_route.dart index 7c62d61c..e8b3db4f 100644 --- a/lib/presentation/routes/bottom_bar_routes/tab_routes/home_route.dart +++ b/lib/presentation/routes/bottom_bar_routes/tab_routes/home_route.dart @@ -1284,14 +1284,15 @@ class EconomyStatsState extends ConsumerState { } String firstMainTopic = data.first['main_topic'] ?? ''; return Container( - decoration: isDarkTheme - ? BoxDecoration( - image: DecorationImage( - image: AssetImage('assets/dark_bg.png'), - fit: BoxFit.cover, - ), - ) - : null, + color: isDarkTheme ? Color(0xFF000000) : Color(0xFFFFFFFF), + // decoration: isDarkTheme + // ? BoxDecoration( + // image: DecorationImage( + // image: AssetImage('assets/dark_bg.png'), + // fit: BoxFit.cover, + // ), + // ) + // : null, height: myheight, // color: Colors.cyan, child: Padding( @@ -1523,7 +1524,7 @@ class RoundedCornerContainer extends StatelessWidget { return Container( decoration: BoxDecoration( color: backgroundColor, - borderRadius: BorderRadius.circular(16), // Rounded corners + borderRadius: BorderRadius.only(topRight: Radius.circular(20),topLeft: Radius.circular(20)), // Rounded corners ), child: Center( child: Text( @@ -1603,7 +1604,7 @@ class InfoCard extends StatelessWidget { decoration: BoxDecoration( color: isDarkTheme ? Color(0xFF111111) : null, border: Border.all(color: bordercolor), - borderRadius: BorderRadius.circular(8), + borderRadius: BorderRadius.circular(10), ), child: Column( mainAxisSize: MainAxisSize.min, @@ -1634,7 +1635,7 @@ class InfoCard extends StatelessWidget { title, style: TextStyle( fontSize: 13, - fontWeight: FontWeight.w400, + fontWeight: FontWeight.w700, letterSpacing: 0, // color: Colors.black, fontFamily: context.translate( diff --git a/lib/presentation/routes/drawer_routes/Drawer Items/bookmark.dart b/lib/presentation/routes/drawer_routes/Drawer Items/bookmark.dart index 568ae1ab..3c57bc86 100644 --- a/lib/presentation/routes/drawer_routes/Drawer Items/bookmark.dart +++ b/lib/presentation/routes/drawer_routes/Drawer Items/bookmark.dart @@ -1,8 +1,11 @@ +import 'dart:convert'; + import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:flutter_svg/svg.dart'; import 'package:go_router/go_router.dart'; import 'package:dio/dio.dart'; +import 'package:http/http.dart' as http; import 'package:flutter_gen/gen_l10n/app_localizations.dart'; import 'package:pocketbase/pocketbase.dart'; import 'package:shared_preferences/shared_preferences.dart'; @@ -13,6 +16,7 @@ import 'package:uae_stat/config/toggle_lang_service.dart'; import 'package:uae_stat/domain/use_cases/language.dart'; import 'package:uae_stat/infrastructure/services/img_asset_paths/icons/bookmark_asset_path.dart'; import 'package:uae_stat/infrastructure/services/img_asset_paths/icons/uae_numbers_asset_path.dart'; +// import 'package:uae_stat/l10n/app_localizations.dart'; import 'package:uae_stat/presentation/components/indicators/locale_provider.dart'; import 'package:uae_stat/presentation/routes/drawer_routes/custom_drawer_routes.dart'; @@ -29,11 +33,14 @@ class _BookMarkState extends ConsumerState { bool isLoading = true; Map> groupedMap = {}; int? expandedIndex = 0; - // Current selected tab index +// Current selected tab index int selectedTabIndex = 0; late UserService _userService; late ThemeMode currentTheme; + List homePageData = []; + List filteredData = []; + @override void initState() { super.initState(); @@ -42,13 +49,44 @@ class _BookMarkState extends ConsumerState { currentTheme = ref.read(themeProvider); print('123456789'); print(currentTheme); - final isDark = currentTheme == ThemeMode.dark || - (currentTheme == ThemeMode.system && - MediaQuery.of(context).platformBrightness == Brightness.dark); +// final isDark = currentTheme == ThemeMode.dark || +// (currentTheme == ThemeMode.system && +// MediaQuery.of(context).platformBrightness == Brightness.dark); - final themeMode = (isDark ? 'dark' : 'light'); + WidgetsBinding.instance.addPostFrameCallback((_) { + final isDark = currentTheme == ThemeMode.dark || + (currentTheme == ThemeMode.system && + MediaQuery.of(context).platformBrightness == Brightness.dark); - fetchBookmarks(locale?.languageCode ?? 'en',themeMode); + final themeMode = (isDark ? 'dark' : 'light'); + print("ThemeMode - $themeMode"); + fetchData(locale?.languageCode ?? 'en', themeMode); + fetchBookmarks(locale?.languageCode ?? 'en', themeMode); + }); + } + + Future fetchData(locale, themeMode) async { + const baseUrl = '$apiUrl/api/getUAENumbersData'; + try { + final response = await http + .get(Uri.parse(baseUrl + '?language=$locale&color_mode=$themeMode')); + if (response.statusCode == 200) { + setState(() { + homePageData = (json.decode(response.body) as List) + .map((e) => Map.from(e)) + .toList(); + filteredData = List.from(homePageData); + isLoading = false; + }); + } else { + throw Exception('Failed to load data'); + } + } catch (e) { + setState(() { + isLoading = false; + }); + print('Error fetching data: $e'); + } } String colorToHex(Color color) { @@ -57,7 +95,7 @@ class _BookMarkState extends ConsumerState { '${color.blue.toRadixString(16).padLeft(2, '0').toUpperCase()}'; } - // Function to convert hex color string to int +// Function to convert hex color string to int Color _parseColor(String? colorString) { if (colorString == null || colorString.isEmpty) { return const Color(0xFF80A8CD); // Default color @@ -71,7 +109,7 @@ class _BookMarkState extends ConsumerState { } } - Future fetchBookmarks(locale,themeMode) async { + Future fetchBookmarks(locale, themeMode) async { try { final prefs = await SharedPreferences.getInstance(); final userID = prefs.getString('userId') ?? ''; @@ -85,13 +123,17 @@ class _BookMarkState extends ConsumerState { final response = await Dio().get( '$apiUrl/api/getUserBookmark', - queryParameters: {'user_id': userID, 'language': locale,'color_mode':themeMode}, + queryParameters: { + 'user_id': userID, + 'language': locale, + 'color_mode': themeMode + }, ); if (response.statusCode == 200 && response.data != null) { if (response.data is Map && response.data.containsKey("error")) { - // API returned an error message instead of bookmark data +// API returned an error message instead of bookmark data setState(() { dataList = []; // Clear the list }); @@ -117,24 +159,24 @@ class _BookMarkState extends ConsumerState { List> transformAndStore( List> fetchedData) { - // Define the required order +// Define the required order List order = [ context.translate('ECONOMY', 'الاقتصاد'), context.translate('SOCIAL', 'الاجتماعي'), context.translate('ENVIRONMENT', 'البيئة') ]; - // Create a list to store sorted data +// Create a list to store sorted data List> sortedList = []; - // Group data based on categories +// Group data based on categories Map>> groupedData = { context.translate('ECONOMY', 'الاقتصاد'): [], context.translate('SOCIAL', 'الاجتماعي'): [], context.translate('ENVIRONMENT', 'البيئة'): [] }; - // Categorize data +// Categorize data for (var item in fetchedData) { String mainTopic = item["main_topic"]?.toString() ?? ""; if (groupedData.containsKey(mainTopic)) { @@ -142,14 +184,14 @@ class _BookMarkState extends ConsumerState { } } - // Store sorted data in the correct order +// Store sorted data in the correct order for (String topic in order) { if (groupedData.containsKey(topic)) { sortedList.addAll(groupedData[topic]!); } } - // Store the sorted list (replace this with your storage method) +// Store the sorted list (replace this with your storage method) return sortedList; } @@ -158,10 +200,10 @@ class _BookMarkState extends ConsumerState { String? mainTopic = item['main_topic']; String subtitle = item['subtitle']; - // Ignore if main_topic is null +// Ignore if main_topic is null if (mainTopic == null) continue; - // If main_topic doesn't exist in groupedMap, create a new entry +// If main_topic doesn't exist in groupedMap, create a new entry if (!groupedMap.containsKey(mainTopic)) { groupedMap[mainTopic] = { 'main_topic': mainTopic, @@ -170,7 +212,7 @@ class _BookMarkState extends ConsumerState { }; } - // Add subtitle as a key with its corresponding map value +// Add subtitle as a key with its corresponding map value groupedMap[mainTopic]!['SubTopic'].add({ 'subtitle': subtitle, 'isBookmark': item['isBookmark'], @@ -208,9 +250,9 @@ class _BookMarkState extends ConsumerState { 'Authorization': adminToken, }); - // currentTheme = ref.read(themeProvider); - // print('123456789'); - // print(currentTheme); +// currentTheme = ref.read(themeProvider); +// print('123456789'); +// print(currentTheme); final isDark = currentTheme == ThemeMode.dark || (currentTheme == ThemeMode.system && MediaQuery.of(context).platformBrightness == Brightness.dark); @@ -219,8 +261,8 @@ class _BookMarkState extends ConsumerState { final locale = ref.read(localeProvider); - fetchBookmarks(locale?.languageCode ?? 'en',themeMode); - // ToastUtil.showSuccessToast("Removed from Bookmark."); + fetchBookmarks(locale?.languageCode ?? 'en', themeMode); +// ToastUtil.showSuccessToast("Removed from Bookmark."); ScaffoldMessenger.of(context).showSnackBar( SnackBar( @@ -228,10 +270,9 @@ class _BookMarkState extends ConsumerState { AppLocalizations.of(context)!.removed_from_Bookmark, style: TextStyle( fontFamily: context.translate( - 'Roboto', - 'NotoKufi', - ) - ), + 'Roboto', + 'NotoKufi', + )), ), duration: Duration(seconds: 2), ), @@ -242,13 +283,17 @@ class _BookMarkState extends ConsumerState { SnackBar( content: Text( context.translate( - 'Unable to remove from bookmarks. Please try again', - 'تعذر الإزالة من الإشارات المرجعية. يرجى المحاولة مرة أخرى.',), - style: - TextStyle(color: Color(0xFFEB5F24), fontWeight: FontWeight.w600, fontFamily: context.translate( - 'Roboto', - 'NotoKufi', - ),), + 'Unable to remove from bookmarks. Please try again', + 'تعذر الإزالة من الإشارات المرجعية. يرجى المحاولة مرة أخرى.', + ), + style: TextStyle( + color: Color(0xFFEB5F24), + fontWeight: FontWeight.w600, + fontFamily: context.translate( + 'Roboto', + 'NotoKufi', + ), + ), ), backgroundColor: Color(0xFFD6E9C6), duration: Duration(seconds: 2), @@ -349,11 +394,14 @@ class _BookMarkState extends ConsumerState { ), child: Text( context.translate('Yes', 'نعم'), - style: TextStyle(color: Colors.white, fontSize: 16, + style: TextStyle( + color: Colors.white, + fontSize: 16, fontFamily: context.translate( 'Roboto', 'NotoKufi', - ),), + ), + ), ), ), ), @@ -372,25 +420,6 @@ class _BookMarkState extends ConsumerState { } }); - final List> tabs = [ - { - 'title': AppLocalizations.of(context)!.all_bookmarks, - 'color': Colors.black - }, - { - 'title': AppLocalizations.of(context)!.economy_title, - 'color': Color(0xFF90B0D5) - }, - { - 'title': AppLocalizations.of(context)!.social_title, - 'color': Color(0xFFAA8E83) - }, - { - 'title': AppLocalizations.of(context)!.environment_title, - 'color': Color(0xFF7DAFBC) - }, - ]; - ref.listen(localeProvider, (previous, next) async { final localeCode = next?.languageCode ?? 'en'; // Default to 'en' if null setState(() { @@ -405,14 +434,14 @@ class _BookMarkState extends ConsumerState { final themeString = isDark ? 'dark' : 'light'; - fetchBookmarks(localeCode,themeString); + fetchBookmarks(localeCode, themeString); }); ref.listen(themeProvider, (previous, next) async { final localeCode = ref.watch(localeProvider)?.languageCode ?? 'en'; print(localeCode); - // Default to 'en' if null +// Default to 'en' if null setState(() { isLoading = true; print('isLoadingref $isLoading'); @@ -424,13 +453,31 @@ class _BookMarkState extends ConsumerState { MediaQuery.of(context).platformBrightness == Brightness.dark); final themeString = isDark ? 'dark' : 'light'; - fetchBookmarks(localeCode,themeString); + fetchBookmarks(localeCode, themeString); }); final isDarkTheme = ref.watch(themeProvider) == ThemeMode.dark || (ref.watch(themeProvider) == ThemeMode.system && MediaQuery.of(context).platformBrightness == Brightness.dark); + final List> tabs = [ + { + 'title': AppLocalizations.of(context)!.all_bookmarks, + 'color': isDarkTheme ? Colors.white : Colors.black, + }, + { + 'title': AppLocalizations.of(context)!.economy_title, + 'color': isDarkTheme ? Color(0xFF89AFD8) : Color(0xFF89AFD8) + }, + { + 'title': AppLocalizations.of(context)!.social_title, + 'color': isDarkTheme ? Color(0xFF675863) : Color(0xFF675863) + }, + { + 'title': AppLocalizations.of(context)!.environment_title, + 'color': isDarkTheme ? Color(0xFFB3CF99) : Color(0xFFB3CF99) + }, + ]; List> bookmarks = dataList.where((item) => item['isBookmark'] == true).toList(); @@ -439,13 +486,13 @@ class _BookMarkState extends ConsumerState { String selectedTabTitle = tabs[selectedTabIndex]['title'].toString().trim().toLowerCase(); - // Debugging prints +// Debugging prints print( "main_topic: '$mainTopic', selected_tab_title: '$selectedTabTitle'"); return mainTopic == selectedTabTitle; }).toList(); - // print( 'filtered one :${filteredBookmarks['main_topic']} , Tabs : ${tabs[selectedTabIndex]["title"]}'); +// print( 'filtered one :${filteredBookmarks['main_topic']} , Tabs : ${tabs[selectedTabIndex]["title"]}'); List> transformedList = groupedMap.values.toList(); print('filtered $filteredBookmarks'); return PopScope( @@ -455,19 +502,21 @@ class _BookMarkState extends ConsumerState { context.go('/myhomepage'); }, child: BaseScaffold( + backgroundColor: isDarkTheme ? Color(0xFF111111) : Colors.white, + appbarColor: isDarkTheme ? Color(0xFF111111) : Colors.white, title: Text( AppLocalizations.of(context)!.bookmarks, style: TextStyle( - color: isDarkTheme ? Colors.white : Colors.black, + color: isDarkTheme ? Colors.white : Colors.black, fontFamily: context.translate( 'Roboto', 'NotoKufi', - ) - ), + )), ), body: isLoading ? Container( - color: Color(0x98FFFCE5), // Semi-transparent background + color: isDarkTheme ? Color(0xFF111111) : Colors.white, +// color: Color(0x98FFFCE5), // Semi-transparent background child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ @@ -488,21 +537,21 @@ class _BookMarkState extends ConsumerState { : Column( children: [ TabBarHeader( - tabs: tabs, - selectedIndex: selectedTabIndex, - onTabSelected: (index) { - setState(() { - selectedTabIndex = index; - }); - }, - ), + tabs: tabs, + selectedIndex: selectedTabIndex, + onTabSelected: (index) { + setState(() { + selectedTabIndex = index; + }); + }, + isDarkTheme: isDarkTheme), Expanded( child: selectedTabIndex == 0 ? (bookmarks.isNotEmpty ? SingleChildScrollView( child: Column( - children: - List.generate(transformedList.length, (i) { + children: List.generate( + transformedList.length, (i) { final mainTopic = transformedList[i]; print('oustside1 $mainTopic'); final list = @@ -512,24 +561,28 @@ class _BookMarkState extends ConsumerState { index: i, isExpanded: expandedIndex == i, onTap: (int index) { - // 🔹 Expecting an index +// 🔹 Expecting an index setState(() { - expandedIndex = (expandedIndex == index) - ? null - : index; + expandedIndex = + (expandedIndex == index) + ? null + : index; }); }, title: mainTopic['main_topic'] ?? 'No Topic', childWidget: Container( decoration: BoxDecoration( - color: Colors.white, - // borderRadius: BorderRadius.all(Radius.circular(20)) + color: isDarkTheme + ? Color(0xFF111111) + : Colors.white, +// borderRadius: BorderRadius.all(Radius.circular(20)) ), padding: const EdgeInsets.all(16), child: GridView.builder( shrinkWrap: true, - physics: NeverScrollableScrollPhysics(), + physics: + NeverScrollableScrollPhysics(), gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount( crossAxisCount: 2, @@ -542,15 +595,17 @@ class _BookMarkState extends ConsumerState { return _buildBoxes( mainTopic['SubTopic'][index], context, - mainTopic['valueColor']); + mainTopic['valueColor'], + isDarkTheme); }, ), ), - filteredBookmarks: - List.from(mainTopic['SubTopic'] ?? []), + filteredBookmarks: List.from( + mainTopic['SubTopic'] ?? []), titleBackgroundColor: mainTopic['valueColor'], - // Ensure it's a new list +// Ensure it's a new list + isDarkTheme: isDarkTheme, ); }), ), @@ -566,11 +621,12 @@ class _BookMarkState extends ConsumerState { context.translate('No BookMark Added', 'لم يتم إضافة أي علامة مرجعية'), style: TextStyle( - fontFamily: context.translate( - 'Roboto', - 'NotoKufi', + fontFamily: context.translate( + 'Roboto', + 'NotoKufi', ), - fontSize: 16, color: Colors.grey), + fontSize: 16, + color: Colors.grey), ), ], ), @@ -587,7 +643,8 @@ class _BookMarkState extends ConsumerState { context.translate('No BookMark Added', 'لم يتم إضافة أي علامة مرجعية'), style: TextStyle( - fontSize: 16, color: Colors.grey, + fontSize: 16, + color: Colors.grey, fontFamily: context.translate( 'Roboto', 'NotoKufi', @@ -603,11 +660,15 @@ class _BookMarkState extends ConsumerState { children: [ Container( decoration: BoxDecoration( - color: tabs[selectedTabIndex]['color'], + color: tabs[selectedTabIndex] + ['color'], borderRadius: BorderRadius.all( Radius.circular(35))), padding: const EdgeInsets.only( - left: 16, bottom: 5, top: 5, right: 10), + left: 16, + bottom: 5, + top: 5, + right: 10), child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, @@ -619,7 +680,7 @@ class _BookMarkState extends ConsumerState { 'Roboto', 'NotoKufi', ), - color: Colors.white, + color: Colors.white, fontWeight: FontWeight.w600, fontSize: 20, ), @@ -642,7 +703,9 @@ class _BookMarkState extends ConsumerState { itemCount: filteredBookmarks.length, itemBuilder: (context, index) { return _buildBox( - filteredBookmarks[index], context); + filteredBookmarks[index], + context, + isDarkTheme); }, ), ), @@ -656,8 +719,9 @@ class _BookMarkState extends ConsumerState { ); } - Widget _buildBox(Map data, BuildContext context) { - // Color borderColor = data['valueColor']; + Widget _buildBox( + Map data, BuildContext context, bool isDarkTheme) { +// Color borderColor = data['valueColor']; return GestureDetector( onTap: () { final data_set = data['data_set']; @@ -677,7 +741,7 @@ class _BookMarkState extends ConsumerState { height: 100, padding: const EdgeInsets.all(8.0), decoration: BoxDecoration( - color: Colors.white, + color: isDarkTheme ? Color(0xFF111111) : Colors.white, borderRadius: BorderRadius.circular(10), border: Border.all(color: data['valueColor']), ), @@ -698,11 +762,14 @@ class _BookMarkState extends ConsumerState { alignment: Alignment.center, child: Text( data['title'] ?? '', - style: TextStyle(fontWeight: FontWeight.w500, + style: TextStyle( + fontWeight: FontWeight.w500, fontFamily: context.translate( 'Roboto', 'NotoKufi', - ),), + ), + color: isDarkTheme ? Colors.white : null, + ), overflow: TextOverflow.ellipsis, maxLines: 1, ), @@ -712,7 +779,7 @@ class _BookMarkState extends ConsumerState { onTap: () { debugPrint("Icon clicked in: ${data['title']}"); showRemoveBookmarkDialog(data['id']); - // removeBookmark(data['id']); +// removeBookmark(data['id']); }, child: SvgPicture.asset( BookmarkAssetPath.delete, @@ -721,23 +788,24 @@ class _BookMarkState extends ConsumerState { height: 20, )), - // GestureDetector( - // onTap: () { - // debugPrint("Icon clicked in: ${data['title']}"); - // // showRemoveBookmarkDialog(data['id']); - // }, - // child: const Icon( - // Icons.bookmarks_rounded, - // color: Colors.black, - // size: 20, - // ), - // ), +// GestureDetector( +// onTap: () { +// debugPrint("Icon clicked in: ${data['title']}"); +// // showRemoveBookmarkDialog(data['id']); +// }, +// child: const Icon( +// Icons.bookmarks_rounded, +// color: Colors.black, +// size: 20, +// ), +// ), ], ), Text( data['value_source'] ?? '', style: TextStyle( - fontWeight: FontWeight.w500, color: Colors.grey, + fontWeight: FontWeight.w500, + color: Colors.grey, fontFamily: context.translate( 'Roboto', 'NotoKufi', @@ -768,14 +836,18 @@ class _BookMarkState extends ConsumerState { } Widget _buildBoxes( - Map data, BuildContext context, Color styleColor) { - // Color borderColor = data['valueColor']; + Map data, + BuildContext context, + Color styleColor, + bool isDarkTheme, + ) { +// Color borderColor = data['valueColor']; print('inside function $data'); return GestureDetector( onTap: () { final data_set = data['data_set']; - // final Color colorPattern = data['valueColor']; +// final Color colorPattern = data['valueColor']; final encodedMainTopic = data['main_topic']; final encodedTitle = data['title']; String hexColor = colorToHex(styleColor); @@ -783,10 +855,10 @@ class _BookMarkState extends ConsumerState { debugPrint( '/chartScreen/$data_set?bgColor=$hexColor&mainTopic=$encodedMainTopic&title=$encodedTitle'); - // String hexColor = colorToHex(colorPattern); // Get hex string - // print(hexColor); // Prints: 0xFFAA8E83 +// String hexColor = colorToHex(colorPattern); // Get hex string +// print(hexColor); // Prints: 0xFFAA8E83 - // debugPrint("Box clicked: ${data['title']}"); +// debugPrint("Box clicked: ${data['title']}"); context.push( '/chartScreen/$data_set?bgColor=$hexColor&mainTopic=$encodedMainTopic&title=$encodedTitle'); }, @@ -795,7 +867,7 @@ class _BookMarkState extends ConsumerState { height: 100, padding: const EdgeInsets.all(8.0), decoration: BoxDecoration( - color: Colors.white, + color: isDarkTheme ? Color(0xFF111111) : Colors.white, borderRadius: BorderRadius.circular(10), border: Border.all(color: styleColor), ), @@ -814,10 +886,14 @@ class _BookMarkState extends ConsumerState { alignment: Alignment.center, child: Text( data['title'] ?? '', - style: TextStyle(fontWeight: FontWeight.w500, fontFamily: context.translate( - 'Roboto', - 'NotoKufi', - ),), + style: TextStyle( + fontWeight: FontWeight.w500, + fontFamily: context.translate( + 'Roboto', + 'NotoKufi', + ), + color: isDarkTheme ? Colors.white : null, + ), overflow: TextOverflow.ellipsis, maxLines: 1, ), @@ -839,10 +915,13 @@ class _BookMarkState extends ConsumerState { Text( data['value_source'] ?? '', style: TextStyle( - fontWeight: FontWeight.w500, color: Colors.grey, fontFamily: context.translate( - 'Roboto', - 'NotoKufi', - ),), + fontWeight: FontWeight.w500, + color: Colors.grey, + fontFamily: context.translate( + 'Roboto', + 'NotoKufi', + ), + ), overflow: TextOverflow.ellipsis, maxLines: 1, ), @@ -870,17 +949,18 @@ class TabBarHeader extends StatelessWidget { final List> tabs; final int selectedIndex; final ValueChanged onTabSelected; + bool isDarkTheme; - const TabBarHeader({ - required this.tabs, - required this.selectedIndex, - required this.onTabSelected, - }); + TabBarHeader( + {required this.tabs, + required this.selectedIndex, + required this.onTabSelected, + required this.isDarkTheme}); @override Widget build(BuildContext context) { return Container( - color: Colors.white, + color: isDarkTheme ? Color(0xFF111111) : Colors.white, padding: const EdgeInsets.symmetric(vertical: 8), child: SingleChildScrollView( scrollDirection: Axis.horizontal, @@ -901,11 +981,15 @@ class TabBarHeader extends StatelessWidget { : Colors.grey[700]; }), ), - child: Text(text, - style: TextStyle( fontFamily: context.translate( - 'Roboto', - 'NotoKufi', - ),),), + child: Text( + text, + style: TextStyle( + fontFamily: context.translate( + 'Roboto', + 'NotoKufi', + ), + ), + ), ), if (index < tabs.length - 1) buildDivider(), ], @@ -936,6 +1020,7 @@ class CustomExpandableTile extends StatefulWidget { final bool isExpanded; final ValueChanged onTap; final Widget childWidget; + final bool isDarkTheme; const CustomExpandableTile({ required this.title, @@ -945,6 +1030,7 @@ class CustomExpandableTile extends StatefulWidget { required this.isExpanded, required this.onTap, required this.childWidget, + required this.isDarkTheme, }); @override @@ -960,7 +1046,7 @@ class _CustomExpandableTileState extends State { @override Widget build(BuildContext context) { double myheight = MediaQuery.of(context).size.height; - // print(widget.filteredBookmarks); +// print(widget.filteredBookmarks); return Card( elevation: 0, child: Column( @@ -969,8 +1055,10 @@ class _CustomExpandableTileState extends State { onTap: () => widget.onTap(widget.index), child: Container( decoration: BoxDecoration( - color: Colors - .white, // Ensuring the background outside the rounded container is white + color: widget.isDarkTheme + ? Color(0xFF111111) + : Colors + .white, // Ensuring the background outside the rounded container is white ), child: Container( decoration: BoxDecoration( @@ -997,7 +1085,7 @@ class _CustomExpandableTileState extends State { widget.isExpanded ? Icons.keyboard_arrow_up : Icons.keyboard_arrow_down, - color: Colors.white, + color: widget.isDarkTheme ? Colors.black : Colors.white, size: 28.0, ), ], @@ -1010,35 +1098,35 @@ class _CustomExpandableTileState extends State { duration: Duration(milliseconds: 300), curve: Curves.easeInOut, width: double.infinity, - color: Colors.white, - // height: widget.isExpanded ? myheight * 0.4 : 0, + color: widget.isDarkTheme ? Colors.black : Colors.white, +// height: widget.isExpanded ? myheight * 0.4 : 0, child: widget.isExpanded ? SingleChildScrollView( child: Column( children: [ widget.childWidget, - // Container( - // decoration: BoxDecoration( - // color: Colors.white, - // // borderRadius: BorderRadius.all(Radius.circular(20)) - // ), - // padding: const EdgeInsets.all(16), - // child: GridView.builder( - // shrinkWrap: true, - // physics: NeverScrollableScrollPhysics(), - // gridDelegate: - // const SliverGridDelegateWithFixedCrossAxisCount( - // crossAxisCount: 2, - // crossAxisSpacing: 10.0, - // mainAxisSpacing: 10.0, - // mainAxisExtent: 100, - // ), - // itemCount: widget.filteredBookmarks.length, - // itemBuilder: (context, index) { - // return _buildBox(widget.filteredBookmarks[index], context,widget.titleBackgroundColor); - // }, - // ), - // ), +// Container( +// decoration: BoxDecoration( +// color: Colors.white, +// // borderRadius: BorderRadius.all(Radius.circular(20)) +// ), +// padding: const EdgeInsets.all(16), +// child: GridView.builder( +// shrinkWrap: true, +// physics: NeverScrollableScrollPhysics(), +// gridDelegate: +// const SliverGridDelegateWithFixedCrossAxisCount( +// crossAxisCount: 2, +// crossAxisSpacing: 10.0, +// mainAxisSpacing: 10.0, +// mainAxisExtent: 100, +// ), +// itemCount: widget.filteredBookmarks.length, +// itemBuilder: (context, index) { +// return _buildBox(widget.filteredBookmarks[index], context,widget.titleBackgroundColor); +// }, +// ), +// ), ], ), ) diff --git a/lib/presentation/routes/drawer_routes/Drawer Items/contactUs.dart b/lib/presentation/routes/drawer_routes/Drawer Items/contactUs.dart index a86273cb..29242495 100644 --- a/lib/presentation/routes/drawer_routes/Drawer Items/contactUs.dart +++ b/lib/presentation/routes/drawer_routes/Drawer Items/contactUs.dart @@ -1,7 +1,12 @@ +import 'dart:convert'; + import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:go_router/go_router.dart'; +import 'package:http/http.dart' as http; +import 'package:uae_stat/config/api_config.dart'; import 'package:uae_stat/config/connectivity_provider.dart'; +import 'package:uae_stat/config/theme/theme_provider.dart'; import 'package:uae_stat/config/toggle_lang_service.dart'; import 'package:uae_stat/domain/use_cases/language.dart'; import 'package:uae_stat/infrastructure/services/img_asset_paths/icons/enquiry_asset_icon_path.dart'; @@ -20,10 +25,53 @@ class Contact extends ConsumerStatefulWidget { class _ContactState extends ConsumerState { late UserService _userService; + List homePageData = []; + List filteredData = []; + late ThemeMode currentTheme; + bool isLoading = true; + @override void initState() { super.initState(); _userService = UserService(); + + final locale = ref.read(localeProvider); + currentTheme = ref.read(themeProvider); + print('123456789'); + print(currentTheme); + WidgetsBinding.instance.addPostFrameCallback((_) { + final isDark = currentTheme == ThemeMode.dark || + (currentTheme == ThemeMode.system && + MediaQuery.of(context).platformBrightness == Brightness.dark); + + final themeMode = (isDark ? 'dark' : 'light'); + print("ThemeMode - $themeMode"); + fetchData(locale?.languageCode ?? 'en', themeMode); + }); + } + + Future fetchData(locale, themeMode) async { + const baseUrl = '$apiUrl/api/getUAENumbersData'; + try { + final response = await http + .get(Uri.parse(baseUrl + '?language=$locale&color_mode=$themeMode')); + if (response.statusCode == 200) { + setState(() { + homePageData = (json.decode(response.body) as List) + .map((e) => Map.from(e)) + .toList(); + filteredData = List.from(homePageData); + isLoading = false; + }); + } else { + throw Exception('Failed to load data'); + } + } catch (e) { + setState(() { + isLoading = false; + }); + print('Error fetching data: $e'); + } } @override @@ -42,6 +90,49 @@ class _ContactState extends ConsumerState { await _userService.updateLanguage(localeCode); }); + ref.listen(localeProvider, (previous, next) async { + final localeCode = next?.languageCode ?? 'en'; + setState(() { + isLoading = true; + }); + await _userService.updateLanguage(localeCode); + final currentTheme = ref.read(themeProvider); + final isDark = currentTheme == ThemeMode.dark || + (currentTheme == ThemeMode.system && + MediaQuery.of(context).platformBrightness == Brightness.dark); + + final themeString = isDark ? 'dark' : 'light'; + fetchData(localeCode, themeString); + }); + + ref.listen(themeProvider, (previous, next) async { + final localeCode = ref.watch(localeProvider)?.languageCode ?? 'en'; + print(localeCode); + + // Default to 'en' if null + setState(() { + isLoading = true; + print('isLoadingref $isLoading'); + }); + + final currentTheme = ref.read(themeProvider); + final isDark = currentTheme == ThemeMode.dark || + (currentTheme == ThemeMode.system && + MediaQuery.of(context).platformBrightness == Brightness.dark); + + final themeString = isDark ? 'dark' : 'light'; + + print("themeString- $themeString"); + fetchData(localeCode, themeString); + }); + + final themeMode = ref.read(themeProvider); + final isDarkTheme = themeMode == ThemeMode.dark || + (themeMode == ThemeMode.system && + MediaQuery.of(context).platformBrightness == Brightness.dark); + + print("isDarkTheme - $isDarkTheme"); + return PopScope( canPop: false, onPopInvokedWithResult: (didPop, result) { @@ -49,145 +140,175 @@ class _ContactState extends ConsumerState { context.go('/myhomepage'); }, child: BaseScaffold( - body: Container( - color: Colors.grey[200], - width: screenWidth, - padding: const EdgeInsets.all(16.0), - child: SingleChildScrollView( - child: Column( - children: [ - buildContactCard( - context, - title: 'DUBAI - EMIRATES TOWER - 32ND FLOOR', - titleAr: 'دبي - أبراج الإمارات - الطابق 32', - details: [ - { - 'icon': EnquiryAssetIconPath.building, - 'text': 'Office: Dubai - Emirates Tower - 32nd Floor', - 'textAr': 'المقر الرئيسي: دبي - أبراج الإمارات - الطابق 32' - }, - { - 'icon': EnquiryAssetIconPath.phone, - 'text': 'Tel: 00971 4608 0000', - 'textAr': 'الهاتف: 0097146080000' - }, - { - 'icon': EnquiryAssetIconPath.fax, - 'text': 'Fax: 00971 4327 3535', - 'textAr': 'فاكس: 0097143273535' - }, - { - 'icon': EnquiryAssetIconPath.map, - 'text': 'P.O.Box: 127000 Dubai', - 'textAr': 'ص.ب: 127000 دبي' - }, - { - 'icon': EnquiryAssetIconPath.at, - 'text': 'Email Address: info@fcsc.gov.ae', - 'textAr': 'البريد الإلكتروني: info@fcsc.gov.ae' - }, - { - 'icon': EnquiryAssetIconPath.map, - 'text': 'Latitude: 25.223926', - 'textAr': 'خط العرض: 25.223926' - }, - { - 'icon': EnquiryAssetIconPath.map, - 'text': 'Longitude: 55.350526', - 'textAr': 'خط الطول: 55.350526' - }, + backgroundColor: isDarkTheme ? Color(0xFF333333) : Colors.white, + appbarColor: isDarkTheme ? Color(0xFF333333) : Colors.white, + body: isLoading + ? Container( + // color: Color(0x98FFFCE5), // Semi-transparent background + color: isDarkTheme + ? Color(0xFF333333) + : Color(0x98FFFCE5), // Semi-transparent background + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Container( + margin: EdgeInsets.symmetric( + horizontal: 40), // Left & Right space + child: LinearProgressIndicator( + minHeight: 5, // Adjust thickness + backgroundColor: + Colors.grey[100], // Optional: Background color + valueColor: AlwaysStoppedAnimation( + Color(0xFFAA8E83)), // Loader color + ), + ), ], ), - const SizedBox(height: 10), - buildContactCard( - context, - title: 'MEDIA SECTION', - titleAr: 'قسم الاعلام', - details: [ - { - 'icon': EnquiryAssetIconPath.building, - 'text': 'Office: Media Section', - 'textAr': 'المقر الرئيسي: قسم الاعلام' - }, - { - 'icon': EnquiryAssetIconPath.phone, - 'text': 'Tel: 00971 4608 0000', - 'textAr': 'الهاتف: 0097146080000' - }, - { - 'icon': EnquiryAssetIconPath.fax, - 'text': 'Fax: 00971 4327 3535', - 'textAr': 'فاكس: 0097143273535' - }, - { - 'icon': EnquiryAssetIconPath.map, - 'text': 'P.O.Box: 127000 Dubai', - 'textAr': 'ص.ب: 127000 دبي' - }, - { - 'icon': EnquiryAssetIconPath.at, - 'text': 'Email Address: GCO@fcsc.gov.ae', - 'textAr': 'البريد الإلكتروني: GCO@fcsc.gov.ae' - }, - { - 'icon': EnquiryAssetIconPath.map, - 'text': 'Latitude: 25.223926', - 'textAr': 'خط العرض: 25.223926' - }, - { - 'icon': EnquiryAssetIconPath.map, - 'text': 'Longitude: 55.350526', - 'textAr': 'خط الطول: 55.350526' - }, - ], + ) + : Container( + // color: Colors.grey[200], + // color: isDarkTheme ? Color(0xFF3B3C3F) : Colors.grey[200], + color: isDarkTheme ? Color(0xFF333333) : Colors.grey[200], + width: screenWidth, + padding: const EdgeInsets.all(16.0), + child: SingleChildScrollView( + child: Column( + children: [ + buildContactCard(context, + title: 'DUBAI - EMIRATES TOWER - 32ND FLOOR', + titleAr: 'دبي - أبراج الإمارات - الطابق 32', + details: [ + { + 'icon': EnquiryAssetIconPath.building, + 'text': + 'Office: Dubai - Emirates Tower - 32nd Floor', + 'textAr': + 'المقر الرئيسي: دبي - أبراج الإمارات - الطابق 32' + }, + { + 'icon': EnquiryAssetIconPath.phone, + 'text': 'Tel: 00971 4608 0000', + 'textAr': 'الهاتف: 0097146080000' + }, + { + 'icon': EnquiryAssetIconPath.fax, + 'text': 'Fax: 00971 4327 3535', + 'textAr': 'فاكس: 0097143273535' + }, + { + 'icon': EnquiryAssetIconPath.map, + 'text': 'P.O.Box: 127000 Dubai', + 'textAr': 'ص.ب: 127000 دبي' + }, + { + 'icon': EnquiryAssetIconPath.at, + 'text': 'Email Address: info@fcsc.gov.ae', + 'textAr': 'البريد الإلكتروني: info@fcsc.gov.ae' + }, + { + 'icon': EnquiryAssetIconPath.map, + 'text': 'Latitude: 25.223926', + 'textAr': 'خط العرض: 25.223926' + }, + { + 'icon': EnquiryAssetIconPath.map, + 'text': 'Longitude: 55.350526', + 'textAr': 'خط الطول: 55.350526' + }, + ], + isDarkTheme: isDarkTheme), + const SizedBox(height: 10), + buildContactCard( + context, + title: 'MEDIA SECTION', + titleAr: 'قسم الاعلام', + details: [ + { + 'icon': EnquiryAssetIconPath.building, + 'text': 'Office: Media Section', + 'textAr': 'المقر الرئيسي: قسم الاعلام' + }, + { + 'icon': EnquiryAssetIconPath.phone, + 'text': 'Tel: 00971 4608 0000', + 'textAr': 'الهاتف: 0097146080000' + }, + { + 'icon': EnquiryAssetIconPath.fax, + 'text': 'Fax: 00971 4327 3535', + 'textAr': 'فاكس: 0097143273535' + }, + { + 'icon': EnquiryAssetIconPath.map, + 'text': 'P.O.Box: 127000 Dubai', + 'textAr': 'ص.ب: 127000 دبي' + }, + { + 'icon': EnquiryAssetIconPath.at, + 'text': 'Email Address: GCO@fcsc.gov.ae', + 'textAr': 'البريد الإلكتروني: GCO@fcsc.gov.ae' + }, + { + 'icon': EnquiryAssetIconPath.map, + 'text': 'Latitude: 25.223926', + 'textAr': 'خط العرض: 25.223926' + }, + { + 'icon': EnquiryAssetIconPath.map, + 'text': 'Longitude: 55.350526', + 'textAr': 'خط الطول: 55.350526' + }, + ], + isDarkTheme: isDarkTheme, + ), + const SizedBox(height: 10), + buildContactCard( + context, + title: 'SGDS', + titleAr: 'أهداف التنمية المستدامة', + details: [ + { + 'icon': EnquiryAssetIconPath.building, + 'text': 'Office: SDGs', + 'textAr': 'المقر الرئيسي: أهداف التنمية المستدامة' + }, + { + 'icon': EnquiryAssetIconPath.phone, + 'text': 'Tel: 00971 4608 0000', + 'textAr': 'الهاتف: 0097146080000' + }, + { + 'icon': EnquiryAssetIconPath.fax, + 'text': 'Fax: 00971 4327 3535', + 'textAr': 'فاكس : 0097143273535' + }, + { + 'icon': EnquiryAssetIconPath.map, + 'text': 'P.O.Box: 127000 Dubai', + 'textAr': 'ص.ب: 127000 دبي' + }, + { + 'icon': EnquiryAssetIconPath.at, + 'text': 'Email Address: sdgs@fcsc.gov.ae', + 'textAr': 'البريد الإلكتروني: sdgs@fcsc.gov.ae' + }, + { + 'icon': EnquiryAssetIconPath.map, + 'text': 'Latitude: 25.223926', + 'textAr': 'خط العرض: 25.223926' + }, + { + 'icon': EnquiryAssetIconPath.map, + 'text': 'Longitude: 55.350526', + 'textAr': 'خط الطول: 55.350526' + }, + ], + isDarkTheme: isDarkTheme, + ), + ], + ), ), - const SizedBox(height: 10), - buildContactCard( - context, - title: 'SGDS', - titleAr: 'أهداف التنمية المستدامة', - details: [ - { - 'icon': EnquiryAssetIconPath.building, - 'text': 'Office: SDGs', - 'textAr': 'المقر الرئيسي: أهداف التنمية المستدامة' - }, - { - 'icon': EnquiryAssetIconPath.phone, - 'text': 'Tel: 00971 4608 0000', - 'textAr': 'الهاتف: 0097146080000' - }, - { - 'icon': EnquiryAssetIconPath.fax, - 'text': 'Fax: 00971 4327 3535', - 'textAr': 'فاكس : 0097143273535' - }, - { - 'icon': EnquiryAssetIconPath.map, - 'text': 'P.O.Box: 127000 Dubai', - 'textAr': 'ص.ب: 127000 دبي' - }, - { - 'icon': EnquiryAssetIconPath.at, - 'text': 'Email Address: sdgs@fcsc.gov.ae', - 'textAr': 'البريد الإلكتروني: sdgs@fcsc.gov.ae' - }, - { - 'icon': EnquiryAssetIconPath.map, - 'text': 'Latitude: 25.223926', - 'textAr': 'خط العرض: 25.223926' - }, - { - 'icon': EnquiryAssetIconPath.map, - 'text': 'Longitude: 55.350526', - 'textAr': 'خط الطول: 55.350526' - }, - ], - ), - ], - ), - ), - ), + ), title: Text(context.translate('Contact Us', 'اتصل بنا')), ), ); @@ -196,11 +317,13 @@ class _ContactState extends ConsumerState { Widget buildContactCard(BuildContext context, {required String title, required String titleAr, - required List> details}) { + required List> details, + isDarkTheme}) { return Container( padding: const EdgeInsets.symmetric(vertical: 10, horizontal: 12), decoration: BoxDecoration( - color: Colors.white, + // color: Colors.white, + color: isDarkTheme ? Color(0xFF030303) : Colors.white, borderRadius: BorderRadius.circular(6.0), boxShadow: [ BoxShadow( @@ -226,31 +349,38 @@ class _ContactState extends ConsumerState { ), ), const SizedBox(height: 8), - ...details.map((item) => buildTextRow(item['icon']!, - context.translate(item['text']!, item['textAr']!))), + ...details.map((item) => buildTextRow( + item['icon']!, + context.translate( + item['text']!, + item['textAr']!, + ), + isDarkTheme)), ], ), ); } - Widget buildTextRow(String iconName, String text) { + Widget buildTextRow(String iconName, String text, bool isDarkTheme) { List values = List.filled(2, ''); String cleanText = ''; - if (text.toLowerCase().contains('tel:') || text.toLowerCase().contains('الهاتف:')) { + if (text.toLowerCase().contains('tel:') || + text.toLowerCase().contains('الهاتف:')) { values = text.split(':'); - print ('List of values----- :$values'); - print ('value 1 ${values[0]}'); - cleanText=values[1].replaceAll(' ', ''); - } else if(text.toLowerCase().contains('email address:') || text.toLowerCase().contains('البريد الإلكتروني:')){ + print('List of values----- :$values'); + print('value 1 ${values[0]}'); + cleanText = values[1].replaceAll(' ', ''); + } else if (text.toLowerCase().contains('email address:') || + text.toLowerCase().contains('البريد الإلكتروني:')) { values = text.split(':'); cleanText = values[1].replaceAll(' ', ''); - } else{ + } else { cleanText = text; } Future sendEmail(String emailAddress) async { - print ('before email : $emailAddress'); + print('before email : $emailAddress'); final uri = Uri( scheme: 'mailto', path: emailAddress, @@ -275,76 +405,99 @@ class _ContactState extends ConsumerState { const SizedBox(width: 10), iconName == EnquiryAssetIconPath.phone ? InkWell( - onTap: () async{ - print('clean test : $cleanText'); - final uri = Uri(scheme: 'tel', path: cleanText); - if (await canLaunchUrl(uri)) { - await launchUrl(uri); - } else { - debugPrint('Could not launch $uri'); - } - }, - child: RichText( - text: TextSpan( - text: values[0], - style: TextStyle(fontSize: 14, color: Color(0xFF5F5F5F), fontFamily: context.translate( - 'Roboto', - 'NotoKufi', - ),), - children: [ - TextSpan(text: ':',), - TextSpan(text: values[1], - style: TextStyle(fontSize: 14, color:Color(0xFF985400), fontFamily: context.translate( - 'Roboto', - 'NotoKufi', - ),) + onTap: () async { + print('clean test : $cleanText'); + final uri = Uri(scheme: 'tel', path: cleanText); + if (await canLaunchUrl(uri)) { + await launchUrl(uri); + } else { + debugPrint('Could not launch $uri'); + } + }, + child: RichText( + text: TextSpan( + text: values[0], + style: TextStyle( + fontSize: 14, + color: isDarkTheme ? Colors.white : Color(0xFF5F5F5F), + fontFamily: context.translate( + 'Roboto', + 'NotoKufi', + ), + ), + children: [ + TextSpan( + text: ':', + ), + TextSpan( + text: values[1], + style: TextStyle( + fontSize: 14, + color: Color(0xFF985400), + fontFamily: context.translate( + 'Roboto', + 'NotoKufi', + ), + )), + ], + ), ), - ], - ), - ), - // child: Text( - // text, - // style: const TextStyle( - // fontSize: 14, - // color: Color(0xFF5F5F5F), - // ), - // ), - ) + // child: Text( + // text, + // style: const TextStyle( + // fontSize: 14, + // color: Color(0xFF5F5F5F), + // ), + // ), + ) : iconName == EnquiryAssetIconPath.at - ? InkWell( - onTap: () => sendEmail(cleanText), - child: RichText( - text: TextSpan( - text: values[0], - style: TextStyle(fontSize: 14, color: Color(0xFF5F5F5F), fontFamily: context.translate( - 'Roboto', - 'NotoKufi', - ),), - children: [ - TextSpan(text: ':',), - TextSpan(text: values[1], - style: TextStyle(fontSize: 14, color:Color(0xFF985400), fontFamily: context.translate( - 'Roboto', - 'NotoKufi', - ),) - ), - ], - ), - ), - ) - :Expanded( - child: Text( - text, - style: TextStyle( - fontFamily: context.translate( - 'Roboto', - 'NotoKufi', - ), - fontSize: 14, - color: Color(0xFF5F5F5F), - ), - ), - ), + ? InkWell( + onTap: () => sendEmail(cleanText), + child: RichText( + text: TextSpan( + text: values[0], + style: TextStyle( + fontSize: 14, + color: + isDarkTheme ? Colors.white : Color(0xFF5F5F5F), + // color: Color(0xFF5F5F5F), + fontFamily: context.translate( + 'Roboto', + 'NotoKufi', + ), + ), + children: [ + TextSpan( + text: ':', + ), + TextSpan( + text: values[1], + style: TextStyle( + fontSize: 14, + color: Color(0xFF985400), + fontFamily: context.translate( + 'Roboto', + 'NotoKufi', + ), + )), + ], + ), + ), + ) + : Expanded( + child: Text( + text, + style: TextStyle( + fontFamily: context.translate( + 'Roboto', + 'NotoKufi', + ), + fontSize: 14, + color: isDarkTheme ? Colors.white : Color(0xFF5F5F5F), + // color: Color(0xFF5F5F5F), + ), + ), + ), ], ), ); diff --git a/lib/presentation/routes/drawer_routes/Drawer Items/edit_profile.dart b/lib/presentation/routes/drawer_routes/Drawer Items/edit_profile.dart index 7fb71013..76db2f88 100644 --- a/lib/presentation/routes/drawer_routes/Drawer Items/edit_profile.dart +++ b/lib/presentation/routes/drawer_routes/Drawer Items/edit_profile.dart @@ -13,7 +13,7 @@ import 'package:image_picker/image_picker.dart'; import 'package:intl/intl.dart'; import 'package:pocketbase/pocketbase.dart'; import 'package:shared_preferences/shared_preferences.dart'; -import 'package:flutter_gen/gen_l10n/app_localizations.dart'; +// import 'package:flutter_gen/gen_l10n/app_localizations.dart'; import 'package:uae_stat/config/api_config.dart'; import 'package:uae_stat/config/connectivity_provider.dart'; import 'package:uae_stat/config/my_theme.dart'; @@ -23,6 +23,7 @@ import 'package:uae_stat/domain/use_cases/language.dart'; import 'package:uae_stat/infrastructure/services/img_asset_paths/icons/misc_icon_asset_path.dart'; import 'package:uae_stat/presentation/components/indicators/locale_provider.dart'; import 'package:uae_stat/presentation/routes/drawer_routes/custom_drawer_routes.dart'; +import 'package:flutter_gen/gen_l10n/app_localizations.dart'; class EditProfile extends ConsumerStatefulWidget { const EditProfile({super.key}); @@ -279,13 +280,14 @@ class _EditProfileState extends ConsumerState { ScaffoldMessenger.of(context).showSnackBar( SnackBar( content: Text( - context.translate('Please select a JPG, JPEG, or PNG file.','يرجى تحديد ملف بصيغة JPG أو JPEG أو PNG.'), - style: TextStyle( - fontFamily: context.translate( - 'Roboto', - 'NotoKufi', - ) - ),)), + context.translate('Please select a JPG, JPEG, or PNG file.', + 'يرجى تحديد ملف بصيغة JPG أو JPEG أو PNG.'), + style: TextStyle( + fontFamily: context.translate( + 'Roboto', + 'NotoKufi', + )), + )), ); } } @@ -435,14 +437,13 @@ class _EditProfileState extends ConsumerState { ScaffoldMessenger.of(context).showSnackBar( SnackBar( content: Text( - AppLocalizations.of(context)!.profile_updated_successfully, - style: TextStyle( - fontFamily: context.translate( - 'Roboto', - 'NotoKufi', - ) - ), - )), + AppLocalizations.of(context)!.profile_updated_successfully, + style: TextStyle( + fontFamily: context.translate( + 'Roboto', + 'NotoKufi', + )), + )), ); }); @@ -454,13 +455,14 @@ class _EditProfileState extends ConsumerState { }); ScaffoldMessenger.of(context).showSnackBar( SnackBar( - content: Text('Failed to update profile: ${response.statusCode}', + content: Text( + 'Failed to update profile: ${response.statusCode}', style: TextStyle( fontFamily: context.translate( - 'Roboto', - 'NotoKufi', - ) - ),), + 'Roboto', + 'NotoKufi', + )), + ), ), ); } @@ -469,13 +471,15 @@ class _EditProfileState extends ConsumerState { isLoader = false; }); ScaffoldMessenger.of(context).showSnackBar( - SnackBar(content: Text('Failed to update profile: $error', + SnackBar( + content: Text( + 'Failed to update profile: $error', style: TextStyle( fontFamily: context.translate( - 'Roboto', - 'NotoKufi', - ) - ),)), + 'Roboto', + 'NotoKufi', + )), + )), ); } } else { @@ -547,790 +551,852 @@ class _EditProfileState extends ConsumerState { context.go('/myhomepage'); // Show exit confirmation dialog }, child: BaseScaffold( - title: Text( - AppLocalizations.of(context)!.my_profile, - style: TextStyle(color: Color(0xFF985400), fontFamily: context.translate( - 'Roboto', - 'NotoKufi', - ),), - ), - body: isLoader - ? Container( - color: Color(0x98FFFCE5), // Semi-transparent background - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Container( - margin: EdgeInsets.symmetric( - horizontal: 40), // Left & Right space - child: LinearProgressIndicator( - minHeight: 5, // Adjust thickness - backgroundColor: - Colors.grey[100], // Optional: Background color - valueColor: AlwaysStoppedAnimation( - Color(0xFFAA8E83)), // Loader color + backgroundColor: isDarkTheme ? Color(0xFF111111) : Colors.white, + appbarColor: isDarkTheme ? Color(0xFF111111) : Colors.white, + title: Text( + AppLocalizations.of(context)!.my_profile, + style: TextStyle( + color: isDarkTheme ? Colors.white : Color(0xFF985400), + fontFamily: context.translate( + 'Roboto', + 'NotoKufi', + ), + ), + ), + body: isLoader + ? Container( + color: Color(0x98FFFCE5), // Semi-transparent background + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Container( + margin: EdgeInsets.symmetric( + horizontal: 40), // Left & Right space + child: LinearProgressIndicator( + minHeight: 5, // Adjust thickness + backgroundColor: + Colors.grey[100], // Optional: Background color + valueColor: AlwaysStoppedAnimation( + Color(0xFFAA8E83)), // Loader color + ), ), - ), - ], - ), - ) - : Container( - color: isDarkTheme ? Color(0xFF111111) : null, - child: SingleChildScrollView( - child: Padding( - padding: const EdgeInsets.only( - left: 10.0, right: 10.0, top: 3.0), - child: Column( - children: [ - SingleChildScrollView( - child: Form( - key: _formKey, - child: Padding( - // padding: const EdgeInsets.all(20.0), - padding: const EdgeInsets.only( - top: 20.0, bottom: 20.0, left: 25, right: 25), - child: Column( - children: [ - // CircleAvatar( - // radius: 50, - // backgroundImage: _profileImage != null - // ? FileImage( - // _profileImage!) // If a local file is selected - // : _avatarUrl.isNotEmpty - // ? NetworkImage(_avatarUrl) // Load from URL - // : AssetImage( - // "assets/edit_profile/profile.png") - // as ImageProvider, - // - // //backgroundImage: NetworkImage(_avatarUrl) as ImageProvider, - // - // child: - // Align( - // alignment: Alignment.bottomRight, - // child: GestureDetector( - // onTap: _pickImage, // Call `_pickImage` on tap - // child: CircleAvatar( - // radius: 15, - // backgroundColor: Colors.white, - // child: Icon( - // Icons.camera_alt, - // size: 15, - // color: Colors.grey, - // ), - // ), - // ), - // ), - // ), + ], + ), + ) + : Container( + color: isDarkTheme ? Color(0xFF111111) : null, + child: SingleChildScrollView( + child: Padding( + padding: const EdgeInsets.only( + left: 10.0, right: 10.0, top: 3.0), + child: Column( + children: [ + SingleChildScrollView( + child: Form( + key: _formKey, + child: Padding( + // padding: const EdgeInsets.all(20.0), + padding: const EdgeInsets.only( + top: 20.0, + bottom: 20.0, + left: 25, + right: 25), + child: Column( + children: [ + // CircleAvatar( + // radius: 50, + // backgroundImage: _profileImage != null + // ? FileImage( + // _profileImage!) // If a local file is selected + // : _avatarUrl.isNotEmpty + // ? NetworkImage(_avatarUrl) // Load from URL + // : AssetImage( + // "assets/edit_profile/profile.png") + // as ImageProvider, + // + // //backgroundImage: NetworkImage(_avatarUrl) as ImageProvider, + // + // child: + // Align( + // alignment: Alignment.bottomRight, + // child: GestureDetector( + // onTap: _pickImage, // Call `_pickImage` on tap + // child: CircleAvatar( + // radius: 15, + // backgroundColor: Colors.white, + // child: Icon( + // Icons.camera_alt, + // size: 15, + // color: Colors.grey, + // ), + // ), + // ), + // ), + // ), - // Stack( - // alignment: Alignment.center, - // children: [ - // // FutureBuilder to load the image - // FutureBuilder( - // future: _loadProfileImage(), - // builder: (context, snapshot) { - // if (snapshot.connectionState == ConnectionState.waiting) { - // // While the image is loading, show a progress indicator - // return CircleAvatar( - // radius: 50, - // child: CircularProgressIndicator(), - // ); - // } else if (snapshot.hasError || snapshot.data == null) { - // // If there's an error or no image, show an error icon - // return CircleAvatar( - // radius: 50, - // child: CircularProgressIndicator(), - // ); - // } else { - // // Display the loaded image - // return CircleAvatar( - // radius: 50, - // backgroundImage: snapshot.data, - // child: Align( - // alignment: Alignment.bottomRight, - // child: GestureDetector( - // onTap: _pickImage, - // child: CircleAvatar( - // radius: 15, - // backgroundColor: Colors.white, - // child: Icon( - // Icons.camera_alt, - // size: 15, - // color: Colors.grey, - // ), - // ), - // ), - // ), - // ); - // } - // }, - // ), - // ], - // ), + // Stack( + // alignment: Alignment.center, + // children: [ + // // FutureBuilder to load the image + // FutureBuilder( + // future: _loadProfileImage(), + // builder: (context, snapshot) { + // if (snapshot.connectionState == ConnectionState.waiting) { + // // While the image is loading, show a progress indicator + // return CircleAvatar( + // radius: 50, + // child: CircularProgressIndicator(), + // ); + // } else if (snapshot.hasError || snapshot.data == null) { + // // If there's an error or no image, show an error icon + // return CircleAvatar( + // radius: 50, + // child: CircularProgressIndicator(), + // ); + // } else { + // // Display the loaded image + // return CircleAvatar( + // radius: 50, + // backgroundImage: snapshot.data, + // child: Align( + // alignment: Alignment.bottomRight, + // child: GestureDetector( + // onTap: _pickImage, + // child: CircleAvatar( + // radius: 15, + // backgroundColor: Colors.white, + // child: Icon( + // Icons.camera_alt, + // size: 15, + // color: Colors.grey, + // ), + // ), + // ), + // ), + // ); + // } + // }, + // ), + // ], + // ), - Stack( - alignment: Alignment.center, - children: [ - CircleAvatar( - radius: 50, - backgroundImage: _profileImage != null - ? FileImage( - _profileImage!) // If a local file is selected - : _avatarUrl.isNotEmpty - ? NetworkImage( - _avatarUrl) // Load from URL - : AssetImage( - 'assets/edit_profile/profile.jpg') - as ImageProvider, - child: _avatarUrl.isNotEmpty - ? FutureBuilder( - future: _loadImage(_avatarUrl), - builder: (context, snapshot) { - if (snapshot - .connectionState == - ConnectionState.waiting) { - return Center( - child: - CircularProgressIndicator(), - ); - } else if (snapshot - .hasError) { - return Center( - child: Icon(Icons.error), - ); - } else { - return Align( - alignment: - Alignment.bottomRight, - child: GestureDetector( - onTap: - _pickImage, // Call `_pickImage` on tap - child: CircleAvatar( - radius: 15, - backgroundColor: - Colors.white, - child: Icon( - Icons.camera_alt, - size: 15, - color: Colors.grey, - ), - ), - ), - ); - } - }, - ) - : Align( - alignment: - Alignment.bottomRight, - child: GestureDetector( - onTap: - _pickImage, // Call `_pickImage` on tap - child: CircleAvatar( - radius: 15, - backgroundColor: - Colors.white, - child: Icon( - Icons.camera_alt, - size: 15, - color: Colors.grey, + Stack( + alignment: Alignment.center, + children: [ + CircleAvatar( + radius: 50, + backgroundImage: _profileImage != + null + ? FileImage( + _profileImage!) // If a local file is selected + : _avatarUrl.isNotEmpty + ? NetworkImage( + _avatarUrl) // Load from URL + : AssetImage( + 'assets/edit_profile/profile.jpg') + as ImageProvider, + child: _avatarUrl.isNotEmpty + ? FutureBuilder( + future: + _loadImage(_avatarUrl), + builder: + (context, snapshot) { + if (snapshot + .connectionState == + ConnectionState + .waiting) { + return Center( + child: + CircularProgressIndicator(), + ); + } else if (snapshot + .hasError) { + return Center( + child: + Icon(Icons.error), + ); + } else { + return Align( + alignment: Alignment + .bottomRight, + child: + GestureDetector( + onTap: + _pickImage, // Call `_pickImage` on tap + child: CircleAvatar( + radius: 15, + backgroundColor: + Colors.white, + child: Icon( + Icons + .camera_alt, + size: 15, + color: + Colors.grey, + ), + ), + ), + ); + } + }, + ) + : Align( + alignment: + Alignment.bottomRight, + child: GestureDetector( + onTap: + _pickImage, // Call `_pickImage` on tap + child: CircleAvatar( + radius: 15, + backgroundColor: + Colors.white, + child: Icon( + Icons.camera_alt, + size: 15, + color: Colors.grey, + ), + ), + ), + ), ), - ), + ], ), - ), - ), - ], - ), - SizedBox(height: 20), - Row( - mainAxisAlignment: MainAxisAlignment.start, - children: [ - Text( - AppLocalizations.of(context)! - .register_name, - style: TextStyle( - fontFamily: context.translate( - 'Roboto', - 'NotoKufi', - ), - fontSize: 16, - fontWeight: FontWeight.w500, - color: Colors.grey, - ), - ), - ], - ), - SizedBox(height: 10), - TextFormField( - controller: _usernameController, - focusNode: _focusNodes[0], - decoration: InputDecoration( - // hintText: _showHints[0] ? 'Mohammad Hassan' : null, - hintStyle: TextStyle(color: Colors.grey, fontFamily: context.translate( - 'Roboto', - 'NotoKufi', - ),), - border: OutlineInputBorder( - borderRadius: BorderRadius.circular(8), - ), - enabled: false, - ), - ), - SizedBox(height: 10), - Row( - mainAxisAlignment: MainAxisAlignment.start, - children: [ - Text( - AppLocalizations.of(context)!.email_id, - style: TextStyle( - fontFamily: context.translate( - 'Roboto', - 'NotoKufi', - ), - fontSize: 16, - fontWeight: FontWeight.w500, - color: Colors.grey, - ), - ), - ], - ), - SizedBox(height: 10), - TextFormField( - controller: _emailController, - focusNode: _focusNodes[1], - decoration: InputDecoration( - // hintText: _showHints[1]? 'mohammad.hassan@fcsc.gov.ae': null, - border: OutlineInputBorder( - borderRadius: BorderRadius.circular(8), - ), - enabled: false, - ), - ), - SizedBox(height: 10), - Row( - mainAxisAlignment: MainAxisAlignment.start, - children: [ - Text( - AppLocalizations.of(context)!.full_name, - style: TextStyle( - fontFamily: context.translate( - 'Roboto', - 'NotoKufi', - ), - fontSize: 16, - fontWeight: FontWeight.w500, - color: Colors.grey, - ), - ), - ], - ), - SizedBox(height: 10), - TextFormField( - enabled: false, - validator: (value) { - if (value == null || value.isEmpty) { - return context.translate( - 'Required', 'مطلوب'); - } - - //RegExp(r"^[a-zA-Z\s]+$"); - final nameRegex = RegExp( - r"^[a-zA-Z0-9'\-\u0627\u0639~\u00C0-\u00FF\s]+$", - ); - if (!nameRegex.hasMatch(value)) { - return AppLocalizations.of(context)! - .invalid_characters; - } - return null; - }, - controller: _fullNameController, - focusNode: _focusNodes[2], - decoration: InputDecoration( - // hintText: _showHints[2] ? 'Mohammad' : null, - hintStyle: TextStyle(color: Colors.grey, - fontFamily: context.translate( - 'Roboto', - 'NotoKufi', - ),), - border: OutlineInputBorder( - borderRadius: BorderRadius.circular(8), - ), - // counterText: '', - enabled: !_isProfileCompleted, - ), - // maxLength: - // 40, // Set the maximum length to 20 characters - // maxLengthEnforcement: - // MaxLengthEnforcement.enforced, - ), - SizedBox(height: 10), - Row( - mainAxisAlignment: MainAxisAlignment.start, - children: [ - Text( - AppLocalizations.of(context)!.dob, - style: TextStyle( - fontFamily: context.translate( - 'Roboto', - 'NotoKufi', - ), - fontSize: 16, - fontWeight: FontWeight.w500, - color: Colors.grey, - ), - ), - ], - ), - SizedBox(height: 10), - TextFormField( - controller: _dateController, - focusNode: _focusNodes[3], - decoration: InputDecoration( - border: OutlineInputBorder( - borderRadius: BorderRadius.circular(8), - ), - // hintText: _showHints[3] ? 'Select your Date of Birth' : null, - hintStyle: TextStyle(color: Colors.grey, fontFamily: context.translate( - 'Roboto', - 'NotoKufi', - ),), - suffixIcon: Container( - width: 45, - padding: EdgeInsets.only(right: 1), - alignment: Alignment - .center, // Center the icon vertically - child: Icon( - Icons.keyboard_arrow_down_sharp, - color: Colors.grey, - ), - ), - enabled: !_isProfileCompleted, - ), - readOnly: true, - onTap: _pickDate, - validator: _validateDob, - ), - SizedBox(height: 10), - Row( - mainAxisAlignment: MainAxisAlignment.start, - children: [ - Text( - AppLocalizations.of(context)!.region, - style: TextStyle( - fontFamily: context.translate( - 'Roboto', - 'NotoKufi', - ), - fontSize: 16, - fontWeight: FontWeight.w500, - ), - ), - ], - ), - SizedBox(height: 10), - MouseRegion( - onEnter: (_) => setState( - () => _isHoveringDropdown = true), - onExit: (_) => setState( - () => _isHoveringDropdown = false), - child: DropdownButtonFormField( - style: TextStyle( - fontFamily: context.translate( - 'Roboto', - 'NotoKufi', - ), - fontSize: 16, - fontWeight: FontWeight.normal, - color: Color(0xFF544C4C), - ), - value: _selectedCountry, - decoration: InputDecoration( - enabledBorder: OutlineInputBorder( - borderRadius: - BorderRadius.circular(10), - borderSide: BorderSide( - color: MyTheme.topicColor( - IndicatorTopic.economy) - .shade400, - width: 1), // Enabled border - ), - border: OutlineInputBorder( - borderSide: BorderSide( - color: Color(0xFF7296BE), - ), - borderRadius: - BorderRadius.circular(8), - ), - labelText: 'Select', - ), - icon: Icon( - Icons.keyboard_arrow_down_sharp, - color: _isHoveringDropdown - ? Colors.black - : Colors.grey), - items: _countries - .map( - (item) => DropdownMenuItem( - value: item, - child: Text(item, - style: TextStyle( - fontFamily: context.translate( - 'Roboto', - 'NotoKufi', - ) - ),), - ), - ) - .toList(), - onChanged: (String? newValue) { - setState(() { - _selectedCountry = newValue; - }); - }, - validator: _validateDropdown, - ), - ), - Row( - mainAxisAlignment: MainAxisAlignment.start, - children: [ - Text( - AppLocalizations.of(context)! - .preferredLang, - style: TextStyle( - fontFamily: context.translate( - 'Roboto', - 'NotoKufi', - ), - fontSize: 16, - fontWeight: FontWeight.w500), - ), - ], - ), - SizedBox(height: 10), - MouseRegion( - onEnter: (_) => setState( - () => _isHoveringPreferredLang = true), - onExit: (_) => setState( - () => _isHoveringPreferredLang = false), - child: DropdownButtonFormField( - style: TextStyle( - fontFamily: context.translate( - 'Roboto', - 'NotoKufi', - ), - fontSize: 16, - fontWeight: FontWeight.normal, - color: Color(0xFF544C4C), - ), - value: _selectedLanguage, - decoration: InputDecoration( - enabledBorder: OutlineInputBorder( - borderRadius: - BorderRadius.circular(10), - borderSide: BorderSide( - color: MyTheme.topicColor( - IndicatorTopic.economy) - .shade400, - width: 1), // Enabled border - ), - border: OutlineInputBorder( - borderSide: BorderSide( - color: Color(0xFF7296BE), - ), - borderRadius: - BorderRadius.circular(8), - ), - labelText: 'Select', - ), - icon: Icon( - Icons.keyboard_arrow_down_sharp, - color: _isHoveringPreferredLang - ? Colors.black - : Colors.grey), - items: preferred_language - .map( - (item) => DropdownMenuItem( - value: item, - child: Text(item, - style: TextStyle( - fontFamily: context.translate( - 'Roboto', - 'NotoKufi', - ) - ),), - ), - ) - .toList(), - onChanged: (String? newValue) { - setState(() { - _selectedLanguage = newValue; - changedPreferredLanguage = 1; - }); - }, - validator: _validatePreferredLang, - ), - ), - - SizedBox(height: 20), - if (!_isProfileCompleted) // Conditional rendering - Column( - crossAxisAlignment: - CrossAxisAlignment.start, - children: [ - Row( - children: [ - Checkbox( - value: isChecked, - onChanged: (value) { - setState(() { - isChecked = value ?? false; - showError = false; - }); - }, - side: BorderSide( - color: showError - ? Color(0xFFb22222) - : MyTheme.topicColor( - IndicatorTopic - .economy) - .shade400, - width: 1.5, - ), - ), - Expanded( - child: Column( - mainAxisAlignment: - MainAxisAlignment.start, - crossAxisAlignment: - CrossAxisAlignment.start, - children: [ - SizedBox(height: 10), - Text.rich( - TextSpan( - text: AppLocalizations.of( - context)! - .agree, - style: TextStyle( - fontFamily: context.translate( - 'Roboto', - 'NotoKufi', - ), - color: Colors.black), - children: [ - TextSpan( - text: AppLocalizations - .of( - context, - )! - .terms_conditions, - style: TextStyle( - fontFamily: context.translate( - 'Roboto', - 'NotoKufi', - ), - // color: Colors.blue, - color: Color( - 0xFF648CBA), - decoration: - TextDecoration - .underline, - ), - recognizer: - TapGestureRecognizer() - ..onTap = () => - context.push( - '/termsandconditions'), - ), - TextSpan( - text: AppLocalizations - .of( - context, - )! - .t_and, - style: TextStyle( - fontFamily: context.translate( - 'Roboto', - 'NotoKufi', - ), - color: Colors.black, - ), - ), - TextSpan( - text: AppLocalizations - .of( - context, - )! - .privacy_policy, - style: TextStyle( - fontFamily: context.translate( - 'Roboto', - 'NotoKufi', - ), - // color: Colors.blue, - color: Color( - 0xFF648CBA), - decoration: - TextDecoration - .underline, - ), - recognizer: - TapGestureRecognizer() - ..onTap = () => - context.push( - '/privacy_policy'), - ), - TextSpan( - text: AppLocalizations - .of( - context, - )! - .conditions, - style: TextStyle( - fontFamily: context.translate( - 'Roboto', - 'NotoKufi', - ), - color: Colors.black, - ), - ), - ], - ), - textAlign: TextAlign.start, - maxLines: 2, - overflow: - TextOverflow.visible, - softWrap: true, - ), - ], - ), - ), - ], - ), - if (showError) + SizedBox(height: 20), Row( mainAxisAlignment: - MainAxisAlignment.start, + MainAxisAlignment.start, children: [ - Padding( - padding: const EdgeInsets.only( - left: 10.0), - child: Text( - 'Please agree to terms and conditions', - style: TextStyle( - fontFamily: context.translate( - 'Roboto', - 'NotoKufi', - ), - color: Colors.red[700], - fontSize: 12, + Text( + AppLocalizations.of(context)! + .register_name, + style: TextStyle( + fontFamily: context.translate( + 'Roboto', + 'NotoKufi', ), + fontSize: 16, + fontWeight: FontWeight.w500, + color: Colors.grey, ), ), ], ), - ], - ), - Center( - child: GestureDetector( - onTap: () { - final email = _emailController.text; - context.push( - '/createNewPw/$userId/$email?key=editProfile'); - }, - child: Text( - AppLocalizations.of(context)! - .change_password, - style: TextStyle( - // color: Color(0xFF648CBA), - color: Color(0xFF985400), - fontSize: 14, - fontWeight: FontWeight.w700, - fontFamily: context.translate( - 'Roboto', - 'NotoKufi', + SizedBox(height: 10), + TextFormField( + controller: _usernameController, + focusNode: _focusNodes[0], + decoration: InputDecoration( + // hintText: _showHints[0] ? 'Mohammad Hassan' : null, + hintStyle: TextStyle( + color: Colors.grey, + fontFamily: context.translate( + 'Roboto', + 'NotoKufi', + ), + ), + border: OutlineInputBorder( + borderRadius: + BorderRadius.circular(8), + ), + enabled: false, + ), ), - // decoration: TextDecoration.underline - ), + SizedBox(height: 10), + Row( + mainAxisAlignment: + MainAxisAlignment.start, + children: [ + Text( + AppLocalizations.of(context)! + .email_id, + style: TextStyle( + fontFamily: context.translate( + 'Roboto', + 'NotoKufi', + ), + fontSize: 16, + fontWeight: FontWeight.w500, + color: Colors.grey, + ), + ), + ], + ), + SizedBox(height: 10), + TextFormField( + controller: _emailController, + focusNode: _focusNodes[1], + decoration: InputDecoration( + // hintText: _showHints[1]? 'mohammad.hassan@fcsc.gov.ae': null, + border: OutlineInputBorder( + borderRadius: + BorderRadius.circular(8), + ), + enabled: false, + ), + ), + SizedBox(height: 10), + Row( + mainAxisAlignment: + MainAxisAlignment.start, + children: [ + Text( + AppLocalizations.of(context)! + .full_name, + style: TextStyle( + fontFamily: context.translate( + 'Roboto', + 'NotoKufi', + ), + fontSize: 16, + fontWeight: FontWeight.w500, + color: Colors.grey, + ), + ), + ], + ), + SizedBox(height: 10), + TextFormField( + enabled: false, + validator: (value) { + if (value == null || value.isEmpty) { + return context.translate( + 'Required', 'مطلوب'); + } + + //RegExp(r"^[a-zA-Z\s]+$"); + final nameRegex = RegExp( + r"^[a-zA-Z0-9'\-\u0627\u0639~\u00C0-\u00FF\s]+$", + ); + if (!nameRegex.hasMatch(value)) { + return AppLocalizations.of(context)! + .invalid_characters; + } + return null; + }, + controller: _fullNameController, + focusNode: _focusNodes[2], + decoration: InputDecoration( + // hintText: _showHints[2] ? 'Mohammad' : null, + hintStyle: TextStyle( + color: Colors.grey, + fontFamily: context.translate( + 'Roboto', + 'NotoKufi', + ), + ), + border: OutlineInputBorder( + borderRadius: + BorderRadius.circular(8), + ), + // counterText: '', + enabled: !_isProfileCompleted, + ), + // maxLength: + // 40, // Set the maximum length to 20 characters + // maxLengthEnforcement: + // MaxLengthEnforcement.enforced, + ), + SizedBox(height: 10), + Row( + mainAxisAlignment: + MainAxisAlignment.start, + children: [ + Text( + AppLocalizations.of(context)!.dob, + style: TextStyle( + fontFamily: context.translate( + 'Roboto', + 'NotoKufi', + ), + fontSize: 16, + fontWeight: FontWeight.w500, + color: Colors.grey, + ), + ), + ], + ), + SizedBox(height: 10), + TextFormField( + controller: _dateController, + focusNode: _focusNodes[3], + decoration: InputDecoration( + border: OutlineInputBorder( + borderRadius: + BorderRadius.circular(8), + ), + // hintText: _showHints[3] ? 'Select your Date of Birth' : null, + hintStyle: TextStyle( + color: Colors.grey, + fontFamily: context.translate( + 'Roboto', + 'NotoKufi', + ), + ), + suffixIcon: Container( + width: 45, + padding: EdgeInsets.only(right: 1), + alignment: Alignment + .center, // Center the icon vertically + child: Icon( + Icons.keyboard_arrow_down_sharp, + color: Colors.grey, + ), + ), + enabled: !_isProfileCompleted, + ), + readOnly: true, + onTap: _pickDate, + validator: _validateDob, + ), + SizedBox(height: 10), + Row( + mainAxisAlignment: + MainAxisAlignment.start, + children: [ + Text( + AppLocalizations.of(context)! + .region, + style: TextStyle( + fontFamily: context.translate( + 'Roboto', + 'NotoKufi', + ), + fontSize: 16, + fontWeight: FontWeight.w500, + ), + ), + ], + ), + SizedBox(height: 10), + MouseRegion( + onEnter: (_) => setState( + () => _isHoveringDropdown = true), + onExit: (_) => setState( + () => _isHoveringDropdown = false), + child: DropdownButtonFormField( + style: TextStyle( + fontFamily: context.translate( + 'Roboto', + 'NotoKufi', + ), + fontSize: 16, + fontWeight: FontWeight.normal, + color: Color(0xFF544C4C), + ), + value: _selectedCountry, + decoration: InputDecoration( + enabledBorder: OutlineInputBorder( + borderRadius: + BorderRadius.circular(10), + borderSide: BorderSide( + color: MyTheme.topicColor( + IndicatorTopic + .economy) + .shade400, + width: 1), // Enabled border + ), + border: OutlineInputBorder( + borderSide: BorderSide( + color: Color(0xFF7296BE), + ), + borderRadius: + BorderRadius.circular(8), + ), + labelText: 'Select', + ), + icon: Icon( + Icons.keyboard_arrow_down_sharp, + color: _isHoveringDropdown + ? Colors.black + : Colors.grey), + items: _countries + .map( + (item) => + DropdownMenuItem( + value: item, + child: Text( + item, + style: TextStyle( + fontFamily: + context.translate( + 'Roboto', + 'NotoKufi', + )), + ), + ), + ) + .toList(), + onChanged: (String? newValue) { + setState(() { + _selectedCountry = newValue; + }); + }, + validator: _validateDropdown, + ), + ), + Row( + mainAxisAlignment: + MainAxisAlignment.start, + children: [ + Text( + AppLocalizations.of(context)! + .preferredLang, + style: TextStyle( + fontFamily: context.translate( + 'Roboto', + 'NotoKufi', + ), + fontSize: 16, + fontWeight: FontWeight.w500), + ), + ], + ), + SizedBox(height: 10), + MouseRegion( + onEnter: (_) => setState(() => + _isHoveringPreferredLang = true), + onExit: (_) => setState(() => + _isHoveringPreferredLang = false), + child: DropdownButtonFormField( + style: TextStyle( + fontFamily: context.translate( + 'Roboto', + 'NotoKufi', + ), + fontSize: 16, + fontWeight: FontWeight.normal, + color: Color(0xFF544C4C), + ), + value: _selectedLanguage, + decoration: InputDecoration( + enabledBorder: OutlineInputBorder( + borderRadius: + BorderRadius.circular(10), + borderSide: BorderSide( + color: MyTheme.topicColor( + IndicatorTopic + .economy) + .shade400, + width: 1), // Enabled border + ), + border: OutlineInputBorder( + borderSide: BorderSide( + color: Color(0xFF7296BE), + ), + borderRadius: + BorderRadius.circular(8), + ), + labelText: 'Select', + ), + icon: Icon( + Icons.keyboard_arrow_down_sharp, + color: _isHoveringPreferredLang + ? Colors.black + : Colors.grey), + items: preferred_language + .map( + (item) => + DropdownMenuItem( + value: item, + child: Text( + item, + style: TextStyle( + fontFamily: + context.translate( + 'Roboto', + 'NotoKufi', + )), + ), + ), + ) + .toList(), + onChanged: (String? newValue) { + setState(() { + _selectedLanguage = newValue; + changedPreferredLanguage = 1; + }); + }, + validator: _validatePreferredLang, + ), + ), + + SizedBox(height: 20), + if (!_isProfileCompleted) // Conditional rendering + Column( + crossAxisAlignment: + CrossAxisAlignment.start, + children: [ + Row( + children: [ + Checkbox( + value: isChecked, + onChanged: (value) { + setState(() { + isChecked = + value ?? false; + showError = false; + }); + }, + side: BorderSide( + color: showError + ? Color(0xFFb22222) + : MyTheme.topicColor( + IndicatorTopic + .economy) + .shade400, + width: 1.5, + ), + ), + Expanded( + child: Column( + mainAxisAlignment: + MainAxisAlignment.start, + crossAxisAlignment: + CrossAxisAlignment + .start, + children: [ + SizedBox(height: 10), + Text.rich( + TextSpan( + text: AppLocalizations + .of(context)! + .agree, + style: TextStyle( + fontFamily: context + .translate( + 'Roboto', + 'NotoKufi', + ), + color: + Colors.black), + children: [ + TextSpan( + text: AppLocalizations + .of( + context, + )! + .terms_conditions, + style: TextStyle( + fontFamily: context + .translate( + 'Roboto', + 'NotoKufi', + ), + // color: Colors.blue, + color: Color( + 0xFF648CBA), + decoration: + TextDecoration + .underline, + ), + recognizer: TapGestureRecognizer() + ..onTap = () => + context.push( + '/termsandconditions'), + ), + TextSpan( + text: + AppLocalizations + .of( + context, + )! + .t_and, + style: TextStyle( + fontFamily: context + .translate( + 'Roboto', + 'NotoKufi', + ), + color: Colors + .black, + ), + ), + TextSpan( + text: AppLocalizations + .of( + context, + )! + .privacy_policy, + style: TextStyle( + fontFamily: context + .translate( + 'Roboto', + 'NotoKufi', + ), + // color: Colors.blue, + color: Color( + 0xFF648CBA), + decoration: + TextDecoration + .underline, + ), + recognizer: TapGestureRecognizer() + ..onTap = () => + context.push( + '/privacy_policy'), + ), + TextSpan( + text: AppLocalizations + .of( + context, + )! + .conditions, + style: TextStyle( + fontFamily: context + .translate( + 'Roboto', + 'NotoKufi', + ), + color: Colors + .black, + ), + ), + ], + ), + textAlign: + TextAlign.start, + maxLines: 2, + overflow: TextOverflow + .visible, + softWrap: true, + ), + ], + ), + ), + ], + ), + if (showError) + Row( + mainAxisAlignment: + MainAxisAlignment.start, + children: [ + Padding( + padding: + const EdgeInsets.only( + left: 10.0), + child: Text( + 'Please agree to terms and conditions', + style: TextStyle( + fontFamily: + context.translate( + 'Roboto', + 'NotoKufi', + ), + color: Colors.red[700], + fontSize: 12, + ), + ), + ), + ], + ), + ], + ), + Center( + child: GestureDetector( + onTap: () { + final email = _emailController.text; + context.push( + '/createNewPw/$userId/$email?key=editProfile'); + }, + child: Text( + AppLocalizations.of(context)! + .change_password, + style: TextStyle( + // color: Color(0xFF648CBA), + color: isDarkTheme ? Color(0xFF9EB3E4) : Color(0xFF985400), + fontSize: 14, + fontWeight: FontWeight.w700, + fontFamily: context.translate( + 'Roboto', + 'NotoKufi', + ), + // decoration: TextDecoration.underline + ), + ), + ), + ), + SizedBox(height: 20), + // ElevatedButton.icon( + // onPressed: () { + // showConfirmationDialog(context); + // }, + // icon: Icon( + // Icons.save, + // color: Colors.white, + // ), + // label: Text( + // AppLocalizations.of(context)!.save, + // style: TextStyle(color: Colors.white), + // ), + // style: ElevatedButton.styleFrom( + // backgroundColor: Color(0xFF92722A), + // minimumSize: Size(double.infinity, 50), + // shape: RoundedRectangleBorder( + // borderRadius: BorderRadius.circular(8), + // ), + // ), + // ), + ElevatedButton( + onPressed: () { + // if ((_formKey.currentState?.validate() ?? false) && (isChecked)) { + // _formKey.currentState?.save(); + showConfirmationDialog(context); + // } else { + // setState(() { + // showError = !isChecked; // Show error if the checkbox is not checked + // }); + // } + }, + style: ElevatedButton.styleFrom( + backgroundColor: isDarkTheme ? Color(0xFF24B4FB) : Color(0xFF92722A), + minimumSize: + Size(double.infinity, 50), + shape: RoundedRectangleBorder( + borderRadius: + BorderRadius.circular(8), + ), + ), + child: Row( + mainAxisAlignment: MainAxisAlignment + .center, // Center the content + children: [ + Text( + AppLocalizations.of(context)! + .save, + style: TextStyle( + color: Colors.white, + fontFamily: context.translate( + 'Roboto', + 'NotoKufi', + ), + ), + ), + SizedBox( + width: + 8), // Add space between text and icon + Image.asset( + MiscIconAssetPath.save, + color: Colors.white, + width: 20, + height: 20, + ), + ], + ), + ) + ], ), ), ), - SizedBox(height: 20), - // ElevatedButton.icon( - // onPressed: () { - // showConfirmationDialog(context); - // }, - // icon: Icon( - // Icons.save, - // color: Colors.white, - // ), - // label: Text( - // AppLocalizations.of(context)!.save, - // style: TextStyle(color: Colors.white), - // ), - // style: ElevatedButton.styleFrom( - // backgroundColor: Color(0xFF92722A), - // minimumSize: Size(double.infinity, 50), - // shape: RoundedRectangleBorder( - // borderRadius: BorderRadius.circular(8), - // ), - // ), - // ), - ElevatedButton( - onPressed: () { - // if ((_formKey.currentState?.validate() ?? false) && (isChecked)) { - // _formKey.currentState?.save(); - showConfirmationDialog(context); - // } else { - // setState(() { - // showError = !isChecked; // Show error if the checkbox is not checked - // }); - // } - }, - style: ElevatedButton.styleFrom( - backgroundColor: Color(0xFF92722A), - minimumSize: Size(double.infinity, 50), - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(8), - ), - ), - child: Row( - mainAxisAlignment: MainAxisAlignment - .center, // Center the content - children: [ - Text( - AppLocalizations.of(context)!.save, - style: TextStyle(color: Colors.white, fontFamily: context.translate( - 'Roboto', - 'NotoKufi', - ),), - ), - SizedBox( - width: - 8), // Add space between text and icon - Image.asset( - MiscIconAssetPath.save, - color: Colors.white, - width: 20, - height: 20, - ), - ], - ), - ) - ], - ), + ), + ], ), ), ), - ], - ), - ), - ), - ) + ) - - //bottomNavigationBar: MyBottomNavBar(), - )); + //bottomNavigationBar: MyBottomNavBar(), + )); } } @@ -1371,11 +1437,13 @@ class ConfirmationDialog extends StatelessWidget { children: [ TextSpan( text: 'Country', - style: - TextStyle(fontWeight: FontWeight.w500, fontFamily: context.translate( - 'Roboto', - 'NotoKufi', - ),), // Bold for "name" + style: TextStyle( + fontWeight: FontWeight.w500, + fontFamily: context.translate( + 'Roboto', + 'NotoKufi', + ), + ), // Bold for "name" ), TextSpan( text: ' or ', @@ -1422,10 +1490,13 @@ class ConfirmationDialog extends StatelessWidget { ), child: Text( 'Cancel', - style: TextStyle(color: Color(0xFF92722A), fontFamily: context.translate( - 'Roboto', - 'NotoKufi', - ),), + style: TextStyle( + color: Color(0xFF92722A), + fontFamily: context.translate( + 'Roboto', + 'NotoKufi', + ), + ), ), ), ElevatedButton( diff --git a/lib/presentation/routes/drawer_routes/Drawer Items/feedback.dart b/lib/presentation/routes/drawer_routes/Drawer Items/feedback.dart index 5a998a9f..44fbf93b 100644 --- a/lib/presentation/routes/drawer_routes/Drawer Items/feedback.dart +++ b/lib/presentation/routes/drawer_routes/Drawer Items/feedback.dart @@ -1,9 +1,13 @@ +import 'dart:convert'; + import 'package:external_repos/external_repos.dart'; import 'package:flutter/material.dart'; import 'package:flutter_rating_bar/flutter_rating_bar.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:go_router/go_router.dart'; +import 'package:http/http.dart' as http; import 'package:intl/intl.dart'; +import 'package:uae_stat/config/theme/theme_provider.dart'; import 'package:flutter_gen/gen_l10n/app_localizations.dart'; import 'package:pocketbase/pocketbase.dart'; import 'package:shared_preferences/shared_preferences.dart'; @@ -39,6 +43,8 @@ class _FeedbackFormState extends ConsumerState // PocketBase('http://127.0.0.1:8090'); // Initialize PocketBase client final TextEditingController _feedbackController = TextEditingController(); + List homePageData = []; + List filteredData = []; double _easeOfUseRating = 0; double _qualityRating = 0; @@ -107,18 +113,59 @@ class _FeedbackFormState extends ConsumerState bool _hasError = false; String _errorMessage = ''; late UserService _userService; + late ThemeMode currentTheme; @override void initState() { super.initState(); _userService = UserService(); + + final locale = ref.read(localeProvider); + currentTheme = ref.read(themeProvider); + print('123456789'); + print(currentTheme); + WidgetsBinding.instance.addPostFrameCallback((_) { + final isDark = currentTheme == ThemeMode.dark || + (currentTheme == ThemeMode.system && + MediaQuery.of(context).platformBrightness == Brightness.dark); + + final themeMode = (isDark ? 'dark' : 'light'); + print("ThemeMode - $themeMode"); + fetchData(locale?.languageCode ?? 'en', themeMode); + }); + WidgetsBinding.instance.addObserver(this); _loadFeedbackText(); _feedbackController.addListener(_handleTextChange); // fetchEmailConfiguration(); + checkUserId(); } + Future fetchData(locale, themeMode) async { + const baseUrl = '$apiUrl/api/getUAENumbersData'; + try { + final response = await http + .get(Uri.parse(baseUrl + '?language=$locale&color_mode=$themeMode')); + if (response.statusCode == 200) { + setState(() { + homePageData = (json.decode(response.body) as List) + .map((e) => Map.from(e)) + .toList(); + filteredData = List.from(homePageData); + isLoading = false; + }); + } else { + throw Exception('Failed to load data'); + } + } catch (e) { + setState(() { + isLoading = false; + }); + print('Error fetching data: $e'); + } + } + Future getUserId() async { final prefs = await SharedPreferences.getInstance(); return prefs.getString('userId'); // Retrieve the userId @@ -248,11 +295,54 @@ class _FeedbackFormState extends ConsumerState } }); + // ref.listen(localeProvider, (previous, next) async { + // final localeCode = next?.languageCode ?? 'en'; // Default to 'en' if null + // await _userService.updateLanguage(localeCode); + // }); + ref.listen(localeProvider, (previous, next) async { - final localeCode = next?.languageCode ?? 'en'; // Default to 'en' if null + final localeCode = next?.languageCode ?? 'en'; + setState(() { + isLoading = true; + }); await _userService.updateLanguage(localeCode); + final currentTheme = ref.read(themeProvider); + final isDark = currentTheme == ThemeMode.dark || + (currentTheme == ThemeMode.system && + MediaQuery.of(context).platformBrightness == Brightness.dark); + + final themeString = isDark ? 'dark' : 'light'; + fetchData(localeCode, themeString); }); + ref.listen(themeProvider, (previous, next) async { + final localeCode = ref.watch(localeProvider)?.languageCode ?? 'en'; + print(localeCode); + + // Default to 'en' if null + setState(() { + isLoading = true; + print('isLoadingref $isLoading'); + }); + + final currentTheme = ref.read(themeProvider); + final isDark = currentTheme == ThemeMode.dark || + (currentTheme == ThemeMode.system && + MediaQuery.of(context).platformBrightness == Brightness.dark); + + final themeString = isDark ? 'dark' : 'light'; + + print("themeString- $themeString"); + fetchData(localeCode, themeString); + }); + + final themeMode = ref.read(themeProvider); + final isDarkTheme = themeMode == ThemeMode.dark || + (themeMode == ThemeMode.system && + MediaQuery.of(context).platformBrightness == Brightness.dark); + + print("isDarkTheme - $isDarkTheme"); + final userName = GoRouterState.of(context).extra as String? ?? 'Guest User'; return PopScope( canPop: false, // Allow back navigation only if not login screen @@ -261,6 +351,11 @@ class _FeedbackFormState extends ConsumerState context.go('/myhomepage'); // Show exit confirmation dialog }, child: BaseScaffold( + backgroundColor: isDarkTheme ? Color(0xFF111111) : Colors.white, + appbarColor: isDarkTheme ? Color(0xFF111111) : Colors.white, + // backgroundColor: isDarkTheme ? Color(0xFF333333) : Color(0xFF414042), + // appbarColor: isDarkTheme ? Color(0xFF333333) : Color(0xFF414042), + // title: Text("Feedback"), title: Text( AppLocalizations.of(context)!.feedback_title, @@ -292,7 +387,9 @@ class _FeedbackFormState extends ConsumerState // ), body: isLoading ? Container( - color: Color(0x98FFFCE5), // Semi-transparent background + // color: Color(0x98FFFCE5), // Semi-transparent background + + color: isDarkTheme ? Color(0xFF000000) : Colors.white, child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ @@ -315,16 +412,16 @@ class _FeedbackFormState extends ConsumerState top: 8.0, bottom: 16.0, left: 23.0, right: 23.0), child: SingleChildScrollView( child: _isFeedbackSubmitted - ? _buildThankYouMessage(userName) + ? _buildThankYouMessage(userName, isDarkTheme) : _isFeedbackFailed - ? _buildFailureMessage() - : _buildFeedbackForm(), + ? _buildFailureMessage(isDarkTheme) + : _buildFeedbackForm(isDarkTheme), ), ), )); } - Widget _buildFeedbackForm() { + Widget _buildFeedbackForm(bool isDarkTheme) { return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ @@ -335,7 +432,7 @@ class _FeedbackFormState extends ConsumerState ), style: TextStyle( fontSize: 18, - color: Color(0xFF898C81), + color: isDarkTheme ? Colors.white : Color(0xFF898C81), fontFamily: context.translate( 'Roboto', 'NotoKufi', @@ -359,7 +456,8 @@ class _FeedbackFormState extends ConsumerState 'NotoKufi', ), fontWeight: FontWeight.w400, - color: Color(0xff898C81), + color: isDarkTheme ? Colors.white : Color(0xff898C81), + // color: Color(0xff898C81), ), ), ), @@ -387,6 +485,7 @@ class _FeedbackFormState extends ConsumerState // icon: _emojiOptions[index]["icon"], label: _emojiOptions[index]["label"], index: index, + isDarkTheme: isDarkTheme, ); }), ), @@ -398,10 +497,14 @@ class _FeedbackFormState extends ConsumerState 'Please rate your experience before submitting your feedback.', 'يرجى تقييم تجربتك قبل تقديم ملاحظاتك.', ), - style: TextStyle(color: Color(0xFFD83731), fontSize: 14, fontFamily: context.translate( - 'Roboto', - 'NotoKufi', - ),), + style: TextStyle( + color: Color(0xFFD83731), + fontSize: 14, + fontFamily: context.translate( + 'Roboto', + 'NotoKufi', + ), + ), ), ), ], @@ -421,19 +524,17 @@ class _FeedbackFormState extends ConsumerState 'NotoKufi', ), fontWeight: FontWeight.w400, - color: Color(0xFF898C81), + // color: Color(0xFF898C81), + color: isDarkTheme ? Colors.white : Color(0xff898C81), ), )), const SizedBox(height: 15), - _buildRatingRow( - context.translate('Ease of use', 'سهولة الاستخدام'), - _easeOfUseRating, - (rating) { - setState(() { - _easeOfUseRating = rating; - }); - }, - ), + _buildRatingRow(context.translate('Ease of use', 'سهولة الاستخدام'), + _easeOfUseRating, (rating) { + setState(() { + _easeOfUseRating = rating; + }); + }, isDarkTheme), _buildRatingRow( context.translate('Quality', 'الجودة'), _qualityRating, @@ -442,6 +543,7 @@ class _FeedbackFormState extends ConsumerState _qualityRating = rating; }); }, + isDarkTheme, ), _buildRatingRow( context.translate('Design', 'التصميم'), @@ -451,6 +553,7 @@ class _FeedbackFormState extends ConsumerState _designRating = rating; }); }, + isDarkTheme, ), _buildRatingRow( context.translate('Redundant', 'مكرر'), @@ -460,6 +563,7 @@ class _FeedbackFormState extends ConsumerState _redundancyRating = rating; }); }, + isDarkTheme, ), const SizedBox(height: 20), TextField( @@ -467,42 +571,51 @@ class _FeedbackFormState extends ConsumerState minLines: 5, // Start with 5 lines maxLines: null, // Allows the field to expand automatically maxLength: _characterLimit, - style: TextStyle(color: Color(0xFF898C81), fontFamily: context.translate( - 'Roboto', - 'NotoKufi', - ),), + style: TextStyle( + color: isDarkTheme ? Colors.white : Color(0xFF898C81), + fontFamily: context.translate( + 'Roboto', + 'NotoKufi', + ), + ), decoration: InputDecoration( hintText: context.translate( 'Tell us how we can improve', 'أخبرنا كيف يمكننا التحسين'), - hintStyle: TextStyle(color: Color(0xFF898C81), fontFamily: context.translate( - 'Roboto', - 'NotoKufi', - ),), + hintStyle: TextStyle( + color: isDarkTheme ? Colors.white : Color(0xFF898C81), + fontFamily: context.translate( + 'Roboto', + 'NotoKufi', + ), + ), border: OutlineInputBorder( borderRadius: BorderRadius.circular(10.0), - borderSide: BorderSide(color: Color(0xFF7296BE), width: 1), + borderSide: BorderSide(color: Color(0xFFB68A34), width: 2), ), // Border when the TextField is enabled but not focused enabledBorder: OutlineInputBorder( borderRadius: BorderRadius.circular(10.0), - borderSide: BorderSide(color: Color(0xFF7296BE), width: 1), + borderSide: BorderSide(color: Color(0xFFB68A34), width: 2), ), // Border when there is an error errorBorder: OutlineInputBorder( borderRadius: BorderRadius.circular(10.0), - borderSide: BorderSide(color: Color(0xFFD83731), width: 1), + borderSide: BorderSide(color: Color(0xFFD83731), width: 2), ), // Border when focused and there is an error focusedErrorBorder: OutlineInputBorder( borderRadius: BorderRadius.circular(10.0), - borderSide: BorderSide(color: Color(0xFFD83731), width: 1), + borderSide: BorderSide(color: Color(0xFFD83731), width: 2), ), errorText: _hasError ? _errorMessage : null, // Show error below field + errorStyle: TextStyle( + color: Color(0xFFD83731), + ), ), onChanged: (text) { // Trigger re-validation and character limit on each change @@ -532,9 +645,10 @@ class _FeedbackFormState extends ConsumerState fontWeight: FontWeight.w600, ), ), - backgroundColor: WidgetStatePropertyAll( - MyTheme.topicColor(IndicatorTopic.environment), - ), + backgroundColor: WidgetStatePropertyAll(Color(0xFFB68A34)), + // backgroundColor: WidgetStatePropertyAll( + // MyTheme.topicColor(IndicatorTopic.environment), + // ), foregroundColor: const WidgetStatePropertyAll( Colors.white, ), @@ -548,16 +662,18 @@ class _FeedbackFormState extends ConsumerState 'إرسال', ), style: TextStyle( - fontFamily: context.translate( - 'Roboto', - 'NotoKufi', - ) + fontFamily: context.translate( + 'Roboto', + 'NotoKufi', + ), + color: isDarkTheme ? Colors.black : Colors.white, ), ), 6.horizontalSpace, - const Icon( + Icon( Icons.chevron_right_outlined, - color: Colors.white, + // color: Colors.white, + color: isDarkTheme ? Colors.black : Colors.white, ), ], ), @@ -567,7 +683,7 @@ class _FeedbackFormState extends ConsumerState ); } - Widget _buildThankYouMessage(String userName) { + Widget _buildThankYouMessage(String userName, bool isDarkTheme) { double screenHeight = MediaQuery.of(context).size.height; return Center( child: Column( @@ -612,18 +728,26 @@ class _FeedbackFormState extends ConsumerState Text( '${AppLocalizations.of(context)!.thankYou} $userName !', - style: TextStyle(fontSize: 24, fontWeight: FontWeight.bold, fontFamily: context.translate( - 'Roboto', - 'NotoKufi', - ),), + style: TextStyle( + fontSize: 24, + fontWeight: FontWeight.bold, + fontFamily: context.translate( + 'Roboto', + 'NotoKufi', + ), + ), ), const SizedBox(height: 15), Text( AppLocalizations.of(context)!.feedback_message, - style: TextStyle(fontSize: 16, color: Color(0xFF898C81), fontFamily: context.translate( - 'Roboto', - 'NotoKufi', - ),), + style: TextStyle( + fontSize: 16, + color: isDarkTheme ? Colors.white : Color(0xFF898C81), + fontFamily: context.translate( + 'Roboto', + 'NotoKufi', + ), + ), textAlign: TextAlign.center, ), // const SizedBox(height: 30), @@ -638,7 +762,7 @@ class _FeedbackFormState extends ConsumerState } // New widget for failure message - Widget _buildFailureMessage() { + Widget _buildFailureMessage(bool isDarkTheme) { double screenHeight = MediaQuery.of(context).size.height; double screenWidth = MediaQuery.of(context).size.width; return Center( @@ -682,14 +806,18 @@ class _FeedbackFormState extends ConsumerState ), fontSize: 24, fontWeight: FontWeight.bold, - color: Color(0xFF414042)), + color: isDarkTheme ? Colors.white : Color(0xFF414042)), ), const SizedBox(height: 10), Text(AppLocalizations.of(context)!.feedback_failed_msg, - style: TextStyle(fontSize: 16, color: Color(0xFF898C81), fontFamily: context.translate( - 'Roboto', - 'NotoKufi', - ),), + style: TextStyle( + fontSize: 16, + color: isDarkTheme ? Colors.white : Color(0xFF898C81), + fontFamily: context.translate( + 'Roboto', + 'NotoKufi', + ), + ), textAlign: TextAlign.center), // const SizedBox(height: 30), // ElevatedButton( @@ -710,6 +838,7 @@ class _FeedbackFormState extends ConsumerState required Widget icon, required String label, required int index, + required bool isDarkTheme, }) { bool isSelected = _selectedEmojiIndex == index; return GestureDetector( @@ -746,7 +875,11 @@ class _FeedbackFormState extends ConsumerState ), fontWeight: FontWeight.w400, fontSize: 14, - color: Colors.black, + color: isDarkTheme + ? Colors.white + : Colors.black, // ❌ Wrong: black in dark theme? + + // color: Colors.black, // color: isSelected ? Colors.green : Colors.black, ), ), @@ -785,6 +918,7 @@ class _FeedbackFormState extends ConsumerState String label, double rating, Function(double) onRatingUpdate, + bool isDarkTheme, ) { return Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, @@ -797,7 +931,8 @@ class _FeedbackFormState extends ConsumerState 'NotoKufi', ), fontWeight: FontWeight.w400, - color: Color(0xFF898C81), + // color: Color(0xFF898C81), + color: isDarkTheme ? Colors.white : Color(0xff898C81), )), RatingBar.builder( initialRating: rating, @@ -839,12 +974,11 @@ class _FeedbackFormState extends ConsumerState SnackBar( content: Text( AppLocalizations.of(context)!.formError, - style: TextStyle( - fontFamily: context.translate( - 'Roboto', - 'NotoKufi', - ) - ), + style: TextStyle( + fontFamily: context.translate( + 'Roboto', + 'NotoKufi', + )), // "Please correct the errors before submitting." )), ); @@ -881,13 +1015,14 @@ class _FeedbackFormState extends ConsumerState await _removeFeedbackText(); ScaffoldMessenger.of(context).showSnackBar( SnackBar( - content: Text(AppLocalizations.of(context)!.feedback_submitted, + content: Text( + AppLocalizations.of(context)!.feedback_submitted, style: TextStyle( fontFamily: context.translate( - 'Roboto', - 'NotoKufi', - ) - ),), + 'Roboto', + 'NotoKufi', + )), + ), ), ); setState(() { @@ -903,12 +1038,11 @@ class _FeedbackFormState extends ConsumerState content: Text( // "Failed to submit feedback: $e" AppLocalizations.of(context)!.feedback_failed(e.toString()), - style: TextStyle( - fontFamily: context.translate( - 'Roboto', - 'NotoKufi', - ) - ), + style: TextStyle( + fontFamily: context.translate( + 'Roboto', + 'NotoKufi', + )), )), ); setState(() { diff --git a/lib/presentation/routes/drawer_routes/Drawer Items/manage_users.dart b/lib/presentation/routes/drawer_routes/Drawer Items/manage_users.dart index 97c8722c..4593cc08 100644 --- a/lib/presentation/routes/drawer_routes/Drawer Items/manage_users.dart +++ b/lib/presentation/routes/drawer_routes/Drawer Items/manage_users.dart @@ -15,6 +15,7 @@ import 'package:uae_stat/presentation/components/my_bottom_nav_bar.dart'; import 'package:uae_stat/presentation/components/my_drawer.dart'; import 'package:uae_stat/presentation/routes/drawer_routes/custom_drawer_routes.dart'; import 'package:flutter_gen/gen_l10n/app_localizations.dart'; +// import 'package:flutter_gen/gen_l10n/app_localizations.dart'; class ManageUserRouter extends ConsumerStatefulWidget { late final Widget title; @@ -153,13 +154,14 @@ class _ManageUserRouterState extends ConsumerState { }); ScaffoldMessenger.of(context).showSnackBar( SnackBar( - content: Text(AppLocalizations.of(context)!.status_success, + content: Text( + AppLocalizations.of(context)!.status_success, style: TextStyle( fontFamily: context.translate( - 'Roboto', - 'NotoKufi', - ) - ),), + 'Roboto', + 'NotoKufi', + )), + ), ), ); } catch (e) { @@ -169,15 +171,15 @@ class _ManageUserRouterState extends ConsumerState { Navigator.of(context).pop(); ScaffoldMessenger.of(context).showSnackBar( SnackBar( - content: Text(context.translate( - 'Error updating status: $e', '$e خطأ في تحديث الحالة: '), - style: TextStyle( - fontFamily: context.translate( - 'Roboto', - 'NotoKufi', - ) - ), - )), + content: Text( + context.translate( + 'Error updating status: $e', '$e خطأ في تحديث الحالة: '), + style: TextStyle( + fontFamily: context.translate( + 'Roboto', + 'NotoKufi', + )), + )), ); } } @@ -307,7 +309,9 @@ class _ManageUserRouterState extends ConsumerState { child: Text( // 'Yes', AppLocalizations.of(context)!.yes, - style: TextStyle(color: Colors.white, fontSize: 16, + style: TextStyle( + color: Colors.white, + fontSize: 16, fontFamily: context.translate( 'Roboto', 'NotoKufi', @@ -357,10 +361,9 @@ class _ManageUserRouterState extends ConsumerState { AppLocalizations.of(context)!.manage_user, style: TextStyle( fontFamily: context.translate( - 'Roboto', - 'NotoKufi', - ) - ), + 'Roboto', + 'NotoKufi', + )), ), body: isLoading ? Container( @@ -440,7 +443,8 @@ class _ManageUserRouterState extends ConsumerState { hintText: AppLocalizations.of(context)!.search, hintStyle: TextStyle( color: Color(0xFFAA8E83), - fontFamily: context.translate('Roboto', 'NotoKufi'), + fontFamily: + context.translate('Roboto', 'NotoKufi'), fontSize: 14, height: 2.5, // Helps with vertical alignment ), @@ -460,7 +464,8 @@ class _ManageUserRouterState extends ConsumerState { Color(0xFFAA8E83), BlendMode.srcIn), ), ), - contentPadding: EdgeInsets.only(top: 14), // Aligns hint text with icon + contentPadding: EdgeInsets.only( + top: 14), // Aligns hint text with icon border: InputBorder.none, ), onChanged: filterUsers, @@ -536,10 +541,9 @@ class _ManageUserRouterState extends ConsumerState { AppLocalizations.of(context)!.user_name, style: TextStyle( fontFamily: context.translate( - 'Roboto', - 'NotoKufi', - ) - ), + 'Roboto', + 'NotoKufi', + )), ), onSort: (columnIndex, ascending) { _sort( @@ -554,10 +558,9 @@ class _ManageUserRouterState extends ConsumerState { AppLocalizations.of(context)!.email_id, style: TextStyle( fontFamily: context.translate( - 'Roboto', - 'NotoKufi', - ) - ), + 'Roboto', + 'NotoKufi', + )), ), onSort: (columnIndex, ascending) { _sort( @@ -572,10 +575,9 @@ class _ManageUserRouterState extends ConsumerState { AppLocalizations.of(context)!.reg_date, style: TextStyle( fontFamily: context.translate( - 'Roboto', - 'NotoKufi', - ) - ), + 'Roboto', + 'NotoKufi', + )), ), onSort: (columnIndex, ascending) { _sort( @@ -591,10 +593,9 @@ class _ManageUserRouterState extends ConsumerState { AppLocalizations.of(context)!.status, style: TextStyle( fontFamily: context.translate( - 'Roboto', - 'NotoKufi', - ) - ), + 'Roboto', + 'NotoKufi', + )), ), onSort: (columnIndex, ascending) { _sort( @@ -616,7 +617,8 @@ class _ManageUserRouterState extends ConsumerState { context)! .no_result_found, style: TextStyle( - fontFamily: context.translate( + fontFamily: context + .translate( 'Roboto', 'NotoKufi', ), @@ -634,38 +636,34 @@ class _ManageUserRouterState extends ConsumerState { return DataRow( cells: [ DataCell( - Text( - user.userName, - style: TextStyle( - fontFamily: context.translate( - 'Roboto', - 'NotoKufi', - ) - ), - ), - - ), - DataCell( - Text( - user.emailId, - style: TextStyle( - fontFamily: context.translate( - 'Roboto', - 'NotoKufi', - ) - ), + Text( + user.userName, + style: TextStyle( + fontFamily: + context.translate( + 'Roboto', + 'NotoKufi', )), - DataCell( - Text( - user.registrationDate, - style: TextStyle( - fontFamily: context.translate( - 'Roboto', - 'NotoKufi', - ) - ), - ) + ), ), + DataCell(Text( + user.emailId, + style: TextStyle( + fontFamily: + context.translate( + 'Roboto', + 'NotoKufi', + )), + )), + DataCell(Text( + user.registrationDate, + style: TextStyle( + fontFamily: + context.translate( + 'Roboto', + 'NotoKufi', + )), + )), DataCell( DropdownButton( value: user.status, @@ -677,7 +675,8 @@ class _ManageUserRouterState extends ConsumerState { child: Text( status.value, style: TextStyle( - fontFamily: context.translate( + fontFamily: + context.translate( 'Roboto', 'NotoKufi', ), diff --git a/lib/presentation/routes/drawer_routes/Drawer Items/notification/notification.dart b/lib/presentation/routes/drawer_routes/Drawer Items/notification/notification.dart index da2c7174..0f459b3e 100644 --- a/lib/presentation/routes/drawer_routes/Drawer Items/notification/notification.dart +++ b/lib/presentation/routes/drawer_routes/Drawer Items/notification/notification.dart @@ -8,12 +8,14 @@ import 'package:pocketbase/pocketbase.dart'; import 'package:shared_preferences/shared_preferences.dart'; import 'package:uae_stat/config/api_config.dart'; import 'package:uae_stat/config/connectivity_provider.dart'; +import 'package:uae_stat/config/theme/theme_provider.dart'; import 'package:uae_stat/config/toggle_lang_service.dart'; import 'package:uae_stat/domain/use_cases/language.dart'; import 'package:uae_stat/presentation/components/indicators/locale_provider.dart'; import '../../custom_drawer_routes.dart'; import 'package:http/http.dart' as http; import 'package:flutter_gen/gen_l10n/app_localizations.dart'; +// import 'package:uae_stat/l10n/app_localizations.dart'; class NotificationPage extends ConsumerStatefulWidget { @override @@ -26,13 +28,17 @@ class _NotificationPageState extends ConsumerState { bool isLoading = true; List> notifications = []; List userReadedNotiOrNot = []; - String notificationCount=''; + String notificationCount = ''; + + List homePageData = []; + List filteredData = []; // Current selected tab index int selectedTabIndex = 0; late final Locale locale; dynamic userID; late UserService _userService; + late ThemeMode currentTheme; // Tab categories // final List tabs = [ @@ -50,17 +56,56 @@ class _NotificationPageState extends ConsumerState { locale = ref.read(localeProvider) ?? const Locale('en'); _userService = UserService(); _initializePage(); + + currentTheme = ref.read(themeProvider); + print('123456789'); + print(currentTheme); + WidgetsBinding.instance.addPostFrameCallback((_) { + final isDark = currentTheme == ThemeMode.dark || + (currentTheme == ThemeMode.system && + MediaQuery.of(context).platformBrightness == Brightness.dark); + + final themeMode = (isDark ? 'dark' : 'light'); + print("ThemeMode - $themeMode"); + fetchData(locale?.languageCode ?? 'en', themeMode); + }); + } + + Future fetchData(locale, themeMode) async { + const baseUrl = '$apiUrl/api/getUAENumbersData'; + try { + final response = await http + .get(Uri.parse(baseUrl + '?language=$locale&color_mode=$themeMode')); + if (response.statusCode == 200) { + setState(() { + homePageData = (json.decode(response.body) as List) + .map((e) => Map.from(e)) + .toList(); + filteredData = List.from(homePageData); + isLoading = false; + }); + } else { + throw Exception('Failed to load data'); + } + } catch (e) { + setState(() { + isLoading = false; + }); + print('Error fetching data: $e'); + } } Future _initializePage() async { _userService = UserService(); - await _fetchUserData();(); - await fetchNotifications(locale?.languageCode ?? 'en'); - _processNotifications(notifications , userReadedNotiOrNot); + await _fetchUserData(); + (); + await fetchNotifications(locale?.languageCode ?? 'en'); + _processNotifications(notifications, userReadedNotiOrNot); } - void _processNotifications( List> notification ,List push ){ - print ('inside last function ${notification.length}'); + void _processNotifications( + List> notification, List push) { + print('inside last function ${notification.length}'); print('inside last function ${push.length}'); int count = 0; @@ -70,9 +115,11 @@ class _NotificationPageState extends ConsumerState { } } print('count is $count'); - if(count>0){ - notificationCount='($count)';} - else{notificationCount='';} + if (count > 0) { + notificationCount = '($count)'; + } else { + notificationCount = ''; + } } Future getUserId() async { @@ -178,14 +225,58 @@ class _NotificationPageState extends ConsumerState { } }); + // ref.listen(localeProvider, (previous, next) async { + // final localeCode = next?.languageCode ?? 'en'; // Default to 'en' if null + // setState(() { + // isLoading = true; + // }); + // await _userService.updateLanguage(localeCode); + // fetchNotifications(localeCode); + // }); + ref.listen(localeProvider, (previous, next) async { - final localeCode = next?.languageCode ?? 'en'; // Default to 'en' if null + final localeCode = next?.languageCode ?? 'en'; setState(() { isLoading = true; }); await _userService.updateLanguage(localeCode); - fetchNotifications(localeCode); + final currentTheme = ref.read(themeProvider); + final isDark = currentTheme == ThemeMode.dark || + (currentTheme == ThemeMode.system && + MediaQuery.of(context).platformBrightness == Brightness.dark); + + final themeString = isDark ? 'dark' : 'light'; + fetchData(localeCode, themeString); }); + + ref.listen(themeProvider, (previous, next) async { + final localeCode = ref.watch(localeProvider)?.languageCode ?? 'en'; + print(localeCode); + + // Default to 'en' if null + setState(() { + isLoading = true; + print('isLoadingref $isLoading'); + }); + + final currentTheme = ref.read(themeProvider); + final isDark = currentTheme == ThemeMode.dark || + (currentTheme == ThemeMode.system && + MediaQuery.of(context).platformBrightness == Brightness.dark); + + final themeString = isDark ? 'dark' : 'light'; + + print("themeString- $themeString"); + fetchData(localeCode, themeString); + }); + + final themeMode = ref.read(themeProvider); + final isDarkTheme = themeMode == ThemeMode.dark || + (themeMode == ThemeMode.system && + MediaQuery.of(context).platformBrightness == Brightness.dark); + + print("isDarkTheme - $isDarkTheme"); + final List> tabs = [ {'title': AppLocalizations.of(context)!.all_updates}, {'title': AppLocalizations.of(context)!.app_updates}, @@ -210,6 +301,8 @@ class _NotificationPageState extends ConsumerState { context.go('/myhomepage'); }, child: BaseScaffold( + backgroundColor: isDarkTheme ? Color(0xFF111111) : Colors.white, + appbarColor: isDarkTheme ? Color(0xFF111111) : Colors.white, title: Text( context.translate( 'Notification $notificationCount', @@ -217,14 +310,16 @@ class _NotificationPageState extends ConsumerState { ), style: TextStyle( fontFamily: context.translate( - 'Roboto', - 'NotoKufi', - ) - ), + 'Roboto', + 'NotoKufi', + )), ), body: isLoading ? Container( - color: Color(0x98FFFCE5), // Semi-transparent background + // color: Color(0x98FFFCE5), // Semi-transparent background + color: isDarkTheme + ? Color(0xFF111111) + : Color(0x98FFFCE5), // Semi-transparent background child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ @@ -247,6 +342,7 @@ class _NotificationPageState extends ConsumerState { TabBarHeader( tabs: tabs.map((tab) => tab['title'] as String).toList(), selectedIndex: selectedTabIndex, + isDarkTheme: isDarkTheme, onTabSelected: (index) { setState(() { selectedTabIndex = index; @@ -265,10 +361,13 @@ class _NotificationPageState extends ConsumerState { Text( 'No notifications available.', style: TextStyle( - fontSize: 16, color: Colors.grey, fontFamily: context.translate( - 'Roboto', - 'NotoKufi', - ),), + fontSize: 16, + color: Colors.grey, + fontFamily: context.translate( + 'Roboto', + 'NotoKufi', + ), + ), ), ], ), @@ -295,6 +394,7 @@ class _NotificationPageState extends ConsumerState { id: notification['id'], userReadedNotiOrNot: userReadedNotiOrNot, userID: userID, + isDarkTheme: isDarkTheme, ), ); }, @@ -311,17 +411,19 @@ class TabBarHeader extends StatelessWidget { final List tabs; final int selectedIndex; final ValueChanged onTabSelected; + bool isDarkTheme; - const TabBarHeader({ + TabBarHeader({ required this.tabs, required this.selectedIndex, required this.onTabSelected, + required this.isDarkTheme, }); @override Widget build(BuildContext context) { return Container( - color: Colors.grey[200], + color: isDarkTheme ? Color(0xFF111111) : Colors.grey[200], padding: const EdgeInsets.symmetric(vertical: 8), child: SingleChildScrollView( scrollDirection: Axis.horizontal, @@ -342,12 +444,14 @@ class TabBarHeader extends StatelessWidget { : Colors.grey[700]; }), ), - child: Text(text, + child: Text( + text, style: TextStyle( fontFamily: context.translate( 'Roboto', 'NotoKufi', - ), ), + ), + ), ), ), if (index < tabs.length - 1) buildDivider(), @@ -379,8 +483,9 @@ class NotificationTile extends StatelessWidget { final String id; final String userID; final List userReadedNotiOrNot; + bool isDarkTheme; - const NotificationTile({ + NotificationTile({ required this.title, required this.message, required this.date, @@ -388,6 +493,7 @@ class NotificationTile extends StatelessWidget { required this.id, required this.userID, required this.userReadedNotiOrNot, + required this.isDarkTheme, }); @override @@ -411,11 +517,19 @@ class NotificationTile extends StatelessWidget { child: ListTile( leading: isPushed ? const Icon(Icons.circle, size: 12, color: Color(0xFFFF274E)) - : const Icon(Icons.circle, size: 12, color: Color(0x99414042)), + : Icon(Icons.circle, + size: 12, + color: isDarkTheme ? Colors.white : const Color(0x99414042)), title: Text( title, style: TextStyle( - color: isPushed ? const Color(0xFF414042) : const Color(0x99414042), + color: isPushed + ? isDarkTheme + ? Colors.white + : Color(0xFF414042) + : isDarkTheme + ? Colors.white + : Color(0x99414042), fontWeight: FontWeight.bold, fontFamily: context.translate( 'Roboto', @@ -426,7 +540,13 @@ class NotificationTile extends StatelessWidget { subtitle: Text( date, style: TextStyle( - color: isPushed ? const Color(0xFF8E8E8E) : const Color(0x998E8E8E), + color: isPushed + ? isDarkTheme + ? Colors.white + : Color(0xFF8E8E8E) + : isDarkTheme + ? Colors.white + : Color(0x998E8E8E), fontSize: 12, fontWeight: FontWeight.w400, fontFamily: context.translate( diff --git a/lib/presentation/routes/drawer_routes/Drawer Items/notification/notification_details.dart b/lib/presentation/routes/drawer_routes/Drawer Items/notification/notification_details.dart index 16eb7d43..5e4969e6 100644 --- a/lib/presentation/routes/drawer_routes/Drawer Items/notification/notification_details.dart +++ b/lib/presentation/routes/drawer_routes/Drawer Items/notification/notification_details.dart @@ -7,6 +7,7 @@ import 'package:pocketbase/pocketbase.dart'; import 'package:shared_preferences/shared_preferences.dart'; import 'package:uae_stat/config/api_config.dart'; import 'package:uae_stat/config/connectivity_provider.dart'; +import 'package:uae_stat/config/theme/theme_provider.dart'; import 'package:uae_stat/config/toggle_lang_service.dart'; import 'package:uae_stat/domain/use_cases/language.dart'; import 'package:uae_stat/presentation/components/indicators/locale_provider.dart'; @@ -42,6 +43,10 @@ class _NotificationDetailsState extends ConsumerState { bool isLoading = true; late UserService _userService; + late ThemeMode currentTheme; + List homePageData = []; + List filteredData = []; + // Current selected tab index int selectedTabIndex = 0; late final Locale locale; @@ -54,6 +59,19 @@ class _NotificationDetailsState extends ConsumerState { locale = ref.read(localeProvider) ?? const Locale('en'); _userService = UserService(); fetchNotifications(locale?.languageCode ?? 'en'); + + currentTheme = ref.read(themeProvider); + print('123456789'); + print(currentTheme); + WidgetsBinding.instance.addPostFrameCallback((_) { + final isDark = currentTheme == ThemeMode.dark || + (currentTheme == ThemeMode.system && + MediaQuery.of(context).platformBrightness == Brightness.dark); + + final themeMode = (isDark ? 'dark' : 'light'); + print("ThemeMode - $themeMode"); + fetchData(locale?.languageCode ?? 'en', themeMode); + }); } String formatDate(String dateString) { @@ -67,6 +85,30 @@ class _NotificationDetailsState extends ConsumerState { } } + Future fetchData(locale, themeMode) async { + const baseUrl = '$apiUrl/api/getUAENumbersData'; + try { + final response = await http + .get(Uri.parse(baseUrl + '?language=$locale&color_mode=$themeMode')); + if (response.statusCode == 200) { + setState(() { + homePageData = (json.decode(response.body) as List) + .map((e) => Map.from(e)) + .toList(); + filteredData = List.from(homePageData); + isLoading = false; + }); + } else { + throw Exception('Failed to load data'); + } + } catch (e) { + setState(() { + isLoading = false; + }); + print('Error fetching data: $e'); + } + } + Future fetchNotifications(locale) async { notificationID = widget.id; final baseUrl = apiUrl + '/api/getNotification'; @@ -129,6 +171,49 @@ class _NotificationDetailsState extends ConsumerState { fetchNotifications(localeCode); }); + ref.listen(localeProvider, (previous, next) async { + final localeCode = next?.languageCode ?? 'en'; + setState(() { + isLoading = true; + }); + await _userService.updateLanguage(localeCode); + final currentTheme = ref.read(themeProvider); + final isDark = currentTheme == ThemeMode.dark || + (currentTheme == ThemeMode.system && + MediaQuery.of(context).platformBrightness == Brightness.dark); + + final themeString = isDark ? 'dark' : 'light'; + fetchData(localeCode, themeString); + }); + + ref.listen(themeProvider, (previous, next) async { + final localeCode = ref.watch(localeProvider)?.languageCode ?? 'en'; + print(localeCode); + + // Default to 'en' if null + setState(() { + isLoading = true; + print('isLoadingref $isLoading'); + }); + + final currentTheme = ref.read(themeProvider); + final isDark = currentTheme == ThemeMode.dark || + (currentTheme == ThemeMode.system && + MediaQuery.of(context).platformBrightness == Brightness.dark); + + final themeString = isDark ? 'dark' : 'light'; + + print("themeString- $themeString"); + fetchData(localeCode, themeString); + }); + + final themeMode = ref.read(themeProvider); + final isDarkTheme = themeMode == ThemeMode.dark || + (themeMode == ThemeMode.system && + MediaQuery.of(context).platformBrightness == Brightness.dark); + + print("isDarkTheme - $isDarkTheme"); + return PopScope( canPop: false, onPopInvokedWithResult: (didPop, result) { @@ -136,6 +221,8 @@ class _NotificationDetailsState extends ConsumerState { context.go('/notification'); }, child: BaseScaffold( + backgroundColor: isDarkTheme ? Color(0xFF111111) : Colors.white, + appbarColor: isDarkTheme ? Color(0xFF111111) : Colors.white, title: Text( context.translate( 'Notification', @@ -143,16 +230,17 @@ class _NotificationDetailsState extends ConsumerState { ), style: TextStyle( fontFamily: context.translate( - 'Roboto', - 'NotoKufi', - ) - ), + 'Roboto', + 'NotoKufi', + )), ), showBackButton: true, navBackArrow: Text(widget.backNavigation ?? 'Default Value'), body: isLoading ? Container( - color: Color(0x98FFFCE5), // Semi-transparent background + color: isDarkTheme + ? Color(0xFF111111) + : Color(0x98FFFCE5), // Semi-transparent background child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ @@ -180,13 +268,12 @@ class _NotificationDetailsState extends ConsumerState { style: TextStyle( fontSize: 18, fontWeight: FontWeight.w500, - color: Color(0xFF414042), + color: + isDarkTheme ? Colors.white : Color(0xFF414042), fontFamily: context.translate( 'Roboto', 'NotoKufi', - ) - ), - + )), ), const SizedBox(height: 20), Center( @@ -209,25 +296,26 @@ class _NotificationDetailsState extends ConsumerState { style: TextStyle( fontSize: 14, fontWeight: FontWeight.w400, - color: Color(0xFF414042), + color: + isDarkTheme ? Colors.white : Color(0xFF414042), fontFamily: context.translate( 'Roboto', 'NotoKufi', - ) - ), + )), ), const SizedBox(height: 10), Text( "Date: ${notification != null ? formatDate(notification!['created'] ?? '') : 'N/A'}", style: TextStyle( - fontSize: 12, - fontWeight: FontWeight.w400, - color: Color(0xFF8E8E8E), + fontSize: 12, + fontWeight: FontWeight.w400, + color: isDarkTheme + ? Colors.white + : Color(0xFF8E8E8E), fontFamily: context.translate( 'Roboto', 'NotoKufi', - ) - ), + )), ), ], ), diff --git a/lib/presentation/routes/drawer_routes/Drawer Items/user_guide/AboutTheApp/AboutFCSC.dart b/lib/presentation/routes/drawer_routes/Drawer Items/user_guide/AboutTheApp/AboutFCSC.dart index 3c2583e9..3f4e32b9 100755 --- a/lib/presentation/routes/drawer_routes/Drawer Items/user_guide/AboutTheApp/AboutFCSC.dart +++ b/lib/presentation/routes/drawer_routes/Drawer Items/user_guide/AboutTheApp/AboutFCSC.dart @@ -1,22 +1,132 @@ +import 'dart:convert'; + import 'package:flutter/material.dart'; +import 'package:flutter_riverpod/flutter_riverpod.dart'; +import 'package:http/http.dart' as http; +import 'package:uae_stat/config/api_config.dart'; +import 'package:uae_stat/config/theme/theme_provider.dart'; +import 'package:uae_stat/config/toggle_lang_service.dart'; import 'package:uae_stat/domain/use_cases/language.dart'; +import 'package:uae_stat/presentation/Screens/Bottom%20Navigation%20Pages/Country_Profile/country_profile.dart'; import 'package:uae_stat/presentation/routes/drawer_routes/custom_drawer_routes.dart'; -class aboutFCSC extends StatelessWidget { +class aboutFCSC extends ConsumerStatefulWidget { const aboutFCSC({super.key}); + @override + ConsumerState createState() => _aboutFCSCState(); +} + +class _aboutFCSCState extends ConsumerState { +// class aboutFCSC extends StatelessWidget { +// const aboutFCSC({super.key}); + List homePageData = []; + List filteredData = []; + + bool isLoading = true; + late UserService _userService; + late ThemeMode currentTheme; + + @override + void initState() { + super.initState(); + _userService = UserService(); + final locale = ref.read(localeProvider); + currentTheme = ref.read(themeProvider); + print('123456789'); + print(currentTheme); + WidgetsBinding.instance.addPostFrameCallback((_) { + final isDark = currentTheme == ThemeMode.dark || + (currentTheme == ThemeMode.system && + MediaQuery.of(context).platformBrightness == Brightness.dark); + + final themeMode = (isDark ? 'dark' : 'light'); + print("ThemeMode - $themeMode"); + fetchData(locale?.languageCode ?? 'en', themeMode); + }); + } + + Future fetchData(locale, themeMode) async { + const baseUrl = '$apiUrl/api/getUAENumbersData'; + try { + final response = await http + .get(Uri.parse(baseUrl + '?language=$locale&color_mode=$themeMode')); + if (response.statusCode == 200) { + setState(() { + homePageData = (json.decode(response.body) as List) + .map((e) => Map.from(e)) + .toList(); + filteredData = List.from(homePageData); + isLoading = false; + }); + } else { + throw Exception('Failed to load data'); + } + } catch (e) { + setState(() { + isLoading = false; + }); + print('Error fetching data: $e'); + } + } + @override Widget build(BuildContext context) { + ref.listen(localeProvider, (previous, next) async { + final localeCode = next?.languageCode ?? 'en'; + setState(() { + isLoading = true; + }); + await _userService.updateLanguage(localeCode); + final currentTheme = ref.read(themeProvider); + final isDark = currentTheme == ThemeMode.dark || + (currentTheme == ThemeMode.system && + MediaQuery.of(context).platformBrightness == Brightness.dark); + + final themeString = isDark ? 'dark' : 'light'; + fetchData(localeCode, themeString); + }); + + ref.listen(themeProvider, (previous, next) async { + final localeCode = ref.watch(localeProvider)?.languageCode ?? 'en'; + print(localeCode); + + // Default to 'en' if null + setState(() { + isLoading = true; + print('isLoadingref $isLoading'); + }); + + final currentTheme = ref.read(themeProvider); + final isDark = currentTheme == ThemeMode.dark || + (currentTheme == ThemeMode.system && + MediaQuery.of(context).platformBrightness == Brightness.dark); + + final themeString = isDark ? 'dark' : 'light'; + + print("themeString- $themeString"); + fetchData(localeCode, themeString); + }); + + final themeMode = ref.read(themeProvider); + final isDarkTheme = themeMode == ThemeMode.dark || + (themeMode == ThemeMode.system && + MediaQuery.of(context).platformBrightness == Brightness.dark); + + print("isDarkTheme - $isDarkTheme"); + return BaseScaffold( + backgroundColor: isDarkTheme ? Colors.black : Colors.white, + appbarColor: isDarkTheme ? Colors.black : Colors.white, showDivider: true, showBackButton: true, dividerColor: Colors.grey[300], - appbarColor: Colors.white, + // appbarColor: Colors.white, bottomColor: Colors.white, mycenterTitle: true, title: Text( - context.translate('Getting Started','البدء'), + context.translate('Getting Started', 'البدء'), style: TextStyle( fontFamily: context.translate( 'Roboto', @@ -31,70 +141,90 @@ class aboutFCSC extends StatelessWidget { body: SingleChildScrollView( physics: ClampingScrollPhysics(), child: Container( - width: MediaQuery.of(context).size.width, - height: MediaQuery.of(context).size.height, - color: Colors.white, + width: MediaQuery.of(context).size.width, + height: MediaQuery.of(context).size.height, + color: isDarkTheme ? Colors.black : Colors.white, padding: EdgeInsets.all(16), child: Column( - mainAxisSize: MainAxisSize.min, - children: [ - Align( - alignment: Alignment.topLeft, - child: Text( - context.translate('About FCSC','حول التطبيق'), - style: TextStyle( - fontSize: 20, - color: Color(0xFF414042), - fontWeight: FontWeight.w600, - fontFamily: context.translate( - 'Roboto', - 'NotoKufi', + mainAxisSize: MainAxisSize.min, + children: [ + Align( + alignment: Alignment.topLeft, + child: Text( + context.translate('About FCSC', 'حول التطبيق'), + style: TextStyle( + fontSize: 20, + color: isDarkTheme ? Colors.white : Color(0xFF414042), + fontWeight: FontWeight.w600, + fontFamily: context.translate( + 'Roboto', + 'NotoKufi', + ), ), ), ), - ), - SizedBox( - width: MediaQuery.of(context).size.width, - height: MediaQuery.of(context).size.height * 0.36, - child: Image.asset( - 'assets/user_guide/AboutFCSC.png', - fit: BoxFit.contain, + SizedBox( + width: MediaQuery.of(context).size.width, + height: MediaQuery.of(context).size.height * 0.36, + child: Image.asset( + 'assets/user_guide/AboutFCSC.png', + fit: BoxFit.contain, + ), ), - ), - SizedBox( - height: 5, - ), - RichText( - text: TextSpan( - text: context.translate('The ', - 'تم تصميم تطبيق المركز الاتحادي للتنافسية والإحصاء (FCSC) لتوفير وصول المستخدمين المسجلين والمعتمدين إلى إحصائيات دقيقة وشاملة حول دولة الإمارات. يعمل التطبيق كمنصة مركزية لاستكشاف البيانات الرئيسية والاتجاهات والرؤى عبر مختلف القطاعات، مما يسهل الوصول إلى المعلومات الضرورية لدعم اتخاذ القرارات والتحليلات.',), - style: TextStyle( - color: Colors.grey, fontSize: 16, fontFamily: context.translate( - 'Roboto', - 'NotoKufi', - ), height: 1.4,), - children: [ - TextSpan( - text: - context.translate(' Federal Competitiveness and Statistics Centre (FCSC),',''), - style: TextStyle( - fontWeight: FontWeight.bold, - color: Color(0xFF414042), - fontFamily: context.translate( - 'Roboto', - 'NotoKufi', - ),), + SizedBox( + height: 5, + ), + RichText( + text: TextSpan( + text: context.translate( + 'The ', + 'تم تصميم تطبيق المركز الاتحادي للتنافسية والإحصاء (FCSC) لتوفير وصول المستخدمين المسجلين والمعتمدين إلى إحصائيات دقيقة وشاملة حول دولة الإمارات. يعمل التطبيق كمنصة مركزية لاستكشاف البيانات الرئيسية والاتجاهات والرؤى عبر مختلف القطاعات، مما يسهل الوصول إلى المعلومات الضرورية لدعم اتخاذ القرارات والتحليلات.', ), - TextSpan( - text: - context.translate(' in your App is designed to provide registered and approved users with access to accurate and comprehensive statistics about the UAE. The app serves as a centralized platform for exploring key datasets, trends, and insights across various sectors.',''),), - ], + style: TextStyle( + color: isDarkTheme ? Colors.white : Colors.grey, + fontSize: 16, + fontFamily: context.translate( + 'Roboto', + 'NotoKufi', + ), + height: 1.4, + ), + children: [ + TextSpan( + text: context.translate( + ' Federal Competitiveness and Statistics Centre (FCSC),', + ''), + style: TextStyle( + fontWeight: FontWeight.bold, + color: isDarkTheme ? Colors.white : Color(0xFF414042), + fontFamily: context.translate( + 'Roboto', + 'NotoKufi', + ), + ), + ), + TextSpan( + text: context.translate( + ' in your App is designed to provide registered and approved users with access to accurate and comprehensive statistics about the UAE. The app serves as a centralized platform for exploring key datasets, trends, and insights across various sectors.', + ''), + style: TextStyle( + color: isDarkTheme ? Colors.white : Colors.grey, + // fontSize: 16, + fontFamily: context.translate( + 'Roboto', + 'NotoKufi', + ), + height: 1.4, + ), + ), + ], + ), ), - ), - SizedBox( - height: 20, - ), - ],), + SizedBox( + height: 20, + ), + ], + ), ), ), ); diff --git a/lib/presentation/routes/drawer_routes/Drawer Items/user_guide/AboutTheApp/getStarted.dart b/lib/presentation/routes/drawer_routes/Drawer Items/user_guide/AboutTheApp/getStarted.dart index 1cbde4ac..d2176c73 100755 --- a/lib/presentation/routes/drawer_routes/Drawer Items/user_guide/AboutTheApp/getStarted.dart +++ b/lib/presentation/routes/drawer_routes/Drawer Items/user_guide/AboutTheApp/getStarted.dart @@ -1,14 +1,121 @@ +import 'dart:convert'; + import 'package:flutter/material.dart'; +import 'package:flutter_riverpod/flutter_riverpod.dart'; +import 'package:http/http.dart' as http; +import 'package:uae_stat/config/api_config.dart'; +import 'package:uae_stat/config/theme/theme_provider.dart'; +import 'package:uae_stat/config/toggle_lang_service.dart'; import 'package:uae_stat/domain/use_cases/language.dart'; +import 'package:uae_stat/presentation/Screens/Bottom%20Navigation%20Pages/Country_Profile/country_profile.dart'; import 'package:uae_stat/presentation/routes/drawer_routes/custom_drawer_routes.dart'; - -class GetStarted extends StatelessWidget { +class GetStarted extends ConsumerStatefulWidget { const GetStarted({super.key}); + @override + ConsumerState createState() => _GetStartedState(); +} + +class _GetStartedState extends ConsumerState { +// class GetStarted extends StatelessWidget { +// const GetStarted({super.key}); + List homePageData = []; + List filteredData = []; + + bool isLoading = true; + late UserService _userService; + late ThemeMode currentTheme; + + @override + void initState() { + super.initState(); + _userService = UserService(); + final locale = ref.read(localeProvider); + currentTheme = ref.read(themeProvider); + print('123456789'); + print(currentTheme); + WidgetsBinding.instance.addPostFrameCallback((_) { + final isDark = currentTheme == ThemeMode.dark || + (currentTheme == ThemeMode.system && + MediaQuery.of(context).platformBrightness == Brightness.dark); + + final themeMode = (isDark ? 'dark' : 'light'); + print("ThemeMode - $themeMode"); + fetchData(locale?.languageCode ?? 'en', themeMode); + }); + } + + Future fetchData(locale, themeMode) async { + const baseUrl = '$apiUrl/api/getUAENumbersData'; + try { + final response = await http + .get(Uri.parse(baseUrl + '?language=$locale&color_mode=$themeMode')); + if (response.statusCode == 200) { + setState(() { + homePageData = (json.decode(response.body) as List) + .map((e) => Map.from(e)) + .toList(); + filteredData = List.from(homePageData); + isLoading = false; + }); + } else { + throw Exception('Failed to load data'); + } + } catch (e) { + setState(() { + isLoading = false; + }); + print('Error fetching data: $e'); + } + } + @override Widget build(BuildContext context) { + ref.listen(localeProvider, (previous, next) async { + final localeCode = next?.languageCode ?? 'en'; + setState(() { + isLoading = true; + }); + await _userService.updateLanguage(localeCode); + final currentTheme = ref.read(themeProvider); + final isDark = currentTheme == ThemeMode.dark || + (currentTheme == ThemeMode.system && + MediaQuery.of(context).platformBrightness == Brightness.dark); + + final themeString = isDark ? 'dark' : 'light'; + fetchData(localeCode, themeString); + }); + + ref.listen(themeProvider, (previous, next) async { + final localeCode = ref.watch(localeProvider)?.languageCode ?? 'en'; + print(localeCode); + + // Default to 'en' if null + setState(() { + isLoading = true; + print('isLoadingref $isLoading'); + }); + + final currentTheme = ref.read(themeProvider); + final isDark = currentTheme == ThemeMode.dark || + (currentTheme == ThemeMode.system && + MediaQuery.of(context).platformBrightness == Brightness.dark); + + final themeString = isDark ? 'dark' : 'light'; + + print("themeString- $themeString"); + fetchData(localeCode, themeString); + }); + + final themeMode = ref.read(themeProvider); + final isDarkTheme = themeMode == ThemeMode.dark || + (themeMode == ThemeMode.system && + MediaQuery.of(context).platformBrightness == Brightness.dark); + + print("isDarkTheme - $isDarkTheme"); + return Theme( data: ThemeData( fontFamily: context.translate( @@ -16,21 +123,27 @@ class GetStarted extends StatelessWidget { 'NotoKufi', ), // Set default font family for this page textTheme: TextTheme( - bodyMedium: TextStyle(fontSize: 16, color: Color(0xFF898C81),fontFamily: context.translate( - 'Roboto', - 'NotoKufi', - ),), + bodyMedium: TextStyle( + fontSize: 16, + color: Color(0xFF898C81), + fontFamily: context.translate( + 'Roboto', + 'NotoKufi', + ), + ), ), ), child: BaseScaffold( + backgroundColor: isDarkTheme ? Colors.black : Colors.white, + appbarColor: isDarkTheme ? Colors.black : Colors.white, showDivider: true, showBackButton: true, dividerColor: Colors.grey[300], - appbarColor: Colors.white, + // appbarColor: Colors.white, bottomColor: Colors.white, mycenterTitle: true, title: Text( - context.translate('Getting Started','البدء'), + context.translate('Getting Started', 'البدء'), style: TextStyle( fontFamily: context.translate( 'Roboto', @@ -44,7 +157,7 @@ class GetStarted extends StatelessWidget { ), body: Container( height: double.infinity, - color: Colors.white, + color: isDarkTheme ? Colors.black : Colors.white, padding: EdgeInsets.all(16), child: SingleChildScrollView( child: Column( @@ -52,47 +165,58 @@ class GetStarted extends StatelessWidget { children: [ Align( alignment: Alignment.topLeft, - child: Text(context.translate('How to Get Started','كيفية البدء'), - style: - TextStyle( + child: Text( + context.translate('How to Get Started', 'كيفية البدء'), + style: TextStyle( fontFamily: context.translate( 'Roboto', 'NotoKufi', ), - fontSize:20, - color: Color(0xFF414042), + fontSize: 20, + color: isDarkTheme ? Colors.white : Color(0xFF414042), fontWeight: FontWeight.w600, - ),), + ), + ), ), SizedBox( - width:MediaQuery.of(context).size.width, - height:MediaQuery.of(context).size.height * 0.36, + width: MediaQuery.of(context).size.width, + height: MediaQuery.of(context).size.height * 0.36, child: Image.asset( 'assets/user_guide/getStarted.png', fit: BoxFit.contain, ), ), - Text( context.translate( - '1. Download the app from the App Store or Google Play Store.', - '1 .قم بتحميل التطبيق من متجر التطبيقات (Appstore) أو متجر جوجل بلاي (Google Play)..', + '1. Download the app from the App Store or Google Play Store.', + '1 .قم بتحميل التطبيق من متجر التطبيقات (Appstore) أو متجر جوجل بلاي (Google Play)..', ), textAlign: TextAlign.justify, // Align the text softWrap: true, - ), - SizedBox(height: 2,), - Text( - context.translate( - '2. Log in to access advanced features', - '2 .قم بتسجيل الدخول لفتح الميزات المتقدمة.',), - textAlign: TextAlign.justify, // Align the text - softWrap: true, + style: TextStyle( + color: isDarkTheme ? Colors.white : Colors.black54, + ), ), SizedBox( - height:MediaQuery.of(context).size.height * 0.12, + height: 2, + ), + Text( + context.translate( + '2. Log in to access advanced features', + '2 .قم بتسجيل الدخول لفتح الميزات المتقدمة.', + ), + textAlign: TextAlign.justify, // Align the text + softWrap: true, + style: TextStyle( + color: isDarkTheme ? Colors.white : Colors.black54, + ), + ), + SizedBox( + height: MediaQuery.of(context).size.height * 0.12, + ), + SizedBox( + height: 20, ), - SizedBox(height: 20,), ], ), ), diff --git a/lib/presentation/routes/drawer_routes/Drawer Items/user_guide/KeyFeatures/AppFeatures.dart b/lib/presentation/routes/drawer_routes/Drawer Items/user_guide/KeyFeatures/AppFeatures.dart index 0dc73b38..07f73a9d 100755 --- a/lib/presentation/routes/drawer_routes/Drawer Items/user_guide/KeyFeatures/AppFeatures.dart +++ b/lib/presentation/routes/drawer_routes/Drawer Items/user_guide/KeyFeatures/AppFeatures.dart @@ -1,14 +1,123 @@ +import 'dart:convert'; + import 'package:flutter/material.dart'; +import 'package:flutter_riverpod/flutter_riverpod.dart'; +import 'package:http/http.dart' as http; +import 'package:uae_stat/config/api_config.dart'; +import 'package:uae_stat/config/theme/theme_provider.dart'; +import 'package:uae_stat/config/toggle_lang_service.dart'; import 'package:uae_stat/domain/use_cases/language.dart'; +import 'package:uae_stat/presentation/Screens/Bottom%20Navigation%20Pages/Country_Profile/country_profile.dart'; import '../../../../../../infrastructure/services/img_asset_paths/banner_asset_path.dart'; import '../../../custom_drawer_routes.dart'; -class AppFeatures extends StatelessWidget { - AppFeatures({super.key}); +class AppFeatures extends ConsumerStatefulWidget { + const AppFeatures({super.key}); + + @override + ConsumerState createState() => _AppFeaturesState(); +} + +class _AppFeaturesState extends ConsumerState { +// class AppFeatures extends StatelessWidget { +// AppFeatures({super.key}); + + List homePageData = []; + List filteredData = []; + + bool isLoading = true; + late UserService _userService; + late ThemeMode currentTheme; + + @override + void initState() { + super.initState(); + _userService = UserService(); + final locale = ref.read(localeProvider); + currentTheme = ref.read(themeProvider); + print('123456789'); + print(currentTheme); + WidgetsBinding.instance.addPostFrameCallback((_) { + final isDark = currentTheme == ThemeMode.dark || + (currentTheme == ThemeMode.system && + MediaQuery.of(context).platformBrightness == Brightness.dark); + + final themeMode = (isDark ? 'dark' : 'light'); + print("ThemeMode - $themeMode"); + fetchData(locale?.languageCode ?? 'en', themeMode); + }); + } + + Future fetchData(locale, themeMode) async { + const baseUrl = '$apiUrl/api/getUAENumbersData'; + try { + final response = await http + .get(Uri.parse(baseUrl + '?language=$locale&color_mode=$themeMode')); + if (response.statusCode == 200) { + setState(() { + homePageData = (json.decode(response.body) as List) + .map((e) => Map.from(e)) + .toList(); + filteredData = List.from(homePageData); + isLoading = false; + }); + } else { + throw Exception('Failed to load data'); + } + } catch (e) { + setState(() { + isLoading = false; + }); + print('Error fetching data: $e'); + } + } @override Widget build(BuildContext context) { + ref.listen(localeProvider, (previous, next) async { + final localeCode = next?.languageCode ?? 'en'; + setState(() { + isLoading = true; + }); + await _userService.updateLanguage(localeCode); + final currentTheme = ref.read(themeProvider); + final isDark = currentTheme == ThemeMode.dark || + (currentTheme == ThemeMode.system && + MediaQuery.of(context).platformBrightness == Brightness.dark); + + final themeString = isDark ? 'dark' : 'light'; + fetchData(localeCode, themeString); + }); + + ref.listen(themeProvider, (previous, next) async { + final localeCode = ref.watch(localeProvider)?.languageCode ?? 'en'; + print(localeCode); + + // Default to 'en' if null + setState(() { + isLoading = true; + print('isLoadingref $isLoading'); + }); + + final currentTheme = ref.read(themeProvider); + final isDark = currentTheme == ThemeMode.dark || + (currentTheme == ThemeMode.system && + MediaQuery.of(context).platformBrightness == Brightness.dark); + + final themeString = isDark ? 'dark' : 'light'; + + print("themeString- $themeString"); + fetchData(localeCode, themeString); + }); + + final themeMode = ref.read(themeProvider); + final isDarkTheme = themeMode == ThemeMode.dark || + (themeMode == ThemeMode.system && + MediaQuery.of(context).platformBrightness == Brightness.dark); + + print("isDarkTheme - $isDarkTheme"); + return Theme( data: ThemeData( fontFamily: context.translate( @@ -20,14 +129,16 @@ class AppFeatures extends StatelessWidget { ), ), child: BaseScaffold( + backgroundColor: isDarkTheme ? Color(0xFF111111) : Colors.white, + appbarColor: isDarkTheme ? Color(0xFF111111) : Colors.white, showDivider: true, showBackButton: true, bottomColor: Colors.white, dividerColor: Colors.grey[300], - appbarColor: Colors.white, + // appbarColor: Colors.white, mycenterTitle: true, title: Text( - context.translate('Key Features','الميزات الرئيسية'), + context.translate('Key Features', 'الميزات الرئيسية'), style: TextStyle( fontFamily: context.translate( 'Roboto', @@ -41,7 +152,8 @@ class AppFeatures extends StatelessWidget { ), body: Container( width: double.infinity, - color: Colors.white, + color: isDarkTheme ? Color(0xFF111111) : Colors.white, + // color: Colors.white, padding: EdgeInsets.all(16), child: SingleChildScrollView( child: Column( @@ -50,77 +162,101 @@ class AppFeatures extends StatelessWidget { Align( alignment: Alignment.topLeft, child: Text( - context.translate('App Features','الميزات الرئيسية'), - style: - TextStyle( + context.translate('App Features', 'الميزات الرئيسية'), + style: TextStyle( fontFamily: context.translate( 'Roboto', 'NotoKufi', ), - fontSize:20, - color: Color(0xFF414042), + fontSize: 20, + color: isDarkTheme ? Colors.white : Color(0xFF414042), fontWeight: FontWeight.w600, - ),), + ), + ), ), SizedBox( - width:MediaQuery.of(context).size.width, - height:MediaQuery.of(context).size.height * 0.36, + width: MediaQuery.of(context).size.width, + height: MediaQuery.of(context).size.height * 0.36, child: Image.asset( 'assets/user_guide/appFeatures.png', fit: BoxFit.contain, ), ), Text( - context.translate('1. Comprehensive Statistics:','1. رؤى مستندة إلى البيانات '), - style:TextStyle( + context.translate('1. Comprehensive Statistics:', + '1. رؤى مستندة إلى البيانات '), + style: TextStyle( fontFamily: context.translate( 'Roboto', 'NotoKufi', ), - fontSize:16, - color: Color(0xFF414042), + fontSize: 16, + color: isDarkTheme ? Colors.white : Color(0xFF414042), fontWeight: FontWeight.w600, ), ), SizedBox(height: 8), Padding( - padding: const EdgeInsets.only(left:7.0), + padding: const EdgeInsets.only(left: 7.0), child: Column( children: [ Row( crossAxisAlignment: CrossAxisAlignment.start, children: [ Padding( - padding: const EdgeInsets.only(top : 6.0), - child: Icon(Icons.brightness_1, size: 5), + padding: const EdgeInsets.only(top: 6.0), + child: Icon( + Icons.brightness_1, + size: 5, + color: isDarkTheme ? Colors.white : Colors.black, + ), ), // Bullet point SizedBox(width: 8), // Space between bullet and text Expanded( child: RichText( text: TextSpan( - text:context.translate( + text: context.translate( 'Access detailed datasets across categories such as ', - 'الوصول إلى مجموعات بيانات تفصيلية عبر فئات مثل الاقتصاد، البيئة، الاجتماعية، وغيرها.',), + 'الوصول إلى مجموعات بيانات تفصيلية عبر فئات مثل الاقتصاد، البيئة، الاجتماعية، وغيرها.', + ), style: TextStyle( - color:Color(0xFF898C81), - fontSize: 16, + color: isDarkTheme + ? Colors.white + : Color(0xFF898C81), + fontSize: 16, fontFamily: context.translate( 'Roboto', 'NotoKufi', ), ), children: [ - TextSpan(text: - context.translate('Economy, Environment, Social, ',''), + TextSpan( + text: context.translate( + 'Economy, Environment, Social, ', ''), style: TextStyle( - fontWeight: FontWeight.bold, - color: Color(0xFF414042), + fontWeight: FontWeight.bold, + color: isDarkTheme + ? Colors.white + : Color(0xFF414042), fontFamily: context.translate( 'Roboto', 'NotoKufi', ), - ),), - TextSpan(text:context.translate('and more.','')), + ), + ), + TextSpan( + text: context.translate('and more.', ''), + style: TextStyle( + color: isDarkTheme + ? Colors.white + : Color(0xFF898C81), + fontSize: 16, + fontFamily: context.translate( + 'Roboto', + 'NotoKufi', + ), + ), + ), ], ), ), @@ -131,58 +267,29 @@ class AppFeatures extends StatelessWidget { crossAxisAlignment: CrossAxisAlignment.start, children: [ Padding( - padding: const EdgeInsets.only(top : 8.0), - child: Icon(Icons.brightness_1, size: 5, color: Color(0xFF414042),), - ), // Bullet point - SizedBox(width: 8), // Space between bullet and text - Expanded( - child: Text( context.translate( - 'Explore statistics presented as smart metrics, graphs, and charts for better understanding.', - 'استكشاف الإحصائيات المقدمة على هيئة مقاييس ذكية ورسوم بيانية ومخططات لتعزيز الفهم.',), - textAlign: TextAlign.justify, // Align the text - softWrap: true, + padding: const EdgeInsets.only(top: 8.0), + child: Icon( + Icons.brightness_1, + size: 5, + color: isDarkTheme + ? Colors.white + : Color(0xFF414042), ), - ), - ], - ), - ], - ), - ), - - - SizedBox(height: 8), - Text( - context.translate('2. Drilldown Navigation:','2. التنقل التفصيلي'), - style:TextStyle( - fontFamily: context.translate( - 'Roboto', - 'NotoKufi', - ), - fontSize:16, - color: Color(0xFF414042), - fontWeight: FontWeight.w600, - ), - ), - SizedBox(height: 8), - Padding( - padding: const EdgeInsets.only(left:7.0), - child: Column( - children: [ - Row( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Padding( - padding: const EdgeInsets.only(top : 8.0), - child: Icon(Icons.brightness_1, size: 5, color: Color(0xFF414042),), ), // Bullet point SizedBox(width: 8), // Space between bullet and text Expanded( child: Text( context.translate( - 'Start with high-level categories and drill down to specific KPIs and metrics for deeper insights.', - 'البدء بالفئات العامة والتنقل وصولًا إلى مؤشرات الأداء الرئيسية (KPIs) والمقاييس المحددة للحصول على رؤى أعمق.',), - textAlign: TextAlign.justify, // Align the text + 'Explore statistics presented as smart metrics, graphs, and charts for better understanding.', + 'استكشاف الإحصائيات المقدمة على هيئة مقاييس ذكية ورسوم بيانية ومخططات لتعزيز الفهم.', + ), + textAlign: TextAlign.justify, // Align the text softWrap: true, + style: TextStyle( + color: isDarkTheme + ? Colors.white + : Color(0xFF898C81), + ), ), ), ], @@ -190,39 +297,52 @@ class AppFeatures extends StatelessWidget { ], ), ), - SizedBox(height: 8), Text( - context.translate('3. Interactive Visualizations:','3. التصورات التفاعلية:'), - style:TextStyle( + context.translate( + '2. Drilldown Navigation:', '2. التنقل التفصيلي'), + style: TextStyle( fontFamily: context.translate( 'Roboto', 'NotoKufi', ), - fontSize:16, - color: Color(0xFF414042), + fontSize: 16, + color: isDarkTheme ? Colors.white : Color(0xFF414042), fontWeight: FontWeight.w600, ), ), SizedBox(height: 8), Padding( - padding: const EdgeInsets.only(left:7.0), + padding: const EdgeInsets.only(left: 7.0), child: Column( children: [ Row( crossAxisAlignment: CrossAxisAlignment.start, children: [ Padding( - padding: const EdgeInsets.only(top : 8.0), - child: Icon(Icons.brightness_1, size: 5, color: Color(0xFF414042),), + padding: const EdgeInsets.only(top: 8.0), + child: Icon( + Icons.brightness_1, + size: 5, + color: isDarkTheme + ? Colors.white + : Color(0xFF414042), + ), ), // Bullet point SizedBox(width: 8), // Space between bullet and text Expanded( - child: Text(context.translate( - 'View trends and relationships with interactive graphs and charts, including bar graphs, line charts, and more.', - 'عرض الاتجاهات والعلاقات باستخدام الرسوم البيانية التفاعلية مثل المخططات الشريطية، المخططات الخطية، وغيرها.',), + child: Text( + context.translate( + 'Start with high-level categories and drill down to specific KPIs and metrics for deeper insights.', + 'البدء بالفئات العامة والتنقل وصولًا إلى مؤشرات الأداء الرئيسية (KPIs) والمقاييس المحددة للحصول على رؤى أعمق.', + ), textAlign: TextAlign.justify, // Align the text softWrap: true, + style: TextStyle( + color: isDarkTheme + ? Colors.white + : Color(0xFF898C81), + ), ), ), ], @@ -230,7 +350,62 @@ class AppFeatures extends StatelessWidget { ], ), ), - SizedBox(height: 20,), + SizedBox(height: 8), + Text( + context.translate('3. Interactive Visualizations:', + '3. التصورات التفاعلية:'), + style: TextStyle( + fontFamily: context.translate( + 'Roboto', + 'NotoKufi', + ), + fontSize: 16, + color: isDarkTheme ? Colors.white : Color(0xFF414042), + fontWeight: FontWeight.w600, + ), + ), + SizedBox(height: 8), + Padding( + padding: const EdgeInsets.only(left: 7.0), + child: Column( + children: [ + Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Padding( + padding: const EdgeInsets.only(top: 8.0), + child: Icon( + Icons.brightness_1, + size: 5, + color: isDarkTheme + ? Colors.white + : Color(0xFF414042), + ), + ), // Bullet point + SizedBox(width: 8), // Space between bullet and text + Expanded( + child: Text( + context.translate( + 'View trends and relationships with interactive graphs and charts, including bar graphs, line charts, and more.', + 'عرض الاتجاهات والعلاقات باستخدام الرسوم البيانية التفاعلية مثل المخططات الشريطية، المخططات الخطية، وغيرها.', + ), + textAlign: TextAlign.justify, // Align the text + softWrap: true, + style: TextStyle( + color: isDarkTheme + ? Colors.white + : Color(0xFF898C81), + ), + ), + ), + ], + ), + ], + ), + ), + SizedBox( + height: 20, + ), ], ), ), diff --git a/lib/presentation/routes/drawer_routes/Drawer Items/user_guide/KeyFeatures/ChangeMyPassword.dart b/lib/presentation/routes/drawer_routes/Drawer Items/user_guide/KeyFeatures/ChangeMyPassword.dart index 37362ef8..1599e202 100755 --- a/lib/presentation/routes/drawer_routes/Drawer Items/user_guide/KeyFeatures/ChangeMyPassword.dart +++ b/lib/presentation/routes/drawer_routes/Drawer Items/user_guide/KeyFeatures/ChangeMyPassword.dart @@ -1,23 +1,136 @@ +import 'dart:convert'; + import 'package:flutter/material.dart'; +import 'package:flutter_riverpod/flutter_riverpod.dart'; +import 'package:http/http.dart' as http; +import 'package:uae_stat/config/api_config.dart'; +import 'package:uae_stat/config/theme/theme_provider.dart'; +import 'package:uae_stat/config/toggle_lang_service.dart'; import 'package:uae_stat/domain/use_cases/language.dart'; +import 'package:uae_stat/presentation/Screens/Bottom%20Navigation%20Pages/Country_Profile/country_profile.dart'; import 'package:uae_stat/presentation/routes/drawer_routes/custom_drawer_routes.dart'; -class ChangeMyPassword extends StatelessWidget { +class ChangeMyPassword extends ConsumerStatefulWidget { const ChangeMyPassword({super.key}); + + @override + ConsumerState createState() => _ChangeMyPasswordState(); +} + +class _ChangeMyPasswordState extends ConsumerState { +// class ChangeMyPassword extends StatelessWidget { +// const ChangeMyPassword({super.key}); + + List homePageData = []; + List filteredData = []; + + bool isLoading = true; + late UserService _userService; + late ThemeMode currentTheme; + + @override + void initState() { + super.initState(); + _userService = UserService(); + final locale = ref.read(localeProvider); + currentTheme = ref.read(themeProvider); + print('123456789'); + print(currentTheme); + WidgetsBinding.instance.addPostFrameCallback((_) { + final isDark = currentTheme == ThemeMode.dark || + (currentTheme == ThemeMode.system && + MediaQuery.of(context).platformBrightness == Brightness.dark); + + final themeMode = (isDark ? 'dark' : 'light'); + print("ThemeMode - $themeMode"); + fetchData(locale?.languageCode ?? 'en', themeMode); + }); + } + + Future fetchData(locale, themeMode) async { + const baseUrl = '$apiUrl/api/getUAENumbersData'; + try { + final response = await http + .get(Uri.parse(baseUrl + '?language=$locale&color_mode=$themeMode')); + if (response.statusCode == 200) { + setState(() { + homePageData = (json.decode(response.body) as List) + .map((e) => Map.from(e)) + .toList(); + filteredData = List.from(homePageData); + isLoading = false; + }); + } else { + throw Exception('Failed to load data'); + } + } catch (e) { + setState(() { + isLoading = false; + }); + print('Error fetching data: $e'); + } + } + @override Widget build(BuildContext context) { + ref.listen(localeProvider, (previous, next) async { + final localeCode = next?.languageCode ?? 'en'; + setState(() { + isLoading = true; + }); + await _userService.updateLanguage(localeCode); + final currentTheme = ref.read(themeProvider); + final isDark = currentTheme == ThemeMode.dark || + (currentTheme == ThemeMode.system && + MediaQuery.of(context).platformBrightness == Brightness.dark); + + final themeString = isDark ? 'dark' : 'light'; + fetchData(localeCode, themeString); + }); + + ref.listen(themeProvider, (previous, next) async { + final localeCode = ref.watch(localeProvider)?.languageCode ?? 'en'; + print(localeCode); + + // Default to 'en' if null + setState(() { + isLoading = true; + print('isLoadingref $isLoading'); + }); + + final currentTheme = ref.read(themeProvider); + final isDark = currentTheme == ThemeMode.dark || + (currentTheme == ThemeMode.system && + MediaQuery.of(context).platformBrightness == Brightness.dark); + + final themeString = isDark ? 'dark' : 'light'; + + print("themeString- $themeString"); + fetchData(localeCode, themeString); + }); + + final themeMode = ref.read(themeProvider); + final isDarkTheme = themeMode == ThemeMode.dark || + (themeMode == ThemeMode.system && + MediaQuery.of(context).platformBrightness == Brightness.dark); + + print("isDarkTheme - $isDarkTheme"); + return Theme( data: ThemeData( fontFamily: context.translate( 'Roboto', 'NotoKufi', - ),// Set default font family for this page + ), // Set default font family for this page textTheme: TextTheme( - bodyMedium: TextStyle(fontSize: 16, color: Color(0xFF898C81), + bodyMedium: TextStyle( + fontSize: 16, + color: Color(0xFF898C81), fontFamily: context.translate( 'Roboto', 'NotoKufi', - ),), + ), + ), ), ), child: BaseScaffold( @@ -25,10 +138,12 @@ class ChangeMyPassword extends StatelessWidget { showBackButton: true, bottomColor: Colors.white, dividerColor: Colors.grey[300], - appbarColor: Colors.white, + // appbarColor: Colors.white, + backgroundColor: isDarkTheme ? Colors.black : Colors.white, + appbarColor: isDarkTheme ? Colors.black : Colors.white, mycenterTitle: true, title: Text( - context.translate('Key Features','الميزات الرئيسية'), + context.translate('Key Features', 'الميزات الرئيسية'), style: TextStyle( fontFamily: context.translate( 'Roboto', @@ -42,7 +157,7 @@ class ChangeMyPassword extends StatelessWidget { ), body: Container( width: double.infinity, - color: Colors.white, + color: isDarkTheme ? Colors.black : Colors.white, padding: EdgeInsets.all(16), child: SingleChildScrollView( child: Column( @@ -52,21 +167,23 @@ class ChangeMyPassword extends StatelessWidget { alignment: Alignment.topLeft, child: Text( context.translate( - 'How to Change My Password', - 'كيفية تغيير كلمة المرور الخاصة بي',), + 'How to Change My Password', + 'كيفية تغيير كلمة المرور الخاصة بي', + ), style: TextStyle( fontFamily: context.translate( 'Roboto', 'NotoKufi', ), - fontSize:20, - color: Color(0xFF414042), + fontSize: 20, + color: isDarkTheme ? Colors.white : Color(0xFF414042), fontWeight: FontWeight.w600, - ),), + ), + ), ), SizedBox( - width:MediaQuery.of(context).size.width, - height:MediaQuery.of(context).size.height * 0.36, + width: MediaQuery.of(context).size.width, + height: MediaQuery.of(context).size.height * 0.36, child: Image.asset( 'assets/user_guide/changePassword.png', fit: BoxFit.contain, @@ -74,75 +191,105 @@ class ChangeMyPassword extends StatelessWidget { ), Text( context.translate( - 'Changing your password helps keep your account secure. Follow these steps to update your password:', - 'يُساعد تغيير كلمة المرور في الحفاظ على أمان حسابك. اتبع هذه الخطوات لتحديث كلمة مرور',), + 'Changing your password helps keep your account secure. Follow these steps to update your password:', + 'يُساعد تغيير كلمة المرور في الحفاظ على أمان حسابك. اتبع هذه الخطوات لتحديث كلمة مرور', + ), + style: TextStyle( + color: isDarkTheme ? Colors.white : Color(0xFF898C81)), ), SizedBox(height: 12), Text( - context.translate('Steps to Change Password','خطوات تغيير كلمة المرور '), - style:TextStyle( + context.translate( + 'Steps to Change Password', 'خطوات تغيير كلمة المرور '), + style: TextStyle( fontFamily: context.translate( 'Roboto', 'NotoKufi', ), - fontSize:22, - color: Color(0xFF414042), + fontSize: 22, + color: isDarkTheme ? Colors.white : Color(0xFF414042), fontWeight: FontWeight.w600, ), ), SizedBox(height: 8), Text( context.translate( - '1. Access the Change Password Page:', - '1. الدخول إلى صفحة تغيير كلمة المرور:',), - style:TextStyle( + '1. Access the Change Password Page:', + '1. الدخول إلى صفحة تغيير كلمة المرور:', + ), + style: TextStyle( fontFamily: context.translate( 'Roboto', 'NotoKufi', ), - fontSize:16, - color: Color(0xFF414042), + fontSize: 16, + color: isDarkTheme ? Colors.white : Color(0xFF414042), fontWeight: FontWeight.w600, ), ), SizedBox(height: 8), Padding( - padding: const EdgeInsets.only(left:8.0), + padding: const EdgeInsets.only(left: 8.0), child: Column( children: [ Row( crossAxisAlignment: CrossAxisAlignment.start, children: [ Padding( - padding: const EdgeInsets.only(top : 8.0), - child: Icon(Icons.brightness_1, size: 5, color: Color(0xFF414042),), + padding: const EdgeInsets.only(top: 8.0), + child: Icon( + Icons.brightness_1, + size: 5, + color: isDarkTheme + ? Colors.white + : Color(0xFF414042), + ), ), // Bullet point SizedBox(width: 8), // Space between bullet and text Expanded( - child: RichText( + child: RichText( text: TextSpan( text: context.translate( - 'From the Profile page, tap on the ', - 'من صفحة الملف الشخصي، انقر على رابط ',), - style: TextStyle(fontSize: 16, color: Color(0xFF898C81), fontFamily: context.translate( - 'Roboto', - 'NotoKufi', - ),), + 'From the Profile page, tap on the ', + 'من صفحة الملف الشخصي، انقر على رابط ', + ), + style: TextStyle( + fontSize: 16, + color: isDarkTheme + ? Colors.white + : Color(0xFF898C81), + fontFamily: context.translate( + 'Roboto', + 'NotoKufi', + ), + ), children: [ - TextSpan(text: context.translate( - '"Change Password"', - '"تغيير كلمة المرور" ',), + TextSpan( + text: context.translate( + '"Change Password"', + '"تغيير كلمة المرور" ', + ), style: TextStyle( - fontWeight: FontWeight.w600, - color: Color(0xFF414042), + fontWeight: FontWeight.w600, + color: isDarkTheme + ? Colors.white + : Color(0xFF414042), fontFamily: context.translate( 'Roboto', 'NotoKufi', ), - ),), - TextSpan(text:context.translate( - ' link at the bottom.', - 'في الأسفل.',), + ), + ), + TextSpan( + text: context.translate( + ' link at the bottom.', + 'في الأسفل.', + ), + style: TextStyle( + color: isDarkTheme + ? Colors.white + : Color(0xFF898C81), + ), ), ], ), @@ -153,195 +300,273 @@ class ChangeMyPassword extends StatelessWidget { ], ), ), - - SizedBox(height: 8), - Text(context.translate( - '2. Enter Old Password:', - '2. إدخال كلمة المرور القديمة:',), - style:TextStyle( - fontFamily: context.translate( - 'Roboto', - 'NotoKufi', - ), - fontSize:16, - color: Color(0xFF414042), - fontWeight: FontWeight.w600, - ), - ), - SizedBox(height: 8), - Padding( - padding: const EdgeInsets.only(left:8.0), - child: Column( - children: [ - Row( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Padding( - padding: const EdgeInsets.only(top : 8.0), - child: Icon(Icons.brightness_1, size: 5), - ), // Bullet point - SizedBox(width: 8), // Space between bullet and text - Expanded( - child: Text( - context.translate( - 'Enter your current password in the first field.', - 'أدخل كلمة المرور الحالية في الحقل الأول.',), - textAlign: TextAlign.justify, // Align the text - softWrap: true, - ), - ), - ], - ), - ], - ), - ), - - SizedBox(height: 8), - Text(context.translate( - '3. Set a New Password:', - '3. تعيين كلمة مرور جديدة:',), - style:TextStyle( - fontFamily: context.translate( - 'Roboto', - 'NotoKufi', - ), - fontSize:16, - color: Color(0xFF414042), - fontWeight: FontWeight.w600, - ), - ), - SizedBox(height: 8), - Padding( - padding: const EdgeInsets.only(left:8.0), - child: Column( - children: [ - Row( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Padding( - padding: const EdgeInsets.only(top : 8.0), - child: Icon(Icons.brightness_1, size: 5, color: Color(0xFF414042),), - ), // Bullet point - SizedBox(width: 8), // Space between bullet and text - Expanded( - child: Text( context.translate( - 'Enter your new password in the second field.', - 'أدخل كلمة المرور الجديدة في الحقل الثاني.',), - textAlign: TextAlign.justify, // Align the text - softWrap: true, - ), - ), - ], - ), - Row( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Padding( - padding: const EdgeInsets.only(top : 8.0), - child: Icon(Icons.brightness_1, size: 5, color: Color(0xFF414042),), - ), // Bullet point - SizedBox(width: 8), // Space between bullet and text - Expanded( - child: Text( - context.translate( - 'Re-enter the new password in the third field for confirmation.', - 'أعد إدخال كلمة المرور الجديدة في الحقل الثالث للتأكيد.',), - textAlign: TextAlign.justify, // Align the text - softWrap: true, - ), - ), - ], - ), - ], - ), - ), - - SizedBox(height: 8), - Text(context.translate( - '4. Password Requirements:','4. متطلبات كلمة المرور:',), - style:TextStyle( - fontFamily: context.translate( - 'Roboto', - 'NotoKufi', - ), - fontSize:16, - color: Color(0xFF414042), - fontWeight: FontWeight.w600, - ), - ), - SizedBox(height: 8), - Padding( - padding: const EdgeInsets.only(left:8.0), - child: Column( - children: [ - Row( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Padding( - padding: const EdgeInsets.only(top : 8.0), - child: Icon(Icons.brightness_1, size: 5, color: Color(0xFF414042),), - ), // Bullet point - SizedBox(width: 8), // Space between bullet and text - Expanded( - child: Text(context.translate( - 'Your new password must be different from the previously used password.', - 'جب أن تكون كلمة المرور الجديدة مختلفة عن كلمة المرور المستخدمة سابقًا',), - textAlign: TextAlign.justify, // Align the text - softWrap: true, - ), - ), - ], - ), - ], - ), - ), - SizedBox(height: 8), Text( - context.translate('5. Save Your Password:','5. حفظ كلمة المرور '), - style:TextStyle( + context.translate( + '2. Enter Old Password:', + '2. إدخال كلمة المرور القديمة:', + ), + style: TextStyle( fontFamily: context.translate( 'Roboto', 'NotoKufi', ), - fontSize:16, - color: Color(0xFF414042), + fontSize: 16, + color: isDarkTheme ? Colors.white : Color(0xFF414042), fontWeight: FontWeight.w600, ), ), SizedBox(height: 8), Padding( - padding: const EdgeInsets.only(left:8.0), + padding: const EdgeInsets.only(left: 8.0), child: Column( children: [ Row( crossAxisAlignment: CrossAxisAlignment.start, children: [ Padding( - padding: const EdgeInsets.only(top : 8.0), - child: Icon(Icons.brightness_1, size: 5, color: Color(0xFF414042),), + padding: const EdgeInsets.only(top: 8.0), + child: Icon( + Icons.brightness_1, + size: 5, + color: isDarkTheme + ? Colors.white + : Color(0xFF414042), + ), ), // Bullet point SizedBox(width: 8), // Space between bullet and text Expanded( - child: RichText( + child: Text( + context.translate( + 'Enter your current password in the first field.', + 'أدخل كلمة المرور الحالية في الحقل الأول.', + ), + style: TextStyle( + color: isDarkTheme + ? Colors.white + : Color(0xFF898C81), + ), + textAlign: TextAlign.justify, // Align the text + softWrap: true, + ), + ), + ], + ), + ], + ), + ), + SizedBox(height: 8), + Text( + context.translate( + '3. Set a New Password:', + '3. تعيين كلمة مرور جديدة:', + ), + style: TextStyle( + fontFamily: context.translate( + 'Roboto', + 'NotoKufi', + ), + fontSize: 16, + color: isDarkTheme ? Colors.white : Color(0xFF414042), + fontWeight: FontWeight.w600, + ), + ), + SizedBox(height: 8), + Padding( + padding: const EdgeInsets.only(left: 8.0), + child: Column( + children: [ + Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Padding( + padding: const EdgeInsets.only(top: 8.0), + child: Icon( + Icons.brightness_1, + size: 5, + color: isDarkTheme + ? Colors.white + : Color(0xFF414042), + ), + ), // Bullet point + SizedBox(width: 8), // Space between bullet and text + Expanded( + child: Text( + context.translate( + 'Enter your new password in the second field.', + 'أدخل كلمة المرور الجديدة في الحقل الثاني.', + ), + textAlign: TextAlign.justify, // Align the text + softWrap: true, + style: TextStyle( + color: isDarkTheme + ? Colors.white + : Color(0xFF898C81), + ), + ), + ), + ], + ), + Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Padding( + padding: const EdgeInsets.only(top: 8.0), + child: Icon( + Icons.brightness_1, + size: 5, + color: isDarkTheme + ? Colors.white + : Color(0xFF414042), + ), + ), // Bullet point + SizedBox(width: 8), // Space between bullet and text + Expanded( + child: Text( + context.translate( + 'Re-enter the new password in the third field for confirmation.', + 'أعد إدخال كلمة المرور الجديدة في الحقل الثالث للتأكيد.', + ), + textAlign: TextAlign.justify, // Align the text + softWrap: true, + style: TextStyle( + color: isDarkTheme + ? Colors.white + : Color(0xFF898C81), + ), + ), + ), + ], + ), + ], + ), + ), + SizedBox(height: 8), + Text( + context.translate( + '4. Password Requirements:', + '4. متطلبات كلمة المرور:', + ), + style: TextStyle( + fontFamily: context.translate( + 'Roboto', + 'NotoKufi', + ), + fontSize: 16, + color: isDarkTheme ? Colors.white : Color(0xFF414042), + fontWeight: FontWeight.w600, + ), + ), + SizedBox(height: 8), + Padding( + padding: const EdgeInsets.only(left: 8.0), + child: Column( + children: [ + Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Padding( + padding: const EdgeInsets.only(top: 8.0), + child: Icon( + Icons.brightness_1, + size: 5, + color: isDarkTheme + ? Colors.white + : Color(0xFF414042), + ), + ), // Bullet point + SizedBox(width: 8), // Space between bullet and text + Expanded( + child: Text( + context.translate( + 'Your new password must be different from the previously used password.', + 'جب أن تكون كلمة المرور الجديدة مختلفة عن كلمة المرور المستخدمة سابقًا', + ), + textAlign: TextAlign.justify, // Align the text + softWrap: true, + style: TextStyle( + color: isDarkTheme + ? Colors.white + : Color(0xFF898C81), + ), + ), + ), + ], + ), + ], + ), + ), + SizedBox(height: 8), + Text( + context.translate( + '5. Save Your Password:', '5. حفظ كلمة المرور '), + style: TextStyle( + fontFamily: context.translate( + 'Roboto', + 'NotoKufi', + ), + fontSize: 16, + color: isDarkTheme ? Colors.white : Color(0xFF414042), + fontWeight: FontWeight.w600, + ), + ), + SizedBox(height: 8), + Padding( + padding: const EdgeInsets.only(left: 8.0), + child: Column( + children: [ + Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Padding( + padding: const EdgeInsets.only(top: 8.0), + child: Icon( + Icons.brightness_1, + size: 5, + color: isDarkTheme + ? Colors.white + : Color(0xFF414042), + ), + ), // Bullet point + SizedBox(width: 8), // Space between bullet and text + Expanded( + child: RichText( text: TextSpan( - text: context.translate('Tap the ','انقرعلى زر '), - style: TextStyle(fontSize: 16, color: Color(0xFF898C81), fontFamily: context.translate( - 'Roboto', - 'NotoKufi', - ),), + text: context.translate( + 'Tap the ', 'انقرعلى زر '), + style: TextStyle( + fontSize: 16, + // color: Color(0xFF898C81), + fontFamily: context.translate( + 'Roboto', + 'NotoKufi', + ), + color: isDarkTheme + ? Colors.white + : Color(0xFF898C81), + ), children: [ - TextSpan(text: - context.translate('Save ','"حفظ".'), + TextSpan( + text: context.translate('Save ', '"حفظ".'), style: TextStyle( - fontWeight: FontWeight.w600, - color: Color(0xFF414042), + fontWeight: FontWeight.w600, + color: isDarkTheme + ? Colors.white + : Color(0xFF414042), fontFamily: context.translate( 'Roboto', 'NotoKufi', ), - ),), - TextSpan(text: context.translate('button',''),), + ), + ), + TextSpan( + text: context.translate('button', ''), + style: TextStyle( + color: isDarkTheme + ? Colors.white + : Color(0xFF898C81), + ), + ), ], ), ), @@ -352,16 +577,29 @@ class ChangeMyPassword extends StatelessWidget { crossAxisAlignment: CrossAxisAlignment.start, children: [ Padding( - padding: const EdgeInsets.only(top : 8.0), - child: Icon(Icons.brightness_1, size: 5, color: Color(0xFF414042),), + padding: const EdgeInsets.only(top: 8.0), + child: Icon( + Icons.brightness_1, + size: 5, + color: isDarkTheme + ? Colors.white + : Color(0xFF414042), + ), ), // Bullet point SizedBox(width: 8), // Space between bullet and text Expanded( - child: Text(context.translate( - 'A confirmation message will appear: “Password has been successfully updated.”', - 'ستظهر رسالة تأكيد: "تم تحديث كلمة المرور بنجاح".',), + child: Text( + context.translate( + 'A confirmation message will appear: “Password has been successfully updated.”', + 'ستظهر رسالة تأكيد: "تم تحديث كلمة المرور بنجاح".', + ), textAlign: TextAlign.justify, // Align the text softWrap: true, + style: TextStyle( + color: isDarkTheme + ? Colors.white + : Color(0xFF898C81), + ), ), ), ], @@ -371,36 +609,49 @@ class ChangeMyPassword extends StatelessWidget { ), SizedBox(height: 8), Text( - context.translate('6. Re-Login:','6. إعادة تسجيل الدخول'), - style:TextStyle( + context.translate('6. Re-Login:', '6. إعادة تسجيل الدخول'), + style: TextStyle( fontFamily: context.translate( 'Roboto', 'NotoKufi', ), - fontSize:16, - color: Color(0xFF414042), + fontSize: 16, + color: isDarkTheme ? Colors.white : Color(0xFF414042), fontWeight: FontWeight.w600, ), ), SizedBox(height: 8), Padding( - padding: const EdgeInsets.only(left:8.0), + padding: const EdgeInsets.only(left: 8.0), child: Column( children: [ Row( crossAxisAlignment: CrossAxisAlignment.start, children: [ Padding( - padding: const EdgeInsets.only(top : 8.0), - child: Icon(Icons.brightness_1, size: 5, color: Color(0xFF414042),), + padding: const EdgeInsets.only(top: 8.0), + child: Icon( + Icons.brightness_1, + size: 5, + color: isDarkTheme + ? Colors.white + : Color(0xFF414042), + ), ), // Bullet point SizedBox(width: 8), // Space between bullet and text Expanded( - child: Text(context.translate( - 'Log in again using your new password to continue using the app', - 'قم بتسجيل الدخول مرة أخرى باستخدام كلمة المرور الجديدة للاستمرار في استخدام التطبيق.',), + child: Text( + context.translate( + 'Log in again using your new password to continue using the app', + 'قم بتسجيل الدخول مرة أخرى باستخدام كلمة المرور الجديدة للاستمرار في استخدام التطبيق.', + ), textAlign: TextAlign.justify, // Align the text softWrap: true, + style: TextStyle( + color: isDarkTheme + ? Colors.white + : Color(0xFF898C81), + ), ), ), ], @@ -408,9 +659,10 @@ class ChangeMyPassword extends StatelessWidget { ], ), ), - SizedBox(height: 20,), + SizedBox( + height: 20, + ), ], - ), ), ), diff --git a/lib/presentation/routes/drawer_routes/Drawer Items/user_guide/KeyFeatures/EditMyProfile.dart b/lib/presentation/routes/drawer_routes/Drawer Items/user_guide/KeyFeatures/EditMyProfile.dart index d8f6c47c..8e31d68f 100755 --- a/lib/presentation/routes/drawer_routes/Drawer Items/user_guide/KeyFeatures/EditMyProfile.dart +++ b/lib/presentation/routes/drawer_routes/Drawer Items/user_guide/KeyFeatures/EditMyProfile.dart @@ -1,557 +1,894 @@ - import 'package:flutter/material.dart'; - import 'package:uae_stat/domain/use_cases/language.dart'; +import 'dart:convert'; +import 'package:flutter/material.dart'; +import 'package:flutter_riverpod/flutter_riverpod.dart'; +import 'package:http/http.dart' as http; +import 'package:uae_stat/config/api_config.dart'; +import 'package:uae_stat/config/theme/theme_provider.dart'; +import 'package:uae_stat/config/toggle_lang_service.dart'; +import 'package:uae_stat/domain/use_cases/language.dart'; +import 'package:uae_stat/presentation/Screens/Bottom%20Navigation%20Pages/Country_Profile/country_profile.dart'; - import 'package:uae_stat/presentation/routes/drawer_routes/custom_drawer_routes.dart'; +import 'package:uae_stat/presentation/routes/drawer_routes/custom_drawer_routes.dart'; - class EditMyProfile extends StatelessWidget { - const EditMyProfile({super.key}); +class EditMyProfile extends ConsumerStatefulWidget { + const EditMyProfile({super.key}); - @override - Widget build(BuildContext context) { - return Theme( - data: ThemeData( - fontFamily: context.translate( - 'Roboto', - 'NotoKufi', - ), // Set default font family for this page - textTheme: TextTheme( - bodyMedium: TextStyle(fontSize: 16, color: Color(0xFF898C81),fontFamily: context.translate( - 'Roboto', - 'NotoKufi', - ),), - ), - ), - child: BaseScaffold( - showDivider: true, - showBackButton: true, - bottomColor: Colors.white, - dividerColor: Colors.grey[300], - appbarColor: Colors.white, - mycenterTitle: true, - title: Text( - context.translate('Key Features','الميزات الرئيسية'), - style: TextStyle( - fontFamily: context.translate( - 'Roboto', - 'NotoKufi', - ), - fontSize: 22, - color: Color(0xFF7DAFBC), - fontWeight: FontWeight.w500, - // fontWeight: FontWeight.w500, - ), - ), - body: Container( - width: double.infinity, - color: Colors.white, - padding: EdgeInsets.all(16), - child: SingleChildScrollView( - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Align( - alignment: Alignment.topLeft, - child: Text( - context.translate('How to Edit My Profile','كيفية تعديل ملفي الشخصي'), - style: - TextStyle( - fontFamily: context.translate( - 'Roboto', - 'NotoKufi', - ), - fontSize:20, - color: Color(0xFF414042), - fontWeight: FontWeight.w600, - ),), - ), - SizedBox( - width:MediaQuery.of(context).size.width, - height:MediaQuery.of(context).size.height * 0.36, - child: Image.asset( - 'assets/user_guide/editProfile.png', - fit: BoxFit.contain, - ), - ), - Text(context.translate( - 'Editing your profile allows you to update specific information while ensuring that critical details remain secure. Follow the steps below to update your profile:', - 'يتيح لك تعديل ملف التعريف الخاص بك بتحديث معلومات معينة مع ضمان أن تبقى البيانات الحساسة آمنة. اتبع الخطوات التالية لتحديث ملفك الشخصي:',), - ), - SizedBox(height: 12), - Text( - context.translate('Steps to Edit Profile','خطوات تعديل الملف الشخصي '), - style:TextStyle( - fontFamily: context.translate( - 'Roboto', - 'NotoKufi', - ), - fontSize:22, - color: Color(0xFF414042), - fontWeight: FontWeight.w600, - ), - ), - SizedBox(height: 8), - Text(context.translate( - '1. Access the Profile Page:', - '1. الوصول إلى صفحة الملف الشخصي:',), - style:TextStyle( - fontFamily: context.translate( - 'Roboto', - 'NotoKufi', - ), - fontSize:16, - color: Color(0xFF414042), - fontWeight: FontWeight.w600, - ), - ), - SizedBox(height: 8), - Padding( - padding: const EdgeInsets.only(left: 8.0), - child: Column( - children: [ Row( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Padding( - padding: const EdgeInsets.only(top : 8.0), - child: Icon(Icons.brightness_1, size: 5, color: Color(0xFF414042),), - ), // Bullet point - SizedBox(width: 8), // Space between bullet and text - Expanded( - child: RichText( - text: TextSpan( - text: context.translate('Tap on the ','انقر على خيار "الملف الشخصي" من شريط التنقل في الزاوية العلوية اليسرى من الشاشة.'), - style: TextStyle(fontSize: 16, color: Color(0xFF898C81), fontFamily: context.translate( - 'Roboto', - 'NotoKufi', - ),), - children: [ - TextSpan(text: context.translate('"Profile"',''), - style: TextStyle( - fontWeight: FontWeight.w600, - color: Color(0xFF414042), - fontFamily: context.translate( - 'Roboto', - 'NotoKufi', - ), - ),), - TextSpan(text: context.translate(' option from the navigation bar at the top left corner of the screen.','')) - ], - ), - ) - ), - ], - ),], - ), - ), + @override + ConsumerState createState() => _EditMyProfileState(); +} - SizedBox(height: 8), - Text( - context.translate('2. Editable Fields:','2. الحقول القابلة للتعديل:'), - style:TextStyle( - fontFamily: context.translate( - 'Roboto', - 'NotoKufi', - ), - fontSize:16, - color: Color(0xFF414042), - fontWeight: FontWeight.w600, - ), - ), - SizedBox(height: 8), - Padding( - padding: const EdgeInsets.only(left: 8.0), - child: Column( - children: [ - Row( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Padding( - padding: const EdgeInsets.only(top : 8.0), - child: Icon(Icons.brightness_1, size: 5), - ), // Bullet point - SizedBox(width: 8), // Space between bullet and text - Expanded( - child: RichText( - text: TextSpan( - style: TextStyle(fontSize: 16, color: Color(0xFF898C81), fontFamily: context.translate( - 'Roboto', - 'NotoKufi', - ),), - children: [ - TextSpan(text: - context.translate('Full Name:','الاسم الكامل: '), - style: TextStyle( - fontWeight: FontWeight.w600, - color: Color(0xFF414042), - fontFamily: context.translate( - 'Roboto', - 'NotoKufi', - ), - ),), - TextSpan(text:context.translate( - ' Tap the text box to enter your name (up to 40 alphanumeric characters).', - 'اضغط على مربع النص لإدخال اسمك (حتى 40 حرفًا أبجديًا رقميًا).',),) - ], - ), - ) - ), - ], - ), - SizedBox(height: 8), - Row( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Padding( - padding: const EdgeInsets.only(top : 8.0), - child: Icon(Icons.brightness_1, size: 5), - ), // Bullet point - SizedBox(width: 8), // Space between bullet and text - Expanded( - child: RichText( - text: TextSpan( - style: TextStyle(fontSize: 16, color: Color(0xFF898C81), fontFamily: context.translate( - 'Roboto', - 'NotoKufi', - ),), - children: [ - TextSpan( - text: context.translate('Date of Birth: ','تاريخ الميلاد: '), - style: TextStyle( - fontWeight: FontWeight.w600, - color: Color(0xFF414042), - fontFamily: context.translate( - 'Roboto', - 'NotoKufi', - ), - ),), - TextSpan( - text:context.translate( - ' Use the calendar dropdown to select your date of birth.', - 'استخدم القائمة المنسدلة لاختيار تاريخ ميلادك.',), - ) - ], - ), - ) - ), - ], - ), - SizedBox(height: 8), - Row( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Padding( - padding: const EdgeInsets.only(top : 8.0), - child: Icon(Icons.brightness_1, size: 5), - ), // Bullet point - SizedBox(width: 8), // Space between bullet and text - Expanded( - child: RichText( - text: TextSpan( - style: TextStyle(fontSize: 16, color: Color(0xFF898C81), fontFamily: context.translate( - 'Roboto', - 'NotoKufi', - ),), - children: [ - TextSpan(text:context.translate( - 'Country/Region: ', - 'البلد/المنطقة:',), - style: TextStyle( - fontWeight: FontWeight.w600, - color: Color(0xFF414042), - fontFamily: context.translate( - 'Roboto', - 'NotoKufi', - ), - ),), - TextSpan(text:context.translate( - ' Choose your current location from the dropdown menu.', - 'اختر موقعك الحالي من القائمة المنسدلة.',), - ), - ], - ), - ) - ), - ], - ), - SizedBox(height: 8), - Row( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Padding( - padding: const EdgeInsets.only(top : 8.0), - child: Icon(Icons.brightness_1, size: 5), - ), // Bullet point - SizedBox(width: 8), // Space between bullet and text - Expanded( - child: RichText( - text: TextSpan( - style: TextStyle(fontSize: 16, color: Color(0xFF898C81), fontFamily: context.translate( - 'Roboto', - 'NotoKufi', - ),), - children: [ - TextSpan(text: - context.translate('User Image: ', 'الصورة الشخصية:'), - style: TextStyle( - fontWeight: FontWeight.w600, - color: Color(0xFF414042), - fontFamily: context.translate( - 'Roboto', - 'NotoKufi', - ), - ),), - TextSpan(text:context.translate( - 'Tap on the avatar icon to upload or change your profile picture.', - 'اضغط على أيقونة رمزالصورة لتحميل أو تغيير صورة الملف الشخصي.',), - ), - ], - ), - ) - ), - ], - ), - ], - ), - ), +class _EditMyProfileState extends ConsumerState { + // class EditMyProfile extends StatelessWidget { + // const EditMyProfile({super.key}); - SizedBox(height: 8), - Text( - context.translate('3. Non-Editable Fields:','3. الحقول غير القابلة للتعديل:'), - style:TextStyle( - fontFamily: context.translate( - 'Roboto', - 'NotoKufi', - ), - fontSize:16, - color: Color(0xFF414042), - fontWeight: FontWeight.w600, - ), - ), - SizedBox(height: 8), - Padding( - padding: const EdgeInsets.only(left: 8.0), - child: Column( - children: [ - Row( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Padding( - padding: const EdgeInsets.only(top : 8.0), - child: Icon(Icons.brightness_1, size: 5), - ), // Bullet point - SizedBox(width: 8), // Space between bullet and text - Expanded( - child: RichText( - text: TextSpan( - style: TextStyle(fontSize: 16, color: Color(0xFF898C81), fontFamily: context.translate( - 'Roboto', - 'NotoKufi', - ),), - children: [ - TextSpan(text: context.translate('Username ','اسم المستخدم وعنوان البريد الإلكتروني: '), - style: TextStyle( - fontWeight: FontWeight.w600, - color: Color(0xFF414042), - fontFamily: context.translate( - 'Roboto', - 'NotoKufi', - ), - ),), - TextSpan(text:context.translate('and ',''),), - TextSpan(text: context.translate('Email Id: ',''), - style: TextStyle( - fontWeight: FontWeight.w600, - color: Color(0xFF414042), - fontFamily: context.translate( - 'Roboto', - 'NotoKufi', - ), - ),), - TextSpan(text:context.translate( - 'These fields cannot be edited to ensure the integrity of your account.', - 'لا يمكن تعديل هذين الحقلين لضمان سلامة حسابك.',), - ), - ], - ), - ) - ), - ], - ), - ], - ), - ), + List homePageData = []; + List filteredData = []; - SizedBox(height: 8), - Text( - context.translate('4. Agree to Terms and Conditions:','4. الموافقة على الشروط والأحكام:'), - style:TextStyle( - fontFamily: context.translate( - 'Roboto', - 'NotoKufi', - ), - fontSize:16, - color: Color(0xFF414042), - fontWeight: FontWeight.w600, - ), - ), - SizedBox(height: 8), - Padding( - padding: const EdgeInsets.only(left: 8.0), - child: Column( - children: [ - Row( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Padding( - padding: const EdgeInsets.only(top : 8.0), - child: Icon(Icons.brightness_1, size: 5, color: Color(0xFF414042),), - ), // Bullet point - SizedBox(width: 8), // Space between bullet and text - Expanded( - child: Text( - context.translate( - 'Ensure that the checkbox for "I agree to Terms & Conditions and Privacy Policy" is selected before saving changes.', - 'تأكد من تحديد خانة "أوافق على الشروط والأحكام وسياسة الخصوصية" قبل حفظ التغييرات.',), - textAlign: TextAlign.justify, // Align the text - softWrap: true, - ), - ), - ], - ), - ], - ), - ), + bool isLoading = true; + late UserService _userService; + late ThemeMode currentTheme; - SizedBox(height: 8), - Text( - context.translate('5. Save Your Changes:','5. حفظ التغييرات:'), - style:TextStyle( - fontFamily: context.translate( - 'Roboto', - 'NotoKufi', - ), - fontSize:16, - color: Color(0xFF414042), - fontWeight: FontWeight.w600, - ), - ), - SizedBox(height: 8), - Padding( - padding: const EdgeInsets.only(left: 8.0), - child: Column( - children: [ - Row( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Padding( - padding: const EdgeInsets.only(top : 8.0), - child: Icon(Icons.brightness_1, size: 5, color: Color(0xFF414042),), - ), // Bullet point - SizedBox(width: 8), // Space between bullet and text - Expanded( - child: RichText( - text: TextSpan( - text: context.translate('Tap the ','اضغط على زر '), - style: TextStyle(fontSize: 16, color: Color(0xFF898C81), fontFamily: context.translate( - 'Roboto', - 'NotoKufi', - ),), - children: [ - TextSpan(text: - context.translate('Save','"حفظ" '), - style: TextStyle( - fontWeight: FontWeight.w600, - color: Color(0xFF414042), - fontFamily: context.translate( - 'Roboto', - 'NotoKufi', - ), - ),), - TextSpan(text: - context.translate( - ' button at the bottom of the screen.', - 'أسفل الشاشة.',), - ) - ], - ), - ), - ), - ], - ), - SizedBox(height: 8), - Row( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Padding( - padding: const EdgeInsets.only(top : 8.0), - child: Icon(Icons.brightness_1, size: 5, color: Color(0xFF414042),), - ), // Bullet point - SizedBox(width: 8), // Space between bullet and text - Expanded( - child: Text(context.translate( - 'A confirmation dialog will appear with the message: “Are you sure you want to save this page? Once saved, you will not be able to change your name or date of birth.”', - 'ستظهر نافذة تأكيد برسالة:"هل أنت متأكد أنك تريد حفظ هذه الصفحة؟ بمجرد الحفظ، لن تتمكن من تغيير اسمك أو تاريخ ميلادك."', - ), - textAlign: TextAlign.justify, // Align the text - softWrap: true, - ), - ), - ], - ), - SizedBox(height: 8), - Row( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Padding( - padding: const EdgeInsets.only(top : 8.0), - child: Icon(Icons.brightness_1, size: 5, color: Color(0xFF414042),), - ), // Bullet point - SizedBox(width: 8), // Space between bullet and text - Expanded( - child:RichText( - text: TextSpan( - text: context.translate('Select ','اختر "تأكيد" لحفظ التغييرات أو "إلغاء" للرجوع.'), - style: TextStyle(fontSize: 16, color: Color(0xFF898C81), fontFamily: context.translate( - 'Roboto', - 'NotoKufi', - ),), - children: [ - TextSpan(text: context.translate('Confirm',''), - style: TextStyle( - fontWeight: FontWeight.w600, - color: Color(0xFF414042), - fontFamily: context.translate( - 'Roboto', - 'NotoKufi', - ), - ),), - TextSpan(text:context.translate(' to save the changes',''),), - TextSpan(text:context.translate(' Cancel',''), - style: TextStyle( - fontWeight: FontWeight.w600, - color: Color(0xFF414042), - fontFamily: context.translate( - 'Roboto', - 'NotoKufi', - ), - ),), - TextSpan(text:context.translate(' to go back.','')), - ], - ), - ), - ), - ], - ), - ], - ), - ), - SizedBox(height: 20,), - ], + @override + void initState() { + super.initState(); + _userService = UserService(); + final locale = ref.read(localeProvider); + currentTheme = ref.read(themeProvider); + print('123456789'); + print(currentTheme); + WidgetsBinding.instance.addPostFrameCallback((_) { + final isDark = currentTheme == ThemeMode.dark || + (currentTheme == ThemeMode.system && + MediaQuery.of(context).platformBrightness == Brightness.dark); - ), - ), - ), - ), - ); - } + final themeMode = (isDark ? 'dark' : 'light'); + print("ThemeMode - $themeMode"); + fetchData(locale?.languageCode ?? 'en', themeMode); + }); + } + + Future fetchData(locale, themeMode) async { + const baseUrl = '$apiUrl/api/getUAENumbersData'; + try { + final response = await http + .get(Uri.parse(baseUrl + '?language=$locale&color_mode=$themeMode')); + if (response.statusCode == 200) { + setState(() { + homePageData = (json.decode(response.body) as List) + .map((e) => Map.from(e)) + .toList(); + filteredData = List.from(homePageData); + isLoading = false; + }); + } else { + throw Exception('Failed to load data'); } + } catch (e) { + setState(() { + isLoading = false; + }); + print('Error fetching data: $e'); + } + } + + @override + Widget build(BuildContext context) { + ref.listen(localeProvider, (previous, next) async { + final localeCode = next?.languageCode ?? 'en'; + setState(() { + isLoading = true; + }); + await _userService.updateLanguage(localeCode); + final currentTheme = ref.read(themeProvider); + final isDark = currentTheme == ThemeMode.dark || + (currentTheme == ThemeMode.system && + MediaQuery.of(context).platformBrightness == Brightness.dark); + + final themeString = isDark ? 'dark' : 'light'; + fetchData(localeCode, themeString); + }); + + ref.listen(themeProvider, (previous, next) async { + final localeCode = ref.watch(localeProvider)?.languageCode ?? 'en'; + print(localeCode); + + // Default to 'en' if null + setState(() { + isLoading = true; + print('isLoadingref $isLoading'); + }); + + final currentTheme = ref.read(themeProvider); + final isDark = currentTheme == ThemeMode.dark || + (currentTheme == ThemeMode.system && + MediaQuery.of(context).platformBrightness == Brightness.dark); + + final themeString = isDark ? 'dark' : 'light'; + + print("themeString- $themeString"); + fetchData(localeCode, themeString); + }); + + final themeMode = ref.read(themeProvider); + final isDarkTheme = themeMode == ThemeMode.dark || + (themeMode == ThemeMode.system && + MediaQuery.of(context).platformBrightness == Brightness.dark); + + print("isDarkTheme - $isDarkTheme"); + + return Theme( + data: ThemeData( + fontFamily: context.translate( + 'Roboto', + 'NotoKufi', + ), // Set default font family for this page + textTheme: TextTheme( + bodyMedium: TextStyle( + fontSize: 16, + color: Color(0xFF898C81), + fontFamily: context.translate( + 'Roboto', + 'NotoKufi', + ), + ), + ), + ), + child: BaseScaffold( + showDivider: true, + showBackButton: true, + bottomColor: Colors.white, + dividerColor: Colors.grey[300], + backgroundColor: isDarkTheme ? Colors.black : Colors.white, + appbarColor: isDarkTheme ? Colors.black : Colors.white, + // appbarColor: Colors.white, + mycenterTitle: true, + title: Text( + context.translate('Key Features', 'الميزات الرئيسية'), + style: TextStyle( + fontFamily: context.translate( + 'Roboto', + 'NotoKufi', + ), + fontSize: 22, + color: Color(0xFF7DAFBC), + fontWeight: FontWeight.w500, + // fontWeight: FontWeight.w500, + ), + ), + body: Container( + width: double.infinity, + color: isDarkTheme ? Colors.black : Colors.white, + padding: EdgeInsets.all(16), + child: SingleChildScrollView( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Align( + alignment: Alignment.topLeft, + child: Text( + context.translate( + 'How to Edit My Profile', 'كيفية تعديل ملفي الشخصي'), + style: TextStyle( + fontFamily: context.translate( + 'Roboto', + 'NotoKufi', + ), + fontSize: 20, + color: isDarkTheme ? Colors.white : Color(0xFF414042), + fontWeight: FontWeight.w600, + ), + ), + ), + SizedBox( + width: MediaQuery.of(context).size.width, + height: MediaQuery.of(context).size.height * 0.36, + child: Image.asset( + 'assets/user_guide/editProfile.png', + fit: BoxFit.contain, + ), + ), + Text( + context.translate( + 'Editing your profile allows you to update specific information while ensuring that critical details remain secure. Follow the steps below to update your profile:', + 'يتيح لك تعديل ملف التعريف الخاص بك بتحديث معلومات معينة مع ضمان أن تبقى البيانات الحساسة آمنة. اتبع الخطوات التالية لتحديث ملفك الشخصي:', + ), + style: TextStyle( + color: isDarkTheme ? Colors.white : Color(0xFF898C81)), + ), + SizedBox(height: 12), + Text( + context.translate( + 'Steps to Edit Profile', 'خطوات تعديل الملف الشخصي '), + style: TextStyle( + fontFamily: context.translate( + 'Roboto', + 'NotoKufi', + ), + fontSize: 22, + color: isDarkTheme ? Colors.white : Color(0xFF414042), + fontWeight: FontWeight.w600, + ), + ), + SizedBox(height: 8), + Text( + context.translate( + '1. Access the Profile Page:', + '1. الوصول إلى صفحة الملف الشخصي:', + ), + style: TextStyle( + fontFamily: context.translate( + 'Roboto', + 'NotoKufi', + ), + fontSize: 16, + color: isDarkTheme ? Colors.white : Color(0xFF414042), + fontWeight: FontWeight.w600, + ), + ), + SizedBox(height: 8), + Padding( + padding: const EdgeInsets.only(left: 8.0), + child: Column( + children: [ + Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Padding( + padding: const EdgeInsets.only(top: 8.0), + child: Icon( + Icons.brightness_1, + size: 5, + color: isDarkTheme + ? Colors.white + : Color(0xFF414042), + ), + ), // Bullet point + SizedBox(width: 8), // Space between bullet and text + Expanded( + child: RichText( + text: TextSpan( + text: context.translate('Tap on the ', + 'انقر على خيار "الملف الشخصي" من شريط التنقل في الزاوية العلوية اليسرى من الشاشة.'), + style: TextStyle( + fontSize: 16, + color: isDarkTheme + ? Colors.white + : Color(0xFF898C81), + fontFamily: context.translate( + 'Roboto', + 'NotoKufi', + ), + ), + children: [ + TextSpan( + text: context.translate('"Profile"', ''), + style: TextStyle( + fontWeight: FontWeight.w600, + color: isDarkTheme + ? Colors.white + : Color(0xFF414042), + fontFamily: context.translate( + 'Roboto', + 'NotoKufi', + ), + ), + ), + TextSpan( + text: context.translate( + ' option from the navigation bar at the top left corner of the screen.', + '')) + ], + ), + )), + ], + ), + ], + ), + ), + SizedBox(height: 8), + Text( + context.translate( + '2. Editable Fields:', '2. الحقول القابلة للتعديل:'), + style: TextStyle( + fontFamily: context.translate( + 'Roboto', + 'NotoKufi', + ), + fontSize: 16, + color: isDarkTheme ? Colors.white : Color(0xFF414042), + fontWeight: FontWeight.w600, + ), + ), + SizedBox(height: 8), + Padding( + padding: const EdgeInsets.only(left: 8.0), + child: Column( + children: [ + Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Padding( + padding: const EdgeInsets.only(top: 8.0), + child: Icon( + Icons.brightness_1, + size: 5, + color: isDarkTheme ? Colors.white : Colors.black, + ), + ), // Bullet point + SizedBox(width: 8), // Space between bullet and text + Expanded( + child: RichText( + text: TextSpan( + style: TextStyle( + fontSize: 16, + color: isDarkTheme + ? Colors.white + : Color(0xFF898C81), + fontFamily: context.translate( + 'Roboto', + 'NotoKufi', + ), + ), + children: [ + TextSpan( + text: context.translate( + 'Full Name:', 'الاسم الكامل: '), + style: TextStyle( + fontWeight: FontWeight.w600, + color: isDarkTheme + ? Colors.white + : Color(0xFF414042), + fontFamily: context.translate( + 'Roboto', + 'NotoKufi', + ), + ), + ), + TextSpan( + text: context.translate( + ' Tap the text box to enter your name (up to 40 alphanumeric characters).', + 'اضغط على مربع النص لإدخال اسمك (حتى 40 حرفًا أبجديًا رقميًا).', + ), + style: TextStyle( + color: isDarkTheme + ? Colors.white + : Color(0xFF898C81))) + ], + ), + )), + ], + ), + SizedBox(height: 8), + Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Padding( + padding: const EdgeInsets.only(top: 8.0), + child: Icon( + Icons.brightness_1, + size: 5, + color: isDarkTheme ? Colors.white : Colors.black, + ), + ), // Bullet point + SizedBox(width: 8), // Space between bullet and text + Expanded( + child: RichText( + text: TextSpan( + style: TextStyle( + fontSize: 16, + color: isDarkTheme + ? Colors.white + : Color(0xFF898C81), + fontFamily: context.translate( + 'Roboto', + 'NotoKufi', + ), + ), + children: [ + TextSpan( + text: context.translate( + 'Date of Birth: ', 'تاريخ الميلاد: '), + style: TextStyle( + fontWeight: FontWeight.w600, + color: isDarkTheme + ? Colors.white + : Color(0xFF414042), + fontFamily: context.translate( + 'Roboto', + 'NotoKufi', + ), + ), + ), + TextSpan( + text: context.translate( + ' Use the calendar dropdown to select your date of birth.', + 'استخدم القائمة المنسدلة لاختيار تاريخ ميلادك.', + ), + style: TextStyle( + color: isDarkTheme + ? Colors.white + : Color(0xFF898C81)), + ) + ], + ), + )), + ], + ), + SizedBox(height: 8), + Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Padding( + padding: const EdgeInsets.only(top: 8.0), + child: Icon( + Icons.brightness_1, + size: 5, + color: isDarkTheme ? Colors.white : Colors.black, + ), + ), // Bullet point + SizedBox(width: 8), // Space between bullet and text + Expanded( + child: RichText( + text: TextSpan( + style: TextStyle( + fontSize: 16, + color: isDarkTheme + ? Colors.white + : Color(0xFF898C81), + fontFamily: context.translate( + 'Roboto', + 'NotoKufi', + ), + ), + children: [ + TextSpan( + text: context.translate( + 'Country/Region: ', + 'البلد/المنطقة:', + ), + style: TextStyle( + fontWeight: FontWeight.w600, + color: isDarkTheme + ? Colors.white + : Color(0xFF414042), + fontFamily: context.translate( + 'Roboto', + 'NotoKufi', + ), + ), + ), + TextSpan( + text: context.translate( + ' Choose your current location from the dropdown menu.', + 'اختر موقعك الحالي من القائمة المنسدلة.', + ), + style: TextStyle( + color: isDarkTheme + ? Colors.white + : Color(0xFF898C81)), + ), + ], + ), + )), + ], + ), + SizedBox(height: 8), + Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Padding( + padding: const EdgeInsets.only(top: 8.0), + child: Icon(Icons.brightness_1, + size: 5, + color: + isDarkTheme ? Colors.white : Colors.black), + ), // Bullet point + SizedBox(width: 8), // Space between bullet and text + Expanded( + child: RichText( + text: TextSpan( + style: TextStyle( + fontSize: 16, + color: isDarkTheme + ? Colors.white + : Color(0xFF898C81), + fontFamily: context.translate( + 'Roboto', + 'NotoKufi', + ), + ), + children: [ + TextSpan( + text: context.translate( + 'User Image: ', 'الصورة الشخصية:'), + style: TextStyle( + fontWeight: FontWeight.w600, + color: isDarkTheme + ? Colors.white + : Color(0xFF414042), + fontFamily: context.translate( + 'Roboto', + 'NotoKufi', + ), + ), + ), + TextSpan( + text: context.translate( + 'Tap on the avatar icon to upload or change your profile picture.', + 'اضغط على أيقونة رمزالصورة لتحميل أو تغيير صورة الملف الشخصي.', + ), + style: TextStyle( + color: isDarkTheme + ? Colors.white + : Color(0xFF898C81)), + ), + ], + ), + )), + ], + ), + ], + ), + ), + SizedBox(height: 8), + Text( + context.translate('3. Non-Editable Fields:', + '3. الحقول غير القابلة للتعديل:'), + style: TextStyle( + fontFamily: context.translate( + 'Roboto', + 'NotoKufi', + ), + fontSize: 16, + color: isDarkTheme ? Colors.white : Color(0xFF414042), + fontWeight: FontWeight.w600, + ), + ), + SizedBox(height: 8), + Padding( + padding: const EdgeInsets.only(left: 8.0), + child: Column( + children: [ + Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Padding( + padding: const EdgeInsets.only(top: 8.0), + child: Icon(Icons.brightness_1, + size: 5, + color: + isDarkTheme ? Colors.white : Colors.black), + ), // Bullet point + SizedBox(width: 8), // Space between bullet and text + Expanded( + child: RichText( + text: TextSpan( + style: TextStyle( + fontSize: 16, + color: isDarkTheme + ? Colors.white + : Color(0xFF898C81), + fontFamily: context.translate( + 'Roboto', + 'NotoKufi', + ), + ), + children: [ + TextSpan( + text: context.translate('Username ', + 'اسم المستخدم وعنوان البريد الإلكتروني: '), + style: TextStyle( + fontWeight: FontWeight.w600, + color: isDarkTheme + ? Colors.white + : Color(0xFF414042), + fontFamily: context.translate( + 'Roboto', + 'NotoKufi', + ), + ), + ), + TextSpan( + text: context.translate('and ', ''), + style: TextStyle( + fontFamily: context.translate( + 'Roboto', + 'NotoKufi', + ), + ), + ), + TextSpan( + text: context.translate('Email Id: ', ''), + style: TextStyle( + fontWeight: FontWeight.w600, + color: isDarkTheme + ? Colors.white + : Color(0xFF414042), + fontFamily: context.translate( + 'Roboto', + 'NotoKufi', + ), + ), + ), + TextSpan( + text: context.translate( + 'These fields cannot be edited to ensure the integrity of your account.', + 'لا يمكن تعديل هذين الحقلين لضمان سلامة حسابك.', + ), + style: TextStyle( + color: isDarkTheme + ? Colors.white + : Color(0xFF898C81)), + ), + ], + ), + )), + ], + ), + ], + ), + ), + SizedBox(height: 8), + Text( + context.translate('4. Agree to Terms and Conditions:', + '4. الموافقة على الشروط والأحكام:'), + style: TextStyle( + fontFamily: context.translate( + 'Roboto', + 'NotoKufi', + ), + fontSize: 16, + color: isDarkTheme ? Colors.white : Color(0xFF414042), + fontWeight: FontWeight.w600, + ), + ), + SizedBox(height: 8), + Padding( + padding: const EdgeInsets.only(left: 8.0), + child: Column( + children: [ + Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Padding( + padding: const EdgeInsets.only(top: 8.0), + child: Icon( + Icons.brightness_1, + size: 5, + color: isDarkTheme ? Colors.white : Colors.black, + ), + ), // Bullet point + SizedBox(width: 8), // Space between bullet and text + Expanded( + child: Text( + context.translate( + 'Ensure that the checkbox for "I agree to Terms & Conditions and Privacy Policy" is selected before saving changes.', + 'تأكد من تحديد خانة "أوافق على الشروط والأحكام وسياسة الخصوصية" قبل حفظ التغييرات.', + ), + textAlign: TextAlign.justify, // Align the text + softWrap: true, + style: TextStyle( + color: isDarkTheme + ? Colors.white + : Color(0xFF898C81)), + ), + ), + ], + ), + ], + ), + ), + SizedBox(height: 8), + Text( + context.translate( + '5. Save Your Changes:', '5. حفظ التغييرات:'), + style: TextStyle( + fontFamily: context.translate( + 'Roboto', + 'NotoKufi', + ), + fontSize: 16, + color: isDarkTheme ? Colors.white : Color(0xFF414042), + fontWeight: FontWeight.w600, + ), + ), + SizedBox(height: 8), + Padding( + padding: const EdgeInsets.only(left: 8.0), + child: Column( + children: [ + Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Padding( + padding: const EdgeInsets.only(top: 8.0), + child: Icon( + Icons.brightness_1, + size: 5, + color: isDarkTheme + ? Colors.white + : Color(0xFF414042), + ), + ), // Bullet point + SizedBox(width: 8), // Space between bullet and text + Expanded( + child: RichText( + text: TextSpan( + text: context.translate( + 'Tap the ', 'اضغط على زر '), + style: TextStyle( + fontSize: 16, + color: isDarkTheme + ? Colors.white + : Color(0xFF898C81), + fontFamily: context.translate( + 'Roboto', + 'NotoKufi', + ), + ), + children: [ + TextSpan( + text: context.translate('Save', '"حفظ" '), + style: TextStyle( + fontWeight: FontWeight.w600, + color: isDarkTheme + ? Colors.white + : Color(0xFF414042), + fontFamily: context.translate( + 'Roboto', + 'NotoKufi', + ), + ), + ), + TextSpan( + text: context.translate( + ' button at the bottom of the screen.', + 'أسفل الشاشة.', + ), + style: TextStyle( + color: isDarkTheme + ? Colors.white + : Color(0xFF898C81)), + ) + ], + ), + ), + ), + ], + ), + SizedBox(height: 8), + Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Padding( + padding: const EdgeInsets.only(top: 8.0), + child: Icon( + Icons.brightness_1, + size: 5, + color: isDarkTheme + ? Colors.white + : Color(0xFF414042), + ), + ), // Bullet point + SizedBox(width: 8), // Space between bullet and text + Expanded( + child: Text( + context.translate( + 'A confirmation dialog will appear with the message: “Are you sure you want to save this page? Once saved, you will not be able to change your name or date of birth.”', + 'ستظهر نافذة تأكيد برسالة:"هل أنت متأكد أنك تريد حفظ هذه الصفحة؟ بمجرد الحفظ، لن تتمكن من تغيير اسمك أو تاريخ ميلادك."', + ), + textAlign: TextAlign.justify, // Align the text + softWrap: true, + style: TextStyle( + color: isDarkTheme + ? Colors.white + : Color(0xFF898C81)), + ), + ), + ], + ), + SizedBox(height: 8), + Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Padding( + padding: const EdgeInsets.only(top: 8.0), + child: Icon( + Icons.brightness_1, + size: 5, + color: isDarkTheme + ? Colors.white + : Color(0xFF414042), + ), + ), // Bullet point + SizedBox(width: 8), // Space between bullet and text + Expanded( + child: RichText( + text: TextSpan( + text: context.translate('Select ', + 'اختر "تأكيد" لحفظ التغييرات أو "إلغاء" للرجوع.'), + style: TextStyle( + fontSize: 16, + color: isDarkTheme + ? Colors.white + : Color(0xFF898C81), + fontFamily: context.translate( + 'Roboto', + 'NotoKufi', + ), + ), + children: [ + TextSpan( + text: context.translate('Confirm', ''), + style: TextStyle( + fontWeight: FontWeight.w600, + color: isDarkTheme + ? Colors.white + : Color(0xFF414042), + fontFamily: context.translate( + 'Roboto', + 'NotoKufi', + ), + ), + ), + TextSpan( + text: context.translate( + ' to save the changes', ''), + style: TextStyle( + fontSize: 16, + color: isDarkTheme + ? Colors.white + : Color(0xFF898C81), + fontFamily: context.translate( + 'Roboto', + 'NotoKufi', + ), + ), + ), + TextSpan( + text: context.translate(' Cancel', ''), + style: TextStyle( + fontWeight: FontWeight.w600, + color: isDarkTheme + ? Colors.white + : Color(0xFF414042), + fontFamily: context.translate( + 'Roboto', + 'NotoKufi', + ), + ), + ), + TextSpan( + text: context.translate(' to go back.', ''), + style: TextStyle( + fontSize: 16, + color: isDarkTheme + ? Colors.white + : Color(0xFF898C81), + fontFamily: context.translate( + 'Roboto', + 'NotoKufi', + ), + ), + ), + ], + ), + ), + ), + ], + ), + ], + ), + ), + SizedBox( + height: 20, + ), + ], + ), + ), + ), + ), + ); + } +} diff --git a/lib/presentation/routes/drawer_routes/Drawer Items/user_guide/KeyFeatures/howUseTheApp.dart b/lib/presentation/routes/drawer_routes/Drawer Items/user_guide/KeyFeatures/howUseTheApp.dart index 010ac5cb..1481abe2 100755 --- a/lib/presentation/routes/drawer_routes/Drawer Items/user_guide/KeyFeatures/howUseTheApp.dart +++ b/lib/presentation/routes/drawer_routes/Drawer Items/user_guide/KeyFeatures/howUseTheApp.dart @@ -1,14 +1,123 @@ -import 'package:flutter/material.dart'; -import 'package:uae_stat/domain/use_cases/language.dart'; +import 'dart:convert'; +import 'package:flutter/material.dart'; +import 'package:flutter_riverpod/flutter_riverpod.dart'; +import 'package:http/http.dart' as http; +import 'package:uae_stat/config/api_config.dart'; +import 'package:uae_stat/config/theme/theme_provider.dart'; +import 'package:uae_stat/config/toggle_lang_service.dart'; +import 'package:uae_stat/domain/use_cases/language.dart'; +import 'package:uae_stat/presentation/Screens/Bottom%20Navigation%20Pages/Country_Profile/country_profile.dart'; import 'package:uae_stat/presentation/routes/drawer_routes/custom_drawer_routes.dart'; -class HowUseTheApp extends StatelessWidget { - const HowUseTheApp({super.key}); +class HowUseTheApp extends ConsumerStatefulWidget { + const HowUseTheApp({super.key}); + + @override + ConsumerState createState() => _HowUseTheAppState(); +} + +class _HowUseTheAppState extends ConsumerState { +// +// class HowUseTheApp extends StatelessWidget { +// const HowUseTheApp({super.key}); + + List homePageData = []; + List filteredData = []; + + bool isLoading = true; + late UserService _userService; + late ThemeMode currentTheme; + + @override + void initState() { + super.initState(); + _userService = UserService(); + final locale = ref.read(localeProvider); + currentTheme = ref.read(themeProvider); + print('123456789'); + print(currentTheme); + WidgetsBinding.instance.addPostFrameCallback((_) { + final isDark = currentTheme == ThemeMode.dark || + (currentTheme == ThemeMode.system && + MediaQuery.of(context).platformBrightness == Brightness.dark); + + final themeMode = (isDark ? 'dark' : 'light'); + print("ThemeMode - $themeMode"); + fetchData(locale?.languageCode ?? 'en', themeMode); + }); + } + + Future fetchData(locale, themeMode) async { + const baseUrl = '$apiUrl/api/getUAENumbersData'; + try { + final response = await http + .get(Uri.parse(baseUrl + '?language=$locale&color_mode=$themeMode')); + if (response.statusCode == 200) { + setState(() { + homePageData = (json.decode(response.body) as List) + .map((e) => Map.from(e)) + .toList(); + filteredData = List.from(homePageData); + isLoading = false; + }); + } else { + throw Exception('Failed to load data'); + } + } catch (e) { + setState(() { + isLoading = false; + }); + print('Error fetching data: $e'); + } + } @override Widget build(BuildContext context) { + ref.listen(localeProvider, (previous, next) async { + final localeCode = next?.languageCode ?? 'en'; + setState(() { + isLoading = true; + }); + await _userService.updateLanguage(localeCode); + final currentTheme = ref.read(themeProvider); + final isDark = currentTheme == ThemeMode.dark || + (currentTheme == ThemeMode.system && + MediaQuery.of(context).platformBrightness == Brightness.dark); + + final themeString = isDark ? 'dark' : 'light'; + fetchData(localeCode, themeString); + }); + + ref.listen(themeProvider, (previous, next) async { + final localeCode = ref.watch(localeProvider)?.languageCode ?? 'en'; + print(localeCode); + + // Default to 'en' if null + setState(() { + isLoading = true; + print('isLoadingref $isLoading'); + }); + + final currentTheme = ref.read(themeProvider); + final isDark = currentTheme == ThemeMode.dark || + (currentTheme == ThemeMode.system && + MediaQuery.of(context).platformBrightness == Brightness.dark); + + final themeString = isDark ? 'dark' : 'light'; + + print("themeString- $themeString"); + fetchData(localeCode, themeString); + }); + + final themeMode = ref.read(themeProvider); + final isDarkTheme = themeMode == ThemeMode.dark || + (themeMode == ThemeMode.system && + MediaQuery.of(context).platformBrightness == Brightness.dark); + + print("isDarkTheme - $isDarkTheme"); + return Theme( data: ThemeData( fontFamily: context.translate( @@ -16,21 +125,27 @@ class HowUseTheApp extends StatelessWidget { 'NotoKufi', ), // Set default font family for this page textTheme: TextTheme( - bodyMedium: TextStyle(fontSize: 16, color: Color(0xFF898C81),fontFamily: context.translate( - 'Roboto', - 'NotoKufi', - ),), + bodyMedium: TextStyle( + fontSize: 16, + color: Color(0xFF898C81), + fontFamily: context.translate( + 'Roboto', + 'NotoKufi', + ), + ), ), ), child: BaseScaffold( + backgroundColor: isDarkTheme ? Colors.black : Colors.white, + appbarColor: isDarkTheme ? Colors.black : Colors.white, showDivider: true, showBackButton: true, dividerColor: Colors.grey[300], - appbarColor: Colors.white, + // appbarColor: Colors.white, bottomColor: Colors.white, mycenterTitle: true, title: Text( - context.translate('Key Features','الميزات الرئيسية'), + context.translate('Key Features', 'الميزات الرئيسية'), style: TextStyle( fontFamily: context.translate( 'Roboto', @@ -44,7 +159,7 @@ class HowUseTheApp extends StatelessWidget { ), body: Container( width: double.infinity, - color: Colors.white, + color: isDarkTheme ? Colors.black : Colors.white, padding: EdgeInsets.all(16), child: SingleChildScrollView( child: Column( @@ -53,14 +168,15 @@ class HowUseTheApp extends StatelessWidget { Align( alignment: Alignment.topLeft, child: Text( - context.translate('How to Use the App','كيفية استخدام التطبيق:'), + context.translate( + 'How to Use the App', 'كيفية استخدام التطبيق:'), style: TextStyle( fontFamily: context.translate( 'Roboto', 'NotoKufi', ), fontSize: 20, - color: Color(0xFF414042), + color: isDarkTheme ? Colors.white : Color(0xFF414042), fontWeight: FontWeight.w600, ), ), @@ -75,15 +191,16 @@ class HowUseTheApp extends StatelessWidget { ), Text( context.translate( - '1. Registration and Approval:', - '1. التسجيل والموافقة:',), + '1. Registration and Approval:', + '1. التسجيل والموافقة:', + ), style: TextStyle( fontFamily: context.translate( 'Roboto', 'NotoKufi', ), fontSize: 16, - color: Color(0xFF414042), + color: isDarkTheme ? Colors.white : Color(0xFF414042), fontWeight: FontWeight.w600, ), ), @@ -96,17 +213,21 @@ class HowUseTheApp extends StatelessWidget { child: Icon( Icons.brightness_1, size: 5, - color: Color(0xFF414042), + color: isDarkTheme ? Colors.white : Color(0xFF414042), ), ), // Bullet point SizedBox(width: 8), // Space between bullet and text Expanded( child: Text( context.translate( - 'Sign up for the app and wait for admin approval.', - 'قم بالتسجيل في التطبيق وانتظر الموافقة من الإدارة.',), + 'Sign up for the app and wait for admin approval.', + 'قم بالتسجيل في التطبيق وانتظر الموافقة من الإدارة.', + ), textAlign: TextAlign.justify, // Align the text softWrap: true, + style: TextStyle( + color: + isDarkTheme ? Colors.white : Color(0xFF898C81)), ), ), ], @@ -114,15 +235,16 @@ class HowUseTheApp extends StatelessWidget { SizedBox(height: 8), Text( context.translate( - '2. Login and Navigation:', - '2. تسجيل الدخول والتصفح:',), + '2. Login and Navigation:', + '2. تسجيل الدخول والتصفح:', + ), style: TextStyle( fontFamily: context.translate( 'Roboto', 'NotoKufi', ), fontSize: 16, - color: Color(0xFF414042), + color: isDarkTheme ? Colors.white : Color(0xFF414042), fontWeight: FontWeight.w600, ), ), @@ -135,17 +257,21 @@ class HowUseTheApp extends StatelessWidget { child: Icon( Icons.brightness_1, size: 5, - color: Color(0xFF414042), + color: isDarkTheme ? Colors.white : Color(0xFF414042), ), ), // Bullet point SizedBox(width: 8), // Space between bullet and text Expanded( child: Text( context.translate( - 'Once approved, log in to access the app. Navigate through the categories on the home screen.', - 'بعد الموافقة، قم بتسجيل الدخول للوصول إلى التطبيق. تصفح الفئات المختلفة على الشاشة الرئيسية.',), + 'Once approved, log in to access the app. Navigate through the categories on the home screen.', + 'بعد الموافقة، قم بتسجيل الدخول للوصول إلى التطبيق. تصفح الفئات المختلفة على الشاشة الرئيسية.', + ), textAlign: TextAlign.justify, // Align the text softWrap: true, + style: TextStyle( + color: + isDarkTheme ? Colors.white : Color(0xFF898C81)), ), ), ], @@ -153,15 +279,16 @@ class HowUseTheApp extends StatelessWidget { SizedBox(height: 8), Text( context.translate( - '3. Access Data:', - '3. الوصول إلى البيانات:',), + '3. Access Data:', + '3. الوصول إلى البيانات:', + ), style: TextStyle( fontFamily: context.translate( 'Roboto', 'NotoKufi', ), fontSize: 16, - color: Color(0xFF414042), + color: isDarkTheme ? Colors.white : Color(0xFF414042), fontWeight: FontWeight.w600, ), ), @@ -174,17 +301,21 @@ class HowUseTheApp extends StatelessWidget { child: Icon( Icons.brightness_1, size: 5, - color: Color(0xFF414042), + color: isDarkTheme ? Colors.white : Color(0xFF414042), ), ), // Bullet point SizedBox(width: 8), // Space between bullet and text Expanded( child: Text( context.translate( - 'Drill down into specific categories like "Economy" or "Environment" to view detailed KPIs and visual insights.', - 'قم بالتعمق في الفئات المحددة مثل "الاقتصاد" أو "البيئة" لعرض مؤشرات الأداء الرئيسية والرؤى المرئية بالتفصيل.',), + 'Drill down into specific categories like "Economy" or "Environment" to view detailed KPIs and visual insights.', + 'قم بالتعمق في الفئات المحددة مثل "الاقتصاد" أو "البيئة" لعرض مؤشرات الأداء الرئيسية والرؤى المرئية بالتفصيل.', + ), textAlign: TextAlign.justify, // Align the text softWrap: true, + style: TextStyle( + color: + isDarkTheme ? Colors.white : Color(0xFF898C81)), ), ), ], @@ -192,15 +323,16 @@ class HowUseTheApp extends StatelessWidget { SizedBox(height: 8), Text( context.translate( - '4. Bookmark Metrics:', - '4. وضع إشارة مرجعية للمقاييس:',), + '4. Bookmark Metrics:', + '4. وضع إشارة مرجعية للمقاييس:', + ), style: TextStyle( fontFamily: context.translate( 'Roboto', 'NotoKufi', ), fontSize: 16, - color: Color(0xFF414042), + color: isDarkTheme ? Colors.white : Color(0xFF414042), fontWeight: FontWeight.w600, ), ), @@ -213,17 +345,21 @@ class HowUseTheApp extends StatelessWidget { child: Icon( Icons.brightness_1, size: 5, - color: Color(0xFF414042), + color: isDarkTheme ? Colors.white : Color(0xFF414042), ), ), // Bullet point SizedBox(width: 8), // Space between bullet and text Expanded( child: Text( context.translate( - 'Drill down into specific categories like "Economy" or "Environment" to view detailed KPIs and visual insights.', - 'احفظ الإحصائيات المهمة للرجوع إليها بسهولة.',), + 'Drill down into specific categories like "Economy" or "Environment" to view detailed KPIs and visual insights.', + 'احفظ الإحصائيات المهمة للرجوع إليها بسهولة.', + ), textAlign: TextAlign.justify, // Align the text softWrap: true, + style: TextStyle( + color: + isDarkTheme ? Colors.white : Color(0xFF898C81)), ), ), ], diff --git a/lib/presentation/routes/drawer_routes/Drawer Items/user_guide/KeyFeatures/purpose.dart b/lib/presentation/routes/drawer_routes/Drawer Items/user_guide/KeyFeatures/purpose.dart index 413dc145..40b826c7 100755 --- a/lib/presentation/routes/drawer_routes/Drawer Items/user_guide/KeyFeatures/purpose.dart +++ b/lib/presentation/routes/drawer_routes/Drawer Items/user_guide/KeyFeatures/purpose.dart @@ -1,12 +1,123 @@ +import 'dart:convert'; + import 'package:flutter/material.dart'; +import 'package:flutter_riverpod/flutter_riverpod.dart'; +import 'package:http/http.dart' as http; +import 'package:uae_stat/config/api_config.dart'; +import 'package:uae_stat/config/theme/theme_provider.dart'; +import 'package:uae_stat/config/toggle_lang_service.dart'; import 'package:uae_stat/domain/use_cases/language.dart'; +import 'package:uae_stat/presentation/Screens/Bottom%20Navigation%20Pages/Country_Profile/country_profile.dart'; import 'package:uae_stat/presentation/routes/drawer_routes/custom_drawer_routes.dart'; -class Purpose extends StatelessWidget { +class Purpose extends ConsumerStatefulWidget { const Purpose({super.key}); + + @override + ConsumerState createState() => _PurposeState(); +} + +class _PurposeState extends ConsumerState { +// +// class Purpose extends StatelessWidget { +// const Purpose({super.key}); + + List homePageData = []; + List filteredData = []; + + bool isLoading = true; + late UserService _userService; + late ThemeMode currentTheme; + + @override + void initState() { + super.initState(); + _userService = UserService(); + final locale = ref.read(localeProvider); + currentTheme = ref.read(themeProvider); + print('123456789'); + print(currentTheme); + WidgetsBinding.instance.addPostFrameCallback((_) { + final isDark = currentTheme == ThemeMode.dark || + (currentTheme == ThemeMode.system && + MediaQuery.of(context).platformBrightness == Brightness.dark); + + final themeMode = (isDark ? 'dark' : 'light'); + print("ThemeMode - $themeMode"); + fetchData(locale?.languageCode ?? 'en', themeMode); + }); + } + + Future fetchData(locale, themeMode) async { + const baseUrl = '$apiUrl/api/getUAENumbersData'; + try { + final response = await http + .get(Uri.parse(baseUrl + '?language=$locale&color_mode=$themeMode')); + if (response.statusCode == 200) { + setState(() { + homePageData = (json.decode(response.body) as List) + .map((e) => Map.from(e)) + .toList(); + filteredData = List.from(homePageData); + isLoading = false; + }); + } else { + throw Exception('Failed to load data'); + } + } catch (e) { + setState(() { + isLoading = false; + }); + print('Error fetching data: $e'); + } + } + @override Widget build(BuildContext context) { + ref.listen(localeProvider, (previous, next) async { + final localeCode = next?.languageCode ?? 'en'; + setState(() { + isLoading = true; + }); + await _userService.updateLanguage(localeCode); + final currentTheme = ref.read(themeProvider); + final isDark = currentTheme == ThemeMode.dark || + (currentTheme == ThemeMode.system && + MediaQuery.of(context).platformBrightness == Brightness.dark); + + final themeString = isDark ? 'dark' : 'light'; + fetchData(localeCode, themeString); + }); + + ref.listen(themeProvider, (previous, next) async { + final localeCode = ref.watch(localeProvider)?.languageCode ?? 'en'; + print(localeCode); + + // Default to 'en' if null + setState(() { + isLoading = true; + print('isLoadingref $isLoading'); + }); + + final currentTheme = ref.read(themeProvider); + final isDark = currentTheme == ThemeMode.dark || + (currentTheme == ThemeMode.system && + MediaQuery.of(context).platformBrightness == Brightness.dark); + + final themeString = isDark ? 'dark' : 'light'; + + print("themeString- $themeString"); + fetchData(localeCode, themeString); + }); + + final themeMode = ref.read(themeProvider); + final isDarkTheme = themeMode == ThemeMode.dark || + (themeMode == ThemeMode.system && + MediaQuery.of(context).platformBrightness == Brightness.dark); + + print("isDarkTheme - $isDarkTheme"); + return Theme( data: ThemeData( fontFamily: context.translate( @@ -25,14 +136,16 @@ class Purpose extends StatelessWidget { ), ), child: BaseScaffold( + backgroundColor: isDarkTheme ? Colors.black : Colors.white, + appbarColor: isDarkTheme ? Colors.black : Colors.white, showDivider: true, showBackButton: true, dividerColor: Colors.grey[300], - appbarColor: Colors.white, + // appbarColor: Colors.white, bottomColor: Colors.white, mycenterTitle: true, title: Text( - context.translate('Key Features','الميزات الرئيسية'), + context.translate('Key Features', 'الميزات الرئيسية'), style: TextStyle( fontFamily: context.translate( 'Roboto', @@ -46,7 +159,7 @@ class Purpose extends StatelessWidget { ), body: Container( height: double.infinity, - color: Colors.white, + color: isDarkTheme ? Colors.black : Colors.white, padding: EdgeInsets.all(16), child: SingleChildScrollView( child: Column( @@ -55,14 +168,14 @@ class Purpose extends StatelessWidget { Align( alignment: Alignment.topLeft, child: Text( - context.translate('Purpose of the App','الغرض من التطبيق'), + context.translate('Purpose of the App', 'الغرض من التطبيق'), style: TextStyle( fontFamily: context.translate( 'Roboto', 'NotoKufi', ), fontSize: 20, - color: Color(0xFF414042), + color: isDarkTheme ? Colors.white : Color(0xFF414042), fontWeight: FontWeight.w600, ), ), @@ -84,35 +197,49 @@ class Purpose extends StatelessWidget { child: Icon( Icons.brightness_1, size: 5, - color: Color(0xFF414042), + color: isDarkTheme ? Colors.white : Color(0xFF414042), ), ), // Bullet point SizedBox(width: 8), // Space between bullet and text Expanded( child: RichText( text: TextSpan( - text: context.translate('Provide ', - 'توفير الإحصائيات الرسمية لدولة الإمارات بشكل سهل الوصول.',), + text: context.translate( + 'Provide ', + 'توفير الإحصائيات الرسمية لدولة الإمارات بشكل سهل الوصول.', + ), style: TextStyle( - color: Color(0xFF898C81), - fontSize: 16, + color: + isDarkTheme ? Colors.white : Color(0xFF898C81), + fontSize: 16, fontFamily: context.translate( 'Roboto', 'NotoKufi', - ),), + ), + ), children: [ TextSpan( - text: context.translate('official statistics ',''), + text: + context.translate('official statistics ', ''), style: TextStyle( - fontWeight: FontWeight.bold, - color: Color(0xFF414042), + fontWeight: FontWeight.bold, + color: isDarkTheme + ? Colors.white + : Color(0xFF414042), fontFamily: context.translate( 'Roboto', 'NotoKufi', - ),), + ), + ), ), TextSpan( - text: context.translate('on the UAE in an accessible format.',''),), + text: context.translate( + 'on the UAE in an accessible format.', ''), + style: TextStyle( + color: isDarkTheme + ? Colors.white + : Color(0xFF898C81)), + ), ], ), ), @@ -127,17 +254,21 @@ class Purpose extends StatelessWidget { child: Icon( Icons.brightness_1, size: 5, - color: Color(0xFF414042), + color: isDarkTheme ? Colors.white : Color(0xFF414042), ), ), // Bullet point SizedBox(width: 8), // Space between bullet and text Expanded( child: Text( context.translate( - 'Support decision-making and research with reliable, up-to-date data.', - 'دعم اتخاذ القرارات والبحوث من خلال بيانات موثوقة ومحدثة.',), + 'Support decision-making and research with reliable, up-to-date data.', + 'دعم اتخاذ القرارات والبحوث من خلال بيانات موثوقة ومحدثة.', + ), textAlign: TextAlign.justify, // Align the text softWrap: true, + style: TextStyle( + color: + isDarkTheme ? Colors.white : Color(0xFF898C81)), ), ), ], @@ -150,17 +281,21 @@ class Purpose extends StatelessWidget { child: Icon( Icons.brightness_1, size: 5, - color: Color(0xFF414042), + color: isDarkTheme ? Colors.white : Color(0xFF414042), ), ), // Bullet point SizedBox(width: 8), // Space between bullet and text Expanded( child: Text( context.translate( - 'Enable users to interact with data visually through graphs and metrics.', - 'تمكين المستخدمين من التفاعل مع البيانات بصريًا من خلال الرسوم البيانية والمقاييس.',), + 'Enable users to interact with data visually through graphs and metrics.', + 'تمكين المستخدمين من التفاعل مع البيانات بصريًا من خلال الرسوم البيانية والمقاييس.', + ), textAlign: TextAlign.justify, // Align the text softWrap: true, + style: TextStyle( + color: + isDarkTheme ? Colors.white : Color(0xFF898C81)), ), ), ], diff --git a/lib/presentation/routes/drawer_routes/Drawer Items/user_guide/KeyFeatures/stayUpdate.dart b/lib/presentation/routes/drawer_routes/Drawer Items/user_guide/KeyFeatures/stayUpdate.dart index c5e1ffc0..075d11fb 100755 --- a/lib/presentation/routes/drawer_routes/Drawer Items/user_guide/KeyFeatures/stayUpdate.dart +++ b/lib/presentation/routes/drawer_routes/Drawer Items/user_guide/KeyFeatures/stayUpdate.dart @@ -1,13 +1,121 @@ +import 'dart:convert'; + import 'package:flutter/material.dart'; +import 'package:flutter_riverpod/flutter_riverpod.dart'; +import 'package:http/http.dart' as http; +import 'package:uae_stat/config/api_config.dart'; +import 'package:uae_stat/config/theme/theme_provider.dart'; +import 'package:uae_stat/config/toggle_lang_service.dart'; import 'package:uae_stat/domain/use_cases/language.dart'; +import 'package:uae_stat/presentation/Screens/Bottom%20Navigation%20Pages/Country_Profile/country_profile.dart'; import 'package:uae_stat/presentation/routes/drawer_routes/custom_drawer_routes.dart'; -class StayUpdate extends StatelessWidget { - const StayUpdate({super.key}); +class StayUpdate extends ConsumerStatefulWidget { + const StayUpdate({super.key}); + + @override + ConsumerState createState() => _StayUpdateState(); +} + +class _StayUpdateState extends ConsumerState { +// class StayUpdate extends StatelessWidget { +// const StayUpdate({super.key}); + + List homePageData = []; + List filteredData = []; + + bool isLoading = true; + late UserService _userService; + late ThemeMode currentTheme; + + @override + void initState() { + super.initState(); + _userService = UserService(); + final locale = ref.read(localeProvider); + currentTheme = ref.read(themeProvider); + print('123456789'); + print(currentTheme); + WidgetsBinding.instance.addPostFrameCallback((_) { + final isDark = currentTheme == ThemeMode.dark || + (currentTheme == ThemeMode.system && + MediaQuery.of(context).platformBrightness == Brightness.dark); + + final themeMode = (isDark ? 'dark' : 'light'); + print("ThemeMode - $themeMode"); + fetchData(locale?.languageCode ?? 'en', themeMode); + }); + } + + Future fetchData(locale, themeMode) async { + const baseUrl = '$apiUrl/api/getUAENumbersData'; + try { + final response = await http + .get(Uri.parse(baseUrl + '?language=$locale&color_mode=$themeMode')); + if (response.statusCode == 200) { + setState(() { + homePageData = (json.decode(response.body) as List) + .map((e) => Map.from(e)) + .toList(); + filteredData = List.from(homePageData); + isLoading = false; + }); + } else { + throw Exception('Failed to load data'); + } + } catch (e) { + setState(() { + isLoading = false; + }); + print('Error fetching data: $e'); + } + } @override Widget build(BuildContext context) { + ref.listen(localeProvider, (previous, next) async { + final localeCode = next?.languageCode ?? 'en'; + setState(() { + isLoading = true; + }); + await _userService.updateLanguage(localeCode); + final currentTheme = ref.read(themeProvider); + final isDark = currentTheme == ThemeMode.dark || + (currentTheme == ThemeMode.system && + MediaQuery.of(context).platformBrightness == Brightness.dark); + + final themeString = isDark ? 'dark' : 'light'; + fetchData(localeCode, themeString); + }); + + ref.listen(themeProvider, (previous, next) async { + final localeCode = ref.watch(localeProvider)?.languageCode ?? 'en'; + print(localeCode); + + // Default to 'en' if null + setState(() { + isLoading = true; + print('isLoadingref $isLoading'); + }); + + final currentTheme = ref.read(themeProvider); + final isDark = currentTheme == ThemeMode.dark || + (currentTheme == ThemeMode.system && + MediaQuery.of(context).platformBrightness == Brightness.dark); + + final themeString = isDark ? 'dark' : 'light'; + + print("themeString- $themeString"); + fetchData(localeCode, themeString); + }); + + final themeMode = ref.read(themeProvider); + final isDarkTheme = themeMode == ThemeMode.dark || + (themeMode == ThemeMode.system && + MediaQuery.of(context).platformBrightness == Brightness.dark); + + print("isDarkTheme - $isDarkTheme"); return Theme( data: ThemeData( fontFamily: context.translate( @@ -29,11 +137,13 @@ class StayUpdate extends StatelessWidget { showDivider: true, showBackButton: true, dividerColor: Colors.grey[300], - appbarColor: Colors.white, + backgroundColor: isDarkTheme ? Colors.black : Colors.white, + appbarColor: isDarkTheme ? Colors.black : Colors.white, + // appbarColor: Colors.white, bottomColor: Colors.white, mycenterTitle: true, title: Text( - context.translate('Key Features','الميزات الرئيسية'), + context.translate('Key Features', 'الميزات الرئيسية'), style: TextStyle( fontFamily: context.translate( 'Roboto', @@ -47,7 +157,7 @@ class StayUpdate extends StatelessWidget { ), body: Container( height: double.infinity, - color: Colors.white, + color: isDarkTheme ? Colors.black : Colors.white, padding: EdgeInsets.all(16), child: SingleChildScrollView( child: Column( @@ -56,14 +166,14 @@ class StayUpdate extends StatelessWidget { Align( alignment: Alignment.topLeft, child: Text( - context.translate('Stay Updated','ابقَ على اطلاع'), + context.translate('Stay Updated', 'ابقَ على اطلاع'), style: TextStyle( fontFamily: context.translate( 'Roboto', 'NotoKufi', ), fontSize: 20, - color: Color(0xFF414042), + color: isDarkTheme ? Colors.white : Color(0xFF414042), fontWeight: FontWeight.w600, ), ), @@ -85,17 +195,21 @@ class StayUpdate extends StatelessWidget { child: Icon( Icons.brightness_1, size: 5, - color: Color(0xFF414042), + color: isDarkTheme ? Colors.white : Color(0xFF414042), ), ), // Bullet point SizedBox(width: 8), // Space between bullet and text Expanded( child: Text( context.translate( - 'The app regularly updates datasets and features to reflect the latest information. Notifications will alert you about new data or improvements.', - 'يتم تحديث مجموعات البيانات وميزات التطبيق بانتظام لتعكس أحدث المعلومات. ستتلقى إشعارات تنبهك حول البيانات الجديدة والتحسينات.',), + 'The app regularly updates datasets and features to reflect the latest information. Notifications will alert you about new data or improvements.', + 'يتم تحديث مجموعات البيانات وميزات التطبيق بانتظام لتعكس أحدث المعلومات. ستتلقى إشعارات تنبهك حول البيانات الجديدة والتحسينات.', + ), textAlign: TextAlign.justify, // Align the text softWrap: true, + style: TextStyle( + color: + isDarkTheme ? Colors.white : Color(0xFF898C81)), ), ), ], diff --git a/lib/presentation/routes/drawer_routes/Drawer Items/user_guide/KeyFeatures/useTheApp.dart b/lib/presentation/routes/drawer_routes/Drawer Items/user_guide/KeyFeatures/useTheApp.dart index 05fc40cc..07f52b67 100755 --- a/lib/presentation/routes/drawer_routes/Drawer Items/user_guide/KeyFeatures/useTheApp.dart +++ b/lib/presentation/routes/drawer_routes/Drawer Items/user_guide/KeyFeatures/useTheApp.dart @@ -1,12 +1,121 @@ +import 'dart:convert'; + import 'package:flutter/material.dart'; +import 'package:flutter_riverpod/flutter_riverpod.dart'; +import 'package:http/http.dart' as http; +import 'package:uae_stat/config/api_config.dart'; +import 'package:uae_stat/config/theme/theme_provider.dart'; +import 'package:uae_stat/config/toggle_lang_service.dart'; import 'package:uae_stat/domain/use_cases/language.dart'; +import 'package:uae_stat/presentation/Screens/Bottom%20Navigation%20Pages/Country_Profile/country_profile.dart'; import 'package:uae_stat/presentation/routes/drawer_routes/custom_drawer_routes.dart'; -class WhoUseTheApp extends StatelessWidget { - const WhoUseTheApp({super.key}); +class WhoUseTheApp extends ConsumerStatefulWidget { + const WhoUseTheApp({super.key}); + + @override + ConsumerState createState() => _WhoUseTheAppState(); +} + +class _WhoUseTheAppState extends ConsumerState { +// class WhoUseTheApp extends StatelessWidget { +// const WhoUseTheApp({super.key}); + + List homePageData = []; + List filteredData = []; + + bool isLoading = true; + late UserService _userService; + late ThemeMode currentTheme; + + @override + void initState() { + super.initState(); + _userService = UserService(); + final locale = ref.read(localeProvider); + currentTheme = ref.read(themeProvider); + print('123456789'); + print(currentTheme); + WidgetsBinding.instance.addPostFrameCallback((_) { + final isDark = currentTheme == ThemeMode.dark || + (currentTheme == ThemeMode.system && + MediaQuery.of(context).platformBrightness == Brightness.dark); + + final themeMode = (isDark ? 'dark' : 'light'); + print("ThemeMode - $themeMode"); + fetchData(locale?.languageCode ?? 'en', themeMode); + }); + } + + Future fetchData(locale, themeMode) async { + const baseUrl = '$apiUrl/api/getUAENumbersData'; + try { + final response = await http + .get(Uri.parse(baseUrl + '?language=$locale&color_mode=$themeMode')); + if (response.statusCode == 200) { + setState(() { + homePageData = (json.decode(response.body) as List) + .map((e) => Map.from(e)) + .toList(); + filteredData = List.from(homePageData); + isLoading = false; + }); + } else { + throw Exception('Failed to load data'); + } + } catch (e) { + setState(() { + isLoading = false; + }); + print('Error fetching data: $e'); + } + } @override Widget build(BuildContext context) { + ref.listen(localeProvider, (previous, next) async { + final localeCode = next?.languageCode ?? 'en'; + setState(() { + isLoading = true; + }); + await _userService.updateLanguage(localeCode); + final currentTheme = ref.read(themeProvider); + final isDark = currentTheme == ThemeMode.dark || + (currentTheme == ThemeMode.system && + MediaQuery.of(context).platformBrightness == Brightness.dark); + + final themeString = isDark ? 'dark' : 'light'; + fetchData(localeCode, themeString); + }); + + ref.listen(themeProvider, (previous, next) async { + final localeCode = ref.watch(localeProvider)?.languageCode ?? 'en'; + print(localeCode); + + // Default to 'en' if null + setState(() { + isLoading = true; + print('isLoadingref $isLoading'); + }); + + final currentTheme = ref.read(themeProvider); + final isDark = currentTheme == ThemeMode.dark || + (currentTheme == ThemeMode.system && + MediaQuery.of(context).platformBrightness == Brightness.dark); + + final themeString = isDark ? 'dark' : 'light'; + + print("themeString- $themeString"); + fetchData(localeCode, themeString); + }); + + final themeMode = ref.read(themeProvider); + final isDarkTheme = themeMode == ThemeMode.dark || + (themeMode == ThemeMode.system && + MediaQuery.of(context).platformBrightness == Brightness.dark); + + print("isDarkTheme - $isDarkTheme"); + return Theme( data: ThemeData( fontFamily: context.translate( @@ -14,22 +123,27 @@ class WhoUseTheApp extends StatelessWidget { 'NotoKufi', ), // Set default font family for this page textTheme: TextTheme( - bodyMedium: TextStyle(fontSize: 16, color: Color(0xFF898C81),fontFamily: context.translate( - 'Roboto', - 'NotoKufi', - ), + bodyMedium: TextStyle( + fontSize: 16, + color: Color(0xFF898C81), + fontFamily: context.translate( + 'Roboto', + 'NotoKufi', + ), ), ), ), child: BaseScaffold( + backgroundColor: isDarkTheme ? Colors.black : Colors.white, + appbarColor: isDarkTheme ? Colors.black : Colors.white, showDivider: true, showBackButton: true, dividerColor: Colors.grey[300], - appbarColor: Colors.white, + // appbarColor: Colors.white, bottomColor: Colors.white, mycenterTitle: true, title: Text( - context.translate('Key Features','الميزات الرئيسية'), + context.translate('Key Features', 'الميزات الرئيسية'), style: TextStyle( fontFamily: context.translate( 'Roboto', @@ -43,7 +157,7 @@ class WhoUseTheApp extends StatelessWidget { ), body: Container( height: double.infinity, - color: Colors.white, + color: isDarkTheme ? Colors.black : Colors.white, padding: EdgeInsets.all(16), child: SingleChildScrollView( child: Column( @@ -52,14 +166,15 @@ class WhoUseTheApp extends StatelessWidget { Align( alignment: Alignment.topLeft, child: Text( - context.translate('Who can use the App?','من يمكنه استخدام التطبيق؟'), + context.translate( + 'Who can use the App?', 'من يمكنه استخدام التطبيق؟'), style: TextStyle( fontFamily: context.translate( 'Roboto', 'NotoKufi', ), fontSize: 20, - color: Color(0xFF414042), + color: isDarkTheme ? Colors.white : Color(0xFF414042), fontWeight: FontWeight.w600, ), ), @@ -73,14 +188,15 @@ class WhoUseTheApp extends StatelessWidget { ), ), Text( - context.translate('This app is intended for:','يستهدف هذا التطبيق:'), + context.translate( + 'This app is intended for:', 'يستهدف هذا التطبيق:'), style: TextStyle( fontFamily: context.translate( 'Roboto', 'NotoKufi', ), fontSize: 16, - color: Color(0xFF414042), + color: isDarkTheme ? Colors.white : Color(0xFF414042), fontWeight: FontWeight.w600, ), ), @@ -93,17 +209,21 @@ class WhoUseTheApp extends StatelessWidget { child: Icon( Icons.brightness_1, size: 5, - color: Color(0xFF414042), + color: isDarkTheme ? Colors.white : Color(0xFF414042), ), ), // Bullet point SizedBox(width: 8), // Space between bullet and text Expanded( child: Text( context.translate( - 'Government officials requiring UAE statistics for decision-making.', - 'المسؤولين الحكوميين الذين يحتاجون إلى إحصاءات دولة الإمارات العربية المتحدة لاتخاذ القرارات.',), - textAlign: TextAlign.justify, // Align the text + 'Government officials requiring UAE statistics for decision-making.', + 'المسؤولين الحكوميين الذين يحتاجون إلى إحصاءات دولة الإمارات العربية المتحدة لاتخاذ القرارات.', + ), + textAlign: TextAlign.justify, // Align the text softWrap: true, + style: TextStyle( + color: + isDarkTheme ? Colors.white : Color(0xFF898C81)), ), ), ], @@ -116,17 +236,21 @@ class WhoUseTheApp extends StatelessWidget { child: Icon( Icons.brightness_1, size: 5, - color: Color(0xFF414042), + color: isDarkTheme ? Colors.white : Color(0xFF414042), ), ), // Bullet point SizedBox(width: 8), // Space between bullet and text Expanded( child: Text( context.translate( - 'Business professionals and researchers analyzing market trends.', - 'المتخصصين في مجال الأعمال والباحثين الذين يقومون بتحليل اتجاهات السوق.',), + 'Business professionals and researchers analyzing market trends.', + 'المتخصصين في مجال الأعمال والباحثين الذين يقومون بتحليل اتجاهات السوق.', + ), textAlign: TextAlign.justify, // Align the text softWrap: true, + style: TextStyle( + color: + isDarkTheme ? Colors.white : Color(0xFF898C81)), ), ), ], @@ -139,22 +263,25 @@ class WhoUseTheApp extends StatelessWidget { child: Icon( Icons.brightness_1, size: 5, - color: Color(0xFF414042), + color: isDarkTheme ? Colors.white : Color(0xFF414042), ), ), // Bullet point SizedBox(width: 8), // Space between bullet and text Expanded( child: Text( context.translate( - 'Students and educators needing reliable data for study and teaching.', - 'الطلاب والمعلمين الذين يحتاجون إلى بيانات موثوقة للدراسة والتعليم.',), + 'Students and educators needing reliable data for study and teaching.', + 'الطلاب والمعلمين الذين يحتاجون إلى بيانات موثوقة للدراسة والتعليم.', + ), textAlign: TextAlign.justify, // Align the text softWrap: true, + style: TextStyle( + color: + isDarkTheme ? Colors.white : Color(0xFF898C81)), ), ), ], ), - SizedBox( height: 20, ), diff --git a/lib/presentation/routes/drawer_routes/Drawer Items/user_guide/aboutApp.dart b/lib/presentation/routes/drawer_routes/Drawer Items/user_guide/aboutApp.dart index dc4a0f3d..2a9bea1d 100755 --- a/lib/presentation/routes/drawer_routes/Drawer Items/user_guide/aboutApp.dart +++ b/lib/presentation/routes/drawer_routes/Drawer Items/user_guide/aboutApp.dart @@ -1,23 +1,131 @@ +import 'dart:convert'; + import 'package:flutter/material.dart'; +import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:go_router/go_router.dart'; +import 'package:http/http.dart' as http; +import 'package:uae_stat/config/api_config.dart'; +import 'package:uae_stat/config/theme/theme_provider.dart'; +import 'package:uae_stat/config/toggle_lang_service.dart'; import 'package:uae_stat/domain/use_cases/language.dart'; +import 'package:uae_stat/presentation/Screens/Bottom%20Navigation%20Pages/Country_Profile/country_profile.dart'; import 'package:uae_stat/presentation/routes/drawer_routes/custom_drawer_routes.dart'; - -class aboutTheApp extends StatelessWidget { +class aboutTheApp extends ConsumerStatefulWidget { const aboutTheApp({super.key}); + @override + ConsumerState createState() => _aboutTheAppState(); +} + +class _aboutTheAppState extends ConsumerState { +// class aboutTheApp extends StatelessWidget { +// aboutTheApp({super.key}); + List homePageData = []; + List filteredData = []; + + bool isLoading = true; + late UserService _userService; + late ThemeMode currentTheme; + + @override + void initState() { + super.initState(); + _userService = UserService(); + final locale = ref.read(localeProvider); + currentTheme = ref.read(themeProvider); + print('123456789'); + print(currentTheme); + WidgetsBinding.instance.addPostFrameCallback((_) { + final isDark = currentTheme == ThemeMode.dark || + (currentTheme == ThemeMode.system && + MediaQuery.of(context).platformBrightness == Brightness.dark); + + final themeMode = (isDark ? 'dark' : 'light'); + print("ThemeMode - $themeMode"); + fetchData(locale?.languageCode ?? 'en', themeMode); + }); + } + + Future fetchData(locale, themeMode) async { + const baseUrl = '$apiUrl/api/getUAENumbersData'; + try { + final response = await http + .get(Uri.parse(baseUrl + '?language=$locale&color_mode=$themeMode')); + if (response.statusCode == 200) { + setState(() { + homePageData = (json.decode(response.body) as List) + .map((e) => Map.from(e)) + .toList(); + filteredData = List.from(homePageData); + isLoading = false; + }); + } else { + throw Exception('Failed to load data'); + } + } catch (e) { + setState(() { + isLoading = false; + }); + print('Error fetching data: $e'); + } + } + @override Widget build(BuildContext context) { + ref.listen(localeProvider, (previous, next) async { + final localeCode = next?.languageCode ?? 'en'; + setState(() { + isLoading = true; + }); + await _userService.updateLanguage(localeCode); + final currentTheme = ref.read(themeProvider); + final isDark = currentTheme == ThemeMode.dark || + (currentTheme == ThemeMode.system && + MediaQuery.of(context).platformBrightness == Brightness.dark); + + final themeString = isDark ? 'dark' : 'light'; + fetchData(localeCode, themeString); + }); + + ref.listen(themeProvider, (previous, next) async { + final localeCode = ref.watch(localeProvider)?.languageCode ?? 'en'; + print(localeCode); + + // Default to 'en' if null + setState(() { + isLoading = true; + print('isLoadingref $isLoading'); + }); + + final currentTheme = ref.read(themeProvider); + final isDark = currentTheme == ThemeMode.dark || + (currentTheme == ThemeMode.system && + MediaQuery.of(context).platformBrightness == Brightness.dark); + + final themeString = isDark ? 'dark' : 'light'; + + print("themeString- $themeString"); + fetchData(localeCode, themeString); + }); + + final themeMode = ref.read(themeProvider); + final isDarkTheme = themeMode == ThemeMode.dark || + (themeMode == ThemeMode.system && + MediaQuery.of(context).platformBrightness == Brightness.dark); + + print("isDarkTheme - $isDarkTheme"); + return BaseScaffold( + backgroundColor: isDarkTheme ? Colors.black : Colors.white, + appbarColor: isDarkTheme ? Colors.black : Colors.white, showDivider: true, showBackButton: true, bottomColor: Colors.white, dividerColor: Colors.grey[300], - appbarColor: Colors.white, mycenterTitle: true, title: Text( - context.translate('Getting Started','البدء'), + context.translate('Getting Started', 'البدء'), style: TextStyle( fontSize: 22, fontFamily: context.translate( @@ -31,15 +139,16 @@ class aboutTheApp extends StatelessWidget { ), body: Container( width: double.infinity, - color: Colors.white, + color: isDarkTheme ? Colors.black : Colors.white, child: Column( children: [ Container( decoration: BoxDecoration( border: Border( bottom: BorderSide( - color: Colors.grey.shade300, - width: 0.5,), // Grey bottom line + color: Colors.grey.shade300, + width: 0.5, + ), // Grey bottom line ), ), child: ListTile( @@ -48,10 +157,10 @@ class aboutTheApp extends StatelessWidget { }, tileColor: Colors.white, title: Text( - context.translate('About FCSC','حول التطبيق'), + context.translate('About FCSC', 'حول التطبيق'), style: TextStyle( fontSize: 16, - color: Color(0xFF414042), + color: isDarkTheme ? Colors.white : Color(0xFF414042), fontWeight: FontWeight.w500, fontFamily: context.translate( 'Roboto', @@ -59,15 +168,19 @@ class aboutTheApp extends StatelessWidget { ), ), ), - trailing: Icon(Icons.keyboard_arrow_right), + trailing: Icon( + Icons.keyboard_arrow_right, + color: isDarkTheme ? Colors.white : Color(0xFF414042), + ), ), ), Container( decoration: BoxDecoration( border: Border( bottom: BorderSide( - color: Colors.grey.shade300, - width: 0.5,), // Grey bottom line + color: Colors.grey.shade300, + width: 0.5, + ), // Grey bottom line ), ), child: ListTile( @@ -76,10 +189,10 @@ class aboutTheApp extends StatelessWidget { }, // tileColor: Colors.white, title: Text( - context.translate('How to Get Started?','كيفية البدء'), + context.translate('How to Get Started?', 'كيفية البدء'), style: TextStyle( fontSize: 16, - color: Color(0xFF414042), + color: isDarkTheme ? Colors.white : Color(0xFF414042), fontWeight: FontWeight.w500, fontFamily: context.translate( 'Roboto', @@ -87,10 +200,15 @@ class aboutTheApp extends StatelessWidget { ), ), ), - trailing: Icon(Icons.keyboard_arrow_right), + trailing: Icon( + Icons.keyboard_arrow_right, + color: isDarkTheme ? Colors.white : Color(0xFF414042), + ), shape: Border( bottom: BorderSide( - color: Colors.black, width: 3,), // Grey bottom line + color: Colors.black, + width: 3, + ), // Grey bottom line ), ), ), diff --git a/lib/presentation/routes/drawer_routes/Drawer Items/user_guide/faq_page.dart b/lib/presentation/routes/drawer_routes/Drawer Items/user_guide/faq_page.dart index 5d87e87b..f8c12d68 100755 --- a/lib/presentation/routes/drawer_routes/Drawer Items/user_guide/faq_page.dart +++ b/lib/presentation/routes/drawer_routes/Drawer Items/user_guide/faq_page.dart @@ -1,26 +1,129 @@ +import 'dart:convert'; + import 'package:flutter/material.dart'; +import 'package:flutter_riverpod/flutter_riverpod.dart'; +import 'package:http/http.dart' as http; +import 'package:uae_stat/config/api_config.dart'; +import 'package:uae_stat/config/theme/theme_provider.dart'; +import 'package:uae_stat/config/toggle_lang_service.dart'; import 'package:uae_stat/domain/use_cases/language.dart'; +import 'package:uae_stat/presentation/Screens/Bottom%20Navigation%20Pages/Country_Profile/country_profile.dart'; import 'package:uae_stat/presentation/routes/drawer_routes/custom_drawer_routes.dart'; -class FAQPage extends StatefulWidget { +class FAQPage extends ConsumerStatefulWidget { const FAQPage({super.key}); @override - State createState() => _FAQPageState(); + ConsumerState createState() => _FAQPageState(); } -class _FAQPageState extends State { +class _FAQPageState extends ConsumerState { +// class _FAQPageState extends State { + List homePageData = []; + List filteredData = []; + + bool isLoading = true; + late UserService _userService; + late ThemeMode currentTheme; + + @override + void initState() { + super.initState(); + _userService = UserService(); + final locale = ref.read(localeProvider); + currentTheme = ref.read(themeProvider); + print('123456789'); + print(currentTheme); + WidgetsBinding.instance.addPostFrameCallback((_) { + final isDark = currentTheme == ThemeMode.dark || + (currentTheme == ThemeMode.system && + MediaQuery.of(context).platformBrightness == Brightness.dark); + + final themeMode = (isDark ? 'dark' : 'light'); + print("ThemeMode - $themeMode"); + fetchData(locale?.languageCode ?? 'en', themeMode); + }); + } + + Future fetchData(locale, themeMode) async { + const baseUrl = '$apiUrl/api/getUAENumbersData'; + try { + final response = await http + .get(Uri.parse(baseUrl + '?language=$locale&color_mode=$themeMode')); + if (response.statusCode == 200) { + setState(() { + homePageData = (json.decode(response.body) as List) + .map((e) => Map.from(e)) + .toList(); + filteredData = List.from(homePageData); + isLoading = false; + }); + } else { + throw Exception('Failed to load data'); + } + } catch (e) { + setState(() { + isLoading = false; + }); + print('Error fetching data: $e'); + } + } @override Widget build(BuildContext context) { + ref.listen(localeProvider, (previous, next) async { + final localeCode = next?.languageCode ?? 'en'; + setState(() { + isLoading = true; + }); + await _userService.updateLanguage(localeCode); + final currentTheme = ref.read(themeProvider); + final isDark = currentTheme == ThemeMode.dark || + (currentTheme == ThemeMode.system && + MediaQuery.of(context).platformBrightness == Brightness.dark); + + final themeString = isDark ? 'dark' : 'light'; + fetchData(localeCode, themeString); + }); + + ref.listen(themeProvider, (previous, next) async { + final localeCode = ref.watch(localeProvider)?.languageCode ?? 'en'; + print(localeCode); + + // Default to 'en' if null + setState(() { + isLoading = true; + print('isLoadingref $isLoading'); + }); + + final currentTheme = ref.read(themeProvider); + final isDark = currentTheme == ThemeMode.dark || + (currentTheme == ThemeMode.system && + MediaQuery.of(context).platformBrightness == Brightness.dark); + + final themeString = isDark ? 'dark' : 'light'; + + print("themeString- $themeString"); + fetchData(localeCode, themeString); + }); + + final themeMode = ref.read(themeProvider); + final isDarkTheme = themeMode == ThemeMode.dark || + (themeMode == ThemeMode.system && + MediaQuery.of(context).platformBrightness == Brightness.dark); + + print("isDarkTheme - $isDarkTheme"); + return BaseScaffold( dividerColor: Colors.grey[300], showBackButton: true, - appbarColor: Colors.white, + // appbarColor: Colors.white, + backgroundColor: isDarkTheme ? Colors.black : Colors.white, + appbarColor: isDarkTheme ? Colors.black : Colors.white, bottomColor: Colors.white, mycenterTitle: true, title: Text( - context.translate(' FAQs','الأسئلة الشائعة'), + context.translate(' FAQs', 'الأسئلة الشائعة'), style: TextStyle( fontFamily: context.translate( 'Roboto', @@ -35,14 +138,16 @@ class _FAQPageState extends State { body: SafeArea( child: Container( height: double.infinity, - color: Colors.white, + color: isDarkTheme ? Colors.black : Colors.white, child: Scrollbar( thumbVisibility: true, thickness: 8, radius: Radius.circular(10), interactive: true, child: SingleChildScrollView( - child: QuestionAnswerScrollView(), + child: QuestionAnswerScrollView( + isDarkTheme: isDarkTheme, + ), ), ), ), @@ -52,7 +157,9 @@ class _FAQPageState extends State { } class QuestionAnswerScrollView extends StatelessWidget { - const QuestionAnswerScrollView({super.key}); + final bool isDarkTheme; + + const QuestionAnswerScrollView({super.key, required this.isDarkTheme}); @override Widget build(BuildContext context) { @@ -62,7 +169,8 @@ class QuestionAnswerScrollView extends StatelessWidget { 'question-ar': 'ما هو الغرض من هذا التطبيق؟', 'answer': 'The app provides official UAE statistics across categories like Economy, Environment, and Social. It allows users to explore datasets, view trends, and access detailed metrics to make informed decisions.', - 'answer-ar':'يوفر التطبيق الإحصائيات الرسمية لدولة الإمارات العربية المتحدة عبر فئات مثل الاقتصاد والبيئة والاجتماعية . يتيح للمستخدمين استكشاف مجموعات البيانات، عرض الاتجاهات، والوصول إلى المقاييس التفصيلية لاتخاذ قرارات مستنيرة.', + 'answer-ar': + 'يوفر التطبيق الإحصائيات الرسمية لدولة الإمارات العربية المتحدة عبر فئات مثل الاقتصاد والبيئة والاجتماعية . يتيح للمستخدمين استكشاف مجموعات البيانات، عرض الاتجاهات، والوصول إلى المقاييس التفصيلية لاتخاذ قرارات مستنيرة.', }, { 'question': 'Do I need to create an account to use the app?', @@ -74,77 +182,101 @@ class QuestionAnswerScrollView extends StatelessWidget { text: 'Yes, the app is strictly for registered and approved users. To access the data:\n\n', style: TextStyle( - color: Colors.grey, fontSize: 16, fontFamily: context.translate( - 'Roboto', - 'NotoKufi', - ),), + color: isDarkTheme ? Colors.white : Colors.grey, + fontSize: 16, + fontFamily: context.translate( + 'Roboto', + 'NotoKufi', + ), + ), ), TextSpan( text: ' 1. You need to sign up using the Register Now option on the login screen.\n', style: TextStyle( - color: Colors.grey, fontSize: 16, fontFamily: context.translate( - 'Roboto', - 'NotoKufi', - ),), + color: isDarkTheme ? Colors.white : Colors.grey, + fontSize: 16, + fontFamily: context.translate( + 'Roboto', + 'NotoKufi', + ), + ), ), TextSpan( text: ' 2. Your registration must be approved by the admin.\n', style: TextStyle( - color: Colors.grey, fontSize: 16, fontFamily: context.translate( - 'Roboto', - 'NotoKufi', - ),), + color: isDarkTheme ? Colors.white : Colors.grey, + fontSize: 16, + fontFamily: context.translate( + 'Roboto', + 'NotoKufi', + ), + ), ), TextSpan( text: " 3. Once approved, you can log in to access the app's features and datasets.\n\nGuest access is not available for this application.\n ", style: TextStyle( - color: Colors.grey, fontSize: 16, fontFamily: context.translate( - 'Roboto', - 'NotoKufi', - ),), + color: isDarkTheme ? Colors.white : Colors.grey, + fontSize: 16, + fontFamily: context.translate( + 'Roboto', + 'NotoKufi', + ), + ), ), ], ), ), - 'answer-ar':RichText( + 'answer-ar': RichText( text: TextSpan( children: [ TextSpan( text: - 'نعم، التطبيق مخصص فقط للمستخدمين المسجلين والمعتمدين. للوصول إلى البيانات:\n\n', + 'نعم، التطبيق مخصص فقط للمستخدمين المسجلين والمعتمدين. للوصول إلى البيانات:\n\n', style: TextStyle( - color: Colors.grey, fontSize: 16, fontFamily: context.translate( - 'Roboto', - 'NotoKufi', - ),), + color: isDarkTheme ? Colors.white : Colors.grey, + fontSize: 16, + fontFamily: context.translate( + 'Roboto', + 'NotoKufi', + ), + ), ), TextSpan( text: - ' 1. يجب عليك التسجيل باستخدام خيار "التسجيل الآن" في شاشة تسجيل الدخول.\n', + ' 1. يجب عليك التسجيل باستخدام خيار "التسجيل الآن" في شاشة تسجيل الدخول.\n', style: TextStyle( - color: Colors.grey, fontSize: 16, fontFamily: context.translate( - 'Roboto', - 'NotoKufi', - ),), + color: isDarkTheme ? Colors.white : Colors.grey, + fontSize: 16, + fontFamily: context.translate( + 'Roboto', + 'NotoKufi', + ), + ), ), TextSpan( text: ' 2. يجب أن يتم الموافقة على تسجيلك من قبل المسؤول.\n', style: TextStyle( - color: Colors.grey, fontSize: 16, fontFamily: context.translate( - 'Roboto', - 'NotoKufi', - ),), + color: isDarkTheme ? Colors.white : Colors.grey, + fontSize: 16, + fontFamily: context.translate( + 'Roboto', + 'NotoKufi', + ), + ), ), TextSpan( text: - ' بعد الموافقة، يمكنك تسجيل الدخول للوصول إلى ميزات التطبيق وبياناته.\n\n لا يتوفر الوصول للزوار في هذا التطبيق.\n', + ' بعد الموافقة، يمكنك تسجيل الدخول للوصول إلى ميزات التطبيق وبياناته.\n\n لا يتوفر الوصول للزوار في هذا التطبيق.\n', style: TextStyle( - color: Colors.grey, fontSize: 16, fontFamily: context.translate( - 'Roboto', - 'NotoKufi', - ),), + color: isDarkTheme ? Colors.white : Colors.grey, + fontSize: 16, + fontFamily: context.translate( + 'Roboto', + 'NotoKufi', + ), + ), ), ], ), @@ -155,21 +287,25 @@ class QuestionAnswerScrollView extends StatelessWidget { 'question-ar': 'كيف يمكنني التنقل عبر التطبيق؟', 'answer': '• Use the main categories on the homepage (e.g., Economy, Environment) to access subcategories and detailed KPIs.\n• Drill down into specific metrics or graphical views by tapping on a KPI.\n• Access additional features like Bookmarks or Profile through the navigation bar.\n', - 'answer-ar': '•استخدم الفئات الرئيسية الموجودة على الصفحة الرئيسية (مثل: الاقتصاد، البيئة) للوصول إلى الفئات الفرعية ومؤشرات الأداء الرئيسية التفصيلية •\n قم بالتعمق في مؤشرات معينة أو عرض الرسوم البيانية من خلال النقر على مؤشر الأداء الرئيسي (KPI). \n • للوصول إلى ميزات إضافية مثل الإشارات المرجعية أو الملف الشخصي، استخدم شريط التنقل.\n', + 'answer-ar': + '•استخدم الفئات الرئيسية الموجودة على الصفحة الرئيسية (مثل: الاقتصاد، البيئة) للوصول إلى الفئات الفرعية ومؤشرات الأداء الرئيسية التفصيلية •\n قم بالتعمق في مؤشرات معينة أو عرض الرسوم البيانية من خلال النقر على مؤشر الأداء الرئيسي (KPI). \n • للوصول إلى ميزات إضافية مثل الإشارات المرجعية أو الملف الشخصي، استخدم شريط التنقل.\n', }, { 'question': 'What types of data are available?', - 'question-ar':'ما أنواع البيانات المتوفرة؟ ', + 'question-ar': 'ما أنواع البيانات المتوفرة؟ ', 'answer': RichText( text: TextSpan( children: [ TextSpan( text: 'The app offers data on:\n\n', style: TextStyle( - color: Colors.grey, fontSize: 16, fontFamily: context.translate( - 'Roboto', - 'NotoKufi', - ),), + color: isDarkTheme ? Colors.white : Colors.grey, + fontSize: 16, + fontFamily: context.translate( + 'Roboto', + 'NotoKufi', + ), + ), ), TextSpan( text: ' • Economy:', @@ -178,17 +314,20 @@ class QuestionAnswerScrollView extends StatelessWidget { 'Roboto', 'NotoKufi', ), - color: Color(0xFF414042), + color: isDarkTheme ? Colors.white : Color(0xFF414042), fontWeight: FontWeight.w500, fontSize: 16), ), TextSpan( text: ' GDP, growth rates, and economic trends\n', style: TextStyle( - color: Colors.grey, fontSize: 16, fontFamily: context.translate( - 'Roboto', - 'NotoKufi', - ),), + color: isDarkTheme ? Colors.white : Colors.grey, + fontSize: 16, + fontFamily: context.translate( + 'Roboto', + 'NotoKufi', + ), + ), ), TextSpan( text: ' • Environment:', @@ -197,17 +336,20 @@ class QuestionAnswerScrollView extends StatelessWidget { 'Roboto', 'NotoKufi', ), - color: Color(0xFF414042), + color: isDarkTheme ? Colors.white : Color(0xFF414042), fontWeight: FontWeight.w500, fontSize: 16), ), TextSpan( text: ' Electricity production, water consumption, and more.\n', style: TextStyle( - color: Colors.grey, fontSize: 16, fontFamily: context.translate( - 'Roboto', - 'NotoKufi', - ),), + color: isDarkTheme ? Colors.white : Colors.grey, + fontSize: 16, + fontFamily: context.translate( + 'Roboto', + 'NotoKufi', + ), + ), ), TextSpan( text: ' • Social:', @@ -216,7 +358,7 @@ class QuestionAnswerScrollView extends StatelessWidget { 'Roboto', 'NotoKufi', ), - color: Color(0xFF414042), + color: isDarkTheme ? Colors.white : Color(0xFF414042), fontWeight: FontWeight.w500, fontSize: 16), ), @@ -224,24 +366,30 @@ class QuestionAnswerScrollView extends StatelessWidget { text: ' Labor force distribution, participation rates, and demographic data.\n', style: TextStyle( - color: Colors.grey, fontSize: 16, fontFamily: context.translate( - 'Roboto', - 'NotoKufi', - ),), + color: isDarkTheme ? Colors.white : Colors.grey, + fontSize: 16, + fontFamily: context.translate( + 'Roboto', + 'NotoKufi', + ), + ), ), ], ), ), - 'answer-ar':RichText( + 'answer-ar': RichText( text: TextSpan( children: [ TextSpan( text: 'يوفر التطبيق بيانات عن:\n\n', style: TextStyle( - color: Colors.grey, fontSize: 16, fontFamily: context.translate( - 'Roboto', - 'NotoKufi', - ),), + color: isDarkTheme ? Colors.white : Colors.grey, + fontSize: 16, + fontFamily: context.translate( + 'Roboto', + 'NotoKufi', + ), + ), ), TextSpan( text: ' • الاقتصاد:', @@ -250,17 +398,21 @@ class QuestionAnswerScrollView extends StatelessWidget { 'Roboto', 'NotoKufi', ), - color: Color(0xFF414042), + color: isDarkTheme ? Colors.white : Color(0xFF414042), fontWeight: FontWeight.w500, fontSize: 16), ), TextSpan( - text: ' الناتج المحلي الإجمالي (GDP)، معدلات النمو، والاتجاهات الاقتصادية.\n', + text: + ' الناتج المحلي الإجمالي (GDP)، معدلات النمو، والاتجاهات الاقتصادية.\n', style: TextStyle( - color: Colors.grey, fontSize: 16, fontFamily: context.translate( - 'Roboto', - 'NotoKufi', - ),), + color: isDarkTheme ? Colors.white : Colors.grey, + fontSize: 16, + fontFamily: context.translate( + 'Roboto', + 'NotoKufi', + ), + ), ), TextSpan( text: ' • البيئة:', @@ -269,17 +421,20 @@ class QuestionAnswerScrollView extends StatelessWidget { 'Roboto', 'NotoKufi', ), - color: Color(0xFF414042), + color: isDarkTheme ? Colors.white : Color(0xFF414042), fontWeight: FontWeight.w500, fontSize: 16), ), TextSpan( text: ' إنتاج الكهرباء، استهلاك المياه، وغيرها.\n', style: TextStyle( - color: Colors.grey, fontSize: 16, fontFamily: context.translate( - 'Roboto', - 'NotoKufi', - ),), + color: isDarkTheme ? Colors.white : Colors.grey, + fontSize: 16, + fontFamily: context.translate( + 'Roboto', + 'NotoKufi', + ), + ), ), TextSpan( text: ' • الاجتماعية:', @@ -288,18 +443,21 @@ class QuestionAnswerScrollView extends StatelessWidget { 'Roboto', 'NotoKufi', ), - color: Color(0xFF414042), + color: isDarkTheme ? Colors.white : Color(0xFF414042), fontWeight: FontWeight.w500, fontSize: 16), ), TextSpan( text: - ' توزيع القوى العاملة، معدلات المشاركة، والبيانات الديموغرافية.\n', + ' توزيع القوى العاملة، معدلات المشاركة، والبيانات الديموغرافية.\n', style: TextStyle( - color: Colors.grey, fontSize: 16, fontFamily: context.translate( - 'Roboto', - 'NotoKufi', - ),), + color: isDarkTheme ? Colors.white : Colors.grey, + fontSize: 16, + fontFamily: context.translate( + 'Roboto', + 'NotoKufi', + ), + ), ), ], ), @@ -314,10 +472,13 @@ class QuestionAnswerScrollView extends StatelessWidget { TextSpan( text: 'When viewing a metric, tap on the', style: TextStyle( - color: Colors.grey, fontSize: 16, fontFamily: context.translate( - 'Roboto', - 'NotoKufi', - ),), + color: isDarkTheme ? Colors.white : Colors.grey, + fontSize: 16, + fontFamily: context.translate( + 'Roboto', + 'NotoKufi', + ), + ), ), TextSpan( text: ' Bookmark ', @@ -326,17 +487,20 @@ class QuestionAnswerScrollView extends StatelessWidget { 'Roboto', 'NotoKufi', ), - color: Color(0xFF414042), + color: isDarkTheme ? Colors.white : Color(0xFF414042), fontWeight: FontWeight.w500, fontSize: 16), ), TextSpan( text: 'icon. Your bookmarks are accessible from the', style: TextStyle( - color: Colors.grey, fontSize: 16, fontFamily: context.translate( - 'Roboto', - 'NotoKufi', - ),), + color: isDarkTheme ? Colors.white : Colors.grey, + fontSize: 16, + fontFamily: context.translate( + 'Roboto', + 'NotoKufi', + ), + ), ), TextSpan( text: 'My Bookmarks', @@ -345,221 +509,20 @@ class QuestionAnswerScrollView extends StatelessWidget { 'Roboto', 'NotoKufi', ), - color: Color(0xFF414042), + color: isDarkTheme ? Colors.white : Color(0xFF414042), fontWeight: FontWeight.w500, fontSize: 16), ), TextSpan( text: 'section in the navigation bar.\n', style: TextStyle( - color: Colors.grey, fontSize: 16, fontFamily: context.translate( - 'Roboto', - 'NotoKufi', - ),), - ), - ], - ), - ), - 'answer-ar':RichText( - text: TextSpan( - children: [ - TextSpan( - text: 'عند عرض المؤشر، اضغط على أيقونة الإشارة المرجعية. يمكنك الوصول إلى الإشارات المرجعية الخاصة بك من قسم "إشاراتي المرجعية" في شريط التنقل.', - style: TextStyle( - color: Colors.grey, fontSize: 16, fontFamily: context.translate( - 'Roboto', - 'NotoKufi', - ),), - ), - - ], - ), - ), - }, - { - 'question': 'Can I view the app in another language?', - 'question-ar':'هل يمكنني عرض التطبيق بلغة أخرى؟', - 'answer': RichText( - text: TextSpan( - children: [ - TextSpan( - text: 'Yes, the app supports both ', - style: TextStyle( - color: Colors.grey, fontSize: 16, fontFamily: context.translate( - 'Roboto', - 'NotoKufi', - ),), - ), - TextSpan( - text: 'English ', - style: TextStyle( - fontFamily: context.translate( - 'Roboto', - 'NotoKufi', - ), - color: Color(0xFF414042), - fontWeight: FontWeight.w500, - fontSize: 16), - ), - TextSpan( - text: 'and', - style: TextStyle( - color: Colors.grey, fontSize: 16, fontFamily: context.translate( - 'Roboto', - 'NotoKufi', - ),), - ), - TextSpan( - text: ' Arabic ', - style: TextStyle( - fontFamily: context.translate( - 'Roboto', - 'NotoKufi', - ), - color: Color(0xFF414042), - fontWeight: FontWeight.w500, - fontSize: 16), - ), - TextSpan( - text: - '. You can toggle the language using the switch in the top-right corner of the app.\n', - style: TextStyle( - color: Colors.grey, fontSize: 16, fontFamily: context.translate( - 'Roboto', - 'NotoKufi', - ),), - ), - ], - ), - ), - 'answer-ar':RichText( - text: TextSpan( - children: [ - TextSpan( - text: 'نعم، التطبيق يدعم اللغتين الإنجليزية والعربية. يمكنك تبديل اللغة باستخدام المفتاح الموجود في الزاوية العلوية اليمنى من التطبيق.', - style: TextStyle( - color: Colors.grey, fontSize: 16, fontFamily: context.translate( - 'Roboto', - 'NotoKufi', - ),), - ), - ], - ), - ), - }, - { - 'question': 'What happens if I forget my password?', - 'question-ar':'ماذا يحدث إذا نسيت كلمة المرور الخاصة بي؟', - 'answer': - 'Tap on the Forgot Password? link on the login page. Follow the steps to reset your password via your registered email address.\n', - 'answer-ar':'انقر على رابط "نسيت كلمة المرور؟" في صفحة تسجيل الدخول. اتبع الخطوات لإعادة تعيين كلمة المرور الخاصة بك عبر عنوان بريدك الإلكتروني المسجل.', - }, - { - 'question': 'Can I edit my profile details?', - 'question-ar':'هل يمكنني تعديل تفاصيل الملف الشخصي؟', - 'answer': - 'Yes, you can edit specific fields such as Date of Birth and User Image. However, certain fields like Username and Email are non-editable for security reasons.\n', - 'answer-ar':'يتم تحديث مجموعات البيانات في التطبيق بشكل منتظم لضمان وصول المستخدمين إلى أحدث الإحصاءات. يتم إرسال إشعارات عند إجراء تحديثات مهمة.', - }, - { - 'question': 'How often is the data updated?', - 'question-ar':'كم مرة يتم تحديث البيانات؟ ', - 'answer': - 'The app updates its datasets regularly to ensure users have access to the latest statistics. Notifications are sent whenever significant updates are made.\n', - 'answer-ar':'يتم تحديث مجموعات البيانات في التطبيق بشكل منتظم لضمان وصول المستخدمين إلى أحدث الإحصاءات. يتم إرسال إشعارات عند إجراء تحديثات مهمة.', - }, - { - 'question': 'What types of graphs and charts are available?', - 'question-ar':'ما أنواع الرسوم البيانية والمخططات المتوفرة؟ ', - 'answer': - 'The app provides a variety of visualizations, including:\n • Line charts for trends.\n • Bar and column charts for comparisons.\n • Stacked charts for multi-layered data views.\n', - 'answer-ar':'يوفر التطبيق مجموعة متنوعة من التصورات البيانية، بما في ذلك:\n• المخططات الخطية لعرض الاتجاهات.\n• المخططات الشريطية والعمودية للمقارنات.\n• المخططات المكدسة لعرض البيانات متعددة الطبقات.\n', - }, - { - 'question': 'Can I share the data or charts?', - 'question-ar':'هل يمكنني مشاركة البيانات أو الرسوم البيانية؟', - 'answer': RichText( - text: TextSpan( - children: [ - TextSpan( - text: - 'Yes, you can share data or charts directly from the app by tapping the ', - style: TextStyle( - color: Colors.grey, fontSize: 16, fontFamily: context.translate( - 'Roboto', - 'NotoKufi', - ),), - ), - TextSpan( - text: 'Share ', - style: TextStyle( - fontFamily: context.translate( - 'Roboto', - 'NotoKufi', - ), - color: Color(0xFF414042), - fontWeight: FontWeight.w500, - fontSize: 16), - ), - TextSpan( - text: 'button available on most pages.\n', - style: TextStyle( - color: Colors.grey, fontSize: 16, fontFamily: context.translate( - 'Roboto', - 'NotoKufi', - ),), - ), - ], - ), - ), - 'answer-ar':RichText( - text: TextSpan( - children: [ - TextSpan( - text: - 'نعم، يمكنك مشاركة البيانات أو الرسوم البيانية مباشرة من التطبيق من خلال النقر على زر "مشاركة" المتوفر في معظم الصفحات.', - style: TextStyle( - color: Colors.grey, fontSize: 16, fontFamily: context.translate( - 'Roboto', - 'NotoKufi', - ),), - ), - ], - ), - ), - }, - { - 'question': 'What should I do if I encounter an issue?', - 'question-ar':'ماذا يجب أن أفعل إذا واجهت مشكلة؟ ', - 'answer': RichText( - text: TextSpan( - children: [ - TextSpan( - text: 'For technical support or feedback, navigate to the ', - style: TextStyle( - color: Colors.grey, fontSize: 16, fontFamily: context.translate( - 'Roboto', - 'NotoKufi', - ),), - ), - TextSpan( - text: 'Help ', - style: TextStyle( - fontFamily: context.translate( - 'Roboto', - 'NotoKufi', - ), - color: Color(0xFF414042), - fontWeight: FontWeight.w500, - fontSize: 16), - ), - TextSpan( - text: 'section in the app and contact the support team.\n', - style: TextStyle( - color: Colors.grey, fontSize: 16, fontFamily: context.translate( - 'Roboto', - 'NotoKufi', - ),), + color: isDarkTheme ? Colors.white : Colors.grey, + fontSize: 16, + fontFamily: context.translate( + 'Roboto', + 'NotoKufi', + ), + ), ), ], ), @@ -568,12 +531,255 @@ class QuestionAnswerScrollView extends StatelessWidget { text: TextSpan( children: [ TextSpan( - text: 'للحصول على الدعم الفني أو تقديم ملاحظات، انتقل إلى قسم "المساعدة" في التطبيق وتواصل مع فريق الدعم.\n', + text: + 'عند عرض المؤشر، اضغط على أيقونة الإشارة المرجعية. يمكنك الوصول إلى الإشارات المرجعية الخاصة بك من قسم "إشاراتي المرجعية" في شريط التنقل.', style: TextStyle( - color: Colors.grey, fontSize: 16, fontFamily: context.translate( - 'Roboto', - 'NotoKufi', - ),), + color: isDarkTheme ? Colors.white : Colors.grey, + fontSize: 16, + fontFamily: context.translate( + 'Roboto', + 'NotoKufi', + ), + ), + ), + ], + ), + ), + }, + { + 'question': 'Can I view the app in another language?', + 'question-ar': 'هل يمكنني عرض التطبيق بلغة أخرى؟', + 'answer': RichText( + text: TextSpan( + children: [ + TextSpan( + text: 'Yes, the app supports both ', + style: TextStyle( + color: isDarkTheme ? Colors.white : Colors.grey, + fontSize: 16, + fontFamily: context.translate( + 'Roboto', + 'NotoKufi', + ), + ), + ), + TextSpan( + text: 'English ', + style: TextStyle( + fontFamily: context.translate( + 'Roboto', + 'NotoKufi', + ), + color: isDarkTheme ? Colors.white : Color(0xFF414042), + fontWeight: FontWeight.w500, + fontSize: 16), + ), + TextSpan( + text: 'and', + style: TextStyle( + color: isDarkTheme ? Colors.white : Colors.grey, + fontSize: 16, + fontFamily: context.translate( + 'Roboto', + 'NotoKufi', + ), + ), + ), + TextSpan( + text: ' Arabic ', + style: TextStyle( + fontFamily: context.translate( + 'Roboto', + 'NotoKufi', + ), + color: isDarkTheme ? Colors.white : Color(0xFF414042), + fontWeight: FontWeight.w500, + fontSize: 16), + ), + TextSpan( + text: + '. You can toggle the language using the switch in the top-right corner of the app.\n', + style: TextStyle( + color: isDarkTheme ? Colors.white : Colors.grey, + fontSize: 16, + fontFamily: context.translate( + 'Roboto', + 'NotoKufi', + ), + ), + ), + ], + ), + ), + 'answer-ar': RichText( + text: TextSpan( + children: [ + TextSpan( + text: + 'نعم، التطبيق يدعم اللغتين الإنجليزية والعربية. يمكنك تبديل اللغة باستخدام المفتاح الموجود في الزاوية العلوية اليمنى من التطبيق.', + style: TextStyle( + color: isDarkTheme ? Colors.white : Colors.grey, + fontSize: 16, + fontFamily: context.translate( + 'Roboto', + 'NotoKufi', + ), + ), + ), + ], + ), + ), + }, + { + 'question': 'What happens if I forget my password?', + 'question-ar': 'ماذا يحدث إذا نسيت كلمة المرور الخاصة بي؟', + 'answer': + 'Tap on the Forgot Password? link on the login page. Follow the steps to reset your password via your registered email address.\n', + 'answer-ar': + 'انقر على رابط "نسيت كلمة المرور؟" في صفحة تسجيل الدخول. اتبع الخطوات لإعادة تعيين كلمة المرور الخاصة بك عبر عنوان بريدك الإلكتروني المسجل.', + }, + { + 'question': 'Can I edit my profile details?', + 'question-ar': 'هل يمكنني تعديل تفاصيل الملف الشخصي؟', + 'answer': + 'Yes, you can edit specific fields such as Date of Birth and User Image. However, certain fields like Username and Email are non-editable for security reasons.\n', + 'answer-ar': + 'يتم تحديث مجموعات البيانات في التطبيق بشكل منتظم لضمان وصول المستخدمين إلى أحدث الإحصاءات. يتم إرسال إشعارات عند إجراء تحديثات مهمة.', + }, + { + 'question': 'How often is the data updated?', + 'question-ar': 'كم مرة يتم تحديث البيانات؟ ', + 'answer': + 'The app updates its datasets regularly to ensure users have access to the latest statistics. Notifications are sent whenever significant updates are made.\n', + 'answer-ar': + 'يتم تحديث مجموعات البيانات في التطبيق بشكل منتظم لضمان وصول المستخدمين إلى أحدث الإحصاءات. يتم إرسال إشعارات عند إجراء تحديثات مهمة.', + }, + { + 'question': 'What types of graphs and charts are available?', + 'question-ar': 'ما أنواع الرسوم البيانية والمخططات المتوفرة؟ ', + 'answer': + 'The app provides a variety of visualizations, including:\n • Line charts for trends.\n • Bar and column charts for comparisons.\n • Stacked charts for multi-layered data views.\n', + 'answer-ar': + 'يوفر التطبيق مجموعة متنوعة من التصورات البيانية، بما في ذلك:\n• المخططات الخطية لعرض الاتجاهات.\n• المخططات الشريطية والعمودية للمقارنات.\n• المخططات المكدسة لعرض البيانات متعددة الطبقات.\n', + }, + { + 'question': 'Can I share the data or charts?', + 'question-ar': 'هل يمكنني مشاركة البيانات أو الرسوم البيانية؟', + 'answer': RichText( + text: TextSpan( + children: [ + TextSpan( + text: + 'Yes, you can share data or charts directly from the app by tapping the ', + style: TextStyle( + color: isDarkTheme ? Colors.white : Colors.grey, + fontSize: 16, + fontFamily: context.translate( + 'Roboto', + 'NotoKufi', + ), + ), + ), + TextSpan( + text: 'Share ', + style: TextStyle( + fontFamily: context.translate( + 'Roboto', + 'NotoKufi', + ), + color: isDarkTheme ? Colors.white : Color(0xFF414042), + fontWeight: FontWeight.w500, + fontSize: 16), + ), + TextSpan( + text: 'button available on most pages.\n', + style: TextStyle( + color: isDarkTheme ? Colors.white : Colors.grey, + fontSize: 16, + fontFamily: context.translate( + 'Roboto', + 'NotoKufi', + ), + ), + ), + ], + ), + ), + 'answer-ar': RichText( + text: TextSpan( + children: [ + TextSpan( + text: + 'نعم، يمكنك مشاركة البيانات أو الرسوم البيانية مباشرة من التطبيق من خلال النقر على زر "مشاركة" المتوفر في معظم الصفحات.', + style: TextStyle( + color: isDarkTheme ? Colors.white : Colors.grey, + fontSize: 16, + fontFamily: context.translate( + 'Roboto', + 'NotoKufi', + ), + ), + ), + ], + ), + ), + }, + { + 'question': 'What should I do if I encounter an issue?', + 'question-ar': 'ماذا يجب أن أفعل إذا واجهت مشكلة؟ ', + 'answer': RichText( + text: TextSpan( + children: [ + TextSpan( + text: 'For technical support or feedback, navigate to the ', + style: TextStyle( + color: isDarkTheme ? Colors.white : Colors.grey, + fontSize: 16, + fontFamily: context.translate( + 'Roboto', + 'NotoKufi', + ), + ), + ), + TextSpan( + text: 'Help ', + style: TextStyle( + fontFamily: context.translate( + 'Roboto', + 'NotoKufi', + ), + color: isDarkTheme ? Colors.white : Color(0xFF414042), + fontWeight: FontWeight.w500, + fontSize: 16), + ), + TextSpan( + text: 'section in the app and contact the support team.\n', + style: TextStyle( + color: isDarkTheme ? Colors.white : Colors.grey, + fontSize: 16, + fontFamily: context.translate( + 'Roboto', + 'NotoKufi', + ), + ), + ), + ], + ), + ), + 'answer-ar': RichText( + text: TextSpan( + children: [ + TextSpan( + text: + 'للحصول على الدعم الفني أو تقديم ملاحظات، انتقل إلى قسم "المساعدة" في التطبيق وتواصل مع فريق الدعم.\n', + style: TextStyle( + color: isDarkTheme ? Colors.white : Colors.grey, + fontSize: 16, + fontFamily: context.translate( + 'Roboto', + 'NotoKufi', + ), + ), ), ], ), @@ -581,17 +787,20 @@ class QuestionAnswerScrollView extends StatelessWidget { }, { 'question': 'How do I log out of the app?', - 'question-ar':'كيف يمكنني تسجيل الخروج من التطبيق؟', + 'question-ar': 'كيف يمكنني تسجيل الخروج من التطبيق؟', 'answer': RichText( text: TextSpan( children: [ TextSpan( text: 'Go to the ', style: TextStyle( - color: Colors.grey, fontSize: 16, fontFamily: context.translate( - 'Roboto', - 'NotoKufi', - ),), + color: isDarkTheme ? Colors.white : Colors.grey, + fontSize: 16, + fontFamily: context.translate( + 'Roboto', + 'NotoKufi', + ), + ), ), TextSpan( text: 'Profile ', @@ -600,17 +809,20 @@ class QuestionAnswerScrollView extends StatelessWidget { 'Roboto', 'NotoKufi', ), - color: Color(0xFF414042), + color: isDarkTheme ? Colors.white : Color(0xFF414042), fontWeight: FontWeight.w500, fontSize: 16), ), TextSpan( text: 'section and tap the ', style: TextStyle( - color: Colors.grey, fontSize: 16, fontFamily: context.translate( - 'Roboto', - 'NotoKufi', - ),), + color: isDarkTheme ? Colors.white : Colors.grey, + fontSize: 16, + fontFamily: context.translate( + 'Roboto', + 'NotoKufi', + ), + ), ), TextSpan( text: 'Logout ', @@ -619,31 +831,38 @@ class QuestionAnswerScrollView extends StatelessWidget { 'Roboto', 'NotoKufi', ), - color: Color(0xFF414042), + color: isDarkTheme ? Colors.white : Color(0xFF414042), fontWeight: FontWeight.w500, fontSize: 16), ), TextSpan( text: 'option in the top-right corner.\n', style: TextStyle( - color: Colors.grey, fontSize: 16, fontFamily: context.translate( - 'Roboto', - 'NotoKufi', - ),), + color: isDarkTheme ? Colors.white70 : Colors.grey, + fontSize: 16, + fontFamily: context.translate( + 'Roboto', + 'NotoKufi', + ), + ), ) ], ), ), - 'answer-ar':RichText( + 'answer-ar': RichText( text: TextSpan( children: [ TextSpan( - text: 'انتقل إلى قسم "الملف الشخصي" واضغط على خيار "تسجيل الخروج" في الزاوية العلوية اليسرى.\n', + text: + 'انتقل إلى قسم "الملف الشخصي" واضغط على خيار "تسجيل الخروج" في الزاوية العلوية اليسرى.\n', style: TextStyle( - color: Colors.grey, fontSize: 16, fontFamily: context.translate( - 'Roboto', - 'NotoKufi', - ),), + color: isDarkTheme ? Colors.white70 : Colors.grey, + fontSize: 16, + fontFamily: context.translate( + 'Roboto', + 'NotoKufi', + ), + ), ) ], ), @@ -654,7 +873,12 @@ class QuestionAnswerScrollView extends StatelessWidget { return SingleChildScrollView( child: Column( children: questionsAndAnswers - .map((qa) => QuestionAnswerCard(qa: qa)) + .map( + (qa) => QuestionAnswerCard( + qa: qa, + isDarkTheme: isDarkTheme, + ), + ) .toList(), ), ); @@ -664,8 +888,10 @@ class QuestionAnswerScrollView extends StatelessWidget { class QuestionAnswerCard extends StatefulWidget { // Use dynamic to accommodate RichText - const QuestionAnswerCard({super.key, required this.qa}); + const QuestionAnswerCard( + {super.key, required this.qa, required this.isDarkTheme}); final Map qa; + final bool isDarkTheme; @override _QuestionAnswerCardState createState() => _QuestionAnswerCardState(); @@ -677,7 +903,8 @@ class _QuestionAnswerCardState extends State { @override Widget build(BuildContext context) { return Card( - color: Colors.white, + // color: Colors.white, + color: widget.isDarkTheme ? Colors.black : Colors.white, shape: Border( bottom: BorderSide(width: 0.5, color: Colors.grey.shade300), ), @@ -689,18 +916,23 @@ class _QuestionAnswerCardState extends State { children: [ ListTile( dense: true, - textColor: Color(0xFF414042), + textColor: widget.isDarkTheme ? Colors.white : Color(0xFF414042), title: Text( - context.translate(widget.qa['question'],widget.qa['question-ar'])!, - style: TextStyle(fontWeight: FontWeight.w500, fontSize: 16,fontFamily: context.translate( - 'Roboto', - 'NotoKufi', - ), + context.translate( + widget.qa['question'], widget.qa['question-ar'])!, + style: TextStyle( + fontWeight: FontWeight.w500, + fontSize: 16, + fontFamily: context.translate( + 'Roboto', + 'NotoKufi', + ), ), ), trailing: Icon(isExpanded ? Icons.keyboard_arrow_up : Icons.keyboard_arrow_down), + iconColor: widget.isDarkTheme ? Colors.white : Color(0xFF414042), onTap: () { setState(() { isExpanded = !isExpanded; @@ -711,17 +943,20 @@ class _QuestionAnswerCardState extends State { Padding( padding: const EdgeInsets.only( left: 16, right: 16, bottom: 16, top: 0), - child:widget.qa['answer'] is RichText - ? context.translate(widget.qa['answer'],widget.qa['answer-ar']) + child: widget.qa['answer'] is RichText + ? context.translate( + widget.qa['answer'], widget.qa['answer-ar']) : Text( - context.translate(widget.qa['answer'] ?? '',widget.qa['answer-ar']), + context.translate( + widget.qa['answer'] ?? '', widget.qa['answer-ar']), style: TextStyle( - color: Colors.grey, - fontSize: 16, + color: widget.isDarkTheme ? Colors.white : Colors.grey, + fontSize: 16, fontFamily: context.translate( 'Roboto', 'NotoKufi', - ),), + ), + ), ), ), ], diff --git a/lib/presentation/routes/drawer_routes/Drawer Items/user_guide/features.dart b/lib/presentation/routes/drawer_routes/Drawer Items/user_guide/features.dart index 8ff224af..dfbe6fac 100755 --- a/lib/presentation/routes/drawer_routes/Drawer Items/user_guide/features.dart +++ b/lib/presentation/routes/drawer_routes/Drawer Items/user_guide/features.dart @@ -1,32 +1,140 @@ +import 'dart:convert'; + import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:go_router/go_router.dart'; +import 'package:http/http.dart' as http; +import 'package:uae_stat/config/api_config.dart'; +import 'package:uae_stat/config/theme/theme_provider.dart'; +import 'package:uae_stat/config/toggle_lang_service.dart'; import 'package:uae_stat/domain/use_cases/language.dart'; +import 'package:uae_stat/presentation/Screens/Bottom%20Navigation%20Pages/Country_Profile/country_profile.dart'; import 'package:uae_stat/presentation/routes/drawer_routes/custom_drawer_routes.dart'; import 'package:uae_stat/infrastructure/services/img_asset_paths/banner_asset_path.dart'; -class UsingFeatures extends StatelessWidget { +class UsingFeatures extends ConsumerStatefulWidget { const UsingFeatures({super.key}); + @override + ConsumerState createState() => _UsingFeaturesState(); +} + +class _UsingFeaturesState extends ConsumerState { +// class UsingFeatures extends StatelessWidget { +// const UsingFeatures({super.key}); + List homePageData = []; + List filteredData = []; + + bool isLoading = true; + late UserService _userService; + late ThemeMode currentTheme; + + @override + void initState() { + super.initState(); + _userService = UserService(); + final locale = ref.read(localeProvider); + currentTheme = ref.read(themeProvider); + print('123456789'); + print(currentTheme); + WidgetsBinding.instance.addPostFrameCallback((_) { + final isDark = currentTheme == ThemeMode.dark || + (currentTheme == ThemeMode.system && + MediaQuery.of(context).platformBrightness == Brightness.dark); + + final themeMode = (isDark ? 'dark' : 'light'); + print("ThemeMode - $themeMode"); + fetchData(locale?.languageCode ?? 'en', themeMode); + }); + } + + Future fetchData(locale, themeMode) async { + const baseUrl = '$apiUrl/api/getUAENumbersData'; + try { + final response = await http + .get(Uri.parse(baseUrl + '?language=$locale&color_mode=$themeMode')); + if (response.statusCode == 200) { + setState(() { + homePageData = (json.decode(response.body) as List) + .map((e) => Map.from(e)) + .toList(); + filteredData = List.from(homePageData); + isLoading = false; + }); + } else { + throw Exception('Failed to load data'); + } + } catch (e) { + setState(() { + isLoading = false; + }); + print('Error fetching data: $e'); + } + } + @override Widget build(BuildContext context) { + ref.listen(localeProvider, (previous, next) async { + final localeCode = next?.languageCode ?? 'en'; + setState(() { + isLoading = true; + }); + await _userService.updateLanguage(localeCode); + final currentTheme = ref.read(themeProvider); + final isDark = currentTheme == ThemeMode.dark || + (currentTheme == ThemeMode.system && + MediaQuery.of(context).platformBrightness == Brightness.dark); + + final themeString = isDark ? 'dark' : 'light'; + fetchData(localeCode, themeString); + }); + + ref.listen(themeProvider, (previous, next) async { + final localeCode = ref.watch(localeProvider)?.languageCode ?? 'en'; + print(localeCode); + + // Default to 'en' if null + setState(() { + isLoading = true; + print('isLoadingref $isLoading'); + }); + + final currentTheme = ref.read(themeProvider); + final isDark = currentTheme == ThemeMode.dark || + (currentTheme == ThemeMode.system && + MediaQuery.of(context).platformBrightness == Brightness.dark); + + final themeString = isDark ? 'dark' : 'light'; + + print("themeString- $themeString"); + fetchData(localeCode, themeString); + }); + + final themeMode = ref.read(themeProvider); + final isDarkTheme = themeMode == ThemeMode.dark || + (themeMode == ThemeMode.system && + MediaQuery.of(context).platformBrightness == Brightness.dark); + + print("isDarkTheme - $isDarkTheme"); return BaseScaffold( showDivider: true, showBackButton: true, dividerColor: Colors.grey[300], bottomColor: Colors.white, - appbarColor: Colors.white, + backgroundColor: isDarkTheme ? Colors.black : Colors.white, + appbarColor: isDarkTheme ? Colors.black : Colors.white, + // appbarColor: Colors.white, mycenterTitle: true, title: Text( - context.translate('Key Features','الميزات الرئيسية'), + context.translate('Key Features', 'الميزات الرئيسية'), style: TextStyle( fontSize: 22, - fontFamily: context.translate( - 'Roboto', - 'NotoKufi', - ), + fontFamily: context.translate( + 'Roboto', + 'NotoKufi', + ), color: Color(0xFF7DAFBC), fontWeight: FontWeight.w500, // fontWeight: FontWeight.w500, @@ -34,7 +142,7 @@ class UsingFeatures extends StatelessWidget { ), body: Container( width: double.infinity, - color: Colors.white, + color: isDarkTheme ? Colors.black : Colors.white, child: Column( children: [ Container( @@ -49,12 +157,12 @@ class UsingFeatures extends StatelessWidget { onTap: () { context.push('/user-guide/features/appFeatures'); }, - tileColor: Colors.white, + tileColor: isDarkTheme ? Colors.grey : Colors.white, title: Text( - context.translate('App Features','الميزات الرئيسية '), + context.translate('App Features', 'الميزات الرئيسية '), style: TextStyle( fontSize: 16, - color: Color(0xFF414042), + color: isDarkTheme ? Colors.white : Color(0xFF414042), fontWeight: FontWeight.w500, fontFamily: context.translate( 'Roboto', @@ -62,7 +170,10 @@ class UsingFeatures extends StatelessWidget { ), ), ), - trailing: Icon(Icons.keyboard_arrow_right), + trailing: Icon( + Icons.keyboard_arrow_right, + color: isDarkTheme ? Colors.white : Color(0xFF414042), + ), ), ), Container( @@ -79,10 +190,11 @@ class UsingFeatures extends StatelessWidget { }, // tileColor: Colors.white, title: Text( - context.translate('Who can use The App?','يمكنه استخدام التطبيق?'), + context.translate( + 'Who can use The App?', 'يمكنه استخدام التطبيق?'), style: TextStyle( fontSize: 16, - color: Color(0xFF414042), + color: isDarkTheme ? Colors.white : Color(0xFF414042), fontWeight: FontWeight.w500, fontFamily: context.translate( 'Roboto', @@ -90,7 +202,10 @@ class UsingFeatures extends StatelessWidget { ), ), ), - trailing: Icon(Icons.keyboard_arrow_right), + trailing: Icon( + Icons.keyboard_arrow_right, + color: isDarkTheme ? Colors.white : Color(0xFF414042), + ), shape: Border( bottom: BorderSide( color: Colors.black, width: 3), // Grey bottom line @@ -111,10 +226,10 @@ class UsingFeatures extends StatelessWidget { }, // tileColor: Colors.white, title: Text( - context.translate('Purpose of the App','ض من التطبيق'), + context.translate('Purpose of the App', 'ض من التطبيق'), style: TextStyle( fontSize: 16, - color: Color(0xFF414042), + color: isDarkTheme ? Colors.white : Color(0xFF414042), fontWeight: FontWeight.w500, fontFamily: context.translate( 'Roboto', @@ -122,7 +237,10 @@ class UsingFeatures extends StatelessWidget { ), ), ), - trailing: Icon(Icons.keyboard_arrow_right), + trailing: Icon( + Icons.keyboard_arrow_right, + color: isDarkTheme ? Colors.white : Color(0xFF414042), + ), shape: Border( bottom: BorderSide( color: Colors.black, width: 3), // Grey bottom line @@ -143,10 +261,11 @@ class UsingFeatures extends StatelessWidget { }, // tileColor: Colors.white, title: Text( - context.translate('How to Use the App','كيفية استخدام التطبيق'), + context.translate( + 'How to Use the App', 'كيفية استخدام التطبيق'), style: TextStyle( fontSize: 16, - color: Color(0xFF414042), + color: isDarkTheme ? Colors.white : Color(0xFF414042), fontWeight: FontWeight.w500, fontFamily: context.translate( 'Roboto', @@ -154,7 +273,10 @@ class UsingFeatures extends StatelessWidget { ), ), ), - trailing: Icon(Icons.keyboard_arrow_right), + trailing: Icon( + Icons.keyboard_arrow_right, + color: isDarkTheme ? Colors.white : Color(0xFF414042), + ), shape: Border( bottom: BorderSide( color: Colors.black, width: 3), // Grey bottom line @@ -175,10 +297,10 @@ class UsingFeatures extends StatelessWidget { }, // tileColor: Colors.white, title: Text( - context.translate('Stay Updated','ابق على اطلاع'), + context.translate('Stay Updated', 'ابق على اطلاع'), style: TextStyle( fontSize: 16, - color: Color(0xFF414042), + color: isDarkTheme ? Colors.white : Color(0xFF414042), fontWeight: FontWeight.w500, fontFamily: context.translate( 'Roboto', @@ -186,7 +308,10 @@ class UsingFeatures extends StatelessWidget { ), ), ), - trailing: Icon(Icons.keyboard_arrow_right), + trailing: Icon( + Icons.keyboard_arrow_right, + color: isDarkTheme ? Colors.white : Color(0xFF414042), + ), shape: Border( bottom: BorderSide( color: Colors.black, width: 3), // Grey bottom line @@ -207,10 +332,11 @@ class UsingFeatures extends StatelessWidget { }, // tileColor: Colors.white, title: Text( - context.translate('How to Change My Password','كيفية تغيير كلمة المرور الخاصة بي'), + context.translate('How to Change My Password', + 'كيفية تغيير كلمة المرور الخاصة بي'), style: TextStyle( fontSize: 16, - color: Color(0xFF414042), + color: isDarkTheme ? Colors.white : Color(0xFF414042), fontWeight: FontWeight.w500, fontFamily: context.translate( 'Roboto', @@ -218,7 +344,10 @@ class UsingFeatures extends StatelessWidget { ), ), ), - trailing: Icon(Icons.keyboard_arrow_right), + trailing: Icon( + Icons.keyboard_arrow_right, + color: isDarkTheme ? Colors.white : Color(0xFF414042), + ), shape: Border( bottom: BorderSide( color: Colors.black, width: 3), // Grey bottom line @@ -239,10 +368,11 @@ class UsingFeatures extends StatelessWidget { }, // tileColor: Colors.white, title: Text( - context.translate('How to Edit My Profile','كيفية تعديل ملفي الشخصي'), + context.translate( + 'How to Edit My Profile', 'كيفية تعديل ملفي الشخصي'), style: TextStyle( fontSize: 16, - color: Color(0xFF414042), + color: isDarkTheme ? Colors.white : Color(0xFF414042), fontWeight: FontWeight.w500, fontFamily: context.translate( 'Roboto', @@ -250,7 +380,10 @@ class UsingFeatures extends StatelessWidget { ), ), ), - trailing: Icon(Icons.keyboard_arrow_right), + trailing: Icon( + Icons.keyboard_arrow_right, + color: isDarkTheme ? Colors.white : Color(0xFF414042), + ), shape: Border( bottom: BorderSide( color: Colors.black, width: 3), // Grey bottom line diff --git a/lib/presentation/routes/drawer_routes/Drawer Items/user_guide/userguide.dart b/lib/presentation/routes/drawer_routes/Drawer Items/user_guide/userguide.dart index 5182e108..d9554040 100755 --- a/lib/presentation/routes/drawer_routes/Drawer Items/user_guide/userguide.dart +++ b/lib/presentation/routes/drawer_routes/Drawer Items/user_guide/userguide.dart @@ -1,25 +1,59 @@ import 'package:flutter/material.dart'; +import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:go_router/go_router.dart'; +import 'package:uae_stat/config/theme/theme_provider.dart'; +import 'package:uae_stat/config/toggle_lang_service.dart'; import 'package:uae_stat/domain/use_cases/language.dart'; +import 'package:uae_stat/presentation/components/indicators/locale_provider.dart'; +// import 'package:uae_stat/presentation/Screens/Bottom%20Navigation%20Pages/Country_Profile/country_profile.dart'; import 'package:uae_stat/presentation/routes/drawer_routes/custom_drawer_routes.dart'; import 'package:iconify_design/iconify_design.dart'; import 'package:flutter_gen/gen_l10n/app_localizations.dart'; +// import 'package:uae_stat/l10n/app_localizations.dart'; - -class Userguide extends StatefulWidget { +class Userguide extends ConsumerStatefulWidget { Userguide({super.key}); @override - State createState() => _UserguideState(); + // _UserguideState createState() => _UserguideState(); + ConsumerState createState() => _UserguideState(); } -class _UserguideState extends State { +class _UserguideState extends ConsumerState { + late bool isDarkTheme; + final List> guideList = [ - {'routePath':'aboutApp','color': Color(0xFF90B0D5), 'text': 'Getting Started', 'icon': 'cbi:start-tv', 'text-ar': 'البدء' }, - {'routePath':'features','color': Color(0xFFAA8E83), 'text': 'Features', 'icon': 'pajamas:issue-type-feature', 'text-ar' : 'الميزات'}, - {'routePath':'faq','color': Color(0xFF7296BE), 'text': 'FAQs', 'icon': 'mdi:faq', 'text-ar': 'لأسئلة الشائعة'}, + { + 'routePath': 'aboutApp', + 'color': Color(0xFF90B0D5), + 'text': 'Getting Started', + 'icon': 'cbi:start-tv', + 'text-ar': 'البدء' + }, + { + 'routePath': 'features', + 'color': Color(0xFFAA8E83), + 'text': 'Features', + 'icon': 'pajamas:issue-type-feature', + 'text-ar': 'الميزات' + }, + { + 'routePath': 'faq', + 'color': Color(0xFF7296BE), + 'text': 'FAQs', + 'icon': 'mdi:faq', + 'text-ar': 'لأسئلة الشائعة' + }, ]; + late ThemeMode currentTheme; + @override + initState() { + super.initState(); + print('123456789'); + + } + @override Widget buildDynamicWidget(dynamic icons, Color color) { if (icons is IconData) { @@ -46,15 +80,23 @@ class _UserguideState extends State { } else { return Text( 'Unsupported type', - style: TextStyle(color: Colors.red,fontFamily: context.translate( - 'Roboto', - 'NotoKufi', - ),), + style: TextStyle( + color: Colors.red, + fontFamily: context.translate( + 'Roboto', + 'NotoKufi', + ), + ), ); } } Widget build(BuildContext context) { + final currentTheme = ref.watch(themeProvider); + isDarkTheme = currentTheme == ThemeMode.dark || + (currentTheme == ThemeMode.system && + MediaQuery.of(context).platformBrightness == Brightness.dark); + return PopScope( canPop: false, onPopInvokedWithResult: (didPop, result) { @@ -63,13 +105,13 @@ class _UserguideState extends State { }, child: BaseScaffold( showDivider: true, - bottomColor: Colors.white, - dividerColor: Colors.grey[300], - appbarColor: Colors.white, - title: Text(AppLocalizations.of(context)!.guide_title) , - body: Container( - color: Colors.white, - padding: const EdgeInsets.symmetric(horizontal: 16 , vertical: 20), + bottomColor: isDarkTheme ? Color(0xFF111111) : Colors.white, + dividerColor: isDarkTheme ? Color(0xFF111111) : Colors.grey[300], + appbarColor: isDarkTheme ? Color(0xFF111111) : Colors.white, + title: Text(AppLocalizations.of(context)!.guide_title,style: TextStyle(color: isDarkTheme ? Colors.white : Color(0xFF414042) ),), + body: Container( + color: isDarkTheme ? Color(0xFF111111) : Colors.white, + padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 20), child: GridView.builder( gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( crossAxisCount: 2, @@ -82,7 +124,8 @@ class _UserguideState extends State { itemBuilder: (context, index) { return HoverContainer( iconName: guideList[index]['icon'], - title: context.translate(guideList[index]['text'], guideList[index]['text-ar']), + title: context.translate( + guideList[index]['text'], guideList[index]['text-ar']), routePath: guideList[index]['routePath'], ); }, @@ -91,83 +134,92 @@ class _UserguideState extends State { ), ); } - } - -class HoverContainer extends StatefulWidget { +class HoverContainer extends ConsumerStatefulWidget { final String iconName; final String title; final String routePath; - - const HoverContainer({Key? key, required this.iconName, required this.title, required this.routePath}) : super(key: key); + const HoverContainer( + {Key? key, + required this.iconName, + required this.title, + required this.routePath}) + : super(key: key); @override - _HoverContainerState createState() => _HoverContainerState(); + ConsumerState createState() => _HoverContainerState(); } -class _HoverContainerState extends State { +class _HoverContainerState extends ConsumerState { bool isHovered = true; @override Widget build(BuildContext context) { - final double screenWidth= MediaQuery.of(context).size.width; - final double screenHeight= MediaQuery.of(context).size.height; + final double screenWidth = MediaQuery.of(context).size.width; + final double screenHeight = MediaQuery.of(context).size.height; + final currentTheme = ref.read(themeProvider); + final isDarkTheme = currentTheme == ThemeMode.dark || + (currentTheme == ThemeMode.system && + MediaQuery.of(context).platformBrightness == Brightness.dark); + return GestureDetector( - onTap: () { context.push('/user-guide/${widget.routePath}');}, - child: MouseRegion( + onTap: () { + context.push('/user-guide/${widget.routePath}'); + }, + child: MouseRegion( onEnter: (_) => setState(() => isHovered = true), onExit: (_) => setState(() => isHovered = true), - child : Container( + child: Container( padding: EdgeInsets.only(top: 4, right: 4, left: 4, bottom: 6), - - width: screenWidth*0.30, + width: screenWidth * 0.30, margin: EdgeInsets.all(1), decoration: BoxDecoration( - color: Colors.white, + color: isDarkTheme ? Color(0xFF111111) : Colors.white, borderRadius: BorderRadius.circular(10), boxShadow: isHovered ? [ - BoxShadow( - color: Colors.black.withOpacity(0.2), - blurRadius:2, - spreadRadius: 1, - offset: Offset(0, 4), - ), - ] + BoxShadow( + color: Colors.black.withOpacity(0.2), + blurRadius: 2, + spreadRadius: 1, + offset: Offset(0, 4), + ), + ] : [], - border: Border.all( - color: Color(0xFF7DAFBC), - width: 1.0 - ), + border: Border.all(color: Color(0xFF7DAFBC), width: 1.0), ), alignment: Alignment.center, // duration: Duration(milliseconds: 200), - child: LayoutBuilder(builder: (context, constraints){ + child: LayoutBuilder(builder: (context, constraints) { double containerWidth = constraints.maxWidth; double containerHeight = constraints.maxHeight; - return Column( + return Column( mainAxisAlignment: MainAxisAlignment.center, children: [ - IconifyIcon(icon: widget.iconName, - color: Color((0xFF7DAFBC)), - size: containerHeight * 0.45,), + IconifyIcon( + icon: widget.iconName, + color: Color(0xFF7DAFBC), + size: containerHeight * 0.45, + ), // buildDynamicWidget(data['icon'], Color(0xFF7DAFBC)), - SizedBox(width: 10,height: containerHeight * 0.04,), // Space between icon and text + SizedBox( + width: 10, + height: containerHeight * 0.04, + ), // Space between icon and text Container( - width: containerWidth* 0.85, + width: containerWidth * 0.85, padding: EdgeInsets.symmetric(horizontal: 4, vertical: 4), margin: EdgeInsets.only(bottom: 3), decoration: BoxDecoration( color: Color(0xFF7DAFBC), borderRadius: BorderRadius.circular(5), - border: Border.all(color: Color(0xFF7DAFBC)) - ), + border: Border.all(color: Color(0xFF7DAFBC))), child: Text( widget.title, style: TextStyle( - color: Colors.white, // Text color + color: Colors.white, // Text color fontWeight: FontWeight.bold, fontFamily: context.translate( 'Roboto', @@ -179,16 +231,8 @@ class _HoverContainerState extends State { ), ], ); - }) - - - ), + })), ), - - - ); - - } -} \ No newline at end of file +} diff --git a/lib/presentation/routes/drawer_routes/custom_drawer_routes.dart b/lib/presentation/routes/drawer_routes/custom_drawer_routes.dart index d3837612..cb4292a1 100644 --- a/lib/presentation/routes/drawer_routes/custom_drawer_routes.dart +++ b/lib/presentation/routes/drawer_routes/custom_drawer_routes.dart @@ -45,10 +45,10 @@ class BaseScaffold extends ConsumerStatefulWidget { this.showBackButton = false, this.colorChange = false, this.mycenterTitle = false, - this.appbarColor, + this.appbarColor = Colors.white, this.mytitleColor, this.bottomColor = null, - this.backgroundColor, + this.backgroundColor = Colors.white, }); final Widget body; final Widget title; @@ -133,7 +133,7 @@ class _BaseScaffoldState extends ConsumerState { void _calculatetooglePosition() { final RenderBox cardRenderBox = - toggleKey.currentContext!.findRenderObject() as RenderBox; + toggleKey.currentContext!.findRenderObject() as RenderBox; final Offset cardPosition = cardRenderBox.localToGlobal(Offset.zero); final Size cardSize = cardRenderBox.size; toggleHeight = cardSize.height; @@ -257,7 +257,7 @@ class _BaseScaffoldState extends ConsumerState { .state = true; ref .read(previousChartsTourProvider - .notifier) + .notifier) .state = false; context.go( '/chartScreen/marriages?bgColor=0xFFAA8E83&mainTopic=null&title=Marriages', @@ -290,7 +290,7 @@ class _BaseScaffoldState extends ConsumerState { .state = true; ref .read(previousChartsTourProvider - .notifier) + .notifier) .state = false; context.go( '/chartScreen/marriages?bgColor=0xFFAA8E83&mainTopic=اجتماعي&title=الزواج&key=home', @@ -579,8 +579,10 @@ class _BaseScaffoldState extends ConsumerState { const SizedBox(width: 10), ElevatedButton( onPressed: () async { - final prefs = await SharedPreferences.getInstance(); - String? loginCount = prefs.getString('login_count'); + final prefs = + await SharedPreferences.getInstance(); + String? loginCount = + prefs.getString('login_count'); if (loginCount == '1') { await prefs.setString('login_count', '2'); } @@ -590,10 +592,10 @@ class _BaseScaffoldState extends ConsumerState { .state = true; ref .read( - previousChartsTourProvider.notifier) + previousChartsTourProvider.notifier) .state = true; ref.read(homeTourProvider.notifier).state = - true; + true; ref .read(previousHomeTourProvider.notifier) .state = true; @@ -602,7 +604,7 @@ class _BaseScaffoldState extends ConsumerState { .state = true; ref .read(previousScaffoldTourProvider - .notifier) + .notifier) .state = true; tutorialCoachMark.finish(); }, @@ -714,7 +716,8 @@ class _BaseScaffoldState extends ConsumerState { String recordId = userId; String collectionId = userDetailsResponse.data['collectionId'] ?? '_pb_users_auth_'; - List userReadedNotification = userDetailsResponse.data['pushed_notification']; + List userReadedNotification = + userDetailsResponse.data['pushed_notification']; // Convert to List userReadedNotiOrNot = List.from(userReadedNotification); @@ -755,7 +758,7 @@ class _BaseScaffoldState extends ConsumerState { print('notifications $notifications'); // isLoading = false; }); - _processNotifications(notifications , userReadedNotiOrNot); + _processNotifications(notifications, userReadedNotiOrNot); } else { throw Exception('Failed to load data'); } @@ -768,7 +771,8 @@ class _BaseScaffoldState extends ConsumerState { } } - void _processNotifications(List> notification, List push) { + void _processNotifications( + List> notification, List push) { print('inside last function ${notification.length}'); print('inside last function ${push.length}'); @@ -802,7 +806,6 @@ class _BaseScaffoldState extends ConsumerState { ); } - // Future logout() async { // final prefs = await SharedPreferences.getInstance(); // // setState(() { @@ -819,13 +822,13 @@ class _BaseScaffoldState extends ConsumerState { final PAuthRepo _authRepo = PAuthRepo(); void _routeToIndex() { - String url=GoRouterState.of(context).uri.toString(); + String url = GoRouterState.of(context).uri.toString(); final uri = Uri.parse(url); final fromValue = uri.queryParameters['key'] ?? ''; - if (fromValue=='home'){ - ref.read(selectedIndexProvider.notifier).state= 0; - }else if (fromValue=='uaenumbers'){ - ref.read(selectedIndexProvider.notifier).state= 1; + if (fromValue == 'home') { + ref.read(selectedIndexProvider.notifier).state = 0; + } else if (fromValue == 'uaenumbers') { + ref.read(selectedIndexProvider.notifier).state = 1; } } @@ -836,7 +839,6 @@ class _BaseScaffoldState extends ConsumerState { context.go('/login'); // Redirect to login after logout } - // void _showThemeDialog(BuildContext context) async { // AppTheme? result = await showDialog( // context: context, @@ -905,7 +907,8 @@ class _BaseScaffoldState extends ConsumerState { // } // } - void _openThemeDialog(BuildContext context, WidgetRef ref, String userId) async { + void _openThemeDialog( + BuildContext context, WidgetRef ref, String userId) async { final currentThemeMode = ref.read(themeProvider); // ThemeMode final platformBrightness = MediaQuery.of(context).platformBrightness; @@ -926,7 +929,9 @@ class _BaseScaffoldState extends ConsumerState { if (selectedTheme != null) { // Update UI immediately - ref.read(themeProvider.notifier).updateTheme(selectedTheme, platformBrightness); + ref + .read(themeProvider.notifier) + .updateTheme(selectedTheme, platformBrightness); // Send only 'light' or 'dark' to PocketBase final themeToSend = selectedTheme == AppTheme.system @@ -937,10 +942,6 @@ class _BaseScaffoldState extends ConsumerState { } } - - - - @override Widget build(BuildContext context) { final locale = ref.watch(localeProvider); @@ -956,7 +957,8 @@ class _BaseScaffoldState extends ConsumerState { final String currentRoute1 = ModalRoute.of(context)?.settings.name ?? ''; return Scaffold( - backgroundColor: Colors.white, + backgroundColor: widget.backgroundColor, + // backgroundColor: Colors.white, appBar: AppBar( title: Padding( padding: EdgeInsets.only(top: 10), @@ -980,32 +982,37 @@ class _BaseScaffoldState extends ConsumerState { ), scrolledUnderElevation: 0, titleSpacing: 0, - flexibleSpace: (isDarkTheme && currentRoute == '/myhomepage') - ? Container( - decoration: const BoxDecoration( - image: DecorationImage( - image: AssetImage('assets/dark_bg.png'), - fit: BoxFit.cover, - ), + flexibleSpace: Container( + decoration: BoxDecoration( + color: isDarkTheme ? Color(0xFF000000) : Color(0xFFFFFFFF), ), - ) - : (isDarkTheme && currentRoute == '/uaenumbers') - ? Container( - decoration: const BoxDecoration( - color: Color(0xFF333333), - ), - ) - : null, + ), + // flexibleSpace: (isDarkTheme && currentRoute == '/myhomepage') + // ? Container( + // decoration: const BoxDecoration( + // image: DecorationImage( + // image: AssetImage('assets/dark_bg.png'), + // fit: BoxFit.cover, + // ), + // ), + // ) + // : (isDarkTheme && currentRoute == '/uaenumbers') + // ? Container( + // decoration: const BoxDecoration( + // color: Color(0xFF333333), + // ), + // ) + // : null, backgroundColor: widget.appbarColor ?? Colors.white, - leadingWidth: widget.showBackButton ? mywidth * 0.18 : null, + leadingWidth: widget.showBackButton ? mywidth * 0.18 : null, bottom: widget.showDivider ? PreferredSize( - preferredSize: Size.fromHeight(1), // Height of the line - child: Container( - color: widget.dividerColor, // Line color - height: 1, // Line thickness - ), - ) + preferredSize: Size.fromHeight(1), // Height of the line + child: Container( + color: widget.dividerColor, // Line color + height: 1, // Line thickness + ), + ) : null, // bottom: widget.showDivider @@ -1048,7 +1055,15 @@ class _BaseScaffoldState extends ConsumerState { child: IconButton( padding: EdgeInsets.zero, constraints: BoxConstraints(), - color: widget.colorChange ? Colors.white : Colors.black, + // color: widget.colorChange ? Colors.white : Colors.black, + color: isDarkTheme + ? widget.colorChange + ? Colors.black + : Colors.white + : widget.colorChange + ? Colors.white + : Colors.black, + icon: const Icon(Icons.arrow_back_ios_new, size: 24), onPressed: () { if (widget.navBackArrow is Text && @@ -1087,7 +1102,7 @@ class _BaseScaffoldState extends ConsumerState { ), ), drawer: Drawer( - backgroundColor: isDarkTheme ? Color(0xFF111111) : Colors.white, + backgroundColor: isDarkTheme ? Color(0xFF111111) : Colors.white, child: Column(children: [ Expanded( child: ListView( @@ -1120,19 +1135,19 @@ class _BaseScaffoldState extends ConsumerState { child: ClipOval( child: _avatarUrl.isNotEmpty ? Image( - image: NetworkImage(_avatarUrl), - fit: BoxFit.cover, - width: double.infinity, - height: double.infinity, - ) + image: NetworkImage(_avatarUrl), + fit: BoxFit.cover, + width: double.infinity, + height: double.infinity, + ) : Image( - image: AssetImage( - 'assets/edit_profile/profile.jpg', - ), - fit: BoxFit.cover, - width: double.infinity, - height: double.infinity, - ), + image: AssetImage( + 'assets/edit_profile/profile.jpg', + ), + fit: BoxFit.cover, + width: double.infinity, + height: double.infinity, + ), ), //child: Image(image: AssetImage('assets/edit_profile/profile.png')) ), @@ -1167,31 +1182,43 @@ class _BaseScaffoldState extends ConsumerState { crossAxisAlignment: CrossAxisAlignment.start, children: [ if (userId == "guest") ...[ - Text(userName ?? 'Guest User', - style: TextStyle( - color: isDarkTheme ? Color(0xFFAAAAAA) : null, - ),), + Text( + userName ?? 'Guest User', + style: TextStyle( + color: isDarkTheme + ? Color(0xFFAAAAAA) + : null, + ), + ), ] else ...[ - Text(userName ?? 'Loading...', - style: TextStyle( - color: isDarkTheme ? Color(0xFFAAAAAA) : null, - ),), + Text( + userName ?? 'Loading...', + style: TextStyle( + color: isDarkTheme + ? Color(0xFFAAAAAA) + : null, + ), + ), Tooltip( message: userEmail ?? 'Loading...', // Shows full email on hover child: SizedBox( width: MediaQuery.of(context) - .size - .width * + .size + .width * 0.6, // Adjust width as needed child: Text( userEmail ?? 'Loading...', - style: TextStyle(fontSize: 12, -color: isDarkTheme ? Color(0xFFAAAAAA) : null, - fontFamily: context.translate( - 'Roboto', - 'NotoKufi', - ),), + style: TextStyle( + fontSize: 12, + color: isDarkTheme + ? Color(0xFFAAAAAA) + : null, + fontFamily: context.translate( + 'Roboto', + 'NotoKufi', + ), + ), // softWrap: true, overflow: TextOverflow.ellipsis, maxLines: 1, @@ -1210,20 +1237,25 @@ color: isDarkTheme ? Color(0xFFAAAAAA) : null, ), if (userId != 'guest') ListTile( - leading: Icon(Icons.notifications_none,color: isDarkTheme ? Color(0xFFFFFFFF) : null), - title: Text(AppLocalizations.of(context)!.notification, + leading: Icon(Icons.notifications_none, + color: isDarkTheme ? Color(0xFFFFFFFF) : null), + title: Text( + AppLocalizations.of(context)!.notification, style: TextStyle( color: isDarkTheme ? Color(0xFFAAAAAA) : null, fontFamily: context.translate( 'Roboto', 'NotoKufi', - ), ), + ), + ), ), - trailing: _buildNotificationBadge(count: notificationCount), + trailing: + _buildNotificationBadge(count: notificationCount), onTap: () => _navigateTo(context, '/notification'), ), ListTile( - leading: Icon(Icons.message_outlined,color: isDarkTheme ? Color(0xFFFFFFFF) : null), + leading: Icon(Icons.message_outlined, + color: isDarkTheme ? Color(0xFFFFFFFF) : null), // leading: Image.asset( // DrawerAssetIconPath.feedback, // color: Colors.black, @@ -1231,19 +1263,23 @@ color: isDarkTheme ? Color(0xFFAAAAAA) : null, // height: 20, // ), // title: const Text('Feedback'), - title: Text(AppLocalizations.of(context)!.feedback_title, + title: Text( + AppLocalizations.of(context)!.feedback_title, style: TextStyle( color: isDarkTheme ? Color(0xFFAAAAAA) : null, fontFamily: context.translate( 'Roboto', 'NotoKufi', - ), ),), + ), + ), + ), onTap: () => _navigateTo(context, '/feedback', extra: userName), ), if (role == 'admin') ListTile( - leading: Icon(Icons.manage_accounts_outlined,color: isDarkTheme ? Color(0xFFFFFFFF) : null), + leading: Icon(Icons.manage_accounts_outlined, + color: isDarkTheme ? Color(0xFFFFFFFF) : null), // leading: Image.asset( // DrawerAssetIconPath.manageUser, // color: Colors.black, @@ -1258,12 +1294,14 @@ color: isDarkTheme ? Color(0xFFAAAAAA) : null, fontFamily: context.translate( 'Roboto', 'NotoKufi', - ), ), + ), + ), ), onTap: () => _navigateTo(context, '/manageuser'), ), ListTile( - leading: Icon(Icons.bookmarks_outlined,color: isDarkTheme ? Color(0xFFFFFFFF) : null), + leading: Icon(Icons.bookmarks_outlined, + color: isDarkTheme ? Color(0xFFFFFFFF) : null), // title: const Text('Bookmark'), title: Text( AppLocalizations.of(context)!.bookmark_title, @@ -1272,12 +1310,14 @@ color: isDarkTheme ? Color(0xFFAAAAAA) : null, fontFamily: context.translate( 'Roboto', 'NotoKufi', - ), ), + ), + ), ), onTap: () => _navigateTo(context, '/bookmark'), ), ListTile( - leading: Icon(Icons.menu_book_outlined,color: isDarkTheme ? Color(0xFFFFFFFF) : null), + leading: Icon(Icons.menu_book_outlined, + color: isDarkTheme ? Color(0xFFFFFFFF) : null), // leading: Image.asset( // DrawerAssetIconPath.guide, // color: Colors.black, @@ -1285,80 +1325,100 @@ color: isDarkTheme ? Color(0xFFAAAAAA) : null, // height: 20, // ), // title: const Text('User Guide'), - title: Text(AppLocalizations.of(context)!.guide_title, + title: Text( + AppLocalizations.of(context)!.guide_title, style: TextStyle( color: isDarkTheme ? Color(0xFFAAAAAA) : null, fontFamily: context.translate( 'Roboto', 'NotoKufi', - ), ), + ), + ), ), onTap: () => _navigateTo(context, '/user-guide'), ), ListTile( - leading: Icon(Icons.mail_outlined,color: isDarkTheme ? Color(0xFFFFFFFF) : null), - title: Text(context.translate('Contact Us', 'اتصل بنا'), + leading: Icon(Icons.mail_outlined, + color: isDarkTheme ? Color(0xFFFFFFFF) : null), + title: Text( + context.translate('Contact Us', 'اتصل بنا'), style: TextStyle( color: isDarkTheme ? Color(0xFFAAAAAA) : null, fontFamily: context.translate( 'Roboto', 'NotoKufi', - ), ),), + ), + ), + ), onTap: () => context.go('/contact'), ), + ListTile( + leading: Icon(Icons.lightbulb_circle_outlined, + color: isDarkTheme ? Color(0xFFFFFFFF) : null), + title: Text( + context.translate('Theme', 'سمة'), + style: TextStyle( + color: isDarkTheme ? Color(0xFFAAAAAA) : null, + fontFamily: context.translate( + 'Roboto', + 'NotoKufi', + ), + ), + ), + onTap: () => _openThemeDialog(context, ref, userId), + ), if (userId != 'guest') ListTile( - leading: Icon(Icons.logout,color: isDarkTheme ? Color(0xFFFFFFFF) : null), + leading: Icon(Icons.logout, + color: isDarkTheme ? Color(0xFFFFFFFF) : null), // title: const Text('Logout'), - title: Text(AppLocalizations.of(context)!.logout, + title: Text( + AppLocalizations.of(context)!.logout, style: TextStyle( color: isDarkTheme ? Color(0xFFAAAAAA) : null, fontFamily: context.translate( 'Roboto', 'NotoKufi', - ), ), + ), + ), ), onTap: () => _showLogoutConfirmationDialog(context), ), if (userId == 'guest') ListTile( - leading: Icon(Icons.login,color: isDarkTheme ? Color(0xFFFFFFFF) : null), + leading: Icon(Icons.login, + color: isDarkTheme ? Color(0xFFFFFFFF) : null), // title: const Text('Login'), - title: Text(AppLocalizations.of(context)!.login_title, + title: Text( + AppLocalizations.of(context)!.login_title, style: TextStyle( color: isDarkTheme ? Color(0xFFAAAAAA) : null, fontFamily: context.translate( 'Roboto', 'NotoKufi', - ), ), + ), + ), ), onTap: () => context.go('/login'), ), if (userId == 'guest') ListTile( - leading: Icon(Icons.app_registration,color: isDarkTheme ? Color(0xFFFFFFFF) : null), + leading: Icon(Icons.app_registration, + color: isDarkTheme ? Color(0xFFFFFFFF) : null), // title: const Text('Register'), - title: Text(AppLocalizations.of(context)!.register_title, + title: Text( + AppLocalizations.of(context)!.register_title, style: TextStyle( color: isDarkTheme ? Color(0xFFAAAAAA) : null, fontFamily: context.translate( 'Roboto', 'NotoKufi', - ), ), + ), + ), ), onTap: () => context.go('/register'), ), - ListTile( - leading: Icon(Icons.lightbulb_circle_outlined,color: isDarkTheme ? Color(0xFFFFFFFF) : null), - title: Text(context.translate('Theme','سمة'), - style: TextStyle( - color: isDarkTheme ? Color(0xFFAAAAAA) : null, - fontFamily: context.translate( - 'Roboto', - 'NotoKufi', - ), ),), - onTap: () => _openThemeDialog(context, ref, userId), - ), + ], ), ), @@ -1370,28 +1430,40 @@ color: isDarkTheme ? Color(0xFFAAAAAA) : null, if (snapshot.connectionState == ConnectionState.waiting) { return Text( 'Loading version...', - style: TextStyle(fontSize: 12, color: isDarkTheme ? Color(0xFFAAAAAA) : Colors.grey,fontFamily: context.translate( - 'Roboto', - 'NotoKufi', - ),), + style: TextStyle( + fontSize: 12, + color: isDarkTheme ? Color(0xFFAAAAAA) : Colors.grey, + fontFamily: context.translate( + 'Roboto', + 'NotoKufi', + ), + ), textAlign: TextAlign.center, ); } else if (snapshot.hasError) { return Text( 'Error fetching version', - style: TextStyle(fontSize: 12, color: Colors.red,fontFamily: context.translate( - 'Roboto', - 'NotoKufi', - ),), + style: TextStyle( + fontSize: 12, + color: Colors.red, + fontFamily: context.translate( + 'Roboto', + 'NotoKufi', + ), + ), textAlign: TextAlign.center, ); } else { return Text( 'Version ${snapshot.data}', - style: TextStyle(fontSize: 12, color: isDarkTheme ? Color(0xFFAAAAAA) : Colors.grey,fontFamily: context.translate( - 'Roboto', - 'NotoKufi', - ),), + style: TextStyle( + fontSize: 12, + color: isDarkTheme ? Color(0xFFAAAAAA) : Colors.grey, + fontFamily: context.translate( + 'Roboto', + 'NotoKufi', + ), + ), textAlign: TextAlign.center, ); } @@ -1410,104 +1482,104 @@ color: isDarkTheme ? Color(0xFFAAAAAA) : null, height: kBottomNavigationBarHeight + 0, // Adjust as needed decoration: BoxDecoration( image: DecorationImage( - image: AssetImage('assets/dark_bg.png'), // your dark mode image + image: AssetImage( + 'assets/dark_bg.png'), // your dark mode image fit: BoxFit.cover, ), ), ), ), BottomNavigationBar( - backgroundColor: isDarkTheme ? Color(0xFF000000) : Colors.white, - currentIndex: _getSelectedIndex(currentRoute), - onTap: (index) => _onItemTapped(context, index), - type: BottomNavigationBarType.fixed, - items: [ - BottomNavigationBarItem( - icon: Padding( - padding: - const EdgeInsets.only(bottom: 4), // Adjust this for spacing - child: Image.asset( - BottomBarAssetIconPath.home, - color: _getSelectedIndex(currentRoute) == 0 - ? (isDarkTheme ? Color(0xFF24B4FB) : Colors.black) - : Color(0xFF989898), - width: 23.98, - height: 25, - ), + backgroundColor: isDarkTheme ? Color(0xFF000000) : Colors.white, + currentIndex: _getSelectedIndex(currentRoute), + onTap: (index) => _onItemTapped(context, index), + type: BottomNavigationBarType.fixed, + items: [ + BottomNavigationBarItem( + icon: Padding( + padding: const EdgeInsets.only( + bottom: 4), // Adjust this for spacing + child: Image.asset( + BottomBarAssetIconPath.home, + color: _getSelectedIndex(currentRoute) == 0 + ? (isDarkTheme ? Color(0xFF24B4FB) : Colors.black) + : Color(0xFF989898), + width: 23.98, + height: 25, ), - // label: 'Home', - label: AppLocalizations.of(context)!.nav_home, ), - BottomNavigationBarItem( - // icon: Icon(Icons.map), - icon: Padding( - padding: - const EdgeInsets.only(bottom: 4), // Adjust this for spacing - child: Image.asset( - BottomBarAssetIconPath.uaeMap, - color: _getSelectedIndex(currentRoute) == 1 - ? (isDarkTheme ? Color(0xFF24B4FB) : Colors.black) - : Color(0xFF989898), - width: 23.98, - height: 25, - ), - ), - // label: 'UAE Numbers' - label: AppLocalizations.of(context)!.nav_uae, - ), - BottomNavigationBarItem( - icon: Padding( - padding: - const EdgeInsets.only(bottom: 4), // Adjust this for spacing - child: Image.asset( - BottomBarAssetIconPath.ranking, - color: _getSelectedIndex(currentRoute) == 2 - ? (isDarkTheme ? Color(0xFF24B4FB) : Colors.black) - : Color(0xFF989898), - width: 23.98, - height: 25, - ), - ), - // label: 'Competitiveness', - label: AppLocalizations.of(context)!.nav_competitiveness, - ), - BottomNavigationBarItem( - icon: Padding( - padding: - const EdgeInsets.only(bottom: 4), // Adjust this for spacing - child: Image.asset( - BottomBarAssetIconPath.globe, - color: _getSelectedIndex(currentRoute) == 3 - ? (isDarkTheme ? Color(0xFF24B4FB) : Colors.black) - : Color(0xFF989898), - width: 23.98, - height: 25, - ), - ), - // label: 'Country Profile', - label: AppLocalizations.of(context)!.country_profile, - ), - ], - key: bottomNavKey, - selectedItemColor: isDarkTheme ? Color(0xFF24B4FB) : Colors.black, - unselectedItemColor: Colors.grey, - selectedLabelStyle: TextStyle( - fontFamily: context.translate( - 'Roboto', - 'NotoKufi', - ), - fontSize: 10, // Font size for unselected label + // label: 'Home', + label: AppLocalizations.of(context)!.nav_home, ), - unselectedLabelStyle: TextStyle( - fontFamily: context.translate( - 'Roboto', - 'NotoKufi', + BottomNavigationBarItem( + // icon: Icon(Icons.map), + icon: Padding( + padding: const EdgeInsets.only( + bottom: 4), // Adjust this for spacing + child: Image.asset( + BottomBarAssetIconPath.uaeMap, + color: _getSelectedIndex(currentRoute) == 1 + ? (isDarkTheme ? Color(0xFF24B4FB) : Colors.black) + : Color(0xFF989898), + width: 23.98, + height: 25, + ), ), - fontSize: 10, // Font size for unselected label + // label: 'UAE Numbers' + label: AppLocalizations.of(context)!.nav_uae, ), - showUnselectedLabels: true, + BottomNavigationBarItem( + icon: Padding( + padding: const EdgeInsets.only( + bottom: 4), // Adjust this for spacing + child: Image.asset( + BottomBarAssetIconPath.ranking, + color: _getSelectedIndex(currentRoute) == 2 + ? (isDarkTheme ? Color(0xFF24B4FB) : Colors.black) + : Color(0xFF989898), + width: 23.98, + height: 25, + ), + ), + // label: 'Competitiveness', + label: AppLocalizations.of(context)!.nav_competitiveness, + ), + BottomNavigationBarItem( + icon: Padding( + padding: const EdgeInsets.only( + bottom: 4), // Adjust this for spacing + child: Image.asset( + BottomBarAssetIconPath.globe, + color: _getSelectedIndex(currentRoute) == 3 + ? (isDarkTheme ? Color(0xFF24B4FB) : Colors.black) + : Color(0xFF989898), + width: 23.98, + height: 25, + ), + ), + // label: 'Country Profile', + label: AppLocalizations.of(context)!.country_profile, + ), + ], + key: bottomNavKey, + selectedItemColor: isDarkTheme ? Color(0xFF24B4FB) : Colors.black, + unselectedItemColor: Colors.grey, + selectedLabelStyle: TextStyle( + fontFamily: context.translate( + 'Roboto', + 'NotoKufi', + ), + fontSize: 10, // Font size for unselected label ), - + unselectedLabelStyle: TextStyle( + fontFamily: context.translate( + 'Roboto', + 'NotoKufi', + ), + fontSize: 10, // Font size for unselected label + ), + showUnselectedLabels: true, + ), ], ), @@ -1669,10 +1741,14 @@ void _showLogoutConfirmationDialog(BuildContext context) { title: Text( context.translate('Log Out Confirmation', 'تأكيد تسجيل الخروج'), textAlign: TextAlign.center, - style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold, fontFamily: context.translate( - 'Roboto', - 'NotoKufi', - ),), + style: TextStyle( + fontSize: 20, + fontWeight: FontWeight.bold, + fontFamily: context.translate( + 'Roboto', + 'NotoKufi', + ), + ), ), content: Padding( padding: const EdgeInsets.all(20.0), @@ -1697,7 +1773,7 @@ void _showLogoutConfirmationDialog(BuildContext context) { children: [ SizedBox( width: - MediaQuery.of(context).size.width * 0.3, // Set button width + MediaQuery.of(context).size.width * 0.3, // Set button width child: TextButton( onPressed: () => Navigator.pop(dialogContext), style: TextButton.styleFrom( @@ -1725,7 +1801,7 @@ void _showLogoutConfirmationDialog(BuildContext context) { SizedBox(width: 16), SizedBox( width: - MediaQuery.of(context).size.width * 0.3, // Set button width + MediaQuery.of(context).size.width * 0.3, // Set button width child: TextButton( onPressed: () => logout(context), style: TextButton.styleFrom( @@ -1740,10 +1816,14 @@ void _showLogoutConfirmationDialog(BuildContext context) { .scaleDown, // Prevents wrapping while adjusting text size child: Text( context.translate('Log Out', 'تسجيل الخروج'), - style: TextStyle(color: Colors.white, fontSize: 16, fontFamily: context.translate( - 'Roboto', - 'NotoKufi', - ),), + style: TextStyle( + color: Colors.white, + fontSize: 16, + fontFamily: context.translate( + 'Roboto', + 'NotoKufi', + ), + ), textAlign: TextAlign.center, ), ), @@ -1755,4 +1835,4 @@ void _showLogoutConfirmationDialog(BuildContext context) { ], ), ); -} +} \ No newline at end of file diff --git a/pubspec.yaml b/pubspec.yaml index 0e72b58c..87d6288d 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,8 +1,8 @@ name: uae_stat description: "View statistics about the UAE from the Federal Center for Statistics and Competitiveness." publish_to: "none" -#version: 1.0.60+61 -version: 1.0.6+7 +#version: 1.0.61+62 +version: 1.0.7+8 environment: sdk: ">=3.2.3 <4.0.0"