diff --git a/.flutter-plugins-dependencies b/.flutter-plugins-dependencies index 73d022f..12acdbd 100644 --- a/.flutter-plugins-dependencies +++ b/.flutter-plugins-dependencies @@ -1 +1 @@ -{"info":"This is a generated file; do not edit or check into version control.","plugins":{"ios":[{"name":"connectivity_plus","path":"/home/venba/.pub-cache/hosted/pub.dev/connectivity_plus-6.1.5/","native_build":true,"dependencies":[],"dev_dependency":false},{"name":"file_picker","path":"/home/venba/.pub-cache/hosted/pub.dev/file_picker-10.3.3/","native_build":true,"dependencies":[],"dev_dependency":false},{"name":"firebase_app_check","path":"/home/venba/.pub-cache/hosted/pub.dev/firebase_app_check-0.4.0+1/","native_build":true,"dependencies":["firebase_core"],"dev_dependency":false},{"name":"firebase_auth","path":"/home/venba/.pub-cache/hosted/pub.dev/firebase_auth-6.0.2/","native_build":true,"dependencies":["firebase_core"],"dev_dependency":false},{"name":"firebase_core","path":"/home/venba/.pub-cache/hosted/pub.dev/firebase_core-4.1.0/","native_build":true,"dependencies":[],"dev_dependency":false},{"name":"firebase_messaging","path":"/home/venba/.pub-cache/hosted/pub.dev/firebase_messaging-16.0.1/","native_build":true,"dependencies":["firebase_core"],"dev_dependency":false},{"name":"flutter_secure_storage","path":"/home/venba/.pub-cache/hosted/pub.dev/flutter_secure_storage-9.2.4/","native_build":true,"dependencies":[],"dev_dependency":false},{"name":"google_sign_in_ios","path":"/home/venba/.pub-cache/hosted/pub.dev/google_sign_in_ios-6.1.0/","shared_darwin_source":true,"native_build":true,"dependencies":[],"dev_dependency":false},{"name":"local_auth_darwin","path":"/home/venba/.pub-cache/hosted/pub.dev/local_auth_darwin-1.6.0/","shared_darwin_source":true,"native_build":true,"dependencies":[],"dev_dependency":false},{"name":"open_file_ios","path":"/home/venba/.pub-cache/hosted/pub.dev/open_file_ios-1.0.3/","native_build":true,"dependencies":[],"dev_dependency":false},{"name":"package_info_plus","path":"/home/venba/.pub-cache/hosted/pub.dev/package_info_plus-8.3.1/","native_build":true,"dependencies":[],"dev_dependency":false},{"name":"path_provider_foundation","path":"/home/venba/.pub-cache/hosted/pub.dev/path_provider_foundation-2.4.2/","shared_darwin_source":true,"native_build":true,"dependencies":[],"dev_dependency":false},{"name":"shared_preferences_foundation","path":"/home/venba/.pub-cache/hosted/pub.dev/shared_preferences_foundation-2.5.4/","shared_darwin_source":true,"native_build":true,"dependencies":[],"dev_dependency":false},{"name":"url_launcher_ios","path":"/home/venba/.pub-cache/hosted/pub.dev/url_launcher_ios-6.3.4/","native_build":true,"dependencies":[],"dev_dependency":false}],"android":[{"name":"connectivity_plus","path":"/home/venba/.pub-cache/hosted/pub.dev/connectivity_plus-6.1.5/","native_build":true,"dependencies":[],"dev_dependency":false},{"name":"file_picker","path":"/home/venba/.pub-cache/hosted/pub.dev/file_picker-10.3.3/","native_build":true,"dependencies":["flutter_plugin_android_lifecycle"],"dev_dependency":false},{"name":"firebase_app_check","path":"/home/venba/.pub-cache/hosted/pub.dev/firebase_app_check-0.4.0+1/","native_build":true,"dependencies":["firebase_core"],"dev_dependency":false},{"name":"firebase_auth","path":"/home/venba/.pub-cache/hosted/pub.dev/firebase_auth-6.0.2/","native_build":true,"dependencies":["firebase_core"],"dev_dependency":false},{"name":"firebase_core","path":"/home/venba/.pub-cache/hosted/pub.dev/firebase_core-4.1.0/","native_build":true,"dependencies":[],"dev_dependency":false},{"name":"firebase_messaging","path":"/home/venba/.pub-cache/hosted/pub.dev/firebase_messaging-16.0.1/","native_build":true,"dependencies":["firebase_core"],"dev_dependency":false},{"name":"flutter_plugin_android_lifecycle","path":"/home/venba/.pub-cache/hosted/pub.dev/flutter_plugin_android_lifecycle-2.0.30/","native_build":true,"dependencies":[],"dev_dependency":false},{"name":"flutter_secure_storage","path":"/home/venba/.pub-cache/hosted/pub.dev/flutter_secure_storage-9.2.4/","native_build":true,"dependencies":[],"dev_dependency":false},{"name":"google_sign_in_android","path":"/home/venba/.pub-cache/hosted/pub.dev/google_sign_in_android-7.0.5/","native_build":true,"dependencies":[],"dev_dependency":false},{"name":"local_auth_android","path":"/home/venba/.pub-cache/hosted/pub.dev/local_auth_android-1.0.52/","native_build":true,"dependencies":["flutter_plugin_android_lifecycle"],"dev_dependency":false},{"name":"open_file_android","path":"/home/venba/.pub-cache/hosted/pub.dev/open_file_android-1.0.6/","native_build":true,"dependencies":[],"dev_dependency":false},{"name":"package_info_plus","path":"/home/venba/.pub-cache/hosted/pub.dev/package_info_plus-8.3.1/","native_build":true,"dependencies":[],"dev_dependency":false},{"name":"path_provider_android","path":"/home/venba/.pub-cache/hosted/pub.dev/path_provider_android-2.2.18/","native_build":true,"dependencies":[],"dev_dependency":false},{"name":"shared_preferences_android","path":"/home/venba/.pub-cache/hosted/pub.dev/shared_preferences_android-2.4.12/","native_build":true,"dependencies":[],"dev_dependency":false},{"name":"url_launcher_android","path":"/home/venba/.pub-cache/hosted/pub.dev/url_launcher_android-6.3.20/","native_build":true,"dependencies":[],"dev_dependency":false}],"macos":[{"name":"connectivity_plus","path":"/home/venba/.pub-cache/hosted/pub.dev/connectivity_plus-6.1.5/","native_build":true,"dependencies":[],"dev_dependency":false},{"name":"file_picker","path":"/home/venba/.pub-cache/hosted/pub.dev/file_picker-10.3.3/","native_build":true,"dependencies":[],"dev_dependency":false},{"name":"firebase_app_check","path":"/home/venba/.pub-cache/hosted/pub.dev/firebase_app_check-0.4.0+1/","native_build":true,"dependencies":["firebase_core"],"dev_dependency":false},{"name":"firebase_auth","path":"/home/venba/.pub-cache/hosted/pub.dev/firebase_auth-6.0.2/","native_build":true,"dependencies":["firebase_core"],"dev_dependency":false},{"name":"firebase_core","path":"/home/venba/.pub-cache/hosted/pub.dev/firebase_core-4.1.0/","native_build":true,"dependencies":[],"dev_dependency":false},{"name":"firebase_messaging","path":"/home/venba/.pub-cache/hosted/pub.dev/firebase_messaging-16.0.1/","native_build":true,"dependencies":["firebase_core"],"dev_dependency":false},{"name":"flutter_secure_storage_macos","path":"/home/venba/.pub-cache/hosted/pub.dev/flutter_secure_storage_macos-3.1.3/","native_build":true,"dependencies":[],"dev_dependency":false},{"name":"google_sign_in_ios","path":"/home/venba/.pub-cache/hosted/pub.dev/google_sign_in_ios-6.1.0/","shared_darwin_source":true,"native_build":true,"dependencies":[],"dev_dependency":false},{"name":"local_auth_darwin","path":"/home/venba/.pub-cache/hosted/pub.dev/local_auth_darwin-1.6.0/","shared_darwin_source":true,"native_build":true,"dependencies":[],"dev_dependency":false},{"name":"open_file_mac","path":"/home/venba/.pub-cache/hosted/pub.dev/open_file_mac-1.0.3/","native_build":true,"dependencies":[],"dev_dependency":false},{"name":"package_info_plus","path":"/home/venba/.pub-cache/hosted/pub.dev/package_info_plus-8.3.1/","native_build":true,"dependencies":[],"dev_dependency":false},{"name":"path_provider_foundation","path":"/home/venba/.pub-cache/hosted/pub.dev/path_provider_foundation-2.4.2/","shared_darwin_source":true,"native_build":true,"dependencies":[],"dev_dependency":false},{"name":"shared_preferences_foundation","path":"/home/venba/.pub-cache/hosted/pub.dev/shared_preferences_foundation-2.5.4/","shared_darwin_source":true,"native_build":true,"dependencies":[],"dev_dependency":false},{"name":"url_launcher_macos","path":"/home/venba/.pub-cache/hosted/pub.dev/url_launcher_macos-3.2.3/","native_build":true,"dependencies":[],"dev_dependency":false}],"linux":[{"name":"connectivity_plus","path":"/home/venba/.pub-cache/hosted/pub.dev/connectivity_plus-6.1.5/","native_build":false,"dependencies":[],"dev_dependency":false},{"name":"file_picker","path":"/home/venba/.pub-cache/hosted/pub.dev/file_picker-10.3.3/","native_build":false,"dependencies":[],"dev_dependency":false},{"name":"flutter_secure_storage_linux","path":"/home/venba/.pub-cache/hosted/pub.dev/flutter_secure_storage_linux-1.2.3/","native_build":true,"dependencies":[],"dev_dependency":false},{"name":"open_file_linux","path":"/home/venba/.pub-cache/hosted/pub.dev/open_file_linux-0.0.5/","native_build":true,"dependencies":[],"dev_dependency":false},{"name":"package_info_plus","path":"/home/venba/.pub-cache/hosted/pub.dev/package_info_plus-8.3.1/","native_build":false,"dependencies":[],"dev_dependency":false},{"name":"path_provider_linux","path":"/home/venba/.pub-cache/hosted/pub.dev/path_provider_linux-2.2.1/","native_build":false,"dependencies":[],"dev_dependency":false},{"name":"shared_preferences_linux","path":"/home/venba/.pub-cache/hosted/pub.dev/shared_preferences_linux-2.4.1/","native_build":false,"dependencies":["path_provider_linux"],"dev_dependency":false},{"name":"url_launcher_linux","path":"/home/venba/.pub-cache/hosted/pub.dev/url_launcher_linux-3.2.1/","native_build":true,"dependencies":[],"dev_dependency":false}],"windows":[{"name":"connectivity_plus","path":"/home/venba/.pub-cache/hosted/pub.dev/connectivity_plus-6.1.5/","native_build":true,"dependencies":[],"dev_dependency":false},{"name":"file_picker","path":"/home/venba/.pub-cache/hosted/pub.dev/file_picker-10.3.3/","native_build":false,"dependencies":[],"dev_dependency":false},{"name":"firebase_auth","path":"/home/venba/.pub-cache/hosted/pub.dev/firebase_auth-6.0.2/","native_build":true,"dependencies":["firebase_core"],"dev_dependency":false},{"name":"firebase_core","path":"/home/venba/.pub-cache/hosted/pub.dev/firebase_core-4.1.0/","native_build":true,"dependencies":[],"dev_dependency":false},{"name":"flutter_secure_storage_windows","path":"/home/venba/.pub-cache/hosted/pub.dev/flutter_secure_storage_windows-3.1.2/","native_build":true,"dependencies":[],"dev_dependency":false},{"name":"local_auth_windows","path":"/home/venba/.pub-cache/hosted/pub.dev/local_auth_windows-1.0.11/","native_build":true,"dependencies":[],"dev_dependency":false},{"name":"open_file_windows","path":"/home/venba/.pub-cache/hosted/pub.dev/open_file_windows-0.0.3/","native_build":false,"dependencies":[],"dev_dependency":false},{"name":"package_info_plus","path":"/home/venba/.pub-cache/hosted/pub.dev/package_info_plus-8.3.1/","native_build":false,"dependencies":[],"dev_dependency":false},{"name":"path_provider_windows","path":"/home/venba/.pub-cache/hosted/pub.dev/path_provider_windows-2.3.0/","native_build":false,"dependencies":[],"dev_dependency":false},{"name":"shared_preferences_windows","path":"/home/venba/.pub-cache/hosted/pub.dev/shared_preferences_windows-2.4.1/","native_build":false,"dependencies":["path_provider_windows"],"dev_dependency":false},{"name":"url_launcher_windows","path":"/home/venba/.pub-cache/hosted/pub.dev/url_launcher_windows-3.1.4/","native_build":true,"dependencies":[],"dev_dependency":false}],"web":[{"name":"connectivity_plus","path":"/home/venba/.pub-cache/hosted/pub.dev/connectivity_plus-6.1.5/","dependencies":[],"dev_dependency":false},{"name":"file_picker","path":"/home/venba/.pub-cache/hosted/pub.dev/file_picker-10.3.3/","dependencies":[],"dev_dependency":false},{"name":"firebase_app_check_web","path":"/home/venba/.pub-cache/hosted/pub.dev/firebase_app_check_web-0.2.0+16/","dependencies":["firebase_core_web"],"dev_dependency":false},{"name":"firebase_auth_web","path":"/home/venba/.pub-cache/hosted/pub.dev/firebase_auth_web-6.0.2/","dependencies":["firebase_core_web"],"dev_dependency":false},{"name":"firebase_core_web","path":"/home/venba/.pub-cache/hosted/pub.dev/firebase_core_web-3.1.0/","dependencies":[],"dev_dependency":false},{"name":"firebase_messaging_web","path":"/home/venba/.pub-cache/hosted/pub.dev/firebase_messaging_web-4.0.1/","dependencies":["firebase_core_web"],"dev_dependency":false},{"name":"flutter_secure_storage_web","path":"/home/venba/.pub-cache/hosted/pub.dev/flutter_secure_storage_web-1.2.1/","dependencies":[],"dev_dependency":false},{"name":"google_sign_in_web","path":"/home/venba/.pub-cache/hosted/pub.dev/google_sign_in_web-1.0.0/","dependencies":[],"dev_dependency":false},{"name":"open_file_web","path":"/home/venba/.pub-cache/hosted/pub.dev/open_file_web-0.0.4/","dependencies":[],"dev_dependency":false},{"name":"package_info_plus","path":"/home/venba/.pub-cache/hosted/pub.dev/package_info_plus-8.3.1/","dependencies":[],"dev_dependency":false},{"name":"shared_preferences_web","path":"/home/venba/.pub-cache/hosted/pub.dev/shared_preferences_web-2.4.3/","dependencies":[],"dev_dependency":false},{"name":"url_launcher_web","path":"/home/venba/.pub-cache/hosted/pub.dev/url_launcher_web-2.4.1/","dependencies":[],"dev_dependency":false}]},"dependencyGraph":[{"name":"connectivity_plus","dependencies":[]},{"name":"file_picker","dependencies":["flutter_plugin_android_lifecycle"]},{"name":"firebase_app_check","dependencies":["firebase_app_check_web","firebase_core"]},{"name":"firebase_app_check_web","dependencies":["firebase_core","firebase_core_web"]},{"name":"firebase_auth","dependencies":["firebase_auth_web","firebase_core"]},{"name":"firebase_auth_web","dependencies":["firebase_core","firebase_core_web"]},{"name":"firebase_core","dependencies":["firebase_core_web"]},{"name":"firebase_core_web","dependencies":[]},{"name":"firebase_messaging","dependencies":["firebase_core","firebase_messaging_web"]},{"name":"firebase_messaging_web","dependencies":["firebase_core","firebase_core_web"]},{"name":"flutter_plugin_android_lifecycle","dependencies":[]},{"name":"flutter_secure_storage","dependencies":["flutter_secure_storage_linux","flutter_secure_storage_macos","flutter_secure_storage_web","flutter_secure_storage_windows"]},{"name":"flutter_secure_storage_linux","dependencies":[]},{"name":"flutter_secure_storage_macos","dependencies":[]},{"name":"flutter_secure_storage_web","dependencies":[]},{"name":"flutter_secure_storage_windows","dependencies":["path_provider"]},{"name":"google_sign_in","dependencies":["google_sign_in_android","google_sign_in_ios","google_sign_in_web"]},{"name":"google_sign_in_android","dependencies":[]},{"name":"google_sign_in_ios","dependencies":[]},{"name":"google_sign_in_web","dependencies":[]},{"name":"local_auth","dependencies":["local_auth_android","local_auth_darwin","local_auth_windows"]},{"name":"local_auth_android","dependencies":["flutter_plugin_android_lifecycle"]},{"name":"local_auth_darwin","dependencies":[]},{"name":"local_auth_windows","dependencies":[]},{"name":"open_file","dependencies":["open_file_android","open_file_web","open_file_ios","open_file_mac","open_file_windows","open_file_linux"]},{"name":"open_file_android","dependencies":[]},{"name":"open_file_ios","dependencies":[]},{"name":"open_file_linux","dependencies":[]},{"name":"open_file_mac","dependencies":[]},{"name":"open_file_web","dependencies":[]},{"name":"open_file_windows","dependencies":[]},{"name":"package_info_plus","dependencies":[]},{"name":"path_provider","dependencies":["path_provider_android","path_provider_foundation","path_provider_linux","path_provider_windows"]},{"name":"path_provider_android","dependencies":[]},{"name":"path_provider_foundation","dependencies":[]},{"name":"path_provider_linux","dependencies":[]},{"name":"path_provider_windows","dependencies":[]},{"name":"shared_preferences","dependencies":["shared_preferences_android","shared_preferences_foundation","shared_preferences_linux","shared_preferences_web","shared_preferences_windows"]},{"name":"shared_preferences_android","dependencies":[]},{"name":"shared_preferences_foundation","dependencies":[]},{"name":"shared_preferences_linux","dependencies":["path_provider_linux"]},{"name":"shared_preferences_web","dependencies":[]},{"name":"shared_preferences_windows","dependencies":["path_provider_windows"]},{"name":"url_launcher","dependencies":["url_launcher_android","url_launcher_ios","url_launcher_linux","url_launcher_macos","url_launcher_web","url_launcher_windows"]},{"name":"url_launcher_android","dependencies":[]},{"name":"url_launcher_ios","dependencies":[]},{"name":"url_launcher_linux","dependencies":[]},{"name":"url_launcher_macos","dependencies":[]},{"name":"url_launcher_web","dependencies":[]},{"name":"url_launcher_windows","dependencies":[]}],"date_created":"2025-10-17 14:07:34.777923","version":"3.32.1","swift_package_manager_enabled":{"ios":false,"macos":false}} \ No newline at end of file +{"info":"This is a generated file; do not edit or check into version control.","plugins":{"ios":[{"name":"connectivity_plus","path":"/home/venba/.pub-cache/hosted/pub.dev/connectivity_plus-6.1.5/","native_build":true,"dependencies":[],"dev_dependency":false},{"name":"file_picker","path":"/home/venba/.pub-cache/hosted/pub.dev/file_picker-10.3.3/","native_build":true,"dependencies":[],"dev_dependency":false},{"name":"firebase_app_check","path":"/home/venba/.pub-cache/hosted/pub.dev/firebase_app_check-0.4.0+1/","native_build":true,"dependencies":["firebase_core"],"dev_dependency":false},{"name":"firebase_auth","path":"/home/venba/.pub-cache/hosted/pub.dev/firebase_auth-6.0.2/","native_build":true,"dependencies":["firebase_core"],"dev_dependency":false},{"name":"firebase_core","path":"/home/venba/.pub-cache/hosted/pub.dev/firebase_core-4.1.0/","native_build":true,"dependencies":[],"dev_dependency":false},{"name":"firebase_messaging","path":"/home/venba/.pub-cache/hosted/pub.dev/firebase_messaging-16.0.1/","native_build":true,"dependencies":["firebase_core"],"dev_dependency":false},{"name":"flutter_secure_storage","path":"/home/venba/.pub-cache/hosted/pub.dev/flutter_secure_storage-9.2.4/","native_build":true,"dependencies":[],"dev_dependency":false},{"name":"google_sign_in_ios","path":"/home/venba/.pub-cache/hosted/pub.dev/google_sign_in_ios-6.1.0/","shared_darwin_source":true,"native_build":true,"dependencies":[],"dev_dependency":false},{"name":"local_auth_darwin","path":"/home/venba/.pub-cache/hosted/pub.dev/local_auth_darwin-1.6.0/","shared_darwin_source":true,"native_build":true,"dependencies":[],"dev_dependency":false},{"name":"open_file_ios","path":"/home/venba/.pub-cache/hosted/pub.dev/open_file_ios-1.0.3/","native_build":true,"dependencies":[],"dev_dependency":false},{"name":"package_info_plus","path":"/home/venba/.pub-cache/hosted/pub.dev/package_info_plus-8.3.1/","native_build":true,"dependencies":[],"dev_dependency":false},{"name":"path_provider_foundation","path":"/home/venba/.pub-cache/hosted/pub.dev/path_provider_foundation-2.4.2/","shared_darwin_source":true,"native_build":true,"dependencies":[],"dev_dependency":false},{"name":"shared_preferences_foundation","path":"/home/venba/.pub-cache/hosted/pub.dev/shared_preferences_foundation-2.5.4/","shared_darwin_source":true,"native_build":true,"dependencies":[],"dev_dependency":false},{"name":"url_launcher_ios","path":"/home/venba/.pub-cache/hosted/pub.dev/url_launcher_ios-6.3.4/","native_build":true,"dependencies":[],"dev_dependency":false}],"android":[{"name":"connectivity_plus","path":"/home/venba/.pub-cache/hosted/pub.dev/connectivity_plus-6.1.5/","native_build":true,"dependencies":[],"dev_dependency":false},{"name":"file_picker","path":"/home/venba/.pub-cache/hosted/pub.dev/file_picker-10.3.3/","native_build":true,"dependencies":["flutter_plugin_android_lifecycle"],"dev_dependency":false},{"name":"firebase_app_check","path":"/home/venba/.pub-cache/hosted/pub.dev/firebase_app_check-0.4.0+1/","native_build":true,"dependencies":["firebase_core"],"dev_dependency":false},{"name":"firebase_auth","path":"/home/venba/.pub-cache/hosted/pub.dev/firebase_auth-6.0.2/","native_build":true,"dependencies":["firebase_core"],"dev_dependency":false},{"name":"firebase_core","path":"/home/venba/.pub-cache/hosted/pub.dev/firebase_core-4.1.0/","native_build":true,"dependencies":[],"dev_dependency":false},{"name":"firebase_messaging","path":"/home/venba/.pub-cache/hosted/pub.dev/firebase_messaging-16.0.1/","native_build":true,"dependencies":["firebase_core"],"dev_dependency":false},{"name":"flutter_plugin_android_lifecycle","path":"/home/venba/.pub-cache/hosted/pub.dev/flutter_plugin_android_lifecycle-2.0.30/","native_build":true,"dependencies":[],"dev_dependency":false},{"name":"flutter_secure_storage","path":"/home/venba/.pub-cache/hosted/pub.dev/flutter_secure_storage-9.2.4/","native_build":true,"dependencies":[],"dev_dependency":false},{"name":"google_sign_in_android","path":"/home/venba/.pub-cache/hosted/pub.dev/google_sign_in_android-7.0.5/","native_build":true,"dependencies":[],"dev_dependency":false},{"name":"local_auth_android","path":"/home/venba/.pub-cache/hosted/pub.dev/local_auth_android-1.0.52/","native_build":true,"dependencies":["flutter_plugin_android_lifecycle"],"dev_dependency":false},{"name":"open_file_android","path":"/home/venba/.pub-cache/hosted/pub.dev/open_file_android-1.0.6/","native_build":true,"dependencies":[],"dev_dependency":false},{"name":"package_info_plus","path":"/home/venba/.pub-cache/hosted/pub.dev/package_info_plus-8.3.1/","native_build":true,"dependencies":[],"dev_dependency":false},{"name":"path_provider_android","path":"/home/venba/.pub-cache/hosted/pub.dev/path_provider_android-2.2.18/","native_build":true,"dependencies":[],"dev_dependency":false},{"name":"shared_preferences_android","path":"/home/venba/.pub-cache/hosted/pub.dev/shared_preferences_android-2.4.12/","native_build":true,"dependencies":[],"dev_dependency":false},{"name":"url_launcher_android","path":"/home/venba/.pub-cache/hosted/pub.dev/url_launcher_android-6.3.20/","native_build":true,"dependencies":[],"dev_dependency":false}],"macos":[{"name":"connectivity_plus","path":"/home/venba/.pub-cache/hosted/pub.dev/connectivity_plus-6.1.5/","native_build":true,"dependencies":[],"dev_dependency":false},{"name":"file_picker","path":"/home/venba/.pub-cache/hosted/pub.dev/file_picker-10.3.3/","native_build":true,"dependencies":[],"dev_dependency":false},{"name":"firebase_app_check","path":"/home/venba/.pub-cache/hosted/pub.dev/firebase_app_check-0.4.0+1/","native_build":true,"dependencies":["firebase_core"],"dev_dependency":false},{"name":"firebase_auth","path":"/home/venba/.pub-cache/hosted/pub.dev/firebase_auth-6.0.2/","native_build":true,"dependencies":["firebase_core"],"dev_dependency":false},{"name":"firebase_core","path":"/home/venba/.pub-cache/hosted/pub.dev/firebase_core-4.1.0/","native_build":true,"dependencies":[],"dev_dependency":false},{"name":"firebase_messaging","path":"/home/venba/.pub-cache/hosted/pub.dev/firebase_messaging-16.0.1/","native_build":true,"dependencies":["firebase_core"],"dev_dependency":false},{"name":"flutter_secure_storage_macos","path":"/home/venba/.pub-cache/hosted/pub.dev/flutter_secure_storage_macos-3.1.3/","native_build":true,"dependencies":[],"dev_dependency":false},{"name":"google_sign_in_ios","path":"/home/venba/.pub-cache/hosted/pub.dev/google_sign_in_ios-6.1.0/","shared_darwin_source":true,"native_build":true,"dependencies":[],"dev_dependency":false},{"name":"local_auth_darwin","path":"/home/venba/.pub-cache/hosted/pub.dev/local_auth_darwin-1.6.0/","shared_darwin_source":true,"native_build":true,"dependencies":[],"dev_dependency":false},{"name":"open_file_mac","path":"/home/venba/.pub-cache/hosted/pub.dev/open_file_mac-1.0.3/","native_build":true,"dependencies":[],"dev_dependency":false},{"name":"package_info_plus","path":"/home/venba/.pub-cache/hosted/pub.dev/package_info_plus-8.3.1/","native_build":true,"dependencies":[],"dev_dependency":false},{"name":"path_provider_foundation","path":"/home/venba/.pub-cache/hosted/pub.dev/path_provider_foundation-2.4.2/","shared_darwin_source":true,"native_build":true,"dependencies":[],"dev_dependency":false},{"name":"shared_preferences_foundation","path":"/home/venba/.pub-cache/hosted/pub.dev/shared_preferences_foundation-2.5.4/","shared_darwin_source":true,"native_build":true,"dependencies":[],"dev_dependency":false},{"name":"url_launcher_macos","path":"/home/venba/.pub-cache/hosted/pub.dev/url_launcher_macos-3.2.3/","native_build":true,"dependencies":[],"dev_dependency":false}],"linux":[{"name":"connectivity_plus","path":"/home/venba/.pub-cache/hosted/pub.dev/connectivity_plus-6.1.5/","native_build":false,"dependencies":[],"dev_dependency":false},{"name":"file_picker","path":"/home/venba/.pub-cache/hosted/pub.dev/file_picker-10.3.3/","native_build":false,"dependencies":[],"dev_dependency":false},{"name":"flutter_secure_storage_linux","path":"/home/venba/.pub-cache/hosted/pub.dev/flutter_secure_storage_linux-1.2.3/","native_build":true,"dependencies":[],"dev_dependency":false},{"name":"open_file_linux","path":"/home/venba/.pub-cache/hosted/pub.dev/open_file_linux-0.0.5/","native_build":true,"dependencies":[],"dev_dependency":false},{"name":"package_info_plus","path":"/home/venba/.pub-cache/hosted/pub.dev/package_info_plus-8.3.1/","native_build":false,"dependencies":[],"dev_dependency":false},{"name":"path_provider_linux","path":"/home/venba/.pub-cache/hosted/pub.dev/path_provider_linux-2.2.1/","native_build":false,"dependencies":[],"dev_dependency":false},{"name":"shared_preferences_linux","path":"/home/venba/.pub-cache/hosted/pub.dev/shared_preferences_linux-2.4.1/","native_build":false,"dependencies":["path_provider_linux"],"dev_dependency":false},{"name":"url_launcher_linux","path":"/home/venba/.pub-cache/hosted/pub.dev/url_launcher_linux-3.2.1/","native_build":true,"dependencies":[],"dev_dependency":false}],"windows":[{"name":"connectivity_plus","path":"/home/venba/.pub-cache/hosted/pub.dev/connectivity_plus-6.1.5/","native_build":true,"dependencies":[],"dev_dependency":false},{"name":"file_picker","path":"/home/venba/.pub-cache/hosted/pub.dev/file_picker-10.3.3/","native_build":false,"dependencies":[],"dev_dependency":false},{"name":"firebase_auth","path":"/home/venba/.pub-cache/hosted/pub.dev/firebase_auth-6.0.2/","native_build":true,"dependencies":["firebase_core"],"dev_dependency":false},{"name":"firebase_core","path":"/home/venba/.pub-cache/hosted/pub.dev/firebase_core-4.1.0/","native_build":true,"dependencies":[],"dev_dependency":false},{"name":"flutter_secure_storage_windows","path":"/home/venba/.pub-cache/hosted/pub.dev/flutter_secure_storage_windows-3.1.2/","native_build":true,"dependencies":[],"dev_dependency":false},{"name":"local_auth_windows","path":"/home/venba/.pub-cache/hosted/pub.dev/local_auth_windows-1.0.11/","native_build":true,"dependencies":[],"dev_dependency":false},{"name":"open_file_windows","path":"/home/venba/.pub-cache/hosted/pub.dev/open_file_windows-0.0.3/","native_build":false,"dependencies":[],"dev_dependency":false},{"name":"package_info_plus","path":"/home/venba/.pub-cache/hosted/pub.dev/package_info_plus-8.3.1/","native_build":false,"dependencies":[],"dev_dependency":false},{"name":"path_provider_windows","path":"/home/venba/.pub-cache/hosted/pub.dev/path_provider_windows-2.3.0/","native_build":false,"dependencies":[],"dev_dependency":false},{"name":"shared_preferences_windows","path":"/home/venba/.pub-cache/hosted/pub.dev/shared_preferences_windows-2.4.1/","native_build":false,"dependencies":["path_provider_windows"],"dev_dependency":false},{"name":"url_launcher_windows","path":"/home/venba/.pub-cache/hosted/pub.dev/url_launcher_windows-3.1.4/","native_build":true,"dependencies":[],"dev_dependency":false}],"web":[{"name":"connectivity_plus","path":"/home/venba/.pub-cache/hosted/pub.dev/connectivity_plus-6.1.5/","dependencies":[],"dev_dependency":false},{"name":"file_picker","path":"/home/venba/.pub-cache/hosted/pub.dev/file_picker-10.3.3/","dependencies":[],"dev_dependency":false},{"name":"firebase_app_check_web","path":"/home/venba/.pub-cache/hosted/pub.dev/firebase_app_check_web-0.2.0+16/","dependencies":["firebase_core_web"],"dev_dependency":false},{"name":"firebase_auth_web","path":"/home/venba/.pub-cache/hosted/pub.dev/firebase_auth_web-6.0.2/","dependencies":["firebase_core_web"],"dev_dependency":false},{"name":"firebase_core_web","path":"/home/venba/.pub-cache/hosted/pub.dev/firebase_core_web-3.1.0/","dependencies":[],"dev_dependency":false},{"name":"firebase_messaging_web","path":"/home/venba/.pub-cache/hosted/pub.dev/firebase_messaging_web-4.0.1/","dependencies":["firebase_core_web"],"dev_dependency":false},{"name":"flutter_secure_storage_web","path":"/home/venba/.pub-cache/hosted/pub.dev/flutter_secure_storage_web-1.2.1/","dependencies":[],"dev_dependency":false},{"name":"google_sign_in_web","path":"/home/venba/.pub-cache/hosted/pub.dev/google_sign_in_web-1.0.0/","dependencies":[],"dev_dependency":false},{"name":"open_file_web","path":"/home/venba/.pub-cache/hosted/pub.dev/open_file_web-0.0.4/","dependencies":[],"dev_dependency":false},{"name":"package_info_plus","path":"/home/venba/.pub-cache/hosted/pub.dev/package_info_plus-8.3.1/","dependencies":[],"dev_dependency":false},{"name":"shared_preferences_web","path":"/home/venba/.pub-cache/hosted/pub.dev/shared_preferences_web-2.4.3/","dependencies":[],"dev_dependency":false},{"name":"url_launcher_web","path":"/home/venba/.pub-cache/hosted/pub.dev/url_launcher_web-2.4.1/","dependencies":[],"dev_dependency":false}]},"dependencyGraph":[{"name":"connectivity_plus","dependencies":[]},{"name":"file_picker","dependencies":["flutter_plugin_android_lifecycle"]},{"name":"firebase_app_check","dependencies":["firebase_app_check_web","firebase_core"]},{"name":"firebase_app_check_web","dependencies":["firebase_core","firebase_core_web"]},{"name":"firebase_auth","dependencies":["firebase_auth_web","firebase_core"]},{"name":"firebase_auth_web","dependencies":["firebase_core","firebase_core_web"]},{"name":"firebase_core","dependencies":["firebase_core_web"]},{"name":"firebase_core_web","dependencies":[]},{"name":"firebase_messaging","dependencies":["firebase_core","firebase_messaging_web"]},{"name":"firebase_messaging_web","dependencies":["firebase_core","firebase_core_web"]},{"name":"flutter_plugin_android_lifecycle","dependencies":[]},{"name":"flutter_secure_storage","dependencies":["flutter_secure_storage_linux","flutter_secure_storage_macos","flutter_secure_storage_web","flutter_secure_storage_windows"]},{"name":"flutter_secure_storage_linux","dependencies":[]},{"name":"flutter_secure_storage_macos","dependencies":[]},{"name":"flutter_secure_storage_web","dependencies":[]},{"name":"flutter_secure_storage_windows","dependencies":["path_provider"]},{"name":"google_sign_in","dependencies":["google_sign_in_android","google_sign_in_ios","google_sign_in_web"]},{"name":"google_sign_in_android","dependencies":[]},{"name":"google_sign_in_ios","dependencies":[]},{"name":"google_sign_in_web","dependencies":[]},{"name":"local_auth","dependencies":["local_auth_android","local_auth_darwin","local_auth_windows"]},{"name":"local_auth_android","dependencies":["flutter_plugin_android_lifecycle"]},{"name":"local_auth_darwin","dependencies":[]},{"name":"local_auth_windows","dependencies":[]},{"name":"open_file","dependencies":["open_file_android","open_file_web","open_file_ios","open_file_mac","open_file_windows","open_file_linux"]},{"name":"open_file_android","dependencies":[]},{"name":"open_file_ios","dependencies":[]},{"name":"open_file_linux","dependencies":[]},{"name":"open_file_mac","dependencies":[]},{"name":"open_file_web","dependencies":[]},{"name":"open_file_windows","dependencies":[]},{"name":"package_info_plus","dependencies":[]},{"name":"path_provider","dependencies":["path_provider_android","path_provider_foundation","path_provider_linux","path_provider_windows"]},{"name":"path_provider_android","dependencies":[]},{"name":"path_provider_foundation","dependencies":[]},{"name":"path_provider_linux","dependencies":[]},{"name":"path_provider_windows","dependencies":[]},{"name":"shared_preferences","dependencies":["shared_preferences_android","shared_preferences_foundation","shared_preferences_linux","shared_preferences_web","shared_preferences_windows"]},{"name":"shared_preferences_android","dependencies":[]},{"name":"shared_preferences_foundation","dependencies":[]},{"name":"shared_preferences_linux","dependencies":["path_provider_linux"]},{"name":"shared_preferences_web","dependencies":[]},{"name":"shared_preferences_windows","dependencies":["path_provider_windows"]},{"name":"url_launcher","dependencies":["url_launcher_android","url_launcher_ios","url_launcher_linux","url_launcher_macos","url_launcher_web","url_launcher_windows"]},{"name":"url_launcher_android","dependencies":[]},{"name":"url_launcher_ios","dependencies":[]},{"name":"url_launcher_linux","dependencies":[]},{"name":"url_launcher_macos","dependencies":[]},{"name":"url_launcher_web","dependencies":[]},{"name":"url_launcher_windows","dependencies":[]}],"date_created":"2025-10-25 15:59:36.526728","version":"3.32.1","swift_package_manager_enabled":{"ios":false,"macos":false}} \ No newline at end of file diff --git a/lib/core/config/env.dart b/lib/core/config/env.dart index 28866d4..5e69ddf 100644 --- a/lib/core/config/env.dart +++ b/lib/core/config/env.dart @@ -1,7 +1,18 @@ class Env { - static const String envName = String.fromEnvironment('ENV', defaultValue: 'dev'); - static const String apiUrl = String.fromEnvironment('API_URL', defaultValue: 'https://venbait.in/nhance/partner/dev/api/'); - static const String baseUrl = String.fromEnvironment('BASE_URL', defaultValue: '/nhance/partner/app'); - static const String App_Signature = String.fromEnvironment('App_Signature', defaultValue: 'nhance-partner-2025-signature-35468846JRhH551HK'); + static const String envName = String.fromEnvironment( + 'ENV', + defaultValue: 'dev', + ); + static const String apiUrl = String.fromEnvironment( + 'API_URL', + defaultValue: 'https://venbait.in/nhance/partner/dev/api/', + ); + static const String baseUrl = String.fromEnvironment( + 'BASE_URL', + defaultValue: '/nhance/partner/app', + ); + static const String App_Signature = String.fromEnvironment( + 'App_Signature', + defaultValue: 'nhance-partner-2025-signature-35468846JRhH551HK', + ); } - diff --git a/lib/core/routing/app_router.dart b/lib/core/routing/app_router.dart index 8d8a1bc..5270078 100644 --- a/lib/core/routing/app_router.dart +++ b/lib/core/routing/app_router.dart @@ -27,7 +27,8 @@ import '../../presentation/screens/staff/policy/policy_list.dart'; import '../../presentation/screens/staff/quotations/quotation.dart'; final GoRouter appRouter = GoRouter( - initialLocation: AppRoutes.home, + initialLocation: AppRoutes.login, + // initialLocation: AppRoutes.home, routes: [ GoRoute( path: AppRoutes.splash, @@ -37,10 +38,10 @@ final GoRouter appRouter = GoRouter( path: AppRoutes.login, builder: (context, state) => const LoginScreen(), ), - GoRoute( - path: AppRoutes.home, - builder: (context, state) => const HomeScreen(), - ), + // GoRoute( + // path: AppRoutes.home, + // builder: (context, state) => const HomeScreen(), + // ), GoRoute( path: AppRoutes.dashboard, builder: (context, state) => const DashboardScreen(), @@ -193,7 +194,7 @@ final GoRouter appRouter = GoRouter( if (loggedIn && goingToLogin) { // Logged in but going to login → send to "next" if present final next = state.uri.queryParameters['next']; - return next ?? AppRoutes.home; + return next ?? AppRoutes.login; } // if (!loggedIn && !goingToLogin) return AppRoutes.login; diff --git a/lib/core/services/api_service.dart b/lib/core/services/api_service.dart index 652da8a..c1fbe1e 100644 --- a/lib/core/services/api_service.dart +++ b/lib/core/services/api_service.dart @@ -1,6 +1,7 @@ import 'package:file_picker/file_picker.dart'; import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; +import 'package:go_router/go_router.dart'; import 'package:http/http.dart' as http; import 'package:nhance_partner/data/services/auth_service.dart'; import 'package:shared_preferences/shared_preferences.dart'; @@ -10,6 +11,8 @@ import '../config/env.dart'; import 'package:universal_html/html.dart' as html; import 'package:http/http.dart' as http; +import '../routing/routes.dart'; + class ApiService { late final BuildContext context; @@ -20,12 +23,14 @@ class ApiService { print("APISERTOKEN - $_token"); } - Future _clearLocalStorageAndRedirect() async { - final prefs = await SharedPreferences.getInstance(); - await prefs.clear(); + Future clearLocalStorageAndRedirect() async { + // final prefs = await SharedPreferences.getInstance(); + // await prefs.clear(); // Assuming you have access to the context ToastHelper.showErrorToast(context, 'Session Out'); - Navigator.pushNamed(context, 'login'); + // Navigator.pushNamed(context, 'login'); + AuthService.clearToken(); + context.go(AppRoutes.login); } Future> _makeGetRequest( @@ -46,7 +51,7 @@ class ApiService { // if (response.statusCode == 200) { // return jsonDecode(response.body); // } else if (response.statusCode == 401) { - // await _clearLocalStorageAndRedirect(); + // await clearLocalStorageAndRedirect(); // return {}; // } else { // throw Exception('Failed to load data'); @@ -61,6 +66,9 @@ class ApiService { if (response.statusCode == 200) { return response; // return full http.Response, not Map + } else if (response.statusCode == 403) { + await clearLocalStorageAndRedirect(); + return http.Response('Forbidden', 403); } else { throw Exception('Failed request: ${response.statusCode}'); } @@ -83,8 +91,8 @@ class ApiService { Future> _handleResponse(http.Response response) async { if (response.statusCode == 200) { return jsonDecode(response.body); - } else if (response.statusCode == 401) { - await _clearLocalStorageAndRedirect(); + } else if (response.statusCode == 401 || response.statusCode == 403) { + await clearLocalStorageAndRedirect(); return {}; } else { throw Exception('Failed to load data'); @@ -107,7 +115,7 @@ class ApiService { final headers = { 'Authorization': 'Bearer $_token' ?? '', - 'App-Signature': 'nhance-partner-2025-signature-35468846JRhH551HK', + 'app-signature': Env.App_Signature, }; final response = await _makeGethttpRequest(url, headers); @@ -200,7 +208,8 @@ class ApiService { final headers = { 'Authorization': 'Bearer $_token', - 'App-Signature': 'nhance-partner-2025-signature-35468846JRhH551HK', + // 'App-Signature': Env.App_Signature, + 'app-signature': Env.App_Signature, }; final response = await _makeGethttpRequest(url, headers); @@ -260,6 +269,8 @@ class ApiService { ], ), ); + } else if (response.statusCode == 403) { + await clearLocalStorageAndRedirect(); } else if (response.statusCode == 500) { ToastHelper.showInfoToast(context, 'No File Not Found'); } else { @@ -303,6 +314,7 @@ class ApiService { } Future> updateStatus(id, status, role) async { + print('updateStatusupdateStatus'); final Map data = { "id": int.parse(id), "is_active": int.parse(status), @@ -330,7 +342,8 @@ class ApiService { final headers = { 'Authorization': 'Bearer $_token', 'Content-Type': 'application/json', - 'app-signature': 'nhance-partner-2025-signature-35468846JRhH551HK', + 'app-signature': Env.App_Signature, + // 'app-signature': 'nhance-partner-2025-signature-35468846JRhH551HK', }; final response = await _makePostRequestJson(url, data, headers); @@ -362,7 +375,7 @@ class ApiService { // ); final headers = { 'Authorization': 'Bearer $_token' ?? '', - 'App-Signature': 'nhance-partner-2025-signature-35468846JRhH551HK', + 'app-signature': Env.App_Signature, }; final response = await _makeGetRequest(url, headers); @@ -386,7 +399,7 @@ class ApiService { // ); final headers = { 'Authorization': 'Bearer $_token' ?? '', - 'App-Signature': 'nhance-partner-2025-signature-35468846JRhH551HK', + 'app-signature': Env.App_Signature, }; final response = await _makeGetRequest(url, headers); return response; @@ -404,7 +417,7 @@ class ApiService { final headers = { 'Authorization': 'Bearer $_token' ?? '', - 'App-Signature': 'nhance-partner-2025-signature-35468846JRhH551HK', + 'app-signature': Env.App_Signature, }; final response = await _makeGetRequest(url, headers); return response; @@ -423,7 +436,7 @@ class ApiService { final headers = { 'Authorization': 'Bearer $_token' ?? '', - 'App-Signature': 'nhance-partner-2025-signature-35468846JRhH551HK', + 'app-signature': Env.App_Signature, }; final response = await _makeGetRequest(url, headers); return response; @@ -442,7 +455,7 @@ class ApiService { final url = Uri.parse('${Env.apiUrl}agent/findAgent?id=$id'); final headers = { 'Authorization': 'Bearer $_token' ?? '', - 'App-Signature': 'nhance-partner-2025-signature-35468846JRhH551HK', + 'app-signature': Env.App_Signature, }; final response = await _makeGetRequest(url, headers); return response; @@ -461,7 +474,7 @@ class ApiService { final url = Uri.parse('${Env.apiUrl}agent/deleteAgentIncentiveFile?id=$id'); final headers = { 'Authorization': 'Bearer $_token' ?? '', - 'App-Signature': 'nhance-partner-2025-signature-35468846JRhH551HK', + 'app-signature': Env.App_Signature, }; final response = await _makeGetRequest(url, headers); return response; @@ -490,7 +503,7 @@ class ApiService { final headers = { 'Authorization': 'Bearer $_token' ?? '', - 'App-Signature': 'nhance-partner-2025-signature-35468846JRhH551HK', + 'app-signature': Env.App_Signature, }; final response = await _makeGetRequest(url, headers); return response; @@ -509,7 +522,7 @@ class ApiService { final url = Uri.parse('${Env.apiUrl}staff/findStaff?id=$id'); final headers = { 'Authorization': 'Bearer $_token' ?? '', - 'App-Signature': 'nhance-partner-2025-signature-35468846JRhH551HK', + 'app-signature': Env.App_Signature, }; final response = await _makeGetRequest(url, headers); return response; @@ -543,7 +556,7 @@ class ApiService { // ); final headers = { 'Authorization': 'Bearer $_token' ?? '', - 'App-Signature': 'nhance-partner-2025-signature-35468846JRhH551HK', + 'app-signature': Env.App_Signature, }; final response = await _makeGetRequest(url, headers); return response; @@ -554,6 +567,8 @@ class ApiService { String role, { String? fromDate, String? toDate, + String? selectedStatus, + String? selectedStaffId, }) async { if (_token == null) { await _initializeToken(); @@ -573,13 +588,16 @@ class ApiService { query = 'agent_id=$id'; } + // final url = Uri.parse( + // '${Env.apiUrl}enquiry/enquiryList?$query&from_date=${fromDate ?? ''}&to_date=${toDate ?? ''}', + // ); final url = Uri.parse( - '${Env.apiUrl}enquiry/enquiryList?$query&from_date=${fromDate ?? ''}&to_date=${toDate ?? ''}', + '${Env.apiUrl}enquiry/enquiryList?$query&from_date=${fromDate ?? ''}&to_date=${toDate ?? ''}&status=$selectedStatus&staff_id=$selectedStaffId', ); final headers = { 'Authorization': 'Bearer $_token' ?? '', - 'App-Signature': 'nhance-partner-2025-signature-35468846JRhH551HK', + 'app-signature': Env.App_Signature, }; final response = await _makeGetRequest(url, headers); @@ -588,6 +606,7 @@ class ApiService { Future> fetchAttndanceOFAllStaffList({ required String month, + required dynamic mangerId, }) async { if (_token == null) { await _initializeToken(); @@ -600,12 +619,12 @@ class ApiService { // } final url = Uri.parse( - '${Env.apiUrl}staff/monthlyLoginCount?month=${month ?? ''}', + '${Env.apiUrl}staff/monthlyLoginCount?month=${month ?? ''}&manager_id=$mangerId', ); final headers = { 'Authorization': 'Bearer $_token' ?? '', - 'App-Signature': 'nhance-partner-2025-signature-35468846JRhH551HK', + 'app-signature': Env.App_Signature, }; final response = await _makeGetRequest(url, headers); @@ -628,7 +647,7 @@ class ApiService { final headers = { 'Authorization': 'Bearer $_token' ?? '', - 'App-Signature': 'nhance-partner-2025-signature-35468846JRhH551HK', + 'app-signature': Env.App_Signature, }; final response = await _makeGetRequest(url, headers); @@ -643,7 +662,7 @@ class ApiService { final url = Uri.parse('${Env.apiUrl}enquiry/enquiryList?enquiry_id=$id'); final headers = { 'Authorization': 'Bearer $_token' ?? '', - 'App-Signature': 'nhance-partner-2025-signature-35468846JRhH551HK', + 'app-signature': Env.App_Signature, }; final response = await _makeGetRequest(url, headers); return response; @@ -661,7 +680,7 @@ class ApiService { ); final headers = { 'Authorization': 'Bearer $_token' ?? '', - 'App-Signature': 'nhance-partner-2025-signature-35468846JRhH551HK', + 'app-signature': Env.App_Signature, }; print('findEnqQuotePolicyVie2w 3'); final response = await _makeGetRequest(url, headers); @@ -694,7 +713,7 @@ class ApiService { ); final headers = { 'Authorization': 'Bearer $_token' ?? '', - 'App-Signature': 'nhance-partner-2025-signature-35468846JRhH551HK', + 'app-signature': Env.App_Signature, }; final response = await _makeGetRequest(url, headers); return response; @@ -708,7 +727,7 @@ class ApiService { final url = Uri.parse('${Env.apiUrl}quotation/findQuotation?id=$id'); final headers = { 'Authorization': 'Bearer $_token' ?? '', - 'App-Signature': 'nhance-partner-2025-signature-35468846JRhH551HK', + 'app-signature': Env.App_Signature, }; final response = await _makeGetRequest(url, headers); return response; @@ -721,17 +740,18 @@ class ApiService { role, { String? fromDate, String? toDate, + String? selectedStatus, + String? selectedStaffId, }) async { // print(_token); if (_token == null) { await _initializeToken(); } - final userId = '1'; final url; final String query; - + final String val = 'Proposal Created'; if (role == 'manager') { query = 'manager_id=$id'; } else if (role == 'staff') { @@ -740,8 +760,12 @@ class ApiService { query = 'agent_id=$id'; } + // url = Uri.parse( + // '${Env.apiUrl}enquiry/enquiryList?$query&from_date=${fromDate ?? ''}&to_date=${toDate ?? ''}', + // ); + url = Uri.parse( - '${Env.apiUrl}enquiry/enquiryList?$query&from_date=${fromDate ?? ''}&to_date=${toDate ?? ''}', + '${Env.apiUrl}enquiry/enquiryList?$query&from_date=${fromDate ?? ''}&to_date=${toDate ?? ''}&status=$selectedStatus&staff_id=$selectedStaffId', ); // if (role == 'manager') { @@ -757,7 +781,7 @@ class ApiService { // ); final headers = { 'Authorization': 'Bearer $_token' ?? '', - 'App-Signature': 'nhance-partner-2025-signature-35468846JRhH551HK', + 'app-signature': Env.App_Signature, }; final response = await _makeGetRequest(url, headers); return response; @@ -768,6 +792,7 @@ class ApiService { role, { String? fromDate, String? toDate, + String? selectedStaffId, }) async { // print(_token); if (_token == null) { @@ -787,7 +812,7 @@ class ApiService { } final url = Uri.parse( - '${Env.apiUrl}enquiry/enquiryList?$query&only_policy_data=true&from_date=${fromDate ?? ''}&to_date=${toDate ?? ''}', + '${Env.apiUrl}enquiry/enquiryList?$query&only_policy_data=true&from_date=${fromDate ?? ''}&to_date=${toDate ?? ''}&staff_id=$selectedStaffId', ); // if (role == 'manager') { @@ -809,7 +834,7 @@ class ApiService { // ); final headers = { 'Authorization': 'Bearer $_token' ?? '', - 'App-Signature': 'nhance-partner-2025-signature-35468846JRhH551HK', + 'app-signature': Env.App_Signature, }; final response = await _makeGetRequest(url, headers); return response; @@ -840,7 +865,7 @@ class ApiService { // ); final headers = { 'Authorization': 'Bearer $_token' ?? '', - 'App-Signature': 'nhance-partner-2025-signature-35468846JRhH551HK', + 'app-signature': Env.App_Signature, }; final response = await _makeGetRequest(url, headers); return response; @@ -855,7 +880,7 @@ class ApiService { final headers = { 'Authorization': 'Bearer $_token' ?? '', - 'App-Signature': 'nhance-partner-2025-signature-35468846JRhH551HK', + 'app-signature': Env.App_Signature, }; final response = await _makeGetRequest(url, headers); return response; @@ -888,7 +913,7 @@ class ApiService { // ); final headers = { 'Authorization': 'Bearer $_token' ?? '', - 'App-Signature': 'nhance-partner-2025-signature-35468846JRhH551HK', + 'app-signature': Env.App_Signature, }; final response = await _makeGetRequest(url, headers); return response; @@ -905,7 +930,7 @@ class ApiService { final headers = { 'Authorization': 'Bearer $_token' ?? '', - 'App-Signature': 'nhance-partner-2025-signature-35468846JRhH551HK', + 'app-signature': Env.App_Signature, }; final response = await _makeGetRequest(url, headers); return response; @@ -941,7 +966,7 @@ class ApiService { final headers = { 'Authorization': 'Bearer $_token' ?? '', - 'App-Signature': 'nhance-partner-2025-signature-35468846JRhH551HK', + 'app-signature': Env.App_Signature, }; final response = await _makeGetRequest(url, headers); return response; @@ -961,7 +986,7 @@ class ApiService { print('fetchHandlerNameDropDown 2'); final headers = { 'Authorization': 'Bearer $_token' ?? '', - 'App-Signature': 'nhance-partner-2025-signature-35468846JRhH551HK', + 'app-signature': Env.App_Signature, }; print('fetchHandlerNameDropDown 3'); final response = await _makeGetRequest(url, headers); @@ -985,7 +1010,7 @@ class ApiService { print('fetchHandlerNameDropDown 2'); final headers = { 'Authorization': 'Bearer $_token' ?? '', - 'App-Signature': 'nhance-partner-2025-signature-35468846JRhH551HK', + 'app-signature': Env.App_Signature, }; print('fetchHandlerNameDropDown 3'); final response = await _makeGetRequest(url, headers); @@ -1007,7 +1032,7 @@ class ApiService { print('fetchAGENTNameDropDown 2'); final headers = { 'Authorization': 'Bearer $_token' ?? '', - 'App-Signature': 'nhance-partner-2025-signature-35468846JRhH551HK', + 'app-signature': Env.App_Signature, }; print('fetchAGENTNameDropDown 3'); final response = await _makeGetRequest(url, headers); diff --git a/lib/presentation/providers/manager_provider.dart b/lib/presentation/providers/manager_provider.dart index 099526f..9b1f74b 100644 --- a/lib/presentation/providers/manager_provider.dart +++ b/lib/presentation/providers/manager_provider.dart @@ -11,3 +11,7 @@ final staffIndiviualAttendanceIdProvider = StateProvider( final staffIndiviualAttendanceNameIdProvider = StateProvider( (ref) => null, ); + +final dashboardKeyProvider = StateProvider((ref) => null); +final dashboardStatusProvider = StateProvider((ref) => null); +final dashboardStaffIdProvider = StateProvider((ref) => null); diff --git a/lib/presentation/screens/Enquiry/enquiry/enquiry_tab.dart b/lib/presentation/screens/Enquiry/enquiry/enquiry_tab.dart index f3cfbca..5ba6bc7 100644 --- a/lib/presentation/screens/Enquiry/enquiry/enquiry_tab.dart +++ b/lib/presentation/screens/Enquiry/enquiry/enquiry_tab.dart @@ -468,8 +468,7 @@ class EnquiryTabState extends ConsumerState { // Use MultipartRequest (POST only) final request = http.MultipartRequest('POST', uri); request.headers['Authorization'] = 'Bearer $_token'; - request.headers['app-signature'] = - 'nhance-partner-2025-signature-35468846JRhH551HK'; + request.headers['app-signature'] = Env.App_Signature; // If updating, spoof the method Laravel-style if (isUpdating) { @@ -532,6 +531,8 @@ class EnquiryTabState extends ConsumerState { } } setState(() => isSaving = false); + } else if (response.statusCode == 403) { + await apiService.clearLocalStorageAndRedirect(); } else { print("❌ Submission failed. Status: ${response.statusCode}"); print("Body: ${response.body}"); @@ -755,7 +756,7 @@ class EnquiryTabState extends ConsumerState { Widget buildName(BuildContext context) { return buildResponsiveField( - label: "Full Name *", + label: "Insured Name *", field: ThemedFormField( controller: controllers['name']!, @@ -773,6 +774,9 @@ class EnquiryTabState extends ConsumerState { field: ThemedFormField( controller: controllers['email']!, validator: (value) => Validators.email(value, "email"), + inputFormatters: [ + FilteringTextInputFormatter.allow(RegExp(r'[a-zA-Z0-9_@.]')), + ], txtwidth: ResponsiveLayout.isMobile(context) ? null : MediaQuery.of(context).size.width * 0.26, @@ -786,6 +790,7 @@ class EnquiryTabState extends ConsumerState { field: ThemedFormField( controller: controllers['mobile']!, validator: (value) => Validators.phone(value, "phNumber"), + inputFormatters: [FilteringTextInputFormatter.allow(RegExp(r'[ 0-9]'))], txtwidth: ResponsiveLayout.isMobile(context) ? null : MediaQuery.of(context).size.width * 0.26, @@ -795,7 +800,7 @@ class EnquiryTabState extends ConsumerState { Widget buildId(BuildContext context) { return buildResponsiveField( - label: "Registration Number *", + label: "Vehicle Number *", field: ThemedFormField( controller: controllers['regNo']!, inputFormatters: [ diff --git a/lib/presentation/screens/Enquiry/enquiry/policy_popup.dart b/lib/presentation/screens/Enquiry/enquiry/policy_popup.dart index 062c04b..67b4f4b 100644 --- a/lib/presentation/screens/Enquiry/enquiry/policy_popup.dart +++ b/lib/presentation/screens/Enquiry/enquiry/policy_popup.dart @@ -216,55 +216,6 @@ class _AddDialogState extends State { } } - Future createUserData1(data, val) async { - // final bool isUpdating = widget.id != null && widget.id != 'create'; - final String apiUrldata; - - apiUrldata = (val == 'Claims') - ? '${Env.apiUrl}claim/createClaim' - : '${Env.apiUrl}endorsement/createEndorsement'; - - // final token = await getToken(); // Fetch token - - if (_token == null) { - throw Exception('Token not found. Please log in.'); - } - - print("data------- $data}"); - - try { - final response = await http.post( - Uri.parse(apiUrldata), - headers: { - 'Authorization': 'Bearer $_token', - 'Content-Type': 'application/json', - 'app-signature': 'nhance-partner-2025-signature-35468846JRhH551HK', - }, - body: jsonEncode(data), // Convert map to JSON - ); - - if (response.statusCode == 200) { - print("Staff submitted successfully!"); - print("Response: ${response.body}"); - ToastHelper.showSuccessToast(context, 'Saved Successfully'); - Navigator.of(context).pop(); - - widget.onSubmit("success"); - // context.go(AppRoutes.staffLst); - } else { - final responseBody = jsonDecode(response.body); - dynamic msg = responseBody['data']; - - print("Failed to submit plan. Status: ${response.statusCode}"); - print("Error: ${response.body}"); - - ToastHelper.showErrorToast(context, 'Failed To Save'); - } - } catch (e) { - print(" Error submitting Staff: $e"); - } - } - Future createUserData(data, val) async { final Uri uri = (val == 'Claims') ? Uri.parse('${Env.apiUrl}claim/createClaim') @@ -277,8 +228,7 @@ class _AddDialogState extends State { // Use MultipartRequest (POST only) final request = http.MultipartRequest('POST', uri); request.headers['Authorization'] = 'Bearer $_token'; - request.headers['app-signature'] = - 'nhance-partner-2025-signature-35468846JRhH551HK'; + request.headers['app-signature'] = Env.App_Signature; print("USerDAta - $data"); @@ -360,6 +310,8 @@ class _AddDialogState extends State { Navigator.of(context).pop(); widget.onSubmit("success"); + } else if (response.statusCode == 403) { + await apiService.clearLocalStorageAndRedirect(); } else { final responseBody = jsonDecode(response.body); dynamic msg = responseBody['data']; diff --git a/lib/presentation/screens/Enquiry/enquiry/policy_tab.dart b/lib/presentation/screens/Enquiry/enquiry/policy_tab.dart index 957f0e4..7a3592c 100644 --- a/lib/presentation/screens/Enquiry/enquiry/policy_tab.dart +++ b/lib/presentation/screens/Enquiry/enquiry/policy_tab.dart @@ -712,9 +712,10 @@ class PolicyTabState extends ConsumerState { Widget buildName(BuildContext context) { return buildResponsiveField( - label: "Registration Number", + label: "Vehicle Number", field: ThemedFormField( controller: controllers['regNum']!, + readOnly: true, // validator: (value) => Validators.requiredField(value, "name"), txtwidth: ResponsiveLayout.isMobile(context) ? null @@ -725,9 +726,10 @@ class PolicyTabState extends ConsumerState { Widget buildInsusrer(BuildContext context) { return buildResponsiveField( - label: "Insusrer", + label: "Insurer", field: ThemedFormField( controller: controllers['insurer']!, + readOnly: true, txtwidth: ResponsiveLayout.isMobile(context) ? null : MediaQuery.of(context).size.width * 0.26, @@ -740,7 +742,8 @@ class PolicyTabState extends ConsumerState { label: "IDV", field: ThemedFormField( controller: controllers['idv']!, - validator: (value) => Validators.phone(value, "phNumber"), + readOnly: true, + // validator: (value) => Validators.phone(value, "phNumber"), txtwidth: ResponsiveLayout.isMobile(context) ? null : MediaQuery.of(context).size.width * 0.26, @@ -753,6 +756,7 @@ class PolicyTabState extends ConsumerState { label: "Insured Name", field: ThemedFormField( controller: controllers['insurerName']!, + readOnly: true, // validator: (value) => Validators.phone(value, "phNumber"), txtwidth: ResponsiveLayout.isMobile(context) ? null @@ -766,6 +770,7 @@ class PolicyTabState extends ConsumerState { label: "Policy Number", field: ThemedFormField( controller: controllers['policyNo']!, + readOnly: true, // validator: (value) => Validators.phone(value, "phNumber"), txtwidth: ResponsiveLayout.isMobile(context) ? null @@ -778,6 +783,7 @@ class PolicyTabState extends ConsumerState { return buildResponsiveField( label: "Payment Mode", field: ThemedFormField( + readOnly: true, controller: controllers['paymentMode']!, txtwidth: ResponsiveLayout.isMobile(context) ? null @@ -791,7 +797,8 @@ class PolicyTabState extends ConsumerState { label: "Plan Type", field: ThemedFormField( controller: controllers['planType']!, - validator: (value) => Validators.phone(value, "phNumber"), + readOnly: true, + // validator: (value) => Validators.phone(value, "phNumber"), txtwidth: ResponsiveLayout.isMobile(context) ? null : MediaQuery.of(context).size.width * 0.26, @@ -804,7 +811,8 @@ class PolicyTabState extends ConsumerState { label: "Premium Amount", field: ThemedFormField( controller: controllers['premAmount']!, - validator: (value) => Validators.phone(value, "phNumber"), + readOnly: true, + // validator: (value) => Validators.phone(value, "phNumber"), txtwidth: ResponsiveLayout.isMobile(context) ? null : MediaQuery.of(context).size.width * 0.26, diff --git a/lib/presentation/screens/Enquiry/enquiry/quotation_tab.dart b/lib/presentation/screens/Enquiry/enquiry/quotation_tab.dart index 3d87d70..69d6d0c 100644 --- a/lib/presentation/screens/Enquiry/enquiry/quotation_tab.dart +++ b/lib/presentation/screens/Enquiry/enquiry/quotation_tab.dart @@ -4,6 +4,7 @@ import 'package:dropdown_search/dropdown_search.dart'; import 'package:file_picker/file_picker.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:http/http.dart' as http; import 'package:nhance_partner/presentation/providers/userRoleProvider.dart'; @@ -297,7 +298,7 @@ class QuotationTabState extends ConsumerState { headers: { 'Authorization': 'Bearer $_token', 'Content-Type': 'application/json', - 'app-signature': 'nhance-partner-2025-signature-35468846JRhH551HK', + 'app-signature': Env.App_Signature, }, body: jsonEncode(data), // Convert map to JSON ); @@ -321,6 +322,8 @@ class QuotationTabState extends ConsumerState { // tabKey.currentState?.loadQuotationTab(widget.id ?? ""); // }); // context.go(AppRoutes.staffLst); + } else if (response.statusCode == 403) { + await apiService.clearLocalStorageAndRedirect(); } else { final responseBody = jsonDecode(response.body); dynamic msg = responseBody['data']; @@ -349,8 +352,7 @@ class QuotationTabState extends ConsumerState { // Use MultipartRequest (POST only) final request = http.MultipartRequest('POST', uri); request.headers['Authorization'] = 'Bearer $_token'; - request.headers['app-signature'] = - 'nhance-partner-2025-signature-35468846JRhH551HK'; + request.headers['app-signature'] = Env.App_Signature; print("USerDAta - $userData"); @@ -408,6 +410,8 @@ class QuotationTabState extends ConsumerState { await widget.onRefresh!(); } // context.go(AppRoutes.agentLst); + } else if (response.statusCode == 403) { + await apiService.clearLocalStorageAndRedirect(); } else { final responseBody = jsonDecode(response.body); dynamic msg = responseBody['data']; @@ -643,7 +647,7 @@ class QuotationTabState extends ConsumerState { Widget buildName(BuildContext context) { return buildResponsiveField( - label: "Registration Number", + label: "Vehicle Number", field: ThemedFormField( controller: controllers['regNum']!, readOnly: true, @@ -657,7 +661,7 @@ class QuotationTabState extends ConsumerState { Widget buildInsusrer(BuildContext context) { return buildResponsiveField( - label: "Insusrer", + label: "Insurer", field: ThemedFormField( controller: controllers['insurer']!, readOnly: true, @@ -674,6 +678,7 @@ class QuotationTabState extends ConsumerState { field: ThemedFormField( controller: controllers['idv']!, readOnly: true, + txtwidth: ResponsiveLayout.isMobile(context) ? null : MediaQuery.of(context).size.width * 0.26, @@ -709,7 +714,7 @@ class QuotationTabState extends ConsumerState { Widget buildDocuments(BuildContext context) { return buildResponsiveUploadField( - label: 'Quotation Documents', + label: 'Proposal Documents', hintText: selectedFileNames, onFileSelected: (fileName, file) { setState(() { @@ -915,7 +920,7 @@ class QuotationTabState extends ConsumerState { Widget buildId(BuildContext context) { return buildResponsiveField( - label: "Registration Number *", + label: "Vehicle Number *", field: ThemedFormField( controller: controllers['regNo']!, validator: (value) => Validators.requiredField(value, "regNo"), @@ -936,10 +941,7 @@ class QuotationTabState extends ConsumerState { child: const Row( children: [ Expanded(flex: 1, child: Text(' ', style: _headerStyle)), - Expanded( - flex: 1, - child: Text('Registration Number', style: _headerStyle), - ), + Expanded(flex: 1, child: Text('Vehicle Number', style: _headerStyle)), Expanded(flex: 1, child: Text('Insurer', style: _headerStyle)), Expanded(flex: 1, child: Text('IDV', style: _headerStyle)), Expanded(flex: 1, child: Text('Plan Type', style: _headerStyle)), diff --git a/lib/presentation/screens/Enquiry/enquiry/tabs.dart b/lib/presentation/screens/Enquiry/enquiry/tabs.dart index 13f0ef3..66f2276 100644 --- a/lib/presentation/screens/Enquiry/enquiry/tabs.dart +++ b/lib/presentation/screens/Enquiry/enquiry/tabs.dart @@ -50,7 +50,7 @@ class TabEnquiryListState extends ConsumerState { setState(() => isLoading = false); tabs = [ TabItem("Enquiry", EnquiryTab()), - TabItem("Quotation", QuotationTab()), + TabItem("Proposal", QuotationTab()), TabItem("Policy", PolicyTab()), ]; } @@ -86,7 +86,7 @@ class TabEnquiryListState extends ConsumerState { EnquiryTab(data: enquiryData?["enquiry"], id: id ?? ""), ), TabItem( - "Quotation", + "Proposal", QuotationTab( data: (enquiryData?["quotations"] as List?) @@ -121,7 +121,7 @@ class TabEnquiryListState extends ConsumerState { // ), ), - // TabItem("Quotation", QuotationTab(data: enquiryData?["quotations"])), + // TabItem("Proposal", QuotationTab(data: enquiryData?["quotations"])), // TabItem("Policy", PolicyTab()), ]; }); @@ -141,7 +141,7 @@ class TabEnquiryListState extends ConsumerState { EnquiryTab(data: enquiryData?["enquiry"], id: id ?? ""), ), TabItem( - "Quotation", + "Proposal", QuotationTab( data: (enquiryData?["quotations"] as List?) diff --git a/lib/presentation/screens/Enquiry/enquiryList.dart b/lib/presentation/screens/Enquiry/enquiryList.dart index 474a1b9..abdb23d 100644 --- a/lib/presentation/screens/Enquiry/enquiryList.dart +++ b/lib/presentation/screens/Enquiry/enquiryList.dart @@ -32,6 +32,9 @@ class EnquiryListState extends ConsumerState { late ApiService apiService; dynamic roleId; dynamic userId; + dynamic SelectedStatus; + dynamic SelectedStaffId; + late final String? selectedStatusVal; final _formKey = GlobalKey(); // List> dataVal = []; @@ -82,26 +85,27 @@ class EnquiryListState extends ConsumerState { } void filterDateRange() { - // ✅ Validate the form first - if (!_formKey.currentState!.validate()) { - // stop execution if validation fails - return; - } + print('SelectedStatus - $SelectedStatus'); + // // ✅ Validate the form first + // if (!_formKey.currentState!.validate()) { + // // stop execution if validation fails + // return; + // } + // + // final fromDateText = controllers['startDate']?.text ?? ''; + // final toDateText = controllers['endDate']?.text ?? ''; - final fromDateText = controllers['startDate']?.text ?? ''; - final toDateText = controllers['endDate']?.text ?? ''; - - // Optional: double-check End >= Start - final fromDate = DateFormat('dd-MM-yyyy').parse(fromDateText); - final toDate = DateFormat('dd-MM-yyyy').parse(toDateText); - - if (toDate.isBefore(fromDate)) { - // This is already caught by the validator, but extra safety - ScaffoldMessenger.of(context).showSnackBar( - SnackBar(content: Text("End Date cannot be earlier than Start Date")), - ); - return; - } + // // Optional: double-check End >= Start + // final fromDate = DateFormat('dd-MM-yyyy').parse(fromDateText); + // final toDate = DateFormat('dd-MM-yyyy').parse(toDateText); + // + // if (toDate.isBefore(fromDate)) { + // // This is already caught by the validator, but extra safety + // ScaffoldMessenger.of(context).showSnackBar( + // SnackBar(content: Text("End Date cannot be earlier than Start Date")), + // ); + // return; + // } // ✅ Call your API getStaffList(userId, roleId); @@ -109,6 +113,8 @@ class EnquiryListState extends ConsumerState { void refrshfilterDateRange() { setState(() { + SelectedStatus = ''; + SelectedStaffId = null; controllers['startDate']!.clear(); controllers['endDate']!.clear(); @@ -184,6 +190,8 @@ class EnquiryListState extends ConsumerState { role, fromDate: controllers['startDate']?.text ?? '', toDate: controllers['endDate']?.text ?? '', + selectedStatus: SelectedStatus != null ? SelectedStatus : '', + selectedStaffId: SelectedStaffId ?? '', ); if (response['status'] == 'success') { @@ -384,7 +392,7 @@ class EnquiryListState extends ConsumerState { ), const SizedBox(width: 5), // spacing between icon and text Text( - "Enquiries", + "Enquiries ", style: GoogleFonts.inter( fontSize: ResponsiveLayout.isMobile(context) ? 14 : 18, fontWeight: FontWeight.w600, @@ -451,8 +459,20 @@ class EnquiryListState extends ConsumerState { padding: EdgeInsets.all(8.0), color: Color(0xffD9EBE8), child: DateFilterRow( + key: ValueKey(SelectedStatus ?? ''), + role: roleId, + id: userId, + onFilterStaff: (val) { + print('Selected Filterd STAFF Id - $val'); + SelectedStaffId = val; + }, + selectedStaffId: SelectedStaffId, + selectedStatusVal: SelectedStatus, startController: controllers['startDate']!, endController: controllers['endDate']!, + onStatusChanged: (val) { + SelectedStatus = val; // update parent + }, formKey: _formKey, isMobile: ResponsiveLayout.isMobile(context), onFilter: () { @@ -476,8 +496,21 @@ class EnquiryListState extends ConsumerState { children: [ if (!ResponsiveLayout.isMobile(context)) ...[ DateFilterRow( + role: roleId, + id: userId, + key: ValueKey(SelectedStatus ?? ''), + onFilterStaff: (val) { + print('Selected Filterd STAFF Id - $val'); + SelectedStaffId = val; + }, + selectedStaffId: SelectedStaffId, + selectedStatusVal: SelectedStatus, startController: controllers['startDate']!, endController: controllers['endDate']!, + onStatusChanged: (val) { + SelectedStatus = val; // update parent + }, + formKey: _formKey, isMobile: ResponsiveLayout.isMobile(context), onFilter: () { @@ -500,7 +533,7 @@ class EnquiryListState extends ConsumerState { controller: _searchStaffController, txtwidth: ResponsiveLayout.isMobile(context) ? MediaQuery.of(context).size.width * 0.6 - : MediaQuery.of(context).size.width * 0.2, + : MediaQuery.of(context).size.width * 0.13, ), ResponsiveLayout.isMobile(context) ? Spacer() diff --git a/lib/presentation/screens/Enquiry/policy_claims_endros/sub_claims.dart b/lib/presentation/screens/Enquiry/policy_claims_endros/sub_claims.dart index 217cb34..0c5dfe3 100644 --- a/lib/presentation/screens/Enquiry/policy_claims_endros/sub_claims.dart +++ b/lib/presentation/screens/Enquiry/policy_claims_endros/sub_claims.dart @@ -282,7 +282,13 @@ class ClaimsSubListState extends ConsumerState { ), Expanded( flex: 2, - child: Text(item['claim_status_value'] ?? '-', style: _dataBold), + child: Text( + item['claim_status_value'] != null + ? '${item['claim_status_value'][0].toUpperCase()}${item['claim_status_value'].substring(1).toLowerCase()}' + : '-', + style: _dataBold, + ), + // child: Text(item['claim_status_value'] ?? '-', style: _dataBold), ), // Expanded( diff --git a/lib/presentation/screens/StaffAttendance/attendanceAllDetails.dart b/lib/presentation/screens/StaffAttendance/attendanceAllDetails.dart index 7c4d83f..785c8f6 100644 --- a/lib/presentation/screens/StaffAttendance/attendanceAllDetails.dart +++ b/lib/presentation/screens/StaffAttendance/attendanceAllDetails.dart @@ -144,6 +144,7 @@ class AttendanceAllDetailsState extends ConsumerState { try { final response = await apiService.fetchAttndanceOFAllStaffList( month: monthForApi, + mangerId: managerId, // toDate: controllers['endDate']?.text ?? '', ); diff --git a/lib/presentation/screens/StaffAttendance/individual_Attendance.dart b/lib/presentation/screens/StaffAttendance/individual_Attendance.dart index a926da2..e0e133f 100644 --- a/lib/presentation/screens/StaffAttendance/individual_Attendance.dart +++ b/lib/presentation/screens/StaffAttendance/individual_Attendance.dart @@ -441,7 +441,7 @@ class IndividualAttendanceDetailsState Expanded(flex: 2, child: Text('Date', style: _headerStyle)), Expanded(flex: 2, child: Text('Login', style: _headerStyle)), - Expanded(flex: 2, child: Text('Login Time', style: _headerStyle)), + Expanded(flex: 2, child: Text('Logout', style: _headerStyle)), Expanded( flex: 2, child: Text('Number Of Hours', style: _headerStyle), diff --git a/lib/presentation/screens/UserManagement/Agent/agent.dart b/lib/presentation/screens/UserManagement/Agent/agent.dart index fe147b4..83158ba 100644 --- a/lib/presentation/screens/UserManagement/Agent/agent.dart +++ b/lib/presentation/screens/UserManagement/Agent/agent.dart @@ -5,6 +5,7 @@ import 'package:file_picker/file_picker.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:go_router/go_router.dart'; import 'package:http/http.dart' as http; @@ -151,8 +152,7 @@ class AgentState extends ConsumerState { // Use MultipartRequest (POST only) final request = http.MultipartRequest('POST', uri); request.headers['Authorization'] = 'Bearer $_token'; - request.headers['app-signature'] = - 'nhance-partner-2025-signature-35468846JRhH551HK'; + request.headers['app-signature'] = Env.App_Signature; // If updating, spoof the method Laravel-style if (isUpdating) { @@ -248,6 +248,8 @@ class AgentState extends ConsumerState { 'Partner Created Successfully', ); context.go(AppRoutes.agentLst); + } else if (response.statusCode == 403) { + await apiService.clearLocalStorageAndRedirect(); } else { final responseBody = jsonDecode(response.body); dynamic msg = responseBody['data']; @@ -491,6 +493,9 @@ class AgentState extends ConsumerState { ThemedFormField( controller: controllers['email']!, validator: (value) => Validators.email(value, "email"), + inputFormatters: [ + FilteringTextInputFormatter.allow(RegExp(r'[a-zA-Z0-9_@.]')), + ], txtwidth: MediaQuery.of(context).size.width * 0.26, ), ], @@ -506,6 +511,9 @@ class AgentState extends ConsumerState { ThemedFormField( controller: controllers['mobile']!, validator: (value) => Validators.phone(value, "phNumber"), + inputFormatters: [ + FilteringTextInputFormatter.allow(RegExp(r'[ 0-9]')), + ], txtwidth: MediaQuery.of(context).size.width * 0.26, ), ], diff --git a/lib/presentation/screens/UserManagement/Agent/agentIncentiveFile.dart b/lib/presentation/screens/UserManagement/Agent/agentIncentiveFile.dart index 9a78bc8..60446ad 100644 --- a/lib/presentation/screens/UserManagement/Agent/agentIncentiveFile.dart +++ b/lib/presentation/screens/UserManagement/Agent/agentIncentiveFile.dart @@ -241,8 +241,7 @@ class UploadIncentiveModalState extends ConsumerState { // Use MultipartRequest (POST only) final request = http.MultipartRequest('POST', uri); request.headers['Authorization'] = 'Bearer $_token'; - request.headers['app-signature'] = - 'nhance-partner-2025-signature-35468846JRhH551HK'; + request.headers['app-signature'] = Env.App_Signature; print("USerDAta - $dataSet"); @@ -337,6 +336,8 @@ class UploadIncentiveModalState extends ConsumerState { } // context.go(AppRoutes.agentLst); + } else if (response.statusCode == 403) { + await apiService.clearLocalStorageAndRedirect(); } else { print("❌ Submission failed. Status: ${response.statusCode}"); print("📨 Body: ${response.body}"); diff --git a/lib/presentation/screens/UserManagement/Profile/profile_mobile.dart b/lib/presentation/screens/UserManagement/Profile/profile_mobile.dart index 5078308..6611e19 100644 --- a/lib/presentation/screens/UserManagement/Profile/profile_mobile.dart +++ b/lib/presentation/screens/UserManagement/Profile/profile_mobile.dart @@ -209,7 +209,10 @@ class ProfileState extends ConsumerState { ), Text( // profileData?['role'] ?? '-', - role ?? '-', + (role == 'agent') + ? 'partner' + : role ?? '-', + // role ?? '-', style: TextStyle( fontSize: 14, fontWeight: FontWeight.w400, @@ -248,7 +251,8 @@ class ProfileState extends ConsumerState { ), const SizedBox(height: 16), if (profileData?['role_id'] != '1' && - profileData?['role_id'] != '2') ...[ + profileData?['role_id'] != '2' && + profileData?['role_id'] != '3') ...[ Row( crossAxisAlignment: CrossAxisAlignment.start, @@ -272,7 +276,7 @@ class ProfileState extends ConsumerState { const SizedBox(height: 20), ], - if (profileData?['role_id'] != 2) ...[ + if (profileData?['role_id'] != 3) ...[ Container( padding: const EdgeInsets.all(6), color: Color(0xffEDF6F5), @@ -281,11 +285,12 @@ class ProfileState extends ConsumerState { print("Download - $latestId"); dynamic path; - if (roleId == 1) { + if (roleId == 1 && + roleId == 2 && + roleId == 3) { path = - 'api/agent/downloadManagerIncentiveFile?id=$latestId'; - } else if (roleId != 1 && - roleId != 2) { + 'api/staff/downloadManagerIncentiveFile?id=$latestId'; + } else { path = 'api/agent/downloadAgentIncentiveFile?id=$latestId'; } @@ -375,11 +380,12 @@ class ProfileState extends ConsumerState { dynamic path; - if (roleId == 1) { + if (roleId == 1 && + roleId == 2 && + roleId == 3) { path = - 'api/agent/downloadManagerIncentiveFile?id=$selectedId'; - } else if (roleId != 1 && - roleId != 2) { + 'api/staff/downloadManagerIncentiveFile?id=$selectedId'; + } else { path = 'api/agent/downloadAgentIncentiveFile?id=$selectedId'; } @@ -508,7 +514,8 @@ class ProfileState extends ConsumerState { ), const SizedBox(height: 16), if (profileData?['role_id'] != '1' && - profileData?['role_id'] != '2') ...[ + profileData?['role_id'] != '2' && + profileData?['role_id'] != '3') ...[ Row( crossAxisAlignment: CrossAxisAlignment.start, @@ -532,7 +539,7 @@ class ProfileState extends ConsumerState { const SizedBox(height: 20), ], - if (profileData?['role_id'] != 2) ...[ + if (profileData?['role_id'] != 3) ...[ Container( padding: const EdgeInsets.all(6), color: Color(0xffEDF6F5), @@ -541,11 +548,14 @@ class ProfileState extends ConsumerState { print("Download - $latestId"); dynamic path; - if (roleId == 1) { + if (roleId == 1 && + roleId == 2 && + roleId == 3) { + print('teRole - $roleId'); + path = - 'api/agent/downloadManagerIncentiveFile?id=$latestId'; - } else if (roleId != 1 && - roleId != 2) { + 'api/staff/downloadManagerIncentiveFile?id=$latestId'; + } else { path = 'api/agent/downloadAgentIncentiveFile?id=$latestId'; } @@ -635,11 +645,12 @@ class ProfileState extends ConsumerState { dynamic path; - if (roleId == 1) { + if (roleId == 1 && + roleId == 2 && + roleId == 3) { path = - 'api/agent/downloadManagerIncentiveFile?id=$selectedId'; - } else if (roleId != 1 && - roleId != 2) { + 'api/staff/downloadManagerIncentiveFile?id=$selectedId'; + } else { path = 'api/agent/downloadAgentIncentiveFile?id=$selectedId'; } diff --git a/lib/presentation/screens/UserManagement/Profile/profile_web.dart b/lib/presentation/screens/UserManagement/Profile/profile_web.dart index dc7682d..1fb52d7 100644 --- a/lib/presentation/screens/UserManagement/Profile/profile_web.dart +++ b/lib/presentation/screens/UserManagement/Profile/profile_web.dart @@ -227,7 +227,7 @@ class ProfilePopUpState extends ConsumerState { style: _headerStyle, ), Text( - role ?? '-', + (role == 'agent') ? 'partner' : role ?? '-', style: TextStyle( fontSize: 14, fontWeight: FontWeight.w400, @@ -300,7 +300,7 @@ class ProfilePopUpState extends ConsumerState { if (roleId == 1) { path = - 'api/agent/downloadManagerIncentiveFile?id=$latestId'; + 'api/staff/downloadManagerIncentiveFile?id=$latestId'; } else if (roleId != 1 && roleId != 2) { path = 'api/agent/downloadAgentIncentiveFile?id=$latestId'; @@ -383,7 +383,7 @@ class ProfilePopUpState extends ConsumerState { if (roleId == 1) { path = - 'api/agent/downloadManagerIncentiveFile?id=$selectedId'; + 'api/staff/downloadManagerIncentiveFile?id=$selectedId'; } else if (roleId != 1 && roleId != 2) { path = 'api/agent/downloadAgentIncentiveFile?id=$selectedId'; diff --git a/lib/presentation/screens/UserManagement/Staff/staff.dart b/lib/presentation/screens/UserManagement/Staff/staff.dart index 20836ba..f190420 100644 --- a/lib/presentation/screens/UserManagement/Staff/staff.dart +++ b/lib/presentation/screens/UserManagement/Staff/staff.dart @@ -4,6 +4,7 @@ import 'dart:typed_data'; // Import for Uint8List import 'package:dropdown_search/dropdown_search.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:go_router/go_router.dart'; import 'package:http/http.dart' as http; @@ -183,7 +184,7 @@ class StaffState extends ConsumerState { headers: { 'Authorization': 'Bearer $_token', 'Content-Type': 'application/json', - 'app-signature': 'nhance-partner-2025-signature-35468846JRhH551HK', + 'app-signature': Env.App_Signature, }, body: jsonEncode(data), // Convert map to JSON ); @@ -202,6 +203,8 @@ class StaffState extends ConsumerState { 'Staff Created Successfully', ); context.go(AppRoutes.staffLst); + } else if (response.statusCode == 403) { + await apiService.clearLocalStorageAndRedirect(); } else { final responseBody = jsonDecode(response.body); dynamic msg = responseBody['data']; @@ -475,6 +478,9 @@ class StaffState extends ConsumerState { ThemedFormField( controller: controllers['email']!, validator: (value) => Validators.email(value, "email"), + inputFormatters: [ + FilteringTextInputFormatter.allow(RegExp(r'[a-zA-Z0-9_@.]')), + ], txtwidth: MediaQuery.of(context).size.width * 0.26, ), ], @@ -490,6 +496,9 @@ class StaffState extends ConsumerState { ThemedFormField( controller: controllers['mobile']!, validator: (value) => Validators.phone(value, "phNumber"), + inputFormatters: [ + FilteringTextInputFormatter.allow(RegExp(r'[ 0-9]')), + ], txtwidth: MediaQuery.of(context).size.width * 0.26, ), ], diff --git a/lib/presentation/screens/dashboard/dashboard.dart b/lib/presentation/screens/dashboard/dashboard.dart index 825e82d..b90923c 100644 --- a/lib/presentation/screens/dashboard/dashboard.dart +++ b/lib/presentation/screens/dashboard/dashboard.dart @@ -1344,29 +1344,70 @@ class othersPendings extends StatelessWidget { ), Expanded( flex: 2, - child: Text( - row['awaiting_quotation'] ?? "", - // row['total_approval_pending'] ?? "", - textAlign: TextAlign.center, - style: _tableDataStyle, + child: InkWell( + onTap: () { + print( + 'Awaiting Proposal : ${row['awaiting_quotation']}', + ); + + handleDashboardNavigation( + context, + status: "Awaiting Proposal", + staffId: row['staff_id'], + role: role, + ); + }, + child: Text( + row['awaiting_quotation'] ?? "", + // row['total_approval_pending'] ?? "", + textAlign: TextAlign.center, + style: _tableDataStyle, + ), ), ), Expanded( flex: 2, - child: Text( - row['pending_quotation_approval'] ?? "", - // row['total_approval_pending'] ?? "", - textAlign: TextAlign.center, - style: _tableDataStyle, + child: InkWell( + onTap: () async { + print( + 'Awaiting Approval : ${row['pending_quotation_approval']} - ${row['staff_id']}', + ); + handleDashboardNavigation( + context, + status: "Proposal Created", + staffId: row['staff_id'], + role: role, + ); + }, + child: Text( + row['pending_quotation_approval'] ?? "", + // row['total_approval_pending'] ?? "", + textAlign: TextAlign.center, + style: _tableDataStyle, + ), ), ), Expanded( flex: 2, - child: Text( - row['awaiting_policy'] ?? "", - // row['total_approval_pending'] ?? "", - textAlign: TextAlign.center, - style: _tableDataStyle, + child: InkWell( + onTap: () { + print( + 'Awaiting Policy : ${row['awaiting_policy']}', + ); + + handleDashboardNavigation( + context, + status: "Proposal Accepted", + staffId: row['staff_id'], + role: role, + ); + }, + child: Text( + row['awaiting_policy'] ?? "", + // row['total_approval_pending'] ?? "", + textAlign: TextAlign.center, + style: _tableDataStyle, + ), ), ), // Expanded( @@ -1884,6 +1925,34 @@ class UnassignedEnq extends StatelessWidget { } } +Future handleDashboardNavigation( + BuildContext context, { + required String status, + required String staffId, + required String role, +}) async { + print('Dashboard Tap => Status: $status | Staff: $staffId'); + + final prefs = await SharedPreferences.getInstance(); + + // ✅ Clear any old data + await prefs.remove('dashboardKeyProvider'); + await prefs.remove('dashboardStatusProvider'); + await prefs.remove('dashboardStaffIdProvider'); + + // ✅ Save new values + await prefs.setString('dashboardKeyProvider', 'fromDashboard'); + await prefs.setString('dashboardStatusProvider', status); + await prefs.setString('dashboardStaffIdProvider', staffId); + + // ✅ Navigate + if (role == 'manager') { + context.go(AppRoutes.enquiryForStaff); + } else { + context.go(AppRoutes.enquiryHandlerLst); + } +} + final _headerStyle = GoogleFonts.inter( fontWeight: FontWeight.w600, fontSize: 14, diff --git a/lib/presentation/screens/handler/enquiryList.dart b/lib/presentation/screens/handler/enquiryList.dart index 20c66f6..493b52c 100644 --- a/lib/presentation/screens/handler/enquiryList.dart +++ b/lib/presentation/screens/handler/enquiryList.dart @@ -39,6 +39,9 @@ class EnquiryHandlerState extends ConsumerState { late ApiService apiService; dynamic userId; dynamic managerId; + dynamic dashboardKey; + dynamic SelectedStatus; + dynamic SelectedStaffId; dynamic handlerId; final _formKey = GlobalKey(); @@ -62,16 +65,44 @@ class EnquiryHandlerState extends ConsumerState { controllers[field] = TextEditingController(); } - Future.microtask(() { + Future.microtask(() async { final id = ref.read(managerIdProvider); roleId = ref.read(userRoleProvider); userId = ref.read(userIdProvider); managerId = ref.read(managerIdProvider); + + // dashboardKey = ref.read(dashboardKeyProvider); + // final dashboardStatus = ref.read(dashboardStatusProvider); + // final dashboardStaffId = ref.read(dashboardStaffIdProvider); + final prefs = await SharedPreferences.getInstance(); + dashboardKey = prefs.getString('dashboardKeyProvider'); + final dashboardStatus = prefs.getString('dashboardStatusProvider'); + final dashboardStaffId = prefs.getString('dashboardStaffIdProvider'); // handlerId = ref.read(handlerIdProvider); print('handlerIdENQ - $handlerId'); print("C72 => r : $roleId | mId: $id | uId: $userId !mID : $managerId "); - if (managerId != null) { + + print('dashboardKey - $dashboardKey'); + print('dashboardStatus - $dashboardStatus'); + print('dashboardStaffId - $dashboardStaffId'); + + if (managerId != null && + dashboardKey != null && + dashboardKey == 'fromDashboard' && + dashboardStatus != null && + dashboardStaffId != null) { + print("DASHBOARD STATus-$dashboardStatus -- $dashboardStaffId -"); + SelectedStatus = dashboardStatus; + SelectedStaffId = dashboardStaffId; + getStaffList( + managerId, + roleId, + SelectedStatus: dashboardStatus, + SelectedStaffId: dashboardStaffId, + ); + } else { + print('ELSE'); getStaffList(managerId, roleId); } }); @@ -89,26 +120,27 @@ class EnquiryHandlerState extends ConsumerState { } void filterDateRange() { - // ✅ Validate the form first - if (!_formKey.currentState!.validate()) { - // stop execution if validation fails - return; - } - - final fromDateText = controllers['startDate']?.text ?? ''; - final toDateText = controllers['endDate']?.text ?? ''; - - // Optional: double-check End >= Start - final fromDate = DateFormat('dd-MM-yyyy').parse(fromDateText); - final toDate = DateFormat('dd-MM-yyyy').parse(toDateText); - - if (toDate.isBefore(fromDate)) { - // This is already caught by the validator, but extra safety - ScaffoldMessenger.of(context).showSnackBar( - SnackBar(content: Text("End Date cannot be earlier than Start Date")), - ); - return; - } + // print('SelectedStatus - $SelectedStatus'); + // // ✅ Validate the form first + // if (!_formKey.currentState!.validate()) { + // // stop execution if validation fails + // return; + // } + // + // final fromDateText = controllers['startDate']?.text ?? ''; + // final toDateText = controllers['endDate']?.text ?? ''; + // + // // Optional: double-check End >= Start + // final fromDate = DateFormat('dd-MM-yyyy').parse(fromDateText); + // final toDate = DateFormat('dd-MM-yyyy').parse(toDateText); + // + // if (toDate.isBefore(fromDate)) { + // // This is already caught by the validator, but extra safety + // ScaffoldMessenger.of(context).showSnackBar( + // SnackBar(content: Text("End Date cannot be earlier than Start Date")), + // ); + // return; + // } // ✅ Call your API getStaffList(managerId, roleId); @@ -116,6 +148,8 @@ class EnquiryHandlerState extends ConsumerState { void refrshfilterDateRange() { setState(() { + SelectedStatus = ''; + SelectedStaffId = null; controllers['startDate']!.clear(); controllers['endDate']!.clear(); @@ -132,6 +166,8 @@ class EnquiryHandlerState extends ConsumerState { role, { String fromDate = '', String toDate = '', + String SelectedStatus = '', + String SelectedStaffId = '', }) async { print('A72 => Fns called => $managerId | $role'); setState(() { @@ -144,6 +180,8 @@ class EnquiryHandlerState extends ConsumerState { role, fromDate: controllers['startDate']?.text ?? '', toDate: controllers['endDate']?.text ?? '', + selectedStatus: SelectedStatus != null ? SelectedStatus : '', + selectedStaffId: SelectedStaffId ?? '', ); if (response['status'] == 'success') { @@ -516,13 +554,17 @@ class EnquiryHandlerState extends ConsumerState { Tooltip( message: 'Back', child: IconButton( - icon: const Icon(Icons.arrow_left_sharp), - onPressed: () { + icon: const Icon(Icons.arrow_left_sharp, size: 25), + onPressed: () async { context.go(AppRoutes.dashboard); + final prefs = await SharedPreferences.getInstance(); + await prefs.remove('dashboardKeyProvider'); + await prefs.remove('dashboardStatusProvider'); + await prefs.remove('dashboardStaffIdProvider'); }, - splashRadius: 28, + splashRadius: 18, + padding: const EdgeInsets.all(4), hoverColor: Colors.black12, - padding: const EdgeInsets.all(8), constraints: const BoxConstraints(), ), ), @@ -538,7 +580,7 @@ class EnquiryHandlerState extends ConsumerState { ), ), ), - SizedBox(height: 10), + SizedBox(height: 5), ResponsiveLayout.isMobile(context) ? Container( height: MediaQuery.of(context).size.height * 0.69, @@ -604,10 +646,23 @@ class EnquiryHandlerState extends ConsumerState { padding: EdgeInsets.all(8.0), color: Color(0xffD9EBE8), child: DateFilterRow( + key: ValueKey(SelectedStatus ?? ''), + onFilterStaff: (val) { + print('Selected Filterd STAFF Id - $val'); + SelectedStaffId = val; + }, + selectedStaffId: SelectedStaffId, + role: roleId, + id: userId, + selectedStatusVal: SelectedStatus, startController: controllers['startDate']!, endController: controllers['endDate']!, formKey: _formKey, isMobile: ResponsiveLayout.isMobile(context), + onStatusChanged: (val) { + SelectedStatus = val; // update parent + }, + onFilter: () { // call your filter logic filterDateRange(); @@ -624,13 +679,25 @@ class EnquiryHandlerState extends ConsumerState { // height: 40, // color: Colors.pink, child: Row( - crossAxisAlignment: CrossAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.end, mainAxisAlignment: MainAxisAlignment.start, children: [ if (!ResponsiveLayout.isMobile(context)) ...[ DateFilterRow( + key: ValueKey(SelectedStatus ?? ''), + role: roleId, + id: userId, + selectedStatusVal: SelectedStatus, + onFilterStaff: (val) { + print('Selected Filterd STAFF Id - $val'); + SelectedStaffId = val; + }, + selectedStaffId: SelectedStaffId, startController: controllers['startDate']!, endController: controllers['endDate']!, + onStatusChanged: (val) { + SelectedStatus = val; // update parent + }, formKey: _formKey, isMobile: ResponsiveLayout.isMobile(context), onFilter: () { @@ -653,7 +720,7 @@ class EnquiryHandlerState extends ConsumerState { controller: _searchStaffController, txtwidth: ResponsiveLayout.isMobile(context) ? MediaQuery.of(context).size.width * 0.7 - : MediaQuery.of(context).size.width * 0.2, + : MediaQuery.of(context).size.width * 0.13, ), ResponsiveLayout.isMobile(context) diff --git a/lib/presentation/screens/login/login_screen.dart b/lib/presentation/screens/login/login_screen.dart index 715620c..733edab 100644 --- a/lib/presentation/screens/login/login_screen.dart +++ b/lib/presentation/screens/login/login_screen.dart @@ -250,7 +250,7 @@ class _LoginScreenState extends ConsumerState { body: json.encode(payload), headers: { HttpHeaders.contentTypeHeader: 'application/json', - 'App-Signature': Env.App_Signature, + 'app-signature': Env.App_Signature, }, ); @@ -311,7 +311,7 @@ class _LoginScreenState extends ConsumerState { body: json.encode(payload), headers: { HttpHeaders.contentTypeHeader: 'application/json', - 'App-Signature': Env.App_Signature, + 'app-signature': Env.App_Signature, }, ); @@ -939,6 +939,11 @@ class _LoginScreenState extends ConsumerState { Validators.email(value, "Email"), // imgPath: "MiscIconAssetPath.person", controller: _emailController, + inputFormatters: [ + FilteringTextInputFormatter.allow( + RegExp(r'[a-zA-Z0-9_@.]'), + ), + ], ), if (switcherStatus == 1) ThemedFormField( @@ -948,6 +953,7 @@ class _LoginScreenState extends ConsumerState { Validators.phone(value, "Phone"), // imgPath: "MiscIconAssetPath.person", controller: _PhoneNumberController, + // txtwidth: MediaQuery.of(context).size.width * 0.5, keyboardType: TextInputType.number, maxLength: 10, diff --git a/lib/presentation/screens/staff/Enquiry/enquiry_list.dart b/lib/presentation/screens/staff/Enquiry/enquiry_list.dart index ec5cd48..9077ec8 100644 --- a/lib/presentation/screens/staff/Enquiry/enquiry_list.dart +++ b/lib/presentation/screens/staff/Enquiry/enquiry_list.dart @@ -54,6 +54,8 @@ class EnquiryStaffState extends ConsumerState { late ApiService apiService; dynamic userId; final _formKey = GlobalKey(); + dynamic SelectedStatus; + dynamic SelectedStaffId; // List> dataVal = []; List> getStaffData = []; @@ -99,33 +101,64 @@ class EnquiryStaffState extends ConsumerState { } void filterDateRange() { + print('SelectedStatus - $SelectedStatus'); + print('SelectedStaffId - $SelectedStaffId'); // ✅ Validate the form first - if (!_formKey.currentState!.validate()) { - // stop execution if validation fails - return; - } + // if (!_formKey.currentState!.validate()) { + // // stop execution if validation fails + // return; + // } - final fromDateText = controllers['startDate']?.text ?? ''; - final toDateText = controllers['endDate']?.text ?? ''; + // final fromDateText = controllers['startDate']?.text ?? ''; + // final toDateText = controllers['endDate']?.text ?? ''; + // + // print("fromDateText - $fromDateText"); + // print("toDateText - $toDateText"); // Optional: double-check End >= Start - final fromDate = DateFormat('dd-MM-yyyy').parse(fromDateText); - final toDate = DateFormat('dd-MM-yyyy').parse(toDateText); - - if (toDate.isBefore(fromDate)) { - // This is already caught by the validator, but extra safety - ScaffoldMessenger.of(context).showSnackBar( - SnackBar(content: Text("End Date cannot be earlier than Start Date")), - ); - return; - } + // final fromDate = DateFormat('dd-MM-yyyy').parse(fromDateText); + // final toDate = DateFormat('dd-MM-yyyy').parse(toDateText); + // + // if (toDate.isBefore(fromDate)) { + // // This is already caught by the validator, but extra safety + // ScaffoldMessenger.of(context).showSnackBar( + // SnackBar(content: Text("End Date cannot be earlier than Start Date")), + // ); + // return; + // } + // DateTime? fromDate; + // DateTime? toDate; + // + // // ✅ Only parse if the date text is not empty + // if (fromDateText.isNotEmpty) { + // fromDate = DateFormat('dd-MM-yyyy').parse(fromDateText); + // } + // if (toDateText.isNotEmpty) { + // toDate = DateFormat('dd-MM-yyyy').parse(toDateText); + // } + // + // // ✅ Check if both dates are given before comparing + // if (fromDate != null && toDate != null && toDate.isBefore(fromDate)) { + // ScaffoldMessenger.of(context).showSnackBar( + // const SnackBar( + // content: Text("End Date cannot be earlier than Start Date"), + // ), + // ); + // return; + // } // ✅ Call your API getStaffList(userId, roleId); } void refrshfilterDateRange() { + print('refrshfilterDateRange--1'); setState(() { + SelectedStatus = ''; + SelectedStaffId = null; + + print('refrshselectedStaff - $SelectedStaffId'); + print('refrshfilterDateRange--1 - $SelectedStatus'); controllers['startDate']!.clear(); controllers['endDate']!.clear(); @@ -154,6 +187,8 @@ class EnquiryStaffState extends ConsumerState { role, fromDate: controllers['startDate']?.text ?? '', toDate: controllers['endDate']?.text ?? '', + selectedStatus: SelectedStatus ?? '', + selectedStaffId: SelectedStaffId ?? '', ); print('FromDate : $fromDate'); @@ -169,8 +204,9 @@ class EnquiryStaffState extends ConsumerState { print('ToDate : $toDate'); setState(() { controllers['startDate']?.text = fromDate; + print('1'); controllers['endDate']?.text = toDate; - + print('2'); if (data is List) { // Already a list of maps getStaffData = List>.from(data); @@ -180,9 +216,12 @@ class EnquiryStaffState extends ConsumerState { } else { getStaffData = []; } + print('3'); // getStaffData = List>.from(response['data']); originalData = getStaffData; + print('4'); filteredData = List.from(originalData); + print('5'); // print('originalData - $getClaimPolicies'); }); } else { @@ -351,97 +390,97 @@ class EnquiryStaffState extends ConsumerState { // ), // ), // ], - Material( - color: Colors.transparent, - child: InkWell( - onTap: () async { - Navigator.pop(context); - final prefs = await SharedPreferences.getInstance(); - - // ✅ Remove old value (if any) - await prefs.remove('enqStaffDataId'); - - // ✅ Save the new id - await prefs.setString('enqStaffDataId', id.toString()); - - // Read it back if needed - // final dynamic? enqStaffDataId = prefs.getString('enqStaffDataId'); - - // ✅ Update provider too - // ref.read(quotationStaffIdProvider.notifier).state = enqStaffDataId; - ref.read(quotationStaffIdProvider.notifier).state = id; - - context.go(AppRoutes.quotation); - }, - hoverColor: Color(0xFFE3F1F0), - splashColor: Color(0xFFE3F1F0), - borderRadius: BorderRadius.circular(6), - child: Padding( - padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 4), - child: Row( - // mainAxisSize: MainAxisSize.min, - children: [ - Image.asset( - "assets/miscellaneous/image_1.png", - height: 15, - width: 15, - ), - - const SizedBox(width: 10), - ((data['status'] == 'Policy Created') || - (data['status'] == 'Quotation Accepted')) - ? const Text('View Quotation') - : const Text('Create Quotation'), - ], - ), - ), - ), - ), - - if (data['status'] == 'Quotation Accepted' || - data['status'] == 'Policy Created') - Material( - color: Colors.transparent, - child: InkWell( - onTap: () async { - Navigator.pop(context); - - final prefs = await SharedPreferences.getInstance(); - - // ✅ Remove old value (if any) - await prefs.remove('enqStaffDataId'); - - // ✅ Save the new id - await prefs.setString('enqStaffDataId', id.toString()); - - // ✅ Update provider too - - ref.read(quotationStaffIdProvider.notifier).state = id; - context.go(AppRoutes.policy); - }, - hoverColor: Color(0xFFE3F1F0), - splashColor: Color(0xFFE3F1F0), - borderRadius: BorderRadius.circular(6), - child: Padding( - padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 4), - child: Row( - // mainAxisSize: MainAxisSize.min, - children: [ - Image.asset( - "assets/miscellaneous/image_2.png", - height: 15, - width: 15, - ), - - const SizedBox(width: 10), - data['status'] == 'Policy Created' - ? Text('View Policy') - : Text('Create Policy'), - ], - ), - ), - ), - ), + // Material( + // color: Colors.transparent, + // child: InkWell( + // onTap: () async { + // Navigator.pop(context); + // final prefs = await SharedPreferences.getInstance(); + // + // // ✅ Remove old value (if any) + // await prefs.remove('enqStaffDataId'); + // + // // ✅ Save the new id + // await prefs.setString('enqStaffDataId', id.toString()); + // + // // Read it back if needed + // // final dynamic? enqStaffDataId = prefs.getString('enqStaffDataId'); + // + // // ✅ Update provider too + // // ref.read(quotationStaffIdProvider.notifier).state = enqStaffDataId; + // ref.read(quotationStaffIdProvider.notifier).state = id; + // + // context.go(AppRoutes.quotation); + // }, + // hoverColor: Color(0xFFE3F1F0), + // splashColor: Color(0xFFE3F1F0), + // borderRadius: BorderRadius.circular(6), + // child: Padding( + // padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 4), + // child: Row( + // // mainAxisSize: MainAxisSize.min, + // children: [ + // Image.asset( + // "assets/miscellaneous/image_1.png", + // height: 15, + // width: 15, + // ), + // + // const SizedBox(width: 10), + // ((data['status'] == 'Policy Created') || + // (data['status'] == 'Quotation Accepted')) + // ? const Text('View Quotation') + // : const Text('Create Quotation'), + // ], + // ), + // ), + // ), + // ), + // + // if (data['status'] == 'Quotation Accepted' || + // data['status'] == 'Policy Created') + // Material( + // color: Colors.transparent, + // child: InkWell( + // onTap: () async { + // Navigator.pop(context); + // + // final prefs = await SharedPreferences.getInstance(); + // + // // ✅ Remove old value (if any) + // await prefs.remove('enqStaffDataId'); + // + // // ✅ Save the new id + // await prefs.setString('enqStaffDataId', id.toString()); + // + // // ✅ Update provider too + // + // ref.read(quotationStaffIdProvider.notifier).state = id; + // context.go(AppRoutes.policy); + // }, + // hoverColor: Color(0xFFE3F1F0), + // splashColor: Color(0xFFE3F1F0), + // borderRadius: BorderRadius.circular(6), + // child: Padding( + // padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 4), + // child: Row( + // // mainAxisSize: MainAxisSize.min, + // children: [ + // Image.asset( + // "assets/miscellaneous/image_2.png", + // height: 15, + // width: 15, + // ), + // + // const SizedBox(width: 10), + // data['status'] == 'Policy Created' + // ? Text('View Policy') + // : Text('Create Policy'), + // ], + // ), + // ), + // ), + // ), ]; } @@ -491,13 +530,13 @@ class EnquiryStaffState extends ConsumerState { Tooltip( message: 'Back', child: IconButton( - icon: const Icon(Icons.arrow_left_sharp), + icon: const Icon(Icons.arrow_left_sharp, size: 25), onPressed: () { context.go(AppRoutes.dashboard); }, - splashRadius: 28, + splashRadius: 18, hoverColor: Colors.black12, - padding: const EdgeInsets.all(8), + padding: const EdgeInsets.all(4), constraints: const BoxConstraints(), ), ), @@ -579,8 +618,21 @@ class EnquiryStaffState extends ConsumerState { padding: EdgeInsets.all(8.0), color: Color(0xffD9EBE8), child: DateFilterRow( + key: ValueKey((SelectedStatus ?? '') || (SelectedStaffId ?? '')), + onFilterStaff: (val) { + print('Selected Filterd STAFF Id - $val'); + SelectedStaffId = val; + }, + selectedStaffId: SelectedStaffId, + role: roleId, + id: userId, + selectedStatusVal: SelectedStatus, + startController: controllers['startDate']!, endController: controllers['endDate']!, + onStatusChanged: (val) { + SelectedStatus = val; // update parent + }, formKey: _formKey, isMobile: ResponsiveLayout.isMobile(context), onFilter: () { @@ -599,15 +651,27 @@ class EnquiryStaffState extends ConsumerState { // height: 40, // color: Colors.pink, child: Row( - crossAxisAlignment: CrossAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.end, mainAxisAlignment: MainAxisAlignment.start, children: [ if (!ResponsiveLayout.isMobile(context)) ...[ DateFilterRow( + key: ValueKey(SelectedStatus ?? ''), + role: roleId, + id: userId, + onFilterStaff: (val) { + print('Selected Filterd STAFF Id - $val'); + SelectedStaffId = val; + }, + selectedStaffId: SelectedStaffId, + selectedStatusVal: SelectedStatus, startController: controllers['startDate']!, endController: controllers['endDate']!, formKey: _formKey, isMobile: ResponsiveLayout.isMobile(context), + onStatusChanged: (val) { + SelectedStatus = val; // update parent + }, onFilter: () { // call your filter logic filterDateRange(); @@ -693,7 +757,7 @@ class EnquiryStaffState extends ConsumerState { ], ), ), - // SizedBox(height: 10), + SizedBox(height: 8), if (!ResponsiveLayout.isMobile(context)) Container( decoration: BoxDecoration( @@ -859,7 +923,19 @@ class EnquiryStaffState extends ConsumerState { color: Colors.white, ); }, - child: Text(item['reg_no'] ?? '-', style: _dataBold), + child: Tooltip( + message: + 'Click and Download Enquiry Files', // what appears on hover/long press + waitDuration: const Duration(milliseconds: 500), // optional + showDuration: const Duration(seconds: 2), // optional + child: Text( + item['reg_no'] ?? '-', + style: _dataBold, + overflow: TextOverflow + .ellipsis, // optional, if text might overflow + ), + ), + // child: Text(item['reg_no'] ?? '-', style: _dataBold), ), ), ), @@ -901,7 +977,17 @@ class EnquiryStaffState extends ConsumerState { ref.read(quotationStaffIdProvider.notifier).state = enqId; buildStatusActions(context, status, enqId); }, - child: Text(item['status'] ?? '-', style: _dataBold), + child: Tooltip( + message: 'Click to View or Process Enquiry', // + waitDuration: const Duration(milliseconds: 500), // optional + showDuration: const Duration(seconds: 2), // optional + child: Text( + item['status'] ?? '-', + style: _dataBold, + overflow: TextOverflow.ellipsis, // + ), + ), + // child: Text(item['status'] ?? '-', style: _dataBold), ), ), ], diff --git a/lib/presentation/screens/staff/Enquiry/enquiry_list_old.dart b/lib/presentation/screens/staff/Enquiry/enquiry_list_old.dart index 975222d..f69715e 100644 --- a/lib/presentation/screens/staff/Enquiry/enquiry_list_old.dart +++ b/lib/presentation/screens/staff/Enquiry/enquiry_list_old.dart @@ -1,1175 +1,1175 @@ -// import 'dart:io' as html; -import 'package:http/http.dart' as http; -import 'package:dropdown_search/dropdown_search.dart'; -import 'package:flutter/cupertino.dart'; -import 'package:flutter/material.dart'; -import 'package:flutter_riverpod/flutter_riverpod.dart'; -import 'package:go_router/go_router.dart'; -import 'package:google_fonts/google_fonts.dart'; -import 'package:intl/intl.dart'; -import 'package:shared_preferences/shared_preferences.dart'; - -import '../../../../core/config/env.dart'; -import '../../../../core/routing/routes.dart'; -import '../../../../core/services/api_service.dart'; -import '../../../../data/services/auth_service.dart'; - -import 'package:toastification/toastification.dart'; -import 'package:universal_html/html.dart' as html; - -import '../../../../core/routing/routes.dart'; -import '../../../../core/services/api_service.dart'; -import '../../../../data/services/auth_service.dart'; -import '../../../../data/utils/Pagination.dart'; -import '../../../../data/utils/toastNotification.dart'; -import '../../../../data/utils/validators.dart'; - -import '../../../layouts/main_layout.dart'; -import '../../../layouts/responsive_layout.dart'; -import '../../../providers/manager_provider.dart'; -import '../../../providers/quotation_staff_proivder.dart'; -import '../../../providers/userRoleProvider.dart'; -import '../../../themes/indicators/customizd_file_upload.dart'; -import '../../../themes/indicators/date_field_theme.dart'; -import '../../../themes/indicators/export_btn.dart'; -import '../../../themes/indicators/search_field_theme.dart'; -import '../../../themes/indicators/text_field_theme.dart'; - -import 'package:file_picker/file_picker.dart'; - -import '../../../widgets/custom_Stdate_EnDate_Filter.dart'; -import '../../../widgets/custom_action_popup.dart'; -import '../assignStaff.dart'; - -class EnquiryStaff extends ConsumerStatefulWidget { - const EnquiryStaff({super.key}); - @override - ConsumerState createState() => EnquiryStaffState(); -} - -class EnquiryStaffState extends ConsumerState { - int currentPage = 1; - int itemsPerPage = 10; - late ApiService apiService; - dynamic userId; - final _formKey = GlobalKey(); - - // List> dataVal = []; - List> getStaffData = []; - List> originalData = []; - List> filteredData = []; - bool isLoading = false; - dynamic roleId; - - Map controllers = {}; - List tabHeader = ['startDate', 'endDate']; - - @override - void initState() { - super.initState(); - - apiService = ApiService(); - - for (String field in tabHeader) { - controllers[field] = TextEditingController(); - } - - Future.microtask(() { - final id = ref.read(managerIdProvider); - roleId = ref.read(userRoleProvider); - userId = ref.read(userIdProvider); - - print("C72 => r : $roleId | mId: $id | uId: $userId "); - if (userId != null) { - getStaffList(userId, roleId); - } - }); - } - - void refresh() { - final id = ref.read(managerIdProvider); - final roleId = ref.read(userRoleProvider); - final userId = ref.read(userIdProvider); - - print("C82 => r : $roleId | mId: $id | uId: $userId "); - if (userId != null) { - getStaffList(userId, roleId); - } - } - - void filterDateRange() { - // ✅ Validate the form first - if (!_formKey.currentState!.validate()) { - // stop execution if validation fails - return; - } - - final fromDateText = controllers['startDate']?.text ?? ''; - final toDateText = controllers['endDate']?.text ?? ''; - - // Optional: double-check End >= Start - final fromDate = DateFormat('dd-MM-yyyy').parse(fromDateText); - final toDate = DateFormat('dd-MM-yyyy').parse(toDateText); - - if (toDate.isBefore(fromDate)) { - // This is already caught by the validator, but extra safety - ScaffoldMessenger.of(context).showSnackBar( - SnackBar(content: Text("End Date cannot be earlier than Start Date")), - ); - return; - } - - // ✅ Call your API - getStaffList(userId, roleId); - } - - void refrshfilterDateRange() { - setState(() { - controllers['startDate']!.clear(); - controllers['endDate']!.clear(); - - controllers['startDate']?.text = ''; - controllers['endDate']?.text = ''; - // Reset the FormField validation - _formKey.currentState?.reset(); - }); - getStaffList(userId, roleId); - } - - Future getStaffList( - int managerId, - role, { - String fromDate = '', - String toDate = '', - }) async { - print('C89 => Fns called => $managerId | $role'); - setState(() { - isLoading = true; - }); - - try { - final response = await apiService.fetchPolicyList( - managerId, - role, - fromDate: controllers['startDate']?.text ?? '', - toDate: controllers['endDate']?.text ?? '', - ); - - print('FromDate : $fromDate'); - print('ToDate : $toDate'); - - if (response['status'] == 'success') { - final data = response['data']; - print('C99 => getStaffListData => ${response['data']}'); - final fromDate = response['from_date'] ?? ''; - final toDate = response['to_date'] ?? ''; - - print('FromDate : $fromDate'); - print('ToDate : $toDate'); - setState(() { - controllers['startDate']?.text = fromDate; - controllers['endDate']?.text = toDate; - - if (data is List) { - // Already a list of maps - getStaffData = List>.from(data); - } else if (data is Map) { - // Single object, wrap in a list - getStaffData = [Map.from(data)]; - } else { - getStaffData = []; - } - // getStaffData = List>.from(response['data']); - originalData = getStaffData; - filteredData = List.from(originalData); - // print('originalData - $getClaimPolicies'); - }); - } else { - getStaffData = []; - originalData = []; - } - } catch (e) { - print('Exception occurred: $e'); - } finally { - setState(() { - isLoading = false; - }); - } - } - - List get _paginatedData2 { - // Sort descending by id first - final sortedData = [...filteredData] - ..sort((a, b) => int.parse(b['id']) - int.parse(a['id'])); - - // final sortedData = [...filteredData]; - final startIndex = (currentPage - 1) * itemsPerPage; - final endIndex = (currentPage * itemsPerPage).clamp(0, sortedData.length); - - return sortedData.sublist(startIndex, endIndex); - } - - List get _paginatedData { - // Sort descending by id first - final sortedData = [...filteredData] - ..sort((a, b) => int.parse(b['id']) - int.parse(a['id'])); - - if (sortedData.isEmpty) return []; - - // Ensure currentPage is valid - final maxPage = (sortedData.length / itemsPerPage).ceil(); - final safePage = currentPage.clamp(1, maxPage); - - final startIndex = (safePage - 1) * itemsPerPage; - final endIndex = (startIndex + itemsPerPage).clamp(0, sortedData.length); - - return sortedData.sublist(startIndex, endIndex); - } - - void filterData(String query) { - print("FilterDAta - $query"); - setState(() { - filteredData = getStaffData.where((item) { - // final isActiveStatus = item['is_active'] == "1" ? "active" : "inactive"; - - return (item['agent_name'] ?? '-').toLowerCase().contains( - query.toLowerCase(), - ) || - (item['reg_no'] ?? '-').toLowerCase().contains( - query.toLowerCase(), - ) || - (item['insurer_name'] ?? '-').toLowerCase().contains( - query.toLowerCase(), - ) || - (item['assigned_to_name'] ?? '-').toLowerCase().contains( - query.toLowerCase(), - ) || - (item['insured_name'] ?? '-').toLowerCase().contains( - query.toLowerCase(), - ) || - (item['premium_amount'] ?? '-').toLowerCase().contains( - query.toLowerCase(), - ) || - (item['payment_mode'] ?? '-').toLowerCase().contains( - query.toLowerCase(), - ) || - (_formatDate(item['created_on']) ?? '-').toLowerCase().contains( - query.toLowerCase(), - ) || - (_formatDate(item['updated_on']) ?? '-').toLowerCase().contains( - query.toLowerCase(), - ) || - (item['policy_number'] ?? '-').toLowerCase().contains( - query.toLowerCase(), - ) || - (item['status'] ?? '-').toLowerCase().contains(query.toLowerCase()); - }).toList(); - }); - } - - final TextEditingController _searchStaffController = TextEditingController(); - - String _formatDate(String rawDate) { - try { - final dateTime = DateTime.parse(rawDate); - return DateFormat( - 'dd-MM-yyyy HH:mm', - ).format(dateTime); // 24-hour format - } catch (e) { - return rawDate; // fallback if parsing fails - } - } - - List _buildPopupMenuActions( - BuildContext context, - dynamic data, - id, - regNum, - ) { - return [ - // if (roleId == 'manager' && data['status'] == 'Awaiting Quotation') ...[ - // Material( - // color: Colors.transparent, - // child: InkWell( - // onTap: () { - // Navigator.pop(context); - // showDialog( - // context: context, - // builder: (ctx) => AssignStaffDialog( - // enquiryPrimaryId: id, - // regNum: regNum, - // userId: 1, - // onSubmit: (value) { - // debugPrint("New assignY: $value"); - // refresh(); - // }, - // ), - // ); - // }, - // hoverColor: Color(0xFFE3F1F0), - // splashColor: Color(0xFFE3F1F0), - // borderRadius: BorderRadius.circular(6), - // child: Padding( - // padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 4), - // child: Row( - // // mainAxisSize: MainAxisSize.min, - // children: [ - // Image.asset( - // "assets/miscellaneous/image_3.png", - // // height: 45, - // // width: 15, - // ), - // - // SizedBox(width: 10), - // Text('Assign Staff'), - // ], - // ), - // ), - // ), - // ), - // ], - Material( - color: Colors.transparent, - child: InkWell( - onTap: () async { - Navigator.pop(context); - final prefs = await SharedPreferences.getInstance(); - - // ✅ Remove old value (if any) - await prefs.remove('enqStaffDataId'); - - // ✅ Save the new id - await prefs.setString('enqStaffDataId', id.toString()); - - // Read it back if needed - // final dynamic? enqStaffDataId = prefs.getString('enqStaffDataId'); - - // ✅ Update provider too - // ref.read(quotationStaffIdProvider.notifier).state = enqStaffDataId; - ref.read(quotationStaffIdProvider.notifier).state = id; - - context.go(AppRoutes.quotation); - }, - hoverColor: Color(0xFFE3F1F0), - splashColor: Color(0xFFE3F1F0), - borderRadius: BorderRadius.circular(6), - child: Padding( - padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 4), - child: Row( - // mainAxisSize: MainAxisSize.min, - children: [ - Image.asset( - "assets/miscellaneous/image_1.png", - height: 15, - width: 15, - ), - - const SizedBox(width: 10), - ((data['status'] == 'Policy Created') || - (data['status'] == 'Quotation Accepted')) - ? const Text('View Quotation') - : const Text('Create Quotation'), - ], - ), - ), - ), - ), - - if (data['status'] == 'Quotation Accepted' || - data['status'] == 'Policy Created') - Material( - color: Colors.transparent, - child: InkWell( - onTap: () async { - Navigator.pop(context); - - final prefs = await SharedPreferences.getInstance(); - - // ✅ Remove old value (if any) - await prefs.remove('enqStaffDataId'); - - // ✅ Save the new id - await prefs.setString('enqStaffDataId', id.toString()); - - // ✅ Update provider too - - ref.read(quotationStaffIdProvider.notifier).state = id; - context.go(AppRoutes.policy); - }, - hoverColor: Color(0xFFE3F1F0), - splashColor: Color(0xFFE3F1F0), - borderRadius: BorderRadius.circular(6), - child: Padding( - padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 4), - child: Row( - // mainAxisSize: MainAxisSize.min, - children: [ - Image.asset( - "assets/miscellaneous/image_2.png", - height: 15, - width: 15, - ), - - const SizedBox(width: 10), - data['status'] == 'Policy Created' - ? Text('View Policy') - : Text('Create Policy'), - ], - ), - ), - ), - ), - ]; - } - - @override - Widget build(BuildContext context) { - return MainLayout( - title: "Enquiries", - body: Container( - // color: Colors.yellow.shade50, - width: MediaQuery.of(context).size.width, - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - mainAxisAlignment: MainAxisAlignment.start, - children: [ - Container( - height: 40, - width: MediaQuery.of(context).size.width, - child: GestureDetector( - onTap: () { - context.go(AppRoutes.dashboard); - }, - child: Row( - crossAxisAlignment: CrossAxisAlignment.center, - mainAxisAlignment: MainAxisAlignment.start, - children: [ - Tooltip( - message: 'Back', - child: IconButton( - icon: const Icon(Icons.arrow_left_sharp), - onPressed: () { - context.go(AppRoutes.dashboard); - }, - splashRadius: 28, - hoverColor: Colors.black12, - padding: const EdgeInsets.all(8), - constraints: const BoxConstraints(), - ), - ), - const SizedBox(width: 5), // spacing between icon and text - Text( - "Enquiries", - style: TextStyle( - fontSize: 18, - fontWeight: FontWeight.w600, - ), - ), - ], - ), - ), - ), - SizedBox(height: 10), - ResponsiveLayout.isMobile(context) - ? Container( - height: MediaQuery.of(context).size.height * 0.69, - child: SingleChildScrollView( - child: Padding( - padding: EdgeInsets.all(8), - child: _buildContent(context), - ), - ), - ) - : Expanded( - child: Container( - width: MediaQuery.of(context).size.width, - padding: EdgeInsets.all(8.0), - child: _buildContent(context), - ), - ), - - // Expanded( - // child: Container( - // // color: Colors.green, - // // color: Colors.green.shade50, - // width: MediaQuery.of(context).size.width, - // - // padding: EdgeInsets.all(8.0), - // child: - // ), - // ), - Container( - // height: 20, - width: MediaQuery.of(context).size.width, - // color: Colors.green.shade50, - child: PaginationControls( - currentPage: currentPage, - itemsPerPage: itemsPerPage, - // totalItems: dataVal.length, - totalItems: filteredData.length, - // activeColor: layoutColor, // your theme color - onPageChanged: (page) { - setState(() { - currentPage = page; - }); - }, - onItemsPerPageChanged: (items) { - setState(() { - itemsPerPage = items; - currentPage = 1; - }); - }, - ), - ), - ], - ), - ), - ); - } - - Widget _buildContent(BuildContext context) { - return Column( - children: [ - if (ResponsiveLayout.isMobile(context)) ...[ - Container( - padding: EdgeInsets.all(8.0), - color: Color(0xffD9EBE8), - child: DateFilterRow( - startController: controllers['startDate']!, - endController: controllers['endDate']!, - formKey: _formKey, - isMobile: ResponsiveLayout.isMobile(context), - onFilter: () { - // call your filter logic - filterDateRange(); - }, - onRefresh: () { - // call your refresh logic - refrshfilterDateRange(); - }, - ), - ), - ], - - Container( - // height: 40, - // color: Colors.pink, - child: Row( - crossAxisAlignment: CrossAxisAlignment.start, - mainAxisAlignment: MainAxisAlignment.start, - children: [ - if (!ResponsiveLayout.isMobile(context)) ...[ - DateFilterRow( - startController: controllers['startDate']!, - endController: controllers['endDate']!, - formKey: _formKey, - isMobile: ResponsiveLayout.isMobile(context), - onFilter: () { - // call your filter logic - filterDateRange(); - }, - onRefresh: () { - // call your refresh logic - refrshfilterDateRange(); - }, - ), - - // Form( - // key: _formKey, - // child: Row( - // mainAxisAlignment: MainAxisAlignment.start, - // crossAxisAlignment: CrossAxisAlignment.end, - // children: [ - // buildStartDate(context), - // SizedBox(width: 10), - // buildEndDate(context), - // SizedBox(width: 10), - // - // Padding( - // padding: const EdgeInsets.symmetric( - // vertical: 8.0, - // ), - // child: GestureDetector( - // // onTap: filterDateRange, - // onTap: () { - // if (_formKey.currentState!.validate()) { - // filterDateRange(); // only runs if valid - // } - // }, - // child: Icon(Icons.filter_alt_outlined), - // ), - // ), - // - // Padding( - // padding: const EdgeInsets.all(8.0), - // child: GestureDetector( - // onTap: refrshfilterDateRange, - // child: Icon(Icons.refresh), - // ), - // ), - // ], - // ), - // ), - Spacer(), - ], - - ThemedSearchField( - hintText: 'Search', - backgroundColor: Color(0xFFF6F8F8), - onChanged: filterData, - controller: _searchStaffController, - txtwidth: ResponsiveLayout.isMobile(context) - ? MediaQuery.of(context).size.width * 0.7 - : MediaQuery.of(context).size.width * 0.2, - ), - - ResponsiveLayout.isMobile(context) - ? Spacer() - : SizedBox(width: 10), - - ExportBtn( - sheetName: "Enquiry", - fileName: "Enquiry_list", - data: filteredData, - txt: !ResponsiveLayout.isMobile(context) ? true : false, - headers: [ - "created_on", - "updated_on", - "reg_no", - "agent_name", - "assigned_to_name", - "insurer_name", - "insured_name", - "premium_amount", - "payment_mode", - "policy_number", - "status", - ], - ), - - // SizedBox(width: 10), - // GestureDetector( - // onTap: () { - // // print('Export'); - // }, - // child: Container( - // padding: EdgeInsets.all(8.0), - // decoration: BoxDecoration( - // color: Color(0xFF425B5B), - // borderRadius: BorderRadius.circular(8.0), - // ), - // child: Row( - // mainAxisSize: MainAxisSize.min, - // children: [ - // Icon(Icons.add, color: Colors.white), - // - // if (!ResponsiveLayout.isMobile(context)) ...[ - // SizedBox(width: 10), - // - // GestureDetector( - // onTap: () { - // // context.go(AppRoutes.agent / create); - // context.go('/staff/create'); - // }, - // child: Text( - // 'Create New Staff', - // style: TextStyle( - // color: Colors.white, - // fontWeight: FontWeight.w600, - // fontSize: 14, - // ), - // ), - // ), - // ], - // ], - // ), - // ), - // ), - ], - ), - ), - SizedBox(height: 10), - if (!ResponsiveLayout.isMobile(context)) - Container( - decoration: BoxDecoration( - color: Color(0xFFEDF6F5), - borderRadius: BorderRadius.circular(6), - ), - padding: const EdgeInsets.symmetric(vertical: 12, horizontal: 16), - child: const Row( - children: [ - Expanded( - flex: 3, - child: Text('Received Date & Time', style: _headerStyle), - ), - Expanded( - flex: 3, - child: Text('Updated Date', style: _headerStyle), - ), - Expanded( - flex: 2, - child: Text('Vehicle.No', style: _headerStyle), - ), - Expanded(flex: 2, child: Text('Partner', style: _headerStyle)), - Expanded( - flex: 2, - child: Text('Assigned To', style: _headerStyle), - ), - Expanded(flex: 3, child: Text('Insurer', style: _headerStyle)), - Expanded( - flex: 3, - child: Padding( - padding: EdgeInsets.only(left: 8.0), - child: Text('Insured Name', style: _headerStyle), - ), - ), - Expanded(flex: 2, child: Text('Premium', style: _headerStyle)), - Expanded( - flex: 2, - child: Text('Payment Mode', style: _headerStyle), - ), - Expanded( - flex: 2, - child: Text('Policy Number', style: _headerStyle), - ), - - Expanded(flex: 3, child: Text('Status', style: _headerStyle)), - Expanded(flex: 1, child: Text('Action', style: _headerStyle)), - ], - ), - ), - ResponsiveLayout.isMobile(context) - ? _buildDataTable(context) - : Expanded(child: _buildDataTable(context)), - ], - ); - } - - Widget _buildDataTable(BuildContext context) { - if (filteredData.isEmpty) { - return const SizedBox( - height: 50, - child: Center(child: Text('No available data')), - ); - } - - final sortedData = [..._paginatedData]; - - if (ResponsiveLayout.isMobile(context)) { - // Use Column instead of ListView - return Column( - children: List.generate(sortedData.length, (index) { - final startIndex = (currentPage - 1) * itemsPerPage; - final item = sortedData[index]; - final sno = startIndex + index; - return _buildDataCard(item, sno); - }), - ); - } - - // Desktop: keep ListView.builder - return ListView.builder( - itemCount: sortedData.length + 1, - itemBuilder: (context, index) { - if (index == 0) return _buildHeader(); - final startIndex = (currentPage - 1) * itemsPerPage; - final item = sortedData[index - 1]; - final sno = startIndex + index; - return _buildDataRow(item, sno); - }, - ); - } - - // Widget _buildDataTable(BuildContext context) { - // if (filteredData.isEmpty) { - // return const SizedBox( - // height: 50, - // child: Center(child: Text('No available data')), - // ); - // } - // - // final sortedData = [..._paginatedData]; - // return ListView.builder( - // itemCount: ResponsiveLayout.isMobile(context) - // ? sortedData - // .length // only cards for mobile - // : sortedData.length + 1, // +1 for header in desktop - // itemBuilder: (context, index) { - // if (!ResponsiveLayout.isMobile(context) && index == 0) { - // return _buildHeader(); - // } - // - // final startIndex = (currentPage - 1) * itemsPerPage; - // final item = - // sortedData[index - (ResponsiveLayout.isMobile(context) ? 0 : 1)]; - // final sno = startIndex + index; - // - // return !ResponsiveLayout.isMobile(context) - // ? _buildDataRow(item, sno) - // : _buildDataCard(item, sno); - // }, - // ); - // } - - Widget _buildHeader() { - return SizedBox.shrink(); - } - - Widget _buildDataRow(Map item, sno) { - return Container( - padding: const EdgeInsets.symmetric(vertical: 10, horizontal: 16), - // margin: const EdgeInsets.only(top: 10), - decoration: BoxDecoration( - color: Colors.white, - // color: Color(0xFFE0F7F9), - border: const Border( - bottom: BorderSide(color: Color(0xFFEAEAEA), width: 1), - ), - borderRadius: BorderRadius.circular(8), - ), - child: Row( - children: [ - Expanded( - flex: 3, - child: Text( - _formatDate(item['created_on']) ?? '-', - style: _dataBold, - softWrap: true, - maxLines: 3, - ), - ), - Expanded( - flex: 3, - child: Text( - _formatDate(item['updated_on']) ?? '-', - style: _dataBold, - softWrap: true, - maxLines: 3, - ), - ), - Expanded( - flex: 2, - child: Text(item['reg_no'] ?? '-', style: _dataBold), - ), - Expanded( - flex: 2, - child: Text( - _formatDate(item['agent_name']) ?? '-', - style: _dataBold, - ), - ), - Expanded( - flex: 2, - child: Text(item['assigned_to_name'] ?? '-', style: _dataBold), - ), - Expanded( - flex: 3, - child: Text( - item['insurer_name'] ?? '-', - style: _dataBold, - softWrap: true, - maxLines: 3, - ), - ), - Expanded( - flex: 3, - child: Center( - child: Text( - item['insured_name'] ?? '-', - style: _dataBold, - softWrap: true, - maxLines: 3, - ), - ), - ), - Expanded( - flex: 2, - child: Text( - item['premium_amount'] ?? '-', - style: _dataBold, - softWrap: true, - maxLines: 3, - ), - ), - Expanded( - flex: 2, - child: Text( - item['payment_mode'] ?? '-', - style: _dataBold, - softWrap: true, - maxLines: 3, - ), - ), - Expanded( - flex: 2, - child: Text( - item['policy_number'] ?? '-', - style: _dataBold, - softWrap: true, - maxLines: 3, - ), - ), - - Expanded( - flex: 3, - child: Text(item['status'] ?? '-', style: _dataBold), - ), - - Expanded( - flex: 1, - child: Row( - children: [ - PopupMenuButton( - color: Colors.white, - padding: EdgeInsets.zero, - offset: Offset(0, 30), - icon: Icon( - Icons.more_vert, - color: Color(0xFF475569), - size: 14, - ), - itemBuilder: (context) => [ - CustomPopupMenuEntry( - child: Container( - padding: EdgeInsets.symmetric( - horizontal: 8, - vertical: 8, - ), - child: Column( - mainAxisSize: MainAxisSize.min, - mainAxisAlignment: MainAxisAlignment.start, - crossAxisAlignment: CrossAxisAlignment.start, - children: _buildPopupMenuActions( - context, - item, - item['id'], - item['reg_no'], - ), - ), - ), - ), - ], - ), - ], - ), - ), - ], - ), - ); - } - - Widget _buildDataCard(Map item, int sno) { - return Container( - margin: const EdgeInsets.symmetric(vertical: 6, horizontal: 8), - padding: const EdgeInsets.all(12), - decoration: BoxDecoration( - color: const Color(0xFFF6FEFD), - borderRadius: BorderRadius.circular(8.0), - border: Border.all(color: const Color(0xffD9EBE8)), - ), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - /// Top row: Reg.No + Action menu - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Text(item['reg_no'] ?? '-', style: _headerStyle), - PopupMenuButton( - color: Colors.white, - padding: EdgeInsets.zero, - offset: Offset(0, 30), - icon: Icon(Icons.more_vert, color: Color(0xFF475569), size: 14), - itemBuilder: (context) => [ - CustomPopupMenuEntry( - child: Container( - padding: EdgeInsets.symmetric(horizontal: 8, vertical: 8), - child: Column( - mainAxisSize: MainAxisSize.min, - children: _buildPopupMenuActions( - context, - item, - item['id'], - item['reg_no'], - ), - ), - ), - ), - ], - ), - ], - ), - const Divider(color: Color(0xffD9EBE8), thickness: 0.8), - - /// Company + Status - Row( - children: [ - Expanded( - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - const Text("Insurer", style: _cardheaderStyle), - Text(item['insurer_name'] ?? '-', style: _cardBodyStyle), - ], - ), - ), - const SizedBox(width: 5), - Expanded( - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - const Text("Status", style: _cardheaderStyle), - Text(item['status'] ?? '-', style: _cardBodyStyle), - ], - ), - ), - ], - ), - const SizedBox(height: 15), - - /// Agents + Assigned To - Row( - children: [ - Expanded( - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - const Text("Partner", style: _cardheaderStyle), - Text(item['agent_name'] ?? '-', style: _cardBodyStyle), - ], - ), - ), - const SizedBox(width: 5), - Expanded( - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - const Text("Assigned To", style: _cardheaderStyle), - Text( - item['assigned_to_name'] ?? '-', - style: _cardBodyStyle, - ), - ], - ), - ), - ], - ), - const SizedBox(height: 15), - - /// Insured Name + Premium - Row( - children: [ - Expanded( - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - const Text("Insured Name", style: _cardheaderStyle), - Text(item['insured_name'] ?? '-', style: _cardBodyStyle), - ], - ), - ), - const SizedBox(width: 5), - Expanded( - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - const Text("Premium", style: _cardheaderStyle), - Text(item['premium_amount'] ?? '-', style: _cardBodyStyle), - ], - ), - ), - ], - ), - const SizedBox(height: 15), - - /// Payment Mode + Policy Number - Row( - children: [ - Expanded( - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - const Text("Payment Mode", style: _cardheaderStyle), - Text(item['payment_mode'] ?? '-', style: _cardBodyStyle), - ], - ), - ), - const SizedBox(width: 5), - Expanded( - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - const Text("Policy Number", style: _cardheaderStyle), - Text(item['policy_number'] ?? '-', style: _cardBodyStyle), - ], - ), - ), - ], - ), - const SizedBox(height: 15), - - /// Date + Remarks - Row( - children: [ - Expanded( - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - const Text("Date", style: _cardheaderStyle), - Text( - _formatDate(item['updated_on']) ?? '-', - style: _cardBodyStyle, - ), - ], - ), - ), - const SizedBox(width: 5), - Expanded( - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - const Text("Remarks", style: _cardheaderStyle), - Text( - item['remarks'] ?? '-', - style: _cardBodyStyle, - maxLines: 3, - ), - ], - ), - ), - ], - ), - ], - ), - ); - } - - static final _dataBold = TextStyle( - fontSize: 14, - - fontWeight: FontWeight.w400, - color: Color(0xFF000000), - ); - - static final _dataSub = TextStyle( - fontSize: 10, - fontWeight: FontWeight.w300, - color: Color(0xFF585757), - ); - - static const _headerStyle = TextStyle( - color: Colors.black, - fontWeight: FontWeight.bold, - ); - static const _cardheaderStyle = TextStyle( - color: Colors.black, - fontWeight: FontWeight.w600, - fontSize: 12, - ); - - static const _cardBodyStyle = TextStyle( - color: Color(0xFF545454), - fontWeight: FontWeight.w400, - fontSize: 12, - ); -} +// // import 'dart:io' as html; +// import 'package:http/http.dart' as http; +// import 'package:dropdown_search/dropdown_search.dart'; +// import 'package:flutter/cupertino.dart'; +// import 'package:flutter/material.dart'; +// import 'package:flutter_riverpod/flutter_riverpod.dart'; +// import 'package:go_router/go_router.dart'; +// import 'package:google_fonts/google_fonts.dart'; +// import 'package:intl/intl.dart'; +// import 'package:shared_preferences/shared_preferences.dart'; +// +// import '../../../../core/config/env.dart'; +// import '../../../../core/routing/routes.dart'; +// import '../../../../core/services/api_service.dart'; +// import '../../../../data/services/auth_service.dart'; +// +// import 'package:toastification/toastification.dart'; +// import 'package:universal_html/html.dart' as html; +// +// import '../../../../core/routing/routes.dart'; +// import '../../../../core/services/api_service.dart'; +// import '../../../../data/services/auth_service.dart'; +// import '../../../../data/utils/Pagination.dart'; +// import '../../../../data/utils/toastNotification.dart'; +// import '../../../../data/utils/validators.dart'; +// +// import '../../../layouts/main_layout.dart'; +// import '../../../layouts/responsive_layout.dart'; +// import '../../../providers/manager_provider.dart'; +// import '../../../providers/quotation_staff_proivder.dart'; +// import '../../../providers/userRoleProvider.dart'; +// import '../../../themes/indicators/customizd_file_upload.dart'; +// import '../../../themes/indicators/date_field_theme.dart'; +// import '../../../themes/indicators/export_btn.dart'; +// import '../../../themes/indicators/search_field_theme.dart'; +// import '../../../themes/indicators/text_field_theme.dart'; +// +// import 'package:file_picker/file_picker.dart'; +// +// import '../../../widgets/custom_Stdate_EnDate_Filter.dart'; +// import '../../../widgets/custom_action_popup.dart'; +// import '../assignStaff.dart'; +// +// class EnquiryStaff extends ConsumerStatefulWidget { +// const EnquiryStaff({super.key}); +// @override +// ConsumerState createState() => EnquiryStaffState(); +// } +// +// class EnquiryStaffState extends ConsumerState { +// int currentPage = 1; +// // int itemsPerPage = 10; +// late ApiService apiService; +// dynamic userId; +// final _formKey = GlobalKey(); +// +// // List> dataVal = []; +// List> getStaffData = []; +// List> originalData = []; +// List> filteredData = []; +// bool isLoading = false; +// dynamic roleId; +// +// Map controllers = {}; +// List tabHeader = ['startDate', 'endDate']; +// +// @override +// void initState() { +// super.initState(); +// +// apiService = ApiService(); +// +// for (String field in tabHeader) { +// controllers[field] = TextEditingController(); +// } +// +// Future.microtask(() { +// final id = ref.read(managerIdProvider); +// roleId = ref.read(userRoleProvider); +// userId = ref.read(userIdProvider); +// +// print("C72 => r : $roleId | mId: $id | uId: $userId "); +// if (userId != null) { +// getStaffList(userId, roleId); +// } +// }); +// } +// +// void refresh() { +// final id = ref.read(managerIdProvider); +// final roleId = ref.read(userRoleProvider); +// final userId = ref.read(userIdProvider); +// +// print("C82 => r : $roleId | mId: $id | uId: $userId "); +// if (userId != null) { +// getStaffList(userId, roleId); +// } +// } +// +// void filterDateRange() { +// // ✅ Validate the form first +// if (!_formKey.currentState!.validate()) { +// // stop execution if validation fails +// return; +// } +// +// final fromDateText = controllers['startDate']?.text ?? ''; +// final toDateText = controllers['endDate']?.text ?? ''; +// +// // Optional: double-check End >= Start +// final fromDate = DateFormat('dd-MM-yyyy').parse(fromDateText); +// final toDate = DateFormat('dd-MM-yyyy').parse(toDateText); +// +// if (toDate.isBefore(fromDate)) { +// // This is already caught by the validator, but extra safety +// ScaffoldMessenger.of(context).showSnackBar( +// SnackBar(content: Text("End Date cannot be earlier than Start Date")), +// ); +// return; +// } +// +// // ✅ Call your API +// getStaffList(userId, roleId); +// } +// +// void refrshfilterDateRange() { +// setState(() { +// controllers['startDate']!.clear(); +// controllers['endDate']!.clear(); +// +// controllers['startDate']?.text = ''; +// controllers['endDate']?.text = ''; +// // Reset the FormField validation +// _formKey.currentState?.reset(); +// }); +// getStaffList(userId, roleId); +// } +// +// Future getStaffList( +// int managerId, +// role, { +// String fromDate = '', +// String toDate = '', +// }) async { +// print('C89 => Fns called => $managerId | $role'); +// setState(() { +// isLoading = true; +// }); +// +// try { +// final response = await apiService.fetchPolicyList( +// managerId, +// role, +// fromDate: controllers['startDate']?.text ?? '', +// toDate: controllers['endDate']?.text ?? '', +// ); +// +// print('FromDate : $fromDate'); +// print('ToDate : $toDate'); +// +// if (response['status'] == 'success') { +// final data = response['data']; +// print('C99 => getStaffListData => ${response['data']}'); +// final fromDate = response['from_date'] ?? ''; +// final toDate = response['to_date'] ?? ''; +// +// print('FromDate : $fromDate'); +// print('ToDate : $toDate'); +// setState(() { +// controllers['startDate']?.text = fromDate; +// controllers['endDate']?.text = toDate; +// +// if (data is List) { +// // Already a list of maps +// getStaffData = List>.from(data); +// } else if (data is Map) { +// // Single object, wrap in a list +// getStaffData = [Map.from(data)]; +// } else { +// getStaffData = []; +// } +// // getStaffData = List>.from(response['data']); +// originalData = getStaffData; +// filteredData = List.from(originalData); +// // print('originalData - $getClaimPolicies'); +// }); +// } else { +// getStaffData = []; +// originalData = []; +// } +// } catch (e) { +// print('Exception occurred: $e'); +// } finally { +// setState(() { +// isLoading = false; +// }); +// } +// } +// +// List get _paginatedData2 { +// // Sort descending by id first +// final sortedData = [...filteredData] +// ..sort((a, b) => int.parse(b['id']) - int.parse(a['id'])); +// +// // final sortedData = [...filteredData]; +// final startIndex = (currentPage - 1) * itemsPerPage; +// final endIndex = (currentPage * itemsPerPage).clamp(0, sortedData.length); +// +// return sortedData.sublist(startIndex, endIndex); +// } +// +// List get _paginatedData { +// // Sort descending by id first +// final sortedData = [...filteredData] +// ..sort((a, b) => int.parse(b['id']) - int.parse(a['id'])); +// +// if (sortedData.isEmpty) return []; +// +// // Ensure currentPage is valid +// final maxPage = (sortedData.length / itemsPerPage).ceil(); +// final safePage = currentPage.clamp(1, maxPage); +// +// final startIndex = (safePage - 1) * itemsPerPage; +// final endIndex = (startIndex + itemsPerPage).clamp(0, sortedData.length); +// +// return sortedData.sublist(startIndex, endIndex); +// } +// +// void filterData(String query) { +// print("FilterDAta - $query"); +// setState(() { +// filteredData = getStaffData.where((item) { +// // final isActiveStatus = item['is_active'] == "1" ? "active" : "inactive"; +// +// return (item['agent_name'] ?? '-').toLowerCase().contains( +// query.toLowerCase(), +// ) || +// (item['reg_no'] ?? '-').toLowerCase().contains( +// query.toLowerCase(), +// ) || +// (item['insurer_name'] ?? '-').toLowerCase().contains( +// query.toLowerCase(), +// ) || +// (item['assigned_to_name'] ?? '-').toLowerCase().contains( +// query.toLowerCase(), +// ) || +// (item['insured_name'] ?? '-').toLowerCase().contains( +// query.toLowerCase(), +// ) || +// (item['premium_amount'] ?? '-').toLowerCase().contains( +// query.toLowerCase(), +// ) || +// (item['payment_mode'] ?? '-').toLowerCase().contains( +// query.toLowerCase(), +// ) || +// (_formatDate(item['created_on']) ?? '-').toLowerCase().contains( +// query.toLowerCase(), +// ) || +// (_formatDate(item['updated_on']) ?? '-').toLowerCase().contains( +// query.toLowerCase(), +// ) || +// (item['policy_number'] ?? '-').toLowerCase().contains( +// query.toLowerCase(), +// ) || +// (item['status'] ?? '-').toLowerCase().contains(query.toLowerCase()); +// }).toList(); +// }); +// } +// +// final TextEditingController _searchStaffController = TextEditingController(); +// +// String _formatDate(String rawDate) { +// try { +// final dateTime = DateTime.parse(rawDate); +// return DateFormat( +// 'dd-MM-yyyy HH:mm', +// ).format(dateTime); // 24-hour format +// } catch (e) { +// return rawDate; // fallback if parsing fails +// } +// } +// +// List _buildPopupMenuActions( +// BuildContext context, +// dynamic data, +// id, +// regNum, +// ) { +// return [ +// // if (roleId == 'manager' && data['status'] == 'Awaiting Quotation') ...[ +// // Material( +// // color: Colors.transparent, +// // child: InkWell( +// // onTap: () { +// // Navigator.pop(context); +// // showDialog( +// // context: context, +// // builder: (ctx) => AssignStaffDialog( +// // enquiryPrimaryId: id, +// // regNum: regNum, +// // userId: 1, +// // onSubmit: (value) { +// // debugPrint("New assignY: $value"); +// // refresh(); +// // }, +// // ), +// // ); +// // }, +// // hoverColor: Color(0xFFE3F1F0), +// // splashColor: Color(0xFFE3F1F0), +// // borderRadius: BorderRadius.circular(6), +// // child: Padding( +// // padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 4), +// // child: Row( +// // // mainAxisSize: MainAxisSize.min, +// // children: [ +// // Image.asset( +// // "assets/miscellaneous/image_3.png", +// // // height: 45, +// // // width: 15, +// // ), +// // +// // SizedBox(width: 10), +// // Text('Assign Staff'), +// // ], +// // ), +// // ), +// // ), +// // ), +// // ], +// Material( +// color: Colors.transparent, +// child: InkWell( +// onTap: () async { +// Navigator.pop(context); +// final prefs = await SharedPreferences.getInstance(); +// +// // ✅ Remove old value (if any) +// await prefs.remove('enqStaffDataId'); +// +// // ✅ Save the new id +// await prefs.setString('enqStaffDataId', id.toString()); +// +// // Read it back if needed +// // final dynamic? enqStaffDataId = prefs.getString('enqStaffDataId'); +// +// // ✅ Update provider too +// // ref.read(quotationStaffIdProvider.notifier).state = enqStaffDataId; +// ref.read(quotationStaffIdProvider.notifier).state = id; +// +// context.go(AppRoutes.quotation); +// }, +// hoverColor: Color(0xFFE3F1F0), +// splashColor: Color(0xFFE3F1F0), +// borderRadius: BorderRadius.circular(6), +// child: Padding( +// padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 4), +// child: Row( +// // mainAxisSize: MainAxisSize.min, +// children: [ +// Image.asset( +// "assets/miscellaneous/image_1.png", +// height: 15, +// width: 15, +// ), +// +// const SizedBox(width: 10), +// ((data['status'] == 'Policy Created') || +// (data['status'] == 'Quotation Accepted')) +// ? const Text('View Quotation') +// : const Text('Create Quotation'), +// ], +// ), +// ), +// ), +// ), +// +// if (data['status'] == 'Quotation Accepted' || +// data['status'] == 'Policy Created') +// Material( +// color: Colors.transparent, +// child: InkWell( +// onTap: () async { +// Navigator.pop(context); +// +// final prefs = await SharedPreferences.getInstance(); +// +// // ✅ Remove old value (if any) +// await prefs.remove('enqStaffDataId'); +// +// // ✅ Save the new id +// await prefs.setString('enqStaffDataId', id.toString()); +// +// // ✅ Update provider too +// +// ref.read(quotationStaffIdProvider.notifier).state = id; +// context.go(AppRoutes.policy); +// }, +// hoverColor: Color(0xFFE3F1F0), +// splashColor: Color(0xFFE3F1F0), +// borderRadius: BorderRadius.circular(6), +// child: Padding( +// padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 4), +// child: Row( +// // mainAxisSize: MainAxisSize.min, +// children: [ +// Image.asset( +// "assets/miscellaneous/image_2.png", +// height: 15, +// width: 15, +// ), +// +// const SizedBox(width: 10), +// data['status'] == 'Policy Created' +// ? Text('View Policy') +// : Text('Create Policy'), +// ], +// ), +// ), +// ), +// ), +// ]; +// } +// +// @override +// Widget build(BuildContext context) { +// return MainLayout( +// title: "Enquiries", +// body: Container( +// // color: Colors.yellow.shade50, +// width: MediaQuery.of(context).size.width, +// child: Column( +// crossAxisAlignment: CrossAxisAlignment.start, +// mainAxisAlignment: MainAxisAlignment.start, +// children: [ +// Container( +// height: 40, +// width: MediaQuery.of(context).size.width, +// child: GestureDetector( +// onTap: () { +// context.go(AppRoutes.dashboard); +// }, +// child: Row( +// crossAxisAlignment: CrossAxisAlignment.center, +// mainAxisAlignment: MainAxisAlignment.start, +// children: [ +// Tooltip( +// message: 'Back', +// child: IconButton( +// icon: const Icon(Icons.arrow_left_sharp), +// onPressed: () { +// context.go(AppRoutes.dashboard); +// }, +// splashRadius: 28, +// hoverColor: Colors.black12, +// padding: const EdgeInsets.all(8), +// constraints: const BoxConstraints(), +// ), +// ), +// const SizedBox(width: 5), // spacing between icon and text +// Text( +// "Enquiries", +// style: TextStyle( +// fontSize: 18, +// fontWeight: FontWeight.w600, +// ), +// ), +// ], +// ), +// ), +// ), +// SizedBox(height: 10), +// ResponsiveLayout.isMobile(context) +// ? Container( +// height: MediaQuery.of(context).size.height * 0.69, +// child: SingleChildScrollView( +// child: Padding( +// padding: EdgeInsets.all(8), +// child: _buildContent(context), +// ), +// ), +// ) +// : Expanded( +// child: Container( +// width: MediaQuery.of(context).size.width, +// padding: EdgeInsets.all(8.0), +// child: _buildContent(context), +// ), +// ), +// +// // Expanded( +// // child: Container( +// // // color: Colors.green, +// // // color: Colors.green.shade50, +// // width: MediaQuery.of(context).size.width, +// // +// // padding: EdgeInsets.all(8.0), +// // child: +// // ), +// // ), +// Container( +// // height: 20, +// width: MediaQuery.of(context).size.width, +// // color: Colors.green.shade50, +// child: PaginationControls( +// currentPage: currentPage, +// itemsPerPage: itemsPerPage, +// // totalItems: dataVal.length, +// totalItems: filteredData.length, +// // activeColor: layoutColor, // your theme color +// onPageChanged: (page) { +// setState(() { +// currentPage = page; +// }); +// }, +// onItemsPerPageChanged: (items) { +// setState(() { +// itemsPerPage = items; +// currentPage = 1; +// }); +// }, +// ), +// ), +// ], +// ), +// ), +// ); +// } +// +// Widget _buildContent(BuildContext context) { +// return Column( +// children: [ +// if (ResponsiveLayout.isMobile(context)) ...[ +// Container( +// padding: EdgeInsets.all(8.0), +// color: Color(0xffD9EBE8), +// child: DateFilterRow( +// startController: controllers['startDate']!, +// endController: controllers['endDate']!, +// formKey: _formKey, +// isMobile: ResponsiveLayout.isMobile(context), +// onFilter: () { +// // call your filter logic +// filterDateRange(); +// }, +// onRefresh: () { +// // call your refresh logic +// refrshfilterDateRange(); +// }, +// ), +// ), +// ], +// +// Container( +// // height: 40, +// // color: Colors.pink, +// child: Row( +// crossAxisAlignment: CrossAxisAlignment.start, +// mainAxisAlignment: MainAxisAlignment.start, +// children: [ +// if (!ResponsiveLayout.isMobile(context)) ...[ +// DateFilterRow( +// startController: controllers['startDate']!, +// endController: controllers['endDate']!, +// formKey: _formKey, +// isMobile: ResponsiveLayout.isMobile(context), +// onFilter: () { +// // call your filter logic +// filterDateRange(); +// }, +// onRefresh: () { +// // call your refresh logic +// refrshfilterDateRange(); +// }, +// ), +// +// // Form( +// // key: _formKey, +// // child: Row( +// // mainAxisAlignment: MainAxisAlignment.start, +// // crossAxisAlignment: CrossAxisAlignment.end, +// // children: [ +// // buildStartDate(context), +// // SizedBox(width: 10), +// // buildEndDate(context), +// // SizedBox(width: 10), +// // +// // Padding( +// // padding: const EdgeInsets.symmetric( +// // vertical: 8.0, +// // ), +// // child: GestureDetector( +// // // onTap: filterDateRange, +// // onTap: () { +// // if (_formKey.currentState!.validate()) { +// // filterDateRange(); // only runs if valid +// // } +// // }, +// // child: Icon(Icons.filter_alt_outlined), +// // ), +// // ), +// // +// // Padding( +// // padding: const EdgeInsets.all(8.0), +// // child: GestureDetector( +// // onTap: refrshfilterDateRange, +// // child: Icon(Icons.refresh), +// // ), +// // ), +// // ], +// // ), +// // ), +// Spacer(), +// ], +// +// ThemedSearchField( +// hintText: 'Search', +// backgroundColor: Color(0xFFF6F8F8), +// onChanged: filterData, +// controller: _searchStaffController, +// txtwidth: ResponsiveLayout.isMobile(context) +// ? MediaQuery.of(context).size.width * 0.7 +// : MediaQuery.of(context).size.width * 0.2, +// ), +// +// ResponsiveLayout.isMobile(context) +// ? Spacer() +// : SizedBox(width: 10), +// +// ExportBtn( +// sheetName: "Enquiry", +// fileName: "Enquiry_list", +// data: filteredData, +// txt: !ResponsiveLayout.isMobile(context) ? true : false, +// headers: [ +// "created_on", +// "updated_on", +// "reg_no", +// "agent_name", +// "assigned_to_name", +// "insurer_name", +// "insured_name", +// "premium_amount", +// "payment_mode", +// "policy_number", +// "status", +// ], +// ), +// +// // SizedBox(width: 10), +// // GestureDetector( +// // onTap: () { +// // // print('Export'); +// // }, +// // child: Container( +// // padding: EdgeInsets.all(8.0), +// // decoration: BoxDecoration( +// // color: Color(0xFF425B5B), +// // borderRadius: BorderRadius.circular(8.0), +// // ), +// // child: Row( +// // mainAxisSize: MainAxisSize.min, +// // children: [ +// // Icon(Icons.add, color: Colors.white), +// // +// // if (!ResponsiveLayout.isMobile(context)) ...[ +// // SizedBox(width: 10), +// // +// // GestureDetector( +// // onTap: () { +// // // context.go(AppRoutes.agent / create); +// // context.go('/staff/create'); +// // }, +// // child: Text( +// // 'Create New Staff', +// // style: TextStyle( +// // color: Colors.white, +// // fontWeight: FontWeight.w600, +// // fontSize: 14, +// // ), +// // ), +// // ), +// // ], +// // ], +// // ), +// // ), +// // ), +// ], +// ), +// ), +// SizedBox(height: 10), +// if (!ResponsiveLayout.isMobile(context)) +// Container( +// decoration: BoxDecoration( +// color: Color(0xFFEDF6F5), +// borderRadius: BorderRadius.circular(6), +// ), +// padding: const EdgeInsets.symmetric(vertical: 12, horizontal: 16), +// child: const Row( +// children: [ +// Expanded( +// flex: 3, +// child: Text('Received Date & Time', style: _headerStyle), +// ), +// Expanded( +// flex: 3, +// child: Text('Updated Date', style: _headerStyle), +// ), +// Expanded( +// flex: 2, +// child: Text('Vehicle.No', style: _headerStyle), +// ), +// Expanded(flex: 2, child: Text('Partner', style: _headerStyle)), +// Expanded( +// flex: 2, +// child: Text('Assigned To', style: _headerStyle), +// ), +// Expanded(flex: 3, child: Text('Insurer', style: _headerStyle)), +// Expanded( +// flex: 3, +// child: Padding( +// padding: EdgeInsets.only(left: 8.0), +// child: Text('Insured Name', style: _headerStyle), +// ), +// ), +// Expanded(flex: 2, child: Text('Premium', style: _headerStyle)), +// Expanded( +// flex: 2, +// child: Text('Payment Mode', style: _headerStyle), +// ), +// Expanded( +// flex: 2, +// child: Text('Policy Number', style: _headerStyle), +// ), +// +// Expanded(flex: 3, child: Text('Status', style: _headerStyle)), +// Expanded(flex: 1, child: Text('Action', style: _headerStyle)), +// ], +// ), +// ), +// ResponsiveLayout.isMobile(context) +// ? _buildDataTable(context) +// : Expanded(child: _buildDataTable(context)), +// ], +// ); +// } +// +// Widget _buildDataTable(BuildContext context) { +// if (filteredData.isEmpty) { +// return const SizedBox( +// height: 50, +// child: Center(child: Text('No available data')), +// ); +// } +// +// final sortedData = [..._paginatedData]; +// +// if (ResponsiveLayout.isMobile(context)) { +// // Use Column instead of ListView +// return Column( +// children: List.generate(sortedData.length, (index) { +// final startIndex = (currentPage - 1) * itemsPerPage; +// final item = sortedData[index]; +// final sno = startIndex + index; +// return _buildDataCard(item, sno); +// }), +// ); +// } +// +// // Desktop: keep ListView.builder +// return ListView.builder( +// itemCount: sortedData.length + 1, +// itemBuilder: (context, index) { +// if (index == 0) return _buildHeader(); +// final startIndex = (currentPage - 1) * itemsPerPage; +// final item = sortedData[index - 1]; +// final sno = startIndex + index; +// return _buildDataRow(item, sno); +// }, +// ); +// } +// +// // Widget _buildDataTable(BuildContext context) { +// // if (filteredData.isEmpty) { +// // return const SizedBox( +// // height: 50, +// // child: Center(child: Text('No available data')), +// // ); +// // } +// // +// // final sortedData = [..._paginatedData]; +// // return ListView.builder( +// // itemCount: ResponsiveLayout.isMobile(context) +// // ? sortedData +// // .length // only cards for mobile +// // : sortedData.length + 1, // +1 for header in desktop +// // itemBuilder: (context, index) { +// // if (!ResponsiveLayout.isMobile(context) && index == 0) { +// // return _buildHeader(); +// // } +// // +// // final startIndex = (currentPage - 1) * itemsPerPage; +// // final item = +// // sortedData[index - (ResponsiveLayout.isMobile(context) ? 0 : 1)]; +// // final sno = startIndex + index; +// // +// // return !ResponsiveLayout.isMobile(context) +// // ? _buildDataRow(item, sno) +// // : _buildDataCard(item, sno); +// // }, +// // ); +// // } +// +// Widget _buildHeader() { +// return SizedBox.shrink(); +// } +// +// Widget _buildDataRow(Map item, sno) { +// return Container( +// padding: const EdgeInsets.symmetric(vertical: 10, horizontal: 16), +// // margin: const EdgeInsets.only(top: 10), +// decoration: BoxDecoration( +// color: Colors.white, +// // color: Color(0xFFE0F7F9), +// border: const Border( +// bottom: BorderSide(color: Color(0xFFEAEAEA), width: 1), +// ), +// borderRadius: BorderRadius.circular(8), +// ), +// child: Row( +// children: [ +// Expanded( +// flex: 3, +// child: Text( +// _formatDate(item['created_on']) ?? '-', +// style: _dataBold, +// softWrap: true, +// maxLines: 3, +// ), +// ), +// Expanded( +// flex: 3, +// child: Text( +// _formatDate(item['updated_on']) ?? '-', +// style: _dataBold, +// softWrap: true, +// maxLines: 3, +// ), +// ), +// Expanded( +// flex: 2, +// child: Text(item['reg_no'] ?? '-', style: _dataBold), +// ), +// Expanded( +// flex: 2, +// child: Text( +// _formatDate(item['agent_name']) ?? '-', +// style: _dataBold, +// ), +// ), +// Expanded( +// flex: 2, +// child: Text(item['assigned_to_name'] ?? '-', style: _dataBold), +// ), +// Expanded( +// flex: 3, +// child: Text( +// item['insurer_name'] ?? '-', +// style: _dataBold, +// softWrap: true, +// maxLines: 3, +// ), +// ), +// Expanded( +// flex: 3, +// child: Center( +// child: Text( +// item['insured_name'] ?? '-', +// style: _dataBold, +// softWrap: true, +// maxLines: 3, +// ), +// ), +// ), +// Expanded( +// flex: 2, +// child: Text( +// item['premium_amount'] ?? '-', +// style: _dataBold, +// softWrap: true, +// maxLines: 3, +// ), +// ), +// Expanded( +// flex: 2, +// child: Text( +// item['payment_mode'] ?? '-', +// style: _dataBold, +// softWrap: true, +// maxLines: 3, +// ), +// ), +// Expanded( +// flex: 2, +// child: Text( +// item['policy_number'] ?? '-', +// style: _dataBold, +// softWrap: true, +// maxLines: 3, +// ), +// ), +// +// Expanded( +// flex: 3, +// child: Text(item['status'] ?? '-', style: _dataBold), +// ), +// +// Expanded( +// flex: 1, +// child: Row( +// children: [ +// PopupMenuButton( +// color: Colors.white, +// padding: EdgeInsets.zero, +// offset: Offset(0, 30), +// icon: Icon( +// Icons.more_vert, +// color: Color(0xFF475569), +// size: 14, +// ), +// itemBuilder: (context) => [ +// CustomPopupMenuEntry( +// child: Container( +// padding: EdgeInsets.symmetric( +// horizontal: 8, +// vertical: 8, +// ), +// child: Column( +// mainAxisSize: MainAxisSize.min, +// mainAxisAlignment: MainAxisAlignment.start, +// crossAxisAlignment: CrossAxisAlignment.start, +// children: _buildPopupMenuActions( +// context, +// item, +// item['id'], +// item['reg_no'], +// ), +// ), +// ), +// ), +// ], +// ), +// ], +// ), +// ), +// ], +// ), +// ); +// } +// +// Widget _buildDataCard(Map item, int sno) { +// return Container( +// margin: const EdgeInsets.symmetric(vertical: 6, horizontal: 8), +// padding: const EdgeInsets.all(12), +// decoration: BoxDecoration( +// color: const Color(0xFFF6FEFD), +// borderRadius: BorderRadius.circular(8.0), +// border: Border.all(color: const Color(0xffD9EBE8)), +// ), +// child: Column( +// crossAxisAlignment: CrossAxisAlignment.start, +// children: [ +// /// Top row: Reg.No + Action menu +// Row( +// mainAxisAlignment: MainAxisAlignment.spaceBetween, +// children: [ +// Text(item['reg_no'] ?? '-', style: _headerStyle), +// PopupMenuButton( +// color: Colors.white, +// padding: EdgeInsets.zero, +// offset: Offset(0, 30), +// icon: Icon(Icons.more_vert, color: Color(0xFF475569), size: 14), +// itemBuilder: (context) => [ +// CustomPopupMenuEntry( +// child: Container( +// padding: EdgeInsets.symmetric(horizontal: 8, vertical: 8), +// child: Column( +// mainAxisSize: MainAxisSize.min, +// children: _buildPopupMenuActions( +// context, +// item, +// item['id'], +// item['reg_no'], +// ), +// ), +// ), +// ), +// ], +// ), +// ], +// ), +// const Divider(color: Color(0xffD9EBE8), thickness: 0.8), +// +// /// Company + Status +// Row( +// children: [ +// Expanded( +// child: Column( +// crossAxisAlignment: CrossAxisAlignment.start, +// children: [ +// const Text("Insurer", style: _cardheaderStyle), +// Text(item['insurer_name'] ?? '-', style: _cardBodyStyle), +// ], +// ), +// ), +// const SizedBox(width: 5), +// Expanded( +// child: Column( +// crossAxisAlignment: CrossAxisAlignment.start, +// children: [ +// const Text("Status", style: _cardheaderStyle), +// Text(item['status'] ?? '-', style: _cardBodyStyle), +// ], +// ), +// ), +// ], +// ), +// const SizedBox(height: 15), +// +// /// Agents + Assigned To +// Row( +// children: [ +// Expanded( +// child: Column( +// crossAxisAlignment: CrossAxisAlignment.start, +// children: [ +// const Text("Partner", style: _cardheaderStyle), +// Text(item['agent_name'] ?? '-', style: _cardBodyStyle), +// ], +// ), +// ), +// const SizedBox(width: 5), +// Expanded( +// child: Column( +// crossAxisAlignment: CrossAxisAlignment.start, +// children: [ +// const Text("Assigned To", style: _cardheaderStyle), +// Text( +// item['assigned_to_name'] ?? '-', +// style: _cardBodyStyle, +// ), +// ], +// ), +// ), +// ], +// ), +// const SizedBox(height: 15), +// +// /// Insured Name + Premium +// Row( +// children: [ +// Expanded( +// child: Column( +// crossAxisAlignment: CrossAxisAlignment.start, +// children: [ +// const Text("Insured Name", style: _cardheaderStyle), +// Text(item['insured_name'] ?? '-', style: _cardBodyStyle), +// ], +// ), +// ), +// const SizedBox(width: 5), +// Expanded( +// child: Column( +// crossAxisAlignment: CrossAxisAlignment.start, +// children: [ +// const Text("Premium", style: _cardheaderStyle), +// Text(item['premium_amount'] ?? '-', style: _cardBodyStyle), +// ], +// ), +// ), +// ], +// ), +// const SizedBox(height: 15), +// +// /// Payment Mode + Policy Number +// Row( +// children: [ +// Expanded( +// child: Column( +// crossAxisAlignment: CrossAxisAlignment.start, +// children: [ +// const Text("Payment Mode", style: _cardheaderStyle), +// Text(item['payment_mode'] ?? '-', style: _cardBodyStyle), +// ], +// ), +// ), +// const SizedBox(width: 5), +// Expanded( +// child: Column( +// crossAxisAlignment: CrossAxisAlignment.start, +// children: [ +// const Text("Policy Number", style: _cardheaderStyle), +// Text(item['policy_number'] ?? '-', style: _cardBodyStyle), +// ], +// ), +// ), +// ], +// ), +// const SizedBox(height: 15), +// +// /// Date + Remarks +// Row( +// children: [ +// Expanded( +// child: Column( +// crossAxisAlignment: CrossAxisAlignment.start, +// children: [ +// const Text("Date", style: _cardheaderStyle), +// Text( +// _formatDate(item['updated_on']) ?? '-', +// style: _cardBodyStyle, +// ), +// ], +// ), +// ), +// const SizedBox(width: 5), +// Expanded( +// child: Column( +// crossAxisAlignment: CrossAxisAlignment.start, +// children: [ +// const Text("Remarks", style: _cardheaderStyle), +// Text( +// item['remarks'] ?? '-', +// style: _cardBodyStyle, +// maxLines: 3, +// ), +// ], +// ), +// ), +// ], +// ), +// ], +// ), +// ); +// } +// +// static final _dataBold = TextStyle( +// fontSize: 14, +// +// fontWeight: FontWeight.w400, +// color: Color(0xFF000000), +// ); +// +// static final _dataSub = TextStyle( +// fontSize: 10, +// fontWeight: FontWeight.w300, +// color: Color(0xFF585757), +// ); +// +// static const _headerStyle = TextStyle( +// color: Colors.black, +// fontWeight: FontWeight.bold, +// ); +// static const _cardheaderStyle = TextStyle( +// color: Colors.black, +// fontWeight: FontWeight.w600, +// fontSize: 12, +// ); +// +// static const _cardBodyStyle = TextStyle( +// color: Color(0xFF545454), +// fontWeight: FontWeight.w400, +// fontSize: 12, +// ); +// } diff --git a/lib/presentation/screens/staff/Enquiry/tabs/createQuotation.dart b/lib/presentation/screens/staff/Enquiry/tabs/createQuotation.dart index 359754f..23f475c 100644 --- a/lib/presentation/screens/staff/Enquiry/tabs/createQuotation.dart +++ b/lib/presentation/screens/staff/Enquiry/tabs/createQuotation.dart @@ -4,6 +4,7 @@ import 'package:dropdown_search/dropdown_search.dart'; import 'package:file_picker/file_picker.dart'; import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:go_router/go_router.dart'; import 'package:google_fonts/google_fonts.dart'; @@ -130,6 +131,7 @@ class CreateQuotationFormState extends ConsumerState { } void reset() { + print('RESET'); _formKey.currentState?.reset(); // Clear all TextEditingControllers for (var controller in controllers.values) { @@ -303,8 +305,7 @@ class CreateQuotationFormState extends ConsumerState { // Use MultipartRequest (POST only) final request = http.MultipartRequest('POST', uri); request.headers['Authorization'] = 'Bearer $_token'; - request.headers['app-signature'] = - 'nhance-partner-2025-signature-35468846JRhH551HK'; + request.headers['app-signature'] = Env.App_Signature; // If updating, spoof the method Laravel-style if (isUpdating) { @@ -370,6 +371,8 @@ class CreateQuotationFormState extends ConsumerState { widget.onSubmit('Success'); reset(); // Navigator.of(context).pop(); + } else if (response.statusCode == 403) { + await apiService.clearLocalStorageAndRedirect(); } else { final responseBody = jsonDecode(response.body); dynamic msg = responseBody['data']; @@ -479,6 +482,9 @@ class CreateQuotationFormState extends ConsumerState { SizedBox(height: 10), ThemedFormField( controller: controllers['idv']!, + inputFormatters: [ + FilteringTextInputFormatter.allow(RegExp(r'[0-9.]')), + ], validator: (value) => Validators.doubleNumber(value, "IDV"), // validator: (value) => Validators.number(value, "IDV"), backgroundColor: Color(0xFFEDF6F5), @@ -591,6 +597,9 @@ class CreateQuotationFormState extends ConsumerState { ThemedFormField( controller: controllers['premium_Amount']!, backgroundColor: Color(0xFFEDF6F5), + inputFormatters: [ + FilteringTextInputFormatter.allow(RegExp(r'[0-9.]')), + ], validator: (value) => Validators.doubleNumber(value, "PremiumAmount"), // validator: (value) => Validators.number(value, "PremiumAmount "), txtwidth: ResponsiveLayout.isMobile(context) diff --git a/lib/presentation/screens/staff/Enquiry/tabs/policyTab.dart b/lib/presentation/screens/staff/Enquiry/tabs/policyTab.dart index 6aa3644..dc0f57c 100644 --- a/lib/presentation/screens/staff/Enquiry/tabs/policyTab.dart +++ b/lib/presentation/screens/staff/Enquiry/tabs/policyTab.dart @@ -428,8 +428,7 @@ class PolicyStaffTabState extends ConsumerState { // Use MultipartRequest (POST only) final request = http.MultipartRequest('POST', uri); request.headers['Authorization'] = 'Bearer $_token'; - request.headers['app-signature'] = - 'nhance-partner-2025-signature-35468846JRhH551HK'; + request.headers['app-signature'] = Env.App_Signature; // If updating, spoof the method Laravel-style if (isUpdating) { @@ -482,6 +481,8 @@ class PolicyStaffTabState extends ConsumerState { ref.read(enquiryIdProvider.notifier).state = null; context.go(AppRoutes.enquiryForStaff); } + } else if (response.statusCode == 403) { + await apiService.clearLocalStorageAndRedirect(); } else { print("❌ Submission failed. Status: ${response.statusCode}"); print("Body: ${response.body}"); @@ -879,7 +880,7 @@ class PolicyStaffTabState extends ConsumerState { return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - Text('Registration Number*', style: _textStyle), + Text('Vehicle Number*', style: _textStyle), SizedBox(height: 10), ThemedFormField( controller: controllers['regNum']!, diff --git a/lib/presentation/screens/staff/Enquiry/tabs/quotationTab.dart b/lib/presentation/screens/staff/Enquiry/tabs/quotationTab.dart index 2777e4a..c4bd15b 100644 --- a/lib/presentation/screens/staff/Enquiry/tabs/quotationTab.dart +++ b/lib/presentation/screens/staff/Enquiry/tabs/quotationTab.dart @@ -176,6 +176,11 @@ class QuotationStaffTabState extends ConsumerState { void refresh() { print("refresh--"); + setState(() { + selectedQuotationFrmListId = null; + selectedQuotationFrmListData = null; + }); + if (enqQuotation != null) { _loadData(enqQuotation); } @@ -307,7 +312,7 @@ class QuotationStaffTabState extends ConsumerState { return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - Text('Registration Number', style: _textStyle), + Text('Vehicle Number', style: _textStyle), SizedBox(height: 10), ThemedFormField( controller: controllers['regNum']!, @@ -364,7 +369,7 @@ class QuotationStaffTabState extends ConsumerState { Widget buildId(BuildContext context) { return buildResponsiveField( - label: "Registration Number *", + label: "Vehicle Number *", field: ThemedFormField( controller: controllers['regNo']!, validator: (value) => Validators.requiredField(value, "regNo"), @@ -426,10 +431,7 @@ class QuotationStaffTabState extends ConsumerState { child: Row( children: [ // Expanded(flex: 3, child: Text(' ', style: _headerStyle)), - Expanded( - flex: 2, - child: Text('Registration Number', style: _headerStyle), - ), + Expanded(flex: 2, child: Text('Vehicle Number', style: _headerStyle)), Expanded(flex: 3, child: Text('Insurer', style: _headerStyle)), Expanded(flex: 2, child: Text('IDV', style: _headerStyle)), Expanded(flex: 2, child: Text('Plan Type', style: _headerStyle)), diff --git a/lib/presentation/screens/staff/assignStaff.dart b/lib/presentation/screens/staff/assignStaff.dart index a159a44..eaed5a1 100644 --- a/lib/presentation/screens/staff/assignStaff.dart +++ b/lib/presentation/screens/staff/assignStaff.dart @@ -211,7 +211,7 @@ class _AddDialogState extends ConsumerState { headers: { 'Authorization': 'Bearer $_token', 'Content-Type': 'application/json', - 'app-signature': 'nhance-partner-2025-signature-35468846JRhH551HK', + 'app-signature': Env.App_Signature, }, body: jsonEncode(data), // Convert map to JSON ); @@ -229,6 +229,8 @@ class _AddDialogState extends ConsumerState { // widget.onSubmit("success"); // context.go(AppRoutes.staffLst); + } else if (response.statusCode == 403) { + await apiService.clearLocalStorageAndRedirect(); } else { final responseBody = jsonDecode(response.body); dynamic msg = responseBody['data']; @@ -387,7 +389,7 @@ class _AddDialogState extends ConsumerState { return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - Text("Registration Number", style: _textStyle), + Text("Vehicle Number", style: _textStyle), SizedBox(height: 10), ThemedFormField( controller: controllers['regNum']!, diff --git a/lib/presentation/screens/staff/policy/policy.dart b/lib/presentation/screens/staff/policy/policy.dart index ad87971..1830eb5 100644 --- a/lib/presentation/screens/staff/policy/policy.dart +++ b/lib/presentation/screens/staff/policy/policy.dart @@ -434,8 +434,7 @@ class PolicyScreenState extends ConsumerState { // Use MultipartRequest (POST only) final request = http.MultipartRequest('POST', uri); request.headers['Authorization'] = 'Bearer $_token'; - request.headers['app-signature'] = - 'nhance-partner-2025-signature-35468846JRhH551HK'; + request.headers['app-signature'] = Env.App_Signature; // If updating, spoof the method Laravel-style if (isUpdating) { @@ -1011,7 +1010,7 @@ class PolicyScreenState extends ConsumerState { return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - Text('Registration Number*', style: _textStyle), + Text('Vehicle Number*', style: _textStyle), SizedBox(height: 10), ThemedFormField( controller: controllers['regNum']!, diff --git a/lib/presentation/screens/staff/policy/policy_list.dart b/lib/presentation/screens/staff/policy/policy_list.dart index 632910d..685ba72 100644 --- a/lib/presentation/screens/staff/policy/policy_list.dart +++ b/lib/presentation/screens/staff/policy/policy_list.dart @@ -29,6 +29,8 @@ class policylistState extends ConsumerState { int itemsPerPage = 10; late ApiService apiService; dynamic userId; + dynamic SelectedStatus; + dynamic SelectedStaffId; // List> dataVal = []; List> getStaffData = []; List> originalData = []; @@ -89,6 +91,7 @@ class policylistState extends ConsumerState { role, fromDate: controllers['startDate']?.text ?? '', toDate: controllers['endDate']?.text ?? '', + selectedStaffId: SelectedStaffId ?? '', ); if (response['status'] == 'success') { @@ -149,25 +152,25 @@ class policylistState extends ConsumerState { void filterDateRange() { // ✅ Validate the form first - if (!_formKey.currentState!.validate()) { - // stop execution if validation fails - return; - } - - final fromDateText = controllers['startDate']?.text ?? ''; - final toDateText = controllers['endDate']?.text ?? ''; - - // Optional: double-check End >= Start - final fromDate = DateFormat('dd-MM-yyyy').parse(fromDateText); - final toDate = DateFormat('dd-MM-yyyy').parse(toDateText); - - if (toDate.isBefore(fromDate)) { - // This is already caught by the validator, but extra safety - ScaffoldMessenger.of(context).showSnackBar( - SnackBar(content: Text("End Date cannot be earlier than Start Date")), - ); - return; - } + // if (!_formKey.currentState!.validate()) { + // // stop execution if validation fails + // return; + // } + // + // final fromDateText = controllers['startDate']?.text ?? ''; + // final toDateText = controllers['endDate']?.text ?? ''; + // + // // Optional: double-check End >= Start + // final fromDate = DateFormat('dd-MM-yyyy').parse(fromDateText); + // final toDate = DateFormat('dd-MM-yyyy').parse(toDateText); + // + // if (toDate.isBefore(fromDate)) { + // // This is already caught by the validator, but extra safety + // ScaffoldMessenger.of(context).showSnackBar( + // SnackBar(content: Text("End Date cannot be earlier than Start Date")), + // ); + // return; + // } // ✅ Call your API getStaffList(userId, roleId); @@ -175,6 +178,7 @@ class policylistState extends ConsumerState { void refrshfilterDateRange() { setState(() { + SelectedStaffId = null; controllers['startDate']!.clear(); controllers['endDate']!.clear(); @@ -465,8 +469,19 @@ class policylistState extends ConsumerState { padding: EdgeInsets.all(8.0), color: Color(0xffD9EBE8), child: DateFilterRow( + dataFrom: 'Policy', + role: roleId, + id: userId, + onFilterStaff: (val) { + print('Selected Filterd STAFF Id - $val'); + SelectedStaffId = val; + }, + selectedStaffId: SelectedStaffId, startController: controllers['startDate']!, endController: controllers['endDate']!, + onStatusChanged: (val) { + SelectedStatus = val; // update parent + }, formKey: _formKey, isMobile: ResponsiveLayout.isMobile(context), onFilter: () { @@ -490,8 +505,19 @@ class policylistState extends ConsumerState { children: [ if (!ResponsiveLayout.isMobile(context)) ...[ DateFilterRow( + dataFrom: 'Policy', + role: roleId, + id: userId, + onFilterStaff: (val) { + print('Selected Filterd STAFF Id - $val'); + SelectedStaffId = val; + }, + selectedStaffId: SelectedStaffId, startController: controllers['startDate']!, endController: controllers['endDate']!, + onStatusChanged: (val) { + SelectedStatus = val; // update parent + }, formKey: _formKey, isMobile: ResponsiveLayout.isMobile(context), onFilter: () { diff --git a/lib/presentation/screens/staff/quotations/createQuotationPopUp.dart b/lib/presentation/screens/staff/quotations/createQuotationPopUp.dart index 96caacd..1b2aed6 100644 --- a/lib/presentation/screens/staff/quotations/createQuotationPopUp.dart +++ b/lib/presentation/screens/staff/quotations/createQuotationPopUp.dart @@ -3,6 +3,7 @@ import 'dart:convert'; import 'package:dropdown_search/dropdown_search.dart'; import 'package:file_picker/file_picker.dart'; import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; import 'package:google_fonts/google_fonts.dart'; import 'package:http/http.dart' as http; import 'package:toastification/toastification.dart'; @@ -262,8 +263,7 @@ class createQuotatDialogState extends State { // Use MultipartRequest (POST only) final request = http.MultipartRequest('POST', uri); request.headers['Authorization'] = 'Bearer $_token'; - request.headers['app-signature'] = - 'nhance-partner-2025-signature-35468846JRhH551HK'; + request.headers['app-signature'] = Env.App_Signature; // If updating, spoof the method Laravel-style if (isUpdating) { @@ -458,6 +458,9 @@ class createQuotatDialogState extends State { ThemedFormField( controller: controllers['idv']!, validator: (value) => Validators.doubleNumber(value, "IDV"), + inputFormatters: [ + FilteringTextInputFormatter.allow(RegExp(r'[0-9.]')), + ], // validator: (value) => Validators.number(value, "IDV"), backgroundColor: Color(0xFFEDF6F5), // readOnly: true, diff --git a/lib/presentation/screens/staff/quotations/quotation.dart b/lib/presentation/screens/staff/quotations/quotation.dart index 0f1c3c6..1650e86 100644 --- a/lib/presentation/screens/staff/quotations/quotation.dart +++ b/lib/presentation/screens/staff/quotations/quotation.dart @@ -653,7 +653,7 @@ class QuotationScreenState extends ConsumerState { return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - Text('Registration Number', style: _textStyle), + Text('Vehicle Number', style: _textStyle), SizedBox(height: 10), ThemedFormField( controller: controllers['regNum']!, @@ -710,7 +710,7 @@ class QuotationScreenState extends ConsumerState { Widget buildId(BuildContext context) { return buildResponsiveField( - label: "Registration Number *", + label: "Vehicle Number *", field: ThemedFormField( controller: controllers['regNo']!, validator: (value) => Validators.requiredField(value, "regNo"), @@ -773,10 +773,7 @@ class QuotationScreenState extends ConsumerState { child: Row( children: [ // Expanded(flex: 3, child: Text(' ', style: _headerStyle)), - Expanded( - flex: 2, - child: Text('Registration Number', style: _headerStyle), - ), + Expanded(flex: 2, child: Text('Vehicle Number', style: _headerStyle)), Expanded(flex: 4, child: Text('Insurer', style: _headerStyle)), Expanded(flex: 2, child: Text('IDV', style: _headerStyle)), Expanded(flex: 2, child: Text('Plan Type', style: _headerStyle)), diff --git a/lib/presentation/themes/indicators/text_field_theme.dart b/lib/presentation/themes/indicators/text_field_theme.dart index efa2cdf..2fca464 100644 --- a/lib/presentation/themes/indicators/text_field_theme.dart +++ b/lib/presentation/themes/indicators/text_field_theme.dart @@ -143,7 +143,10 @@ class ThemedFormField extends HookWidget { readOnly: readOnly, // ✅ now supported keyboardType: keyboardType, // ✅ e.g. TextInputType.number maxLength: maxLength, // ✅ max length - inputFormatters: inputFormatters, + inputFormatters: + inputFormatters ?? + [FilteringTextInputFormatter.allow(RegExp(r'[a-z A-Z]'))], + // ✅ allow multiline if user sets maxLines / minLines minLines: (keyboardType == TextInputType.multiline) ? 3 : 1, maxLines: (keyboardType == TextInputType.multiline) ? null : 1, diff --git a/lib/presentation/widgets/custom_Stdate_EnDate_Filter.dart b/lib/presentation/widgets/custom_Stdate_EnDate_Filter.dart index 2fe77db..981970f 100644 --- a/lib/presentation/widgets/custom_Stdate_EnDate_Filter.dart +++ b/lib/presentation/widgets/custom_Stdate_EnDate_Filter.dart @@ -1,15 +1,53 @@ +import 'package:dropdown_search/dropdown_search.dart'; import 'package:flutter/material.dart'; +import 'package:flutter_riverpod/flutter_riverpod.dart'; +import 'package:google_fonts/google_fonts.dart'; import 'package:intl/intl.dart'; +import '../../core/services/api_service.dart'; import '../layouts/responsive_layout.dart'; +import '../providers/manager_provider.dart'; +import '../providers/userRoleProvider.dart'; import '../themes/indicators/date_field_theme.dart'; +import '../themes/indicators/input_field_decoration.dart'; -class DateFilterRow extends StatelessWidget { +// class DateFilterRow extends StatelessWidget { +// final TextEditingController startController; +// final String? selectedStatusVal; +// final TextEditingController endController; +// final ValueChanged? onStatusChanged; +// final String? dataFrom; +// final VoidCallback onFilter; +// final VoidCallback onRefresh; +// final GlobalKey formKey; +// final bool isMobile; +// +// DateFilterRow({ +// super.key, +// required this.startController, +// required this.endController, +// required this.onFilter, +// required this.onRefresh, +// required this.onStatusChanged, +// this.selectedStatusVal, +// required this.formKey, +// this.isMobile = false, +// this.dataFrom, +// }); + +class DateFilterRow extends ConsumerStatefulWidget { final TextEditingController startController; + final String? selectedStatusVal; + final String? selectedStaffId; final TextEditingController endController; + final ValueChanged? onStatusChanged; + final ValueChanged? onFilterStaff; + final String? dataFrom; final VoidCallback onFilter; final VoidCallback onRefresh; final GlobalKey formKey; final bool isMobile; + final role; + final id; const DateFilterRow({ super.key, @@ -17,10 +55,93 @@ class DateFilterRow extends StatelessWidget { required this.endController, required this.onFilter, required this.onRefresh, + required this.onStatusChanged, + required this.onFilterStaff, + required this.selectedStaffId, + this.selectedStatusVal, required this.formKey, + required this.role, + required this.id, this.isMobile = false, + this.dataFrom, }); + @override + ConsumerState createState() => _DateFilterRowState(); +} + +class _DateFilterRowState extends ConsumerState { + final GlobalKey>> dropDownKey = + GlobalKey>>(); + late ApiService apiService; + List> getStaffDetailsData = []; + List> filteredStaffData = []; + + String? selectedStaff; + String? selectedStaffName; + dynamic role; + + bool isLoading = false; + + @override + void initState() { + super.initState(); + apiService = ApiService(); + + Future.microtask(() { + final managerId = ref.watch(managerIdProvider); + final userID = ref.watch(userIdProvider); + // final handlerId = ref.watch(handlerIdProvider); + role = ref.watch(userRoleProvider); + print("managerId - $managerId"); + if (userID != null && role != null) { + print('hansles'); + getStaffDetails(userID); + } + }); + + // Future.microtask(() { + // print("CUSTuserID - ${widget.id}, CUSTrole -${widget.role}"); + // if (widget.role != null && widget.id != null) { + // print('hansles'); + // getStaffDetails(widget.id); + // } + // }); + } + + Future getStaffDetails(int id) async { + print('getStaffDetails called By handler'); + setState(() { + isLoading = true; + }); + + try { + final response = await apiService.fetchStaffUserList(id, role); + + if (response['status'] == 'success') { + print('getStaffDetails - ${response['data']}'); + setState(() { + getStaffDetailsData = List>.from( + response['data'], + ); + print('API Data - $getStaffDetailsData'); + + filteredStaffData = List.from(getStaffDetailsData); + print('originalData - $filteredStaffData'); + }); + } else { + getStaffDetailsData = []; + filteredStaffData = []; + } + } catch (e) { + print('Exception occurred: $e'); + } finally { + setState(() { + isLoading = false; + }); + } + } + @override Widget build(BuildContext context) { final spacing = 10.0; @@ -51,6 +172,16 @@ class DateFilterRow extends StatelessWidget { SizedBox(width: spacing), buildEndDate(context), SizedBox(width: spacing), + + if (widget.dataFrom == null && widget.dataFrom != 'Policy') ...[ + buildStatusSearch(context), + SizedBox(width: spacing), + ], + + if (widget.role == 'manager' || widget.role == 'handler') ...[ + buildSelectStaffMem(context), + SizedBox(width: spacing), + ], ]; final buttons = [ @@ -67,8 +198,8 @@ class DateFilterRow extends StatelessWidget { child: IconButton( icon: const Icon(Icons.filter_alt_outlined), onPressed: () { - if (formKey.currentState!.validate()) { - onFilter(); + if (widget.formKey.currentState!.validate()) { + widget.onFilter(); } }, ), @@ -80,7 +211,7 @@ class DateFilterRow extends StatelessWidget { child: Tooltip( message: 'Refresh', child: IconButton( - onPressed: onRefresh, + onPressed: widget.onRefresh, icon: const Icon(Icons.refresh), ), ), @@ -101,15 +232,15 @@ class DateFilterRow extends StatelessWidget { } return Form( - key: formKey, - child: isMobile + key: widget.formKey, + child: widget.isMobile ? Column( crossAxisAlignment: CrossAxisAlignment.end, - children: getRowChildren(isMobile, spacing), + children: getRowChildren(widget.isMobile, spacing), ) : Row( crossAxisAlignment: CrossAxisAlignment.end, - children: getRowChildren(isMobile, spacing), + children: getRowChildren(widget.isMobile, spacing), ), ); } @@ -124,15 +255,15 @@ class DateFilterRow extends StatelessWidget { hintText: "Select Date", txtwidth: ResponsiveLayout.isMobile(context) ? null - : MediaQuery.of(context).size.width * 0.16, + : MediaQuery.of(context).size.width * 0.1, // txtheight: 50, // backgroundColor: const Color(0xFFECECEC), // validator: (value) => Validators.requiredField(value, "date"), - controller: startController, + controller: widget.startController, onDateSelected: (date) { print("Picked Date: $date"); - startController.text = DateFormat('dd-MM-yyyy').format(date); + widget.startController.text = DateFormat('dd-MM-yyyy').format(date); // controllers['date']?.text = date as String; }, ), @@ -150,17 +281,16 @@ class DateFilterRow extends StatelessWidget { hintText: "Select Date", txtwidth: ResponsiveLayout.isMobile(context) ? null - : MediaQuery.of(context).size.width * 0.16, + : MediaQuery.of(context).size.width * 0.1, // txtheight: 50, // backgroundColor: const Color(0xFFECECEC), validator: (value) { - if (value == null || value.isEmpty) { - return "End Date is required"; - } - - final fromText = startController.text ?? ''; + final fromText = widget.startController.text ?? ''; if (fromText.isNotEmpty) { final startDate = DateFormat('dd-MM-yyyy').parse(fromText); + if (value == null || value.isEmpty) { + return "End Date is required"; + } final endDate = DateFormat('dd-MM-yyyy').parse(value); if (endDate.isBefore(startDate)) { @@ -169,11 +299,11 @@ class DateFilterRow extends StatelessWidget { } return null; // ✅ no error }, - controller: endController, + controller: widget.endController, lastDate: DateTime.now(), onDateSelected: (date) { print("Picked Date: $date"); - endController.text = DateFormat('dd-MM-yyyy').format(date); + widget.endController.text = DateFormat('dd-MM-yyyy').format(date); // controllers['date']?.text = date as String; }, ), @@ -181,6 +311,256 @@ class DateFilterRow extends StatelessWidget { ); } + Widget buildStatusSearch(BuildContext context) { + final List> statusOptions = [ + {'id': 1, 'status': 'Awaiting Proposal'}, + {'id': 2, 'status': 'Proposal Created'}, + {'id': 3, 'status': 'Proposal Accepted'}, + {'id': 4, 'status': 'Proposal Rejected'}, + {'id': 5, 'status': 'Policy Created'}, + ]; + Map? selectedStatusMap = statusOptions + .where((element) => element['status'] == widget.selectedStatusVal) + .cast>() + .toList() + .firstOrNull; + Map? selectedItem = statusOptions + .cast>() + .firstWhere( + (e) => e['status'] == widget.selectedStatusVal, + orElse: () => {}, // return empty map + ); + + if (selectedItem.isEmpty) selectedItem = null; + // Map? selectedStatus; // ✅ Default: no selection + + return Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text('Status', style: _textStyle), + SizedBox(height: 5), + SizedBox( + height: 40, + child: Container( + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(5.0), + border: Border.all(color: Colors.grey.shade100), + // color: Colors.black, + ), + width: ResponsiveLayout.isMobile(context) + ? null + : MediaQuery.of(context).size.width * 0.14, + child: DropdownSearch>( + // selectedItem: selectedStatus, + selectedItem: selectedStatusMap, + // selectedItem: statusOptions.firstWhere( + // (element) => element['status'] == selectedStatusVal, + // orElse: () => null, // ✅ return null if not found + // ), + items: (filter, infiniteScrollProps) => statusOptions, + + itemAsString: (val) => val['status'].toString(), + compareFn: (item, selectedItem) => + item['id'] == selectedItem['id'], + + // validator: (val) { + // if (val == null) { + // return "Please select a status"; + // } + // return null; + // }, + decoratorProps: DropDownDecoratorProps( + decoration: AppInputDecorations.dropdownDecoration( + label: "Select Status", + ).copyWith(filled: true, fillColor: Colors.white), + ), + // popupProps: PopupProps.menu( + // fit: FlexFit.loose, + // constraints: BoxConstraints(maxHeight: 200), + // menuProps: MenuProps(backgroundColor: Colors.white), + // showSearchBox: false, // 👈 no search box since it's static + // + // ), + popupProps: PopupProps.menu( + fit: FlexFit.loose, + constraints: const BoxConstraints(maxHeight: 200), + menuProps: const MenuProps(backgroundColor: Colors.white), + showSearchBox: false, + + itemBuilder: (context, item, isDisabled, isSelected) { + // ✅ 4 parameters + return Container( + // color: isSelected ? Colors.blue.withOpacity(0.1) : null, + padding: const EdgeInsets.symmetric( + horizontal: 12, + vertical: 6, + ), + child: Text( + item['status'].toString(), + style: GoogleFonts.inter( + fontSize: 13, + color: Colors.black, + ), + ), + ); + }, + ), + + onChanged: (val) { + if (val != null) { + print("Selected Status: ${val['status']}"); + if (widget.onStatusChanged != null) + widget.onStatusChanged!(val['status']); + } + }, + ), + ), + ), + ], + ); + } + + Widget buildSelectStaffMem(BuildContext context) { + // Map? selectedVehicle = filteredStaffData.firstWhere( + // (item) => item['id'].toString() == selectedStaff, + // orElse: () => {}, + // ); + + // Map? selectedVehicle; + // try { + // selectedVehicle = filteredStaffData.firstWhere( + // (item) => item['id'].toString() == selectedStaff, + // ); + // } catch (e) { + // selectedVehicle = null; // ✅ fallback + // } + + Map? selectedVehicle; + if (widget.selectedStaffId == null) { + selectedVehicle = null; + } else if (widget.selectedStaffId != null) { + selectedVehicle = filteredStaffData.firstWhere( + (item) => item['id'] == widget.selectedStaffId, + orElse: () => {}, // empty map + ); + if (selectedVehicle.isEmpty) selectedVehicle = null; + } else if (selectedStaff != null) { + selectedVehicle = filteredStaffData.firstWhere( + (item) => item['id'] == selectedStaff, + orElse: () => {}, // empty map + ); + if (selectedVehicle.isEmpty) selectedVehicle = null; + } else { + selectedVehicle = null; + } + return Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text("Staff Name", style: _textStyle), + SizedBox(height: 10), + Container( + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(5.0), + border: Border.all(color: Colors.grey.shade100), + // color: Colors.black, + ), + + width: ResponsiveLayout.isMobile(context) + ? null + : MediaQuery.of(context).size.width * 0.13, + height: 40, + child: DropdownSearch>( + // key: dropDownKey, + key: ValueKey(selectedStaff), + // selectedItem: selectedVehicle.isNotEmpty ? selectedVehicle : null, + selectedItem: selectedVehicle, + + items: (filter, infiniteScrollProps) { + return filteredStaffData; + }, + + itemAsString: (val) => val['name'].toString(), + compareFn: (item, selectedItem) => + item['id'] == selectedItem['id'], // ✅ compare by id + + decoratorProps: DropDownDecoratorProps( + decoration: + AppInputDecorations.dropdownDecoration( + label: "Select Staff ", + ).copyWith( + filled: true, + fillColor: + Colors.white, // 👈 makes the dropdown input white + ), + ), + + popupProps: PopupProps.menu( + fit: FlexFit.loose, + constraints: BoxConstraints(maxHeight: 250), + menuProps: MenuProps( + backgroundColor: + Colors.white, // 👈 sets dropdown background to white + ), + showSearchBox: true, + searchFieldProps: TextFieldProps( + decoration: InputDecoration( + filled: true, + fillColor: Colors.white, + hintText: "Search Staff ...", + hintStyle: GoogleFonts.inter( + fontSize: 12, + color: Colors.black, + ), + enabledBorder: OutlineInputBorder( + borderSide: BorderSide( + color: Colors.white, + ), // 👈 Normal border + ), + focusedBorder: OutlineInputBorder( + borderSide: BorderSide( + color: Colors.white, + width: 1.5, + ), // 👈 Focused border + ), + ), + ), + + itemBuilder: (context, item, isDisabled, isSelected) { + // ✅ 4 parameters + return Container( + // color: isSelected ? Colors.blue.withOpacity(0.1) : null, + padding: const EdgeInsets.symmetric( + horizontal: 8, + vertical: 3, + ), + child: Text( + item['name'].toString(), + style: GoogleFonts.inter(fontSize: 13, color: Colors.black), + ), + ); + }, + // constraints: BoxConstraints(), + ), + + onChanged: (val) { + if (val != null) { + print("Selected Staff : ${val['name']}"); + print("Id: ${val['id']}"); + selectedStaffName = val['name']; + selectedStaff = val['id']; + + if (widget.onFilterStaff != null) + widget.onFilterStaff!(val['id']); + // controllers['agentId']?.text = val['agent_code']; + // agentId = agent['id']; + } + }, + ), + ), + ], + ); + } + static const _textStyle = TextStyle( fontSize: 12, fontWeight: FontWeight.w600, @@ -188,25 +568,27 @@ class DateFilterRow extends StatelessWidget { Widget buildStartDate1() { return ThemedDateField( - controller: startController, + controller: widget.startController, hintText: 'Select Start Date', validator: (value) => value == null || value.isEmpty ? "Start Date required" : null, onDateSelected: (date) => - startController.text = DateFormat('dd-MM-yyyy').format(date), + widget.startController.text = DateFormat('dd-MM-yyyy').format(date), ); } Widget buildEndDate1() { return ThemedDateField( - controller: endController, + controller: widget.endController, hintText: 'Select End Date', lastDate: DateTime.now(), validator: (value) { if (value == null || value.isEmpty) return "End Date required"; - if (startController.text.isNotEmpty) { - final start = DateFormat('dd-MM-yyyy').parse(startController.text); + if (widget.startController.text.isNotEmpty) { + final start = DateFormat( + 'dd-MM-yyyy', + ).parse(widget.startController.text); final end = DateFormat('dd-MM-yyyy').parse(value); if (end.isBefore(start)) return "End Date cannot be earlier than Start Date"; @@ -214,7 +596,7 @@ class DateFilterRow extends StatelessWidget { return null; }, onDateSelected: (date) => - endController.text = DateFormat('dd-MM-yyyy').format(date), + widget.endController.text = DateFormat('dd-MM-yyyy').format(date), ); } } diff --git a/lib/presentation/widgets/drawer_menu.dart b/lib/presentation/widgets/drawer_menu.dart index f1fd697..4890f3e 100644 --- a/lib/presentation/widgets/drawer_menu.dart +++ b/lib/presentation/widgets/drawer_menu.dart @@ -1,6 +1,7 @@ import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:google_fonts/google_fonts.dart'; +import 'package:shared_preferences/shared_preferences.dart'; import '../../core/routing/routes.dart'; import 'package:go_router/go_router.dart'; @@ -112,8 +113,13 @@ class DrawerMenuState extends ConsumerState { width: 25, ), label: "Dashboard", - onTap: () { + onTap: () async { _hidePopup(); + + final prefs = await SharedPreferences.getInstance(); + await prefs.remove('dashboardKeyProvider'); + await prefs.remove('dashboardStatusProvider'); + await prefs.remove('dashboardStaffIdProvider'); context.go(AppRoutes.dashboard); }, ), @@ -123,7 +129,11 @@ class DrawerMenuState extends ConsumerState { context: context, icon: Icon(Icons.list_alt_rounded, size: 30, color: Colors.black), label: "Enquiry", - onTap: () { + onTap: () async { + final prefs = await SharedPreferences.getInstance(); + await prefs.remove('dashboardKeyProvider'); + await prefs.remove('dashboardStatusProvider'); + await prefs.remove('dashboardStaffIdProvider'); _hidePopup(); if (roleId == 'agent') { context.go(AppRoutes.enquiryLst);