From d5c68c503230f82a3fee9787c94728f73dab83bc Mon Sep 17 00:00:00 2001 From: Haroon Amjad Date: Mon, 8 Nov 2021 01:59:01 +0300 Subject: [PATCH] Packages & offers design --- .../responses/PackagesResponseModel.dart | 8 +- lib/core/service/client/base_app_client.dart | 1 - .../PackagesOffersServices.dart | 257 +++++--- .../OfferAndPackageDetailPage.dart | 5 +- .../packages_offers/OfferAndPackagesPage.dart | 594 +++++++++--------- .../offers_packages/PackagesOfferCard.dart | 245 ++++---- 6 files changed, 569 insertions(+), 541 deletions(-) diff --git a/lib/core/model/packages_offers/responses/PackagesResponseModel.dart b/lib/core/model/packages_offers/responses/PackagesResponseModel.dart index 7297a20a..8d4f619b 100644 --- a/lib/core/model/packages_offers/responses/PackagesResponseModel.dart +++ b/lib/core/model/packages_offers/responses/PackagesResponseModel.dart @@ -207,12 +207,10 @@ class PackagesResponseModel with JsonConvert { String seName; String getName() { - if(localizedNames.length == 2){ - if(localizedNames.first.languageId == 2) + if (localizedNames.length == 2) { + if (localizedNames.first.languageId == 2) return localizedNames.first.localizedName ?? name; - - else if(localizedNames.first.languageId == 1) - return localizedNames.last.localizedName ?? name; + else if (localizedNames.first.languageId == 1) return localizedNames.last.localizedName ?? name; } return name; } diff --git a/lib/core/service/client/base_app_client.dart b/lib/core/service/client/base_app_client.dart index 322ec08b..206c45c6 100644 --- a/lib/core/service/client/base_app_client.dart +++ b/lib/core/service/client/base_app_client.dart @@ -514,7 +514,6 @@ class BaseAppClient { simpleGet(String fullUrl, {Function(dynamic response, int statusCode) onSuccess, Function(String error, int statusCode) onFailure, Map queryParams, Map headers}) async { String url = fullUrl; - print("URL Query String: $url"); var haveParams = (queryParams != null); if (haveParams) { diff --git a/lib/core/service/packages_offers/PackagesOffersServices.dart b/lib/core/service/packages_offers/PackagesOffersServices.dart index d05bc274..3b34b957 100644 --- a/lib/core/service/packages_offers/PackagesOffersServices.dart +++ b/lib/core/service/packages_offers/PackagesOffersServices.dart @@ -21,7 +21,8 @@ import 'package:diplomaticquarterapp/uitl/gif_loader_dialog_utils.dart'; import 'package:diplomaticquarterapp/uitl/utils.dart'; import 'package:flutter/cupertino.dart'; -var packagesAuthHeader = {'Authorization' : ''}; +var packagesAuthHeader = {'Authorization': ''}; + class OffersAndPackagesServices extends BaseService { AuthenticatedUser patientUser; List categoryList = List(); @@ -33,52 +34,62 @@ class OffersAndPackagesServices extends BaseService { List cartItemList = List(); String cartItemCount = ""; - PackagesCustomerResponseModel customer; - Future> getAllCategories(OffersCategoriesRequestModel request) async { + Future> getAllCategories( + OffersCategoriesRequestModel request) async { Future errorThrow; var url = EXA_CART_API_BASE_URL + PACKAGES_CATEGORIES; - await baseAppClient.simpleGet(url, headers: packagesAuthHeader, onSuccess: (dynamic stringResponse, int statusCode) { + await baseAppClient.simpleGet(url, headers: packagesAuthHeader, + onSuccess: (dynamic stringResponse, int statusCode) { if (statusCode == 200) { var jsonResponse = json.decode(stringResponse); jsonResponse['categories'].forEach((json) { categoryList.add(PackagesCategoriesResponseModel().fromJson(json)); }); } - }, onFailure: (String error, int statusCode) { - }, queryParams: request.toFlatMap()); + }, + onFailure: (String error, int statusCode) {}, + queryParams: request.toFlatMap()); return categoryList; } - Future> getAllProducts({@required OffersProductsRequestModel request, @required BuildContext context, @required bool showLoading = true}) async { + Future> getAllProducts( + {@required OffersProductsRequestModel request, + @required BuildContext context, + @required bool showLoading = true}) async { Future errorThrow; request.sinceId = (productList.isNotEmpty) ? productList.last.id : 0; - + productList = List(); var url = EXA_CART_API_BASE_URL + PACKAGES_PRODUCTS; - await baseAppClient.simpleGet(url, headers: packagesAuthHeader, onSuccess: (dynamic stringResponse, int statusCode) { + await baseAppClient.simpleGet(url, headers: packagesAuthHeader, + onSuccess: (dynamic stringResponse, int statusCode) { if (statusCode == 200) { var jsonResponse = json.decode(stringResponse); jsonResponse['products'].forEach((json) { productList.add(PackagesResponseModel().fromJson(json)); }); } - }, onFailure: (String error, int statusCode) { - }, queryParams: request.toFlatMap()); + }, + onFailure: (String error, int statusCode) {}, + queryParams: request.toFlatMap()); return productList; } - Future> getTamaraOptions({@required BuildContext context, @required bool showLoading = true}) async { - if(tamaraPaymentOptions != null && tamaraPaymentOptions.isNotEmpty) + Future> getTamaraOptions( + {@required BuildContext context, + @required bool showLoading = true}) async { + if (tamaraPaymentOptions != null && tamaraPaymentOptions.isNotEmpty) return tamaraPaymentOptions; var url = EXA_CART_API_BASE_URL + PACKAGES_TAMARA_OPT; - await baseAppClient.simpleGet(url, headers: packagesAuthHeader, onSuccess: (dynamic stringResponse, int statusCode) { + await baseAppClient.simpleGet(url, headers: packagesAuthHeader, + onSuccess: (dynamic stringResponse, int statusCode) { if (statusCode == 200) { var jsonResponse = json.decode(stringResponse); jsonResponse['payment_option'].forEach((json) { @@ -92,10 +103,13 @@ class OffersAndPackagesServices extends BaseService { return tamaraPaymentOptions; } - Future> getLatestOffers({@required OffersProductsRequestModel request, @required BuildContext context, @required bool showLoading = true}) async { - + Future> getLatestOffers( + {@required OffersProductsRequestModel request, + @required BuildContext context, + @required bool showLoading = true}) async { var url = EXA_CART_API_BASE_URL + PACKAGES_PRODUCTS; - await baseAppClient.simpleGet(url, headers: packagesAuthHeader, onSuccess: (dynamic stringResponse, int statusCode) { + await baseAppClient.simpleGet(url, headers: packagesAuthHeader, + onSuccess: (dynamic stringResponse, int statusCode) { if (statusCode == 200) { var jsonResponse = json.decode(stringResponse); jsonResponse['products'].forEach((json) { @@ -109,10 +123,14 @@ class OffersAndPackagesServices extends BaseService { return latestOffersList; } - Future> getBestSellers({@required OffersProductsRequestModel request, @required BuildContext context, @required bool showLoading = true}) async { - + Future> getBestSellers( + {@required OffersProductsRequestModel request, + @required BuildContext context, + @required bool showLoading = true}) async { var url = EXA_CART_API_BASE_URL + PACKAGES_PRODUCTS; - await baseAppClient.simpleGet(url, headers: packagesAuthHeader, onSuccess: (dynamic stringResponse, int statusCode) { + await baseAppClient.simpleGet(url, headers: packagesAuthHeader, + onSuccess: (dynamic stringResponse, int statusCode) { + bestSellerList.clear(); if (statusCode == 200) { var jsonResponse = json.decode(stringResponse); jsonResponse['products'].forEach((json) { @@ -126,10 +144,13 @@ class OffersAndPackagesServices extends BaseService { return bestSellerList; } - - Future> getBanners({@required OffersProductsRequestModel request, @required BuildContext context, @required bool showLoading = true}) async { + Future> getBanners( + {@required OffersProductsRequestModel request, + @required BuildContext context, + @required bool showLoading = true}) async { var url = EXA_CART_API_BASE_URL + PACKAGES_PRODUCTS; - await baseAppClient.simpleGet(url, headers: packagesAuthHeader, onSuccess: (dynamic stringResponse, int statusCode) { + await baseAppClient.simpleGet(url, headers: packagesAuthHeader, + onSuccess: (dynamic stringResponse, int statusCode) { if (statusCode == 200) { var jsonResponse = json.decode(stringResponse); jsonResponse['products'].forEach((json) { @@ -143,15 +164,16 @@ class OffersAndPackagesServices extends BaseService { return bannersList; } - Future loadOffersPackagesDataForMainPage({@required BuildContext context, bool showLoading = true, Function completion }) async { + Future loadOffersPackagesDataForMainPage( + {@required BuildContext context, + bool showLoading = true, + Function completion}) async { var finished = 0; - var totalCalls = 3; - - - completedAll(){ + var totalCalls = 2; + completedAll() { finished++; - if(completion != null && finished == totalCalls) { + if (completion != null && finished == totalCalls) { _hideLoading(context, showLoading); completion(); } @@ -160,57 +182,71 @@ class OffersAndPackagesServices extends BaseService { _showLoading(context, showLoading); final auth_token = await baseAppClient.generatePackagesToken(); - if(auth_token == null){ + if (auth_token == null) { throw 'Something went wrong while authentication, Please try again letter'; } packagesAuthHeader["Authorization"] = 'Bearer $auth_token'; - // Check and Create Customer - if(patientUser != null){ - customer = await getCurrentCustomer(context: context, showLoading: showLoading); - if(customer == null){ - createCustomer(PackagesCustomerRequestModel.fromUser(patientUser), context: context); + if (patientUser != null) { + customer = + await getCurrentCustomer(context: context, showLoading: showLoading); + if (customer == null) { + createCustomer(PackagesCustomerRequestModel.fromUser(patientUser), + context: context); } } // Performing Parallel Request on same time // # 1 - getBestSellers(request: OffersProductsRequestModel(), context: context, showLoading: false).then((value){ - completedAll(); + getBestSellers( + request: OffersProductsRequestModel(), + context: context, + showLoading: false) + .then((value) { + completedAll(); }); // # 2 - getLatestOffers(request: OffersProductsRequestModel(), context: context, showLoading: false).then((value){ + getLatestOffers( + request: OffersProductsRequestModel(), + context: context, + showLoading: false) + .then((value) { completedAll(); }); // # 3 - getBanners(request: OffersProductsRequestModel(), context: context, showLoading: false).then((value){ - completedAll(); - }); - + // getBanners( + // request: OffersProductsRequestModel(), + // context: context, + // showLoading: false) + // .then((value) { + // completedAll(); + // }); } // -------------------- // Create Customer // -------------------- - Future createCustomer(PackagesCustomerRequestModel request, {@required BuildContext context, bool showLoading = true, Function(bool) completion }) async{ - if(customer != null) - return Future.value(customer); + Future createCustomer(PackagesCustomerRequestModel request, + {@required BuildContext context, + bool showLoading = true, + Function(bool) completion}) async { + if (customer != null) return Future.value(customer); customer = null; Future errorThrow; _showLoading(context, showLoading); var url = EXA_CART_API_BASE_URL + PACKAGES_CUSTOMER; - await baseAppClient.simplePost(url, headers: packagesAuthHeader, body: request.json(), onSuccess: (dynamic stringResponse, int statusCode){ - + await baseAppClient + .simplePost(url, headers: packagesAuthHeader, body: request.json(), + onSuccess: (dynamic stringResponse, int statusCode) { var jsonResponse = json.decode(stringResponse); var customerJson = jsonResponse['customers'].first; customer = PackagesCustomerResponseModel.fromJson(customerJson); - - }, onFailure: (String error, int statusCode){ + }, onFailure: (String error, int statusCode) { errorThrow = Future.error(error); log(error); }); @@ -221,55 +257,60 @@ class OffersAndPackagesServices extends BaseService { return errorThrow ?? customer; } - Future getCurrentCustomer({@required BuildContext context, bool showLoading = true}) async{ - if(customer != null) - return Future.value(customer); + Future getCurrentCustomer( + {@required BuildContext context, bool showLoading = true}) async { + if (customer != null) return Future.value(customer); _showLoading(context, showLoading); - var url = EXA_CART_API_BASE_URL + PACKAGES_CUSTOMER + "/username/${patientUser.patientID}"; - await baseAppClient.simpleGet(url, headers: packagesAuthHeader, onSuccess: (dynamic stringResponse, int statusCode){ + var url = EXA_CART_API_BASE_URL + + PACKAGES_CUSTOMER + + "/username/${patientUser.patientID}"; + await baseAppClient.simpleGet(url, headers: packagesAuthHeader, + onSuccess: (dynamic stringResponse, int statusCode) { var jsonResponse = json.decode(stringResponse); var customerJson = jsonResponse['customers'].first; customer = PackagesCustomerResponseModel.fromJson(customerJson); - - }, onFailure: (String error, int statusCode){ + }, onFailure: (String error, int statusCode) { log(error); }); _hideLoading(context, showLoading); - return customer; + return customer; } - - // -------------------- // Shopping Cart // -------------------- - Future> cartItems({@required BuildContext context, bool showLoading = true}) async{ + Future> cartItems( + {@required BuildContext context, bool showLoading = true}) async { Future errorThrow; cartItemList.clear(); _showLoading(context, showLoading); - var url = EXA_CART_API_BASE_URL + PACKAGES_SHOPPING_CART + '/${customer.id}'; - Map jsonResponse; - await baseAppClient.simpleGet(url, headers: packagesAuthHeader, onSuccess: (dynamic stringResponse, int statusCode) { + var url = + EXA_CART_API_BASE_URL + PACKAGES_SHOPPING_CART + '/${customer.id}'; + Map jsonResponse; + await baseAppClient.simpleGet(url, headers: packagesAuthHeader, + onSuccess: (dynamic stringResponse, int statusCode) { _hideLoading(context, showLoading); jsonResponse = json.decode(stringResponse); jsonResponse['shopping_carts'].forEach((json) { cartItemList.add(PackagesCartItemsResponseModel.fromJson(json)); }); - }, onFailure: (String error, int statusCode) { _hideLoading(context, showLoading); log(error); - errorThrow = Future.error({"error":error, "statusCode":statusCode}); + errorThrow = Future.error({"error": error, "statusCode": statusCode}); }, queryParams: null); return errorThrow ?? jsonResponse; } - Future> addProductToCart(AddProductToCartRequestModel request, {@required BuildContext context, bool showLoading = true}) async{ + Future> addProductToCart( + AddProductToCartRequestModel request, + {@required BuildContext context, + bool showLoading = true}) async { Future errorThrow; ResponseModel response; @@ -277,55 +318,64 @@ class OffersAndPackagesServices extends BaseService { _showLoading(context, showLoading); var url = EXA_CART_API_BASE_URL + PACKAGES_SHOPPING_CART; - await baseAppClient.simplePost(url, headers: packagesAuthHeader, body: request.json(), onSuccess: (dynamic stringResponse, int statusCode){ + await baseAppClient + .simplePost(url, headers: packagesAuthHeader, body: request.json(), + onSuccess: (dynamic stringResponse, int statusCode) { _hideLoading(context, showLoading); var jsonResponse = json.decode(stringResponse); var jsonCartItem = jsonResponse["shopping_carts"][0]; - response = ResponseModel(status: true, data: PackagesCartItemsResponseModel.fromJson(jsonCartItem), error: null); + response = ResponseModel( + status: true, + data: PackagesCartItemsResponseModel.fromJson(jsonCartItem), + error: null); cartItemCount = (jsonResponse['count'] ?? 0).toString(); - - }, onFailure: (String error, int statusCode){ + }, onFailure: (String error, int statusCode) { _hideLoading(context, showLoading); - errorThrow = Future.error(ResponseModel(status: true, data: null, error: error)); + errorThrow = + Future.error(ResponseModel(status: true, data: null, error: error)); }); return errorThrow ?? response; } - Future updateProductToCart(int cartItemID, {UpdateProductToCartRequestModel request, @required BuildContext context, bool showLoading = true}) async{ + Future updateProductToCart(int cartItemID, + {UpdateProductToCartRequestModel request, + @required BuildContext context, + bool showLoading = true}) async { Future errorThrow; _showLoading(context, showLoading); var url = EXA_CART_API_BASE_URL + PACKAGES_SHOPPING_CART + '/$cartItemID'; - await baseAppClient.simplePut(url, headers: packagesAuthHeader, body: request.json(), onSuccess: (dynamic stringResponse, int statusCode){ + await baseAppClient + .simplePut(url, headers: packagesAuthHeader, body: request.json(), + onSuccess: (dynamic stringResponse, int statusCode) { _hideLoading(context, showLoading); var jsonResponse = json.decode(stringResponse); - - }, onFailure: (String error, int statusCode){ + }, onFailure: (String error, int statusCode) { _hideLoading(context, showLoading); log(error); - errorThrow = Future.error({"error":error, "statusCode":statusCode}); + errorThrow = Future.error({"error": error, "statusCode": statusCode}); }); return errorThrow ?? bannersList; } - - Future deleteProductFromCart(int cartItemID, {@required BuildContext context, bool showLoading = true}) async{ + Future deleteProductFromCart(int cartItemID, + {@required BuildContext context, bool showLoading = true}) async { Future errorThrow; _showLoading(context, showLoading); var url = EXA_CART_API_BASE_URL + PACKAGES_SHOPPING_CART + '/$cartItemID'; - await baseAppClient.simpleDelete(url, headers: packagesAuthHeader, onSuccess: (dynamic stringResponse, int statusCode){ + await baseAppClient.simpleDelete(url, headers: packagesAuthHeader, + onSuccess: (dynamic stringResponse, int statusCode) { _hideLoading(context, showLoading); // var jsonResponse = json.decode(stringResponse); - - }, onFailure: (String error, int statusCode){ + }, onFailure: (String error, int statusCode) { _hideLoading(context, showLoading); log(error); - errorThrow = Future.error({"error":error, "statusCode":statusCode}); + errorThrow = Future.error({"error": error, "statusCode": statusCode}); }); return errorThrow ?? true; @@ -334,29 +384,33 @@ class OffersAndPackagesServices extends BaseService { // -------------------- // Place Order // -------------------- - Future placeOrder({@required Map paymentParams, @required BuildContext context, bool showLoading = true}) async{ + Future placeOrder( + {@required Map paymentParams, + @required BuildContext context, + bool showLoading = true}) async { Future errorThrow; - Map jsonBody = { - "customer_id" : customer.id, + Map jsonBody = { + "customer_id": customer.id, "billing_address": { "email": patientUser.emailAddress, "phone_number": patientUser.mobileNumber }, }; jsonBody.addAll(paymentParams); - jsonBody = {'order' : jsonBody}; + jsonBody = {'order': jsonBody}; int order_id; _showLoading(context, showLoading); var url = EXA_CART_API_BASE_URL + PACKAGES_ORDERS; - await baseAppClient.simplePost(url, headers: packagesAuthHeader, body: jsonBody, onSuccess: (dynamic stringResponse, int statusCode){ + await baseAppClient.simplePost(url, + headers: packagesAuthHeader, + body: jsonBody, onSuccess: (dynamic stringResponse, int statusCode) { _hideLoading(context, showLoading); var jsonResponse = json.decode(stringResponse); order_id = jsonResponse['orders'][0]['id']; - - }, onFailure: (String error, int statusCode){ + }, onFailure: (String error, int statusCode) { _hideLoading(context, showLoading); log(error); errorThrow = Future.error(error); @@ -365,35 +419,34 @@ class OffersAndPackagesServices extends BaseService { return errorThrow ?? order_id; } - Future> getOrderById(int id, {@required BuildContext context, bool showLoading = true}) async{ + Future> getOrderById(int id, + {@required BuildContext context, bool showLoading = true}) async { Future errorThrow; ResponseModel response; _showLoading(context, showLoading); var url = EXA_CART_API_BASE_URL + PACKAGES_ORDERS + '/$id'; - await baseAppClient.simpleGet(url, headers: packagesAuthHeader, onSuccess: (dynamic stringResponse, int statusCode) { + await baseAppClient.simpleGet(url, headers: packagesAuthHeader, + onSuccess: (dynamic stringResponse, int statusCode) { _hideLoading(context, showLoading); var jsonResponse = json.decode(stringResponse); var jsonOrder = jsonResponse['orders'][0]; - response = ResponseModel(status: true, data: PackagesOrderResponseModel.fromJson(jsonOrder)); - + response = ResponseModel( + status: true, data: PackagesOrderResponseModel.fromJson(jsonOrder)); }, onFailure: (String error, int statusCode) { _hideLoading(context, showLoading); - errorThrow = Future.error(ResponseModel(status: false,error: error)); + errorThrow = Future.error(ResponseModel(status: false, error: error)); }, queryParams: null); return errorThrow ?? response; } - } -_showLoading(BuildContext context, bool flag){ - if(flag) - GifLoaderDialogUtils.showMyDialog(context); +_showLoading(BuildContext context, bool flag) { + if (flag) GifLoaderDialogUtils.showMyDialog(context); } -_hideLoading(BuildContext context, bool flag){ - if(flag) - GifLoaderDialogUtils.hideDialog(context); -} \ No newline at end of file +_hideLoading(BuildContext context, bool flag) { + if (flag) GifLoaderDialogUtils.hideDialog(context); +} diff --git a/lib/pages/packages_offers/OfferAndPackageDetailPage.dart b/lib/pages/packages_offers/OfferAndPackageDetailPage.dart index f2ff8f6c..24e75797 100644 --- a/lib/pages/packages_offers/OfferAndPackageDetailPage.dart +++ b/lib/pages/packages_offers/OfferAndPackageDetailPage.dart @@ -1,3 +1,4 @@ +import 'package:diplomaticquarterapp/core/model/packages_offers/responses/PackagesResponseModel.dart'; import 'package:diplomaticquarterapp/core/viewModels/packages_offers/PackagesOffersViewModel.dart'; import 'package:diplomaticquarterapp/pages/base/base_view.dart'; import 'package:diplomaticquarterapp/pages/pharmacies/ProductCheckTypeWidget.dart'; @@ -10,9 +11,9 @@ import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; class OfferAndPackagesDetail extends StatefulWidget{ - final dynamic model; + final PackagesResponseModel itemModel; - const OfferAndPackagesDetail({@required this.model, Key key}) : super(key: key); + const OfferAndPackagesDetail({@required this.itemModel, Key key}) : super(key: key); @override State createState() => OfferAndPackagesDetailState(); diff --git a/lib/pages/packages_offers/OfferAndPackagesPage.dart b/lib/pages/packages_offers/OfferAndPackagesPage.dart index 056e23e1..063cc541 100644 --- a/lib/pages/packages_offers/OfferAndPackagesPage.dart +++ b/lib/pages/packages_offers/OfferAndPackagesPage.dart @@ -1,13 +1,13 @@ -import 'package:after_layout/after_layout.dart'; -import 'package:carousel_slider/carousel_slider.dart'; import 'package:diplomaticquarterapp/config/config.dart'; import 'package:diplomaticquarterapp/config/shared_pref_kay.dart'; import 'package:diplomaticquarterapp/core/model/ImagesInfo.dart'; import 'package:diplomaticquarterapp/core/model/packages_offers/requests/AddProductToCartRequestModel.dart'; import 'package:diplomaticquarterapp/core/model/packages_offers/requests/OffersCategoriesRequestModel.dart'; import 'package:diplomaticquarterapp/core/model/packages_offers/requests/OffersProductsRequestModel.dart'; +import 'package:diplomaticquarterapp/core/model/packages_offers/responses/PackagesCategoriesResponseModel.dart'; import 'package:diplomaticquarterapp/core/model/packages_offers/responses/PackagesResponseModel.dart'; import 'package:diplomaticquarterapp/core/viewModels/packages_offers/PackagesOffersViewModel.dart'; +import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; import 'package:diplomaticquarterapp/models/Authentication/authenticated_user.dart'; import 'package:diplomaticquarterapp/models/Authentication/select_device_imei_res.dart'; import 'package:diplomaticquarterapp/pages/base/base_view.dart'; @@ -17,229 +17,261 @@ import 'package:diplomaticquarterapp/pages/packages_offers/OfferAndPackageDetail import 'package:diplomaticquarterapp/pages/packages_offers/OfferAndPackagesCartPage.dart'; import 'package:diplomaticquarterapp/routes.dart'; import 'package:diplomaticquarterapp/services/authentication/auth_provider.dart' as auth; +import 'package:diplomaticquarterapp/theme/colors.dart'; import 'package:diplomaticquarterapp/uitl/gif_loader_dialog_utils.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/uitl/utils.dart' as utils; -import 'package:diplomaticquarterapp/widgets/carousel_indicator/carousel_indicator.dart'; +import 'package:diplomaticquarterapp/uitl/utils_new.dart'; +import 'package:diplomaticquarterapp/widgets/buttons/defaultButton.dart'; import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; +import 'package:diplomaticquarterapp/widgets/dialogs/radio_selection_dialog.dart'; import 'package:diplomaticquarterapp/widgets/offers_packages/PackagesOfferCard.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:flutter/rendering.dart'; -import 'package:flutter_material_pickers/flutter_material_pickers.dart'; - -dynamic languageID; +import 'package:provider/provider.dart'; class PackagesHomePage extends StatefulWidget { final AuthenticatedUser user; + PackagesHomePage(this.user); @override _PackagesHomePageState createState() => _PackagesHomePageState(); - } -class _PackagesHomePageState extends State with AfterLayoutMixin{ - getLanguageID() async { - languageID = await sharedPref.getString(APP_LANGUAGE); - } +class _PackagesHomePageState extends State { + ProjectViewModel projectViewModel; @override void initState() { super.initState(); - getLanguageID(); - } - - @override - void afterFirstLayout(BuildContext context) async{ - viewModel.service.patientUser = widget.user; - viewModel.service.loadOffersPackagesDataForMainPage(context: context, completion: (){ - setState((){}); + WidgetsBinding.instance.addPostFrameCallback((timeStamp) { + viewModel.service.loadOffersPackagesDataForMainPage( + context: context, + completion: () { + setState(() {}); + }); }); } // Controllers var _searchTextController = TextEditingController(); - var _filterTextController = TextEditingController(); - var _carouselController = CarouselController(); - - - int carouselIndicatorIndex = 0; - CarouselSlider _bannerCarousel; - TextField _textFieldSearch; - TextField _textFieldFilterSelection; ListView _listViewLatestOffers; ListView _listViewBestSeller; PackagesViewModel viewModel; - onCartClick(){ - if (viewModel.service.customer == null){ + onCartClick() { + if (viewModel.service.customer == null) { utils.Utils.showErrorToast("Cart is empty for your current session"); return; } - Navigator.of(context).push( - MaterialPageRoute( - builder: (BuildContext context) => PackagesCartPage() - ) - ); + Navigator.of(context).push(MaterialPageRoute(builder: (BuildContext context) => PackagesCartPage())); } onProductCartClick(PackagesResponseModel product) async { - if(viewModel.service.customer == null) { + if (viewModel.service.customer == null) { // viewModel.service.customer = await CreateCustomerDialogPage(context: context).show(); loginCheck(context); } - - if(viewModel.service.customer != null) { + + if (viewModel.service.customer != null) { var request = AddProductToCartRequestModel(product_id: product.id, customer_id: viewModel.service.customer.id); - await viewModel.service.addProductToCart(request, context: context).then((response){ - // appScaffold.appBar.badgeUpdater(viewModel.service.cartItemCount); - }).catchError((error) { + await viewModel.service.addProductToCart(request, context: context).then((response) {}).catchError((error) { utils.Utils.showErrorToast(error.toString()); }); } } AppScaffold appScaffold; + PackagesCategoriesResponseModel selectedClinic; + @override Widget build(BuildContext context) { + projectViewModel = Provider.of(context); return BaseView( - allowAny: true, - onModelReady: (model) => viewModel = model, - builder: (_, model, wi){ - return - appScaffold = - AppScaffold( - description: TranslationBase.of(context).offerAndPackagesDetails, - imagesInfo: [ImagesInfo(imageAr: 'https://hmgwebservices.com/Images/MobileApp/CMC/ar/0.png', imageEn: 'https://hmgwebservices.com/Images/MobileApp/CMC/en/0.png')], - appBarTitle: TranslationBase.of(context).offerAndPackages, - isShowAppBar: true, - isPharmacy: false, - showPharmacyCart: false, - showHomeAppBarIcon: false, - isOfferPackages: true, - showOfferPackagesCart: true, - isShowDecPage: false, - body: ListView( + allowAny: true, + onModelReady: (model) => viewModel = model, + builder: (_, model, wi) { + return appScaffold = AppScaffold( + description: TranslationBase.of(context).offerAndPackagesDetails, + imagesInfo: [ImagesInfo(imageAr: 'https://hmgwebservices.com/Images/MobileApp/CMC/ar/0.png', imageEn: 'https://hmgwebservices.com/Images/MobileApp/CMC/en/0.png')], + appBarTitle: TranslationBase.of(context).offerAndPackages, + isShowAppBar: true, + isPharmacy: false, + showPharmacyCart: false, + isOfferPackages: true, + showOfferPackagesCart: false, + isShowDecPage: false, + showNewAppBar: true, + showNewAppBarTitle: true, + body: SingleChildScrollView( + child: Column( + children: [ + SizedBox( + height: 10, + ), + Padding( + padding: const EdgeInsets.all(21), + child: Column( children: [ - - // Top Banner Carousel - AspectRatio( - aspectRatio: 2.2/1, - child: bannerCarousel() + inputWidget(TranslationBase.of(context).search, "", _searchTextController, isInputTypeNum: false), + SizedBox( + height: 10, ), - - Center( - child: CarouselIndicator( - activeColor: Theme.of(context).appBarTheme.color, - color: Colors.grey[300], - cornerRadius: 15, - width: 15, height: 15, - count: _bannerCarousel.itemCount, - index: carouselIndicatorIndex, - onClick: (index){ - debugPrint('onClick at ${index}'); + InkWell( + onTap: () => showClinicSelectionList(), + child: Container( + padding: EdgeInsets.all(12), + width: double.infinity, + height: 65, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(12), + border: Border.all( + color: Color(0xffefefef), + width: 1, + ), + color: Colors.white), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text( + selectedClinic != null ? selectedClinic.name : "Browse offers by clinic", + style: TextStyle( + fontSize: 14, + fontWeight: FontWeight.w600, + letterSpacing: -0.46, + ), + ), + Icon(Icons.arrow_drop_down), + ], + ), + ), + ), + SizedBox( + height: 20, + ), + Container( + width: double.infinity, + height: MediaQuery.of(context).size.width * 0.8, + child: ListView.separated( + scrollDirection: Axis.horizontal, + shrinkWrap: true, + itemCount: viewModel.bestSellerList.length, + separatorBuilder: (context, index) { + return mWidth(9.0); + }, + itemBuilder: (BuildContext context, int index) { + return PackagesItemCard( + itemModel: viewModel.bestSellerList[index], + onCartClick: onProductCartClick, + ); }, ), ), - - SizedBox(height: 10,), - - Padding( - padding: const EdgeInsets.all(15), - child: Column( - children: [ - // Search Textfield - searchTextField(), - - SizedBox(height: 10,), - - // Filter Selection - filterOptionSelection(), - - SizedBox(height: 20,), - - // Horizontal Scrollable Cards - Texts( - "Latest offers", - fontWeight: FontWeight.bold, - color: Colors.black87, - fontSize: 20 - ), - - // Latest Offers Horizontal Scrollable List - AspectRatio( - aspectRatio: 1.3/1, - child: LayoutBuilder(builder: (context, constraints){ - double itemContentPadding = 10; - double itemWidth = (constraints.maxWidth/2) - (itemContentPadding*2); - return latestOfferListView(itemWidth: itemWidth, itemContentPadding: itemContentPadding); - }), - ), - - SizedBox(height: 10,), - - Texts( - "Best sellers", - fontWeight: FontWeight.bold, - color: Colors.black87, - fontSize: 20 - ), - - - // Best Seller Horizontal Scrollable List - AspectRatio( - aspectRatio: 1.3/1, - child: LayoutBuilder(builder: (context, constraints){ - double itemContentPadding = 10; // 10 is content padding in each item - double itemWidth = (constraints.maxWidth/2) - (itemContentPadding*2 /* 2 = LeftRight */); - return bestSellerListView(itemWidth: itemWidth, itemContentPadding: itemContentPadding); - }), - ) - - ],), + SizedBox( + height: 21, + ), + // // Best Seller Horizontal Scrollable List + Container( + width: double.infinity, + height: MediaQuery.of(context).size.width * 0.8, + child: ListView.separated( + scrollDirection: Axis.horizontal, + shrinkWrap: true, + itemCount: viewModel.latestOffersList.length, + separatorBuilder: (context, index) { + return mWidth(9.0); + }, + itemBuilder: (BuildContext context, int index) { + return PackagesItemCard( + itemModel: viewModel.latestOffersList[index], + onCartClick: onProductCartClick, + ); + }, + ), ), ], ), + ), + SizedBox( + height: 50.0, ) - .setOnAppBarCartClick(onCartClick); - } + ], + ), + ), + bottomSheet: Container( + color: Colors.white, + padding: const EdgeInsets.all(12.0), + child: SizedBox( + height: 43, + width: double.infinity, + child: FlatButton( + onPressed: () { + onCartClick(); + }, + child: Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Padding( + padding: const EdgeInsets.only(left: 8.0, right: 8.0), + child: Icon( + Icons.add_shopping_cart_rounded, + size: 30.0, + color: Colors.white, + ), + ), + Container( + child: Text( + TranslationBase.of(context).shoppingCart, + textAlign: TextAlign.center, + style: TextStyle(fontSize: 16, fontWeight: FontWeight.w600, color: Colors.white, letterSpacing: -0.48), + ), + ), + ], + ), + color: const Color(0xffD02127), + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(6), + ), + ), + ), + ), + ); + }, ); } - - - showClinicSelectionList() async { var clinics = viewModel.service.categoryList; - if(clinics.isEmpty) { + if (clinics.isEmpty) { GifLoaderDialogUtils.showMyDialog(context); clinics = await viewModel.service.getAllCategories(OffersCategoriesRequestModel()); GifLoaderDialogUtils.hideDialog(context); } - List options = clinics.map((e) => e.toString()).toList(); - - showMaterialSelectionPicker( + List list = [ + for (int i = 0; i < clinics.length; i++) RadioSelectionDialogModel(clinics[i].name, i), + ]; + showDialog( context: context, - title: "Select Clinic", - items: options, - selectedItem: options.first, - onChanged: (value) async { - var selectedClinic = clinics.firstWhere((element) => element.toString() == value); - var clinicProducts = await viewModel.service.getAllProducts(request: OffersProductsRequestModel(categoryId: selectedClinic.id), context: context, showLoading: true); - if(clinicProducts.isNotEmpty) - Navigator.of(context).push( - MaterialPageRoute( - builder: (BuildContext context) => ClinicPackagesPage(products: clinicProducts) - ) - ); - else - utils.Utils.showErrorToast("No offers available for this clinic"); - }, + child: RadioSelectionDialog( + listData: list, + selectedIndex: 0, + isScrollable: true, + onValueSelected: (index) async { + selectedClinic = clinics[index]; + var clinicProducts = await viewModel.service.getAllProducts(request: OffersProductsRequestModel(categoryId: selectedClinic.id), context: context, showLoading: true); + if (clinicProducts.isNotEmpty) + Navigator.of(context).push(MaterialPageRoute(builder: (BuildContext context) => ClinicPackagesPage(products: clinicProducts))); + else + utils.Utils.showErrorToast("No offers available for this clinic"); + setState(() {}); + }, + ), ); } @@ -247,182 +279,46 @@ class _PackagesHomePageState extends State with AfterLayoutMix // Main Widgets of Page //---------------------------------- - CarouselSlider bannerCarousel(){ - _bannerCarousel = CarouselSlider.builder( - carouselController: _carouselController, - itemCount: 10, - itemBuilder: (BuildContext context, int itemIndex) { - return Padding( - padding: const EdgeInsets.only(top: 10, bottom: 10, left: 15, right: 15), - child: FractionallySizedBox( - widthFactor: 1, - heightFactor: 1, - child: utils.applyShadow( - spreadRadius: 1, - blurRadius: 5, - child: InkWell( - child: ClipRRect( - borderRadius: BorderRadius.circular(10), - child: utils.Utils.loadNetworkImage(url: "https://wallpaperaccess.com/full/30103.jpg",) - ), - onTap: (){ - Navigator.of(context).push( - MaterialPageRoute( - builder: (BuildContext context) => OfferAndPackagesDetail(model: "",) - ) - ); - }, - ) - ), - ), + Widget latestOfferListView({@required double itemWidth, @required double itemContentPadding}) { + return _listViewLatestOffers = ListView.separated( + scrollDirection: Axis.horizontal, + shrinkWrap: true, + itemCount: viewModel.bestSellerList.length, + itemBuilder: (BuildContext context, int index) { + return PackagesItemCard( + itemWidth: itemWidth, + itemContentPadding: itemContentPadding, + itemModel: viewModel.bestSellerList[index], + onCartClick: onProductCartClick, ); }, - options: CarouselOptions( - autoPlayInterval: Duration(milliseconds: 3500), - enlargeStrategy: CenterPageEnlargeStrategy.scale, - enlargeCenterPage: true, - autoPlay: false, - autoPlayCurve: Curves.fastOutSlowIn, - enableInfiniteScroll: true, - autoPlayAnimationDuration: Duration(milliseconds: 1500), - viewportFraction: 1, - onPageChanged: (page, reason){ - setState(() { - carouselIndicatorIndex = page; - }); - }, - ), + separatorBuilder: separator, ); - return _bannerCarousel; - } - - TextField searchTextField(){ - return _textFieldSearch = - TextField( - controller: _searchTextController, - decoration: InputDecoration( - contentPadding: EdgeInsets.only(top: 0.0, bottom: 0.0, left: 10, right: 10), - enabledBorder: OutlineInputBorder( - borderSide: BorderSide( width: 0.5, color: Colors.grey), - borderRadius: const BorderRadius.all( - const Radius.circular(10.0), - ), - ), - focusedBorder: OutlineInputBorder( - borderSide: BorderSide( width: 1, color: Colors.grey), - borderRadius: const BorderRadius.all( - const Radius.circular(10.0), - ), - ), - filled: true, - fillColor: Colors.white, - hintText: "Search", - hintStyle: TextStyle(color: Colors.grey[350], fontWeight: FontWeight.bold), - suffixIcon: IconButton( - onPressed: (){ - // viewModel.search(text: _searchTextController.text); - }, - icon: Icon(Icons.search_rounded, size: 35,), - ), - ), - ); - } - Widget filterOptionSelection(){ - _textFieldFilterSelection = - TextField( - enabled: false, - controller: _searchTextController, - decoration: InputDecoration( - contentPadding: EdgeInsets.only(top: 0.0, bottom: 0.0, left: 10, right: 10), - border: OutlineInputBorder( - borderSide: BorderSide(color: Colors.grey, width: 1), - borderRadius: const BorderRadius.all( - const Radius.circular(10.0), - ), - ), - disabledBorder: OutlineInputBorder( - borderSide: BorderSide( width: 0.5, color: Colors.grey), - borderRadius: const BorderRadius.all( - const Radius.circular(10.0), - ), - ), - focusedBorder: OutlineInputBorder( - borderRadius: const BorderRadius.all( - const Radius.circular(10.0), - ), - ), - filled: true, - fillColor: Colors.white, - hintText: "Browse offers by Clinic", - hintStyle: TextStyle(color: Colors.grey[350], fontWeight: FontWeight.bold), - suffixIcon: IconButton( - onPressed: (){ - showClinicSelectionList(); - }, - icon: Icon(Icons.keyboard_arrow_down_rounded, size: 35, color: Colors.grey,), - ), - ), + Widget bestSellerListView({@required double itemWidth, @required double itemContentPadding}) { + return _listViewLatestOffers = ListView.separated( + scrollDirection: Axis.horizontal, + itemCount: viewModel.bestSellerList.length, + itemBuilder: (BuildContext context, int index) { + return PackagesItemCard( + itemWidth: itemWidth, + itemContentPadding: itemContentPadding, + itemModel: viewModel.bestSellerList[index], + onCartClick: onProductCartClick, ); - - return InkWell( - child: _textFieldFilterSelection, - onTap: (){ - showClinicSelectionList(); }, + separatorBuilder: separator, ); - } - Widget latestOfferListView({@required double itemWidth, @required double itemContentPadding}){ - return _listViewLatestOffers = - ListView.separated( - scrollDirection: Axis.horizontal, - itemCount: viewModel.bestSellerList.length, - itemBuilder: (BuildContext context, int index) { - return PackagesItemCard(itemWidth: itemWidth, itemContentPadding: itemContentPadding, itemModel: viewModel.bestSellerList[index], onCartClick: onProductCartClick,); - }, - separatorBuilder: separator, - ); - - } - - Widget bestSellerListView({@required double itemWidth, @required double itemContentPadding}){ - return _listViewLatestOffers = - ListView.separated( - scrollDirection: Axis.horizontal, - itemCount: viewModel.bestSellerList.length, - itemBuilder: (BuildContext context, int index) { - return PackagesItemCard(itemWidth: itemWidth, itemContentPadding: itemContentPadding, itemModel: viewModel.bestSellerList[index], onCartClick: onProductCartClick,); - }, - separatorBuilder: separator, - ); - - } - - - Widget separator(BuildContext context, int index){ + Widget separator(BuildContext context, int index) { return Container( width: 1, - decoration: BoxDecoration( - gradient: LinearGradient( - begin: Alignment(-1.0, -2.0), - end: Alignment(1.0, 4.0), - colors: [ - Colors.grey, - Colors.grey[100], - Colors.grey[200], - Colors.grey[300], - Colors.grey[400], - Colors.grey[500] - ] - )), + decoration: BoxDecoration(gradient: LinearGradient(begin: Alignment(-1.0, -2.0), end: Alignment(1.0, 4.0), colors: [Colors.grey, Colors.grey[100], Colors.grey[200], Colors.grey[300], Colors.grey[400], Colors.grey[500]])), ); } - - loginCheck(context) async { var data = await sharedPref.getObject(IMEI_USER_DATA); sharedPref.remove(REGISTER_DATA_FOR_LOGIIN); @@ -449,4 +345,74 @@ class _PackagesHomePageState extends State with AfterLayoutMix }); } } + + Widget inputWidget(String _labelText, String _hintText, TextEditingController _controller, {VoidCallback suffixTap, bool isEnable = true, bool hasSelection = false, int lines, bool isInputTypeNum = false}) { + return Container( + padding: EdgeInsets.only(left: 16, right: 16, bottom: 15, top: 15), + alignment: Alignment.center, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(15), + color: Colors.white, + border: Border.all( + color: Color(0xffefefef), + width: 1, + ), + ), + child: InkWell( + onTap: hasSelection ? () {} : null, + child: Row( + children: [ + Expanded( + child: Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + _labelText, + style: TextStyle( + fontSize: 11, + fontWeight: FontWeight.w600, + color: Color(0xff2B353E), + letterSpacing: -0.44, + ), + ), + TextField( + enabled: isEnable, + scrollPadding: EdgeInsets.zero, + keyboardType: isInputTypeNum ? TextInputType.number : TextInputType.text, + controller: _controller, + maxLines: lines, + onChanged: (value) => {setState(() {})}, + style: TextStyle( + fontSize: 14, + height: 21 / 14, + fontWeight: FontWeight.w400, + color: Color(0xff2B353E), + letterSpacing: -0.44, + ), + decoration: InputDecoration( + isDense: true, + hintText: _hintText, + hintStyle: TextStyle( + fontSize: 14, + height: 21 / 14, + fontWeight: FontWeight.w400, + color: Color(0xff575757), + letterSpacing: -0.56, + ), + contentPadding: EdgeInsets.zero, + border: InputBorder.none, + focusedBorder: InputBorder.none, + enabledBorder: InputBorder.none, + ), + ), + ], + ), + ), + Icon(Icons.search_outlined), + ], + ), + ), + ); + } } diff --git a/lib/widgets/offers_packages/PackagesOfferCard.dart b/lib/widgets/offers_packages/PackagesOfferCard.dart index 2242f01d..470550c6 100644 --- a/lib/widgets/offers_packages/PackagesOfferCard.dart +++ b/lib/widgets/offers_packages/PackagesOfferCard.dart @@ -1,10 +1,14 @@ import 'package:diplomaticquarterapp/core/model/packages_offers/responses/PackagesResponseModel.dart'; +import 'package:diplomaticquarterapp/pages/packages_offers/OfferAndPackageDetailPage.dart'; +import 'package:diplomaticquarterapp/theme/colors.dart'; +import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/uitl/utils.dart'; +import 'package:diplomaticquarterapp/uitl/utils_new.dart'; import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; import 'package:diplomaticquarterapp/widgets/others/StarRating.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; - +import 'package:rating_bar/rating_bar.dart'; bool wide = true; @@ -15,15 +19,7 @@ class PackagesItemCard extends StatefulWidget { final PackagesResponseModel itemModel; final Function(PackagesResponseModel product) onCartClick; - const PackagesItemCard( - { - this.itemWidth, - this.itemHeight, - @required this.itemModel, - @required this.itemContentPadding, - @required this.onCartClick, - Key key}) - : super(key: key); + const PackagesItemCard({this.itemWidth, this.itemHeight, @required this.itemModel, @required this.itemContentPadding, @required this.onCartClick, Key key}) : super(key: key); @override State createState() => PackagesItemCardState(); @@ -35,123 +31,138 @@ class PackagesItemCardState extends State { @override Widget build(BuildContext context) { wide = !wide; - return Directionality( - textDirection: TextDirection.rtl, - child: Stack( - children: [ - Padding( - padding: EdgeInsets.only( - left: widget.itemContentPadding, - right: widget.itemContentPadding, - top: widget.itemContentPadding + 5), - child: Container( - width: widget.itemWidth, - color: Colors.transparent, - child: Stack( + return InkWell( + onTap: () { + Navigator.of(context).push(MaterialPageRoute(builder: (BuildContext context) => OfferAndPackagesDetail(itemModel: widget.itemModel))); + }, + child: Container( + // width: widget.itemWidth, + // color: Colors.transparent, + decoration: cardRadius(15.0), + width: MediaQuery.of(context).size.width * 0.46, + padding: const EdgeInsets.all(9.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + ClipRRect( + borderRadius: BorderRadius.circular(15.0), + child: Image.network("https://mdlaboratories.com/offersdiscounts/images/thumbs/0000162_dermatology-testing.jpeg", fit: BoxFit.fill, height: 180.0, width: 180.0), + ), + Container(margin: const EdgeInsets.only(top: 8.0), child: Text(widget.itemModel.name, maxLines: 1, style: TextStyle(fontSize: 14.0, fontWeight: FontWeight.bold, letterSpacing: -0.56))), + Container(width: MediaQuery.of(context).size.width * 0.4, child: Text("Special discount for all HMG Employees and their first…", maxLines: 2, style: TextStyle(fontSize: 10.0, fontWeight: FontWeight.w600, letterSpacing: -0.4, color: CustomColors.textColor), overflow: TextOverflow.clip)), + if (widget.itemModel.hasDiscountsApplied) Container(margin: const EdgeInsets.only(top: 19.0), child: Text(widget.itemModel.oldPrice.toString() + " " + TranslationBase.of(context).sar, style: TextStyle(fontSize: 9.0, fontWeight: FontWeight.w600, letterSpacing: -0.36, decoration: TextDecoration.lineThrough, color: CustomColors.grey2))), + Container( + margin: widget.itemModel.hasDiscountsApplied ? const EdgeInsets.only(top: 0.0) : const EdgeInsets.only(top: 19.0), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Column( - mainAxisSize: MainAxisSize.max, + crossAxisAlignment: CrossAxisAlignment.start, children: [ - AspectRatio( - aspectRatio:1 / 1, - child: applyShadow( - child: ClipRRect( - borderRadius: BorderRadius.circular(10), - child: Utils.loadNetworkImage( - url: imageUrl(), - )), - )), - Texts( - widget.itemModel.getName(), - fontWeight: FontWeight.normal, - color: Colors.black, - fontSize: 15 - ), - Padding( - padding: const EdgeInsets.only(left: 10, right: 10), - child: Row( - crossAxisAlignment: CrossAxisAlignment.end, - mainAxisSize: MainAxisSize.max, - children: [ - Stack( - children: [ - Texts( - '${widget.itemModel.oldPrice} ${'SAR'}', - fontWeight: FontWeight.normal, - decoration: TextDecoration.lineThrough, - color: Colors.grey, - fontSize: 12 - ), - Padding( - padding: const EdgeInsets.only(top: 8), - child: Texts( - '${widget.itemModel.price} ${'SAR'}', - fontWeight: FontWeight.bold, - color: Colors.green, - fontSize: 18 - ), - ), - Padding( - padding: const EdgeInsets.only(top: 35), - child: StarRating( - size: 15, - totalCount: null, - totalAverage: widget.itemModel.approvedRatingSum.toDouble(), - forceStars: true), - ) - ], - ), - Spacer( - flex: 1, - ), - InkWell( - child: Icon( - Icons.add_shopping_cart_rounded, - size: 30.0, - color: Colors.grey, - ), - onTap: () { - widget.onCartClick(widget.itemModel); - }, - ), - ], - ), + Container(margin: const EdgeInsets.only(top: 0.0), child: Text(widget.itemModel.price.toString().trim() + " " + TranslationBase.of(context).sar, style: TextStyle(fontSize: 12.0, fontWeight: FontWeight.bold, letterSpacing: -0.56))), + RatingBar.readOnly( + initialRating: 4.5, + size: 18.0, + filledColor: Color(0XFFD02127), + emptyColor: Color(0XFFD02127), + isHalfAllowed: true, + halfFilledIcon: Icons.star_half, + filledIcon: Icons.star, + emptyIcon: Icons.star_border, ), ], ), + InkWell( + child: Icon( + Icons.add_shopping_cart_rounded, + size: 30.0, + color: Colors.black, + ), + onTap: () { + widget.onCartClick(widget.itemModel); + }, + ), ], ), ), - ), - Positioned( - top: 0, - right: 0, - child: Visibility( - visible: false, - child: InkWell( - child: Icon( - Icons.favorite, - size: 40.0, - color: Colors.red, - ), - onTap: () { - - }, - ), - ), - ), - - Positioned( - top: 7, - left: 2, - child: Image.asset( - 'assets/images/discount_${'en'}.png', - height: 60, - width: 60, - ), - ), - ], + ], + ), ), ); + // Stack( + // children: [ + // Column( + // mainAxisSize: MainAxisSize.max, + // children: [ + // AspectRatio( + // aspectRatio:1 / 1, + // child: applyShadow( + // child: ClipRRect( + // borderRadius: BorderRadius.circular(10), + // child: Utils.loadNetworkImage( + // url: imageUrl(), + // )), + // )), + // Texts( + // widget.itemModel.getName(), + // fontWeight: FontWeight.normal, + // color: Colors.black, + // fontSize: 15 + // ), + // Padding( + // padding: const EdgeInsets.only(left: 10, right: 10), + // child: Row( + // crossAxisAlignment: CrossAxisAlignment.end, + // mainAxisSize: MainAxisSize.max, + // children: [ + // Stack( + // children: [ + // Texts( + // '${widget.itemModel.oldPrice} ${'SAR'}', + // fontWeight: FontWeight.normal, + // decoration: TextDecoration.lineThrough, + // color: Colors.grey, + // fontSize: 12 + // ), + // Padding( + // padding: const EdgeInsets.only(top: 8), + // child: Texts( + // '${widget.itemModel.price} ${'SAR'}', + // fontWeight: FontWeight.bold, + // color: Colors.green, + // fontSize: 18 + // ), + // ), + // Padding( + // padding: const EdgeInsets.only(top: 35), + // child: StarRating( + // size: 15, + // totalCount: null, + // totalAverage: widget.itemModel.approvedRatingSum.toDouble(), + // forceStars: true), + // ) + // ], + // ), + // Spacer( + // flex: 1, + // ), + // InkWell( + // child: Icon( + // Icons.add_shopping_cart_rounded, + // size: 30.0, + // color: Colors.grey, + // ), + // onTap: () { + // widget.onCartClick(widget.itemModel); + // }, + // ), + // ], + // ), + // ), + // ], + // ), + // ], + // ), + // ); } }