diff --git a/agrilink_vocpro/assets/images/valve.png b/agrilink_vocpro/assets/images/valve.png new file mode 100644 index 0000000..5a4bbfd Binary files /dev/null and b/agrilink_vocpro/assets/images/valve.png differ diff --git a/agrilink_vocpro/lib/core/constant/app_constant.dart b/agrilink_vocpro/lib/core/constant/app_constant.dart index a7dcbf6..e464b3a 100644 --- a/agrilink_vocpro/lib/core/constant/app_constant.dart +++ b/agrilink_vocpro/lib/core/constant/app_constant.dart @@ -2,7 +2,7 @@ class AppConstant { static const String appName = 'Kebun Pintar'; static const String appVersion = '1.0.0'; - static const String baseUrl = 'https://agrilinkvocpropisdev.id/api/v1'; + static const String baseUrl = 'http://192.168.11.41:3333/api/'; static const String mqttServer = 'armadillo.rmq.cloudamqp.com'; static const String mqttUsername = 'obyskxhx:obyskxhx'; diff --git a/agrilink_vocpro/lib/core/widgets/show_info.dart b/agrilink_vocpro/lib/core/widgets/show_info.dart new file mode 100644 index 0000000..2344d35 --- /dev/null +++ b/agrilink_vocpro/lib/core/widgets/show_info.dart @@ -0,0 +1,28 @@ +import 'package:flutter/material.dart'; + +Future showInfo(BuildContext context, String title, String content) { + return showDialog( + context: context, + builder: (context) => AlertDialog( + content: Column( + mainAxisSize: MainAxisSize.min, + children: [ + Text(title), + const SizedBox(height: 16), + Text( + style: Theme.of(context).textTheme.bodySmall, + content, + ), + ], + ), + actions: [ + TextButton( + onPressed: () { + Navigator.pop(context); + }, + child: const Text('OK'), + ) + ], + ), + ); +} diff --git a/agrilink_vocpro/lib/data/model/relay_response.dart b/agrilink_vocpro/lib/data/model/relay_response.dart new file mode 100644 index 0000000..bdae310 --- /dev/null +++ b/agrilink_vocpro/lib/data/model/relay_response.dart @@ -0,0 +1,66 @@ +class RelayResponse { + bool? success; + List? data; + + RelayResponse({this.success, this.data}); + + RelayResponse.fromJson(Map json) { + success = json['success']; + if (json['data'] != null) { + data = []; + json['data'].forEach((v) { + data!.add(Relay.fromJson(v)); + }); + } + } + + Map toJson() { + final Map data = {}; + data['success'] = success; + if (this.data != null) { + data['data'] = this.data!.map((v) => v.toJson()).toList(); + } + return data; + } +} + +class Relay { + int? id; + int? number; + String? enabledAt; + String? disabledAt; + bool? currentStatus; + String? createdAt; + String? updatedAt; + + Relay( + {this.id, + this.number, + this.enabledAt, + this.disabledAt, + this.currentStatus, + this.createdAt, + this.updatedAt}); + + Relay.fromJson(Map json) { + id = json['id']; + number = json['number']; + enabledAt = json['enabled_at']; + disabledAt = json['disabled_at']; + currentStatus = json['current_status']; + createdAt = json['created_at']; + updatedAt = json['updated_at']; + } + + Map toJson() { + final Map data = {}; + data['id'] = id; + data['number'] = number; + data['enabled_at'] = enabledAt; + data['disabled_at'] = disabledAt; + data['current_status'] = currentStatus; + data['created_at'] = createdAt; + data['updated_at'] = updatedAt; + return data; + } +} diff --git a/agrilink_vocpro/lib/domain/service/app_service.dart b/agrilink_vocpro/lib/domain/service/app_service.dart index bb89afc..0d9cb8a 100644 --- a/agrilink_vocpro/lib/domain/service/app_service.dart +++ b/agrilink_vocpro/lib/domain/service/app_service.dart @@ -1,4 +1,5 @@ -import 'package:agrilink_vocpro/core/constant/app_contant.dart'; +import 'package:agrilink_vocpro/core/constant/app_constant.dart'; +import 'package:agrilink_vocpro/data/model/relay_response.dart'; import 'package:dio/dio.dart'; import 'package:flutter/foundation.dart'; @@ -9,8 +10,17 @@ class AppService { ), ); - Future getGreenHouseData() async { - try {} on DioException catch (e) { + Future getRelayStatus() async { + try { + await Future.delayed(const Duration(seconds: 3)); + final result = await _dioWithoutInterceptor.get('get-relay'); + if (result.statusCode == 200) { + final data = RelayResponse.fromJson(result.data); + return data; + } else { + throw Exception('Failed to load data'); + } + } on DioException catch (e) { if (kDebugMode) { print(e); } diff --git a/agrilink_vocpro/lib/features/control/provider/control_provider.dart b/agrilink_vocpro/lib/features/control/provider/control_provider.dart index 42b96a6..21ed0dd 100644 --- a/agrilink_vocpro/lib/features/control/provider/control_provider.dart +++ b/agrilink_vocpro/lib/features/control/provider/control_provider.dart @@ -1,86 +1,125 @@ +import 'dart:math'; + import 'package:agrilink_vocpro/core/state/result_state.dart'; -import 'package:agrilink_vocpro/domain/service/mqtt_service.dart'; +import 'package:agrilink_vocpro/domain/service/app_service.dart'; import 'package:flutter/material.dart'; class ControlProvider extends ChangeNotifier { - final MQTTService _mqttService = MQTTService(); + final AppService _appService = AppService(); bool _control_1 = false; - bool get control_1 => _control_1; + bool _control_2 = false; + bool get control_2 => _control_2; + ControlProvider() { - connectMqtt(); + getRelayStatus(); } - ResultState mqttState = ResultState.initial; - ResultState subscribeState = ResultState.initial; + // ResultState mqttState = ResultState.initial; + // ResultState subscribeState = ResultState.initial; - Future connectMqtt() async { - mqttState = ResultState.loading; - subscribeState = ResultState.loading; + ResultState relayState = ResultState.initial; + + // Future connectMqtt() async { + // mqttState = ResultState.loading; + // subscribeState = ResultState.loading; + // notifyListeners(); + + // try { + // final result = await _mqttService.setupMqtt(); + // if (result == ResultState.hasData) { + // mqttState = result; + // final result2 = await _mqttService.subscribeToRelayStatus(); + // // if (result2 == true) { + // // subscribeState = ResultState.hasData; + // // _control_1 = true; + // // } else { + // // subscribeState = ResultState.hasData; + // // _control_1 = false; + // // } + // } else { + // mqttState = ResultState.error; + // } + // } catch (e) { + // mqttState = ResultState.error; + // print(e); + // } + + // notifyListeners(); + // } + + Future getRelayStatus() async { + relayState = ResultState.loading; notifyListeners(); - 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; - // } + final result = await _appService.getRelayStatus(); + if (result.success == true) { + for (var element in result.data!) { + if (element.number == 1) { + switchControl1(element.currentStatus ?? false); + } + if (element.number == 2) { + switchControl2(element.currentStatus ?? false); + } + } + relayState = ResultState.hasData; + notifyListeners(); } else { - mqttState = ResultState.error; + relayState = ResultState.error; + notifyListeners(); } } catch (e) { - mqttState = ResultState.error; - print(e); - } - - notifyListeners(); - } - - Future disconnectMqtt() async { - try { - await _mqttService.disconnectMqtt(); - } catch (e) { - print(e); - rethrow; - } - notifyListeners(); - } - - @override - void dispose() { - disconnectMqtt(); - super.dispose(); - } - - void switchControl1() { - _control_1 = !_control_1; - notifyListeners(); - } - - Future publishMessage(String topic, String message) async { - try { - final result = await _mqttService.publishMessage(topic, message); - return result; - } catch (e) { + relayState = ResultState.error; + notifyListeners(); print(e); rethrow; } } - Future subscribeToTopic(String topic) async { - try { - await _mqttService.subscribeToTopic(topic); - } catch (e) { - print(e); - rethrow; - } + // Future disconnectMqtt() async { + // try { + // await _mqttService.disconnectMqtt(); + // } catch (e) { + // print(e); + // rethrow; + // } + // notifyListeners(); + // } + + // @override + // void dispose() { + // disconnectMqtt(); + // super.dispose(); + // } + + void switchControl1(bool value) { + _control_1 = value; + notifyListeners(); } + + void switchControl2(bool value) { + _control_2 = value; + notifyListeners(); + } + + // Future publishMessage(String topic, String message) async { + // try { + // final result = await _mqttService.publishMessage(topic, message); + // return result; + // } catch (e) { + // print(e); + // rethrow; + // } + // } + + // Future subscribeToTopic(String topic) async { + // try { + // await _mqttService.subscribeToTopic(topic); + // } catch (e) { + // print(e); + // rethrow; + // } + // } } diff --git a/agrilink_vocpro/lib/features/control/view/control_screen.dart b/agrilink_vocpro/lib/features/control/view/control_screen.dart index c824b06..87e63ec 100644 --- a/agrilink_vocpro/lib/features/control/view/control_screen.dart +++ b/agrilink_vocpro/lib/features/control/view/control_screen.dart @@ -1,6 +1,8 @@ +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:bootstrap_icons/bootstrap_icons.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; @@ -11,6 +13,7 @@ class ControlScreen extends StatelessWidget { @override Widget build(BuildContext context) { + final provider = Provider.of(context, listen: true); return Scaffold( appBar: AppBar( title: Text('Control', style: AppTheme.labelMedium), @@ -18,39 +21,114 @@ class ControlScreen extends StatelessWidget { backgroundColor: Colors.white, scrolledUnderElevation: 0, ), - body: Consumer( - builder: (context, provider, child) { - return SafeArea( - child: ListView( - children: [ - Center( - child: provider.mqttState == ResultState.loading - ? const CupertinoActivityIndicator() - : provider.mqttState == ResultState.hasData - ? const Text('Terhubung ke Broker') - : const Text('Gagal terhubung ke Broker'), - ), - SizedBox(height: 16.h), - ListTile( - title: Text('Control 1', style: AppTheme.labelMedium), - subtitle: const Text('Control 1 description'), - trailing: Switch( - value: provider.control_1, - onChanged: (value) { - provider.control_1 == false - ? provider.publishMessage( - 'smartfarming/relay/232', 'ON') - : provider.publishMessage( - 'smartfarming/relay/232', 'OFF'); - provider.switchControl1(); - }, + body: RefreshIndicator( + onRefresh: () async => + await context.read().getRelayStatus(), + child: SafeArea( + child: ListView( + children: [ + SizedBox(height: 16.h), + GridView( + padding: EdgeInsets.all(16.r), + physics: const NeverScrollableScrollPhysics(), + shrinkWrap: true, + gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( + crossAxisCount: 2, + crossAxisSpacing: 16.r, + mainAxisSpacing: 16.r, + childAspectRatio: 1.4.h, ), - ), - // Control lainnya... - ], - ), - ); - }, + children: [ + ControlButtonWidget( + title: 'Katup Air', + subtitle: 'Relay 1', + isActive: provider.control_1, + onTap: () {}, + ), + ControlButtonWidget( + title: 'Lampu Utama', + subtitle: 'Relay 2', + isActive: provider.control_2, + onTap: () {}, + ), + ]), + ], + ), + ), + ), + ); + } +} + +class ControlButtonWidget extends StatelessWidget { + const ControlButtonWidget({ + 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( + padding: EdgeInsets.all(16.r), + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(16.r), + boxShadow: [ + BoxShadow( + color: Colors.grey.withOpacity(0.2), + spreadRadius: 1.r, + blurRadius: 16.r, + offset: Offset(0, 12.r), + ), + ], + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text(title, style: AppTheme.labelMedium), + Text(subtitle, style: AppTheme.labelSmall), + const Spacer(), + Row( + mainAxisAlignment: MainAxisAlignment.end, + children: [ + Consumer( + builder: (context, provider, child) { + switch (provider.relayState) { + case ResultState.loading: + return CircleAvatar( + radius: 20.r, + backgroundColor: Colors.transparent, + child: const CupertinoActivityIndicator(), + ); + default: + return InkWell( + highlightColor: Colors.black, + onTap: onTap, + child: CircleAvatar( + radius: 20.r, + backgroundColor: isActive + ? AppColor.secondary + : Colors.grey.shade400, + child: const Icon( + BootstrapIcons.power, + color: Colors.white, + ), + ), + ); + } + }, + ), + ], + ) + ], ), ); } diff --git a/agrilink_vocpro/lib/features/home/pages/conductivity/view/conductivity_screen.dart b/agrilink_vocpro/lib/features/home/pages/conductivity/view/conductivity_screen.dart index 2129116..3eb7ae7 100644 --- a/agrilink_vocpro/lib/features/home/pages/conductivity/view/conductivity_screen.dart +++ b/agrilink_vocpro/lib/features/home/pages/conductivity/view/conductivity_screen.dart @@ -23,7 +23,7 @@ class ConductivityScreen extends StatelessWidget { padding: EdgeInsets.only(right: 16), child: Icon( Icons.electric_bolt_rounded, - color: Colors.blue, + color: Colors.teal, ), ) ], @@ -38,7 +38,7 @@ class ConductivityScreen extends StatelessWidget { Icon( Icons.electric_bolt_rounded, size: 64.r, - color: Colors.blue, + color: Colors.teal, ), Text('$value µS/cm', style: AppTheme.headline1), ], @@ -70,7 +70,12 @@ class ConductivityScreen extends StatelessWidget { borderRadius: BorderRadius.circular(16.w), border: Border.all(color: Colors.grey.shade300, width: 1.w), ), - child: const GarphicWidget(), + child: const GarphicWidget( + gradientColors: [ + Colors.cyan, + Colors.teal, + ], + ), ), ) ], diff --git a/agrilink_vocpro/lib/features/home/pages/humidity/view/humidity_screen.dart b/agrilink_vocpro/lib/features/home/pages/humidity/view/humidity_screen.dart index 40142d3..b3d9cb6 100644 --- a/agrilink_vocpro/lib/features/home/pages/humidity/view/humidity_screen.dart +++ b/agrilink_vocpro/lib/features/home/pages/humidity/view/humidity_screen.dart @@ -110,13 +110,19 @@ class HumidityScreen extends StatelessWidget { AspectRatio( aspectRatio: 2.h, child: Container( - margin: EdgeInsets.symmetric(horizontal: 16.w), - decoration: BoxDecoration( - color: Colors.white, - borderRadius: BorderRadius.circular(16.w), - border: Border.all( - color: Colors.grey.shade300, width: 1.w)), - child: const GarphicWidget()), + margin: EdgeInsets.symmetric(horizontal: 16.w), + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(16.w), + border: + Border.all(color: Colors.grey.shade300, width: 1.w)), + child: GarphicWidget( + gradientColors: [ + Colors.blue.shade200, + Colors.blue, + ], + ), + ), ), SizedBox(height: 16.h), Padding( diff --git a/agrilink_vocpro/lib/features/home/pages/light/view/light_screen.dart b/agrilink_vocpro/lib/features/home/pages/light/view/light_screen.dart index 683a237..2a80b81 100644 --- a/agrilink_vocpro/lib/features/home/pages/light/view/light_screen.dart +++ b/agrilink_vocpro/lib/features/home/pages/light/view/light_screen.dart @@ -104,13 +104,18 @@ class LightScreen extends StatelessWidget { const Text('Grafik'), SizedBox(height: 16.h), AspectRatio( - aspectRatio: 1.5.h, + aspectRatio: 1.8.h, child: Container( decoration: BoxDecoration( border: Border.all(color: Colors.grey.shade300, width: 1.w), borderRadius: BorderRadius.circular(16.w), ), - child: const GarphicWidget(), + child: GarphicWidget( + gradientColors: [ + Colors.yellow.shade100, + Colors.orange.shade200, + ], + ), ), ) // Row( diff --git a/agrilink_vocpro/lib/features/home/pages/nitrogen/view/nitrogen_screen.dart b/agrilink_vocpro/lib/features/home/pages/nitrogen/view/nitrogen_screen.dart index 5753173..9b99e91 100644 --- a/agrilink_vocpro/lib/features/home/pages/nitrogen/view/nitrogen_screen.dart +++ b/agrilink_vocpro/lib/features/home/pages/nitrogen/view/nitrogen_screen.dart @@ -41,7 +41,7 @@ class NitrogenScreen extends StatelessWidget { size: 64.r, color: Colors.blue, ), - Text('$value µS/cm', style: AppTheme.headline1), + Text('$value ppm', style: AppTheme.headline1), ], ), SizedBox(height: 32.h), @@ -71,7 +71,12 @@ class NitrogenScreen extends StatelessWidget { borderRadius: BorderRadius.circular(16.w), border: Border.all(color: Colors.grey.shade300, width: 1.w), ), - child: const GarphicWidget(), + child: GarphicWidget( + gradientColors: [ + Colors.blue.shade200, + Colors.blue, + ], + ), ), ) ], diff --git a/agrilink_vocpro/lib/features/home/pages/ph/view/ph_screen.dart b/agrilink_vocpro/lib/features/home/pages/ph/view/ph_screen.dart index 85ea0d7..a8c7517 100644 --- a/agrilink_vocpro/lib/features/home/pages/ph/view/ph_screen.dart +++ b/agrilink_vocpro/lib/features/home/pages/ph/view/ph_screen.dart @@ -167,7 +167,12 @@ class PhScreen extends StatelessWidget { borderRadius: BorderRadius.circular(16.w), border: Border.all(color: Colors.grey.shade300, width: 1.w), ), - child: const GarphicWidget(), + child: GarphicWidget( + gradientColors: [ + Colors.amber.shade200, + Colors.orange, + ], + ), ), ) ], diff --git a/agrilink_vocpro/lib/features/home/pages/phosphorus/view/phosphorus_screen.dart b/agrilink_vocpro/lib/features/home/pages/phosphorus/view/phosphorus_screen.dart index d273827..e77cc61 100644 --- a/agrilink_vocpro/lib/features/home/pages/phosphorus/view/phosphorus_screen.dart +++ b/agrilink_vocpro/lib/features/home/pages/phosphorus/view/phosphorus_screen.dart @@ -71,7 +71,12 @@ class PhosphorusScreen extends StatelessWidget { borderRadius: BorderRadius.circular(16.w), border: Border.all(color: Colors.grey.shade300, width: 1.w), ), - child: const GarphicWidget(), + child: GarphicWidget( + gradientColors: [ + Colors.blue.shade200, + Colors.blue, + ], + ), ), ) ], diff --git a/agrilink_vocpro/lib/features/home/pages/potassium/view/potassium_screen.dart b/agrilink_vocpro/lib/features/home/pages/potassium/view/potassium_screen.dart index d38d726..6be5a5a 100644 --- a/agrilink_vocpro/lib/features/home/pages/potassium/view/potassium_screen.dart +++ b/agrilink_vocpro/lib/features/home/pages/potassium/view/potassium_screen.dart @@ -71,7 +71,12 @@ class PotassiumScreen extends StatelessWidget { borderRadius: BorderRadius.circular(16.w), border: Border.all(color: Colors.grey.shade300, width: 1.w), ), - child: const GarphicWidget(), + child: const GarphicWidget( + gradientColors: [ + Colors.teal, + Colors.green, + ], + ), ), ) ], diff --git a/agrilink_vocpro/lib/features/home/pages/soil_moisture/view/soil_moisture_screen.dart b/agrilink_vocpro/lib/features/home/pages/soil_moisture/view/soil_moisture_screen.dart index 05de5ca..c05a466 100644 --- a/agrilink_vocpro/lib/features/home/pages/soil_moisture/view/soil_moisture_screen.dart +++ b/agrilink_vocpro/lib/features/home/pages/soil_moisture/view/soil_moisture_screen.dart @@ -1,4 +1,7 @@ +import 'package:agrilink_vocpro/core/constant/app_constant.dart'; import 'package:agrilink_vocpro/core/constant/app_theme.dart'; +import 'package:agrilink_vocpro/core/widgets/show_info.dart'; +import 'package:agrilink_vocpro/features/home/widgets/graphic_widget.dart'; import 'package:bootstrap_icons/bootstrap_icons.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; @@ -34,10 +37,8 @@ class SoilMoistureScreen extends StatelessWidget { ), body: SafeArea( child: ListView( + padding: EdgeInsets.all(16.w), children: [ - SizedBox( - height: MediaQuery.of(context).size.height * 0.05, - ), SizedBox( height: 280.h, child: Stack( @@ -80,7 +81,47 @@ class SoilMoistureScreen extends StatelessWidget { ], ), ), - const SizedBox(height: 16), + SizedBox(height: 16.h), + Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Text( + 'Soil Temperature', + style: AppTheme.labelMedium, + textAlign: TextAlign.center, + ), + IconButton( + iconSize: 20.r, + color: Colors.blue, + onPressed: () { + showInfo( + context, + 'Soil Temperature', + AppConstant.soilTempInfo, + ); + }, + icon: const Icon(BootstrapIcons.info_circle)) + ], + ), + SizedBox(height: 16.h), + const Text('Grafik'), + SizedBox(height: 16.h), + AspectRatio( + aspectRatio: 1.8.h, + child: Container( + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(16.w), + border: Border.all(color: Colors.grey.shade300, width: 1.w), + ), + child: GarphicWidget( + gradientColors: [ + Colors.blue.shade200, + Colors.blue, + ], + ), + ), + ) ], ), ), diff --git a/agrilink_vocpro/lib/features/home/pages/soil_temperature/view/soil_temperature_screen.dart b/agrilink_vocpro/lib/features/home/pages/soil_temperature/view/soil_temperature_screen.dart index 5dae429..6715b63 100644 --- a/agrilink_vocpro/lib/features/home/pages/soil_temperature/view/soil_temperature_screen.dart +++ b/agrilink_vocpro/lib/features/home/pages/soil_temperature/view/soil_temperature_screen.dart @@ -1,5 +1,6 @@ import 'package:agrilink_vocpro/core/constant/app_constant.dart'; import 'package:agrilink_vocpro/core/constant/app_theme.dart'; +import 'package:agrilink_vocpro/core/widgets/show_info.dart'; import 'package:agrilink_vocpro/features/home/widgets/graphic_widget.dart'; import 'package:bootstrap_icons/bootstrap_icons.dart'; import 'package:flutter/material.dart'; @@ -85,8 +86,7 @@ class SoilTemperatureScreen extends StatelessWidget { ], ), ), - const SizedBox(height: 16), - const SizedBox(height: 16), + SizedBox(height: 16.h), Row( mainAxisAlignment: MainAxisAlignment.center, children: [ @@ -218,7 +218,12 @@ class SoilTemperatureScreen extends StatelessWidget { borderRadius: BorderRadius.circular(16.w), border: Border.all(color: Colors.grey.shade300, width: 1.w), ), - child: const GarphicWidget(), + child: const GarphicWidget( + gradientColors: [ + Colors.cyan, + Colors.amber, + ], + ), ), ) ], @@ -226,31 +231,4 @@ class SoilTemperatureScreen extends StatelessWidget { ), ); } - - Future showInfo(BuildContext context, String title, String content) { - return showDialog( - context: context, - builder: (context) => AlertDialog( - content: Column( - mainAxisSize: MainAxisSize.min, - children: [ - Text(title), - const SizedBox(height: 16), - Text( - style: Theme.of(context).textTheme.bodySmall, - content, - ), - ], - ), - actions: [ - TextButton( - onPressed: () { - Navigator.pop(context); - }, - child: const Text('OK'), - ) - ], - ), - ); - } } diff --git a/agrilink_vocpro/lib/features/home/pages/temperature/view/temperature_screen.dart b/agrilink_vocpro/lib/features/home/pages/temperature/view/temperature_screen.dart index 3340242..dad687f 100644 --- a/agrilink_vocpro/lib/features/home/pages/temperature/view/temperature_screen.dart +++ b/agrilink_vocpro/lib/features/home/pages/temperature/view/temperature_screen.dart @@ -75,7 +75,7 @@ class TemperatureScreen extends StatelessWidget { ), progressBar: const GaugeBasicProgressBar( gradient: GaugeAxisGradient(colors: [ - Colors.blue, + Colors.white12, Colors.orange, ]), ), @@ -211,7 +211,12 @@ class TemperatureScreen extends StatelessWidget { borderRadius: BorderRadius.circular(16.w), border: Border.all(color: Colors.grey.shade300, width: 1.w), ), - child: const GarphicWidget(), + child: const GarphicWidget( + gradientColors: [ + Colors.cyan, + Colors.amber, + ], + ), ), ) ], diff --git a/agrilink_vocpro/lib/features/home/widgets/graphic_widget.dart b/agrilink_vocpro/lib/features/home/widgets/graphic_widget.dart index 40630d2..2660ba8 100644 --- a/agrilink_vocpro/lib/features/home/widgets/graphic_widget.dart +++ b/agrilink_vocpro/lib/features/home/widgets/graphic_widget.dart @@ -1,191 +1,115 @@ -import 'package:agrilink_vocpro/core/constant/app_color.dart'; +import 'package:agrilink_vocpro/core/constant/app_theme.dart'; import 'package:fl_chart/fl_chart.dart'; import 'package:flutter/material.dart'; +import 'package:flutter_screenutil/flutter_screenutil.dart'; class GarphicWidget extends StatelessWidget { - const GarphicWidget({super.key, thi}); + const GarphicWidget({super.key, required this.gradientColors}); + + final List gradientColors; @override Widget build(BuildContext context) { - return BarChart( - BarChartData( - barTouchData: barTouchData, - titlesData: titlesData, - borderData: borderData, - barGroups: barGroups, - gridData: const FlGridData(show: false), - alignment: BarChartAlignment.spaceAround, - maxY: 20, + return Padding( + padding: EdgeInsets.all(8.r), + child: LineChart( + mainData(), ), ); } -} -BarTouchData get barTouchData => BarTouchData( - enabled: false, - touchTooltipData: BarTouchTooltipData( - getTooltipColor: (group) => Colors.transparent, - tooltipPadding: EdgeInsets.zero, - tooltipMargin: 8, - getTooltipItem: ( - BarChartGroupData group, - int groupIndex, - BarChartRodData rod, - int rodIndex, - ) { - return BarTooltipItem( - rod.toY.round().toString(), - const TextStyle( - color: AppColor.textDark, - fontWeight: FontWeight.bold, - ), - ); - }, - ), + Widget bottomTitleWidgets(double value, TitleMeta meta) { + TextStyle style = AppTheme.labelSmall; + Widget text; + switch (value.toInt()) { + case 1: + text = Text('01.00', style: style); + break; + case 6: + text = Text('06.00', style: style); + break; + case 12: + text = Text('12.00', style: style); + break; + case 18: + text = Text('18.00', style: style); + break; + case 23: + text = Text('23.00', style: style); + break; + default: + text = Text('', style: style); + break; + } + + return SideTitleWidget( + axisSide: meta.axisSide, + child: text, ); - -Widget getTitles(double value, TitleMeta meta) { - const style = TextStyle( - color: AppColor.textDark, - fontWeight: FontWeight.bold, - fontSize: 14, - ); - String text; - switch (value.toInt()) { - case 0: - text = 'Mon'; - break; - case 1: - text = 'Tue'; - break; - case 2: - text = 'Wed'; - break; - case 3: - text = 'Thu'; - break; - case 4: - text = 'Fri'; - break; - case 5: - text = 'Sat'; - break; - case 6: - text = 'Sun'; - break; - default: - text = ''; - break; } - return SideTitleWidget( - axisSide: meta.axisSide, - space: 4, - child: Text(text, style: style), - ); -} -FlTitlesData get titlesData => const FlTitlesData( - show: true, - bottomTitles: AxisTitles( - sideTitles: SideTitles( - showTitles: true, - reservedSize: 30, - getTitlesWidget: getTitles, + LineChartData mainData() { + return LineChartData( + gridData: const FlGridData( + show: false, + ), + titlesData: FlTitlesData( + show: true, + rightTitles: const AxisTitles( + sideTitles: SideTitles(showTitles: false), + ), + topTitles: const AxisTitles( + sideTitles: SideTitles(showTitles: false), + ), + bottomTitles: AxisTitles( + sideTitles: SideTitles( + showTitles: true, + reservedSize: 30, + interval: 1, + getTitlesWidget: bottomTitleWidgets, + ), + ), + leftTitles: const AxisTitles( + sideTitles: SideTitles(showTitles: false), ), ), - leftTitles: AxisTitles( - sideTitles: SideTitles(showTitles: false), + borderData: FlBorderData( + show: false, + border: Border.all(color: const Color(0xff37434d)), ), - topTitles: AxisTitles( - sideTitles: SideTitles(showTitles: false), - ), - rightTitles: AxisTitles( - sideTitles: SideTitles(showTitles: false), - ), - ); - -FlBorderData get borderData => FlBorderData( - show: false, - ); - -LinearGradient get _barsGradient => const LinearGradient( - colors: [ - AppColor.secondary, - AppColor.ternary, + minX: 0, + maxX: 24, + minY: 0, + maxY: 100, + lineBarsData: [ + LineChartBarData( + spots: const [ + FlSpot(0, 38), + FlSpot(1, 42), + FlSpot(2, 50), + FlSpot(3, 53), + FlSpot(4, 58), + FlSpot(5, 64), + FlSpot(7, 49), + ], + isCurved: true, + gradient: LinearGradient( + colors: gradientColors, + ), + barWidth: 5, + isStrokeCapRound: true, + dotData: const FlDotData( + show: false, + ), + belowBarData: BarAreaData( + show: true, + gradient: LinearGradient( + colors: gradientColors + .map((color) => color.withOpacity(0.3)) + .toList()), + ), + ), ], - begin: Alignment.bottomCenter, - end: Alignment.topCenter, ); - -List get barGroups => [ - BarChartGroupData( - x: 0, - barRods: [ - BarChartRodData( - toY: 8, - gradient: _barsGradient, - ) - ], - showingTooltipIndicators: [0], - ), - BarChartGroupData( - x: 1, - barRods: [ - BarChartRodData( - toY: 10, - gradient: _barsGradient, - ) - ], - showingTooltipIndicators: [0], - ), - BarChartGroupData( - x: 2, - barRods: [ - BarChartRodData( - toY: 14, - gradient: _barsGradient, - ) - ], - showingTooltipIndicators: [0], - ), - BarChartGroupData( - x: 3, - barRods: [ - BarChartRodData( - toY: 15, - gradient: _barsGradient, - ) - ], - showingTooltipIndicators: [0], - ), - BarChartGroupData( - x: 4, - barRods: [ - BarChartRodData( - toY: 13, - gradient: _barsGradient, - ) - ], - showingTooltipIndicators: [0], - ), - BarChartGroupData( - x: 5, - barRods: [ - BarChartRodData( - toY: 10, - gradient: _barsGradient, - ) - ], - showingTooltipIndicators: [0], - ), - BarChartGroupData( - x: 6, - barRods: [ - BarChartRodData( - toY: 16, - gradient: _barsGradient, - ) - ], - showingTooltipIndicators: [0], - ), - ]; + } +} diff --git a/agrilink_vocpro/lib/features/home/widgets/list_data_from_censor_dht.dart b/agrilink_vocpro/lib/features/home/widgets/list_data_from_censor_dht.dart index 015f729..628ca9d 100644 --- a/agrilink_vocpro/lib/features/home/widgets/list_data_from_censor_dht.dart +++ b/agrilink_vocpro/lib/features/home/widgets/list_data_from_censor_dht.dart @@ -64,12 +64,12 @@ class ListDataFromCensorDht extends StatelessWidget { DataDisplayerWidget( title: 'Temperature', subtitle: 'suhu greenhouse', - value: '28', + value: '43', unit: '°C', icon: BootstrapIcons.thermometer_half, color: Colors.white, onTap: () async { - await context.push('${AppRoute.temperature}/28'); + await context.push('${AppRoute.temperature}/43'); }, ), DataDisplayerWidget(