From 3b5b4041ce6903ddd4737076f4add7aa26de1fc2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Albert=20Ma=C3=B1osa?= Date: Sun, 15 Jan 2023 09:54:57 +0100 Subject: [PATCH] perf(booking_form): set `Cabin` reference on `CabinDropdown` changed (#184) * perf(booking_form): set `Cabin` reference on `CabinDropdown` changed * perf(cabin_dropdown): use `Cabin` object as dropdown value --- lib/widgets/booking/booking_form.dart | 304 ++++++++++++-------------- lib/widgets/cabin/cabin_dropdown.dart | 12 +- 2 files changed, 148 insertions(+), 168 deletions(-) diff --git a/lib/widgets/booking/booking_form.dart b/lib/widgets/booking/booking_form.dart index 465f1942..8afdf807 100644 --- a/lib/widgets/booking/booking_form.dart +++ b/lib/widgets/booking/booking_form.dart @@ -13,7 +13,6 @@ import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:flutter_gen/gen_l10n/app_localizations.dart'; import 'package:intl/intl.dart'; -import 'package:provider/provider.dart'; class BookingForm extends StatefulWidget { final Booking booking; @@ -61,6 +60,7 @@ class _BookingFormState extends State { _recurringEndDate = booking.recurringEndDate; _endDateController.text = DateFormat.yMd().format(_recurringEndDate!); + _occurrencesController.text = '${booking.occurrences}'; } } @@ -81,20 +81,15 @@ class _BookingFormState extends State { _startTimeController.text = _startTime!.format(context); _endTimeController.text = _endTime!.format(context); - final booking = _booking; - if (booking is RecurringBooking) { - _occurrencesController.text = '${booking.occurrences}'; - } - return Form( key: _formKey, child: Column( children: [ CabinDropdown( - value: _booking.cabin!.id, - onChanged: (value) { - if (value == null) return; - setState(() => _booking.cabin?.id = value); + cabin: _booking.cabin!, + onChanged: (cabin) { + if (cabin == null) return; + setState(() => _booking.cabin = cabin); }, ), const SizedBox(height: 24), @@ -126,167 +121,152 @@ class _BookingFormState extends State { children: [ Expanded( flex: 10, - child: Consumer( - builder: (context, cabinCollection, child) { - return TextFormField( - controller: _startTimeController, - decoration: InputDecoration( - icon: const Icon(Icons.schedule), - labelText: appLocalizations.start, - ), - onTap: () async { - final time = await showTimePicker( - context: context, - initialTime: _startTime!, - initialEntryMode: Platform.isMacOS || - Platform.isWindows || - Platform.isLinux - ? TimePickerEntryMode.input - : TimePickerEntryMode.dial, - ); - - if (time == null) return; - - setState(() { - _startTime = time; - _startTimeController.text = time.format(context); - }); - }, - onSaved: (value) { - final timeOfDay = - TimeOfDayExtension.tryParse(value ?? ''); - if (timeOfDay == null) return; - _booking.startDate = - _booking.startDate!.addLocalTimeOfDay(timeOfDay); - }, - validator: (value) { - if (value == null || value.isEmpty) { - return appLocalizations.enterStartTime; - } - - final parsedTimeOfDay = - TimeOfDayExtension.tryParse(value); - - if (parsedTimeOfDay == null) { - return appLocalizations.enterStartTime; - } - - _booking.startDate = _booking.startDate! - .addLocalTimeOfDay(parsedTimeOfDay); - - if (_startTime != parsedTimeOfDay) { - _startTime = parsedTimeOfDay; - } - - final parsedDateTime = widget.booking.dateOnly! - .addLocalTimeOfDay(parsedTimeOfDay); - - if (parsedDateTime.isAfter( - widget.booking.dateOnly!.addLocalTimeOfDay( - _endTime ?? TimeOfDay.now(), - ), - ) || - parsedDateTime.isBefore( - widget.booking.dateOnly! - .addLocalTimeOfDay(kTimeTableStartTime), - )) { - return appLocalizations.enterValidRange; - } - - if (cabinCollection - .cabinFromId(_booking.cabin?.id) - .bookingCollection - .bookingsOverlapWith(_booking)) { - return appLocalizations.occupied; - } - - return null; - }, - autovalidateMode: AutovalidateMode.always, + child: TextFormField( + controller: _startTimeController, + decoration: InputDecoration( + icon: const Icon(Icons.schedule), + labelText: appLocalizations.start, + ), + onTap: () async { + final time = await showTimePicker( + context: context, + initialTime: _startTime!, + initialEntryMode: Platform.isMacOS || + Platform.isWindows || + Platform.isLinux + ? TimePickerEntryMode.input + : TimePickerEntryMode.dial, ); + + if (time == null) return; + + setState(() { + _startTime = time; + _startTimeController.text = time.format(context); + }); + }, + onSaved: (value) { + final timeOfDay = TimeOfDayExtension.tryParse(value ?? ''); + if (timeOfDay == null) return; + _booking.startDate = + _booking.startDate!.addLocalTimeOfDay(timeOfDay); + }, + validator: (value) { + if (value == null || value.isEmpty) { + return appLocalizations.enterStartTime; + } + + final parsedTimeOfDay = TimeOfDayExtension.tryParse(value); + + if (parsedTimeOfDay == null) { + return appLocalizations.enterStartTime; + } + + _booking.startDate = + _booking.startDate!.addLocalTimeOfDay(parsedTimeOfDay); + + if (_startTime != parsedTimeOfDay) { + _startTime = parsedTimeOfDay; + } + + final parsedDateTime = widget.booking.dateOnly! + .addLocalTimeOfDay(parsedTimeOfDay); + + if (parsedDateTime.isAfter( + widget.booking.dateOnly!.addLocalTimeOfDay( + _endTime ?? TimeOfDay.now(), + ), + ) || + parsedDateTime.isBefore( + widget.booking.dateOnly! + .addLocalTimeOfDay(kTimeTableStartTime), + )) { + return appLocalizations.enterValidRange; + } + + if (_booking.cabin?.bookingCollection + .bookingsOverlapWith(_booking) ?? + false) { + return appLocalizations.occupied; + } + + return null; }, + autovalidateMode: AutovalidateMode.always, ), ), const SizedBox(width: 16), Expanded( flex: 8, - child: Consumer( - builder: (context, cabinCollection, child) { - return TextFormField( - controller: _endTimeController, - decoration: - InputDecoration(labelText: appLocalizations.end), - onTap: () async { - final time = await showTimePicker( - context: context, - initialTime: _endTime!, - initialEntryMode: Platform.isMacOS || - Platform.isWindows || - Platform.isLinux - ? TimePickerEntryMode.input - : TimePickerEntryMode.dial, - ); - - if (time == null) return; - - setState(() { - _endTime = time; - _endTimeController.text = time.format(context); - }); - }, - onSaved: (value) { - final timeOfDay = - TimeOfDayExtension.tryParse(value ?? ''); - if (timeOfDay == null) return; - _booking.endDate = - _booking.endDate!.addLocalTimeOfDay(timeOfDay); - }, - validator: (value) { - if (value == null || value.isEmpty) { - return appLocalizations.enterEndTime; - } - - final parsedTimeOfDay = - TimeOfDayExtension.tryParse(value); - - if (parsedTimeOfDay == null) { - return appLocalizations.enterEndTime; - } - - _booking.endDate = _booking.endDate! - .addLocalTimeOfDay(parsedTimeOfDay); - - if (_endTime != parsedTimeOfDay) { - _endTime = parsedTimeOfDay; - } - - final parsedDateTime = widget.booking.dateOnly! - .addLocalTimeOfDay(parsedTimeOfDay); - - if (parsedDateTime.isBefore( - widget.booking.dateOnly!.addLocalTimeOfDay( - _startTime ?? TimeOfDay.now(), - ), - ) || - parsedDateTime.isAfter( - widget.booking.dateOnly! - .addLocalTimeOfDay(kTimeTableEndTime), - )) { - return appLocalizations.enterValidRange; - } - - if (cabinCollection - .cabinFromId(_booking.cabin?.id) - .bookingCollection - .bookingsOverlapWith(_booking)) { - return appLocalizations.occupied; - } - - return null; - }, - autovalidateMode: AutovalidateMode.always, + child: TextFormField( + controller: _endTimeController, + decoration: InputDecoration(labelText: appLocalizations.end), + onTap: () async { + final time = await showTimePicker( + context: context, + initialTime: _endTime!, + initialEntryMode: Platform.isMacOS || + Platform.isWindows || + Platform.isLinux + ? TimePickerEntryMode.input + : TimePickerEntryMode.dial, ); + + if (time == null) return; + + setState(() { + _endTime = time; + _endTimeController.text = time.format(context); + }); + }, + onSaved: (value) { + final timeOfDay = TimeOfDayExtension.tryParse(value ?? ''); + if (timeOfDay == null) return; + _booking.endDate = + _booking.endDate!.addLocalTimeOfDay(timeOfDay); + }, + validator: (value) { + if (value == null || value.isEmpty) { + return appLocalizations.enterEndTime; + } + + final parsedTimeOfDay = TimeOfDayExtension.tryParse(value); + + if (parsedTimeOfDay == null) { + return appLocalizations.enterEndTime; + } + + _booking.endDate = + _booking.endDate!.addLocalTimeOfDay(parsedTimeOfDay); + + if (_endTime != parsedTimeOfDay) { + _endTime = parsedTimeOfDay; + } + + final parsedDateTime = widget.booking.dateOnly! + .addLocalTimeOfDay(parsedTimeOfDay); + + if (parsedDateTime.isBefore( + widget.booking.dateOnly!.addLocalTimeOfDay( + _startTime ?? TimeOfDay.now(), + ), + ) || + parsedDateTime.isAfter( + widget.booking.dateOnly! + .addLocalTimeOfDay(kTimeTableEndTime), + )) { + return appLocalizations.enterValidRange; + } + + if (_booking.cabin?.bookingCollection + .bookingsOverlapWith(_booking) ?? + false) { + return appLocalizations.occupied; + } + + return null; }, + autovalidateMode: AutovalidateMode.always, ), ), ], diff --git a/lib/widgets/cabin/cabin_dropdown.dart b/lib/widgets/cabin/cabin_dropdown.dart index 10aee0ad..3b36f3ba 100644 --- a/lib/widgets/cabin/cabin_dropdown.dart +++ b/lib/widgets/cabin/cabin_dropdown.dart @@ -4,26 +4,26 @@ import 'package:flutter_gen/gen_l10n/app_localizations.dart'; import 'package:provider/provider.dart'; class CabinDropdown extends StatelessWidget { - final String value; - final void Function(String?)? onChanged; + final Cabin cabin; + final void Function(Cabin?)? onChanged; - const CabinDropdown({super.key, required this.value, this.onChanged}); + const CabinDropdown({super.key, required this.cabin, this.onChanged}); @override Widget build(BuildContext context) { return Consumer( builder: (context, cabinCollection, child) { - return DropdownButtonFormField( + return DropdownButtonFormField( items: [ for (final cabin in cabinCollection.cabins) DropdownMenuItem( - value: cabin.id, + value: cabin, child: Text( '${AppLocalizations.of(context)!.cabin} ${cabin.number}', ), ), ], - value: value, + value: cabin, onChanged: onChanged, isExpanded: true, );