diff --git a/lib/pages/device_managment/water_heater/bloc/water_heater_bloc.dart b/lib/pages/device_managment/water_heater/bloc/water_heater_bloc.dart index 47632653..01507097 100644 --- a/lib/pages/device_managment/water_heater/bloc/water_heater_bloc.dart +++ b/lib/pages/device_managment/water_heater/bloc/water_heater_bloc.dart @@ -12,6 +12,7 @@ class WaterHeaterBloc extends Bloc { WaterHeaterBloc() : super(WaterHeaterInitial()) { on(_fetchWaterHeaterStatus); on(_controlWaterHeater); + on(_showScheduleView); on(_updateScheduleEvent); on(_stopScheduleEvent); } @@ -23,14 +24,24 @@ class WaterHeaterBloc extends Bloc { UpdateScheduleEvent event, Emitter emit, ) { - emit(WaterHeaterScheduleState( - scheduleType: event.scheduleType, + emit(WaterHeaterScheduleViewState( + scheduleMode: event.scheduleMode, hours: event.hours, minutes: event.minutes, isActive: true, )); } + FutureOr _showScheduleView( + ShowScheduleViewEvent event, Emitter emit) { + emit(const WaterHeaterScheduleViewState( + scheduleMode: ScheduleModes.countdown, + hours: 6, + minutes: 23, + isActive: false, + )); + } + FutureOr _stopScheduleEvent( StopScheduleEvent event, Emitter emit, diff --git a/lib/pages/device_managment/water_heater/bloc/water_heater_event.dart b/lib/pages/device_managment/water_heater/bloc/water_heater_event.dart index 3adf23dd..2f508a35 100644 --- a/lib/pages/device_managment/water_heater/bloc/water_heater_event.dart +++ b/lib/pages/device_managment/water_heater/bloc/water_heater_event.dart @@ -18,14 +18,15 @@ final class ToggleWaterHeaterEvent extends WaterHeaterEvent { } final class UpdateScheduleEvent extends WaterHeaterEvent { - final ScheduleType scheduleType; + final ScheduleModes scheduleMode; final int hours; final int minutes; - const UpdateScheduleEvent(this.scheduleType, this.hours, this.minutes); + const UpdateScheduleEvent( + {required this.scheduleMode, required this.hours, required this.minutes}); @override - List get props => [scheduleType, hours, minutes]; + List get props => [scheduleMode, hours, minutes]; } final class StopScheduleEvent extends WaterHeaterEvent {} @@ -47,3 +48,7 @@ class WaterHeaterFetchBatchStatusEvent extends WaterHeaterEvent { @override List get props => [deviceId]; } + +class ShowScheduleViewEvent extends WaterHeaterEvent { + const ShowScheduleViewEvent(); +} diff --git a/lib/pages/device_managment/water_heater/bloc/water_heater_state.dart b/lib/pages/device_managment/water_heater/bloc/water_heater_state.dart index bc9ac051..349be2be 100644 --- a/lib/pages/device_managment/water_heater/bloc/water_heater_state.dart +++ b/lib/pages/device_managment/water_heater/bloc/water_heater_state.dart @@ -21,7 +21,7 @@ final class WaterHeaterToggleState extends WaterHeaterState { } final class WaterHeaterScheduleState extends WaterHeaterState { - final ScheduleType scheduleType; + final ScheduleModes scheduleType; final int hours; final int minutes; final bool isActive; @@ -74,3 +74,20 @@ final class WaterHeaterBatchFailedState extends WaterHeaterState { } final class WaterHeaterLoadingState extends WaterHeaterState {} + +class WaterHeaterScheduleViewState extends WaterHeaterState { + final ScheduleModes scheduleMode; + final int hours; + final int minutes; + final bool isActive; + + const WaterHeaterScheduleViewState({ + required this.scheduleMode, + required this.hours, + required this.minutes, + required this.isActive, + }); + + @override + List get props => [scheduleMode, hours, minutes]; +} diff --git a/lib/pages/device_managment/water_heater/view/water_heater_device_control.dart b/lib/pages/device_managment/water_heater/view/water_heater_device_control.dart index 75a697e3..2d975370 100644 --- a/lib/pages/device_managment/water_heater/view/water_heater_device_control.dart +++ b/lib/pages/device_managment/water_heater/view/water_heater_device_control.dart @@ -28,6 +28,8 @@ class WaterHeaterDeviceControl extends StatelessWidget return const Center(child: CircularProgressIndicator()); } else if (state is WaterHeaterDeviceStatusLoaded) { return _buildStatusControls(context, state.status); + } else if (state is WaterHeaterScheduleViewState) { + return _buildScheduleView(context, state); } else if (state is WaterHeaterFailedState || state is WaterHeaterBatchFailedState) { return const Center(child: Text('Error fetching status')); @@ -66,39 +68,223 @@ class WaterHeaterDeviceControl extends StatelessWidget )); }, ), - DeviceControlsContainer( - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Container( - width: 60, - height: 60, - decoration: const BoxDecoration( - shape: BoxShape.circle, - color: ColorsManager.whiteColors, - ), - margin: const EdgeInsets.symmetric(horizontal: 4), - padding: const EdgeInsets.all(12), - child: ClipOval( - child: SvgPicture.asset( - Assets.scheduling, - fit: BoxFit.fill, + GestureDetector( + onTap: () { + context.read().add(const ShowScheduleViewEvent()); + }, + child: DeviceControlsContainer( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Container( + width: 60, + height: 60, + decoration: const BoxDecoration( + shape: BoxShape.circle, + color: ColorsManager.whiteColors, + ), + margin: const EdgeInsets.symmetric(horizontal: 4), + padding: const EdgeInsets.all(12), + child: ClipOval( + child: SvgPicture.asset( + Assets.scheduling, + fit: BoxFit.fill, + ), ), ), - ), - const Spacer(), - Text( - 'Scheduling', - textAlign: TextAlign.center, - style: context.textTheme.titleMedium!.copyWith( - fontWeight: FontWeight.w400, - color: ColorsManager.blackColor, + const Spacer(), + Text( + 'Scheduling', + textAlign: TextAlign.center, + style: context.textTheme.titleMedium!.copyWith( + fontWeight: FontWeight.w400, + color: ColorsManager.blackColor, + ), ), - ), - ], + ], + ), ), ) ], ); } + + Widget _buildScheduleView( + BuildContext context, WaterHeaterScheduleViewState state) { + return Padding( + padding: const EdgeInsets.symmetric(horizontal: 16.0), + child: Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + 'Scheduling', + style: context.textTheme.titleLarge!.copyWith( + fontWeight: FontWeight.bold, + color: ColorsManager.dialogBlueTitle, + ), + ), + const SizedBox(height: 20), + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Expanded( + child: ListTile( + title: const Text('Countdown'), + leading: Radio( + value: ScheduleModes.countdown, + groupValue: state.scheduleMode, + onChanged: (ScheduleModes? value) { + if (value != null) { + context.read().add(UpdateScheduleEvent( + scheduleMode: value, + hours: state.hours, + minutes: state.minutes, + )); + } + }, + ), + ), + ), + Expanded( + child: ListTile( + title: const Text('Schedule'), + leading: Radio( + value: ScheduleModes.schedule, + groupValue: state.scheduleMode, + onChanged: (ScheduleModes? value) { + if (value != null) { + context.read().add(UpdateScheduleEvent( + scheduleMode: value, + hours: state.hours, + minutes: state.minutes, + )); + } + }, + ), + ), + ), + Expanded( + child: ListTile( + title: const Text('Circulate'), + leading: Radio( + value: ScheduleModes.circulate, + groupValue: state.scheduleMode, + onChanged: (ScheduleModes? value) { + if (value != null) { + context.read().add(UpdateScheduleEvent( + scheduleMode: value, + hours: state.hours, + minutes: state.minutes, + )); + } + }, + ), + ), + ), + Expanded( + child: ListTile( + title: const Text('Inching'), + leading: Radio( + value: ScheduleModes.inching, + groupValue: state.scheduleMode, + onChanged: (ScheduleModes? value) { + if (value != null) { + context.read().add(UpdateScheduleEvent( + scheduleMode: value, + hours: state.hours, + minutes: state.minutes, + )); + } + }, + ), + ), + ), + ], + ), + const SizedBox(height: 20), + if (state.scheduleMode == ScheduleModes.countdown || + state.scheduleMode == ScheduleModes.inching) ...[ + Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + // Hours input + _buildTimeInputField( + label: 'h', + initialValue: state.hours.toString(), + onChanged: (value) { + int hours = int.tryParse(value) ?? 0; + context.read().add(UpdateScheduleEvent( + scheduleMode: state.scheduleMode, + hours: hours, + minutes: state.minutes, + )); + }, + ), + const SizedBox(width: 10), + // Minutes input + _buildTimeInputField( + label: 'm', + initialValue: state.minutes.toString(), + onChanged: (value) { + int minutes = int.tryParse(value) ?? 0; + context.read().add(UpdateScheduleEvent( + scheduleMode: state.scheduleMode, + hours: state.hours, + minutes: minutes, + )); + }, + ), + ], + ), + ], + const SizedBox(height: 20), + Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + ElevatedButton( + onPressed: () { + Navigator.of(context) + .pop(); // Close the dialog or scheduling view + }, + style: ElevatedButton.styleFrom( + backgroundColor: Colors.grey[400], + ), + child: const Text('Cancel'), + ), + const SizedBox(width: 20), + ElevatedButton( + onPressed: () { + // Handle saving schedule logic + }, + child: const Text('Save'), + ), + ], + ), + ], + ), + ); + } + + Widget _buildTimeInputField({ + required String label, + required String initialValue, + required Function(String) onChanged, + }) { + return Column( + children: [ + Text(label, style: const TextStyle(fontSize: 18)), + SizedBox( + width: 50, + child: TextField( + keyboardType: TextInputType.number, + textAlign: TextAlign.center, + decoration: const InputDecoration(border: UnderlineInputBorder()), + onChanged: onChanged, + controller: TextEditingController(text: initialValue), + ), + ), + ], + ); + } }