diff --git a/.flutter-plugins-dependencies b/.flutter-plugins-dependencies index 7fec512..c341e2b 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":"fluttertoast","path":"/home/venba/.pub-cache/hosted/pub.dev/fluttertoast-9.0.0/","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":"fluttertoast","path":"/home/venba/.pub-cache/hosted/pub.dev/fluttertoast-9.0.0/","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":"fluttertoast","path":"/home/venba/.pub-cache/hosted/pub.dev/fluttertoast-9.0.0/","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":"fluttertoast","dependencies":[]},{"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-12-03 11:51:56.891228","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_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.2.1/","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":"fluttertoast","path":"/home/venba/.pub-cache/hosted/pub.dev/fluttertoast-9.0.0/","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_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.2.1/","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":"fluttertoast","path":"/home/venba/.pub-cache/hosted/pub.dev/fluttertoast-9.0.0/","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_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.2.1/","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.2.1/","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_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.3.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":"fluttertoast","path":"/home/venba/.pub-cache/hosted/pub.dev/fluttertoast-9.0.0/","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_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":"fluttertoast","dependencies":[]},{"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-12-05 11:12:12.089489","version":"3.32.1","swift_package_manager_enabled":{"ios":false,"macos":false}} \ No newline at end of file diff --git a/lib/core/routing/app_router.dart b/lib/core/routing/app_router.dart index 97c2374..411398a 100644 --- a/lib/core/routing/app_router.dart +++ b/lib/core/routing/app_router.dart @@ -5,7 +5,7 @@ import 'package:nhance_partner/core/routing/routes.dart'; import 'package:nhance_partner/presentation/screens/Enquiry/enquiryList.dart'; import 'package:nhance_partner/presentation/screens/Masters/PaymentMode/paymentList.dart'; import 'package:nhance_partner/presentation/screens/UserManagement/Profile/profile_web.dart'; -import 'package:nhance_partner/presentation/screens/dashboard/dashboard.dart'; +import 'package:nhance_partner/presentation/screens/dashboard/dashboard_nw.dart'; import 'package:nhance_partner/presentation/screens/payout/invoice_list.dart'; import '../../data/services/auth_service.dart'; @@ -21,6 +21,7 @@ import '../../presentation/screens/UserManagement/Agent/agentList.dart'; import '../../presentation/screens/UserManagement/Profile/profile_mobile.dart'; import '../../presentation/screens/UserManagement/Staff/staff.dart'; import '../../presentation/screens/UserManagement/Staff/staffList.dart'; +import '../../presentation/screens/dashboard/dashboard.dart'; import '../../presentation/screens/handler/enquiryList.dart'; import '../../presentation/screens/handler/enquiryListOld.dart'; import '../../presentation/screens/home/home_screen.dart'; @@ -53,7 +54,8 @@ final GoRouter appRouter = GoRouter( // ), GoRoute( path: AppRoutes.dashboard, - builder: (context, state) => const DashboardScreen(), + // builder: (context, state) => const DashboardScreen(), + builder: (context, state) => const Dashboard(), ), GoRoute( diff --git a/lib/core/services/api_service.dart b/lib/core/services/api_service.dart index bd531fc..3eb8e42 100644 --- a/lib/core/services/api_service.dart +++ b/lib/core/services/api_service.dart @@ -820,6 +820,28 @@ class ApiService { return response; } + Future> deleteEnquiy(id, val) async { + final url = Uri.parse( + '${Env.apiUrl}/enquiry/updateEnquiryStatus?enquiry_id=$id&is_active=$val', + ); + + // final token = await getToken(); // Fetch token + + if (_token == null) { + throw Exception('Token not found. Please log in.'); + } + + final headers = { + 'Authorization': 'Bearer $_token', + 'Content-Type': 'application/json', + 'app-signature': Env.App_Signature, + // 'app-signature': 'nhance-partner-2025-signature-35468846JRhH551HK', + }; + + // final response = await _makePostRequestJson(url, data, headers); + final response = await _makeGetRequest(url, headers); + return response; + } //------------------------------------ Quotation ------------------------------------------------ Future> fetchQuickQuotationList(int managerId) async { diff --git a/lib/main.dart b/lib/main.dart index 10f714f..ed59631 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -1,4 +1,4 @@ -import 'package:firebase_app_check/firebase_app_check.dart'; +// import 'package:firebase_app_check/firebase_app_check.dart'; import 'package:firebase_core/firebase_core.dart'; import 'package:firebase_messaging/firebase_messaging.dart'; import 'package:flutter/foundation.dart'; @@ -62,12 +62,12 @@ Future main() async { ), ); } else { - await Firebase.initializeApp(); - await FirebaseAppCheck.instance.activate( - // webProvider: ReCaptchaV3Provider('recaptcha-v3-site-key'), - androidProvider: AndroidProvider.playIntegrity, - appleProvider: AppleProvider.appAttest, - ); + // await Firebase.initializeApp(); + // await FirebaseAppCheck.instance.activate( + // // webProvider: ReCaptchaV3Provider('recaptcha-v3-site-key'), + // androidProvider: AndroidProvider.playIntegrity, + // appleProvider: AppleProvider.appAttest, + // ); // FirebaseMessaging.onBackgroundMessage(_firebaseMessagingBackgroundHandler); // FirebaseMessaging messaging = FirebaseMessaging.instance; diff --git a/lib/presentation/screens/dashboard/dashboard.dart b/lib/presentation/screens/dashboard/dashboard.dart index 106331c..b66a4c1 100644 --- a/lib/presentation/screens/dashboard/dashboard.dart +++ b/lib/presentation/screens/dashboard/dashboard.dart @@ -600,19 +600,20 @@ class _DashboardScreenState extends ConsumerState { data: staffQuotationsPendingList, stringFlag: "Proposal", role: role!, + onRefresh: refresh, ), ), - if (role == 'handler') ...[ - Expanded( - child: UnassignedEnq( - key: UniqueKey(), - title: "Unassigned Enquiries", - role: role, - data: unAssignedEnqList, - onRefresh: refresh, - ), + // if (role == 'handler') ...[ + Expanded( + child: UnassignedEnq( + key: UniqueKey(), + title: "Unassigned Enquiries", + role: role!, + data: unAssignedEnqList, + onRefresh: refresh, ), - ], + ), + // ], ], ) : Row( @@ -737,50 +738,40 @@ class _DashboardScreenState extends ConsumerState { ], ), ), - const SizedBox(height: 5), - // Container( - // child: DynamicHorizontalBarChart( - // data: [ - // {"label": "Jan", "value": 30}, - // {"label": "Feb", "value": 45}, - // {"label": "Mar", "value": 20}, - // ], + // const SizedBox(height: 5), + // if (role == 'manager') + // SizedBox( + // // ✅ replace Expanded + // height: 350, // adjust height as needed + // child: Row( + // children: [ + // Expanded( + // child: UnassignedEnq( + // key: UniqueKey(), + // title: "Unassigned Enquiries", + // role: role!, + // data: unAssignedEnqList, + // onRefresh: refresh, + // ), + // ), + // SizedBox(width: 16), + // Expanded( + // child: Performance( + // title: "Performing Partner", + // data: agentsPerformanceList, + // ), + // ), + // SizedBox(width: 16), + // Expanded( + // child: Performance( + // title: "Non-Performing Partner", + // data: nonAgentsPerformanceList, + // ), + // ), + // ], + // ), // ), - // ), - const SizedBox(height: 5), - if (role == 'manager') - SizedBox( - // ✅ replace Expanded - height: 350, // adjust height as needed - child: Row( - children: [ - Expanded( - child: UnassignedEnq( - key: UniqueKey(), - title: "Unassigned Enquiries", - role: role!, - data: unAssignedEnqList, - onRefresh: refresh, - ), - ), - SizedBox(width: 16), - Expanded( - child: Performance( - title: "Performing Partner", - data: agentsPerformanceList, - ), - ), - SizedBox(width: 16), - Expanded( - child: Performance( - title: "Non-Performing Partner", - data: nonAgentsPerformanceList, - ), - ), - ], - ), - ), ], ), ), @@ -1210,6 +1201,7 @@ class othersPendings extends StatelessWidget { final String stringFlag; String role; final List> data; + final VoidCallback? onRefresh; othersPendings({ Key? key, @@ -1217,6 +1209,7 @@ class othersPendings extends StatelessWidget { required this.role, required this.data, required this.stringFlag, + required this.onRefresh, }) : super(key: key); @override @@ -1228,12 +1221,33 @@ class othersPendings extends StatelessWidget { int totalPending = 0; int totalInProgress = 0; int totalCompleted = 0; + int totalPrevPending = 0; + int totalPendingAll = 0; for (var row in data) { totalTodayAssigned += int.tryParse(row['today_assigned'] ?? '0') ?? 0; - totalPending += int.tryParse(row['pending_assigned'] ?? '0') ?? 0; - totalInProgress += int.tryParse(row['total_in_progress'] ?? '0') ?? 0; - totalCompleted += int.tryParse(row['total_completed'] ?? '0') ?? 0; + totalPending += int.tryParse(row['today_pending'] ?? '0') ?? 0; + totalInProgress += int.tryParse(row['today_in_progress'] ?? '0') ?? 0; + totalCompleted += int.tryParse(row['today_completed'] ?? '0') ?? 0; + totalPrevPending += int.tryParse(row['total_completed'] ?? '0') ?? 0; + + int totalPendingdata = + int.tryParse(row['total_pending']?.toString() ?? '0') ?? 0; + int todayAssigned = + int.tryParse(row['today_assigned']?.toString() ?? '0') ?? 0; + + // totalTodayAssigned += todayAssigned; + totalPendingAll += totalPendingdata; + + int staffPending = totalPendingdata - todayAssigned; + + // totalPrevPending += staffPending; + + final rowPrevPending = + (int.tryParse(row['total_pending'] ?? '0') ?? 0) - + (int.tryParse(row['today_assigned'] ?? '0') ?? 0); + + totalPrevPending += rowPrevPending < 0 ? 0 : rowPrevPending; } return Card( @@ -1247,7 +1261,19 @@ class othersPendings extends StatelessWidget { crossAxisAlignment: CrossAxisAlignment.start, children: [ // Title - Text(title, style: _title), + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text(title, style: _title), + + InkWell( + onTap: () { + onRefresh!(); + }, + child: Icon(Icons.refresh, size: 18), + ), + ], + ), const SizedBox(height: 10), // Header row @@ -1345,6 +1371,14 @@ class othersPendings extends StatelessWidget { style: _headerStyle, ), ), + Expanded( + flex: 2, + child: Text( + 'Prev Pending', + textAlign: TextAlign.center, + style: _headerStyle, + ), + ), // Expanded( // flex: 2, // child: Text( @@ -1366,6 +1400,18 @@ class othersPendings extends StatelessWidget { itemBuilder: (context, index) { final row = data[index]; + final totalPending = + int.tryParse(row['total_pending']?.toString() ?? '0') ?? + 0; + final todayAssigned = + int.tryParse(row['today_assigned']?.toString() ?? '0') ?? + 0; + + final staffPending = (totalPending - todayAssigned); + final safePending = staffPending < 0 ? 0 : staffPending; + + // final staffPending = totalPending - todayAssigned; + final issuedCount = stringFlag == "Policies" ? (row['total_policis_pending'] ?? 0).toString() : (row['total_quotation_pending'] ?? 0).toString(); @@ -1396,8 +1442,8 @@ class othersPendings extends StatelessWidget { flex: 2, child: Text( row['staff_name'] ?? "", - - textAlign: TextAlign.center, + textAlign: TextAlign.left, + // textAlign: TextAlign.center, style: _tableDataStyle, ), ), @@ -1416,7 +1462,8 @@ class othersPendings extends StatelessWidget { handleDashboardNavigation( context, - status: "Assigned", + status: '', + // status: "Assigned", staffId: row['staff_id'] ?? '', role: role, ); @@ -1451,7 +1498,7 @@ class othersPendings extends StatelessWidget { ); }, child: Text( - row['pending_assigned'] ?? "", + row['today_pending'] ?? "", // row['total_approval_pending'] ?? "", textAlign: TextAlign.center, style: _tableDataStyle, @@ -1481,7 +1528,7 @@ class othersPendings extends StatelessWidget { }, child: Text( - row['total_in_progress'] ?? "", + row['today_in_progress'] ?? "", // row['total_approval_pending'] ?? "", textAlign: TextAlign.center, style: _tableDataStyle, @@ -1509,7 +1556,35 @@ class othersPendings extends StatelessWidget { ); }, child: Text( - row['total_completed'] ?? "", + row['today_completed'] ?? "", + // row['total_approval_pending'] ?? "", + textAlign: TextAlign.center, + style: _tableDataStyle, + ), + ), + ), + ), + ), + Expanded( + flex: 2, + child: Material( + color: Colors.white, + child: Center( + child: InkWell( + hoverColor: Color(0xFFEAF6F4), + onTap: () async { + print( + 'Awaiting Approval : ${row['total_completed']} - ${row['staff_id']}', + ); + handleDashboardNavigation( + context, + status: 'PrevPending', + staffId: row['staff_id'] ?? '', + role: role, + ); + }, + child: Text( + safePending.toString() ?? "", // row['total_approval_pending'] ?? "", textAlign: TextAlign.center, style: _tableDataStyle, @@ -1585,6 +1660,14 @@ class othersPendings extends StatelessWidget { style: _headerStyle, ), ), + Expanded( + flex: 2, + child: Text( + totalPrevPending.toString(), + textAlign: TextAlign.center, + style: _headerStyle, + ), + ), ], ), ), diff --git a/lib/presentation/screens/dashboard/dashboard_nw.dart b/lib/presentation/screens/dashboard/dashboard_nw.dart new file mode 100644 index 0000000..44c1812 --- /dev/null +++ b/lib/presentation/screens/dashboard/dashboard_nw.dart @@ -0,0 +1,146 @@ +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:nhance_partner/presentation/screens/dashboard/tabs/bussiness.dart'; +import 'package:nhance_partner/presentation/screens/dashboard/tabs/chart.dart'; +import 'package:nhance_partner/presentation/screens/dashboard/tabs/live.dart'; +import 'package:shared_preferences/shared_preferences.dart'; +import '../../../core/responsive/responsive_builder.dart'; +import '../../../core/routing/routes.dart'; +import '../../../core/services/api_service.dart'; +import '../../layouts/main_layout.dart'; +import '../../providers/manager_provider.dart'; +import '../../providers/quotation_staff_proivder.dart'; +import '../../providers/userRoleProvider.dart'; +import '../../themes/charts/barChart.dart'; +import '../staff/Enquiry/tabs/tab.dart'; +import '../staff/assignStaff.dart'; + +final enquiriesProvider = Provider>>((ref) { + return List.generate(5, (i) { + return { + "reg": "rrTN64V4387", + "Insurer": "rrNew India", + "date": "rr09/09/2025", + "time": "rr11:30 AM", + }; + }); +}); + +class Dashboard extends ConsumerStatefulWidget { + const Dashboard({super.key}); + + @override + ConsumerState createState() => _DashboardState(); +} + +class _DashboardState extends ConsumerState + with SingleTickerProviderStateMixin { + late TabController _tabController; + + // Dynamic items (4 values) + final List tabs = ["Live", "Business", "Partner", "Productivity"]; + + @override + void initState() { + super.initState(); + _tabController = TabController(length: tabs.length, vsync: this); + } + + @override + void dispose() { + _tabController.dispose(); + super.dispose(); + } + + final List tabColors = [ + Colors.amber.shade100, // Live + // Color(0XFFF1556C), // Business + // Color(0XFF02A8B5), // Business + Colors.blue.shade100, // Business + Colors.orange.shade100, // Partner + Colors.green.shade100, // Productivity + ]; + + @override + Widget build(BuildContext context) { + return MainLayout( + title: "Dashboard", + + body: SafeArea( + child: Container( + // color: Colors.amber.shade100, + child: Column( + children: [ + // TabBar( + // padding: EdgeInsets.zero, + // controller: _tabController, + // isScrollable: false, + // indicatorColor: Colors.teal, + // labelColor: Colors.teal, + // unselectedLabelColor: Colors.grey, + // tabs: tabs.map((e) => Tab(text: e)).toList(), + // ), + Row( + // mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: List.generate(tabs.length, (index) { + final isSelected = _tabController.index == index; + + return GestureDetector( + onTap: () { + _tabController.animateTo(index); + setState(() {}); + }, + child: Container( + padding: const EdgeInsets.symmetric( + vertical: 2, + horizontal: 10, + ), + margin: EdgeInsets.only(left: 10), + decoration: BoxDecoration( + // color: isSelected ? Colors.teal : tabColors[index], + color: tabColors[index], + borderRadius: BorderRadius.circular(5), + + border: Border.all( + color: isSelected ? Colors.teal : tabColors[index], + width: 1, + ), + ), + child: Text( + tabs[index], + style: TextStyle( + // color: isSelected ? Colors.white : Colors.black87, + color: Colors.black87, + fontSize: 11, + fontWeight: FontWeight.w500, + ), + ), + ), + ); + }), + ), + + Expanded( + child: TabBarView( + controller: _tabController, + children: [ + // Text('A'), + LiveDashboard(), + BussinessDashboard(), + // BarChartSample7(), + // ReportsPage(), + // UsersPage(), + // SettingsPage(), + ], + ), + ), + ], + ), + ), + ), + ); + } +} diff --git a/lib/presentation/screens/dashboard/dashboard_old.dart b/lib/presentation/screens/dashboard/dashboard_old.dart index 07ada68..506b7b0 100644 --- a/lib/presentation/screens/dashboard/dashboard_old.dart +++ b/lib/presentation/screens/dashboard/dashboard_old.dart @@ -11,6 +11,7 @@ import '../../layouts/main_layout.dart'; import '../../providers/manager_provider.dart'; import '../../providers/quotation_staff_proivder.dart'; import '../../providers/userRoleProvider.dart'; +import '../../themes/charts/barChart.dart'; import '../staff/Enquiry/tabs/tab.dart'; import '../staff/assignStaff.dart'; @@ -584,7 +585,7 @@ class _DashboardScreenState extends ConsumerState { ? MediaQuery.of(context).size.height * 0.69 //400 : (role == 'manager') - ? MediaQuery.of(context).size.height * 0.5 + ? MediaQuery.of(context).size.height * 0.85 : (role == 'staff' || role == 'handler') ? MediaQuery.of(context).size.height * 0.85 : MediaQuery.of(context).size.height * @@ -599,19 +600,20 @@ class _DashboardScreenState extends ConsumerState { data: staffQuotationsPendingList, stringFlag: "Proposal", role: role!, + onRefresh: refresh, ), ), - if (role == 'handler') ...[ - Expanded( - child: UnassignedEnq( - key: UniqueKey(), - title: "Unassigned Enquiries", - role: role, - data: unAssignedEnqList, - onRefresh: refresh, - ), + // if (role == 'handler') ...[ + Expanded( + child: UnassignedEnq( + key: UniqueKey(), + title: "Unassigned Enquiries", + role: role!, + data: unAssignedEnqList, + onRefresh: refresh, ), - ], + ), + // ], ], ) : Row( @@ -736,39 +738,40 @@ class _DashboardScreenState extends ConsumerState { ], ), ), - const SizedBox(height: 5), - if (role == 'manager') - SizedBox( - // ✅ replace Expanded - height: 350, // adjust height as needed - child: Row( - children: [ - Expanded( - child: UnassignedEnq( - key: UniqueKey(), - title: "Unassigned Enquiries", - role: role!, - data: unAssignedEnqList, - onRefresh: refresh, - ), - ), - SizedBox(width: 16), - Expanded( - child: Performance( - title: "Performing Partner", - data: agentsPerformanceList, - ), - ), - SizedBox(width: 16), - Expanded( - child: Performance( - title: "Non-Performing Partner", - data: nonAgentsPerformanceList, - ), - ), - ], - ), - ), + + // const SizedBox(height: 5), + // if (role == 'manager') + // SizedBox( + // // ✅ replace Expanded + // height: 350, // adjust height as needed + // child: Row( + // children: [ + // Expanded( + // child: UnassignedEnq( + // key: UniqueKey(), + // title: "Unassigned Enquiries", + // role: role!, + // data: unAssignedEnqList, + // onRefresh: refresh, + // ), + // ), + // SizedBox(width: 16), + // Expanded( + // child: Performance( + // title: "Performing Partner", + // data: agentsPerformanceList, + // ), + // ), + // SizedBox(width: 16), + // Expanded( + // child: Performance( + // title: "Non-Performing Partner", + // data: nonAgentsPerformanceList, + // ), + // ), + // ], + // ), + // ), ], ), ), @@ -1198,6 +1201,7 @@ class othersPendings extends StatelessWidget { final String stringFlag; String role; final List> data; + final VoidCallback? onRefresh; othersPendings({ Key? key, @@ -1205,12 +1209,47 @@ class othersPendings extends StatelessWidget { required this.role, required this.data, required this.stringFlag, + required this.onRefresh, }) : super(key: key); @override Widget build(BuildContext context) { print(' Data: $data'); + // Compute totals + int totalTodayAssigned = 0; + int totalPending = 0; + int totalInProgress = 0; + int totalCompleted = 0; + int totalPrevPending = 0; + int totalPendingAll = 0; + + for (var row in data) { + totalTodayAssigned += int.tryParse(row['today_assigned'] ?? '0') ?? 0; + totalPending += int.tryParse(row['today_pending'] ?? '0') ?? 0; + totalInProgress += int.tryParse(row['today_in_progress'] ?? '0') ?? 0; + totalCompleted += int.tryParse(row['today_completed'] ?? '0') ?? 0; + totalPrevPending += int.tryParse(row['total_completed'] ?? '0') ?? 0; + + int totalPendingdata = + int.tryParse(row['total_pending']?.toString() ?? '0') ?? 0; + int todayAssigned = + int.tryParse(row['today_assigned']?.toString() ?? '0') ?? 0; + + totalTodayAssigned += todayAssigned; + totalPendingAll += totalPendingdata; + + int staffPending = totalPendingdata - todayAssigned; + + // totalPrevPending += staffPending; + + final rowPrevPending = + (int.tryParse(row['total_pending'] ?? '0') ?? 0) - + (int.tryParse(row['today_assigned'] ?? '0') ?? 0); + + totalPrevPending += rowPrevPending < 0 ? 0 : rowPrevPending; + } + return Card( color: Colors.white, // color: const Color(0xFFEAF6F4), @@ -1222,7 +1261,19 @@ class othersPendings extends StatelessWidget { crossAxisAlignment: CrossAxisAlignment.start, children: [ // Title - Text(title, style: _title), + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text(title, style: _title), + + InkWell( + onTap: () { + onRefresh!(); + }, + child: Icon(Icons.refresh, size: 18), + ), + ], + ), const SizedBox(height: 10), // Header row @@ -1320,6 +1371,14 @@ class othersPendings extends StatelessWidget { style: _headerStyle, ), ), + Expanded( + flex: 2, + child: Text( + 'Prev Pending', + textAlign: TextAlign.center, + style: _headerStyle, + ), + ), // Expanded( // flex: 2, // child: Text( @@ -1341,6 +1400,18 @@ class othersPendings extends StatelessWidget { itemBuilder: (context, index) { final row = data[index]; + final totalPending = + int.tryParse(row['total_pending']?.toString() ?? '0') ?? + 0; + final todayAssigned = + int.tryParse(row['today_assigned']?.toString() ?? '0') ?? + 0; + + final staffPending = (totalPending - todayAssigned); + final safePending = staffPending < 0 ? 0 : staffPending; + + // final staffPending = totalPending - todayAssigned; + final issuedCount = stringFlag == "Policies" ? (row['total_policis_pending'] ?? 0).toString() : (row['total_quotation_pending'] ?? 0).toString(); @@ -1350,9 +1421,9 @@ class othersPendings extends StatelessWidget { : row['total_premium_value']; return Container( - margin: const EdgeInsets.symmetric(vertical: 5), + margin: const EdgeInsets.symmetric(vertical: 3), padding: const EdgeInsets.symmetric( - vertical: 5, + vertical: 4, horizontal: 12, ), decoration: BoxDecoration( @@ -1367,25 +1438,6 @@ class othersPendings extends StatelessWidget { ), child: Row( children: [ - // Expanded( - // flex: 1, - // child: Text( - // (index + 1).toString(), - // textAlign: TextAlign.center, - // style: _tableDataStyle, - // ), - // ), - // if (role == 'manager') ...[ - // Expanded( - // flex: 2, - // child: Text( - // row['handler_name'] ?? "", - // - // textAlign: TextAlign.center, - // style: _tableDataStyle, - // ), - // ), - // ], Expanded( flex: 2, child: Text( @@ -1396,44 +1448,6 @@ class othersPendings extends StatelessWidget { ), ), - // Expanded( - // flex: 2, - // child: Text( - // row['total_assigned'] ?? "", - // // row['total_approval_pending'] ?? "", - // textAlign: TextAlign.center, - // style: _tableDataStyle, - // ), - // ), - // Expanded( - // flex: 2, - // child: Material( - // color: Colors.white, - // child: Center( - // child: InkWell( - // hoverColor: Color(0xFFEAF6F4), - // onTap: () { - // print( - // 'total_assigned : ${row['total_assigned']}', - // ); - // - // handleDashboardNavigation( - // context, - // status: "Assigned", - // staffId: row['staff_id'] ?? '', - // role: role, - // ); - // }, - // child: Text( - // row['total_assigned'] ?? "", - // // row['total_approval_pending'] ?? "", - // textAlign: TextAlign.center, - // style: _tableDataStyle, - // ), - // ), - // ), - // ), - // ), Expanded( flex: 2, child: Material( @@ -1483,7 +1497,7 @@ class othersPendings extends StatelessWidget { ); }, child: Text( - row['pending_assigned'] ?? "", + row['today_pending'] ?? "", // row['total_approval_pending'] ?? "", textAlign: TextAlign.center, style: _tableDataStyle, @@ -1513,7 +1527,7 @@ class othersPendings extends StatelessWidget { }, child: Text( - row['total_in_progress'] ?? "", + row['today_in_progress'] ?? "", // row['total_approval_pending'] ?? "", textAlign: TextAlign.center, style: _tableDataStyle, @@ -1541,7 +1555,35 @@ class othersPendings extends StatelessWidget { ); }, child: Text( - row['total_completed'] ?? "", + row['today_completed'] ?? "", + // row['total_approval_pending'] ?? "", + textAlign: TextAlign.center, + style: _tableDataStyle, + ), + ), + ), + ), + ), + Expanded( + flex: 2, + child: Material( + color: Colors.white, + child: Center( + child: InkWell( + hoverColor: Color(0xFFEAF6F4), + onTap: () async { + print( + 'Awaiting Approval : ${row['total_completed']} - ${row['staff_id']}', + ); + handleDashboardNavigation( + context, + status: 'PrevPending', + staffId: row['staff_id'] ?? '', + role: role, + ); + }, + child: Text( + safePending.toString() ?? "", // row['total_approval_pending'] ?? "", textAlign: TextAlign.center, style: _tableDataStyle, @@ -1566,6 +1608,60 @@ class othersPendings extends StatelessWidget { }, ), ), + const SizedBox(height: 8), + // Header row + Container( + padding: const EdgeInsets.symmetric(vertical: 8, horizontal: 12), + decoration: BoxDecoration( + color: Color(0xFFF1F5F9), + // color: Color(0xFFE3F9F8), + borderRadius: BorderRadius.circular(10), + ), + child: Row( + children: [ + Expanded( + flex: 2, + child: Text( + "Total", + textAlign: TextAlign.center, + style: _headerStyle, + ), + ), + Expanded( + flex: 2, + child: Text( + totalTodayAssigned.toString(), + textAlign: TextAlign.center, + style: _headerStyle, + ), + ), + Expanded( + flex: 2, + child: Text( + totalPending.toString(), + textAlign: TextAlign.center, + style: _headerStyle, + ), + ), + Expanded( + flex: 2, + child: Text( + totalInProgress.toString(), + textAlign: TextAlign.center, + style: _headerStyle, + ), + ), + Expanded( + flex: 2, + child: Text( + totalPrevPending.toString(), + textAlign: TextAlign.center, + style: _headerStyle, + ), + ), + ], + ), + ), ], ), ), diff --git a/lib/presentation/screens/dashboard/tabs/bussiness.dart b/lib/presentation/screens/dashboard/tabs/bussiness.dart new file mode 100644 index 0000000..110e631 --- /dev/null +++ b/lib/presentation/screens/dashboard/tabs/bussiness.dart @@ -0,0 +1,48 @@ +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter/src/widgets/framework.dart'; +import 'package:flutter_riverpod/flutter_riverpod.dart'; +import 'package:google_fonts/google_fonts.dart'; + +import '../../../themes/charts/barChart.dart'; + +class BussinessDashboard extends ConsumerStatefulWidget { + const BussinessDashboard({super.key}); + + @override + ConsumerState createState() => _BussinessDashboardState(); +} + +class _BussinessDashboardState extends ConsumerState { + @override + Widget build(BuildContext context) { + return Container( + margin: EdgeInsets.all(10), + // color: Colors.white, + // color: Colors.amber.shade100, + child: Column( + children: [ + Row( + children: [ + Text('Product Wise', style: _headerStyle2), + // BarChart( + // dataList: [ + // _BarData(Colors.blue, 10, 8), + // _BarData(Colors.orange, 12, 10), + // _BarData(Colors.green, 8, 5), + // ], + // labels: ["A", "B", "C"], + // ), + ], + ), + ], + ), + ); + } +} + +final _headerStyle2 = GoogleFonts.poppins( + fontSize: 12, + color: Colors.black, + fontWeight: FontWeight.w500, +); diff --git a/lib/presentation/screens/dashboard/tabs/chart.dart b/lib/presentation/screens/dashboard/tabs/chart.dart new file mode 100644 index 0000000..950bf03 --- /dev/null +++ b/lib/presentation/screens/dashboard/tabs/chart.dart @@ -0,0 +1,242 @@ +import 'dart:math' as math; + +import 'package:fl_chart/fl_chart.dart'; + +import 'package:flutter/material.dart'; + +import '../../../themes/charts/appChartColors.dart'; + +class BarChartSample7 extends StatefulWidget { + BarChartSample7({super.key}); + + final shadowColor = const Color(0xFFCCCCCC); + final dataList = [ + _BarData(AppColors.contentColorYellow, 18, 18), + _BarData(AppColors.contentColorGreen, 17, 8), + _BarData(AppColors.contentColorOrange, 10, 15), + _BarData(AppColors.contentColorPink, 2.5, 5), + _BarData(AppColors.contentColorBlue, 2, 2.5), + _BarData(AppColors.contentColorRed, 2, 2), + ]; + + @override + State createState() => _BarChartSample7State(); +} + +class _BarChartSample7State extends State { + BarChartGroupData generateBarGroup( + int x, + Color color, + double value, + double shadowValue, + ) { + return BarChartGroupData( + x: x, + barRods: [ + BarChartRodData(toY: value, color: color, width: 6), + BarChartRodData(toY: shadowValue, color: widget.shadowColor, width: 6), + ], + showingTooltipIndicators: touchedGroupIndex == x ? [0] : [], + ); + } + + int touchedGroupIndex = -1; + + int rotationTurns = 1; + + @override + Widget build(BuildContext context) { + return Padding( + padding: const EdgeInsets.all(24), + child: Column( + children: [ + Row( + children: [ + Expanded(child: Container()), + const Text( + 'Horizontal Bar Chart', + style: TextStyle(color: AppColors.mainTextColor1, fontSize: 20), + ), + Expanded( + child: Align( + alignment: Alignment.centerRight, + child: Tooltip( + message: 'Rotate the chart 90 degrees (cw)', + child: IconButton( + onPressed: () { + setState(() { + rotationTurns += 1; + }); + }, + icon: RotatedBox( + quarterTurns: rotationTurns - 1, + child: const Icon(Icons.rotate_90_degrees_cw), + ), + ), + ), + ), + ), + ], + ), + const SizedBox(height: 18), + AspectRatio( + aspectRatio: 1.4, + child: BarChart( + BarChartData( + alignment: BarChartAlignment.spaceBetween, + rotationQuarterTurns: rotationTurns, + borderData: FlBorderData( + show: true, + border: Border.symmetric( + horizontal: BorderSide( + color: AppColors.borderColor.withValues(alpha: 0.2), + ), + ), + ), + titlesData: FlTitlesData( + show: true, + leftTitles: const AxisTitles( + drawBelowEverything: true, + sideTitles: SideTitles(showTitles: true, reservedSize: 30), + ), + bottomTitles: AxisTitles( + sideTitles: SideTitles( + showTitles: true, + reservedSize: 50, + getTitlesWidget: (value, meta) { + final index = value.toInt(); + return SideTitleWidget( + meta: meta, + child: Text('data'), + // child: _IconWidget( + // color: widget.dataList[index].color, + // isSelected: touchedGroupIndex == index, + // ), + ); + }, + ), + ), + // rightTitles: const AxisTitles(), + // topTitles: const AxisTitles(), + ), + gridData: FlGridData( + show: true, + drawVerticalLine: false, + getDrawingHorizontalLine: (value) => FlLine( + color: AppColors.borderColor.withValues(alpha: 0.2), + strokeWidth: 1, + ), + ), + barGroups: widget.dataList.asMap().entries.map((e) { + final index = e.key; + final data = e.value; + return generateBarGroup( + index, + data.color, + data.value, + data.shadowValue, + ); + }).toList(), + maxY: 20, + barTouchData: BarTouchData( + enabled: true, + handleBuiltInTouches: false, + touchTooltipData: BarTouchTooltipData( + getTooltipColor: (group) => Colors.transparent, + tooltipMargin: 0, + getTooltipItem: + ( + BarChartGroupData group, + int groupIndex, + BarChartRodData rod, + int rodIndex, + ) { + return BarTooltipItem( + rod.toY.toString(), + TextStyle( + fontWeight: FontWeight.bold, + color: rod.color, + fontSize: 18, + shadows: const [ + Shadow(color: Colors.black26, blurRadius: 12), + ], + ), + ); + }, + ), + touchCallback: (event, response) { + if (event.isInterestedForInteractions && + response != null && + response.spot != null) { + setState(() { + touchedGroupIndex = response.spot!.touchedBarGroupIndex; + }); + } else { + setState(() { + touchedGroupIndex = -1; + }); + } + }, + ), + ), + ), + ), + ], + ), + ); + } +} + +class _BarData { + const _BarData(this.color, this.value, this.shadowValue); + + final Color color; + final double value; + final double shadowValue; +} + +class _IconWidget extends ImplicitlyAnimatedWidget { + const _IconWidget({required this.color, required this.isSelected}) + : super(duration: const Duration(milliseconds: 300)); + final Color color; + final bool isSelected; + + @override + ImplicitlyAnimatedWidgetState createState() => + _IconWidgetState(); +} + +class _IconWidgetState extends AnimatedWidgetBaseState<_IconWidget> { + Tween? _rotationTween; + + @override + Widget build(BuildContext context) { + final rotation = math.pi * 4 * _rotationTween!.evaluate(animation); + final scale = 1 + _rotationTween!.evaluate(animation) * 0.5; + return Transform( + transform: Matrix4.identity()..scale(0.8), + // transform: Matrix4.rotationZ(rotation)..scaled(scale, scale, scale), + // transform: Matrix4.rotationZ(rotation)..scale(scale, scale, scale), + origin: const Offset(14, 14), + child: Icon( + widget.isSelected ? Icons.face_retouching_natural : Icons.face, + color: widget.color, + size: 28, + ), + ); + } + + @override + void forEachTween(TweenVisitor visitor) { + _rotationTween = + visitor( + _rotationTween, + widget.isSelected ? 1.0 : 0.0, + (dynamic value) => Tween( + begin: value as double, + end: widget.isSelected ? 1.0 : 0.0, + ), + ) + as Tween?; + } +} diff --git a/lib/presentation/screens/dashboard/tabs/live.dart b/lib/presentation/screens/dashboard/tabs/live.dart new file mode 100644 index 0000000..06dae63 --- /dev/null +++ b/lib/presentation/screens/dashboard/tabs/live.dart @@ -0,0 +1,2261 @@ +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/responsive/responsive_builder.dart'; +import '../../../../core/routing/routes.dart'; +import '../../../../core/services/api_service.dart'; +import '../../../providers/manager_provider.dart'; +import '../../../providers/quotation_staff_proivder.dart'; +import '../../../providers/userRoleProvider.dart'; +import '../../staff/Enquiry/tabs/tab.dart'; +import '../../staff/assignStaff.dart'; + +final enquiriesProvider = Provider>>((ref) { + return List.generate(5, (i) { + return { + "reg": "rrTN64V4387", + "Insurer": "rrNew India", + "date": "rr09/09/2025", + "time": "rr11:30 AM", + }; + }); +}); + +String formatToCroresLakhsAndThousands(String value) { + double numValue = double.parse(value); + + if (numValue >= 10000000) { + return "₹ ${(numValue / 10000000).toStringAsFixed(2)} Crores"; + } else if (numValue >= 100000) { + return "₹ ${(numValue / 100000).toStringAsFixed(2)} Lakhs"; + } else if (numValue >= 1000) { + return "₹ ${(numValue / 1000).toStringAsFixed(2)} Thousands"; + } else { + return "₹ $numValue"; + } +} + +class LiveDashboard extends ConsumerStatefulWidget { + const LiveDashboard({super.key}); + + @override + ConsumerState createState() => _DashboardState(); +} + +class _DashboardState extends ConsumerState { + int selectedIndex = 1; + int switcherStatus = 1; + late ApiService apiService; + String? policiesIssuedToday; + String? policiesIssuedYear; + String? policiesIssuedMonth; + String? premiumValueToday; + String? premiumValueYear; + String? premiumValueMonth; + String? earningsToday; + String? earningsMonth; + String? earningsYear; + String? quotationsPendingCounts; // cross verify + String? currentKey; // cross verify + + // List> dataVal = []; + List> getStaffData = []; + List> originalData = []; + List> filteredData = []; + int selectedTabIndex = 0; + List> currentList = []; + + List> staffQuotationsPendingList = []; // cross verify + List> quotationsPendingList = []; // cross verify + List> policiesPendingList = []; // cross verify + List> awaitingApprovalList = []; // cross verify + List> unAssignedEnqList = []; // cross verify + List> agentsPerformanceList = []; // cross verify + List> nonAgentsPerformanceList = []; // cross verify + dynamic prefid; + dynamic prefroleId; + bool isLoading = false; + + @override + void initState() { + super.initState(); + + apiService = ApiService(); + + Future.microtask(() { + final prefmanagerid = ref.read(managerIdProvider); + final prefuserid = ref.read(userIdProvider); + final prefroleId = ref.read(userRoleProvider); + + print("B81 => roleId: $prefroleId | userId: $prefuserid "); + if (prefuserid != null) { + getStaffList(prefmanagerid!, prefroleId, prefuserid); + } + }); + } + + void refresh() { + print('___DASHBOARD___'); + final prefmanagerid = ref.read(managerIdProvider); + final prefuserid = ref.read(userIdProvider); + final prefroleId = ref.read(userRoleProvider); + + if (prefuserid != null) { + print("REFRESH- calling getStaffList with $prefmanagerid, $prefuserid"); + getStaffList(prefmanagerid!, prefroleId, prefuserid); + } + } + + Future handleEdit(String id) async { + // Navigator.pop(context); + print('EDITStaff'); + print('EDITStaff - $id'); + // dynamic id = data['id']; + // context.go('/tabEnquiry/$id'); + + final prefs = await SharedPreferences.getInstance(); + // ✅ Remove old value (if any) + await prefs.remove('enqAgentDataId'); + + // setState(() { + // final id = item['id'].toString(); + // ✅ Save the new id + // await prefs.setString('enqAgentDataId', id.toString()); + await prefs.setString('enqAgentDataId', id); + ref.read(enquiryIdProvider.notifier).state = id; + context.go(AppRoutes.tabEnquiry); + } + + Future handleStaffEdit(String id, String? flag) async { + // Navigator.pop(context); ddd + dynamic val; + print('EDITStaff - $id'); + + if (flag == "Policies") { + val = 'Policy'; + } else { + val = ''; + } + + var enqId = id; + + final prefs = await SharedPreferences.getInstance(); + + // ✅ Remove old value (if any) + await prefs.remove('enqStaffDataId'); + + // ✅ Save the new id + await prefs.setString('enqStaffDataId', enqId.toString()); + await prefs.setString('navFromDashboard', 'Dashboard'); + + ref.read(quotationStaffIdProvider.notifier).state = enqId; + ref.read(navFromEnqStaffProvider.notifier).state = 'Dashboard'; + + // showDialog( + // context: context, + // builder: (context) => TabEnquiryStaffList(showKey: val), + // ); + + final result = await showDialog( + context: context, + barrierDismissible: + false, // optional - prevents closing by tapping outside + builder: (context) => TabEnquiryStaffList(showKey: val), + ); + + // ✅ Code here runs *after* the dialog is closed + print("Dialog closed"); + print("Dialog result: $result"); + refresh(); + } + + Future getStaffList(int managerId, role, userId) async { + print('B89 => Fns called => $managerId | $role'); + setState(() { + isLoading = true; + }); + + try { + final response = await apiService.fetchDashboard(managerId, role, userId); + + if (response['status'] == 'success') { + final data = response['data']; + print('B99 => getStaffListData => ${response['data']}'); + setState(() { + // policiesIssuedToday = data['policies_issued']['today'].toString(); + // policiesIssuedYear = data['policies_issued']['year'].toString(); + // policiesIssuedMonth = data['policies_issued']['month'].toString(); + // premiumValueToday = data['premium_value']['today'].toString(); + // premiumValueYear = data['premium_value']['year'].toString(); + // premiumValueMonth = data['premium_value']['month'].toString(); + // earningsToday = data['earnings']['today'].toString(); + // earningsYear = data['earnings']['year'].toString(); + // earningsMonth = data['earnings']['month'].toString(); + + // Policies Issued + if (data['policies_issued'] != null) { + policiesIssuedToday = + data['policies_issued']['today']?.toString() ?? "0"; + policiesIssuedYear = + data['policies_issued']['year']?.toString() ?? "0"; + policiesIssuedMonth = + data['policies_issued']['month']?.toString() ?? "0"; + } else { + policiesIssuedToday = "0"; + policiesIssuedYear = "0"; + policiesIssuedMonth = "0"; + } + + // Premium Value + if (data['premium_value'] != null) { + premiumValueToday = + data['premium_value']['today']?.toString() ?? "0"; + premiumValueYear = data['premium_value']['year']?.toString() ?? "0"; + premiumValueMonth = + data['premium_value']['month']?.toString() ?? "0"; + } else { + premiumValueToday = "0"; + premiumValueYear = "0"; + premiumValueMonth = "0"; + } + + // Earnings + if (data['earnings'] != null) { + earningsToday = data['earnings']['today']?.toString() ?? "0"; + earningsYear = data['earnings']['year']?.toString() ?? "0"; + earningsMonth = data['earnings']['month']?.toString() ?? "0"; + } else { + earningsToday = "0"; + earningsYear = "0"; + earningsMonth = "0"; + } + + // agents_performance + if (data['agents_performance'] != null) { + agentsPerformanceList = List>.from( + (data['agents_performance'] as List).map( + (item) => Map.from(item), + ), + ); + + agentsPerformanceList.sort((a, b) { + // int aValue = a['total_policis_pending'] ?? 0; + // int bValue = b['total_policis_pending'] ?? 0; + + int aValue = (a['total_policis_pending'] ?? 0) is int + ? a['total_policis_pending'] + : int.tryParse( + a['total_policis_pending']?.toString() ?? '0', + ) ?? + 0; + int bValue = (b['total_policis_pending'] ?? 0) is int + ? b['total_policis_pending'] + : int.tryParse( + b['total_policis_pending']?.toString() ?? '0', + ) ?? + 0; + return aValue.compareTo(bValue); + // return aValue.compareTo(bValue); // ascending + }); + } + + //nonAgentsPerformanceList + if (data['agents_performance'] != null) { + nonAgentsPerformanceList = List>.from( + (data['agents_performance'] as List).map( + (item) => Map.from(item), + ), + ); + + // Sort descending + nonAgentsPerformanceList.sort((a, b) { + // int aValue = a['total_policy_pending'] ?? 0; + // int bValue = b['total_policy_pending'] ?? 0; + int aValue = (a['total_policis_pending'] ?? 0) is int + ? a['total_policis_pending'] + : int.tryParse( + a['total_policis_pending']?.toString() ?? '0', + ) ?? + 0; + int bValue = (b['total_policis_pending'] ?? 0) is int + ? b['total_policis_pending'] + : int.tryParse( + b['total_policis_pending']?.toString() ?? '0', + ) ?? + 0; + return bValue.compareTo(aValue); // descending + }); + } + + if (data['staff_level_pending_summary'] != null) { + print('staff_level_pending_summary -'); + staffQuotationsPendingList = List>.from( + (data['staff_level_pending_summary'] as List).map( + (item) => Map.from(item), + ), + ); + print('staff_level_pending_summary - $staffQuotationsPendingList'); + } + + if (data['quotations_pending'] != null) { + quotationsPendingList = List>.from( + (data['quotations_pending'] as List).map( + (item) => Map.from(item), + ), + ); + } + + if (data['quotations_approval_pending'] != null) { + awaitingApprovalList = List>.from( + (data['quotations_approval_pending'] as List).map( + (item) => Map.from(item), + ), + ); + } + if (data['policies_pending'] != null) { + policiesPendingList = List>.from( + (data['policies_pending'] as List).map( + (item) => Map.from(item), + ), + ); + } + + if (data['unassigned_enquiry'] != null) { + unAssignedEnqList = List>.from( + (data['unassigned_enquiry'] as List).map( + (item) => Map.from(item), + ), + ); + } + }); + } else { + getStaffData = []; + originalData = []; + } + } catch (e) { + print('Exception occurred: $e'); + } finally { + setState(() { + isLoading = false; + }); + } + } + + @override + Widget build(BuildContext context) { + final enquiries = ref.watch(enquiriesProvider); + final managerId = ref.watch(managerIdProvider); + final userId = ref.watch(userIdProvider); + final role = ref.watch(userRoleProvider); + + return Column( + children: [ + ResponsiveBuilder.isMobile(context) + ? Container( + // color: Colors.redAccent, + // height: MediaQuery.of(context).size.height, + // ✅ take available space + child: SingleChildScrollView( + scrollDirection: Axis.vertical, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + // 🔹 Stats cards stacked + // Padding( + // padding: const EdgeInsets.all(8.0), + // child: StatCard( + // title: "Policies Issued", + // today: policiesIssuedToday ?? '', + // month: policiesIssuedMonth ?? '', + // year: policiesIssuedYear ?? '', + // imagePath: "assets/dashboard/Policy issue icon.png", + // ), + // ), + // // const SizedBox(height: 12), + // Padding( + // padding: const EdgeInsets.all(8.0), + // child: StatCard( + // title: "Premium Value", + // today: premiumValueToday ?? '', + // month: premiumValueMonth ?? '', + // year: premiumValueYear ?? '', + // imagePath: "assets/dashboard/Policy issue icon.png", + // ), + // ), + // // const SizedBox(height: 12), + // Padding( + // padding: const EdgeInsets.all(8.0), + // child: StatCard( + // title: "Earnings", + // today: earningsToday ?? '', + // month: earningsMonth ?? '', + // year: earningsYear ?? '', + // imagePath: "assets/dashboard/Policy issue icon.png", + // ), + // ), + // + // const SizedBox(height: 20), + Container( + padding: const EdgeInsets.all(16.0), + decoration: BoxDecoration( + color: Color(0XFFEDF6F5), + borderRadius: const BorderRadius.only( + topLeft: Radius.circular(50), // adjust radius + topRight: Radius.circular(50), + ), + ), + // 🔹 Tab Switcher + child: Column( + children: [ + Container( + decoration: BoxDecoration( + color: const Color(0xFF425B5B), + borderRadius: BorderRadius.circular(25), + ), + padding: const EdgeInsets.all(6), + child: SingleChildScrollView( + scrollDirection: Axis.horizontal, + child: Row( + children: [ + Padding( + padding: const EdgeInsets.all(8.0), + child: buildTab("Awaiting Proposal", 0), + ), + const SizedBox(width: 10), + Padding( + padding: const EdgeInsets.all(8.0), + child: buildTab("Awaiting Approval", 1), + ), + + const SizedBox(width: 10), + Padding( + padding: const EdgeInsets.all(8.0), + child: buildTab("Awaiting Policy", 2), + ), + ], + ), + ), + ), + + const SizedBox(height: 20), + + // 🔹 Scrollable list + ListView.builder( + itemCount: currentList.length, + shrinkWrap: true, + physics: const NeverScrollableScrollPhysics(), + itemBuilder: (context, index) { + final item = currentList[index]; + + // Split date & time from created_on + String date = ""; + String time = ""; + if ((item['created_on'] ?? "").isNotEmpty) { + final parts = item['created_on'].split(' '); + date = parts[0]; + if (parts.isNotEmpty) { + DateTime parsedDate = DateTime.parse( + parts[0], + ); + date = DateFormat( + 'dd-MM-yyyy', + ).format(parsedDate); // 19/09/2025 + } + // time = parts.length > 1 ? parts[1] : ""; + // Format the time part (HH:mm) + if (parts.length >= 2) { + final timeParts = parts[1].split(":"); + time = + "${timeParts[0]}:${timeParts[1]}"; // 05:45 + } else { + time = ""; + } + } + + return Card( + elevation: 2, + margin: const EdgeInsets.symmetric( + vertical: 8, + ), + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(12), + ), + color: Colors.white, + child: ListTile( + onTap: () { + dynamic id = item['id'].toString(); + + print("Tapped ID: ${item['id']}"); + handleEdit(id); + }, + title: Text( + item["reg_no"] ?? "-", // from API + style: GoogleFonts.inter( + fontWeight: FontWeight.bold, + fontSize: 12, + ), + ), + + subtitle: (currentKey == 'policies') + ? Text( + item["insurer_name"] ?? "-", + style: GoogleFonts.inter( + fontSize: 12, + fontWeight: FontWeight.bold, + ), + ) + : SizedBox.shrink(), + trailing: Column( + mainAxisAlignment: + MainAxisAlignment.center, + children: [ + Text( + date, + style: GoogleFonts.inter( + fontSize: 12, + ), + ), + Text(time, style: _tableDataTimeStyle), + ], + ), + ), + ); + }, + ), + ], + ), + ), + ], + ), + ), + ) + : Container( + // color: Colors.red.shade100, + // height: MediaQuery.of(context).size.height * 0.75, + child: SingleChildScrollView( + scrollDirection: Axis.vertical, + child: Column( + children: [ + // if (role != 'staff') + if (role != 'staff' && + role != 'handler' && + role != 'manager') + Row( + children: [ + Expanded( + child: StatCard( + title: "Policies Issued", + today: policiesIssuedToday ?? '', + month: policiesIssuedMonth ?? '', + year: policiesIssuedYear ?? '', + colorDark: Color(0xFF059669), + imagePath: + "assets/dashboard/Policy issue icon.png", + ), + ), + SizedBox(width: 16), + Expanded( + child: StatCard( + title: "Premium Value", + today: premiumValueToday ?? '', + month: premiumValueMonth ?? '', + year: premiumValueYear ?? '', + colorDark: Color(0XFF1d4ed8), + // colorDark: Color(0xff2563eb), + imagePath: "assets/dashboard/Premium value.png", + ), + ), + SizedBox(width: 16), + Expanded( + child: StatCard( + title: "Earnings", + today: earningsToday ?? '', + month: earningsMonth ?? '', + year: earningsYear ?? '', + colorDark: Color(0xff8b5cf6), + imagePath: "assets/dashboard/Earnings.png", + ), + ), + ], + ), + + const SizedBox(height: 5), + SizedBox( + // ✅ replace Expanded + height: (role == 'agent') + ? MediaQuery.of(context).size.height * + 0.69 //400 + : (role == 'manager') + ? MediaQuery.of(context).size.height * 0.8 + : (role == 'staff' || role == 'handler') + ? MediaQuery.of(context).size.height * 0.8 + : MediaQuery.of(context).size.height * + 0.5, // 350 adjust height as needed + child: (role == 'manager' || role == 'handler') + ? Row( + children: [ + Expanded( + child: othersPendings( + title: + "Staff Wise Pending(${staffQuotationsPendingList.length})", + data: staffQuotationsPendingList, + stringFlag: "Proposal", + role: role!, + onRefresh: refresh, + ), + ), + // if (role == 'handler') ...[ + Expanded( + child: UnassignedEnq( + key: UniqueKey(), + title: "Unassigned Enquiries", + role: role!, + data: unAssignedEnqList, + onRefresh: refresh, + ), + ), + // ], + ], + ) + : Row( + children: [ + Expanded( + child: (role == 'agent') + ? agentPendings( + title: + "Awaiting Proposal (${quotationsPendingList.length})", + data: quotationsPendingList, + role: role!, + onEdit: (row) { + handleEdit( + row, + ); // parent method is called + }, + onStaffEdit: (row, flag) { + handleStaffEdit(row, flag); + }, + ) + : (role == 'manager') + ? SizedBox.shrink() + : agentPendings( + title: + "Awaiting Proposal (${quotationsPendingList.length})", + data: quotationsPendingList, + role: role!, + onEdit: (row) { + handleEdit( + row, + ); // parent method is called + }, + + onStaffEdit: (row, flag) { + handleStaffEdit(row, flag); + }, + ), + ), + const SizedBox(width: 16), + Expanded( + child: (role == 'agent') + ? agentPendings( + title: + "Awaiting Approval (${awaitingApprovalList.length})", + data: awaitingApprovalList, + role: role!, + onEdit: (row) { + handleEdit( + row, + ); // parent method is called + }, + onStaffEdit: (row, flag) { + handleStaffEdit(row, flag); + }, + ) + : (role == 'manager') + ? SizedBox.shrink() + // othersPendings( + // title: + // "Awaiting Proposal (${quotationsPendingList.length})", + // data: quotationsPendingList, + // stringFlag: "Proposal", + // ) + : agentPendings( + title: + "Awaiting Approval (${awaitingApprovalList.length})", + data: awaitingApprovalList, + role: role!, + onEdit: (row) { + handleEdit( + row, + ); // parent method is called + }, + onStaffEdit: (row, flag) { + handleStaffEdit(row, flag); + }, + ), + ), + const SizedBox(width: 16), + Expanded( + child: (role == 'agent') + ? agentPendings( + title: + "Awaiting Policy (${policiesPendingList.length})", + data: policiesPendingList, + stringFlag: "Policies", + role: role!, + onEdit: (row) { + handleEdit( + row, + ); // parent method is called + }, + onStaffEdit: (row, flag) { + handleStaffEdit(row, flag); + }, + ) + : (role == 'staff') + ? + // ? othersPendings( + // title: + // "Awaiting Proposal (${quotationsPendingList.length})", + // data: quotationsPendingList, + // stringFlag: "Proposal", + // ) + agentPendings( + title: + "Awaiting Policy (${policiesPendingList.length})", + data: policiesPendingList, + stringFlag: "Policies", + role: role!, + onEdit: (row) { + handleEdit( + row, + ); // parent method is called + }, + onStaffEdit: (row, flag) { + handleStaffEdit(row, flag); + }, + ) + : SizedBox.shrink(), + ), + ], + ), + ), + + // const SizedBox(height: 5), + // if (role == 'manager') + // SizedBox( + // // ✅ replace Expanded + // height: 350, // adjust height as needed + // child: Row( + // children: [ + // Expanded( + // child: UnassignedEnq( + // key: UniqueKey(), + // title: "Unassigned Enquiries", + // role: role!, + // data: unAssignedEnqList, + // onRefresh: refresh, + // ), + // ), + // SizedBox(width: 16), + // Expanded( + // child: Performance( + // title: "Performing Partner", + // data: agentsPerformanceList, + // ), + // ), + // SizedBox(width: 16), + // Expanded( + // child: Performance( + // title: "Non-Performing Partner", + // data: nonAgentsPerformanceList, + // ), + // ), + // ], + // ), + // ), + ], + ), + ), + ), + ], + ); + } + + // Widget buildTab(String title, int index) { + // final isSelected = selectedIndex == index + 1; + // return GestureDetector( + // onTap: () { + // print('buildTab - $index'); + // + // setState(() { + // selectedIndex = index + 1; + // print('buildTab1 - $selectedIndex'); + // if (selectedIndex == 2) { + // switcherStatus = 0; + // } else { + // switcherStatus = 1; + // } + // }); + // }, + // child: SizedBox( + // child: Container( + // padding: EdgeInsets.symmetric(vertical: 6, horizontal: 10), + // decoration: BoxDecoration( + // color: isSelected ? const Color(0xFFFFFFFF) : Colors.transparent, + // borderRadius: BorderRadius.circular(16), + // ), + // child: Center( + // child: Text( + // title, + // style: GoogleFonts.poppins( + // fontSize: 12, + // + // color: isSelected ? Colors.black : Colors.white, + // fontWeight: FontWeight.w500, + // ), + // maxLines: 2, + // softWrap: true, + // ), + // ), + // ), + // ), + // ); + // } + + Widget buildTab(String title, int index) { + final isSelected = selectedTabIndex == index; + if (selectedTabIndex == 0) { + currentList = quotationsPendingList; + currentKey = 'pending'; + } else if (selectedTabIndex == 1) { + currentList = awaitingApprovalList; + currentKey = 'approval'; + } else if (selectedTabIndex == 2) { + currentList = policiesPendingList; + currentKey = 'policies'; + } + + return GestureDetector( + onTap: () { + setState(() { + selectedTabIndex = index; + }); + }, + child: Container( + padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8), + decoration: BoxDecoration( + color: isSelected ? Colors.white : Colors.transparent, + borderRadius: BorderRadius.circular(20), + ), + child: Text( + title, + style: GoogleFonts.inter( + fontSize: 11, + fontWeight: FontWeight.bold, + color: isSelected ? const Color(0xFF425B5B) : Colors.white, + ), + ), + ), + ); + } +} + +// Stats card widget +class StatCard extends StatelessWidget { + final String title; + final String today; + final String month; + final String year; + final String? imagePath; + final Color? colorDark; + + const StatCard({ + super.key, + required this.title, + required this.today, + required this.month, + required this.year, + this.imagePath, + this.colorDark, + }); + + @override + Widget build(BuildContext context) { + return Card( + color: Colors.white, + // color: Color(0xFFF1F9F8), + // color: Color(0xFFEAF6F4), + elevation: 1, + shadowColor: colorDark ?? null, + shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12)), + child: Padding( + padding: const EdgeInsets.all(8.0), + + child: Column( + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Row( + children: [ + Container( + padding: EdgeInsets.all(4.0), + height: 28, + width: 28, + decoration: BoxDecoration( + color: colorDark ?? Colors.grey, + borderRadius: BorderRadius.circular(15), + ), + child: Image.asset( + imagePath!, + width: 18, + height: 18, + // color: colorDark ?? Colors.grey, + color: Colors.white, + ), + ), + const SizedBox(width: 8), + Text( + title, + style: GoogleFonts.inter( + fontSize: 12, + fontWeight: FontWeight.w700, + color: Color(0xFF425B5B), + ), + ), + ], + ), + Divider(thickness: 0.1, color: colorDark ?? Colors.grey), + const SizedBox(height: 5), + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Expanded( + child: Text( + today, + textAlign: TextAlign.center, + style: GoogleFonts.inter( + fontWeight: FontWeight.bold, + fontSize: 12, + ), + ), + ), + Expanded( + child: Text( + month, + textAlign: TextAlign.center, + style: GoogleFonts.inter( + fontWeight: FontWeight.bold, + fontSize: 12, + ), + ), + ), + Expanded( + child: Text( + year, + textAlign: TextAlign.center, + style: GoogleFonts.inter( + fontWeight: FontWeight.bold, + fontSize: 12, + ), + ), + ), + ], + ), + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Expanded( + child: Text( + "Today", + textAlign: TextAlign.center, + style: topHeaderStyle, + ), + ), + Expanded( + child: Text( + "This Month", + textAlign: TextAlign.center, + style: topHeaderStyle, + ), + ), + Expanded( + child: Text( + "This Year", + textAlign: TextAlign.center, + style: topHeaderStyle, + ), + ), + ], + ), + ], + ), + ), + ); + } +} + +class agentPendings extends StatelessWidget { + final String title; + final String? stringFlag; + String role; + final List> data; + + // final Function(Map)? onEdit; + final Function(String)? onEdit; + // final Function(String)? onStaffEdit; + final Function(String, String?)? onStaffEdit; + + agentPendings({ + Key? key, + required this.title, + required this.data, + this.stringFlag, + required this.onStaffEdit, + required this.role, + required this.onEdit, + }) : super(key: key); + + @override + Widget build(BuildContext context) { + print('-Data: $data'); + + return Card( + color: Colors.white, + // color: const Color(0xFFEAF6F4), + elevation: 1, + shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12)), + child: Padding( + padding: const EdgeInsets.all(12.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + // Title + Text(title, style: _title), + const SizedBox(height: 10), + + // Header row + Container( + padding: const EdgeInsets.symmetric(vertical: 10, horizontal: 12), + decoration: BoxDecoration( + color: Color(0xFFE3F9F8), + // color: const Color(0xFF3E5B56), + borderRadius: BorderRadius.circular(10), + ), + child: Row( + children: [ + // Expanded( + // flex: 1, + // child: Text( + // "S.No", + // textAlign: TextAlign.center, + // style: _headerStyle, + // ), + // ), + Expanded( + flex: 2, + child: Text( + "Date & Time", + textAlign: TextAlign.center, + style: _headerStyle, + ), + ), + Expanded( + flex: 2, + child: Text( + "Vehicle Number", + textAlign: TextAlign.center, + style: _headerStyle, + ), + ), + if (stringFlag == "Policies") ...[ + Expanded( + flex: 2, + child: Text( + "Insurer", + textAlign: TextAlign.center, + style: _headerStyle, + ), + ), + ], + ], + ), + ), + const SizedBox(height: 8), + + // List of rows + Flexible( + child: ListView.builder( + itemCount: data.length, + itemBuilder: (context, index) { + final row = data[index]; + + // Split date & time from created_on + String date = ""; + String time = ""; + if ((row['created_on'] ?? "").isNotEmpty) { + final parts = row['created_on'].split(' '); + date = parts[0]; + if (parts.isNotEmpty) { + DateTime parsedDate = DateTime.parse(parts[0]); + date = DateFormat( + 'dd-MM-yyyy', + ).format(parsedDate); // 19/09/2025 + } + // time = parts.length > 1 ? parts[1] : ""; + // Format the time part (HH:mm) + if (parts.length >= 2) { + final timeParts = parts[1].split(":"); + time = "${timeParts[0]}:${timeParts[1]}"; // 05:45 + } else { + time = ""; + } + } + + return InkWell( + focusColor: Color(0xFF3E5B56), + highlightColor: Color(0xFF3E5B56), + borderRadius: BorderRadius.circular(2), + onTap: (role == 'manager') + ? null + : (role == 'agent') + ? () { + print( + "Clicked Partner role : $role - ${row['id']}", + ); + onEdit!(row['id'].toString()); + // onEdit!(row['id']); + } + : () { + print("Clicked Staff role : $role - ${row['id']}"); + print("Clicked Staff stringFlag : $stringFlag"); + onStaffEdit!(row['id'].toString(), stringFlag); + }, + child: Container( + // margin: const EdgeInsets.symmetric(vertical: 5), + padding: const EdgeInsets.symmetric( + vertical: 5, + horizontal: 12, + ), + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(2), + border: Border( + bottom: BorderSide(color: Colors.blueGrey.shade50), + ), + ), + child: Row( + children: [ + // Expanded( + // flex: 1, + // child: Text( + // (index + 1).toString(), + // textAlign: TextAlign.center, + // style: _tableDataStyle, + // ), + // ), + // Date & Time + Expanded( + flex: 2, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text(date, style: _tableDataStyle), + Text(time, style: _tableDataTimeStyle), + ], + ), + ), + + // Registration number + Expanded( + flex: 2, + child: Text( + row['reg_no'] ?? "", + textAlign: TextAlign.center, + style: _tableDataStyle, + ), + ), + if (stringFlag == "Policies") ...[ + // Insurer company + Expanded( + flex: 2, + child: Text( + row['insurer_short_name'] ?? "", + textAlign: TextAlign.center, + style: _tableDataStyle, + ), + ), + ], + ], + ), + ), + ); + }, + ), + ), + ], + ), + ), + ); + } +} + +class othersPendings extends StatelessWidget { + final String title; + final String stringFlag; + String role; + final List> data; + final VoidCallback? onRefresh; + + othersPendings({ + Key? key, + required this.title, + required this.role, + required this.data, + required this.stringFlag, + required this.onRefresh, + }) : super(key: key); + + @override + Widget build(BuildContext context) { + print(' Data: $data'); + + // Compute totals + int totalTodayAssigned = 0; + int totalPending = 0; + int totalInProgress = 0; + int totalCompleted = 0; + int totalPrevPending = 0; + int totalPendingAll = 0; + + for (var row in data) { + totalTodayAssigned += int.tryParse(row['today_assigned'] ?? '0') ?? 0; + totalPending += int.tryParse(row['today_pending'] ?? '0') ?? 0; + totalInProgress += int.tryParse(row['today_in_progress'] ?? '0') ?? 0; + totalCompleted += int.tryParse(row['today_completed'] ?? '0') ?? 0; + totalPrevPending += int.tryParse(row['total_completed'] ?? '0') ?? 0; + + int totalPendingdata = + int.tryParse(row['total_pending']?.toString() ?? '0') ?? 0; + int todayAssigned = + int.tryParse(row['today_assigned']?.toString() ?? '0') ?? 0; + + // totalTodayAssigned += todayAssigned; + totalPendingAll += totalPendingdata; + + int staffPending = totalPendingdata - todayAssigned; + + // totalPrevPending += staffPending; + + final rowPrevPending = + (int.tryParse(row['total_pending'] ?? '0') ?? 0) - + (int.tryParse(row['today_assigned'] ?? '0') ?? 0); + + totalPrevPending += rowPrevPending < 0 ? 0 : rowPrevPending; + } + + return Card( + color: Colors.white, + // color: const Color(0xFFEAF6F4), + elevation: 1, + shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12)), + child: Padding( + padding: const EdgeInsets.all(12.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + // Title + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text(title, style: _title), + + InkWell( + onTap: () { + onRefresh!(); + }, + child: Icon(Icons.refresh, size: 18), + ), + ], + ), + const SizedBox(height: 10), + + // Header row + Container( + padding: const EdgeInsets.symmetric(vertical: 8, horizontal: 12), + decoration: BoxDecoration( + color: Color(0xFFE3F9F8), + // color: const Color(0xFF3E5B56), + borderRadius: BorderRadius.circular(10), + ), + child: Row( + children: [ + // Expanded( + // flex: 1, + // child: Text( + // "S.No", + // textAlign: TextAlign.center, + // style: _headerStyle, + // ), + // ), + // if (role == 'manager') ...[ + // Expanded( + // flex: 2, + // child: Text( + // "Handler Name", + // textAlign: TextAlign.center, + // style: _headerStyle, + // ), + // ), + // ], + Expanded( + flex: 2, + child: Text( + "Staff Name", + textAlign: TextAlign.center, + style: _headerStyle, + ), + ), + + // Expanded( + // flex: 2, + // child: Text( + // // stringFlag + " Issued", + // 'Total Assigned', + // textAlign: TextAlign.center, + // style: _headerStyle, + // ), + // ), + // Expanded( + // flex: 2, + // child: Text( + // 'To be assigned', + // textAlign: TextAlign.center, + // style: _headerStyle, + // ), + // ), + // Expanded( + // flex: 2, + // child: Text( + // 'Total Assigned', + // textAlign: TextAlign.center, + // style: _headerStyle, + // ), + // ), + Expanded( + flex: 2, + child: Text( + 'Today Assigned', + textAlign: TextAlign.center, + style: _headerStyle, + ), + ), + + Expanded( + flex: 2, + child: Text( + 'Pending', + textAlign: TextAlign.center, + style: _headerStyle, + ), + ), + Expanded( + flex: 2, + child: Text( + 'In Progress', + textAlign: TextAlign.center, + style: _headerStyle, + ), + ), + Expanded( + flex: 2, + child: Text( + 'Completed', + textAlign: TextAlign.center, + style: _headerStyle, + ), + ), + Expanded( + flex: 2, + child: Text( + 'Prev Pending', + textAlign: TextAlign.center, + style: _headerStyle, + ), + ), + // Expanded( + // flex: 2, + // child: Text( + // // stringFlag + " Issued", + // 'Policy Created', + // textAlign: TextAlign.center, + // style: _headerStyle, + // ), + // ), + ], + ), + ), + const SizedBox(height: 8), + + // List of rows + Flexible( + child: ListView.builder( + itemCount: data.length, + itemBuilder: (context, index) { + final row = data[index]; + + final totalPending = + int.tryParse(row['total_pending']?.toString() ?? '0') ?? + 0; + final todayAssigned = + int.tryParse(row['today_assigned']?.toString() ?? '0') ?? + 0; + + final staffPending = (totalPending - todayAssigned); + final safePending = staffPending < 0 ? 0 : staffPending; + + // final staffPending = totalPending - todayAssigned; + + final issuedCount = stringFlag == "Policies" + ? (row['total_policis_pending'] ?? 0).toString() + : (row['total_quotation_pending'] ?? 0).toString(); + + final permiumValue = row['total_premium_value'] == null + ? '0' + : row['total_premium_value']; + + return Container( + margin: const EdgeInsets.symmetric(vertical: 3), + padding: const EdgeInsets.symmetric( + vertical: 4, + horizontal: 12, + ), + decoration: BoxDecoration( + color: Colors.white, + border: Border( + bottom: BorderSide( + color: Colors.blueGrey.shade100, + width: 0.3, + ), + ), + // borderRadius: BorderRadius.circular(10), + ), + child: Row( + children: [ + Expanded( + flex: 2, + child: Text( + row['staff_name'] ?? "", + textAlign: TextAlign.left, + // textAlign: TextAlign.center, + style: _tableDataStyle, + ), + ), + + Expanded( + flex: 2, + child: Material( + color: Colors.white, + child: Center( + child: InkWell( + hoverColor: Color(0xFFEAF6F4), + onTap: () { + print( + 'total_assigned_today : ${row['total_assigned']}', + ); + + handleDashboardNavigation( + context, + status: '', + // status: "Assigned", + staffId: row['staff_id'] ?? '', + role: role, + ); + }, + child: Text( + row['today_assigned'] ?? "", + // row['total_approval_pending'] ?? "", + textAlign: TextAlign.center, + style: _tableDataStyle, + ), + ), + ), + ), + ), + Expanded( + flex: 2, + child: Material( + color: Colors.white, + child: Center( + child: InkWell( + hoverColor: Color(0xFFEAF6F4), + onTap: () { + print( + 'total_assigned : ${row['total_assigned']}', + ); + + handleDashboardNavigation( + context, + status: "Assigned", + staffId: row['staff_id'] ?? '', + role: role, + ); + }, + child: Text( + row['today_pending'] ?? "", + // row['total_approval_pending'] ?? "", + textAlign: TextAlign.center, + style: _tableDataStyle, + ), + ), + ), + ), + ), + Expanded( + flex: 2, + child: Material( + color: Colors.white, + child: Center( + child: InkWell( + // hoverColor: Color(0xFFEAF6F4), + onTap: () { + print( + 'Awaiting Proposal : ${row['total_in_progress']}', + ); + + handleDashboardNavigation( + context, + status: "In progress", + staffId: row['staff_id'] ?? '', + role: role, + ); + }, + + child: Text( + row['today_in_progress'] ?? "", + // row['total_approval_pending'] ?? "", + textAlign: TextAlign.center, + style: _tableDataStyle, + ), + ), + ), + ), + ), + Expanded( + flex: 2, + child: Material( + color: Colors.white, + child: Center( + child: InkWell( + hoverColor: Color(0xFFEAF6F4), + onTap: () async { + print( + 'Awaiting Approval : ${row['total_completed']} - ${row['staff_id']}', + ); + handleDashboardNavigation( + context, + status: "Completed", + staffId: row['staff_id'] ?? '', + role: role, + ); + }, + child: Text( + row['today_completed'] ?? "", + // row['total_approval_pending'] ?? "", + textAlign: TextAlign.center, + style: _tableDataStyle, + ), + ), + ), + ), + ), + Expanded( + flex: 2, + child: Material( + color: Colors.white, + child: Center( + child: InkWell( + hoverColor: Color(0xFFEAF6F4), + onTap: () async { + print( + 'Awaiting Approval : ${row['total_completed']} - ${row['staff_id']}', + ); + handleDashboardNavigation( + context, + status: 'PrevPending', + staffId: row['staff_id'] ?? '', + role: role, + ); + }, + child: Text( + safePending.toString() ?? "", + // row['total_approval_pending'] ?? "", + textAlign: TextAlign.center, + style: _tableDataStyle, + ), + ), + ), + ), + ), + + // Expanded( + // flex: 2, + // child: Text( + // row['policy_created'] ?? "", + // // row['total_approval_pending'] ?? "", + // textAlign: TextAlign.center, + // style: _tableDataStyle, + // ), + // ), + ], + ), + ); + }, + ), + ), + const SizedBox(height: 8), + // Header row + Container( + padding: const EdgeInsets.symmetric(vertical: 8, horizontal: 12), + decoration: BoxDecoration( + color: Color(0xFFF1F5F9), + // color: Color(0xFFE3F9F8), + borderRadius: BorderRadius.circular(10), + ), + child: Row( + children: [ + Expanded( + flex: 2, + child: Text( + "Total", + textAlign: TextAlign.center, + style: _headerStyle, + ), + ), + Expanded( + flex: 2, + child: Text( + totalTodayAssigned.toString(), + textAlign: TextAlign.center, + style: _headerStyle, + ), + ), + Expanded( + flex: 2, + child: Text( + totalPending.toString(), + textAlign: TextAlign.center, + style: _headerStyle, + ), + ), + Expanded( + flex: 2, + child: Text( + totalInProgress.toString(), + textAlign: TextAlign.center, + style: _headerStyle, + ), + ), + Expanded( + flex: 2, + child: Text( + totalCompleted.toString(), + textAlign: TextAlign.center, + style: _headerStyle, + ), + ), + Expanded( + flex: 2, + child: Text( + totalPrevPending.toString(), + textAlign: TextAlign.center, + style: _headerStyle, + ), + ), + ], + ), + ), + ], + ), + ), + ); + } +} + +class awaitingApproval extends StatelessWidget { + final String title; + final String stringFlag; + final List> data; + + awaitingApproval({ + Key? key, + required this.title, + required this.data, + required this.stringFlag, + }) : super(key: key); + + @override + Widget build(BuildContext context) { + print(' Data: $data'); + + return Card( + color: Colors.white, + // color: const Color(0xFFEAF6F4), + elevation: 1, + shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12)), + child: Padding( + padding: const EdgeInsets.all(12.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + // Title + Text(title, style: _title), + const SizedBox(height: 10), + + // Header row + Container( + padding: const EdgeInsets.symmetric(vertical: 8, horizontal: 12), + decoration: BoxDecoration( + // color: const Color(0xFF3E5B56), + color: Color(0xFFE3F9F8), + borderRadius: BorderRadius.circular(10), + ), + child: Row( + children: [ + // Expanded( + // flex: 1, + // child: Text( + // "S.No", + // textAlign: TextAlign.center, + // style: _headerStyle, + // ), + // ), + Expanded( + flex: 2, + child: Text( + "Staff Name", + textAlign: TextAlign.center, + style: _headerStyle, + ), + ), + Expanded( + flex: 2, + child: Text( + // stringFlag + " Issued", + 'Pending Count', + textAlign: TextAlign.center, + style: _headerStyle, + ), + ), + // (stringFlag == "Policies") + // ? Expanded( + // flex: 2, + // child: Text( + // "Total Premium Value", + // textAlign: TextAlign.center, + // style: _headerStyle, + // ), + // ) + // : const SizedBox.shrink(), + ], + ), + ), + const SizedBox(height: 8), + + // List of rows + Flexible( + child: ListView.builder( + itemCount: data.length, + itemBuilder: (context, index) { + final row = data[index]; + + final issuedCount = stringFlag == "Policies" + ? (row['total_policis_pending'] ?? 0).toString() + : (row['total_quotation_pending'] ?? 0).toString(); + + final permiumValue = row['total_premium_value'] == null + ? '0' + : row['total_premium_value']; + + return Container( + margin: const EdgeInsets.symmetric(vertical: 5), + padding: const EdgeInsets.symmetric( + vertical: 5, + horizontal: 12, + ), + decoration: BoxDecoration( + color: Colors.white, + border: Border( + bottom: BorderSide( + color: Colors.blueGrey.shade100, + width: 0.3, + ), + ), + // borderRadius: BorderRadius.circular(10), + ), + child: Row( + children: [ + // Expanded( + // flex: 1, + // child: Text( + // (index + 1).toString(), + // textAlign: TextAlign.center, + // style: _tableDataStyle, + // ), + // ), + Expanded( + flex: 2, + child: Text( + row['staff_name'] ?? "", + + textAlign: TextAlign.center, + style: _tableDataStyle, + ), + ), + + Expanded( + flex: 2, + child: Text( + // issuedCount, + (row['total_approval_pending'] ?? 0).toString(), + textAlign: TextAlign.center, + style: _tableDataStyle, + ), + ), + // stringFlag == "Policies" + // ? Expanded( + // flex: 2, + // child: Text( + // formatToCroresLakhsAndThousands(permiumValue), + // textAlign: TextAlign.center, + // style: GoogleFonts.inter( + // fontSize: 14, + // fontWeight: FontWeight.w500, + // ), + // ), + // ) + // : const SizedBox.shrink(), + ], + ), + ); + }, + ), + ), + ], + ), + ), + ); + } +} + +class Performance extends StatelessWidget { + final String title; + final List> data; + + Performance({Key? key, required this.title, required this.data}) + : super(key: key); + + @override + Widget build(BuildContext context) { + return Card( + // color: const Color(0xFFEAF6F4), + color: Colors.white, + elevation: 1, + shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12)), + child: Padding( + padding: const EdgeInsets.all(12.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + // Title + Text(title, style: _title), + const SizedBox(height: 10), + + // Header row + Container( + padding: const EdgeInsets.symmetric(vertical: 8, horizontal: 12), + decoration: BoxDecoration( + color: Color(0xFFE3F9F8), + // color: const Color(0xFF3E5B56), + borderRadius: BorderRadius.circular(10), + ), + child: Row( + children: [ + // Expanded( + // child: Text( + // "S.No", + // textAlign: TextAlign.center, + // style: _headerStyle, + // ), + // ), + Expanded( + child: Text( + "Partner Name", + textAlign: TextAlign.center, + style: _headerStyle, + ), + ), + Expanded( + child: Text( + "Policies Issued", + textAlign: TextAlign.center, + style: _headerStyle, + ), + ), + Expanded( + child: Text( + title == "Performing Partners" + ? "Premium Value" + : "Status", + textAlign: TextAlign.center, + style: _headerStyle, + ), + ), + ], + ), + ), + const SizedBox(height: 8), + + // List of rows + Flexible( + child: ListView.builder( + itemCount: data.length, + itemBuilder: (context, index) { + final row = data[index]; + + return Container( + // height: 5200, + margin: const EdgeInsets.symmetric(vertical: 5), + padding: const EdgeInsets.symmetric( + vertical: 5, + horizontal: 12, + ), + decoration: BoxDecoration( + color: Colors.white, + border: Border( + bottom: BorderSide( + color: Colors.blueGrey.shade100, + width: 0.3, + ), + ), + // borderRadius: BorderRadius.circular(10), + ), + child: Row( + children: [ + // Expanded( + // child: Text( + // (index + 1).toString(), // convert int to string + // textAlign: TextAlign.center, + // style: _tableDataStyle, + // ), + // ), + Expanded( + child: Text( + row['agent_name'] ?? "", + textAlign: TextAlign.center, + style: _tableDataStyle, + ), + ), + + Expanded( + child: Text( + row['total_policy_issued'] ?? "", + textAlign: TextAlign.center, + style: _tableDataStyle, + ), + ), + + Expanded( + child: Text( + title == "Performing Partners" + ? formatToCroresLakhsAndThousands( + row['total_premium_value'] ?? 0, + ) + : (row['status']?.toString() ?? ""), + textAlign: TextAlign.center, + style: GoogleFonts.inter( + fontSize: 11, + fontWeight: FontWeight.w500, + color: title == "Performing Partners" + ? Colors.black + : (row['status']?.toString().toLowerCase() == + "active" + ? Colors.green + : Colors.red), + ), + ), + ), + ], + ), + ); + }, + ), + ), + ], + ), + ), + ); + } +} + +class UnassignedEnq extends StatelessWidget { + final String title; + final List> data; + final VoidCallback? onRefresh; + String role; + + UnassignedEnq({ + Key? key, + required this.title, + required this.data, + this.onRefresh, + required this.role, + }) : super(key: key); + + @override + Widget build(BuildContext context) { + return Card( + color: Colors.white, + // color: const Color(0xFFEAF6F4), + elevation: 1, + shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12)), + child: Padding( + padding: const EdgeInsets.all(12.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + // Title + Text(title, style: _title), + const SizedBox(height: 10), + + // Header row + Container( + padding: const EdgeInsets.symmetric(vertical: 8, horizontal: 12), + decoration: BoxDecoration( + // color: const Color(0xFF3E5B56), + color: Color(0xFFE3F9F8), + borderRadius: BorderRadius.circular(10), + ), + child: Row( + children: [ + // Expanded( + // child: Text( + // "S.No", + // textAlign: TextAlign.center, + // style: _headerStyle, + // ), + // ), + Expanded( + child: Text( + "Date", + // textAlign: TextAlign.center, + style: _headerStyle, + ), + ), + Expanded( + child: Text( + "Partner", + // textAlign: TextAlign.center, + style: _headerStyle, + ), + ), + Expanded( + child: Text( + "Reg.No.", + // textAlign: TextAlign.center, + style: _headerStyle, + ), + ), + Expanded( + child: Text( + "Insured Name", + // textAlign: TextAlign.center, + style: _headerStyle, + ), + ), + ], + ), + ), + const SizedBox(height: 8), + + // List of rows + Flexible( + child: ListView.builder( + itemCount: data.length, + itemBuilder: (context, index) { + final row = data[index]; + + String date = ""; + String time = ""; + if ((row['created_on'] ?? "").isNotEmpty) { + final parts = row['created_on'].split(' '); + date = parts[0]; + if (parts.isNotEmpty) { + DateTime parsedDate = DateTime.parse(parts[0]); + date = DateFormat( + 'dd-MM-yyyy', + ).format(parsedDate); // 19/09/2025 + } + // time = parts.length > 1 ? parts[1] : ""; + // Format the time part (HH:mm) + if (parts.length >= 2) { + final timeParts = parts[1].split(":"); + time = "${timeParts[0]}:${timeParts[1]}"; // 05:45 + } else { + time = ""; + } + } + + return InkWell( + focusColor: Color(0xFF3E5B56), + highlightColor: Color(0xFF3E5B56), + borderRadius: BorderRadius.circular(2), // for ripple effect + // onTap: () { + // handleDashboardNavigation( + // context, + // status: "To be assigned", + // staffId: row['staff_id'] ?? '', + // role: role, + // ); + // }, + onTap: () { + // Print the id when row is clicked + print("Clicked ID fd: ${row['id']}"); + // You can also navigate or perform any action here + + showDialog( + context: context, + builder: (ctx) => AssignStaffDialog( + enquiryPrimaryId: row['id'], + regNum: row['reg_no'], + userId: 1, + onSubmit: (value) { + debugPrint("New assignY: $value"); + if (onRefresh != null) { + onRefresh!(); // ✅ call the parent's refresh + } + }, + ), + ); + }, + child: Container( + // height: 5200, + margin: const EdgeInsets.symmetric(vertical: 5), + padding: const EdgeInsets.symmetric( + vertical: 5, + horizontal: 12, + ), + decoration: BoxDecoration( + color: Colors.white, + border: Border( + bottom: BorderSide( + color: Colors.blueGrey.shade100, + width: 0.3, + ), + ), + // borderRadius: BorderRadius.circular(10), + ), + child: Row( + children: [ + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text(date, style: _tableDataStyle), + Text(time, style: _tableDataTimeStyle), + ], + ), + ), + Expanded( + child: Text( + row['agent_name'] ?? '', // convert int to string + // textAlign: TextAlign.center, + style: _tableDataStyle, + ), + ), + Expanded( + child: Text( + row['reg_no'] ?? "", + + style: _tableDataStyle, + ), + ), + Expanded( + child: Text( + row['insured_name'] ?? "", + + style: _tableDataStyle, + ), + ), + ], + ), + ), + ); + }, + ), + ), + ], + ), + ), + ); + } +} + +Future handleDashboardNavigation( + BuildContext context, { + required String status, + 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!); + + context.go(AppRoutes.enquiryForStaff); + // // ✅ Navigate + // if (role == 'manager') { + // context.go(AppRoutes.enquiryForStaff); + // } else { + // context.go(AppRoutes.enquiryHandlerLst); + // } +} + +final _headerStyle = GoogleFonts.inter( + fontWeight: FontWeight.w600, + fontSize: 11.5, + color: Colors.black, +); + +final _title = GoogleFonts.inter( + fontWeight: FontWeight.bold, + fontSize: 11.5, + // color: Colors.red, + color: const Color(0xff425B5B), +); + +final _tableDataStyle = GoogleFonts.inter( + fontSize: 11, + fontWeight: FontWeight.w500, +); +final _tableDataTimeStyle = GoogleFonts.inter( + fontSize: 10, + fontWeight: FontWeight.w400, +); + +final topHeaderStyle = GoogleFonts.inter( + fontSize: 11, + color: Colors.black, + fontWeight: FontWeight.w500, +); diff --git a/lib/presentation/screens/staff/Enquiry/enquiry_inline_Edit_17Nov.dart b/lib/presentation/screens/staff/Enquiry/enquiry_inline_Edit_17Nov.dart index 7e861b2..8fa7d86 100644 --- a/lib/presentation/screens/staff/Enquiry/enquiry_inline_Edit_17Nov.dart +++ b/lib/presentation/screens/staff/Enquiry/enquiry_inline_Edit_17Nov.dart @@ -2413,6 +2413,7 @@ class EnquiryStaffState extends ConsumerState { print("Enquiry saved successfully"); // RESET FORM raiseEnqKey.currentState?.resetFormFields(); + getStaffDetailsForEnquiryAssignment(userId); } catch (e) { showDialog( context: context, diff --git a/lib/presentation/screens/staff/Enquiry/enquiry_inline_dec1.dart b/lib/presentation/screens/staff/Enquiry/enquiry_inline_dec1.dart index 2a6673e..197f97f 100644 --- a/lib/presentation/screens/staff/Enquiry/enquiry_inline_dec1.dart +++ b/lib/presentation/screens/staff/Enquiry/enquiry_inline_dec1.dart @@ -10,7 +10,7 @@ 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:nhance_partner/presentation/screens/dashboard/dashboard.dart'; +import 'package:nhance_partner/presentation/screens/dashboard/dashboard_nw.dart'; import 'package:nhance_partner/presentation/screens/staff/Enquiry/quotationPopUpAccptReject.dart'; import 'package:nhance_partner/presentation/screens/staff/Enquiry/raise_enq_form.dart'; import 'package:nhance_partner/presentation/screens/staff/Enquiry/staff_policy.dart'; diff --git a/lib/presentation/screens/staff/Enquiry/enquiry_inline_list.dart b/lib/presentation/screens/staff/Enquiry/enquiry_inline_list.dart index 4112c96..42f94e0 100644 --- a/lib/presentation/screens/staff/Enquiry/enquiry_inline_list.dart +++ b/lib/presentation/screens/staff/Enquiry/enquiry_inline_list.dart @@ -10,7 +10,7 @@ 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:nhance_partner/presentation/screens/dashboard/dashboard.dart'; +import 'package:nhance_partner/presentation/screens/dashboard/dashboard_nw.dart'; import 'package:nhance_partner/presentation/screens/staff/Enquiry/quotationPopUpAccptReject.dart'; import 'package:nhance_partner/presentation/screens/staff/Enquiry/raise_enq_form.dart'; import 'package:nhance_partner/presentation/screens/staff/Enquiry/staff_policy.dart'; @@ -96,6 +96,8 @@ class EnquiryStaffState extends ConsumerState { 'remarks', ]; + String formRebuildKey = UniqueKey().toString(); + Map isEditingRow = {}; Map> rowControllers = {}; @@ -206,8 +208,9 @@ class EnquiryStaffState extends ConsumerState { String? selectedBroker; final ScrollController _horizontalScrollController = ScrollController(); - late Timer timer; - + // late Timer timer; + Timer? timer; + int selectedSeconds = 30; bool isActionable = false; //---------------------- Assign Staff Ends -------------------------------- // @@ -218,12 +221,14 @@ class EnquiryStaffState extends ConsumerState { super.initState(); apiService = ApiService(); - timer = Timer.periodic(Duration(seconds: 10), (Timer t) => callRefresh()); + // timer = Timer.periodic(Duration(seconds: 10), (Timer t) => callRefresh()); //static + + startTimer(); for (String field in tabHeader) { controllers[field] = TextEditingController(); } _initializeToken(); - + loadPreferences(); Future.microtask(() async { // final id = ref.read(managerIdProvider); roleId = ref.read(userRoleProvider); @@ -280,16 +285,53 @@ class EnquiryStaffState extends ConsumerState { getPaymentMode(); } + Future loadPreferences() async { + final prefs = await SharedPreferences.getInstance(); + + setState(() { + isActionable = prefs.getBool('isActionable') ?? false; + selectedSeconds = prefs.getInt('selectedSeconds') ?? 30; + + _showFilterRow = true; + }); + + startTimer(); // restart timer using stored value + } + + Future resetPreferences() async { + final prefs = await SharedPreferences.getInstance(); + + await prefs.remove('isActionable'); + await prefs.remove('selectedSeconds'); + + setState(() { + // isActionable = false; // default + selectedSeconds = 30; // default + }); + + startTimer(); // restart timer with default value + + print("Storage cleared & reset completed"); + } + Future _initializeToken() async { _token = await AuthService.getToken(); print("APISERTOKEN - $_token"); } + void startTimer() { + timer?.cancel(); // stop existing timer + + timer = Timer.periodic(Duration(seconds: selectedSeconds), (Timer t) { + callRefresh(); + }); + } + void callRefresh() { print('Call Refresh'); if (!isActionable) { print('Call Refresh isActionable'); - refrshfilterDateRange(); + autoRefrshfilterDateRange(); } } @@ -321,6 +363,26 @@ class EnquiryStaffState extends ConsumerState { super.dispose(); } + Future autoRefrshfilterDateRange() async { + print('autorefrshfilterDateRange'); + // setState(() async { + final prefs = await SharedPreferences.getInstance(); + + // _formKey.currentState?.reset(); + + final int parsedManagerId = int.tryParse(managerId.toString()) ?? 0; + print('autorefrshfilterDateRange 1'); + getStaffList( + // managerId, + parsedManagerId, + roleId, + SelectedStatus: SelectedStatus ?? '', + SelectedStaffId: SelectedStaffId ?? '', + ); + _searchStaffController.clear(); + print('refrshfilterDateRange 2'); + } + Future refrshfilterDateRange() async { print('refrshfilterDateRange'); // setState(() async { @@ -526,7 +588,7 @@ class EnquiryStaffState extends ConsumerState { String SelectedStatus = '', String SelectedStaffId = '', }) async { - print('A72 => Fns called => $managerId | $role'); + print('DAJJshA72 => Fns called => $managerId | $role'); setState(() { isLoading = true; }); @@ -538,13 +600,40 @@ class EnquiryStaffState extends ConsumerState { final toDateVal = controllers['endDate']?.text ?? ''; final dateFormat = DateFormat('dd-MM-yyyy'); - if (dashboardKey != 'fromDashboard' && + if (dashboardKey == 'fromDashboard' && SelectedStatus == "PrevPending") { + // For PREV PENDING → set date range until yesterday + final today = DateTime.now(); + + // Change to dd-MM-yyyy + final dateFormat = DateFormat('dd-MM-yyyy'); + + final yesterday = today.subtract(Duration(days: 1)); + + fromDt = dateFormat.format(yesterday.subtract(Duration(days: 15))); + toDt = dateFormat.format(yesterday); + + print('PrevPending FROM TO - $fromDt - $toDt'); + } else if (dashboardKey == 'fromDashboard' && + SelectedStatus != "PrevPending" && + SelectedStatus != '') { + // For PREV PENDING → set date range until yesterday + final today = DateTime.now(); + + // Change to dd-MM-yyyy + final dateFormat = DateFormat('dd-MM-yyyy'); + + fromDt = dateFormat.format(today); + toDt = dateFormat.format(today); + + print('PrevPending FROM TO - $fromDt - $toDt'); + } else if (dashboardKey != 'fromDashboard' && fromDateVal == '' && toDateVal == '') { print("ENQ LIST PAGE"); final today = DateTime.now(); fromDt = dateFormat.format(today.subtract(Duration(days: 15))); + // fromDt = dateFormat.format(today); toDt = dateFormat.format(today); print('Enq FROM TO - $fromDt - $toDt'); @@ -560,7 +649,10 @@ class EnquiryStaffState extends ConsumerState { role, fromDate: fromDt, toDate: toDt, - selectedStatus: SelectedStatus != null ? SelectedStatus : '', + selectedStatus: + (SelectedStatus != '' && SelectedStatus != 'PrevPending') + ? SelectedStatus + : '', selectedStaffId: SelectedStaffId ?? '', ); @@ -627,18 +719,27 @@ class EnquiryStaffState extends ConsumerState { return (item['agent_name'] ?? '-').toLowerCase().contains( query.toLowerCase(), ) || + (item['agent_code'] ?? '-').toLowerCase().contains( + query.toLowerCase(), + ) || (item['reg_no'] ?? '-').toLowerCase().contains( query.toLowerCase(), ) || (item['insurer_name'] ?? '-').toLowerCase().contains( query.toLowerCase(), ) || + (item['enquiry_status'] ?? '-').toLowerCase().contains( + query.toLowerCase(), + ) || (item['assigned_to_name'] ?? '-').toLowerCase().contains( query.toLowerCase(), ) || (item['insured_name'] ?? '-').toLowerCase().contains( query.toLowerCase(), ) || + (item['insurer_short_name'] ?? '-').toLowerCase().contains( + query.toLowerCase(), + ) || (item['premium_amount'] ?? '-').toLowerCase().contains( query.toLowerCase(), ) || @@ -716,6 +817,18 @@ class EnquiryStaffState extends ConsumerState { (); } + Future handleDeleteEnq(Map item) async { + final id = int.tryParse(item['id'].toString()) ?? 0; + idPrimary = item['id']; + + print("handleDeleteEnq - $idPrimary"); + final res = await apiService.deleteEnquiy(id, 0); + + if (res['status'] == 'success') { + autoRefrshfilterDateRange(); + } + } + void handleEdit(Map item) { print("handleEdit"); @@ -745,6 +858,7 @@ class EnquiryStaffState extends ConsumerState { selectedInsurer = item['insurer_id']; selectedStaff = item['assigned_to']; + selectedBroker = item['broker_id']; setState(() {}); } @@ -983,9 +1097,24 @@ class EnquiryStaffState extends ConsumerState { horizontal: 8, vertical: 3, ), - child: Text( - item['name'].toString(), - style: GoogleFonts.inter(fontSize: 12, color: Colors.black), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + item['name'].toString(), + style: GoogleFonts.inter( + fontSize: 12, + color: Colors.black, + ), + ), + Text( + "(${item['today_assigned']} / ${item['total_pending']})", + style: GoogleFonts.poppins( + fontSize: 10, + color: Colors.blueGrey.shade200, + ), + ), + ], ), ); }, @@ -1177,123 +1306,149 @@ class EnquiryStaffState extends ConsumerState { (item) => item['id'].toString() == selectedBroker, orElse: () => {}, ); - return SizedBox( - height: 30, - width: MediaQuery.of(context).size.width * 0.07, - child: DropdownSearch>( - key: dropDownKeyBroker, - selectedItem: selectedBrokers.isNotEmpty ? selectedBrokers : null, - items: (filter, infiniteScrollProps) { - return filteredBrokerData; - }, + return Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text('Broker', style: _subLabelTimeStyle), + SizedBox(height: 5), + SizedBox( + height: 30, + width: MediaQuery.of(context).size.width * 0.07, + child: DropdownSearch>( + key: dropDownKeyBroker, + selectedItem: selectedBrokers.isNotEmpty ? selectedBrokers : null, + items: (filter, infiniteScrollProps) { + return filteredBrokerData; + }, - itemAsString: (val) => val['name'].toString(), // what to show - compareFn: (item, selectedItem) => - item['id'] == selectedItem['id'], // ✅ compare by id - validator: (val) { - if (val == null) { - return "Required"; // ✅ error message - } - return null; - }, - suffixProps: DropdownSuffixProps( - // make sure the dropdown button is visible - dropdownButtonProps: DropdownButtonProps( - isVisible: true, - padding: EdgeInsets.zero, // remove default padding - constraints: const BoxConstraints( - // shrink icon tap area - minWidth: 12, - minHeight: 12, - ), - iconSize: 15, // smaller icon - // icon: const Icon(Icons.arrow_drop_down), - ), - ), - dropdownBuilder: (context, selectedItem) => Align( - alignment: Alignment.centerLeft, - child: Text( - selectedItem != null ? selectedItem['name'].toString() : "", - style: GoogleFonts.poppins(fontSize: 11, color: Colors.black), - overflow: TextOverflow.ellipsis, - maxLines: 1, - softWrap: false, - ), - ), - decoratorProps: DropDownDecoratorProps( - decoration: - AppInputDecorations.dropdownDecoration( - label: "Select Broker", - ).copyWith( - filled: true, - fillColor: Colors.white, // 👈 makes the dropdown input white - isDense: true, - border: OutlineInputBorder( - borderRadius: BorderRadius.circular(5), - borderSide: const BorderSide(color: Colors.black, width: 0.1), + itemAsString: (val) => val['name'].toString(), // what to show + compareFn: (item, selectedItem) => + item['id'] == selectedItem['id'], // ✅ compare by id + validator: (val) { + if (val == null) { + return "Required"; // ✅ error message + } + return null; + }, + suffixProps: DropdownSuffixProps( + // make sure the dropdown button is visible + dropdownButtonProps: DropdownButtonProps( + isVisible: true, + padding: EdgeInsets.zero, // remove default padding + constraints: const BoxConstraints( + // shrink icon tap area + minWidth: 12, + minHeight: 12, ), - enabledBorder: OutlineInputBorder( - borderRadius: BorderRadius.circular(5), - borderSide: const BorderSide(color: Colors.black, width: 0.1), - ), - contentPadding: EdgeInsets.symmetric( - horizontal: 8, - vertical: 6, - ), - ), - ), - - popupProps: PopupProps.menu( - fit: FlexFit.loose, - constraints: BoxConstraints(maxHeight: 250), - menuProps: MenuProps( - backgroundColor: - Colors.white, // 👈 sets dropdown background to white - ), - showSearchBox: true, - searchFieldProps: TextFieldProps( - style: GoogleFonts.inter(fontSize: 11, color: Colors.black), - decoration: InputDecoration( - contentPadding: EdgeInsets.all(1), - filled: true, - fillColor: Colors.white, - hintText: "Search Broker...", - 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 + iconSize: 15, // smaller icon + // icon: const Icon(Icons.arrow_drop_down), ), ), - ), - - itemBuilder: (context, item, isDisabled, isSelected) { - return Container( - // color: isSelected ? Colors.blue.withOpacity(0.1) : null, - padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 3), + dropdownBuilder: (context, selectedItem) => Align( + alignment: Alignment.centerLeft, child: Text( - item['name'].toString(), - style: GoogleFonts.inter(fontSize: 12, color: Colors.black), + selectedItem != null ? selectedItem['name'].toString() : "", + style: GoogleFonts.poppins( + fontSize: 11, + color: Color(0XFF6366F1), + ), + overflow: TextOverflow.ellipsis, + maxLines: 1, + softWrap: false, ), - ); - }, - // constraints: BoxConstraints(), - ), + ), + decoratorProps: DropDownDecoratorProps( + decoration: + AppInputDecorations.dropdownDecoration( + label: "Select Broker", + ).copyWith( + filled: true, + fillColor: + Colors.white, // 👈 makes the dropdown input white + isDense: true, + border: OutlineInputBorder( + borderRadius: BorderRadius.circular(5), + borderSide: const BorderSide( + color: Color(0XFF6366F1), + width: 0.1, + ), + ), + enabledBorder: OutlineInputBorder( + borderRadius: BorderRadius.circular(5), + borderSide: const BorderSide( + color: Color(0XFF6366F1), + width: 0.5, + ), + ), + contentPadding: EdgeInsets.symmetric( + horizontal: 8, + vertical: 6, + ), + ), + ), - onChanged: (val) { - if (val != null) { - print("Selected Broker : ${val['name']}"); - print("Id: ${val['id']}"); - selectedBroker = val['id']; - // controllers['agentId']?.text = val['agent_code']; - // agentId = agent['id']; - } - }, - ), + popupProps: PopupProps.menu( + fit: FlexFit.loose, + constraints: BoxConstraints(maxHeight: 250), + menuProps: MenuProps( + backgroundColor: + Colors.white, // 👈 sets dropdown background to white + ), + showSearchBox: true, + searchFieldProps: TextFieldProps( + autofocus: true, + style: GoogleFonts.inter(fontSize: 11, color: Colors.black), + decoration: InputDecoration( + contentPadding: EdgeInsets.all(1), + filled: true, + fillColor: Colors.white, + hintText: "Search Broker...", + 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) { + 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: 12, color: Colors.black), + ), + ); + }, + // constraints: BoxConstraints(), + ), + + onChanged: (val) { + if (val != null) { + print("Selected Broker : ${val['name']}"); + print("Id: ${val['id']}"); + selectedBroker = val['id']; + // controllers['agentId']?.text = val['agent_code']; + // agentId = agent['id']; + } + }, + ), + ), + ], ); } @@ -1582,7 +1737,7 @@ class EnquiryStaffState extends ConsumerState { SizedBox(height: 5), SizedBox( width: MediaQuery.of(context).size.width * 0.08, - child: ThemedFormInlineField( + child: ThemedFormField( controller: controllers['regNo']!, hintText: 'Vehicle Number', borderColor: Color(0XFF6366F1), @@ -1593,7 +1748,7 @@ class EnquiryStaffState extends ConsumerState { FilteringTextInputFormatter.allow(RegExp(r'[A-Za-z0-9- ]')), ], validator: (value) => Validators.requiredVechileNum(value, "regNo"), - widthNone: true, + // widthNone: true, ), ), ], @@ -2425,6 +2580,7 @@ class EnquiryStaffState extends ConsumerState { buildSelectStaffMem(context), buildAgentName(context, fromHeader: false), buildInsurer(context), + buildBroker(context), buildInsuredName(context), buildVehicleNumber(context), @@ -2537,7 +2693,7 @@ class EnquiryStaffState extends ConsumerState { splashRadius: 14, // ripple radius onPressed: () { setState(() { - isActionable = false; + // isActionable = false; bool isOpen = rowExpanded[id] ?? false; rowExpanded.clear(); // close all @@ -2866,6 +3022,7 @@ class EnquiryStaffState extends ConsumerState { docUploadedFile = null; }); refrshfilterDateRange(); + setState(() {}); return; } @@ -2911,7 +3068,8 @@ class EnquiryStaffState extends ConsumerState { Container( // height: MediaQuery.of(context).size.height*0. child: RaiseEnqForm( - key: raiseEnqKey, + // key: raiseEnqKey, + key: ValueKey(formRebuildKey), onSubmit: (dataSet) async { print('Check checking dataSet $dataSet'); try { @@ -2919,6 +3077,10 @@ class EnquiryStaffState extends ConsumerState { print("Enquiry saved successfully"); // RESET FORM raiseEnqKey.currentState?.resetFormFields(); + // REBUILD THE ENTIRE FORM + setState(() { + formRebuildKey = UniqueKey().toString(); + }); } catch (e) { showDialog( context: context, @@ -3038,9 +3200,9 @@ class EnquiryStaffState extends ConsumerState { print("Dialog closed"); print("Dialog result: $result"); if (result) { - setState(() { - isActionable = false; - }); + // setState(() { + // isActionable = false; + // }); refrshfilterDateRange(); } } @@ -3101,17 +3263,119 @@ class EnquiryStaffState extends ConsumerState { }); }, ), + + SizedBox(width: 10), + Container( + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(10), + border: Border.all(color: Color(0xFFE2E8F0), width: 1), + ), + child: Row( + children: [ + Container( + // color: Colors.yellow.shade50, + child: Row( + mainAxisSize: MainAxisSize.min, + children: [ + Text( + isActionable ? "OFF" : "ON", + style: GoogleFonts.poppins( + fontSize: 10, + color: !isActionable ? Colors.green : Colors.grey, + ), + ), + SizedBox( + height: 10, + width: 30, + child: Padding( + padding: EdgeInsets.zero, + child: Transform.scale( + scale: 0.4, + child: Switch( + value: !isActionable, + onChanged: (v) async { + bool newValue = !v; + setState(() => isActionable = newValue); + + final prefs = + await SharedPreferences.getInstance(); + await prefs.setBool( + 'isActionable', + newValue, + ); + }, + ), + ), + ), + ), + ], + ), + ), + Tooltip( + message: 'Set AutoRefresh Timer', + child: Container( + padding: EdgeInsets.symmetric(horizontal: 5), + decoration: BoxDecoration( + // color: Colors.white, + // borderRadius: BorderRadius.circular(30), + border: Border( + left: BorderSide( + color: Color(0xFFE2E8F0), + width: 2, + ), + // right: BorderSide( + // color: Color(0xFFE2E8F0), + // width: 2, + // ), + ), + ), + height: 30, + child: DropdownButton( + value: selectedSeconds, + underline: SizedBox(), + items: [30, 45, 60].map((e) { + return DropdownMenuItem( + value: e, + child: Text( + "$e sec", + style: GoogleFonts.poppins(fontSize: 11), + ), + ); + }).toList(), + onChanged: (value) async { + setState(() { + selectedSeconds = value!; + startTimer(); // restart timer with new value + }); + + final prefs = await SharedPreferences.getInstance(); + await prefs.setInt('selectedSeconds', value!); + }, + ), + ), + ), + // + // InkWell( + // onTap: () { + // resetPreferences(); + // }, + // child: Icon(Icons.refresh, size: 18), + // ), + ], + ), + ), + SizedBox(width: 10), MouseRegion( onEnter: (_) { - setState(() { - isActionable = true; - }); + // setState(() { + // isActionable = true; + // }); }, onExit: (_) { - setState(() { - // isActionable = false; - isActionable = _searchStaffController.text.isNotEmpty; - }); + // setState(() { + // // isActionable = false; + // isActionable = _searchStaffController.text.isNotEmpty; + // }); }, child: ThemedSearchField( hintText: 'Search', @@ -3725,12 +3989,27 @@ class EnquiryStaffState extends ConsumerState { // Insurer Name DataCell( - SizedBox( - width: 60, - child: Text( - item['insurer_short_name'] ?? '-', - style: _dataBoldthm2, - ), + Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.center, + children: [ + SizedBox( + width: 60, + child: Text( + item['insurer_short_name'] ?? '-', + style: _dataBoldthm2, + ), + ), + Tooltip( + message: 'Broker : ${item['broker_name']}', + child: Text( + item['broker_name'] != null + ? _truncateText(item['broker_name'], 8) + : '-', + style: _dataBoldthm4, + ), + ), + ], ), ), @@ -3820,7 +4099,7 @@ class EnquiryStaffState extends ConsumerState { DataCell( SizedBox( - width: 70.0, + width: 80.0, child: Row( children: [ Tooltip( @@ -3874,13 +4153,13 @@ class EnquiryStaffState extends ConsumerState { tooltip: "Edit", onPressed: () { setState(() { - isActionable = false; + // isActionable = false; bool isOpen = rowExpanded[id] ?? false; rowExpanded.clear(); // close all if (!isOpen) { - isActionable = true; + // isActionable = true; rowExpanded[id] = true; // open only if previously closed } @@ -3943,6 +4222,28 @@ class EnquiryStaffState extends ConsumerState { ), ), ), + + if (item['enquiry_status'] != 'Completed') ...[ + IconButton( + padding: EdgeInsets.zero, // remove outer padding + constraints: BoxConstraints( + // reduce clickable area + minWidth: 24, + minHeight: 24, + ), + icon: Icon( + Icons.delete, + color: Colors.red.shade400, + size: 15, + ), + + tooltip: "Delete Enquiry", + onPressed: () { + setState(() {}); + handleDeleteEnq(item); + }, + ), + ], ], ), ), @@ -4556,91 +4857,209 @@ class EnquiryStaffState extends ConsumerState { ((item['enquiry_status'] == 'Assigned') && (item['quotation_id'] == null))) ? Text('-') - : ThemedUploadField( - // key: ValueKey(selectedFileNames), - // hintText: item['policy_pdf_file_name'] ?? "Upload Document", - hintText: - selectedFileNames ?? - item['policy_pdf_file_name'] ?? - "Upload Document", + : Row( + children: [ + if ((((item['enquiry_status'] == 'Completed') && + (item['quotation_id'] != null)))) ...[ + // Text(item['policy_pdf_file_name']), + Tooltip( + message: 'Download Policy File', + child: InkWell( + onTap: () => apiService.downloadFile( + apiUrl: + 'api/policy/downloadPolicyFile?policy_id=${item["policy_id"]}&file_type=policy_pdf', + apiId: item["policy_id"], + localFile: null, + fileName: item['policy_pdf_file_name'], + ), - // txtheight: 30, - padHorizontal: 4, - padVertical: 5, - fontSZ: 11, - borderCirculr: 5, - txtwidth: ResponsiveLayout.isMobile(context) - ? null - : MediaQuery.of(context).size.width * 0.18, - borderColor: Color(0xFFE2E8F0), - - // highlightColor: Color(0xFF50A398), - // backgroundColor: Color(0xFFEDF6F5), - onFileSelected: (fileName, file) async { - print("Picked file: $fileName (${file.size} bytes)"); - - if (lastPickedFile == fileName) { - print("❌ Cancel clicked. Ignoring old file."); - setState(() { - print('Clear Fields'); - selectedFileNames = null; // clears the field - docUploadedFile = null; - print('Clear Fields - 1'); - }); - // refrshfilterDateRange(); - return; - } - - lastPickedFile = fileName; - - // setState(() { - // docUploadedFile = null; - // selectedFileNames = null; - // }); - - // ❗ User canceled picker - if (file == null || - fileName == null || - fileName.isEmpty || - file.size == 0) { - print("❌ File selection canceled. No upload."); - return; - } - - print("Picked file: $fileName (${file.size} bytes)"); - - if (!fileName.toLowerCase().endsWith('.pdf')) { - ToastHelper.showErrorToast( - context, - 'Only PDF files are allowed.', - ); - ScaffoldMessenger.of(context).showSnackBar( - const SnackBar( - content: Text('Only PDF files are allowed.'), - backgroundColor: Colors.red, + child: Icon( + Icons.file_download, + size: 14, + color: Colors.blueAccent, + ), ), - ); - return; // Stop here - } + ), + ], - print("Picked file: $fileName (${file.size} bytes)"); - setState(() { - docUploadedFile = file; - }); - await uploadPolicyPDF( - file: docUploadedFile, - data: { - "quotation_id": item["quotation_id"], - "manager_id": managerId, - "created_by": userId, - "updated_by": userId, - "id": item["policy_id"], // ONLY while updating - }, - ); - // if (selectedBrokerName == 'Nhance') { - // handleUploadPolicy(); - // } - }, + Builder( + builder: (buttonContext) => Material( + color: Colors.white, + child: InkWell( + // hoverColor: Color(0xFFEAF6F4), + onTap: () async { + // ✅ Get overlay and button position RELATIVE to InkWell + final RenderBox button = + buttonContext.findRenderObject() as RenderBox; + final RenderBox overlay = + Overlay.of( + buttonContext, + ).context.findRenderObject() + as RenderBox; + + final Offset position = button.localToGlobal( + Offset.zero, + ancestor: overlay, + ); + + await showMenu( + context: buttonContext, + position: RelativeRect.fromLTRB( + position.dx, + position.dy + button.size.height, + overlay.size.width, + // overlay.size.width - position.dx, + 0, + ), + items: [ + PopupMenuItem( + child: Column( + crossAxisAlignment: + CrossAxisAlignment.start, + mainAxisSize: MainAxisSize.min, + children: [ + Text( + 'Upload Policy PDF', + style: _dataBold, + ), + SizedBox(height: 10), + ThemedUploadField( + // key: ValueKey(selectedFileNames), + // hintText: item['policy_pdf_file_name'] ?? "Upload Document", + hintText: + selectedFileNames ?? + item['policy_pdf_file_name'] ?? + "Upload Document", + + // txtheight: 30, + padHorizontal: 4, + padVertical: 5, + fontSZ: 11, + borderCirculr: 5, + txtwidth: + ResponsiveLayout.isMobile(context) + ? null + : MediaQuery.of( + context, + ).size.width * + 0.18, + borderColor: Color(0xFFE2E8F0), + + // highlightColor: Color(0xFF50A398), + // backgroundColor: Color(0xFFEDF6F5), + onFileSelected: (fileName, file) async { + print( + "Picked file: $fileName (${file.size} bytes)", + ); + + if (lastPickedFile == fileName) { + print( + "❌ Cancel clicked. Ignoring old file.", + ); + setState(() { + print('Clear Fields'); + selectedFileNames = + null; // clears the field + docUploadedFile = null; + print('Clear Fields - 1'); + }); + // Navigator.of(context).pop(); + // refrshfilterDateRange(); + return; + } + + lastPickedFile = fileName; + + // setState(() { + // docUploadedFile = null; + // selectedFileNames = null; + // }); + + // ❗ User canceled picker + if (file == null || + fileName == null || + fileName.isEmpty || + file.size == 0) { + print( + "❌ File selection canceled. No upload.", + ); + return; + } + + print( + "Picked file: $fileName (${file.size} bytes)", + ); + + if (!fileName + .toLowerCase() + .endsWith('.pdf')) { + ToastHelper.showErrorToast( + context, + 'Only PDF files are allowed.', + ); + ScaffoldMessenger.of( + context, + ).showSnackBar( + const SnackBar( + content: Text( + 'Only PDF files are allowed.', + ), + backgroundColor: Colors.red, + ), + ); + return; // Stop here + } + + print( + "Picked file: $fileName (${file.size} bytes)", + ); + setState(() { + docUploadedFile = file; + }); + await uploadPolicyPDF( + file: docUploadedFile, + data: { + "quotation_id": + item["quotation_id"], + "manager_id": managerId, + "created_by": userId, + "updated_by": userId, + "id": + item["policy_id"], // ONLY while updating + }, + ); + Navigator.of(context).pop(); + // if (selectedBrokerName == 'Nhance') { + // handleUploadPolicy(); + // } + }, + ), + ], + ), + ), + ], + color: Colors.white, + ); + }, + child: Tooltip( + message: + 'Click and Upload Policy PDF', // what appears on hover/long press + waitDuration: const Duration( + milliseconds: 500, + ), // optional + showDuration: const Duration( + seconds: 2, + ), // optional + child: Icon( + Icons.file_upload_outlined, + size: 15, + color: Colors.green, + ), + ), + ), + ), + ), + ], ), ), ), diff --git a/lib/presentation/screens/staff/Enquiry/raise_enq_form.dart b/lib/presentation/screens/staff/Enquiry/raise_enq_form.dart index c9ba735..771e14a 100644 --- a/lib/presentation/screens/staff/Enquiry/raise_enq_form.dart +++ b/lib/presentation/screens/staff/Enquiry/raise_enq_form.dart @@ -192,6 +192,8 @@ class RaiseEnqFormState extends ConsumerState { // 3. Reset form validation _formKey.currentState?.reset(); + + setState(() {}); } Future getVehicleType() async { @@ -365,6 +367,7 @@ class RaiseEnqFormState extends ConsumerState { // color: Color(0xFFFCFCFC), // margin: const EdgeInsets.symmetric(vertical: 8), padding: const EdgeInsets.symmetric(vertical: 8, horizontal: 25), + height: MediaQuery.of(context).size.height * 0.16, decoration: BoxDecoration( color: Colors.white, // color: Colors.amber, @@ -387,7 +390,7 @@ class RaiseEnqFormState extends ConsumerState { key: _formKey, child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, - crossAxisAlignment: CrossAxisAlignment.end, + crossAxisAlignment: CrossAxisAlignment.center, children: [ buildAgentName(context, fromHeader: true), if (roleId != 'staff') ...[buildSelectStaffMem(context)], @@ -398,6 +401,7 @@ class RaiseEnqFormState extends ConsumerState { // buildInsuredName(context, fromHeader: true), buildVehicleNumber(context), Row( + mainAxisAlignment: MainAxisAlignment.start, children: [ buildRefresh(context), SizedBox(width: 5), @@ -952,9 +956,25 @@ class RaiseEnqFormState extends ConsumerState { horizontal: 8, vertical: 3, ), - child: Text( - item['name'].toString(), - style: GoogleFonts.inter(fontSize: 12, color: Colors.black), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text( + item['name'].toString(), + style: GoogleFonts.inter( + fontSize: 12, + color: Colors.black, + ), + ), + + Text( + "(${item['today_assigned']} / ${item['total_pending']})", + style: GoogleFonts.poppins( + fontSize: 10, + color: Colors.blueGrey.shade200, + ), + ), + ], ), ); }, diff --git a/lib/presentation/themes/charts/appChartColors.dart b/lib/presentation/themes/charts/appChartColors.dart new file mode 100644 index 0000000..a1ca589 --- /dev/null +++ b/lib/presentation/themes/charts/appChartColors.dart @@ -0,0 +1,25 @@ +import 'package:flutter/material.dart'; + +class AppColors { + static const Color primary = contentColorCyan; + static const Color menuBackground = Color(0xFF090912); + static const Color itemsBackground = Color(0xFF1B2339); + static const Color pageBackground = Color(0xFF282E45); + static const Color mainTextColor1 = Colors.white; + static const Color mainTextColor2 = Colors.white70; + static const Color mainTextColor3 = Colors.white38; + static const Color mainGridLineColor = Colors.white10; + static const Color borderColor = Colors.white54; + static const Color gridLinesColor = Color(0x11FFFFFF); + + static const Color contentColorBlack = Colors.black; + static const Color contentColorWhite = Colors.white; + static const Color contentColorBlue = Color(0xFF2196F3); + static const Color contentColorYellow = Color(0xFFFFC300); + static const Color contentColorOrange = Color(0xFFFF683B); + static const Color contentColorGreen = Color(0xFF3BFF49); + static const Color contentColorPurple = Color(0xFF6E1BFF); + static const Color contentColorPink = Color(0xFFFF3AF2); + static const Color contentColorRed = Color(0xFFE80054); + static const Color contentColorCyan = Color(0xFF50E4FF); +} diff --git a/lib/presentation/themes/charts/barChart.dart b/lib/presentation/themes/charts/barChart.dart index af5d81c..ae031d6 100644 --- a/lib/presentation/themes/charts/barChart.dart +++ b/lib/presentation/themes/charts/barChart.dart @@ -1,87 +1,136 @@ -// import 'package:fl_chart/fl_chart.dart'; -// import 'package:flutter/material.dart'; -// -// class DynamicHorizontalBarChart extends StatelessWidget { -// final List> data; -// // Example: -// // [ -// // {"label": "Apple", "value": 35}, -// // {"label": "Banana", "value": 20}, -// // {"label": "Orange", "value": 15}, -// // ] -// -// const DynamicHorizontalBarChart({super.key, required this.data}); -// -// @override -// Widget build(BuildContext context) { -// double maxValue = data -// .map((e) => e["value"] as double) -// .reduce((a, b) => a > b ? a : b); -// -// return SizedBox( -// height: data.length * 50, -// child: BarChart( -// BarChartData( -// maxY: maxValue + 10, -// barTouchData: BarTouchData(enabled: false), -// -// titlesData: FlTitlesData( -// leftTitles: AxisTitles( -// sideTitles: SideTitles( -// showTitles: true, -// reservedSize: 100, -// getTitlesWidget: (value, meta) { -// int index = value.toInt(); -// if (index < data.length) { -// return Text( -// data[index]["label"], -// style: const TextStyle(fontSize: 12), -// ); -// } -// return Container(); -// }, -// ), -// ), -// rightTitles: AxisTitles(), -// topTitles: AxisTitles(), -// bottomTitles: AxisTitles(), -// ), -// -// gridData: FlGridData(show: false), -// borderData: FlBorderData(show: false), -// -// barGroups: List.generate(data.length, (index) { -// final item = data[index]; -// final double value = item["value"] * 1.0; -// -// return BarChartGroupData( -// x: index, -// barRods: [ -// BarChartRodData( -// toY: value, -// width: 25, -// color: Colors.teal, -// borderRadius: BorderRadius.circular(5), -// -// // 🟩 LABEL INSIDE THE BAR -// rodStackItems: [ -// BarChartRodStackItem( -// 0, -// value, -// Colors.transparent, -// // BorderSide(), -// // StackItemLabel( -// // label: "${value.toInt()}", -// // labelStyle: const TextStyle(color: Colors.white), -// // ), -// ), -// ], -// ), -// ], -// ); -// }), -// ), -// ), -// ); -// } -// } +import 'package:fl_chart/fl_chart.dart'; +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; + +import 'appChartColors.dart'; + +class BarChart extends StatefulWidget { + final List<_BarData>? dataList; + final List? labels; + final String title; + final double maxY; + final int initialRotation; + + const BarChart( + BarChartData barChartData, { + super.key, + this.dataList, + this.labels, + this.title = "Horizontal Bar Chart", + this.maxY = 20, + this.initialRotation = 1, + }); + + final shadowColor = const Color(0xFFCCCCCC); + + @override + State createState() => _BarChartState(); +} + +class _BarChartState extends State { + int touchedGroupIndex = -1; + late int rotationTurns; + + @override + void initState() { + super.initState(); + rotationTurns = widget.initialRotation; + } + + BarChartGroupData generateBarGroup( + int x, + Color color, + double value, + double shadowValue, + ) { + return BarChartGroupData( + x: x, + barRods: [ + BarChartRodData(toY: value, color: color, width: 6), + BarChartRodData(toY: shadowValue, color: widget.shadowColor, width: 6), + ], + showingTooltipIndicators: touchedGroupIndex == x ? [0] : [], + ); + } + + @override + Widget build(BuildContext context) { + return Padding( + padding: const EdgeInsets.all(24), + child: Column( + children: [ + Row( + children: [ + const Spacer(), + Text( + widget.title, + style: const TextStyle( + color: AppColors.mainTextColor1, + fontSize: 20, + ), + ), + Spacer(), + IconButton( + onPressed: () { + setState(() => rotationTurns += 1); + }, + icon: RotatedBox( + quarterTurns: rotationTurns - 1, + child: const Icon(Icons.rotate_90_degrees_cw), + ), + ), + ], + ), + const SizedBox(height: 18), + AspectRatio( + aspectRatio: 1.4, + child: BarChart( + BarChartData( + alignment: BarChartAlignment.spaceBetween, + rotationQuarterTurns: rotationTurns, + borderData: FlBorderData(show: false), + titlesData: FlTitlesData( + bottomTitles: AxisTitles( + sideTitles: SideTitles( + showTitles: true, + getTitlesWidget: (value, meta) { + final i = value.toInt(); + if (i >= widget.labels!.length) return const SizedBox(); + return SideTitleWidget( + meta: meta, + child: Text(widget.labels![i]), + ); + }, + ), + ), + leftTitles: const AxisTitles(), + ), + gridData: const FlGridData(show: false), + barGroups: widget.dataList?.asMap().entries.map((e) { + final index = e.key; + final data = e.value; + return generateBarGroup( + index, + data.color, + data.value, + data.shadowValue, + ); + }).toList(), + maxY: widget.maxY, + ), + // dataList: [], + // labels: [], + ), + ), + ], + ), + ); + } +} + +class _BarData { + final Color color; + final double value; + final double shadowValue; + const _BarData(this.color, this.value, this.shadowValue); +} diff --git a/lib/presentation/widgets/custom_Stdate_EnDate_Filter.dart b/lib/presentation/widgets/custom_Stdate_EnDate_Filter.dart index 7170049..9d64642 100644 --- a/lib/presentation/widgets/custom_Stdate_EnDate_Filter.dart +++ b/lib/presentation/widgets/custom_Stdate_EnDate_Filter.dart @@ -200,7 +200,7 @@ class _DateFilterRowState extends ConsumerState { message: 'Filter', child: IconButton( icon: const Icon( - Icons.filter_alt_outlined, + Icons.search_rounded, size: 18, color: const Color(0xFF94A3B8), ), diff --git a/macos/Flutter/GeneratedPluginRegistrant.swift b/macos/Flutter/GeneratedPluginRegistrant.swift index 3eb8669..7f6af1d 100644 --- a/macos/Flutter/GeneratedPluginRegistrant.swift +++ b/macos/Flutter/GeneratedPluginRegistrant.swift @@ -7,7 +7,6 @@ import Foundation import connectivity_plus import file_picker -import firebase_app_check import firebase_auth import firebase_core import firebase_messaging @@ -23,7 +22,6 @@ import url_launcher_macos func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) { ConnectivityPlusPlugin.register(with: registry.registrar(forPlugin: "ConnectivityPlusPlugin")) FilePickerPlugin.register(with: registry.registrar(forPlugin: "FilePickerPlugin")) - FLTFirebaseAppCheckPlugin.register(with: registry.registrar(forPlugin: "FLTFirebaseAppCheckPlugin")) FLTFirebaseAuthPlugin.register(with: registry.registrar(forPlugin: "FLTFirebaseAuthPlugin")) FLTFirebaseCorePlugin.register(with: registry.registrar(forPlugin: "FLTFirebaseCorePlugin")) FLTFirebaseMessagingPlugin.register(with: registry.registrar(forPlugin: "FLTFirebaseMessagingPlugin")) diff --git a/pubspec.lock b/pubspec.lock index bbb6d37..15933bd 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -13,10 +13,10 @@ packages: dependency: transitive description: name: _flutterfire_internals - sha256: "948f7d74f41dd6f2d563ea9f4c21d7ea764f8e047d2b24138974c19c24d37eb6" + sha256: "8a1f5f3020ef2a74fb93f7ab3ef127a8feea33a7a2276279113660784ee7516a" url: "https://pub.dev" source: hosted - version: "1.3.61" + version: "1.3.64" analyzer: dependency: transitive description: @@ -297,30 +297,6 @@ packages: url: "https://pub.dev" source: hosted version: "10.3.3" - firebase_app_check: - dependency: "direct main" - description: - name: firebase_app_check - sha256: "3bf5d9c9043723ae12c09b2a012ca5f32653a1bc30a0a9818983766ea06d72a8" - url: "https://pub.dev" - source: hosted - version: "0.4.0+1" - firebase_app_check_platform_interface: - dependency: transitive - description: - name: firebase_app_check_platform_interface - sha256: bdda519aa487be605a53093ececa564d48afadd1a1d018520ce45d00415ac03d - url: "https://pub.dev" - source: hosted - version: "0.2.0+1" - firebase_app_check_web: - dependency: transitive - description: - name: firebase_app_check_web - sha256: ab7b57c95faf266e2d5cd9fc57cda54d1fdfbc2c429c09b095830d4186f25920 - url: "https://pub.dev" - source: hosted - version: "0.2.0+16" firebase_auth: dependency: "direct main" description: @@ -349,26 +325,26 @@ packages: dependency: "direct main" description: name: firebase_core - sha256: "967dae9a65f69377beb9f4ab292ea63ce5befa1ce24682cab1b69ca4b7a46927" + sha256: "1f2dfd9f535d81f8b06d7a50ecda6eac1e6922191ed42e09ca2c84bd2288927c" url: "https://pub.dev" source: hosted - version: "4.1.0" + version: "4.2.1" firebase_core_platform_interface: dependency: transitive description: name: firebase_core_platform_interface - sha256: "5dbc900677dcbe5873d22ad7fbd64b047750124f1f9b7ebe2a33b9ddccc838eb" + sha256: cccb4f572325dc14904c02fcc7db6323ad62ba02536833dddb5c02cac7341c64 url: "https://pub.dev" source: hosted - version: "6.0.0" + version: "6.0.2" firebase_core_web: dependency: transitive description: name: firebase_core_web - sha256: f7ee08febc1c4451588ce58ffcf28edaee857e9a196fee88b85deb889990094a + sha256: ff18fabb0ad0ed3595d2f2c85007ecc794aadecdff5b3bb1460b7ee47cded398 url: "https://pub.dev" source: hosted - version: "3.1.0" + version: "3.3.0" firebase_messaging: dependency: "direct main" description: @@ -401,6 +377,14 @@ packages: url: "https://pub.dev" source: hosted version: "1.1.1" + fl_chart: + dependency: "direct main" + description: + name: fl_chart + sha256: "5276944c6ffc975ae796569a826c38a62d2abcf264e26b88fa6f482e107f4237" + url: "https://pub.dev" + source: hosted + version: "0.70.2" flutter: dependency: "direct main" description: flutter diff --git a/pubspec.yaml b/pubspec.yaml index 890a6c1..3566bc5 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -58,7 +58,6 @@ dependencies: google_sign_in: ^7.1.1 firebase_core: ^4.1.0 firebase_auth: ^6.0.2 - firebase_app_check: ^0.4.0+1 package_info_plus: ^8.3.1 flutter_lints: ^6.0.0 easy_loading_button: ^0.4.0 @@ -69,6 +68,8 @@ dependencies: dropdown_search: ^6.0.2 file_picker: ^10.3.3 fluttertoast: ^9.0.0 + fl_chart: ^0.70.0 + # fl_chart: ^1.1.0