mirror of
https://github.com/SyncrowIOT/web.git
synced 2026-10-26 22:47:55 +00:00
Compare commits
29
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f7f3843fa7 | ||
|
|
c6b55cb28b | ||
|
|
bfd8e964f7 | ||
|
|
08725201d5 | ||
|
|
7fe34c61b2 | ||
|
|
0c6e4fed80 | ||
|
|
69c23525ba | ||
|
|
3a98f71ff3 | ||
|
|
24a7f3ac2a | ||
|
|
79b974ee6c | ||
|
|
651ac6785e | ||
|
|
9fa59ce78b | ||
|
|
e2c44ba85f | ||
|
|
1edeb664aa | ||
|
|
25a55ad820 | ||
|
|
e48fc8b82c | ||
|
|
8d999f118c | ||
|
|
bcb6e49a01 | ||
|
|
b0ed844893 | ||
|
|
3d183528c5 | ||
|
|
2c4da63266 | ||
|
|
4ebe65f820 | ||
|
|
5654d66b60 | ||
|
|
b6879035f0 | ||
|
|
8ad048e18d | ||
|
|
d92b699a2b | ||
|
|
6ffb677c33 | ||
|
|
e7476a084d | ||
|
|
511acc186f |
@@ -8,6 +8,8 @@ class AnalyticsDevice {
|
|||||||
this.isActive,
|
this.isActive,
|
||||||
this.productDevice,
|
this.productDevice,
|
||||||
this.spaceUuid,
|
this.spaceUuid,
|
||||||
|
this.latitude,
|
||||||
|
this.longitude,
|
||||||
});
|
});
|
||||||
|
|
||||||
final String uuid;
|
final String uuid;
|
||||||
@@ -18,6 +20,8 @@ class AnalyticsDevice {
|
|||||||
final bool? isActive;
|
final bool? isActive;
|
||||||
final ProductDevice? productDevice;
|
final ProductDevice? productDevice;
|
||||||
final String? spaceUuid;
|
final String? spaceUuid;
|
||||||
|
final double? latitude;
|
||||||
|
final double? longitude;
|
||||||
|
|
||||||
factory AnalyticsDevice.fromJson(Map<String, dynamic> json) {
|
factory AnalyticsDevice.fromJson(Map<String, dynamic> json) {
|
||||||
return AnalyticsDevice(
|
return AnalyticsDevice(
|
||||||
@@ -35,6 +39,8 @@ class AnalyticsDevice {
|
|||||||
? ProductDevice.fromJson(json['productDevice'] as Map<String, dynamic>)
|
? ProductDevice.fromJson(json['productDevice'] as Map<String, dynamic>)
|
||||||
: null,
|
: null,
|
||||||
spaceUuid: json['spaceUuid'] as String?,
|
spaceUuid: json['spaceUuid'] as String?,
|
||||||
|
latitude: json['lat'] != null ? double.parse(json['lat'] as String) : null,
|
||||||
|
longitude: json['lon'] != null ? double.parse(json['lon'] as String) : null,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,55 @@
|
|||||||
|
import 'package:equatable/equatable.dart';
|
||||||
|
|
||||||
|
class DeviceLocationInfo extends Equatable {
|
||||||
|
const DeviceLocationInfo({
|
||||||
|
this.airQuality,
|
||||||
|
this.humidity,
|
||||||
|
this.city,
|
||||||
|
this.country,
|
||||||
|
this.address,
|
||||||
|
this.temperature,
|
||||||
|
});
|
||||||
|
|
||||||
|
final double? airQuality;
|
||||||
|
final double? humidity;
|
||||||
|
final String? city;
|
||||||
|
final String? country;
|
||||||
|
final String? address;
|
||||||
|
final double? temperature;
|
||||||
|
|
||||||
|
factory DeviceLocationInfo.fromJson(Map<String, dynamic> json) {
|
||||||
|
return DeviceLocationInfo(
|
||||||
|
airQuality: json['aqi'] as double?,
|
||||||
|
humidity: json['humidity'] as double?,
|
||||||
|
temperature: json['temperature'] as double?,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
DeviceLocationInfo copyWith({
|
||||||
|
double? airQuality,
|
||||||
|
double? humidity,
|
||||||
|
String? city,
|
||||||
|
String? country,
|
||||||
|
String? address,
|
||||||
|
double? temperature,
|
||||||
|
}) {
|
||||||
|
return DeviceLocationInfo(
|
||||||
|
airQuality: airQuality ?? this.airQuality,
|
||||||
|
humidity: humidity ?? this.humidity,
|
||||||
|
city: city ?? this.city,
|
||||||
|
country: country ?? this.country,
|
||||||
|
address: address ?? this.address,
|
||||||
|
temperature: temperature ?? this.temperature,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
List<Object?> get props => [
|
||||||
|
airQuality,
|
||||||
|
humidity,
|
||||||
|
city,
|
||||||
|
country,
|
||||||
|
address,
|
||||||
|
temperature,
|
||||||
|
];
|
||||||
|
}
|
||||||
+50
@@ -0,0 +1,50 @@
|
|||||||
|
import 'package:bloc/bloc.dart';
|
||||||
|
import 'package:equatable/equatable.dart';
|
||||||
|
import 'package:syncrow_web/pages/analytics/models/device_location_info.dart';
|
||||||
|
import 'package:syncrow_web/pages/analytics/params/get_device_location_data_param.dart';
|
||||||
|
import 'package:syncrow_web/pages/analytics/services/device_location/device_location_service.dart';
|
||||||
|
|
||||||
|
part 'device_location_event.dart';
|
||||||
|
part 'device_location_state.dart';
|
||||||
|
|
||||||
|
class DeviceLocationBloc extends Bloc<DeviceLocationEvent, DeviceLocationState> {
|
||||||
|
DeviceLocationBloc(
|
||||||
|
this._deviceLocationService,
|
||||||
|
) : super(const DeviceLocationState()) {
|
||||||
|
on<LoadDeviceLocationEvent>(_onLoadDeviceLocation);
|
||||||
|
on<ClearDeviceLocationEvent>(_onClearDeviceLocation);
|
||||||
|
}
|
||||||
|
|
||||||
|
final DeviceLocationService _deviceLocationService;
|
||||||
|
|
||||||
|
Future<void> _onLoadDeviceLocation(
|
||||||
|
LoadDeviceLocationEvent event,
|
||||||
|
Emitter<DeviceLocationState> emit,
|
||||||
|
) async {
|
||||||
|
emit(const DeviceLocationState(status: DeviceLocationStatus.loading));
|
||||||
|
|
||||||
|
try {
|
||||||
|
final locationInfo = await _deviceLocationService.get(event.param);
|
||||||
|
emit(
|
||||||
|
DeviceLocationState(
|
||||||
|
status: DeviceLocationStatus.success,
|
||||||
|
locationInfo: locationInfo,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
} catch (e) {
|
||||||
|
emit(
|
||||||
|
DeviceLocationState(
|
||||||
|
status: DeviceLocationStatus.failure,
|
||||||
|
errorMessage: e.toString(),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void _onClearDeviceLocation(
|
||||||
|
ClearDeviceLocationEvent event,
|
||||||
|
Emitter<DeviceLocationState> emit,
|
||||||
|
) {
|
||||||
|
emit(const DeviceLocationState());
|
||||||
|
}
|
||||||
|
}
|
||||||
+21
@@ -0,0 +1,21 @@
|
|||||||
|
part of 'device_location_bloc.dart';
|
||||||
|
|
||||||
|
sealed class DeviceLocationEvent extends Equatable {
|
||||||
|
const DeviceLocationEvent();
|
||||||
|
|
||||||
|
@override
|
||||||
|
List<Object?> get props => [];
|
||||||
|
}
|
||||||
|
|
||||||
|
final class LoadDeviceLocationEvent extends DeviceLocationEvent {
|
||||||
|
const LoadDeviceLocationEvent(this.param);
|
||||||
|
|
||||||
|
final GetDeviceLocationDataParam param;
|
||||||
|
|
||||||
|
@override
|
||||||
|
List<Object?> get props => [param];
|
||||||
|
}
|
||||||
|
|
||||||
|
final class ClearDeviceLocationEvent extends DeviceLocationEvent {
|
||||||
|
const ClearDeviceLocationEvent();
|
||||||
|
}
|
||||||
+18
@@ -0,0 +1,18 @@
|
|||||||
|
part of 'device_location_bloc.dart';
|
||||||
|
|
||||||
|
enum DeviceLocationStatus { initial, loading, success, failure }
|
||||||
|
|
||||||
|
final class DeviceLocationState extends Equatable {
|
||||||
|
const DeviceLocationState({
|
||||||
|
this.status = DeviceLocationStatus.initial,
|
||||||
|
this.locationInfo,
|
||||||
|
this.errorMessage,
|
||||||
|
});
|
||||||
|
|
||||||
|
final DeviceLocationStatus status;
|
||||||
|
final DeviceLocationInfo? locationInfo;
|
||||||
|
final String? errorMessage;
|
||||||
|
|
||||||
|
@override
|
||||||
|
List<Object?> get props => [status, locationInfo, errorMessage];
|
||||||
|
}
|
||||||
@@ -1,12 +1,14 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
import 'package:syncrow_web/pages/analytics/modules/air_quality/blocs/air_quality_distribution/air_quality_distribution_bloc.dart';
|
import 'package:syncrow_web/pages/analytics/modules/air_quality/blocs/air_quality_distribution/air_quality_distribution_bloc.dart';
|
||||||
|
import 'package:syncrow_web/pages/analytics/modules/air_quality/blocs/device_location/device_location_bloc.dart';
|
||||||
import 'package:syncrow_web/pages/analytics/modules/air_quality/blocs/range_of_aqi/range_of_aqi_bloc.dart';
|
import 'package:syncrow_web/pages/analytics/modules/air_quality/blocs/range_of_aqi/range_of_aqi_bloc.dart';
|
||||||
import 'package:syncrow_web/pages/analytics/modules/analytics/blocs/analytics_date_picker_bloc/analytics_date_picker_bloc.dart';
|
import 'package:syncrow_web/pages/analytics/modules/analytics/blocs/analytics_date_picker_bloc/analytics_date_picker_bloc.dart';
|
||||||
import 'package:syncrow_web/pages/analytics/modules/analytics/blocs/analytics_devices/analytics_devices_bloc.dart';
|
import 'package:syncrow_web/pages/analytics/modules/analytics/blocs/analytics_devices/analytics_devices_bloc.dart';
|
||||||
import 'package:syncrow_web/pages/analytics/modules/energy_management/blocs/realtime_device_changes/realtime_device_changes_bloc.dart';
|
import 'package:syncrow_web/pages/analytics/modules/energy_management/blocs/realtime_device_changes/realtime_device_changes_bloc.dart';
|
||||||
import 'package:syncrow_web/pages/analytics/params/get_air_quality_distribution_param.dart';
|
import 'package:syncrow_web/pages/analytics/params/get_air_quality_distribution_param.dart';
|
||||||
import 'package:syncrow_web/pages/analytics/params/get_analytics_devices_param.dart';
|
import 'package:syncrow_web/pages/analytics/params/get_analytics_devices_param.dart';
|
||||||
|
import 'package:syncrow_web/pages/analytics/params/get_device_location_data_param.dart';
|
||||||
import 'package:syncrow_web/pages/analytics/params/get_range_of_aqi_param.dart';
|
import 'package:syncrow_web/pages/analytics/params/get_range_of_aqi_param.dart';
|
||||||
|
|
||||||
abstract final class FetchAirQualityDataHelper {
|
abstract final class FetchAirQualityDataHelper {
|
||||||
@@ -48,6 +50,8 @@ abstract final class FetchAirQualityDataHelper {
|
|||||||
const ClearAirQualityDistribution(),
|
const ClearAirQualityDistribution(),
|
||||||
);
|
);
|
||||||
context.read<RangeOfAqiBloc>().add(const ClearRangeOfAqiEvent());
|
context.read<RangeOfAqiBloc>().add(const ClearRangeOfAqiEvent());
|
||||||
|
|
||||||
|
context.read<DeviceLocationBloc>().add(const ClearDeviceLocationEvent());
|
||||||
}
|
}
|
||||||
|
|
||||||
static void loadAnalyticsDevices(
|
static void loadAnalyticsDevices(
|
||||||
@@ -61,12 +65,21 @@ abstract final class FetchAirQualityDataHelper {
|
|||||||
communityUuid: communityUuid,
|
communityUuid: communityUuid,
|
||||||
spaceUuid: spaceUuid,
|
spaceUuid: spaceUuid,
|
||||||
deviceTypes: ['AQI'],
|
deviceTypes: ['AQI'],
|
||||||
requestType: AnalyticsDeviceRequestType.energyManagement,
|
requestType: AnalyticsDeviceRequestType.occupancy,
|
||||||
),
|
),
|
||||||
onSuccess: (device) {
|
onSuccess: (device) {
|
||||||
context.read<RealtimeDeviceChangesBloc>()
|
context.read<RealtimeDeviceChangesBloc>()
|
||||||
..add(const RealtimeDeviceChangesClosed())
|
..add(const RealtimeDeviceChangesClosed())
|
||||||
..add(RealtimeDeviceChangesStarted(device.uuid));
|
..add(RealtimeDeviceChangesStarted(device.uuid));
|
||||||
|
|
||||||
|
context.read<DeviceLocationBloc>().add(
|
||||||
|
LoadDeviceLocationEvent(
|
||||||
|
GetDeviceLocationDataParam(
|
||||||
|
latitude: device.latitude ?? 0,
|
||||||
|
longitude: device.longitude ?? 0,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -72,9 +72,9 @@ class AqiDeviceInfo extends StatelessWidget {
|
|||||||
return Container(
|
return Container(
|
||||||
decoration: secondarySection.copyWith(boxShadow: const []),
|
decoration: secondarySection.copyWith(boxShadow: const []),
|
||||||
padding: const EdgeInsetsDirectional.all(20),
|
padding: const EdgeInsetsDirectional.all(20),
|
||||||
child: Expanded(
|
|
||||||
child: Column(
|
child: Column(
|
||||||
spacing: 6,
|
spacing: 6,
|
||||||
|
mainAxisSize: MainAxisSize.max,
|
||||||
children: [
|
children: [
|
||||||
const AirQualityEndSideLiveIndicator(),
|
const AirQualityEndSideLiveIndicator(),
|
||||||
AirQualityEndSideGaugeAndInfo(
|
AirQualityEndSideGaugeAndInfo(
|
||||||
@@ -121,7 +121,6 @@ class AqiDeviceInfo extends StatelessWidget {
|
|||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -6,7 +6,34 @@ import 'package:syncrow_web/utils/extension/build_context_x.dart';
|
|||||||
import 'package:syncrow_web/utils/style.dart';
|
import 'package:syncrow_web/utils/style.dart';
|
||||||
|
|
||||||
class AqiLocation extends StatelessWidget {
|
class AqiLocation extends StatelessWidget {
|
||||||
const AqiLocation({super.key});
|
const AqiLocation({
|
||||||
|
required this.city,
|
||||||
|
required this.country,
|
||||||
|
required this.address,
|
||||||
|
super.key,
|
||||||
|
});
|
||||||
|
|
||||||
|
final String? city;
|
||||||
|
final String? country;
|
||||||
|
final String? address;
|
||||||
|
|
||||||
|
String _getFormattedLocation() {
|
||||||
|
if (city == null && country == null && address == null) {
|
||||||
|
return 'N/A';
|
||||||
|
}
|
||||||
|
|
||||||
|
final parts = <String>[];
|
||||||
|
|
||||||
|
if (city != null) parts.add(city!);
|
||||||
|
if (address != null) parts.add(address!);
|
||||||
|
final locationPart = parts.join(', ');
|
||||||
|
|
||||||
|
if (country != null) {
|
||||||
|
return locationPart.isEmpty ? country! : '$locationPart - $country';
|
||||||
|
}
|
||||||
|
|
||||||
|
return locationPart;
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
@@ -24,7 +51,7 @@ class AqiLocation extends StatelessWidget {
|
|||||||
_buildLocationPin(),
|
_buildLocationPin(),
|
||||||
Expanded(
|
Expanded(
|
||||||
child: Text(
|
child: Text(
|
||||||
'Business Bay, Dubai - UAE',
|
_getFormattedLocation(),
|
||||||
style: context.textTheme.bodySmall?.copyWith(
|
style: context.textTheme.bodySmall?.copyWith(
|
||||||
color: ColorsManager.textPrimaryColor,
|
color: ColorsManager.textPrimaryColor,
|
||||||
fontWeight: FontWeight.w400,
|
fontWeight: FontWeight.w400,
|
||||||
|
|||||||
@@ -1,4 +1,6 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
|
import 'package:syncrow_web/pages/analytics/modules/air_quality/blocs/device_location/device_location_bloc.dart';
|
||||||
import 'package:syncrow_web/pages/analytics/modules/air_quality/widgets/aqi_location.dart';
|
import 'package:syncrow_web/pages/analytics/modules/air_quality/widgets/aqi_location.dart';
|
||||||
import 'package:syncrow_web/pages/analytics/modules/air_quality/widgets/aqi_location_info_cell.dart';
|
import 'package:syncrow_web/pages/analytics/modules/air_quality/widgets/aqi_location_info_cell.dart';
|
||||||
import 'package:syncrow_web/utils/constants/assets.dart';
|
import 'package:syncrow_web/utils/constants/assets.dart';
|
||||||
@@ -9,30 +11,37 @@ class AqiLocationInfo extends StatelessWidget {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
|
return BlocBuilder<DeviceLocationBloc, DeviceLocationState>(
|
||||||
|
builder: (context, state) {
|
||||||
|
final info = state.locationInfo;
|
||||||
return Container(
|
return Container(
|
||||||
decoration: secondarySection.copyWith(boxShadow: const []),
|
decoration: secondarySection.copyWith(boxShadow: const []),
|
||||||
padding: const EdgeInsetsDirectional.all(20),
|
padding: const EdgeInsetsDirectional.all(20),
|
||||||
child: const Column(
|
child: Column(
|
||||||
spacing: 8,
|
spacing: 8,
|
||||||
children: [
|
children: [
|
||||||
AqiLocation(),
|
AqiLocation(
|
||||||
|
city: info?.city,
|
||||||
|
country: info?.country,
|
||||||
|
address: info?.address,
|
||||||
|
),
|
||||||
Expanded(
|
Expanded(
|
||||||
child: Row(
|
child: Row(
|
||||||
spacing: 8,
|
spacing: 8,
|
||||||
children: [
|
children: [
|
||||||
AqiLocationInfoCell(
|
AqiLocationInfoCell(
|
||||||
label: 'Temperature',
|
label: 'Temperature',
|
||||||
value: ' 25°',
|
value: ' ${info?.temperature?.roundToDouble() ?? '--'}°',
|
||||||
svgPath: Assets.aqiTemperature,
|
svgPath: Assets.aqiTemperature,
|
||||||
),
|
),
|
||||||
AqiLocationInfoCell(
|
AqiLocationInfoCell(
|
||||||
label: 'Humidity',
|
label: 'Humidity',
|
||||||
value: '25%',
|
value: '${info?.humidity?.roundToDouble() ?? '--'}%',
|
||||||
svgPath: Assets.aqiHumidity,
|
svgPath: Assets.aqiHumidity,
|
||||||
),
|
),
|
||||||
AqiLocationInfoCell(
|
AqiLocationInfoCell(
|
||||||
label: 'Air Quality',
|
label: 'Air Quality',
|
||||||
value: ' 120',
|
value: ' ${info?.airQuality?.roundToDouble() ?? '--'}',
|
||||||
svgPath: Assets.aqiAirQuality,
|
svgPath: Assets.aqiAirQuality,
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
@@ -41,5 +50,7 @@ class AqiLocationInfo extends StatelessWidget {
|
|||||||
],
|
],
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+8
@@ -3,6 +3,7 @@ import 'package:equatable/equatable.dart';
|
|||||||
import 'package:syncrow_web/pages/analytics/models/analytics_device.dart';
|
import 'package:syncrow_web/pages/analytics/models/analytics_device.dart';
|
||||||
import 'package:syncrow_web/pages/analytics/params/get_analytics_devices_param.dart';
|
import 'package:syncrow_web/pages/analytics/params/get_analytics_devices_param.dart';
|
||||||
import 'package:syncrow_web/pages/analytics/services/analytics_devices/analytics_devices_service.dart';
|
import 'package:syncrow_web/pages/analytics/services/analytics_devices/analytics_devices_service.dart';
|
||||||
|
import 'package:syncrow_web/services/api/api_exception.dart';
|
||||||
|
|
||||||
part 'analytics_devices_event.dart';
|
part 'analytics_devices_event.dart';
|
||||||
part 'analytics_devices_state.dart';
|
part 'analytics_devices_state.dart';
|
||||||
@@ -36,6 +37,13 @@ class AnalyticsDevicesBloc
|
|||||||
if (devices.isNotEmpty) {
|
if (devices.isNotEmpty) {
|
||||||
event.onSuccess(devices.first);
|
event.onSuccess(devices.first);
|
||||||
}
|
}
|
||||||
|
} on APIException catch (e) {
|
||||||
|
emit(
|
||||||
|
AnalyticsDevicesState(
|
||||||
|
status: AnalyticsDevicesStatus.failure,
|
||||||
|
errorMessage: e.message,
|
||||||
|
),
|
||||||
|
);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
emit(
|
emit(
|
||||||
AnalyticsDevicesState(
|
AnalyticsDevicesState(
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
|
import 'package:dio/dio.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
import 'package:syncrow_web/pages/analytics/modules/air_quality/blocs/air_quality_distribution/air_quality_distribution_bloc.dart';
|
import 'package:syncrow_web/pages/analytics/modules/air_quality/blocs/air_quality_distribution/air_quality_distribution_bloc.dart';
|
||||||
|
import 'package:syncrow_web/pages/analytics/modules/air_quality/blocs/device_location/device_location_bloc.dart';
|
||||||
import 'package:syncrow_web/pages/analytics/modules/air_quality/blocs/range_of_aqi/range_of_aqi_bloc.dart';
|
import 'package:syncrow_web/pages/analytics/modules/air_quality/blocs/range_of_aqi/range_of_aqi_bloc.dart';
|
||||||
import 'package:syncrow_web/pages/analytics/modules/analytics/blocs/analytics_date_picker_bloc/analytics_date_picker_bloc.dart';
|
import 'package:syncrow_web/pages/analytics/modules/analytics/blocs/analytics_date_picker_bloc/analytics_date_picker_bloc.dart';
|
||||||
import 'package:syncrow_web/pages/analytics/modules/analytics/blocs/analytics_devices/analytics_devices_bloc.dart';
|
import 'package:syncrow_web/pages/analytics/modules/analytics/blocs/analytics_devices/analytics_devices_bloc.dart';
|
||||||
@@ -18,6 +20,8 @@ import 'package:syncrow_web/pages/analytics/services/air_quality_distribution/fa
|
|||||||
import 'package:syncrow_web/pages/analytics/services/analytics_devices/analytics_devices_service_delagate.dart';
|
import 'package:syncrow_web/pages/analytics/services/analytics_devices/analytics_devices_service_delagate.dart';
|
||||||
import 'package:syncrow_web/pages/analytics/services/analytics_devices/remote_energy_management_analytics_devices_service.dart';
|
import 'package:syncrow_web/pages/analytics/services/analytics_devices/remote_energy_management_analytics_devices_service.dart';
|
||||||
import 'package:syncrow_web/pages/analytics/services/analytics_devices/remote_occupancy_analytics_devices_service.dart';
|
import 'package:syncrow_web/pages/analytics/services/analytics_devices/remote_occupancy_analytics_devices_service.dart';
|
||||||
|
import 'package:syncrow_web/pages/analytics/services/device_location/device_location_details_service_decorator.dart';
|
||||||
|
import 'package:syncrow_web/pages/analytics/services/device_location/remote_device_location_service.dart';
|
||||||
import 'package:syncrow_web/pages/analytics/services/energy_consumption_by_phases/remote_energy_consumption_by_phases_service.dart';
|
import 'package:syncrow_web/pages/analytics/services/energy_consumption_by_phases/remote_energy_consumption_by_phases_service.dart';
|
||||||
import 'package:syncrow_web/pages/analytics/services/energy_consumption_per_device/remote_energy_consumption_per_device_service.dart';
|
import 'package:syncrow_web/pages/analytics/services/energy_consumption_per_device/remote_energy_consumption_per_device_service.dart';
|
||||||
import 'package:syncrow_web/pages/analytics/services/occupacy/remote_occupancy_service.dart';
|
import 'package:syncrow_web/pages/analytics/services/occupacy/remote_occupancy_service.dart';
|
||||||
@@ -108,6 +112,18 @@ class _AnalyticsPageState extends State<AnalyticsPage> {
|
|||||||
FakeAirQualityDistributionService(),
|
FakeAirQualityDistributionService(),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
BlocProvider(
|
||||||
|
create: (context) => DeviceLocationBloc(
|
||||||
|
DeviceLocationDetailsServiceDecorator(
|
||||||
|
RemoteDeviceLocationService(_httpService),
|
||||||
|
Dio(
|
||||||
|
BaseOptions(
|
||||||
|
baseUrl: 'https://nominatim.openstreetmap.org/',
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
],
|
],
|
||||||
child: const AnalyticsPageForm(),
|
child: const AnalyticsPageForm(),
|
||||||
);
|
);
|
||||||
|
|||||||
+8
@@ -3,6 +3,7 @@ import 'package:equatable/equatable.dart';
|
|||||||
import 'package:syncrow_web/pages/analytics/models/phases_energy_consumption.dart';
|
import 'package:syncrow_web/pages/analytics/models/phases_energy_consumption.dart';
|
||||||
import 'package:syncrow_web/pages/analytics/params/get_energy_consumption_by_phases_param.dart';
|
import 'package:syncrow_web/pages/analytics/params/get_energy_consumption_by_phases_param.dart';
|
||||||
import 'package:syncrow_web/pages/analytics/services/energy_consumption_by_phases/energy_consumption_by_phases_service.dart';
|
import 'package:syncrow_web/pages/analytics/services/energy_consumption_by_phases/energy_consumption_by_phases_service.dart';
|
||||||
|
import 'package:syncrow_web/services/api/api_exception.dart';
|
||||||
|
|
||||||
part 'energy_consumption_by_phases_event.dart';
|
part 'energy_consumption_by_phases_event.dart';
|
||||||
part 'energy_consumption_by_phases_state.dart';
|
part 'energy_consumption_by_phases_state.dart';
|
||||||
@@ -31,6 +32,13 @@ class EnergyConsumptionByPhasesBloc
|
|||||||
chartData: chartData,
|
chartData: chartData,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
} on APIException catch (e) {
|
||||||
|
emit(
|
||||||
|
state.copyWith(
|
||||||
|
status: EnergyConsumptionByPhasesStatus.failure,
|
||||||
|
errorMessage: e.message,
|
||||||
|
),
|
||||||
|
);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
emit(
|
emit(
|
||||||
state.copyWith(
|
state.copyWith(
|
||||||
|
|||||||
+10
-1
@@ -3,6 +3,7 @@ import 'package:equatable/equatable.dart';
|
|||||||
import 'package:syncrow_web/pages/analytics/models/device_energy_data_model.dart';
|
import 'package:syncrow_web/pages/analytics/models/device_energy_data_model.dart';
|
||||||
import 'package:syncrow_web/pages/analytics/params/get_energy_consumption_per_device_param.dart';
|
import 'package:syncrow_web/pages/analytics/params/get_energy_consumption_per_device_param.dart';
|
||||||
import 'package:syncrow_web/pages/analytics/services/energy_consumption_per_device/energy_consumption_per_device_service.dart';
|
import 'package:syncrow_web/pages/analytics/services/energy_consumption_per_device/energy_consumption_per_device_service.dart';
|
||||||
|
import 'package:syncrow_web/services/api/api_exception.dart';
|
||||||
|
|
||||||
part 'energy_consumption_per_device_event.dart';
|
part 'energy_consumption_per_device_event.dart';
|
||||||
part 'energy_consumption_per_device_state.dart';
|
part 'energy_consumption_per_device_state.dart';
|
||||||
@@ -13,7 +14,8 @@ class EnergyConsumptionPerDeviceBloc
|
|||||||
this._energyConsumptionPerDeviceService,
|
this._energyConsumptionPerDeviceService,
|
||||||
) : super(const EnergyConsumptionPerDeviceState()) {
|
) : super(const EnergyConsumptionPerDeviceState()) {
|
||||||
on<LoadEnergyConsumptionPerDeviceEvent>(_onLoadEnergyConsumptionPerDeviceEvent);
|
on<LoadEnergyConsumptionPerDeviceEvent>(_onLoadEnergyConsumptionPerDeviceEvent);
|
||||||
on<ClearEnergyConsumptionPerDeviceEvent>(_onClearEnergyConsumptionPerDeviceEvent);
|
on<ClearEnergyConsumptionPerDeviceEvent>(
|
||||||
|
_onClearEnergyConsumptionPerDeviceEvent);
|
||||||
}
|
}
|
||||||
|
|
||||||
final EnergyConsumptionPerDeviceService _energyConsumptionPerDeviceService;
|
final EnergyConsumptionPerDeviceService _energyConsumptionPerDeviceService;
|
||||||
@@ -31,6 +33,13 @@ class EnergyConsumptionPerDeviceBloc
|
|||||||
chartData: chartData,
|
chartData: chartData,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
} on APIException catch (e) {
|
||||||
|
emit(
|
||||||
|
state.copyWith(
|
||||||
|
status: EnergyConsumptionPerDeviceStatus.failure,
|
||||||
|
errorMessage: e.message,
|
||||||
|
),
|
||||||
|
);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
emit(
|
emit(
|
||||||
state.copyWith(
|
state.copyWith(
|
||||||
|
|||||||
+8
@@ -3,6 +3,7 @@ import 'package:equatable/equatable.dart';
|
|||||||
import 'package:syncrow_web/pages/analytics/services/power_clamp_info/power_clamp_info_service.dart';
|
import 'package:syncrow_web/pages/analytics/services/power_clamp_info/power_clamp_info_service.dart';
|
||||||
import 'package:syncrow_web/pages/device_managment/all_devices/models/device_status.dart';
|
import 'package:syncrow_web/pages/device_managment/all_devices/models/device_status.dart';
|
||||||
import 'package:syncrow_web/pages/device_managment/power_clamp/models/power_clamp_model.dart';
|
import 'package:syncrow_web/pages/device_managment/power_clamp/models/power_clamp_model.dart';
|
||||||
|
import 'package:syncrow_web/services/api/api_exception.dart';
|
||||||
|
|
||||||
part 'power_clamp_info_event.dart';
|
part 'power_clamp_info_event.dart';
|
||||||
part 'power_clamp_info_state.dart';
|
part 'power_clamp_info_state.dart';
|
||||||
@@ -31,6 +32,13 @@ class PowerClampInfoBloc extends Bloc<PowerClampInfoEvent, PowerClampInfoState>
|
|||||||
powerClampModel: powerClampModel,
|
powerClampModel: powerClampModel,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
} on APIException catch (e) {
|
||||||
|
emit(
|
||||||
|
state.copyWith(
|
||||||
|
status: PowerClampInfoStatus.error,
|
||||||
|
errorMessage: e.message,
|
||||||
|
),
|
||||||
|
);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
emit(
|
emit(
|
||||||
state.copyWith(
|
state.copyWith(
|
||||||
|
|||||||
+8
@@ -3,6 +3,7 @@ import 'package:equatable/equatable.dart';
|
|||||||
import 'package:syncrow_web/pages/analytics/models/energy_data_model.dart';
|
import 'package:syncrow_web/pages/analytics/models/energy_data_model.dart';
|
||||||
import 'package:syncrow_web/pages/analytics/params/get_total_energy_consumption_param.dart';
|
import 'package:syncrow_web/pages/analytics/params/get_total_energy_consumption_param.dart';
|
||||||
import 'package:syncrow_web/pages/analytics/services/total_energy_consumption/total_energy_consumption_service.dart';
|
import 'package:syncrow_web/pages/analytics/services/total_energy_consumption/total_energy_consumption_service.dart';
|
||||||
|
import 'package:syncrow_web/services/api/api_exception.dart';
|
||||||
|
|
||||||
part 'total_energy_consumption_event.dart';
|
part 'total_energy_consumption_event.dart';
|
||||||
part 'total_energy_consumption_state.dart';
|
part 'total_energy_consumption_state.dart';
|
||||||
@@ -31,6 +32,13 @@ class TotalEnergyConsumptionBloc
|
|||||||
status: TotalEnergyConsumptionStatus.loaded,
|
status: TotalEnergyConsumptionStatus.loaded,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
} on APIException catch (e) {
|
||||||
|
emit(
|
||||||
|
state.copyWith(
|
||||||
|
errorMessage: e.message,
|
||||||
|
status: TotalEnergyConsumptionStatus.failure,
|
||||||
|
),
|
||||||
|
);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
emit(
|
emit(
|
||||||
state.copyWith(
|
state.copyWith(
|
||||||
|
|||||||
+1
-24
@@ -1,34 +1,11 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
|
||||||
import 'package:syncrow_web/pages/analytics/modules/energy_management/helpers/fetch_energy_management_data_helper.dart';
|
|
||||||
import 'package:syncrow_web/pages/analytics/modules/energy_management/widgets/energy_consumption_per_device_chart_box.dart';
|
import 'package:syncrow_web/pages/analytics/modules/energy_management/widgets/energy_consumption_per_device_chart_box.dart';
|
||||||
import 'package:syncrow_web/pages/analytics/modules/energy_management/widgets/power_clamp_energy_data_widget.dart';
|
import 'package:syncrow_web/pages/analytics/modules/energy_management/widgets/power_clamp_energy_data_widget.dart';
|
||||||
import 'package:syncrow_web/pages/analytics/modules/energy_management/widgets/total_energy_consumption_chart_box.dart';
|
import 'package:syncrow_web/pages/analytics/modules/energy_management/widgets/total_energy_consumption_chart_box.dart';
|
||||||
import 'package:syncrow_web/pages/space_tree/bloc/space_tree_bloc.dart';
|
|
||||||
|
|
||||||
class AnalyticsEnergyManagementView extends StatefulWidget {
|
class AnalyticsEnergyManagementView extends StatelessWidget {
|
||||||
const AnalyticsEnergyManagementView({super.key});
|
const AnalyticsEnergyManagementView({super.key});
|
||||||
|
|
||||||
@override
|
|
||||||
State<AnalyticsEnergyManagementView> createState() =>
|
|
||||||
_AnalyticsEnergyManagementViewState();
|
|
||||||
}
|
|
||||||
|
|
||||||
class _AnalyticsEnergyManagementViewState
|
|
||||||
extends State<AnalyticsEnergyManagementView> {
|
|
||||||
@override
|
|
||||||
void initState() {
|
|
||||||
final spaceTreeBloc = context.read<SpaceTreeBloc>();
|
|
||||||
final communityId = spaceTreeBloc.state.selectedCommunities.firstOrNull;
|
|
||||||
final spaceId = spaceTreeBloc.state.selectedSpaces.firstOrNull;
|
|
||||||
FetchEnergyManagementDataHelper.loadEnergyManagementData(
|
|
||||||
context,
|
|
||||||
communityId: communityId ?? '',
|
|
||||||
spaceId: spaceId ?? '',
|
|
||||||
);
|
|
||||||
super.initState();
|
|
||||||
}
|
|
||||||
|
|
||||||
static const _padding = EdgeInsetsDirectional.all(32);
|
static const _padding = EdgeInsetsDirectional.all(32);
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ import 'package:equatable/equatable.dart';
|
|||||||
import 'package:syncrow_web/pages/analytics/models/occupacy.dart';
|
import 'package:syncrow_web/pages/analytics/models/occupacy.dart';
|
||||||
import 'package:syncrow_web/pages/analytics/params/get_occupancy_param.dart';
|
import 'package:syncrow_web/pages/analytics/params/get_occupancy_param.dart';
|
||||||
import 'package:syncrow_web/pages/analytics/services/occupacy/occupacy_service.dart';
|
import 'package:syncrow_web/pages/analytics/services/occupacy/occupacy_service.dart';
|
||||||
|
import 'package:syncrow_web/services/api/api_exception.dart';
|
||||||
|
|
||||||
part 'occupancy_event.dart';
|
part 'occupancy_event.dart';
|
||||||
part 'occupancy_state.dart';
|
part 'occupancy_state.dart';
|
||||||
@@ -23,6 +24,8 @@ class OccupancyBloc extends Bloc<OccupancyEvent, OccupancyState> {
|
|||||||
try {
|
try {
|
||||||
final chartData = await _occupacyService.load(event.param);
|
final chartData = await _occupacyService.load(event.param);
|
||||||
emit(state.copyWith(chartData: chartData, status: OccupancyStatus.loaded));
|
emit(state.copyWith(chartData: chartData, status: OccupancyStatus.loaded));
|
||||||
|
} on APIException catch (e) {
|
||||||
|
emit(state.copyWith(status: OccupancyStatus.failure, errorMessage: e.message));
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
emit(state.copyWith(status: OccupancyStatus.failure, errorMessage: '$e'));
|
emit(state.copyWith(status: OccupancyStatus.failure, errorMessage: '$e'));
|
||||||
}
|
}
|
||||||
|
|||||||
+8
@@ -3,6 +3,7 @@ import 'package:equatable/equatable.dart';
|
|||||||
import 'package:syncrow_web/pages/analytics/models/occupancy_heat_map_model.dart';
|
import 'package:syncrow_web/pages/analytics/models/occupancy_heat_map_model.dart';
|
||||||
import 'package:syncrow_web/pages/analytics/params/get_occupancy_heat_map_param.dart';
|
import 'package:syncrow_web/pages/analytics/params/get_occupancy_heat_map_param.dart';
|
||||||
import 'package:syncrow_web/pages/analytics/services/occupancy_heat_map/occupancy_heat_map_service.dart';
|
import 'package:syncrow_web/pages/analytics/services/occupancy_heat_map/occupancy_heat_map_service.dart';
|
||||||
|
import 'package:syncrow_web/services/api/api_exception.dart';
|
||||||
|
|
||||||
part 'occupancy_heat_map_event.dart';
|
part 'occupancy_heat_map_event.dart';
|
||||||
part 'occupancy_heat_map_state.dart';
|
part 'occupancy_heat_map_state.dart';
|
||||||
@@ -30,6 +31,13 @@ class OccupancyHeatMapBloc
|
|||||||
heatMapData: occupancyHeatMap,
|
heatMapData: occupancyHeatMap,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
} on APIException catch (e) {
|
||||||
|
emit(
|
||||||
|
state.copyWith(
|
||||||
|
status: OccupancyHeatMapStatus.failure,
|
||||||
|
errorMessage: e.message,
|
||||||
|
),
|
||||||
|
);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
emit(
|
emit(
|
||||||
state.copyWith(
|
state.copyWith(
|
||||||
|
|||||||
@@ -0,0 +1,11 @@
|
|||||||
|
class GetDeviceLocationDataParam {
|
||||||
|
const GetDeviceLocationDataParam({
|
||||||
|
required this.latitude,
|
||||||
|
required this.longitude,
|
||||||
|
});
|
||||||
|
|
||||||
|
final double latitude;
|
||||||
|
final double longitude;
|
||||||
|
|
||||||
|
Map<String, dynamic> toJson() => {'lat': latitude, 'lon': longitude};
|
||||||
|
}
|
||||||
@@ -10,7 +10,7 @@ class GetEnergyConsumptionPerDeviceParam {
|
|||||||
Map<String, dynamic> toJson() => {
|
Map<String, dynamic> toJson() => {
|
||||||
'monthDate':
|
'monthDate':
|
||||||
'${monthDate?.year}-${monthDate?.month.toString().padLeft(2, '0')}',
|
'${monthDate?.year}-${monthDate?.month.toString().padLeft(2, '0')}',
|
||||||
if (spaceId == null || spaceId == null) 'spaceUuid': spaceId,
|
if (spaceId != null) 'spaceUuid': spaceId,
|
||||||
'groupByDevice': true,
|
'groupByDevice': true,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ class GetTotalEnergyConsumptionParam {
|
|||||||
return {
|
return {
|
||||||
'monthDate':
|
'monthDate':
|
||||||
'${monthDate?.year}-${monthDate?.month.toString().padLeft(2, '0')}',
|
'${monthDate?.year}-${monthDate?.month.toString().padLeft(2, '0')}',
|
||||||
if (spaceId == null || spaceId == null) 'spaceUuid': spaceId,
|
if (spaceId != null) 'spaceUuid': spaceId,
|
||||||
'groupByDevice': false,
|
'groupByDevice': false,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
+11
-1
@@ -1,6 +1,8 @@
|
|||||||
|
import 'package:dio/dio.dart';
|
||||||
import 'package:syncrow_web/pages/analytics/models/analytics_device.dart';
|
import 'package:syncrow_web/pages/analytics/models/analytics_device.dart';
|
||||||
import 'package:syncrow_web/pages/analytics/params/get_analytics_devices_param.dart';
|
import 'package:syncrow_web/pages/analytics/params/get_analytics_devices_param.dart';
|
||||||
import 'package:syncrow_web/pages/analytics/services/analytics_devices/analytics_devices_service.dart';
|
import 'package:syncrow_web/pages/analytics/services/analytics_devices/analytics_devices_service.dart';
|
||||||
|
import 'package:syncrow_web/services/api/api_exception.dart';
|
||||||
import 'package:syncrow_web/services/api/http_service.dart';
|
import 'package:syncrow_web/services/api/http_service.dart';
|
||||||
|
|
||||||
final class RemoteEnergyManagementAnalyticsDevicesService
|
final class RemoteEnergyManagementAnalyticsDevicesService
|
||||||
@@ -9,6 +11,8 @@ final class RemoteEnergyManagementAnalyticsDevicesService
|
|||||||
|
|
||||||
final HTTPService _httpService;
|
final HTTPService _httpService;
|
||||||
|
|
||||||
|
static const _defaultErrorMessage = 'Failed to load analytics devices';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<List<AnalyticsDevice>> getDevices(GetAnalyticsDevicesParam param) async {
|
Future<List<AnalyticsDevice>> getDevices(GetAnalyticsDevicesParam param) async {
|
||||||
try {
|
try {
|
||||||
@@ -29,8 +33,14 @@ final class RemoteEnergyManagementAnalyticsDevicesService
|
|||||||
);
|
);
|
||||||
|
|
||||||
return response;
|
return response;
|
||||||
|
} on DioException catch (e) {
|
||||||
|
final message = e.response?.data as Map<String, dynamic>?;
|
||||||
|
final error = message?['error'] as Map<String, dynamic>?;
|
||||||
|
final errorMessage = error?['error'] as String? ?? '';
|
||||||
|
final formattedErrorMessage = [_defaultErrorMessage, errorMessage].join(': ');
|
||||||
|
throw APIException(formattedErrorMessage);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
throw Exception('Failed to load total energy consumption: $e');
|
throw APIException('$_defaultErrorMessage: $e');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+19
-2
@@ -1,7 +1,9 @@
|
|||||||
|
import 'package:dio/dio.dart';
|
||||||
import 'package:syncrow_web/pages/analytics/models/analytics_device.dart';
|
import 'package:syncrow_web/pages/analytics/models/analytics_device.dart';
|
||||||
import 'package:syncrow_web/pages/analytics/params/get_analytics_devices_param.dart';
|
import 'package:syncrow_web/pages/analytics/params/get_analytics_devices_param.dart';
|
||||||
import 'package:syncrow_web/pages/analytics/services/analytics_devices/analytics_devices_service.dart';
|
import 'package:syncrow_web/pages/analytics/services/analytics_devices/analytics_devices_service.dart';
|
||||||
import 'package:syncrow_web/pages/common/bloc/project_manager.dart';
|
import 'package:syncrow_web/pages/common/bloc/project_manager.dart';
|
||||||
|
import 'package:syncrow_web/services/api/api_exception.dart';
|
||||||
import 'package:syncrow_web/services/api/http_service.dart';
|
import 'package:syncrow_web/services/api/http_service.dart';
|
||||||
|
|
||||||
class RemoteOccupancyAnalyticsDevicesService implements AnalyticsDevicesService {
|
class RemoteOccupancyAnalyticsDevicesService implements AnalyticsDevicesService {
|
||||||
@@ -9,6 +11,8 @@ class RemoteOccupancyAnalyticsDevicesService implements AnalyticsDevicesService
|
|||||||
|
|
||||||
final HTTPService _httpService;
|
final HTTPService _httpService;
|
||||||
|
|
||||||
|
static const _defaultErrorMessage = 'Failed to load analytics devices';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<List<AnalyticsDevice>> getDevices(GetAnalyticsDevicesParam param) async {
|
Future<List<AnalyticsDevice>> getDevices(GetAnalyticsDevicesParam param) async {
|
||||||
try {
|
try {
|
||||||
@@ -26,8 +30,15 @@ class RemoteOccupancyAnalyticsDevicesService implements AnalyticsDevicesService
|
|||||||
|
|
||||||
final result = requests.map((e) => e.first).toList();
|
final result = requests.map((e) => e.first).toList();
|
||||||
return result;
|
return result;
|
||||||
|
} on DioException catch (e) {
|
||||||
|
final message = e.response?.data as Map<String, dynamic>?;
|
||||||
|
final error = message?['error'] as Map<String, dynamic>?;
|
||||||
|
final errorMessage = error?['error'] as String? ?? '';
|
||||||
|
final formattedErrorMessage = [_defaultErrorMessage, errorMessage].join(': ');
|
||||||
|
throw APIException(formattedErrorMessage);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
throw Exception('Failed to load total energy consumption: $e');
|
final formattedErrorMessage = [_defaultErrorMessage, e.toString()].join(': ');
|
||||||
|
throw APIException(formattedErrorMessage);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -54,8 +65,14 @@ class RemoteOccupancyAnalyticsDevicesService implements AnalyticsDevicesService
|
|||||||
},
|
},
|
||||||
);
|
);
|
||||||
return response;
|
return response;
|
||||||
|
} on DioException catch (e) {
|
||||||
|
final message = e.response?.data as Map<String, dynamic>?;
|
||||||
|
final error = message?['error'] as Map<String, dynamic>?;
|
||||||
|
final errorMessage = error?['error'] as String? ?? '';
|
||||||
|
final formattedErrorMessage = [_defaultErrorMessage, errorMessage].join(': ');
|
||||||
|
throw APIException(formattedErrorMessage);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
rethrow;
|
throw APIException('$_defaultErrorMessage: $e');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+40
@@ -0,0 +1,40 @@
|
|||||||
|
import 'package:dio/dio.dart';
|
||||||
|
import 'package:syncrow_web/pages/analytics/models/device_location_info.dart';
|
||||||
|
import 'package:syncrow_web/pages/analytics/params/get_device_location_data_param.dart';
|
||||||
|
import 'package:syncrow_web/pages/analytics/services/device_location/device_location_service.dart';
|
||||||
|
|
||||||
|
class DeviceLocationDetailsServiceDecorator implements DeviceLocationService {
|
||||||
|
const DeviceLocationDetailsServiceDecorator(this._decoratee, this._dio);
|
||||||
|
|
||||||
|
final DeviceLocationService _decoratee;
|
||||||
|
final Dio _dio;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<DeviceLocationInfo> get(GetDeviceLocationDataParam param) async {
|
||||||
|
try {
|
||||||
|
final deviceLocationInfo = await _decoratee.get(param);
|
||||||
|
final response = await _dio.get<Map<String, dynamic>>(
|
||||||
|
'reverse',
|
||||||
|
queryParameters: {
|
||||||
|
'format': 'json',
|
||||||
|
'lat': param.latitude,
|
||||||
|
'lon': param.longitude,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
final data = response.data;
|
||||||
|
if (data != null) {
|
||||||
|
final addressData = data['address'] as Map<String, dynamic>;
|
||||||
|
return deviceLocationInfo.copyWith(
|
||||||
|
city: addressData['city'],
|
||||||
|
country: addressData['country_code'].toString().toUpperCase(),
|
||||||
|
address: addressData['state'],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return deviceLocationInfo;
|
||||||
|
} catch (e) {
|
||||||
|
throw Exception('Failed to load device location info: ${e.toString()}');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
import 'package:syncrow_web/pages/analytics/models/device_location_info.dart';
|
||||||
|
import 'package:syncrow_web/pages/analytics/params/get_device_location_data_param.dart';
|
||||||
|
|
||||||
|
abstract interface class DeviceLocationService {
|
||||||
|
Future<DeviceLocationInfo> get(GetDeviceLocationDataParam param);
|
||||||
|
}
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
import 'package:dio/dio.dart';
|
||||||
|
import 'package:syncrow_web/pages/analytics/models/device_location_info.dart';
|
||||||
|
import 'package:syncrow_web/pages/analytics/params/get_device_location_data_param.dart';
|
||||||
|
import 'package:syncrow_web/pages/analytics/services/device_location/device_location_service.dart';
|
||||||
|
import 'package:syncrow_web/services/api/http_service.dart';
|
||||||
|
|
||||||
|
class RemoteDeviceLocationService implements DeviceLocationService {
|
||||||
|
const RemoteDeviceLocationService(this._httpService);
|
||||||
|
|
||||||
|
final HTTPService _httpService;
|
||||||
|
|
||||||
|
static const _defaultErrorMessage = 'Failed to load device location';
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<DeviceLocationInfo> get(GetDeviceLocationDataParam param) async {
|
||||||
|
try {
|
||||||
|
final response = await _httpService.get(
|
||||||
|
path: '/weather',
|
||||||
|
queryParameters: param.toJson(),
|
||||||
|
expectedResponseModel: (data) {
|
||||||
|
final response = data as Map<String, dynamic>;
|
||||||
|
final location = response['data'] as Map<String, dynamic>;
|
||||||
|
|
||||||
|
return DeviceLocationInfo.fromJson(location);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
return response;
|
||||||
|
} on DioException catch (e) {
|
||||||
|
final message = e.response?.data as Map<String, dynamic>?;
|
||||||
|
final error = message?['error'] as Map<String, dynamic>?;
|
||||||
|
final errorMessage = error?['error'] as String? ?? '';
|
||||||
|
throw Exception(errorMessage);
|
||||||
|
} catch (e) {
|
||||||
|
throw Exception('$_defaultErrorMessage: $e');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+12
-1
@@ -1,6 +1,8 @@
|
|||||||
|
import 'package:dio/dio.dart';
|
||||||
import 'package:syncrow_web/pages/analytics/models/phases_energy_consumption.dart';
|
import 'package:syncrow_web/pages/analytics/models/phases_energy_consumption.dart';
|
||||||
import 'package:syncrow_web/pages/analytics/params/get_energy_consumption_by_phases_param.dart';
|
import 'package:syncrow_web/pages/analytics/params/get_energy_consumption_by_phases_param.dart';
|
||||||
import 'package:syncrow_web/pages/analytics/services/energy_consumption_by_phases/energy_consumption_by_phases_service.dart';
|
import 'package:syncrow_web/pages/analytics/services/energy_consumption_by_phases/energy_consumption_by_phases_service.dart';
|
||||||
|
import 'package:syncrow_web/services/api/api_exception.dart';
|
||||||
import 'package:syncrow_web/services/api/http_service.dart';
|
import 'package:syncrow_web/services/api/http_service.dart';
|
||||||
|
|
||||||
final class RemoteEnergyConsumptionByPhasesService
|
final class RemoteEnergyConsumptionByPhasesService
|
||||||
@@ -9,6 +11,8 @@ final class RemoteEnergyConsumptionByPhasesService
|
|||||||
|
|
||||||
final HTTPService _httpService;
|
final HTTPService _httpService;
|
||||||
|
|
||||||
|
static const _defaultErrorMessage = 'Failed to load energy consumption per phase';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<List<PhasesEnergyConsumption>> load(
|
Future<List<PhasesEnergyConsumption>> load(
|
||||||
GetEnergyConsumptionByPhasesParam param,
|
GetEnergyConsumptionByPhasesParam param,
|
||||||
@@ -28,8 +32,15 @@ final class RemoteEnergyConsumptionByPhasesService
|
|||||||
},
|
},
|
||||||
);
|
);
|
||||||
return response;
|
return response;
|
||||||
|
} on DioException catch (e) {
|
||||||
|
final message = e.response?.data as Map<String, dynamic>?;
|
||||||
|
final error = message?['error'] as Map<String, dynamic>?;
|
||||||
|
final errorMessage = error?['error'] as String? ?? '';
|
||||||
|
final formattedErrorMessage = [_defaultErrorMessage, errorMessage].join(': ');
|
||||||
|
throw APIException(formattedErrorMessage);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
throw Exception('Failed to load energy consumption per phase: $e');
|
final formattedErrorMessage = [_defaultErrorMessage, '$e'].join(': ');
|
||||||
|
throw APIException(formattedErrorMessage);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+12
-1
@@ -1,8 +1,10 @@
|
|||||||
|
import 'package:dio/dio.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:syncrow_web/pages/analytics/models/device_energy_data_model.dart';
|
import 'package:syncrow_web/pages/analytics/models/device_energy_data_model.dart';
|
||||||
import 'package:syncrow_web/pages/analytics/models/energy_data_model.dart';
|
import 'package:syncrow_web/pages/analytics/models/energy_data_model.dart';
|
||||||
import 'package:syncrow_web/pages/analytics/params/get_energy_consumption_per_device_param.dart';
|
import 'package:syncrow_web/pages/analytics/params/get_energy_consumption_per_device_param.dart';
|
||||||
import 'package:syncrow_web/pages/analytics/services/energy_consumption_per_device/energy_consumption_per_device_service.dart';
|
import 'package:syncrow_web/pages/analytics/services/energy_consumption_per_device/energy_consumption_per_device_service.dart';
|
||||||
|
import 'package:syncrow_web/services/api/api_exception.dart';
|
||||||
import 'package:syncrow_web/services/api/http_service.dart';
|
import 'package:syncrow_web/services/api/http_service.dart';
|
||||||
|
|
||||||
class RemoteEnergyConsumptionPerDeviceService
|
class RemoteEnergyConsumptionPerDeviceService
|
||||||
@@ -11,6 +13,8 @@ class RemoteEnergyConsumptionPerDeviceService
|
|||||||
|
|
||||||
final HTTPService _httpService;
|
final HTTPService _httpService;
|
||||||
|
|
||||||
|
static const _defaultErrorMessage = 'Failed to load energy consumption per device';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<List<DeviceEnergyDataModel>> load(
|
Future<List<DeviceEnergyDataModel>> load(
|
||||||
GetEnergyConsumptionPerDeviceParam param,
|
GetEnergyConsumptionPerDeviceParam param,
|
||||||
@@ -23,8 +27,15 @@ class RemoteEnergyConsumptionPerDeviceService
|
|||||||
expectedResponseModel: _EnergyConsumptionPerDeviceMapper.map,
|
expectedResponseModel: _EnergyConsumptionPerDeviceMapper.map,
|
||||||
);
|
);
|
||||||
return response;
|
return response;
|
||||||
|
} on DioException catch (e) {
|
||||||
|
final message = e.response?.data as Map<String, dynamic>?;
|
||||||
|
final error = message?['error'] as Map<String, dynamic>?;
|
||||||
|
final errorMessage = error?['error'] as String? ?? '';
|
||||||
|
final formattedErrorMessage = [_defaultErrorMessage, errorMessage].join(': ');
|
||||||
|
throw APIException(formattedErrorMessage);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
throw Exception('Failed to load energy consumption per device: $e');
|
final formattedErrorMessage = [_defaultErrorMessage, '$e'].join(': ');
|
||||||
|
throw APIException(formattedErrorMessage);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
|
import 'package:dio/dio.dart';
|
||||||
import 'package:syncrow_web/pages/analytics/models/occupacy.dart';
|
import 'package:syncrow_web/pages/analytics/models/occupacy.dart';
|
||||||
import 'package:syncrow_web/pages/analytics/params/get_occupancy_param.dart';
|
import 'package:syncrow_web/pages/analytics/params/get_occupancy_param.dart';
|
||||||
import 'package:syncrow_web/pages/analytics/services/occupacy/occupacy_service.dart';
|
import 'package:syncrow_web/pages/analytics/services/occupacy/occupacy_service.dart';
|
||||||
|
import 'package:syncrow_web/services/api/api_exception.dart';
|
||||||
import 'package:syncrow_web/services/api/http_service.dart';
|
import 'package:syncrow_web/services/api/http_service.dart';
|
||||||
|
|
||||||
final class RemoteOccupancyService implements OccupacyService {
|
final class RemoteOccupancyService implements OccupacyService {
|
||||||
@@ -8,6 +10,8 @@ final class RemoteOccupancyService implements OccupacyService {
|
|||||||
|
|
||||||
final HTTPService _httpService;
|
final HTTPService _httpService;
|
||||||
|
|
||||||
|
static const _defaultErrorMessage = 'Failed to load occupancy';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<List<Occupacy>> load(GetOccupancyParam param) async {
|
Future<List<Occupacy>> load(GetOccupancyParam param) async {
|
||||||
try {
|
try {
|
||||||
@@ -25,8 +29,15 @@ final class RemoteOccupancyService implements OccupacyService {
|
|||||||
},
|
},
|
||||||
);
|
);
|
||||||
return response;
|
return response;
|
||||||
|
} on DioException catch (e) {
|
||||||
|
final message = e.response?.data as Map<String, dynamic>?;
|
||||||
|
final error = message?['error'] as Map<String, dynamic>?;
|
||||||
|
final errorMessage = error?['error'] as String? ?? '';
|
||||||
|
final formattedErrorMessage = [_defaultErrorMessage, errorMessage].join(': ');
|
||||||
|
throw APIException(formattedErrorMessage);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
throw Exception('Failed to load energy consumption per phase: $e');
|
final formattedErrorMessage = [_defaultErrorMessage, '$e'].join(': ');
|
||||||
|
throw APIException(formattedErrorMessage);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+12
-1
@@ -1,6 +1,8 @@
|
|||||||
|
import 'package:dio/dio.dart';
|
||||||
import 'package:syncrow_web/pages/analytics/models/occupancy_heat_map_model.dart';
|
import 'package:syncrow_web/pages/analytics/models/occupancy_heat_map_model.dart';
|
||||||
import 'package:syncrow_web/pages/analytics/params/get_occupancy_heat_map_param.dart';
|
import 'package:syncrow_web/pages/analytics/params/get_occupancy_heat_map_param.dart';
|
||||||
import 'package:syncrow_web/pages/analytics/services/occupancy_heat_map/occupancy_heat_map_service.dart';
|
import 'package:syncrow_web/pages/analytics/services/occupancy_heat_map/occupancy_heat_map_service.dart';
|
||||||
|
import 'package:syncrow_web/services/api/api_exception.dart';
|
||||||
import 'package:syncrow_web/services/api/http_service.dart';
|
import 'package:syncrow_web/services/api/http_service.dart';
|
||||||
|
|
||||||
final class RemoteOccupancyHeatMapService implements OccupancyHeatMapService {
|
final class RemoteOccupancyHeatMapService implements OccupancyHeatMapService {
|
||||||
@@ -8,6 +10,8 @@ final class RemoteOccupancyHeatMapService implements OccupancyHeatMapService {
|
|||||||
|
|
||||||
final HTTPService _httpService;
|
final HTTPService _httpService;
|
||||||
|
|
||||||
|
static const _defaultErrorMessage = 'Failed to load occupancy heat map';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<List<OccupancyHeatMapModel>> load(GetOccupancyHeatMapParam param) async {
|
Future<List<OccupancyHeatMapModel>> load(GetOccupancyHeatMapParam param) async {
|
||||||
try {
|
try {
|
||||||
@@ -28,8 +32,15 @@ final class RemoteOccupancyHeatMapService implements OccupancyHeatMapService {
|
|||||||
);
|
);
|
||||||
|
|
||||||
return response;
|
return response;
|
||||||
|
} on DioException catch (e) {
|
||||||
|
final message = e.response?.data as Map<String, dynamic>?;
|
||||||
|
final error = message?['error'] as Map<String, dynamic>?;
|
||||||
|
final errorMessage = error?['error'] as String? ?? '';
|
||||||
|
final formattedErrorMessage = [_defaultErrorMessage, errorMessage].join(': ');
|
||||||
|
throw APIException(formattedErrorMessage);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
throw Exception('Failed to load total energy consumption:');
|
final formattedErrorMessage = [_defaultErrorMessage, '$e'].join(': ');
|
||||||
|
throw APIException(formattedErrorMessage);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
|
import 'package:dio/dio.dart';
|
||||||
import 'package:syncrow_web/pages/analytics/services/power_clamp_info/power_clamp_info_service.dart';
|
import 'package:syncrow_web/pages/analytics/services/power_clamp_info/power_clamp_info_service.dart';
|
||||||
import 'package:syncrow_web/pages/device_managment/power_clamp/models/power_clamp_model.dart';
|
import 'package:syncrow_web/pages/device_managment/power_clamp/models/power_clamp_model.dart';
|
||||||
|
import 'package:syncrow_web/services/api/api_exception.dart';
|
||||||
import 'package:syncrow_web/services/api/http_service.dart';
|
import 'package:syncrow_web/services/api/http_service.dart';
|
||||||
|
|
||||||
final class RemotePowerClampInfoService implements PowerClampInfoService {
|
final class RemotePowerClampInfoService implements PowerClampInfoService {
|
||||||
@@ -7,6 +9,8 @@ final class RemotePowerClampInfoService implements PowerClampInfoService {
|
|||||||
|
|
||||||
final HTTPService _httpService;
|
final HTTPService _httpService;
|
||||||
|
|
||||||
|
static const _defaultErrorMessage = 'Failed to fetch power clamp info';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<PowerClampModel> getInfo(String deviceId) async {
|
Future<PowerClampModel> getInfo(String deviceId) async {
|
||||||
try {
|
try {
|
||||||
@@ -20,8 +24,15 @@ final class RemotePowerClampInfoService implements PowerClampInfoService {
|
|||||||
},
|
},
|
||||||
);
|
);
|
||||||
return response;
|
return response;
|
||||||
|
} on DioException catch (e) {
|
||||||
|
final message = e.response?.data as Map<String, dynamic>?;
|
||||||
|
final error = message?['error'] as Map<String, dynamic>?;
|
||||||
|
final errorMessage = error?['error'] as String? ?? '';
|
||||||
|
final formattedErrorMessage = [_defaultErrorMessage, errorMessage].join(': ');
|
||||||
|
throw APIException(formattedErrorMessage);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
throw Exception('Failed to fetch power clamp info: $e');
|
final formattedErrorMessage = [_defaultErrorMessage, '$e'].join(': ');
|
||||||
|
throw APIException(formattedErrorMessage);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+12
-1
@@ -1,6 +1,8 @@
|
|||||||
|
import 'package:dio/dio.dart';
|
||||||
import 'package:syncrow_web/pages/analytics/models/energy_data_model.dart';
|
import 'package:syncrow_web/pages/analytics/models/energy_data_model.dart';
|
||||||
import 'package:syncrow_web/pages/analytics/params/get_total_energy_consumption_param.dart';
|
import 'package:syncrow_web/pages/analytics/params/get_total_energy_consumption_param.dart';
|
||||||
import 'package:syncrow_web/pages/analytics/services/total_energy_consumption/total_energy_consumption_service.dart';
|
import 'package:syncrow_web/pages/analytics/services/total_energy_consumption/total_energy_consumption_service.dart';
|
||||||
|
import 'package:syncrow_web/services/api/api_exception.dart';
|
||||||
import 'package:syncrow_web/services/api/http_service.dart';
|
import 'package:syncrow_web/services/api/http_service.dart';
|
||||||
|
|
||||||
class RemoteTotalEnergyConsumptionService implements TotalEnergyConsumptionService {
|
class RemoteTotalEnergyConsumptionService implements TotalEnergyConsumptionService {
|
||||||
@@ -8,6 +10,8 @@ class RemoteTotalEnergyConsumptionService implements TotalEnergyConsumptionServi
|
|||||||
|
|
||||||
final HTTPService _httpService;
|
final HTTPService _httpService;
|
||||||
|
|
||||||
|
static const _defaultErrorMessage = 'Failed to load total energy consumption';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<List<EnergyDataModel>> load(
|
Future<List<EnergyDataModel>> load(
|
||||||
GetTotalEnergyConsumptionParam param,
|
GetTotalEnergyConsumptionParam param,
|
||||||
@@ -21,8 +25,15 @@ class RemoteTotalEnergyConsumptionService implements TotalEnergyConsumptionServi
|
|||||||
);
|
);
|
||||||
|
|
||||||
return response;
|
return response;
|
||||||
|
} on DioException catch (e) {
|
||||||
|
final message = e.response?.data as Map<String, dynamic>?;
|
||||||
|
final error = message?['error'] as Map<String, dynamic>?;
|
||||||
|
final errorMessage = error?['error'] as String? ?? '';
|
||||||
|
final formattedErrorMessage = [_defaultErrorMessage, errorMessage].join(': ');
|
||||||
|
throw APIException(formattedErrorMessage);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
throw Exception('Failed to load total energy consumption: $e');
|
final formattedErrorMessage = [_defaultErrorMessage, '$e'].join(': ');
|
||||||
|
throw APIException(formattedErrorMessage);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,10 +1,12 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
|
import 'package:flutter_svg/svg.dart';
|
||||||
import 'package:syncrow_web/pages/device_managment/all_devices/models/devices_model.dart';
|
import 'package:syncrow_web/pages/device_managment/all_devices/models/devices_model.dart';
|
||||||
import 'package:syncrow_web/pages/device_managment/device_setting/settings_model/device_info_model.dart';
|
import 'package:syncrow_web/pages/device_managment/device_setting/settings_model/device_info_model.dart';
|
||||||
import 'package:syncrow_web/pages/device_managment/device_setting/settings_model/sub_space_model.dart';
|
import 'package:syncrow_web/pages/device_managment/device_setting/settings_model/sub_space_model.dart';
|
||||||
import 'package:syncrow_web/pages/device_managment/device_setting/sub_space_dialog.dart';
|
import 'package:syncrow_web/pages/device_managment/device_setting/sub_space_dialog.dart';
|
||||||
import 'package:syncrow_web/utils/color_manager.dart';
|
import 'package:syncrow_web/utils/color_manager.dart';
|
||||||
|
import 'package:syncrow_web/utils/constants/assets.dart';
|
||||||
import 'package:syncrow_web/utils/extension/build_context_x.dart';
|
import 'package:syncrow_web/utils/extension/build_context_x.dart';
|
||||||
import 'package:syncrow_web/web_layout/default_container.dart';
|
import 'package:syncrow_web/web_layout/default_container.dart';
|
||||||
|
|
||||||
@@ -28,7 +30,7 @@ class DeviceManagementContent extends StatelessWidget {
|
|||||||
Widget? trailing,
|
Widget? trailing,
|
||||||
required Color? valueColor}) {
|
required Color? valueColor}) {
|
||||||
return Padding(
|
return Padding(
|
||||||
padding: const EdgeInsets.symmetric(vertical: 6.0),
|
padding: const EdgeInsets.symmetric(vertical: 10.0, horizontal: 10),
|
||||||
child: Row(
|
child: Row(
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
children: [
|
children: [
|
||||||
@@ -39,6 +41,7 @@ class DeviceManagementContent extends StatelessWidget {
|
|||||||
color: ColorsManager.grayColor,
|
color: ColorsManager.grayColor,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
const SizedBox(width: 15),
|
||||||
Expanded(
|
Expanded(
|
||||||
child: Text(
|
child: Text(
|
||||||
value,
|
value,
|
||||||
@@ -48,7 +51,7 @@ class DeviceManagementContent extends StatelessWidget {
|
|||||||
overflow: TextOverflow.ellipsis,
|
overflow: TextOverflow.ellipsis,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
const SizedBox(width: 8),
|
const SizedBox(width: 12),
|
||||||
trailing ?? const SizedBox.shrink(),
|
trailing ?? const SizedBox.shrink(),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
@@ -75,13 +78,13 @@ class DeviceManagementContent extends StatelessWidget {
|
|||||||
child: infoRow(
|
child: infoRow(
|
||||||
label: 'Sub-Space:',
|
label: 'Sub-Space:',
|
||||||
value: deviceInfo.subspace.subspaceName,
|
value: deviceInfo.subspace.subspaceName,
|
||||||
valueColor: ColorsManager.textGray,
|
valueColor: ColorsManager.blackColor,
|
||||||
trailing: const Icon(
|
trailing: SvgPicture.asset(
|
||||||
Icons.arrow_forward_ios,
|
Assets.arrowDown,
|
||||||
size: 16,
|
width: 10,
|
||||||
|
height: 10,
|
||||||
color: ColorsManager.greyColor,
|
color: ColorsManager.greyColor,
|
||||||
),
|
)),
|
||||||
),
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
const Divider(color: ColorsManager.dividerColor),
|
const Divider(color: ColorsManager.dividerColor),
|
||||||
@@ -104,7 +107,7 @@ class DeviceManagementContent extends StatelessWidget {
|
|||||||
},
|
},
|
||||||
child: const Icon(
|
child: const Icon(
|
||||||
Icons.copy,
|
Icons.copy,
|
||||||
size: 16,
|
size: 15,
|
||||||
color: ColorsManager.greyColor,
|
color: ColorsManager.greyColor,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -51,8 +51,7 @@ class DeviceSettingsPanel extends StatelessWidget {
|
|||||||
Container(
|
Container(
|
||||||
width: MediaQuery.of(context).size.width * 0.3,
|
width: MediaQuery.of(context).size.width * 0.3,
|
||||||
color: ColorsManager.grey25,
|
color: ColorsManager.grey25,
|
||||||
padding: const EdgeInsets.symmetric(
|
padding: const EdgeInsets.all(10),
|
||||||
horizontal: 20, vertical: 24),
|
|
||||||
child: ListView(
|
child: ListView(
|
||||||
children: [
|
children: [
|
||||||
Row(
|
Row(
|
||||||
@@ -70,22 +69,26 @@ class DeviceSettingsPanel extends StatelessWidget {
|
|||||||
children: [
|
children: [
|
||||||
Text(
|
Text(
|
||||||
'Device Settings',
|
'Device Settings',
|
||||||
style:
|
style: context.theme.textTheme.titleLarge!
|
||||||
context.theme.textTheme.titleLarge!.copyWith(
|
.copyWith(
|
||||||
fontWeight: FontWeight.bold,
|
fontWeight: FontWeight.w700,
|
||||||
color: ColorsManager.primaryColor,
|
color: ColorsManager.vividBlue
|
||||||
),
|
.withOpacity(0.7),
|
||||||
|
fontSize: 24),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
const SizedBox(height: 24),
|
const SizedBox(height: 24),
|
||||||
DefaultContainer(
|
DefaultContainer(
|
||||||
|
borderRadius: BorderRadius.circular(15),
|
||||||
child: Row(
|
child: Row(
|
||||||
children: [
|
children: [
|
||||||
CircleAvatar(
|
Padding(
|
||||||
radius: 40,
|
padding: const EdgeInsets.only(left: 15),
|
||||||
|
child: CircleAvatar(
|
||||||
|
radius: 38,
|
||||||
backgroundColor:
|
backgroundColor:
|
||||||
const Color.fromARGB(177, 213, 213, 213),
|
ColorsManager.grayBorder.withOpacity(0.5),
|
||||||
child: CircleAvatar(
|
child: CircleAvatar(
|
||||||
backgroundColor: ColorsManager.whiteColors,
|
backgroundColor: ColorsManager.whiteColors,
|
||||||
radius: 36,
|
radius: 36,
|
||||||
@@ -95,12 +98,14 @@ class DeviceSettingsPanel extends StatelessWidget {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
const SizedBox(width: 12),
|
),
|
||||||
|
const SizedBox(width: 25),
|
||||||
Expanded(
|
Expanded(
|
||||||
child: Column(
|
child: Column(
|
||||||
mainAxisAlignment: MainAxisAlignment.start,
|
mainAxisAlignment: MainAxisAlignment.start,
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
|
const SizedBox(height: 15),
|
||||||
Text(
|
Text(
|
||||||
'Device Name:',
|
'Device Name:',
|
||||||
style: context.textTheme.bodyMedium!
|
style: context.textTheme.bodyMedium!
|
||||||
@@ -108,10 +113,19 @@ class DeviceSettingsPanel extends StatelessWidget {
|
|||||||
color: ColorsManager.grayColor,
|
color: ColorsManager.grayColor,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
TextFormField(
|
SizedBox(
|
||||||
|
height: 35,
|
||||||
|
child: Row(
|
||||||
|
children: [
|
||||||
|
SizedBox(
|
||||||
|
height: 50,
|
||||||
|
width: 190,
|
||||||
|
child: TextFormField(
|
||||||
|
scrollPadding: EdgeInsets.zero,
|
||||||
maxLength: 30,
|
maxLength: 30,
|
||||||
style: const TextStyle(
|
style: const TextStyle(
|
||||||
color: ColorsManager.blackColor,
|
color: ColorsManager.blackColor,
|
||||||
|
fontSize: 16,
|
||||||
),
|
),
|
||||||
textAlign: TextAlign.start,
|
textAlign: TextAlign.start,
|
||||||
focusNode: _bloc.focusNode,
|
focusNode: _bloc.focusNode,
|
||||||
@@ -121,37 +135,57 @@ class DeviceSettingsPanel extends StatelessWidget {
|
|||||||
_bloc.add(const ChangeNameEvent(
|
_bloc.add(const ChangeNameEvent(
|
||||||
value: false));
|
value: false));
|
||||||
},
|
},
|
||||||
decoration: const InputDecoration(
|
decoration: InputDecoration(
|
||||||
|
isDense: true,
|
||||||
|
contentPadding: EdgeInsets.zero,
|
||||||
border: InputBorder.none,
|
border: InputBorder.none,
|
||||||
fillColor: Colors.white10,
|
fillColor: Colors.white10,
|
||||||
counterText: '',
|
counterText: '',
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
),
|
||||||
|
Column(
|
||||||
|
children: [
|
||||||
|
SizedBox(
|
||||||
|
width: 15,
|
||||||
|
height: 25,
|
||||||
|
child: Visibility(
|
||||||
|
visible:
|
||||||
|
_bloc.editName != true,
|
||||||
|
replacement: const SizedBox(),
|
||||||
|
child: InkWell(
|
||||||
|
onTap: () {
|
||||||
|
_bloc.add(
|
||||||
|
const ChangeNameEvent(
|
||||||
|
value: true));
|
||||||
|
},
|
||||||
|
child: SvgPicture.asset(
|
||||||
|
Assets
|
||||||
|
.editNameIconSettings,
|
||||||
|
color: ColorsManager
|
||||||
|
.lightGrayBorderColor,
|
||||||
|
height: 15,
|
||||||
|
width: 15,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
const SizedBox(width: 8),
|
],
|
||||||
Visibility(
|
|
||||||
visible: _bloc.editName != true,
|
|
||||||
replacement: const SizedBox(),
|
|
||||||
child: GestureDetector(
|
|
||||||
onTap: () {
|
|
||||||
_bloc.add(
|
|
||||||
const ChangeNameEvent(value: true));
|
|
||||||
},
|
|
||||||
child: SvgPicture.asset(
|
|
||||||
Assets.editNameIconSettings,
|
|
||||||
color: ColorsManager.grayColor,
|
|
||||||
height: 20,
|
|
||||||
width: 20,
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
)
|
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
const SizedBox(height: 32),
|
const SizedBox(height: 32),
|
||||||
Text('Device Management', style: sectionTitle),
|
Padding(
|
||||||
|
padding: const EdgeInsets.only(left: 10),
|
||||||
|
child: Text('Device Management', style: sectionTitle),
|
||||||
|
),
|
||||||
DeviceManagementContent(
|
DeviceManagementContent(
|
||||||
device: device,
|
device: device,
|
||||||
subSpaces: subSpaces.cast<SubSpaceModel>(),
|
subSpaces: subSpaces.cast<SubSpaceModel>(),
|
||||||
|
|||||||
@@ -61,6 +61,7 @@ dependencies:
|
|||||||
firebase_crashlytics: ^4.3.2
|
firebase_crashlytics: ^4.3.2
|
||||||
firebase_database: ^11.3.2
|
firebase_database: ^11.3.2
|
||||||
bloc: ^9.0.0
|
bloc: ^9.0.0
|
||||||
|
geocoding: ^4.0.0
|
||||||
gauge_indicator: ^0.4.3
|
gauge_indicator: ^0.4.3
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user