From 6d6c71655a410a9f45b622641a00b04fd2190dd9 Mon Sep 17 00:00:00 2001 From: Mohammad Aljammal Date: Mon, 13 Jul 2020 22:16:01 +0300 Subject: [PATCH] add new widget by Elham Rababah and Mohammad Aljammal --- lib/config/size_config.dart | 4 - lib/main.dart | 2 +- lib/widgets/avatar/large_avatar.dart | 82 +++++++++++++++++++ lib/widgets/charts/app_line_chart.dart | 44 ++++++++++ lib/widgets/charts/app_time_series_chart.dart | 64 +++++++++++++++ .../cards/card_rounded_widget.dart | 46 +++++++++++ .../data_display/list/ListContainer.dart | 15 +++- lib/widgets/errors/app_embedded_error.dart | 24 ++++++ .../others/app_expandable_notifier.dart | 65 +++++++++++++++ lib/widgets/others/app_scaffold_widget.dart | 8 +- 10 files changed, 339 insertions(+), 15 deletions(-) create mode 100644 lib/widgets/avatar/large_avatar.dart create mode 100644 lib/widgets/charts/app_line_chart.dart create mode 100644 lib/widgets/charts/app_time_series_chart.dart create mode 100644 lib/widgets/data_display/cards/card_rounded_widget.dart create mode 100644 lib/widgets/errors/app_embedded_error.dart create mode 100644 lib/widgets/others/app_expandable_notifier.dart diff --git a/lib/config/size_config.dart b/lib/config/size_config.dart index 76f52149..e7e1b41b 100644 --- a/lib/config/size_config.dart +++ b/lib/config/size_config.dart @@ -31,15 +31,11 @@ class SizeConfig { if (realScreenWidth < 450) { isMobilePortrait = true; } - // textMultiplier = _blockHeight; - // imageSizeMultiplier = _blockWidth; screenHeight = realScreenHeight; screenWidth = realScreenWidth; } else { isPortrait = false; isMobilePortrait = false; - // textMultiplier = _blockWidth; - // imageSizeMultiplier = _blockHeight; screenHeight = realScreenWidth; screenWidth = realScreenHeight; } diff --git a/lib/main.dart b/lib/main.dart index ea3bf58b..dff61ac6 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -59,7 +59,7 @@ class MyApp extends StatelessWidget { backgroundColor: Color.fromRGBO(255, 255, 255, 1), highlightColor: Colors.grey[100].withOpacity(0.4), splashColor: Colors.transparent, - primaryColor: Color.fromRGBO(78, 62, 253, 1.0), + primaryColor: Colors.grey, cursorColor: Color.fromRGBO(78, 62, 253, 1.0), iconTheme:IconThemeData( diff --git a/lib/widgets/avatar/large_avatar.dart b/lib/widgets/avatar/large_avatar.dart new file mode 100644 index 00000000..ad3cd277 --- /dev/null +++ b/lib/widgets/avatar/large_avatar.dart @@ -0,0 +1,82 @@ +import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; + +class LargeAvatar extends StatelessWidget { + LargeAvatar( + {Key key, + this.name, + this.url, + this.disableProfileView: false, + this.radius = 60.0, + this.width = 90, + this.height = 90}) + : super(key: key); + + final String name; + final String url; + final bool disableProfileView; + final double radius; + final double width; + final double height; + + Widget _getAvatar() { + if (url != null && url.isNotEmpty && Uri.parse(url).isAbsolute) { + return Center( + child: ClipRRect( + borderRadius: BorderRadius.all(Radius.circular(radius)), + child: Image.network( + url.trim(), + fit: BoxFit.cover, + width: width, + height: height, + ), + ), + ); + } else if (name == null || name.isEmpty) { + return Center( + child: Texts( + 'DR', + color: Colors.white, + )); + } else { + return Center( + child: Texts( + name[0].toUpperCase(), + color: Colors.white, + fontSize: 18, + )); + } + } + + @override + Widget build(BuildContext context) { + return InkWell( + onTap: disableProfileView + ? null + : () { + //TODO when we need that + }, + child: Container( + decoration: BoxDecoration( + gradient: LinearGradient( + begin: Alignment(-1, -1), + end: Alignment(1, 1), + colors: [ + Colors.grey[100], + Colors.grey[800], + ]), + boxShadow: [ + BoxShadow( + color: Color.fromRGBO(0, 0, 0, 0.08), + offset: Offset(0.0, 5.0), + blurRadius: 16.0) + ], + borderRadius: BorderRadius.all(Radius.circular(50.0)), + ), + width: width, + height: height, + child: _getAvatar()), + ); + } +} diff --git a/lib/widgets/charts/app_line_chart.dart b/lib/widgets/charts/app_line_chart.dart new file mode 100644 index 00000000..553afec8 --- /dev/null +++ b/lib/widgets/charts/app_line_chart.dart @@ -0,0 +1,44 @@ +import 'package:flutter/material.dart'; +import 'package:charts_flutter/flutter.dart' as charts; + +/// chart line +/// [seriesList] charts series +/// [chartTitle] the charts title +/// [animate] enable and disable animate on create chart +/// [includeArea] chart include Area +/// [stacked] stacked chart over the design +class AppLineChart extends StatelessWidget { + final List seriesList; + final String chartTitle; + final bool animate; + final bool includeArea; + final bool stacked; + + AppLineChart( + {Key key, + @required this.seriesList, + this.chartTitle, + this.animate = true, + this.includeArea = false, + this.stacked = true}); + + @override + Widget build(BuildContext context) { + return Container( + child: Column( + children: [ + Text( + chartTitle, + style: TextStyle(fontSize: 24.0, fontWeight: FontWeight.bold), + ), + Expanded( + child: charts.LineChart(seriesList, + defaultRenderer: charts.LineRendererConfig( + includeArea: false, stacked: true), + animate: animate), + ), + ], + ), + ); + } +} diff --git a/lib/widgets/charts/app_time_series_chart.dart b/lib/widgets/charts/app_time_series_chart.dart new file mode 100644 index 00000000..9cff8163 --- /dev/null +++ b/lib/widgets/charts/app_time_series_chart.dart @@ -0,0 +1,64 @@ +import 'package:charts_flutter/flutter.dart' as charts; +import 'package:charts_flutter/flutter.dart'; +import 'package:diplomaticquarterapp/config/size_config.dart'; +import 'package:diplomaticquarterapp/widgets/data_display/list/ListContainer.dart'; +import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; +import 'package:flutter/material.dart'; + +/// App Time Series Chart +/// [seriesList] the series list +/// [chartName] the name of the chart +/// [startDate] the start date +/// [endDate] the end date +class AppTimeSeriesChart extends StatelessWidget { + AppTimeSeriesChart({ + Key key, + @required this.seriesList, + this.chartName = '', + this.startDate, + this.endDate, + }); + + final String chartName; + final List> seriesList; + final DateTime startDate; + final DateTime endDate; + + @override + Widget build(BuildContext context) { + return ListContainer( + heightFactor: 0.47, + child: Column( + children: [ + Texts(chartName, fontSize: SizeConfig.textMultiplier * 3), + Container( + height: SizeConfig.realScreenHeight * 0.37, + child: Center( + child: Container( + child: charts.TimeSeriesChart( + seriesList, + animate: true, + behaviors: [ + charts.RangeAnnotation( + [ + charts.RangeAnnotationSegment(startDate, endDate, + charts.RangeAnnotationAxisType.domain), + ], + ), + ], + ), + ), + ), + ), + ], + ), + ); + } +} + +class TimeSeriesSales { + final DateTime time; + final int sales; + + TimeSeriesSales(this.time, this.sales); +} diff --git a/lib/widgets/data_display/cards/card_rounded_widget.dart b/lib/widgets/data_display/cards/card_rounded_widget.dart new file mode 100644 index 00000000..e490b7b8 --- /dev/null +++ b/lib/widgets/data_display/cards/card_rounded_widget.dart @@ -0,0 +1,46 @@ +import 'package:flutter/material.dart'; + +/// [child] A widget that centers its child within itself. +/// [padding] The amount of space by which to inset the child. +/// [color] By default, the color is derived from the [type] of material. +/// [radius] radius value +class CardRoundedWidget extends StatelessWidget { + final Widget child; + final double padding; + final Color color; + final double radius; + + CardRoundedWidget( + {@required this.child, + this.color = Colors.white, + this.radius = 10.0, + this.padding = 10.0}); + + @override + Widget build(BuildContext context) { + return Container( + margin: EdgeInsets.symmetric(vertical: 10.0), + width: double.infinity, + decoration: BoxDecoration( + borderRadius: BorderRadius.all( + Radius.circular(radius), + ), + ), + child: Material( + borderRadius: BorderRadius.all(Radius.circular(radius)), + color: color, + child: Stack( + children: [ + Center( + child: Container( + child: Padding( + padding: EdgeInsets.all(padding), + child: Center(child: child), + )), + ) + ], + ), + ), + ); + } +} diff --git a/lib/widgets/data_display/list/ListContainer.dart b/lib/widgets/data_display/list/ListContainer.dart index 8a3bd47d..f622ede7 100644 --- a/lib/widgets/data_display/list/ListContainer.dart +++ b/lib/widgets/data_display/list/ListContainer.dart @@ -1,17 +1,24 @@ import 'package:flutter/material.dart'; class ListContainer extends StatelessWidget { - final double size; + final double widthFactor; + final double heightFactor; final EdgeInsets padding; final Widget child; - ListContainer({Key key, this.size, this.padding, this.child}) - : super(key: key); + ListContainer({ + Key key, + this.widthFactor = 0.9, + this.heightFactor = 1, + this.padding, + this.child, + }) : super(key: key); @override Widget build(BuildContext context) { return FractionallySizedBox( - widthFactor: size ?? 0.9, + widthFactor: widthFactor, + heightFactor: heightFactor, child: ClipRRect( borderRadius: BorderRadius.circular(8.0), child: Material( diff --git a/lib/widgets/errors/app_embedded_error.dart b/lib/widgets/errors/app_embedded_error.dart new file mode 100644 index 00000000..a4c956ca --- /dev/null +++ b/lib/widgets/errors/app_embedded_error.dart @@ -0,0 +1,24 @@ +import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; +import 'package:flutter/material.dart'; + +///show App Embedded Error +/// [error] the message we show to the user +class AppEmbeddedError extends StatelessWidget { + const AppEmbeddedError({ + Key key, + @required this.error, + }) : super(key: key); + + final String error; + + @override + Widget build(BuildContext context) { + return Center( + child: Texts( + error, + color: Theme.of(context).errorColor, + textAlign: TextAlign.center, + ), + ); + } +} diff --git a/lib/widgets/others/app_expandable_notifier.dart b/lib/widgets/others/app_expandable_notifier.dart new file mode 100644 index 00000000..fca61f1f --- /dev/null +++ b/lib/widgets/others/app_expandable_notifier.dart @@ -0,0 +1,65 @@ +import 'package:expandable/expandable.dart'; +import 'package:flutter/material.dart'; + +/// App Expandable Notifier with animation +/// [headerWidget] widget want to show in the header +/// [bodyWidget] widget want to show in the body +/// [title] the widget title +/// [collapsed] The widget shown in the collapsed state +class AppExpandableNotifier extends StatelessWidget { + final Widget headerWidget; + final Widget bodyWidget; + final String title; + final Widget collapsed; + + AppExpandableNotifier( + {this.headerWidget, this.bodyWidget, this.title, this.collapsed}); + + @override + Widget build(BuildContext context) { + return ExpandableNotifier( + child: Padding( + padding: const EdgeInsets.all(10), + child: Card( + clipBehavior: Clip.antiAlias, + child: Column( + children: [ + SizedBox( + child: headerWidget, + ), + ScrollOnExpand( + scrollOnExpand: true, + scrollOnCollapse: false, + child: ExpandablePanel( + theme: const ExpandableThemeData( + headerAlignment: ExpandablePanelHeaderAlignment.center, + tapBodyToCollapse: true, + ), + header: Padding( + padding: EdgeInsets.all(10), + child: Text( + title, + style: TextStyle(fontWeight: FontWeight.bold), + ), + ), + collapsed: collapsed, + expanded: bodyWidget, + builder: (_, collapsed, expanded) { + return Padding( + padding: EdgeInsets.only(left: 10, right: 10, bottom: 10), + child: Expandable( + collapsed: collapsed, + expanded: expanded, + theme: const ExpandableThemeData(crossFadePoint: 0), + ), + ); + }, + ), + ), + ], + ), + ), + ), + ); + } +} diff --git a/lib/widgets/others/app_scaffold_widget.dart b/lib/widgets/others/app_scaffold_widget.dart index 8954e409..27c0a826 100644 --- a/lib/widgets/others/app_scaffold_widget.dart +++ b/lib/widgets/others/app_scaffold_widget.dart @@ -1,10 +1,10 @@ import 'package:diplomaticquarterapp/config/config.dart'; import 'package:diplomaticquarterapp/providers/project_provider.dart'; import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; +import 'arrow_back.dart'; import 'file:///D:/Mohammad/diplomatic_quarter_app/lib/widgets/progress_indicator/app_loader_widget.dart'; import 'package:flutter/material.dart'; import 'package:font_awesome_flutter/font_awesome_flutter.dart'; -import 'package:hexcolor/hexcolor.dart'; import 'package:provider/provider.dart'; class AppScaffold extends StatelessWidget { @@ -36,11 +36,7 @@ class AppScaffold extends StatelessWidget { title: Text(appBarTitle.toUpperCase()), leading: Builder( builder: (BuildContext context) { - return IconButton( - icon: Icon(Icons.arrow_back_ios), - color: Colors.white, - onPressed: () => Navigator.pop(context), - ); + return ArrowBack(); }, ), centerTitle: true,