@@ -83,14 +83,8 @@ class _ShopInBitTravelFormState extends ConsumerState<ShopInBitTravelForm> {
8383 final FocusNode _destinationsFocusNode = FocusNode ();
8484 bool _destinationsTouched = false ;
8585
86- final TextEditingController _departureDateController =
87- TextEditingController ();
88- final FocusNode _departureDateFocusNode = FocusNode ();
89- bool _departureDateTouched = false ;
90-
91- final TextEditingController _returnDateController = TextEditingController ();
92- final FocusNode _returnDateFocusNode = FocusNode ();
93- bool _returnDateTouched = false ;
86+ DateTime ? _departureDate;
87+ DateTime ? _returnDate;
9488
9589 final TextEditingController _tripLengthController = TextEditingController ();
9690 final FocusNode _tripLengthFocusNode = FocusNode ();
@@ -130,11 +124,6 @@ class _ShopInBitTravelFormState extends ConsumerState<ShopInBitTravelForm> {
130124 () => _departureCityTouched = true ,
131125 );
132126 _wireTouchOnBlur (_destinationsFocusNode, () => _destinationsTouched = true );
133- _wireTouchOnBlur (
134- _departureDateFocusNode,
135- () => _departureDateTouched = true ,
136- );
137- _wireTouchOnBlur (_returnDateFocusNode, () => _returnDateTouched = true );
138127 _wireTouchOnBlur (_tripLengthFocusNode, () => _tripLengthTouched = true );
139128 _wireTouchOnBlur (_travelBudgetFocusNode, () => _travelBudgetTouched = true );
140129 }
@@ -154,10 +143,6 @@ class _ShopInBitTravelFormState extends ConsumerState<ShopInBitTravelForm> {
154143 _departureCityFocusNode.dispose ();
155144 _destinationsController.dispose ();
156145 _destinationsFocusNode.dispose ();
157- _departureDateController.dispose ();
158- _departureDateFocusNode.dispose ();
159- _returnDateController.dispose ();
160- _returnDateFocusNode.dispose ();
161146 _tripLengthController.dispose ();
162147 _tripLengthFocusNode.dispose ();
163148 _travelBudgetController.dispose ();
@@ -170,9 +155,7 @@ class _ShopInBitTravelFormState extends ConsumerState<ShopInBitTravelForm> {
170155 _selectedYear != null &&
171156 _selectedMonthSeason != null &&
172157 _tripLengthController.text.trim ().isNotEmpty,
173- _exactDates =>
174- _departureDateController.text.trim ().isNotEmpty &&
175- _returnDateController.text.trim ().isNotEmpty,
158+ _exactDates => _departureDate != null && _returnDate != null ,
176159 _ => false ,
177160 };
178161
@@ -196,25 +179,6 @@ class _ShopInBitTravelFormState extends ConsumerState<ShopInBitTravelForm> {
196179 travelBudgetValue >= _minTravelBudget;
197180 }
198181
199- Future <void > _pickDate (
200- TextEditingController target,
201- VoidCallback onPicked,
202- ) async {
203- final now = DateTime .now ();
204- final DateTime ? picked = (await showSWDatePicker (
205- context,
206- firstDate: now,
207- lastDate: now.add (const Duration (days: 3650 )),
208- currentDate: _current,
209- ))? .first;
210- if (picked != null ) {
211- setState (() {
212- target.text = _formatDate (picked);
213- onPicked ();
214- });
215- }
216- }
217-
218182 String _formatDate (DateTime date) {
219183 final String day = date.day.toString ().padLeft (2 , "0" );
220184 final String month = date.month.toString ().padLeft (2 , "0" );
@@ -241,8 +205,8 @@ class _ShopInBitTravelFormState extends ConsumerState<ShopInBitTravelForm> {
241205 ? " ($_selectedFlexibility )"
242206 : "" ;
243207 parts.add (
244- "Dates: ${_departureDateController . text . trim ( )} - "
245- "${_returnDateController . text . trim ( )}$flex " ,
208+ "Dates: ${_formatDate ( _departureDate ! )} - "
209+ "${_formatDate ( _returnDate ! )}$flex " ,
246210 );
247211 } else if (_selectedDateMode == _flexibleDates) {
248212 parts.add (
@@ -311,16 +275,6 @@ class _ShopInBitTravelFormState extends ConsumerState<ShopInBitTravelForm> {
311275 ? "Required (or check 'I need recommendations')"
312276 : null ;
313277
314- final String ? departureDateError =
315- _departureDateTouched && _departureDateController.text.trim ().isEmpty
316- ? "Required"
317- : null ;
318-
319- final String ? returnDateError =
320- _returnDateTouched && _returnDateController.text.trim ().isEmpty
321- ? "Required"
322- : null ;
323-
324278 final String ? tripLengthError =
325279 _tripLengthTouched && _tripLengthController.text.trim ().isEmpty
326280 ? "Required"
@@ -419,36 +373,17 @@ class _ShopInBitTravelFormState extends ConsumerState<ShopInBitTravelForm> {
419373 SizedBox (height: isDesktop ? 24 : 16 ),
420374
421375 if (_selectedDateMode == _exactDates) ...[
422- AdaptiveTextField (
423- controller: _departureDateController,
424- focusNode: _departureDateFocusNode,
425- labelText: "Departure date" ,
426- hintText: "DD/MM/YYYY" ,
427- readOnly: true ,
428- onTap: () => _pickDate (
429- _departureDateController,
430- () => _departureDateTouched = true ,
431- ),
432- suffixIcons: const [Icon (Icons .calendar_today, size: 18 )],
433- autocorrect: false ,
434- enableSuggestions: false ,
435- errorText: departureDateError,
436- ),
437- SizedBox (height: isDesktop ? 24 : 16 ),
438- AdaptiveTextField (
439- controller: _returnDateController,
440- focusNode: _returnDateFocusNode,
441- labelText: "Return date" ,
442- hintText: "DD/MM/YYYY" ,
443- readOnly: true ,
444- onTap: () => _pickDate (
445- _returnDateController,
446- () => _returnDateTouched = true ,
447- ),
448- suffixIcons: const [Icon (Icons .calendar_today, size: 18 )],
449- autocorrect: false ,
450- enableSuggestions: false ,
451- errorText: returnDateError,
376+ StackDateRangePicker (
377+ fromDate: _departureDate,
378+ toDate: _returnDate,
379+ firstDate: DateTime .now (),
380+ lastDate: DateTime .now ().add (const Duration (days: 3650 )),
381+ onChanged: (from, to) {
382+ setState (() {
383+ _departureDate = from;
384+ _returnDate = to;
385+ });
386+ },
452387 ),
453388 SizedBox (height: isDesktop ? 24 : 16 ),
454389 ShopInBitStep4Dropdown (
0 commit comments