Merge branch 'development' of https://gitlab.com/Cloud_Solution/diplomatic-quarter into fix_product_tile

 Conflicts:
	lib/pages/pharmacies/ProductCheckTypeWidget.dart
	lib/pages/pharmacies/screens/cart-order-page.dart
	lib/pages/pharmacies/screens/pharmacy_module_page.dart
merge-requests/421/head
Mohammad Aljammal 5 years ago
commit 0150bc4684

@ -1555,6 +1555,7 @@ const Map localizedValues = {
"quantitySize": {"en": "Quantity", "ar": "كميه"}, "quantitySize": {"en": "Quantity", "ar": "كميه"},
"addToCart": {"en": "Add to Cart", "ar": "إضف للسلة"}, "addToCart": {"en": "Add to Cart", "ar": "إضف للسلة"},
"addToWishlist": {"en": "Add to Wishlist", "ar": "اضف للمفضلة"}, "addToWishlist": {"en": "Add to Wishlist", "ar": "اضف للمفضلة"},
"removeFromWishlist": {"en": "Remove From Wishlist", "ar": "احذف للمفضلة"},
"noData": {"en": "There is no data", "ar": "لايوجد بيانات"}, "noData": {"en": "There is no data", "ar": "لايوجد بيانات"},
"no_data": {"en": "No data", "ar": "لايوجد بيانات"}, "no_data": {"en": "No data", "ar": "لايوجد بيانات"},
"buyNow": {"en": "buy now", "ar": "إشتري الان"}, "buyNow": {"en": "buy now", "ar": "إشتري الان"},

@ -113,6 +113,7 @@ class PharmacyModuleService extends BaseService {
} }
Future getTopManufacturerList() async { Future getTopManufacturerList() async {
if (manufacturerList.isNotEmpty) return;
Map<String, String> queryParams = {'page': '1', 'limit': '8'}; Map<String, String> queryParams = {'page': '1', 'limit': '8'};
try { try {
await baseAppClient.getPharmacy(GET_PHARMACY_TOP_MANUFACTURER, await baseAppClient.getPharmacy(GET_PHARMACY_TOP_MANUFACTURER,
@ -121,7 +122,7 @@ class PharmacyModuleService extends BaseService {
response['manufacturer'].forEach((item) { response['manufacturer'].forEach((item) {
Manufacturer manufacturer = Manufacturer.fromJson(item); Manufacturer manufacturer = Manufacturer.fromJson(item);
// if (manufacturer.image != null) { // if (manufacturer.image != null) {
manufacturerList.add(Manufacturer.fromJson(item)); manufacturerList.add(Manufacturer.fromJson(item));
// } // }
}); });
hasError = false; hasError = false;
@ -135,6 +136,8 @@ class PharmacyModuleService extends BaseService {
} }
Future getBestSellerProducts() async { Future getBestSellerProducts() async {
if (bestSellerProducts.isNotEmpty) return;
Map<String, String> queryParams = { Map<String, String> queryParams = {
'fields': 'fields':
'id,discount_ids,name,namen,localized_names,display_order,short_description,full_description,full_descriptionn,sku,order_minimum_quantity,order_maximum_quantity,price,old_price,images,is_rx,rx_message,rx_messagen,discount_name,discount_namen,approved_rating_sum,approved_total_reviews,allow_back_in_stock_subscriptions,stock_quantity,stock_availability,stock_availabilityn,discount_percentage,reviews', 'id,discount_ids,name,namen,localized_names,display_order,short_description,full_description,full_descriptionn,sku,order_minimum_quantity,order_maximum_quantity,price,old_price,images,is_rx,rx_message,rx_messagen,discount_name,discount_namen,approved_rating_sum,approved_total_reviews,allow_back_in_stock_subscriptions,stock_quantity,stock_availability,stock_availabilityn,discount_percentage,reviews',
@ -173,7 +176,8 @@ class PharmacyModuleService extends BaseService {
}); });
hasError = false; hasError = false;
}, onFailure: (String error, int statusCode) { }, onFailure: (String error, int statusCode) {
hasError = true; // sharedPref.setString(PHARMACY_LAST_VISITED_PRODUCTS, ""); hasError =
true; // sharedPref.setString(PHARMACY_LAST_VISITED_PRODUCTS, "");
super.error = error; super.error = error;
}); });
} catch (error) { } catch (error) {

@ -13,15 +13,16 @@ class PrescriptionViewModel extends BaseViewModel {
_prescriptionService.prescriptionsList; _prescriptionService.prescriptionsList;
getPrescription() async { getPrescription() async {
setState(ViewState.Busy);
await getSavedLanguage(); await getSavedLanguage();
await _prescriptionService.getPrescription(); if(prescriptionsList.isNotEmpty){
if (_prescriptionService.hasError) { setState(ViewState.Busy);
error = _prescriptionService.error; await _prescriptionService.getPrescription();
setState(ViewState.Error); if (_prescriptionService.hasError) {
} else { error = _prescriptionService.error;
setState(ViewState.Idle); setState(ViewState.Error);
} else {
setState(ViewState.Idle);
}
} }
} }
} }

@ -5,6 +5,8 @@ import 'package:diplomaticquarterapp/models/pharmacy/locationModel.dart';
import 'package:diplomaticquarterapp/models/pharmacy/productDetailModel.dart'; import 'package:diplomaticquarterapp/models/pharmacy/productDetailModel.dart';
import 'package:diplomaticquarterapp/services/pharmacy_services/product_detail_service.dart'; import 'package:diplomaticquarterapp/services/pharmacy_services/product_detail_service.dart';
import 'package:diplomaticquarterapp/models/pharmacy/specification.dart'; import 'package:diplomaticquarterapp/models/pharmacy/specification.dart';
import 'package:diplomaticquarterapp/uitl/gif_loader_dialog_utils.dart';
import 'package:diplomaticquarterapp/uitl/navigation_service.dart';
import '../../../locator.dart'; import '../../../locator.dart';
@ -36,7 +38,7 @@ class ProductDetailViewModel extends BaseViewModel{
Future getProductLocationData() async { Future getProductLocationData() async {
hasError = false; hasError = false;
setState(ViewState.Busy); setState(ViewState.BusyLocal);
await _productDetailService.getProductAvailabiltyDetail(); await _productDetailService.getProductAvailabiltyDetail();
if (_productDetailService.hasError) { if (_productDetailService.hasError) {
error = _productDetailService.error; error = _productDetailService.error;
@ -69,8 +71,13 @@ class ProductDetailViewModel extends BaseViewModel{
Future addToWishlistData(itemID) async { Future addToWishlistData(itemID) async {
hasError = false; hasError = false;
setState(ViewState.Busy); setState(ViewState.BusyLocal);
GifLoaderDialogUtils.showMyDialog(
locator<NavigationService>().navigatorKey.currentContext);
await _productDetailService.addToWishlist(itemID); await _productDetailService.addToWishlist(itemID);
GifLoaderDialogUtils.hideDialog(
locator<NavigationService>().navigatorKey.currentContext);
if (_productDetailService.hasError) { if (_productDetailService.hasError) {
error = _productDetailService.error; error = _productDetailService.error;
setState(ViewState.ErrorLocal); setState(ViewState.ErrorLocal);
@ -90,10 +97,15 @@ class ProductDetailViewModel extends BaseViewModel{
} }
Future deletWishlistData(itemID) async { Future deleteWishlistData(itemID) async {
hasError = false; hasError = false;
setState(ViewState.Busy); setState(ViewState.BusyLocal);
await _productDetailService.delteItemFromWishlist(itemID); GifLoaderDialogUtils.showMyDialog(
locator<NavigationService>().navigatorKey.currentContext);
await _productDetailService.deleteItemFromWishlist(itemID);
GifLoaderDialogUtils.hideDialog(
locator<NavigationService>().navigatorKey.currentContext);
if (_productDetailService.hasError) { if (_productDetailService.hasError) {
error = _productDetailService.error; error = _productDetailService.error;
setState(ViewState.ErrorLocal); setState(ViewState.ErrorLocal);
@ -113,4 +125,10 @@ class ProductDetailViewModel extends BaseViewModel{
setState(ViewState.Idle); setState(ViewState.Idle);
} }
clearReview(){
productDetailService.clear();
}
} }

@ -51,6 +51,9 @@ class _PickupLocationState extends State<PickupLocation> {
void initState() { void initState() {
super.initState(); super.initState();
_getCurrentLocation(); _getCurrentLocation();
setState(() {
});
} }
_getCurrentLocation() async { _getCurrentLocation() async {
@ -61,6 +64,7 @@ class _PickupLocationState extends State<PickupLocation> {
_longitude = 0; _longitude = 0;
_latitude = 0; _latitude = 0;
}); });
} }
@override @override
@ -89,8 +93,8 @@ class _PickupLocationState extends State<PickupLocation> {
context, context,
FadePage( FadePage(
page: PickupLocationFromMap( page: PickupLocationFromMap(
latitude: _latitude, latitude: _latitude??0,
longitude: _longitude, longitude: _longitude??0,
onPick: (value) { onPick: (value) {
setState(() { setState(() {
_result = value; _result = value;

@ -49,7 +49,6 @@ class _FinalProductsPageState extends State<FinalProductsPage> {
Widget build(BuildContext context) { Widget build(BuildContext context) {
return BaseView<PharmacyCategoriseViewModel>( return BaseView<PharmacyCategoriseViewModel>(
onModelReady: (model) { onModelReady: (model) {
//TODO Elham* fix all services in order handel errors in better way in the service
if (widget.productType == 1) { if (widget.productType == 1) {
model.getFinalProducts(i: id); model.getFinalProducts(i: id);
appBarTitle = TranslationBase.of(context).products; appBarTitle = TranslationBase.of(context).products;

@ -2,6 +2,7 @@ import 'package:barcode_scan_fix/barcode_scan.dart';
import 'package:diplomaticquarterapp/config/config.dart'; import 'package:diplomaticquarterapp/config/config.dart';
import 'package:diplomaticquarterapp/core/model/pharmacies/PharmacyProduct.dart'; import 'package:diplomaticquarterapp/core/model/pharmacies/PharmacyProduct.dart';
import 'package:diplomaticquarterapp/core/service/client/base_app_client.dart'; import 'package:diplomaticquarterapp/core/service/client/base_app_client.dart';
import 'package:diplomaticquarterapp/core/service/parmacyModule/parmacy_module_service.dart';
import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart';
import 'package:diplomaticquarterapp/pages/pharmacies/screens/product-details/product-detail.dart'; import 'package:diplomaticquarterapp/pages/pharmacies/screens/product-details/product-detail.dart';
import 'package:diplomaticquarterapp/pages/pharmacies/screens/cart-order-page.dart'; import 'package:diplomaticquarterapp/pages/pharmacies/screens/cart-order-page.dart';
@ -18,6 +19,8 @@ import 'package:diplomaticquarterapp/widgets/pharmacy/bottom_nav_pharmacy_bar.da
import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import '../../locator.dart';
class LandingPagePharmacy extends StatefulWidget { class LandingPagePharmacy extends StatefulWidget {
@override @override
_LandingPagePharmacyState createState() => _LandingPagePharmacyState(); _LandingPagePharmacyState createState() => _LandingPagePharmacyState();
@ -37,93 +40,102 @@ class _LandingPagePharmacyState extends State<LandingPagePharmacy> {
void initState() { void initState() {
super.initState(); super.initState();
locator<PharmacyModuleService>().manufacturerList = [];
locator<PharmacyModuleService>().bestSellerProducts = [];
locator<PharmacyModuleService>().lastVisitedProducts = [];
pageController = PageController(keepPage: true); pageController = PageController(keepPage: true);
} }
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Scaffold( return WillPopScope(
appBar: currentTab != 4 && currentTab != 3 onWillPop: ()async{
? AppBar( return false;
backgroundColor: Color(0xff5AB145), },
elevation: 0, child: Scaffold(
title: Container( appBar: currentTab != 4 && currentTab != 3
height: MediaQuery.of(context).size.height * 0.056, ? AppBar(
decoration: BoxDecoration( backgroundColor: Color(0xff5AB145),
borderRadius: BorderRadius.circular(5.0), elevation: 0,
color: Colors.white, title: Container(
), height: MediaQuery.of(context).size.height * 0.056,
child: InkWell( decoration: BoxDecoration(
child: Padding( borderRadius: BorderRadius.circular(5.0),
padding: EdgeInsets.all(5.0), color: Colors.white,
child: Row( ),
//crossAxisAlignment: CrossAxisAlignment.center, child: InkWell(
mainAxisAlignment: MainAxisAlignment.start, child: Padding(
children: [ padding: EdgeInsets.all(5.0),
Icon(Icons.search, size: 25.0), child: Row(
SizedBox( //crossAxisAlignment: CrossAxisAlignment.center,
width: 15.0, mainAxisAlignment: MainAxisAlignment.start,
), children: [
Texts( Icon(Icons.search, size: 25.0),
TranslationBase.of(context).searchProductHere, SizedBox(
fontSize: 13, width: 15.0,
) ),
], Texts(
TranslationBase.of(context).searchProductHere,
fontSize: 13,
)
],
),
), ),
onTap: () {
Navigator.push(
context,
FadePage(page: SearchProductsPage()),
);
},
), ),
onTap: () { ),
Navigator.push( leading: Builder(
context, builder: (BuildContext context) {
FadePage(page: SearchProductsPage()), return InkWell(
onTap: () {
setState(() {
currentTab = 0;
pageController.jumpToPage(0);
});
},
child: Container(
height: 2.0,
width: 10.0,
child: Image.asset(
'assets/images/pharmacy_logo.png',
),
),
); );
}, },
), ),
), actions: [
leading: Builder( IconButton(
builder: (BuildContext context) { // iconSize: 70,
return InkWell( icon: Image.asset(
onTap: () { 'assets/images/new-design/qr-code.png',
setState(() {
currentTab = 0;
pageController.jumpToPage(0);
});
},
child: Container(
height: 2.0,
width: 10.0,
child: Image.asset(
'assets/images/pharmacy_logo.png',
), ),
), onPressed: _scanQrAndGetProduct //do something,
); )
}, ],
), centerTitle: true,
actions: [ )
IconButton( : null,
// iconSize: 70, extendBody: false,
icon: Image.asset( body: PageView(
'assets/images/new-design/qr-code.png', physics: NeverScrollableScrollPhysics(),
), controller: pageController,
onPressed: _scanQrAndGetProduct //do something, children: [
) PharmacyPage(),
], PharmacyCategorisePage(),
centerTitle: true, PharmacyProfilePage(),
) CartOrderPage(),
: null, ],
extendBody: false, ),
body: PageView( bottomNavigationBar: BottomNavPharmacyBar(
physics: NeverScrollableScrollPhysics(), changeIndex: _changeCurrentTab,
controller: pageController, index: currentTab,
children: [ ),
PharmacyPage(),
PharmacyCategorisePage(),
PharmacyProfilePage(),
CartOrderPage(),
],
),
bottomNavigationBar: BottomNavPharmacyBar(
changeIndex: _changeCurrentTab,
index: currentTab,
), ),
); );
} }

@ -47,7 +47,7 @@ class _ProductCheckTypeWidgetState extends State<ProductCheckTypeWidget> {
deleteWishListItem(itemID) async { deleteWishListItem(itemID) async {
ProductDetailViewModel x = new ProductDetailViewModel(); ProductDetailViewModel x = new ProductDetailViewModel();
GifLoaderDialogUtils.showMyDialog(context); GifLoaderDialogUtils.showMyDialog(context);
await x.deletWishlistData(itemID); await x.deleteWishlistData(itemID);
await widget.model.getWishlistData(isLocalLoader: true); await widget.model.getWishlistData(isLocalLoader: true);
GifLoaderDialogUtils.hideDialog(context); GifLoaderDialogUtils.hideDialog(context);
} }

@ -137,7 +137,7 @@ reviewDetails(data, rate, myRate) {
: Alignment.topLeft, : Alignment.topLeft,
child: RichText( child: RichText(
text: TextSpan( text: TextSpan(
text: data.product.price.toString() + text: data.product.quantity.toString() +
" " + " " +
data.product.currency, data.product.currency,
style: TextStyle( style: TextStyle(

@ -46,6 +46,7 @@ class _CartOrderPageState extends State<CartOrderPage> {
isShowAppBar: true, isShowAppBar: true,
isPharmacy: true, isPharmacy: true,
showHomeAppBarIcon: false, showHomeAppBarIcon: false,
isShowDecPage: true,
baseViewModel: model, baseViewModel: model,
backgroundColor: Colors.white, backgroundColor: Colors.white,
body: !(model.cartResponse.shoppingCarts == null || body: !(model.cartResponse.shoppingCarts == null ||

@ -48,7 +48,11 @@ class _PharmacyPageState extends State<PharmacyPage> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return BaseView<PharmacyModuleViewModel>( return WillPopScope(
onWillPop: ()async{
return false;
},
child:BaseView<PharmacyModuleViewModel>(
onModelReady: (model) async { onModelReady: (model) async {
await model.getSavedLanguage(); await model.getSavedLanguage();
await model.getBannerList(); await model.getBannerList();
@ -73,7 +77,7 @@ class _PharmacyPageState extends State<PharmacyPage> {
ShopByBrandWidget(), ShopByBrandWidget(),
RecentlyViewedWidget(), RecentlyViewedWidget(),
BestSellerWidget(), BestSellerWidget(),
], ],),
), ),
), ),
), ),

@ -1,66 +0,0 @@
import 'package:flutter/material.dart';
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
import '../cart-order-page.dart';
import 'CustomIcon.dart';
class ProductAppBar extends StatelessWidget with PreferredSizeWidget {
@override
Widget build(BuildContext context) {
return Container(
color: Colors.white,
child: Column(
children: [
SizedBox(
height: 30,
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Row(
children: [
IconWithBg(
icon: Icons.arrow_back_ios,
color: Colors.grey,
onPress: () {
Navigator.pop(context);
},
),
],
),
Row(
children: [
IconWithBg(
icon: Icons.shopping_cart,
color: Colors.grey,
onPress: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => CartOrderPage()),
);
}),
IconWithBg(
icon: FontAwesomeIcons.ellipsisV,
color: Colors.grey,
onPress: () {
//TODO Elham*
// settingModalBottomSheet(context);
},
),
],
)
],
),
],
),
);
}
@override
// TODO: implement preferredSize
@override
Size get preferredSize => Size(double.maxFinite, 50);
}

@ -6,80 +6,85 @@ import 'package:diplomaticquarterapp/widgets/others/network_base_view.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
class AvailabilityInfo extends StatelessWidget { class AvailabilityInfo extends StatelessWidget {
final ProductDetailViewModel previousModel;
const AvailabilityInfo({Key key, this.previousModel}) : super(key: key);
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return BaseView<ProductDetailViewModel>( return previousModel.productLocationService.length == 0
onModelReady: (model) => model.getProductLocationData(), ? Container(
padding: EdgeInsets.all(15),
builder: (_, model, wi) => NetworkBaseView( alignment: Alignment.center,
baseViewModel: model, child: Text(
child: model.productLocationService.length == 0 TranslationBase.of(context).noLocationAvailable,
? Container( ),
padding: EdgeInsets.all(15), )
alignment: Alignment.center, : ListView.builder(
child: Text( physics: ScrollPhysics(),
TranslationBase.of(context).noLocationAvailable, scrollDirection: Axis.vertical,
), shrinkWrap: true,
) itemCount: previousModel.productLocationService.length,
: ListView.builder( itemBuilder: (BuildContext context, int index) {
physics: ScrollPhysics(), return Padding(
scrollDirection: Axis.vertical, padding: EdgeInsets.all(8.0),
shrinkWrap: true, child: Column(
itemCount: model.productLocationService.length, children: [
itemBuilder: (BuildContext context, int index) { Row(
return Padding( mainAxisAlignment: MainAxisAlignment.start,
padding: EdgeInsets.all(8.0), children: [
child: Column( Expanded(
children: [ flex: 1,
Row( child: Image.network(previousModel
mainAxisAlignment: MainAxisAlignment.start, .productLocationService[index].projectImageUrl),
children: [ ),
Expanded( SizedBox(
flex: 1, width: 10,
child: Image.network(model ),
.productLocationService[index].projectImageUrl), Expanded(
), flex: 4,
SizedBox( child: Text(
width: 10, previousModel.productLocationService[index]
), .locationDescription +
Expanded( "\n" +
flex: 4, convertCityName(
child: Text( previousModel.productLocationService[0].cityName
model.productLocationService[index] .toString(),
.locationDescription + ),
"\n" + style: TextStyle(fontSize: 12),
convertCityName( ),
model.productLocationService[0].cityName ),
.toString(), Expanded(
), flex: 1,
style: TextStyle(fontSize: 12), child: IconButton(
), icon: Icon(Icons.location_on),
), color: Colors.red,
Expanded( onPressed: () {},
flex: 1, ),
child: IconButton( ),
icon: Icon(Icons.location_on), Expanded(
color: Colors.red, flex: 1,
onPressed: () {}, child: IconButton(
), icon: Icon(Icons.phone),
), color: Colors.red,
Expanded( onPressed: () {},
flex: 1,
child: IconButton(
icon: Icon(Icons.phone),
color: Colors.red,
onPressed: () {},
),
),
],
),
Divider(height: 1.2, color: Colors.grey)
],
), ),
); ),
}, ],
), ),
), Divider(height: 1.2, color: Colors.grey)
],
),
);
},
); );
} }
convertCityName(txt) {
String stringTxt;
String newTxt;
stringTxt = txt.toString();
newTxt = stringTxt.split('.')[1];
return newTxt;
}
} }

@ -1,5 +1,4 @@
import 'package:diplomaticquarterapp/core/model/pharmacies/PharmacyProduct.dart'; import 'package:diplomaticquarterapp/core/model/pharmacies/PharmacyProduct.dart';
import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
class DiscountDescription extends StatelessWidget { class DiscountDescription extends StatelessWidget {

@ -1,4 +1,5 @@
import 'package:diplomaticquarterapp/core/model/pharmacies/PharmacyProduct.dart'; import 'package:diplomaticquarterapp/core/model/pharmacies/PharmacyProduct.dart';
import 'package:diplomaticquarterapp/core/service/AuthenticatedUserObject.dart';
import 'package:diplomaticquarterapp/pages/pharmacies/screens/product-details/footor/quantity_box.dart'; import 'package:diplomaticquarterapp/pages/pharmacies/screens/product-details/footor/quantity_box.dart';
import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart';
import 'package:diplomaticquarterapp/widgets/buttons/secondary_button.dart'; import 'package:diplomaticquarterapp/widgets/buttons/secondary_button.dart';
@ -6,6 +7,8 @@ import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:hexcolor/hexcolor.dart'; import 'package:hexcolor/hexcolor.dart';
import '../../../../../locator.dart';
import '../../../../../routes.dart';
import '../../cart-order-page.dart'; import '../../cart-order-page.dart';
class FooterWidget extends StatefulWidget { class FooterWidget extends StatefulWidget {
@ -16,20 +19,22 @@ class FooterWidget extends StatefulWidget {
final PharmacyProduct item; final PharmacyProduct item;
final Function addToCartFunction; final Function addToCartFunction;
int price; int quantity;
bool isOverQuantity; bool isOverQuantity;
FooterWidget(this.isAvailable, this.maxQuantity, this.minQuantity, FooterWidget(this.isAvailable, this.maxQuantity, this.minQuantity,
this.quantityLimit, this.item, this.quantityLimit, this.item,
{this.price, this.isOverQuantity = false, this.addToCartFunction}); {this.quantity, this.isOverQuantity = false, this.addToCartFunction});
@override @override
_FooterWidgetState createState() => _FooterWidgetState(); _FooterWidgetState createState() => _FooterWidgetState();
} }
class _FooterWidgetState extends State<FooterWidget> { class _FooterWidgetState extends State<FooterWidget> {
double quantityUI = 70; double quantityUI = 80;
bool showUI = false; bool showUI = false;
AuthenticatedUserObject authenticatedUserObject =
locator<AuthenticatedUserObject>();
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
@ -72,7 +77,7 @@ class _FooterWidgetState extends State<FooterWidget> {
child: Icon(Icons.close, color: Colors.black), child: Icon(Icons.close, color: Colors.black),
onTap: () { onTap: () {
setState(() { setState(() {
quantityUI = 70; quantityUI = 80;
showUI = false; showUI = false;
}); });
}, },
@ -92,7 +97,7 @@ class _FooterWidgetState extends State<FooterWidget> {
QuantityBox( QuantityBox(
label: i, label: i,
onTapFunc: onChangeValue, onTapFunc: onChangeValue,
isSelected: widget.price == i), isSelected: widget.quantity == i),
Column( Column(
children: [ children: [
Container( Container(
@ -106,14 +111,14 @@ class _FooterWidgetState extends State<FooterWidget> {
decoration: InputDecoration( decoration: InputDecoration(
labelText: 'quantity #'), labelText: 'quantity #'),
onChanged: (text) { onChanged: (text) {
print(widget.price); print(widget.quantity);
print(widget.quantityLimit); print(widget.quantityLimit);
if (int.tryParse(text) == null) { if (int.tryParse(text) == null) {
text = ''; text = '';
} else { } else {
setState(() { setState(() {
widget.price = int.parse(text); widget.quantity = int.parse(text);
if (widget.price >= if (widget.quantity >=
widget.quantityLimit) { widget.quantityLimit) {
widget.isOverQuantity = true; widget.isOverQuantity = true;
} else { } else {
@ -151,7 +156,7 @@ class _FooterWidgetState extends State<FooterWidget> {
Expanded( Expanded(
flex: 4, flex: 4,
child: Text( child: Text(
widget.price.toString(), widget.quantity.toString(),
style: TextStyle(fontSize: 20), style: TextStyle(fontSize: 20),
), ),
), ),
@ -167,7 +172,7 @@ class _FooterWidgetState extends State<FooterWidget> {
onPressed: () { onPressed: () {
setState(() { setState(() {
if (showUI) { if (showUI) {
quantityUI = 70; quantityUI = 80;
showUI = false; showUI = false;
} else { } else {
quantityUI = 150; quantityUI = 150;
@ -178,41 +183,49 @@ class _FooterWidgetState extends State<FooterWidget> {
), ),
), ),
Container( Container(
width: MediaQuery.of(context).size.width * 0.4, width: MediaQuery.of(context).size.width * 0.45,
child: SecondaryButton( child: SecondaryButton(
label: TranslationBase.of(context).addToCart.toUpperCase(), label: TranslationBase.of(context).addToCart.toUpperCase(),
disabled: !widget.isAvailable && widget.price > 0 || disabled: !widget.isAvailable && widget.quantity > 0 ||
widget.price > widget.quantityLimit || widget.quantity > widget.quantityLimit ||
widget.item.rxMessage != null, widget.item.rxMessage != null,
onTap: () { disableColor: Color(0xFF4CAF50),
widget.addToCartFunction( onTap: () async {
widget.price, widget.item.id, context); if (!authenticatedUserObject.isLogin) {
Navigator.of(context).pushNamed(
WELCOME_LOGIN,
);
} else
await widget.addToCartFunction(
widget.quantity, widget.item.id, context);
}, },
borderColor: Color(0xFF4CAF50),
borderRadius: 5, borderRadius: 5,
color: Colors.green, color: Color(0xFF4CAF50),
), ),
), ),
SizedBox( SizedBox(
width: 5, width: 5,
), ),
Container( Container(
width: MediaQuery.of(context).size.width * 0.3, width: MediaQuery.of(context).size.width * 0.35,
child: SecondaryButton( child: SecondaryButton(
label: TranslationBase.of(context).buyNow.toUpperCase(), label: TranslationBase.of(context).buyNow.toUpperCase(),
disabled: !widget.isAvailable && widget.price > 0 || disabled: !widget.isAvailable && widget.quantity > 0 ||
widget.price > widget.quantityLimit || widget.quantity > widget.quantityLimit ||
widget.item.rxMessage != null, widget.item.rxMessage != null,
onTap: () { onTap: () async {
widget.addToCartFunction( await widget.addToCartFunction(
widget.price, widget.item.id, context); widget.quantity, widget.item.id, context);
Navigator.push( Navigator.push(
context, context,
FadePage(page: CartOrderPage()), FadePage(page: CartOrderPage()),
); );
}, },
borderRadius: 5, borderRadius: 5,
color: !widget.isAvailable && widget.price > 0 || disableColor: Colors.grey[700],
widget.price > widget.quantityLimit || color: !widget.isAvailable && widget.quantity > 0 ||
widget.quantity > widget.quantityLimit ||
widget.item.rxMessage != null widget.item.rxMessage != null
? Colors.grey ? Colors.grey
: Colors.grey[800], : Colors.grey[800],
@ -227,13 +240,12 @@ class _FooterWidgetState extends State<FooterWidget> {
onChangeValue(int i) { onChangeValue(int i) {
setState(() { setState(() {
///TODO Elham* Check this if its good widget.quantity = i;
widget.price = i; if (widget.quantity >= widget.quantityLimit) {
if (widget.price >= widget.quantityLimit) {
widget.isOverQuantity = true; widget.isOverQuantity = true;
} else { } else {
widget.isOverQuantity = false; widget.isOverQuantity = false;
return widget.price; return widget.quantity;
} }
}); });
} }

@ -1,4 +1,5 @@
import 'package:diplomaticquarterapp/core/model/pharmacies/PharmacyProduct.dart'; import 'package:diplomaticquarterapp/core/model/pharmacies/PharmacyProduct.dart';
import 'package:diplomaticquarterapp/core/service/AuthenticatedUserObject.dart';
import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart';
import 'package:diplomaticquarterapp/uitl/gif_loader_dialog_utils.dart'; import 'package:diplomaticquarterapp/uitl/gif_loader_dialog_utils.dart';
import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart';
@ -8,7 +9,8 @@ import 'package:font_awesome_flutter/font_awesome_flutter.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
import 'package:rating_bar/rating_bar.dart'; import 'package:rating_bar/rating_bar.dart';
import 'CustomIcon.dart'; import '../../../../locator.dart';
import 'shared/icon_with_bg.dart';
class ProductNameAndPrice extends StatefulWidget { class ProductNameAndPrice extends StatefulWidget {
BuildContext context; BuildContext context;
@ -19,6 +21,9 @@ class ProductNameAndPrice extends StatefulWidget {
final Function addToWishlistFunction; final Function addToWishlistFunction;
final Function deleteFromWishlistFunction; final Function deleteFromWishlistFunction;
AuthenticatedUserObject authenticatedUserObject =
locator<AuthenticatedUserObject>();
ProductNameAndPrice(this.context, this.item, ProductNameAndPrice(this.context, this.item,
{this.customerId, {this.customerId,
this.isInWishList, this.isInWishList,
@ -46,7 +51,7 @@ class _ProductNameAndPriceState extends State<ProductNameAndPrice> {
child: Row( child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween, mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [ children: [
Texts(widget.item.price.toString() + " " + "SAR", Texts(widget.item.price.toString() + " " + "SR",
fontWeight: FontWeight.bold, fontSize: 20), fontWeight: FontWeight.bold, fontSize: 20),
Texts( Texts(
projectViewModel.isArabic projectViewModel.isArabic
@ -59,49 +64,52 @@ class _ProductNameAndPriceState extends State<ProductNameAndPrice> {
: Colors.green, : Colors.green,
), ),
// SizedBox(width: 20), // SizedBox(width: 20),
widget.item.stockAvailability == 'Out of stock' && if (widget.authenticatedUserObject.isLogin)
widget.customerId != null widget.item.stockAvailability == 'Out of stock' &&
? InkWell( widget.customerId != null
onTap: () => ? InkWell(
widget.notifyMeWhenAvailable(context, widget.item.id), onTap: () => widget.notifyMeWhenAvailable(
child: Row(children: [ context, widget.item.id),
Texts( child: Row(children: [
TranslationBase.of(context).notifyMe, Texts(
decoration: TextDecoration.underline, TranslationBase.of(context).notifyMe,
color: Colors.blue, decoration: TextDecoration.underline,
), color: Colors.blue,
SizedBox(width: 4), ),
Icon( SizedBox(width: 4),
FontAwesomeIcons.bell, Icon(
color: Colors.blue, FontAwesomeIcons.bell,
size: 15.0, color: Colors.blue,
) size: 15.0,
]), )
) ]),
: IconWithBg( )
icon: !widget.isInWishList : IconWithBg(
? Icons.favorite_border icon: !widget.isInWishList
: Icons.favorite, ? Icons.favorite_border
color: !widget.isInWishList ? Colors.white : Colors.red, : Icons.favorite,
onPress: () async { color: !widget.isInWishList
{ ? Colors.white
if (widget.customerId != null) { : Colors.red[800],
if (!widget.isInWishList) { onPress: () async {
GifLoaderDialogUtils.showMyDialog(context); {
await widget if (widget.customerId != null) {
.addToWishlistFunction(widget.item.id); if (!widget.isInWishList) {
GifLoaderDialogUtils.hideDialog(context);
await widget
.addToWishlistFunction(widget.item.id);
} else {
await widget
.deleteFromWishlistFunction(widget.item.id);
}
} else { } else {
await widget return;
.deleteFromWishlistFunction(widget.item.id);
} }
} else { setState(() {});
return;
} }
setState(() {}); },
} )
},
)
], ],
), ),
), ),
@ -157,29 +165,32 @@ class _ProductNameAndPriceState extends State<ProductNameAndPrice> {
"(${widget.item.approvedTotalReviews}${TranslationBase.of(context).review})", "(${widget.item.approvedTotalReviews}${TranslationBase.of(context).review})",
fontSize: 12, fontSize: 12,
), ),
SizedBox(
width: 70,
),
if (widget.item.rxMessage != null)
Row(
children: [
Text(
projectViewModel.isArabic
? widget.item.rxMessagen.toString()
: widget.item.rxMessage.toString(),
style: TextStyle(color: Colors.red, fontSize: 10),
),
SizedBox(
width: 5,
),
Icon(
FontAwesomeIcons.questionCircle,
color: Colors.red,
size: 15.0,
)
],
)
], ],
), ),
), ),
), ),
Expanded(
flex: 1,
child: Container(
child: widget.item.rxMessage != null
? Text(
projectViewModel.isArabic
? widget.item.rxMessagen.toString()
: widget.item.rxMessage.toString(),
style: TextStyle(color: Colors.red, fontSize: 10),
)
: Container()),
),
widget.item.rxMessage != null
? Icon(
FontAwesomeIcons.questionCircle,
color: Colors.red,
size: 15.0,
)
: Container(),
], ],
), ),
), ),

@ -1,388 +0,0 @@
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/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/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;
const RecommendedProducts({Key key, this.product}) : super(key: key);
@override
_RecommendedProductsState createState() => _RecommendedProductsState();
}
class _RecommendedProductsState extends State<RecommendedProducts> {
@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(
color: Colors.white,
height: 210,
margin: EdgeInsets.only(bottom: 75),
padding: EdgeInsets.only(bottom: 5),
// margin: EdgeInsets.symmetric(horizontal: 6, vertical: 4),
child: BaseView<PharmacyModuleViewModel>(
onModelReady: (model) => model
.getRecommendedProducts(widget.product.id),
builder: (_, model, wi) => Container(
child:
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 (customerId !=
null) {
if (!isInWishList &&
model.recommendedProductList[index].isinwishlist !=
true) {
GifLoaderDialogUtils.showMyDialog(
context);
await addToWishlistFunction(model
.recommendedProductList[index]
.id);
// checkWishlist();
GifLoaderDialogUtils.hideDialog(
context);
setState(
() {
model.recommendedProductList[index].isinwishlist =
true;
});
} else {
GifLoaderDialogUtils.showMyDialog(
context);
await deleteFromWishlistFunction(model
.recommendedProductList[index]
.id);
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: <
Widget>[
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,
),
],
),
),
),
),
),
],
),
),
);
}
}

@ -1,96 +1,90 @@
import 'package:diplomaticquarterapp/core/model/pharmacies/PharmacyProduct.dart'; import 'package:diplomaticquarterapp/core/model/pharmacies/PharmacyProduct.dart';
import 'package:diplomaticquarterapp/core/viewModels/pharmacyModule/product_detail_view_model.dart'; import 'package:diplomaticquarterapp/core/viewModels/pharmacyModule/product_detail_view_model.dart';
import 'package:diplomaticquarterapp/pages/base/base_view.dart';
import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart';
import 'package:diplomaticquarterapp/widgets/others/network_base_view.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:rating_bar/rating_bar.dart'; import 'package:rating_bar/rating_bar.dart';
class ReviewsInfo extends StatelessWidget { class ReviewsInfo extends StatelessWidget {
final PharmacyProduct product; final PharmacyProduct product;
final ProductDetailViewModel previousModel;
const ReviewsInfo({Key key, this.product}) : super(key: key); const ReviewsInfo({Key key, this.product, this.previousModel})
: super(key: key);
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return BaseView<ProductDetailViewModel>( return previousModel.productDetailService.length != 0 &&
onModelReady: (model) => model.getProductReviewsData(product.id), previousModel.productDetailService[0].reviews.length != 0
builder: (_, model, wi) => NetworkBaseView( ? ListView.builder(
baseViewModel:model , physics: ScrollPhysics(),
child: model.productDetailService.length != 0 && itemCount: previousModel.productDetailService[0].reviews.length,
model.productDetailService[0].reviews.length != 0 scrollDirection: Axis.vertical,
? ListView.builder( shrinkWrap: true,
physics: ScrollPhysics(), itemBuilder: (BuildContext context, int index) {
itemCount: model.productDetailService[0].reviews.length, return Padding(
scrollDirection: Axis.vertical, padding: EdgeInsets.all(8.0),
shrinkWrap: true, child: Column(
itemBuilder: (BuildContext context, int index) { mainAxisAlignment: MainAxisAlignment.start,
return Padding( crossAxisAlignment: CrossAxisAlignment.start,
padding: EdgeInsets.all(8.0), children: [
child: Column( Container(
mainAxisAlignment: MainAxisAlignment.start, child: Row(
crossAxisAlignment: CrossAxisAlignment.start, children: [
children: [ Container(
Container( child: Text(
child: Row( previousModel.productDetailService[0]
children: [ .reviews[index].customerId
Container( .toString(),
child: Text( style: TextStyle(
model.productDetailService[0].reviews[index] fontSize: 17,
.customerId color: Colors.grey,
.toString(), fontWeight: FontWeight.w600),
style: TextStyle( ),
fontSize: 17,
color: Colors.grey,
fontWeight: FontWeight.w600),
),
),
Container(
margin: EdgeInsets.only(left: 210),
child: RatingBar.readOnly(
initialRating: model.productDetailService[0]
.reviews[index].rating
.toDouble(),
size: 15.0,
filledColor: Colors.yellow[700],
emptyColor: Colors.grey[500],
isHalfAllowed: true,
halfFilledIcon: Icons.star_half,
filledIcon: Icons.star,
emptyIcon: Icons.star,
),
),
],
), ),
), Container(
SizedBox( margin: EdgeInsets.only(left: 210),
height: 10, child: RatingBar.readOnly(
), initialRating: previousModel
Container( .productDetailService[0].reviews[index].rating
child: Text( .toDouble(),
model.productDetailService[0].reviews[index] size: 15.0,
.reviewText, filledColor: Colors.yellow[700],
style: TextStyle(fontSize: 20), emptyColor: Colors.grey[500],
isHalfAllowed: true,
halfFilledIcon: Icons.star_half,
filledIcon: Icons.star,
emptyIcon: Icons.star,
),
), ),
), ],
SizedBox( ),
height: 50,
),
Divider(height: 1, color: Colors.grey),
],
), ),
); SizedBox(
}, height: 10,
) ),
: Container( Container(
padding: EdgeInsets.all(15), child: Text(
alignment: Alignment.center, previousModel
child: Text( .productDetailService[0].reviews[index].reviewText,
TranslationBase.of(context).noReviewsAvailable, style: TextStyle(fontSize: 20),
),
),
SizedBox(
height: 50,
),
Divider(height: 1, color: Colors.grey),
],
), ),
);
},
)
: Container(
padding: EdgeInsets.all(15),
alignment: Alignment.center,
child: Text(
TranslationBase.of(context).noReviewsAvailable,
),
// Text('No Reviews Available'), // Text('No Reviews Available'),
), );
),
);
} }
} }

@ -0,0 +1,19 @@
import 'package:flutter/material.dart';
class CustomDivider extends StatelessWidget {
const CustomDivider({
Key key,
this.color,
}) : super(key: key);
final Color color;
@override
Widget build(BuildContext context) {
return Container(
width: 120,
height: 2,
color: color,
);
}
}

@ -11,19 +11,20 @@ class IconWithBg extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Container( return Container(
margin: EdgeInsets.only(left: 25),
width: 40, width: 40,
height: 40, height: 40,
decoration: BoxDecoration( decoration: BoxDecoration(
color: Colors.grey[300], color: Colors.grey[200],
borderRadius: BorderRadius.circular(30), borderRadius: BorderRadius.circular(30),
), ),
child: IconButton( child: Center(
icon: Icon(icon), child: IconButton(
color: color, icon: Icon(icon, size: 20,),
onPressed: () async { color: color,
onPress(); onPressed: () async {
}, onPress();
},
),
)); ));
} }
} }

@ -0,0 +1,161 @@
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/product-detail.dart';
import 'package:diplomaticquarterapp/uitl/app_toast.dart';
import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart';
import 'package:flutter/material.dart';
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
import 'package:provider/provider.dart';
import '../../../../../locator.dart';
import '../../../compare-list.dart';
import '../../cart-order-page.dart';
import 'icon_with_bg.dart';
class ProductAppBar extends StatelessWidget with PreferredSizeWidget {
final PharmacyProduct product;
final ProductDetailViewModel model;
final Function addToWishlistFunction;
final Function deleteFromWishlistFunction;
final int quantity;
final bool isInWishList;
ProductAppBar(
{Key key,
this.product,
this.model,
this.addToWishlistFunction,
this.quantity,
this.deleteFromWishlistFunction,
this.isInWishList})
: super(key: key);
AuthenticatedUserObject authenticatedUserObject =
locator<AuthenticatedUserObject>();
@override
Widget build(BuildContext context) {
return Container(
color: Colors.white,
child: FractionallySizedBox(
widthFactor: 0.95,
child: Column(
children: [
SizedBox(
height: 30,
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Row(
children: [
IconWithBg(
icon: Icons.arrow_back,
color: Colors.grey,
onPress: () {
Navigator.pop(context);
},
),
],
),
if (authenticatedUserObject.isLogin)
Row(
children: [
IconWithBg(
icon: Icons.shopping_cart,
color: Colors.grey[800],
onPress: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => CartOrderPage()),
);
}),
SizedBox(
width: 10,
),
IconWithBg(
icon: FontAwesomeIcons.ellipsisV,
color: Colors.grey,
onPress: () {
settingModalBottomSheet(context);
},
),
],
)
],
),
],
),
),
);
}
@override
Size get preferredSize => Size(double.maxFinite, 50);
settingModalBottomSheet(context) {
showModalBottomSheet(
context: context,
builder: (BuildContext bc) {
return Container(
child: new Wrap(
children: <Widget>[
if (product.stockAvailability != 'Out of stock')
new ListTile(
leading: Icon(Icons.shopping_cart),
title: Text(
TranslationBase.of(context).addToCart,
),
onTap: () async {
if (quantity > 0) {
{
await addToCartFunction(
quantity: quantity,
itemID: itemID,
context: context,
model: model);
Navigator.of(context).pop();
}
} else {
AppToast.showErrorToast(
message: "you should add quantity");
}
}),
ListTile(
leading: Icon(
!isInWishList ? Icons.favorite_border : Icons.favorite,
color: !isInWishList ? Colors.white : Colors.red[800],
),
title: Text(
isInWishList
? TranslationBase.of(context).removeFromWishlist
: TranslationBase.of(context).addToWishlist,
),
onTap: () async {
if (isInWishList)
await deleteFromWishlistFunction();
else
await addToWishlistFunction();
Navigator.of(context).pop();
}),
ListTile(
leading: Icon(Icons.compare),
title: Text(
TranslationBase.of(context).compare,
),
onTap: () {
Provider.of<CompareList>(context, listen: false)
.addItem(specificationData);
Navigator.of(context).pop();
},
),
],
),
);
});
}
}

@ -13,8 +13,9 @@ import 'package:provider/provider.dart';
class ProductTileItem extends StatelessWidget { class ProductTileItem extends StatelessWidget {
final AppSharedPreferences sharedPref = AppSharedPreferences(); final AppSharedPreferences sharedPref = AppSharedPreferences();
final PharmacyProduct item; final PharmacyProduct item;
final double itemHeight;
ProductTileItem(this.item); ProductTileItem(this.item, this.itemHeight);
void productOnClick(BuildContext ctx) { void productOnClick(BuildContext ctx) {
_saveLastVisitProducts(); _saveLastVisitProducts();
@ -92,12 +93,12 @@ class ProductTileItem extends StatelessWidget {
? Image.network( ? Image.network(
item.images[0].src, item.images[0].src,
fit: BoxFit.cover, fit: BoxFit.cover,
height: 80, height: itemHeight / 2,
) )
: Image.asset( : Image.asset(
"assets/images/no_image.png", "assets/images/no_image.png",
fit: BoxFit.cover, fit: BoxFit.cover,
height: 80, height: itemHeight / 2,
), ),
), ),
Container( Container(
@ -125,42 +126,48 @@ class ProductTileItem extends StatelessWidget {
], ],
), ),
SizedBox(height: 8,), SizedBox(height: 8,),
Container( Padding(
margin: EdgeInsets.symmetric( padding: const EdgeInsets.symmetric(horizontal: 6.0),
horizontal: 6, child: Texts(
vertical: 0, projectProvider.isArabic ? item.namen : item.name,
regular: true,
fontSize: 12,
fontWeight: FontWeight.w400,
), ),
child: Column( ),
crossAxisAlignment: CrossAxisAlignment.start, Expanded(
children: [ child: Container(
Texts( margin: EdgeInsets.symmetric(
projectProvider.isArabic ? item.namen : item.name, horizontal: 6,
regular: true, vertical: 0,
fontSize: 12, ),
fontWeight: FontWeight.w400, child: Column(
), crossAxisAlignment: CrossAxisAlignment.start,
Padding( mainAxisAlignment: MainAxisAlignment.end,
padding: const EdgeInsets.only(top: 4, bottom: 4), children: [
child: Texts( Padding(
"SAR ${item.price}", padding: const EdgeInsets.only(top: 4, bottom: 4),
fontWeight: FontWeight.w600, child: Texts(
fontSize: 14, "SAR ${item.price}",
), fontWeight: FontWeight.w600,
), fontSize: 14,
Row(
children: [
Expanded(
child: StarRating(
totalAverage: item.approvedTotalReviews > 0
? (item.approvedRatingSum.toDouble() /
item.approvedTotalReviews.toDouble())
.toDouble()
: 0,
forceStars: true),
), ),
], ),
), Row(
], children: [
Expanded(
child: StarRating(
totalAverage: item.approvedTotalReviews > 0
? (item.approvedRatingSum.toDouble() /
item.approvedTotalReviews.toDouble())
.toDouble()
: 0,
forceStars: true),
),
],
),
],
),
), ),
), ),
SizedBox(height: 5,), SizedBox(height: 5,),

@ -29,10 +29,10 @@ class BestSellerWidget extends StatelessWidget {
)), )),
if (model.state != ViewState.BusyLocal) if (model.state != ViewState.BusyLocal)
Container( Container(
height: MediaQuery.of(context).size.height / 4 + 20, height: MediaQuery.of(context).size.height / 3 + 20,
child: ListView.builder( child: ListView.builder(
itemBuilder: (ctx, i) => itemBuilder: (ctx, i) =>
ProductTileItem(model.bestSellerProduct[i]), ProductTileItem(model.bestSellerProduct[i], MediaQuery.of(context).size.height / 4 + 20),
scrollDirection: Axis.horizontal, scrollDirection: Axis.horizontal,
itemCount: model.bestSellerProduct.length, itemCount: model.bestSellerProduct.length,
), ),

@ -47,6 +47,7 @@ class GridViewCard extends StatelessWidget {
TranslationBase.of(context).viewAll, TranslationBase.of(context).viewAll,
handler: handler, handler: handler,
tPadding: 0, tPadding: 0,
textColor: Color(0xFF5ab145),
bPadding: 0, bPadding: 0,
), ),
Expanded(child: Container()), Expanded(child: Container()),

@ -30,11 +30,11 @@ class RecentlyViewedWidget extends StatelessWidget {
if (model.state != ViewState.BusyLocal) if (model.state != ViewState.BusyLocal)
Container( Container(
height: model.lastVisitedProducts.length > 0 height: model.lastVisitedProducts.length > 0
? MediaQuery.of(context).size.height / 4 + 20 ? MediaQuery.of(context).size.height / 3 + 20
: 0, : 0,
child: ListView.builder( child: ListView.builder(
itemBuilder: (ctx, i) => itemBuilder: (ctx, i) =>
ProductTileItem(model.lastVisitedProducts[i]), ProductTileItem(model.lastVisitedProducts[i], MediaQuery.of(context).size.height / 4 + 20),
scrollDirection: Axis.horizontal, scrollDirection: Axis.horizontal,
itemCount: model.lastVisitedProducts.length, itemCount: model.lastVisitedProducts.length,
), ),

@ -25,7 +25,7 @@ class ShopByBrandWidget extends StatelessWidget {
ProductBrandsPage()), ProductBrandsPage()),
if (model.state != ViewState.BusyLocal) if (model.state != ViewState.BusyLocal)
Container( Container(
height: 100, height: 150,
child: ListView.builder( child: ListView.builder(
itemBuilder: (ctx, i) => itemBuilder: (ctx, i) =>
ManufacturerItem(model.manufacturerList[i]), ManufacturerItem(model.manufacturerList[i]),

@ -25,6 +25,7 @@ class ManufacturerItem extends StatelessWidget {
); );
}, },
child: Container( child: Container(
width: 100,
margin: EdgeInsets.symmetric( margin: EdgeInsets.symmetric(
horizontal: 12, horizontal: 12,
vertical: 4, vertical: 4,
@ -38,8 +39,9 @@ class ManufacturerItem extends StatelessWidget {
top: BorderSide(color: Colors.grey.shade300, width: 1)), top: BorderSide(color: Colors.grey.shade300, width: 1)),
), ),
child: item.image == null child: item.image == null
? Padding( ? Container(
padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 10), padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 10),
alignment: Alignment.topCenter,
child: AppText(item.name, fontWeight: FontWeight.w500,fontSize: 14,), child: AppText(item.name, fontWeight: FontWeight.w500,fontSize: 14,),
) )
: Padding( : Padding(

@ -35,8 +35,14 @@ class _AddAddressPageState extends State<AddAddressPage> {
} else { } else {
_getCurrentLocation(); _getCurrentLocation();
} }
setState(() {
});
} }
_getCurrentLocation() async { _getCurrentLocation() async {
await Geolocator.getLastKnownPosition().then((value) { await Geolocator.getLastKnownPosition().then((value) {
_latitude = value.latitude; _latitude = value.latitude;
@ -44,9 +50,12 @@ class _AddAddressPageState extends State<AddAddressPage> {
}).catchError((e) { }).catchError((e) {
_longitude = 0; _longitude = 0;
_latitude = 0; _latitude = 0;
}); });
} }
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final mediaQuery = MediaQuery.of(context); final mediaQuery = MediaQuery.of(context);
@ -63,8 +72,8 @@ class _AddAddressPageState extends State<AddAddressPage> {
body: Container( body: Container(
height: height * 1, height: height * 1,
child: PickupLocationFromMap( child: PickupLocationFromMap(
latitude: _latitude, latitude: _latitude??0,
longitude: _longitude, longitude: _longitude??0,
isWithAppBar: false, isWithAppBar: false,
buttonColor: Color(0xFF5AB145), buttonColor: Color(0xFF5AB145),
buttonLabel: TranslationBase.of(context).save, buttonLabel: TranslationBase.of(context).save,

@ -7,6 +7,7 @@ import 'package:diplomaticquarterapp/models/pharmacy/productDetailModel.dart';
import 'package:diplomaticquarterapp/config/shared_pref_kay.dart'; import 'package:diplomaticquarterapp/config/shared_pref_kay.dart';
import 'package:diplomaticquarterapp/uitl/app_toast.dart'; import 'package:diplomaticquarterapp/uitl/app_toast.dart';
import 'package:diplomaticquarterapp/models/pharmacy/specification.dart'; import 'package:diplomaticquarterapp/models/pharmacy/specification.dart';
import 'package:diplomaticquarterapp/uitl/utils.dart';
class ProductDetailService extends BaseService { class ProductDetailService extends BaseService {
bool isLogin = false; bool isLogin = false;
@ -98,7 +99,7 @@ class ProductDetailService extends BaseService {
}, onFailure: (String error, int statusCode) { }, onFailure: (String error, int statusCode) {
hasError = true; hasError = true;
super.error = error; super.error = error;
AppToast.showErrorToast(message: super.error??'something went wrong please try again'); AppToast.showErrorToast(message: error??Utils.generateContactAdminMessage());
}, body: request); }, body: request);
} }
@ -109,7 +110,7 @@ class ProductDetailService extends BaseService {
}, onFailure: (String error, int statusCode) { }, onFailure: (String error, int statusCode) {
hasError = true; hasError = true;
super.error = error; super.error = error;
AppToast.showErrorToast(message: 'something went wrong please try again'); AppToast.showErrorToast(message: error??Utils.generateContactAdminMessage());
}); });
} }
@ -126,12 +127,13 @@ class ProductDetailService extends BaseService {
_wishListProducts.clear(); _wishListProducts.clear();
response['shopping_carts'].forEach((item) { response['shopping_carts'].forEach((item) {
_wishListProducts.add(Wishlist.fromJson(item)); _wishListProducts.add(Wishlist.fromJson(item));
AppToast.showSuccessToast(message: 'You have added a product to the Wishlist');
}); });
AppToast.showSuccessToast(message: 'You have added a product to the Wishlist');
}, onFailure: (String error, int statusCode) { }, onFailure: (String error, int statusCode) {
hasError = true; hasError = true;
super.error = error; super.error = error;
AppToast.showErrorToast(message: 'something went wrong please try again'); AppToast.showErrorToast(message: error??Utils.generateContactAdminMessage());
}, body: request); }, body: request);
} }
@ -149,7 +151,7 @@ class ProductDetailService extends BaseService {
super.error = error; super.error = error;
}); });
} }
Future delteItemFromWishlist(itemID) async { Future deleteItemFromWishlist(itemID) async {
var customerId = await sharedPref.getString(PHARMACY_CUSTOMER_ID); var customerId = await sharedPref.getString(PHARMACY_CUSTOMER_ID);
hasError = false; hasError = false;
await baseAppClient.getPharmacy(DELETE_WISHLIST+customerId+"+&product_id="+itemID+"&cart_type=Wishlist", await baseAppClient.getPharmacy(DELETE_WISHLIST+customerId+"+&product_id="+itemID+"&cart_type=Wishlist",

@ -1398,6 +1398,8 @@ class TranslationBase {
String get addToCart => localizedValues['addToCart'][locale.languageCode]; String get addToCart => localizedValues['addToCart'][locale.languageCode];
String get addToWishlist => String get addToWishlist =>
localizedValues['addToWishlist'][locale.languageCode]; localizedValues['addToWishlist'][locale.languageCode];
String get removeFromWishlist =>
localizedValues['removeFromWishlist'][locale.languageCode];
String get buyNow => localizedValues['buyNow'][locale.languageCode]; String get buyNow => localizedValues['buyNow'][locale.languageCode];
String get quantityShortcut => String get quantityShortcut =>
localizedValues['quantityShortcut'][locale.languageCode]; localizedValues['quantityShortcut'][locale.languageCode];

@ -29,7 +29,7 @@ class SecondaryButton extends StatefulWidget {
this.small = false, this.small = false,
this.disabled = false, this.disabled = false,
this.borderColor, this.borderColor,
this.noBorderRadius = false, this.borderRadius}) this.noBorderRadius = false, this.borderRadius, this.disableColor})
: super(key: key); : super(key: key);
final String label; final String label;
@ -44,6 +44,7 @@ class SecondaryButton extends StatefulWidget {
final bool disabled; final bool disabled;
final bool noBorderRadius; final bool noBorderRadius;
final double borderRadius; final double borderRadius;
final Color disableColor;
@ -183,7 +184,7 @@ class _SecondaryButtonState extends State<SecondaryButton>
height: 100, height: 100,
decoration: BoxDecoration( decoration: BoxDecoration(
color: widget.disabled color: widget.disabled
? Colors.grey ? widget.disableColor??Colors.grey
: widget.color ?? Theme.of(context).buttonColor), : widget.color ?? Theme.of(context).buttonColor),
), ),
), ),

@ -1,281 +0,0 @@
import 'package:diplomaticquarterapp/config/config.dart';
import 'package:diplomaticquarterapp/config/size_config.dart';
import 'package:diplomaticquarterapp/config/size_config.dart';
import 'package:diplomaticquarterapp/core/service/AuthenticatedUserObject.dart';
import 'package:diplomaticquarterapp/core/viewModels/base_view_model.dart';
import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart';
import 'package:diplomaticquarterapp/pages/insurance/insurance_update_screen.dart';
import 'package:diplomaticquarterapp/pages/landing/landing_page.dart';
import 'package:diplomaticquarterapp/pages/pharmacies/compare-list.dart';
import 'package:diplomaticquarterapp/routes.dart';
import 'package:diplomaticquarterapp/uitl/app_toast.dart';
import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart';
import 'package:diplomaticquarterapp/widgets/data_display/text.dart';
import 'package:diplomaticquarterapp/widgets/others/bottom_bar.dart';
import 'package:diplomaticquarterapp/widgets/progress_indicator/app_loader_widget.dart';
import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart';
import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
import 'package:provider/provider.dart';
import '../../locator.dart';
import 'floating_button_search.dart';
import '../progress_indicator/app_loader_widget.dart';
import 'arrow_back.dart';
import 'network_base_view.dart';
import 'not_auh_page.dart';
import 'package:diplomaticquarterapp/pages/pharmacies/screens/product-details/product-detail.dart';
import 'package:diplomaticquarterapp/pages/pharmacies/screens/cart-order-page.dart';
class DetailPageScafold extends StatefulWidget {
final String appBarTitle;
final Widget body;
final Widget bottomSheet;
final bool isLoading;
final bool isShowAppBar;
final bool hasAppBarParam;
final BaseViewModel baseViewModel;
final bool isBottomBar;
final Widget floatingActionButton;
final bool isPharmacy;
final String title;
final String description;
final String image;
final bool isShowDecPage;
final List<String> infoList;
final Color backgroundColor;
final double preferredSize;
final List<Widget> appBarIcons;
final PreferredSizeWidget appBarWidget;
DetailPageScafold(
{@required this.body,
this.appBarTitle = '',
this.isLoading = false,
this.isShowAppBar = false,
this.hasAppBarParam,
this.bottomSheet,
this.baseViewModel,
this.floatingActionButton,
this.isPharmacy = false,
this.title,
this.description,
this.isShowDecPage = true,
this.isBottomBar,
this.backgroundColor,
this.preferredSize = 0.0,
this.appBarIcons,
this.appBarWidget,
this.image,
this.infoList});
@override
_DetailPageScafoldState createState() => _DetailPageScafoldState();
}
class _DetailPageScafoldState extends State<DetailPageScafold> {
AuthenticatedUserObject authenticatedUserObject =
locator<AuthenticatedUserObject>();
@override
Widget build(BuildContext context) {
AppGlobal.context = context;
PreferredSizeWidget appBar;
if (this.widget.appBarWidget == null) {
PreferredSizeWidget appBarWidget = AppBarWidget(
widget.appBarTitle,
widget.appBarIcons,
widget.isShowAppBar,
isPharmacy: widget.isPharmacy,
isShowDecPage: widget.isShowDecPage,
image: widget.image,
);
appBar = widget.preferredSize == 0
? appBarWidget
: PreferredSize(
child: appBarWidget,
preferredSize: Size.fromHeight(widget.preferredSize));
} else {
appBar = this.widget.appBarWidget;
}
return Scaffold(
backgroundColor:
widget.backgroundColor ?? Theme.of(context).scaffoldBackgroundColor,
appBar: appBar,
body: (!Provider.of<ProjectViewModel>(context, listen: false).isLogin &&
widget.isShowDecPage)
? NotAutPage(
title: widget.appBarTitle,
description: widget.description,
infoList: widget.infoList,
)
: widget.baseViewModel != null
? NetworkBaseView(
child: buildBodyWidget(),
baseViewModel: widget.baseViewModel,
)
: buildBodyWidget(),
bottomSheet: widget.bottomSheet,
//floatingActionButton: floatingActionButton ?? floatingActionButton,
// bottomNavigationBar:
// this.isBottomBar == true ? BottomBarSearch() : SizedBox()
// floatingActionButton: FloatingSearchButton(),
);
}
buildAppLoaderWidget(bool isLoading) {
return isLoading ? AppLoaderWidget() : Container();
}
buildBodyWidget() {
// return body; //Stack(children: <Widget>[body, buildAppLoaderWidget(isLoading)]);
return Stack(children: <Widget>[
widget.body, /*FloatingSearchButton()*/
]);
}
}
class AppBarWidget extends StatelessWidget with PreferredSizeWidget {
final AuthenticatedUserObject authenticatedUserObject =
locator<AuthenticatedUserObject>();
final String appBarTitle;
final List<Widget> appBarIcons;
final bool isShowAppBar;
final bool isPharmacy;
final bool isShowDecPage;
final String image;
AppBarWidget(this.appBarTitle, this.appBarIcons, this.isShowAppBar,
{this.isPharmacy = true, this.isShowDecPage = true, this.image});
@override
Widget build(BuildContext context) {
return buildAppBar(context);
}
Widget buildAppBar(BuildContext context) {
return isShowAppBar
? AppBar(
elevation: 0,
backgroundColor: Colors.white,
// isPharmacy ? Colors.green : Theme.of(context).appBarTheme.color,
textTheme: TextTheme(
headline6:
TextStyle(color: Colors.white, fontWeight: FontWeight.bold),
),
title: Texts(
authenticatedUserObject.isLogin || !isShowDecPage
? appBarTitle.toUpperCase()
: TranslationBase.of(context).serviceInformationTitle,
color: Colors.white,
bold: true,
),
leading: Builder(
builder: (BuildContext context) {
return GestureDetector(
behavior: HitTestBehavior.opaque,
onTap: () => Navigator.pop(context),
child: Icon(Icons.arrow_back_ios, color: Colors.grey),
);
},
),
centerTitle: true,
actions: <Widget>[
/// TODO Elham* fix this
if(isPharmacy)
IconButton(
icon: Icon(Icons.shopping_cart),
color: Colors.grey,
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => CartOrderPage()),
);
}),
image != null
? InkWell(
onTap: () => Navigator.push(
context,
FadePage(
page: InsuranceUpdate(),
),
),
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Image.asset(
image,
height: SizeConfig.heightMultiplier * 5,
width: SizeConfig.heightMultiplier * 5,
color: Colors.grey,
),
),
)
: IconButton(
icon: Icon(FontAwesomeIcons.ellipsisV),
color: Colors.grey,
onPressed: () {
settingModalBottomSheet(context);
},
),
if (appBarIcons != null) ...appBarIcons
],
)
: Container(
height: 0,
width: 0,
);
}
@override
Size get preferredSize => Size(double.maxFinite, 60);
settingModalBottomSheet(context) {
showModalBottomSheet(
context: context,
builder: (BuildContext bc) {
return Container(
child: new Wrap(
children: <Widget>[
new ListTile(
leading: Icon(Icons.shopping_cart),
title: Text(
TranslationBase.of(context).addToCart,
),
onTap: () => {
if (price > 0)
{addToCartFunction(price, itemID, context)}
else
{
AppToast.showErrorToast(
message: "you should add quantity")
}
}),
ListTile(
leading: Icon(Icons.favorite_border),
title: Text(
TranslationBase.of(context).addToWishlist,
),
onTap: () => {addToWishlistFunction(itemID)},
),
ListTile(
leading: Icon(Icons.compare),
title: Text(
TranslationBase.of(context).compare,
),
onTap: () => {
Provider.of<CompareList>(context, listen: false)
.addItem(specificationData),
},
),
],
),
);
});
}
}
Loading…
Cancel
Save