diff --git a/assets/icons/3GangSwitch.svg b/assets/icons/3GangSwitch.svg new file mode 100644 index 00000000..ecb9992b --- /dev/null +++ b/assets/icons/3GangSwitch.svg @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + + + + + diff --git a/assets/icons/AC.svg b/assets/icons/AC.svg new file mode 100644 index 00000000..92f6fc59 --- /dev/null +++ b/assets/icons/AC.svg @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/assets/icons/Curtain.svg b/assets/icons/Curtain.svg new file mode 100644 index 00000000..a2e4f235 --- /dev/null +++ b/assets/icons/Curtain.svg @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + diff --git a/assets/icons/Gateway.svg b/assets/icons/Gateway.svg new file mode 100644 index 00000000..e293999e --- /dev/null +++ b/assets/icons/Gateway.svg @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + + + + + diff --git a/assets/icons/Light.svg b/assets/icons/Light.svg new file mode 100644 index 00000000..c8cfff59 --- /dev/null +++ b/assets/icons/Light.svg @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/assets/icons/doorLock.svg b/assets/icons/doorLock.svg new file mode 100644 index 00000000..6f27673f --- /dev/null +++ b/assets/icons/doorLock.svg @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/icons/sensors.svg b/assets/icons/sensors.svg new file mode 100644 index 00000000..7fbb1506 --- /dev/null +++ b/assets/icons/sensors.svg @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + + + + + diff --git a/lib/pages/device_managment/all_devices/helper/route_controls_based_code.dart b/lib/pages/device_managment/all_devices/helper/route_controls_based_code.dart index 632cbc68..6076f95f 100644 --- a/lib/pages/device_managment/all_devices/helper/route_controls_based_code.dart +++ b/lib/pages/device_managment/all_devices/helper/route_controls_based_code.dart @@ -3,6 +3,7 @@ import 'package:flutter/material.dart'; import 'package:syncrow_web/pages/device_managment/ac/view/ac_device_control.dart'; import 'package:syncrow_web/pages/device_managment/all_devices/models/devices_model.dart'; import 'package:syncrow_web/pages/device_managment/ceiling_sensor/view/ceiling_sensor_controls.dart'; +import 'package:syncrow_web/pages/device_managment/gateway/view/gateway_view.dart'; import 'package:syncrow_web/pages/device_managment/living_room_switch/view/living_room_device_control.dart'; import 'package:syncrow_web/pages/device_managment/wall_sensor/view/wall_sensor_conrtols.dart'; @@ -14,7 +15,9 @@ mixin RouteControlsBasedCode { device: device, ); case 'GW': - return const SizedBox(); + return GateWayControls( + gatewayId: device.uuid!, + ); case 'DL': return const SizedBox(); case 'WPS': diff --git a/lib/pages/device_managment/gateway/bloc/gate_way_bloc.dart b/lib/pages/device_managment/gateway/bloc/gate_way_bloc.dart new file mode 100644 index 00000000..ca572bf0 --- /dev/null +++ b/lib/pages/device_managment/gateway/bloc/gate_way_bloc.dart @@ -0,0 +1,30 @@ +import 'dart:async'; + +import 'package:bloc/bloc.dart'; +import 'package:equatable/equatable.dart'; +import 'package:syncrow_web/pages/visitor_password/model/device_model.dart'; +import 'package:syncrow_web/services/devices_mang_api.dart'; + +part 'gate_way_event.dart'; +part 'gate_way_state.dart'; + +class GateWayBloc extends Bloc { + GateWayBloc() : super(GateWayInitial()) { + on((event, emit) {}); + on(_getGatWayById); + } + + FutureOr _getGatWayById( + GatWayById event, Emitter emit) async { + emit(GatewayLoadingState()); + try { + List devicesList = + await DevicesManagementApi.getDevicesByGatewayId(event.getWayId); + + emit(UpdateGatewayState(list: devicesList)); + } catch (e) { + emit(ErrorState(message: e.toString())); + return; + } + } +} diff --git a/lib/pages/device_managment/gateway/bloc/gate_way_event.dart b/lib/pages/device_managment/gateway/bloc/gate_way_event.dart new file mode 100644 index 00000000..22c81a12 --- /dev/null +++ b/lib/pages/device_managment/gateway/bloc/gate_way_event.dart @@ -0,0 +1,20 @@ +part of 'gate_way_bloc.dart'; + +sealed class GateWayEvent extends Equatable { + const GateWayEvent(); + + @override + List get props => []; +} + +class GateWayLoading extends GateWayEvent {} + +class GateWayFetch extends GateWayEvent { + final String deviceId; + const GateWayFetch(this.deviceId); +} + +class GatWayById extends GateWayEvent { + final String getWayId; + const GatWayById(this.getWayId); +} diff --git a/lib/pages/device_managment/gateway/bloc/gate_way_state.dart b/lib/pages/device_managment/gateway/bloc/gate_way_state.dart new file mode 100644 index 00000000..8d6b616e --- /dev/null +++ b/lib/pages/device_managment/gateway/bloc/gate_way_state.dart @@ -0,0 +1,26 @@ +part of 'gate_way_bloc.dart'; + +sealed class GateWayState extends Equatable { + const GateWayState(); + + @override + List get props => []; +} + +final class GateWayInitial extends GateWayState {} + +class GatewayLoadingState extends GateWayState {} + +class UpdateGatewayState extends GateWayState { + final List list; + const UpdateGatewayState({required this.list}); + @override + List get props => [list]; +} + +class ErrorState extends GateWayState { + final String message; + const ErrorState({required this.message}); + @override + List get props => [message]; +} diff --git a/lib/pages/device_managment/gateway/view/gateway_view.dart b/lib/pages/device_managment/gateway/view/gateway_view.dart new file mode 100644 index 00000000..248884da --- /dev/null +++ b/lib/pages/device_managment/gateway/view/gateway_view.dart @@ -0,0 +1,98 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:flutter_svg/flutter_svg.dart'; +import 'package:syncrow_web/pages/device_managment/gateway/bloc/gate_way_bloc.dart'; +import 'package:syncrow_web/pages/device_managment/shared/device_controls_container.dart'; +import 'package:syncrow_web/pages/visitor_password/model/device_model.dart'; +import 'package:syncrow_web/utils/color_manager.dart'; +import 'package:syncrow_web/utils/helpers/responsice_layout_helper/responsive_layout_helper.dart'; + +class GateWayControls extends StatelessWidget with HelperResponsiveLayout { + const GateWayControls({super.key, required this.gatewayId}); + + final String gatewayId; + + @override + Widget build(BuildContext context) { + final isLarge = isLargeScreenSize(context); + final isMedium = isMediumScreenSize(context); + + return BlocProvider( + create: (context) => GateWayBloc()..add(GatWayById(gatewayId)), + child: BlocBuilder( + builder: (context, state) { + if (state is GatewayLoadingState) { + return const Center(child: CircularProgressIndicator()); + } else if (state is UpdateGatewayState) { + return GridView.builder( + padding: const EdgeInsets.symmetric(horizontal: 50), + shrinkWrap: true, + physics: const NeverScrollableScrollPhysics(), + gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( + crossAxisCount: isLarge + ? 3 + : isMedium + ? 2 + : 1, + mainAxisExtent: 150, + crossAxisSpacing: 12, + mainAxisSpacing: 12, + ), + itemCount: state.list.length, + itemBuilder: (context, index) { + final device = state.list[index]; + return _DeviceItem(device: device); + }, + ); + } else { + return const Center(child: Text('Error fetching devices')); + } + }, + ), + ); + } +} + +class _DeviceItem extends StatelessWidget { + const _DeviceItem({ + required this.device, + }); + + final DeviceModel device; + + @override + Widget build(BuildContext context) { + return DeviceControlsContainer( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Container( + width: 60, + height: 60, + decoration: const BoxDecoration( + shape: BoxShape.circle, + color: ColorsManager.whiteColors, + ), + margin: const EdgeInsets.symmetric(horizontal: 4), + padding: const EdgeInsets.all(4), + child: ClipOval( + child: SvgPicture.asset( + device.icon, + fit: BoxFit.fill, + ), + ), + ), + const Spacer(), + Text( + device.name ?? 'Unknown Device', + textAlign: TextAlign.center, + style: const TextStyle( + fontWeight: FontWeight.bold, + fontSize: 14, + ), + ), + ], + ), + ); + } +} diff --git a/lib/pages/visitor_password/model/device_model.dart b/lib/pages/visitor_password/model/device_model.dart index 9d4e9290..6446634b 100644 --- a/lib/pages/visitor_password/model/device_model.dart +++ b/lib/pages/visitor_password/model/device_model.dart @@ -1,4 +1,6 @@ +import 'package:syncrow_web/utils/constants/assets.dart'; import 'package:syncrow_web/utils/constants/const.dart'; +import 'package:syncrow_web/utils/enum/device_types.dart'; class DeviceModel { dynamic productUuid; @@ -47,6 +49,27 @@ class DeviceModel { // Deserialize from JSON factory DeviceModel.fromJson(Map json) { + String tempIcon = ''; + DeviceType type = devicesTypesMap[json['productType']] ?? DeviceType.Other; + + if (type == DeviceType.LightBulb) { + tempIcon = Assets.lightBulb; + } else if (type == DeviceType.CeilingSensor || + type == DeviceType.WallSensor) { + tempIcon = Assets.sensors; + } else if (type == DeviceType.AC) { + tempIcon = Assets.ac; + } else if (type == DeviceType.DoorLock) { + tempIcon = Assets.doorLock; + } else if (type == DeviceType.Curtain) { + tempIcon = Assets.curtain; + } else if (type == DeviceType.ThreeGang) { + tempIcon = Assets.gangSwitch; + } else if (type == DeviceType.Gateway) { + tempIcon = Assets.gateway; + } else { + tempIcon = Assets.logo; + } return DeviceModel( productUuid: json['productUuid'], productType: json['productType'], @@ -55,7 +78,7 @@ class DeviceModel { categoryName: json['categoryName'], createTime: json['createTime'], gatewayId: json['gatewayId'], - icon: json['icon'], + icon: tempIcon, ip: json['ip'], lat: json['lat'], localKey: json['localKey'], diff --git a/lib/services/devices_mang_api.dart b/lib/services/devices_mang_api.dart index ef2a9544..9115c03b 100644 --- a/lib/services/devices_mang_api.dart +++ b/lib/services/devices_mang_api.dart @@ -1,6 +1,7 @@ import 'package:flutter/material.dart'; import 'package:syncrow_web/pages/device_managment/all_devices/models/device_status.dart'; import 'package:syncrow_web/pages/device_managment/all_devices/models/devices_model.dart'; +import 'package:syncrow_web/pages/visitor_password/model/device_model.dart'; import 'package:syncrow_web/services/api/http_service.dart'; import 'package:syncrow_web/utils/constants/api_const.dart'; @@ -46,7 +47,6 @@ class DevicesManagementApi { } //deviceControl - Future deviceControl(String uuid, Status status) async { try { final response = await HTTPService().post( @@ -63,4 +63,23 @@ class DevicesManagementApi { return false; } } + + static Future> getDevicesByGatewayId( + String gatewayId) async { + final response = await HTTPService().get( + path: ApiEndpoints.gatewayApi.replaceAll('{gatewayUuid}', gatewayId), + showServerMessage: false, + expectedResponseModel: (json) { + List devices = []; + if (json == null || json.isEmpty || json == []) { + return devices; + } + for (var device in json['devices']) { + devices.add(DeviceModel.fromJson(device)); + } + return devices; + }, + ); + return response; + } } diff --git a/lib/utils/constants/api_const.dart b/lib/utils/constants/api_const.dart index 6e92445c..8f73cb3f 100644 --- a/lib/utils/constants/api_const.dart +++ b/lib/utils/constants/api_const.dart @@ -33,4 +33,5 @@ abstract class ApiEndpoints { '$baseUrl/device/{uuid}/functions/status'; static const String deviceControl = '$baseUrl/device/{uuid}/control'; + static const String gatewayApi = '/device/gateway/{gatewayUuid}/devices'; } diff --git a/lib/utils/constants/assets.dart b/lib/utils/constants/assets.dart index b040c3a1..2c3c1c0c 100644 --- a/lib/utils/constants/assets.dart +++ b/lib/utils/constants/assets.dart @@ -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,7 +60,8 @@ 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 @@ -64,36 +69,65 @@ class Assets { "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 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 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 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 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"; // 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"; static const String acAirConditioner = "assets/icons/ac_air.svg"; static const String acSun = "assets/icons/ac_sun.svg"; + + //assets/icons/3GangSwitch.svg + static const String gangSwitch = "assets/icons/3GangSwitch.svg"; + //assets/icons/AC.svg + static const String ac = "assets/icons/AC.svg"; + //assets/icons/Curtain.svg + static const String curtain = "assets/icons/Curtain.svg"; + //assets/icons/doorLock.svg + static const String doorLock = "assets/icons/doorLock.svg"; + //assets/icons/Gateway.svg + static const String gateway = "assets/icons/Gateway.svg"; + //assets/icons/Light.svg + static const String lightBulb = "assets/icons/Light.svg"; + //assets/icons/sensors.svg + static const String sensors = "assets/icons/sensors.svg"; } diff --git a/lib/utils/enum/device_types.dart b/lib/utils/enum/device_types.dart new file mode 100644 index 00000000..94821ef6 --- /dev/null +++ b/lib/utils/enum/device_types.dart @@ -0,0 +1,21 @@ +enum DeviceType { + AC, + LightBulb, + DoorLock, + Curtain, + Blind, + ThreeGang, + Gateway, + CeilingSensor, + WallSensor, + Other, +} + +Map devicesTypesMap = { + "AC": DeviceType.AC, + "GW": DeviceType.Gateway, + "CPS": DeviceType.CeilingSensor, + "DL": DeviceType.DoorLock, + "WPS": DeviceType.WallSensor, + "3G": DeviceType.ThreeGang, +};