diff --git a/lib/features/auth/bloc/auth_cubit.dart b/lib/features/auth/bloc/auth_cubit.dart index 2952e70..276bfd8 100644 --- a/lib/features/auth/bloc/auth_cubit.dart +++ b/lib/features/auth/bloc/auth_cubit.dart @@ -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'; diff --git a/lib/features/devices/bloc/door_sensor_bloc/door_sensor_bloc.dart b/lib/features/devices/bloc/door_sensor_bloc/door_sensor_bloc.dart index 636edc7..213dbeb 100644 --- a/lib/features/devices/bloc/door_sensor_bloc/door_sensor_bloc.dart +++ b/lib/features/devices/bloc/door_sensor_bloc/door_sensor_bloc.dart @@ -16,7 +16,7 @@ class DoorSensorBloc extends Bloc { DoorSensorBloc({ required this.DSId, }) : super(const DoorSensorState()) { - on(_fetchWaterHeaterStatus); + on(_fetchStatus); on(fetchLogsForLastMonth); on(_toggleLowBattery); on(_toggleClosingReminder); @@ -26,9 +26,11 @@ class DoorSensorBloc extends Bloc { 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 emit) async { + void _fetchStatus( + DoorSensorInitial event, Emitter emit) async { emit(DoorSensorLoadingState()); try { var response = await DevicesAPI.getDeviceStatus(DSId); @@ -49,7 +51,8 @@ class DoorSensorBloc extends Bloc { } // Toggle functions for each switch - void _toggleLowBattery(ToggleLowBatteryEvent event, Emitter emit) async { + void _toggleLowBattery( + ToggleLowBatteryEvent event, Emitter emit) async { emit(LoadingNewSate(doorSensor: deviceStatus)); try { lowBattery = event.isLowBatteryEnabled; @@ -90,7 +93,8 @@ class DoorSensorBloc extends Bloc { } } - void _toggleDoorAlarm(ToggleDoorAlarmEvent event, Emitter emit) async { + void _toggleDoorAlarm( + ToggleDoorAlarmEvent event, Emitter emit) async { emit(LoadingNewSate(doorSensor: deviceStatus)); try { doorAlarm = event.isDoorAlarmEnabled; @@ -110,9 +114,11 @@ class DoorSensorBloc extends Bloc { } } - DeviceReport recordGroups = DeviceReport(startTime: '0', endTime: '0', data: []); + DeviceReport recordGroups = + DeviceReport(startTime: '0', endTime: '0', data: []); - Future fetchLogsForLastMonth(ReportLogsInitial event, Emitter emit) async { + Future fetchLogsForLastMonth( + ReportLogsInitial event, Emitter emit) async { // Get the current date and time DateTime now = DateTime.now(); @@ -123,15 +129,18 @@ class DoorSensorBloc extends Bloc { 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 { _listenToChanges() { try { - DatabaseReference ref = FirebaseDatabase.instance.ref('device-status/$DSId'); + DatabaseReference ref = + FirebaseDatabase.instance.ref('device-status/$DSId'); Stream stream = ref.onValue; stream.listen((DatabaseEvent event) async { if (_timer != null) { await Future.delayed(const Duration(seconds: 2)); } - Map usersMap = event.snapshot.value as Map; + Map usersMap = + event.snapshot.value as Map; List statusList = []; usersMap['status'].forEach((element) { diff --git a/lib/features/devices/model/device_report_model.dart b/lib/features/devices/model/device_report_model.dart index b73dc77..c640d81 100644 --- a/lib/features/devices/model/device_report_model.dart +++ b/lib/features/devices/model/device_report_model.dart @@ -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? data; DeviceReport({ diff --git a/lib/features/devices/view/widgets/door_sensor/door_records_screen.dart b/lib/features/devices/view/widgets/door_sensor/door_records_screen.dart index 11b5d34..9b4b961 100644 --- a/lib/features/devices/view/widgets/door_sensor/door_records_screen.dart +++ b/lib/features/devices/view/widgets/door_sensor/door_records_screen.dart @@ -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( -// builder: (context, state) { -// final doorSensorBloc = BlocProvider.of(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( builder: (context, state) { + final doorSensorBloc = BlocProvider.of(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> groupedRecords = {}; - if (state is UpdateState) { - final recordGroups = context.read().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 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.')); }, ), diff --git a/lib/features/devices/view/widgets/three_gang/schedule_screen.dart b/lib/features/devices/view/widgets/three_gang/schedule_screen.dart index 8e1388a..03232c5 100644 --- a/lib/features/devices/view/widgets/three_gang/schedule_screen.dart +++ b/lib/features/devices/view/widgets/three_gang/schedule_screen.dart @@ -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", diff --git a/lib/features/devices/view/widgets/three_gang/timer_screen.dart b/lib/features/devices/view/widgets/three_gang/timer_screen.dart index 23dcdf5..eb486f4 100644 --- a/lib/features/devices/view/widgets/three_gang/timer_screen.dart +++ b/lib/features/devices/view/widgets/three_gang/timer_screen.dart @@ -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( @@ -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 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 + 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, + )); + }, + ), ), - ), - ), - ], + ], + ), + ), ), ], ), diff --git a/lib/features/devices/view/widgets/two_gang/two_timer_screen.dart b/lib/features/devices/view/widgets/two_gang/two_timer_screen.dart index a86ae8c..fcdf71c 100644 --- a/lib/features/devices/view/widgets/two_gang/two_timer_screen.dart +++ b/lib/features/devices/view/widgets/two_gang/two_timer_screen.dart @@ -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 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 + 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, + )); + }, + ), + ), + ], + ), + ), + ), + ], + ), ), ], ), - ), - ], - ), - )) - ); + ))); }, ), ), diff --git a/lib/features/devices/view/widgets/water_heater/circulate_list_view.dart b/lib/features/devices/view/widgets/water_heater/circulate_list_view.dart index cdc2b9a..a6792f9 100644 --- a/lib/features/devices/view/widgets/water_heater/circulate_list_view.dart +++ b/lib/features/devices/view/widgets/water_heater/circulate_list_view.dart @@ -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 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()); } } diff --git a/lib/features/devices/view/widgets/water_heater/wh_timer_schedule_screen.dart b/lib/features/devices/view/widgets/water_heater/wh_timer_schedule_screen.dart index f1325ba..5787f9c 100644 --- a/lib/features/devices/view/widgets/water_heater/wh_timer_schedule_screen.dart +++ b/lib/features/devices/view/widgets/water_heater/wh_timer_schedule_screen.dart @@ -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 - 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 + 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(), + ), + ], + ) ], ), ), diff --git a/lib/features/shared_widgets/schedule_list.dart b/lib/features/shared_widgets/schedule_list.dart index 15e2b6e..9292fcb 100644 --- a/lib/features/shared_widgets/schedule_list.dart +++ b/lib/features/shared_widgets/schedule_list.dart @@ -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()), + ], + ); } } diff --git a/lib/services/api/devices_api.dart b/lib/services/api/devices_api.dart index 1d38fd0..f7e6b14 100644 --- a/lib/services/api/devices_api.dart +++ b/lib/services/api/devices_api.dart @@ -72,7 +72,8 @@ class DevicesAPI { static Future> 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> 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> getDeviceByGroupName(String unitId, String groupName) async { + static Future> 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> getDevicesByGatewayId(String gatewayId) async { + static Future> 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); }, );