mirror of
https://github.com/SyncrowIOT/web.git
synced 2026-10-24 15:17:56 +00:00
push water leak device
This commit is contained in:
@@ -30,6 +30,8 @@ import 'package:syncrow_web/pages/device_managment/wall_sensor/view/wall_sensor_
|
||||
import 'package:syncrow_web/pages/device_managment/wall_sensor/view/wall_sensor_conrtols.dart';
|
||||
import 'package:syncrow_web/pages/device_managment/water_heater/view/water_heater_batch_control.dart';
|
||||
import 'package:syncrow_web/pages/device_managment/water_heater/view/water_heater_device_control.dart';
|
||||
import 'package:syncrow_web/pages/device_managment/water_leak/view/water_leak_batch_control_view.dart';
|
||||
import 'package:syncrow_web/pages/device_managment/water_leak/view/water_leak_control_view.dart';
|
||||
|
||||
import '../../one_g_glass_switch/view/one_gang_glass_switch_control_view.dart';
|
||||
|
||||
@@ -88,6 +90,10 @@ mixin RouteControlsBasedCode {
|
||||
return GarageDoorControlView(
|
||||
deviceId: device.uuid!,
|
||||
);
|
||||
case 'WL':
|
||||
return WaterLeakView(
|
||||
deviceId: device.uuid!,
|
||||
);
|
||||
default:
|
||||
return const SizedBox();
|
||||
}
|
||||
@@ -211,6 +217,13 @@ mixin RouteControlsBasedCode {
|
||||
.map((e) => e.uuid!)
|
||||
.toList(),
|
||||
);
|
||||
case 'WL':
|
||||
return WaterLeakBatchControlView(
|
||||
deviceIds: devices
|
||||
.where((e) => (e.productType == 'WL'))
|
||||
.map((e) => e.uuid!)
|
||||
.toList(),
|
||||
);
|
||||
default:
|
||||
return const SizedBox();
|
||||
}
|
||||
|
||||
@@ -14,6 +14,7 @@ class ReportsTable extends StatelessWidget {
|
||||
bool? hideValueShowDescription;
|
||||
bool? mainDoorSensor;
|
||||
bool? garageDoorSensor;
|
||||
bool? waterLeak;
|
||||
|
||||
ReportsTable({
|
||||
super.key,
|
||||
@@ -25,6 +26,7 @@ class ReportsTable extends StatelessWidget {
|
||||
this.hideValueShowDescription,
|
||||
this.mainDoorSensor,
|
||||
this.garageDoorSensor,
|
||||
this.waterLeak,
|
||||
});
|
||||
|
||||
@override
|
||||
@@ -55,7 +57,8 @@ class ReportsTable extends StatelessWidget {
|
||||
DeviceEvent data = entry.value;
|
||||
|
||||
// Parse eventTime into Date and Time
|
||||
DateTime eventDateTime = DateTime.fromMillisecondsSinceEpoch(data.eventTime!);
|
||||
DateTime eventDateTime =
|
||||
DateTime.fromMillisecondsSinceEpoch(data.eventTime!);
|
||||
String date = DateFormat('dd/MM/yyyy').format(eventDateTime);
|
||||
String time = DateFormat('HH:mm').format(eventDateTime);
|
||||
|
||||
@@ -63,8 +66,12 @@ class ReportsTable extends StatelessWidget {
|
||||
if (hideValueShowDescription == true) {
|
||||
if (mainDoorSensor != null && mainDoorSensor == true) {
|
||||
value = data.value == 'true' ? 'Open' : 'Close';
|
||||
} else if (garageDoorSensor != null && garageDoorSensor == true) {
|
||||
} else if (garageDoorSensor != null &&
|
||||
garageDoorSensor == true) {
|
||||
value = data.value == 'true' ? 'Opened' : 'Closed';
|
||||
} else if (waterLeak != null && waterLeak == true) {
|
||||
value =
|
||||
data.value == 'normal' ? 'Normal' : 'Leak Detected';
|
||||
} else {
|
||||
value = '${data.value!} ${thirdColumnDescription ?? ''}';
|
||||
}
|
||||
|
||||
@@ -0,0 +1,173 @@
|
||||
import 'package:bloc/bloc.dart';
|
||||
import 'package:syncrow_web/pages/device_managment/all_devices/models/device_reports.dart';
|
||||
import 'package:syncrow_web/pages/device_managment/all_devices/models/device_status.dart';
|
||||
import 'package:syncrow_web/pages/device_managment/water_leak/bloc/water_leak_event.dart';
|
||||
import 'package:syncrow_web/pages/device_managment/water_leak/bloc/water_leak_state.dart';
|
||||
import 'package:syncrow_web/pages/device_managment/water_leak/model/water_leak_status_model.dart';
|
||||
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:syncrow_web/services/devices_mang_api.dart';
|
||||
|
||||
class WaterLeakBloc extends Bloc<WaterLeakEvent, WaterLeakState> {
|
||||
WaterLeakStatusModel? deviceStatus;
|
||||
Timer? _timer;
|
||||
final String deviceId;
|
||||
|
||||
WaterLeakBloc(this.deviceId) : super(WaterLeakInitialState()) {
|
||||
on<FetchWaterLeakStatusEvent>(_onFetchWaterLeakStatus);
|
||||
on<WaterLeakControlEvent>(_onControl);
|
||||
on<WaterLeakBatchControlEvent>(_onBatchControl);
|
||||
on<FetchWaterLeakBatchStatusEvent>(_onFetchBatchStatus);
|
||||
on<FetchWaterLeakReportsEvent>(_onFetchWaterLeakReports);
|
||||
on<WaterLeakFactoryResetEvent>(_onFactoryReset);
|
||||
}
|
||||
|
||||
Future<void> _onFetchWaterLeakStatus(
|
||||
FetchWaterLeakStatusEvent event, Emitter<WaterLeakState> emit) async {
|
||||
emit(WaterLeakLoadingState());
|
||||
try {
|
||||
final response =
|
||||
await DevicesManagementApi().getDeviceStatus(event.deviceId);
|
||||
deviceStatus = WaterLeakStatusModel.fromJson(deviceId, response.status);
|
||||
emit(WaterLeakLoadedState(deviceStatus!));
|
||||
} catch (e) {
|
||||
emit(WaterLeakErrorState(e.toString()));
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> _onControl(
|
||||
WaterLeakControlEvent event, Emitter<WaterLeakState> emit) async {
|
||||
final oldValue = deviceStatus!.watersensorState;
|
||||
|
||||
_updateLocalValue(event.code, event.value);
|
||||
emit(WaterLeakLoadedState(deviceStatus!));
|
||||
|
||||
await _runDebounce(
|
||||
deviceId: event.deviceId,
|
||||
code: event.code,
|
||||
value: event.value,
|
||||
oldValue: oldValue,
|
||||
emit: emit,
|
||||
isBatch: false,
|
||||
);
|
||||
}
|
||||
|
||||
Future<void> _onFactoryReset(
|
||||
WaterLeakFactoryResetEvent event, Emitter<WaterLeakState> emit) async {
|
||||
emit(WaterLeakLoadingState());
|
||||
try {
|
||||
final response = await DevicesManagementApi().factoryReset(
|
||||
event.factoryReset,
|
||||
event.deviceId,
|
||||
);
|
||||
if (response) {
|
||||
emit(WaterLeakInitialState());
|
||||
} else {
|
||||
emit(const WaterLeakErrorState('Factory reset failed'));
|
||||
}
|
||||
} catch (e) {
|
||||
emit(WaterLeakErrorState(e.toString()));
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> _onBatchControl(
|
||||
WaterLeakBatchControlEvent event, Emitter<WaterLeakState> emit) async {
|
||||
final oldValue = deviceStatus!.watersensorState;
|
||||
|
||||
_updateLocalValue(event.code, event.value);
|
||||
emit(WaterLeakBatchStatusLoadedState(deviceStatus!));
|
||||
|
||||
await _runDebounce(
|
||||
deviceId: event.deviceIds,
|
||||
code: event.code,
|
||||
value: event.value,
|
||||
oldValue: oldValue,
|
||||
emit: emit,
|
||||
isBatch: true,
|
||||
);
|
||||
}
|
||||
|
||||
Future<void> _onFetchBatchStatus(FetchWaterLeakBatchStatusEvent event,
|
||||
Emitter<WaterLeakState> emit) async {
|
||||
emit(WaterLeakLoadingState());
|
||||
try {
|
||||
final response =
|
||||
await DevicesManagementApi().getBatchStatus(event.deviceIds);
|
||||
deviceStatus = WaterLeakStatusModel.fromJson(deviceId, response.status);
|
||||
emit(WaterLeakBatchStatusLoadedState(deviceStatus!));
|
||||
} catch (e) {
|
||||
emit(WaterLeakErrorState(e.toString()));
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> _runDebounce({
|
||||
required dynamic deviceId,
|
||||
required String code,
|
||||
required dynamic value,
|
||||
required dynamic oldValue,
|
||||
required Emitter<WaterLeakState> emit,
|
||||
required bool isBatch,
|
||||
}) async {
|
||||
late String id;
|
||||
if (deviceId is List) {
|
||||
id = deviceId.first;
|
||||
} else {
|
||||
id = deviceId;
|
||||
}
|
||||
|
||||
if (_timer != null) {
|
||||
_timer!.cancel();
|
||||
}
|
||||
|
||||
_timer = Timer(const Duration(milliseconds: 500), () async {
|
||||
try {
|
||||
late bool response;
|
||||
if (isBatch) {
|
||||
response = await DevicesManagementApi()
|
||||
.deviceBatchControl(deviceId, code, value);
|
||||
} else {
|
||||
response = await DevicesManagementApi()
|
||||
.deviceControl(deviceId, Status(code: code, value: value));
|
||||
}
|
||||
|
||||
if (!response) {
|
||||
_revertValueAndEmit(id, code, oldValue, emit);
|
||||
}
|
||||
} catch (e) {
|
||||
_revertValueAndEmit(id, code, oldValue, emit);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void _updateLocalValue(String code, dynamic value) {
|
||||
if (code == 'watersensor_state') {
|
||||
deviceStatus = deviceStatus!.copyWith(watersensorState: value);
|
||||
} else if (code == 'battery_percentage') {
|
||||
deviceStatus = deviceStatus!.copyWith(batteryPercentage: value);
|
||||
}
|
||||
}
|
||||
|
||||
void _revertValueAndEmit(String deviceId, String code, dynamic oldValue,
|
||||
Emitter<WaterLeakState> emit) {
|
||||
_updateLocalValue(code, oldValue);
|
||||
emit(WaterLeakLoadedState(deviceStatus!));
|
||||
}
|
||||
|
||||
Future<void> _onFetchWaterLeakReports(
|
||||
FetchWaterLeakReportsEvent event, Emitter<WaterLeakState> emit) async {
|
||||
emit(WaterLeakReportsLoadingState());
|
||||
try {
|
||||
final from = DateTime.now()
|
||||
.subtract(const Duration(days: 30))
|
||||
.millisecondsSinceEpoch;
|
||||
final to = DateTime.now().millisecondsSinceEpoch;
|
||||
final DeviceReport records =
|
||||
await DevicesManagementApi.getDeviceReportsByDate(
|
||||
event.deviceId, event.code, from.toString(), to.toString());
|
||||
emit(WaterLeakReportsLoadedState(records));
|
||||
} catch (e) {
|
||||
emit(WaterLeakReportsFailedState(e.toString()));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,87 @@
|
||||
import 'package:equatable/equatable.dart';
|
||||
import 'package:syncrow_web/pages/device_managment/all_devices/models/factory_reset_model.dart';
|
||||
|
||||
abstract class WaterLeakEvent extends Equatable {
|
||||
const WaterLeakEvent();
|
||||
|
||||
@override
|
||||
List<Object> get props => [];
|
||||
}
|
||||
|
||||
class FetchWaterLeakStatusEvent extends WaterLeakEvent {
|
||||
final String deviceId;
|
||||
|
||||
const FetchWaterLeakStatusEvent(this.deviceId);
|
||||
|
||||
@override
|
||||
List<Object> get props => [deviceId];
|
||||
}
|
||||
|
||||
class WaterLeakControlEvent extends WaterLeakEvent {
|
||||
final String deviceId;
|
||||
final String code;
|
||||
final dynamic value;
|
||||
|
||||
const WaterLeakControlEvent({
|
||||
required this.deviceId,
|
||||
required this.code,
|
||||
required this.value,
|
||||
});
|
||||
|
||||
@override
|
||||
List<Object> get props => [deviceId, code, value];
|
||||
}
|
||||
|
||||
class WaterLeakBatchControlEvent extends WaterLeakEvent {
|
||||
final List<String> deviceIds;
|
||||
final String code;
|
||||
final dynamic value;
|
||||
|
||||
const WaterLeakBatchControlEvent({
|
||||
required this.deviceIds,
|
||||
required this.code,
|
||||
required this.value,
|
||||
});
|
||||
|
||||
@override
|
||||
List<Object> get props => [deviceIds, code, value];
|
||||
}
|
||||
|
||||
class FetchWaterLeakBatchStatusEvent extends WaterLeakEvent {
|
||||
final List<String> deviceIds;
|
||||
|
||||
const FetchWaterLeakBatchStatusEvent(this.deviceIds);
|
||||
|
||||
@override
|
||||
List<Object> get props => [deviceIds];
|
||||
}
|
||||
|
||||
class FetchWaterLeakReportsEvent extends WaterLeakEvent {
|
||||
final String deviceId;
|
||||
final String code;
|
||||
final int from;
|
||||
final int to;
|
||||
|
||||
const FetchWaterLeakReportsEvent({
|
||||
required this.deviceId,
|
||||
required this.code,
|
||||
required this.from,
|
||||
required this.to,
|
||||
});
|
||||
|
||||
@override
|
||||
List<Object> get props => [deviceId, code, from, to];
|
||||
}
|
||||
|
||||
class WaterLeakFactoryResetEvent extends WaterLeakEvent {
|
||||
final String deviceId;
|
||||
final FactoryResetModel factoryReset;
|
||||
|
||||
const WaterLeakFactoryResetEvent({
|
||||
required this.deviceId,
|
||||
required this.factoryReset,
|
||||
});
|
||||
|
||||
@override
|
||||
List<Object> get props => [deviceId];
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
import 'package:equatable/equatable.dart';
|
||||
import 'package:syncrow_web/pages/device_managment/all_devices/models/device_reports.dart';
|
||||
import 'package:syncrow_web/pages/device_managment/water_leak/model/water_leak_status_model.dart';
|
||||
|
||||
abstract class WaterLeakState extends Equatable {
|
||||
const WaterLeakState();
|
||||
|
||||
@override
|
||||
List<Object> get props => [];
|
||||
}
|
||||
|
||||
class WaterLeakInitialState extends WaterLeakState {}
|
||||
|
||||
class WaterLeakLoadingState extends WaterLeakState {}
|
||||
|
||||
class WaterLeakLoadedState extends WaterLeakState {
|
||||
final WaterLeakStatusModel status;
|
||||
|
||||
const WaterLeakLoadedState(this.status);
|
||||
|
||||
@override
|
||||
List<Object> get props => [status];
|
||||
}
|
||||
|
||||
class WaterLeakBatchStatusLoadedState extends WaterLeakState {
|
||||
final WaterLeakStatusModel status;
|
||||
|
||||
const WaterLeakBatchStatusLoadedState(this.status);
|
||||
|
||||
@override
|
||||
List<Object> get props => [status];
|
||||
}
|
||||
|
||||
class WaterLeakErrorState extends WaterLeakState {
|
||||
final String message;
|
||||
|
||||
const WaterLeakErrorState(this.message);
|
||||
|
||||
@override
|
||||
List<Object> get props => [message];
|
||||
}
|
||||
|
||||
class WaterLeakReportsLoadingState extends WaterLeakState {}
|
||||
|
||||
class WaterLeakReportsLoadedState extends WaterLeakState {
|
||||
final DeviceReport deviceReport;
|
||||
|
||||
const WaterLeakReportsLoadedState(this.deviceReport);
|
||||
|
||||
@override
|
||||
List<Object> get props => [deviceReport];
|
||||
}
|
||||
|
||||
class WaterLeakReportsFailedState extends WaterLeakState {
|
||||
final String error;
|
||||
|
||||
const WaterLeakReportsFailedState(this.error);
|
||||
|
||||
@override
|
||||
List<Object> get props => [error];
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
import 'package:syncrow_web/pages/device_managment/all_devices/models/device_status.dart';
|
||||
|
||||
class WaterLeakStatusModel {
|
||||
final String productUuid;
|
||||
final String productType;
|
||||
final String watersensorState;
|
||||
final int batteryPercentage;
|
||||
|
||||
WaterLeakStatusModel({
|
||||
required this.productUuid,
|
||||
required this.productType,
|
||||
required this.watersensorState,
|
||||
required this.batteryPercentage,
|
||||
});
|
||||
factory WaterLeakStatusModel.fromJson(String id, List<Status> jsonList) {
|
||||
late String watersensorState;
|
||||
late int batteryPercentage;
|
||||
|
||||
for (var i = 0; i < jsonList.length; i++) {
|
||||
if (jsonList[i].code == 'watersensor_state') {
|
||||
watersensorState = jsonList[i].value;
|
||||
} else if (jsonList[i].code == 'battery_percentage') {
|
||||
batteryPercentage = jsonList[i].value;
|
||||
}
|
||||
}
|
||||
|
||||
return WaterLeakStatusModel(
|
||||
productUuid: id,
|
||||
productType: 'WL',
|
||||
watersensorState: watersensorState,
|
||||
batteryPercentage: batteryPercentage,
|
||||
);
|
||||
}
|
||||
|
||||
WaterLeakStatusModel copyWith({
|
||||
String? productUuid,
|
||||
String? productType,
|
||||
String? watersensorState,
|
||||
int? batteryPercentage,
|
||||
}) {
|
||||
return WaterLeakStatusModel(
|
||||
productUuid: productUuid ?? this.productUuid,
|
||||
productType: productType ?? this.productType,
|
||||
watersensorState: watersensorState ?? this.watersensorState,
|
||||
batteryPercentage: batteryPercentage ?? this.batteryPercentage,
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:syncrow_web/pages/device_managment/all_devices/models/factory_reset_model.dart';
|
||||
import 'package:syncrow_web/pages/device_managment/shared/batch_control/factory_reset.dart';
|
||||
import 'package:syncrow_web/pages/device_managment/shared/batch_control/firmware_update.dart';
|
||||
|
||||
import 'package:syncrow_web/pages/device_managment/water_leak/bloc/water_leak_bloc.dart';
|
||||
import 'package:syncrow_web/pages/device_managment/water_leak/bloc/water_leak_event.dart';
|
||||
import 'package:syncrow_web/pages/device_managment/water_leak/bloc/water_leak_state.dart';
|
||||
import 'package:syncrow_web/pages/device_managment/water_leak/model/water_leak_status_model.dart';
|
||||
import 'package:syncrow_web/utils/helpers/responsice_layout_helper/responsive_layout_helper.dart';
|
||||
|
||||
class WaterLeakBatchControlView extends StatelessWidget
|
||||
with HelperResponsiveLayout {
|
||||
final List<String> deviceIds;
|
||||
|
||||
const WaterLeakBatchControlView({Key? key, required this.deviceIds})
|
||||
: super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return BlocProvider(
|
||||
create: (context) => WaterLeakBloc(deviceIds.first)
|
||||
..add(FetchWaterLeakBatchStatusEvent(deviceIds)),
|
||||
child: BlocBuilder<WaterLeakBloc, WaterLeakState>(
|
||||
builder: (context, state) {
|
||||
if (state is WaterLeakLoadingState) {
|
||||
return const Center(child: CircularProgressIndicator());
|
||||
} else if (state is WaterLeakBatchStatusLoadedState) {
|
||||
return _buildStatusControls(context, state.status);
|
||||
} else if (state is WaterLeakErrorState) {
|
||||
return Center(child: Text('Error: ${state.message}'));
|
||||
} else {
|
||||
return const Center(child: CircularProgressIndicator());
|
||||
}
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildStatusControls(
|
||||
BuildContext context, WaterLeakStatusModel status) {
|
||||
return Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
SizedBox(
|
||||
width: 170,
|
||||
height: 140,
|
||||
child: FirmwareUpdateWidget(deviceId: deviceIds.first, version: 2)),
|
||||
const SizedBox(
|
||||
width: 12,
|
||||
),
|
||||
SizedBox(
|
||||
width: 170,
|
||||
height: 140,
|
||||
child: FactoryResetWidget(
|
||||
callFactoryReset: () {
|
||||
context.read<WaterLeakBloc>().add(WaterLeakFactoryResetEvent(
|
||||
deviceId: deviceIds.first,
|
||||
factoryReset: FactoryResetModel(devicesUuid: deviceIds)));
|
||||
},
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,128 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:syncrow_web/pages/device_managment/main_door_sensor/view/main_door_control_view.dart';
|
||||
import 'package:syncrow_web/pages/device_managment/water_leak/bloc/water_leak_bloc.dart';
|
||||
import 'package:syncrow_web/pages/device_managment/water_leak/bloc/water_leak_event.dart';
|
||||
import 'package:syncrow_web/pages/device_managment/water_leak/bloc/water_leak_state.dart';
|
||||
import 'package:syncrow_web/pages/device_managment/water_leak/widgets/water_leak_notifi_dialog.dart';
|
||||
import 'package:syncrow_web/utils/color_manager.dart';
|
||||
import 'package:syncrow_web/utils/constants/assets.dart';
|
||||
import 'package:syncrow_web/pages/device_managment/shared/table/report_table.dart';
|
||||
import 'package:syncrow_web/utils/helpers/responsice_layout_helper/responsive_layout_helper.dart';
|
||||
|
||||
class WaterLeakView extends StatelessWidget with HelperResponsiveLayout {
|
||||
final String deviceId;
|
||||
|
||||
const WaterLeakView({Key? key, required this.deviceId}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final isExtraLarge = isExtraLargeScreenSize(context);
|
||||
final isLarge = isLargeScreenSize(context);
|
||||
final isMedium = isMediumScreenSize(context);
|
||||
return BlocProvider(
|
||||
create: (context) =>
|
||||
WaterLeakBloc(deviceId)..add(FetchWaterLeakStatusEvent(deviceId)),
|
||||
child: BlocBuilder<WaterLeakBloc, WaterLeakState>(
|
||||
builder: (context, state) {
|
||||
if (state is WaterLeakLoadingState) {
|
||||
return const Center(child: CircularProgressIndicator());
|
||||
} else if (state is WaterLeakLoadedState) {
|
||||
return GridView(
|
||||
shrinkWrap: true,
|
||||
padding: const EdgeInsets.symmetric(horizontal: 50),
|
||||
physics: const NeverScrollableScrollPhysics(),
|
||||
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
|
||||
crossAxisCount: isExtraLarge || isLarge
|
||||
? 3
|
||||
: isMedium
|
||||
? 2
|
||||
: 1,
|
||||
mainAxisExtent: 140,
|
||||
crossAxisSpacing: 12,
|
||||
mainAxisSpacing: 12,
|
||||
),
|
||||
children: [
|
||||
IconNameStatusContainer(
|
||||
isFullIcon: false,
|
||||
name: state.status.watersensorState == 'normal'
|
||||
? 'Normal'
|
||||
: 'Leak Detection',
|
||||
icon: state.status.watersensorState == 'normal'
|
||||
? Assets.waterLeakNormal
|
||||
: Assets.waterLeakDetected,
|
||||
onTap: () {},
|
||||
status: state.status.watersensorState == 'normal',
|
||||
textColor: state.status.watersensorState == 'normal'
|
||||
? ColorsManager.blackColor
|
||||
: ColorsManager.red,
|
||||
),
|
||||
IconNameStatusContainer(
|
||||
isFullIcon: false,
|
||||
name: 'Records',
|
||||
icon: Assets.records,
|
||||
onTap: () {
|
||||
context
|
||||
.read<WaterLeakBloc>()
|
||||
.add(FetchWaterLeakReportsEvent(
|
||||
deviceId: deviceId,
|
||||
code: 'watersensor_state',
|
||||
from: DateTime.now()
|
||||
.subtract(const Duration(days: 30))
|
||||
.millisecondsSinceEpoch,
|
||||
to: DateTime.now().millisecondsSinceEpoch,
|
||||
));
|
||||
},
|
||||
status: false,
|
||||
textColor: ColorsManager.blackColor,
|
||||
),
|
||||
IconNameStatusContainer(
|
||||
isFullIcon: false,
|
||||
name: 'Automation Record',
|
||||
icon: Assets.automationRecords,
|
||||
onTap: () {},
|
||||
status: false,
|
||||
textColor: ColorsManager.blackColor,
|
||||
),
|
||||
IconNameStatusContainer(
|
||||
isFullIcon: false,
|
||||
name: 'Notifications\nSettings',
|
||||
icon: Assets.mainDoorNotifi,
|
||||
onTap: () {
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: (context) => const WaterLeakNotificationDialog(),
|
||||
);
|
||||
},
|
||||
status: false,
|
||||
textColor: ColorsManager.blackColor,
|
||||
paddingAmount: 14,
|
||||
),
|
||||
],
|
||||
);
|
||||
} else if (state is WaterLeakReportsLoadingState) {
|
||||
return const Center(child: CircularProgressIndicator());
|
||||
} else if (state is WaterLeakReportsLoadedState) {
|
||||
return ReportsTable(
|
||||
report: state.deviceReport,
|
||||
hideValueShowDescription: true,
|
||||
waterLeak: true,
|
||||
onRowTap: (index) {},
|
||||
onClose: () {
|
||||
context
|
||||
.read<WaterLeakBloc>()
|
||||
.add(FetchWaterLeakStatusEvent(deviceId));
|
||||
},
|
||||
);
|
||||
} else if (state is WaterLeakReportsFailedState) {
|
||||
return Center(child: Text('Error: ${state.error}'));
|
||||
} else if (state is WaterLeakErrorState) {
|
||||
return Center(child: Text('Error: ${state.message}'));
|
||||
} else {
|
||||
return const Center(child: Text('No data available'));
|
||||
}
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,89 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:syncrow_web/pages/device_managment/shared/toggle_widget.dart';
|
||||
import 'package:syncrow_web/utils/color_manager.dart';
|
||||
|
||||
class WaterLeakNotificationDialog extends StatelessWidget {
|
||||
const WaterLeakNotificationDialog({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Dialog(
|
||||
backgroundColor: Colors.white,
|
||||
insetPadding: const EdgeInsets.all(20),
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(20),
|
||||
),
|
||||
child: SizedBox(
|
||||
width: 400,
|
||||
child: SingleChildScrollView(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(20.0),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
const SizedBox(),
|
||||
Text(
|
||||
'Notification Settings',
|
||||
style: TextStyle(
|
||||
fontWeight: FontWeight.bold,
|
||||
fontSize: 22,
|
||||
color: ColorsManager.dialogBlueTitle,
|
||||
),
|
||||
),
|
||||
Container(
|
||||
width: 25,
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.transparent,
|
||||
shape: BoxShape.circle,
|
||||
border: Border.all(
|
||||
color: Colors.grey,
|
||||
width: 1.0,
|
||||
),
|
||||
),
|
||||
child: IconButton(
|
||||
padding: EdgeInsets.all(1),
|
||||
icon: const Icon(
|
||||
Icons.close,
|
||||
color: Colors.grey,
|
||||
size: 18,
|
||||
),
|
||||
onPressed: () {
|
||||
Navigator.of(context).pop();
|
||||
},
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 20),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
||||
children: [
|
||||
ToggleWidget(
|
||||
value: true,
|
||||
code: 'notification',
|
||||
deviceId: '',
|
||||
label: 'Low Battery',
|
||||
onChange: (v) {},
|
||||
icon: '-1',
|
||||
),
|
||||
ToggleWidget(
|
||||
value: true,
|
||||
code: 'notification',
|
||||
deviceId: '',
|
||||
label: 'Water Leakage',
|
||||
onChange: (v) {},
|
||||
icon: '-1',
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -13,10 +13,12 @@ class Assets {
|
||||
static const String rightLine = "assets/images/right_line.png";
|
||||
static const String google = "assets/images/google.svg";
|
||||
static const String facebook = "assets/images/facebook.svg";
|
||||
static const String invisiblePassword = "assets/images/Password_invisible.svg";
|
||||
static const String invisiblePassword =
|
||||
"assets/images/Password_invisible.svg";
|
||||
static const String visiblePassword = "assets/images/password_visible.svg";
|
||||
static const String accessIcon = "assets/images/access_icon.svg";
|
||||
static const String spaseManagementIcon = "assets/images/spase_management_icon.svg";
|
||||
static const String spaseManagementIcon =
|
||||
"assets/images/spase_management_icon.svg";
|
||||
static const String devicesIcon = "assets/images/devices_icon.svg";
|
||||
static const String moveinIcon = "assets/images/movein_icon.svg";
|
||||
static const String constructionIcon = "assets/images/construction_icon.svg";
|
||||
@@ -29,13 +31,15 @@ class Assets {
|
||||
static const String emptyTable = "assets/images/empty_table.svg";
|
||||
|
||||
// General assets
|
||||
static const String motionlessDetection = "assets/icons/motionless_detection.svg";
|
||||
static const String motionlessDetection =
|
||||
"assets/icons/motionless_detection.svg";
|
||||
static const String acHeating = "assets/icons/ac_heating.svg";
|
||||
static const String acPowerOff = "assets/icons/ac_power_off.svg";
|
||||
static const String acFanMiddle = "assets/icons/ac_fan_middle.svg";
|
||||
static const String switchAlarmSound = "assets/icons/switch_alarm_sound.svg";
|
||||
static const String resetOff = "assets/icons/reset_off.svg";
|
||||
static const String sensitivityOperationIcon = "assets/icons/sesitivity_operation_icon.svg";
|
||||
static const String sensitivityOperationIcon =
|
||||
"assets/icons/sesitivity_operation_icon.svg";
|
||||
static const String motionDetection = "assets/icons/motion_detection.svg";
|
||||
static const String freezing = "assets/icons/freezing.svg";
|
||||
static const String indicator = "assets/icons/indicator.svg";
|
||||
@@ -56,35 +60,56 @@ class Assets {
|
||||
static const String celsiusDegrees = "assets/icons/celsius_degrees.svg";
|
||||
static const String masterState = "assets/icons/master_state.svg";
|
||||
static const String acPower = "assets/icons/ac_power.svg";
|
||||
static const String farDetectionFunction = "assets/icons/far_detection_function.svg";
|
||||
static const String farDetectionFunction =
|
||||
"assets/icons/far_detection_function.svg";
|
||||
static const String nobodyTime = "assets/icons/nobody_time.svg";
|
||||
|
||||
// Automation functions
|
||||
static const String tempPasswordUnlock = "assets/icons/automation_functions/temp_password_unlock.svg";
|
||||
static const String doorlockNormalOpen = "assets/icons/automation_functions/doorlock_normal_open.svg";
|
||||
static const String doorbell = "assets/icons/automation_functions/doorbell.svg";
|
||||
static const String remoteUnlockViaApp = "assets/icons/automation_functions/remote_unlock_via_app.svg";
|
||||
static const String doubleLock = "assets/icons/automation_functions/double_lock.svg";
|
||||
static const String selfTestResult = "assets/icons/automation_functions/self_test_result.svg";
|
||||
static const String lockAlarm = "assets/icons/automation_functions/lock_alarm.svg";
|
||||
static const String presenceState = "assets/icons/automation_functions/presence_state.svg";
|
||||
static const String currentTemp = "assets/icons/automation_functions/current_temp.svg";
|
||||
static const String presence = "assets/icons/automation_functions/presence.svg";
|
||||
static const String residualElectricity = "assets/icons/automation_functions/residual_electricity.svg";
|
||||
static const String hijackAlarm = "assets/icons/automation_functions/hijack_alarm.svg";
|
||||
static const String passwordUnlock = "assets/icons/automation_functions/password_unlock.svg";
|
||||
static const String remoteUnlockRequest = "assets/icons/automation_functions/remote_unlock_req.svg";
|
||||
static const String cardUnlock = "assets/icons/automation_functions/card_unlock.svg";
|
||||
static const String tempPasswordUnlock =
|
||||
"assets/icons/automation_functions/temp_password_unlock.svg";
|
||||
static const String doorlockNormalOpen =
|
||||
"assets/icons/automation_functions/doorlock_normal_open.svg";
|
||||
static const String doorbell =
|
||||
"assets/icons/automation_functions/doorbell.svg";
|
||||
static const String remoteUnlockViaApp =
|
||||
"assets/icons/automation_functions/remote_unlock_via_app.svg";
|
||||
static const String doubleLock =
|
||||
"assets/icons/automation_functions/double_lock.svg";
|
||||
static const String selfTestResult =
|
||||
"assets/icons/automation_functions/self_test_result.svg";
|
||||
static const String lockAlarm =
|
||||
"assets/icons/automation_functions/lock_alarm.svg";
|
||||
static const String presenceState =
|
||||
"assets/icons/automation_functions/presence_state.svg";
|
||||
static const String currentTemp =
|
||||
"assets/icons/automation_functions/current_temp.svg";
|
||||
static const String presence =
|
||||
"assets/icons/automation_functions/presence.svg";
|
||||
static const String residualElectricity =
|
||||
"assets/icons/automation_functions/residual_electricity.svg";
|
||||
static const String hijackAlarm =
|
||||
"assets/icons/automation_functions/hijack_alarm.svg";
|
||||
static const String passwordUnlock =
|
||||
"assets/icons/automation_functions/password_unlock.svg";
|
||||
static const String remoteUnlockRequest =
|
||||
"assets/icons/automation_functions/remote_unlock_req.svg";
|
||||
static const String cardUnlock =
|
||||
"assets/icons/automation_functions/card_unlock.svg";
|
||||
static const String motion = "assets/icons/automation_functions/motion.svg";
|
||||
static const String fingerprintUnlock = "assets/icons/automation_functions/fingerprint_unlock.svg";
|
||||
static const String fingerprintUnlock =
|
||||
"assets/icons/automation_functions/fingerprint_unlock.svg";
|
||||
|
||||
// Presence Sensor Assets
|
||||
static const String sensorMotionIcon = "assets/icons/sensor_motion_ic.svg";
|
||||
static const String sensorPresenceIcon = "assets/icons/sensor_presence_ic.svg";
|
||||
static const String sensorPresenceIcon =
|
||||
"assets/icons/sensor_presence_ic.svg";
|
||||
static const String sensorVacantIcon = "assets/icons/sensor_vacant_ic.svg";
|
||||
static const String illuminanceRecordIcon = "assets/icons/illuminance_record_ic.svg";
|
||||
static const String presenceRecordIcon = "assets/icons/presence_record_ic.svg";
|
||||
static const String helpDescriptionIcon = "assets/icons/help_description_ic.svg";
|
||||
static const String illuminanceRecordIcon =
|
||||
"assets/icons/illuminance_record_ic.svg";
|
||||
static const String presenceRecordIcon =
|
||||
"assets/icons/presence_record_ic.svg";
|
||||
static const String helpDescriptionIcon =
|
||||
"assets/icons/help_description_ic.svg";
|
||||
|
||||
static const String lightPulp = "assets/icons/light_pulb.svg";
|
||||
static const String acDevice = "assets/icons/ac_device.svg";
|
||||
@@ -155,4 +180,12 @@ class Assets {
|
||||
static const String closedDoor = 'assets/icons/closed_door.svg';
|
||||
static const String doorDelay = 'assets/icons/door_delay.svg';
|
||||
static const String records = 'assets/icons/records.svg';
|
||||
//assets/icons/water_leak_normal.svg
|
||||
static const String waterLeakNormal = 'assets/icons/water_leak_normal.svg';
|
||||
//assets/icons/water_leak_detected.svg
|
||||
static const String waterLeakDetected =
|
||||
'assets/icons/water_leak_detected.svg';
|
||||
|
||||
//assets/icons/automation_records.svg
|
||||
static const String automationRecords = 'assets/icons/automation_records.svg';
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user