diff --git a/lib/presentation/screens/Enquiry/enquiryList.dart b/lib/presentation/screens/Enquiry/enquiryList.dart index 1302f01..c336083 100644 --- a/lib/presentation/screens/Enquiry/enquiryList.dart +++ b/lib/presentation/screens/Enquiry/enquiryList.dart @@ -17,6 +17,7 @@ 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'; import '../../widgets/custom_action_popup.dart'; class EnquiryList extends ConsumerStatefulWidget { @@ -69,7 +70,7 @@ class EnquiryListState extends ConsumerState { }); } - void filterDateRange() { + void filterDateRange1() { print("filterDateRange"); // if (!_formKey.currentState!.validate()) return; @@ -80,6 +81,32 @@ class EnquiryListState extends ConsumerState { getStaffList(userId, roleId); } + void filterDateRange() { + // ✅ Validate the form first + if (!_formKey.currentState!.validate()) { + // stop execution if validation fails + return; + } + + final fromDateText = controllers['startDate']?.text ?? ''; + final toDateText = controllers['endDate']?.text ?? ''; + + // Optional: double-check End >= Start + final fromDate = DateFormat('dd-MM-yyyy').parse(fromDateText); + final toDate = DateFormat('dd-MM-yyyy').parse(toDateText); + + if (toDate.isBefore(fromDate)) { + // This is already caught by the validator, but extra safety + ScaffoldMessenger.of(context).showSnackBar( + SnackBar(content: Text("End Date cannot be earlier than Start Date")), + ); + return; + } + + // ✅ Call your API + getStaffList(userId, roleId); + } + void refrshfilterDateRange() { setState(() { controllers['startDate']!.clear(); @@ -87,6 +114,8 @@ class EnquiryListState extends ConsumerState { controllers['startDate']?.text = ''; controllers['endDate']?.text = ''; + // Reset the FormField validation + _formKey.currentState?.reset(); }); getStaffList(userId, roleId); } @@ -363,42 +392,19 @@ class EnquiryListState extends ConsumerState { Container( padding: EdgeInsets.all(8.0), color: Color(0xffD9EBE8), - child: Form( - key: _formKey, - child: Column( - crossAxisAlignment: CrossAxisAlignment.end, - mainAxisAlignment: MainAxisAlignment.end, - children: [ - buildStartDate(context), - SizedBox(height: 10), - buildEndDate(context), - // SizedBox(height: 10), - Row( - crossAxisAlignment: CrossAxisAlignment.end, - mainAxisAlignment: MainAxisAlignment.end, - children: [ - Padding( - padding: const EdgeInsets.all(8.0), - child: GestureDetector( - onTap: filterDateRange, - child: Icon( - Icons.filter_list_outlined, - size: 18, - ), - ), - ), - - Padding( - padding: const EdgeInsets.all(8.0), - child: GestureDetector( - onTap: refrshfilterDateRange, - child: Icon(Icons.refresh, size: 18), - ), - ), - ], - ), - ], - ), + child: DateFilterRow( + startController: controllers['startDate']!, + endController: controllers['endDate']!, + formKey: _formKey, + isMobile: ResponsiveLayout.isMobile(context), + onFilter: () { + // call your filter logic + filterDateRange(); + }, + onRefresh: () { + // call your refresh logic + refrshfilterDateRange(); + }, ), ), ], @@ -411,26 +417,57 @@ class EnquiryListState extends ConsumerState { mainAxisAlignment: MainAxisAlignment.start, children: [ if (!ResponsiveLayout.isMobile(context)) ...[ - buildStartDate(context), - SizedBox(width: 10), - buildEndDate(context), - SizedBox(width: 10), - - Padding( - padding: const EdgeInsets.all(8.0), - child: GestureDetector( - onTap: filterDateRange, - child: Icon(Icons.filter_list_outlined), - ), + DateFilterRow( + startController: controllers['startDate']!, + endController: controllers['endDate']!, + formKey: _formKey, + isMobile: ResponsiveLayout.isMobile(context), + onFilter: () { + // call your filter logic + filterDateRange(); + }, + onRefresh: () { + // call your refresh logic + refrshfilterDateRange(); + }, ), - Padding( - padding: const EdgeInsets.all(8.0), - child: GestureDetector( - onTap: refrshfilterDateRange, - child: Icon(Icons.refresh), - ), - ), + // Form( + // key: _formKey, + // child: Row( + // mainAxisAlignment: MainAxisAlignment.start, + // crossAxisAlignment: CrossAxisAlignment.end, + // children: [ + // buildStartDate(context), + // SizedBox(width: 10), + // buildEndDate(context), + // SizedBox(width: 10), + // + // Padding( + // padding: const EdgeInsets.symmetric( + // vertical: 8.0, + // ), + // child: GestureDetector( + // // onTap: filterDateRange, + // onTap: () { + // if (_formKey.currentState!.validate()) { + // filterDateRange(); // only runs if valid + // } + // }, + // child: Icon(Icons.filter_alt_outlined), + // ), + // ), + // + // Padding( + // padding: const EdgeInsets.all(8.0), + // child: GestureDetector( + // onTap: refrshfilterDateRange, + // child: Icon(Icons.refresh), + // ), + // ), + // ], + // ), + // ), Spacer(), ], ThemedSearchField( @@ -949,8 +986,24 @@ class EnquiryListState extends ConsumerState { : MediaQuery.of(context).size.width * 0.16, // txtheight: 50, // backgroundColor: const Color(0xFFECECEC), - // validator: (value) => Validators.requiredField(value, "date"), + 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("Picked Date: $date"); controllers['endDate']?.text = DateFormat( diff --git a/lib/presentation/themes/indicators/date_field_theme.dart b/lib/presentation/themes/indicators/date_field_theme.dart index 33b8603..643a803 100644 --- a/lib/presentation/themes/indicators/date_field_theme.dart +++ b/lib/presentation/themes/indicators/date_field_theme.dart @@ -14,7 +14,8 @@ class ThemedDateField extends StatefulWidget { this.errorBorderColor, this.onDateSelected, this.controller, - this.validator, // ✅ new + this.validator, + this.lastDate, // ✅ new }); final String? hintText; @@ -26,6 +27,7 @@ class ThemedDateField extends StatefulWidget { final TextEditingController? controller; final Function(DateTime)? onDateSelected; final String? Function(String? value)? validator; // ✅ new + final DateTime? lastDate; @override State createState() => _ThemedDateFieldState(); @@ -42,7 +44,8 @@ class _ThemedDateFieldState extends State { context: context, initialDate: selectedDate ?? DateTime.now(), firstDate: DateTime(2000), - lastDate: DateTime(2100), + // lastDate: DateTime(2100), + lastDate: widget.lastDate ?? DateTime(2100), initialEntryMode: DatePickerEntryMode.calendarOnly, ); diff --git a/lib/presentation/widgets/custom_Stdate_EnDate_Filter.dart b/lib/presentation/widgets/custom_Stdate_EnDate_Filter.dart new file mode 100644 index 0000000..7eeeb15 --- /dev/null +++ b/lib/presentation/widgets/custom_Stdate_EnDate_Filter.dart @@ -0,0 +1,202 @@ +import 'package:flutter/material.dart'; +import 'package:intl/intl.dart'; +import '../layouts/responsive_layout.dart'; +import '../themes/indicators/date_field_theme.dart'; + +class DateFilterRow extends StatelessWidget { + final TextEditingController startController; + final TextEditingController endController; + final VoidCallback onFilter; + final VoidCallback onRefresh; + final GlobalKey formKey; + final bool isMobile; + + const DateFilterRow({ + super.key, + required this.startController, + required this.endController, + required this.onFilter, + required this.onRefresh, + required this.formKey, + this.isMobile = false, + }); + + @override + Widget build(BuildContext context) { + final spacing = 10.0; + + // final rowChildren = [ + // buildStartDate(context), + // SizedBox(width: spacing), + // buildEndDate(context), + // SizedBox(width: spacing), + // Padding( + // padding: const EdgeInsets.symmetric(vertical: 8.0), + // child: GestureDetector( + // onTap: () { + // if (formKey.currentState!.validate()) onFilter(); + // }, + // child: Icon(Icons.filter_alt_outlined), + // ), + // ), + // Padding( + // padding: const EdgeInsets.all(8.0), + // child: GestureDetector(onTap: onRefresh, child: Icon(Icons.refresh)), + // ), + // ]; + + List getRowChildren(bool isMobile, double spacing) { + final dateFields = [ + buildStartDate(context), + SizedBox(width: spacing), + buildEndDate(context), + SizedBox(width: spacing), + ]; + + final buttons = [ + Padding( + padding: const EdgeInsets.symmetric(vertical: 8.0), + child: GestureDetector( + onTap: () { + if (formKey.currentState!.validate()) onFilter(); + }, + child: Icon(Icons.filter_alt_outlined), + ), + ), + Padding( + padding: const EdgeInsets.all(8.0), + child: GestureDetector(onTap: onRefresh, child: Icon(Icons.refresh)), + ), + ]; + + 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, ...buttons]; + } + } + + return Form( + key: formKey, + child: isMobile + ? Column( + crossAxisAlignment: CrossAxisAlignment.end, + children: getRowChildren(isMobile, spacing), + ) + : Row( + crossAxisAlignment: CrossAxisAlignment.end, + children: getRowChildren(isMobile, spacing), + ), + ); + } + + 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: startController, + onDateSelected: (date) { + print("Picked Date: $date"); + + startController.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 = startController.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: endController, + lastDate: DateTime.now(), + onDateSelected: (date) { + print("Picked Date: $date"); + endController.text = DateFormat('dd-MM-yyyy').format(date); + // controllers['date']?.text = date as String; + }, + ), + ], + ); + } + + static const _textStyle = TextStyle( + fontSize: 12, + fontWeight: FontWeight.w600, + ); + + Widget buildStartDate1() { + return ThemedDateField( + controller: startController, + hintText: 'Select Start Date', + validator: (value) => + value == null || value.isEmpty ? "Start Date required" : null, + onDateSelected: (date) => + startController.text = DateFormat('dd-MM-yyyy').format(date), + ); + } + + Widget buildEndDate1() { + return ThemedDateField( + controller: endController, + hintText: 'Select End Date', + lastDate: DateTime.now(), + validator: (value) { + if (value == null || value.isEmpty) return "End Date required"; + + if (startController.text.isNotEmpty) { + final start = DateFormat('dd-MM-yyyy').parse(startController.text); + final end = DateFormat('dd-MM-yyyy').parse(value); + if (end.isBefore(start)) + return "End Date cannot be earlier than Start Date"; + } + return null; + }, + onDateSelected: (date) => + endController.text = DateFormat('dd-MM-yyyy').format(date), + ); + } +}