Merge pull request 'Merge to main' (#1) from develop-gitea into main
Reviewed-on: #1
This commit is contained in:
commit
9b715a6765
3
.vscode/settings.json
vendored
Normal file
3
.vscode/settings.json
vendored
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
{
|
||||||
|
"java.configuration.updateBuildConfiguration": "interactive"
|
||||||
|
}
|
||||||
64
README.md
64
README.md
|
|
@ -35,11 +35,11 @@ This project uses several packages to support various functionalities. Below is
|
||||||
## Installation Guide
|
## Installation Guide
|
||||||
1. Clone the repository:
|
1. Clone the repository:
|
||||||
```bash
|
```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
|
```bash
|
||||||
cd smart-farming
|
cd agrilink_vocpro
|
||||||
```
|
```
|
||||||
3. Install dependencies:
|
3. Install dependencies:
|
||||||
```bash
|
```bash
|
||||||
|
|
@ -52,6 +52,18 @@ This project uses several packages to support various functionalities. Below is
|
||||||
flutter pub upgrade --major-versions
|
flutter pub upgrade --major-versions
|
||||||
```
|
```
|
||||||
or check your latest dart version make sure it compatible with this project
|
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:
|
4. Run the project:
|
||||||
```bash
|
```bash
|
||||||
flutter run
|
flutter run
|
||||||
|
|
@ -63,26 +75,48 @@ Berikan deskripsi singkat tentang struktur folder dan file penting di dalam proy
|
||||||
|
|
||||||
## Project Structure
|
## Project Structure
|
||||||
- `lib/`: Contains the Flutter app source code.
|
- `lib/`: Contains the Flutter app source code.
|
||||||
- `core/`: Contains all constant vaalue and data needed for the project.
|
- `core/`: Contains all constant value and data needed for the project.
|
||||||
- `data/`: Conatains model and data response
|
- `data/`: Contains model and data response
|
||||||
- `domain/`: logic and service of the application
|
- `domain/`: logic and service of the application
|
||||||
- `feature/`: Contains every feature in the app
|
- `feature/`: Contains every feature in the app
|
||||||
- `provider/`
|
- `provider/`: Contains a function to integrate with domain layer
|
||||||
- `view`
|
- `view` : contains the main screen UI code
|
||||||
- `widget`
|
- `widget` : conatins the widget UI code
|
||||||
- `pubspec.yaml`: Project dependencies and configurations.
|
- `pubspec.yaml`: Project dependencies and configurations.
|
||||||
|
|
||||||
|
|
||||||
## Progress Report
|
## Progress Report
|
||||||
|
|
||||||
| Date | Type | Description |
|
| Date | Type | Description |
|
||||||
|------------|-------|-----------------------------------------------------------------------------------------------------|
|
|------------|-------|------------------------------------------------------------------------------------------------------|
|
||||||
| 2024-10-09 | feat | Completed the integration of MQTT for sensor data and IoT device control. |
|
| 2024-09-09 | feat | Created basic app structure for Agrilink Vocpro. |
|
||||||
| 2024-10-02 | fix | Implemented auto-reconnect for MQTT on app open/close. |
|
| 2024-09-10 | feat | Sliced splash screen and login screen. |
|
||||||
| 2024-09-30 | feat | Added UI for displaying soil pH level with a linear bar. |
|
| 2024-09-11 | feat | Sliced home page for Agrilink Vocpro. |
|
||||||
| 2024-09-27 | feat | Finalized group display for 'Doses' in ExpansionTile for medicine dosage recommendations. |
|
| 2024-09-12 | fix | Revamped home page for Agrilink Vocpro. |
|
||||||
| 2024-09-24 | feat | Completed sorting dialog functionality with single sorter selection capability. |
|
| 2024-09-13 | feat | Created and animated graph or flowchart with `fl_chart`. |
|
||||||
| 2024-09-20 | feat | Implemented patient data creation form with validation and state management using dialogs. |
|
| 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
|
## Contributing
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@ plugins {
|
||||||
android {
|
android {
|
||||||
namespace = "com.pis.agrilink_vocpro"
|
namespace = "com.pis.agrilink_vocpro"
|
||||||
compileSdk = flutter.compileSdkVersion
|
compileSdk = flutter.compileSdkVersion
|
||||||
ndkVersion = flutter.ndkVersion
|
ndkVersion = "27.0.12077973"
|
||||||
|
|
||||||
compileOptions {
|
compileOptions {
|
||||||
sourceCompatibility = JavaVersion.VERSION_1_8
|
sourceCompatibility = JavaVersion.VERSION_1_8
|
||||||
|
|
@ -33,11 +33,19 @@ android {
|
||||||
versionName = flutter.versionName
|
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 {
|
buildTypes {
|
||||||
release {
|
release {
|
||||||
// TODO: Add your own signing config for the release build.
|
signingConfig signingConfigs.release
|
||||||
// Signing with the debug keys for now, so `flutter run --release` works.
|
minifyEnabled true // You can set to true for release builds
|
||||||
signingConfig = signingConfigs.debug
|
shrinkResources true // Set to true if minify is true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@
|
||||||
<uses-permission android:name="android.permission.INTERNET" />
|
<uses-permission android:name="android.permission.INTERNET" />
|
||||||
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
|
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
|
||||||
<application
|
<application
|
||||||
android:label="agrilink_vocpro"
|
android:label="Agrilink Vocpro"
|
||||||
android:name="${applicationName}"
|
android:name="${applicationName}"
|
||||||
android:icon="@mipmap/ic_launcher"
|
android:icon="@mipmap/ic_launcher"
|
||||||
android:enableOnBackInvokedCallback="true">
|
android:enableOnBackInvokedCallback="true">
|
||||||
|
|
|
||||||
|
|
@ -18,11 +18,11 @@ pluginManagement {
|
||||||
|
|
||||||
plugins {
|
plugins {
|
||||||
id "dev.flutter.flutter-plugin-loader" version "1.0.0"
|
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
|
// START: FlutterFire Configuration
|
||||||
id "com.google.gms.google-services" version "4.3.15" apply false
|
id "com.google.gms.google-services" version "4.3.15" apply false
|
||||||
// END: FlutterFire Configuration
|
// 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"
|
include ":app"
|
||||||
|
|
|
||||||
Binary file not shown.
|
Before Width: | Height: | Size: 44 KiB After Width: | Height: | Size: 7.2 KiB |
BIN
agrilink_vocpro/assets/images/water_pump.png
Normal file
BIN
agrilink_vocpro/assets/images/water_pump.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 6.5 KiB |
|
|
@ -2,27 +2,33 @@ class AppConstant {
|
||||||
static const String appName = 'Kebun Pintar';
|
static const String appName = 'Kebun Pintar';
|
||||||
static const String appVersion = '1.0.0';
|
static const String appVersion = '1.0.0';
|
||||||
|
|
||||||
static const String baseUrl = 'https://jx027dj4-3333.asse.devtunnels.ms';
|
static const String baseUrl = 'http://192.168.60.108';
|
||||||
|
|
||||||
static const String mqttServer = 'armadillo.rmq.cloudamqp.com';
|
static const String mqttServer = 'armadillo.rmq.cloudamqp.com';
|
||||||
static const String mqttUsername = 'obyskxhx:obyskxhx';
|
static const String mqttUsername = 'obyskxhx:obyskxhx';
|
||||||
static const String mqttPassword = 'Fe_3_tBuwmc8vMMqT2hYiboTsBlBmPz1';
|
static const String mqttPassword = 'Fe_3_tBuwmc8vMMqT2hYiboTsBlBmPz1';
|
||||||
|
|
||||||
static const String soilTempInfo =
|
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 npk1 = 'npk1';
|
||||||
static const String npk2 = 'npk2';
|
static const String npk2 = 'npk2';
|
||||||
static const String dht = 'dht';
|
static const String dht = 'dht';
|
||||||
|
|
||||||
static const String soilTemp = 'soilTemperature';
|
static const String soilTemp = 'soilTemperature';
|
||||||
static const String soilMoisture = 'soilMoisture';
|
static const String soilMoisture = 'soilHumidity';
|
||||||
static const String airTemp = 'viciTemperature';
|
static const String airTemp = 'viciTemperature';
|
||||||
static const String humidity = 'humidity';
|
static const String humidity = 'viciHumidity';
|
||||||
static const String lightIntensity = 'lightIntensity';
|
static const String lightIntensity = 'viciluminosity';
|
||||||
static const String conductivity = 'conductivity';
|
static const String conductivity = 'soilConductivity';
|
||||||
static const String ph = 'ph';
|
static const String ph = 'soilPh';
|
||||||
static const String nitrogen = 'nitrogen';
|
static const String nitrogen = 'soilNitrogen';
|
||||||
static const String phosphorus = 'phosphorus';
|
static const String phosphorus = 'soilPhosphorus';
|
||||||
static const String potassium = 'potassium';
|
static const String potassium = 'soilPotassium';
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,10 @@ String dateFormatterShort(String date) {
|
||||||
return formatter.format(dateTime);
|
return formatter.format(dateTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
String setTwoDigitAfterComma(double number) {
|
||||||
|
return number.toStringAsFixed(2);
|
||||||
|
}
|
||||||
|
|
||||||
String getGreeting(String time) {
|
String getGreeting(String time) {
|
||||||
DateTime parsedTime = DateTime.parse(time);
|
DateTime parsedTime = DateTime.parse(time);
|
||||||
int hour = parsedTime.hour;
|
int hour = parsedTime.hour;
|
||||||
|
|
@ -30,3 +34,32 @@ String getGreeting(String time) {
|
||||||
return 'Selamat Malam';
|
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";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,15 +1,16 @@
|
||||||
import 'package:agrilink_vocpro/features/auth/view/login_screen.dart';
|
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/dashboard/view/dashboard_screen.dart';
|
||||||
import 'package:agrilink_vocpro/features/home/pages/conductivity/view/conductivity_screen.dart';
|
import 'package:agrilink_vocpro/features/home/detail_pages/conductivity/view/conductivity_screen.dart';
|
||||||
import 'package:agrilink_vocpro/features/home/pages/humidity/view/humidity_screen.dart';
|
import 'package:agrilink_vocpro/features/home/detail_pages/humidity/view/humidity_screen.dart';
|
||||||
import 'package:agrilink_vocpro/features/home/pages/luminosity/view/light_screen.dart';
|
import 'package:agrilink_vocpro/features/home/detail_pages/luminosity/view/light_screen.dart';
|
||||||
import 'package:agrilink_vocpro/features/home/pages/nitrogen/view/nitrogen_screen.dart';
|
import 'package:agrilink_vocpro/features/home/detail_pages/nitrogen/view/nitrogen_screen.dart';
|
||||||
import 'package:agrilink_vocpro/features/home/pages/ph/view/ph_screen.dart';
|
import 'package:agrilink_vocpro/features/home/detail_pages/ph/view/ph_screen.dart';
|
||||||
import 'package:agrilink_vocpro/features/home/pages/phosphorus/view/phosphorus_screen.dart';
|
import 'package:agrilink_vocpro/features/home/detail_pages/phosphorus/view/phosphorus_screen.dart';
|
||||||
import 'package:agrilink_vocpro/features/home/pages/potassium/view/potassium_screen.dart';
|
import 'package:agrilink_vocpro/features/home/detail_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/detail_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/detail_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/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:agrilink_vocpro/features/splash/view/splash_screen.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:go_router/go_router.dart';
|
import 'package:go_router/go_router.dart';
|
||||||
|
|
@ -21,6 +22,7 @@ class AppRoute {
|
||||||
static const String home = '/home';
|
static const String home = '/home';
|
||||||
static const String profile = '/profile';
|
static const String profile = '/profile';
|
||||||
static const String setting = '/setting';
|
static const String setting = '/setting';
|
||||||
|
static const String account = '/dashboard/account';
|
||||||
static const String humidity = '/dashboard/humidity';
|
static const String humidity = '/dashboard/humidity';
|
||||||
static const String temperature = '/dashboard/temperature';
|
static const String temperature = '/dashboard/temperature';
|
||||||
static const String soilTemperature = '/dashboard/soil_temperature';
|
static const String soilTemperature = '/dashboard/soil_temperature';
|
||||||
|
|
@ -69,6 +71,11 @@ class AppRoute {
|
||||||
buildPhosphorusRoute(),
|
buildPhosphorusRoute(),
|
||||||
// potassium
|
// potassium
|
||||||
buildPotassiumRoute(),
|
buildPotassiumRoute(),
|
||||||
|
GoRoute(
|
||||||
|
path: 'account',
|
||||||
|
builder: (context, state) {
|
||||||
|
return AccountScreen();
|
||||||
|
})
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
|
|
||||||
|
|
@ -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,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -3,10 +3,10 @@ import 'package:bootstrap_icons/bootstrap_icons.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
||||||
|
|
||||||
class GraphicErrorWidget extends StatelessWidget {
|
class NoDataStateWidget extends StatelessWidget {
|
||||||
const GraphicErrorWidget({super.key, required this.message});
|
const NoDataStateWidget({
|
||||||
|
super.key,
|
||||||
final String message;
|
});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
|
|
@ -14,9 +14,15 @@ class GraphicErrorWidget extends StatelessWidget {
|
||||||
child: Column(
|
child: Column(
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
children: [
|
children: [
|
||||||
Icon(BootstrapIcons.exclamation_circle, color: Colors.grey.shade400),
|
Icon(
|
||||||
|
BootstrapIcons.database_fill_x,
|
||||||
|
color: Colors.grey.shade400,
|
||||||
|
),
|
||||||
SizedBox(height: 8.h),
|
SizedBox(height: 8.h),
|
||||||
Text(message, style: AppTheme.labelSmall),
|
Text(
|
||||||
|
'Tidak Ada Data',
|
||||||
|
style: AppTheme.labelSmall,
|
||||||
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
@ -1,28 +1 @@
|
||||||
import 'package:flutter/material.dart';
|
|
||||||
|
|
||||||
Future<dynamic> 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'),
|
|
||||||
)
|
|
||||||
],
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -31,7 +31,6 @@ class Relay {
|
||||||
String? disabledAt;
|
String? disabledAt;
|
||||||
bool? currentStatus;
|
bool? currentStatus;
|
||||||
String? createdAt;
|
String? createdAt;
|
||||||
String? updatedAt;
|
|
||||||
|
|
||||||
Relay(
|
Relay(
|
||||||
{this.id,
|
{this.id,
|
||||||
|
|
@ -39,8 +38,7 @@ class Relay {
|
||||||
this.enabledAt,
|
this.enabledAt,
|
||||||
this.disabledAt,
|
this.disabledAt,
|
||||||
this.currentStatus,
|
this.currentStatus,
|
||||||
this.createdAt,
|
this.createdAt});
|
||||||
this.updatedAt});
|
|
||||||
|
|
||||||
Relay.fromJson(Map<String, dynamic> json) {
|
Relay.fromJson(Map<String, dynamic> json) {
|
||||||
id = json['id'];
|
id = json['id'];
|
||||||
|
|
@ -49,7 +47,6 @@ class Relay {
|
||||||
disabledAt = json['disabled_at'];
|
disabledAt = json['disabled_at'];
|
||||||
currentStatus = json['current_status'];
|
currentStatus = json['current_status'];
|
||||||
createdAt = json['created_at'];
|
createdAt = json['created_at'];
|
||||||
updatedAt = json['updated_at'];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Map<String, dynamic> toJson() {
|
Map<String, dynamic> toJson() {
|
||||||
|
|
@ -60,7 +57,6 @@ class Relay {
|
||||||
data['disabled_at'] = disabledAt;
|
data['disabled_at'] = disabledAt;
|
||||||
data['current_status'] = currentStatus;
|
data['current_status'] = currentStatus;
|
||||||
data['created_at'] = createdAt;
|
data['created_at'] = createdAt;
|
||||||
data['updated_at'] = updatedAt;
|
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -107,14 +107,14 @@ class AppService {
|
||||||
final String auth = 'Bearer ${pref.getString('token')}';
|
final String auth = 'Bearer ${pref.getString('token')}';
|
||||||
try {
|
try {
|
||||||
await Future.delayed(const Duration(seconds: 3));
|
await Future.delayed(const Duration(seconds: 3));
|
||||||
final result = await _dioWithoutInterceptor.get(
|
final response = await _dioWithoutInterceptor.get(
|
||||||
'/api/get-relay',
|
'/api/relay/get-relay',
|
||||||
options: Options(
|
options: Options(
|
||||||
headers: {'Authorization': auth},
|
headers: {'Authorization': auth},
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
if (result.statusCode == 200) {
|
if (response.statusCode == 200) {
|
||||||
final data = RelayResponse.fromJson(result.data);
|
final data = RelayResponse.fromJson(response.data);
|
||||||
return data;
|
return data;
|
||||||
} else {
|
} else {
|
||||||
throw Exception('Failed to load data');
|
throw Exception('Failed to load data');
|
||||||
|
|
@ -134,7 +134,7 @@ class AppService {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
final response = await _dioWithoutInterceptor.post(
|
final response = await _dioWithoutInterceptor.post(
|
||||||
'/api/set-relay',
|
'/api/relay/set-relay',
|
||||||
data: {
|
data: {
|
||||||
'id': relayNumber,
|
'id': relayNumber,
|
||||||
'state': state,
|
'state': state,
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,4 @@
|
||||||
import 'package:firebase_messaging/firebase_messaging.dart';
|
import 'package:firebase_messaging/firebase_messaging.dart';
|
||||||
import 'package:flutter/foundation.dart';
|
|
||||||
|
|
||||||
class FirebaseApi {
|
class FirebaseApi {
|
||||||
final _firebaseMessaging = FirebaseMessaging.instance;
|
final _firebaseMessaging = FirebaseMessaging.instance;
|
||||||
|
|
@ -11,10 +10,5 @@ class FirebaseApi {
|
||||||
provisional: false,
|
provisional: false,
|
||||||
sound: true,
|
sound: true,
|
||||||
);
|
);
|
||||||
|
|
||||||
final fCMToken = await _firebaseMessaging.getToken();
|
|
||||||
if (kDebugMode) {
|
|
||||||
print('FCM Token: $fCMToken');
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,11 @@
|
||||||
import 'dart:convert';
|
// import 'dart:convert';
|
||||||
|
|
||||||
import 'package:agrilink_vocpro/core/state/result_state.dart';
|
import 'package:agrilink_vocpro/core/state/result_state.dart';
|
||||||
import 'package:agrilink_vocpro/domain/service/app_service.dart';
|
import 'package:agrilink_vocpro/domain/service/app_service.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter/services.dart';
|
// import 'package:flutter/services.dart';
|
||||||
import 'package:googleapis_auth/auth_io.dart';
|
// import 'package:googleapis_auth/auth_io.dart';
|
||||||
import 'package:http/http.dart' as http;
|
// import 'package:http/http.dart' as http;
|
||||||
|
|
||||||
class AuthProvider extends ChangeNotifier {
|
class AuthProvider extends ChangeNotifier {
|
||||||
TextEditingController emailController = TextEditingController();
|
TextEditingController emailController = TextEditingController();
|
||||||
|
|
@ -80,30 +80,30 @@ class AuthProvider extends ChangeNotifier {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> getAccessToken() async {
|
// Future<void> getAccessToken() async {
|
||||||
try {
|
// try {
|
||||||
final serviceAccountJson = await rootBundle.loadString(
|
// final serviceAccountJson = await rootBundle.loadString(
|
||||||
'assets/json/agrilink-vocpro-b37f9-firebase-adminsdk-a4f6g-e6565344e3.json',
|
// 'assets/json/agrilink-vocpro-b37f9-firebase-adminsdk-a4f6g-e6565344e3.json',
|
||||||
);
|
// );
|
||||||
|
|
||||||
final accountCredentials = ServiceAccountCredentials.fromJson(
|
// final accountCredentials = ServiceAccountCredentials.fromJson(
|
||||||
json.decode(serviceAccountJson),
|
// 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 {
|
// try {
|
||||||
final accessCredential = await obtainAccessCredentialsViaServiceAccount(
|
// final accessCredential = await obtainAccessCredentialsViaServiceAccount(
|
||||||
accountCredentials, scope, client);
|
// accountCredentials, scope, client);
|
||||||
final accessToken = accessCredential.accessToken.data;
|
// final accessToken = accessCredential.accessToken.data;
|
||||||
print('Access Token: $accessToken');
|
// print('Access Token: $accessToken');
|
||||||
} catch (e) {
|
// } catch (e) {
|
||||||
print('Error: $e');
|
// print('Error: $e');
|
||||||
}
|
// }
|
||||||
} catch (e) {
|
// } catch (e) {
|
||||||
print('Error 2: $e');
|
// print('Error 2: $e');
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -23,15 +23,15 @@ class LoginScreen extends StatelessWidget {
|
||||||
children: [
|
children: [
|
||||||
const SizedBox(height: 40),
|
const SizedBox(height: 40),
|
||||||
Text(
|
Text(
|
||||||
'Hello, Welcome back 👋',
|
'Halo, Selamat Datang 👋',
|
||||||
style: AppTheme.titleLarge,
|
style: AppTheme.titleLarge,
|
||||||
),
|
),
|
||||||
Text(
|
Text(
|
||||||
'Happy to have you back',
|
'Senang melihatmu kembali',
|
||||||
style: AppTheme.titleMedium,
|
style: AppTheme.titleMedium,
|
||||||
),
|
),
|
||||||
const SizedBox(height: 40),
|
const SizedBox(height: 40),
|
||||||
Text('Email address', style: AppTheme.labelLarge),
|
Text('Alamat Email', style: AppTheme.labelLarge),
|
||||||
const SizedBox(height: 4),
|
const SizedBox(height: 4),
|
||||||
AppTextfield(
|
AppTextfield(
|
||||||
controller: authP.emailController,
|
controller: authP.emailController,
|
||||||
|
|
@ -77,11 +77,11 @@ class LoginScreen extends StatelessWidget {
|
||||||
text: 'Login',
|
text: 'Login',
|
||||||
),
|
),
|
||||||
SizedBox(height: 24),
|
SizedBox(height: 24),
|
||||||
AppButton(
|
// AppButton(
|
||||||
onPressed: () {
|
// onPressed: () {
|
||||||
authP.getAccessToken();
|
// authP.getAccessToken();
|
||||||
},
|
// },
|
||||||
text: 'Get Access Token'),
|
// text: 'Get Access Token'),
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
import 'package:agrilink_vocpro/core/state/result_state.dart';
|
import 'package:agrilink_vocpro/core/state/result_state.dart';
|
||||||
|
import 'package:agrilink_vocpro/data/model/relay_response.dart';
|
||||||
import 'package:agrilink_vocpro/domain/service/app_service.dart';
|
import 'package:agrilink_vocpro/domain/service/app_service.dart';
|
||||||
import 'package:flutter/foundation.dart';
|
import 'package:flutter/foundation.dart';
|
||||||
|
|
||||||
|
|
@ -11,43 +12,24 @@ class ControlProvider extends ChangeNotifier {
|
||||||
bool _control_2 = false;
|
bool _control_2 = false;
|
||||||
bool get control_2 => _control_2;
|
bool get control_2 => _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() {
|
ControlProvider() {
|
||||||
getRelayStatus();
|
getRelayStatus();
|
||||||
}
|
}
|
||||||
|
|
||||||
// ResultState mqttState = ResultState.initial;
|
|
||||||
// ResultState subscribeState = ResultState.initial;
|
|
||||||
|
|
||||||
ResultState relayState = ResultState.initial;
|
ResultState relayState = ResultState.initial;
|
||||||
|
|
||||||
// Future<void> 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<void> getRelayStatus() async {
|
Future<void> getRelayStatus() async {
|
||||||
relayState = ResultState.loading;
|
relayState = ResultState.loading;
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
|
|
@ -59,10 +41,16 @@ class ControlProvider extends ChangeNotifier {
|
||||||
if (result.success == true) {
|
if (result.success == true) {
|
||||||
for (var element in result.data!) {
|
for (var element in result.data!) {
|
||||||
if (element.number == 1) {
|
if (element.number == 1) {
|
||||||
switchControl1(element.currentStatus ?? false);
|
_relay1 = element;
|
||||||
|
switchControl(element.currentStatus ?? false, relayNumber: 1);
|
||||||
}
|
}
|
||||||
if (element.number == 2) {
|
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;
|
relayState = ResultState.hasData;
|
||||||
|
|
@ -75,7 +63,7 @@ class ControlProvider extends ChangeNotifier {
|
||||||
relayState = ResultState.error;
|
relayState = ResultState.error;
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
if (kDebugMode) {
|
if (kDebugMode) {
|
||||||
print(e);
|
print('Error Getting Relay Status: $e');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -84,15 +72,13 @@ class ControlProvider extends ChangeNotifier {
|
||||||
relayState = ResultState.loading;
|
relayState = ResultState.loading;
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
|
|
||||||
final int stateConverted;
|
final int stateConverted = state ? 1 : 0;
|
||||||
if (state == true) {
|
|
||||||
stateConverted = 1;
|
|
||||||
} else {
|
|
||||||
stateConverted = 0;
|
|
||||||
}
|
|
||||||
try {
|
try {
|
||||||
final result = await _appService.switchRelay(
|
final result = await _appService.switchRelay(
|
||||||
relayNumber: relayNumber, state: stateConverted);
|
relayNumber: relayNumber,
|
||||||
|
state: stateConverted,
|
||||||
|
);
|
||||||
|
|
||||||
if (result.success == true) {
|
if (result.success == true) {
|
||||||
relayState = ResultState.hasData;
|
relayState = ResultState.hasData;
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
|
|
@ -113,32 +99,20 @@ class ControlProvider extends ChangeNotifier {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void switchControl1(bool value) {
|
void switchControl(bool value, {required int relayNumber}) {
|
||||||
|
switch (relayNumber) {
|
||||||
|
case 1:
|
||||||
_control_1 = value;
|
_control_1 = value;
|
||||||
notifyListeners();
|
break;
|
||||||
}
|
case 2:
|
||||||
|
|
||||||
void switchControl2(bool value) {
|
|
||||||
_control_2 = value;
|
_control_2 = value;
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
_control_3 = value;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return;
|
||||||
|
}
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Future<ResultState> publishMessage(String topic, String message) async {
|
|
||||||
// try {
|
|
||||||
// final result = await _mqttService.publishMessage(topic, message);
|
|
||||||
// return result;
|
|
||||||
// } catch (e) {
|
|
||||||
// print(e);
|
|
||||||
// rethrow;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// Future<void> subscribeToTopic(String topic) async {
|
|
||||||
// try {
|
|
||||||
// await _mqttService.subscribeToTopic(topic);
|
|
||||||
// } catch (e) {
|
|
||||||
// print(e);
|
|
||||||
// rethrow;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,8 @@ import 'package:agrilink_vocpro/core/constant/app_theme.dart';
|
||||||
import 'package:agrilink_vocpro/core/state/result_state.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/provider/control_provider.dart';
|
||||||
import 'package:agrilink_vocpro/features/control/widgets/control_button_widget.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:bootstrap_icons/bootstrap_icons.dart';
|
||||||
import 'package:flutter/cupertino.dart';
|
import 'package:flutter/cupertino.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
|
@ -16,7 +18,7 @@ class ControlScreen extends StatelessWidget {
|
||||||
final provider = Provider.of<ControlProvider>(context, listen: true);
|
final provider = Provider.of<ControlProvider>(context, listen: true);
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
appBar: AppBar(
|
appBar: AppBar(
|
||||||
title: Text('Control', style: AppTheme.labelMedium),
|
title: Text('Kontrol', style: AppTheme.labelMedium),
|
||||||
centerTitle: true,
|
centerTitle: true,
|
||||||
backgroundColor: Colors.white,
|
backgroundColor: Colors.white,
|
||||||
scrolledUnderElevation: 0,
|
scrolledUnderElevation: 0,
|
||||||
|
|
@ -34,7 +36,7 @@ class ControlScreen extends StatelessWidget {
|
||||||
return const StatusBarWidget(
|
return const StatusBarWidget(
|
||||||
text: 'Memuat...',
|
text: 'Memuat...',
|
||||||
icon: BootstrapIcons.cloud,
|
icon: BootstrapIcons.cloud,
|
||||||
color: Colors.cyan,
|
color: Colors.grey,
|
||||||
isLoading: true,
|
isLoading: true,
|
||||||
);
|
);
|
||||||
case ResultState.hasData:
|
case ResultState.hasData:
|
||||||
|
|
@ -59,6 +61,12 @@ class ControlScreen extends StatelessWidget {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
|
PumpStatusWidget(
|
||||||
|
title: 'Pompa Air',
|
||||||
|
subtitle: 'Relay 3',
|
||||||
|
isActive: provider.control_3,
|
||||||
|
onTap: () {},
|
||||||
|
),
|
||||||
SizedBox(height: 16.h),
|
SizedBox(height: 16.h),
|
||||||
GridView(
|
GridView(
|
||||||
padding: EdgeInsets.all(16.r),
|
padding: EdgeInsets.all(16.r),
|
||||||
|
|
@ -72,36 +80,118 @@ class ControlScreen extends StatelessWidget {
|
||||||
),
|
),
|
||||||
children: [
|
children: [
|
||||||
ControlButtonWidget(
|
ControlButtonWidget(
|
||||||
title: 'Katup Air',
|
title: 'Katup Nutrisi',
|
||||||
subtitle: 'Relay 1',
|
subtitle: 'Relay 1',
|
||||||
isActive: provider.control_1,
|
isActive: provider.control_1,
|
||||||
onTap: () async {
|
onTap: () async {
|
||||||
final result = provider.control_1 != true
|
await _changeRelayStateAction(
|
||||||
? await provider.switchRelay(1, true)
|
provider: provider,
|
||||||
: await provider.switchRelay(1, false);
|
relayOn: 1,
|
||||||
result == true
|
relayOff: 2,
|
||||||
? provider.switchControl1(!provider.control_1)
|
);
|
||||||
: provider.switchControl1(provider.control_1);
|
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
ControlButtonWidget(
|
ControlButtonWidget(
|
||||||
title: 'Lampu Utama',
|
title: 'Katup Air',
|
||||||
subtitle: 'Relay 2',
|
subtitle: 'Relay 2',
|
||||||
isActive: provider.control_2,
|
isActive: provider.control_2,
|
||||||
onTap: () {
|
onTap: () async {
|
||||||
provider.control_2 != true
|
await _changeRelayStateAction(
|
||||||
? provider.switchControl2(true)
|
provider: provider,
|
||||||
: provider.switchControl2(false);
|
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<ControlProvider>(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<void> _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 {
|
class StatusBarWidget extends StatelessWidget {
|
||||||
|
|
|
||||||
|
|
@ -32,8 +32,8 @@ class ControlButtonWidget extends StatelessWidget {
|
||||||
boxShadow: [
|
boxShadow: [
|
||||||
BoxShadow(
|
BoxShadow(
|
||||||
color: isActive
|
color: isActive
|
||||||
? AppColor.secondary.withOpacity(0.2)
|
? AppColor.secondary.withValues(alpha: 0.2)
|
||||||
: Colors.grey.withOpacity(0.2),
|
: Colors.grey.withValues(alpha: 0.2),
|
||||||
spreadRadius: 1.r,
|
spreadRadius: 1.r,
|
||||||
blurRadius: 16.r,
|
blurRadius: 16.r,
|
||||||
offset: Offset(0, 12.r),
|
offset: Offset(0, 12.r),
|
||||||
|
|
|
||||||
|
|
@ -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.withValues(alpha: 0.2)
|
||||||
|
: Colors.grey.withValues(alpha: 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<ControlProvider>(
|
||||||
|
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,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -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,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -26,22 +26,22 @@ class DashboardScreen extends StatelessWidget {
|
||||||
BottomNavigationBarItem(
|
BottomNavigationBarItem(
|
||||||
icon: Icon(BootstrapIcons.house),
|
icon: Icon(BootstrapIcons.house),
|
||||||
activeIcon: Icon(BootstrapIcons.house_fill),
|
activeIcon: Icon(BootstrapIcons.house_fill),
|
||||||
label: 'Home',
|
label: 'Beranda',
|
||||||
),
|
),
|
||||||
BottomNavigationBarItem(
|
BottomNavigationBarItem(
|
||||||
icon: Icon(BootstrapIcons.toggle_off),
|
icon: Icon(BootstrapIcons.toggle_off),
|
||||||
activeIcon: Icon(BootstrapIcons.toggle_on),
|
activeIcon: Icon(BootstrapIcons.toggle_on),
|
||||||
label: 'Control',
|
label: 'Kontrol',
|
||||||
),
|
),
|
||||||
BottomNavigationBarItem(
|
BottomNavigationBarItem(
|
||||||
icon: Icon(BootstrapIcons.flower1),
|
icon: Icon(BootstrapIcons.flower1),
|
||||||
activeIcon: Icon(BootstrapIcons.flower1),
|
activeIcon: Icon(BootstrapIcons.flower1),
|
||||||
label: 'Plants',
|
label: 'Tanaman',
|
||||||
),
|
),
|
||||||
BottomNavigationBarItem(
|
BottomNavigationBarItem(
|
||||||
icon: Icon(BootstrapIcons.gear),
|
icon: Icon(BootstrapIcons.gear),
|
||||||
activeIcon: Icon(BootstrapIcons.gear_fill),
|
activeIcon: Icon(BootstrapIcons.gear_fill),
|
||||||
label: 'Setting',
|
label: 'Pengaturan',
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
|
|
||||||
|
|
@ -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/core/state/result_state.dart';
|
||||||
import 'package:agrilink_vocpro/data/model/latest_data_response.dart';
|
import 'package:agrilink_vocpro/data/model/latest_data_response.dart';
|
||||||
import 'package:agrilink_vocpro/domain/service/app_service.dart';
|
import 'package:agrilink_vocpro/domain/service/app_service.dart';
|
||||||
|
|
@ -17,8 +18,8 @@ class ConductivityProvider extends ChangeNotifier {
|
||||||
dataState = ResultState.loading;
|
dataState = ResultState.loading;
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
try {
|
try {
|
||||||
final result =
|
final result = await AppService()
|
||||||
await AppService().getGraphicDataNpk1(metric: 'soilConductivity');
|
.getGraphicDataNpk1(metric: AppConstant.conductivity);
|
||||||
if (result.data == null || result.data!.npk1!.isEmpty) {
|
if (result.data == null || result.data!.npk1!.isEmpty) {
|
||||||
dataState = ResultState.noData;
|
dataState = ResultState.noData;
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -27,7 +28,7 @@ class ConductivityProvider extends ChangeNotifier {
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
if (kDebugMode) {
|
if (kDebugMode) {
|
||||||
print('Get Grafik Soil Temp Error: $e');
|
print('Get Grafik Conductivity Error: $e');
|
||||||
}
|
}
|
||||||
dataState = ResultState.error;
|
dataState = ResultState.error;
|
||||||
}
|
}
|
||||||
|
|
@ -38,8 +39,8 @@ class ConductivityProvider extends ChangeNotifier {
|
||||||
dataState = ResultState.loading;
|
dataState = ResultState.loading;
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
try {
|
try {
|
||||||
final result =
|
final result = await AppService()
|
||||||
await AppService().getGraphicDataNpk2(metric: 'soilConductivity');
|
.getGraphicDataNpk2(metric: AppConstant.conductivity);
|
||||||
if (result.data == null || result.data!.npk2!.isEmpty) {
|
if (result.data == null || result.data!.npk2!.isEmpty) {
|
||||||
dataState = ResultState.noData;
|
dataState = ResultState.noData;
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -48,7 +49,7 @@ class ConductivityProvider extends ChangeNotifier {
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
if (kDebugMode) {
|
if (kDebugMode) {
|
||||||
print('Get Grafik Soil Temp Error: $e');
|
print('Get Grafik Conductivity Error: $e');
|
||||||
}
|
}
|
||||||
dataState = ResultState.error;
|
dataState = ResultState.error;
|
||||||
}
|
}
|
||||||
|
|
@ -1,7 +1,8 @@
|
||||||
import 'package:agrilink_vocpro/core/constant/app_theme.dart';
|
import 'package:agrilink_vocpro/core/constant/app_theme.dart';
|
||||||
import 'package:agrilink_vocpro/core/state/result_state.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/core/widgets/error_data_state_widget.dart';
|
||||||
import 'package:agrilink_vocpro/features/home/widgets/graphic_error_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_widget.dart';
|
import 'package:agrilink_vocpro/features/home/widgets/graphic_widget.dart';
|
||||||
import 'package:bootstrap_icons/bootstrap_icons.dart';
|
import 'package:bootstrap_icons/bootstrap_icons.dart';
|
||||||
import 'package:flutter/cupertino.dart';
|
import 'package:flutter/cupertino.dart';
|
||||||
|
|
@ -94,7 +95,7 @@ class ConductivityScreen extends StatelessWidget {
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
children: [
|
children: [
|
||||||
Text(
|
Text(
|
||||||
'Soil Condutivity',
|
'Konduktifitas Tanah',
|
||||||
style: AppTheme.labelMedium,
|
style: AppTheme.labelMedium,
|
||||||
textAlign: TextAlign.center,
|
textAlign: TextAlign.center,
|
||||||
),
|
),
|
||||||
|
|
@ -143,14 +144,12 @@ class ConductivityScreen extends StatelessWidget {
|
||||||
? provider.dataFetchedNpk1[index].soilconductivity ?? 0
|
? provider.dataFetchedNpk1[index].soilconductivity ?? 0
|
||||||
: provider.dataFetchedNpk2[index].soilconductivity ?? 0,
|
: provider.dataFetchedNpk2[index].soilconductivity ?? 0,
|
||||||
),
|
),
|
||||||
maxValue: 1,
|
|
||||||
);
|
);
|
||||||
case ResultState.error:
|
case ResultState.error:
|
||||||
return const GraphicErrorWidget(message: 'Terjadi Kesalahan');
|
return const ErrorDataStateWidget();
|
||||||
case ResultState.noData:
|
case ResultState.noData:
|
||||||
return const GraphicErrorWidget(message: 'Tidak Ada Data');
|
return const NoDataStateWidget();
|
||||||
case ResultState.initial:
|
case ResultState.initial:
|
||||||
default:
|
|
||||||
return const SizedBox.shrink();
|
return const SizedBox.shrink();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
@ -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/core/state/result_state.dart';
|
||||||
import 'package:agrilink_vocpro/data/model/latest_data_response.dart';
|
import 'package:agrilink_vocpro/data/model/latest_data_response.dart';
|
||||||
import 'package:agrilink_vocpro/domain/service/app_service.dart';
|
import 'package:agrilink_vocpro/domain/service/app_service.dart';
|
||||||
|
|
@ -16,7 +17,7 @@ class HumidityProvider extends ChangeNotifier {
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
try {
|
try {
|
||||||
final result =
|
final result =
|
||||||
await AppService().getGrafikDataDht(metric: 'viciHumidity');
|
await AppService().getGrafikDataDht(metric: AppConstant.humidity);
|
||||||
if (result.data == null || result.data!.dht!.isEmpty) {
|
if (result.data == null || result.data!.dht!.isEmpty) {
|
||||||
dataState = ResultState.noData;
|
dataState = ResultState.noData;
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -1,6 +1,8 @@
|
||||||
import 'package:agrilink_vocpro/core/constant/app_theme.dart';
|
import 'package:agrilink_vocpro/core/constant/app_theme.dart';
|
||||||
import 'package:agrilink_vocpro/core/state/result_state.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/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/provider/home_provider.dart';
|
||||||
import 'package:agrilink_vocpro/features/home/widgets/graphic_widget.dart';
|
import 'package:agrilink_vocpro/features/home/widgets/graphic_widget.dart';
|
||||||
import 'package:bootstrap_icons/bootstrap_icons.dart';
|
import 'package:bootstrap_icons/bootstrap_icons.dart';
|
||||||
|
|
@ -94,7 +96,7 @@ class HumidityScreen extends StatelessWidget {
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
children: [
|
children: [
|
||||||
Text(
|
Text(
|
||||||
'Humidity',
|
'Kelembaban Udara',
|
||||||
style: AppTheme.labelMedium,
|
style: AppTheme.labelMedium,
|
||||||
textAlign: TextAlign.center,
|
textAlign: TextAlign.center,
|
||||||
),
|
),
|
||||||
|
|
@ -108,7 +110,7 @@ class HumidityScreen extends StatelessWidget {
|
||||||
const SizedBox(height: 16),
|
const SizedBox(height: 16),
|
||||||
Padding(
|
Padding(
|
||||||
padding: EdgeInsets.only(left: 16.w),
|
padding: EdgeInsets.only(left: 16.w),
|
||||||
child: const Text('Grafik dalam 7 hari terakhir'),
|
child: const Text('Grafik'),
|
||||||
),
|
),
|
||||||
const SizedBox(height: 16),
|
const SizedBox(height: 16),
|
||||||
AspectRatio(
|
AspectRatio(
|
||||||
|
|
@ -145,54 +147,16 @@ class HumidityScreen extends StatelessWidget {
|
||||||
0),
|
0),
|
||||||
);
|
);
|
||||||
case ResultState.error:
|
case ResultState.error:
|
||||||
return Center(
|
return const ErrorDataStateWidget();
|
||||||
child: Column(
|
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
|
||||||
children: [
|
|
||||||
Icon(
|
|
||||||
BootstrapIcons.exclamation_circle,
|
|
||||||
color: Colors.grey.shade400,
|
|
||||||
),
|
|
||||||
SizedBox(height: 8.h),
|
|
||||||
Text(
|
|
||||||
'Terjadi Kesalahan',
|
|
||||||
style: AppTheme.labelSmall,
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
);
|
|
||||||
case ResultState.noData:
|
case ResultState.noData:
|
||||||
return Center(
|
return const NoDataStateWidget();
|
||||||
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,
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
);
|
|
||||||
case ResultState.initial:
|
case ResultState.initial:
|
||||||
return const SizedBox.shrink();
|
return const SizedBox.shrink();
|
||||||
default:
|
|
||||||
return const Center(
|
|
||||||
child: Text('Default Error'),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
SizedBox(height: 16.h),
|
SizedBox(height: 16.h),
|
||||||
Padding(
|
|
||||||
padding: EdgeInsets.only(left: 16.w),
|
|
||||||
child: const Text('Deskripsi'),
|
|
||||||
),
|
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
}),
|
}),
|
||||||
|
|
@ -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/core/state/result_state.dart';
|
||||||
import 'package:agrilink_vocpro/data/model/latest_data_response.dart';
|
import 'package:agrilink_vocpro/data/model/latest_data_response.dart';
|
||||||
import 'package:agrilink_vocpro/domain/service/app_service.dart';
|
import 'package:agrilink_vocpro/domain/service/app_service.dart';
|
||||||
|
|
@ -15,8 +16,8 @@ class LumProvider extends ChangeNotifier {
|
||||||
dataState = ResultState.loading;
|
dataState = ResultState.loading;
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
try {
|
try {
|
||||||
final result =
|
final result = await AppService()
|
||||||
await AppService().getGrafikDataDht(metric: 'viciluminosity');
|
.getGrafikDataDht(metric: AppConstant.lightIntensity);
|
||||||
if (result.data == null || result.data!.dht!.isEmpty) {
|
if (result.data == null || result.data!.dht!.isEmpty) {
|
||||||
dataState = ResultState.noData;
|
dataState = ResultState.noData;
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
import 'package:agrilink_vocpro/core/constant/app_theme.dart';
|
import 'package:agrilink_vocpro/core/constant/app_theme.dart';
|
||||||
import 'package:agrilink_vocpro/core/state/result_state.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:agrilink_vocpro/features/home/widgets/graphic_widget.dart';
|
||||||
import 'package:bootstrap_icons/bootstrap_icons.dart';
|
import 'package:bootstrap_icons/bootstrap_icons.dart';
|
||||||
import 'package:flutter/cupertino.dart';
|
import 'package:flutter/cupertino.dart';
|
||||||
|
|
@ -64,7 +64,7 @@ class LightScreen extends StatelessWidget {
|
||||||
axis: GaugeAxis(
|
axis: GaugeAxis(
|
||||||
degrees: 360,
|
degrees: 360,
|
||||||
min: 0,
|
min: 0,
|
||||||
max: 1000,
|
max: 500,
|
||||||
style: GaugeAxisStyle(
|
style: GaugeAxisStyle(
|
||||||
background: Colors.grey.shade100,
|
background: Colors.grey.shade100,
|
||||||
thickness: 100,
|
thickness: 100,
|
||||||
|
|
@ -82,7 +82,7 @@ class LightScreen extends StatelessWidget {
|
||||||
),
|
),
|
||||||
const SizedBox(height: 16),
|
const SizedBox(height: 16),
|
||||||
Text(
|
Text(
|
||||||
'${value.toStringAsFixed(0)} lux',
|
'$value lux',
|
||||||
textAlign: TextAlign.center,
|
textAlign: TextAlign.center,
|
||||||
style: const TextStyle(
|
style: const TextStyle(
|
||||||
fontSize: 28,
|
fontSize: 28,
|
||||||
|
|
@ -137,6 +137,7 @@ class LightScreen extends StatelessWidget {
|
||||||
provider.dataFetched[index].vicihumidity
|
provider.dataFetched[index].vicihumidity
|
||||||
?.toDouble() ??
|
?.toDouble() ??
|
||||||
0),
|
0),
|
||||||
|
maxValue: 500,
|
||||||
);
|
);
|
||||||
case ResultState.error:
|
case ResultState.error:
|
||||||
return Center(
|
return Center(
|
||||||
|
|
@ -174,10 +175,6 @@ class LightScreen extends StatelessWidget {
|
||||||
);
|
);
|
||||||
case ResultState.initial:
|
case ResultState.initial:
|
||||||
return const SizedBox.shrink();
|
return const SizedBox.shrink();
|
||||||
default:
|
|
||||||
return const Center(
|
|
||||||
child: Text('Default Error'),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
),
|
),
|
||||||
|
|
@ -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/core/state/result_state.dart';
|
||||||
import 'package:agrilink_vocpro/data/model/latest_data_response.dart';
|
import 'package:agrilink_vocpro/data/model/latest_data_response.dart';
|
||||||
import 'package:agrilink_vocpro/domain/service/app_service.dart';
|
import 'package:agrilink_vocpro/domain/service/app_service.dart';
|
||||||
|
|
@ -18,7 +19,7 @@ class NitrogenProvider extends ChangeNotifier {
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
try {
|
try {
|
||||||
final result =
|
final result =
|
||||||
await AppService().getGraphicDataNpk1(metric: 'soilNitrogen');
|
await AppService().getGraphicDataNpk1(metric: AppConstant.nitrogen);
|
||||||
if (result.data == null || result.data!.npk1!.isEmpty) {
|
if (result.data == null || result.data!.npk1!.isEmpty) {
|
||||||
dataState = ResultState.noData;
|
dataState = ResultState.noData;
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -39,7 +40,7 @@ class NitrogenProvider extends ChangeNotifier {
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
try {
|
try {
|
||||||
final result =
|
final result =
|
||||||
await AppService().getGraphicDataNpk2(metric: 'soilNitrogen');
|
await AppService().getGraphicDataNpk2(metric: AppConstant.nitrogen);
|
||||||
if (result.data == null || result.data!.npk2!.isEmpty) {
|
if (result.data == null || result.data!.npk2!.isEmpty) {
|
||||||
dataState = ResultState.noData;
|
dataState = ResultState.noData;
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -1,7 +1,8 @@
|
||||||
import 'package:agrilink_vocpro/core/constant/app_theme.dart';
|
import 'package:agrilink_vocpro/core/constant/app_theme.dart';
|
||||||
import 'package:agrilink_vocpro/core/state/result_state.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/core/widgets/error_data_state_widget.dart';
|
||||||
import 'package:agrilink_vocpro/features/home/widgets/graphic_error_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_widget.dart';
|
import 'package:agrilink_vocpro/features/home/widgets/graphic_widget.dart';
|
||||||
import 'package:bootstrap_icons/bootstrap_icons.dart';
|
import 'package:bootstrap_icons/bootstrap_icons.dart';
|
||||||
import 'package:flutter/cupertino.dart';
|
import 'package:flutter/cupertino.dart';
|
||||||
|
|
@ -83,7 +84,7 @@ class NitrogenScreen extends StatelessWidget {
|
||||||
size: 64.r,
|
size: 64.r,
|
||||||
color: Colors.blue,
|
color: Colors.blue,
|
||||||
),
|
),
|
||||||
Text('$value ppm', style: AppTheme.headline1),
|
Text('$value mg/L', style: AppTheme.headline1),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
@ -94,7 +95,7 @@ class NitrogenScreen extends StatelessWidget {
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
children: [
|
children: [
|
||||||
Text(
|
Text(
|
||||||
'Soil Nitrogen',
|
'Nitrogen Tanah',
|
||||||
style: AppTheme.labelMedium,
|
style: AppTheme.labelMedium,
|
||||||
textAlign: TextAlign.center,
|
textAlign: TextAlign.center,
|
||||||
),
|
),
|
||||||
|
|
@ -143,14 +144,13 @@ class NitrogenScreen extends StatelessWidget {
|
||||||
? provider.dataFetchedNpk1[index].soilnitrogen ?? 0
|
? provider.dataFetchedNpk1[index].soilnitrogen ?? 0
|
||||||
: provider.dataFetchedNpk2[index].soilnitrogen ?? 0,
|
: provider.dataFetchedNpk2[index].soilnitrogen ?? 0,
|
||||||
),
|
),
|
||||||
maxValue: 1,
|
maxValue: 10,
|
||||||
);
|
);
|
||||||
case ResultState.error:
|
case ResultState.error:
|
||||||
return const GraphicErrorWidget(message: 'Terjadi Kesalahan');
|
return const ErrorDataStateWidget();
|
||||||
case ResultState.noData:
|
case ResultState.noData:
|
||||||
return const GraphicErrorWidget(message: 'Tidak Ada Data');
|
return const NoDataStateWidget();
|
||||||
case ResultState.initial:
|
case ResultState.initial:
|
||||||
default:
|
|
||||||
return const SizedBox.shrink();
|
return const SizedBox.shrink();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
@ -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/core/state/result_state.dart';
|
||||||
import 'package:agrilink_vocpro/data/model/latest_data_response.dart';
|
import 'package:agrilink_vocpro/data/model/latest_data_response.dart';
|
||||||
import 'package:agrilink_vocpro/domain/service/app_service.dart';
|
import 'package:agrilink_vocpro/domain/service/app_service.dart';
|
||||||
|
|
@ -17,7 +18,8 @@ class PhProvider extends ChangeNotifier {
|
||||||
dataState = ResultState.loading;
|
dataState = ResultState.loading;
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
try {
|
try {
|
||||||
final result = await AppService().getGraphicDataNpk1(metric: 'soilPh');
|
final result =
|
||||||
|
await AppService().getGraphicDataNpk1(metric: AppConstant.ph);
|
||||||
if (result.data == null || result.data!.npk1!.isEmpty) {
|
if (result.data == null || result.data!.npk1!.isEmpty) {
|
||||||
dataState = ResultState.noData;
|
dataState = ResultState.noData;
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -26,7 +28,7 @@ class PhProvider extends ChangeNotifier {
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
if (kDebugMode) {
|
if (kDebugMode) {
|
||||||
print('Get Grafik Soil Temp Error: $e');
|
print('Get Grafik Soil pH Error: $e');
|
||||||
}
|
}
|
||||||
dataState = ResultState.error;
|
dataState = ResultState.error;
|
||||||
}
|
}
|
||||||
|
|
@ -37,7 +39,8 @@ class PhProvider extends ChangeNotifier {
|
||||||
dataState = ResultState.loading;
|
dataState = ResultState.loading;
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
try {
|
try {
|
||||||
final result = await AppService().getGraphicDataNpk2(metric: 'soilPh');
|
final result =
|
||||||
|
await AppService().getGraphicDataNpk2(metric: AppConstant.ph);
|
||||||
if (result.data == null || result.data!.npk2!.isEmpty) {
|
if (result.data == null || result.data!.npk2!.isEmpty) {
|
||||||
dataState = ResultState.noData;
|
dataState = ResultState.noData;
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -46,7 +49,7 @@ class PhProvider extends ChangeNotifier {
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
if (kDebugMode) {
|
if (kDebugMode) {
|
||||||
print('Get Grafik Soil Temp Error: $e');
|
print('Get Grafik Soil pH Error: $e');
|
||||||
}
|
}
|
||||||
dataState = ResultState.error;
|
dataState = ResultState.error;
|
||||||
}
|
}
|
||||||
|
|
@ -1,8 +1,9 @@
|
||||||
import 'package:agrilink_vocpro/core/constant/app_theme.dart';
|
import 'package:agrilink_vocpro/core/constant/app_theme.dart';
|
||||||
import 'package:agrilink_vocpro/core/state/result_state.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/core/widgets/error_data_state_widget.dart';
|
||||||
import 'package:agrilink_vocpro/features/home/pages/ph/widget/ph_bar_pointer.dart';
|
import 'package:agrilink_vocpro/core/widgets/no_data_state_widget.dart';
|
||||||
import 'package:agrilink_vocpro/features/home/widgets/graphic_error_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_widget.dart';
|
import 'package:agrilink_vocpro/features/home/widgets/graphic_widget.dart';
|
||||||
import 'package:bootstrap_icons/bootstrap_icons.dart';
|
import 'package:bootstrap_icons/bootstrap_icons.dart';
|
||||||
import 'package:flutter/cupertino.dart';
|
import 'package:flutter/cupertino.dart';
|
||||||
|
|
@ -85,7 +86,7 @@ class PhScreen extends StatelessWidget {
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
children: [
|
children: [
|
||||||
Text(
|
Text(
|
||||||
'Soil Acidity',
|
'pH Tanah',
|
||||||
style: AppTheme.labelMedium,
|
style: AppTheme.labelMedium,
|
||||||
textAlign: TextAlign.center,
|
textAlign: TextAlign.center,
|
||||||
),
|
),
|
||||||
|
|
@ -137,11 +138,10 @@ class PhScreen extends StatelessWidget {
|
||||||
maxValue: 14,
|
maxValue: 14,
|
||||||
);
|
);
|
||||||
case ResultState.error:
|
case ResultState.error:
|
||||||
return const GraphicErrorWidget(message: 'Terjadi Kesalahan');
|
return const ErrorDataStateWidget();
|
||||||
case ResultState.noData:
|
case ResultState.noData:
|
||||||
return const GraphicErrorWidget(message: 'Tidak Ada Data');
|
return const NoDataStateWidget();
|
||||||
case ResultState.initial:
|
case ResultState.initial:
|
||||||
default:
|
|
||||||
return const SizedBox.shrink();
|
return const SizedBox.shrink();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
@ -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/core/state/result_state.dart';
|
||||||
import 'package:agrilink_vocpro/data/model/latest_data_response.dart';
|
import 'package:agrilink_vocpro/data/model/latest_data_response.dart';
|
||||||
import 'package:agrilink_vocpro/domain/service/app_service.dart';
|
import 'package:agrilink_vocpro/domain/service/app_service.dart';
|
||||||
|
|
@ -18,7 +19,7 @@ class PhosporusProvider extends ChangeNotifier {
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
try {
|
try {
|
||||||
final result =
|
final result =
|
||||||
await AppService().getGraphicDataNpk1(metric: 'soilPhosphorus');
|
await AppService().getGraphicDataNpk1(metric: AppConstant.phosphorus);
|
||||||
if (result.data == null || result.data!.npk1!.isEmpty) {
|
if (result.data == null || result.data!.npk1!.isEmpty) {
|
||||||
dataState = ResultState.noData;
|
dataState = ResultState.noData;
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -27,7 +28,7 @@ class PhosporusProvider extends ChangeNotifier {
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
if (kDebugMode) {
|
if (kDebugMode) {
|
||||||
print('Get Grafik Soil Temp Error: $e');
|
print('Get Grafik Phosphor Error: $e');
|
||||||
}
|
}
|
||||||
dataState = ResultState.error;
|
dataState = ResultState.error;
|
||||||
}
|
}
|
||||||
|
|
@ -39,7 +40,7 @@ class PhosporusProvider extends ChangeNotifier {
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
try {
|
try {
|
||||||
final result =
|
final result =
|
||||||
await AppService().getGraphicDataNpk2(metric: 'soilPhosphorus');
|
await AppService().getGraphicDataNpk2(metric: AppConstant.phosphorus);
|
||||||
if (result.data == null || result.data!.npk2!.isEmpty) {
|
if (result.data == null || result.data!.npk2!.isEmpty) {
|
||||||
dataState = ResultState.noData;
|
dataState = ResultState.noData;
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -48,7 +49,7 @@ class PhosporusProvider extends ChangeNotifier {
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
if (kDebugMode) {
|
if (kDebugMode) {
|
||||||
print('Get Grafik Soil Temp Error: $e');
|
print('Get Grafik Phosphor Error: $e');
|
||||||
}
|
}
|
||||||
dataState = ResultState.error;
|
dataState = ResultState.error;
|
||||||
}
|
}
|
||||||
|
|
@ -1,7 +1,8 @@
|
||||||
import 'package:agrilink_vocpro/core/constant/app_theme.dart';
|
import 'package:agrilink_vocpro/core/constant/app_theme.dart';
|
||||||
import 'package:agrilink_vocpro/core/state/result_state.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/core/widgets/error_data_state_widget.dart';
|
||||||
import 'package:agrilink_vocpro/features/home/widgets/graphic_error_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_widget.dart';
|
import 'package:agrilink_vocpro/features/home/widgets/graphic_widget.dart';
|
||||||
import 'package:bootstrap_icons/bootstrap_icons.dart';
|
import 'package:bootstrap_icons/bootstrap_icons.dart';
|
||||||
import 'package:flutter/cupertino.dart';
|
import 'package:flutter/cupertino.dart';
|
||||||
|
|
@ -83,7 +84,7 @@ class PhosphorusScreen extends StatelessWidget {
|
||||||
size: 64.r,
|
size: 64.r,
|
||||||
color: Colors.blue,
|
color: Colors.blue,
|
||||||
),
|
),
|
||||||
Text('$value ppm', style: AppTheme.headline1),
|
Text('$value mg/L', style: AppTheme.headline1),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
@ -94,7 +95,7 @@ class PhosphorusScreen extends StatelessWidget {
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
children: [
|
children: [
|
||||||
Text(
|
Text(
|
||||||
'Soil Phosphorus',
|
'Fosfor Tanah',
|
||||||
style: AppTheme.labelMedium,
|
style: AppTheme.labelMedium,
|
||||||
textAlign: TextAlign.center,
|
textAlign: TextAlign.center,
|
||||||
),
|
),
|
||||||
|
|
@ -143,14 +144,13 @@ class PhosphorusScreen extends StatelessWidget {
|
||||||
? provider.dataFetchedNpk1[index].soilphosphorus ?? 0
|
? provider.dataFetchedNpk1[index].soilphosphorus ?? 0
|
||||||
: provider.dataFetchedNpk2[index].soilphosphorus ?? 0,
|
: provider.dataFetchedNpk2[index].soilphosphorus ?? 0,
|
||||||
),
|
),
|
||||||
maxValue: 10,
|
maxValue: 100,
|
||||||
);
|
);
|
||||||
case ResultState.error:
|
case ResultState.error:
|
||||||
return const GraphicErrorWidget(message: 'Terjadi Kesalahan');
|
return const ErrorDataStateWidget();
|
||||||
case ResultState.noData:
|
case ResultState.noData:
|
||||||
return const GraphicErrorWidget(message: 'Tidak Ada Data');
|
return const NoDataStateWidget();
|
||||||
case ResultState.initial:
|
case ResultState.initial:
|
||||||
default:
|
|
||||||
return const SizedBox.shrink();
|
return const SizedBox.shrink();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
@ -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/core/state/result_state.dart';
|
||||||
import 'package:agrilink_vocpro/data/model/latest_data_response.dart';
|
import 'package:agrilink_vocpro/data/model/latest_data_response.dart';
|
||||||
import 'package:agrilink_vocpro/domain/service/app_service.dart';
|
import 'package:agrilink_vocpro/domain/service/app_service.dart';
|
||||||
|
|
@ -18,7 +19,7 @@ class PotassiumProvider extends ChangeNotifier {
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
try {
|
try {
|
||||||
final result =
|
final result =
|
||||||
await AppService().getGraphicDataNpk1(metric: 'soilPotassium');
|
await AppService().getGraphicDataNpk1(metric: AppConstant.potassium);
|
||||||
if (result.data == null || result.data!.npk1!.isEmpty) {
|
if (result.data == null || result.data!.npk1!.isEmpty) {
|
||||||
dataState = ResultState.noData;
|
dataState = ResultState.noData;
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -27,7 +28,7 @@ class PotassiumProvider extends ChangeNotifier {
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
if (kDebugMode) {
|
if (kDebugMode) {
|
||||||
print('Get Grafik Soil Temp Error: $e');
|
print('Get Grafik Potassium Error: $e');
|
||||||
}
|
}
|
||||||
dataState = ResultState.error;
|
dataState = ResultState.error;
|
||||||
}
|
}
|
||||||
|
|
@ -39,7 +40,7 @@ class PotassiumProvider extends ChangeNotifier {
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
try {
|
try {
|
||||||
final result =
|
final result =
|
||||||
await AppService().getGraphicDataNpk2(metric: 'soilPotassium');
|
await AppService().getGraphicDataNpk2(metric: AppConstant.potassium);
|
||||||
if (result.data == null || result.data!.npk2!.isEmpty) {
|
if (result.data == null || result.data!.npk2!.isEmpty) {
|
||||||
dataState = ResultState.noData;
|
dataState = ResultState.noData;
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -48,7 +49,7 @@ class PotassiumProvider extends ChangeNotifier {
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
if (kDebugMode) {
|
if (kDebugMode) {
|
||||||
print('Get Grafik Soil Temp Error: $e');
|
print('Get Grafik Potassium Error: $e');
|
||||||
}
|
}
|
||||||
dataState = ResultState.error;
|
dataState = ResultState.error;
|
||||||
}
|
}
|
||||||
|
|
@ -1,7 +1,8 @@
|
||||||
import 'package:agrilink_vocpro/core/constant/app_theme.dart';
|
import 'package:agrilink_vocpro/core/constant/app_theme.dart';
|
||||||
import 'package:agrilink_vocpro/core/state/result_state.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/core/widgets/error_data_state_widget.dart';
|
||||||
import 'package:agrilink_vocpro/features/home/widgets/graphic_error_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_widget.dart';
|
import 'package:agrilink_vocpro/features/home/widgets/graphic_widget.dart';
|
||||||
import 'package:bootstrap_icons/bootstrap_icons.dart';
|
import 'package:bootstrap_icons/bootstrap_icons.dart';
|
||||||
import 'package:flutter/cupertino.dart';
|
import 'package:flutter/cupertino.dart';
|
||||||
|
|
@ -24,7 +25,7 @@ class PotassiumScreen extends StatelessWidget {
|
||||||
length: 2,
|
length: 2,
|
||||||
child: Scaffold(
|
child: Scaffold(
|
||||||
appBar: AppBar(
|
appBar: AppBar(
|
||||||
title: Text('Soil Potassium', style: AppTheme.labelMedium),
|
title: Text('Soil Potassium (Kalium)', style: AppTheme.labelMedium),
|
||||||
centerTitle: true,
|
centerTitle: true,
|
||||||
backgroundColor: Colors.white,
|
backgroundColor: Colors.white,
|
||||||
scrolledUnderElevation: 0,
|
scrolledUnderElevation: 0,
|
||||||
|
|
@ -83,7 +84,7 @@ class PotassiumScreen extends StatelessWidget {
|
||||||
size: 64.r,
|
size: 64.r,
|
||||||
color: Colors.red,
|
color: Colors.red,
|
||||||
),
|
),
|
||||||
Text('$value ppm', style: AppTheme.headline1),
|
Text('$value mg/L', style: AppTheme.headline1),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
@ -94,7 +95,7 @@ class PotassiumScreen extends StatelessWidget {
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
children: [
|
children: [
|
||||||
Text(
|
Text(
|
||||||
'Soil Potassium',
|
'Kalium Tanah',
|
||||||
style: AppTheme.labelMedium,
|
style: AppTheme.labelMedium,
|
||||||
textAlign: TextAlign.center,
|
textAlign: TextAlign.center,
|
||||||
),
|
),
|
||||||
|
|
@ -143,14 +144,13 @@ class PotassiumScreen extends StatelessWidget {
|
||||||
? provider.dataFetchedNpk1[index].soilpotassium ?? 0
|
? provider.dataFetchedNpk1[index].soilpotassium ?? 0
|
||||||
: provider.dataFetchedNpk2[index].soilpotassium ?? 0,
|
: provider.dataFetchedNpk2[index].soilpotassium ?? 0,
|
||||||
),
|
),
|
||||||
maxValue: 1,
|
maxValue: 100,
|
||||||
);
|
);
|
||||||
case ResultState.error:
|
case ResultState.error:
|
||||||
return const GraphicErrorWidget(message: 'Terjadi Kesalahan');
|
return const ErrorDataStateWidget();
|
||||||
case ResultState.noData:
|
case ResultState.noData:
|
||||||
return const GraphicErrorWidget(message: 'Tidak Ada Data');
|
return const NoDataStateWidget();
|
||||||
case ResultState.initial:
|
case ResultState.initial:
|
||||||
default:
|
|
||||||
return const SizedBox.shrink();
|
return const SizedBox.shrink();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
@ -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/core/state/result_state.dart';
|
||||||
import 'package:agrilink_vocpro/data/model/latest_data_response.dart';
|
import 'package:agrilink_vocpro/data/model/latest_data_response.dart';
|
||||||
import 'package:agrilink_vocpro/domain/service/app_service.dart';
|
import 'package:agrilink_vocpro/domain/service/app_service.dart';
|
||||||
|
|
@ -17,8 +18,8 @@ class SoilMoistureProvider extends ChangeNotifier {
|
||||||
dataState = ResultState.loading;
|
dataState = ResultState.loading;
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
try {
|
try {
|
||||||
final result =
|
final result = await AppService()
|
||||||
await AppService().getGraphicDataNpk1(metric: 'soilhumidity');
|
.getGraphicDataNpk1(metric: AppConstant.soilMoisture);
|
||||||
if (result.data == null || result.data!.npk1!.isEmpty) {
|
if (result.data == null || result.data!.npk1!.isEmpty) {
|
||||||
dataState = ResultState.noData;
|
dataState = ResultState.noData;
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -38,8 +39,8 @@ class SoilMoistureProvider extends ChangeNotifier {
|
||||||
dataState = ResultState.loading;
|
dataState = ResultState.loading;
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
try {
|
try {
|
||||||
final result =
|
final result = await AppService()
|
||||||
await AppService().getGraphicDataNpk2(metric: 'soilhumidity');
|
.getGraphicDataNpk2(metric: AppConstant.soilMoisture);
|
||||||
if (result.data == null || result.data!.npk2!.isEmpty) {
|
if (result.data == null || result.data!.npk2!.isEmpty) {
|
||||||
dataState = ResultState.noData;
|
dataState = ResultState.noData;
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -1,7 +1,8 @@
|
||||||
import 'package:agrilink_vocpro/core/constant/app_theme.dart';
|
import 'package:agrilink_vocpro/core/constant/app_theme.dart';
|
||||||
import 'package:agrilink_vocpro/core/state/result_state.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/core/widgets/error_data_state_widget.dart';
|
||||||
import 'package:agrilink_vocpro/features/home/widgets/graphic_error_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_widget.dart';
|
import 'package:agrilink_vocpro/features/home/widgets/graphic_widget.dart';
|
||||||
import 'package:bootstrap_icons/bootstrap_icons.dart';
|
import 'package:bootstrap_icons/bootstrap_icons.dart';
|
||||||
import 'package:flutter/cupertino.dart';
|
import 'package:flutter/cupertino.dart';
|
||||||
|
|
@ -124,7 +125,7 @@ class SoilMoistureScreen extends StatelessWidget {
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
children: [
|
children: [
|
||||||
Text(
|
Text(
|
||||||
'Soil Moisture',
|
'Kelembaban Tanah',
|
||||||
style: AppTheme.labelMedium,
|
style: AppTheme.labelMedium,
|
||||||
textAlign: TextAlign.center,
|
textAlign: TextAlign.center,
|
||||||
),
|
),
|
||||||
|
|
@ -150,7 +151,6 @@ class SoilMoistureScreen extends StatelessWidget {
|
||||||
child: Consumer<SoilMoistureProvider>(
|
child: Consumer<SoilMoistureProvider>(
|
||||||
builder: (context, provider, child) {
|
builder: (context, provider, child) {
|
||||||
final dataState = provider.dataState;
|
final dataState = provider.dataState;
|
||||||
|
|
||||||
switch (dataState) {
|
switch (dataState) {
|
||||||
case ResultState.loading:
|
case ResultState.loading:
|
||||||
return const Center(child: CupertinoActivityIndicator());
|
return const Center(child: CupertinoActivityIndicator());
|
||||||
|
|
@ -173,14 +173,12 @@ class SoilMoistureScreen extends StatelessWidget {
|
||||||
? provider.dataFetchedNpk1[index].soilhumidity ?? 0
|
? provider.dataFetchedNpk1[index].soilhumidity ?? 0
|
||||||
: provider.dataFetchedNpk2[index].soilhumidity ?? 0,
|
: provider.dataFetchedNpk2[index].soilhumidity ?? 0,
|
||||||
),
|
),
|
||||||
maxValue: 1,
|
|
||||||
);
|
);
|
||||||
case ResultState.error:
|
case ResultState.error:
|
||||||
return const GraphicErrorWidget(message: 'Terjadi Kesalahan');
|
return const ErrorDataStateWidget();
|
||||||
case ResultState.noData:
|
case ResultState.noData:
|
||||||
return const GraphicErrorWidget(message: 'Tidak Ada Data');
|
return const NoDataStateWidget();
|
||||||
case ResultState.initial:
|
case ResultState.initial:
|
||||||
default:
|
|
||||||
return const SizedBox.shrink();
|
return const SizedBox.shrink();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
@ -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/core/state/result_state.dart';
|
||||||
import 'package:agrilink_vocpro/data/model/latest_data_response.dart';
|
import 'package:agrilink_vocpro/data/model/latest_data_response.dart';
|
||||||
import 'package:agrilink_vocpro/domain/service/app_service.dart';
|
import 'package:agrilink_vocpro/domain/service/app_service.dart';
|
||||||
|
|
@ -18,7 +19,7 @@ class SoilTempProvider extends ChangeNotifier {
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
try {
|
try {
|
||||||
final result =
|
final result =
|
||||||
await AppService().getGraphicDataNpk1(metric: 'soilTemperature');
|
await AppService().getGraphicDataNpk1(metric: AppConstant.soilTemp);
|
||||||
if (result.data == null || result.data!.npk1!.isEmpty) {
|
if (result.data == null || result.data!.npk1!.isEmpty) {
|
||||||
dataState = ResultState.noData;
|
dataState = ResultState.noData;
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -39,7 +40,7 @@ class SoilTempProvider extends ChangeNotifier {
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
try {
|
try {
|
||||||
final result =
|
final result =
|
||||||
await AppService().getGraphicDataNpk2(metric: 'soilTemperature');
|
await AppService().getGraphicDataNpk2(metric: AppConstant.soilTemp);
|
||||||
if (result.data == null || result.data!.npk2!.isEmpty) {
|
if (result.data == null || result.data!.npk2!.isEmpty) {
|
||||||
dataState = ResultState.noData;
|
dataState = ResultState.noData;
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -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:flutter/material.dart';
|
||||||
import 'package:bootstrap_icons/bootstrap_icons.dart';
|
import 'package:bootstrap_icons/bootstrap_icons.dart';
|
||||||
import 'package:flutter/cupertino.dart';
|
import 'package:flutter/cupertino.dart';
|
||||||
|
|
@ -6,8 +7,7 @@ import 'package:provider/provider.dart';
|
||||||
import 'package:agrilink_vocpro/core/constant/app_constant.dart';
|
import 'package:agrilink_vocpro/core/constant/app_constant.dart';
|
||||||
import 'package:agrilink_vocpro/core/constant/app_theme.dart';
|
import 'package:agrilink_vocpro/core/constant/app_theme.dart';
|
||||||
import 'package:agrilink_vocpro/core/state/result_state.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/pages/soil_temperature/provider/soil_temp_provider.dart';
|
|
||||||
import 'package:agrilink_vocpro/features/home/widgets/graphic_widget.dart';
|
import 'package:agrilink_vocpro/features/home/widgets/graphic_widget.dart';
|
||||||
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
||||||
import 'package:gauge_indicator/gauge_indicator.dart';
|
import 'package:gauge_indicator/gauge_indicator.dart';
|
||||||
|
|
@ -149,7 +149,7 @@ class SoilTemperatureScreen extends StatelessWidget {
|
||||||
height: 100.h,
|
height: 100.h,
|
||||||
width: 100.w,
|
width: 100.w,
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
color: color.withOpacity(0.1),
|
color: color.withValues(alpha: 0.1),
|
||||||
borderRadius: BorderRadius.circular(16),
|
borderRadius: BorderRadius.circular(16),
|
||||||
border: Border.all(color: color, width: 2),
|
border: Border.all(color: color, width: 2),
|
||||||
),
|
),
|
||||||
|
|
@ -171,7 +171,7 @@ class SoilTemperatureScreen extends StatelessWidget {
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
children: [
|
children: [
|
||||||
Text(
|
Text(
|
||||||
'Soil Temperature',
|
'Suhu Tanah',
|
||||||
style: AppTheme.labelMedium,
|
style: AppTheme.labelMedium,
|
||||||
textAlign: TextAlign.center,
|
textAlign: TextAlign.center,
|
||||||
),
|
),
|
||||||
|
|
@ -179,7 +179,7 @@ class SoilTemperatureScreen extends StatelessWidget {
|
||||||
iconSize: 20.r,
|
iconSize: 20.r,
|
||||||
color: Colors.blue,
|
color: Colors.blue,
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
showInfo(context, 'Soil Temperature', AppConstant.soilTempInfo);
|
showInfo(context, 'Suhu Tanah', AppConstant.soilTempInfo);
|
||||||
},
|
},
|
||||||
icon: const Icon(BootstrapIcons.info_circle),
|
icon: const Icon(BootstrapIcons.info_circle),
|
||||||
),
|
),
|
||||||
|
|
@ -226,11 +226,10 @@ class SoilTemperatureScreen extends StatelessWidget {
|
||||||
maxValue: 70,
|
maxValue: 70,
|
||||||
);
|
);
|
||||||
case ResultState.error:
|
case ResultState.error:
|
||||||
return const GraphicErrorWidget(message: 'Terjadi Kesalahan');
|
return const ErrorDataStateWidget();
|
||||||
case ResultState.noData:
|
case ResultState.noData:
|
||||||
return const GraphicErrorWidget(message: 'Tidak Ada Data');
|
return const NoDataStateWidget();
|
||||||
case ResultState.initial:
|
case ResultState.initial:
|
||||||
default:
|
|
||||||
return const SizedBox.shrink();
|
return const SizedBox.shrink();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
@ -239,3 +238,30 @@ class SoilTemperatureScreen extends StatelessWidget {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<dynamic> 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'),
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
@ -1,6 +1,8 @@
|
||||||
import 'package:agrilink_vocpro/core/constant/app_theme.dart';
|
import 'package:agrilink_vocpro/core/constant/app_theme.dart';
|
||||||
import 'package:agrilink_vocpro/core/state/result_state.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/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:agrilink_vocpro/features/home/widgets/graphic_widget.dart';
|
||||||
import 'package:bootstrap_icons/bootstrap_icons.dart';
|
import 'package:bootstrap_icons/bootstrap_icons.dart';
|
||||||
import 'package:flutter/cupertino.dart';
|
import 'package:flutter/cupertino.dart';
|
||||||
|
|
@ -30,7 +32,7 @@ class TemperatureScreen extends StatelessWidget {
|
||||||
padding: EdgeInsets.only(right: 16),
|
padding: EdgeInsets.only(right: 16),
|
||||||
child: Icon(
|
child: Icon(
|
||||||
BootstrapIcons.thermometer_half,
|
BootstrapIcons.thermometer_half,
|
||||||
color: Colors.red,
|
color: Colors.orange,
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
],
|
],
|
||||||
|
|
@ -96,7 +98,7 @@ class TemperatureScreen extends StatelessWidget {
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
children: [
|
children: [
|
||||||
Text(
|
Text(
|
||||||
'Temperature',
|
'Suhu Ruangan',
|
||||||
style: AppTheme.labelMedium,
|
style: AppTheme.labelMedium,
|
||||||
textAlign: TextAlign.center,
|
textAlign: TextAlign.center,
|
||||||
),
|
),
|
||||||
|
|
@ -116,7 +118,7 @@ class TemperatureScreen extends StatelessWidget {
|
||||||
width: 100.w,
|
width: 100.w,
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
borderRadius: BorderRadius.circular(16),
|
borderRadius: BorderRadius.circular(16),
|
||||||
color: Colors.blue.withOpacity(0.1),
|
color: Colors.blue.withValues(alpha: 0.1),
|
||||||
border: Border.all(
|
border: Border.all(
|
||||||
color: Colors.blue,
|
color: Colors.blue,
|
||||||
width: 2,
|
width: 2,
|
||||||
|
|
@ -141,7 +143,7 @@ class TemperatureScreen extends StatelessWidget {
|
||||||
height: 100.h,
|
height: 100.h,
|
||||||
width: 100.w,
|
width: 100.w,
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
color: Colors.green.withOpacity(0.1),
|
color: Colors.green.withValues(alpha: 0.1),
|
||||||
borderRadius: BorderRadius.circular(16),
|
borderRadius: BorderRadius.circular(16),
|
||||||
border: Border.all(
|
border: Border.all(
|
||||||
color: Colors.green,
|
color: Colors.green,
|
||||||
|
|
@ -167,7 +169,7 @@ class TemperatureScreen extends StatelessWidget {
|
||||||
height: 100.h,
|
height: 100.h,
|
||||||
width: 100.w,
|
width: 100.w,
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
color: Colors.orange.withOpacity(0.1),
|
color: Colors.orange.withValues(alpha: 0.1),
|
||||||
borderRadius: BorderRadius.circular(16),
|
borderRadius: BorderRadius.circular(16),
|
||||||
border: Border.all(
|
border: Border.all(
|
||||||
color: Colors.orange.shade800,
|
color: Colors.orange.shade800,
|
||||||
|
|
@ -226,47 +228,14 @@ class TemperatureScreen extends StatelessWidget {
|
||||||
provider.dataFetched[index].vicitemperature
|
provider.dataFetched[index].vicitemperature
|
||||||
?.toDouble() ??
|
?.toDouble() ??
|
||||||
0),
|
0),
|
||||||
|
maxValue: 60,
|
||||||
);
|
);
|
||||||
case ResultState.error:
|
case ResultState.error:
|
||||||
return Center(
|
return ErrorDataStateWidget();
|
||||||
child: Column(
|
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
|
||||||
children: [
|
|
||||||
Icon(
|
|
||||||
BootstrapIcons.exclamation_circle,
|
|
||||||
color: Colors.grey.shade400,
|
|
||||||
),
|
|
||||||
SizedBox(height: 8.h),
|
|
||||||
Text(
|
|
||||||
'Terjadi Kesalahan',
|
|
||||||
style: AppTheme.labelSmall,
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
);
|
|
||||||
case ResultState.noData:
|
case ResultState.noData:
|
||||||
return Center(
|
return NoDataStateWidget();
|
||||||
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,
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
);
|
|
||||||
case ResultState.initial:
|
case ResultState.initial:
|
||||||
return const SizedBox.shrink();
|
return const SizedBox.shrink();
|
||||||
default:
|
|
||||||
return const Center(
|
|
||||||
child: Text('Default Error'),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
|
|
@ -98,7 +98,7 @@ class HomeProvider extends ChangeNotifier {
|
||||||
if (kDebugMode) {
|
if (kDebugMode) {
|
||||||
print('Get Latest Error: $e');
|
print('Get Latest Error: $e');
|
||||||
}
|
}
|
||||||
dataState = ResultState.error;
|
dataState = ResultState.hasData;
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -126,6 +126,7 @@ class _HomeScreenState extends State<HomeScreen> {
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
body: DefaultTabController(
|
body: DefaultTabController(
|
||||||
|
initialIndex: 1,
|
||||||
length: 3,
|
length: 3,
|
||||||
child: Stack(
|
child: Stack(
|
||||||
children: [
|
children: [
|
||||||
|
|
|
||||||
|
|
@ -41,7 +41,7 @@ class DataDisplayerWidget extends StatelessWidget {
|
||||||
borderRadius: BorderRadius.circular(16.r), // Bentuk sudut yang bundar
|
borderRadius: BorderRadius.circular(16.r), // Bentuk sudut yang bundar
|
||||||
),
|
),
|
||||||
elevation: 20, // Efek bayangan
|
elevation: 20, // Efek bayangan
|
||||||
shadowColor: Colors.grey.withOpacity(0.2),
|
shadowColor: Colors.grey.withValues(alpha: 0.2),
|
||||||
),
|
),
|
||||||
child: Column(
|
child: Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
|
@ -52,7 +52,7 @@ class DataDisplayerWidget extends StatelessWidget {
|
||||||
child: Text(
|
child: Text(
|
||||||
censorIdentifier ?? '',
|
censorIdentifier ?? '',
|
||||||
style: AppTheme.labelSmall
|
style: AppTheme.labelSmall
|
||||||
.copyWith(color: textColor.withOpacity(0.5)),
|
.copyWith(color: textColor.withValues(alpha: 0.5)),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
Icon(icon, color: iconColor, size: 32.r),
|
Icon(icon, color: iconColor, size: 32.r),
|
||||||
|
|
@ -67,7 +67,7 @@ class DataDisplayerWidget extends StatelessWidget {
|
||||||
Text(
|
Text(
|
||||||
subtitle,
|
subtitle,
|
||||||
style: AppTheme.labelSmall
|
style: AppTheme.labelSmall
|
||||||
.copyWith(color: textColor.withOpacity(0.5)),
|
.copyWith(color: textColor.withValues(alpha: 0.5)),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
|
|
||||||
|
|
@ -111,7 +111,7 @@ class GarphicWidget extends StatelessWidget {
|
||||||
show: true,
|
show: true,
|
||||||
gradient: LinearGradient(
|
gradient: LinearGradient(
|
||||||
colors: gradientColors
|
colors: gradientColors
|
||||||
.map((color) => color.withOpacity(0.3))
|
.map((color) => color.withValues(alpha: 0.3))
|
||||||
.toList()),
|
.toList()),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
|
||||||
|
|
@ -1,4 +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/route/app_route.dart';
|
||||||
import 'package:agrilink_vocpro/core/state/result_state.dart';
|
import 'package:agrilink_vocpro/core/state/result_state.dart';
|
||||||
import 'package:agrilink_vocpro/features/home/provider/home_provider.dart';
|
import 'package:agrilink_vocpro/features/home/provider/home_provider.dart';
|
||||||
|
|
@ -50,13 +50,11 @@ class ListDataFromCensorDht extends StatelessWidget {
|
||||||
DataDisplayerWidget(
|
DataDisplayerWidget(
|
||||||
title: 'Humidity',
|
title: 'Humidity',
|
||||||
subtitle: 'kelembaban udara',
|
subtitle: 'kelembaban udara',
|
||||||
value: provider.dhtHumidity.toString(),
|
value: setTwoDigitAfterComma(provider.dhtHumidity.toDouble()),
|
||||||
unit: '%',
|
unit: '%',
|
||||||
icon: BootstrapIcons.droplet_half,
|
icon: BootstrapIcons.droplet_half,
|
||||||
textColor: Colors.white,
|
color: Colors.white,
|
||||||
color: AppColor.secondary,
|
censorIdentifier: 'DHT',
|
||||||
iconColor: Colors.white,
|
|
||||||
censorIdentifier: 'NPK 1',
|
|
||||||
onTap: () async {
|
onTap: () async {
|
||||||
await context
|
await context
|
||||||
.push('${AppRoute.humidity}/${provider.dhtHumidity}');
|
.push('${AppRoute.humidity}/${provider.dhtHumidity}');
|
||||||
|
|
@ -69,6 +67,7 @@ class ListDataFromCensorDht extends StatelessWidget {
|
||||||
unit: '°C',
|
unit: '°C',
|
||||||
icon: BootstrapIcons.thermometer_half,
|
icon: BootstrapIcons.thermometer_half,
|
||||||
color: Colors.white,
|
color: Colors.white,
|
||||||
|
censorIdentifier: 'DHT',
|
||||||
onTap: () async {
|
onTap: () async {
|
||||||
await context.push(
|
await context.push(
|
||||||
'${AppRoute.temperature}/${provider.dhtTemperature}');
|
'${AppRoute.temperature}/${provider.dhtTemperature}');
|
||||||
|
|
@ -81,6 +80,7 @@ class ListDataFromCensorDht extends StatelessWidget {
|
||||||
unit: 'lux',
|
unit: 'lux',
|
||||||
icon: BootstrapIcons.sun,
|
icon: BootstrapIcons.sun,
|
||||||
color: Colors.white,
|
color: Colors.white,
|
||||||
|
censorIdentifier: 'DHT',
|
||||||
onTap: () async {
|
onTap: () async {
|
||||||
await context
|
await context
|
||||||
.push('${AppRoute.light}/${provider.dhtLuminosity}');
|
.push('${AppRoute.light}/${provider.dhtLuminosity}');
|
||||||
|
|
@ -102,8 +102,6 @@ class ListDataFromCensorDht extends StatelessWidget {
|
||||||
));
|
));
|
||||||
case ResultState.initial:
|
case ResultState.initial:
|
||||||
return const SizedBox.shrink();
|
return const SizedBox.shrink();
|
||||||
default:
|
|
||||||
return const SizedBox.shrink();
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -46,15 +46,58 @@ class ListDataFromCensorNpk1 extends StatelessWidget {
|
||||||
childAspectRatio: 0.9,
|
childAspectRatio: 0.9,
|
||||||
),
|
),
|
||||||
children: [
|
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,
|
||||||
|
censorIdentifier: censorIdentifier,
|
||||||
|
onTap: () async {
|
||||||
|
await context.push(
|
||||||
|
'${AppRoute.nitrogen}/${provider.npk1SoilNitrogen}/${provider.npk2SoilNitrogen}');
|
||||||
|
},
|
||||||
|
),
|
||||||
|
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,
|
||||||
|
censorIdentifier: censorIdentifier,
|
||||||
|
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,
|
||||||
|
censorIdentifier: censorIdentifier,
|
||||||
|
onTap: () async {
|
||||||
|
await context.push(
|
||||||
|
'${AppRoute.potassium}/${provider.npk1SoilPotassium}/${provider.npk2SoilPotassium}');
|
||||||
|
},
|
||||||
|
),
|
||||||
DataDisplayerWidget(
|
DataDisplayerWidget(
|
||||||
title: 'Temperature',
|
title: 'Temperature',
|
||||||
subtitle: 'Suhu tanah',
|
subtitle: 'Suhu tanah',
|
||||||
value: provider.npk1Temperature.toString(),
|
value: provider.npk1Temperature.toString(),
|
||||||
unit: '°C',
|
unit: '°C',
|
||||||
icon: BootstrapIcons.thermometer_half,
|
icon: BootstrapIcons.thermometer_half,
|
||||||
textColor: Colors.white,
|
color: Colors.white,
|
||||||
color: AppColor.secondary,
|
|
||||||
iconColor: Colors.white,
|
|
||||||
censorIdentifier: censorIdentifier,
|
censorIdentifier: censorIdentifier,
|
||||||
onTap: () async {
|
onTap: () async {
|
||||||
await context.push(
|
await context.push(
|
||||||
|
|
@ -100,42 +143,6 @@ class ListDataFromCensorNpk1 extends StatelessWidget {
|
||||||
'${AppRoute.conductivity}/${provider.npk1SoilEc}/${provider.npk2SoilEc}');
|
'${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:
|
case ResultState.noData:
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,7 @@ class ListDataFromCensorNpk2 extends StatelessWidget {
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
const String censorIdentifier = 'NPK 1';
|
const String censorIdentifier = 'NPK 2';
|
||||||
return Consumer<HomeProvider>(builder: (context, provider, child) {
|
return Consumer<HomeProvider>(builder: (context, provider, child) {
|
||||||
switch (provider.dataState) {
|
switch (provider.dataState) {
|
||||||
case ResultState.loading:
|
case ResultState.loading:
|
||||||
|
|
@ -46,15 +46,58 @@ class ListDataFromCensorNpk2 extends StatelessWidget {
|
||||||
childAspectRatio: 0.9,
|
childAspectRatio: 0.9,
|
||||||
),
|
),
|
||||||
children: [
|
children: [
|
||||||
|
DataDisplayerWidget(
|
||||||
|
title: 'Nitrogen',
|
||||||
|
subtitle: 'Kadar Nitrogen',
|
||||||
|
value: provider.npk2SoilNitrogen.toString(),
|
||||||
|
unit: 'mg/L',
|
||||||
|
icon: CupertinoIcons.eyedropper,
|
||||||
|
textColor: Colors.white,
|
||||||
|
color: AppColor.secondary,
|
||||||
|
censorIdentifier: censorIdentifier,
|
||||||
|
iconColor: Colors.white,
|
||||||
|
onTap: () async {
|
||||||
|
await context.push(
|
||||||
|
'${AppRoute.nitrogen}/${provider.npk1SoilNitrogen}/${provider.npk2SoilNitrogen}');
|
||||||
|
},
|
||||||
|
),
|
||||||
|
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,
|
||||||
|
censorIdentifier: censorIdentifier,
|
||||||
|
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,
|
||||||
|
censorIdentifier: censorIdentifier,
|
||||||
|
onTap: () async {
|
||||||
|
await context.push(
|
||||||
|
'${AppRoute.potassium}/${provider.npk1SoilPotassium}/${provider.npk2SoilPotassium}');
|
||||||
|
},
|
||||||
|
),
|
||||||
DataDisplayerWidget(
|
DataDisplayerWidget(
|
||||||
title: 'Temperature',
|
title: 'Temperature',
|
||||||
subtitle: 'Suhu tanah',
|
subtitle: 'Suhu tanah',
|
||||||
value: provider.npk2Temperature.toString(),
|
value: provider.npk2Temperature.toString(),
|
||||||
unit: '°C',
|
unit: '°C',
|
||||||
icon: BootstrapIcons.thermometer_half,
|
icon: BootstrapIcons.thermometer_half,
|
||||||
textColor: Colors.white,
|
color: Colors.white,
|
||||||
color: AppColor.secondary,
|
|
||||||
iconColor: Colors.white,
|
|
||||||
censorIdentifier: censorIdentifier,
|
censorIdentifier: censorIdentifier,
|
||||||
onTap: () async {
|
onTap: () async {
|
||||||
await context.push(
|
await context.push(
|
||||||
|
|
@ -100,42 +143,6 @@ class ListDataFromCensorNpk2 extends StatelessWidget {
|
||||||
'${AppRoute.conductivity}/${provider.npk1SoilEc}/${provider.npk2SoilEc}');
|
'${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:
|
case ResultState.noData:
|
||||||
|
|
|
||||||
|
|
@ -15,10 +15,10 @@ class PlantsScreen extends StatelessWidget {
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
children: [
|
children: [
|
||||||
Icon(Icons.eco_rounded, size: 100.r, color: AppColor.secondary),
|
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),
|
SizedBox(height: 8.h),
|
||||||
Text(
|
Text(
|
||||||
'This featureis under development',
|
'Fitur ini sedang dalam tahap pengembangan',
|
||||||
textAlign: TextAlign.center,
|
textAlign: TextAlign.center,
|
||||||
style: AppTheme.labelSmall,
|
style: AppTheme.labelSmall,
|
||||||
),
|
),
|
||||||
|
|
|
||||||
|
|
@ -10,11 +10,13 @@ class SettingProvider extends ChangeNotifier {
|
||||||
|
|
||||||
String userFullName = '';
|
String userFullName = '';
|
||||||
String userEmail = '';
|
String userEmail = '';
|
||||||
|
String userName = '';
|
||||||
|
|
||||||
void _init() async {
|
void _init() async {
|
||||||
SharedPreferences prefs = await SharedPreferences.getInstance();
|
SharedPreferences prefs = await SharedPreferences.getInstance();
|
||||||
userFullName = prefs.getString('fullName') ?? 'unknown';
|
userFullName = prefs.getString('fullName') ?? 'unknown';
|
||||||
userEmail = prefs.getString('email') ?? 'unknown';
|
userEmail = prefs.getString('email') ?? 'unknown';
|
||||||
|
userName = prefs.getString('username') ?? 'unknown';
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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 Akun', style: AppTheme.labelMedium),
|
||||||
|
centerTitle: true,
|
||||||
|
backgroundColor: Colors.white,
|
||||||
|
scrolledUnderElevation: 0,
|
||||||
|
),
|
||||||
|
body: Consumer<SettingProvider>(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),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -16,7 +16,7 @@ class SettingScreen extends StatelessWidget {
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
appBar: AppBar(
|
appBar: AppBar(
|
||||||
title: Text('Setting', style: AppTheme.labelMedium),
|
title: Text('Pengaturan', style: AppTheme.labelMedium),
|
||||||
centerTitle: true,
|
centerTitle: true,
|
||||||
backgroundColor: Colors.white,
|
backgroundColor: Colors.white,
|
||||||
scrolledUnderElevation: 0,
|
scrolledUnderElevation: 0,
|
||||||
|
|
@ -52,7 +52,7 @@ class SettingScreen extends StatelessWidget {
|
||||||
children: [
|
children: [
|
||||||
ListTile(
|
ListTile(
|
||||||
tileColor: Colors.white,
|
tileColor: Colors.white,
|
||||||
title: Text('Account',
|
title: Text('Akun',
|
||||||
style: AppTheme.labelSmall
|
style: AppTheme.labelSmall
|
||||||
.copyWith(color: Colors.black87)),
|
.copyWith(color: Colors.black87)),
|
||||||
leading: const Icon(BootstrapIcons.person),
|
leading: const Icon(BootstrapIcons.person),
|
||||||
|
|
@ -60,35 +60,37 @@ class SettingScreen extends StatelessWidget {
|
||||||
Icons.arrow_forward_ios,
|
Icons.arrow_forward_ios,
|
||||||
size: 16.r,
|
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(
|
ListTile(
|
||||||
tileColor: Colors.white,
|
tileColor: Colors.white,
|
||||||
title: Text('Kebijakan & privasi',
|
title: Text('Keluar',
|
||||||
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',
|
|
||||||
style: AppTheme.labelSmall.copyWith(color: Colors.red)),
|
style: AppTheme.labelSmall.copyWith(color: Colors.red)),
|
||||||
leading: const Icon(
|
leading: const Icon(
|
||||||
BootstrapIcons.box_arrow_right,
|
BootstrapIcons.box_arrow_right,
|
||||||
|
|
|
||||||
|
|
@ -58,7 +58,7 @@ class _SplashScreenState extends State<SplashScreen> {
|
||||||
}
|
}
|
||||||
|
|
||||||
void _navigateAfterSplash(bool isLoggedIn) {
|
void _navigateAfterSplash(bool isLoggedIn) {
|
||||||
Timer(const Duration(seconds: 2), () {
|
Timer(const Duration(seconds: 1), () {
|
||||||
if (isLoggedIn == true) {
|
if (isLoggedIn == true) {
|
||||||
context.go(AppRoute.dashboard);
|
context.go(AppRoute.dashboard);
|
||||||
} else {
|
} else {
|
||||||
|
|
|
||||||
|
|
@ -5,10 +5,10 @@ packages:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: _flutterfire_internals
|
name: _flutterfire_internals
|
||||||
sha256: "5534e701a2c505fed1f0799e652dd6ae23bd4d2c4cf797220e5ced5764a7c1c2"
|
sha256: eae3133cbb06de9205899b822e3897fc6a8bc278ad4c944b4ce612689369694b
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.3.44"
|
version: "1.3.47"
|
||||||
animated_segmented_tab_control:
|
animated_segmented_tab_control:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
|
|
@ -29,18 +29,18 @@ packages:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: async
|
name: async
|
||||||
sha256: "947bfcf187f74dbc5e146c9eb9c0f10c9f8b30743e341481c1e2ed3ecc18c20c"
|
sha256: d2872f9c19731c2e5f10444b14686eb7cc85c76274bd6c16e1816bff9a3bab63
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.11.0"
|
version: "2.12.0"
|
||||||
boolean_selector:
|
boolean_selector:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: boolean_selector
|
name: boolean_selector
|
||||||
sha256: "6cfb5af12253eaf2b368f07bacc5a80d1301a071c73360d746b7f2e32d762c66"
|
sha256: "8aab1771e1243a5063b8b0ff68042d67334e3feab9e95b9490f9a6ebf73b42ea"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.1.1"
|
version: "2.1.2"
|
||||||
bootstrap_icons:
|
bootstrap_icons:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
|
|
@ -61,42 +61,42 @@ packages:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: charcode
|
name: charcode
|
||||||
sha256: fb98c0f6d12c920a02ee2d998da788bca066ca5f148492b7085ee23372b12306
|
sha256: fb0f1107cac15a5ea6ef0a6ef71a807b9e4267c713bb93e00e92d737cc8dbd8a
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.3.1"
|
version: "1.4.0"
|
||||||
clock:
|
clock:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: clock
|
name: clock
|
||||||
sha256: cb6d7f03e1de671e34607e909a7213e31d7752be4fb66a86d29fe1eb14bfb5cf
|
sha256: fddb70d9b5277016c77a80201021d40a2247104d9f4aa7bab7157b7e3f05b84b
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.1.1"
|
version: "1.1.2"
|
||||||
collection:
|
collection:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: collection
|
name: collection
|
||||||
sha256: ee67cb0715911d28db6bf4af1026078bd6f0128b07a5f66fb2ed94ec6783c09a
|
sha256: a1ace0a119f20aabc852d165077c036cd864315bd99b7eaa10a60100341941bf
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.18.0"
|
version: "1.19.0"
|
||||||
crypto:
|
crypto:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: crypto
|
name: crypto
|
||||||
sha256: ec30d999af904f33454ba22ed9a86162b35e52b44ac4807d1d93c288041d7d27
|
sha256: "1e445881f28f22d6140f181e07737b22f1e099a5e1ff94b0af2f9e4a463f4855"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "3.0.5"
|
version: "3.0.6"
|
||||||
csslib:
|
csslib:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: csslib
|
name: csslib
|
||||||
sha256: "706b5707578e0c1b4b7550f64078f0a0f19dec3f50a178ffae7006b0a9ca58fb"
|
sha256: "09bad715f418841f976c77db72d5398dc1253c21fb9c0c7f0b0b985860b2d58e"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.0.0"
|
version: "1.0.2"
|
||||||
cupertino_icons:
|
cupertino_icons:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
|
|
@ -125,10 +125,10 @@ packages:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: equatable
|
name: equatable
|
||||||
sha256: c2b87cb7756efdf69892005af546c56c0b5037f54d2a88269b4f347a505e3ca2
|
sha256: "567c64b3cb4cf82397aac55f4f0cbd3ca20d77c6c03bedbc4ceaddc08904aef7"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.0.5"
|
version: "2.0.7"
|
||||||
event_bus:
|
event_bus:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
|
@ -141,10 +141,10 @@ packages:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: fake_async
|
name: fake_async
|
||||||
sha256: "511392330127add0b769b75a987850d136345d9227c6b94c96a04cf4a391bf78"
|
sha256: "6a95e56b2449df2273fd8c45a662d6947ce1ebb7aafe80e550a3f68297f3cacc"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.3.1"
|
version: "1.3.2"
|
||||||
ffi:
|
ffi:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
|
@ -165,58 +165,58 @@ packages:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: firebase_core
|
name: firebase_core
|
||||||
sha256: "51dfe2fbf3a984787a2e7b8592f2f05c986bfedd6fdacea3f9e0a7beb334de96"
|
sha256: fef81a53ba1ca618def1f8bef4361df07968434e62cb204c1fb90bb880a03da2
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "3.6.0"
|
version: "3.8.1"
|
||||||
firebase_core_platform_interface:
|
firebase_core_platform_interface:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: firebase_core_platform_interface
|
name: firebase_core_platform_interface
|
||||||
sha256: e30da58198a6d4b49d5bce4e852f985c32cb10db329ebef9473db2b9f09ce810
|
sha256: b94b217e3ad745e784960603d33d99471621ecca151c99c670869b76e50ad2a6
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "5.3.0"
|
version: "5.3.1"
|
||||||
firebase_core_web:
|
firebase_core_web:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: firebase_core_web
|
name: firebase_core_web
|
||||||
sha256: f967a7138f5d2ffb1ce15950e2a382924239eaa521150a8f144af34e68b3b3e5
|
sha256: "9e69806bb3d905aeec3c1242e0e1475de6ea6d48f456af29d598fb229a2b4e5e"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.18.1"
|
version: "2.18.2"
|
||||||
firebase_messaging:
|
firebase_messaging:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: firebase_messaging
|
name: firebase_messaging
|
||||||
sha256: eb6e28a3a35deda61fe8634967c84215efc19133ba58d8e0fc6c9a2af2cba05e
|
sha256: "151a3ee68736abf293aab66d1317ade53c88abe1db09c75a0460aebf7767bbdf"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "15.1.3"
|
version: "15.1.6"
|
||||||
firebase_messaging_platform_interface:
|
firebase_messaging_platform_interface:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: firebase_messaging_platform_interface
|
name: firebase_messaging_platform_interface
|
||||||
sha256: b316c4ee10d93d32c033644207afc282d9b2b4372f3cf9c6022f3558b3873d2d
|
sha256: f331ee51e40c243f90cc7bc059222dfec4e5df53125b08d31fb28961b00d2a9d
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "4.5.46"
|
version: "4.5.49"
|
||||||
firebase_messaging_web:
|
firebase_messaging_web:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: firebase_messaging_web
|
name: firebase_messaging_web
|
||||||
sha256: d7f0147a1a9fe4313168e20154a01fd5cf332898de1527d3930ff77b8c7f5387
|
sha256: efaf3fdc54cd77e0eedb8e75f7f01c808828c64d052ddbf94d3009974e47d30f
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "3.9.2"
|
version: "3.9.5"
|
||||||
fl_chart:
|
fl_chart:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: fl_chart
|
name: fl_chart
|
||||||
sha256: "94307bef3a324a0d329d3ab77b2f0c6e5ed739185ffc029ed28c0f9b019ea7ef"
|
sha256: "74959b99b92b9eebeed1a4049426fd67c4abc3c5a0f4d12e2877097d6a11ae08"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.69.0"
|
version: "0.69.2"
|
||||||
flutter:
|
flutter:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description: flutter
|
description: flutter
|
||||||
|
|
@ -260,10 +260,10 @@ packages:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: go_router
|
name: go_router
|
||||||
sha256: "6f1b756f6e863259a99135ff3c95026c3cdca17d10ebef2bba2261a25ddc8bbc"
|
sha256: "2fd11229f59e23e967b0775df8d5948a519cd7e1e8b6e849729e010587b46539"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "14.3.0"
|
version: "14.6.2"
|
||||||
google_fonts:
|
google_fonts:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
|
|
@ -276,10 +276,10 @@ packages:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: google_identity_services_web
|
name: google_identity_services_web
|
||||||
sha256: "5be191523702ba8d7a01ca97c17fca096822ccf246b0a9f11923a6ded06199b6"
|
sha256: "55580f436822d64c8ff9a77e37d61f5fb1e6c7ec9d632a43ee324e2a05c3c6c9"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.3.1+4"
|
version: "0.3.3"
|
||||||
googleapis_auth:
|
googleapis_auth:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
|
|
@ -292,10 +292,10 @@ packages:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: html
|
name: html
|
||||||
sha256: "3a7812d5bcd2894edf53dfaf8cd640876cf6cef50a8f238745c8b8120ea74d3a"
|
sha256: "1fc58edeaec4307368c60d59b7e15b9d658b57d7f3125098b6294153c75337ec"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.15.4"
|
version: "0.15.5"
|
||||||
http:
|
http:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
|
|
@ -308,10 +308,10 @@ packages:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: http_parser
|
name: http_parser
|
||||||
sha256: "2aa08ce0341cc9b354a498388e30986515406668dbcc4f7c950c3e715496693b"
|
sha256: "76d306a1c3afb33fe82e2bbacad62a61f409b5634c915fceb0d799de1a913360"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "4.0.2"
|
version: "4.1.1"
|
||||||
intl:
|
intl:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
|
|
@ -332,18 +332,18 @@ packages:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: leak_tracker
|
name: leak_tracker
|
||||||
sha256: "3f87a60e8c63aecc975dda1ceedbc8f24de75f09e4856ea27daf8958f2f0ce05"
|
sha256: c35baad643ba394b40aac41080300150a4f08fd0fd6a10378f8f7c6bc161acec
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "10.0.5"
|
version: "10.0.8"
|
||||||
leak_tracker_flutter_testing:
|
leak_tracker_flutter_testing:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: leak_tracker_flutter_testing
|
name: leak_tracker_flutter_testing
|
||||||
sha256: "932549fb305594d82d7183ecd9fa93463e9914e1b67cacc34bc40906594a1806"
|
sha256: f8b613e7e6a13ec79cfdc0e97638fddb3ab848452eff057653abd3edba760573
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "3.0.5"
|
version: "3.0.9"
|
||||||
leak_tracker_testing:
|
leak_tracker_testing:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
|
@ -356,18 +356,18 @@ packages:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: lints
|
name: lints
|
||||||
sha256: "3315600f3fb3b135be672bf4a178c55f274bebe368325ae18462c89ac1e3b413"
|
sha256: "4a16b3f03741e1252fda5de3ce712666d010ba2122f8e912c94f9f7b90e1a4c3"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "5.0.0"
|
version: "5.1.0"
|
||||||
logging:
|
logging:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: logging
|
name: logging
|
||||||
sha256: "623a88c9594aa774443aa3eb2d41807a48486b5613e67599fb4c41c0ad47c340"
|
sha256: c8245ada5f1717ed44271ed1c26b8ce85ca3228fd2ffdb75468ab01979309d61
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.2.0"
|
version: "1.3.0"
|
||||||
matcher:
|
matcher:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
|
@ -412,34 +412,34 @@ packages:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: path
|
name: path
|
||||||
sha256: "087ce49c3f0dc39180befefc60fdb4acd8f8620e5682fe2476afd0b3688bb4af"
|
sha256: "75cca69d1490965be98c73ceaea117e8a04dd21217b37b292c9ddbec0d955bc5"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.9.0"
|
version: "1.9.1"
|
||||||
path_provider:
|
path_provider:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: path_provider
|
name: path_provider
|
||||||
sha256: fec0d61223fba3154d87759e3cc27fe2c8dc498f6386c6d6fc80d1afdd1bf378
|
sha256: "50c5dd5b6e1aaf6fb3a78b33f6aa3afca52bf903a8a5298f53101fdaee55bbcd"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.1.4"
|
version: "2.1.5"
|
||||||
path_provider_android:
|
path_provider_android:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: path_provider_android
|
name: path_provider_android
|
||||||
sha256: c464428172cb986b758c6d1724c603097febb8fb855aa265aeecc9280c294d4a
|
sha256: "4adf4fd5423ec60a29506c76581bc05854c55e3a0b72d35bb28d661c9686edf2"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.2.12"
|
version: "2.2.15"
|
||||||
path_provider_foundation:
|
path_provider_foundation:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: path_provider_foundation
|
name: path_provider_foundation
|
||||||
sha256: f234384a3fdd67f989b4d54a5d73ca2a6c422fa55ae694381ae0f4375cd1ea16
|
sha256: "4843174df4d288f5e29185bd6e72a6fbdf5a4a4602717eed565497429f179942"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.4.0"
|
version: "2.4.1"
|
||||||
path_provider_linux:
|
path_provider_linux:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
|
@ -468,10 +468,10 @@ packages:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: platform
|
name: platform
|
||||||
sha256: "9b71283fc13df574056616011fb138fd3b793ea47cc509c189a6c3fa5f8a1a65"
|
sha256: "5d6b1b0036a5f331ebc77c850ebc8506cbc1e9416c27e59b439f917a902a4984"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "3.1.5"
|
version: "3.1.6"
|
||||||
plugin_platform_interface:
|
plugin_platform_interface:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
|
@ -492,18 +492,18 @@ packages:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: shared_preferences
|
name: shared_preferences
|
||||||
sha256: "746e5369a43170c25816cc472ee016d3a66bc13fcf430c0bc41ad7b4b2922051"
|
sha256: "95f9997ca1fb9799d494d0cb2a780fd7be075818d59f00c43832ed112b158a82"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.3.2"
|
version: "2.3.3"
|
||||||
shared_preferences_android:
|
shared_preferences_android:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: shared_preferences_android
|
name: shared_preferences_android
|
||||||
sha256: "3b9febd815c9ca29c9e3520d50ec32f49157711e143b7a4ca039eb87e8ade5ab"
|
sha256: "7f172d1b06de5da47b6264c2692ee2ead20bbbc246690427cdb4fc301cd0c549"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.3.3"
|
version: "2.3.4"
|
||||||
shared_preferences_foundation:
|
shared_preferences_foundation:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
|
@ -556,7 +556,7 @@ packages:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description: flutter
|
description: flutter
|
||||||
source: sdk
|
source: sdk
|
||||||
version: "0.0.99"
|
version: "0.0.0"
|
||||||
source_span:
|
source_span:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
|
@ -569,10 +569,10 @@ packages:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: stack_trace
|
name: stack_trace
|
||||||
sha256: "73713990125a6d93122541237550ee3352a2d84baad52d375a4cad2eb9b7ce0b"
|
sha256: "9f47fd3630d76be3ab26f0ee06d213679aa425996925ff3feffdec504931c377"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.11.1"
|
version: "1.12.0"
|
||||||
stream_channel:
|
stream_channel:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
|
@ -585,10 +585,10 @@ packages:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: string_scanner
|
name: string_scanner
|
||||||
sha256: "556692adab6cfa87322a115640c11f13cb77b3f076ddcc5d6ae3c20242bedcde"
|
sha256: "0bd04f5bb74fcd6ff0606a888a30e917af9bd52820b178eaa464beb11dca84b6"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.2.0"
|
version: "1.4.0"
|
||||||
term_glyph:
|
term_glyph:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
|
@ -601,18 +601,18 @@ packages:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: test_api
|
name: test_api
|
||||||
sha256: "5b8a98dafc4d5c4c9c72d8b31ab2b23fc13422348d2997120294d3bac86b4ddb"
|
sha256: "664d3a9a64782fcdeb83ce9c6b39e78fd2971d4e37827b9b06c3aa1edc5e760c"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.7.2"
|
version: "0.7.3"
|
||||||
typed_data:
|
typed_data:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: typed_data
|
name: typed_data
|
||||||
sha256: facc8d6582f16042dd49f2463ff1bd6e2c9ef9f3d5da3d9b087e244a7b564b3c
|
sha256: f9049c039ebfeb4cf7a7104a675823cd72dba8297f264b6637062516699fa006
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.3.2"
|
version: "1.4.0"
|
||||||
universal_html:
|
universal_html:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
|
@ -641,10 +641,10 @@ packages:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: vm_service
|
name: vm_service
|
||||||
sha256: "5c5f338a667b4c644744b661f309fb8080bb94b18a7e91ef1dbd343bed00ed6d"
|
sha256: "0968250880a6c5fe7edc067ed0a13d4bae1577fe2771dcf3010d52c4a9d3ca14"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "14.2.5"
|
version: "14.3.1"
|
||||||
web:
|
web:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
|
@ -662,5 +662,5 @@ packages:
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.1.0"
|
version: "1.1.0"
|
||||||
sdks:
|
sdks:
|
||||||
dart: ">=3.5.1 <4.0.0"
|
dart: ">=3.6.0-0 <4.0.0"
|
||||||
flutter: ">=3.24.0"
|
flutter: ">=3.24.0"
|
||||||
|
|
|
||||||
BIN
upload-keystore.jks
Normal file
BIN
upload-keystore.jks
Normal file
Binary file not shown.
Loading…
Reference in New Issue
Block a user