From 8fac62bcb103201c1e4bb79c7bef59d65a04df9e Mon Sep 17 00:00:00 2001 From: Elham Rababh Date: Thu, 7 Oct 2021 14:42:01 +0300 Subject: [PATCH 1/2] fix bottom sheet functions --- .../product_detail_view_model.dart | 4 +- .../product-details/footor/footer-widget.dart | 80 ++++++++++--------- .../product-details/product-detail.dart | 22 ++--- .../shared/product_details_app_bar.dart | 7 +- lib/widgets/buttons/secondary_button.dart | 14 ++-- 5 files changed, 70 insertions(+), 57 deletions(-) diff --git a/lib/core/viewModels/pharmacyModule/product_detail_view_model.dart b/lib/core/viewModels/pharmacyModule/product_detail_view_model.dart index 968fe029..014ba7fb 100644 --- a/lib/core/viewModels/pharmacyModule/product_detail_view_model.dart +++ b/lib/core/viewModels/pharmacyModule/product_detail_view_model.dart @@ -49,7 +49,7 @@ class ProductDetailViewModel extends BaseViewModel{ Future notifyMe(customerId, itemID) async { hasError = false; - setState(ViewState.Busy); + setState(ViewState.BusyLocal); await _productDetailService.notifyMe(customerId, itemID); if (_productDetailService.hasError) { error = _productDetailService.error; @@ -60,7 +60,7 @@ class ProductDetailViewModel extends BaseViewModel{ Future addToCartData(quantity, itemID) async { hasError = false; - setState(ViewState.Busy); + setState(ViewState.BusyLocal); await _productDetailService.addToCart(quantity, itemID); if (_productDetailService.hasError) { error = _productDetailService.error; diff --git a/lib/pages/pharmacies/screens/product-details/footor/footer-widget.dart b/lib/pages/pharmacies/screens/product-details/footor/footer-widget.dart index 854f5d4c..583c904f 100644 --- a/lib/pages/pharmacies/screens/product-details/footor/footer-widget.dart +++ b/lib/pages/pharmacies/screens/product-details/footor/footer-widget.dart @@ -1,5 +1,6 @@ import 'package:diplomaticquarterapp/core/model/pharmacies/PharmacyProduct.dart'; import 'package:diplomaticquarterapp/core/service/AuthenticatedUserObject.dart'; +import 'package:diplomaticquarterapp/core/viewModels/pharmacyModule/product_detail_view_model.dart'; import 'package:diplomaticquarterapp/pages/pharmacies/screens/product-details/footor/quantity_box.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/widgets/buttons/secondary_button.dart'; @@ -10,6 +11,7 @@ import 'package:hexcolor/hexcolor.dart'; import '../../../../../locator.dart'; import '../../../../../routes.dart'; import '../../cart-order-page.dart'; +import '../product-detail.dart'; class FooterWidget extends StatefulWidget { final bool isAvailable; @@ -18,13 +20,17 @@ class FooterWidget extends StatefulWidget { final int quantityLimit; final PharmacyProduct item; final Function addToCartFunction; + final ProductDetailViewModel model; int quantity; bool isOverQuantity; FooterWidget(this.isAvailable, this.maxQuantity, this.minQuantity, this.quantityLimit, this.item, - {this.quantity, this.isOverQuantity = false, this.addToCartFunction}); + {this.quantity, + this.isOverQuantity = false, + this.addToCartFunction, + this.model}); @override _FooterWidgetState createState() => _FooterWidgetState(); @@ -98,38 +104,31 @@ class _FooterWidgetState extends State { label: i, onTapFunc: onChangeValue, isSelected: widget.quantity == i), - Column( - children: [ - Container( - width: 100, - decoration: BoxDecoration( - border: - Border.all(color: Colors.grey[300]), - color: Colors.white, - ), - child: TextField( - decoration: InputDecoration( - labelText: 'quantity #'), - onChanged: (text) { - print(widget.quantity); - print(widget.quantityLimit); - if (int.tryParse(text) == null) { - text = ''; + Container( + width: 100, + decoration: BoxDecoration( + border: Border.all(color: Colors.grey[300]), + color: Colors.white, + ), + child: TextField( + decoration: InputDecoration( + labelText: ' Quantity # '), + onChanged: (text) { + if (int.tryParse(text) == null) { + text = ''; + } else { + setState(() { + widget.quantity = int.parse(text); + if (widget.quantity >= + widget.quantityLimit) { + widget.isOverQuantity = true; } else { - setState(() { - widget.quantity = int.parse(text); - if (widget.quantity >= - widget.quantityLimit) { - widget.isOverQuantity = true; - } else { - widget.isOverQuantity = false; - } - }); + widget.isOverQuantity = false; } - }, - ), - ), - ], + }); + } + }, + ), ), ], ), @@ -175,7 +174,7 @@ class _FooterWidgetState extends State { quantityUI = 80; showUI = false; } else { - quantityUI = 150; + quantityUI = 160; showUI = true; } }); @@ -197,10 +196,13 @@ class _FooterWidgetState extends State { ); } else await widget.addToCartFunction( - widget.quantity, widget.item.id, context); + quantity: widget.quantity, + itemID: widget.item.id, + model: widget.model); }, + fontWeight: FontWeight.w600, borderColor: Color(0xFF4CAF50), - borderRadius: 5, + borderRadius: 3, color: Color(0xFF4CAF50), ), ), @@ -215,14 +217,18 @@ class _FooterWidgetState extends State { widget.quantity > widget.quantityLimit || widget.item.rxMessage != null, onTap: () async { - await widget.addToCartFunction( - widget.quantity, widget.item.id, context); + await widget.addToCartFunction( + quantity: widget.quantity, + itemID: widget.item.id, + model: widget.model); Navigator.push( context, FadePage(page: CartOrderPage()), ); }, - borderRadius: 5, + fontWeight: FontWeight.w600, + borderColor: Colors.grey[800], + borderRadius: 3, disableColor: Colors.grey[700], color: !widget.isAvailable && widget.quantity > 0 || widget.quantity > widget.quantityLimit || diff --git a/lib/pages/pharmacies/screens/product-details/product-detail.dart b/lib/pages/pharmacies/screens/product-details/product-detail.dart index 6ac5ec25..db43e6da 100644 --- a/lib/pages/pharmacies/screens/product-details/product-detail.dart +++ b/lib/pages/pharmacies/screens/product-details/product-detail.dart @@ -103,7 +103,8 @@ class __ProductDetailPageState extends State { deleteFromWishlistFunction: () async { await deleteFromWishlistFunction(itemID: itemID, model: model); }, - isInWishList:isInWishList + isInWishList:isInWishList, + addToCartFunction:addToCartFunction , ), body: SingleChildScrollView( child: Column( @@ -323,6 +324,7 @@ class __ProductDetailPageState extends State { quantity: quantity, isOverQuantity: isOverQuantity, addToCartFunction: addToCartFunction, + model: model, ), )); } @@ -338,17 +340,17 @@ class __ProductDetailPageState extends State { await model.deleteWishlistData(itemID); setState(() {}); } + addToCartFunction( + {quantity, + itemID, + ProductDetailViewModel model}) async { + GifLoaderDialogUtils.showMyDialog(context); + await model.addToCartData(quantity, itemID); + GifLoaderDialogUtils.hideDialog(context); + } } -addToCartFunction( - {quantity, - itemID, - BuildContext context, - ProductDetailViewModel model}) async { - GifLoaderDialogUtils.showMyDialog(context); - await model.addToCartData(quantity, itemID); - GifLoaderDialogUtils.hideDialog(context); -} + notifyMeWhenAvailable( {itemId, customerId, ProductDetailViewModel model}) async { diff --git a/lib/pages/pharmacies/screens/product-details/shared/product_details_app_bar.dart b/lib/pages/pharmacies/screens/product-details/shared/product_details_app_bar.dart index 8069d0ed..ee1bcd60 100644 --- a/lib/pages/pharmacies/screens/product-details/shared/product_details_app_bar.dart +++ b/lib/pages/pharmacies/screens/product-details/shared/product_details_app_bar.dart @@ -23,6 +23,8 @@ class ProductAppBar extends StatelessWidget with PreferredSizeWidget { final Function deleteFromWishlistFunction; final int quantity; final bool isInWishList; + final Function addToCartFunction; + ProductAppBar( {Key key, @@ -31,7 +33,7 @@ class ProductAppBar extends StatelessWidget with PreferredSizeWidget { this.addToWishlistFunction, this.quantity, this.deleteFromWishlistFunction, - this.isInWishList}) + this.isInWishList, this.addToCartFunction}) : super(key: key); AuthenticatedUserObject authenticatedUserObject = @@ -83,7 +85,7 @@ class ProductAppBar extends StatelessWidget with PreferredSizeWidget { top:0, right: -1.0, child: Container( decoration: BoxDecoration( - color: Colors.red, + color: Colors.red[800], borderRadius: BorderRadius.circular(15), ), @@ -136,7 +138,6 @@ class ProductAppBar extends StatelessWidget with PreferredSizeWidget { await addToCartFunction( quantity: quantity, itemID: itemID, - context: context, model: model); Navigator.of(context).pop(); diff --git a/lib/widgets/buttons/secondary_button.dart b/lib/widgets/buttons/secondary_button.dart index 4b2f23a9..4ada4d86 100644 --- a/lib/widgets/buttons/secondary_button.dart +++ b/lib/widgets/buttons/secondary_button.dart @@ -29,7 +29,10 @@ class SecondaryButton extends StatefulWidget { this.small = false, this.disabled = false, this.borderColor, - this.noBorderRadius = false, this.borderRadius, this.disableColor}) + this.noBorderRadius = false, + this.borderRadius, + this.disableColor, + this.fontWeight}) : super(key: key); final String label; @@ -45,7 +48,7 @@ class SecondaryButton extends StatefulWidget { final bool noBorderRadius; final double borderRadius; final Color disableColor; - + final FontWeight fontWeight; @override @@ -173,7 +176,8 @@ class _SecondaryButtonState extends State child: ClipRRect( borderRadius: widget.noBorderRadius ? BorderRadius.all(Radius.circular(0.0)) - : BorderRadius.all(Radius.circular(widget.borderRadius??10.0)), + : BorderRadius.all( + Radius.circular(widget.borderRadius ?? 10.0), ), child: Stack( children: [ Positioned( @@ -184,7 +188,7 @@ class _SecondaryButtonState extends State height: 100, decoration: BoxDecoration( color: widget.disabled - ? widget.disableColor??Colors.grey + ? widget.disableColor ?? Colors.grey : widget.color ?? Theme.of(context).buttonColor), ), ), @@ -246,7 +250,7 @@ class _SecondaryButtonState extends State style: TextStyle( color: widget.textColor, fontSize: widget.small ? 12.0 : 14.0, - // fontWeight: FontWeight.w800, + fontWeight: widget.fontWeight, fontFamily: projectViewModel.isArabic ? 'Cairo' : 'WorkSans'), From be21cb352bc8ee1d78929e30765efcf019ce4580 Mon Sep 17 00:00:00 2001 From: Elham Rababh Date: Sun, 10 Oct 2021 11:15:43 +0300 Subject: [PATCH 2/2] return recommended products --- .../product-details/product-detail.dart | 6 +- .../product-details/recommended_products.dart | 377 ++++++++++++++++++ .../product_detail_service.dart | 3 + 3 files changed, 384 insertions(+), 2 deletions(-) create mode 100644 lib/pages/pharmacies/screens/product-details/recommended_products.dart diff --git a/lib/pages/pharmacies/screens/product-details/product-detail.dart b/lib/pages/pharmacies/screens/product-details/product-detail.dart index db43e6da..ef3b7d8a 100644 --- a/lib/pages/pharmacies/screens/product-details/product-detail.dart +++ b/lib/pages/pharmacies/screens/product-details/product-detail.dart @@ -5,6 +5,7 @@ import 'package:diplomaticquarterapp/core/viewModels/pharmacyModule/product_deta import 'package:diplomaticquarterapp/pages/base/base_view.dart'; import 'package:diplomaticquarterapp/pages/pharmacies/compare-list.dart'; import 'package:diplomaticquarterapp/pages/pharmacies/screens/product-details/product-name-and-price.dart'; +import 'package:diplomaticquarterapp/pages/pharmacies/screens/product-details/recommended_products.dart'; import 'package:diplomaticquarterapp/pages/pharmacies/screens/product-details/reviews_info.dart'; import 'package:diplomaticquarterapp/pages/pharmacies/screens/product-details/shared/custom-divider.dart'; import 'package:diplomaticquarterapp/uitl/app_shared_preferences.dart'; @@ -310,8 +311,9 @@ class __ProductDetailPageState extends State { ), ), SizedBox( - height: 80, - ) + height: 10, + ), + RecommendedProducts(product: widget.product) ], ), ), diff --git a/lib/pages/pharmacies/screens/product-details/recommended_products.dart b/lib/pages/pharmacies/screens/product-details/recommended_products.dart new file mode 100644 index 00000000..2070a29e --- /dev/null +++ b/lib/pages/pharmacies/screens/product-details/recommended_products.dart @@ -0,0 +1,377 @@ +import 'package:diplomaticquarterapp/core/enum/viewstate.dart'; +import 'package:diplomaticquarterapp/core/model/pharmacies/PharmacyProduct.dart'; +import 'package:diplomaticquarterapp/core/model/pharmacies/recommendedProduct_model.dart'; +import 'package:diplomaticquarterapp/core/viewModels/pharmacyModule/pharmacy_module_view_model.dart'; +import 'package:diplomaticquarterapp/core/viewModels/pharmacyModule/product_detail_view_model.dart'; +import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; +import 'package:diplomaticquarterapp/pages/base/base_view.dart'; +import 'package:diplomaticquarterapp/pages/pharmacies/screens/product-details/product-detail.dart'; +import 'package:diplomaticquarterapp/uitl/gif_loader_dialog_utils.dart'; +import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; +import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; +import 'package:diplomaticquarterapp/widgets/others/network_base_view.dart'; +import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; +import 'package:flutter/material.dart'; +import 'package:provider/provider.dart'; +import 'package:rating_bar/rating_bar.dart'; + +class RecommendedProducts extends StatefulWidget { + final PharmacyProduct product; + final String customerId; + final ProductDetailViewModel productDetailViewModel; + final bool isOverQuantity; + final bool isInWishList; + final Function addToWishlistFunction; + final Function deleteFromWishlistFunction; + + RecommendedProducts( + {Key key, + this.product, + this.productDetailViewModel, + this.customerId, + this.isOverQuantity = false, + this.isInWishList = false, + this.addToWishlistFunction, + this.deleteFromWishlistFunction}) + : super(key: key); + + @override + _RecommendedProductsState createState() => _RecommendedProductsState(); +} + +class _RecommendedProductsState extends State { + @override + Widget build(BuildContext context) { + ProjectViewModel projectViewModel = Provider.of(context); + return SingleChildScrollView( + child: Container( + width: 410, + color: Colors.white, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Container( + margin: EdgeInsets.only(top: 9), + width: 410, + color: Colors.white, + child: Texts( + TranslationBase.of(context).recommended, + fontWeight: FontWeight.bold, fontSize: 16 + ), + ), + Container( + color: Colors.white, + height: 210, + margin: EdgeInsets.only(bottom: 75), + padding: EdgeInsets.only(bottom: 5), + // margin: EdgeInsets.symmetric(horizontal: 6, vertical: 4), + child: BaseView( + onModelReady: (model) => + model.getRecommendedProducts(widget.product.id), + builder: (_, model, wi) => NetworkBaseView( + isLocalLoader: true, + baseViewModel: model, + child: Container( + child: model.state== ViewState.BusyLocal?Container( + height: 80, + child: Center( + child: CircularProgressIndicator( + backgroundColor: Colors.white, + valueColor: AlwaysStoppedAnimation( + Colors.grey[500], + ), + ), + ), + ):model.recommendedProductList.length != null + ? ListView.builder( + scrollDirection: Axis.horizontal, + shrinkWrap: true, + physics: ScrollPhysics(), + // physics: NeverScrollableScrollPhysics(), + itemCount: model.recommendedProductList.length, + itemBuilder: (context, index) { + return InkWell( + onTap: () async { + GifLoaderDialogUtils.showMyDialog(context); + RecommendedProductModel data = + model.recommendedProductList[index]; + var json = data.toJson(); + PharmacyProduct product = + new PharmacyProduct.fromJson(json); + await Navigator.pushReplacement( + context, + FadePage( + page: ProductDetailPage(product), + ), + ); + GifLoaderDialogUtils.hideDialog(context); + }, + child: Card( + elevation: 2, + shape: RoundedRectangleBorder( + side: BorderSide( + color: Colors.grey[300], width: 2), + borderRadius: BorderRadius.circular(10), + ), + margin: EdgeInsets.symmetric( + horizontal: 8, + vertical: 0, + ), + child: Container( + decoration: BoxDecoration( + borderRadius: BorderRadius.all( + Radius.circular(15), + ), + ), + padding: EdgeInsets.symmetric(horizontal: 4), + width: MediaQuery.of(context).size.width / 3, + child: Column( + crossAxisAlignment: + CrossAxisAlignment.start, + children: [ + Stack(children: [ + Container( + child: Align( + alignment: Alignment.topRight, + child: IconButton( + icon: Icon(model + .recommendedProductList[ + index] + .isinwishlist != + true + ? Icons.favorite_border + : Icons.favorite), + color: model + .recommendedProductList[ + index] + .isinwishlist != + true + ? Colors.grey + : Colors.red, + onPressed: () async { + if (widget.customerId != null) { + if (!widget.isInWishList && + model + .recommendedProductList[ + index] + .isinwishlist != + true) { + GifLoaderDialogUtils + .showMyDialog(context); + await widget.addToWishlistFunction( + itemID: model + .recommendedProductList[ + index] + .id, + model: widget + .productDetailViewModel); +// checkWishlist(); + GifLoaderDialogUtils + .hideDialog(context); + setState(() { + model + .recommendedProductList[ + index] + .isinwishlist = true; + }); + } else { + GifLoaderDialogUtils + .showMyDialog(context); + await widget.deleteFromWishlistFunction( + itemID: model + .recommendedProductList[ + index] + .id, + model: widget + .productDetailViewModel); + GifLoaderDialogUtils + .hideDialog(context); + setState(() { + model + .recommendedProductList[ + index] + .isinwishlist = false; + }); + } + } else { + return; + } + setState(() { + // checkWishlist(); + }); + }, + ), + ), + ), + Container( + margin: EdgeInsets.fromLTRB( + 0, 16, 10, 16), + alignment: Alignment.center, + child: (model + .recommendedProductList[ + index] + .images != + null && + model + .recommendedProductList[ + index] + .images + .length > + 0) + ? Image.network( + model + .recommendedProductList[ + index] + .images[0] + .src + .toString(), + fit: BoxFit.cover, + height: 60, + ) + : Image.asset( + "assets/images/no_image.png", + fit: BoxFit.cover, + height: 60, + ), + ), + Container( + width: model + .recommendedProductList[ + index] + .rxMessage != + null + ? MediaQuery.of(context) + .size + .width / + 5 + : 0, + padding: EdgeInsets.all(4), + decoration: BoxDecoration( + color: Color(0xffb23838), + borderRadius: BorderRadius.only( + topLeft: Radius.circular(6), + ), + ), + child: model + .recommendedProductList[ + index] + .rxMessage != + null + ? Texts( + projectViewModel.isArabic + ? model + .recommendedProductList[ + index] + .rxMessagen + : model + .recommendedProductList[ + index] + .rxMessage, + color: Colors.white, + regular: true, + fontSize: 10, + fontWeight: FontWeight.w400, + ) + : Texts(""), + ), + ]), + Container( + margin: EdgeInsets.symmetric( + horizontal: 6, + vertical: 0, + ), + child: Column( + crossAxisAlignment: + CrossAxisAlignment.start, + children: [ + Text( + projectViewModel.isArabic + ? model + .recommendedProductList[ + index] + .namen + : model + .recommendedProductList[ + index] + .name, + style: TextStyle( + color: Colors.black, + fontSize: 13.0, +// fontWeight: FontWeight.bold, + ), + ), + Padding( +// padding: const EdgeInsets.only(top: 15, bottom: 10), + padding: const EdgeInsets.only( + top: 10, bottom: 5), + child: Texts( + "SAR ${model.recommendedProductList[index].price}", + bold: true, + fontSize: 14, + ), + ), + ], + ), + ), + Row( + crossAxisAlignment: + CrossAxisAlignment.start, + children: [ + Container( + padding: + EdgeInsets.only(right: 10), + child: Align( + alignment: Alignment.topLeft, + child: RatingBar.readOnly( + initialRating: model + .recommendedProductList[ + index] + .approvedRatingSum + .toDouble(), + size: 13.0, + filledColor: + Colors.yellow[700], + emptyColor: Colors.grey[500], + isHalfAllowed: true, + halfFilledIcon: + Icons.star_half, + filledIcon: Icons.star, + emptyIcon: Icons.star, + ), + ), + ), + Texts( + "(${model.recommendedProductList[index].notApprovedTotalReviews.toString()})", +// bold: true, + fontSize: 12, + ), + ]), + ], + ), + ), + ), + ); + }) + : Container( + // color: Colors.white, + child: Row( + mainAxisAlignment: MainAxisAlignment.center, + // crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Texts( + TranslationBase.of(context).nonRecommended, + color: Colors.black, + ), + ], + ), + ), + ), + ), + ), + ), + ], + ), + ), + ); + } +} diff --git a/lib/services/pharmacy_services/product_detail_service.dart b/lib/services/pharmacy_services/product_detail_service.dart index 990b5f23..4f457cad 100644 --- a/lib/services/pharmacy_services/product_detail_service.dart +++ b/lib/services/pharmacy_services/product_detail_service.dart @@ -89,6 +89,9 @@ class ProductDetailService extends BaseService { "language_id": 1 } }; + + + await baseAppClient.pharmacyPost(GET_SHOPPING_CART, isExternal: false, onSuccess: (dynamic response, int statusCode) { _addToCartModel.clear();