mirror of
https://github.com/SyncrowIOT/web.git
synced 2025-07-10 15:17:31 +00:00
working on schedual table
This commit is contained in:
@ -17,6 +17,7 @@ class DefaultButton extends StatelessWidget {
|
|||||||
this.borderRadius,
|
this.borderRadius,
|
||||||
this.height,
|
this.height,
|
||||||
this.padding,
|
this.padding,
|
||||||
|
this.borderColor,
|
||||||
});
|
});
|
||||||
final void Function()? onPressed;
|
final void Function()? onPressed;
|
||||||
final Widget child;
|
final Widget child;
|
||||||
@ -31,6 +32,8 @@ class DefaultButton extends StatelessWidget {
|
|||||||
final ButtonStyle? customButtonStyle;
|
final ButtonStyle? customButtonStyle;
|
||||||
final Color? backgroundColor;
|
final Color? backgroundColor;
|
||||||
final Color? foregroundColor;
|
final Color? foregroundColor;
|
||||||
|
final Color? borderColor;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return ElevatedButton(
|
return ElevatedButton(
|
||||||
@ -61,6 +64,7 @@ class DefaultButton extends StatelessWidget {
|
|||||||
}),
|
}),
|
||||||
shape: MaterialStateProperty.all(
|
shape: MaterialStateProperty.all(
|
||||||
RoundedRectangleBorder(
|
RoundedRectangleBorder(
|
||||||
|
side: BorderSide(color: borderColor ?? Colors.transparent),
|
||||||
borderRadius: BorderRadius.circular(borderRadius ?? 20),
|
borderRadius: BorderRadius.circular(borderRadius ?? 20),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
@ -163,9 +163,27 @@ class _BuildScheduleViewState extends State<BuildScheduleView> {
|
|||||||
return Column(
|
return Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
ElevatedButton(
|
SizedBox(
|
||||||
onPressed: () => _showAddScheduleDialog(context),
|
width: 170,
|
||||||
child: Text('+ Add new schedule'),
|
height: 40,
|
||||||
|
child: DefaultButton(
|
||||||
|
borderColor: ColorsManager.boxColor,
|
||||||
|
padding: 2,
|
||||||
|
backgroundColor: ColorsManager.graysColor,
|
||||||
|
borderRadius: 15,
|
||||||
|
onPressed: () => _showAddScheduleDialog(context),
|
||||||
|
child: Row(
|
||||||
|
children: [
|
||||||
|
const Icon(Icons.add, color: ColorsManager.primaryColor),
|
||||||
|
Text(
|
||||||
|
' Add new schedule',
|
||||||
|
style: context.textTheme.bodySmall!.copyWith(
|
||||||
|
color: ColorsManager.blackColor,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
),
|
),
|
||||||
const SizedBox(height: 20),
|
const SizedBox(height: 20),
|
||||||
_buildScheduleTable(state),
|
_buildScheduleTable(state),
|
||||||
@ -219,8 +237,8 @@ class _BuildScheduleViewState extends State<BuildScheduleView> {
|
|||||||
children: [
|
children: [
|
||||||
Center(
|
Center(
|
||||||
child: schedule.functionOn
|
child: schedule.functionOn
|
||||||
? Icon(Icons.radio_button_checked)
|
? const Icon(Icons.radio_button_checked)
|
||||||
: Icon(Icons.radio_button_unchecked)),
|
: const Icon(Icons.radio_button_unchecked)),
|
||||||
Center(child: Text(_getSelectedDays(schedule.selectedDays))),
|
Center(child: Text(_getSelectedDays(schedule.selectedDays))),
|
||||||
Center(child: Text(schedule.time.format(context))),
|
Center(child: Text(schedule.time.format(context))),
|
||||||
Center(child: Text(schedule.functionOn ? 'On' : 'Off')),
|
Center(child: Text(schedule.functionOn ? 'On' : 'Off')),
|
||||||
@ -230,7 +248,8 @@ class _BuildScheduleViewState extends State<BuildScheduleView> {
|
|||||||
children: [
|
children: [
|
||||||
TextButton(
|
TextButton(
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
_showEditScheduleDialog(context, schedule, index);
|
_showAddScheduleDialog(context);
|
||||||
|
// _showEditScheduleDialog(context, schedule, index);
|
||||||
},
|
},
|
||||||
child: Text(
|
child: Text(
|
||||||
'Edit',
|
'Edit',
|
||||||
@ -298,7 +317,6 @@ class _BuildScheduleViewState extends State<BuildScheduleView> {
|
|||||||
},
|
},
|
||||||
child: Text(selectedTime.format(context)),
|
child: Text(selectedTime.format(context)),
|
||||||
),
|
),
|
||||||
// Same checkboxes and function on/off logic as before
|
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
actions: [
|
actions: [
|
||||||
@ -340,7 +358,8 @@ class _BuildScheduleViewState extends State<BuildScheduleView> {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
void _showAddScheduleDialog(BuildContext context) {
|
void _showAddScheduleDialog(
|
||||||
|
BuildContext context) {
|
||||||
showDialog(
|
showDialog(
|
||||||
context: context,
|
context: context,
|
||||||
builder: (ctx) {
|
builder: (ctx) {
|
||||||
@ -352,10 +371,10 @@ class _BuildScheduleViewState extends State<BuildScheduleView> {
|
|||||||
false,
|
false,
|
||||||
false,
|
false,
|
||||||
false
|
false
|
||||||
]; // Mon - Sun
|
];
|
||||||
|
|
||||||
TimeOfDay? selectedTime;
|
TimeOfDay? selectedTime;
|
||||||
bool isOn = false;
|
bool isOn = false;
|
||||||
|
|
||||||
return BlocProvider.value(
|
return BlocProvider.value(
|
||||||
value: BlocProvider.of<WaterHeaterBloc>(context),
|
value: BlocProvider.of<WaterHeaterBloc>(context),
|
||||||
child: StatefulBuilder(
|
child: StatefulBuilder(
|
||||||
@ -363,44 +382,88 @@ class _BuildScheduleViewState extends State<BuildScheduleView> {
|
|||||||
return AlertDialog(
|
return AlertDialog(
|
||||||
shape: RoundedRectangleBorder(
|
shape: RoundedRectangleBorder(
|
||||||
borderRadius: BorderRadius.circular(20)),
|
borderRadius: BorderRadius.circular(20)),
|
||||||
title: const Text('Scheduling'),
|
|
||||||
content: Column(
|
content: Column(
|
||||||
mainAxisSize: MainAxisSize.min,
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
ElevatedButton(
|
|
||||||
onPressed: () async {
|
|
||||||
TimeOfDay? time = await showTimePicker(
|
|
||||||
context: context,
|
|
||||||
initialTime: TimeOfDay.now(),
|
|
||||||
);
|
|
||||||
if (time != null) {
|
|
||||||
setState(() {
|
|
||||||
selectedTime = time;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
},
|
|
||||||
child: Text(
|
|
||||||
selectedTime == null
|
|
||||||
? 'Time'
|
|
||||||
: '${selectedTime!.format(context)}',
|
|
||||||
),
|
|
||||||
),
|
|
||||||
const SizedBox(height: 10),
|
|
||||||
Row(
|
Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
children: [
|
children: [
|
||||||
_buildDayCheckbox(setState, 'Mon', 0, selectedDays),
|
const SizedBox(),
|
||||||
_buildDayCheckbox(setState, 'Tue', 1, selectedDays),
|
Text(
|
||||||
_buildDayCheckbox(setState, 'Wed', 2, selectedDays),
|
'Scheduling',
|
||||||
_buildDayCheckbox(setState, 'Thu', 3, selectedDays),
|
style: context.textTheme.titleLarge!.copyWith(
|
||||||
_buildDayCheckbox(setState, 'Fri', 4, selectedDays),
|
color: ColorsManager.dialogBlueTitle,
|
||||||
_buildDayCheckbox(setState, 'Sat', 5, selectedDays),
|
fontWeight: FontWeight.bold,
|
||||||
_buildDayCheckbox(setState, 'Sun', 6, selectedDays),
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
const SizedBox(height: 10),
|
const SizedBox(
|
||||||
|
height: 24,
|
||||||
|
),
|
||||||
|
SizedBox(
|
||||||
|
width: 150,
|
||||||
|
height: 40,
|
||||||
|
child: DefaultButton(
|
||||||
|
padding: 8,
|
||||||
|
backgroundColor: ColorsManager.boxColor,
|
||||||
|
borderRadius: 15,
|
||||||
|
onPressed: () async {
|
||||||
|
TimeOfDay? time = await showTimePicker(
|
||||||
|
context: context,
|
||||||
|
initialTime: TimeOfDay.now(),
|
||||||
|
);
|
||||||
|
if (time != null) {
|
||||||
|
setState(() {
|
||||||
|
selectedTime = time;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
child: Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
selectedTime == null
|
||||||
|
? 'Time'
|
||||||
|
: selectedTime!.format(context),
|
||||||
|
style: context.textTheme.bodySmall!.copyWith(
|
||||||
|
color: ColorsManager.grayColor,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const Icon(
|
||||||
|
Icons.access_time,
|
||||||
|
color: ColorsManager.grayColor,
|
||||||
|
size: 18,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(height: 16),
|
||||||
Row(
|
Row(
|
||||||
children: [
|
children: [
|
||||||
const Text('Function:'),
|
_buildDayCheckbox(setState, 'Mon.', 0, selectedDays),
|
||||||
|
_buildDayCheckbox(setState, 'Tue.', 1, selectedDays),
|
||||||
|
_buildDayCheckbox(setState, 'Wed.', 2, selectedDays),
|
||||||
|
_buildDayCheckbox(setState, 'Thu.', 3, selectedDays),
|
||||||
|
_buildDayCheckbox(setState, 'Fri.', 4, selectedDays),
|
||||||
|
_buildDayCheckbox(setState, 'Sat.', 5, selectedDays),
|
||||||
|
_buildDayCheckbox(setState, 'Sun.', 6, selectedDays),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
const SizedBox(height: 16),
|
||||||
|
Row(
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
'Function:',
|
||||||
|
style: context.textTheme.bodySmall!
|
||||||
|
.copyWith(color: ColorsManager.grayColor),
|
||||||
|
),
|
||||||
|
const SizedBox(
|
||||||
|
width: 10,
|
||||||
|
),
|
||||||
Radio<bool>(
|
Radio<bool>(
|
||||||
value: true,
|
value: true,
|
||||||
groupValue: isOn,
|
groupValue: isOn,
|
||||||
@ -411,6 +474,9 @@ class _BuildScheduleViewState extends State<BuildScheduleView> {
|
|||||||
},
|
},
|
||||||
),
|
),
|
||||||
const Text('On'),
|
const Text('On'),
|
||||||
|
const SizedBox(
|
||||||
|
width: 10,
|
||||||
|
),
|
||||||
Radio<bool>(
|
Radio<bool>(
|
||||||
value: false,
|
value: false,
|
||||||
groupValue: isOn,
|
groupValue: isOn,
|
||||||
@ -426,25 +492,37 @@ class _BuildScheduleViewState extends State<BuildScheduleView> {
|
|||||||
],
|
],
|
||||||
),
|
),
|
||||||
actions: [
|
actions: [
|
||||||
TextButton(
|
SizedBox(
|
||||||
onPressed: () {
|
width: 200,
|
||||||
Navigator.pop(context);
|
child: DefaultButton(
|
||||||
},
|
height: 40,
|
||||||
child: const Text('Cancel'),
|
onPressed: () {
|
||||||
|
Navigator.pop(context);
|
||||||
|
},
|
||||||
|
backgroundColor: ColorsManager.boxColor,
|
||||||
|
child: Text(
|
||||||
|
'Cancel',
|
||||||
|
style: context.textTheme.bodyMedium,
|
||||||
|
),
|
||||||
|
),
|
||||||
),
|
),
|
||||||
TextButton(
|
SizedBox(
|
||||||
onPressed: () {
|
width: 200,
|
||||||
// Dispatch Bloc Event to Add Schedule
|
child: DefaultButton(
|
||||||
if (selectedTime != null) {
|
height: 40,
|
||||||
context.read<WaterHeaterBloc>().add(AddScheduleEvent(
|
onPressed: () {
|
||||||
time: selectedTime!,
|
if (selectedTime != null) {
|
||||||
selectedDays: selectedDays,
|
context.read<WaterHeaterBloc>().add(AddScheduleEvent(
|
||||||
functionOn: isOn,
|
time: selectedTime!,
|
||||||
));
|
selectedDays: selectedDays,
|
||||||
Navigator.pop(context); // Close the dialog
|
functionOn: isOn,
|
||||||
}
|
));
|
||||||
},
|
Navigator.pop(context);
|
||||||
child: const Text('Save'),
|
}
|
||||||
|
},
|
||||||
|
backgroundColor: ColorsManager.primaryColor,
|
||||||
|
child: const Text('Save'),
|
||||||
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
@ -556,21 +634,31 @@ class _BuildScheduleViewState extends State<BuildScheduleView> {
|
|||||||
|
|
||||||
List<Widget> _buildCountDownAngInchingView(
|
List<Widget> _buildCountDownAngInchingView(
|
||||||
BuildContext context, WaterHeaterDeviceStatusLoaded state) {
|
BuildContext context, WaterHeaterDeviceStatusLoaded state) {
|
||||||
|
final isCountDown =
|
||||||
|
state.scheduleMode?.name == ScheduleModes.countdown.name;
|
||||||
return [
|
return [
|
||||||
Text(
|
Text(
|
||||||
'Countdown:',
|
isCountDown ? 'Countdown:' : 'Inching:',
|
||||||
style: context.textTheme.bodySmall!.copyWith(
|
style: context.textTheme.bodySmall!.copyWith(
|
||||||
fontSize: 13,
|
fontSize: 13,
|
||||||
color: ColorsManager.grayColor,
|
color: ColorsManager.grayColor,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
const SizedBox(height: 4),
|
const SizedBox(height: 8),
|
||||||
|
Visibility(
|
||||||
|
visible: !isCountDown,
|
||||||
|
child: const Text(
|
||||||
|
'Once enabled this feature, each time the device is turned on, it will automatically turn of after a period time as pre-set.'),
|
||||||
|
),
|
||||||
|
const SizedBox(height: 8),
|
||||||
_hourMinutesWheel(state, context)
|
_hourMinutesWheel(state, context)
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
Row _hourMinutesWheel(
|
Row _hourMinutesWheel(
|
||||||
WaterHeaterDeviceStatusLoaded state, BuildContext context) {
|
WaterHeaterDeviceStatusLoaded state, BuildContext context) {
|
||||||
|
final isActive =
|
||||||
|
(state.countdownRemaining != null && state.isActive == true);
|
||||||
return Row(
|
return Row(
|
||||||
mainAxisAlignment: MainAxisAlignment.start,
|
mainAxisAlignment: MainAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
@ -580,7 +668,7 @@ class _BuildScheduleViewState extends State<BuildScheduleView> {
|
|||||||
hours: value,
|
hours: value,
|
||||||
minutes: state.minutes ?? 0,
|
minutes: state.minutes ?? 0,
|
||||||
));
|
));
|
||||||
}),
|
}, isActive: isActive),
|
||||||
const SizedBox(width: 10),
|
const SizedBox(width: 10),
|
||||||
_buildPickerColumn(context, 'm', state.minutes ?? 0, 60, (value) {
|
_buildPickerColumn(context, 'm', state.minutes ?? 0, 60, (value) {
|
||||||
context.read<WaterHeaterBloc>().add(UpdateScheduleEvent(
|
context.read<WaterHeaterBloc>().add(UpdateScheduleEvent(
|
||||||
@ -588,18 +676,19 @@ class _BuildScheduleViewState extends State<BuildScheduleView> {
|
|||||||
hours: state.hours ?? 0,
|
hours: state.hours ?? 0,
|
||||||
minutes: value,
|
minutes: value,
|
||||||
));
|
));
|
||||||
}),
|
}, isActive: isActive),
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget _buildPickerColumn(BuildContext context, String label,
|
Widget _buildPickerColumn(BuildContext context, String label,
|
||||||
int initialValue, int itemCount, ValueChanged<int> onSelected) {
|
int initialValue, int itemCount, ValueChanged<int> onSelected,
|
||||||
|
{required bool isActive}) {
|
||||||
return Row(
|
return Row(
|
||||||
mainAxisSize: MainAxisSize.min,
|
mainAxisSize: MainAxisSize.min,
|
||||||
children: [
|
children: [
|
||||||
Container(
|
Container(
|
||||||
height: 50,
|
height: 40,
|
||||||
width: 80,
|
width: 80,
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 16),
|
padding: const EdgeInsets.symmetric(horizontal: 16),
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
@ -619,7 +708,10 @@ class _BuildScheduleViewState extends State<BuildScheduleView> {
|
|||||||
return Center(
|
return Center(
|
||||||
child: Text(
|
child: Text(
|
||||||
index.toString().padLeft(2, '0'),
|
index.toString().padLeft(2, '0'),
|
||||||
style: const TextStyle(fontSize: 24),
|
style: TextStyle(
|
||||||
|
fontSize: 24,
|
||||||
|
color: isActive ? ColorsManager.grayColor : Colors.black,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
@ -627,7 +719,7 @@ class _BuildScheduleViewState extends State<BuildScheduleView> {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
const SizedBox(height: 8),
|
const SizedBox(width: 8),
|
||||||
Text(
|
Text(
|
||||||
label,
|
label,
|
||||||
style: const TextStyle(
|
style: const TextStyle(
|
||||||
|
@ -5,9 +5,10 @@ final myTheme = ThemeData(
|
|||||||
fontFamily: 'Aftika',
|
fontFamily: 'Aftika',
|
||||||
textTheme: const TextTheme(
|
textTheme: const TextTheme(
|
||||||
bodySmall: TextStyle(
|
bodySmall: TextStyle(
|
||||||
fontSize: 13,
|
fontSize: 13,
|
||||||
color: ColorsManager.whiteColors,
|
color: ColorsManager.whiteColors,
|
||||||
fontWeight: FontWeight.bold),
|
fontWeight: FontWeight.normal,
|
||||||
|
),
|
||||||
bodyMedium: TextStyle(color: Colors.black87, fontSize: 14),
|
bodyMedium: TextStyle(color: Colors.black87, fontSize: 14),
|
||||||
bodyLarge: TextStyle(fontSize: 16, color: Colors.white),
|
bodyLarge: TextStyle(fontSize: 16, color: Colors.white),
|
||||||
headlineSmall: TextStyle(color: Colors.black87, fontSize: 18),
|
headlineSmall: TextStyle(color: Colors.black87, fontSize: 18),
|
||||||
|
Reference in New Issue
Block a user