From d73f745cf223744f7eae8c3687d2eeef8f724d3e Mon Sep 17 00:00:00 2001 From: SurendarSuri30 Date: Mon, 6 Apr 2026 17:23:16 +0530 Subject: [PATCH] bug fix --- .flutter-plugins-dependencies | 2 +- lib/presentation/layouts/appheader.dart | 2 +- .../screens/Enquiry/enquiryList.dart | 77 --- .../policy_claims_endros/endrosment.dart | 43 +- lib/presentation/screens/Grid/gridView.dart | 36 -- .../Masters/VehicleType/vehicleList.dart | 56 ++- .../dashboard/partner_portal_dashboard.dart | 8 +- .../screens/payout/custom_dateRange.dart | 212 ++++----- .../screens/payout/payout_details.dart | 276 +++++++---- .../screens/payout/payout_details_view.dart | 269 +++++++---- .../screens/payout/payout_report.dart | 78 +-- .../indicators/date_range_picker_dialog.dart | 446 ++++++++++++++++++ .../indicators/date_range_picker_field.dart | 255 ++++++++++ .../widgets/custom_Stdate_EnDate_Filter.dart | 89 +--- pubspec.lock | 22 +- 15 files changed, 1293 insertions(+), 578 deletions(-) create mode 100644 lib/presentation/themes/indicators/date_range_picker_dialog.dart create mode 100644 lib/presentation/themes/indicators/date_range_picker_field.dart diff --git a/.flutter-plugins-dependencies b/.flutter-plugins-dependencies index 7ba81ee..f38d3ae 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":"device_info_plus","path":"/home/venba/.pub-cache/hosted/pub.dev/device_info_plus-11.5.0/","native_build":true,"dependencies":[],"dev_dependency":false},{"name":"file_picker","path":"/home/venba/.pub-cache/hosted/pub.dev/file_picker-10.3.7/","native_build":true,"dependencies":[],"dev_dependency":false},{"name":"firebase_auth","path":"/home/venba/.pub-cache/hosted/pub.dev/firebase_auth-6.1.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.4/","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.2.1/","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":"pdf_render","path":"/home/venba/.pub-cache/hosted/pub.dev/pdf_render-1.4.12/","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":"syncfusion_flutter_pdfviewer","path":"/home/venba/.pub-cache/hosted/pub.dev/syncfusion_flutter_pdfviewer-31.1.19/","native_build":true,"dependencies":["device_info_plus"],"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":"device_info_plus","path":"/home/venba/.pub-cache/hosted/pub.dev/device_info_plus-11.5.0/","native_build":true,"dependencies":[],"dev_dependency":false},{"name":"file_picker","path":"/home/venba/.pub-cache/hosted/pub.dev/file_picker-10.3.7/","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.1.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.4/","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.31/","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.2.1/","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.19/","native_build":true,"dependencies":[],"dev_dependency":false},{"name":"pdf_render","path":"/home/venba/.pub-cache/hosted/pub.dev/pdf_render-1.4.12/","native_build":true,"dependencies":[],"dev_dependency":false},{"name":"shared_preferences_android","path":"/home/venba/.pub-cache/hosted/pub.dev/shared_preferences_android-2.4.13/","native_build":true,"dependencies":[],"dev_dependency":false},{"name":"syncfusion_flutter_pdfviewer","path":"/home/venba/.pub-cache/hosted/pub.dev/syncfusion_flutter_pdfviewer-31.1.19/","native_build":true,"dependencies":["device_info_plus"],"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":"device_info_plus","path":"/home/venba/.pub-cache/hosted/pub.dev/device_info_plus-11.5.0/","native_build":true,"dependencies":[],"dev_dependency":false},{"name":"file_picker","path":"/home/venba/.pub-cache/hosted/pub.dev/file_picker-10.3.7/","native_build":true,"dependencies":[],"dev_dependency":false},{"name":"firebase_auth","path":"/home/venba/.pub-cache/hosted/pub.dev/firebase_auth-6.1.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.4/","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.2.1/","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":"pdf_render","path":"/home/venba/.pub-cache/hosted/pub.dev/pdf_render-1.4.12/","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":"syncfusion_pdfviewer_macos","path":"/home/venba/.pub-cache/hosted/pub.dev/syncfusion_pdfviewer_macos-31.1.19/","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":"device_info_plus","path":"/home/venba/.pub-cache/hosted/pub.dev/device_info_plus-11.5.0/","native_build":false,"dependencies":[],"dev_dependency":false},{"name":"file_picker","path":"/home/venba/.pub-cache/hosted/pub.dev/file_picker-10.3.7/","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":"syncfusion_pdfviewer_linux","path":"/home/venba/.pub-cache/hosted/pub.dev/syncfusion_pdfviewer_linux-31.1.19/","native_build":true,"dependencies":[],"dev_dependency":false},{"name":"url_launcher_linux","path":"/home/venba/.pub-cache/hosted/pub.dev/url_launcher_linux-3.2.2/","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":"device_info_plus","path":"/home/venba/.pub-cache/hosted/pub.dev/device_info_plus-11.5.0/","native_build":false,"dependencies":[],"dev_dependency":false},{"name":"file_picker","path":"/home/venba/.pub-cache/hosted/pub.dev/file_picker-10.3.7/","native_build":false,"dependencies":[],"dev_dependency":false},{"name":"firebase_auth","path":"/home/venba/.pub-cache/hosted/pub.dev/firebase_auth-6.1.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":"syncfusion_pdfviewer_windows","path":"/home/venba/.pub-cache/hosted/pub.dev/syncfusion_pdfviewer_windows-31.1.19/","native_build":true,"dependencies":[],"dev_dependency":false},{"name":"url_launcher_windows","path":"/home/venba/.pub-cache/hosted/pub.dev/url_launcher_windows-3.1.5/","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":"device_info_plus","path":"/home/venba/.pub-cache/hosted/pub.dev/device_info_plus-11.5.0/","dependencies":[],"dev_dependency":false},{"name":"file_picker","path":"/home/venba/.pub-cache/hosted/pub.dev/file_picker-10.3.7/","dependencies":[],"dev_dependency":false},{"name":"firebase_auth_web","path":"/home/venba/.pub-cache/hosted/pub.dev/firebase_auth_web-6.1.0/","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.1.0/","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.1.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":"pdf_render","path":"/home/venba/.pub-cache/hosted/pub.dev/pdf_render-1.4.12/","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":"syncfusion_pdfviewer_web","path":"/home/venba/.pub-cache/hosted/pub.dev/syncfusion_pdfviewer_web-31.1.19/","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":"device_info_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":"pdf_render","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":"syncfusion_flutter_pdfviewer","dependencies":["url_launcher","device_info_plus","syncfusion_pdfviewer_web","syncfusion_pdfviewer_macos","syncfusion_pdfviewer_windows","syncfusion_pdfviewer_linux"]},{"name":"syncfusion_pdfviewer_linux","dependencies":[]},{"name":"syncfusion_pdfviewer_macos","dependencies":[]},{"name":"syncfusion_pdfviewer_web","dependencies":[]},{"name":"syncfusion_pdfviewer_windows","dependencies":[]},{"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":"2026-04-04 18:24:15.122412","version":"3.41.4","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":"/Users/venbateam/.pub-cache/hosted/pub.dev/connectivity_plus-6.1.5/","native_build":true,"dependencies":[],"dev_dependency":false},{"name":"device_info_plus","path":"/Users/venbateam/.pub-cache/hosted/pub.dev/device_info_plus-11.5.0/","native_build":true,"dependencies":[],"dev_dependency":false},{"name":"file_picker","path":"/Users/venbateam/.pub-cache/hosted/pub.dev/file_picker-10.3.7/","native_build":true,"dependencies":[],"dev_dependency":false},{"name":"firebase_auth","path":"/Users/venbateam/.pub-cache/hosted/pub.dev/firebase_auth-6.1.2/","native_build":true,"dependencies":["firebase_core"],"dev_dependency":false},{"name":"firebase_core","path":"/Users/venbateam/.pub-cache/hosted/pub.dev/firebase_core-4.2.1/","native_build":true,"dependencies":[],"dev_dependency":false},{"name":"firebase_messaging","path":"/Users/venbateam/.pub-cache/hosted/pub.dev/firebase_messaging-16.0.4/","native_build":true,"dependencies":["firebase_core"],"dev_dependency":false},{"name":"flutter_secure_storage","path":"/Users/venbateam/.pub-cache/hosted/pub.dev/flutter_secure_storage-9.2.4/","native_build":true,"dependencies":[],"dev_dependency":false},{"name":"fluttertoast","path":"/Users/venbateam/.pub-cache/hosted/pub.dev/fluttertoast-9.0.0/","native_build":true,"dependencies":[],"dev_dependency":false},{"name":"google_sign_in_ios","path":"/Users/venbateam/.pub-cache/hosted/pub.dev/google_sign_in_ios-6.2.1/","shared_darwin_source":true,"native_build":true,"dependencies":[],"dev_dependency":false},{"name":"local_auth_darwin","path":"/Users/venbateam/.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":"/Users/venbateam/.pub-cache/hosted/pub.dev/open_file_ios-1.0.3/","native_build":true,"dependencies":[],"dev_dependency":false},{"name":"package_info_plus","path":"/Users/venbateam/.pub-cache/hosted/pub.dev/package_info_plus-8.3.1/","native_build":true,"dependencies":[],"dev_dependency":false},{"name":"path_provider_foundation","path":"/Users/venbateam/.pub-cache/hosted/pub.dev/path_provider_foundation-2.4.2/","shared_darwin_source":true,"native_build":true,"dependencies":[],"dev_dependency":false},{"name":"pdf_render","path":"/Users/venbateam/.pub-cache/hosted/pub.dev/pdf_render-1.4.12/","native_build":true,"dependencies":[],"dev_dependency":false},{"name":"shared_preferences_foundation","path":"/Users/venbateam/.pub-cache/hosted/pub.dev/shared_preferences_foundation-2.5.4/","shared_darwin_source":true,"native_build":true,"dependencies":[],"dev_dependency":false},{"name":"syncfusion_flutter_pdfviewer","path":"/Users/venbateam/.pub-cache/hosted/pub.dev/syncfusion_flutter_pdfviewer-31.1.19/","native_build":true,"dependencies":["device_info_plus"],"dev_dependency":false},{"name":"url_launcher_ios","path":"/Users/venbateam/.pub-cache/hosted/pub.dev/url_launcher_ios-6.3.4/","native_build":true,"dependencies":[],"dev_dependency":false}],"android":[{"name":"connectivity_plus","path":"/Users/venbateam/.pub-cache/hosted/pub.dev/connectivity_plus-6.1.5/","native_build":true,"dependencies":[],"dev_dependency":false},{"name":"device_info_plus","path":"/Users/venbateam/.pub-cache/hosted/pub.dev/device_info_plus-11.5.0/","native_build":true,"dependencies":[],"dev_dependency":false},{"name":"file_picker","path":"/Users/venbateam/.pub-cache/hosted/pub.dev/file_picker-10.3.7/","native_build":true,"dependencies":["flutter_plugin_android_lifecycle"],"dev_dependency":false},{"name":"firebase_auth","path":"/Users/venbateam/.pub-cache/hosted/pub.dev/firebase_auth-6.1.2/","native_build":true,"dependencies":["firebase_core"],"dev_dependency":false},{"name":"firebase_core","path":"/Users/venbateam/.pub-cache/hosted/pub.dev/firebase_core-4.2.1/","native_build":true,"dependencies":[],"dev_dependency":false},{"name":"firebase_messaging","path":"/Users/venbateam/.pub-cache/hosted/pub.dev/firebase_messaging-16.0.4/","native_build":true,"dependencies":["firebase_core"],"dev_dependency":false},{"name":"flutter_plugin_android_lifecycle","path":"/Users/venbateam/.pub-cache/hosted/pub.dev/flutter_plugin_android_lifecycle-2.0.31/","native_build":true,"dependencies":[],"dev_dependency":false},{"name":"flutter_secure_storage","path":"/Users/venbateam/.pub-cache/hosted/pub.dev/flutter_secure_storage-9.2.4/","native_build":true,"dependencies":[],"dev_dependency":false},{"name":"fluttertoast","path":"/Users/venbateam/.pub-cache/hosted/pub.dev/fluttertoast-9.0.0/","native_build":true,"dependencies":[],"dev_dependency":false},{"name":"google_sign_in_android","path":"/Users/venbateam/.pub-cache/hosted/pub.dev/google_sign_in_android-7.2.1/","native_build":true,"dependencies":[],"dev_dependency":false},{"name":"local_auth_android","path":"/Users/venbateam/.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":"/Users/venbateam/.pub-cache/hosted/pub.dev/open_file_android-1.0.6/","native_build":true,"dependencies":[],"dev_dependency":false},{"name":"package_info_plus","path":"/Users/venbateam/.pub-cache/hosted/pub.dev/package_info_plus-8.3.1/","native_build":true,"dependencies":[],"dev_dependency":false},{"name":"path_provider_android","path":"/Users/venbateam/.pub-cache/hosted/pub.dev/path_provider_android-2.2.19/","native_build":true,"dependencies":[],"dev_dependency":false},{"name":"pdf_render","path":"/Users/venbateam/.pub-cache/hosted/pub.dev/pdf_render-1.4.12/","native_build":true,"dependencies":[],"dev_dependency":false},{"name":"shared_preferences_android","path":"/Users/venbateam/.pub-cache/hosted/pub.dev/shared_preferences_android-2.4.13/","native_build":true,"dependencies":[],"dev_dependency":false},{"name":"syncfusion_flutter_pdfviewer","path":"/Users/venbateam/.pub-cache/hosted/pub.dev/syncfusion_flutter_pdfviewer-31.1.19/","native_build":true,"dependencies":["device_info_plus"],"dev_dependency":false},{"name":"url_launcher_android","path":"/Users/venbateam/.pub-cache/hosted/pub.dev/url_launcher_android-6.3.20/","native_build":true,"dependencies":[],"dev_dependency":false}],"macos":[{"name":"connectivity_plus","path":"/Users/venbateam/.pub-cache/hosted/pub.dev/connectivity_plus-6.1.5/","native_build":true,"dependencies":[],"dev_dependency":false},{"name":"device_info_plus","path":"/Users/venbateam/.pub-cache/hosted/pub.dev/device_info_plus-11.5.0/","native_build":true,"dependencies":[],"dev_dependency":false},{"name":"file_picker","path":"/Users/venbateam/.pub-cache/hosted/pub.dev/file_picker-10.3.7/","native_build":true,"dependencies":[],"dev_dependency":false},{"name":"firebase_auth","path":"/Users/venbateam/.pub-cache/hosted/pub.dev/firebase_auth-6.1.2/","native_build":true,"dependencies":["firebase_core"],"dev_dependency":false},{"name":"firebase_core","path":"/Users/venbateam/.pub-cache/hosted/pub.dev/firebase_core-4.2.1/","native_build":true,"dependencies":[],"dev_dependency":false},{"name":"firebase_messaging","path":"/Users/venbateam/.pub-cache/hosted/pub.dev/firebase_messaging-16.0.4/","native_build":true,"dependencies":["firebase_core"],"dev_dependency":false},{"name":"flutter_secure_storage_macos","path":"/Users/venbateam/.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":"/Users/venbateam/.pub-cache/hosted/pub.dev/google_sign_in_ios-6.2.1/","shared_darwin_source":true,"native_build":true,"dependencies":[],"dev_dependency":false},{"name":"local_auth_darwin","path":"/Users/venbateam/.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":"/Users/venbateam/.pub-cache/hosted/pub.dev/open_file_mac-1.0.3/","native_build":true,"dependencies":[],"dev_dependency":false},{"name":"package_info_plus","path":"/Users/venbateam/.pub-cache/hosted/pub.dev/package_info_plus-8.3.1/","native_build":true,"dependencies":[],"dev_dependency":false},{"name":"path_provider_foundation","path":"/Users/venbateam/.pub-cache/hosted/pub.dev/path_provider_foundation-2.4.2/","shared_darwin_source":true,"native_build":true,"dependencies":[],"dev_dependency":false},{"name":"pdf_render","path":"/Users/venbateam/.pub-cache/hosted/pub.dev/pdf_render-1.4.12/","native_build":true,"dependencies":[],"dev_dependency":false},{"name":"shared_preferences_foundation","path":"/Users/venbateam/.pub-cache/hosted/pub.dev/shared_preferences_foundation-2.5.4/","shared_darwin_source":true,"native_build":true,"dependencies":[],"dev_dependency":false},{"name":"syncfusion_pdfviewer_macos","path":"/Users/venbateam/.pub-cache/hosted/pub.dev/syncfusion_pdfviewer_macos-31.1.19/","native_build":true,"dependencies":[],"dev_dependency":false},{"name":"url_launcher_macos","path":"/Users/venbateam/.pub-cache/hosted/pub.dev/url_launcher_macos-3.2.3/","native_build":true,"dependencies":[],"dev_dependency":false}],"linux":[{"name":"connectivity_plus","path":"/Users/venbateam/.pub-cache/hosted/pub.dev/connectivity_plus-6.1.5/","native_build":false,"dependencies":[],"dev_dependency":false},{"name":"device_info_plus","path":"/Users/venbateam/.pub-cache/hosted/pub.dev/device_info_plus-11.5.0/","native_build":false,"dependencies":[],"dev_dependency":false},{"name":"file_picker","path":"/Users/venbateam/.pub-cache/hosted/pub.dev/file_picker-10.3.7/","native_build":false,"dependencies":[],"dev_dependency":false},{"name":"flutter_secure_storage_linux","path":"/Users/venbateam/.pub-cache/hosted/pub.dev/flutter_secure_storage_linux-1.2.3/","native_build":true,"dependencies":[],"dev_dependency":false},{"name":"open_file_linux","path":"/Users/venbateam/.pub-cache/hosted/pub.dev/open_file_linux-0.0.5/","native_build":true,"dependencies":[],"dev_dependency":false},{"name":"package_info_plus","path":"/Users/venbateam/.pub-cache/hosted/pub.dev/package_info_plus-8.3.1/","native_build":false,"dependencies":[],"dev_dependency":false},{"name":"path_provider_linux","path":"/Users/venbateam/.pub-cache/hosted/pub.dev/path_provider_linux-2.2.1/","native_build":false,"dependencies":[],"dev_dependency":false},{"name":"shared_preferences_linux","path":"/Users/venbateam/.pub-cache/hosted/pub.dev/shared_preferences_linux-2.4.1/","native_build":false,"dependencies":["path_provider_linux"],"dev_dependency":false},{"name":"syncfusion_pdfviewer_linux","path":"/Users/venbateam/.pub-cache/hosted/pub.dev/syncfusion_pdfviewer_linux-31.1.19/","native_build":true,"dependencies":[],"dev_dependency":false},{"name":"url_launcher_linux","path":"/Users/venbateam/.pub-cache/hosted/pub.dev/url_launcher_linux-3.2.2/","native_build":true,"dependencies":[],"dev_dependency":false}],"windows":[{"name":"connectivity_plus","path":"/Users/venbateam/.pub-cache/hosted/pub.dev/connectivity_plus-6.1.5/","native_build":true,"dependencies":[],"dev_dependency":false},{"name":"device_info_plus","path":"/Users/venbateam/.pub-cache/hosted/pub.dev/device_info_plus-11.5.0/","native_build":false,"dependencies":[],"dev_dependency":false},{"name":"file_picker","path":"/Users/venbateam/.pub-cache/hosted/pub.dev/file_picker-10.3.7/","native_build":false,"dependencies":[],"dev_dependency":false},{"name":"firebase_auth","path":"/Users/venbateam/.pub-cache/hosted/pub.dev/firebase_auth-6.1.2/","native_build":true,"dependencies":["firebase_core"],"dev_dependency":false},{"name":"firebase_core","path":"/Users/venbateam/.pub-cache/hosted/pub.dev/firebase_core-4.2.1/","native_build":true,"dependencies":[],"dev_dependency":false},{"name":"flutter_secure_storage_windows","path":"/Users/venbateam/.pub-cache/hosted/pub.dev/flutter_secure_storage_windows-3.1.2/","native_build":true,"dependencies":[],"dev_dependency":false},{"name":"local_auth_windows","path":"/Users/venbateam/.pub-cache/hosted/pub.dev/local_auth_windows-1.0.11/","native_build":true,"dependencies":[],"dev_dependency":false},{"name":"open_file_windows","path":"/Users/venbateam/.pub-cache/hosted/pub.dev/open_file_windows-0.0.3/","native_build":false,"dependencies":[],"dev_dependency":false},{"name":"package_info_plus","path":"/Users/venbateam/.pub-cache/hosted/pub.dev/package_info_plus-8.3.1/","native_build":false,"dependencies":[],"dev_dependency":false},{"name":"path_provider_windows","path":"/Users/venbateam/.pub-cache/hosted/pub.dev/path_provider_windows-2.3.0/","native_build":false,"dependencies":[],"dev_dependency":false},{"name":"shared_preferences_windows","path":"/Users/venbateam/.pub-cache/hosted/pub.dev/shared_preferences_windows-2.4.1/","native_build":false,"dependencies":["path_provider_windows"],"dev_dependency":false},{"name":"syncfusion_pdfviewer_windows","path":"/Users/venbateam/.pub-cache/hosted/pub.dev/syncfusion_pdfviewer_windows-31.1.19/","native_build":true,"dependencies":[],"dev_dependency":false},{"name":"url_launcher_windows","path":"/Users/venbateam/.pub-cache/hosted/pub.dev/url_launcher_windows-3.1.5/","native_build":true,"dependencies":[],"dev_dependency":false}],"web":[{"name":"connectivity_plus","path":"/Users/venbateam/.pub-cache/hosted/pub.dev/connectivity_plus-6.1.5/","dependencies":[],"dev_dependency":false},{"name":"device_info_plus","path":"/Users/venbateam/.pub-cache/hosted/pub.dev/device_info_plus-11.5.0/","dependencies":[],"dev_dependency":false},{"name":"file_picker","path":"/Users/venbateam/.pub-cache/hosted/pub.dev/file_picker-10.3.7/","dependencies":[],"dev_dependency":false},{"name":"firebase_auth_web","path":"/Users/venbateam/.pub-cache/hosted/pub.dev/firebase_auth_web-6.1.0/","dependencies":["firebase_core_web"],"dev_dependency":false},{"name":"firebase_core_web","path":"/Users/venbateam/.pub-cache/hosted/pub.dev/firebase_core_web-3.3.0/","dependencies":[],"dev_dependency":false},{"name":"firebase_messaging_web","path":"/Users/venbateam/.pub-cache/hosted/pub.dev/firebase_messaging_web-4.1.0/","dependencies":["firebase_core_web"],"dev_dependency":false},{"name":"flutter_secure_storage_web","path":"/Users/venbateam/.pub-cache/hosted/pub.dev/flutter_secure_storage_web-1.2.1/","dependencies":[],"dev_dependency":false},{"name":"fluttertoast","path":"/Users/venbateam/.pub-cache/hosted/pub.dev/fluttertoast-9.0.0/","dependencies":[],"dev_dependency":false},{"name":"google_sign_in_web","path":"/Users/venbateam/.pub-cache/hosted/pub.dev/google_sign_in_web-1.1.0/","dependencies":[],"dev_dependency":false},{"name":"open_file_web","path":"/Users/venbateam/.pub-cache/hosted/pub.dev/open_file_web-0.0.4/","dependencies":[],"dev_dependency":false},{"name":"package_info_plus","path":"/Users/venbateam/.pub-cache/hosted/pub.dev/package_info_plus-8.3.1/","dependencies":[],"dev_dependency":false},{"name":"pdf_render","path":"/Users/venbateam/.pub-cache/hosted/pub.dev/pdf_render-1.4.12/","dependencies":[],"dev_dependency":false},{"name":"shared_preferences_web","path":"/Users/venbateam/.pub-cache/hosted/pub.dev/shared_preferences_web-2.4.3/","dependencies":[],"dev_dependency":false},{"name":"syncfusion_pdfviewer_web","path":"/Users/venbateam/.pub-cache/hosted/pub.dev/syncfusion_pdfviewer_web-31.1.19/","dependencies":[],"dev_dependency":false},{"name":"url_launcher_web","path":"/Users/venbateam/.pub-cache/hosted/pub.dev/url_launcher_web-2.4.1/","dependencies":[],"dev_dependency":false}]},"dependencyGraph":[{"name":"connectivity_plus","dependencies":[]},{"name":"device_info_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":"pdf_render","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":"syncfusion_flutter_pdfviewer","dependencies":["url_launcher","device_info_plus","syncfusion_pdfviewer_web","syncfusion_pdfviewer_macos","syncfusion_pdfviewer_windows","syncfusion_pdfviewer_linux"]},{"name":"syncfusion_pdfviewer_linux","dependencies":[]},{"name":"syncfusion_pdfviewer_macos","dependencies":[]},{"name":"syncfusion_pdfviewer_web","dependencies":[]},{"name":"syncfusion_pdfviewer_windows","dependencies":[]},{"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":"2026-04-06 15:58:42.611708","version":"3.35.7","swift_package_manager_enabled":{"ios":false,"macos":false}} \ No newline at end of file diff --git a/lib/presentation/layouts/appheader.dart b/lib/presentation/layouts/appheader.dart index 1cd2181..b76b05f 100644 --- a/lib/presentation/layouts/appheader.dart +++ b/lib/presentation/layouts/appheader.dart @@ -374,7 +374,7 @@ class _AppHeaderState extends ConsumerState { ), const SizedBox(height: 2), _buildPopupItem( - label: "Payout upload", + label: "Payout Upload", onTap: () { _hidePopup(); setState(() => _activeMenu = 'PayoutUpload'); diff --git a/lib/presentation/screens/Enquiry/enquiryList.dart b/lib/presentation/screens/Enquiry/enquiryList.dart index 1f0adac..fae9cd3 100644 --- a/lib/presentation/screens/Enquiry/enquiryList.dart +++ b/lib/presentation/screens/Enquiry/enquiryList.dart @@ -14,7 +14,6 @@ import '../../../data/utils/validators.dart'; import '../../layouts/main_layout.dart'; import '../../layouts/responsive_layout.dart'; import '../../providers/manager_provider.dart'; -import '../../themes/indicators/date_field_theme.dart'; import '../../themes/indicators/export_btn.dart'; import '../../themes/indicators/search_field_theme.dart'; import '../../widgets/custom_Stdate_EnDate_Filter.dart'; @@ -1077,77 +1076,6 @@ class EnquiryListState extends ConsumerState { ); } - Widget buildStartDate(BuildContext context) { - return Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text('Start Date', style: _textStyle), - SizedBox(height: 5), - ThemedDateField( - hintText: "Select Date", - txtwidth: ResponsiveLayout.isMobile(context) - ? null - : MediaQuery.of(context).size.width * 0.16, - // txtheight: 50, - // backgroundColor: const Color(0xFFECECEC), - // validator: (value) => Validators.requiredField(value, "date"), - controller: controllers['startDate']!, - onDateSelected: (date) { - print("SPicked Date: $date"); - - controllers['startDate']?.text = DateFormat( - 'dd-MM-yyyy', - ).format(date); - // controllers['date']?.text = date as String; - }, - ), - ], - ); - } - - Widget buildEndDate(BuildContext context) { - return Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text('End Date', style: _textStyle), - SizedBox(height: 5), - ThemedDateField( - hintText: "Select Date", - txtwidth: ResponsiveLayout.isMobile(context) - ? null - : MediaQuery.of(context).size.width * 0.16, - // txtheight: 50, - // backgroundColor: const Color(0xFFECECEC), - validator: (value) { - if (value == null || value.isEmpty) { - return "End Date is required"; - } - - final fromText = controllers['startDate']?.text ?? ''; - if (fromText.isNotEmpty) { - final startDate = DateFormat('dd-MM-yyyy').parse(fromText); - final endDate = DateFormat('dd-MM-yyyy').parse(value); - - if (endDate.isBefore(startDate)) { - return "End Date cannot be earlier than Start Date"; - } - } - return null; // ✅ no error - }, - controller: controllers['endDate']!, - lastDate: DateTime.now(), - onDateSelected: (date) { - print("EPicked Date: $date"); - controllers['endDate']?.text = DateFormat( - 'dd-MM-yyyy', - ).format(date); - // controllers['date']?.text = date as String; - }, - ), - ], - ); - } - static final _dataBold = GoogleFonts.inter( fontSize: 12, @@ -1186,9 +1114,4 @@ class EnquiryListState extends ConsumerState { fontWeight: FontWeight.w400, fontSize: 12, ); - - static const _textStyle = TextStyle( - fontSize: 12, - fontWeight: FontWeight.w600, - ); } diff --git a/lib/presentation/screens/Enquiry/policy_claims_endros/endrosment.dart b/lib/presentation/screens/Enquiry/policy_claims_endros/endrosment.dart index 9df7d45..f47a58d 100644 --- a/lib/presentation/screens/Enquiry/policy_claims_endros/endrosment.dart +++ b/lib/presentation/screens/Enquiry/policy_claims_endros/endrosment.dart @@ -15,7 +15,7 @@ import '../../../layouts/main_layout.dart'; import '../../../layouts/responsive_layout.dart'; import '../../../providers/manager_provider.dart'; import '../../../themes/indicators/customizd_file_upload.dart'; -import '../../../themes/indicators/date_field_theme.dart'; +import '../../../themes/indicators/date_range_picker_field.dart'; import '../../../themes/indicators/export_btn.dart'; import '../../../themes/indicators/input_field_decoration.dart'; import '../../../themes/indicators/search_field_theme.dart'; @@ -795,10 +795,7 @@ class endosementState extends ConsumerState { scrollDirection: Axis.horizontal, child: Row( children: [ - buildStartDate(context), - const SizedBox(width: 12), - - buildEndDate(context), + buildDateRangeFilter(context), const SizedBox(width: 12), buildEndorsementTypeSearch(context), @@ -1448,38 +1445,20 @@ class endosementState extends ConsumerState { ); } - Widget buildStartDate(BuildContext context) { + Widget buildDateRangeFilter(BuildContext context) { return SizedBox( height: 36, width: ResponsiveLayout.isMobile(context) ? null - : MediaQuery.of(context).size.width * 0.10, - child: ThemedDateField( - hintText: "Start Date", - controller: startController, - onDateSelected: (date) { - startController.text = - DateFormat('dd-MM-yyyy').format(date); - }, - ), - ); - } - - Widget buildEndDate(BuildContext context) { - return SizedBox( - height: 36, - width: ResponsiveLayout.isMobile(context) - ? null - : MediaQuery.of(context).size.width * 0.10, - child: ThemedDateField( - hintText: "End Date", - controller: endController, + : MediaQuery.of(context).size.width * 0.15, + child: DateRangePickerField( + startController: startController, + endController: endController, + hintText: 'Select date range', + showLabelAboveField: false, + txtheight: 36, lastDate: DateTime.now(), - onDateSelected: (date) { - endController.text = - DateFormat('dd-MM-yyyy').format(date); - // refresh(); - }, + useFormField: false, ), ); } diff --git a/lib/presentation/screens/Grid/gridView.dart b/lib/presentation/screens/Grid/gridView.dart index 5ce8559..984037f 100644 --- a/lib/presentation/screens/Grid/gridView.dart +++ b/lib/presentation/screens/Grid/gridView.dart @@ -4388,42 +4388,6 @@ Expanded( ); } - Widget buildStartDate(BuildContext context) { - return SizedBox( - height: 36, - width: ResponsiveLayout.isMobile(context) - ? null - : MediaQuery.of(context).size.width * 0.10, - child: ThemedDateField( - hintText: "Start Date", - controller: startController, - onDateSelected: (date) { - startController.text = - DateFormat('dd-MM-yyyy').format(date); - }, - ), - ); - } - - Widget buildEndDate(BuildContext context) { - return SizedBox( - height: 36, - width: ResponsiveLayout.isMobile(context) - ? null - : MediaQuery.of(context).size.width * 0.10, - child: ThemedDateField( - hintText: "End Date", - controller: endController, - lastDate: DateTime.now(), - onDateSelected: (date) { - endController.text = - DateFormat('dd-MM-yyyy').format(date); - // refresh(); - }, - ), - ); - } - Widget buildRTOSearch(BuildContext context) { final List> endorsementOptions = List>.from(filteredEndrosmentData); diff --git a/lib/presentation/screens/Masters/VehicleType/vehicleList.dart b/lib/presentation/screens/Masters/VehicleType/vehicleList.dart index fc3441d..c4a11b7 100644 --- a/lib/presentation/screens/Masters/VehicleType/vehicleList.dart +++ b/lib/presentation/screens/Masters/VehicleType/vehicleList.dart @@ -286,7 +286,9 @@ class VehicleTypeListState extends ConsumerState { ), Expanded( flex: 2, - child: Text('Action', style: _headerStyle), + child: Center( + child: Text('Action', style: _headerStyle), + ), ), ], ), @@ -415,38 +417,34 @@ class VehicleTypeListState extends ConsumerState { ), Expanded( flex: 2, - child: Center( // Add Center wrapper - child: Row( - mainAxisSize: MainAxisSize.min, // Add this - children: [ - item['is_active'] == "1" - ? Tooltip( - message: 'Edit', - child: IconButton( - icon: Image.asset( - "assets/miscellaneous/Edit.png", + child: Align( + alignment: Alignment.center, + child: item['is_active'] == "1" + ? Tooltip( + message: 'Edit', + child: IconButton( + icon: Image.asset( + "assets/miscellaneous/Edit.png", + height: 12, + width: 15, + ), + onPressed: () { + handleEdit(item); + }, + splashRadius: 20, + hoverColor: Colors.black12, + padding: const EdgeInsets.all(8), + constraints: const BoxConstraints(), + ), + ) + : Padding( + padding: const EdgeInsets.all(8.0), + child: Image.asset( + "assets/miscellaneous/Edit_muted.png", height: 12, width: 15, ), - onPressed: () { - handleEdit(item); - }, - splashRadius: 28, - hoverColor: Colors.black12, - padding: const EdgeInsets.all(8), - constraints: const BoxConstraints(), ), - ) - : Padding( - padding: const EdgeInsets.all(8.0), // Match IconButton padding - child: Image.asset( - "assets/miscellaneous/Edit_muted.png", - height: 12, - width: 15, - ), - ), - ], - ), ), ), ], diff --git a/lib/presentation/screens/dashboard/partner_portal_dashboard.dart b/lib/presentation/screens/dashboard/partner_portal_dashboard.dart index 558c7c3..563d4f6 100644 --- a/lib/presentation/screens/dashboard/partner_portal_dashboard.dart +++ b/lib/presentation/screens/dashboard/partner_portal_dashboard.dart @@ -427,7 +427,10 @@ class _RenewalAlertsCard extends StatelessWidget { }); @override - Widget build(BuildContext context) => _DashCard( + Widget build(BuildContext context) { + final visibleRowCount = renewals.length.clamp(1, kVisibleRows); + final listHeight = visibleRowCount * kRowHeight; + return _DashCard( header: Row(children: [ Container( width: 30, @@ -519,7 +522,7 @@ class _RenewalAlertsCard extends StatelessWidget { ), ), SizedBox( - height: kVisibleRows * kRowHeight, + height: listHeight, child: ListView.separated( physics: const ClampingScrollPhysics(), itemCount: renewals.length, @@ -534,6 +537,7 @@ class _RenewalAlertsCard extends StatelessWidget { ], ), ); + } } class _RenewalTableRow extends StatelessWidget { diff --git a/lib/presentation/screens/payout/custom_dateRange.dart b/lib/presentation/screens/payout/custom_dateRange.dart index 5715d26..f95a426 100644 --- a/lib/presentation/screens/payout/custom_dateRange.dart +++ b/lib/presentation/screens/payout/custom_dateRange.dart @@ -1,14 +1,16 @@ +import 'dart:math' show min; + import 'package:dropdown_search/dropdown_search.dart'; import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:google_fonts/google_fonts.dart'; -import 'package:intl/intl.dart'; +import 'package:nhance_partner/data/utils/toastNotification.dart'; import '../../../core/services/api_service.dart'; import '../../layouts/responsive_layout.dart'; import '../../providers/manager_provider.dart'; import '../../providers/userRoleProvider.dart'; -import '../../themes/indicators/date_field_theme.dart'; +import '../../themes/indicators/date_range_picker_field.dart'; import '../../themes/indicators/input_field_decoration.dart'; class DateFilterRowPayout extends ConsumerStatefulWidget { @@ -28,6 +30,13 @@ class DateFilterRowPayout extends ConsumerStatefulWidget { final role; final id; + /// When non-null, toggles filter layout for payout details: + /// - `false` — no table rows: show date range only (hide partner + actions). + /// - `true` — table has rows: show partner (+ broker if [showBrokerFilter]) and + /// search/reset aligned to the right; hide date range. + /// When `null`, legacy: date range and partner row together. + final bool? policyTableHasRows; + const DateFilterRowPayout({ super.key, this.showBrokerFilter = true, @@ -45,6 +54,7 @@ class DateFilterRowPayout extends ConsumerStatefulWidget { required this.id, this.isMobile = false, this.dataFrom, + this.policyTableHasRows, }); @override @@ -224,28 +234,17 @@ class _DateFilterRowState extends ConsumerState { final spacing = 5.0; List getRowChildren(bool isMobile, double spacing) { - final dateFields = [ - buildStartDate(context), - SizedBox(width: spacing), - buildEndDate(context), - SizedBox(width: spacing), - if (widget.showBrokerFilter) ...[ - buildBroker(context), - SizedBox(width: spacing), - ], - buildPartner(context), - SizedBox(width: spacing), - ]; + final hasDateRange = widget.startController.text.trim().isNotEmpty && + widget.endController.text.trim().isNotEmpty; + + double partnerMaxWidth() { + final sw = MediaQuery.sizeOf(context).width; + return min(sw * 0.32, 420); + } final buttons = [ Padding( padding: const EdgeInsets.symmetric(vertical: 0.0), - // child: GestureDetector( - // onTap: () { - // if (formKey.currentState!.validate()) onFilter(); - // }, - // child: Icon(Icons.filter_alt_outlined), - // ), child: Tooltip( message: 'Filter', child: IconButton( @@ -254,18 +253,26 @@ class _DateFilterRowState extends ConsumerState { size: 18, color: const Color(0xFF94A3B8), ), - onPressed: () { - if (widget.formKey.currentState!.validate()) { - widget.onFilter(); + if (widget.formKey.currentState?.validate() != true) return; + final partners = widget.selectedParnter; + final hasPartner = partners != null && + partners.isNotEmpty && + partners.any((e) => e.toString().trim().isNotEmpty); + if (!hasPartner) { + ToastHelper.showWarningToast( + context, + 'Please select a partner before searching.', + ); + return; } + widget.onFilter(); }, ), ), ), Padding( padding: const EdgeInsets.all(0.0), - // child: GestureDetector(onTap: onRefresh, child: Icon(Icons.refresh)), child: Tooltip( message: 'Refresh', child: IconButton( @@ -280,17 +287,38 @@ class _DateFilterRowState extends ConsumerState { ), ]; - if (isMobile) { - // For mobile: buttons below fields - return [ - ...dateFields, - SizedBox(height: 10), - Row(mainAxisAlignment: MainAxisAlignment.end, children: buttons), - ]; - } else { - // For desktop: buttons inline with fields - return [...dateFields, Spacer(), ...buttons]; + final partnerActionsRow = [ + if (widget.showBrokerFilter) ...[ + buildBroker(context), + SizedBox(width: spacing), + ], + buildPartner(context, maxWidth: partnerMaxWidth()), + SizedBox(width: spacing), + ...buttons, + ]; + + if (!hasDateRange) { + return [buildDateRangeFilter(context)]; } + + if (isMobile) { + return [ + buildDateRangeFilter(context), + const SizedBox(height: 10), + Wrap( + spacing: spacing, + runSpacing: 8, + crossAxisAlignment: WrapCrossAlignment.end, + children: partnerActionsRow, + ), + ]; + } + return [ + buildDateRangeFilter(context), + SizedBox(width: spacing), + Spacer(), + ...partnerActionsRow, + ]; } return Form( @@ -309,78 +337,19 @@ class _DateFilterRowState extends ConsumerState { ); } - Widget buildStartDate(BuildContext context) { - return Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text('Start Date *', style: _textStyle), - SizedBox(height: 5), - SizedBox( - height: 35, - child: ThemedDateField( - hintText: "Select Date", - txtwidth: ResponsiveLayout.isMobile(context) - ? null - : MediaQuery.of(context).size.width * 0.15, - // txtheight: 50, - // backgroundColor: const Color(0xFFECECEC), - // validator: (value) => Validators.requiredField(value, "date"), - controller: widget.startController, - onDateSelected: (date) { - print("Picked Date: $date"); - widget.startController.text = DateFormat( - 'dd-MM-yyyy', - ).format(date); - // controllers['date']?.text = date as String; - Future.microtask(() => widget.onFilter()); - }, - ), - ), - ], - ); - } - - Widget buildEndDate(BuildContext context) { - return Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text('End Date *', style: _textStyle), - SizedBox(height: 5), - SizedBox( - height: 35, - child: ThemedDateField( - hintText: "Select Date", - txtwidth: ResponsiveLayout.isMobile(context) - ? null - : MediaQuery.of(context).size.width * 0.15, - // txtheight: 50, - // backgroundColor: const Color(0xFFECECEC), - validator: (value) { - final fromText = widget.startController.text ?? ''; - if (fromText.isNotEmpty) { - final startDate = DateFormat('dd-MM-yyyy').parse(fromText); - if (value == null || value.isEmpty) { - return "End Date is required"; - } - final endDate = DateFormat('dd-MM-yyyy').parse(value); - - if (endDate.isBefore(startDate)) { - return "End Date cannot be earlier than Start Date"; - } - } - return null; // ✅ no error - }, - controller: widget.endController, - // lastDate: DateTime.now(), - onDateSelected: (date) { - print("Picked Date: $date"); - widget.endController.text = DateFormat('dd-MM-yyyy').format(date); - Future.microtask(() => widget.onFilter()); - // controllers['date']?.text = date as String; - }, - ), - ), - ], + Widget buildDateRangeFilter(BuildContext context) { + final w = ResponsiveLayout.isMobile(context) + ? null + : MediaQuery.of(context).size.width * 0.15; + return DateRangePickerField( + startController: widget.startController, + endController: widget.endController, + hintText: 'Select date range', + txtwidth: w, + txtheight: 32, + lastDate: DateTime.now(), + rangeValidator: DateRangePickerField.defaultFilterValidator, + onRangeSelected: (_) => Future.microtask(() => widget.onFilter()), ); } @@ -555,8 +524,8 @@ class _DateFilterRowState extends ConsumerState { ); } - Widget buildPartner(BuildContext context) { - final isReadOnly = false; + Widget buildPartner(BuildContext context, {double? maxWidth}) { + final w = maxWidth ?? MediaQuery.of(context).size.width * 0.4; return Column( crossAxisAlignment: CrossAxisAlignment.start, @@ -565,7 +534,7 @@ class _DateFilterRowState extends ConsumerState { SizedBox(height: 5), SizedBox( height: 35, - width: MediaQuery.of(context).size.width * 0.4, + width: w, child: DropdownSearch>.multiSelection( key: dropDownKeyPartner, @@ -591,6 +560,28 @@ class _DateFilterRowState extends ConsumerState { "${val['agent_name']} | ${val['unused_commission_amount']} (${val['total_policies']})", compareFn: (item, selectedItem) => item['agent_id'] == selectedItem['agent_id'], // ✅ compare by id + dropdownBuilder: (context, selectedItems) { + final safeItems = selectedItems; + final text = safeItems.isEmpty + ? 'Select Partner' + : safeItems.length == 1 + ? "${safeItems.first['agent_name']} | ${safeItems.first['unused_commission_amount']} (${safeItems.first['total_policies']})" + : '${safeItems.length} partners selected'; + return Align( + alignment: Alignment.centerLeft, + child: Text( + text, + style: GoogleFonts.inter( + fontSize: 12, + color: safeItems.isEmpty + ? const Color(0xFF64748B) + : Colors.black, + ), + maxLines: 1, + overflow: TextOverflow.ellipsis, + ), + ); + }, // validator: (val) { // if (val == null) { // return "Required"; // ✅ error message @@ -612,8 +603,9 @@ class _DateFilterRowState extends ConsumerState { decoratorProps: DropDownDecoratorProps( decoration: AppInputDecorations.dropdownDecoration( - label: "Select Partner", + label: "", ).copyWith( + hintText: null, hintStyle: GoogleFonts.inter( fontSize: 12, color: Colors.black, diff --git a/lib/presentation/screens/payout/payout_details.dart b/lib/presentation/screens/payout/payout_details.dart index fd0b252..53414bc 100644 --- a/lib/presentation/screens/payout/payout_details.dart +++ b/lib/presentation/screens/payout/payout_details.dart @@ -5,13 +5,16 @@ import 'package:go_router/go_router.dart'; import 'package:google_fonts/google_fonts.dart'; import 'package:intl/intl.dart'; import 'package:nhance_partner/data/utils/toastNotification.dart'; +import 'dart:math' show max; +import '../../../data/utils/Pagination.dart'; import '../../../core/routing/routes.dart'; import '../../../core/services/api_service.dart'; import '../../layouts/main_layout.dart'; import '../../layouts/responsive_layout.dart'; import '../../providers/manager_provider.dart'; import '../../providers/userRoleProvider.dart'; +import '../../themes/indicators/export_btn.dart'; import 'custom_dateRange.dart'; class PayOutDetails extends ConsumerStatefulWidget { @@ -92,6 +95,8 @@ class _PayOutDetailsState extends ConsumerState { bool isLoading = false; bool hasFetchedTableData = false; + int currentPage = 1; + int itemsPerPage = 10; final Set _inlineSavingIds = {}; /// Per-policy payout editors so [setState] rebuilds do not reset focus/text. final Map _commissionControllers = {}; @@ -184,6 +189,7 @@ class _PayOutDetailsState extends ConsumerState { return TextFormField( key: fieldKey, controller: controller, + textAlign: TextAlign.right, style: fieldStyle, keyboardType: const TextInputType.numberWithOptions(decimal: true), inputFormatters: _commissionInputFormatter, @@ -195,6 +201,7 @@ class _PayOutDetailsState extends ConsumerState { return TextFormField( key: fieldKey, initialValue: (p["commission_amount"] ?? '').toString(), + textAlign: TextAlign.right, style: fieldStyle, keyboardType: const TextInputType.numberWithOptions(decimal: true), inputFormatters: _commissionInputFormatter, @@ -206,6 +213,9 @@ class _PayOutDetailsState extends ConsumerState { @override void dispose() { + for (final controller in controllers.values) { + controller.dispose(); + } _disposeCommissionControllers(); super.dispose(); } @@ -217,6 +227,7 @@ class _PayOutDetailsState extends ConsumerState { print('PD => filteredPolicies1 - $filteredPolicies'); setState(() { + currentPage = 1; if (query.trim().isEmpty) { print('PD => filteredPolicies2'); filteredPolicies = List.from(masterPolicies); @@ -253,7 +264,6 @@ class _PayOutDetailsState extends ConsumerState { setState(() { for (var controller in controllers.values) { controller.clear(); - controller.dispose(); } selectedBrokerID = ''; @@ -262,6 +272,7 @@ class _PayOutDetailsState extends ConsumerState { totalPolicies = ''; totalCommission = ''; filteredPolicies = []; + currentPage = 1; _disposeCommissionControllers(); hasFetchedTableData = false; // dropDownKeyPartner.currentState?.clear(); @@ -380,8 +391,9 @@ class _PayOutDetailsState extends ConsumerState { hasFetchedTableData = false; }); try { - final List agentIds = (selectedAgentId ?? []) - .map((e) => int.parse(e)) + final List agentIds = (selectedAgentId ?? []) + .map((e) => e.toString().trim()) + .where((e) => e.isNotEmpty) .toList(); final jsondata = { @@ -400,6 +412,7 @@ class _PayOutDetailsState extends ConsumerState { filteredPolicies = List>.from(response['data']); _rebuildCommissionControllers(filteredPolicies); hasFetchedTableData = true; + currentPage = 1; print('PD =>API Data - $filteredPolicies'); // filteredPolicies = allPolicies.where((p) { // if (p["agentId"] != selectedAgentId) return false; @@ -414,6 +427,7 @@ class _PayOutDetailsState extends ConsumerState { filteredPolicies = []; _rebuildCommissionControllers(filteredPolicies); hasFetchedTableData = true; + currentPage = 1; }); } } catch (e) { @@ -422,6 +436,7 @@ class _PayOutDetailsState extends ConsumerState { filteredPolicies = []; _rebuildCommissionControllers(filteredPolicies); hasFetchedTableData = false; + currentPage = 1; }); } finally { setState(() { @@ -450,13 +465,13 @@ class _PayOutDetailsState extends ConsumerState { // Save invoice (simulation) Future saveInvoice() async { try { - if (selectedAgentId == null) { - ToastHelper.showWarningToast( - context, - "Please select a partner before saving.", - ); - return; - } + // if (selectedAgentId == null) { + // ToastHelper.showWarningToast( + // context, + // "Please select a partner before saving.", + // ); + // return; + // } if (selectedPolicies.isEmpty) { ToastHelper.showWarningToast( @@ -848,6 +863,30 @@ class _PayOutDetailsState extends ConsumerState { ), ), const SizedBox(width: 10), + ExportBtn( + sheetName: 'Payout Details', + fileName: + 'payout_details_${DateFormat('yyyyMMdd_HHmmss').format(DateTime.now())}', + data: _exportRows, + displayHeaders: const [ + 'S.NO', + 'POLICY NO', + 'POLICY DATE', + 'PARTNER', + 'CUSTOMER', + 'PREMIUM (₹)', + 'PAYOUT (₹)', + ], + keys: const [ + 'sno', + 'policy_no', + 'policy_date', + 'partner', + 'customer', + 'premium', + 'payout', + ], + ), ], ], ), @@ -863,6 +902,7 @@ class _PayOutDetailsState extends ConsumerState { role: roleId, id: userId, showBrokerFilter: false, + policyTableHasRows: filteredPolicies.isNotEmpty, selectedParnter: selectedAgentId, selectedBroker: selectedBrokerID, @@ -913,7 +953,10 @@ class _PayOutDetailsState extends ConsumerState { secondChild: SingleChildScrollView( scrollDirection: Axis.horizontal, child: SizedBox( - width: _tableMinWidth, + width: max( + _tableMinWidth, + MediaQuery.of(context).size.width - 32, + ), child: Column( children: [ _policyTableHeader(), // static header @@ -926,7 +969,6 @@ class _PayOutDetailsState extends ConsumerState { ], ), ), - if (selectedPolicies.isNotEmpty) ...[ Container( padding: const EdgeInsets.all(8), @@ -937,59 +979,59 @@ class _PayOutDetailsState extends ConsumerState { crossAxisAlignment: CrossAxisAlignment.start, children: [ // ---------------- SELECTED COUNT ---------------- - Row( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text( - // selectedPolicies.length.toString(), - totalPolicies, - style: GoogleFonts.poppins( - fontSize: 12, - fontWeight: FontWeight.w500, - color: Colors.blueGrey, - ), - ), - const SizedBox(width: 4), - Text( - "policies selected", - style: GoogleFonts.poppins( - fontSize: 12, - fontWeight: FontWeight.w500, - color: Colors.blueGrey, - ), - ), - const SizedBox(width: 4), - Text( - "|", - style: GoogleFonts.poppins( - fontSize: 12, - fontWeight: FontWeight.w500, - color: Colors.blueGrey, - ), - ), - const SizedBox(width: 4), - Text( - "Total Payout Amount", - style: GoogleFonts.poppins( - fontSize: 12, - fontWeight: FontWeight.w500, - color: Colors.blueGrey, - ), - ), - const SizedBox(width: 4), - - /// NULL-SAFE TOTAL COMMISSION CALCULATION - Text( - // "₹ ${_calculateTotalCommission()}", - "₹ $totalCommission", - style: GoogleFonts.poppins( - fontSize: 14, - fontWeight: FontWeight.w500, - color: Colors.teal, - ), - ), - ], - ), + // Row( + // crossAxisAlignment: CrossAxisAlignment.start, + // children: [ + // Text( + // // selectedPolicies.length.toString(), + // totalPolicies, + // style: GoogleFonts.poppins( + // fontSize: 12, + // fontWeight: FontWeight.w500, + // color: Colors.blueGrey, + // ), + // ), + // const SizedBox(width: 4), + // Text( + // "policies selected", + // style: GoogleFonts.poppins( + // fontSize: 12, + // fontWeight: FontWeight.w500, + // color: Colors.blueGrey, + // ), + // ), + // const SizedBox(width: 4), + // Text( + // "|", + // style: GoogleFonts.poppins( + // fontSize: 12, + // fontWeight: FontWeight.w500, + // color: Colors.blueGrey, + // ), + // ), + // const SizedBox(width: 4), + // Text( + // "Total Payout Amount", + // style: GoogleFonts.poppins( + // fontSize: 12, + // fontWeight: FontWeight.w500, + // color: Colors.blueGrey, + // ), + // ), + // const SizedBox(width: 4), + // + // /// NULL-SAFE TOTAL COMMISSION CALCULATION + // Text( + // // "₹ ${_calculateTotalCommission()}", + // "₹ $totalCommission", + // style: GoogleFonts.poppins( + // fontSize: 14, + // fontWeight: FontWeight.w500, + // color: Colors.teal, + // ), + // ), + // ], + // ), Spacer(), buildUTRNumber(context), @@ -1036,6 +1078,27 @@ class _PayOutDetailsState extends ConsumerState { ), ), ], + if (filteredPolicies.isNotEmpty) + Padding( + padding: const EdgeInsets.fromLTRB(8, 4, 8, 2), + child: Align( + alignment: Alignment.centerRight, + child: PaginationControls( + currentPage: currentPage, + itemsPerPage: itemsPerPage, + totalItems: filteredPolicies.length, + onPageChanged: (page) { + setState(() => currentPage = page); + }, + onItemsPerPageChanged: (items) { + setState(() { + itemsPerPage = items; + currentPage = 1; + }); + }, + ), + ), + ), // ---------------------- // const SizedBox(height: 100), ], @@ -1101,22 +1164,25 @@ class _PayOutDetailsState extends ConsumerState { }, ), ), + _headerText("S.NO", colSno, align: TextAlign.center), _headerText("POLICY NO", colPolicy), _headerText("POLICY DATE", colDate), _headerText("PARTNER", colAgent), _headerText("CUSTOMER", colCustomer), - _headerText("PREMIUM", colPremium), - _headerText("PAYOUT", colCommission), + _headerText("PREMIUM (₹)", colPremium, align: TextAlign.right), + const SizedBox(width: 10), + _headerText("PAYOUT (₹)", colCommission, align: TextAlign.right), ], ), ); } - Widget _headerText(String text, double width) { + Widget _headerText(String text, double width, {TextAlign align = TextAlign.left}) { return SizedBox( width: width, child: Text( text, + textAlign: align, style: GoogleFonts.poppins( fontSize: 11, fontWeight: FontWeight.w500, @@ -1128,12 +1194,15 @@ class _PayOutDetailsState extends ConsumerState { } Widget _policyTableBody() { + final pageRows = _paginatedPolicies; + final startIndex = + filteredPolicies.isEmpty ? 0 : (currentPage - 1) * itemsPerPage; return SizedBox( height: MediaQuery.of(context).size.height * 0.48, child: ListView.builder( - itemCount: filteredPolicies.length, + itemCount: pageRows.length, itemBuilder: (context, index) { - final p = filteredPolicies[index]; + final p = pageRows[index]; final int id = int.tryParse(p["policy_id"]?.toString() ?? "0") ?? 0; final bool isSelected = selectedPolicies.contains(id); @@ -1175,6 +1244,11 @@ class _PayOutDetailsState extends ConsumerState { }, ), ), + _cell( + '${startIndex + index + 1}', + colSno, + align: TextAlign.center, + ), _cell(p["policy_no"], colPolicy), // _cell(p["issued_date"] ?? "-", colDate), _cell(_formatDate(p['issued_date']), colDate), @@ -1186,20 +1260,16 @@ class _PayOutDetailsState extends ConsumerState { colAgent, ), _cell(p["customer_name"], colCustomer), - _cell("₹${p["premium_amount"]}", colPremium), + _cell( + _amountText(p["premium_amount"]), + colPremium, + align: TextAlign.right, + ), + const SizedBox(width: 10), SizedBox( width: colCommission, child: Row( children: [ - const Text( - "₹", - style: TextStyle( - fontSize: 11, - fontWeight: FontWeight.w600, - color: Color(0xFF009B77), - ), - ), - const SizedBox(width: 2), Expanded( child: _commissionAmountField( p, @@ -1218,6 +1288,35 @@ class _PayOutDetailsState extends ConsumerState { ); } + String _amountText(dynamic value) { + final raw = (value ?? '').toString().replaceAll('₹', '').trim(); + if (raw.isEmpty || raw.toLowerCase() == 'null') return '-'; + return raw; + } + + List> get _paginatedPolicies { + if (filteredPolicies.isEmpty) return const >[]; + final start = (currentPage - 1) * itemsPerPage; + final end = (start + itemsPerPage).clamp(0, filteredPolicies.length); + return filteredPolicies.sublist(start, end); + } + + List> get _exportRows { + return filteredPolicies.map((p) { + return { + 'sno': 0, + 'policy_no': p['policy_no'], + 'policy_date': _formatDate((p['issued_date'] ?? '').toString()), + 'partner': (p["agent_code"] != null && p["agent_name"] != null) + ? '${p["agent_code"]} - ${p["agent_name"]}' + : (p["agent_name"] ?? '-').toString(), + 'customer': p['customer_name'], + 'premium': _amountText(p['premium_amount']), + 'payout': _amountText(p['commission_amount']), + }; + }).toList(); + } + double _parseCommissionValue(dynamic value) { if (value == null) return 0; return double.tryParse(value.toString().trim()) ?? 0; @@ -1300,11 +1399,16 @@ class _PayOutDetailsState extends ConsumerState { } } - Widget _cell(String? value, double width) { + Widget _cell( + dynamic value, + double width, { + TextAlign align = TextAlign.left, + }) { return SizedBox( width: width, child: Text( - value ?? "-", + (value ?? "-").toString(), + textAlign: align, overflow: TextOverflow.ellipsis, style: const TextStyle(fontSize: 11), ), @@ -1426,20 +1530,24 @@ class _PayOutDetailsState extends ConsumerState { } static final double colCheck = 44; + static final double colSno = 60; static final double colPolicy = 200; static final double colDate = 200; - static final double colAgent = 200; + static final double colAgent = 400; static final double colCustomer = 200; static final double colPremium = 200; - static final double colCommission = 200; + static final double colPremiumPayoutGap = 10; + static final double colCommission = 150; double get _tableMinWidth => colCheck + + colSno + colPolicy + colDate + colAgent + colCustomer + colPremium + + colPremiumPayoutGap + colCommission + 32; } \ No newline at end of file diff --git a/lib/presentation/screens/payout/payout_details_view.dart b/lib/presentation/screens/payout/payout_details_view.dart index 5a1a1fd..50f7a31 100644 --- a/lib/presentation/screens/payout/payout_details_view.dart +++ b/lib/presentation/screens/payout/payout_details_view.dart @@ -5,11 +5,13 @@ import 'package:go_router/go_router.dart'; import 'package:google_fonts/google_fonts.dart'; import 'package:intl/intl.dart'; +import '../../../data/utils/Pagination.dart'; import '../../../core/routing/routes.dart'; import '../../../core/services/api_service.dart'; import '../../layouts/main_layout.dart'; import '../../layouts/responsive_layout.dart'; import '../../providers/manager_provider.dart'; +import '../../themes/indicators/export_btn.dart'; import '../../themes/indicators/search_field_theme.dart'; /// Read-only payout invoice + policy lines (opened from payout list “View”). @@ -35,15 +37,8 @@ class _PayOutDetailsViewState extends ConsumerState { dynamic totalPolicies = '0'; dynamic totalCommission = '0'; - static const double colPolicy = 150; - static const double colDate = 120; - static const double colAgent = 200; - static const double colCustomer = 200; - static const double colPremium = 200; - static const double colCommission = 120; - - double get _tableMinWidth => - colPolicy + colDate + colAgent + colCustomer + colPremium + colCommission + 32; + int _rowsPerPage = 10; + int _currentPage = 1; @override void initState() { @@ -114,6 +109,7 @@ class _PayOutDetailsViewState extends ConsumerState { totalCommission = totalCommiss; masterPolicies = items; filteredPolicies = List>.from(items); + _currentPage = 1; }); } else { setState(() { @@ -132,22 +128,21 @@ class _PayOutDetailsViewState extends ConsumerState { } void filterPolicyData(String query) { - final lowerQuery = query.toLowerCase(); + final q = query.trim(); setState(() { - if (query.trim().isEmpty) { + _currentPage = 1; + if (q.isEmpty) { filteredPolicies = List.from(masterPolicies); return; } filteredPolicies = masterPolicies.where((item) { - return (item['policy_no'] ?? '').toString().toLowerCase().contains(lowerQuery) || - (item['customer_name'] ?? '').toString().toLowerCase().contains(lowerQuery) || - (item['agent_name'] ?? '').toString().toLowerCase().contains(lowerQuery) || - (item['insurer_name'] ?? '').toString().toLowerCase().contains(lowerQuery) || - (item['premium_amount'] ?? '').toString().toLowerCase().contains(lowerQuery) || - (item['commission_amount'] ?? '').toString().toLowerCase().contains(lowerQuery) || - _formatDate(item['issued_date']?.toString() ?? '') - .toLowerCase() - .contains(lowerQuery); + return (item['policy_no'] ?? '').toString().contains(q) || + (item['customer_name'] ?? '').toString().contains(q) || + (item['agent_name'] ?? '').toString().contains(q) || + (item['insurer_name'] ?? '').toString().contains(q) || + (item['premium_amount'] ?? '').toString().contains(q) || + (item['commission_amount'] ?? '').toString().contains(q) || + _formatDate(item['issued_date']?.toString() ?? '').contains(q); }).toList(); }); } @@ -182,11 +177,37 @@ class _PayOutDetailsViewState extends ConsumerState { } } - Widget _headerText(String text, double width) { + String _amountText(dynamic value) { + final text = _displayText(value); + if (text == '-') return '-'; + return text.replaceAll('₹', '').trim(); + } + + List _columnWidths(double maxWidth) { + const sidePadding = 32.0; // 16 left + 16 right + final usable = (maxWidth - sidePadding).clamp(720.0, 2000.0); + const totalFlex = 2 + 14 + 10 + 20 + 16 + 11 + 11; + return [ + usable * (2 / totalFlex), // S.NO + usable * (14 / totalFlex), // POLICY NO + usable * (10 / totalFlex), // POLICY DATE + usable * (20 / totalFlex), // PARTNER + usable * (16 / totalFlex), // CUSTOMER + usable * (11 / totalFlex), // PREMIUM + usable * (11 / totalFlex), // PAYOUT + ]; + } + + Widget _headerText( + String text, + double width, { + TextAlign align = TextAlign.left, + }) { return SizedBox( width: width, child: Text( text, + textAlign: align, style: GoogleFonts.poppins( fontSize: 11, fontWeight: FontWeight.w500, @@ -197,18 +218,29 @@ class _PayOutDetailsViewState extends ConsumerState { ); } - Widget _cell(String? value, double width) { + Widget _cell( + String? value, + double width, { + TextAlign align = TextAlign.left, + Color? color, + FontWeight? fontWeight, + }) { return SizedBox( width: width, child: Text( value ?? '-', + textAlign: align, overflow: TextOverflow.ellipsis, - style: const TextStyle(fontSize: 11), + style: TextStyle( + fontSize: 11, + color: color, + fontWeight: fontWeight, + ), ), ); } - Widget _policyTableHeader() { + Widget _policyTableHeader(List w) { return Container( height: 30, padding: const EdgeInsets.symmetric(horizontal: 16), @@ -218,18 +250,19 @@ class _PayOutDetailsViewState extends ConsumerState { ), child: Row( children: [ - _headerText('POLICY NO', colPolicy), - _headerText('POLICY DATE', colDate), - _headerText('PARTNER', colAgent), - _headerText('CUSTOMER', colCustomer), - _headerText('PREMIUM', colPremium), - _headerText('PAYOUT', colCommission), + _headerText('S.NO', w[0]), + _headerText('POLICY NO', w[1]), + _headerText('POLICY DATE', w[2]), + _headerText('PARTNER', w[3]), + _headerText('CUSTOMER', w[4]), + _headerText('PREMIUM (₹)', w[5], align: TextAlign.right), + _headerText('PAYOUT (₹)', w[6], align: TextAlign.right), ], ), ); } - Widget _policyRow(Map p) { + Widget _policyRow(Map p, int index, List w) { return Container( height: 38, padding: const EdgeInsets.symmetric(horizontal: 16), @@ -239,33 +272,66 @@ class _PayOutDetailsViewState extends ConsumerState { ), child: Row( children: [ - _cell(p['policy_no']?.toString(), colPolicy), - _cell(_formatDate(p['issued_date']?.toString()), colDate), + _cell('${index + 1}', w[0]), + _cell(p['policy_no']?.toString(), w[1]), + _cell(_formatDate(p['issued_date']?.toString()), w[2]), _cell( (p['agent_code'] != null && p['agent_name'] != null) ? '${p['agent_code']} - ${p['agent_name']}' : (p['agent_name'] ?? '-').toString(), - colAgent, + w[3], ), - _cell(p['customer_name']?.toString(), colCustomer), - _cell('₹${p['premium_amount']}', colPremium), - SizedBox( - width: colCommission, - child: Text( - '₹${_displayText(p['commission_amount'])}', - overflow: TextOverflow.ellipsis, - style: const TextStyle( - fontSize: 11, - fontWeight: FontWeight.w600, - color: Color(0xFF009B77), - ), - ), + _cell(p['customer_name']?.toString(), w[4]), + _cell( + _amountText(p['premium_amount']), + w[5], + align: TextAlign.right, + ), + _cell( + _amountText(p['commission_amount']), + w[6], + align: TextAlign.right, + color: const Color(0xFF009B77), + fontWeight: FontWeight.w600, ), ], ), ); } + int get _totalPages { + if (filteredPolicies.isEmpty) return 1; + return (filteredPolicies.length / _rowsPerPage).ceil(); + } + + List> get _paginatedPolicies { + if (filteredPolicies.isEmpty) return const >[]; + final start = (_currentPage - 1) * _rowsPerPage; + final end = (start + _rowsPerPage).clamp(0, filteredPolicies.length); + return filteredPolicies.sublist(start, end); + } + + void _goToPage(int page) { + if (page < 1 || page > _totalPages) return; + setState(() => _currentPage = page); + } + + List> get _exportRows { + return filteredPolicies.map((p) { + return { + 'sno': 0, + 'policy_no': p['policy_no'], + 'policy_date': _formatDate(p['issued_date']?.toString()), + 'partner': (p['agent_code'] != null && p['agent_name'] != null) + ? '${p['agent_code']} - ${p['agent_name']}' + : (p['agent_name'] ?? '-').toString(), + 'customer': p['customer_name'], + 'premium': _amountText(p['premium_amount']), + 'payout': _amountText(p['commission_amount']), + }; + }).toList(); + } + @override Widget build(BuildContext context) { final statusRaw = widget.viewItem['payout_status']; @@ -356,6 +422,31 @@ class _PayOutDetailsViewState extends ConsumerState { ? MediaQuery.of(context).size.width * 0.7 : MediaQuery.of(context).size.width * 0.15, ), + const SizedBox(width: 10), + ExportBtn( + sheetName: 'Payout Details', + fileName: + 'payout_details_${DateFormat('yyyyMMdd_HHmmss').format(DateTime.now())}', + data: _exportRows, + displayHeaders: const [ + 'S.NO', + 'POLICY NO', + 'POLICY DATE', + 'PARTNER', + 'CUSTOMER', + 'PREMIUM (₹)', + 'PAYOUT (₹)', + ], + keys: const [ + 'sno', + 'policy_no', + 'policy_date', + 'partner', + 'customer', + 'premium', + 'payout', + ], + ), ], ), ), @@ -377,45 +468,38 @@ class _PayOutDetailsViewState extends ConsumerState { ), child: LayoutBuilder( builder: (context, constraints) { - // Same pattern as enquiry list: nested axis scroll views - // avoids broken vertical gestures on web/desktop. - return SingleChildScrollView( - scrollDirection: Axis.horizontal, - primary: false, - child: SingleChildScrollView( - scrollDirection: Axis.vertical, - primary: false, - child: ConstrainedBox( - constraints: BoxConstraints( - minWidth: _tableMinWidth, - minHeight: constraints.maxHeight.isFinite - ? constraints.maxHeight - : 0, - ), - child: Column( - mainAxisSize: MainAxisSize.min, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - _policyTableHeader(), - if (filteredPolicies.isEmpty) - const Padding( - padding: EdgeInsets.all(24), - child: Center( - child: Text( - 'No policies in this payout', - style: TextStyle( - fontSize: 12, - color: Colors.blueGrey, - ), + final widths = _columnWidths(constraints.maxWidth); + final rows = _paginatedPolicies; + final startIdx = (filteredPolicies.isEmpty) + ? 0 + : ((_currentPage - 1) * _rowsPerPage); + + return Column( + children: [ + _policyTableHeader(widths), + Expanded( + child: filteredPolicies.isEmpty + ? const Center( + child: Text( + 'No policies in this payout', + style: TextStyle( + fontSize: 12, + color: Colors.blueGrey, ), ), ) - else - ...filteredPolicies.map(_policyRow), - ], - ), + : ListView.builder( + itemCount: rows.length, + itemBuilder: (context, index) { + return _policyRow( + rows[index], + startIdx + index, + widths, + ); + }, + ), ), - ), + ], ); }, ), @@ -438,7 +522,7 @@ class _PayOutDetailsViewState extends ConsumerState { ), const SizedBox(width: 4), Text( - 'policies', + 'Policies', style: GoogleFonts.poppins( fontSize: 12, fontWeight: FontWeight.w500, @@ -475,6 +559,25 @@ class _PayOutDetailsViewState extends ConsumerState { ], ), ), + if (filteredPolicies.isNotEmpty) + Padding( + padding: const EdgeInsets.fromLTRB(8, 4, 8, 2), + child: Align( + alignment: Alignment.centerRight, + child: PaginationControls( + currentPage: _currentPage, + itemsPerPage: _rowsPerPage, + totalItems: filteredPolicies.length, + onPageChanged: (page) => _goToPage(page), + onItemsPerPageChanged: (items) { + setState(() { + _rowsPerPage = items; + _currentPage = 1; + }); + }, + ), + ), + ), ], ), ), diff --git a/lib/presentation/screens/payout/payout_report.dart b/lib/presentation/screens/payout/payout_report.dart index 8561892..bbaf972 100644 --- a/lib/presentation/screens/payout/payout_report.dart +++ b/lib/presentation/screens/payout/payout_report.dart @@ -11,7 +11,7 @@ import '../../layouts/main_layout.dart'; import '../../layouts/responsive_layout.dart'; import '../../providers/manager_provider.dart'; import '../../providers/userRoleProvider.dart'; -import '../../themes/indicators/date_field_theme.dart'; +import '../../themes/indicators/date_range_picker_field.dart'; import '../../themes/indicators/export_btn.dart'; import '../../themes/indicators/search_field_theme.dart'; @@ -69,6 +69,25 @@ class _PayoutReportScreenState extends ConsumerState { (s.length > 1 ? s.substring(1).toLowerCase() : ''); } + bool _isAccountsReceivedRole() { + final role = (ref.read(userRoleProvider) ?? '') + .toString() + .trim() + .toLowerCase() + .replaceAll(RegExp(r'[\s_\-]+'), ''); + return role == 'accountsreceived' || role == 'accounts'; + } + + String _receivedDisplayLabel(dynamic v) { + final raw = v?.toString().trim().toLowerCase() ?? ''; + if (_isAccountsReceivedRole()) { + if (raw == 'yes' || raw == 'received' || raw == 'paid') { + return 'Paid'; + } + } + return _receivedLabel(v); + } + String? _agentIdForApi() { if (_isAgentRole()) { final uid = ref.read(userIdProvider); @@ -689,7 +708,7 @@ class _PayoutReportScreenState extends ConsumerState { valueColor: const Color(0xFF37474F), ), _summaryChip( - label: 'Raised', + label: 'Paid', value: _fmtSummaryAmount(_summaryRaised), bg: const Color(0xFFE0F2F1), border: const Color(0xFF80CBC4), @@ -787,7 +806,7 @@ class _PayoutReportScreenState extends ConsumerState { 'Premium', 'Payout', 'UTR No', - 'Received', + 'Paid/Received', ], keys: const [ 'sno', @@ -802,7 +821,7 @@ class _PayoutReportScreenState extends ConsumerState { 'received_or_not', ], valueFormatters: { - 'received_or_not': (v, _) => _receivedLabel(v), + 'received_or_not': (v, _) => _receivedDisplayLabel(v), }, ); if (mounted) { @@ -815,27 +834,6 @@ class _PayoutReportScreenState extends ConsumerState { } } - Widget _buildDateField({ - required TextEditingController controller, - required String hintText, - required bool isStart, - }) { - return SizedBox( - height: 35, - child: ThemedDateField( - hintText: hintText, - txtwidth: ResponsiveLayout.isMobile(context) - ? null - : MediaQuery.of(context).size.width * 0.1, - controller: controller, - lastDate: isStart ? null : DateTime.now(), - onDateSelected: (date) { - controller.text = DateFormat('dd-MM-yyyy').format(date); - }, - ), - ); - } - Widget _filterControlsRow(BuildContext context) { final spacing = 5.0; final isMobile = ResponsiveLayout.isMobile(context); @@ -845,16 +843,16 @@ class _PayoutReportScreenState extends ConsumerState { final fields = Row( crossAxisAlignment: CrossAxisAlignment.start, children: [ - _buildDateField( - controller: _startController, - hintText: 'Select Date', - isStart: true, - ), - SizedBox(width: spacing), - _buildDateField( - controller: _endController, - hintText: 'Select Date', - isStart: false, + DateRangePickerField( + startController: _startController, + endController: _endController, + hintText: 'Select date range', + showLabelAboveField: false, + txtwidth: isMobile + ? null + : MediaQuery.of(context).size.width * 0.15, + lastDate: DateTime.now(), + useFormField: false, ), if (showAgentFilter) ...[ SizedBox(width: spacing), @@ -1012,7 +1010,13 @@ class _PayoutReportScreenState extends ConsumerState { child: Text('PAYOUT', style: _headerColumn, textAlign: TextAlign.right), ), const SizedBox(width: 15), - Expanded(flex: 2, child: Text('RECEIVED', style: _headerColumn)), + Expanded( + flex: 2, + child: Text( + _isAccountsReceivedRole() ? 'PAID' : 'RECEIVED', + style: _headerColumn, + ), + ), ], ), ); @@ -1114,7 +1118,7 @@ class _PayoutReportScreenState extends ConsumerState { Expanded( flex: 2, child: Text( - _receivedLabel(item['received_or_not']), + _receivedDisplayLabel(item['received_or_not']), style: rowStyle, maxLines: 2, overflow: TextOverflow.ellipsis, diff --git a/lib/presentation/themes/indicators/date_range_picker_dialog.dart b/lib/presentation/themes/indicators/date_range_picker_dialog.dart new file mode 100644 index 0000000..1d840a2 --- /dev/null +++ b/lib/presentation/themes/indicators/date_range_picker_dialog.dart @@ -0,0 +1,446 @@ +import 'package:flutter/material.dart'; +import 'package:google_fonts/google_fonts.dart'; +import 'package:intl/intl.dart'; + +/// Compact date-range dialog (centered card, not full-screen on web). +/// From/To header, month navigation, range highlight, Cancel / Apply. +Future showCompactDateRangePicker({ + required BuildContext context, + required DateTime firstDate, + required DateTime lastDate, + DateTimeRange? initialRange, +}) { + return showDialog( + context: context, + barrierDismissible: true, + builder: (ctx) => _CompactDateRangeDialog( + firstDate: DateTime(firstDate.year, firstDate.month, firstDate.day), + lastDate: DateTime(lastDate.year, lastDate.month, lastDate.day), + initialRange: initialRange, + ), + ); +} + +class _CompactDateRangeDialog extends StatefulWidget { + const _CompactDateRangeDialog({ + required this.firstDate, + required this.lastDate, + this.initialRange, + }); + + final DateTime firstDate; + final DateTime lastDate; + final DateTimeRange? initialRange; + + @override + State<_CompactDateRangeDialog> createState() => _CompactDateRangeDialogState(); +} + +class _CompactDateRangeDialogState extends State<_CompactDateRangeDialog> { + static const _primary = Color(0xFF2E7D6E); + static const _primaryLight = Color(0xFFE6F4F1); + static const _muted = Color(0xFF64748B); + + late DateTime _focusedMonth; + DateTime? _start; + DateTime? _end; + + final _headerFrom = DateFormat('EEE, dd MMM'); + final _headerMonth = DateFormat('MMMM yyyy'); + + @override + void initState() { + super.initState(); + final ir = widget.initialRange; + if (ir != null) { + _start = DateTime(ir.start.year, ir.start.month, ir.start.day); + _end = DateTime(ir.end.year, ir.end.month, ir.end.day); + _focusedMonth = DateTime(_start!.year, _start!.month, 1); + } else { + final now = DateTime.now(); + final n = DateTime(now.year, now.month, now.day); + _focusedMonth = DateTime(n.year, n.month, 1); + if (n.isBefore(widget.firstDate)) { + _focusedMonth = DateTime(widget.firstDate.year, widget.firstDate.month, 1); + } else if (n.isAfter(widget.lastDate)) { + _focusedMonth = DateTime(widget.lastDate.year, widget.lastDate.month, 1); + } + } + } + + bool _sameDay(DateTime a, DateTime b) => + a.year == b.year && a.month == b.month && a.day == b.day; + + DateTime _norm(DateTime d) => DateTime(d.year, d.month, d.day); + + bool _inSelectedRange(DateTime d) { + if (_start == null) return false; + final x = _norm(d); + final s = _norm(_start!); + final e = _norm(_end ?? _start!); + return !x.isBefore(s) && !x.isAfter(e); + } + + bool _isRangeStart(DateTime d) => _start != null && _sameDay(d, _start!); + + bool _isRangeEnd(DateTime d) { + if (_start == null) return false; + final end = _end ?? _start!; + return _sameDay(d, end); + } + + void _onDayTap(DateTime day) { + final d = _norm(day); + if (d.isBefore(widget.firstDate) || d.isAfter(widget.lastDate)) return; + + setState(() { + if (_start == null || (_start != null && _end != null)) { + _start = d; + _end = null; + } else { + if (d.isBefore(_start!)) { + _end = _start; + _start = d; + } else { + _end = d; + } + } + }); + } + + bool get _canPrev { + final lastOfPrevMonth = DateTime(_focusedMonth.year, _focusedMonth.month, 0); + return !lastOfPrevMonth.isBefore(widget.firstDate); + } + + bool get _canNext { + final firstOfNextMonth = DateTime(_focusedMonth.year, _focusedMonth.month + 1, 1); + return !firstOfNextMonth.isAfter(widget.lastDate); + } + + void _prevMonth() { + if (!_canPrev) return; + setState(() { + _focusedMonth = DateTime(_focusedMonth.year, _focusedMonth.month - 1, 1); + }); + } + + void _nextMonth() { + if (!_canNext) return; + setState(() { + _focusedMonth = DateTime(_focusedMonth.year, _focusedMonth.month + 1, 1); + }); + } + + List _calendarCells() { + final first = DateTime(_focusedMonth.year, _focusedMonth.month, 1); + final daysInMonth = DateTime(_focusedMonth.year, _focusedMonth.month + 1, 0).day; + final leading = first.weekday - 1; + final cells = []; + + final prevEnd = DateTime(_focusedMonth.year, _focusedMonth.month, 0); + for (int i = 0; i < leading; i++) { + final dayNum = prevEnd.day - leading + i + 1; + cells.add(DateTime(prevEnd.year, prevEnd.month, dayNum)); + } + for (int d = 1; d <= daysInMonth; d++) { + cells.add(DateTime(_focusedMonth.year, _focusedMonth.month, d)); + } + var next = 1; + while (cells.length % 7 != 0 || cells.length < 42) { + cells.add(DateTime(_focusedMonth.year, _focusedMonth.month + 1, next)); + next++; + } + return cells; + } + + void _apply() { + if (_start == null) { + Navigator.of(context).pop(); + return; + } + final end = _end ?? _start!; + Navigator.of(context).pop(DateTimeRange(start: _start!, end: end)); + } + + Widget _dayCell(DateTime d) { + final inMonth = d.month == _focusedMonth.month; + final disabled = + d.isBefore(widget.firstDate) || d.isAfter(widget.lastDate); + + if (!inMonth) { + return Center( + child: Text( + '${d.day}', + style: GoogleFonts.inter( + fontSize: 13, + color: const Color(0xFF94A3B8), + fontWeight: FontWeight.w500, + ), + ), + ); + } + + final inRange = !disabled && _inSelectedRange(d); + final isStart = !disabled && _isRangeStart(d); + final isEnd = !disabled && _isRangeEnd(d); + final span = _start != null && + _end != null && + !_sameDay(_start!, _end!); + + BorderRadius? bgRadius; + if (inRange && span) { + if (isStart) { + bgRadius = const BorderRadius.horizontal(left: Radius.circular(20)); + } else if (isEnd) { + bgRadius = const BorderRadius.horizontal(right: Radius.circular(20)); + } else { + bgRadius = BorderRadius.zero; + } + } + + return GestureDetector( + onTap: disabled ? null : () => _onDayTap(d), + behavior: HitTestBehavior.opaque, + child: Container( + decoration: BoxDecoration( + color: (inRange && span) ? _primaryLight : null, + borderRadius: bgRadius, + ), + alignment: Alignment.center, + child: Container( + width: 36, + height: 36, + alignment: Alignment.center, + decoration: BoxDecoration( + shape: BoxShape.circle, + color: (isStart || isEnd) ? _primary : Colors.transparent, + border: (isStart || isEnd) + ? Border.all(color: Colors.white, width: 2) + : null, + ), + child: Text( + '${d.day}', + style: GoogleFonts.inter( + fontSize: 13, + fontWeight: + (isStart || isEnd) ? FontWeight.w700 : FontWeight.w500, + color: disabled + ? const Color(0xFFCBD5E1) + : (isStart || isEnd) + ? Colors.white + : const Color(0xFF0F172A), + ), + ), + ), + ), + ); + } + + @override + Widget build(BuildContext context) { + final cells = _calendarCells(); + + return Dialog( + insetPadding: const EdgeInsets.symmetric(horizontal: 20, vertical: 24), + shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(20)), + clipBehavior: Clip.antiAlias, + child: ConstrainedBox( + constraints: const BoxConstraints(maxWidth: 400), + child: Padding( + padding: const EdgeInsets.fromLTRB(16, 8, 16, 16), + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + Row( + children: [ + IconButton( + icon: const Icon(Icons.close, size: 22), + color: _muted, + onPressed: () => Navigator.of(context).pop(), + visualDensity: VisualDensity.compact, + ), + ], + ), + Container( + decoration: BoxDecoration( + color: const Color(0xFFF8FAFC), + borderRadius: BorderRadius.circular(12), + border: Border.all(color: const Color(0xFFE2E8F0)), + ), + child: Row( + children: [ + Expanded( + child: Padding( + padding: const EdgeInsets.symmetric( + vertical: 12, horizontal: 12), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + 'From', + style: GoogleFonts.inter( + fontSize: 11, + color: _muted, + fontWeight: FontWeight.w500, + ), + ), + const SizedBox(height: 4), + Text( + _start != null + ? _headerFrom.format(_start!) + : '—', + style: GoogleFonts.inter( + fontSize: 14, + fontWeight: FontWeight.w700, + color: const Color(0xFF0F172A), + ), + ), + ], + ), + ), + ), + Container( + width: 1, height: 52, color: const Color(0xFFE2E8F0)), + Expanded( + child: Padding( + padding: const EdgeInsets.symmetric( + vertical: 12, horizontal: 12), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + 'To', + style: GoogleFonts.inter( + fontSize: 11, + color: _muted, + fontWeight: FontWeight.w500, + ), + ), + const SizedBox(height: 4), + Text( + _start != null + ? _headerFrom.format(_end ?? _start!) + : '—', + style: GoogleFonts.inter( + fontSize: 14, + fontWeight: FontWeight.w700, + color: const Color(0xFF0F172A), + ), + ), + ], + ), + ), + ), + ], + ), + ), + const SizedBox(height: 14), + Row( + children: [ + IconButton( + onPressed: _canPrev ? _prevMonth : null, + icon: const Icon(Icons.chevron_left), + color: _primary, + ), + Expanded( + child: Text( + _headerMonth.format(_focusedMonth), + textAlign: TextAlign.center, + style: GoogleFonts.poppins( + fontSize: 15, + fontWeight: FontWeight.w600, + color: const Color(0xFF1E293B), + ), + ), + ), + IconButton( + onPressed: _canNext ? _nextMonth : null, + icon: const Icon(Icons.chevron_right), + color: _primary, + ), + ], + ), + const SizedBox(height: 6), + Row( + children: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'] + .map( + (w) => Expanded( + child: Center( + child: Text( + w, + style: GoogleFonts.inter( + fontSize: 11, + fontWeight: FontWeight.w600, + color: _primary, + ), + ), + ), + ), + ) + .toList(), + ), + const SizedBox(height: 6), + GridView.builder( + shrinkWrap: true, + physics: const NeverScrollableScrollPhysics(), + gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount( + crossAxisCount: 7, + mainAxisSpacing: 2, + crossAxisSpacing: 2, + childAspectRatio: 1.05, + ), + itemCount: cells.length, + itemBuilder: (context, i) => _dayCell(cells[i]), + ), + const SizedBox(height: 16), + Row( + children: [ + Expanded( + child: OutlinedButton( + onPressed: () => Navigator.of(context).pop(), + style: OutlinedButton.styleFrom( + foregroundColor: _primary, + side: const BorderSide(color: _primary), + padding: const EdgeInsets.symmetric(vertical: 12), + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(24), + ), + ), + child: Text( + 'Cancel', + style: + GoogleFonts.poppins(fontWeight: FontWeight.w600), + ), + ), + ), + const SizedBox(width: 12), + Expanded( + child: FilledButton( + onPressed: _start != null ? _apply : null, + style: FilledButton.styleFrom( + backgroundColor: _primary, + disabledBackgroundColor: const Color(0xFFCBD5E1), + padding: const EdgeInsets.symmetric(vertical: 12), + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(24), + ), + ), + child: Text( + 'Apply', + style: GoogleFonts.poppins( + fontWeight: FontWeight.w600, + color: Colors.white, + ), + ), + ), + ), + ], + ), + ], + ), + ), + ), + ); + } +} diff --git a/lib/presentation/themes/indicators/date_range_picker_field.dart b/lib/presentation/themes/indicators/date_range_picker_field.dart new file mode 100644 index 0000000..25a5712 --- /dev/null +++ b/lib/presentation/themes/indicators/date_range_picker_field.dart @@ -0,0 +1,255 @@ +import 'package:flutter/material.dart'; +import 'package:intl/intl.dart'; + +import 'date_range_picker_dialog.dart'; + +/// Single UI control for filter **from** / **to** dates. +/// +/// Writes [dd-MM-yyyy] to [startController] and [endController] (same as [ThemedDateField]). +/// Does not change API keys or request shape — only how the user picks dates. +class DateRangePickerField extends StatefulWidget { + const DateRangePickerField({ + super.key, + required this.startController, + required this.endController, + this.hintText, + this.labelText, + this.txtwidth, + this.txtheight = 35, + this.firstDate, + this.lastDate, + this.onRangeSelected, + this.rangeValidator, + this.showLabelAboveField = false, + this.labelStyle, + this.useFormField = true, + }); + + final TextEditingController startController; + final TextEditingController endController; + + /// Shown when no range is selected. + final String? hintText; + + /// Optional label above the field (e.g. `Date range *`). + final String? labelText; + final double? txtwidth; + final double? txtheight; + final DateTime? firstDate; + final DateTime? lastDate; + + /// Called after user confirms a range (same moment controllers are updated). + final void Function(DateTimeRange range)? onRangeSelected; + + /// When non-null and [useFormField] is true, wrapped in [FormField] for [FormState.validate]. + final String? Function( + TextEditingController start, + TextEditingController end, + )? rangeValidator; + + final bool showLabelAboveField; + final TextStyle? labelStyle; + + /// If false, no [FormField] — use when this widget is not under a [Form]. + final bool useFormField; + + static final DateFormat storageFormat = DateFormat('dd-MM-yyyy'); + static final DateFormat displayFormat = DateFormat('dd MMM yyyy'); + + /// Matches previous end-date-only validation: if start is set, end is required and not before start. + static String? defaultFilterValidator( + TextEditingController start, + TextEditingController end, + ) { + final s = start.text.trim(); + final e = end.text.trim(); + if (s.isNotEmpty) { + try { + storageFormat.parse(s); + if (e.isEmpty) return 'End Date is required'; + final sd = storageFormat.parse(s); + final ed = storageFormat.parse(e); + if (ed.isBefore(sd)) { + return 'End Date cannot be earlier than Start Date'; + } + } catch (_) { + return 'Invalid date'; + } + } + return null; + } + + @override + State createState() => _DateRangePickerFieldState(); +} + +class _DateRangePickerFieldState extends State { + void _onTextChanged() { + if (mounted) setState(() {}); + } + + @override + void initState() { + super.initState(); + widget.startController.addListener(_onTextChanged); + widget.endController.addListener(_onTextChanged); + } + + @override + void dispose() { + widget.startController.removeListener(_onTextChanged); + widget.endController.removeListener(_onTextChanged); + super.dispose(); + } + + String _displayText() { + final s = widget.startController.text.trim(); + final e = widget.endController.text.trim(); + if (s.isEmpty && e.isEmpty) { + return widget.hintText ?? 'Select date range'; + } + if (s.isNotEmpty && e.isNotEmpty) { + try { + final sd = DateRangePickerField.storageFormat.parse(s); + final ed = DateRangePickerField.storageFormat.parse(e); + return '${DateRangePickerField.displayFormat.format(sd)} – ${DateRangePickerField.displayFormat.format(ed)}'; + } catch (_) { + return '$s – $e'; + } + } + if (s.isNotEmpty) return s; + return e; + } + + Future _pick(BuildContext context, FormFieldState? field) async { + final first = widget.firstDate ?? DateTime(2000); + final last = widget.lastDate ?? DateTime(2100); + + DateTimeRange? initial; + try { + final s = widget.startController.text.trim(); + final e = widget.endController.text.trim(); + if (s.isNotEmpty && e.isNotEmpty) { + initial = DateTimeRange( + start: DateRangePickerField.storageFormat.parse(s), + end: DateRangePickerField.storageFormat.parse(e), + ); + } else if (s.isNotEmpty) { + final d = DateRangePickerField.storageFormat.parse(s); + initial = DateTimeRange(start: d, end: d); + } + } catch (_) {} + + final picked = await showCompactDateRangePicker( + context: context, + firstDate: first, + lastDate: last, + initialRange: initial, + ); + + if (picked != null) { + widget.startController.text = + DateRangePickerField.storageFormat.format(picked.start); + widget.endController.text = + DateRangePickerField.storageFormat.format(picked.end); + field?.didChange('range'); + widget.onRangeSelected?.call(picked); + setState(() {}); + } + } + + static const _border = Color(0xFFE2E8F0); + static const _error = Color(0xFFD83731); + + Widget _tappableField({ + required bool hasError, + required VoidCallback onTap, + }) { + final empty = widget.startController.text.trim().isEmpty && + widget.endController.text.trim().isEmpty; + + return InkWell( + onTap: onTap, + borderRadius: BorderRadius.circular(10), + child: Container( + width: widget.txtwidth ?? MediaQuery.sizeOf(context).width, + height: widget.txtheight, + padding: const EdgeInsets.symmetric(vertical: 8, horizontal: 15), + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(10), + border: Border.all( + color: hasError ? _error : _border, + width: 1, + ), + ), + child: Row( + children: [ + Expanded( + child: Text( + _displayText(), + style: TextStyle( + fontSize: 11, + color: hasError + ? _error + : empty + ? const Color(0xFF64748B) + : Colors.black, + ), + overflow: TextOverflow.ellipsis, + ), + ), + const Icon(Icons.date_range, size: 16, color: Color(0xFF5A6C7D)), + ], + ), + ), + ); + } + + @override + Widget build(BuildContext context) { + final labelStyle = widget.labelStyle ?? + const TextStyle(fontSize: 12, fontWeight: FontWeight.w600); + + Widget content({required bool hasError, FormFieldState? field}) { + return Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisSize: MainAxisSize.min, + children: [ + if (widget.showLabelAboveField && widget.labelText != null) ...[ + Text(widget.labelText!, style: labelStyle), + const SizedBox(height: 5), + ], + _tappableField( + hasError: hasError, + onTap: () => _pick(context, field), + ), + if (hasError && field != null && (field.errorText ?? '').isNotEmpty) + Padding( + padding: const EdgeInsets.only(top: 5, left: 5), + child: Text( + field.errorText ?? '', + style: const TextStyle(color: _error, fontSize: 10), + ), + ), + ], + ); + } + + if (!widget.useFormField || widget.rangeValidator == null) { + return content(hasError: false, field: null); + } + + return FormField( + initialValue: '', + validator: (_) => widget.rangeValidator!( + widget.startController, + widget.endController, + ), + builder: (field) { + final hasError = field.hasError; + return content(hasError: hasError, field: field); + }, + ); + } +} diff --git a/lib/presentation/widgets/custom_Stdate_EnDate_Filter.dart b/lib/presentation/widgets/custom_Stdate_EnDate_Filter.dart index 8fdfc3d..3aab0d4 100644 --- a/lib/presentation/widgets/custom_Stdate_EnDate_Filter.dart +++ b/lib/presentation/widgets/custom_Stdate_EnDate_Filter.dart @@ -8,6 +8,7 @@ import '../layouts/responsive_layout.dart'; import '../providers/manager_provider.dart'; import '../providers/userRoleProvider.dart'; import '../themes/indicators/date_field_theme.dart'; +import '../themes/indicators/date_range_picker_field.dart'; import '../themes/indicators/input_field_decoration.dart'; // class DateFilterRow extends StatelessWidget { @@ -276,9 +277,7 @@ class _DateFilterRowState extends ConsumerState { List getRowChildren(bool isMobile, double spacing) { final dateFields = [ - buildStartDate(context), - SizedBox(width: spacing), - buildEndDate(context), + buildDateRangeFilter(context), SizedBox(width: spacing), if (!widget.compactDateFiltersOnly) ...[ @@ -371,78 +370,18 @@ class _DateFilterRowState extends ConsumerState { ); } - Widget buildStartDate(BuildContext context) { - return Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - // Text('Start Date', style: _textStyle), - // SizedBox(height: 5), - SizedBox( - height: 35, - child: ThemedDateField( - hintText: "Select Date", - txtwidth: ResponsiveLayout.isMobile(context) - ? null - : MediaQuery.of(context).size.width * 0.1, - // txtheight: 50, - // backgroundColor: const Color(0xFFECECEC), - // validator: (value) => Validators.requiredField(value, "date"), - controller: widget.startController, - onDateSelected: (date) { - print("SPicked Date: $date"); - widget.startController.text = DateFormat( - 'dd-MM-yyyy', - ).format(date); - // controllers['date']?.text = date as String; - // Future.microtask(() => widget.onFilter()); - }, - ), - ), - ], - ); - } - - Widget buildEndDate(BuildContext context) { - return Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - // Text('End Date', style: _textStyle), - // SizedBox(height: 5), - SizedBox( - height: 35, - child: ThemedDateField( - hintText: "Select Date", - txtwidth: ResponsiveLayout.isMobile(context) - ? null - : MediaQuery.of(context).size.width * 0.1, - // txtheight: 50, - // backgroundColor: const Color(0xFFECECEC), - validator: (value) { - final fromText = widget.startController.text ?? ''; - if (fromText.isNotEmpty) { - final startDate = DateFormat('dd-MM-yyyy').parse(fromText); - if (value == null || value.isEmpty) { - return "End Date is required"; - } - final endDate = DateFormat('dd-MM-yyyy').parse(value); - - if (endDate.isBefore(startDate)) { - return "End Date cannot be earlier than Start Date"; - } - } - return null; // ✅ no error - }, - controller: widget.endController, - lastDate: DateTime.now(), - onDateSelected: (edate) { - print("EPicked Date: $edate"); - widget.endController.text = DateFormat('dd-MM-yyyy').format(edate); - Future.microtask(() => widget.onFilter()); - // controllers['date']?.text = date as String; - }, - ), - ), - ], + Widget buildDateRangeFilter(BuildContext context) { + final w = ResponsiveLayout.isMobile(context) + ? null + : MediaQuery.of(context).size.width * 0.15; + return DateRangePickerField( + startController: widget.startController, + endController: widget.endController, + hintText: 'Select date range', + txtwidth: w, + lastDate: DateTime.now(), + rangeValidator: DateRangePickerField.defaultFilterValidator, + onRangeSelected: (_) => Future.microtask(() => widget.onFilter()), ); } diff --git a/pubspec.lock b/pubspec.lock index ea3eafc..abbeba9 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -117,10 +117,10 @@ packages: dependency: transitive description: name: characters - sha256: faf38497bda5ead2a8c7615f4f7939df04333478bf32e4173fcb06d428b5716b + sha256: f71061c654a3380576a52b451dd5532377954cf9dbd272a78fc8479606670803 url: "https://pub.dev" source: hosted - version: "1.4.1" + version: "1.4.0" charcode: dependency: transitive description: @@ -780,26 +780,26 @@ packages: dependency: transitive description: name: matcher - sha256: dc0b7dc7651697ea4ff3e69ef44b0407ea32c487a39fff6a4004fa585e901861 + sha256: dc58c723c3c24bf8d3e2d3ad3f2f9d7bd9cf43ec6feaa64181775e60190153f2 url: "https://pub.dev" source: hosted - version: "0.12.19" + version: "0.12.17" material_color_utilities: dependency: transitive description: name: material_color_utilities - sha256: "9c337007e82b1889149c82ed242ed1cb24a66044e30979c44912381e9be4c48b" + sha256: f7142bb1154231d7ea5f96bc7bde4bda2a0945d2806bb11670e30b850d56bdec url: "https://pub.dev" source: hosted - version: "0.13.0" + version: "0.11.1" meta: dependency: transitive description: name: meta - sha256: "23f08335362185a5ea2ad3a4e597f1375e78bce8a040df5c600c8d3552ef2394" + sha256: e3641ec5d63ebf0d9b41bd43201a66e3fc79a65db5f61fc181f04cd27aab950c url: "https://pub.dev" source: hosted - version: "1.17.0" + version: "1.16.0" mime: dependency: transitive description: @@ -1297,10 +1297,10 @@ packages: dependency: transitive description: name: test_api - sha256: "8161c84903fd860b26bfdefb7963b3f0b68fee7adea0f59ef805ecca346f0c7a" + sha256: "522f00f556e73044315fa4585ec3270f1808a4b186c936e612cab0b565ff1e00" url: "https://pub.dev" source: hosted - version: "0.7.10" + version: "0.7.6" toastification: dependency: "direct main" description: @@ -1502,5 +1502,5 @@ packages: source: hosted version: "3.1.3" sdks: - dart: ">=3.9.0-0 <4.0.0" + dart: ">=3.8.1 <4.0.0" flutter: ">=3.32.0"