From 1223ab7a17137020ee70b2c562c0ea933a6920dd Mon Sep 17 00:00:00 2001 From: Sikander Saleem Date: Wed, 13 Oct 2021 14:25:42 +0300 Subject: [PATCH] h20 week & month graph updated & improvements. --- lib/config/config.dart | 4 +- .../AlHabibMedicalService/H2O_view_model.dart | 31 ++- .../AlHabibMedicalService/h2o/h2o_page.dart | 184 ++++++------------ .../AlHabibMedicalService/h2o/month_page.dart | 63 +++--- .../AlHabibMedicalService/h2o/week_page.dart | 66 +++---- .../medical/vital_sign/vital_sign_item.dart | 3 +- lib/widgets/charts/custom_line_chart.dart | 148 ++++++++++++++ lib/widgets/others/app_scaffold_widget.dart | 8 +- 8 files changed, 311 insertions(+), 196 deletions(-) create mode 100644 lib/widgets/charts/custom_line_chart.dart diff --git a/lib/config/config.dart b/lib/config/config.dart index 7840b97d..d7ffabcd 100644 --- a/lib/config/config.dart +++ b/lib/config/config.dart @@ -12,8 +12,8 @@ const PACKAGES_PRODUCTS = '/api/products'; const PACKAGES_CUSTOMER = '/api/customers'; const PACKAGES_SHOPPING_CART = '/api/shopping_cart_items'; const PACKAGES_ORDERS = '/api/orders'; -// const BASE_URL = 'https://uat.hmgwebservices.com/'; -const BASE_URL = 'https://hmgwebservices.com/'; +const BASE_URL = 'https://uat.hmgwebservices.com/'; +// const BASE_URL = 'https://hmgwebservices.com/'; // Pharmacy UAT URLs // const BASE_PHARMACY_URL = 'https://uat.hmgwebservices.com/epharmacy/api/'; diff --git a/lib/core/viewModels/AlHabibMedicalService/H2O_view_model.dart b/lib/core/viewModels/AlHabibMedicalService/H2O_view_model.dart index 219103da..3e980071 100644 --- a/lib/core/viewModels/AlHabibMedicalService/H2O_view_model.dart +++ b/lib/core/viewModels/AlHabibMedicalService/H2O_view_model.dart @@ -9,14 +9,19 @@ import 'package:diplomaticquarterapp/core/model/AlHabibMedicalService/H2O/user_p import 'package:diplomaticquarterapp/core/model/AlHabibMedicalService/H2O/user_progress_for_week_data_model.dart'; import 'package:diplomaticquarterapp/core/service/AlHabibMedicalService/H2O_service.dart'; import 'package:diplomaticquarterapp/core/viewModels/base_view_model.dart'; +import 'package:diplomaticquarterapp/widgets/charts/custom_line_chart.dart'; import '../../../locator.dart'; class H2OViewModel extends BaseViewModel { H2OService _h2OService = locator(); - List userProgressForWeekDataSeries; - List userProgressForMonthDataSeries; + // + // List userProgressForWeekDataSeries; + List userProgressForWeekDataSeries; + List userProgressForMonthDataSeries; + + // List userProgressForMonthDataSeries; UserDetailModel get userDetail => _h2OService.userDetailModel; @@ -71,7 +76,8 @@ class H2OViewModel extends BaseViewModel { error = _h2OService.error; setState(ViewState.Error); } else { - userProgressForWeekDataSeries = createUserProgressForWeekDataSeries(); + // userProgressForWeekDataSeries = createUserProgressForWeekDataSeries(); + userProgressForWeekDataSeries = createUserProgressForWeekDataSeriesNew(); setState(ViewState.Idle); } } @@ -83,7 +89,7 @@ class H2OViewModel extends BaseViewModel { error = _h2OService.error; setState(ViewState.Error); } else { - userProgressForMonthDataSeries = createUserProgressForMonthDataSeries(); + userProgressForMonthDataSeries = createUserProgressForMonthDataSeriesNew(); setState(ViewState.Idle); } } @@ -113,6 +119,23 @@ class H2OViewModel extends BaseViewModel { ]; } + List createUserProgressForWeekDataSeriesNew() { + List list = []; + + _h2OService.userProgressForWeekDataList.forEach((UserProgressForWeekDataModel data) { + list.add(new LineChartModel(data.dayName, data.percentageConsumed)); + }); + return list; + } + + List createUserProgressForMonthDataSeriesNew() { + List list = []; + _h2OService.userProgressForMonthDataList.forEach((UserProgressForMonthDataModel data) { + list.add(new LineChartModel(data.monthName, data.percentageConsumed)); + }); + return list; + } + List> createUserProgressForMonthDataSeries() { List globalData = []; _h2OService.userProgressForMonthDataList.forEach((UserProgressForMonthDataModel data) { diff --git a/lib/pages/AlHabibMedicalService/h2o/h2o_page.dart b/lib/pages/AlHabibMedicalService/h2o/h2o_page.dart index 982b9044..69488bfe 100644 --- a/lib/pages/AlHabibMedicalService/h2o/h2o_page.dart +++ b/lib/pages/AlHabibMedicalService/h2o/h2o_page.dart @@ -77,132 +77,70 @@ class _H2OPageState extends State with SingleTickerProviderStateMixin { }, ), ], - body: Scaffold( - // extendBodyBehindAppBar: true, - // appBar: PreferredSize( - // preferredSize: Size.fromHeight(65.0), - // child: Stack( - // children: [ - // Positioned( - // bottom: 1, - // left: 0, - // right: 0, - // child: BackdropFilter( - // filter: ImageFilter.blur(sigmaX: 10, sigmaY: 10), - // child: Container( - // color: Theme.of(context).scaffoldBackgroundColor.withOpacity(0.8), - // height: 70.0, - // ), - // ), - // ), - // Center( - // child: Container( - // height: 60.0, - // alignment: Alignment.center, - // // margin: EdgeInsets.only(top: 10.0), - // // width: MediaQuery.of(context).size.width * 0.9, - // - // child: TabBar( - // isScrollable: false, - // controller: _tabController, - // indicatorWeight: 5.0, - // indicatorSize: TabBarIndicatorSize.tab, - // indicatorColor: Colors.red[800], - // labelColor: Theme.of(context).primaryColor, - // labelPadding: EdgeInsets.only(top: 4.0, left: 10.0, right: 13.0), - // unselectedLabelColor: Colors.grey[800], - // tabs: [ - // Container( - // width: MediaQuery.of(context).size.width * 0.28, - // child: Center( - // child: Texts(TranslationBase.of(context).today), - // ), - // ), - // Container( - // width: MediaQuery.of(context).size.width * 0.28, - // child: Center( - // child: Texts(TranslationBase.of(context).week), - // ), - // ), - // Container( - // width: MediaQuery.of(context).size.width * 0.28, - // child: Center( - // child: Texts(TranslationBase.of(context).month), - // ), - // ), - // ], - // ), - // ), - // ), - // ], - // ), - // ), - // backgroundColor: Colors.white, - body: Column( - children: [ - TabBar( + body: Column( + children: [ + TabBar( + controller: _tabController, + indicatorWeight: 3.0, + indicatorSize: TabBarIndicatorSize.tab, + labelColor: Color(0xff2B353E), + unselectedLabelColor: Color(0xff575757), + labelPadding: EdgeInsets.only(top: 15, bottom: 13, left: 20, right: 20), + labelStyle: TextStyle( + fontFamily: projectViewModel.isArabic ? 'Cairo' : 'Poppins', + fontSize: 16, + fontWeight: FontWeight.w600, + letterSpacing: -0.48, + ), + unselectedLabelStyle: TextStyle( + fontFamily: projectViewModel.isArabic ? 'Cairo' : 'Poppins', + fontSize: 16, + fontWeight: FontWeight.w600, + letterSpacing: -0.48, + ), + tabs: [Text(TranslationBase.of(context).today), Text(TranslationBase.of(context).week), Text(TranslationBase.of(context).month.toLowerCase().capitalizeFirstofEach)], + ), + Expanded( + child: TabBarView( + physics: BouncingScrollPhysics(), controller: _tabController, - indicatorWeight: 3.0, - indicatorSize: TabBarIndicatorSize.tab, - labelColor: Color(0xff2B353E), - unselectedLabelColor: Color(0xff575757), - labelPadding: EdgeInsets.only(top: 15, bottom: 13, left: 20, right: 20), - labelStyle: TextStyle( - fontFamily: projectViewModel.isArabic ? 'Cairo' : 'Poppins', - fontSize: 16, - fontWeight: FontWeight.w600, - letterSpacing: -0.48, - ), - unselectedLabelStyle: TextStyle( - fontFamily: projectViewModel.isArabic ? 'Cairo' : 'Poppins', - fontSize: 16, - fontWeight: FontWeight.w600, - letterSpacing: -0.48, - ), - tabs: [Text(TranslationBase.of(context).today), Text(TranslationBase.of(context).week), Text(TranslationBase.of(context).month.toLowerCase().capitalizeFirstofEach)], + children: [TodayPage(), WeekPage(), MonthPage()], ), - Expanded( - child: TabBarView( - physics: BouncingScrollPhysics(), - controller: _tabController, - children: [TodayPage(), WeekPage(), MonthPage()], - ), - ) - ], - ), - bottomNavigationBar: BottomNavBar( - changeIndex: (index) { - if (index == 0) { - IS_VOICE_COMMAND_CLOSED = false; - } else if (index == 1) { - Navigator.push( - context, - FadePage( - page: AppScaffold( - appBarTitle: TranslationBase.of(context).medicalProfile, - isShowAppBar: true, - showHomeAppBarIcon: false, - appBarIcons: [ - IconButton( - icon: Image.asset("assets/images/new-design/setting_gear_icon.png"), - color: Colors.white, - onPressed: () => Navigator.of(context).pushNamed( - SETTINGS, - ), + ) + ], + ), + bottomNavigationBar: BottomNavBar( + changeIndex: (index) { + if (index == 0) { + IS_VOICE_COMMAND_CLOSED = false; + } else if (index == 1) { + Navigator.push( + context, + FadePage( + page: AppScaffold( + appBarTitle: TranslationBase.of(context).medicalProfile, + isShowAppBar: true, + showHomeAppBarIcon: false, + appBarIcons: [ + IconButton( + icon: Image.asset("assets/images/new-design/setting_gear_icon.png"), + color: Colors.white, + onPressed: () => Navigator.of(context).pushNamed( + SETTINGS, ), - ], - body: MedicalProfilePageNew()))); - } else if (index == 2) { - Navigator.of(context).pushNamedAndRemoveUntil(HOME, (Route route) => false); - } else if (index == 3) { - Navigator.of(context).pushNamed(MY_FAMILIY); - } else if (index == 4) { - Navigator.push(context, FadePage(page: ToDo(isShowAppBar: false))); - } - }, - showHomeIcon: true, - index: 0, - ), + ), + ], + body: MedicalProfilePageNew()))); + } else if (index == 2) { + Navigator.of(context).pushNamedAndRemoveUntil(HOME, (Route route) => false); + } else if (index == 3) { + Navigator.of(context).pushNamed(MY_FAMILIY); + } else if (index == 4) { + Navigator.push(context, FadePage(page: ToDo(isShowAppBar: false))); + } + }, + showHomeIcon: true, + index: 0, ), ), ); diff --git a/lib/pages/AlHabibMedicalService/h2o/month_page.dart b/lib/pages/AlHabibMedicalService/h2o/month_page.dart index 8867fb77..daf91cb9 100644 --- a/lib/pages/AlHabibMedicalService/h2o/month_page.dart +++ b/lib/pages/AlHabibMedicalService/h2o/month_page.dart @@ -6,10 +6,11 @@ import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/widgets/charts/app_bar_chart.dart'; import 'package:diplomaticquarterapp/widgets/errors/app_embedded_error.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; -import 'package:diplomaticquarterapp/widgets/progress_indicator/app_circular_progress_Indeicator.dart'; +import 'package:diplomaticquarterapp/uitl/utils_new.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; +import 'package:diplomaticquarterapp/widgets/charts/custom_line_chart.dart'; class MonthPage extends StatelessWidget { @override @@ -21,37 +22,39 @@ class MonthPage extends StatelessWidget { isShowAppBar: false, appBarTitle: TranslationBase.of(context).h2o, baseViewModel: model, - body: Padding( - padding: EdgeInsets.all(8.0), - child: ListView( - children: [ - Center( - child: Text( - TranslationBase.of(context).waterConsumedInMonth, - textAlign: TextAlign.center, - style: TextStyle(fontSize: 20.0, color: Colors.black87), - ), - ), - SizedBox(height: 16), - Row( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Container( - height: 10, - width: 40, - color: Colors.blue, + body: SingleChildScrollView( + padding: EdgeInsets.all(21), + physics: BouncingScrollPhysics(), + child: (model.userProgressForMonthDataSeries ?? []).isEmpty + ? getNoDataWidget(context) + : Container( + padding: EdgeInsets.fromLTRB(16, 14, 16, 14), + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.all( + Radius.circular(10.0), + ), + boxShadow: [ + BoxShadow( + color: Color(0xff000000).withOpacity(.05), + blurRadius: 27, + offset: Offset(0, -3), + ), + ], ), - SizedBox(width: 8), - Text( - TranslationBase.of(context).waterConsumedInMonth, - style: TextStyle(fontSize: 12.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisSize: MainAxisSize.min, + children: [ + Text( + TranslationBase.of(context).waterConsumedInMonth, + style: TextStyle(fontSize: 16.0, color: Color(0xff2E303A), fontWeight: FontWeight.w600, letterSpacing: -0.64), + ), + SizedBox(height: 24), + CustomLineChart(model.userProgressForMonthDataSeries, projectViewModel.isArabic), + ], ), - ], - ), - // SizedBox(height: 8), - AppBarChart(seriesList: model.userProgressForMonthDataSeries, isArabic: projectViewModel.isArabic), - ], - ), + ), ), ), ); diff --git a/lib/pages/AlHabibMedicalService/h2o/week_page.dart b/lib/pages/AlHabibMedicalService/h2o/week_page.dart index 6f4423b2..83529afd 100644 --- a/lib/pages/AlHabibMedicalService/h2o/week_page.dart +++ b/lib/pages/AlHabibMedicalService/h2o/week_page.dart @@ -1,12 +1,10 @@ -import 'package:diplomaticquarterapp/core/enum/viewstate.dart'; import 'package:diplomaticquarterapp/core/viewModels/AlHabibMedicalService/H2O_view_model.dart'; import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; import 'package:diplomaticquarterapp/pages/base/base_view.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; -import 'package:diplomaticquarterapp/widgets/charts/app_bar_chart.dart'; -import 'package:diplomaticquarterapp/widgets/errors/app_embedded_error.dart'; +import 'package:diplomaticquarterapp/uitl/utils_new.dart'; +import 'package:diplomaticquarterapp/widgets/charts/custom_line_chart.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; -import 'package:diplomaticquarterapp/widgets/progress_indicator/app_circular_progress_Indeicator.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; @@ -21,37 +19,39 @@ class WeekPage extends StatelessWidget { isShowAppBar: false, appBarTitle: TranslationBase.of(context).h2o, baseViewModel: model, - body: Padding( - padding: EdgeInsets.all(8.0), - child: ListView( - children: [ - Center( - child: Text( - TranslationBase.of(context).waterConsumedInWeek, - textAlign: TextAlign.center, - style: TextStyle(fontSize: 20.0, color: Colors.black87), - ), - ), - SizedBox(height: 16), - Row( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Container( - height: 10, - width: 40, - color: Colors.blue, + body: SingleChildScrollView( + padding: EdgeInsets.all(21), + physics: BouncingScrollPhysics(), + child: (model.userProgressForWeekDataSeries ?? []).isEmpty + ? getNoDataWidget(context) + : Container( + padding: EdgeInsets.fromLTRB(16, 14, 16, 14), + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.all( + Radius.circular(10.0), + ), + boxShadow: [ + BoxShadow( + color: Color(0xff000000).withOpacity(.05), + blurRadius: 27, + offset: Offset(0, -3), + ), + ], ), - SizedBox(width: 8), - Text( - TranslationBase.of(context).waterConsumedInWeek, - style: TextStyle(fontSize: 12.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisSize: MainAxisSize.min, + children: [ + Text( + TranslationBase.of(context).waterConsumedInWeek, + style: TextStyle(fontSize: 16.0, color: Color(0xff2E303A), fontWeight: FontWeight.w600, letterSpacing: -0.64), + ), + SizedBox(height: 24), + CustomLineChart(model.userProgressForWeekDataSeries, projectViewModel.isArabic), + ], ), - ], - ), - // SizedBox(height: 8), - AppBarChart(seriesList: model.userProgressForWeekDataSeries,isArabic: projectViewModel.isArabic), - ], - ), + ), ), ), ); diff --git a/lib/pages/medical/vital_sign/vital_sign_item.dart b/lib/pages/medical/vital_sign/vital_sign_item.dart index 37cbbf27..1549db39 100644 --- a/lib/pages/medical/vital_sign/vital_sign_item.dart +++ b/lib/pages/medical/vital_sign/vital_sign_item.dart @@ -42,6 +42,7 @@ class VitalSignItem extends StatelessWidget { maxLines: 1, style: TextStyle( fontSize: 15, + color: Color(0xff2B353E), letterSpacing: -0.45, fontWeight: FontWeight.bold, ), @@ -64,7 +65,7 @@ class VitalSignItem extends StatelessWidget { height: MediaQuery.of(context).size.width / 16, child: SvgPicture.asset( vitalSign.icon, - color: Colors.black, + color: Color(0xff2E303A), ), ), ], diff --git a/lib/widgets/charts/custom_line_chart.dart b/lib/widgets/charts/custom_line_chart.dart new file mode 100644 index 00000000..cfd1e718 --- /dev/null +++ b/lib/widgets/charts/custom_line_chart.dart @@ -0,0 +1,148 @@ +import 'dart:math' as math; + +import 'package:fl_chart/fl_chart.dart'; +import 'package:flutter/material.dart'; + +class LineChartModel { + int value; + String title; + + LineChartModel(this.title, this.value); +} + +class CustomLineChart extends StatefulWidget { + final List list; + final bool isArabic; + CustomLineChart(this.list, this.isArabic); + + @override + _CustomLineChartState createState() => _CustomLineChartState(); +} + +class _CustomLineChartState extends State { + bool showAvg = false; + + final List myList = [ + LineChartModel("", 0), + LineChartModel("", 0), + // LineChartModel("", 0), + ]; + + List list = []; + + @override + void initState() { + super.initState(); + if (widget.list.isEmpty) { + list = myList; + } else { + list = widget.list; + } + } + + @override + Widget build(BuildContext context) { + return Stack( + children: [ + AspectRatio( + aspectRatio: 1.0, + child: LineChart( + mainData(), + ), + ), + SizedBox( + width: 60, + height: 34, + child: TextButton( + onPressed: () { + setState(() { + showAvg = !showAvg; + }); + }, + child: Text( + '', + style: TextStyle(fontSize: 12, color: showAvg ? Colors.white.withOpacity(0.5) : Colors.white), + ), + ), + ), + ], + ); + } + + LineChartData mainData() { + SideTitles right = SideTitles( + showTitles: true, + margin: 0, + reservedSize: 8, + getTitles: (value) { + return ''; + }, + ); + SideTitles left = SideTitles( + showTitles: true, + interval: 1, + getTextStyles: (value) => const TextStyle(color: Color(0xff2E303A), fontWeight: FontWeight.w600, fontSize: 12, letterSpacing: 0), + getTitles: (value) { + if (widget.list.isEmpty) { + return (value).toInt().toString(); + } + return (value * 20).toInt().toString(); + }, + reservedSize: 22, + margin: 12, + ); + return LineChartData( + lineTouchData: LineTouchData(enabled: false), + gridData: FlGridData( + show: true, + drawVerticalLine: false, + getDrawingHorizontalLine: (value) { + return FlLine( + color: const Color(0xffEFEFEF), + strokeWidth: 1, + ); + }, + ), + titlesData: FlTitlesData( + show: true, + topTitles: SideTitles(showTitles: false), + bottomTitles: SideTitles( + showTitles: true, + reservedSize: 22, + interval: 1, + getTextStyles: (value) => const TextStyle(color: Color(0xff2E303A), fontWeight: FontWeight.w600, fontSize: 12, letterSpacing: 0), + getTitles: (value) { + String _title = list[value.toInt()].title; + return (_title.length > 3 ? (widget.isArabic ? _title : _title.substring(0, 3)) : _title).toUpperCase(); + }, + margin: 12, + ), + rightTitles: widget.isArabic ? left : right, + leftTitles: widget.isArabic ? right : left), + borderData: FlBorderData( + show: true, + border: Border.symmetric( + horizontal: BorderSide(color: const Color(0xffEFEFEF), width: 1), + ), + ), + minX: 0, + maxX: widget.list.isEmpty ? 1 : widget.list.length - 1.0, + minY: widget.list.isEmpty ? -1 : 0, + maxY: widget.list.isEmpty ? 1 : 5, + lineBarsData: [ + LineChartBarData( + spots: [ + for (int i = 0; i < list.length; i++) FlSpot(i + 0.0, (list[i].value / 20) + 0.0), + ], + isCurved: true, + preventCurveOverShooting: true, + barWidth: 2, + isStrokeCapRound: true, + dotData: FlDotData( + show: false, + ), + ), + ], + ); + } +} diff --git a/lib/widgets/others/app_scaffold_widget.dart b/lib/widgets/others/app_scaffold_widget.dart index 5d4e3704..a0f95c1d 100644 --- a/lib/widgets/others/app_scaffold_widget.dart +++ b/lib/widgets/others/app_scaffold_widget.dart @@ -28,6 +28,7 @@ class AppScaffold extends StatelessWidget { final String appBarTitle; final Widget body; final Widget bottomSheet; + final Widget bottomNavigationBar; final bool isLoading; final bool isShowAppBar; final bool showNewAppBar; @@ -70,6 +71,7 @@ class AppScaffold extends StatelessWidget { this.showNewAppBarTitle = false, this.hasAppBarParam, this.bottomSheet, + this.bottomNavigationBar, this.baseViewModel, this.floatingActionButton, this.isPharmacy = false, @@ -118,7 +120,7 @@ class AppScaffold extends StatelessWidget { dropDownList: dropDownList ?? [], dropDownIndexChange: dropDownIndexChange, appBarIcons: appBarIcons, - onTap: onTap, + onTap: onTap, ) : (isShowAppBar ? appBar = AppBarWidget( @@ -151,6 +153,7 @@ class AppScaffold extends StatelessWidget { ) : buildBodyWidget(context), ), + bottomNavigationBar: bottomNavigationBar, floatingActionButton: floatingActionButton, ); } @@ -174,8 +177,7 @@ class NewAppBarWidget extends StatelessWidget with PreferredSizeWidget { final List appBarIcons; Function onTap; - NewAppBarWidget( - {Key key, this.showTitle = false, this.showDropDown = false, this.title = "", this.dropDownList, this.appBarIcons, this.dropdownIndexValue, this.dropDownIndexChange, this.onTap}) + NewAppBarWidget({Key key, this.showTitle = false, this.showDropDown = false, this.title = "", this.dropDownList, this.appBarIcons, this.dropdownIndexValue, this.dropDownIndexChange, this.onTap}) : super(key: key); @override