diff --git a/assets/images/Icon-awesome-calendar.png b/assets/images/Icon-awesome-calendar.png new file mode 100644 index 00000000..f058ca77 Binary files /dev/null and b/assets/images/Icon-awesome-calendar.png differ diff --git a/assets/images/medical/doctor_icon.png b/assets/images/medical/doctor_icon.png new file mode 100644 index 00000000..02b3b9fa Binary files /dev/null and b/assets/images/medical/doctor_icon.png differ diff --git a/assets/images/medical/insurance_approvals_icon.png b/assets/images/medical/insurance_approvals_icon.png new file mode 100644 index 00000000..11a00256 Binary files /dev/null and b/assets/images/medical/insurance_approvals_icon.png differ diff --git a/assets/images/medical/insurance_card_icon.png b/assets/images/medical/insurance_card_icon.png new file mode 100644 index 00000000..6fa5b5bf Binary files /dev/null and b/assets/images/medical/insurance_card_icon.png differ diff --git a/assets/images/medical/lab_result_icon.png b/assets/images/medical/lab_result_icon.png new file mode 100644 index 00000000..c9425278 Binary files /dev/null and b/assets/images/medical/lab_result_icon.png differ diff --git a/assets/images/medical/medical_history_icon.png b/assets/images/medical/medical_history_icon.png new file mode 100644 index 00000000..9a820f12 Binary files /dev/null and b/assets/images/medical/medical_history_icon.png differ diff --git a/assets/images/medical/prescription_icon.png b/assets/images/medical/prescription_icon.png new file mode 100644 index 00000000..1d40e95d Binary files /dev/null and b/assets/images/medical/prescription_icon.png differ diff --git a/assets/images/medical/radiology_icon.png b/assets/images/medical/radiology_icon.png new file mode 100644 index 00000000..9e760d65 Binary files /dev/null and b/assets/images/medical/radiology_icon.png differ diff --git a/ios/Flutter/Debug.xcconfig b/ios/Flutter/Debug.xcconfig index 592ceee8..e8efba11 100644 --- a/ios/Flutter/Debug.xcconfig +++ b/ios/Flutter/Debug.xcconfig @@ -1 +1,2 @@ +#include "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig" #include "Generated.xcconfig" diff --git a/ios/Flutter/Release.xcconfig b/ios/Flutter/Release.xcconfig index 592ceee8..399e9340 100644 --- a/ios/Flutter/Release.xcconfig +++ b/ios/Flutter/Release.xcconfig @@ -1 +1,2 @@ +#include "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig" #include "Generated.xcconfig" diff --git a/lib/main.dart b/lib/main.dart index 2eb5dd26..186ec52f 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -53,6 +53,7 @@ class MyApp extends StatelessWidget { hintColor: Colors.grey[400], disabledColor: Colors.grey[300], errorColor: Color.fromRGBO(235, 80, 60, 1.0), + scaffoldBackgroundColor: Colors.grey[100], textSelectionColor: Color.fromRGBO(80, 100, 253, 0.5), textSelectionHandleColor: Color.fromRGBO(80, 100, 253, 1.0), canvasColor: Colors.white, @@ -63,7 +64,7 @@ class MyApp extends StatelessWidget { cursorColor: Color.fromRGBO(78, 62, 253, 1.0), iconTheme: IconThemeData(), appBarTheme: AppBarTheme( - color: Colors.grey, + color: Colors.grey[700], brightness: Brightness.light, elevation: 0.0, actionsIconTheme: IconThemeData( diff --git a/lib/pages/landing/landing_page.dart b/lib/pages/landing/landing_page.dart index ec9e1524..b92804a5 100644 --- a/lib/pages/landing/landing_page.dart +++ b/lib/pages/landing/landing_page.dart @@ -1,4 +1,6 @@ import 'package:diplomaticquarterapp/pages/landing/replay_page.dart'; +import 'package:diplomaticquarterapp/pages/medical/medical_page.dart'; +import 'package:diplomaticquarterapp/pages/medical/my_admissions_page.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/widgets/bottom_navigation/bottom_nav_bar.dart'; import 'package:diplomaticquarterapp/widgets/drawer/app_drawer_widget.dart'; @@ -55,7 +57,7 @@ class _LandingPageState extends State { body: PageView( physics: NeverScrollableScrollPhysics(), controller: pageController, - children: [HomePage(), ReplayPage(), Container(), Container()], + children: [HomePage(), ReplayPage(), MedicalPage(), MyAdmissionsPage()], ), bottomNavigationBar: BottomNavBar(changeIndex: _changeCurrentTab), ); diff --git a/lib/pages/medical/medical_page.dart b/lib/pages/medical/medical_page.dart new file mode 100644 index 00000000..049ba0bc --- /dev/null +++ b/lib/pages/medical/medical_page.dart @@ -0,0 +1,132 @@ +import 'dart:math'; + +import 'package:diplomaticquarterapp/widgets/data_display/medical/medical_profile_item.dart'; +import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; +import 'package:diplomaticquarterapp/widgets/others/sliver_app_bar_delegate.dart'; +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; + +class MedicalPage extends StatefulWidget { + @override + _MedicalPageState createState() => _MedicalPageState(); + +} + +class _MedicalPageState extends State { + @override + Widget build(BuildContext context) { + return AppScaffold( + body: CustomScrollView( + physics: BouncingScrollPhysics(), + key: PageStorageKey("medical"), + slivers: [ + SliverPersistentHeader( + delegate: SliverAppBarDelegate( + maxHeight: 200.0, + minHeight: 200.0, + child: Container( + width: double.infinity, + height: 200, + color: Colors.grey, + ), + ), + ), + SliverPersistentHeader( + delegate: SliverAppBarDelegate( + maxHeight: double.maxFinite, + minHeight: double.maxFinite, + child: Padding( + padding: EdgeInsets.symmetric(vertical: 12.0), + child: Column( + children: [ + + Row( + children: [ + Expanded( + flex: 1, + child: MedicalProfileItem( + title: 'My Doctor', + imagePath: 'doctor_icon.png', + subTitle: 'List', + ), + ), + Expanded( + flex: 1, + child: MedicalProfileItem( + title: 'Lab', + imagePath: 'lab_result_icon.png', + subTitle: 'Result', + ), + ) + ], + ), + Row( + children: [ + Expanded( + flex: 1, + child: MedicalProfileItem( + title: 'Radiology', + imagePath: 'radiology_icon.png', + subTitle: 'Service', + ), + ), + Expanded( + flex: 1, + child: MedicalProfileItem( + title: 'Medicines', + imagePath: 'prescription_icon.png', + subTitle: 'Prescriptions', + ), + ) + ], + ), + Row( + children: [ + Expanded( + flex: 1, + child: MedicalProfileItem( + title: 'Insurance', + imagePath: 'insurance_card_icon.png', + subTitle: 'Card', + ), + ), + Expanded( + flex: 1, + child: MedicalProfileItem( + title: 'Insurance', + imagePath: 'insurance_approvals_icon.png', + subTitle: 'Approvals', + ), + ) + ], + ), + Row( + children: [ + Expanded( + flex: 1, + child: MedicalProfileItem( + title: 'Medical', + imagePath: 'medical_history_icon.png', + subTitle: 'Reports', + ), + ), + Expanded( + flex: 1, + child: Container(), + ) + + ], + ), + ], + ), + ), + ), + ), + ], + + ), + ); + } +} + + diff --git a/lib/pages/medical/my_admissions_page.dart b/lib/pages/medical/my_admissions_page.dart new file mode 100644 index 00000000..ff25884e --- /dev/null +++ b/lib/pages/medical/my_admissions_page.dart @@ -0,0 +1,61 @@ +import 'package:diplomaticquarterapp/widgets/data_display/medical/doctor_card.dart'; +import 'package:diplomaticquarterapp/widgets/others/app_expandable_notifier.dart'; +import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; +import 'package:flutter/cupertino.dart'; + +class MyAdmissionsPage extends StatefulWidget { + @override + _MyAdmissionsPageState createState() => _MyAdmissionsPageState(); +} + +class _MyAdmissionsPageState extends State { + @override + Widget build(BuildContext context) { + return AppScaffold( + body: ListView( + children: [ + AppExpandableNotifier( + title: 'Arryan Hospital', + bodyWidget: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + DoctorCard( + name: 'Dr Mohammad Aljammal', + date: 'Feb 14, 2020', + profileUrl: + 'https://scontent.famm4-1.fna.fbcdn.net/v/t31.0-8/30425660_1862582094040824_7851633779570222226_o.jpg?_nc_cat=101&_nc_sid=09cbfe&_nc_eui2=AeF3TI6D2_tFS5QoQsqyaCKd2zBfzh74hOzbMF_OHviE7PQdLHRwmBoIOiKyWmK9MskOshPjkU73a5EdQMA3dqnV&_nc_ohc=1feou2fDCuIAX_Ra9qB&_nc_ht=scontent.famm4-1.fna&oh=709d34d1c284de1d0aa08ed37b0ac09a&oe=5F3C5ACB', + rat: 3.8, + subName: 'Jammal', + ), + DoctorCard( + name: 'Dr Mohammad Aljammal', + date: 'Feb 14, 2020', + profileUrl: + 'https://scontent.famm4-1.fna.fbcdn.net/v/t31.0-8/30425660_1862582094040824_7851633779570222226_o.jpg?_nc_cat=101&_nc_sid=09cbfe&_nc_eui2=AeF3TI6D2_tFS5QoQsqyaCKd2zBfzh74hOzbMF_OHviE7PQdLHRwmBoIOiKyWmK9MskOshPjkU73a5EdQMA3dqnV&_nc_ohc=1feou2fDCuIAX_Ra9qB&_nc_ht=scontent.famm4-1.fna&oh=709d34d1c284de1d0aa08ed37b0ac09a&oe=5F3C5ACB', + rat: 3.8, + subName: 'Jammal', + ), + ], + ), + ), + + AppExpandableNotifier( + title: 'Arryan Hospital', + bodyWidget: DoctorCard( + onTap: () { + //TODO when we need it + }, + name: 'Dr Mohammad Aljammal', + date: 'Feb 14, 2020', + profileUrl: + 'https://scontent.famm4-1.fna.fbcdn.net/v/t31.0-8/30425660_1862582094040824_7851633779570222226_o.jpg?_nc_cat=101&_nc_sid=09cbfe&_nc_eui2=AeF3TI6D2_tFS5QoQsqyaCKd2zBfzh74hOzbMF_OHviE7PQdLHRwmBoIOiKyWmK9MskOshPjkU73a5EdQMA3dqnV&_nc_ohc=1feou2fDCuIAX_Ra9qB&_nc_ht=scontent.famm4-1.fna&oh=709d34d1c284de1d0aa08ed37b0ac09a&oe=5F3C5ACB', + rat: 4.8, + subName: 'Jammal', + ), + ), + + ], + ), + ); + } +} diff --git a/lib/widgets/avatar/large_avatar.dart b/lib/widgets/avatar/large_avatar.dart index cd6ee539..ed904d03 100644 --- a/lib/widgets/avatar/large_avatar.dart +++ b/lib/widgets/avatar/large_avatar.dart @@ -16,9 +16,9 @@ class LargeAvatar extends StatelessWidget { @required this.name, this.url, this.disableProfileView: false, - this.radius = 60.0, - this.width = 90, - this.height = 90, + this.radius = 70.0, + this.width = 70, + this.height = 60, this.onTap}) : super(key: key); @@ -71,7 +71,7 @@ class LargeAvatar extends StatelessWidget { offset: Offset(0.0, 5.0), blurRadius: 16.0) ], - borderRadius: BorderRadius.all(Radius.circular(50.0)), + borderRadius: BorderRadius.all(Radius.circular(radius)), ), width: width, height: height, diff --git a/lib/widgets/data_display/medical/doctor_card.dart b/lib/widgets/data_display/medical/doctor_card.dart new file mode 100644 index 00000000..e9a94895 --- /dev/null +++ b/lib/widgets/data_display/medical/doctor_card.dart @@ -0,0 +1,99 @@ +import 'package:diplomaticquarterapp/widgets/avatar/large_avatar.dart'; +import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; +import 'package:diplomaticquarterapp/widgets/others/StarRating.dart'; +import 'package:diplomaticquarterapp/widgets/others/rounded_container_widget.dart'; +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import 'package:font_awesome_flutter/font_awesome_flutter.dart'; + +class DoctorCard extends StatelessWidget { + final String name; + final String subName; + final double rat; + final String date; + final String profileUrl; + final Function onTap; + + DoctorCard( + {this.name, + this.subName, + this.rat, + this.date, + this.profileUrl, + this.onTap}); + + @override + Widget build(BuildContext context) { + return RoundedContainer( + child: InkWell( + onTap: onTap, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Padding( + padding: const EdgeInsets.all(8.0), + child: Row( + children: [ + Expanded( + flex: 1, + child: LargeAvatar( + name: name, + url: profileUrl, + ), + ), + Expanded( + flex: 4, + child: Container( + margin: EdgeInsets.all(10), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Texts( + name, + bold: true, + ), + Texts( + subName, + variant: 'bodyText', + ), + StarRating(totalAverage: rat, forceStars: true), + ], + ), + ), + ), + ], + ), + ), + + Divider( + height: 8, + color: Colors.grey[400], + ), + Padding( + padding: const EdgeInsets.all(5.0), + child: Row( + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + SizedBox( + width: 10, + ), + Image.asset( + 'assets/images/Icon-awesome-calendar.png', + width: 30, + height: 30, + ), + Expanded( + child: Texts( + date, + variant: 'bodyText', + ), + ) + ], + ), + ) + ], + ), + ), + ); + } +} diff --git a/lib/widgets/data_display/medical/medical_profile_item.dart b/lib/widgets/data_display/medical/medical_profile_item.dart new file mode 100644 index 00000000..6357d830 --- /dev/null +++ b/lib/widgets/data_display/medical/medical_profile_item.dart @@ -0,0 +1,53 @@ +import 'package:diplomaticquarterapp/config/size_config.dart'; +import 'package:diplomaticquarterapp/widgets/others/rounded_container_widget.dart'; +import 'package:flutter/material.dart'; +import 'package:hexcolor/hexcolor.dart'; + +class MedicalProfileItem extends StatelessWidget { + MedicalProfileItem({ + @required this.imagePath, + @required this.title, + @required this.subTitle, + }); + + final String imagePath; + final String title; + final String subTitle; + + @override + Widget build(BuildContext context) { + return RoundedContainer( + child: Container( + padding: EdgeInsets.all(5), + child: Column( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + title, + style: TextStyle( + fontSize: 1.7 * SizeConfig.textMultiplier, + color: Hexcolor('#B8382C'), + fontWeight: FontWeight.bold), + ), + RichText( + text: TextSpan( + style: TextStyle(color: Colors.black), + children: [ + TextSpan(text: subTitle), + ], + ), + ), + Align( + alignment: Alignment.bottomRight, + child: Image.asset( + "assets/images/medical/$imagePath", + height: SizeConfig.heightMultiplier * 7, + ), + ) + ], + ), + ), + ); + } +} diff --git a/lib/widgets/others/StarRating.dart b/lib/widgets/others/StarRating.dart new file mode 100644 index 00000000..f33ced32 --- /dev/null +++ b/lib/widgets/others/StarRating.dart @@ -0,0 +1,39 @@ +import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; +import 'package:eva_icons_flutter/eva_icons_flutter.dart'; +import 'package:flutter/material.dart'; + +class StarRating extends StatelessWidget { + + final double totalAverage; + final double size; + final int totalCount; + final bool forceStars; + + StarRating({Key key, this.totalAverage: 0.0, this.size: 16.0, this.totalCount, this.forceStars = false}) : super(key: key); + + @override + Widget build(BuildContext context) { + return Row( + mainAxisAlignment: MainAxisAlignment.start, + children: [ + if (!forceStars && (totalAverage==null || totalAverage==0)) + Texts("New", style: "caption"), + if (forceStars || (totalAverage!=null && totalAverage>0)) + ...List.generate(5, (index) => + Padding( + padding: EdgeInsets.only(right: 1.0), + child: Icon( + (index+1) <= (totalAverage ?? 0) ? EvaIcons.star : EvaIcons.starOutline, + size: size, + color: (index+1) <= (totalAverage ?? 0) ? Color.fromRGBO(255, 186, 0, 1.0) : Theme.of(context).hintColor + ), + ) + ), + if (totalCount!=null) + SizedBox(width: 9.0), + if (totalCount!=null) + Texts("("+totalCount.toString()+")", style: "overline", color: Colors.grey[400],) + ] + ); + } +} \ No newline at end of file diff --git a/lib/widgets/others/app_expandable_notifier.dart b/lib/widgets/others/app_expandable_notifier.dart index fca61f1f..0e2a3c4b 100644 --- a/lib/widgets/others/app_expandable_notifier.dart +++ b/lib/widgets/others/app_expandable_notifier.dart @@ -19,7 +19,7 @@ class AppExpandableNotifier extends StatelessWidget { Widget build(BuildContext context) { return ExpandableNotifier( child: Padding( - padding: const EdgeInsets.all(10), + padding: const EdgeInsets.only(left: 10,right: 10,top: 4), child: Card( clipBehavior: Clip.antiAlias, child: Column( @@ -39,14 +39,14 @@ class AppExpandableNotifier extends StatelessWidget { padding: EdgeInsets.all(10), child: Text( title, - style: TextStyle(fontWeight: FontWeight.bold), + style: TextStyle(fontWeight: FontWeight.bold,fontSize: 22,), ), ), - collapsed: collapsed, + collapsed: collapsed ?? Container(), expanded: bodyWidget, builder: (_, collapsed, expanded) { return Padding( - padding: EdgeInsets.only(left: 10, right: 10, bottom: 10), + padding: EdgeInsets.only(left: 5, right: 5, bottom: 5), child: Expandable( collapsed: collapsed, expanded: expanded, diff --git a/lib/widgets/others/card_with_bg_widget.dart b/lib/widgets/others/card_with_bg_widget.dart new file mode 100644 index 00000000..1b96008a --- /dev/null +++ b/lib/widgets/others/card_with_bg_widget.dart @@ -0,0 +1,71 @@ +import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; +import 'package:flutter/material.dart'; +import 'package:hexcolor/hexcolor.dart'; +import 'package:provider/provider.dart'; + +/* + *@author: Mohammad Aljammal + *@Date:27/4/2020 + *@param: Widget + *@return: + *@desc: Card With Bg Widget + */ + +class CardWithBgWidget extends StatelessWidget { + final Widget child; + + CardWithBgWidget({@required this.child}); + + @override + Widget build(BuildContext context) { + ProjectViewModel projectProvider = Provider.of(context); + return Container( + margin: EdgeInsets.symmetric(vertical: 10.0), + width: double.infinity, + decoration: BoxDecoration( + borderRadius: BorderRadius.all( + Radius.circular(10.0), + ), + border: Border.all(color: Colors.grey, width: 1.0), + ), + child: Material( + borderRadius: BorderRadius.all(Radius.circular(10.0)), + child: Stack( + children: [ + if (projectProvider.isArabic) + Positioned( + child: Container( + width: 10, + color: Hexcolor('#58434F'), + ), + bottom: 0, + top: 0, + right: 0, + ) + else + Positioned( + child: Container( + decoration: BoxDecoration( + borderRadius: BorderRadius.only( + topLeft: Radius.circular(9.0), + bottomLeft: Radius.circular(9.0), + ),color: Colors.blueAccent, + + ), + width: 15, + + ), + bottom: 0, + top: 0, + left: 0, + ), + Container( + padding: EdgeInsets.all(15.0), + margin: EdgeInsets.only(left: 10), + child: child) + ], + ), + ), + ); + } +} diff --git a/lib/widgets/others/rounded_container_widget.dart b/lib/widgets/others/rounded_container_widget.dart new file mode 100644 index 00000000..58d9a034 --- /dev/null +++ b/lib/widgets/others/rounded_container_widget.dart @@ -0,0 +1,86 @@ +import 'package:flutter/material.dart'; + +/// DESCRIPTION : Custom widget for rounded container and custom decoration + +class RoundedContainer extends StatefulWidget { + final double width; + final double height; + final double raduis; + final Color backgroundColor; + final double margin; + final double elevation; + final bool showBorder; + final Color borderColor; + final bool customCornerRaduis; + final double topLeft; + final double bottomRight; + final double topRight; + final double bottomLeft; + final Widget child; + final double borderWidth; + + RoundedContainer( + {@required this.child, + this.width, + this.height, + this.raduis = 10, + this.backgroundColor = Colors.white, + this.margin = 10, + this.elevation = 1, + this.showBorder = false, + this.borderColor = Colors.grey, + this.customCornerRaduis = false, + this.topLeft = 0, + this.topRight = 0, + this.bottomRight = 0, + this.bottomLeft = 0, + this.borderWidth = 1}); + + @override + _RoundedContainerState createState() => _RoundedContainerState(); +} + +class _RoundedContainerState extends State { + @override + Widget build(BuildContext context) { + return Container( + width: widget.width, + height: widget.height, + margin: EdgeInsets.all(widget.margin), + decoration: widget.showBorder == true + ? BoxDecoration( + color: Theme.of(context).primaryColor, + border: Border.all( + color: widget.borderColor, width: widget.borderWidth), + borderRadius: widget.customCornerRaduis + ? BorderRadius.only( + topLeft: Radius.circular(widget.topLeft), + topRight: Radius.circular(widget.topRight), + bottomRight: Radius.circular(widget.bottomRight), + bottomLeft: Radius.circular(widget.bottomLeft)) + : BorderRadius.circular(widget.raduis), + boxShadow: [ + BoxShadow( + color: Colors.grey.withOpacity(0.1), + spreadRadius: 10, + blurRadius: 5, + offset: Offset(0, 5), // changes position of shadow + ), + ]) + : null, + child: Card( + margin: EdgeInsets.all(0), + shape: RoundedRectangleBorder( + borderRadius: widget.customCornerRaduis + ? BorderRadius.only( + topLeft: Radius.circular(widget.topLeft), + topRight: Radius.circular(widget.topRight), + bottomRight: Radius.circular(widget.bottomRight), + bottomLeft: Radius.circular(widget.bottomLeft)) + : BorderRadius.circular(widget.raduis), + ), + color: widget.backgroundColor, + child: widget.child, + )); + } +} diff --git a/lib/widgets/others/sliver_app_bar_delegate.dart b/lib/widgets/others/sliver_app_bar_delegate.dart new file mode 100644 index 00000000..49c9b4fd --- /dev/null +++ b/lib/widgets/others/sliver_app_bar_delegate.dart @@ -0,0 +1,34 @@ +import 'dart:math'; + +import 'package:flutter/cupertino.dart'; + +class SliverAppBarDelegate extends SliverPersistentHeaderDelegate { + SliverAppBarDelegate({ + @required this.minHeight, + @required this.maxHeight, + @required this.child, + }); + + final double minHeight; + final double maxHeight; + final Widget child; + + @override + double get minExtent => minHeight; + + @override + double get maxExtent => max(maxHeight, minHeight); + + @override + Widget build( + BuildContext context, + double shrinkOffset, + bool overlapsContent) + { + return new SizedBox.expand(child: child); + } + @override + bool shouldRebuild(SliverAppBarDelegate oldDelegate) { + return false; + } +} \ No newline at end of file diff --git a/pubspec.yaml b/pubspec.yaml index 4bb76eaa..426404b8 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -84,6 +84,7 @@ flutter: # assets: assets: - assets/images/ + - assets/images/medical/ fonts: - family: WorkSans