From 1622082f5c36e3259b86f7b0339d79549ae12c81 Mon Sep 17 00:00:00 2001 From: Syaroful Date: Thu, 24 Oct 2024 14:09:30 +0700 Subject: [PATCH 01/19] refactor: change relay endpoint --- .../lib/core/extension/extention.dart | 4 + .../lib/data/model/relay_response.dart | 18 ++-- .../lib/domain/service/app_service.dart | 10 +-- .../lib/domain/service/firebase_api.dart | 6 -- .../control/provider/control_provider.dart | 52 +----------- .../features/control/view/control_screen.dart | 15 ++-- .../widgets/list_data_from_censor_dht.dart | 7 +- .../widgets/list_data_from_censor_npk1.dart | 83 ++++++++++--------- .../widgets/list_data_from_censor_npk2.dart | 82 +++++++++--------- 9 files changed, 116 insertions(+), 161 deletions(-) diff --git a/agrilink_vocpro/lib/core/extension/extention.dart b/agrilink_vocpro/lib/core/extension/extention.dart index a19384f..cb84c9e 100644 --- a/agrilink_vocpro/lib/core/extension/extention.dart +++ b/agrilink_vocpro/lib/core/extension/extention.dart @@ -16,6 +16,10 @@ String dateFormatterShort(String date) { return formatter.format(dateTime); } +String setTwoDigitAfterComma(double number) { + return number.toStringAsFixed(2); +} + String getGreeting(String time) { DateTime parsedTime = DateTime.parse(time); int hour = parsedTime.hour; diff --git a/agrilink_vocpro/lib/data/model/relay_response.dart b/agrilink_vocpro/lib/data/model/relay_response.dart index bdae310..a9f09e8 100644 --- a/agrilink_vocpro/lib/data/model/relay_response.dart +++ b/agrilink_vocpro/lib/data/model/relay_response.dart @@ -1,15 +1,15 @@ class RelayResponse { bool? success; - List? data; + List? data; RelayResponse({this.success, this.data}); RelayResponse.fromJson(Map json) { success = json['success']; if (json['data'] != null) { - data = []; + data = []; json['data'].forEach((v) { - data!.add(Relay.fromJson(v)); + data!.add(Data.fromJson(v)); }); } } @@ -24,32 +24,29 @@ class RelayResponse { } } -class Relay { +class Data { int? id; int? number; String? enabledAt; String? disabledAt; bool? currentStatus; String? createdAt; - String? updatedAt; - Relay( + Data( {this.id, this.number, this.enabledAt, this.disabledAt, this.currentStatus, - this.createdAt, - this.updatedAt}); + this.createdAt}); - Relay.fromJson(Map json) { + Data.fromJson(Map json) { id = json['id']; number = json['number']; enabledAt = json['enabled_at']; disabledAt = json['disabled_at']; currentStatus = json['current_status']; createdAt = json['created_at']; - updatedAt = json['updated_at']; } Map toJson() { @@ -60,7 +57,6 @@ class Relay { data['disabled_at'] = disabledAt; data['current_status'] = currentStatus; data['created_at'] = createdAt; - data['updated_at'] = updatedAt; return data; } } diff --git a/agrilink_vocpro/lib/domain/service/app_service.dart b/agrilink_vocpro/lib/domain/service/app_service.dart index 1f17a61..58a3017 100644 --- a/agrilink_vocpro/lib/domain/service/app_service.dart +++ b/agrilink_vocpro/lib/domain/service/app_service.dart @@ -107,14 +107,14 @@ class AppService { final String auth = 'Bearer ${pref.getString('token')}'; try { await Future.delayed(const Duration(seconds: 3)); - final result = await _dioWithoutInterceptor.get( - '/api/get-relay', + final response = await _dioWithoutInterceptor.get( + '/api/relay/get-relay', options: Options( headers: {'Authorization': auth}, ), ); - if (result.statusCode == 200) { - final data = RelayResponse.fromJson(result.data); + if (response.statusCode == 200) { + final data = RelayResponse.fromJson(response.data); return data; } else { throw Exception('Failed to load data'); @@ -134,7 +134,7 @@ class AppService { try { final response = await _dioWithoutInterceptor.post( - '/api/set-relay', + '/api/relay/set-relay', data: { 'id': relayNumber, 'state': state, diff --git a/agrilink_vocpro/lib/domain/service/firebase_api.dart b/agrilink_vocpro/lib/domain/service/firebase_api.dart index 024e72b..d2891bc 100644 --- a/agrilink_vocpro/lib/domain/service/firebase_api.dart +++ b/agrilink_vocpro/lib/domain/service/firebase_api.dart @@ -1,5 +1,4 @@ import 'package:firebase_messaging/firebase_messaging.dart'; -import 'package:flutter/foundation.dart'; class FirebaseApi { final _firebaseMessaging = FirebaseMessaging.instance; @@ -11,10 +10,5 @@ class FirebaseApi { provisional: false, sound: true, ); - - final fCMToken = await _firebaseMessaging.getToken(); - if (kDebugMode) { - print('FCM Token: $fCMToken'); - } } } diff --git a/agrilink_vocpro/lib/features/control/provider/control_provider.dart b/agrilink_vocpro/lib/features/control/provider/control_provider.dart index 378a2a3..9361162 100644 --- a/agrilink_vocpro/lib/features/control/provider/control_provider.dart +++ b/agrilink_vocpro/lib/features/control/provider/control_provider.dart @@ -15,39 +15,8 @@ class ControlProvider extends ChangeNotifier { getRelayStatus(); } - // ResultState mqttState = ResultState.initial; - // ResultState subscribeState = ResultState.initial; - ResultState relayState = ResultState.initial; - // Future connectMqtt() async { - // mqttState = ResultState.loading; - // subscribeState = ResultState.loading; - // notifyListeners(); - - // try { - // final result = await _mqttService.setupMqtt(); - // if (result == ResultState.hasData) { - // mqttState = result; - // final result2 = await _mqttService.subscribeToRelayStatus(); - // // if (result2 == true) { - // // subscribeState = ResultState.hasData; - // // _control_1 = true; - // // } else { - // // subscribeState = ResultState.hasData; - // // _control_1 = false; - // // } - // } else { - // mqttState = ResultState.error; - // } - // } catch (e) { - // mqttState = ResultState.error; - // print(e); - // } - - // notifyListeners(); - // } - Future getRelayStatus() async { relayState = ResultState.loading; notifyListeners(); @@ -75,7 +44,7 @@ class ControlProvider extends ChangeNotifier { relayState = ResultState.error; notifyListeners(); if (kDebugMode) { - print(e); + print('Error Getting Relay Status: $e'); } } } @@ -122,23 +91,4 @@ class ControlProvider extends ChangeNotifier { _control_2 = value; notifyListeners(); } - - // Future publishMessage(String topic, String message) async { - // try { - // final result = await _mqttService.publishMessage(topic, message); - // return result; - // } catch (e) { - // print(e); - // rethrow; - // } - // } - - // Future subscribeToTopic(String topic) async { - // try { - // await _mqttService.subscribeToTopic(topic); - // } catch (e) { - // print(e); - // rethrow; - // } - // } } diff --git a/agrilink_vocpro/lib/features/control/view/control_screen.dart b/agrilink_vocpro/lib/features/control/view/control_screen.dart index 2489d8a..e6eedbd 100644 --- a/agrilink_vocpro/lib/features/control/view/control_screen.dart +++ b/agrilink_vocpro/lib/features/control/view/control_screen.dart @@ -72,7 +72,7 @@ class ControlScreen extends StatelessWidget { ), children: [ ControlButtonWidget( - title: 'Katup Air', + title: 'Katup Nutrisi', subtitle: 'Relay 1', isActive: provider.control_1, onTap: () async { @@ -85,13 +85,16 @@ class ControlScreen extends StatelessWidget { }, ), ControlButtonWidget( - title: 'Lampu Utama', + title: 'Katup Air', subtitle: 'Relay 2', isActive: provider.control_2, - onTap: () { - provider.control_2 != true - ? provider.switchControl2(true) - : provider.switchControl2(false); + onTap: () async { + final result = provider.control_2 != true + ? await provider.switchRelay(2, true) + : await provider.switchRelay(2, false); + result == true + ? provider.switchControl2(!provider.control_2) + : provider.switchControl2(provider.control_2); }, ), ], diff --git a/agrilink_vocpro/lib/features/home/widgets/list_data_from_censor_dht.dart b/agrilink_vocpro/lib/features/home/widgets/list_data_from_censor_dht.dart index 740b38d..b4517e7 100644 --- a/agrilink_vocpro/lib/features/home/widgets/list_data_from_censor_dht.dart +++ b/agrilink_vocpro/lib/features/home/widgets/list_data_from_censor_dht.dart @@ -1,4 +1,5 @@ import 'package:agrilink_vocpro/core/constant/app_color.dart'; +import 'package:agrilink_vocpro/core/extension/extention.dart'; import 'package:agrilink_vocpro/core/route/app_route.dart'; import 'package:agrilink_vocpro/core/state/result_state.dart'; import 'package:agrilink_vocpro/features/home/provider/home_provider.dart'; @@ -50,12 +51,10 @@ class ListDataFromCensorDht extends StatelessWidget { DataDisplayerWidget( title: 'Humidity', subtitle: 'kelembaban udara', - value: provider.dhtHumidity.toString(), + value: setTwoDigitAfterComma(provider.dhtHumidity.toDouble()), unit: '%', icon: BootstrapIcons.droplet_half, - textColor: Colors.white, - color: AppColor.secondary, - iconColor: Colors.white, + color: Colors.white, censorIdentifier: 'NPK 1', onTap: () async { await context diff --git a/agrilink_vocpro/lib/features/home/widgets/list_data_from_censor_npk1.dart b/agrilink_vocpro/lib/features/home/widgets/list_data_from_censor_npk1.dart index dce8afc..dc2f4d3 100644 --- a/agrilink_vocpro/lib/features/home/widgets/list_data_from_censor_npk1.dart +++ b/agrilink_vocpro/lib/features/home/widgets/list_data_from_censor_npk1.dart @@ -1,4 +1,5 @@ import 'package:agrilink_vocpro/core/constant/app_color.dart'; +import 'package:agrilink_vocpro/core/extension/extention.dart'; import 'package:agrilink_vocpro/core/route/app_route.dart'; import 'package:agrilink_vocpro/core/state/result_state.dart'; import 'package:agrilink_vocpro/features/home/provider/home_provider.dart'; @@ -46,15 +47,55 @@ class ListDataFromCensorNpk1 extends StatelessWidget { childAspectRatio: 0.9, ), children: [ + DataDisplayerWidget( + title: 'Nitrogen', + subtitle: 'Kadar Nitrogen', + value: provider.npk1SoilNitrogen.toString(), + unit: 'mg/L', + icon: CupertinoIcons.eyedropper, + textColor: Colors.white, + color: AppColor.secondary, + iconColor: Colors.white, + onTap: () async { + await context.push( + '${AppRoute.nitrogen}/${provider.npk2SoilNitrogen}/${provider.npk1SoilNitrogen}'); + }, + ), + DataDisplayerWidget( + title: 'Phosphorus', + subtitle: 'Kadar Fosfor', + value: provider.npk1SoilPhosphorus.toString(), + unit: 'mg/L', + icon: CupertinoIcons.eyedropper, + textColor: Colors.white, + color: AppColor.secondary, + iconColor: Colors.white, + onTap: () async { + await context.push( + '${AppRoute.phosphorus}/${provider.npk1SoilPhosphorus}/${provider.npk2SoilPhosphorus}'); + }, + ), + DataDisplayerWidget( + title: 'Kalium', + subtitle: 'Kadar kalium', + value: provider.npk1SoilPotassium.toString(), + unit: 'mg/L', + icon: CupertinoIcons.eyedropper, + textColor: Colors.white, + color: AppColor.secondary, + iconColor: Colors.white, + onTap: () async { + await context.push( + '${AppRoute.potassium}/${provider.npk1SoilPotassium}/${provider.npk2SoilPotassium}'); + }, + ), DataDisplayerWidget( title: 'Temperature', subtitle: 'Suhu tanah', value: provider.npk1Temperature.toString(), unit: '°C', icon: BootstrapIcons.thermometer_half, - textColor: Colors.white, - color: AppColor.secondary, - iconColor: Colors.white, + color: Colors.white, censorIdentifier: censorIdentifier, onTap: () async { await context.push( @@ -100,42 +141,6 @@ class ListDataFromCensorNpk1 extends StatelessWidget { '${AppRoute.conductivity}/${provider.npk1SoilEc}/${provider.npk2SoilEc}'); }, ), - DataDisplayerWidget( - title: 'Nitrogen', - subtitle: 'Kadar Nitrogen', - value: provider.npk1SoilNitrogen.toString(), - unit: 'ppm', - icon: CupertinoIcons.eyedropper, - color: Colors.white, - onTap: () async { - await context.push( - '${AppRoute.nitrogen}/${provider.npk2SoilNitrogen}/${provider.npk1SoilNitrogen}'); - }, - ), - DataDisplayerWidget( - title: 'Potassium', - subtitle: 'Kadar kalium', - value: provider.npk1SoilPotassium.toString(), - unit: 'ppm', - icon: CupertinoIcons.eyedropper, - color: Colors.white, - onTap: () async { - await context.push( - '${AppRoute.potassium}/${provider.npk1SoilPotassium}/${provider.npk2SoilPotassium}'); - }, - ), - DataDisplayerWidget( - title: 'Phosphorus', - subtitle: 'Kadar Fosfor', - value: provider.npk1SoilPhosphorus.toString(), - unit: 'ppm', - icon: CupertinoIcons.eyedropper, - color: Colors.white, - onTap: () async { - await context.push( - '${AppRoute.phosphorus}/${provider.npk1SoilPhosphorus}/${provider.npk2SoilPhosphorus}'); - }, - ), ], ); case ResultState.noData: diff --git a/agrilink_vocpro/lib/features/home/widgets/list_data_from_censor_npk2.dart b/agrilink_vocpro/lib/features/home/widgets/list_data_from_censor_npk2.dart index eae8708..5905e9e 100644 --- a/agrilink_vocpro/lib/features/home/widgets/list_data_from_censor_npk2.dart +++ b/agrilink_vocpro/lib/features/home/widgets/list_data_from_censor_npk2.dart @@ -46,15 +46,55 @@ class ListDataFromCensorNpk2 extends StatelessWidget { childAspectRatio: 0.9, ), children: [ + DataDisplayerWidget( + title: 'Nitrogen', + subtitle: 'Kadar Nitrogen', + value: provider.npk2SoilNitrogen.toString(), + unit: 'mg/L', + icon: CupertinoIcons.eyedropper, + textColor: Colors.white, + color: AppColor.secondary, + iconColor: Colors.white, + onTap: () async { + await context.push( + '${AppRoute.nitrogen}/${provider.npk2SoilNitrogen}/${provider.npk1SoilNitrogen}'); + }, + ), + DataDisplayerWidget( + title: 'Phosphorus', + subtitle: 'Kadar Fosfor', + value: provider.npk2SoilPhosphorus.toString(), + unit: 'mg/L', + icon: CupertinoIcons.eyedropper, + textColor: Colors.white, + color: AppColor.secondary, + iconColor: Colors.white, + onTap: () async { + await context.push( + '${AppRoute.phosphorus}/${provider.npk1SoilPhosphorus}/${provider.npk2SoilPhosphorus}'); + }, + ), + DataDisplayerWidget( + title: 'Kalium', + subtitle: 'Kadar kalium', + value: provider.npk2SoilPotassium.toString(), + unit: 'mg/L', + icon: CupertinoIcons.eyedropper, + textColor: Colors.white, + color: AppColor.secondary, + iconColor: Colors.white, + onTap: () async { + await context.push( + '${AppRoute.potassium}/${provider.npk1SoilPotassium}/${provider.npk2SoilPotassium}'); + }, + ), DataDisplayerWidget( title: 'Temperature', subtitle: 'Suhu tanah', value: provider.npk2Temperature.toString(), unit: '°C', icon: BootstrapIcons.thermometer_half, - textColor: Colors.white, - color: AppColor.secondary, - iconColor: Colors.white, + color: Colors.white, censorIdentifier: censorIdentifier, onTap: () async { await context.push( @@ -100,42 +140,6 @@ class ListDataFromCensorNpk2 extends StatelessWidget { '${AppRoute.conductivity}/${provider.npk1SoilEc}/${provider.npk2SoilEc}'); }, ), - DataDisplayerWidget( - title: 'Nitrogen', - subtitle: 'Kadar Nitrogen', - value: provider.npk2SoilNitrogen.toString(), - unit: 'ppm', - icon: CupertinoIcons.eyedropper, - color: Colors.white, - onTap: () async { - await context.push( - '${AppRoute.nitrogen}/${provider.npk2SoilNitrogen}/${provider.npk1SoilNitrogen}'); - }, - ), - DataDisplayerWidget( - title: 'Potassium', - subtitle: 'Kadar kalium', - value: provider.npk2SoilPotassium.toString(), - unit: 'ppm', - icon: CupertinoIcons.eyedropper, - color: Colors.white, - onTap: () async { - await context.push( - '${AppRoute.potassium}/${provider.npk1SoilPotassium}/${provider.npk2SoilPotassium}'); - }, - ), - DataDisplayerWidget( - title: 'Phosphorus', - subtitle: 'Kadar Fosfor', - value: provider.npk2SoilPhosphorus.toString(), - unit: 'ppm', - icon: CupertinoIcons.eyedropper, - color: Colors.white, - onTap: () async { - await context.push( - '${AppRoute.phosphorus}/${provider.npk1SoilPhosphorus}/${provider.npk2SoilPhosphorus}'); - }, - ), ], ); case ResultState.noData: -- 2.43.0 From 9b6131dd347935f1ac5d6ebb2606273d5c32487c Mon Sep 17 00:00:00 2001 From: Syaroful Date: Sat, 2 Nov 2024 05:52:43 +0700 Subject: [PATCH 02/19] refactor: change endpoint --- .../android/app/src/main/AndroidManifest.xml | 16 ++++++++-------- .../lib/core/constant/app_constant.dart | 10 ++++++++-- .../lib/features/auth/view/login_screen.dart | 10 +++++----- .../features/home/provider/home_provider.dart | 2 +- .../home/widgets/list_data_from_censor_dht.dart | 1 - .../home/widgets/list_data_from_censor_npk1.dart | 1 - 6 files changed, 22 insertions(+), 18 deletions(-) diff --git a/agrilink_vocpro/android/app/src/main/AndroidManifest.xml b/agrilink_vocpro/android/app/src/main/AndroidManifest.xml index 2088e2f..c15afda 100644 --- a/agrilink_vocpro/android/app/src/main/AndroidManifest.xml +++ b/agrilink_vocpro/android/app/src/main/AndroidManifest.xml @@ -21,12 +21,12 @@ while the Flutter UI initializes. After that, this theme continues to determine the Window background behind the Flutter UI. --> + android:name="io.flutter.embedding.android.NormalTheme" + android:resource="@style/NormalTheme" + /> - - + + - - + + - + \ No newline at end of file diff --git a/agrilink_vocpro/lib/core/constant/app_constant.dart b/agrilink_vocpro/lib/core/constant/app_constant.dart index e39365c..3c93688 100644 --- a/agrilink_vocpro/lib/core/constant/app_constant.dart +++ b/agrilink_vocpro/lib/core/constant/app_constant.dart @@ -2,14 +2,20 @@ class AppConstant { static const String appName = 'Kebun Pintar'; static const String appVersion = '1.0.0'; - static const String baseUrl = 'https://jx027dj4-3333.asse.devtunnels.ms'; + static const String baseUrl = 'http://54.196.58.97:3333'; static const String mqttServer = 'armadillo.rmq.cloudamqp.com'; static const String mqttUsername = 'obyskxhx:obyskxhx'; static const String mqttPassword = 'Fe_3_tBuwmc8vMMqT2hYiboTsBlBmPz1'; static const String soilTempInfo = - 'Suhu tanah mengacu pada suhu tanah di permukaan atau pada kedalaman tertentu, yang berperan penting dalam pertumbuhan tanaman dan proses pertanian. Suhu ini memengaruhi perkecambahan benih, aktivitas akar, serta penyerapan air dan nutrisi, yang semuanya esensial bagi perkembangan tanaman. Selain itu, suhu tanah juga memengaruhi aktivitas mikroorganisme yang berkontribusi pada kesuburan tanah. Dalam pertanian pintar, sensor suhu tanah sering digunakan untuk memantau dan mengoptimalkan kondisi tanah, memastikan tanaman tumbuh dalam rentang suhu yang ideal.'; + 'Suhu tanah mengacu pada suhu tanah di permukaan atau pada kedalaman tertentu, ' + 'yang berperan penting dalam pertumbuhan tanaman dan proses pertanian. ' + 'Suhu ini memengaruhi perkecambahan benih, aktivitas akar, serta penyerapan air dan nutrisi, ' + 'yang semuanya esensial bagi perkembangan tanaman. Selain itu, ' + 'suhu tanah juga memengaruhi aktivitas mikroorganisme yang berkontribusi pada kesuburan tanah. ' + 'Dalam pertanian pintar, sensor suhu tanah sering digunakan untuk memantau dan mengoptimalkan ' + 'kondisi tanah, memastikan tanaman tumbuh dalam rentang suhu yang ideal.'; static const String npk1 = 'npk1'; static const String npk2 = 'npk2'; diff --git a/agrilink_vocpro/lib/features/auth/view/login_screen.dart b/agrilink_vocpro/lib/features/auth/view/login_screen.dart index 3272067..53d6ed9 100644 --- a/agrilink_vocpro/lib/features/auth/view/login_screen.dart +++ b/agrilink_vocpro/lib/features/auth/view/login_screen.dart @@ -77,11 +77,11 @@ class LoginScreen extends StatelessWidget { text: 'Login', ), SizedBox(height: 24), - AppButton( - onPressed: () { - authP.getAccessToken(); - }, - text: 'Get Access Token'), + // AppButton( + // onPressed: () { + // authP.getAccessToken(); + // }, + // text: 'Get Access Token'), ], ); }, diff --git a/agrilink_vocpro/lib/features/home/provider/home_provider.dart b/agrilink_vocpro/lib/features/home/provider/home_provider.dart index e7785fb..01f8623 100644 --- a/agrilink_vocpro/lib/features/home/provider/home_provider.dart +++ b/agrilink_vocpro/lib/features/home/provider/home_provider.dart @@ -98,7 +98,7 @@ class HomeProvider extends ChangeNotifier { if (kDebugMode) { print('Get Latest Error: $e'); } - dataState = ResultState.error; + dataState = ResultState.hasData; notifyListeners(); } } diff --git a/agrilink_vocpro/lib/features/home/widgets/list_data_from_censor_dht.dart b/agrilink_vocpro/lib/features/home/widgets/list_data_from_censor_dht.dart index b4517e7..a95ecb1 100644 --- a/agrilink_vocpro/lib/features/home/widgets/list_data_from_censor_dht.dart +++ b/agrilink_vocpro/lib/features/home/widgets/list_data_from_censor_dht.dart @@ -1,4 +1,3 @@ -import 'package:agrilink_vocpro/core/constant/app_color.dart'; import 'package:agrilink_vocpro/core/extension/extention.dart'; import 'package:agrilink_vocpro/core/route/app_route.dart'; import 'package:agrilink_vocpro/core/state/result_state.dart'; diff --git a/agrilink_vocpro/lib/features/home/widgets/list_data_from_censor_npk1.dart b/agrilink_vocpro/lib/features/home/widgets/list_data_from_censor_npk1.dart index dc2f4d3..c715e83 100644 --- a/agrilink_vocpro/lib/features/home/widgets/list_data_from_censor_npk1.dart +++ b/agrilink_vocpro/lib/features/home/widgets/list_data_from_censor_npk1.dart @@ -1,5 +1,4 @@ import 'package:agrilink_vocpro/core/constant/app_color.dart'; -import 'package:agrilink_vocpro/core/extension/extention.dart'; import 'package:agrilink_vocpro/core/route/app_route.dart'; import 'package:agrilink_vocpro/core/state/result_state.dart'; import 'package:agrilink_vocpro/features/home/provider/home_provider.dart'; -- 2.43.0 From 2ca76146502d385cc720fcd518e14b5b871bee00 Mon Sep 17 00:00:00 2001 From: Syaroful Date: Mon, 4 Nov 2024 09:00:45 +0700 Subject: [PATCH 03/19] refactor: change folder name --- agrilink_vocpro/lib/core/route/app_route.dart | 20 +++++++++---------- .../provider/conductivity_provider.dart | 0 .../view/conductivity_screen.dart | 2 +- .../humidity/provider/humidity_provider.dart | 0 .../humidity/view/humidity_screen.dart | 6 +----- .../luminosity/provider/lum_provider.dart | 0 .../luminosity/view/light_screen.dart | 6 +++--- .../nitrogen/provider/nitrogen_provider.dart | 0 .../nitrogen/view/nitrogen_screen.dart | 2 +- .../ph/provider/ph_provider.dart | 0 .../ph/view/ph_screen.dart | 4 ++-- .../ph/widget/ph_bar_pointer.dart | 0 .../provider/phosporus_provider.dart | 0 .../phosphorus/view/phosphorus_screen.dart | 2 +- .../provider/potassium_provider.dart | 0 .../potassium/view/potassium_screen.dart | 2 +- .../provider/soil_moisture_provider.dart | 0 .../view/soil_moisture_screen.dart | 2 +- .../provider/soil_temp_provider.dart | 0 .../view/soil_temperature_screen.dart | 2 +- .../temperature/provider/temp_provider.dart | 0 .../temperature/view/temperature_screen.dart | 2 +- 22 files changed, 23 insertions(+), 27 deletions(-) rename agrilink_vocpro/lib/features/home/{pages => detail_pages}/conductivity/provider/conductivity_provider.dart (100%) rename agrilink_vocpro/lib/features/home/{pages => detail_pages}/conductivity/view/conductivity_screen.dart (97%) rename agrilink_vocpro/lib/features/home/{pages => detail_pages}/humidity/provider/humidity_provider.dart (100%) rename agrilink_vocpro/lib/features/home/{pages => detail_pages}/humidity/view/humidity_screen.dart (97%) rename agrilink_vocpro/lib/features/home/{pages => detail_pages}/luminosity/provider/lum_provider.dart (100%) rename agrilink_vocpro/lib/features/home/{pages => detail_pages}/luminosity/view/light_screen.dart (97%) rename agrilink_vocpro/lib/features/home/{pages => detail_pages}/nitrogen/provider/nitrogen_provider.dart (100%) rename agrilink_vocpro/lib/features/home/{pages => detail_pages}/nitrogen/view/nitrogen_screen.dart (98%) rename agrilink_vocpro/lib/features/home/{pages => detail_pages}/ph/provider/ph_provider.dart (100%) rename agrilink_vocpro/lib/features/home/{pages => detail_pages}/ph/view/ph_screen.dart (96%) rename agrilink_vocpro/lib/features/home/{pages => detail_pages}/ph/widget/ph_bar_pointer.dart (100%) rename agrilink_vocpro/lib/features/home/{pages => detail_pages}/phosphorus/provider/phosporus_provider.dart (100%) rename agrilink_vocpro/lib/features/home/{pages => detail_pages}/phosphorus/view/phosphorus_screen.dart (98%) rename agrilink_vocpro/lib/features/home/{pages => detail_pages}/potassium/provider/potassium_provider.dart (100%) rename agrilink_vocpro/lib/features/home/{pages => detail_pages}/potassium/view/potassium_screen.dart (98%) rename agrilink_vocpro/lib/features/home/{pages => detail_pages}/soil_moisture/provider/soil_moisture_provider.dart (100%) rename agrilink_vocpro/lib/features/home/{pages => detail_pages}/soil_moisture/view/soil_moisture_screen.dart (98%) rename agrilink_vocpro/lib/features/home/{pages => detail_pages}/soil_temperature/provider/soil_temp_provider.dart (100%) rename agrilink_vocpro/lib/features/home/{pages => detail_pages}/soil_temperature/view/soil_temperature_screen.dart (98%) rename agrilink_vocpro/lib/features/home/{pages => detail_pages}/temperature/provider/temp_provider.dart (100%) rename agrilink_vocpro/lib/features/home/{pages => detail_pages}/temperature/view/temperature_screen.dart (99%) diff --git a/agrilink_vocpro/lib/core/route/app_route.dart b/agrilink_vocpro/lib/core/route/app_route.dart index 8c2d740..e5d4f9f 100644 --- a/agrilink_vocpro/lib/core/route/app_route.dart +++ b/agrilink_vocpro/lib/core/route/app_route.dart @@ -1,15 +1,15 @@ import 'package:agrilink_vocpro/features/auth/view/login_screen.dart'; import 'package:agrilink_vocpro/features/dashboard/view/dashboard_screen.dart'; -import 'package:agrilink_vocpro/features/home/pages/conductivity/view/conductivity_screen.dart'; -import 'package:agrilink_vocpro/features/home/pages/humidity/view/humidity_screen.dart'; -import 'package:agrilink_vocpro/features/home/pages/luminosity/view/light_screen.dart'; -import 'package:agrilink_vocpro/features/home/pages/nitrogen/view/nitrogen_screen.dart'; -import 'package:agrilink_vocpro/features/home/pages/ph/view/ph_screen.dart'; -import 'package:agrilink_vocpro/features/home/pages/phosphorus/view/phosphorus_screen.dart'; -import 'package:agrilink_vocpro/features/home/pages/potassium/view/potassium_screen.dart'; -import 'package:agrilink_vocpro/features/home/pages/soil_moisture/view/soil_moisture_screen.dart'; -import 'package:agrilink_vocpro/features/home/pages/soil_temperature/view/soil_temperature_screen.dart'; -import 'package:agrilink_vocpro/features/home/pages/temperature/view/temperature_screen.dart'; +import 'package:agrilink_vocpro/features/home/detail_pages/conductivity/view/conductivity_screen.dart'; +import 'package:agrilink_vocpro/features/home/detail_pages/humidity/view/humidity_screen.dart'; +import 'package:agrilink_vocpro/features/home/detail_pages/luminosity/view/light_screen.dart'; +import 'package:agrilink_vocpro/features/home/detail_pages/nitrogen/view/nitrogen_screen.dart'; +import 'package:agrilink_vocpro/features/home/detail_pages/ph/view/ph_screen.dart'; +import 'package:agrilink_vocpro/features/home/detail_pages/phosphorus/view/phosphorus_screen.dart'; +import 'package:agrilink_vocpro/features/home/detail_pages/potassium/view/potassium_screen.dart'; +import 'package:agrilink_vocpro/features/home/detail_pages/soil_moisture/view/soil_moisture_screen.dart'; +import 'package:agrilink_vocpro/features/home/detail_pages/soil_temperature/view/soil_temperature_screen.dart'; +import 'package:agrilink_vocpro/features/home/detail_pages/temperature/view/temperature_screen.dart'; import 'package:agrilink_vocpro/features/splash/view/splash_screen.dart'; import 'package:flutter/material.dart'; import 'package:go_router/go_router.dart'; diff --git a/agrilink_vocpro/lib/features/home/pages/conductivity/provider/conductivity_provider.dart b/agrilink_vocpro/lib/features/home/detail_pages/conductivity/provider/conductivity_provider.dart similarity index 100% rename from agrilink_vocpro/lib/features/home/pages/conductivity/provider/conductivity_provider.dart rename to agrilink_vocpro/lib/features/home/detail_pages/conductivity/provider/conductivity_provider.dart diff --git a/agrilink_vocpro/lib/features/home/pages/conductivity/view/conductivity_screen.dart b/agrilink_vocpro/lib/features/home/detail_pages/conductivity/view/conductivity_screen.dart similarity index 97% rename from agrilink_vocpro/lib/features/home/pages/conductivity/view/conductivity_screen.dart rename to agrilink_vocpro/lib/features/home/detail_pages/conductivity/view/conductivity_screen.dart index cc9eec7..fe76f07 100644 --- a/agrilink_vocpro/lib/features/home/pages/conductivity/view/conductivity_screen.dart +++ b/agrilink_vocpro/lib/features/home/detail_pages/conductivity/view/conductivity_screen.dart @@ -1,6 +1,6 @@ import 'package:agrilink_vocpro/core/constant/app_theme.dart'; import 'package:agrilink_vocpro/core/state/result_state.dart'; -import 'package:agrilink_vocpro/features/home/pages/conductivity/provider/conductivity_provider.dart'; +import 'package:agrilink_vocpro/features/home/detail_pages/conductivity/provider/conductivity_provider.dart'; import 'package:agrilink_vocpro/features/home/widgets/graphic_error_widget.dart'; import 'package:agrilink_vocpro/features/home/widgets/graphic_widget.dart'; import 'package:bootstrap_icons/bootstrap_icons.dart'; diff --git a/agrilink_vocpro/lib/features/home/pages/humidity/provider/humidity_provider.dart b/agrilink_vocpro/lib/features/home/detail_pages/humidity/provider/humidity_provider.dart similarity index 100% rename from agrilink_vocpro/lib/features/home/pages/humidity/provider/humidity_provider.dart rename to agrilink_vocpro/lib/features/home/detail_pages/humidity/provider/humidity_provider.dart diff --git a/agrilink_vocpro/lib/features/home/pages/humidity/view/humidity_screen.dart b/agrilink_vocpro/lib/features/home/detail_pages/humidity/view/humidity_screen.dart similarity index 97% rename from agrilink_vocpro/lib/features/home/pages/humidity/view/humidity_screen.dart rename to agrilink_vocpro/lib/features/home/detail_pages/humidity/view/humidity_screen.dart index a97297f..8733026 100644 --- a/agrilink_vocpro/lib/features/home/pages/humidity/view/humidity_screen.dart +++ b/agrilink_vocpro/lib/features/home/detail_pages/humidity/view/humidity_screen.dart @@ -1,6 +1,6 @@ import 'package:agrilink_vocpro/core/constant/app_theme.dart'; import 'package:agrilink_vocpro/core/state/result_state.dart'; -import 'package:agrilink_vocpro/features/home/pages/humidity/provider/humidity_provider.dart'; +import 'package:agrilink_vocpro/features/home/detail_pages/humidity/provider/humidity_provider.dart'; import 'package:agrilink_vocpro/features/home/provider/home_provider.dart'; import 'package:agrilink_vocpro/features/home/widgets/graphic_widget.dart'; import 'package:bootstrap_icons/bootstrap_icons.dart'; @@ -189,10 +189,6 @@ class HumidityScreen extends StatelessWidget { ), ), SizedBox(height: 16.h), - Padding( - padding: EdgeInsets.only(left: 16.w), - child: const Text('Deskripsi'), - ), ], ); }), diff --git a/agrilink_vocpro/lib/features/home/pages/luminosity/provider/lum_provider.dart b/agrilink_vocpro/lib/features/home/detail_pages/luminosity/provider/lum_provider.dart similarity index 100% rename from agrilink_vocpro/lib/features/home/pages/luminosity/provider/lum_provider.dart rename to agrilink_vocpro/lib/features/home/detail_pages/luminosity/provider/lum_provider.dart diff --git a/agrilink_vocpro/lib/features/home/pages/luminosity/view/light_screen.dart b/agrilink_vocpro/lib/features/home/detail_pages/luminosity/view/light_screen.dart similarity index 97% rename from agrilink_vocpro/lib/features/home/pages/luminosity/view/light_screen.dart rename to agrilink_vocpro/lib/features/home/detail_pages/luminosity/view/light_screen.dart index 0a589fb..ce1c5e4 100644 --- a/agrilink_vocpro/lib/features/home/pages/luminosity/view/light_screen.dart +++ b/agrilink_vocpro/lib/features/home/detail_pages/luminosity/view/light_screen.dart @@ -1,6 +1,6 @@ import 'package:agrilink_vocpro/core/constant/app_theme.dart'; import 'package:agrilink_vocpro/core/state/result_state.dart'; -import 'package:agrilink_vocpro/features/home/pages/luminosity/provider/lum_provider.dart'; +import 'package:agrilink_vocpro/features/home/detail_pages/luminosity/provider/lum_provider.dart'; import 'package:agrilink_vocpro/features/home/widgets/graphic_widget.dart'; import 'package:bootstrap_icons/bootstrap_icons.dart'; import 'package:flutter/cupertino.dart'; @@ -64,7 +64,7 @@ class LightScreen extends StatelessWidget { axis: GaugeAxis( degrees: 360, min: 0, - max: 1000, + max: 500, style: GaugeAxisStyle( background: Colors.grey.shade100, thickness: 100, @@ -82,7 +82,7 @@ class LightScreen extends StatelessWidget { ), const SizedBox(height: 16), Text( - '${value.toStringAsFixed(0)} lux', + '$value lux', textAlign: TextAlign.center, style: const TextStyle( fontSize: 28, diff --git a/agrilink_vocpro/lib/features/home/pages/nitrogen/provider/nitrogen_provider.dart b/agrilink_vocpro/lib/features/home/detail_pages/nitrogen/provider/nitrogen_provider.dart similarity index 100% rename from agrilink_vocpro/lib/features/home/pages/nitrogen/provider/nitrogen_provider.dart rename to agrilink_vocpro/lib/features/home/detail_pages/nitrogen/provider/nitrogen_provider.dart diff --git a/agrilink_vocpro/lib/features/home/pages/nitrogen/view/nitrogen_screen.dart b/agrilink_vocpro/lib/features/home/detail_pages/nitrogen/view/nitrogen_screen.dart similarity index 98% rename from agrilink_vocpro/lib/features/home/pages/nitrogen/view/nitrogen_screen.dart rename to agrilink_vocpro/lib/features/home/detail_pages/nitrogen/view/nitrogen_screen.dart index 3676520..aab46d2 100644 --- a/agrilink_vocpro/lib/features/home/pages/nitrogen/view/nitrogen_screen.dart +++ b/agrilink_vocpro/lib/features/home/detail_pages/nitrogen/view/nitrogen_screen.dart @@ -1,6 +1,6 @@ import 'package:agrilink_vocpro/core/constant/app_theme.dart'; import 'package:agrilink_vocpro/core/state/result_state.dart'; -import 'package:agrilink_vocpro/features/home/pages/nitrogen/provider/nitrogen_provider.dart'; +import 'package:agrilink_vocpro/features/home/detail_pages/nitrogen/provider/nitrogen_provider.dart'; import 'package:agrilink_vocpro/features/home/widgets/graphic_error_widget.dart'; import 'package:agrilink_vocpro/features/home/widgets/graphic_widget.dart'; import 'package:bootstrap_icons/bootstrap_icons.dart'; diff --git a/agrilink_vocpro/lib/features/home/pages/ph/provider/ph_provider.dart b/agrilink_vocpro/lib/features/home/detail_pages/ph/provider/ph_provider.dart similarity index 100% rename from agrilink_vocpro/lib/features/home/pages/ph/provider/ph_provider.dart rename to agrilink_vocpro/lib/features/home/detail_pages/ph/provider/ph_provider.dart diff --git a/agrilink_vocpro/lib/features/home/pages/ph/view/ph_screen.dart b/agrilink_vocpro/lib/features/home/detail_pages/ph/view/ph_screen.dart similarity index 96% rename from agrilink_vocpro/lib/features/home/pages/ph/view/ph_screen.dart rename to agrilink_vocpro/lib/features/home/detail_pages/ph/view/ph_screen.dart index ebc33d8..5992eed 100644 --- a/agrilink_vocpro/lib/features/home/pages/ph/view/ph_screen.dart +++ b/agrilink_vocpro/lib/features/home/detail_pages/ph/view/ph_screen.dart @@ -1,7 +1,7 @@ import 'package:agrilink_vocpro/core/constant/app_theme.dart'; import 'package:agrilink_vocpro/core/state/result_state.dart'; -import 'package:agrilink_vocpro/features/home/pages/ph/provider/ph_provider.dart'; -import 'package:agrilink_vocpro/features/home/pages/ph/widget/ph_bar_pointer.dart'; +import 'package:agrilink_vocpro/features/home/detail_pages/ph/provider/ph_provider.dart'; +import 'package:agrilink_vocpro/features/home/detail_pages/ph/widget/ph_bar_pointer.dart'; import 'package:agrilink_vocpro/features/home/widgets/graphic_error_widget.dart'; import 'package:agrilink_vocpro/features/home/widgets/graphic_widget.dart'; import 'package:bootstrap_icons/bootstrap_icons.dart'; diff --git a/agrilink_vocpro/lib/features/home/pages/ph/widget/ph_bar_pointer.dart b/agrilink_vocpro/lib/features/home/detail_pages/ph/widget/ph_bar_pointer.dart similarity index 100% rename from agrilink_vocpro/lib/features/home/pages/ph/widget/ph_bar_pointer.dart rename to agrilink_vocpro/lib/features/home/detail_pages/ph/widget/ph_bar_pointer.dart diff --git a/agrilink_vocpro/lib/features/home/pages/phosphorus/provider/phosporus_provider.dart b/agrilink_vocpro/lib/features/home/detail_pages/phosphorus/provider/phosporus_provider.dart similarity index 100% rename from agrilink_vocpro/lib/features/home/pages/phosphorus/provider/phosporus_provider.dart rename to agrilink_vocpro/lib/features/home/detail_pages/phosphorus/provider/phosporus_provider.dart diff --git a/agrilink_vocpro/lib/features/home/pages/phosphorus/view/phosphorus_screen.dart b/agrilink_vocpro/lib/features/home/detail_pages/phosphorus/view/phosphorus_screen.dart similarity index 98% rename from agrilink_vocpro/lib/features/home/pages/phosphorus/view/phosphorus_screen.dart rename to agrilink_vocpro/lib/features/home/detail_pages/phosphorus/view/phosphorus_screen.dart index 85bb910..9e1c304 100644 --- a/agrilink_vocpro/lib/features/home/pages/phosphorus/view/phosphorus_screen.dart +++ b/agrilink_vocpro/lib/features/home/detail_pages/phosphorus/view/phosphorus_screen.dart @@ -1,6 +1,6 @@ import 'package:agrilink_vocpro/core/constant/app_theme.dart'; import 'package:agrilink_vocpro/core/state/result_state.dart'; -import 'package:agrilink_vocpro/features/home/pages/phosphorus/provider/phosporus_provider.dart'; +import 'package:agrilink_vocpro/features/home/detail_pages/phosphorus/provider/phosporus_provider.dart'; import 'package:agrilink_vocpro/features/home/widgets/graphic_error_widget.dart'; import 'package:agrilink_vocpro/features/home/widgets/graphic_widget.dart'; import 'package:bootstrap_icons/bootstrap_icons.dart'; diff --git a/agrilink_vocpro/lib/features/home/pages/potassium/provider/potassium_provider.dart b/agrilink_vocpro/lib/features/home/detail_pages/potassium/provider/potassium_provider.dart similarity index 100% rename from agrilink_vocpro/lib/features/home/pages/potassium/provider/potassium_provider.dart rename to agrilink_vocpro/lib/features/home/detail_pages/potassium/provider/potassium_provider.dart diff --git a/agrilink_vocpro/lib/features/home/pages/potassium/view/potassium_screen.dart b/agrilink_vocpro/lib/features/home/detail_pages/potassium/view/potassium_screen.dart similarity index 98% rename from agrilink_vocpro/lib/features/home/pages/potassium/view/potassium_screen.dart rename to agrilink_vocpro/lib/features/home/detail_pages/potassium/view/potassium_screen.dart index b650dd2..f9a0f2c 100644 --- a/agrilink_vocpro/lib/features/home/pages/potassium/view/potassium_screen.dart +++ b/agrilink_vocpro/lib/features/home/detail_pages/potassium/view/potassium_screen.dart @@ -1,6 +1,6 @@ import 'package:agrilink_vocpro/core/constant/app_theme.dart'; import 'package:agrilink_vocpro/core/state/result_state.dart'; -import 'package:agrilink_vocpro/features/home/pages/potassium/provider/potassium_provider.dart'; +import 'package:agrilink_vocpro/features/home/detail_pages/potassium/provider/potassium_provider.dart'; import 'package:agrilink_vocpro/features/home/widgets/graphic_error_widget.dart'; import 'package:agrilink_vocpro/features/home/widgets/graphic_widget.dart'; import 'package:bootstrap_icons/bootstrap_icons.dart'; diff --git a/agrilink_vocpro/lib/features/home/pages/soil_moisture/provider/soil_moisture_provider.dart b/agrilink_vocpro/lib/features/home/detail_pages/soil_moisture/provider/soil_moisture_provider.dart similarity index 100% rename from agrilink_vocpro/lib/features/home/pages/soil_moisture/provider/soil_moisture_provider.dart rename to agrilink_vocpro/lib/features/home/detail_pages/soil_moisture/provider/soil_moisture_provider.dart diff --git a/agrilink_vocpro/lib/features/home/pages/soil_moisture/view/soil_moisture_screen.dart b/agrilink_vocpro/lib/features/home/detail_pages/soil_moisture/view/soil_moisture_screen.dart similarity index 98% rename from agrilink_vocpro/lib/features/home/pages/soil_moisture/view/soil_moisture_screen.dart rename to agrilink_vocpro/lib/features/home/detail_pages/soil_moisture/view/soil_moisture_screen.dart index efe21f4..451b1f6 100644 --- a/agrilink_vocpro/lib/features/home/pages/soil_moisture/view/soil_moisture_screen.dart +++ b/agrilink_vocpro/lib/features/home/detail_pages/soil_moisture/view/soil_moisture_screen.dart @@ -1,6 +1,6 @@ import 'package:agrilink_vocpro/core/constant/app_theme.dart'; import 'package:agrilink_vocpro/core/state/result_state.dart'; -import 'package:agrilink_vocpro/features/home/pages/soil_moisture/provider/soil_moisture_provider.dart'; +import 'package:agrilink_vocpro/features/home/detail_pages/soil_moisture/provider/soil_moisture_provider.dart'; import 'package:agrilink_vocpro/features/home/widgets/graphic_error_widget.dart'; import 'package:agrilink_vocpro/features/home/widgets/graphic_widget.dart'; import 'package:bootstrap_icons/bootstrap_icons.dart'; diff --git a/agrilink_vocpro/lib/features/home/pages/soil_temperature/provider/soil_temp_provider.dart b/agrilink_vocpro/lib/features/home/detail_pages/soil_temperature/provider/soil_temp_provider.dart similarity index 100% rename from agrilink_vocpro/lib/features/home/pages/soil_temperature/provider/soil_temp_provider.dart rename to agrilink_vocpro/lib/features/home/detail_pages/soil_temperature/provider/soil_temp_provider.dart diff --git a/agrilink_vocpro/lib/features/home/pages/soil_temperature/view/soil_temperature_screen.dart b/agrilink_vocpro/lib/features/home/detail_pages/soil_temperature/view/soil_temperature_screen.dart similarity index 98% rename from agrilink_vocpro/lib/features/home/pages/soil_temperature/view/soil_temperature_screen.dart rename to agrilink_vocpro/lib/features/home/detail_pages/soil_temperature/view/soil_temperature_screen.dart index 7870eec..02ee21b 100644 --- a/agrilink_vocpro/lib/features/home/pages/soil_temperature/view/soil_temperature_screen.dart +++ b/agrilink_vocpro/lib/features/home/detail_pages/soil_temperature/view/soil_temperature_screen.dart @@ -7,7 +7,7 @@ import 'package:agrilink_vocpro/core/constant/app_constant.dart'; import 'package:agrilink_vocpro/core/constant/app_theme.dart'; import 'package:agrilink_vocpro/core/state/result_state.dart'; import 'package:agrilink_vocpro/core/widgets/show_info.dart'; -import 'package:agrilink_vocpro/features/home/pages/soil_temperature/provider/soil_temp_provider.dart'; +import 'package:agrilink_vocpro/features/home/detail_pages/soil_temperature/provider/soil_temp_provider.dart'; import 'package:agrilink_vocpro/features/home/widgets/graphic_widget.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:gauge_indicator/gauge_indicator.dart'; diff --git a/agrilink_vocpro/lib/features/home/pages/temperature/provider/temp_provider.dart b/agrilink_vocpro/lib/features/home/detail_pages/temperature/provider/temp_provider.dart similarity index 100% rename from agrilink_vocpro/lib/features/home/pages/temperature/provider/temp_provider.dart rename to agrilink_vocpro/lib/features/home/detail_pages/temperature/provider/temp_provider.dart diff --git a/agrilink_vocpro/lib/features/home/pages/temperature/view/temperature_screen.dart b/agrilink_vocpro/lib/features/home/detail_pages/temperature/view/temperature_screen.dart similarity index 99% rename from agrilink_vocpro/lib/features/home/pages/temperature/view/temperature_screen.dart rename to agrilink_vocpro/lib/features/home/detail_pages/temperature/view/temperature_screen.dart index 5654709..df4ce7c 100644 --- a/agrilink_vocpro/lib/features/home/pages/temperature/view/temperature_screen.dart +++ b/agrilink_vocpro/lib/features/home/detail_pages/temperature/view/temperature_screen.dart @@ -1,6 +1,6 @@ import 'package:agrilink_vocpro/core/constant/app_theme.dart'; import 'package:agrilink_vocpro/core/state/result_state.dart'; -import 'package:agrilink_vocpro/features/home/pages/temperature/provider/temp_provider.dart'; +import 'package:agrilink_vocpro/features/home/detail_pages/temperature/provider/temp_provider.dart'; import 'package:agrilink_vocpro/features/home/widgets/graphic_widget.dart'; import 'package:bootstrap_icons/bootstrap_icons.dart'; import 'package:flutter/cupertino.dart'; -- 2.43.0 From 3ae244f9054c477c32620eacd0fd8d532e2fef39 Mon Sep 17 00:00:00 2001 From: Syaroful Date: Mon, 4 Nov 2024 09:18:27 +0700 Subject: [PATCH 04/19] feat: add detail account screen --- agrilink_vocpro/lib/core/route/app_route.dart | 7 +++ .../setting/provider/setting_provider.dart | 2 + .../features/setting/view/account_screen.dart | 40 ++++++++++++++ .../features/setting/view/setting_screen.dart | 52 ++++++++++--------- 4 files changed, 76 insertions(+), 25 deletions(-) create mode 100644 agrilink_vocpro/lib/features/setting/view/account_screen.dart diff --git a/agrilink_vocpro/lib/core/route/app_route.dart b/agrilink_vocpro/lib/core/route/app_route.dart index e5d4f9f..feb9f2e 100644 --- a/agrilink_vocpro/lib/core/route/app_route.dart +++ b/agrilink_vocpro/lib/core/route/app_route.dart @@ -10,6 +10,7 @@ import 'package:agrilink_vocpro/features/home/detail_pages/potassium/view/potass import 'package:agrilink_vocpro/features/home/detail_pages/soil_moisture/view/soil_moisture_screen.dart'; import 'package:agrilink_vocpro/features/home/detail_pages/soil_temperature/view/soil_temperature_screen.dart'; import 'package:agrilink_vocpro/features/home/detail_pages/temperature/view/temperature_screen.dart'; +import 'package:agrilink_vocpro/features/setting/view/account_screen.dart'; import 'package:agrilink_vocpro/features/splash/view/splash_screen.dart'; import 'package:flutter/material.dart'; import 'package:go_router/go_router.dart'; @@ -21,6 +22,7 @@ class AppRoute { static const String home = '/home'; static const String profile = '/profile'; static const String setting = '/setting'; + static const String account = '/dashboard/account'; static const String humidity = '/dashboard/humidity'; static const String temperature = '/dashboard/temperature'; static const String soilTemperature = '/dashboard/soil_temperature'; @@ -69,6 +71,11 @@ class AppRoute { buildPhosphorusRoute(), // potassium buildPotassiumRoute(), + GoRoute( + path: 'account', + builder: (context, state) { + return AccountScreen(); + }) ], ), ], diff --git a/agrilink_vocpro/lib/features/setting/provider/setting_provider.dart b/agrilink_vocpro/lib/features/setting/provider/setting_provider.dart index d480b21..48b60aa 100644 --- a/agrilink_vocpro/lib/features/setting/provider/setting_provider.dart +++ b/agrilink_vocpro/lib/features/setting/provider/setting_provider.dart @@ -10,11 +10,13 @@ class SettingProvider extends ChangeNotifier { String userFullName = ''; String userEmail = ''; + String userName = ''; void _init() async { SharedPreferences prefs = await SharedPreferences.getInstance(); userFullName = prefs.getString('fullName') ?? 'unknown'; userEmail = prefs.getString('email') ?? 'unknown'; + userName = prefs.getString('username') ?? 'unknown'; notifyListeners(); } diff --git a/agrilink_vocpro/lib/features/setting/view/account_screen.dart b/agrilink_vocpro/lib/features/setting/view/account_screen.dart new file mode 100644 index 0000000..3553acc --- /dev/null +++ b/agrilink_vocpro/lib/features/setting/view/account_screen.dart @@ -0,0 +1,40 @@ +import 'package:agrilink_vocpro/core/constant/app_theme.dart'; +import 'package:agrilink_vocpro/features/setting/provider/setting_provider.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_screenutil/flutter_screenutil.dart'; +import 'package:provider/provider.dart'; + +class AccountScreen extends StatelessWidget { + const AccountScreen({super.key}); + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + title: Text('Detail Account', style: AppTheme.labelMedium), + centerTitle: true, + backgroundColor: Colors.white, + scrolledUnderElevation: 0, + ), + body: Consumer(builder: (context, provider, child) { + return ListView( + padding: EdgeInsets.all(16.r), + children: [ + ListTile( + title: Text('Username', style: AppTheme.labelMedium), + trailing: Text(provider.userName, style: AppTheme.labelSmall), + ), + ListTile( + title: Text('Email', style: AppTheme.labelMedium), + trailing: Text(provider.userEmail, style: AppTheme.labelSmall), + ), + ListTile( + title: Text('Name', style: AppTheme.labelMedium), + trailing: Text(provider.userFullName, style: AppTheme.labelSmall), + ), + ], + ); + }), + ); + } +} diff --git a/agrilink_vocpro/lib/features/setting/view/setting_screen.dart b/agrilink_vocpro/lib/features/setting/view/setting_screen.dart index b11c725..197a1af 100644 --- a/agrilink_vocpro/lib/features/setting/view/setting_screen.dart +++ b/agrilink_vocpro/lib/features/setting/view/setting_screen.dart @@ -60,32 +60,34 @@ class SettingScreen extends StatelessWidget { Icons.arrow_forward_ios, size: 16.r, ), - onTap: () {}, - ), - ListTile( - tileColor: Colors.white, - title: Text('Kebijakan & privasi', - style: AppTheme.labelSmall - .copyWith(color: Colors.black87)), - leading: const Icon(BootstrapIcons.shield_check), - trailing: Icon( - Icons.arrow_forward_ios, - size: 16.r, - ), - onTap: () {}, - ), - ListTile( - tileColor: Colors.white, - title: Text('Syarat & ketentuan', - style: AppTheme.labelSmall - .copyWith(color: Colors.black87)), - leading: const Icon(BootstrapIcons.file_text), - trailing: Icon( - Icons.arrow_forward_ios, - size: 16.r, - ), - onTap: () {}, + onTap: () { + context.go(AppRoute.account); + }, ), + // ListTile( + // tileColor: Colors.white, + // title: Text('Kebijakan & privasi', + // style: AppTheme.labelSmall + // .copyWith(color: Colors.black87)), + // leading: const Icon(BootstrapIcons.shield_check), + // trailing: Icon( + // Icons.arrow_forward_ios, + // size: 16.r, + // ), + // onTap: () {}, + // ), + // ListTile( + // tileColor: Colors.white, + // title: Text('Syarat & ketentuan', + // style: AppTheme.labelSmall + // .copyWith(color: Colors.black87)), + // leading: const Icon(BootstrapIcons.file_text), + // trailing: Icon( + // Icons.arrow_forward_ios, + // size: 16.r, + // ), + // onTap: () {}, + // ), ListTile( tileColor: Colors.white, title: Text('Logout', -- 2.43.0 From dcef0cf99d6b73d83fea12cb88fb2c668c85955b Mon Sep 17 00:00:00 2001 From: Syaroful Date: Wed, 6 Nov 2024 08:33:29 +0700 Subject: [PATCH 05/19] refactor: tidy up the ui --- .../core/widgets/error_data_state_widget.dart | 30 +++++++++++ .../widgets/no_data_state_widget.dart} | 18 ++++--- .../features/auth/provider/auth_provider.dart | 52 +++++++++---------- .../view/conductivity_screen.dart | 7 +-- .../nitrogen/view/nitrogen_screen.dart | 7 +-- .../home/detail_pages/ph/view/ph_screen.dart | 7 +-- .../phosphorus/view/phosphorus_screen.dart | 7 +-- .../potassium/view/potassium_screen.dart | 7 +-- .../view/soil_moisture_screen.dart | 7 +-- .../view/soil_temperature_screen.dart | 7 +-- .../temperature/view/temperature_screen.dart | 38 ++------------ .../widgets/list_data_from_censor_dht.dart | 4 +- .../widgets/list_data_from_censor_npk1.dart | 3 ++ .../widgets/list_data_from_censor_npk2.dart | 5 +- 14 files changed, 111 insertions(+), 88 deletions(-) create mode 100644 agrilink_vocpro/lib/core/widgets/error_data_state_widget.dart rename agrilink_vocpro/lib/{features/home/widgets/graphic_error_widget.dart => core/widgets/no_data_state_widget.dart} (59%) diff --git a/agrilink_vocpro/lib/core/widgets/error_data_state_widget.dart b/agrilink_vocpro/lib/core/widgets/error_data_state_widget.dart new file mode 100644 index 0000000..0cb21a3 --- /dev/null +++ b/agrilink_vocpro/lib/core/widgets/error_data_state_widget.dart @@ -0,0 +1,30 @@ +import 'package:agrilink_vocpro/core/constant/app_theme.dart'; +import 'package:bootstrap_icons/bootstrap_icons.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_screenutil/flutter_screenutil.dart'; + +class ErrorDataStateWidget extends StatelessWidget { + const ErrorDataStateWidget({ + super.key, + }); + + @override + Widget build(BuildContext context) { + return Center( + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Icon( + BootstrapIcons.exclamation_circle, + color: Colors.grey.shade400, + ), + SizedBox(height: 8.h), + Text( + 'Terjadi Kesalahan', + style: AppTheme.labelSmall, + ), + ], + ), + ); + } +} diff --git a/agrilink_vocpro/lib/features/home/widgets/graphic_error_widget.dart b/agrilink_vocpro/lib/core/widgets/no_data_state_widget.dart similarity index 59% rename from agrilink_vocpro/lib/features/home/widgets/graphic_error_widget.dart rename to agrilink_vocpro/lib/core/widgets/no_data_state_widget.dart index 9654ce3..33d66aa 100644 --- a/agrilink_vocpro/lib/features/home/widgets/graphic_error_widget.dart +++ b/agrilink_vocpro/lib/core/widgets/no_data_state_widget.dart @@ -3,10 +3,10 @@ import 'package:bootstrap_icons/bootstrap_icons.dart'; import 'package:flutter/material.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; -class GraphicErrorWidget extends StatelessWidget { - const GraphicErrorWidget({super.key, required this.message}); - - final String message; +class NoDataStateWidget extends StatelessWidget { + const NoDataStateWidget({ + super.key, + }); @override Widget build(BuildContext context) { @@ -14,9 +14,15 @@ class GraphicErrorWidget extends StatelessWidget { child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ - Icon(BootstrapIcons.exclamation_circle, color: Colors.grey.shade400), + Icon( + BootstrapIcons.database_fill_x, + color: Colors.grey.shade400, + ), SizedBox(height: 8.h), - Text(message, style: AppTheme.labelSmall), + Text( + 'Tidak Ada Data', + style: AppTheme.labelSmall, + ), ], ), ); diff --git a/agrilink_vocpro/lib/features/auth/provider/auth_provider.dart b/agrilink_vocpro/lib/features/auth/provider/auth_provider.dart index 0126368..749f0ff 100644 --- a/agrilink_vocpro/lib/features/auth/provider/auth_provider.dart +++ b/agrilink_vocpro/lib/features/auth/provider/auth_provider.dart @@ -1,11 +1,11 @@ -import 'dart:convert'; +// import 'dart:convert'; import 'package:agrilink_vocpro/core/state/result_state.dart'; import 'package:agrilink_vocpro/domain/service/app_service.dart'; import 'package:flutter/material.dart'; -import 'package:flutter/services.dart'; -import 'package:googleapis_auth/auth_io.dart'; -import 'package:http/http.dart' as http; +// import 'package:flutter/services.dart'; +// import 'package:googleapis_auth/auth_io.dart'; +// import 'package:http/http.dart' as http; class AuthProvider extends ChangeNotifier { TextEditingController emailController = TextEditingController(); @@ -80,30 +80,30 @@ class AuthProvider extends ChangeNotifier { return true; } - Future getAccessToken() async { - try { - final serviceAccountJson = await rootBundle.loadString( - 'assets/json/agrilink-vocpro-b37f9-firebase-adminsdk-a4f6g-e6565344e3.json', - ); + // Future getAccessToken() async { + // try { + // final serviceAccountJson = await rootBundle.loadString( + // 'assets/json/agrilink-vocpro-b37f9-firebase-adminsdk-a4f6g-e6565344e3.json', + // ); - final accountCredentials = ServiceAccountCredentials.fromJson( - json.decode(serviceAccountJson), - ); + // final accountCredentials = ServiceAccountCredentials.fromJson( + // json.decode(serviceAccountJson), + // ); - const scope = ['https://www.googleapis.com/auth/firebase.messaging']; + // const scope = ['https://www.googleapis.com/auth/firebase.messaging']; - final client = http.Client(); + // final client = http.Client(); - try { - final accessCredential = await obtainAccessCredentialsViaServiceAccount( - accountCredentials, scope, client); - final accessToken = accessCredential.accessToken.data; - print('Access Token: $accessToken'); - } catch (e) { - print('Error: $e'); - } - } catch (e) { - print('Error 2: $e'); - } - } + // try { + // final accessCredential = await obtainAccessCredentialsViaServiceAccount( + // accountCredentials, scope, client); + // final accessToken = accessCredential.accessToken.data; + // print('Access Token: $accessToken'); + // } catch (e) { + // print('Error: $e'); + // } + // } catch (e) { + // print('Error 2: $e'); + // } + // } } diff --git a/agrilink_vocpro/lib/features/home/detail_pages/conductivity/view/conductivity_screen.dart b/agrilink_vocpro/lib/features/home/detail_pages/conductivity/view/conductivity_screen.dart index fe76f07..3be4dbf 100644 --- a/agrilink_vocpro/lib/features/home/detail_pages/conductivity/view/conductivity_screen.dart +++ b/agrilink_vocpro/lib/features/home/detail_pages/conductivity/view/conductivity_screen.dart @@ -1,7 +1,8 @@ import 'package:agrilink_vocpro/core/constant/app_theme.dart'; import 'package:agrilink_vocpro/core/state/result_state.dart'; +import 'package:agrilink_vocpro/core/widgets/error_data_state_widget.dart'; +import 'package:agrilink_vocpro/core/widgets/no_data_state_widget.dart'; import 'package:agrilink_vocpro/features/home/detail_pages/conductivity/provider/conductivity_provider.dart'; -import 'package:agrilink_vocpro/features/home/widgets/graphic_error_widget.dart'; import 'package:agrilink_vocpro/features/home/widgets/graphic_widget.dart'; import 'package:bootstrap_icons/bootstrap_icons.dart'; import 'package:flutter/cupertino.dart'; @@ -146,9 +147,9 @@ class ConductivityScreen extends StatelessWidget { maxValue: 1, ); case ResultState.error: - return const GraphicErrorWidget(message: 'Terjadi Kesalahan'); + return const ErrorDataStateWidget(); case ResultState.noData: - return const GraphicErrorWidget(message: 'Tidak Ada Data'); + return const NoDataStateWidget(); case ResultState.initial: default: return const SizedBox.shrink(); diff --git a/agrilink_vocpro/lib/features/home/detail_pages/nitrogen/view/nitrogen_screen.dart b/agrilink_vocpro/lib/features/home/detail_pages/nitrogen/view/nitrogen_screen.dart index aab46d2..2038526 100644 --- a/agrilink_vocpro/lib/features/home/detail_pages/nitrogen/view/nitrogen_screen.dart +++ b/agrilink_vocpro/lib/features/home/detail_pages/nitrogen/view/nitrogen_screen.dart @@ -1,7 +1,8 @@ import 'package:agrilink_vocpro/core/constant/app_theme.dart'; import 'package:agrilink_vocpro/core/state/result_state.dart'; +import 'package:agrilink_vocpro/core/widgets/error_data_state_widget.dart'; +import 'package:agrilink_vocpro/core/widgets/no_data_state_widget.dart'; import 'package:agrilink_vocpro/features/home/detail_pages/nitrogen/provider/nitrogen_provider.dart'; -import 'package:agrilink_vocpro/features/home/widgets/graphic_error_widget.dart'; import 'package:agrilink_vocpro/features/home/widgets/graphic_widget.dart'; import 'package:bootstrap_icons/bootstrap_icons.dart'; import 'package:flutter/cupertino.dart'; @@ -146,9 +147,9 @@ class NitrogenScreen extends StatelessWidget { maxValue: 1, ); case ResultState.error: - return const GraphicErrorWidget(message: 'Terjadi Kesalahan'); + return const ErrorDataStateWidget(); case ResultState.noData: - return const GraphicErrorWidget(message: 'Tidak Ada Data'); + return const NoDataStateWidget(); case ResultState.initial: default: return const SizedBox.shrink(); diff --git a/agrilink_vocpro/lib/features/home/detail_pages/ph/view/ph_screen.dart b/agrilink_vocpro/lib/features/home/detail_pages/ph/view/ph_screen.dart index 5992eed..471e0e6 100644 --- a/agrilink_vocpro/lib/features/home/detail_pages/ph/view/ph_screen.dart +++ b/agrilink_vocpro/lib/features/home/detail_pages/ph/view/ph_screen.dart @@ -1,8 +1,9 @@ import 'package:agrilink_vocpro/core/constant/app_theme.dart'; import 'package:agrilink_vocpro/core/state/result_state.dart'; +import 'package:agrilink_vocpro/core/widgets/error_data_state_widget.dart'; +import 'package:agrilink_vocpro/core/widgets/no_data_state_widget.dart'; import 'package:agrilink_vocpro/features/home/detail_pages/ph/provider/ph_provider.dart'; import 'package:agrilink_vocpro/features/home/detail_pages/ph/widget/ph_bar_pointer.dart'; -import 'package:agrilink_vocpro/features/home/widgets/graphic_error_widget.dart'; import 'package:agrilink_vocpro/features/home/widgets/graphic_widget.dart'; import 'package:bootstrap_icons/bootstrap_icons.dart'; import 'package:flutter/cupertino.dart'; @@ -137,9 +138,9 @@ class PhScreen extends StatelessWidget { maxValue: 14, ); case ResultState.error: - return const GraphicErrorWidget(message: 'Terjadi Kesalahan'); + return const ErrorDataStateWidget(); case ResultState.noData: - return const GraphicErrorWidget(message: 'Tidak Ada Data'); + return const NoDataStateWidget(); case ResultState.initial: default: return const SizedBox.shrink(); diff --git a/agrilink_vocpro/lib/features/home/detail_pages/phosphorus/view/phosphorus_screen.dart b/agrilink_vocpro/lib/features/home/detail_pages/phosphorus/view/phosphorus_screen.dart index 9e1c304..fadbb7f 100644 --- a/agrilink_vocpro/lib/features/home/detail_pages/phosphorus/view/phosphorus_screen.dart +++ b/agrilink_vocpro/lib/features/home/detail_pages/phosphorus/view/phosphorus_screen.dart @@ -1,7 +1,8 @@ import 'package:agrilink_vocpro/core/constant/app_theme.dart'; import 'package:agrilink_vocpro/core/state/result_state.dart'; +import 'package:agrilink_vocpro/core/widgets/error_data_state_widget.dart'; +import 'package:agrilink_vocpro/core/widgets/no_data_state_widget.dart'; import 'package:agrilink_vocpro/features/home/detail_pages/phosphorus/provider/phosporus_provider.dart'; -import 'package:agrilink_vocpro/features/home/widgets/graphic_error_widget.dart'; import 'package:agrilink_vocpro/features/home/widgets/graphic_widget.dart'; import 'package:bootstrap_icons/bootstrap_icons.dart'; import 'package:flutter/cupertino.dart'; @@ -146,9 +147,9 @@ class PhosphorusScreen extends StatelessWidget { maxValue: 10, ); case ResultState.error: - return const GraphicErrorWidget(message: 'Terjadi Kesalahan'); + return const ErrorDataStateWidget(); case ResultState.noData: - return const GraphicErrorWidget(message: 'Tidak Ada Data'); + return const NoDataStateWidget(); case ResultState.initial: default: return const SizedBox.shrink(); diff --git a/agrilink_vocpro/lib/features/home/detail_pages/potassium/view/potassium_screen.dart b/agrilink_vocpro/lib/features/home/detail_pages/potassium/view/potassium_screen.dart index f9a0f2c..e6f3ecd 100644 --- a/agrilink_vocpro/lib/features/home/detail_pages/potassium/view/potassium_screen.dart +++ b/agrilink_vocpro/lib/features/home/detail_pages/potassium/view/potassium_screen.dart @@ -1,7 +1,8 @@ import 'package:agrilink_vocpro/core/constant/app_theme.dart'; import 'package:agrilink_vocpro/core/state/result_state.dart'; +import 'package:agrilink_vocpro/core/widgets/error_data_state_widget.dart'; +import 'package:agrilink_vocpro/core/widgets/no_data_state_widget.dart'; import 'package:agrilink_vocpro/features/home/detail_pages/potassium/provider/potassium_provider.dart'; -import 'package:agrilink_vocpro/features/home/widgets/graphic_error_widget.dart'; import 'package:agrilink_vocpro/features/home/widgets/graphic_widget.dart'; import 'package:bootstrap_icons/bootstrap_icons.dart'; import 'package:flutter/cupertino.dart'; @@ -146,9 +147,9 @@ class PotassiumScreen extends StatelessWidget { maxValue: 1, ); case ResultState.error: - return const GraphicErrorWidget(message: 'Terjadi Kesalahan'); + return const ErrorDataStateWidget(); case ResultState.noData: - return const GraphicErrorWidget(message: 'Tidak Ada Data'); + return const NoDataStateWidget(); case ResultState.initial: default: return const SizedBox.shrink(); diff --git a/agrilink_vocpro/lib/features/home/detail_pages/soil_moisture/view/soil_moisture_screen.dart b/agrilink_vocpro/lib/features/home/detail_pages/soil_moisture/view/soil_moisture_screen.dart index 451b1f6..9a45447 100644 --- a/agrilink_vocpro/lib/features/home/detail_pages/soil_moisture/view/soil_moisture_screen.dart +++ b/agrilink_vocpro/lib/features/home/detail_pages/soil_moisture/view/soil_moisture_screen.dart @@ -1,7 +1,8 @@ import 'package:agrilink_vocpro/core/constant/app_theme.dart'; import 'package:agrilink_vocpro/core/state/result_state.dart'; +import 'package:agrilink_vocpro/core/widgets/error_data_state_widget.dart'; +import 'package:agrilink_vocpro/core/widgets/no_data_state_widget.dart'; import 'package:agrilink_vocpro/features/home/detail_pages/soil_moisture/provider/soil_moisture_provider.dart'; -import 'package:agrilink_vocpro/features/home/widgets/graphic_error_widget.dart'; import 'package:agrilink_vocpro/features/home/widgets/graphic_widget.dart'; import 'package:bootstrap_icons/bootstrap_icons.dart'; import 'package:flutter/cupertino.dart'; @@ -176,9 +177,9 @@ class SoilMoistureScreen extends StatelessWidget { maxValue: 1, ); case ResultState.error: - return const GraphicErrorWidget(message: 'Terjadi Kesalahan'); + return const ErrorDataStateWidget(); case ResultState.noData: - return const GraphicErrorWidget(message: 'Tidak Ada Data'); + return const NoDataStateWidget(); case ResultState.initial: default: return const SizedBox.shrink(); diff --git a/agrilink_vocpro/lib/features/home/detail_pages/soil_temperature/view/soil_temperature_screen.dart b/agrilink_vocpro/lib/features/home/detail_pages/soil_temperature/view/soil_temperature_screen.dart index 02ee21b..6c6284c 100644 --- a/agrilink_vocpro/lib/features/home/detail_pages/soil_temperature/view/soil_temperature_screen.dart +++ b/agrilink_vocpro/lib/features/home/detail_pages/soil_temperature/view/soil_temperature_screen.dart @@ -1,4 +1,5 @@ -import 'package:agrilink_vocpro/features/home/widgets/graphic_error_widget.dart'; +import 'package:agrilink_vocpro/core/widgets/error_data_state_widget.dart'; +import 'package:agrilink_vocpro/core/widgets/no_data_state_widget.dart'; import 'package:flutter/material.dart'; import 'package:bootstrap_icons/bootstrap_icons.dart'; import 'package:flutter/cupertino.dart'; @@ -226,9 +227,9 @@ class SoilTemperatureScreen extends StatelessWidget { maxValue: 70, ); case ResultState.error: - return const GraphicErrorWidget(message: 'Terjadi Kesalahan'); + return const ErrorDataStateWidget(); case ResultState.noData: - return const GraphicErrorWidget(message: 'Tidak Ada Data'); + return const NoDataStateWidget(); case ResultState.initial: default: return const SizedBox.shrink(); diff --git a/agrilink_vocpro/lib/features/home/detail_pages/temperature/view/temperature_screen.dart b/agrilink_vocpro/lib/features/home/detail_pages/temperature/view/temperature_screen.dart index df4ce7c..a5f1968 100644 --- a/agrilink_vocpro/lib/features/home/detail_pages/temperature/view/temperature_screen.dart +++ b/agrilink_vocpro/lib/features/home/detail_pages/temperature/view/temperature_screen.dart @@ -1,5 +1,7 @@ import 'package:agrilink_vocpro/core/constant/app_theme.dart'; import 'package:agrilink_vocpro/core/state/result_state.dart'; +import 'package:agrilink_vocpro/core/widgets/error_data_state_widget.dart'; +import 'package:agrilink_vocpro/core/widgets/no_data_state_widget.dart'; import 'package:agrilink_vocpro/features/home/detail_pages/temperature/provider/temp_provider.dart'; import 'package:agrilink_vocpro/features/home/widgets/graphic_widget.dart'; import 'package:bootstrap_icons/bootstrap_icons.dart'; @@ -30,7 +32,7 @@ class TemperatureScreen extends StatelessWidget { padding: EdgeInsets.only(right: 16), child: Icon( BootstrapIcons.thermometer_half, - color: Colors.red, + color: Colors.orange, ), ) ], @@ -228,39 +230,9 @@ class TemperatureScreen extends StatelessWidget { 0), ); case ResultState.error: - return Center( - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Icon( - BootstrapIcons.exclamation_circle, - color: Colors.grey.shade400, - ), - SizedBox(height: 8.h), - Text( - 'Terjadi Kesalahan', - style: AppTheme.labelSmall, - ), - ], - ), - ); + return ErrorDataStateWidget(); case ResultState.noData: - return Center( - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Icon( - BootstrapIcons.database_fill_x, - color: Colors.grey.shade400, - ), - SizedBox(height: 8.h), - Text( - 'Tidak Ada Data', - style: AppTheme.labelSmall, - ), - ], - ), - ); + return NoDataStateWidget(); case ResultState.initial: return const SizedBox.shrink(); default: diff --git a/agrilink_vocpro/lib/features/home/widgets/list_data_from_censor_dht.dart b/agrilink_vocpro/lib/features/home/widgets/list_data_from_censor_dht.dart index a95ecb1..f4aa3b0 100644 --- a/agrilink_vocpro/lib/features/home/widgets/list_data_from_censor_dht.dart +++ b/agrilink_vocpro/lib/features/home/widgets/list_data_from_censor_dht.dart @@ -54,7 +54,7 @@ class ListDataFromCensorDht extends StatelessWidget { unit: '%', icon: BootstrapIcons.droplet_half, color: Colors.white, - censorIdentifier: 'NPK 1', + censorIdentifier: 'DHT', onTap: () async { await context .push('${AppRoute.humidity}/${provider.dhtHumidity}'); @@ -67,6 +67,7 @@ class ListDataFromCensorDht extends StatelessWidget { unit: '°C', icon: BootstrapIcons.thermometer_half, color: Colors.white, + censorIdentifier: 'DHT', onTap: () async { await context.push( '${AppRoute.temperature}/${provider.dhtTemperature}'); @@ -79,6 +80,7 @@ class ListDataFromCensorDht extends StatelessWidget { unit: 'lux', icon: BootstrapIcons.sun, color: Colors.white, + censorIdentifier: 'DHT', onTap: () async { await context .push('${AppRoute.light}/${provider.dhtLuminosity}'); diff --git a/agrilink_vocpro/lib/features/home/widgets/list_data_from_censor_npk1.dart b/agrilink_vocpro/lib/features/home/widgets/list_data_from_censor_npk1.dart index c715e83..1e24e6d 100644 --- a/agrilink_vocpro/lib/features/home/widgets/list_data_from_censor_npk1.dart +++ b/agrilink_vocpro/lib/features/home/widgets/list_data_from_censor_npk1.dart @@ -55,6 +55,7 @@ class ListDataFromCensorNpk1 extends StatelessWidget { textColor: Colors.white, color: AppColor.secondary, iconColor: Colors.white, + censorIdentifier: censorIdentifier, onTap: () async { await context.push( '${AppRoute.nitrogen}/${provider.npk2SoilNitrogen}/${provider.npk1SoilNitrogen}'); @@ -69,6 +70,7 @@ class ListDataFromCensorNpk1 extends StatelessWidget { textColor: Colors.white, color: AppColor.secondary, iconColor: Colors.white, + censorIdentifier: censorIdentifier, onTap: () async { await context.push( '${AppRoute.phosphorus}/${provider.npk1SoilPhosphorus}/${provider.npk2SoilPhosphorus}'); @@ -83,6 +85,7 @@ class ListDataFromCensorNpk1 extends StatelessWidget { textColor: Colors.white, color: AppColor.secondary, iconColor: Colors.white, + censorIdentifier: censorIdentifier, onTap: () async { await context.push( '${AppRoute.potassium}/${provider.npk1SoilPotassium}/${provider.npk2SoilPotassium}'); diff --git a/agrilink_vocpro/lib/features/home/widgets/list_data_from_censor_npk2.dart b/agrilink_vocpro/lib/features/home/widgets/list_data_from_censor_npk2.dart index 5905e9e..326c436 100644 --- a/agrilink_vocpro/lib/features/home/widgets/list_data_from_censor_npk2.dart +++ b/agrilink_vocpro/lib/features/home/widgets/list_data_from_censor_npk2.dart @@ -18,7 +18,7 @@ class ListDataFromCensorNpk2 extends StatelessWidget { @override Widget build(BuildContext context) { - const String censorIdentifier = 'NPK 1'; + const String censorIdentifier = 'NPK 2'; return Consumer(builder: (context, provider, child) { switch (provider.dataState) { case ResultState.loading: @@ -54,6 +54,7 @@ class ListDataFromCensorNpk2 extends StatelessWidget { icon: CupertinoIcons.eyedropper, textColor: Colors.white, color: AppColor.secondary, + censorIdentifier: censorIdentifier, iconColor: Colors.white, onTap: () async { await context.push( @@ -69,6 +70,7 @@ class ListDataFromCensorNpk2 extends StatelessWidget { textColor: Colors.white, color: AppColor.secondary, iconColor: Colors.white, + censorIdentifier: censorIdentifier, onTap: () async { await context.push( '${AppRoute.phosphorus}/${provider.npk1SoilPhosphorus}/${provider.npk2SoilPhosphorus}'); @@ -83,6 +85,7 @@ class ListDataFromCensorNpk2 extends StatelessWidget { textColor: Colors.white, color: AppColor.secondary, iconColor: Colors.white, + censorIdentifier: censorIdentifier, onTap: () async { await context.push( '${AppRoute.potassium}/${provider.npk1SoilPotassium}/${provider.npk2SoilPotassium}'); -- 2.43.0 From b797ac3f5ee6f46d3b98adc65c465f8a99fbdf80 Mon Sep 17 00:00:00 2001 From: Syaroful Date: Wed, 6 Nov 2024 08:54:08 +0700 Subject: [PATCH 06/19] refactor: tidy up ui code --- .../lib/core/widgets/show_info.dart | 27 ------------- .../features/control/view/control_screen.dart | 2 +- .../dashboard/view/dashboard_screen.dart | 8 ++-- .../view/conductivity_screen.dart | 2 +- .../humidity/view/humidity_screen.dart | 38 +++---------------- .../nitrogen/view/nitrogen_screen.dart | 2 +- .../home/detail_pages/ph/view/ph_screen.dart | 2 +- .../phosphorus/view/phosphorus_screen.dart | 2 +- .../potassium/view/potassium_screen.dart | 4 +- .../view/soil_moisture_screen.dart | 3 +- .../view/soil_temperature_screen.dart | 32 ++++++++++++++-- .../temperature/view/temperature_screen.dart | 2 +- .../features/plants/view/plants_screen.dart | 4 +- .../features/setting/view/account_screen.dart | 2 +- .../features/setting/view/setting_screen.dart | 6 +-- 15 files changed, 53 insertions(+), 83 deletions(-) diff --git a/agrilink_vocpro/lib/core/widgets/show_info.dart b/agrilink_vocpro/lib/core/widgets/show_info.dart index 2344d35..8b13789 100644 --- a/agrilink_vocpro/lib/core/widgets/show_info.dart +++ b/agrilink_vocpro/lib/core/widgets/show_info.dart @@ -1,28 +1 @@ -import 'package:flutter/material.dart'; -Future showInfo(BuildContext context, String title, String content) { - return showDialog( - context: context, - builder: (context) => AlertDialog( - content: Column( - mainAxisSize: MainAxisSize.min, - children: [ - Text(title), - const SizedBox(height: 16), - Text( - style: Theme.of(context).textTheme.bodySmall, - content, - ), - ], - ), - actions: [ - TextButton( - onPressed: () { - Navigator.pop(context); - }, - child: const Text('OK'), - ) - ], - ), - ); -} diff --git a/agrilink_vocpro/lib/features/control/view/control_screen.dart b/agrilink_vocpro/lib/features/control/view/control_screen.dart index e6eedbd..0ed74d5 100644 --- a/agrilink_vocpro/lib/features/control/view/control_screen.dart +++ b/agrilink_vocpro/lib/features/control/view/control_screen.dart @@ -16,7 +16,7 @@ class ControlScreen extends StatelessWidget { final provider = Provider.of(context, listen: true); return Scaffold( appBar: AppBar( - title: Text('Control', style: AppTheme.labelMedium), + title: Text('Kontrol', style: AppTheme.labelMedium), centerTitle: true, backgroundColor: Colors.white, scrolledUnderElevation: 0, diff --git a/agrilink_vocpro/lib/features/dashboard/view/dashboard_screen.dart b/agrilink_vocpro/lib/features/dashboard/view/dashboard_screen.dart index 08f98bc..030e4cd 100644 --- a/agrilink_vocpro/lib/features/dashboard/view/dashboard_screen.dart +++ b/agrilink_vocpro/lib/features/dashboard/view/dashboard_screen.dart @@ -26,22 +26,22 @@ class DashboardScreen extends StatelessWidget { BottomNavigationBarItem( icon: Icon(BootstrapIcons.house), activeIcon: Icon(BootstrapIcons.house_fill), - label: 'Home', + label: 'Beranda', ), BottomNavigationBarItem( icon: Icon(BootstrapIcons.toggle_off), activeIcon: Icon(BootstrapIcons.toggle_on), - label: 'Control', + label: 'Kontrol', ), BottomNavigationBarItem( icon: Icon(BootstrapIcons.flower1), activeIcon: Icon(BootstrapIcons.flower1), - label: 'Plants', + label: 'Tanaman', ), BottomNavigationBarItem( icon: Icon(BootstrapIcons.gear), activeIcon: Icon(BootstrapIcons.gear_fill), - label: 'Setting', + label: 'Pengaturan', ), ], ), diff --git a/agrilink_vocpro/lib/features/home/detail_pages/conductivity/view/conductivity_screen.dart b/agrilink_vocpro/lib/features/home/detail_pages/conductivity/view/conductivity_screen.dart index 3be4dbf..0ead696 100644 --- a/agrilink_vocpro/lib/features/home/detail_pages/conductivity/view/conductivity_screen.dart +++ b/agrilink_vocpro/lib/features/home/detail_pages/conductivity/view/conductivity_screen.dart @@ -95,7 +95,7 @@ class ConductivityScreen extends StatelessWidget { mainAxisAlignment: MainAxisAlignment.center, children: [ Text( - 'Soil Condutivity', + 'Konduktifitas Tanah', style: AppTheme.labelMedium, textAlign: TextAlign.center, ), diff --git a/agrilink_vocpro/lib/features/home/detail_pages/humidity/view/humidity_screen.dart b/agrilink_vocpro/lib/features/home/detail_pages/humidity/view/humidity_screen.dart index 8733026..ab15400 100644 --- a/agrilink_vocpro/lib/features/home/detail_pages/humidity/view/humidity_screen.dart +++ b/agrilink_vocpro/lib/features/home/detail_pages/humidity/view/humidity_screen.dart @@ -1,5 +1,7 @@ import 'package:agrilink_vocpro/core/constant/app_theme.dart'; import 'package:agrilink_vocpro/core/state/result_state.dart'; +import 'package:agrilink_vocpro/core/widgets/error_data_state_widget.dart'; +import 'package:agrilink_vocpro/core/widgets/no_data_state_widget.dart'; import 'package:agrilink_vocpro/features/home/detail_pages/humidity/provider/humidity_provider.dart'; import 'package:agrilink_vocpro/features/home/provider/home_provider.dart'; import 'package:agrilink_vocpro/features/home/widgets/graphic_widget.dart'; @@ -94,7 +96,7 @@ class HumidityScreen extends StatelessWidget { mainAxisAlignment: MainAxisAlignment.center, children: [ Text( - 'Humidity', + 'Kelembaban Udara', style: AppTheme.labelMedium, textAlign: TextAlign.center, ), @@ -145,39 +147,9 @@ class HumidityScreen extends StatelessWidget { 0), ); case ResultState.error: - return Center( - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Icon( - BootstrapIcons.exclamation_circle, - color: Colors.grey.shade400, - ), - SizedBox(height: 8.h), - Text( - 'Terjadi Kesalahan', - style: AppTheme.labelSmall, - ), - ], - ), - ); + return const ErrorDataStateWidget(); case ResultState.noData: - return Center( - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Icon( - BootstrapIcons.database_fill_x, - color: Colors.grey.shade400, - ), - SizedBox(height: 8.h), - Text( - 'Tidak Ada Data', - style: AppTheme.labelSmall, - ), - ], - ), - ); + return const NoDataStateWidget(); case ResultState.initial: return const SizedBox.shrink(); default: diff --git a/agrilink_vocpro/lib/features/home/detail_pages/nitrogen/view/nitrogen_screen.dart b/agrilink_vocpro/lib/features/home/detail_pages/nitrogen/view/nitrogen_screen.dart index 2038526..0cae22d 100644 --- a/agrilink_vocpro/lib/features/home/detail_pages/nitrogen/view/nitrogen_screen.dart +++ b/agrilink_vocpro/lib/features/home/detail_pages/nitrogen/view/nitrogen_screen.dart @@ -95,7 +95,7 @@ class NitrogenScreen extends StatelessWidget { mainAxisAlignment: MainAxisAlignment.center, children: [ Text( - 'Soil Nitrogen', + 'Nitrogen Tanah', style: AppTheme.labelMedium, textAlign: TextAlign.center, ), diff --git a/agrilink_vocpro/lib/features/home/detail_pages/ph/view/ph_screen.dart b/agrilink_vocpro/lib/features/home/detail_pages/ph/view/ph_screen.dart index 471e0e6..4412c29 100644 --- a/agrilink_vocpro/lib/features/home/detail_pages/ph/view/ph_screen.dart +++ b/agrilink_vocpro/lib/features/home/detail_pages/ph/view/ph_screen.dart @@ -86,7 +86,7 @@ class PhScreen extends StatelessWidget { mainAxisAlignment: MainAxisAlignment.center, children: [ Text( - 'Soil Acidity', + 'pH Tanah', style: AppTheme.labelMedium, textAlign: TextAlign.center, ), diff --git a/agrilink_vocpro/lib/features/home/detail_pages/phosphorus/view/phosphorus_screen.dart b/agrilink_vocpro/lib/features/home/detail_pages/phosphorus/view/phosphorus_screen.dart index fadbb7f..0664528 100644 --- a/agrilink_vocpro/lib/features/home/detail_pages/phosphorus/view/phosphorus_screen.dart +++ b/agrilink_vocpro/lib/features/home/detail_pages/phosphorus/view/phosphorus_screen.dart @@ -95,7 +95,7 @@ class PhosphorusScreen extends StatelessWidget { mainAxisAlignment: MainAxisAlignment.center, children: [ Text( - 'Soil Phosphorus', + 'Fosfor Tanah', style: AppTheme.labelMedium, textAlign: TextAlign.center, ), diff --git a/agrilink_vocpro/lib/features/home/detail_pages/potassium/view/potassium_screen.dart b/agrilink_vocpro/lib/features/home/detail_pages/potassium/view/potassium_screen.dart index e6f3ecd..b224c6c 100644 --- a/agrilink_vocpro/lib/features/home/detail_pages/potassium/view/potassium_screen.dart +++ b/agrilink_vocpro/lib/features/home/detail_pages/potassium/view/potassium_screen.dart @@ -25,7 +25,7 @@ class PotassiumScreen extends StatelessWidget { length: 2, child: Scaffold( appBar: AppBar( - title: Text('Soil Potassium', style: AppTheme.labelMedium), + title: Text('Soil Potassium (Kalium)', style: AppTheme.labelMedium), centerTitle: true, backgroundColor: Colors.white, scrolledUnderElevation: 0, @@ -95,7 +95,7 @@ class PotassiumScreen extends StatelessWidget { mainAxisAlignment: MainAxisAlignment.center, children: [ Text( - 'Soil Potassium', + 'Kalium Tanah', style: AppTheme.labelMedium, textAlign: TextAlign.center, ), diff --git a/agrilink_vocpro/lib/features/home/detail_pages/soil_moisture/view/soil_moisture_screen.dart b/agrilink_vocpro/lib/features/home/detail_pages/soil_moisture/view/soil_moisture_screen.dart index 9a45447..209e00d 100644 --- a/agrilink_vocpro/lib/features/home/detail_pages/soil_moisture/view/soil_moisture_screen.dart +++ b/agrilink_vocpro/lib/features/home/detail_pages/soil_moisture/view/soil_moisture_screen.dart @@ -125,7 +125,7 @@ class SoilMoistureScreen extends StatelessWidget { mainAxisAlignment: MainAxisAlignment.center, children: [ Text( - 'Soil Moisture', + 'Kelembaban Tanah', style: AppTheme.labelMedium, textAlign: TextAlign.center, ), @@ -151,7 +151,6 @@ class SoilMoistureScreen extends StatelessWidget { child: Consumer( builder: (context, provider, child) { final dataState = provider.dataState; - switch (dataState) { case ResultState.loading: return const Center(child: CupertinoActivityIndicator()); diff --git a/agrilink_vocpro/lib/features/home/detail_pages/soil_temperature/view/soil_temperature_screen.dart b/agrilink_vocpro/lib/features/home/detail_pages/soil_temperature/view/soil_temperature_screen.dart index 6c6284c..ff35554 100644 --- a/agrilink_vocpro/lib/features/home/detail_pages/soil_temperature/view/soil_temperature_screen.dart +++ b/agrilink_vocpro/lib/features/home/detail_pages/soil_temperature/view/soil_temperature_screen.dart @@ -7,7 +7,6 @@ import 'package:provider/provider.dart'; import 'package:agrilink_vocpro/core/constant/app_constant.dart'; import 'package:agrilink_vocpro/core/constant/app_theme.dart'; import 'package:agrilink_vocpro/core/state/result_state.dart'; -import 'package:agrilink_vocpro/core/widgets/show_info.dart'; import 'package:agrilink_vocpro/features/home/detail_pages/soil_temperature/provider/soil_temp_provider.dart'; import 'package:agrilink_vocpro/features/home/widgets/graphic_widget.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; @@ -172,7 +171,7 @@ class SoilTemperatureScreen extends StatelessWidget { mainAxisAlignment: MainAxisAlignment.center, children: [ Text( - 'Soil Temperature', + 'Suhu Tanah', style: AppTheme.labelMedium, textAlign: TextAlign.center, ), @@ -180,7 +179,7 @@ class SoilTemperatureScreen extends StatelessWidget { iconSize: 20.r, color: Colors.blue, onPressed: () { - showInfo(context, 'Soil Temperature', AppConstant.soilTempInfo); + showInfo(context, 'Suhu Tanah', AppConstant.soilTempInfo); }, icon: const Icon(BootstrapIcons.info_circle), ), @@ -240,3 +239,30 @@ class SoilTemperatureScreen extends StatelessWidget { ); } } + +Future showInfo(BuildContext context, String title, String content) { + return showDialog( + context: context, + builder: (context) => AlertDialog( + content: Column( + mainAxisSize: MainAxisSize.min, + children: [ + Text(title), + const SizedBox(height: 16), + Text( + style: Theme.of(context).textTheme.bodySmall, + content, + ), + ], + ), + actions: [ + TextButton( + onPressed: () { + Navigator.pop(context); + }, + child: const Text('OK'), + ) + ], + ), + ); +} diff --git a/agrilink_vocpro/lib/features/home/detail_pages/temperature/view/temperature_screen.dart b/agrilink_vocpro/lib/features/home/detail_pages/temperature/view/temperature_screen.dart index a5f1968..c4bf2e5 100644 --- a/agrilink_vocpro/lib/features/home/detail_pages/temperature/view/temperature_screen.dart +++ b/agrilink_vocpro/lib/features/home/detail_pages/temperature/view/temperature_screen.dart @@ -98,7 +98,7 @@ class TemperatureScreen extends StatelessWidget { mainAxisAlignment: MainAxisAlignment.center, children: [ Text( - 'Temperature', + 'Suhu Ruangan', style: AppTheme.labelMedium, textAlign: TextAlign.center, ), diff --git a/agrilink_vocpro/lib/features/plants/view/plants_screen.dart b/agrilink_vocpro/lib/features/plants/view/plants_screen.dart index 1a5d423..8254d73 100644 --- a/agrilink_vocpro/lib/features/plants/view/plants_screen.dart +++ b/agrilink_vocpro/lib/features/plants/view/plants_screen.dart @@ -15,10 +15,10 @@ class PlantsScreen extends StatelessWidget { mainAxisAlignment: MainAxisAlignment.center, children: [ Icon(Icons.eco_rounded, size: 100.r, color: AppColor.secondary), - Text('Coming Soon', style: AppTheme.titleLarge), + Text('Segera Hadir', style: AppTheme.titleLarge), SizedBox(height: 8.h), Text( - 'This featureis under development', + 'Fitur ini sedang dalam tahap pengembangan', textAlign: TextAlign.center, style: AppTheme.labelSmall, ), diff --git a/agrilink_vocpro/lib/features/setting/view/account_screen.dart b/agrilink_vocpro/lib/features/setting/view/account_screen.dart index 3553acc..902118c 100644 --- a/agrilink_vocpro/lib/features/setting/view/account_screen.dart +++ b/agrilink_vocpro/lib/features/setting/view/account_screen.dart @@ -11,7 +11,7 @@ class AccountScreen extends StatelessWidget { Widget build(BuildContext context) { return Scaffold( appBar: AppBar( - title: Text('Detail Account', style: AppTheme.labelMedium), + title: Text('Detail Akun', style: AppTheme.labelMedium), centerTitle: true, backgroundColor: Colors.white, scrolledUnderElevation: 0, diff --git a/agrilink_vocpro/lib/features/setting/view/setting_screen.dart b/agrilink_vocpro/lib/features/setting/view/setting_screen.dart index 197a1af..5aabaf3 100644 --- a/agrilink_vocpro/lib/features/setting/view/setting_screen.dart +++ b/agrilink_vocpro/lib/features/setting/view/setting_screen.dart @@ -16,7 +16,7 @@ class SettingScreen extends StatelessWidget { Widget build(BuildContext context) { return Scaffold( appBar: AppBar( - title: Text('Setting', style: AppTheme.labelMedium), + title: Text('Pengaturan', style: AppTheme.labelMedium), centerTitle: true, backgroundColor: Colors.white, scrolledUnderElevation: 0, @@ -52,7 +52,7 @@ class SettingScreen extends StatelessWidget { children: [ ListTile( tileColor: Colors.white, - title: Text('Account', + title: Text('Akun', style: AppTheme.labelSmall .copyWith(color: Colors.black87)), leading: const Icon(BootstrapIcons.person), @@ -90,7 +90,7 @@ class SettingScreen extends StatelessWidget { // ), ListTile( tileColor: Colors.white, - title: Text('Logout', + title: Text('Keluar', style: AppTheme.labelSmall.copyWith(color: Colors.red)), leading: const Icon( BootstrapIcons.box_arrow_right, -- 2.43.0 From adb647235d245bb799add8ce9a49ec1b42b2d334 Mon Sep 17 00:00:00 2001 From: Syaroful Date: Wed, 6 Nov 2024 08:55:52 +0700 Subject: [PATCH 07/19] refactor: change String --- .../home/detail_pages/humidity/view/humidity_screen.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/agrilink_vocpro/lib/features/home/detail_pages/humidity/view/humidity_screen.dart b/agrilink_vocpro/lib/features/home/detail_pages/humidity/view/humidity_screen.dart index ab15400..447b4a7 100644 --- a/agrilink_vocpro/lib/features/home/detail_pages/humidity/view/humidity_screen.dart +++ b/agrilink_vocpro/lib/features/home/detail_pages/humidity/view/humidity_screen.dart @@ -110,7 +110,7 @@ class HumidityScreen extends StatelessWidget { const SizedBox(height: 16), Padding( padding: EdgeInsets.only(left: 16.w), - child: const Text('Grafik dalam 7 hari terakhir'), + child: const Text('Grafik'), ), const SizedBox(height: 16), AspectRatio( -- 2.43.0 From 949603ecfa6fb72919423f5b857c6eae7bd743c9 Mon Sep 17 00:00:00 2001 From: Syaroful Date: Wed, 6 Nov 2024 09:09:05 +0700 Subject: [PATCH 08/19] refactor: tidy up hardcoded --- .../lib/core/constant/app_constant.dart | 16 ++++++++-------- .../provider/conductivity_provider.dart | 13 +++++++------ .../humidity/provider/humidity_provider.dart | 3 ++- .../luminosity/provider/lum_provider.dart | 5 +++-- .../nitrogen/provider/nitrogen_provider.dart | 5 +++-- .../detail_pages/ph/provider/ph_provider.dart | 11 +++++++---- .../phosphorus/provider/phosporus_provider.dart | 9 +++++---- .../potassium/provider/potassium_provider.dart | 9 +++++---- .../provider/soil_moisture_provider.dart | 9 +++++---- .../provider/soil_temp_provider.dart | 5 +++-- 10 files changed, 48 insertions(+), 37 deletions(-) diff --git a/agrilink_vocpro/lib/core/constant/app_constant.dart b/agrilink_vocpro/lib/core/constant/app_constant.dart index 3c93688..f7ab4eb 100644 --- a/agrilink_vocpro/lib/core/constant/app_constant.dart +++ b/agrilink_vocpro/lib/core/constant/app_constant.dart @@ -22,13 +22,13 @@ class AppConstant { static const String dht = 'dht'; static const String soilTemp = 'soilTemperature'; - static const String soilMoisture = 'soilMoisture'; + static const String soilMoisture = 'soilHumidity'; static const String airTemp = 'viciTemperature'; - static const String humidity = 'humidity'; - static const String lightIntensity = 'lightIntensity'; - static const String conductivity = 'conductivity'; - static const String ph = 'ph'; - static const String nitrogen = 'nitrogen'; - static const String phosphorus = 'phosphorus'; - static const String potassium = 'potassium'; + static const String humidity = 'viciHumidity'; + static const String lightIntensity = 'viciluminosity'; + static const String conductivity = 'soilConductivity'; + static const String ph = 'soilPh'; + static const String nitrogen = 'soilNitrogen'; + static const String phosphorus = 'soilPhosphorus'; + static const String potassium = 'soilPotassium'; } diff --git a/agrilink_vocpro/lib/features/home/detail_pages/conductivity/provider/conductivity_provider.dart b/agrilink_vocpro/lib/features/home/detail_pages/conductivity/provider/conductivity_provider.dart index 50c6969..ae5a525 100644 --- a/agrilink_vocpro/lib/features/home/detail_pages/conductivity/provider/conductivity_provider.dart +++ b/agrilink_vocpro/lib/features/home/detail_pages/conductivity/provider/conductivity_provider.dart @@ -1,3 +1,4 @@ +import 'package:agrilink_vocpro/core/constant/app_constant.dart'; import 'package:agrilink_vocpro/core/state/result_state.dart'; import 'package:agrilink_vocpro/data/model/latest_data_response.dart'; import 'package:agrilink_vocpro/domain/service/app_service.dart'; @@ -17,8 +18,8 @@ class ConductivityProvider extends ChangeNotifier { dataState = ResultState.loading; notifyListeners(); try { - final result = - await AppService().getGraphicDataNpk1(metric: 'soilConductivity'); + final result = await AppService() + .getGraphicDataNpk1(metric: AppConstant.conductivity); if (result.data == null || result.data!.npk1!.isEmpty) { dataState = ResultState.noData; } else { @@ -27,7 +28,7 @@ class ConductivityProvider extends ChangeNotifier { } } catch (e) { if (kDebugMode) { - print('Get Grafik Soil Temp Error: $e'); + print('Get Grafik Conductivity Error: $e'); } dataState = ResultState.error; } @@ -38,8 +39,8 @@ class ConductivityProvider extends ChangeNotifier { dataState = ResultState.loading; notifyListeners(); try { - final result = - await AppService().getGraphicDataNpk2(metric: 'soilConductivity'); + final result = await AppService() + .getGraphicDataNpk2(metric: AppConstant.conductivity); if (result.data == null || result.data!.npk2!.isEmpty) { dataState = ResultState.noData; } else { @@ -48,7 +49,7 @@ class ConductivityProvider extends ChangeNotifier { } } catch (e) { if (kDebugMode) { - print('Get Grafik Soil Temp Error: $e'); + print('Get Grafik Conductivity Error: $e'); } dataState = ResultState.error; } diff --git a/agrilink_vocpro/lib/features/home/detail_pages/humidity/provider/humidity_provider.dart b/agrilink_vocpro/lib/features/home/detail_pages/humidity/provider/humidity_provider.dart index 36a2050..03d7705 100644 --- a/agrilink_vocpro/lib/features/home/detail_pages/humidity/provider/humidity_provider.dart +++ b/agrilink_vocpro/lib/features/home/detail_pages/humidity/provider/humidity_provider.dart @@ -1,3 +1,4 @@ +import 'package:agrilink_vocpro/core/constant/app_constant.dart'; import 'package:agrilink_vocpro/core/state/result_state.dart'; import 'package:agrilink_vocpro/data/model/latest_data_response.dart'; import 'package:agrilink_vocpro/domain/service/app_service.dart'; @@ -16,7 +17,7 @@ class HumidityProvider extends ChangeNotifier { notifyListeners(); try { final result = - await AppService().getGrafikDataDht(metric: 'viciHumidity'); + await AppService().getGrafikDataDht(metric: AppConstant.humidity); if (result.data == null || result.data!.dht!.isEmpty) { dataState = ResultState.noData; } else { diff --git a/agrilink_vocpro/lib/features/home/detail_pages/luminosity/provider/lum_provider.dart b/agrilink_vocpro/lib/features/home/detail_pages/luminosity/provider/lum_provider.dart index ccad851..fa38e05 100644 --- a/agrilink_vocpro/lib/features/home/detail_pages/luminosity/provider/lum_provider.dart +++ b/agrilink_vocpro/lib/features/home/detail_pages/luminosity/provider/lum_provider.dart @@ -1,3 +1,4 @@ +import 'package:agrilink_vocpro/core/constant/app_constant.dart'; import 'package:agrilink_vocpro/core/state/result_state.dart'; import 'package:agrilink_vocpro/data/model/latest_data_response.dart'; import 'package:agrilink_vocpro/domain/service/app_service.dart'; @@ -15,8 +16,8 @@ class LumProvider extends ChangeNotifier { dataState = ResultState.loading; notifyListeners(); try { - final result = - await AppService().getGrafikDataDht(metric: 'viciluminosity'); + final result = await AppService() + .getGrafikDataDht(metric: AppConstant.lightIntensity); if (result.data == null || result.data!.dht!.isEmpty) { dataState = ResultState.noData; } else { diff --git a/agrilink_vocpro/lib/features/home/detail_pages/nitrogen/provider/nitrogen_provider.dart b/agrilink_vocpro/lib/features/home/detail_pages/nitrogen/provider/nitrogen_provider.dart index 7b1da62..93f2841 100644 --- a/agrilink_vocpro/lib/features/home/detail_pages/nitrogen/provider/nitrogen_provider.dart +++ b/agrilink_vocpro/lib/features/home/detail_pages/nitrogen/provider/nitrogen_provider.dart @@ -1,3 +1,4 @@ +import 'package:agrilink_vocpro/core/constant/app_constant.dart'; import 'package:agrilink_vocpro/core/state/result_state.dart'; import 'package:agrilink_vocpro/data/model/latest_data_response.dart'; import 'package:agrilink_vocpro/domain/service/app_service.dart'; @@ -18,7 +19,7 @@ class NitrogenProvider extends ChangeNotifier { notifyListeners(); try { final result = - await AppService().getGraphicDataNpk1(metric: 'soilNitrogen'); + await AppService().getGraphicDataNpk1(metric: AppConstant.nitrogen); if (result.data == null || result.data!.npk1!.isEmpty) { dataState = ResultState.noData; } else { @@ -39,7 +40,7 @@ class NitrogenProvider extends ChangeNotifier { notifyListeners(); try { final result = - await AppService().getGraphicDataNpk2(metric: 'soilNitrogen'); + await AppService().getGraphicDataNpk2(metric: AppConstant.nitrogen); if (result.data == null || result.data!.npk2!.isEmpty) { dataState = ResultState.noData; } else { diff --git a/agrilink_vocpro/lib/features/home/detail_pages/ph/provider/ph_provider.dart b/agrilink_vocpro/lib/features/home/detail_pages/ph/provider/ph_provider.dart index 8b8c66b..5050a37 100644 --- a/agrilink_vocpro/lib/features/home/detail_pages/ph/provider/ph_provider.dart +++ b/agrilink_vocpro/lib/features/home/detail_pages/ph/provider/ph_provider.dart @@ -1,3 +1,4 @@ +import 'package:agrilink_vocpro/core/constant/app_constant.dart'; import 'package:agrilink_vocpro/core/state/result_state.dart'; import 'package:agrilink_vocpro/data/model/latest_data_response.dart'; import 'package:agrilink_vocpro/domain/service/app_service.dart'; @@ -17,7 +18,8 @@ class PhProvider extends ChangeNotifier { dataState = ResultState.loading; notifyListeners(); try { - final result = await AppService().getGraphicDataNpk1(metric: 'soilPh'); + final result = + await AppService().getGraphicDataNpk1(metric: AppConstant.ph); if (result.data == null || result.data!.npk1!.isEmpty) { dataState = ResultState.noData; } else { @@ -26,7 +28,7 @@ class PhProvider extends ChangeNotifier { } } catch (e) { if (kDebugMode) { - print('Get Grafik Soil Temp Error: $e'); + print('Get Grafik Soil pH Error: $e'); } dataState = ResultState.error; } @@ -37,7 +39,8 @@ class PhProvider extends ChangeNotifier { dataState = ResultState.loading; notifyListeners(); try { - final result = await AppService().getGraphicDataNpk2(metric: 'soilPh'); + final result = + await AppService().getGraphicDataNpk2(metric: AppConstant.ph); if (result.data == null || result.data!.npk2!.isEmpty) { dataState = ResultState.noData; } else { @@ -46,7 +49,7 @@ class PhProvider extends ChangeNotifier { } } catch (e) { if (kDebugMode) { - print('Get Grafik Soil Temp Error: $e'); + print('Get Grafik Soil pH Error: $e'); } dataState = ResultState.error; } diff --git a/agrilink_vocpro/lib/features/home/detail_pages/phosphorus/provider/phosporus_provider.dart b/agrilink_vocpro/lib/features/home/detail_pages/phosphorus/provider/phosporus_provider.dart index 158db16..e36e934 100644 --- a/agrilink_vocpro/lib/features/home/detail_pages/phosphorus/provider/phosporus_provider.dart +++ b/agrilink_vocpro/lib/features/home/detail_pages/phosphorus/provider/phosporus_provider.dart @@ -1,3 +1,4 @@ +import 'package:agrilink_vocpro/core/constant/app_constant.dart'; import 'package:agrilink_vocpro/core/state/result_state.dart'; import 'package:agrilink_vocpro/data/model/latest_data_response.dart'; import 'package:agrilink_vocpro/domain/service/app_service.dart'; @@ -18,7 +19,7 @@ class PhosporusProvider extends ChangeNotifier { notifyListeners(); try { final result = - await AppService().getGraphicDataNpk1(metric: 'soilPhosphorus'); + await AppService().getGraphicDataNpk1(metric: AppConstant.phosphorus); if (result.data == null || result.data!.npk1!.isEmpty) { dataState = ResultState.noData; } else { @@ -27,7 +28,7 @@ class PhosporusProvider extends ChangeNotifier { } } catch (e) { if (kDebugMode) { - print('Get Grafik Soil Temp Error: $e'); + print('Get Grafik Phosphor Error: $e'); } dataState = ResultState.error; } @@ -39,7 +40,7 @@ class PhosporusProvider extends ChangeNotifier { notifyListeners(); try { final result = - await AppService().getGraphicDataNpk2(metric: 'soilPhosphorus'); + await AppService().getGraphicDataNpk2(metric: AppConstant.phosphorus); if (result.data == null || result.data!.npk2!.isEmpty) { dataState = ResultState.noData; } else { @@ -48,7 +49,7 @@ class PhosporusProvider extends ChangeNotifier { } } catch (e) { if (kDebugMode) { - print('Get Grafik Soil Temp Error: $e'); + print('Get Grafik Phosphor Error: $e'); } dataState = ResultState.error; } diff --git a/agrilink_vocpro/lib/features/home/detail_pages/potassium/provider/potassium_provider.dart b/agrilink_vocpro/lib/features/home/detail_pages/potassium/provider/potassium_provider.dart index a771937..1591347 100644 --- a/agrilink_vocpro/lib/features/home/detail_pages/potassium/provider/potassium_provider.dart +++ b/agrilink_vocpro/lib/features/home/detail_pages/potassium/provider/potassium_provider.dart @@ -1,3 +1,4 @@ +import 'package:agrilink_vocpro/core/constant/app_constant.dart'; import 'package:agrilink_vocpro/core/state/result_state.dart'; import 'package:agrilink_vocpro/data/model/latest_data_response.dart'; import 'package:agrilink_vocpro/domain/service/app_service.dart'; @@ -18,7 +19,7 @@ class PotassiumProvider extends ChangeNotifier { notifyListeners(); try { final result = - await AppService().getGraphicDataNpk1(metric: 'soilPotassium'); + await AppService().getGraphicDataNpk1(metric: AppConstant.potassium); if (result.data == null || result.data!.npk1!.isEmpty) { dataState = ResultState.noData; } else { @@ -27,7 +28,7 @@ class PotassiumProvider extends ChangeNotifier { } } catch (e) { if (kDebugMode) { - print('Get Grafik Soil Temp Error: $e'); + print('Get Grafik Potassium Error: $e'); } dataState = ResultState.error; } @@ -39,7 +40,7 @@ class PotassiumProvider extends ChangeNotifier { notifyListeners(); try { final result = - await AppService().getGraphicDataNpk2(metric: 'soilPotassium'); + await AppService().getGraphicDataNpk2(metric: AppConstant.potassium); if (result.data == null || result.data!.npk2!.isEmpty) { dataState = ResultState.noData; } else { @@ -48,7 +49,7 @@ class PotassiumProvider extends ChangeNotifier { } } catch (e) { if (kDebugMode) { - print('Get Grafik Soil Temp Error: $e'); + print('Get Grafik Potassium Error: $e'); } dataState = ResultState.error; } diff --git a/agrilink_vocpro/lib/features/home/detail_pages/soil_moisture/provider/soil_moisture_provider.dart b/agrilink_vocpro/lib/features/home/detail_pages/soil_moisture/provider/soil_moisture_provider.dart index f0ecba4..13a4f7d 100644 --- a/agrilink_vocpro/lib/features/home/detail_pages/soil_moisture/provider/soil_moisture_provider.dart +++ b/agrilink_vocpro/lib/features/home/detail_pages/soil_moisture/provider/soil_moisture_provider.dart @@ -1,3 +1,4 @@ +import 'package:agrilink_vocpro/core/constant/app_constant.dart'; import 'package:agrilink_vocpro/core/state/result_state.dart'; import 'package:agrilink_vocpro/data/model/latest_data_response.dart'; import 'package:agrilink_vocpro/domain/service/app_service.dart'; @@ -17,8 +18,8 @@ class SoilMoistureProvider extends ChangeNotifier { dataState = ResultState.loading; notifyListeners(); try { - final result = - await AppService().getGraphicDataNpk1(metric: 'soilhumidity'); + final result = await AppService() + .getGraphicDataNpk1(metric: AppConstant.soilMoisture); if (result.data == null || result.data!.npk1!.isEmpty) { dataState = ResultState.noData; } else { @@ -38,8 +39,8 @@ class SoilMoistureProvider extends ChangeNotifier { dataState = ResultState.loading; notifyListeners(); try { - final result = - await AppService().getGraphicDataNpk2(metric: 'soilhumidity'); + final result = await AppService() + .getGraphicDataNpk2(metric: AppConstant.soilMoisture); if (result.data == null || result.data!.npk2!.isEmpty) { dataState = ResultState.noData; } else { diff --git a/agrilink_vocpro/lib/features/home/detail_pages/soil_temperature/provider/soil_temp_provider.dart b/agrilink_vocpro/lib/features/home/detail_pages/soil_temperature/provider/soil_temp_provider.dart index 5c95391..66d5ea7 100644 --- a/agrilink_vocpro/lib/features/home/detail_pages/soil_temperature/provider/soil_temp_provider.dart +++ b/agrilink_vocpro/lib/features/home/detail_pages/soil_temperature/provider/soil_temp_provider.dart @@ -1,3 +1,4 @@ +import 'package:agrilink_vocpro/core/constant/app_constant.dart'; import 'package:agrilink_vocpro/core/state/result_state.dart'; import 'package:agrilink_vocpro/data/model/latest_data_response.dart'; import 'package:agrilink_vocpro/domain/service/app_service.dart'; @@ -18,7 +19,7 @@ class SoilTempProvider extends ChangeNotifier { notifyListeners(); try { final result = - await AppService().getGraphicDataNpk1(metric: 'soilTemperature'); + await AppService().getGraphicDataNpk1(metric: AppConstant.soilTemp); if (result.data == null || result.data!.npk1!.isEmpty) { dataState = ResultState.noData; } else { @@ -39,7 +40,7 @@ class SoilTempProvider extends ChangeNotifier { notifyListeners(); try { final result = - await AppService().getGraphicDataNpk2(metric: 'soilTemperature'); + await AppService().getGraphicDataNpk2(metric: AppConstant.soilTemp); if (result.data == null || result.data!.npk2!.isEmpty) { dataState = ResultState.noData; } else { -- 2.43.0 From 0e2b194e20a70835dfe144de38ef25a0f7265940 Mon Sep 17 00:00:00 2001 From: Syaroful Date: Wed, 6 Nov 2024 09:11:44 +0700 Subject: [PATCH 09/19] refactor: tidy up code --- agrilink_vocpro/lib/features/auth/view/login_screen.dart | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/agrilink_vocpro/lib/features/auth/view/login_screen.dart b/agrilink_vocpro/lib/features/auth/view/login_screen.dart index 53d6ed9..1418622 100644 --- a/agrilink_vocpro/lib/features/auth/view/login_screen.dart +++ b/agrilink_vocpro/lib/features/auth/view/login_screen.dart @@ -23,15 +23,15 @@ class LoginScreen extends StatelessWidget { children: [ const SizedBox(height: 40), Text( - 'Hello, Welcome back 👋', + 'Halo, Selamat Datang 👋', style: AppTheme.titleLarge, ), Text( - 'Happy to have you back', + 'Senang melihatmu kembali', style: AppTheme.titleMedium, ), const SizedBox(height: 40), - Text('Email address', style: AppTheme.labelLarge), + Text('Alamat Email', style: AppTheme.labelLarge), const SizedBox(height: 4), AppTextfield( controller: authP.emailController, -- 2.43.0 From ecfd6e71453df58259396e3534026ede21fc2a55 Mon Sep 17 00:00:00 2001 From: Syaroful Date: Wed, 6 Nov 2024 09:19:40 +0700 Subject: [PATCH 10/19] update: readme for logbook --- README.md | 38 ++++++++++++++++++++++++++++++-------- 1 file changed, 30 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 063adaf..0635004 100644 --- a/README.md +++ b/README.md @@ -75,14 +75,36 @@ Berikan deskripsi singkat tentang struktur folder dan file penting di dalam proy ## Progress Report -| Date | Type | Description | -|------------|-------|-----------------------------------------------------------------------------------------------------| -| 2024-10-09 | feat | Completed the integration of MQTT for sensor data and IoT device control. | -| 2024-10-02 | fix | Implemented auto-reconnect for MQTT on app open/close. | -| 2024-09-30 | feat | Added UI for displaying soil pH level with a linear bar. | -| 2024-09-27 | feat | Finalized group display for 'Doses' in ExpansionTile for medicine dosage recommendations. | -| 2024-09-24 | feat | Completed sorting dialog functionality with single sorter selection capability. | -| 2024-09-20 | feat | Implemented patient data creation form with validation and state management using dialogs. | +| Date | Type | Description | +|------------|-------|------------------------------------------------------------------------------------------------------| +| 2024-09-09 | feat | Created basic app structure for Agrilink Vocpro. | +| 2024-09-10 | feat | Sliced splash screen and login screen. | +| 2024-09-11 | feat | Sliced home page for Agrilink Vocpro. | +| 2024-09-12 | fix | Revamped home page for Agrilink Vocpro. | +| 2024-09-13 | feat | Created and animated graph or flowchart with `fl_chart`. | +| 2024-09-16 | learn | Learned about implementing graphics UI in Flutter. | +| 2024-09-17 | feat | Created bottom nav bar and revamped data display widgets in Agrilink app. | +| 2024-09-18 | feat | Added detail screen for Potassium, Nitrogen, and Phosphorus. | +| 2024-09-19 | feat | Created custom screen for soil pH data. | +| 2024-09-20 | feat | Handled POST requests with dialog. | +| 2024-09-23 | feat | Added basic app routes for Agrilink app. | +| 2024-09-24 | fix | Revamped home page again in Agrilink app. | +| 2024-09-25 | feat | Created detail screen for temperature and light intensity features. | +| 2024-09-26 | feat | Sliced setting screen. | +| 2024-09-27 | feat | Implemented infinite scroll with `infinite_scroll_pagination` package. | +| 2024-10-01 | meet | Conducted progress report with Pak Vipkas. | +| 2024-10-02 | feat | Connected Flutter with MQTT broker using `mqtt_client` dependency. | +| 2024-10-03 | feat | Created request to publish message to MQTT broker. | +| 2024-10-04 | test | Tested subscribe and publish message to real device. | +| 2024-10-07 | feat | Added error and no data screens in Agrilink Vocpro. | +| 2024-10-08 | fix | Revamped graph UI in Agrilink app; integrated relay control with backend. | +| 2024-10-09 | doc | Created project documentation in `README.md` on GitLab. | +| 2024-10-10 | fix | Revamped detail screen for each DHT data sensor. | +| 2024-10-11 | fix | Revamped detail screen for each NPK data sensor. | +| 2024-10-14 | feat | Integrated REST API for fetching current data. | +| 2024-10-15 | feat | Integrated REST API for fetching historical data and displaying it in a graph. | +| 2024-10-16 | feat | Integrated REST API for controlling relay. | +| 2024-11-06 | feat | Tidy up the code | ## Contributing -- 2.43.0 From ff74888996703257f31aa463c731802b811d0ad5 Mon Sep 17 00:00:00 2001 From: Syaroful Date: Tue, 12 Nov 2024 10:53:31 +0700 Subject: [PATCH 11/19] feat: add timeAgo extention --- .../lib/core/extension/extention.dart | 29 +++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/agrilink_vocpro/lib/core/extension/extention.dart b/agrilink_vocpro/lib/core/extension/extention.dart index cb84c9e..9d0057f 100644 --- a/agrilink_vocpro/lib/core/extension/extention.dart +++ b/agrilink_vocpro/lib/core/extension/extention.dart @@ -34,3 +34,32 @@ String getGreeting(String time) { return 'Selamat Malam'; } } + +String timeAgo(String? dateString) { + if (dateString == null) { + return ''; + } + DateTime date = DateTime.parse(dateString); + DateTime now = DateTime.now(); + + Duration difference = now.difference(date); + + if (difference.inMinutes < 1) { + return "Baru saja"; + } else if (difference.inMinutes < 60) { + return "${difference.inMinutes} menit yang lalu"; + } else if (difference.inHours < 24) { + return "${difference.inHours} jam yang lalu"; + } else if (difference.inDays < 7) { + return "${difference.inDays} hari yang lalu"; + } else if (difference.inDays < 30) { + int weeks = (difference.inDays / 7).floor(); + return "$weeks minggu yang lalu"; + } else if (difference.inDays < 365) { + int months = (difference.inDays / 30).floor(); + return "$months bulan yang lalu"; + } else { + int years = (difference.inDays / 365).floor(); + return "$years tahun yang lalu"; + } +} -- 2.43.0 From 6350a22b007dd687c475c9346343b7f0b234551f Mon Sep 17 00:00:00 2001 From: Syaroful Date: Tue, 12 Nov 2024 10:54:42 +0700 Subject: [PATCH 12/19] feat: add water pump status UI --- agrilink_vocpro/assets/images/valve.png | Bin 44937 -> 7369 bytes agrilink_vocpro/assets/images/water_pump.png | Bin 0 -> 6653 bytes .../control/provider/control_provider.dart | 56 ++++++--- .../features/control/view/control_screen.dart | 118 ++++++++++++++++-- .../control/widgets/pump_status_widget.dart | 75 +++++++++++ .../lib/features/home/view/home_screen.dart | 1 + .../features/splash/view/splash_screen.dart | 2 +- 7 files changed, 222 insertions(+), 30 deletions(-) create mode 100644 agrilink_vocpro/assets/images/water_pump.png create mode 100644 agrilink_vocpro/lib/features/control/widgets/pump_status_widget.dart diff --git a/agrilink_vocpro/assets/images/valve.png b/agrilink_vocpro/assets/images/valve.png index 5a4bbfd689458d91edf30d9760332610449c5e2c..6472d7c032014fd7ed450f8675d4bb001956e853 100644 GIT binary patch literal 7369 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 literal 44937 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%0AaEQqlnVpY&eJ8)Y(z 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 _control_2; + bool _control_3 = false; + bool get control_3 => _control_3; + + Relay _relay1 = Relay(); + Relay get relay1 => _relay1; + + Relay _relay2 = Relay(); + Relay get relay2 => _relay2; + + Relay _relay3 = Relay(); + Relay get relay3 => _relay3; + ControlProvider() { getRelayStatus(); } @@ -28,10 +41,16 @@ class ControlProvider extends ChangeNotifier { if (result.success == true) { for (var element in result.data!) { if (element.number == 1) { - switchControl1(element.currentStatus ?? false); + _relay1 = element; + switchControl(element.currentStatus ?? false, relayNumber: 1); } if (element.number == 2) { - switchControl2(element.currentStatus ?? false); + _relay2 = element; + switchControl(element.currentStatus ?? false, relayNumber: 2); + } + if (element.number == 3) { + _relay3 = element; + switchControl(element.currentStatus ?? false, relayNumber: 3); } } relayState = ResultState.hasData; @@ -53,15 +72,13 @@ class ControlProvider extends ChangeNotifier { relayState = ResultState.loading; notifyListeners(); - final int stateConverted; - if (state == true) { - stateConverted = 1; - } else { - stateConverted = 0; - } + final int stateConverted = state ? 1 : 0; try { final result = await _appService.switchRelay( - relayNumber: relayNumber, state: stateConverted); + relayNumber: relayNumber, + state: stateConverted, + ); + if (result.success == true) { relayState = ResultState.hasData; notifyListeners(); @@ -82,13 +99,20 @@ class ControlProvider extends ChangeNotifier { } } - void switchControl1(bool value) { - _control_1 = value; - notifyListeners(); - } - - void switchControl2(bool value) { - _control_2 = value; + void switchControl(bool value, {required int relayNumber}) { + switch (relayNumber) { + case 1: + _control_1 = value; + break; + case 2: + _control_2 = value; + break; + case 3: + _control_3 = value; + break; + default: + return; + } notifyListeners(); } } diff --git a/agrilink_vocpro/lib/features/control/view/control_screen.dart b/agrilink_vocpro/lib/features/control/view/control_screen.dart index 0ed74d5..dcc7dea 100644 --- a/agrilink_vocpro/lib/features/control/view/control_screen.dart +++ b/agrilink_vocpro/lib/features/control/view/control_screen.dart @@ -1,11 +1,18 @@ +import 'dart:math'; + +import 'package:agrilink_vocpro/core/constant/app_color.dart'; import 'package:agrilink_vocpro/core/constant/app_theme.dart'; +import 'package:agrilink_vocpro/core/extension/extention.dart'; import 'package:agrilink_vocpro/core/state/result_state.dart'; import 'package:agrilink_vocpro/features/control/provider/control_provider.dart'; import 'package:agrilink_vocpro/features/control/widgets/control_button_widget.dart'; +import 'package:agrilink_vocpro/features/control/widgets/pump_status_widget.dart'; +import 'package:agrilink_vocpro/features/control/widgets/relay_status_history_widget.dart'; import 'package:bootstrap_icons/bootstrap_icons.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; +import 'package:gauge_indicator/gauge_indicator.dart'; import 'package:provider/provider.dart'; class ControlScreen extends StatelessWidget { @@ -34,7 +41,7 @@ class ControlScreen extends StatelessWidget { return const StatusBarWidget( text: 'Memuat...', icon: BootstrapIcons.cloud, - color: Colors.cyan, + color: Colors.grey, isLoading: true, ); case ResultState.hasData: @@ -59,6 +66,12 @@ class ControlScreen extends StatelessWidget { ); } }), + PumpStatusWidget( + title: 'Pompa Air', + subtitle: 'Relay 3', + isActive: provider.control_3, + onTap: () {}, + ), SizedBox(height: 16.h), GridView( padding: EdgeInsets.all(16.r), @@ -76,12 +89,11 @@ class ControlScreen extends StatelessWidget { subtitle: 'Relay 1', isActive: provider.control_1, onTap: () async { - final result = provider.control_1 != true - ? await provider.switchRelay(1, true) - : await provider.switchRelay(1, false); - result == true - ? provider.switchControl1(!provider.control_1) - : provider.switchControl1(provider.control_1); + await _changeRelayStateAction( + provider: provider, + relayOn: 1, + relayOff: 2, + ); }, ), ControlButtonWidget( @@ -89,22 +101,102 @@ class ControlScreen extends StatelessWidget { subtitle: 'Relay 2', isActive: provider.control_2, onTap: () async { - final result = provider.control_2 != true - ? await provider.switchRelay(2, true) - : await provider.switchRelay(2, false); - result == true - ? provider.switchControl2(!provider.control_2) - : provider.switchControl2(provider.control_2); + await _changeRelayStateAction( + provider: provider, + relayOn: 2, + relayOff: 1, + ); }, ), ], ), + SizedBox(height: 16.h), + Padding( + padding: EdgeInsets.fromLTRB(16.r, 0, 16.r, 16.h), + child: Row( + children: [ + Icon( + BootstrapIcons.clock, + size: 20.r, + ), + SizedBox(width: 8.w), + Text( + 'Terakhir Diperbarui', + style: AppTheme.labelMedium, + ), + ], + ), + ), + Consumer(builder: (context, provider, child) { + return Column( + children: [ + RelayStatusHistoryWidget( + name: 'Katup Nutrisi', + imageUrl: 'assets/images/valve.png', + enabledAt: provider.relay1.enabledAt, + disabledAt: provider.relay1.disabledAt, + ), + RelayStatusHistoryWidget( + name: 'Katup Air', + imageUrl: 'assets/images/valve.png', + enabledAt: provider.relay2.enabledAt, + disabledAt: provider.relay2.disabledAt, + ), + RelayStatusHistoryWidget( + name: 'Pompa Air', + imageUrl: 'assets/images/water_pump.png', + enabledAt: provider.relay3.enabledAt, + disabledAt: provider.relay3.disabledAt, + ), + ], + ); + }), ], ), ), ), ); } + + Future _changeRelayStateAction({ + required ControlProvider provider, + required int relayOn, + required int relayOff, + }) async { + if (relayOn == 1) { + // Aktifkan relay 1 dan relay 3, matikan relay 2 + if (provider.control_1 == false) { + await provider.switchRelay(relayOff, false); // Matikan relay 2 + await provider.switchRelay(3, true); // Aktifkan relay 3 + await provider.switchRelay(relayOn, true); // Aktifkan relay 1 + provider.switchControl(true, relayNumber: 1); + provider.switchControl(true, relayNumber: 3); + provider.switchControl(false, relayNumber: 2); + } else { + // Matikan semua relay jika relay 1 dimatikan + await provider.switchRelay(3, false); + await provider.switchRelay(relayOn, false); + provider.switchControl(false, relayNumber: 1); + provider.switchControl(false, relayNumber: 3); + } + } else if (relayOn == 2) { + // Aktifkan relay 2 dan relay 3, matikan relay 1 + if (provider.control_2 == false) { + await provider.switchRelay(relayOff, false); // Matikan relay 1 + await provider.switchRelay(3, true); // Aktifkan relay 3 + await provider.switchRelay(relayOn, true); // Aktifkan relay 2 + provider.switchControl(true, relayNumber: 2); + provider.switchControl(true, relayNumber: 3); + provider.switchControl(false, relayNumber: 1); + } else { + // Matikan semua relay jika relay 2 dimatikan + await provider.switchRelay(3, false); + await provider.switchRelay(relayOn, false); + provider.switchControl(false, relayNumber: 2); + provider.switchControl(false, relayNumber: 3); + } + } + } } class StatusBarWidget extends StatelessWidget { diff --git a/agrilink_vocpro/lib/features/control/widgets/pump_status_widget.dart b/agrilink_vocpro/lib/features/control/widgets/pump_status_widget.dart new file mode 100644 index 0000000..5bca5ba --- /dev/null +++ b/agrilink_vocpro/lib/features/control/widgets/pump_status_widget.dart @@ -0,0 +1,75 @@ +import 'package:agrilink_vocpro/core/constant/app_color.dart'; +import 'package:agrilink_vocpro/core/constant/app_theme.dart'; +import 'package:agrilink_vocpro/core/state/result_state.dart'; +import 'package:agrilink_vocpro/features/control/provider/control_provider.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_screenutil/flutter_screenutil.dart'; +import 'package:provider/provider.dart'; + +class PumpStatusWidget extends StatelessWidget { + const PumpStatusWidget({ + super.key, + required this.title, + required this.subtitle, + required this.isActive, + required this.onTap, + }); + + final String title; + final String subtitle; + final bool isActive; + final Function() onTap; + + @override + Widget build(BuildContext context) { + return Container( + height: 100.h, + padding: EdgeInsets.all(16.r), + margin: EdgeInsets.symmetric(horizontal: 16.r), + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(16.r), + boxShadow: [ + BoxShadow( + color: isActive + ? AppColor.secondary.withOpacity(0.2) + : Colors.grey.withOpacity(0.2), + spreadRadius: 1.r, + blurRadius: 16.r, + offset: Offset(0, 12.r), + ), + ], + ), + child: Row( + children: [ + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text(title, style: AppTheme.labelMedium), + Text(subtitle, style: AppTheme.labelSmall), + ], + ), + Spacer(), + Consumer( + builder: (context, provider, child) { + switch (provider.relayState) { + case ResultState.loading: + return Image.asset( + 'assets/images/water_pump.png', + width: 80.r, + color: AppColor.textDisable, + ); + default: + return Image.asset( + 'assets/images/water_pump.png', + width: 80.r, + color: isActive ? AppColor.secondary : AppColor.textDisable, + ); + } + }, + ) + ], + ), + ); + } +} diff --git a/agrilink_vocpro/lib/features/home/view/home_screen.dart b/agrilink_vocpro/lib/features/home/view/home_screen.dart index f3fea3d..47dee48 100644 --- a/agrilink_vocpro/lib/features/home/view/home_screen.dart +++ b/agrilink_vocpro/lib/features/home/view/home_screen.dart @@ -126,6 +126,7 @@ class _HomeScreenState extends State { ), ), body: DefaultTabController( + initialIndex: 1, length: 3, child: Stack( children: [ diff --git a/agrilink_vocpro/lib/features/splash/view/splash_screen.dart b/agrilink_vocpro/lib/features/splash/view/splash_screen.dart index e0e9dbd..ab584c2 100644 --- a/agrilink_vocpro/lib/features/splash/view/splash_screen.dart +++ b/agrilink_vocpro/lib/features/splash/view/splash_screen.dart @@ -58,7 +58,7 @@ class _SplashScreenState extends State { } void _navigateAfterSplash(bool isLoggedIn) { - Timer(const Duration(seconds: 2), () { + Timer(const Duration(seconds: 1), () { if (isLoggedIn == true) { context.go(AppRoute.dashboard); } else { -- 2.43.0 From 305443f291a88700f177db2dd4675ae0a8472839 Mon Sep 17 00:00:00 2001 From: Syaroful Date: Tue, 12 Nov 2024 10:55:12 +0700 Subject: [PATCH 13/19] feat: add relay actived history --- .../lib/data/model/relay_response.dart | 12 ++-- .../widgets/relay_status_history_widget.dart | 68 +++++++++++++++++++ 2 files changed, 74 insertions(+), 6 deletions(-) create mode 100644 agrilink_vocpro/lib/features/control/widgets/relay_status_history_widget.dart diff --git a/agrilink_vocpro/lib/data/model/relay_response.dart b/agrilink_vocpro/lib/data/model/relay_response.dart index a9f09e8..5444c5b 100644 --- a/agrilink_vocpro/lib/data/model/relay_response.dart +++ b/agrilink_vocpro/lib/data/model/relay_response.dart @@ -1,15 +1,15 @@ class RelayResponse { bool? success; - List? data; + List? data; RelayResponse({this.success, this.data}); RelayResponse.fromJson(Map json) { success = json['success']; if (json['data'] != null) { - data = []; + data = []; json['data'].forEach((v) { - data!.add(Data.fromJson(v)); + data!.add(Relay.fromJson(v)); }); } } @@ -24,7 +24,7 @@ class RelayResponse { } } -class Data { +class Relay { int? id; int? number; String? enabledAt; @@ -32,7 +32,7 @@ class Data { bool? currentStatus; String? createdAt; - Data( + Relay( {this.id, this.number, this.enabledAt, @@ -40,7 +40,7 @@ class Data { this.currentStatus, this.createdAt}); - Data.fromJson(Map json) { + Relay.fromJson(Map json) { id = json['id']; number = json['number']; enabledAt = json['enabled_at']; diff --git a/agrilink_vocpro/lib/features/control/widgets/relay_status_history_widget.dart b/agrilink_vocpro/lib/features/control/widgets/relay_status_history_widget.dart new file mode 100644 index 0000000..f0b2581 --- /dev/null +++ b/agrilink_vocpro/lib/features/control/widgets/relay_status_history_widget.dart @@ -0,0 +1,68 @@ +import 'package:agrilink_vocpro/core/constant/app_theme.dart'; +import 'package:agrilink_vocpro/core/extension/extention.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_screenutil/flutter_screenutil.dart'; + +import '../../../core/constant/app_color.dart'; + +class RelayStatusHistoryWidget extends StatelessWidget { + const RelayStatusHistoryWidget({ + super.key, + required this.disabledAt, + required this.enabledAt, + required this.name, + required this.imageUrl, + }); + + final String? disabledAt; + final String? enabledAt; + final String name; + final String imageUrl; + + @override + Widget build(BuildContext context) { + return ListTile( + leading: CircleAvatar( + radius: 26.r, + backgroundColor: AppColor.ternary, + child: Image.asset( + imageUrl, + width: 24.r, + color: Colors.white, + ), + ), + title: Text( + name, + style: AppTheme.labelMedium, + ), + subtitle: Column( + children: [ + Row( + children: [ + CircleAvatar( + backgroundColor: Colors.greenAccent, + radius: 4.r, + ), + Text( + ' Aktif ${timeAgo(enabledAt)}', + style: AppTheme.labelSmall, + ), + ], + ), + Row( + children: [ + CircleAvatar( + backgroundColor: Colors.grey.shade300, + radius: 4.r, + ), + Text( + ' Nonaktif ${timeAgo(disabledAt)}', + style: AppTheme.labelSmall, + ), + ], + ) + ], + ), + ); + } +} -- 2.43.0 From ad15e58f33f496771ad41cea2d60ad4158985081 Mon Sep 17 00:00:00 2001 From: Syaroful Date: Tue, 12 Nov 2024 10:56:00 +0700 Subject: [PATCH 14/19] refactor: delete unused import --- .../lib/features/control/view/control_screen.dart | 5 ----- 1 file changed, 5 deletions(-) diff --git a/agrilink_vocpro/lib/features/control/view/control_screen.dart b/agrilink_vocpro/lib/features/control/view/control_screen.dart index dcc7dea..e81c9b7 100644 --- a/agrilink_vocpro/lib/features/control/view/control_screen.dart +++ b/agrilink_vocpro/lib/features/control/view/control_screen.dart @@ -1,8 +1,4 @@ -import 'dart:math'; - -import 'package:agrilink_vocpro/core/constant/app_color.dart'; import 'package:agrilink_vocpro/core/constant/app_theme.dart'; -import 'package:agrilink_vocpro/core/extension/extention.dart'; import 'package:agrilink_vocpro/core/state/result_state.dart'; import 'package:agrilink_vocpro/features/control/provider/control_provider.dart'; import 'package:agrilink_vocpro/features/control/widgets/control_button_widget.dart'; @@ -12,7 +8,6 @@ import 'package:bootstrap_icons/bootstrap_icons.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; -import 'package:gauge_indicator/gauge_indicator.dart'; import 'package:provider/provider.dart'; class ControlScreen extends StatelessWidget { -- 2.43.0 From 6d6440732de3e0955ca24d80b86e4cfdaa7d3216 Mon Sep 17 00:00:00 2001 From: Syaroful Date: Thu, 12 Dec 2024 09:33:15 +0700 Subject: [PATCH 15/19] refactor: fix a bit bug --- .vscode/settings.json | 3 + agrilink_vocpro/android/app/build.gradle | 2 +- agrilink_vocpro/android/settings.gradle | 4 +- .../nitrogen/view/nitrogen_screen.dart | 2 +- .../phosphorus/view/phosphorus_screen.dart | 2 +- .../potassium/view/potassium_screen.dart | 2 +- .../widgets/list_data_from_censor_npk1.dart | 2 +- .../widgets/list_data_from_censor_npk2.dart | 2 +- agrilink_vocpro/pubspec.lock | 152 +++++++++--------- 9 files changed, 87 insertions(+), 84 deletions(-) create mode 100644 .vscode/settings.json diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..c5f3f6b --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "java.configuration.updateBuildConfiguration": "interactive" +} \ No newline at end of file diff --git a/agrilink_vocpro/android/app/build.gradle b/agrilink_vocpro/android/app/build.gradle index cfbe6a0..5641eb6 100644 --- a/agrilink_vocpro/android/app/build.gradle +++ b/agrilink_vocpro/android/app/build.gradle @@ -11,7 +11,7 @@ plugins { android { namespace = "com.pis.agrilink_vocpro" compileSdk = flutter.compileSdkVersion - ndkVersion = flutter.ndkVersion + ndkVersion = "27.0.12077973" compileOptions { sourceCompatibility = JavaVersion.VERSION_1_8 diff --git a/agrilink_vocpro/android/settings.gradle b/agrilink_vocpro/android/settings.gradle index 7fb86d7..bcb6793 100644 --- a/agrilink_vocpro/android/settings.gradle +++ b/agrilink_vocpro/android/settings.gradle @@ -18,11 +18,11 @@ pluginManagement { plugins { id "dev.flutter.flutter-plugin-loader" version "1.0.0" - id "com.android.application" version "7.3.0" apply false + id "com.android.application" version "8.7.0" apply false // START: FlutterFire Configuration id "com.google.gms.google-services" version "4.3.15" apply false // END: FlutterFire Configuration - id "org.jetbrains.kotlin.android" version "1.7.10" apply false + id "org.jetbrains.kotlin.android" version "2.0.20" apply false } include ":app" diff --git a/agrilink_vocpro/lib/features/home/detail_pages/nitrogen/view/nitrogen_screen.dart b/agrilink_vocpro/lib/features/home/detail_pages/nitrogen/view/nitrogen_screen.dart index 0cae22d..ab0f68a 100644 --- a/agrilink_vocpro/lib/features/home/detail_pages/nitrogen/view/nitrogen_screen.dart +++ b/agrilink_vocpro/lib/features/home/detail_pages/nitrogen/view/nitrogen_screen.dart @@ -84,7 +84,7 @@ class NitrogenScreen extends StatelessWidget { size: 64.r, color: Colors.blue, ), - Text('$value ppm', style: AppTheme.headline1), + Text('$value mg/L', style: AppTheme.headline1), ], ), ); diff --git a/agrilink_vocpro/lib/features/home/detail_pages/phosphorus/view/phosphorus_screen.dart b/agrilink_vocpro/lib/features/home/detail_pages/phosphorus/view/phosphorus_screen.dart index 0664528..c68694e 100644 --- a/agrilink_vocpro/lib/features/home/detail_pages/phosphorus/view/phosphorus_screen.dart +++ b/agrilink_vocpro/lib/features/home/detail_pages/phosphorus/view/phosphorus_screen.dart @@ -84,7 +84,7 @@ class PhosphorusScreen extends StatelessWidget { size: 64.r, color: Colors.blue, ), - Text('$value ppm', style: AppTheme.headline1), + Text('$value mg/L', style: AppTheme.headline1), ], ), ); diff --git a/agrilink_vocpro/lib/features/home/detail_pages/potassium/view/potassium_screen.dart b/agrilink_vocpro/lib/features/home/detail_pages/potassium/view/potassium_screen.dart index b224c6c..7fa24a8 100644 --- a/agrilink_vocpro/lib/features/home/detail_pages/potassium/view/potassium_screen.dart +++ b/agrilink_vocpro/lib/features/home/detail_pages/potassium/view/potassium_screen.dart @@ -84,7 +84,7 @@ class PotassiumScreen extends StatelessWidget { size: 64.r, color: Colors.red, ), - Text('$value ppm', style: AppTheme.headline1), + Text('$value mg/L', style: AppTheme.headline1), ], ), ); diff --git a/agrilink_vocpro/lib/features/home/widgets/list_data_from_censor_npk1.dart b/agrilink_vocpro/lib/features/home/widgets/list_data_from_censor_npk1.dart index 1e24e6d..804a01b 100644 --- a/agrilink_vocpro/lib/features/home/widgets/list_data_from_censor_npk1.dart +++ b/agrilink_vocpro/lib/features/home/widgets/list_data_from_censor_npk1.dart @@ -58,7 +58,7 @@ class ListDataFromCensorNpk1 extends StatelessWidget { censorIdentifier: censorIdentifier, onTap: () async { await context.push( - '${AppRoute.nitrogen}/${provider.npk2SoilNitrogen}/${provider.npk1SoilNitrogen}'); + '${AppRoute.nitrogen}/${provider.npk1SoilNitrogen}/${provider.npk2SoilNitrogen}'); }, ), DataDisplayerWidget( diff --git a/agrilink_vocpro/lib/features/home/widgets/list_data_from_censor_npk2.dart b/agrilink_vocpro/lib/features/home/widgets/list_data_from_censor_npk2.dart index 326c436..272b7d9 100644 --- a/agrilink_vocpro/lib/features/home/widgets/list_data_from_censor_npk2.dart +++ b/agrilink_vocpro/lib/features/home/widgets/list_data_from_censor_npk2.dart @@ -58,7 +58,7 @@ class ListDataFromCensorNpk2 extends StatelessWidget { iconColor: Colors.white, onTap: () async { await context.push( - '${AppRoute.nitrogen}/${provider.npk2SoilNitrogen}/${provider.npk1SoilNitrogen}'); + '${AppRoute.nitrogen}/${provider.npk1SoilNitrogen}/${provider.npk2SoilNitrogen}'); }, ), DataDisplayerWidget( diff --git a/agrilink_vocpro/pubspec.lock b/agrilink_vocpro/pubspec.lock index 4cad5cc..df8ef0d 100644 --- a/agrilink_vocpro/pubspec.lock +++ b/agrilink_vocpro/pubspec.lock @@ -5,10 +5,10 @@ packages: dependency: transitive description: name: _flutterfire_internals - sha256: "5534e701a2c505fed1f0799e652dd6ae23bd4d2c4cf797220e5ced5764a7c1c2" + sha256: eae3133cbb06de9205899b822e3897fc6a8bc278ad4c944b4ce612689369694b url: "https://pub.dev" source: hosted - version: "1.3.44" + version: "1.3.47" animated_segmented_tab_control: dependency: "direct main" description: @@ -29,18 +29,18 @@ packages: dependency: transitive description: name: async - sha256: "947bfcf187f74dbc5e146c9eb9c0f10c9f8b30743e341481c1e2ed3ecc18c20c" + sha256: d2872f9c19731c2e5f10444b14686eb7cc85c76274bd6c16e1816bff9a3bab63 url: "https://pub.dev" source: hosted - version: "2.11.0" + version: "2.12.0" boolean_selector: dependency: transitive description: name: boolean_selector - sha256: "6cfb5af12253eaf2b368f07bacc5a80d1301a071c73360d746b7f2e32d762c66" + sha256: "8aab1771e1243a5063b8b0ff68042d67334e3feab9e95b9490f9a6ebf73b42ea" url: "https://pub.dev" source: hosted - version: "2.1.1" + version: "2.1.2" bootstrap_icons: dependency: "direct main" description: @@ -61,42 +61,42 @@ packages: dependency: transitive description: name: charcode - sha256: fb98c0f6d12c920a02ee2d998da788bca066ca5f148492b7085ee23372b12306 + sha256: fb0f1107cac15a5ea6ef0a6ef71a807b9e4267c713bb93e00e92d737cc8dbd8a url: "https://pub.dev" source: hosted - version: "1.3.1" + version: "1.4.0" clock: dependency: transitive description: name: clock - sha256: cb6d7f03e1de671e34607e909a7213e31d7752be4fb66a86d29fe1eb14bfb5cf + sha256: fddb70d9b5277016c77a80201021d40a2247104d9f4aa7bab7157b7e3f05b84b url: "https://pub.dev" source: hosted - version: "1.1.1" + version: "1.1.2" collection: dependency: transitive description: name: collection - sha256: ee67cb0715911d28db6bf4af1026078bd6f0128b07a5f66fb2ed94ec6783c09a + sha256: a1ace0a119f20aabc852d165077c036cd864315bd99b7eaa10a60100341941bf url: "https://pub.dev" source: hosted - version: "1.18.0" + version: "1.19.0" crypto: dependency: transitive description: name: crypto - sha256: ec30d999af904f33454ba22ed9a86162b35e52b44ac4807d1d93c288041d7d27 + sha256: "1e445881f28f22d6140f181e07737b22f1e099a5e1ff94b0af2f9e4a463f4855" url: "https://pub.dev" source: hosted - version: "3.0.5" + version: "3.0.6" csslib: dependency: transitive description: name: csslib - sha256: "706b5707578e0c1b4b7550f64078f0a0f19dec3f50a178ffae7006b0a9ca58fb" + sha256: "09bad715f418841f976c77db72d5398dc1253c21fb9c0c7f0b0b985860b2d58e" url: "https://pub.dev" source: hosted - version: "1.0.0" + version: "1.0.2" cupertino_icons: dependency: "direct main" description: @@ -125,10 +125,10 @@ packages: dependency: transitive description: name: equatable - sha256: c2b87cb7756efdf69892005af546c56c0b5037f54d2a88269b4f347a505e3ca2 + sha256: "567c64b3cb4cf82397aac55f4f0cbd3ca20d77c6c03bedbc4ceaddc08904aef7" url: "https://pub.dev" source: hosted - version: "2.0.5" + version: "2.0.7" event_bus: dependency: transitive description: @@ -141,10 +141,10 @@ packages: dependency: transitive description: name: fake_async - sha256: "511392330127add0b769b75a987850d136345d9227c6b94c96a04cf4a391bf78" + sha256: "6a95e56b2449df2273fd8c45a662d6947ce1ebb7aafe80e550a3f68297f3cacc" url: "https://pub.dev" source: hosted - version: "1.3.1" + version: "1.3.2" ffi: dependency: transitive description: @@ -165,58 +165,58 @@ packages: dependency: "direct main" description: name: firebase_core - sha256: "51dfe2fbf3a984787a2e7b8592f2f05c986bfedd6fdacea3f9e0a7beb334de96" + sha256: fef81a53ba1ca618def1f8bef4361df07968434e62cb204c1fb90bb880a03da2 url: "https://pub.dev" source: hosted - version: "3.6.0" + version: "3.8.1" firebase_core_platform_interface: dependency: transitive description: name: firebase_core_platform_interface - sha256: e30da58198a6d4b49d5bce4e852f985c32cb10db329ebef9473db2b9f09ce810 + sha256: b94b217e3ad745e784960603d33d99471621ecca151c99c670869b76e50ad2a6 url: "https://pub.dev" source: hosted - version: "5.3.0" + version: "5.3.1" firebase_core_web: dependency: transitive description: name: firebase_core_web - sha256: f967a7138f5d2ffb1ce15950e2a382924239eaa521150a8f144af34e68b3b3e5 + sha256: "9e69806bb3d905aeec3c1242e0e1475de6ea6d48f456af29d598fb229a2b4e5e" url: "https://pub.dev" source: hosted - version: "2.18.1" + version: "2.18.2" firebase_messaging: dependency: "direct main" description: name: firebase_messaging - sha256: eb6e28a3a35deda61fe8634967c84215efc19133ba58d8e0fc6c9a2af2cba05e + sha256: "151a3ee68736abf293aab66d1317ade53c88abe1db09c75a0460aebf7767bbdf" url: "https://pub.dev" source: hosted - version: "15.1.3" + version: "15.1.6" firebase_messaging_platform_interface: dependency: transitive description: name: firebase_messaging_platform_interface - sha256: b316c4ee10d93d32c033644207afc282d9b2b4372f3cf9c6022f3558b3873d2d + sha256: f331ee51e40c243f90cc7bc059222dfec4e5df53125b08d31fb28961b00d2a9d url: "https://pub.dev" source: hosted - version: "4.5.46" + version: "4.5.49" firebase_messaging_web: dependency: transitive description: name: firebase_messaging_web - sha256: d7f0147a1a9fe4313168e20154a01fd5cf332898de1527d3930ff77b8c7f5387 + sha256: efaf3fdc54cd77e0eedb8e75f7f01c808828c64d052ddbf94d3009974e47d30f url: "https://pub.dev" source: hosted - version: "3.9.2" + version: "3.9.5" fl_chart: dependency: "direct main" description: name: fl_chart - sha256: "94307bef3a324a0d329d3ab77b2f0c6e5ed739185ffc029ed28c0f9b019ea7ef" + sha256: "74959b99b92b9eebeed1a4049426fd67c4abc3c5a0f4d12e2877097d6a11ae08" url: "https://pub.dev" source: hosted - version: "0.69.0" + version: "0.69.2" flutter: dependency: "direct main" description: flutter @@ -260,10 +260,10 @@ packages: dependency: "direct main" description: name: go_router - sha256: "6f1b756f6e863259a99135ff3c95026c3cdca17d10ebef2bba2261a25ddc8bbc" + sha256: "2fd11229f59e23e967b0775df8d5948a519cd7e1e8b6e849729e010587b46539" url: "https://pub.dev" source: hosted - version: "14.3.0" + version: "14.6.2" google_fonts: dependency: "direct main" description: @@ -276,10 +276,10 @@ packages: dependency: transitive description: name: google_identity_services_web - sha256: "5be191523702ba8d7a01ca97c17fca096822ccf246b0a9f11923a6ded06199b6" + sha256: "55580f436822d64c8ff9a77e37d61f5fb1e6c7ec9d632a43ee324e2a05c3c6c9" url: "https://pub.dev" source: hosted - version: "0.3.1+4" + version: "0.3.3" googleapis_auth: dependency: "direct main" description: @@ -292,10 +292,10 @@ packages: dependency: transitive description: name: html - sha256: "3a7812d5bcd2894edf53dfaf8cd640876cf6cef50a8f238745c8b8120ea74d3a" + sha256: "1fc58edeaec4307368c60d59b7e15b9d658b57d7f3125098b6294153c75337ec" url: "https://pub.dev" source: hosted - version: "0.15.4" + version: "0.15.5" http: dependency: "direct main" description: @@ -308,10 +308,10 @@ packages: dependency: transitive description: name: http_parser - sha256: "2aa08ce0341cc9b354a498388e30986515406668dbcc4f7c950c3e715496693b" + sha256: "76d306a1c3afb33fe82e2bbacad62a61f409b5634c915fceb0d799de1a913360" url: "https://pub.dev" source: hosted - version: "4.0.2" + version: "4.1.1" intl: dependency: "direct main" description: @@ -332,18 +332,18 @@ packages: dependency: transitive description: name: leak_tracker - sha256: "3f87a60e8c63aecc975dda1ceedbc8f24de75f09e4856ea27daf8958f2f0ce05" + sha256: c35baad643ba394b40aac41080300150a4f08fd0fd6a10378f8f7c6bc161acec url: "https://pub.dev" source: hosted - version: "10.0.5" + version: "10.0.8" leak_tracker_flutter_testing: dependency: transitive description: name: leak_tracker_flutter_testing - sha256: "932549fb305594d82d7183ecd9fa93463e9914e1b67cacc34bc40906594a1806" + sha256: f8b613e7e6a13ec79cfdc0e97638fddb3ab848452eff057653abd3edba760573 url: "https://pub.dev" source: hosted - version: "3.0.5" + version: "3.0.9" leak_tracker_testing: dependency: transitive description: @@ -356,18 +356,18 @@ packages: dependency: transitive description: name: lints - sha256: "3315600f3fb3b135be672bf4a178c55f274bebe368325ae18462c89ac1e3b413" + sha256: "4a16b3f03741e1252fda5de3ce712666d010ba2122f8e912c94f9f7b90e1a4c3" url: "https://pub.dev" source: hosted - version: "5.0.0" + version: "5.1.0" logging: dependency: transitive description: name: logging - sha256: "623a88c9594aa774443aa3eb2d41807a48486b5613e67599fb4c41c0ad47c340" + sha256: c8245ada5f1717ed44271ed1c26b8ce85ca3228fd2ffdb75468ab01979309d61 url: "https://pub.dev" source: hosted - version: "1.2.0" + version: "1.3.0" matcher: dependency: transitive description: @@ -412,34 +412,34 @@ packages: dependency: transitive description: name: path - sha256: "087ce49c3f0dc39180befefc60fdb4acd8f8620e5682fe2476afd0b3688bb4af" + sha256: "75cca69d1490965be98c73ceaea117e8a04dd21217b37b292c9ddbec0d955bc5" url: "https://pub.dev" source: hosted - version: "1.9.0" + version: "1.9.1" path_provider: dependency: transitive description: name: path_provider - sha256: fec0d61223fba3154d87759e3cc27fe2c8dc498f6386c6d6fc80d1afdd1bf378 + sha256: "50c5dd5b6e1aaf6fb3a78b33f6aa3afca52bf903a8a5298f53101fdaee55bbcd" url: "https://pub.dev" source: hosted - version: "2.1.4" + version: "2.1.5" path_provider_android: dependency: transitive description: name: path_provider_android - sha256: c464428172cb986b758c6d1724c603097febb8fb855aa265aeecc9280c294d4a + sha256: "4adf4fd5423ec60a29506c76581bc05854c55e3a0b72d35bb28d661c9686edf2" url: "https://pub.dev" source: hosted - version: "2.2.12" + version: "2.2.15" path_provider_foundation: dependency: transitive description: name: path_provider_foundation - sha256: f234384a3fdd67f989b4d54a5d73ca2a6c422fa55ae694381ae0f4375cd1ea16 + sha256: "4843174df4d288f5e29185bd6e72a6fbdf5a4a4602717eed565497429f179942" url: "https://pub.dev" source: hosted - version: "2.4.0" + version: "2.4.1" path_provider_linux: dependency: transitive description: @@ -468,10 +468,10 @@ packages: dependency: transitive description: name: platform - sha256: "9b71283fc13df574056616011fb138fd3b793ea47cc509c189a6c3fa5f8a1a65" + sha256: "5d6b1b0036a5f331ebc77c850ebc8506cbc1e9416c27e59b439f917a902a4984" url: "https://pub.dev" source: hosted - version: "3.1.5" + version: "3.1.6" plugin_platform_interface: dependency: transitive description: @@ -492,18 +492,18 @@ packages: dependency: "direct main" description: name: shared_preferences - sha256: "746e5369a43170c25816cc472ee016d3a66bc13fcf430c0bc41ad7b4b2922051" + sha256: "95f9997ca1fb9799d494d0cb2a780fd7be075818d59f00c43832ed112b158a82" url: "https://pub.dev" source: hosted - version: "2.3.2" + version: "2.3.3" shared_preferences_android: dependency: transitive description: name: shared_preferences_android - sha256: "3b9febd815c9ca29c9e3520d50ec32f49157711e143b7a4ca039eb87e8ade5ab" + sha256: "7f172d1b06de5da47b6264c2692ee2ead20bbbc246690427cdb4fc301cd0c549" url: "https://pub.dev" source: hosted - version: "2.3.3" + version: "2.3.4" shared_preferences_foundation: dependency: transitive description: @@ -556,7 +556,7 @@ packages: dependency: transitive description: flutter source: sdk - version: "0.0.99" + version: "0.0.0" source_span: dependency: transitive description: @@ -569,10 +569,10 @@ packages: dependency: transitive description: name: stack_trace - sha256: "73713990125a6d93122541237550ee3352a2d84baad52d375a4cad2eb9b7ce0b" + sha256: "9f47fd3630d76be3ab26f0ee06d213679aa425996925ff3feffdec504931c377" url: "https://pub.dev" source: hosted - version: "1.11.1" + version: "1.12.0" stream_channel: dependency: transitive description: @@ -585,10 +585,10 @@ packages: dependency: transitive description: name: string_scanner - sha256: "556692adab6cfa87322a115640c11f13cb77b3f076ddcc5d6ae3c20242bedcde" + sha256: "0bd04f5bb74fcd6ff0606a888a30e917af9bd52820b178eaa464beb11dca84b6" url: "https://pub.dev" source: hosted - version: "1.2.0" + version: "1.4.0" term_glyph: dependency: transitive description: @@ -601,18 +601,18 @@ packages: dependency: transitive description: name: test_api - sha256: "5b8a98dafc4d5c4c9c72d8b31ab2b23fc13422348d2997120294d3bac86b4ddb" + sha256: "664d3a9a64782fcdeb83ce9c6b39e78fd2971d4e37827b9b06c3aa1edc5e760c" url: "https://pub.dev" source: hosted - version: "0.7.2" + version: "0.7.3" typed_data: dependency: transitive description: name: typed_data - sha256: facc8d6582f16042dd49f2463ff1bd6e2c9ef9f3d5da3d9b087e244a7b564b3c + sha256: f9049c039ebfeb4cf7a7104a675823cd72dba8297f264b6637062516699fa006 url: "https://pub.dev" source: hosted - version: "1.3.2" + version: "1.4.0" universal_html: dependency: transitive description: @@ -641,10 +641,10 @@ packages: dependency: transitive description: name: vm_service - sha256: "5c5f338a667b4c644744b661f309fb8080bb94b18a7e91ef1dbd343bed00ed6d" + sha256: "0968250880a6c5fe7edc067ed0a13d4bae1577fe2771dcf3010d52c4a9d3ca14" url: "https://pub.dev" source: hosted - version: "14.2.5" + version: "14.3.1" web: dependency: transitive description: @@ -662,5 +662,5 @@ packages: source: hosted version: "1.1.0" sdks: - dart: ">=3.5.1 <4.0.0" + dart: ">=3.6.0-0 <4.0.0" flutter: ">=3.24.0" -- 2.43.0 From 599f6b6e7377cab7b00b0dbf4f46f6f84bbea3e8 Mon Sep 17 00:00:00 2001 From: Syaroful Date: Thu, 12 Dec 2024 09:39:48 +0700 Subject: [PATCH 16/19] refactor: removing dead code --- .../control/widgets/control_button_widget.dart | 4 ++-- .../features/control/widgets/pump_status_widget.dart | 4 ++-- .../conductivity/view/conductivity_screen.dart | 1 - .../detail_pages/humidity/view/humidity_screen.dart | 4 ---- .../detail_pages/luminosity/view/light_screen.dart | 4 ---- .../detail_pages/nitrogen/view/nitrogen_screen.dart | 1 - .../features/home/detail_pages/ph/view/ph_screen.dart | 1 - .../phosphorus/view/phosphorus_screen.dart | 1 - .../detail_pages/potassium/view/potassium_screen.dart | 1 - .../soil_moisture/view/soil_moisture_screen.dart | 1 - .../soil_temperature/view/soil_temperature_screen.dart | 3 +-- .../temperature/view/temperature_screen.dart | 10 +++------- .../lib/features/home/widgets/data_display_widget.dart | 6 +++--- .../lib/features/home/widgets/graphic_widget.dart | 2 +- .../home/widgets/list_data_from_censor_dht.dart | 2 -- 15 files changed, 12 insertions(+), 33 deletions(-) diff --git a/agrilink_vocpro/lib/features/control/widgets/control_button_widget.dart b/agrilink_vocpro/lib/features/control/widgets/control_button_widget.dart index 0857526..cfdb38a 100644 --- a/agrilink_vocpro/lib/features/control/widgets/control_button_widget.dart +++ b/agrilink_vocpro/lib/features/control/widgets/control_button_widget.dart @@ -32,8 +32,8 @@ class ControlButtonWidget extends StatelessWidget { boxShadow: [ BoxShadow( color: isActive - ? AppColor.secondary.withOpacity(0.2) - : Colors.grey.withOpacity(0.2), + ? AppColor.secondary.withValues(alpha: 0.2) + : Colors.grey.withValues(alpha: 0.2), spreadRadius: 1.r, blurRadius: 16.r, offset: Offset(0, 12.r), diff --git a/agrilink_vocpro/lib/features/control/widgets/pump_status_widget.dart b/agrilink_vocpro/lib/features/control/widgets/pump_status_widget.dart index 5bca5ba..adfe80c 100644 --- a/agrilink_vocpro/lib/features/control/widgets/pump_status_widget.dart +++ b/agrilink_vocpro/lib/features/control/widgets/pump_status_widget.dart @@ -32,8 +32,8 @@ class PumpStatusWidget extends StatelessWidget { boxShadow: [ BoxShadow( color: isActive - ? AppColor.secondary.withOpacity(0.2) - : Colors.grey.withOpacity(0.2), + ? AppColor.secondary.withValues(alpha: 0.2) + : Colors.grey.withValues(alpha: 0.2), spreadRadius: 1.r, blurRadius: 16.r, offset: Offset(0, 12.r), diff --git a/agrilink_vocpro/lib/features/home/detail_pages/conductivity/view/conductivity_screen.dart b/agrilink_vocpro/lib/features/home/detail_pages/conductivity/view/conductivity_screen.dart index 0ead696..3317507 100644 --- a/agrilink_vocpro/lib/features/home/detail_pages/conductivity/view/conductivity_screen.dart +++ b/agrilink_vocpro/lib/features/home/detail_pages/conductivity/view/conductivity_screen.dart @@ -151,7 +151,6 @@ class ConductivityScreen extends StatelessWidget { case ResultState.noData: return const NoDataStateWidget(); case ResultState.initial: - default: return const SizedBox.shrink(); } }, diff --git a/agrilink_vocpro/lib/features/home/detail_pages/humidity/view/humidity_screen.dart b/agrilink_vocpro/lib/features/home/detail_pages/humidity/view/humidity_screen.dart index 447b4a7..2ac1327 100644 --- a/agrilink_vocpro/lib/features/home/detail_pages/humidity/view/humidity_screen.dart +++ b/agrilink_vocpro/lib/features/home/detail_pages/humidity/view/humidity_screen.dart @@ -152,10 +152,6 @@ class HumidityScreen extends StatelessWidget { return const NoDataStateWidget(); case ResultState.initial: return const SizedBox.shrink(); - default: - return const Center( - child: Text('Default Error'), - ); } }), ), diff --git a/agrilink_vocpro/lib/features/home/detail_pages/luminosity/view/light_screen.dart b/agrilink_vocpro/lib/features/home/detail_pages/luminosity/view/light_screen.dart index ce1c5e4..c0ea612 100644 --- a/agrilink_vocpro/lib/features/home/detail_pages/luminosity/view/light_screen.dart +++ b/agrilink_vocpro/lib/features/home/detail_pages/luminosity/view/light_screen.dart @@ -174,10 +174,6 @@ class LightScreen extends StatelessWidget { ); case ResultState.initial: return const SizedBox.shrink(); - default: - return const Center( - child: Text('Default Error'), - ); } }), ), diff --git a/agrilink_vocpro/lib/features/home/detail_pages/nitrogen/view/nitrogen_screen.dart b/agrilink_vocpro/lib/features/home/detail_pages/nitrogen/view/nitrogen_screen.dart index ab0f68a..1e651bf 100644 --- a/agrilink_vocpro/lib/features/home/detail_pages/nitrogen/view/nitrogen_screen.dart +++ b/agrilink_vocpro/lib/features/home/detail_pages/nitrogen/view/nitrogen_screen.dart @@ -151,7 +151,6 @@ class NitrogenScreen extends StatelessWidget { case ResultState.noData: return const NoDataStateWidget(); case ResultState.initial: - default: return const SizedBox.shrink(); } }, diff --git a/agrilink_vocpro/lib/features/home/detail_pages/ph/view/ph_screen.dart b/agrilink_vocpro/lib/features/home/detail_pages/ph/view/ph_screen.dart index 4412c29..d813dd9 100644 --- a/agrilink_vocpro/lib/features/home/detail_pages/ph/view/ph_screen.dart +++ b/agrilink_vocpro/lib/features/home/detail_pages/ph/view/ph_screen.dart @@ -142,7 +142,6 @@ class PhScreen extends StatelessWidget { case ResultState.noData: return const NoDataStateWidget(); case ResultState.initial: - default: return const SizedBox.shrink(); } }, diff --git a/agrilink_vocpro/lib/features/home/detail_pages/phosphorus/view/phosphorus_screen.dart b/agrilink_vocpro/lib/features/home/detail_pages/phosphorus/view/phosphorus_screen.dart index c68694e..73d6975 100644 --- a/agrilink_vocpro/lib/features/home/detail_pages/phosphorus/view/phosphorus_screen.dart +++ b/agrilink_vocpro/lib/features/home/detail_pages/phosphorus/view/phosphorus_screen.dart @@ -151,7 +151,6 @@ class PhosphorusScreen extends StatelessWidget { case ResultState.noData: return const NoDataStateWidget(); case ResultState.initial: - default: return const SizedBox.shrink(); } }, diff --git a/agrilink_vocpro/lib/features/home/detail_pages/potassium/view/potassium_screen.dart b/agrilink_vocpro/lib/features/home/detail_pages/potassium/view/potassium_screen.dart index 7fa24a8..baa8eac 100644 --- a/agrilink_vocpro/lib/features/home/detail_pages/potassium/view/potassium_screen.dart +++ b/agrilink_vocpro/lib/features/home/detail_pages/potassium/view/potassium_screen.dart @@ -151,7 +151,6 @@ class PotassiumScreen extends StatelessWidget { case ResultState.noData: return const NoDataStateWidget(); case ResultState.initial: - default: return const SizedBox.shrink(); } }, diff --git a/agrilink_vocpro/lib/features/home/detail_pages/soil_moisture/view/soil_moisture_screen.dart b/agrilink_vocpro/lib/features/home/detail_pages/soil_moisture/view/soil_moisture_screen.dart index 209e00d..6caebd3 100644 --- a/agrilink_vocpro/lib/features/home/detail_pages/soil_moisture/view/soil_moisture_screen.dart +++ b/agrilink_vocpro/lib/features/home/detail_pages/soil_moisture/view/soil_moisture_screen.dart @@ -180,7 +180,6 @@ class SoilMoistureScreen extends StatelessWidget { case ResultState.noData: return const NoDataStateWidget(); case ResultState.initial: - default: return const SizedBox.shrink(); } }, diff --git a/agrilink_vocpro/lib/features/home/detail_pages/soil_temperature/view/soil_temperature_screen.dart b/agrilink_vocpro/lib/features/home/detail_pages/soil_temperature/view/soil_temperature_screen.dart index ff35554..a68343f 100644 --- a/agrilink_vocpro/lib/features/home/detail_pages/soil_temperature/view/soil_temperature_screen.dart +++ b/agrilink_vocpro/lib/features/home/detail_pages/soil_temperature/view/soil_temperature_screen.dart @@ -149,7 +149,7 @@ class SoilTemperatureScreen extends StatelessWidget { height: 100.h, width: 100.w, decoration: BoxDecoration( - color: color.withOpacity(0.1), + color: color.withValues(alpha: 0.1), borderRadius: BorderRadius.circular(16), border: Border.all(color: color, width: 2), ), @@ -230,7 +230,6 @@ class SoilTemperatureScreen extends StatelessWidget { case ResultState.noData: return const NoDataStateWidget(); case ResultState.initial: - default: return const SizedBox.shrink(); } }, diff --git a/agrilink_vocpro/lib/features/home/detail_pages/temperature/view/temperature_screen.dart b/agrilink_vocpro/lib/features/home/detail_pages/temperature/view/temperature_screen.dart index c4bf2e5..53cbe1a 100644 --- a/agrilink_vocpro/lib/features/home/detail_pages/temperature/view/temperature_screen.dart +++ b/agrilink_vocpro/lib/features/home/detail_pages/temperature/view/temperature_screen.dart @@ -118,7 +118,7 @@ class TemperatureScreen extends StatelessWidget { width: 100.w, decoration: BoxDecoration( borderRadius: BorderRadius.circular(16), - color: Colors.blue.withOpacity(0.1), + color: Colors.blue.withValues(alpha: 0.1), border: Border.all( color: Colors.blue, width: 2, @@ -143,7 +143,7 @@ class TemperatureScreen extends StatelessWidget { height: 100.h, width: 100.w, decoration: BoxDecoration( - color: Colors.green.withOpacity(0.1), + color: Colors.green.withValues(alpha: 0.1), borderRadius: BorderRadius.circular(16), border: Border.all( color: Colors.green, @@ -169,7 +169,7 @@ class TemperatureScreen extends StatelessWidget { height: 100.h, width: 100.w, decoration: BoxDecoration( - color: Colors.orange.withOpacity(0.1), + color: Colors.orange.withValues(alpha: 0.1), borderRadius: BorderRadius.circular(16), border: Border.all( color: Colors.orange.shade800, @@ -235,10 +235,6 @@ class TemperatureScreen extends StatelessWidget { return NoDataStateWidget(); case ResultState.initial: return const SizedBox.shrink(); - default: - return const Center( - child: Text('Default Error'), - ); } }, ), diff --git a/agrilink_vocpro/lib/features/home/widgets/data_display_widget.dart b/agrilink_vocpro/lib/features/home/widgets/data_display_widget.dart index f31afe2..6efd7b1 100644 --- a/agrilink_vocpro/lib/features/home/widgets/data_display_widget.dart +++ b/agrilink_vocpro/lib/features/home/widgets/data_display_widget.dart @@ -41,7 +41,7 @@ class DataDisplayerWidget extends StatelessWidget { borderRadius: BorderRadius.circular(16.r), // Bentuk sudut yang bundar ), elevation: 20, // Efek bayangan - shadowColor: Colors.grey.withOpacity(0.2), + shadowColor: Colors.grey.withValues(alpha: 0.2), ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, @@ -52,7 +52,7 @@ class DataDisplayerWidget extends StatelessWidget { child: Text( censorIdentifier ?? '', style: AppTheme.labelSmall - .copyWith(color: textColor.withOpacity(0.5)), + .copyWith(color: textColor.withValues(alpha: 0.5)), ), ), Icon(icon, color: iconColor, size: 32.r), @@ -67,7 +67,7 @@ class DataDisplayerWidget extends StatelessWidget { Text( subtitle, style: AppTheme.labelSmall - .copyWith(color: textColor.withOpacity(0.5)), + .copyWith(color: textColor.withValues(alpha: 0.5)), ), ], ), diff --git a/agrilink_vocpro/lib/features/home/widgets/graphic_widget.dart b/agrilink_vocpro/lib/features/home/widgets/graphic_widget.dart index 3bbf334..ce2f100 100644 --- a/agrilink_vocpro/lib/features/home/widgets/graphic_widget.dart +++ b/agrilink_vocpro/lib/features/home/widgets/graphic_widget.dart @@ -111,7 +111,7 @@ class GarphicWidget extends StatelessWidget { show: true, gradient: LinearGradient( colors: gradientColors - .map((color) => color.withOpacity(0.3)) + .map((color) => color.withValues(alpha: 0.3)) .toList()), ), ), diff --git a/agrilink_vocpro/lib/features/home/widgets/list_data_from_censor_dht.dart b/agrilink_vocpro/lib/features/home/widgets/list_data_from_censor_dht.dart index f4aa3b0..5ce4c7a 100644 --- a/agrilink_vocpro/lib/features/home/widgets/list_data_from_censor_dht.dart +++ b/agrilink_vocpro/lib/features/home/widgets/list_data_from_censor_dht.dart @@ -102,8 +102,6 @@ class ListDataFromCensorDht extends StatelessWidget { )); case ResultState.initial: return const SizedBox.shrink(); - default: - return const SizedBox.shrink(); } }); } -- 2.43.0 From f1f422d8f6d60f821ed6595915ea796c95822389 Mon Sep 17 00:00:00 2001 From: Syaroful Date: Tue, 17 Dec 2024 13:57:55 +0700 Subject: [PATCH 17/19] feat: change max value in every data sensor graphic --- agrilink_vocpro/android/app/build.gradle | 14 +++++++++++--- .../android/app/src/main/AndroidManifest.xml | 2 +- .../conductivity/view/conductivity_screen.dart | 1 - .../luminosity/view/light_screen.dart | 1 + .../nitrogen/view/nitrogen_screen.dart | 2 +- .../phosphorus/view/phosphorus_screen.dart | 2 +- .../potassium/view/potassium_screen.dart | 2 +- .../soil_moisture/view/soil_moisture_screen.dart | 1 - .../temperature/view/temperature_screen.dart | 1 + upload-keystore.jks | Bin 0 -> 2258 bytes 10 files changed, 17 insertions(+), 9 deletions(-) create mode 100644 upload-keystore.jks diff --git a/agrilink_vocpro/android/app/build.gradle b/agrilink_vocpro/android/app/build.gradle index 5641eb6..e40fede 100644 --- a/agrilink_vocpro/android/app/build.gradle +++ b/agrilink_vocpro/android/app/build.gradle @@ -33,11 +33,19 @@ android { versionName = flutter.versionName } + signingConfigs { + release { + keyAlias 'agrilink-upload' + keyPassword '100403' + storeFile file('D:/Code/real_project/flutter/mobile-smartfarming/upload-keystore.jks') + storePassword '100403' + } + } buildTypes { release { - // TODO: Add your own signing config for the release build. - // Signing with the debug keys for now, so `flutter run --release` works. - signingConfig = signingConfigs.debug + signingConfig signingConfigs.release + minifyEnabled true // You can set to true for release builds + shrinkResources true // Set to true if minify is true } } } diff --git a/agrilink_vocpro/android/app/src/main/AndroidManifest.xml b/agrilink_vocpro/android/app/src/main/AndroidManifest.xml index c15afda..a4c27a4 100644 --- a/agrilink_vocpro/android/app/src/main/AndroidManifest.xml +++ b/agrilink_vocpro/android/app/src/main/AndroidManifest.xml @@ -3,7 +3,7 @@ diff --git a/agrilink_vocpro/lib/features/home/detail_pages/conductivity/view/conductivity_screen.dart b/agrilink_vocpro/lib/features/home/detail_pages/conductivity/view/conductivity_screen.dart index 3317507..e971b82 100644 --- a/agrilink_vocpro/lib/features/home/detail_pages/conductivity/view/conductivity_screen.dart +++ b/agrilink_vocpro/lib/features/home/detail_pages/conductivity/view/conductivity_screen.dart @@ -144,7 +144,6 @@ class ConductivityScreen extends StatelessWidget { ? provider.dataFetchedNpk1[index].soilconductivity ?? 0 : provider.dataFetchedNpk2[index].soilconductivity ?? 0, ), - maxValue: 1, ); case ResultState.error: return const ErrorDataStateWidget(); diff --git a/agrilink_vocpro/lib/features/home/detail_pages/luminosity/view/light_screen.dart b/agrilink_vocpro/lib/features/home/detail_pages/luminosity/view/light_screen.dart index c0ea612..2d84fe9 100644 --- a/agrilink_vocpro/lib/features/home/detail_pages/luminosity/view/light_screen.dart +++ b/agrilink_vocpro/lib/features/home/detail_pages/luminosity/view/light_screen.dart @@ -137,6 +137,7 @@ class LightScreen extends StatelessWidget { provider.dataFetched[index].vicihumidity ?.toDouble() ?? 0), + maxValue: 500, ); case ResultState.error: return Center( diff --git a/agrilink_vocpro/lib/features/home/detail_pages/nitrogen/view/nitrogen_screen.dart b/agrilink_vocpro/lib/features/home/detail_pages/nitrogen/view/nitrogen_screen.dart index 1e651bf..b803bca 100644 --- a/agrilink_vocpro/lib/features/home/detail_pages/nitrogen/view/nitrogen_screen.dart +++ b/agrilink_vocpro/lib/features/home/detail_pages/nitrogen/view/nitrogen_screen.dart @@ -144,7 +144,7 @@ class NitrogenScreen extends StatelessWidget { ? provider.dataFetchedNpk1[index].soilnitrogen ?? 0 : provider.dataFetchedNpk2[index].soilnitrogen ?? 0, ), - maxValue: 1, + maxValue: 10, ); case ResultState.error: return const ErrorDataStateWidget(); diff --git a/agrilink_vocpro/lib/features/home/detail_pages/phosphorus/view/phosphorus_screen.dart b/agrilink_vocpro/lib/features/home/detail_pages/phosphorus/view/phosphorus_screen.dart index 73d6975..1c4e31a 100644 --- a/agrilink_vocpro/lib/features/home/detail_pages/phosphorus/view/phosphorus_screen.dart +++ b/agrilink_vocpro/lib/features/home/detail_pages/phosphorus/view/phosphorus_screen.dart @@ -144,7 +144,7 @@ class PhosphorusScreen extends StatelessWidget { ? provider.dataFetchedNpk1[index].soilphosphorus ?? 0 : provider.dataFetchedNpk2[index].soilphosphorus ?? 0, ), - maxValue: 10, + maxValue: 100, ); case ResultState.error: return const ErrorDataStateWidget(); diff --git a/agrilink_vocpro/lib/features/home/detail_pages/potassium/view/potassium_screen.dart b/agrilink_vocpro/lib/features/home/detail_pages/potassium/view/potassium_screen.dart index baa8eac..85d8e3c 100644 --- a/agrilink_vocpro/lib/features/home/detail_pages/potassium/view/potassium_screen.dart +++ b/agrilink_vocpro/lib/features/home/detail_pages/potassium/view/potassium_screen.dart @@ -144,7 +144,7 @@ class PotassiumScreen extends StatelessWidget { ? provider.dataFetchedNpk1[index].soilpotassium ?? 0 : provider.dataFetchedNpk2[index].soilpotassium ?? 0, ), - maxValue: 1, + maxValue: 100, ); case ResultState.error: return const ErrorDataStateWidget(); diff --git a/agrilink_vocpro/lib/features/home/detail_pages/soil_moisture/view/soil_moisture_screen.dart b/agrilink_vocpro/lib/features/home/detail_pages/soil_moisture/view/soil_moisture_screen.dart index 6caebd3..d450c99 100644 --- a/agrilink_vocpro/lib/features/home/detail_pages/soil_moisture/view/soil_moisture_screen.dart +++ b/agrilink_vocpro/lib/features/home/detail_pages/soil_moisture/view/soil_moisture_screen.dart @@ -173,7 +173,6 @@ class SoilMoistureScreen extends StatelessWidget { ? provider.dataFetchedNpk1[index].soilhumidity ?? 0 : provider.dataFetchedNpk2[index].soilhumidity ?? 0, ), - maxValue: 1, ); case ResultState.error: return const ErrorDataStateWidget(); diff --git a/agrilink_vocpro/lib/features/home/detail_pages/temperature/view/temperature_screen.dart b/agrilink_vocpro/lib/features/home/detail_pages/temperature/view/temperature_screen.dart index 53cbe1a..0a9131a 100644 --- a/agrilink_vocpro/lib/features/home/detail_pages/temperature/view/temperature_screen.dart +++ b/agrilink_vocpro/lib/features/home/detail_pages/temperature/view/temperature_screen.dart @@ -228,6 +228,7 @@ class TemperatureScreen extends StatelessWidget { provider.dataFetched[index].vicitemperature ?.toDouble() ?? 0), + maxValue: 60, ); case ResultState.error: return ErrorDataStateWidget(); diff --git a/upload-keystore.jks b/upload-keystore.jks new file mode 100644 index 0000000000000000000000000000000000000000..3c8fb7a39b089254bc1cf7d9ad96666d662db844 GIT binary patch literal 2258 zcmchYX*ARg8;9p_W)LxCnNi4|2xIIDgUFx}k7X={W{`a;B86r&#=ey-BPL5(T1TQN zktIUHh><0YY-7z*iN|@)`@ZKnr|<8F--rA9bf4?|&VBE&ci12hh+{9nKY@Arg!u;e z2KlRmhXe$B683m@J*WRJ2m}QoiI8pNeoh``P5=TZaR>qcgb10-`aGrkqtI_K#IqYs z%HSdL(F+J?&cp7I@<+{(R?GtqP-Xhn4k*+cTR)_tLx}pGo>-e(lj)yN0L(a+pA-ik zHyqu_=I(Dl5duIP<$aP^nK7bfpS>TK$6k-+7xq9%*`^34*?}KY>vB}C2y@{PUB3JWS9^jWoW)V5-DNRS%qCp8E`h3l*czx2ebqg0-MC=^{T-F zH@UJa#Kpb5b920TrK=W9nqf)L9xcdA8#KC7)|G57Oco!>Wlv0wf513V=4LqsOe z*!~)%Ur_yEpz%cMifNL9B1lu_ZTQ#-7*L!*WZf3AI6Q$$&%Ow~vMxcE&RZp68L#aS zrAKX96s|j_@)2i;q^iMOIkA(u=Pko89BHku9?5D|__f*pBK7j^4S0@LvOu1CZ3TY4 zB8rjqZM0~c^hW;B)Sz=WcQhj^>{Zs>+Y+YYu{Q|yWPKc#<$?=ETgl9c7|%LC`g{(4 zYC`NRqRbfcNzv>G)$Bt-lcZ~n8a~-sB{?e9-$Q9-T$T z$Jgo5wlsFHw`9)|H!d{bQYKb)LV|p(?Lj&;DK83Ww#cS)b>$9g)Q!HJo@c0{ms{x2 z2dWee&+KEIn(TcDHGgjMmXtBkR*9$AU14kGAMe6pBobzCO&MQm&sg8j9_4wU}rZiyV@Xw^Rl5{gsRLh6A) zU?P$TjzJPRyoPmZn#Dk4avv3Pl;?n-sA&-{d-q4KwSXI&k1&ba0+ob z1o;OAUk>^&;r@eg{XuyCAiRGN@c#%>3eJbpR7a_!keW!Ox|Rz9hC*uX4Jf_;fdBJ8 zL_p@>LICKVIRLizO8_1YA^?D%T^4t(@zExh_B}{0xbKIB5qnzt!oUbwZH)vqcHLD% zZdWLHD9)Bw(3#Gs%baJ86fvM_*Y5u;)lDSPEDU(AU%IvF@$<;Qw(JkfqA=+lLhbBi zsm<_5(pAN#nYP}$Jj|t!i{#_6etyUCi)%F13AUI3?tyWV_x>N!{cIL~8ky%Ak%~f;e>KXrt+ZUB0CY zs*~(r94sZ1VF0x++<5OzT=2ro`i4Q{Z^!-&6 zm%iAcO(c;QzrP=67MG5`Rtz-H_I4Xc&*#S`v zap+l!`u)~W>~BTS(dd?E@fpiTE#;WQMEKdcWlTvE>81OS{;OSuH~D~dZoS51u`a0K z-RWtK3q*=>*R`eh;}pJu0L^^%twxJjJqiX@^&+XDX`FY1Ex*LNZoEU6YPPn0{#Si` f&#leYTF2FigOY|V*1< Date: Mon, 30 Dec 2024 11:06:21 +0700 Subject: [PATCH 18/19] feat: update readme decumentation --- README.md | 30 +++++++++++++++++++++--------- 1 file changed, 21 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index 0635004..50f343c 100644 --- a/README.md +++ b/README.md @@ -35,11 +35,11 @@ This project uses several packages to support various functionalities. Below is ## Installation Guide 1. Clone the repository: ```bash - git clone https://github.com/username/smart-farming.git + git clone https://gitlab.com/profile-image/kedaireka/smartfarming/mobile-smartfarming.git ``` -2. Navigate to the project directory: +2. Navigate to the flutter project directory: ```bash - cd smart-farming + cd agrilink_vocpro ``` 3. Install dependencies: ```bash @@ -48,10 +48,22 @@ This project uses several packages to support various functionalities. Below is if it does't work try: ```bash flutter outdated - //follow with + // follow with flutter pub upgrade --major-versions ``` or check your latest dart version make sure it compatible with this project + + project tool version + + ``` + • Flutter version 3.27.0-1.0.pre.685 + • Upstream repository https://github.com/flutter/flutter.git + • Framework revision 227f6a04f7, 2024-12-03 13:21:59 +0100 + • Engine revision f9d4f744e0 + • Dart version 3.7.0 (build 3.7.0-207.0.dev) + • DevTools version 2.41.0 + ``` + 4. Run the project: ```bash flutter run @@ -63,13 +75,13 @@ Berikan deskripsi singkat tentang struktur folder dan file penting di dalam proy ## Project Structure - `lib/`: Contains the Flutter app source code. - - `core/`: Contains all constant vaalue and data needed for the project. - - `data/`: Conatains model and data response + - `core/`: Contains all constant value and data needed for the project. + - `data/`: Contains model and data response - `domain/`: logic and service of the application - `feature/`: Contains every feature in the app - - `provider/` - - `view` - - `widget` + - `provider/`: Contains a function to integrate with domain layer + - `view` : contains the main screen UI code + - `widget` : conatins the widget UI code - `pubspec.yaml`: Project dependencies and configurations. -- 2.43.0 From 39989fa8a07444a94828138c91c9bed6f399dcef Mon Sep 17 00:00:00 2001 From: Syaroful Date: Mon, 30 Dec 2024 11:06:39 +0700 Subject: [PATCH 19/19] feat: change base_url --- agrilink_vocpro/lib/core/constant/app_constant.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/agrilink_vocpro/lib/core/constant/app_constant.dart b/agrilink_vocpro/lib/core/constant/app_constant.dart index f7ab4eb..e2fb6a9 100644 --- a/agrilink_vocpro/lib/core/constant/app_constant.dart +++ b/agrilink_vocpro/lib/core/constant/app_constant.dart @@ -2,7 +2,7 @@ class AppConstant { static const String appName = 'Kebun Pintar'; static const String appVersion = '1.0.0'; - static const String baseUrl = 'http://54.196.58.97:3333'; + static const String baseUrl = 'http://192.168.60.108'; static const String mqttServer = 'armadillo.rmq.cloudamqp.com'; static const String mqttUsername = 'obyskxhx:obyskxhx'; -- 2.43.0