bug fixes 2

This commit is contained in:
mohammad
2024-09-23 14:37:07 +03:00
parent 62e80c89a2
commit 429009aefa
11 changed files with 863 additions and 661 deletions

View File

@ -8,7 +8,6 @@ import 'package:syncrow_app/features/auth/model/user_model.dart';
import 'package:syncrow_app/navigation/navigation_service.dart';
import 'package:syncrow_app/navigation/routing_constants.dart';
import 'package:syncrow_app/services/api/authentication_api.dart';
import 'package:syncrow_app/services/api/profile_api.dart';
import 'package:syncrow_app/utils/helpers/shared_preferences_helper.dart';
import 'package:syncrow_app/utils/helpers/snack_bar.dart';
import 'package:syncrow_app/utils/resource_manager/strings_manager.dart';

View File

@ -16,7 +16,7 @@ class DoorSensorBloc extends Bloc<DoorSensorEvent, DoorSensorState> {
DoorSensorBloc({
required this.DSId,
}) : super(const DoorSensorState()) {
on<DoorSensorInitial>(_fetchWaterHeaterStatus);
on<DoorSensorInitial>(_fetchStatus);
on<ReportLogsInitial>(fetchLogsForLastMonth);
on<ToggleLowBatteryEvent>(_toggleLowBattery);
on<ToggleClosingReminderEvent>(_toggleClosingReminder);
@ -26,9 +26,11 @@ class DoorSensorBloc extends Bloc<DoorSensorEvent, DoorSensorState> {
bool lowBattery = false;
bool closingReminder = false;
bool doorAlarm = false;
DoorSensorModel deviceStatus = DoorSensorModel(doorContactState: false, batteryPercentage: 0);
DoorSensorModel deviceStatus =
DoorSensorModel(doorContactState: false, batteryPercentage: 0);
void _fetchWaterHeaterStatus(DoorSensorInitial event, Emitter<DoorSensorState> emit) async {
void _fetchStatus(
DoorSensorInitial event, Emitter<DoorSensorState> emit) async {
emit(DoorSensorLoadingState());
try {
var response = await DevicesAPI.getDeviceStatus(DSId);
@ -49,7 +51,8 @@ class DoorSensorBloc extends Bloc<DoorSensorEvent, DoorSensorState> {
}
// Toggle functions for each switch
void _toggleLowBattery(ToggleLowBatteryEvent event, Emitter<DoorSensorState> emit) async {
void _toggleLowBattery(
ToggleLowBatteryEvent event, Emitter<DoorSensorState> emit) async {
emit(LoadingNewSate(doorSensor: deviceStatus));
try {
lowBattery = event.isLowBatteryEnabled;
@ -90,7 +93,8 @@ class DoorSensorBloc extends Bloc<DoorSensorEvent, DoorSensorState> {
}
}
void _toggleDoorAlarm(ToggleDoorAlarmEvent event, Emitter<DoorSensorState> emit) async {
void _toggleDoorAlarm(
ToggleDoorAlarmEvent event, Emitter<DoorSensorState> emit) async {
emit(LoadingNewSate(doorSensor: deviceStatus));
try {
doorAlarm = event.isDoorAlarmEnabled;
@ -110,9 +114,11 @@ class DoorSensorBloc extends Bloc<DoorSensorEvent, DoorSensorState> {
}
}
DeviceReport recordGroups = DeviceReport(startTime: '0', endTime: '0', data: []);
DeviceReport recordGroups =
DeviceReport(startTime: '0', endTime: '0', data: []);
Future<void> fetchLogsForLastMonth(ReportLogsInitial event, Emitter<DoorSensorState> emit) async {
Future<void> fetchLogsForLastMonth(
ReportLogsInitial event, Emitter<DoorSensorState> emit) async {
// Get the current date and time
DateTime now = DateTime.now();
@ -123,15 +129,18 @@ class DoorSensorBloc extends Bloc<DoorSensorEvent, DoorSensorState> {
int startTime = lastMonth.millisecondsSinceEpoch;
int endTime = now.millisecondsSinceEpoch;
try {
emit(DoorSensorLoadingState());
var response = await DevicesAPI.getReportLogs(
startTime: startTime.toString(), // Convert to String if the API expects it
startTime:
startTime.toString(), // Convert to String if the API expects it
endTime: endTime.toString(), // Convert to String if the API expects it
deviceUuid: DSId,
code: 'doorcontact_state',
);
print('response======${response}');
recordGroups = response;
// Process response here
print(response);
emit(UpdateState(doorSensor: deviceStatus));
} on DioException catch (e) {
final errorData = e.response!.data;
String errorMessage = errorData['message'];
@ -142,14 +151,16 @@ class DoorSensorBloc extends Bloc<DoorSensorEvent, DoorSensorState> {
_listenToChanges() {
try {
DatabaseReference ref = FirebaseDatabase.instance.ref('device-status/$DSId');
DatabaseReference ref =
FirebaseDatabase.instance.ref('device-status/$DSId');
Stream<DatabaseEvent> stream = ref.onValue;
stream.listen((DatabaseEvent event) async {
if (_timer != null) {
await Future.delayed(const Duration(seconds: 2));
}
Map<dynamic, dynamic> usersMap = event.snapshot.value as Map<dynamic, dynamic>;
Map<dynamic, dynamic> usersMap =
event.snapshot.value as Map<dynamic, dynamic>;
List<StatusModel> statusList = [];
usersMap['status'].forEach((element) {

View File

@ -1,7 +1,7 @@
class DeviceReport {
final String? deviceUuid;
final String? startTime;
final String? endTime;
final dynamic deviceUuid;
final dynamic startTime;
final dynamic endTime;
final List<DeviceEvent>? data;
DeviceReport({

View File

@ -4,27 +4,10 @@ import 'package:intl/intl.dart';
import 'package:syncrow_app/features/devices/bloc/door_sensor_bloc/door_sensor_bloc.dart';
import 'package:syncrow_app/features/devices/bloc/door_sensor_bloc/door_sensor_event.dart';
import 'package:syncrow_app/features/devices/bloc/door_sensor_bloc/door_sensor_state.dart';
import 'package:syncrow_app/features/devices/model/device_report_model.dart';
import 'package:syncrow_app/features/shared_widgets/default_container.dart';
import 'package:syncrow_app/features/shared_widgets/default_scaffold.dart';
// // class DoorRecordsScreen extends StatelessWidget {
// final String DSId;
// const DoorRecordsScreen({super.key, required this.DSId});
// @override
// Widget build(BuildContext context) {
// return DefaultScaffold(
// title: 'Records',
// child: BlocProvider(
// create: (context) =>
// DoorSensorBloc(DSId: DSId)..add(const ReportLogsInitial()),
// child: BlocBuilder<DoorSensorBloc, DoorSensorState>(
// builder: (context, state) {
// final doorSensorBloc = BlocProvider.of<DoorSensorBloc>(context);
// return SizedBox(
// child: ListView.builder(
// itemCount: doorSensorBloc.recordGroups!.data!.length,
// itemBuilder: (context, index) {
// final recordGroup = doorSensorBloc.recordGroups!.data![index];
import 'package:syncrow_app/utils/resource_manager/color_manager.dart';
class DoorRecordsScreen extends StatelessWidget {
final String DSId;
@ -35,36 +18,43 @@ class DoorRecordsScreen extends StatelessWidget {
return DefaultScaffold(
title: 'Records',
child: BlocProvider(
create: (context) => DoorSensorBloc(DSId: DSId)..add(const ReportLogsInitial()),
create: (context) =>
DoorSensorBloc(DSId: DSId)..add(const ReportLogsInitial()),
child: BlocBuilder<DoorSensorBloc, DoorSensorState>(
builder: (context, state) {
final doorSensorBloc = BlocProvider.of<DoorSensorBloc>(context);
if (state is DoorSensorLoadingState) {
return const Center(child: CircularProgressIndicator());
}
if (state is DoorSensorFailedState) {
return Center(
child: Text('Failed to load data: ${state.errorMessage}'),
return const Center(
child: DefaultContainer(
width: 50, height: 50, child: CircularProgressIndicator()),
);
}
} else if (state is UpdateState) {
// Group records by formatted date
final Map<String, List<DeviceEvent>> groupedRecords = {};
if (state is UpdateState) {
final recordGroups = context.read<DoorSensorBloc>().recordGroups;
// Iterate over the data list in DeviceReport
for (var record in doorSensorBloc.recordGroups.data!) {
final DateTime eventDateTime =
DateTime.fromMillisecondsSinceEpoch(record.eventTime!);
final String formattedDate =
DateFormat('EEEE, dd/MM/yyyy').format(eventDateTime);
if (recordGroups.data == null || recordGroups.data!.isEmpty) {
return const Center(child: Text('No records available.'));
// Group by formatted date
if (groupedRecords.containsKey(formattedDate)) {
groupedRecords[formattedDate]!.add(record);
} else {
groupedRecords[formattedDate] = [record];
}
}
// Build the ListView with grouped data
return ListView.builder(
itemCount: recordGroups.data!.length,
itemCount: groupedRecords.length,
itemBuilder: (context, index) {
final record = recordGroups.data![index];
// Convert eventTime to a human-readable format
final DateTime eventDateTime =
DateTime.fromMillisecondsSinceEpoch(record.eventTime!);
final String formattedDate = DateFormat('EEEE, dd/MM/yyyy').format(eventDateTime);
final String formattedTime = DateFormat('HH:mm:ss').format(eventDateTime);
final String date = groupedRecords.keys.elementAt(index);
final List<DeviceEvent> recordsForDate =
groupedRecords[date]!;
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
@ -73,30 +63,57 @@ class DoorRecordsScreen extends StatelessWidget {
Padding(
padding: const EdgeInsets.all(16.0),
child: Text(
formattedDate,
date,
style: const TextStyle(
fontSize: 18,
fontWeight: FontWeight.bold,
color: ColorsManager.grayColor,
fontSize: 13,
fontWeight: FontWeight.w700,
),
),
),
// Display the event details in DefaultContainer
// List of records for the specific date
DefaultContainer(
child: ListTile(
leading: Icon(
record.value == 'true'
? Icons.radio_button_checked
: Icons.radio_button_unchecked,
color: record.value == 'true' ? Colors.blue : Colors.grey,
),
title: Text(
'Status: ${record.value}',
style: const TextStyle(
fontWeight: FontWeight.bold,
fontSize: 18,
),
),
subtitle: Text('Time: $formattedTime'),
child: Column(
children: [
...recordsForDate.map((record) {
final DateTime eventDateTime =
DateTime.fromMillisecondsSinceEpoch(
record.eventTime!);
final String formattedTime =
DateFormat('HH:mm:ss').format(eventDateTime);
return Column(
children: [
Container(
child: ListTile(
leading: Icon(
record.value == 'true'
? Icons.radio_button_checked
: Icons.radio_button_unchecked,
color: record.value == 'true'
? Colors.blue
: Colors.grey,
),
title: Text(
record.value == 'true'
? "Opened"
: "Closed",
style: const TextStyle(
fontWeight: FontWeight.bold,
fontSize: 18,
),
),
subtitle: Text('$formattedTime'),
),
),
const Divider(
color: ColorsManager.graysColor,
)
],
);
}).toList(),
],
),
),
],
@ -104,7 +121,6 @@ class DoorRecordsScreen extends StatelessWidget {
},
);
}
return const Center(child: Text('No data available.'));
},
),

View File

@ -63,17 +63,20 @@ class ScheduleScreen extends StatelessWidget {
Navigator.push(
context,
PageRouteBuilder(
pageBuilder: (context, animation1, animation2) => TimerScheduleScreen(
switchCode :"switch_1",
device: device,
deviceCode: 'countdown_1',
)));
pageBuilder:
(context, animation1, animation2) =>
TimerScheduleScreen(
switchCode: "switch_1",
device: device,
deviceCode: 'countdown_1',
)));
},
child: Container(
padding:
const EdgeInsets.only(left: 25, right: 15, top: 20, bottom: 20),
padding: const EdgeInsets.only(
left: 25, right: 15, top: 20, bottom: 20),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
mainAxisAlignment:
MainAxisAlignment.spaceBetween,
children: [
BodySmall(
text: "Bedside Light",
@ -100,17 +103,20 @@ class ScheduleScreen extends StatelessWidget {
Navigator.push(
context,
PageRouteBuilder(
pageBuilder: (context, animation1, animation2) => TimerScheduleScreen(
switchCode :"switch_2",
device: device,
deviceCode: 'countdown_2',
)));
pageBuilder:
(context, animation1, animation2) =>
TimerScheduleScreen(
switchCode: "switch_2",
device: device,
deviceCode: 'countdown_2',
)));
},
child: Container(
padding:
const EdgeInsets.only(left: 25, right: 15, top: 20, bottom: 20),
padding: const EdgeInsets.only(
left: 25, right: 15, top: 20, bottom: 20),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
mainAxisAlignment:
MainAxisAlignment.spaceBetween,
children: [
BodySmall(
text: "Ceiling Light",
@ -137,17 +143,20 @@ class ScheduleScreen extends StatelessWidget {
Navigator.push(
context,
PageRouteBuilder(
pageBuilder: (context, animation1, animation2) => TimerScheduleScreen(
switchCode :"switch_3",
device: device,
deviceCode: 'countdown_3',
)));
pageBuilder:
(context, animation1, animation2) =>
TimerScheduleScreen(
switchCode: "switch_3",
device: device,
deviceCode: 'countdown_3',
)));
},
child: Container(
padding:
const EdgeInsets.only(left: 25, right: 15, top: 20, bottom: 20),
padding: const EdgeInsets.only(
left: 25, right: 15, top: 20, bottom: 20),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
mainAxisAlignment:
MainAxisAlignment.spaceBetween,
children: [
BodySmall(
text: "Spotlight",

View File

@ -22,7 +22,10 @@ class TimerScheduleScreen extends StatelessWidget {
final String deviceCode;
final String switchCode;
const TimerScheduleScreen(
{required this.device, required this.deviceCode, required this.switchCode, super.key});
{required this.device,
required this.deviceCode,
required this.switchCode,
super.key});
@override
Widget build(BuildContext context) {
@ -32,7 +35,8 @@ class TimerScheduleScreen extends StatelessWidget {
statusBarIconBrightness: Brightness.light,
),
child: BlocProvider(
create: (context) => ThreeGangBloc(switchCode: switchCode, threeGangId: device.uuid ?? '')
create: (context) => ThreeGangBloc(
switchCode: switchCode, threeGangId: device.uuid ?? '')
..add(GetCounterEvent(deviceCode: deviceCode))
..add(GetScheduleEvent()),
child: BlocBuilder<ThreeGangBloc, ThreeGangState>(
@ -94,13 +98,15 @@ class TimerScheduleScreen extends StatelessWidget {
decoration: const ShapeDecoration(
color: ColorsManager.onPrimaryColor,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(30)),
borderRadius:
BorderRadius.all(Radius.circular(30)),
),
),
child: TabBar(
onTap: (value) {
if (value == 0) {
if (threeGangBloc.createSchedule == true) {
if (threeGangBloc.createSchedule ==
true) {
threeGangBloc.toggleCreateSchedule();
}
threeGangBloc.toggleSelectedIndex(0);
@ -108,19 +114,21 @@ class TimerScheduleScreen extends StatelessWidget {
threeGangBloc.toggleSelectedIndex(1);
}
},
indicatorColor: Colors.white, // Customize the indicator
indicatorColor: Colors.white,
dividerHeight: 0,
indicatorSize: TabBarIndicatorSize.tab,
indicator: const ShapeDecoration(
color: ColorsManager.slidingBlueColor,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(20)),
borderRadius: BorderRadius.all(
Radius.circular(20)),
),
),
tabs: [
Tab(
child: Container(
padding: const EdgeInsets.symmetric(vertical: 10),
padding: const EdgeInsets.symmetric(
vertical: 10),
child: BodySmall(
text: 'Countdown',
style: context.bodySmall.copyWith(
@ -133,7 +141,8 @@ class TimerScheduleScreen extends StatelessWidget {
),
Tab(
child: Container(
padding: const EdgeInsets.symmetric(vertical: 10),
padding: const EdgeInsets.symmetric(
vertical: 10),
child: Text(
'Schedule',
style: context.bodySmall.copyWith(
@ -153,84 +162,118 @@ class TimerScheduleScreen extends StatelessWidget {
Center(
child: Container(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
mainAxisAlignment:
MainAxisAlignment.center,
children: [
countNum > 0
? BodyLarge(
text: _formatDuration(countNum),
fontColor: ColorsManager.slidingBlueColor,
text: _formatDuration(
countNum),
fontColor: ColorsManager
.slidingBlueColor,
fontSize: 40,
)
: CupertinoTimerPicker(
mode: CupertinoTimerPickerMode.hm,
mode:
CupertinoTimerPickerMode
.hm,
onTimerDurationChanged:
(Duration newDuration) {
(Duration
newDuration) {
duration = newDuration;
},
),
GestureDetector(
onTap: () {
if (state is LoadingNewSate) {
if (state
is LoadingNewSate) {
return;
}
if (countNum > 0) {
threeGangBloc.add(SetCounterValue(
deviceCode: deviceCode,
duration: Duration.zero));
} else if (duration != Duration.zero) {
threeGangBloc.add(SetCounterValue(
deviceCode: deviceCode,
duration: duration));
threeGangBloc.add(
SetCounterValue(
deviceCode:
deviceCode,
duration: Duration
.zero));
} else if (duration !=
Duration.zero) {
threeGangBloc.add(
SetCounterValue(
deviceCode:
deviceCode,
duration:
duration));
}
},
child: SvgPicture.asset(countNum > 0
? Assets.pauseIcon
: Assets.playIcon)),
child: SvgPicture.asset(
countNum > 0
? Assets.pauseIcon
: Assets.playIcon)),
],
),
),
),
Column(
mainAxisAlignment: threeGangBloc.listSchedule.isNotEmpty
? MainAxisAlignment.start
: MainAxisAlignment.center,
children: [
SizedBox(
child: threeGangBloc.createSchedule == true
? CreateSchedule(
onToggleChanged: (bool isOn) {
threeGangBloc.toggleSchedule = isOn;
},
onDateTimeChanged: (DateTime dateTime) {
threeGangBloc.selectedTime = dateTime;
},
days: threeGangBloc.days,
selectDays: (List<String> selectedDays) {
threeGangBloc.selectedDays = selectedDays;
},
)
: Padding(
padding: const EdgeInsets.only(top: 10),
child: ScheduleListView(
listSchedule: threeGangBloc
.listSchedule, // Pass the schedule list here
onDismissed: (scheduleId) {
threeGangBloc.listSchedule.removeWhere(
(schedule) =>
schedule.scheduleId == scheduleId);
threeGangBloc.add(
DeleteScheduleEvent(id: scheduleId));
},
onToggleSchedule: (scheduleId, isEnabled) {
threeGangBloc.add(ToggleScheduleEvent(
id: scheduleId,
toggle: isEnabled,
));
},
SizedBox(
child: threeGangBloc.createSchedule ==
true
? CreateSchedule(
onToggleChanged: (bool isOn) {
threeGangBloc.toggleSchedule =
isOn;
},
onDateTimeChanged:
(DateTime dateTime) {
threeGangBloc.selectedTime =
dateTime;
},
days: threeGangBloc.days,
selectDays: (List<String>
selectedDays) {
threeGangBloc.selectedDays =
selectedDays;
},
)
: Padding(
padding: const EdgeInsets.only(
top: 10),
child: Column(
mainAxisAlignment:
MainAxisAlignment.start,
crossAxisAlignment:
CrossAxisAlignment.start,
children: [
Expanded(
child: ScheduleListView(
listSchedule: threeGangBloc
.listSchedule, // Pass the schedule list here
onDismissed:
(scheduleId) {
threeGangBloc
.listSchedule
.removeWhere(
(schedule) =>
schedule
.scheduleId ==
scheduleId);
threeGangBloc.add(
DeleteScheduleEvent(
id: scheduleId));
},
onToggleSchedule:
(scheduleId,
isEnabled) {
threeGangBloc.add(
ToggleScheduleEvent(
id: scheduleId,
toggle: isEnabled,
));
},
),
),
),
),
],
],
),
),
),
],
),

View File

@ -63,7 +63,7 @@ class TimerScheduleScreen extends StatelessWidget {
},
child: DefaultTabController(
length: 2,
child: DefaultScaffold(
child: DefaultScaffold(
appBar: AppBar(
backgroundColor: Colors.transparent,
centerTitle: true,
@ -73,177 +73,204 @@ class TimerScheduleScreen extends StatelessWidget {
fontWeight: FontsManager.bold,
),
actions: [
twoGangBloc.createSchedule == true ?
TextButton(
onPressed: () {
twoGangBloc.add(TwoGangSave());
},
child: const Text('Save')
) :
twoGangBloc.selectedTabIndex==1? IconButton(
onPressed: () {
twoGangBloc.toggleCreateSchedule();
},
icon: const Icon(Icons.add),
):SizedBox(),
twoGangBloc.createSchedule == true
? TextButton(
onPressed: () {
twoGangBloc.add(TwoGangSave());
},
child: const Text('Save'))
: twoGangBloc.selectedTabIndex == 1
? IconButton(
onPressed: () {
twoGangBloc.toggleCreateSchedule();
},
icon: const Icon(Icons.add),
)
: SizedBox(),
],
),
child:
state is LoadingInitialState?
const Center(child: CircularProgressIndicator()):
Column(
children: [
Container(
width: MediaQuery.of(context).size.width,
decoration: const ShapeDecoration(
color: ColorsManager.onPrimaryColor,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(30)),
),
),
child: TabBar(
onTap: (value) {
print(value);
if(value==0){
if(twoGangBloc.createSchedule == true){
twoGangBloc.toggleCreateSchedule();
}
twoGangBloc.toggleSelectedIndex(0);
}else{
twoGangBloc.toggleSelectedIndex(1);
}
},
indicatorColor: Colors.white, // Customize the indicator
dividerHeight: 0,
indicatorSize: TabBarIndicatorSize.tab,
indicator: const ShapeDecoration(
color: ColorsManager.slidingBlueColor,
shape: RoundedRectangleBorder(
borderRadius:
BorderRadius.all(Radius.circular(20)),
),
),
tabs: [
Tab(
child: Container(
padding: const EdgeInsets.symmetric(
vertical: 10),
child: BodySmall(
text: 'Countdown',
style: context.bodySmall.copyWith(
color: ColorsManager.blackColor,
fontSize: 12,
fontWeight: FontWeight.w400,
),
),
),
),
Tab(
child: Container(
padding: const EdgeInsets.symmetric(vertical: 10),
child: Text(
'Schedule',
style: context.bodySmall.copyWith(
color: ColorsManager.blackColor,
fontSize: 12,
fontWeight: FontWeight.w400,
),
),
),
),
],
),
),
Expanded(
child: TabBarView(
child: state is LoadingInitialState
? const Center(child: CircularProgressIndicator())
: Column(
children: [
Center(
child: Container(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
countNum > 0
? BodyLarge(
text: _formatDuration(countNum),
fontColor:
ColorsManager.slidingBlueColor,
fontSize: 40,
)
: CupertinoTimerPicker(
mode: CupertinoTimerPickerMode.hm,
onTimerDurationChanged:
(Duration newDuration) {
duration = newDuration;
},
),
GestureDetector(
onTap: () {
if (state is LoadingNewSate) {
return;
}
if (countNum > 0) {
twoGangBloc.add(SetCounterValue(
deviceCode: deviceCode,
duration: Duration.zero));
} else if (duration != Duration.zero) {
twoGangBloc.add(SetCounterValue(
deviceCode: deviceCode,
duration: duration));
}
},
child: SvgPicture.asset(countNum > 0
? Assets.pauseIcon
: Assets.playIcon)),
],
Container(
width: MediaQuery.of(context).size.width,
decoration: const ShapeDecoration(
color: ColorsManager.onPrimaryColor,
shape: RoundedRectangleBorder(
borderRadius:
BorderRadius.all(Radius.circular(30)),
),
),
),
Column(
mainAxisAlignment:twoGangBloc.listSchedule.isNotEmpty?
MainAxisAlignment.start:MainAxisAlignment.center,
children: [
SizedBox(
child: twoGangBloc.createSchedule == true ?
CreateSchedule(
onToggleChanged: (bool isOn) {
twoGangBloc.toggleSchedule = isOn;
},
onDateTimeChanged: (DateTime dateTime) {
twoGangBloc.selectedTime=dateTime;
},
days: twoGangBloc.days,
selectDays: (List<String> selectedDays) {
twoGangBloc.selectedDays = selectedDays;
},
)
:
Padding(
padding: const EdgeInsets.only(top: 10),
child: ScheduleListView(
listSchedule: twoGangBloc.listSchedule, // Pass the schedule list here
onDismissed: (scheduleId) {
twoGangBloc.listSchedule.removeWhere((schedule) => schedule.scheduleId == scheduleId);
twoGangBloc.add(DeleteScheduleEvent(id: scheduleId));
},
onToggleSchedule: (scheduleId, isEnabled) {
twoGangBloc.add(ToggleScheduleEvent(
id: scheduleId,
toggle: isEnabled,
));
},
),
child: TabBar(
onTap: (value) {
print(value);
if (value == 0) {
if (twoGangBloc.createSchedule ==
true) {
twoGangBloc.toggleCreateSchedule();
}
twoGangBloc.toggleSelectedIndex(0);
} else {
twoGangBloc.toggleSelectedIndex(1);
}
},
indicatorColor:
Colors.white, // Customize the indicator
dividerHeight: 0,
indicatorSize: TabBarIndicatorSize.tab,
indicator: const ShapeDecoration(
color: ColorsManager.slidingBlueColor,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.all(
Radius.circular(20)),
),
),
],
tabs: [
Tab(
child: Container(
padding: const EdgeInsets.symmetric(
vertical: 10),
child: BodySmall(
text: 'Countdown',
style: context.bodySmall.copyWith(
color: ColorsManager.blackColor,
fontSize: 12,
fontWeight: FontWeight.w400,
),
),
),
),
Tab(
child: Container(
padding: const EdgeInsets.symmetric(
vertical: 10),
child: Text(
'Schedule',
style: context.bodySmall.copyWith(
color: ColorsManager.blackColor,
fontSize: 12,
fontWeight: FontWeight.w400,
),
),
),
),
],
),
),
Expanded(
child: TabBarView(
children: [
Center(
child: Container(
child: Column(
mainAxisAlignment:
MainAxisAlignment.center,
children: [
countNum > 0
? BodyLarge(
text: _formatDuration(
countNum),
fontColor: ColorsManager
.slidingBlueColor,
fontSize: 40,
)
: CupertinoTimerPicker(
mode:
CupertinoTimerPickerMode
.hm,
onTimerDurationChanged:
(Duration
newDuration) {
duration = newDuration;
},
),
GestureDetector(
onTap: () {
if (state
is LoadingNewSate) {
return;
}
if (countNum > 0) {
twoGangBloc.add(
SetCounterValue(
deviceCode:
deviceCode,
duration: Duration
.zero));
} else if (duration !=
Duration.zero) {
twoGangBloc.add(
SetCounterValue(
deviceCode:
deviceCode,
duration:
duration));
}
},
child: SvgPicture.asset(
countNum > 0
? Assets.pauseIcon
: Assets.playIcon)),
],
),
),
),
SizedBox(
child: twoGangBloc.createSchedule ==
true
? CreateSchedule(
onToggleChanged: (bool isOn) {
twoGangBloc.toggleSchedule =
isOn;
},
onDateTimeChanged:
(DateTime dateTime) {
twoGangBloc.selectedTime =
dateTime;
},
days: twoGangBloc.days,
selectDays: (List<String>
selectedDays) {
twoGangBloc.selectedDays =
selectedDays;
},
)
: Padding(
padding: const EdgeInsets.only(
top: 10),
child: Column(
children: [
Expanded(
child: ScheduleListView(
listSchedule: twoGangBloc.listSchedule, // Pass the schedule list here
onDismissed:(scheduleId) {
twoGangBloc .listSchedule
.removeWhere( (schedule) => schedule .scheduleId == scheduleId);
twoGangBloc.add(
DeleteScheduleEvent( id: scheduleId));
},
onToggleSchedule:
(scheduleId,
isEnabled) {
twoGangBloc.add(
ToggleScheduleEvent(
id: scheduleId,
toggle: isEnabled,
));
},
),
),
],
),
),
),
],
),
),
],
),
),
],
),
))
);
)));
},
),
),

View File

@ -1,8 +1,3 @@
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';
@ -13,7 +8,6 @@ import 'package:syncrow_app/features/shared_widgets/text_widgets/body_large.dart
import 'package:syncrow_app/features/shared_widgets/text_widgets/body_medium.dart';
import 'package:syncrow_app/generated/assets.dart';
class CirculateListView extends StatelessWidget {
final List<ScheduleModel> listSchedule;
final Function(String) onDismissed;
@ -30,96 +24,98 @@ class CirculateListView extends StatelessWidget {
return Center(
child: listSchedule.isNotEmpty
? SizedBox(
child: ListView.builder(
shrinkWrap: true,
itemCount: listSchedule.length,
itemBuilder: (context, index) {
return Dismissible(
key: Key(listSchedule[index].scheduleId),
background: Container(
padding: const EdgeInsets.only(right: 10),
alignment: AlignmentDirectional.centerEnd,
decoration: const ShapeDecoration(
color: Color(0xFFFF0000),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(20)),
),
),
child: Padding(
padding: const EdgeInsets.only(bottom: 10, right: 10),
child: SvgPicture.asset(
Assets.assetsDeleteIcon,
width: 20,
height: 22,
),
),
),
direction: DismissDirection.endToStart,
onDismissed: (direction) {
child: ListView.builder(
shrinkWrap: true,
itemCount: listSchedule.length,
itemBuilder: (context, index) {
return Dismissible(
key: Key(listSchedule[index].scheduleId),
background: Container(
padding: const EdgeInsets.only(right: 10),
alignment: AlignmentDirectional.centerEnd,
decoration: const ShapeDecoration(
color: Color(0xFFFF0000),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(20)),
),
),
child: Padding(
padding: const EdgeInsets.only(bottom: 10, right: 10),
child: SvgPicture.asset(
Assets.assetsDeleteIcon,
width: 20,
height: 22,
),
),
),
direction: DismissDirection.endToStart,
onDismissed: (direction) {
onDismissed(listSchedule[index].scheduleId);
onDismissed(listSchedule[index].scheduleId);
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(content: Text('Schedule removed')),
);
},
child: InkWell(
onTap: () {
},
child: DefaultContainer(
padding: const EdgeInsets.all(20),
height: MediaQuery.of(context).size.height / 6.4,
child: Row(
children: [
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(content: Text('Schedule removed')),
);
},
child: InkWell(
onTap: () {},
child: DefaultContainer(
padding: const EdgeInsets.all(20),
height: MediaQuery.of(context).size.height / 6.5,
child: Row(
children: [
BodyLarge(
text: '12:30 AM - 01:30 PM',
// text: listSchedule[index].time,
fontWeight: FontWeight.w500,
fontColor: Colors.black,
fontSize: 22,
Expanded(
flex: 2,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
children: [
BodyLarge(
text: '12:30 AM - 01:30 PM',
// text: listSchedule[index].time,
fontWeight: FontWeight.w500,
fontColor: Colors.black,
fontSize: 18,
),
],
),
Text(listSchedule[index].days.join(' ')),
// Text('Function ${listSchedule[index].function.value ? "ON" : "OFF"}'),
Text(
'Start Duration: 0h 10m End Duration: 0h 15m'),
],
),
),
Expanded(
child: ListTile(
contentPadding: EdgeInsets.zero,
leading: const BodyMedium(
text: '',
fontWeight: FontWeight.normal,
),
trailing: Transform.scale(
scale: .8,
child: CupertinoSwitch(
value: listSchedule[index].enable,
onChanged: (value) {
onToggleSchedule(
listSchedule[index].scheduleId,
value,
);
},
applyTheme: true,
),
),
),
),
Text(listSchedule[index].days.join(' ')),
// Text('Function ${listSchedule[index].function.value ? "ON" : "OFF"}'),
Text('Start Duration: 0h 10m End Duration: 0h 15m'),
],
),
),
Expanded(
child: ListTile(
contentPadding: EdgeInsets.zero,
leading: const BodyMedium(
text: '',
fontWeight: FontWeight.normal,
),
trailing: Transform.scale(
scale: .8,
child: CupertinoSwitch(
value: listSchedule[index].enable,
onChanged: (value) {
onToggleSchedule(
listSchedule[index].scheduleId,
value,
);
},
applyTheme: true,
),
),
),
),
],
),
),
),
);
},
),
);
},
),
)
: const EmptySchedule()
);
)
: const EmptySchedule());
}
}

View File

@ -76,33 +76,36 @@ class WHTimerScheduleScreen extends StatelessWidget {
fontWeight: FontsManager.bold,
),
actions: [
waterHeaterBloc.createSchedule == true && waterHeaterBloc.selectedTabIndex == 1 ?
TextButton(
onPressed: () {
waterHeaterBloc.add(ScheduleSave());
},
child: const Text('Save')) : waterHeaterBloc.selectedTabIndex == 1
? IconButton(
onPressed: () {
waterHeaterBloc.toggleCreateSchedule();
},
icon: const Icon(Icons.add),
)
: const SizedBox(),
waterHeaterBloc.createCirculate == true &&waterHeaterBloc.selectedTabIndex==2 ?
TextButton(
onPressed: () {
waterHeaterBloc.add(ScheduleSave());
},
child: const Text('Save'))
: waterHeaterBloc.selectedTabIndex == 2
? IconButton(
onPressed: () {
waterHeaterBloc.toggleCreateCirculate();
waterHeaterBloc.createSchedule == true &&
waterHeaterBloc.selectedTabIndex == 1
? TextButton(
onPressed: () {
waterHeaterBloc.add(ScheduleSave());
},
icon: const Icon(Icons.add),
)
: const SizedBox(),
child: const Text('Save'))
: waterHeaterBloc.selectedTabIndex == 1
? IconButton(
onPressed: () {
waterHeaterBloc.toggleCreateSchedule();
},
icon: const Icon(Icons.add),
)
: const SizedBox(),
waterHeaterBloc.createCirculate == true &&
waterHeaterBloc.selectedTabIndex == 2
? TextButton(
onPressed: () {
waterHeaterBloc.add(ScheduleSave());
},
child: const Text('Save'))
: waterHeaterBloc.selectedTabIndex == 2
? IconButton(
onPressed: () {
waterHeaterBloc.toggleCreateCirculate();
},
icon: const Icon(Icons.add),
)
: const SizedBox(),
],
),
child: state is WHLoadingState
@ -124,20 +127,29 @@ class WHTimerScheduleScreen extends StatelessWidget {
labelPadding: EdgeInsets.zero,
onTap: (value) {
if (value == 0) {
if (waterHeaterBloc.createSchedule == true) {
waterHeaterBloc.toggleCreateSchedule();
if (waterHeaterBloc.createSchedule ==
true) {
waterHeaterBloc
.toggleCreateSchedule();
}
waterHeaterBloc.toggleSelectedIndex(value);
} else if (value == 2) {
if (waterHeaterBloc.createCirculate == true) {
waterHeaterBloc.toggleCreateCirculate();
waterHeaterBloc
.toggleSelectedIndex(value);
} else if (value == 2) {
if (waterHeaterBloc.createCirculate ==
true) {
waterHeaterBloc
.toggleCreateCirculate();
}
waterHeaterBloc.toggleSelectedIndex(value);
waterHeaterBloc
.toggleSelectedIndex(value);
} else {
if (waterHeaterBloc.createSchedule == true) {
waterHeaterBloc.toggleCreateSchedule();
if (waterHeaterBloc.createSchedule ==
true) {
waterHeaterBloc
.toggleCreateSchedule();
}
waterHeaterBloc.toggleSelectedIndex(value);
waterHeaterBloc
.toggleSelectedIndex(value);
}
},
indicatorColor: Colors.white,
@ -151,96 +163,128 @@ class WHTimerScheduleScreen extends StatelessWidget {
),
),
isScrollable: false,
labelColor: Colors.white, // Text color when selected
unselectedLabelColor: ColorsManager.blackColor, // Text color when not selected
labelColor: Colors
.white, // Text color when selected
unselectedLabelColor: ColorsManager
.blackColor, // Text color when not selected
tabs: [
Tab(
icon: SvgPicture.asset(
Assets.scheduleTimeIcon,
color: waterHeaterBloc.selectedTabIndex == 0
? Colors.white
: ColorsManager.blackColor, // Change icon color based on selectedIndex
icon: Padding(
padding: const EdgeInsets.only(
top: 10.0),
child: SvgPicture.asset(
Assets.scheduleTimeIcon,
color: waterHeaterBloc
.selectedTabIndex ==
0
? Colors.white
: ColorsManager
.blackColor, // Change icon color based on selectedIndex
),
),
child: Container(
padding: const EdgeInsets.symmetric(
vertical: 10),
vertical: 5),
child: BodySmall(
text: 'Countdown',
style: context.bodySmall.copyWith(
color: waterHeaterBloc.selectedTabIndex == 0
color: waterHeaterBloc
.selectedTabIndex ==
0
? Colors.white
: ColorsManager
.blackColor, // Text color based on selectedTabIndex
fontSize: 8,
fontSize: 10,
fontWeight: FontWeight.w400,
),
),
),
),
Tab(
icon: SvgPicture.asset(
Assets.scheduleCelenderIcon,
color: waterHeaterBloc.selectedTabIndex == 1
? Colors.white
: ColorsManager.blackColor,
icon: Padding(
padding:
const EdgeInsets.only(top: 10),
child: SvgPicture.asset(
Assets.scheduleCelenderIcon,
color: waterHeaterBloc
.selectedTabIndex ==
1
? Colors.white
: ColorsManager.blackColor,
),
),
child: Container(
padding: const EdgeInsets.symmetric(
vertical: 10),
vertical: 5),
child: Text(
'Schedule',
style: context.bodySmall.copyWith(
color: waterHeaterBloc.selectedTabIndex == 1
color: waterHeaterBloc
.selectedTabIndex ==
1
? Colors.white
: ColorsManager.blackColor,
fontSize: 8,
fontSize: 12,
fontWeight: FontWeight.w400,
),
),
),
),
Tab(
icon: SvgPicture.asset(
Assets.scheduleCirculateIcon,
color: waterHeaterBloc.selectedTabIndex == 2
? Colors.white
: ColorsManager.blackColor,
icon: Padding(
padding:
const EdgeInsets.only(top: 10),
child: SvgPicture.asset(
Assets.scheduleCirculateIcon,
color: waterHeaterBloc
.selectedTabIndex ==
2
? Colors.white
: ColorsManager.blackColor,
),
),
child: Container(
padding: const EdgeInsets.symmetric(
vertical: 10),
vertical: 5),
child: Text(
'Circulate',
style: context.bodySmall.copyWith(
color: waterHeaterBloc
.selectedTabIndex == 2
.selectedTabIndex ==
2
? Colors.white
: ColorsManager.blackColor,
fontSize: 8,
fontSize: 12,
fontWeight: FontWeight.w400,
),
),
),
),
Tab(
icon: SvgPicture.asset(
Assets.scheduleInchingIcon,
color: waterHeaterBloc
.selectedTabIndex == 3
? Colors.white
: ColorsManager.blackColor,
icon: Padding(
padding:
const EdgeInsets.only(top: 10),
child: SvgPicture.asset(
Assets.scheduleInchingIcon,
color: waterHeaterBloc
.selectedTabIndex ==
3
? Colors.white
: ColorsManager.blackColor,
),
),
child: Container(
padding: const EdgeInsets.symmetric(
vertical: 10),
vertical: 5),
child: Text(
'Inching',
style: context.bodySmall.copyWith(
color: waterHeaterBloc
.selectedTabIndex == 3
.selectedTabIndex ==
3
? Colors.white
: ColorsManager.blackColor,
fontSize: 8,
fontSize: 12,
fontWeight: FontWeight.w400,
),
),
@ -308,93 +352,132 @@ class WHTimerScheduleScreen extends StatelessWidget {
),
),
),
Column(
mainAxisAlignment: waterHeaterBloc
.listSchedule.isNotEmpty
? MainAxisAlignment.start
: MainAxisAlignment.center,
children: [
SizedBox(
child: waterHeaterBloc.createSchedule == true
? CreateSchedule(
onToggleChanged: (bool isOn) {
waterHeaterBloc.toggleSchedule = isOn;
},
onDateTimeChanged: (DateTime dateTime) {
waterHeaterBloc.selectedTime = dateTime;
},
days: waterHeaterBloc.days,
selectDays: (List<String>
selectedDays) {
waterHeaterBloc
.selectedDays =
selectedDays;
},
)
: Padding(
padding: const EdgeInsets.only(top: 10),
child: ScheduleListView(
listSchedule: waterHeaterBloc.listSchedule, // Pass the schedule list here
onDismissed:
(scheduleId) {
waterHeaterBloc.listSchedule.removeWhere(
(schedule) => schedule.scheduleId == scheduleId);
waterHeaterBloc.add(
DeleteScheduleEvent(id: scheduleId));
},
onToggleSchedule: (scheduleId, isEnabled) {
waterHeaterBloc.add(ToggleScheduleEvent(
id: scheduleId, toggle: isEnabled,
));
},
SizedBox(
child: waterHeaterBloc.createSchedule ==
true
? CreateSchedule(
onToggleChanged: (bool isOn) {
waterHeaterBloc
.toggleSchedule = isOn;
},
onDateTimeChanged:
(DateTime dateTime) {
waterHeaterBloc.selectedTime =
dateTime;
},
days: waterHeaterBloc.days,
selectDays: (List<String>
selectedDays) {
waterHeaterBloc.selectedDays =
selectedDays;
},
)
: Padding(
padding: const EdgeInsets.only(
top: 10),
child: Column(
children: [
Expanded(
child: ScheduleListView(
listSchedule:
waterHeaterBloc
.listSchedule, // Pass the schedule list here
onDismissed:
(scheduleId) {
waterHeaterBloc
.listSchedule
.removeWhere(
(schedule) =>
schedule
.scheduleId ==
scheduleId);
waterHeaterBloc.add(
DeleteScheduleEvent(
id: scheduleId));
},
onToggleSchedule:
(scheduleId,
isEnabled) {
waterHeaterBloc.add(
ToggleScheduleEvent(
id: scheduleId,
toggle: isEnabled,
));
},
),
),
),
),
],
],
),
),
),
Center(
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment:
CrossAxisAlignment.center,
mainAxisAlignment:
MainAxisAlignment.center,
children: [
waterHeaterBloc.createCirculate == true
?
CirculateWidget(
endDuration: () {
waterHeaterBloc.add(SelectTimeEvent(context: context, isEffective: false));
},
startDuration: () {
waterHeaterBloc.add(SelectTimeEvent(context: context, isEffective: false));
},
isStartEndTime: true,
startTime: DateTime.now(),
endTime: DateTime.now(),
days: waterHeaterBloc.days,
selectedDays: [],
onToggleStartEndTime: (c) {},
onTimeChanged: (x, f) {
},
onDaySelected: (p0) {},
):CirculateListView(
listSchedule: waterHeaterBloc.listSchedule, // Pass the schedule list here
onDismissed: (scheduleId) {
waterHeaterBloc.listSchedule.removeWhere((schedule) => schedule.scheduleId == scheduleId);
waterHeaterBloc.add(DeleteScheduleEvent(id: scheduleId));
},
onToggleSchedule: (scheduleId, isEnabled) {
waterHeaterBloc.add(ToggleScheduleEvent(
id: scheduleId, toggle: isEnabled,
));
},
)
waterHeaterBloc.createCirculate ==
true
? CirculateWidget(
endDuration: () {
waterHeaterBloc.add(
SelectTimeEvent(
context: context,
isEffective:
false));
},
startDuration: () {
waterHeaterBloc.add(
SelectTimeEvent(
context: context,
isEffective:
false));
},
isStartEndTime: true,
startTime: DateTime.now(),
endTime: DateTime.now(),
days: waterHeaterBloc.days,
selectedDays: [],
onToggleStartEndTime:
(c) {},
onTimeChanged: (x, f) {},
onDaySelected: (p0) {},
)
: CirculateListView(
listSchedule: [], // Pass the schedule list here
onDismissed: (scheduleId) {
waterHeaterBloc
.listSchedule
.removeWhere((schedule) =>
schedule
.scheduleId ==
scheduleId);
waterHeaterBloc.add(
DeleteScheduleEvent(
id: scheduleId));
},
onToggleSchedule:
(scheduleId,
isEnabled) {
waterHeaterBloc.add(
ToggleScheduleEvent(
id: scheduleId,
toggle: isEnabled,
));
},
)
],
),
),
Column(children: [
SizedBox(height: 20),
Container(child: InchingWidget(),),],)
Column(
children: [
SizedBox(height: 20),
Container(
child: InchingWidget(),
),
],
)
],
),
),

View File

@ -21,94 +21,98 @@ class ScheduleListView extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Center(
child: listSchedule.isNotEmpty
? SizedBox(
child: ListView.builder(
shrinkWrap: true,
itemCount: listSchedule.length,
itemBuilder: (context, index) {
return Dismissible(
key: Key(listSchedule[index].scheduleId),
background: Container(
padding: const EdgeInsets.only(right: 10),
alignment: AlignmentDirectional.centerEnd,
decoration: const ShapeDecoration(
color: Color(0xFFFF0000),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(20)),
),
),
child: Padding(
padding: const EdgeInsets.only(bottom: 10, right: 10),
child: SvgPicture.asset(
Assets.assetsDeleteIcon,
width: 20,
height: 22,
),
),
return listSchedule.isNotEmpty
? SizedBox(
child: ListView.builder(
shrinkWrap: true,
itemCount: listSchedule.length,
itemBuilder: (context, index) {
return Dismissible(
key: Key(listSchedule[index].scheduleId),
background: Container(
padding: const EdgeInsets.only(right: 10),
alignment: AlignmentDirectional.centerEnd,
decoration: const ShapeDecoration(
color: Color(0xFFFF0000),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(20)),
),
direction: DismissDirection.endToStart,
onDismissed: (direction) {
onDismissed(listSchedule[index].scheduleId);
),
child: Padding(
padding: const EdgeInsets.only(bottom: 10, right: 10),
child: SvgPicture.asset(
Assets.assetsDeleteIcon,
width: 20,
height: 22,
),
),
),
direction: DismissDirection.endToStart,
onDismissed: (direction) {
onDismissed(listSchedule[index].scheduleId);
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(content: Text('Schedule removed')),
);
},
child: InkWell(
onTap: () {},
child: DefaultContainer(
padding: const EdgeInsets.all(20),
height: MediaQuery.of(context).size.height / 6.4,
child: Row(
children: [
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
BodyLarge(
text: listSchedule[index].time,
fontWeight: FontWeight.w500,
fontColor: Colors.black,
fontSize: 22,
),
Text(listSchedule[index].days.join(' ')),
Text(
'Function ${listSchedule[index].function.value ? "ON" : "OFF"}'),
],
),
),
Expanded(
child: ListTile(
contentPadding: EdgeInsets.zero,
leading: const BodyMedium(
text: '',
fontWeight: FontWeight.normal,
),
trailing: Transform.scale(
scale: .8,
child: CupertinoSwitch(
value: listSchedule[index].enable,
onChanged: (value) {
onToggleSchedule(
listSchedule[index].scheduleId,
value,
);
},
applyTheme: true,
),
),
),
),
],
),
),
),
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(content: Text('Schedule removed')),
);
},
),
)
: const EmptySchedule());
child: InkWell(
onTap: () {},
child: DefaultContainer(
padding: const EdgeInsets.all(20),
height: MediaQuery.of(context).size.height / 6.4,
child: Row(
children: [
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
BodyLarge(
text: listSchedule[index].time,
fontWeight: FontWeight.w500,
fontColor: Colors.black,
fontSize: 22,
),
Text(listSchedule[index].days.join(' ')),
Text(
'Function ${listSchedule[index].function.value ? "ON" : "OFF"}'),
],
),
),
Expanded(
child: ListTile(
contentPadding: EdgeInsets.zero,
leading: const BodyMedium(
text: '',
fontWeight: FontWeight.normal,
),
trailing: Transform.scale(
scale: .8,
child: CupertinoSwitch(
value: listSchedule[index].enable,
onChanged: (value) {
onToggleSchedule(
listSchedule[index].scheduleId,
value,
);
},
applyTheme: true,
),
),
),
),
],
),
),
),
);
},
),
)
: const Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Center(child: EmptySchedule()),
],
);
}
}

View File

@ -72,7 +72,8 @@ class DevicesAPI {
static Future<Map<String, dynamic>> getDeviceStatus(String deviceId) async {
final response = await _httpService.get(
path: ApiEndpoints.deviceFunctionsStatus.replaceAll('{deviceUuid}', deviceId),
path: ApiEndpoints.deviceFunctionsStatus
.replaceAll('{deviceUuid}', deviceId),
showServerMessage: false,
expectedResponseModel: (json) {
return json;
@ -82,7 +83,9 @@ class DevicesAPI {
}
static Future<Map<String, dynamic>> renamePass(
{required String name, required String doorLockUuid, required String passwordId}) async {
{required String name,
required String doorLockUuid,
required String passwordId}) async {
final response = await _httpService.put(
path: ApiEndpoints.renamePassword
.replaceAll('{doorLockUuid}', doorLockUuid)
@ -107,7 +110,8 @@ class DevicesAPI {
return response;
}
static Future<List<DeviceModel>> getDeviceByGroupName(String unitId, String groupName) async {
static Future<List<DeviceModel>> getDeviceByGroupName(
String unitId, String groupName) async {
final response = await _httpService.get(
path: ApiEndpoints.devicesByGroupName
.replaceAll('{unitUuid}', unitId)
@ -146,7 +150,8 @@ class DevicesAPI {
return response;
}
static Future<List<DeviceModel>> getDevicesByGatewayId(String gatewayId) async {
static Future<List<DeviceModel>> getDevicesByGatewayId(
String gatewayId) async {
final response = await _httpService.get(
path: ApiEndpoints.gatewayApi.replaceAll('{gatewayUuid}', gatewayId),
showServerMessage: false,
@ -168,7 +173,8 @@ class DevicesAPI {
String deviceId,
) async {
final response = await _httpService.get(
path: ApiEndpoints.getTemporaryPassword.replaceAll('{doorLockUuid}', deviceId),
path: ApiEndpoints.getTemporaryPassword
.replaceAll('{doorLockUuid}', deviceId),
showServerMessage: false,
expectedResponseModel: (json) {
return json;
@ -179,7 +185,8 @@ class DevicesAPI {
static Future getOneTimePasswords(String deviceId) async {
final response = await _httpService.get(
path: ApiEndpoints.getOneTimeTemporaryPassword.replaceAll('{doorLockUuid}', deviceId),
path: ApiEndpoints.getOneTimeTemporaryPassword
.replaceAll('{doorLockUuid}', deviceId),
showServerMessage: false,
expectedResponseModel: (json) {
return json;
@ -190,7 +197,8 @@ class DevicesAPI {
static Future getTimeLimitPasswords(String deviceId) async {
final response = await _httpService.get(
path: ApiEndpoints.getMultipleTimeTemporaryPassword.replaceAll('{doorLockUuid}', deviceId),
path: ApiEndpoints.getMultipleTimeTemporaryPassword
.replaceAll('{doorLockUuid}', deviceId),
showServerMessage: false,
expectedResponseModel: (json) {
return json;
@ -215,10 +223,12 @@ class DevicesAPI {
"invalidTime": invalidTime,
};
if (scheduleList != null) {
body["scheduleList"] = scheduleList.map((schedule) => schedule.toJson()).toList();
body["scheduleList"] =
scheduleList.map((schedule) => schedule.toJson()).toList();
}
final response = await _httpService.post(
path: ApiEndpoints.addTemporaryPassword.replaceAll('{doorLockUuid}', deviceId),
path: ApiEndpoints.addTemporaryPassword
.replaceAll('{doorLockUuid}', deviceId),
body: body,
showServerMessage: false,
expectedResponseModel: (json) => json,
@ -229,7 +239,8 @@ class DevicesAPI {
static Future generateOneTimePassword({deviceId}) async {
try {
final response = await _httpService.post(
path: ApiEndpoints.addOneTimeTemporaryPassword.replaceAll('{doorLockUuid}', deviceId),
path: ApiEndpoints.addOneTimeTemporaryPassword
.replaceAll('{doorLockUuid}', deviceId),
showServerMessage: false,
expectedResponseModel: (json) {
return json;
@ -241,10 +252,12 @@ class DevicesAPI {
}
}
static Future generateMultiTimePassword({deviceId, effectiveTime, invalidTime}) async {
static Future generateMultiTimePassword(
{deviceId, effectiveTime, invalidTime}) async {
try {
final response = await _httpService.post(
path: ApiEndpoints.addMultipleTimeTemporaryPassword.replaceAll('{doorLockUuid}', deviceId),
path: ApiEndpoints.addMultipleTimeTemporaryPassword
.replaceAll('{doorLockUuid}', deviceId),
showServerMessage: true,
body: {"effectiveTime": effectiveTime, "invalidTime": invalidTime},
expectedResponseModel: (json) {
@ -361,6 +374,7 @@ class DevicesAPI {
.replaceAll('{startTime}', startTime)
.replaceAll('{endTime}', endTime),
expectedResponseModel: (json) {
print('json-=-=-=-=-=-=-=${json}');
return DeviceReport.fromJson(json);
},
);