diff --git a/assets/images/air_humidity.png b/assets/images/air_humidity.png new file mode 100644 index 0000000..d6bafb7 Binary files /dev/null and b/assets/images/air_humidity.png differ diff --git a/assets/images/air_temperature.png b/assets/images/air_temperature.png new file mode 100644 index 0000000..2a7390b Binary files /dev/null and b/assets/images/air_temperature.png differ diff --git a/assets/images/soil_moisture.png b/assets/images/soil_moisture.png new file mode 100644 index 0000000..d71a866 Binary files /dev/null and b/assets/images/soil_moisture.png differ diff --git a/assets/images/soil_pH.png b/assets/images/soil_pH.png new file mode 100644 index 0000000..41e64d1 Binary files /dev/null and b/assets/images/soil_pH.png differ diff --git a/assets/images/soil_salinity.png b/assets/images/soil_salinity.png new file mode 100644 index 0000000..e9d6801 Binary files /dev/null and b/assets/images/soil_salinity.png differ diff --git a/lib/ui/IoT/IoT_monitoring_page.dart b/lib/ui/IoT/IoT_monitoring_page.dart index 8838f4b..f2311cc 100644 --- a/lib/ui/IoT/IoT_monitoring_page.dart +++ b/lib/ui/IoT/IoT_monitoring_page.dart @@ -1,3 +1,6 @@ +import 'package:farmassist/ui/IoT/reload_bar.dart'; +import 'package:farmassist/ui/IoT/telemetry_data_card.dart'; +import 'package:farmassist/ui/IoT/telemetry_data_card_item.dart'; import 'package:farmassist/ui/widgets/tab_page.dart'; import 'package:flutter/material.dart'; @@ -10,6 +13,17 @@ class IoTMonitoringPage extends TabPage { } class _IoTMonitoringPageState extends TabPageState { + List _cardItems = TelemetryDataCardItem.cardItems; + + @override + void initState() { + tabListView.add(ReloadBar()); + _cardItems.forEach((i) { + tabListView.add(TelemetryDataCard(cardItem: i)); + }); + super.initState(); + } + @override Widget build(BuildContext context) { return super.build(context); diff --git a/lib/ui/IoT/reload_bar.dart b/lib/ui/IoT/reload_bar.dart new file mode 100644 index 0000000..d0c21bb --- /dev/null +++ b/lib/ui/IoT/reload_bar.dart @@ -0,0 +1,57 @@ +import 'package:farmassist/app_theme.dart'; +import 'package:flutter/material.dart'; +import 'package:intl/intl.dart'; + +class ReloadBar extends StatefulWidget { + @override + _ReloadBarState createState() => _ReloadBarState(); +} + +class _ReloadBarState extends State { + String _now = DateFormat.yMd().add_jm().format(DateTime.now()); + + @override + Widget build(BuildContext context) { + return Container( + child: Padding( + padding: const EdgeInsets.only(left: 24.0, right: 24.0), + child: Row( + children: [ + InkWell( + highlightColor: AppTheme.notWhite, + borderRadius: BorderRadius.all(Radius.circular(28.0)), + onTap: () { + setState(() { + _now = DateFormat.yMd().add_jm().format(DateTime.now()); + }); + }, + child: SizedBox( + child: Icon( + Icons.autorenew, + color: AppTheme.darkText, + size: 28, + ), + ), + ), + Expanded( + child: Padding( + padding: const EdgeInsets.only(left: 8.0), + child: Text( + 'Last update: $_now', + textAlign: TextAlign.left, + style: TextStyle( + fontFamily: AppTheme.fontName, + fontWeight: FontWeight.w500, + fontSize: 16, + letterSpacing: 0.5, + color: AppTheme.lightText, + ), + ), + ), + ), + ], + ), + ), + ); + } +} diff --git a/lib/ui/IoT/telemetry_data_card.dart b/lib/ui/IoT/telemetry_data_card.dart new file mode 100644 index 0000000..0c4fa5c --- /dev/null +++ b/lib/ui/IoT/telemetry_data_card.dart @@ -0,0 +1,140 @@ +import 'package:farmassist/app_theme.dart'; +import 'package:farmassist/ui/IoT/telemetry_data_card_item.dart'; +import 'package:flutter/material.dart'; + +class TelemetryDataCard extends StatelessWidget { + const TelemetryDataCard({Key key, this.cardItem}) : super(key: key); + + final TelemetryDataCardItem cardItem; + + @override + Widget build(BuildContext context) { + return Stack( + children: [ + Padding( + padding: const EdgeInsets.only( + left: 24.0, + right: 24.0, + top: 16.0, + bottom: 18.0, + ), + child: Container( + decoration: BoxDecoration( + gradient: LinearGradient( + colors: [ + cardItem.color1, + cardItem.color2, + ], + begin: Alignment.topLeft, + end: Alignment.bottomRight, + ), + borderRadius: BorderRadius.only( + topLeft: Radius.circular(8.0), + bottomLeft: Radius.circular(8.0), + bottomRight: Radius.circular(8.0), + topRight: Radius.circular(68.0), + ), + boxShadow: [ + BoxShadow( + color: AppTheme.grey.withOpacity(0.6), + offset: Offset(1.1, 1.1), + blurRadius: 10.0, + ), + ], + ), + child: Padding( + padding: const EdgeInsets.all(16.0), + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + cardItem.title, + textAlign: TextAlign.left, + style: TextStyle( + fontFamily: AppTheme.fontName, + fontWeight: FontWeight.normal, + fontSize: 20, + letterSpacing: 0.0, + color: AppTheme.white, + ), + ), + Padding( + padding: const EdgeInsets.only(top: 8.0), + child: FractionallySizedBox( + widthFactor: 0.8, + child: Text( + cardItem.description, + textAlign: TextAlign.left, + style: TextStyle( + fontFamily: AppTheme.fontName, + fontWeight: FontWeight.normal, + fontSize: 16, + letterSpacing: 0.0, + color: AppTheme.white, + ), + ), + ), + ), + Padding( + padding: const EdgeInsets.only(top: 16.0), + child: Row( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.center, + children: [ + SizedBox( + height: 30, + width: 30, + child: 1 == 1 // TODO: temporary dummy placeholder + ? Icon( + Icons.warning_rounded, + color: AppTheme.white, + size: 30, + ) + : null, + ), + Expanded( + child: Text( + '68.9', // TODO: temporary dummy placeholder + textAlign: TextAlign.right, + style: TextStyle( + fontFamily: AppTheme.fontName, + fontWeight: FontWeight.w500, + fontSize: 50, + letterSpacing: 0.0, + color: AppTheme.white, + ), + ), + ), + Expanded( + child: Text( + cardItem.unit, + textAlign: TextAlign.left, + style: TextStyle( + fontFamily: AppTheme.fontName, + fontWeight: FontWeight.w500, + fontSize: 22, + letterSpacing: 0.0, + color: AppTheme.white, + ), + ), + ), + ], + ), + ) + ], + ), + ), + ), + ), + Positioned( + top: 4.0, + right: 20.0, + height: 80, + width: 80, + child: Image.asset(cardItem.imagePath), + ) + ], + ); + } +} diff --git a/lib/ui/IoT/telemetry_data_card_item.dart b/lib/ui/IoT/telemetry_data_card_item.dart new file mode 100644 index 0000000..f6cbf1c --- /dev/null +++ b/lib/ui/IoT/telemetry_data_card_item.dart @@ -0,0 +1,69 @@ +import 'dart:ui'; + +class TelemetryDataCardItem { + TelemetryDataCardItem({ + this.title, + this.description, + this.unit, + this.imagePath, + this.color1, + this.color2, + this.index, + }); + + String title; + String description; + String unit; + String imagePath; + Color color1; + Color color2; + int index; + + static List cardItems = [ + TelemetryDataCardItem( + title: 'Air Humidity', + description: 'Relative percentage of water vapour present in air', + unit: '%', + imagePath: 'assets/images/air_humidity.png', + color1: const Color(0xFF6F56E8), + color2: const Color(0xFF79D1FB), + index: 0, + ), + TelemetryDataCardItem( + title: 'Air Temperature', + description: 'Weather parameter that measures how hot or cold the air is', + unit: '°C', + imagePath: 'assets/images/air_temperature.png', + color1: const Color(0xFF006400), + color2: const Color(0xFF1FDF39), + index: 1, + ), + TelemetryDataCardItem( + title: 'Soil Moisture', + description: 'Percentage of volumetric water content in soil', + unit: '%', + imagePath: 'assets/images/soil_moisture.png', + color1: const Color(0xFF800000), + color2: const Color(0xFFD2691E), + index: 2, + ), + TelemetryDataCardItem( + title: 'Soil pH', + description: 'Measure of acidity or alkalinity of soil', + unit: 'pH', + imagePath: 'assets/images/soil_pH.png', + color1: const Color(0xFFFF3F34), + color2: const Color(0xFFFFA334), + index: 3, + ), + TelemetryDataCardItem( + title: 'Soil Salinity', + description: 'Measure of salt content of soil in milliSiemens per cm', + unit: 'mS/cm', + imagePath: 'assets/images/soil_salinity.png', + color1: const Color(0xFF9700CB), + color2: const Color(0xFFF410D9), + index: 4, + ), + ]; +}