mirror of
https://github.com/SyncrowIOT/web.git
synced 2025-07-10 07:07:19 +00:00
start working on scheduling
This commit is contained in:
@ -12,6 +12,7 @@ class WaterHeaterBloc extends Bloc<WaterHeaterEvent, WaterHeaterState> {
|
||||
WaterHeaterBloc() : super(WaterHeaterInitial()) {
|
||||
on<WaterHeaterFetchStatusEvent>(_fetchWaterHeaterStatus);
|
||||
on<ToggleWaterHeaterEvent>(_controlWaterHeater);
|
||||
on<ShowScheduleViewEvent>(_showScheduleView);
|
||||
on<UpdateScheduleEvent>(_updateScheduleEvent);
|
||||
on<StopScheduleEvent>(_stopScheduleEvent);
|
||||
}
|
||||
@ -23,14 +24,24 @@ class WaterHeaterBloc extends Bloc<WaterHeaterEvent, WaterHeaterState> {
|
||||
UpdateScheduleEvent event,
|
||||
Emitter<WaterHeaterState> emit,
|
||||
) {
|
||||
emit(WaterHeaterScheduleState(
|
||||
scheduleType: event.scheduleType,
|
||||
emit(WaterHeaterScheduleViewState(
|
||||
scheduleMode: event.scheduleMode,
|
||||
hours: event.hours,
|
||||
minutes: event.minutes,
|
||||
isActive: true,
|
||||
));
|
||||
}
|
||||
|
||||
FutureOr<void> _showScheduleView(
|
||||
ShowScheduleViewEvent event, Emitter<WaterHeaterState> emit) {
|
||||
emit(const WaterHeaterScheduleViewState(
|
||||
scheduleMode: ScheduleModes.countdown,
|
||||
hours: 6,
|
||||
minutes: 23,
|
||||
isActive: false,
|
||||
));
|
||||
}
|
||||
|
||||
FutureOr<void> _stopScheduleEvent(
|
||||
StopScheduleEvent event,
|
||||
Emitter<WaterHeaterState> emit,
|
||||
|
@ -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<Object?> get props => [scheduleType, hours, minutes];
|
||||
List<Object?> get props => [scheduleMode, hours, minutes];
|
||||
}
|
||||
|
||||
final class StopScheduleEvent extends WaterHeaterEvent {}
|
||||
@ -47,3 +48,7 @@ class WaterHeaterFetchBatchStatusEvent extends WaterHeaterEvent {
|
||||
@override
|
||||
List<Object?> get props => [deviceId];
|
||||
}
|
||||
|
||||
class ShowScheduleViewEvent extends WaterHeaterEvent {
|
||||
const ShowScheduleViewEvent();
|
||||
}
|
||||
|
@ -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<Object> get props => [scheduleMode, hours, minutes];
|
||||
}
|
||||
|
@ -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<WaterHeaterBloc>().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<ScheduleModes>(
|
||||
value: ScheduleModes.countdown,
|
||||
groupValue: state.scheduleMode,
|
||||
onChanged: (ScheduleModes? value) {
|
||||
if (value != null) {
|
||||
context.read<WaterHeaterBloc>().add(UpdateScheduleEvent(
|
||||
scheduleMode: value,
|
||||
hours: state.hours,
|
||||
minutes: state.minutes,
|
||||
));
|
||||
}
|
||||
},
|
||||
),
|
||||
),
|
||||
),
|
||||
Expanded(
|
||||
child: ListTile(
|
||||
title: const Text('Schedule'),
|
||||
leading: Radio<ScheduleModes>(
|
||||
value: ScheduleModes.schedule,
|
||||
groupValue: state.scheduleMode,
|
||||
onChanged: (ScheduleModes? value) {
|
||||
if (value != null) {
|
||||
context.read<WaterHeaterBloc>().add(UpdateScheduleEvent(
|
||||
scheduleMode: value,
|
||||
hours: state.hours,
|
||||
minutes: state.minutes,
|
||||
));
|
||||
}
|
||||
},
|
||||
),
|
||||
),
|
||||
),
|
||||
Expanded(
|
||||
child: ListTile(
|
||||
title: const Text('Circulate'),
|
||||
leading: Radio<ScheduleModes>(
|
||||
value: ScheduleModes.circulate,
|
||||
groupValue: state.scheduleMode,
|
||||
onChanged: (ScheduleModes? value) {
|
||||
if (value != null) {
|
||||
context.read<WaterHeaterBloc>().add(UpdateScheduleEvent(
|
||||
scheduleMode: value,
|
||||
hours: state.hours,
|
||||
minutes: state.minutes,
|
||||
));
|
||||
}
|
||||
},
|
||||
),
|
||||
),
|
||||
),
|
||||
Expanded(
|
||||
child: ListTile(
|
||||
title: const Text('Inching'),
|
||||
leading: Radio<ScheduleModes>(
|
||||
value: ScheduleModes.inching,
|
||||
groupValue: state.scheduleMode,
|
||||
onChanged: (ScheduleModes? value) {
|
||||
if (value != null) {
|
||||
context.read<WaterHeaterBloc>().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<WaterHeaterBloc>().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<WaterHeaterBloc>().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),
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user