mirror of
https://github.com/SyncrowIOT/web.git
synced 2025-07-10 07:07:19 +00:00
@ -35,51 +35,46 @@ class TwoGangDeviceControlView extends StatelessWidget
|
||||
}
|
||||
|
||||
Widget _buildStatusControls(BuildContext context, TwoGangStatusModel status) {
|
||||
final isExtraLarge = isExtraLargeScreenSize(context);
|
||||
final isLarge = isLargeScreenSize(context);
|
||||
final isMedium = isMediumScreenSize(context);
|
||||
return GridView(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 50),
|
||||
shrinkWrap: true,
|
||||
physics: const NeverScrollableScrollPhysics(),
|
||||
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
|
||||
crossAxisCount: isLarge || isExtraLarge
|
||||
? 3
|
||||
: isMedium
|
||||
? 2
|
||||
: 1,
|
||||
mainAxisExtent: 140,
|
||||
crossAxisSpacing: 12,
|
||||
mainAxisSpacing: 12,
|
||||
return Center(
|
||||
child: Wrap(
|
||||
alignment: WrapAlignment.center,
|
||||
spacing: 12,
|
||||
runSpacing: 12,
|
||||
children: [
|
||||
SizedBox(
|
||||
width: 200,
|
||||
child: ToggleWidget(
|
||||
value: status.switch1,
|
||||
code: 'switch_1',
|
||||
deviceId: deviceId,
|
||||
label: 'Wall Light',
|
||||
onChange: (value) {
|
||||
context.read<TwoGangSwitchBloc>().add(TwoGangSwitchControl(
|
||||
deviceId: deviceId,
|
||||
code: 'switch_1',
|
||||
value: value,
|
||||
));
|
||||
},
|
||||
),
|
||||
),
|
||||
SizedBox(
|
||||
width: 200,
|
||||
child: ToggleWidget(
|
||||
value: status.switch2,
|
||||
code: 'switch_2',
|
||||
deviceId: deviceId,
|
||||
label: 'Ceiling Light',
|
||||
onChange: (value) {
|
||||
context.read<TwoGangSwitchBloc>().add(TwoGangSwitchControl(
|
||||
deviceId: deviceId,
|
||||
code: 'switch_2',
|
||||
value: value,
|
||||
));
|
||||
},
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
children: [
|
||||
ToggleWidget(
|
||||
value: status.switch1,
|
||||
code: 'switch_1',
|
||||
deviceId: deviceId,
|
||||
label: 'Wall Light',
|
||||
onChange: (value) {
|
||||
context.read<TwoGangSwitchBloc>().add(TwoGangSwitchControl(
|
||||
deviceId: deviceId,
|
||||
code: 'switch_1',
|
||||
value: value,
|
||||
));
|
||||
},
|
||||
),
|
||||
ToggleWidget(
|
||||
value: status.switch2,
|
||||
code: 'switch_2',
|
||||
deviceId: deviceId,
|
||||
label: 'Ceiling Light',
|
||||
onChange: (value) {
|
||||
context.read<TwoGangSwitchBloc>().add(TwoGangSwitchControl(
|
||||
deviceId: deviceId,
|
||||
code: 'switch_2',
|
||||
value: value,
|
||||
));
|
||||
},
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -5,6 +5,7 @@ import 'package:bloc/bloc.dart';
|
||||
import 'package:equatable/equatable.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:syncrow_web/pages/device_managment/all_devices/models/device_status.dart';
|
||||
import 'package:syncrow_web/pages/device_managment/water_heater/models/schedule_entry.dart';
|
||||
import 'package:syncrow_web/pages/device_managment/water_heater/models/schedule_model.dart';
|
||||
import 'package:syncrow_web/pages/device_managment/water_heater/models/water_heater_status_model.dart';
|
||||
import 'package:syncrow_web/services/devices_mang_api.dart';
|
||||
@ -487,10 +488,8 @@ class WaterHeaterBloc extends Bloc<WaterHeaterEvent, WaterHeaterState> {
|
||||
emit(ScheduleLoadingState());
|
||||
|
||||
try {
|
||||
// List<ScheduleModel> schedules = await DevicesManagementApi()
|
||||
// .getDeviceSchedules(deviceStatus.uuid, event.category);
|
||||
|
||||
List<ScheduleModel> schedules = const [];
|
||||
List<ScheduleModel> schedules = await DevicesManagementApi()
|
||||
.getDeviceSchedules(deviceStatus.uuid, event.category);
|
||||
|
||||
emit(WaterHeaterDeviceStatusLoaded(
|
||||
deviceStatus,
|
||||
@ -513,7 +512,7 @@ class WaterHeaterBloc extends Bloc<WaterHeaterEvent, WaterHeaterState> {
|
||||
if (state is WaterHeaterDeviceStatusLoaded) {
|
||||
final currentState = state as WaterHeaterDeviceStatusLoaded;
|
||||
|
||||
ScheduleModel newSchedule = ScheduleModel(
|
||||
ScheduleEntry newSchedule = ScheduleEntry(
|
||||
category: event.category,
|
||||
time: formatTimeOfDayToISO(event.time),
|
||||
function: Status(code: 'switch_1', value: event.functionOn),
|
||||
@ -526,10 +525,7 @@ class WaterHeaterBloc extends Bloc<WaterHeaterEvent, WaterHeaterState> {
|
||||
.addScheduleRecord(newSchedule, currentState.status.uuid);
|
||||
|
||||
if (success) {
|
||||
final updatedSchedules =
|
||||
List<ScheduleModel>.from(currentState.schedules)..add(newSchedule);
|
||||
|
||||
emit(currentState.copyWith(schedules: updatedSchedules));
|
||||
add(GetSchedulesEvent(category: 'switch_1', uuid: deviceStatus.uuid));
|
||||
} else {
|
||||
emit(currentState);
|
||||
//emit(const WaterHeaterFailedState(error: 'Failed to add schedule.'));
|
||||
@ -544,27 +540,27 @@ class WaterHeaterBloc extends Bloc<WaterHeaterEvent, WaterHeaterState> {
|
||||
if (state is WaterHeaterDeviceStatusLoaded) {
|
||||
final currentState = state as WaterHeaterDeviceStatusLoaded;
|
||||
|
||||
ScheduleModel updatedSchedule = currentState.schedules[event.index]
|
||||
.copyWith(
|
||||
function: Status(code: 'switch_1', value: event.functionOn));
|
||||
|
||||
// emit(ScheduleLoadingState());
|
||||
final updatedSchedules = currentState.schedules.map((schedule) {
|
||||
if (schedule.scheduleId == event.scheduleId) {
|
||||
return schedule.copyWith(
|
||||
function: Status(code: 'switch_1', value: event.functionOn),
|
||||
enable: event.enable,
|
||||
);
|
||||
}
|
||||
return schedule;
|
||||
}).toList();
|
||||
|
||||
bool success = await DevicesManagementApi().updateScheduleRecord(
|
||||
enable: event.functionOn,
|
||||
enable: event.enable,
|
||||
uuid: currentState.status.uuid,
|
||||
scheduleId: event.scheduleId,
|
||||
);
|
||||
|
||||
if (success) {
|
||||
final updatedSchedules =
|
||||
List<ScheduleModel>.from(currentState.schedules)
|
||||
..[event.index] = updatedSchedule;
|
||||
|
||||
emit(currentState.copyWith(schedules: updatedSchedules));
|
||||
} else {
|
||||
emit(currentState);
|
||||
// emit(const WaterHeaterFailedState(error: 'Failed to update schedule.'));
|
||||
// emit(const WaterHeaterFailedState(error: 'Failed to update schedule.'));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -576,20 +572,20 @@ class WaterHeaterBloc extends Bloc<WaterHeaterEvent, WaterHeaterState> {
|
||||
if (state is WaterHeaterDeviceStatusLoaded) {
|
||||
final currentState = state as WaterHeaterDeviceStatusLoaded;
|
||||
|
||||
// emit(ScheduleLoadingState());
|
||||
// emit(ScheduleLoadingState());
|
||||
|
||||
bool success = await DevicesManagementApi()
|
||||
.deleteScheduleRecord(currentState.status.uuid, event.scheduleId);
|
||||
|
||||
if (success) {
|
||||
final updatedSchedules =
|
||||
List<ScheduleModel>.from(currentState.schedules)
|
||||
..removeAt(event.index);
|
||||
final updatedSchedules = currentState.schedules
|
||||
.where((schedule) => schedule.scheduleId != event.scheduleId)
|
||||
.toList();
|
||||
|
||||
emit(currentState.copyWith(schedules: updatedSchedules));
|
||||
} else {
|
||||
emit(currentState);
|
||||
// emit(const WaterHeaterFailedState(error: 'Failed to delete schedule.'));
|
||||
// emit(const WaterHeaterFailedState(error: 'Failed to delete schedule.'));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -82,23 +82,22 @@ final class DeleteScheduleEvent extends WaterHeaterEvent {
|
||||
}
|
||||
|
||||
final class UpdateScheduleEntryEvent extends WaterHeaterEvent {
|
||||
final bool functionOn;
|
||||
final String category;
|
||||
final bool enable;
|
||||
final dynamic functionOn;
|
||||
final String deviceId;
|
||||
final int index;
|
||||
final String scheduleId;
|
||||
|
||||
const UpdateScheduleEntryEvent({
|
||||
required this.enable,
|
||||
required this.functionOn,
|
||||
required this.category,
|
||||
required this.deviceId,
|
||||
required this.scheduleId,
|
||||
required this.index,
|
||||
});
|
||||
|
||||
@override
|
||||
List<Object?> get props =>
|
||||
[category, functionOn, deviceId, scheduleId, index];
|
||||
List<Object?> get props => [enable, deviceId, scheduleId];
|
||||
}
|
||||
|
||||
class GetSchedulesEvent extends WaterHeaterEvent {
|
||||
|
@ -118,7 +118,7 @@ class ScheduleDialogHelper {
|
||||
_buildDayCheckboxes(context, state.selectedDays,
|
||||
isEdit: isEdit),
|
||||
const SizedBox(height: 16),
|
||||
_buildFunctionSwitch(context, state.functionOn),
|
||||
_buildFunctionSwitch(context, state.functionOn, isEdit),
|
||||
],
|
||||
),
|
||||
actions: [
|
||||
@ -143,16 +143,10 @@ class ScheduleDialogHelper {
|
||||
onPressed: () {
|
||||
if (state.selectedTime != null) {
|
||||
if (state.isEditing && index != null) {
|
||||
bloc.add(UpdateScheduleEntryEvent(
|
||||
index: index,
|
||||
deviceId: state.status.uuid,
|
||||
category: 'kg',
|
||||
functionOn: state.functionOn,
|
||||
scheduleId: state.schedules[index].scheduleId,
|
||||
));
|
||||
return;
|
||||
} else {
|
||||
bloc.add(AddScheduleEvent(
|
||||
category: 'kg',
|
||||
category: 'switch_1',
|
||||
time: state.selectedTime!,
|
||||
selectedDays: state.selectedDays,
|
||||
functionOn: state.functionOn,
|
||||
@ -177,8 +171,15 @@ class ScheduleDialogHelper {
|
||||
}
|
||||
|
||||
static TimeOfDay _convertStringToTimeOfDay(String timeString) {
|
||||
final DateTime dateTime = DateTime.parse(timeString);
|
||||
return TimeOfDay(hour: dateTime.hour, minute: dateTime.minute);
|
||||
final regex = RegExp(r'^(\d{2}):(\d{2})$');
|
||||
final match = regex.firstMatch(timeString);
|
||||
if (match != null) {
|
||||
final hour = int.parse(match.group(1)!);
|
||||
final minute = int.parse(match.group(2)!);
|
||||
return TimeOfDay(hour: hour, minute: minute);
|
||||
} else {
|
||||
throw const FormatException('Invalid time format');
|
||||
}
|
||||
}
|
||||
|
||||
static List<bool> _convertDaysStringToBooleans(List<String> selectedDays) {
|
||||
@ -220,7 +221,8 @@ class ScheduleDialogHelper {
|
||||
);
|
||||
}
|
||||
|
||||
static Widget _buildFunctionSwitch(BuildContext context, bool isOn) {
|
||||
static Widget _buildFunctionSwitch(
|
||||
BuildContext context, bool isOn, bool? isEdit) {
|
||||
return Row(
|
||||
children: [
|
||||
Text(
|
||||
@ -233,9 +235,13 @@ class ScheduleDialogHelper {
|
||||
value: true,
|
||||
groupValue: isOn,
|
||||
onChanged: (bool? value) {
|
||||
context
|
||||
.read<WaterHeaterBloc>()
|
||||
.add(const UpdateFunctionOnEvent(true));
|
||||
if (isEdit == true) {
|
||||
return;
|
||||
} else {
|
||||
context
|
||||
.read<WaterHeaterBloc>()
|
||||
.add(const UpdateFunctionOnEvent(true));
|
||||
}
|
||||
},
|
||||
),
|
||||
const Text('On'),
|
||||
@ -244,9 +250,13 @@ class ScheduleDialogHelper {
|
||||
value: false,
|
||||
groupValue: isOn,
|
||||
onChanged: (bool? value) {
|
||||
context
|
||||
.read<WaterHeaterBloc>()
|
||||
.add(const UpdateFunctionOnEvent(false));
|
||||
if (isEdit == true) {
|
||||
return;
|
||||
} else {
|
||||
context
|
||||
.read<WaterHeaterBloc>()
|
||||
.add(const UpdateFunctionOnEvent(false));
|
||||
}
|
||||
},
|
||||
),
|
||||
const Text('Off'),
|
||||
|
@ -1,19 +1,80 @@
|
||||
// import 'package:flutter/material.dart';
|
||||
import 'dart:convert';
|
||||
|
||||
// class ScheduleEntry {
|
||||
// final List<bool> selectedDays;
|
||||
// final TimeOfDay time;
|
||||
// final bool functionOn;
|
||||
// final String category;
|
||||
import 'package:flutter/foundation.dart';
|
||||
|
||||
// ScheduleEntry({
|
||||
// required this.selectedDays,
|
||||
// required this.time,
|
||||
// required this.functionOn,
|
||||
// required this.category,
|
||||
// });
|
||||
import 'package:syncrow_web/pages/device_managment/all_devices/models/device_status.dart';
|
||||
|
||||
// @override
|
||||
// String toString() =>
|
||||
// 'ScheduleEntry(selectedDays: $selectedDays, time: $time, functionOn: $functionOn)';
|
||||
// }
|
||||
class ScheduleEntry {
|
||||
final String category;
|
||||
final String time;
|
||||
final Status function;
|
||||
final List<String> days;
|
||||
|
||||
ScheduleEntry({
|
||||
required this.category,
|
||||
required this.time,
|
||||
required this.function,
|
||||
required this.days,
|
||||
});
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'ScheduleEntry(category: $category, time: $time, function: $function, days: $days)';
|
||||
}
|
||||
|
||||
ScheduleEntry copyWith({
|
||||
String? category,
|
||||
String? time,
|
||||
Status? function,
|
||||
List<String>? days,
|
||||
}) {
|
||||
return ScheduleEntry(
|
||||
category: category ?? this.category,
|
||||
time: time ?? this.time,
|
||||
function: function ?? this.function,
|
||||
days: days ?? this.days,
|
||||
);
|
||||
}
|
||||
|
||||
Map<String, dynamic> toMap() {
|
||||
return {
|
||||
'category': category,
|
||||
'time': time,
|
||||
'function': function.toMap(),
|
||||
'days': days,
|
||||
};
|
||||
}
|
||||
|
||||
factory ScheduleEntry.fromMap(Map<String, dynamic> map) {
|
||||
return ScheduleEntry(
|
||||
category: map['category'] ?? '',
|
||||
time: map['time'] ?? '',
|
||||
function: Status.fromMap(map['function']),
|
||||
days: List<String>.from(map['days']),
|
||||
);
|
||||
}
|
||||
|
||||
String toJson() => json.encode(toMap());
|
||||
|
||||
factory ScheduleEntry.fromJson(String source) =>
|
||||
ScheduleEntry.fromMap(json.decode(source));
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
if (identical(this, other)) return true;
|
||||
|
||||
return other is ScheduleEntry &&
|
||||
other.category == category &&
|
||||
other.time == time &&
|
||||
other.function == function &&
|
||||
listEquals(other.days, days);
|
||||
}
|
||||
|
||||
@override
|
||||
int get hashCode {
|
||||
return category.hashCode ^
|
||||
time.hashCode ^
|
||||
function.hashCode ^
|
||||
days.hashCode;
|
||||
}
|
||||
}
|
||||
|
@ -9,25 +9,30 @@ class ScheduleModel {
|
||||
final String time;
|
||||
final Status function;
|
||||
final List<String> days;
|
||||
final TimeOfDay? timeOfDay;
|
||||
final List<bool>? selectedDays;
|
||||
final String timezoneId;
|
||||
final bool enable;
|
||||
|
||||
ScheduleModel({
|
||||
required this.scheduleId,
|
||||
required this.category,
|
||||
required this.time,
|
||||
required this.function,
|
||||
required this.days,
|
||||
this.timeOfDay,
|
||||
this.selectedDays,
|
||||
this.scheduleId = '',
|
||||
required this.timezoneId,
|
||||
required this.enable,
|
||||
});
|
||||
|
||||
Map<String, dynamic> toMap() {
|
||||
return {
|
||||
'scheduleId': scheduleId,
|
||||
'category': category,
|
||||
'time': time,
|
||||
'function': function.toMap(),
|
||||
'days': days,
|
||||
'timezoneId': timezoneId,
|
||||
'enable': enable,
|
||||
};
|
||||
}
|
||||
|
||||
@ -37,11 +42,11 @@ class ScheduleModel {
|
||||
category: map['category'] ?? '',
|
||||
time: map['time'] ?? '',
|
||||
function: Status.fromMap(map['function']),
|
||||
days: List<String>.from(map['days']),
|
||||
timeOfDay:
|
||||
parseTimeOfDay(map['time']),
|
||||
selectedDays:
|
||||
parseSelectedDays(map['days']),
|
||||
days: List<String>.from(map['days'].map((e) => e.toString())),
|
||||
timezoneId: map['timezoneId'] ?? '',
|
||||
enable: map['enable'] ?? false,
|
||||
selectedDays: parseSelectedDays(
|
||||
List<String>.from(map['days'].map((e) => e.toString()))),
|
||||
);
|
||||
}
|
||||
|
||||
@ -51,22 +56,24 @@ class ScheduleModel {
|
||||
ScheduleModel.fromMap(json.decode(source));
|
||||
|
||||
ScheduleModel copyWith({
|
||||
String? scheduleId,
|
||||
String? category,
|
||||
String? time,
|
||||
Status? function,
|
||||
List<String>? days,
|
||||
TimeOfDay? timeOfDay,
|
||||
List<bool>? selectedDays,
|
||||
String? scheduleId,
|
||||
String? timezoneId,
|
||||
bool? enable,
|
||||
}) {
|
||||
return ScheduleModel(
|
||||
scheduleId: scheduleId ?? this.scheduleId,
|
||||
category: category ?? this.category,
|
||||
time: time ?? this.time,
|
||||
function: function ?? this.function,
|
||||
days: days ?? this.days,
|
||||
timeOfDay: timeOfDay ?? this.timeOfDay,
|
||||
selectedDays: selectedDays ?? this.selectedDays,
|
||||
scheduleId: scheduleId ?? this.scheduleId,
|
||||
timezoneId: timezoneId ?? this.timezoneId,
|
||||
enable: enable ?? this.enable,
|
||||
);
|
||||
}
|
||||
|
||||
@ -97,7 +104,7 @@ class ScheduleModel {
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'ScheduleModel(category: $category, time: $time, function: $function, days: $days, timeOfDay: $timeOfDay, selectedDays: $selectedDays)';
|
||||
return 'ScheduleModel(category: $category, time: $time, function: $function, days: $days, selectedDays: $selectedDays)';
|
||||
}
|
||||
|
||||
@override
|
||||
@ -109,7 +116,7 @@ class ScheduleModel {
|
||||
other.time == time &&
|
||||
other.function == function &&
|
||||
listEquals(other.days, days) &&
|
||||
timeOfDay == other.timeOfDay &&
|
||||
// timeOfDay == other.timeOfDay &&
|
||||
listEquals(other.selectedDays, selectedDays);
|
||||
}
|
||||
|
||||
@ -119,7 +126,7 @@ class ScheduleModel {
|
||||
time.hashCode ^
|
||||
function.hashCode ^
|
||||
days.hashCode ^
|
||||
timeOfDay.hashCode ^
|
||||
// timeOfDay.hashCode ^
|
||||
selectedDays.hashCode;
|
||||
}
|
||||
}
|
||||
|
@ -53,11 +53,10 @@ class _BuildScheduleViewState extends State<BuildScheduleView> {
|
||||
state: state,
|
||||
onAddSchedule: () =>
|
||||
ScheduleDialogHelper.showAddScheduleDialog(
|
||||
context,
|
||||
schedule: null,
|
||||
index: null,
|
||||
isEdit: false
|
||||
),
|
||||
context,
|
||||
schedule: null,
|
||||
index: null,
|
||||
isEdit: false),
|
||||
),
|
||||
if (state.scheduleMode == ScheduleModes.countdown ||
|
||||
state.scheduleMode == ScheduleModes.inching)
|
||||
@ -80,15 +79,31 @@ class _BuildScheduleViewState extends State<BuildScheduleView> {
|
||||
if (state.scheduleMode != ScheduleModes.countdown &&
|
||||
state.scheduleMode != ScheduleModes.inching)
|
||||
ScheduleModeButtons(
|
||||
onSave: () {},
|
||||
onSave: () {
|
||||
Navigator.pop(context);
|
||||
},
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
if (state is WaterHeaterLoadingState) {
|
||||
return const Center(child: CircularProgressIndicator());
|
||||
return const SizedBox(
|
||||
height: 200,
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
ScheduleHeader(),
|
||||
SizedBox(
|
||||
height: 20,
|
||||
),
|
||||
Center(child: CircularProgressIndicator()),
|
||||
],
|
||||
));
|
||||
}
|
||||
return const SizedBox();
|
||||
return const SizedBox(
|
||||
height: 200,
|
||||
child: ScheduleHeader(),
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
|
@ -72,7 +72,7 @@ class ScheduleModeSelector extends StatelessWidget {
|
||||
if (value == ScheduleModes.schedule) {
|
||||
context.read<WaterHeaterBloc>().add(
|
||||
GetSchedulesEvent(
|
||||
category: 'kg',
|
||||
category: 'switch_1',
|
||||
uuid: state.status.uuid,
|
||||
),
|
||||
);
|
||||
|
@ -1,76 +1,76 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:syncrow_web/pages/device_managment/water_heater/models/schedule_model.dart';
|
||||
import 'package:syncrow_web/utils/format_date_time.dart';
|
||||
import 'package:syncrow_web/utils/color_manager.dart';
|
||||
// import 'package:flutter/material.dart';
|
||||
// import 'package:syncrow_web/pages/device_managment/water_heater/models/schedule_model.dart';
|
||||
// import 'package:syncrow_web/utils/format_date_time.dart';
|
||||
// import 'package:syncrow_web/utils/color_manager.dart';
|
||||
|
||||
class ScheduleRowWidget extends StatelessWidget {
|
||||
final ScheduleModel schedule;
|
||||
final int index;
|
||||
final Function onEdit;
|
||||
final Function onDelete;
|
||||
// class ScheduleRowWidget extends StatelessWidget {
|
||||
// final ScheduleModel schedule;
|
||||
// final int index;
|
||||
// final Function onEdit;
|
||||
// final Function onDelete;
|
||||
|
||||
const ScheduleRowWidget({
|
||||
super.key,
|
||||
required this.schedule,
|
||||
required this.index,
|
||||
required this.onEdit,
|
||||
required this.onDelete,
|
||||
});
|
||||
// const ScheduleRowWidget({
|
||||
// super.key,
|
||||
// required this.schedule,
|
||||
// required this.index,
|
||||
// required this.onEdit,
|
||||
// required this.onDelete,
|
||||
// });
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Table(
|
||||
border: TableBorder.all(color: ColorsManager.graysColor),
|
||||
defaultVerticalAlignment: TableCellVerticalAlignment.middle,
|
||||
children: [
|
||||
TableRow(
|
||||
children: [
|
||||
Center(
|
||||
child: schedule.function.value
|
||||
? const Icon(Icons.radio_button_checked,
|
||||
color: ColorsManager.blueColor)
|
||||
: const Icon(Icons.radio_button_unchecked),
|
||||
),
|
||||
Center(child: Text(_getSelectedDays(schedule.selectedDays ?? []))),
|
||||
Center(child: Text(formatIsoStringToTime(schedule.time))),
|
||||
Center(child: Text(schedule.function.value ? 'On' : 'Off')),
|
||||
Center(
|
||||
child: Wrap(
|
||||
runAlignment: WrapAlignment.center,
|
||||
children: [
|
||||
TextButton(
|
||||
style: TextButton.styleFrom(padding: EdgeInsets.zero),
|
||||
onPressed: () => onEdit(),
|
||||
child: const Text(
|
||||
'Edit',
|
||||
style: TextStyle(color: ColorsManager.blueColor),
|
||||
),
|
||||
),
|
||||
TextButton(
|
||||
style: TextButton.styleFrom(padding: EdgeInsets.zero),
|
||||
onPressed: () => onDelete(),
|
||||
child: const Text(
|
||||
'Delete',
|
||||
style: TextStyle(color: ColorsManager.blueColor),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
// @override
|
||||
// Widget build(BuildContext context) {
|
||||
// return Table(
|
||||
// border: TableBorder.all(color: ColorsManager.graysColor),
|
||||
// defaultVerticalAlignment: TableCellVerticalAlignment.middle,
|
||||
// children: [
|
||||
// TableRow(
|
||||
// children: [
|
||||
// Center(
|
||||
// child: schedule.enable
|
||||
// ? const Icon(Icons.radio_button_checked,
|
||||
// color: ColorsManager.blueColor)
|
||||
// : const Icon(Icons.radio_button_unchecked),
|
||||
// ),
|
||||
// Center(child: Text(_getSelectedDays(schedule.selectedDays ?? []))),
|
||||
// Center(child: Text(formatIsoStringToTime(schedule.time, context))),
|
||||
// Center(child: Text(schedule.enable ? 'On' : 'Off')),
|
||||
// Center(
|
||||
// child: Wrap(
|
||||
// runAlignment: WrapAlignment.center,
|
||||
// children: [
|
||||
// TextButton(
|
||||
// style: TextButton.styleFrom(padding: EdgeInsets.zero),
|
||||
// onPressed: () => onEdit(),
|
||||
// child: const Text(
|
||||
// 'Edit',
|
||||
// style: TextStyle(color: ColorsManager.blueColor),
|
||||
// ),
|
||||
// ),
|
||||
// TextButton(
|
||||
// style: TextButton.styleFrom(padding: EdgeInsets.zero),
|
||||
// onPressed: () => onDelete(),
|
||||
// child: const Text(
|
||||
// 'Delete',
|
||||
// style: TextStyle(color: ColorsManager.blueColor),
|
||||
// ),
|
||||
// ),
|
||||
// ],
|
||||
// ),
|
||||
// ),
|
||||
// ],
|
||||
// ),
|
||||
// ],
|
||||
// );
|
||||
// }
|
||||
|
||||
String _getSelectedDays(List<bool> selectedDays) {
|
||||
final days = ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'];
|
||||
List<String> selectedDaysStr = [];
|
||||
for (int i = 0; i < selectedDays.length; i++) {
|
||||
if (selectedDays[i]) {
|
||||
selectedDaysStr.add(days[i]);
|
||||
}
|
||||
}
|
||||
return selectedDaysStr.join(', ');
|
||||
}
|
||||
}
|
||||
// String _getSelectedDays(List<bool> selectedDays) {
|
||||
// final days = ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'];
|
||||
// List<String> selectedDaysStr = [];
|
||||
// for (int i = 0; i < selectedDays.length; i++) {
|
||||
// if (selectedDays[i]) {
|
||||
// selectedDaysStr.add(days[i]);
|
||||
// }
|
||||
// }
|
||||
// return selectedDaysStr.join(', ');
|
||||
// }
|
||||
// }
|
||||
|
@ -68,7 +68,9 @@ class ScheduleTableWidget extends StatelessWidget {
|
||||
),
|
||||
child: _buildTableBody(state, context));
|
||||
}
|
||||
return const SizedBox();
|
||||
return const SizedBox(
|
||||
height: 200,
|
||||
);
|
||||
},
|
||||
),
|
||||
],
|
||||
@ -107,14 +109,17 @@ class ScheduleTableWidget extends StatelessWidget {
|
||||
|
||||
Widget _buildTableBody(
|
||||
WaterHeaterDeviceStatusLoaded state, BuildContext context) {
|
||||
return SingleChildScrollView(
|
||||
child: Table(
|
||||
border: TableBorder.all(color: ColorsManager.graysColor),
|
||||
defaultVerticalAlignment: TableCellVerticalAlignment.middle,
|
||||
children: [
|
||||
for (int i = 0; i < state.schedules.length; i++)
|
||||
_buildScheduleRow(state.schedules[i], i, context),
|
||||
],
|
||||
return SizedBox(
|
||||
height: 200,
|
||||
child: SingleChildScrollView(
|
||||
child: Table(
|
||||
border: TableBorder.all(color: ColorsManager.graysColor),
|
||||
defaultVerticalAlignment: TableCellVerticalAlignment.middle,
|
||||
children: [
|
||||
for (int i = 0; i < state.schedules.length; i++)
|
||||
_buildScheduleRow(state.schedules[i], i, context, state),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
@ -134,19 +139,38 @@ class ScheduleTableWidget extends StatelessWidget {
|
||||
);
|
||||
}
|
||||
|
||||
TableRow _buildScheduleRow(
|
||||
ScheduleModel schedule, int index, BuildContext context) {
|
||||
TableRow _buildScheduleRow(ScheduleModel schedule, int index,
|
||||
BuildContext context, WaterHeaterDeviceStatusLoaded state) {
|
||||
return TableRow(
|
||||
children: [
|
||||
Center(
|
||||
child: schedule.function.value
|
||||
? const Icon(Icons.radio_button_checked,
|
||||
color: ColorsManager.blueColor)
|
||||
: const Icon(Icons.radio_button_unchecked)),
|
||||
child: GestureDetector(
|
||||
onTap: () {
|
||||
context.read<WaterHeaterBloc>().add(UpdateScheduleEntryEvent(
|
||||
index: index,
|
||||
enable: !schedule.enable,
|
||||
scheduleId: schedule.scheduleId,
|
||||
deviceId: state.status.uuid,
|
||||
functionOn: schedule.function.value,
|
||||
));
|
||||
},
|
||||
child: SizedBox(
|
||||
width: 24,
|
||||
height: 24,
|
||||
child: schedule.enable
|
||||
? const Icon(Icons.radio_button_checked,
|
||||
color: ColorsManager.blueColor)
|
||||
: const Icon(
|
||||
Icons.radio_button_unchecked,
|
||||
color: ColorsManager.grayColor,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
Center(
|
||||
child: Text(_getSelectedDays(
|
||||
ScheduleModel.parseSelectedDays(schedule.days)))),
|
||||
Center(child: Text(formatIsoStringToTime(schedule.time))),
|
||||
Center(child: Text(formatIsoStringToTime(schedule.time, context))),
|
||||
Center(child: Text(schedule.function.value ? 'On' : 'Off')),
|
||||
Center(
|
||||
child: Wrap(
|
||||
|
@ -3,6 +3,7 @@ import 'package:syncrow_web/pages/device_managment/all_devices/models/device_rep
|
||||
import 'package:syncrow_web/pages/device_managment/all_devices/models/device_status.dart';
|
||||
import 'package:syncrow_web/pages/device_managment/all_devices/models/devices_model.dart';
|
||||
import 'package:syncrow_web/pages/device_managment/all_devices/models/factory_reset_model.dart';
|
||||
import 'package:syncrow_web/pages/device_managment/water_heater/models/schedule_entry.dart';
|
||||
import 'package:syncrow_web/pages/device_managment/water_heater/models/schedule_model.dart';
|
||||
import 'package:syncrow_web/pages/visitor_password/model/device_model.dart';
|
||||
import 'package:syncrow_web/services/api/http_service.dart';
|
||||
@ -179,7 +180,7 @@ class DevicesManagementApi {
|
||||
}
|
||||
|
||||
Future<bool> addScheduleRecord(
|
||||
ScheduleModel sendSchedule, String uuid) async {
|
||||
ScheduleEntry sendSchedule, String uuid) async {
|
||||
try {
|
||||
final response = await HTTPService().post(
|
||||
path: ApiEndpoints.scheduleByDeviceId.replaceAll('{deviceUuid}', uuid),
|
||||
@ -200,14 +201,14 @@ class DevicesManagementApi {
|
||||
String uuid, String category) async {
|
||||
try {
|
||||
final response = await HTTPService().get(
|
||||
path: ApiEndpoints.scheduleByDeviceId
|
||||
path: ApiEndpoints.getScheduleByDeviceId
|
||||
.replaceAll('{deviceUuid}', uuid)
|
||||
.replaceAll('{category}', category),
|
||||
showServerMessage: true,
|
||||
expectedResponseModel: (json) {
|
||||
List<ScheduleModel> schedules = [];
|
||||
for (var schedule in json['schedules']) {
|
||||
schedules.add(ScheduleModel.fromJson(schedule));
|
||||
for (var schedule in json) {
|
||||
schedules.add(ScheduleModel.fromMap(schedule));
|
||||
}
|
||||
return schedules;
|
||||
},
|
||||
@ -225,7 +226,7 @@ class DevicesManagementApi {
|
||||
required String scheduleId}) async {
|
||||
try {
|
||||
final response = await HTTPService().put(
|
||||
path: ApiEndpoints.scheduleByDeviceId
|
||||
path: ApiEndpoints.updateScheduleByDeviceId
|
||||
.replaceAll('{deviceUuid}', uuid)
|
||||
.replaceAll('{scheduleUuid}', scheduleId),
|
||||
body: {
|
||||
@ -246,7 +247,7 @@ class DevicesManagementApi {
|
||||
Future<bool> deleteScheduleRecord(String uuid, String scheduleId) async {
|
||||
try {
|
||||
final response = await HTTPService().delete(
|
||||
path: ApiEndpoints.scheduleByDeviceId
|
||||
path: ApiEndpoints.deleteScheduleByDeviceId
|
||||
.replaceAll('{deviceUuid}', uuid)
|
||||
.replaceAll('{scheduleUuid}', scheduleId),
|
||||
showServerMessage: true,
|
||||
|
@ -25,7 +25,14 @@ String formatTimeOfDayToISO(TimeOfDay time, {DateTime? currentDate}) {
|
||||
return dateTime.toUtc().toIso8601String();
|
||||
}
|
||||
|
||||
String formatIsoStringToTime(String isoString) {
|
||||
final dateTime = DateTime.parse(isoString);
|
||||
return DateFormat('hh:mm a').format(dateTime);
|
||||
String formatIsoStringToTime(String isoString, BuildContext context) {
|
||||
try {
|
||||
final parts = isoString.split(':');
|
||||
final hour = int.parse(parts[0]);
|
||||
final minute = int.parse(parts[1]);
|
||||
final timeOfDay = TimeOfDay(hour: hour, minute: minute);
|
||||
return timeOfDay.format(context);
|
||||
} catch (e) {
|
||||
return isoString;
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user