Merge branch 'product_detail_page' into 'development'

add loader and cache on images

See merge request Cloud_Solution/diplomatic-quarter!415
merge-update-with-lab-changes
Mohammad Aljammal 4 years ago
commit 00a0e34347

@ -36,7 +36,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;

@ -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;

@ -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(

@ -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(
allowAny: true, 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,8 +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/service/AuthenticatedUserObject.dart';
import 'package:diplomaticquarterapp/pages/landing/landing_page.dart';
import 'package:diplomaticquarterapp/pages/login/login.dart';
import 'package:diplomaticquarterapp/pages/login/welcome.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';
@ -22,12 +19,12 @@ 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();
@ -100,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(
@ -114,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 {
@ -159,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),
), ),
), ),
@ -189,17 +186,18 @@ class _FooterWidgetState extends State<FooterWidget> {
width: MediaQuery.of(context).size.width * 0.45, 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: Colors.green[400],
onTap: () async {
if (!authenticatedUserObject.isLogin) { if (!authenticatedUserObject.isLogin) {
Navigator.of(context).pushNamed( Navigator.of(context).pushNamed(
WELCOME_LOGIN, WELCOME_LOGIN,
); );
} else } else
widget.addToCartFunction( await widget.addToCartFunction(
widget.price, widget.item.id, context); widget.quantity, widget.item.id, context);
}, },
borderRadius: 5, borderRadius: 5,
color: Colors.green, color: Colors.green,
@ -212,20 +210,21 @@ class _FooterWidgetState extends State<FooterWidget> {
width: MediaQuery.of(context).size.width * 0.35, 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],
@ -240,13 +239,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,43 +1,28 @@
import 'package:diplomaticquarterapp/config/shared_pref_kay.dart'; import 'package:diplomaticquarterapp/config/shared_pref_kay.dart';
import 'package:diplomaticquarterapp/config/size_config.dart'; import 'package:diplomaticquarterapp/config/size_config.dart';
import 'package:diplomaticquarterapp/core/model/pharmacies/PharmacyProduct.dart'; import 'package:diplomaticquarterapp/core/model/pharmacies/PharmacyProduct.dart';
import 'package:diplomaticquarterapp/core/viewModels/pharmacyModule/pharmacy_module_view_model.dart';
import 'package:diplomaticquarterapp/core/viewModels/pharmacyModule/product_detail_view_model.dart'; import 'package:diplomaticquarterapp/core/viewModels/pharmacyModule/product_detail_view_model.dart';
import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart';
import 'package:diplomaticquarterapp/pages/base/base_view.dart'; import 'package:diplomaticquarterapp/pages/base/base_view.dart';
import 'package:diplomaticquarterapp/pages/pharmacies/compare-list.dart'; import 'package:diplomaticquarterapp/pages/pharmacies/compare-list.dart';
import 'package:diplomaticquarterapp/pages/pharmacies/screens/product-details/product-name-and-price.dart'; import 'package:diplomaticquarterapp/pages/pharmacies/screens/product-details/product-name-and-price.dart';
import 'package:diplomaticquarterapp/pages/pharmacies/screens/product-details/recommended_products.dart';
import 'package:diplomaticquarterapp/pages/pharmacies/screens/product-details/reviews_info.dart'; import 'package:diplomaticquarterapp/pages/pharmacies/screens/product-details/reviews_info.dart';
import 'package:diplomaticquarterapp/uitl/app_toast.dart'; import 'package:diplomaticquarterapp/pages/pharmacies/screens/product-details/shared/custom-divider.dart';
import 'package:diplomaticquarterapp/uitl/app_shared_preferences.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';
import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; import 'package:diplomaticquarterapp/widgets/data_display/text.dart';
import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart';
import 'package:diplomaticquarterapp/widgets/others/app_scafold_detail_page.dart';
import 'package:diplomaticquarterapp/widgets/text/app_texts_widget.dart';
import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
import 'package:provider/provider.dart';
import 'package:rating_bar/rating_bar.dart';
import 'package:diplomaticquarterapp/core/model/pharmacies/recommendedProduct_model.dart';
import '../cart-order-page.dart';
import 'package:diplomaticquarterapp/uitl/app_shared_preferences.dart';
import 'ProductAppBar.dart';
import 'availability_info.dart'; import 'availability_info.dart';
import 'details_info.dart'; import 'details_info.dart';
import 'discount_description.dart'; import 'discount_description.dart';
import 'footor/footer-widget.dart'; import 'footor/footer-widget.dart';
import 'shared/product_details_app_bar.dart';
int price = 0;
bool isOverQuantity = false;
bool isInWishList = false;
bool isSelected = true;
String itemID; String itemID;
var customerId;
CompareList compareItems = new CompareList();
PharmacyProduct specificationData; PharmacyProduct specificationData;
class ProductDetailPage extends StatefulWidget { class ProductDetailPage extends StatefulWidget {
@ -49,23 +34,27 @@ class ProductDetailPage extends StatefulWidget {
__ProductDetailPageState createState() => __ProductDetailPageState(); __ProductDetailPageState createState() => __ProductDetailPageState();
} }
class __ProductDetailPageState extends State<ProductDetailPage> class __ProductDetailPageState extends State<ProductDetailPage>{
with SingleTickerProviderStateMixin {
TabController _tabController;
AppSharedPreferences sharedPref = AppSharedPreferences(); AppSharedPreferences sharedPref = AppSharedPreferences();
bool isTrue = true; bool isTrue = true;
bool isDetails = true; bool isDetails = true;
bool isReviews = false; bool isReviews = false;
bool isAvailability = false; bool isAvailability = false;
String customerId;
bool isSelected = true;
bool isOverQuantity = false;
bool isInWishList = false;
int quantity = 0;
checkWishlist() async { checkWishlist() async {
GifLoaderDialogUtils.showMyDialog(context); GifLoaderDialogUtils.showMyDialog(context);
ProductDetailViewModel x = new ProductDetailViewModel(); ProductDetailViewModel model = new ProductDetailViewModel();
await x.checkWishlistData(); await model.checkWishlistData();
for (int i = 0; i < x.wishListItems.length; i++) { for (int i = 0; i < model.wishListItems.length; i++) {
if (itemID == x.wishListItems[i].product.id) { if (itemID == model.wishListItems[i].product.id) {
isInWishList = true; isInWishList = true;
break; break;
} else { } else {
@ -77,9 +66,8 @@ class __ProductDetailPageState extends State<ProductDetailPage>
} }
void initState() { void initState() {
price = 1; quantity = 1;
specificationData = widget.product; specificationData = widget.product;
_tabController = TabController(length: 3, vsync: this);
userInfo(); userInfo();
super.initState(); super.initState();
@ -87,7 +75,6 @@ class __ProductDetailPageState extends State<ProductDetailPage>
@override @override
void dispose() { void dispose() {
_tabController.dispose();
super.dispose(); super.dispose();
} }
@ -102,379 +89,255 @@ class __ProductDetailPageState extends State<ProductDetailPage>
} }
Widget build(BuildContext context) { Widget build(BuildContext context) {
ProjectViewModel projectViewModel = Provider.of(context); return BaseView<ProductDetailViewModel>(
final screenSize = MediaQuery.of(context).size; allowAny: true,
builder: (_, model, wi) => AppScaffold(
return AppScaffold( appBarTitle: TranslationBase.of(context).productDetails,
appBarTitle: TranslationBase.of(context).productDetails, isShowAppBar: true,
isShowAppBar: true, isPharmacy: true,
isPharmacy: true, isShowDecPage: false,
isShowDecPage: false, customAppBar: ProductAppBar(
customAppBar: ProductAppBar(product: widget.product,), product: widget.product,
body: SingleChildScrollView( model: model,
child: Column( addToWishlistFunction: (item) {
children: [ addToWishlistFunction(itemID:item,model:model);
Container( setState(() {});
width: double.infinity, },
color: Colors.white, ),
child: Column( body: SingleChildScrollView(
children: [ child: Column(
if (widget.product.images.isNotEmpty) children: [
Container( Container(
height: MediaQuery.of(context).size.height * .40, width: double.infinity,
child: Image.network( color: Colors.white,
widget.product.images[0].src.trim(), child: Column(
fit: BoxFit.contain, children: [
if (widget.product.images.isNotEmpty)
Container(
height: MediaQuery.of(context).size.height * .40,
child: Image.network(
widget.product.images[0].src.trim(),
fit: BoxFit.contain,
),
), ),
), if (widget.product.discountDescription != null)
if (widget.product.discountDescription != null) DiscountDescription(product: widget.product)
DiscountDescription(product: widget.product) ],
], ),
), ),
), SizedBox(
SizedBox( height: 4,
height: 4,
),
Container(
color: Colors.white,
child: ProductNameAndPrice(
context,
widget.product,
customerId: customerId,
addToWishlistFunction: (item) {
addToWishlistFunction(item);
setState(() {});
},
deleteFromWishlistFunction: (item) {
deleteFromWishlistFunction(item);
setState(() {});
},
notifyMeWhenAvailable: (context, itemId) {
notifyMeWhenAvailable(context, itemId);
},
isInWishList: isInWishList,
), ),
), Container(
SizedBox( color: Colors.white,
height: 6, child: ProductNameAndPrice(
), context,
Container( widget.product,
color: Colors.white, customerId: customerId,
child: Column( addToWishlistFunction: (item) {
mainAxisAlignment: MainAxisAlignment.start, addToWishlistFunction(itemID:item,model:model);
crossAxisAlignment: CrossAxisAlignment.start, setState(() {});
children: [ },
Container( deleteFromWishlistFunction: (item) {
padding: EdgeInsets.symmetric( deleteFromWishlistFunction(itemID: item, model: model);
vertical: 15, horizontal: 10), setState(() {});
child: Texts( },
TranslationBase.of(context).specification, notifyMeWhenAvailable: (context, itemId) {
fontSize: 15, notifyMeWhenAvailable(itemId:itemId, customerId: customerId, model: model);
fontWeight: FontWeight.bold, },
isInWishList: isInWishList,
),
),
SizedBox(
height: 6,
),
Container(
color: Colors.white,
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Container(
padding: EdgeInsets.symmetric(
vertical: 15, horizontal: 10),
child: Texts(
TranslationBase.of(context).specification,
fontSize: 15,
fontWeight: FontWeight.bold,
),
width: double.infinity,
), ),
width: double.infinity, // Divider(color: Colors.grey),
), ],
// Divider(color: Colors.grey), ),
],
), ),
), SizedBox(
SizedBox( height: 6,
height: 6, ),
), Container(
// Container( // width: 500,
// height: 500, margin: EdgeInsets.only(bottom: 6),
// color: Colors.white, color: Colors.white,
// child: Scaffold( child: Column(
// backgroundColor: Colors.white, crossAxisAlignment: CrossAxisAlignment.start,
// extendBodyBehindAppBar: false, children: [
// appBar: PreferredSize( Row(
// preferredSize: Size.fromHeight( mainAxisAlignment: MainAxisAlignment.spaceEvenly,
// MediaQuery.of(context).size.height * 0.070), children: [
// child: Container( Column(
// height: MediaQuery.of(context).size.height * 0.070, children: [
// decoration: BoxDecoration( FlatButton(
// border: Border( onPressed: () {
// bottom: BorderSide( setState(() {
// color: Theme.of(context).dividerColor, isDetails = true;
// width: 0.5), //width: 0.7 isReviews = false;
// ), isAvailability = false;
// color: Colors.white), });
// child: Center( },
// child: TabBar( child: Text(
// isScrollable: false, TranslationBase.of(context).details,
// controller: _tabController, style: TextStyle(
// // indicatorColor: Colors.transparent, fontSize: 16,
// indicatorWeight: 1.0, fontWeight: FontWeight.bold),
// indicatorSize: TabBarIndicatorSize.tab, ),
// indicatorColor:Colors.green, color: Colors.white,
// labelColor: Theme.of(context).primaryColor,
// labelPadding: EdgeInsets.only(
// top: 0, left: 0, right: 0, bottom: 0),
// unselectedLabelColor: Colors.grey[800],
// tabs: [
// tabWidget(screenSize, _activeTab == 0,
// TranslationBase.of(context).details,
// ),
// tabWidget(screenSize, _activeTab == 1,
// TranslationBase.of(context).review,
// ),
// tabWidget(screenSize, _activeTab == 2,
// TranslationBase.of(context).availability),
// ],
// ),
// ),
// ),
// ),
// body: Column(
// children: [
// Expanded(
// child: TabBarView(
// physics: BouncingScrollPhysics(),
// controller: _tabController,
// children: [
// DetailsInfo(
// product: widget.product,
// ),
// ReviewsInfo(
// product: widget.product,
// ),
// AvailabilityInfo()
// ],
// ),
// ),
//
// ],
// ),
// ),
// ),
SizedBox(
height: 6,
),
//TODO Elham* Remove this
Container(
// width: 500,
margin: EdgeInsets.only(bottom: 6),
color: Colors.white,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
Column(
children: [
FlatButton(
onPressed: () {
setState(() {
isDetails = true;
isReviews = false;
isAvailability = false;
});
},
child: Text(
TranslationBase.of(context).details,
style: TextStyle(
fontSize: 16,
fontWeight: FontWeight.bold),
), ),
color: Colors.white, CustomDivider(
), color: isDetails
CustomDivider( ? Colors.green
color: isDetails : Colors.transparent,
? Colors.green )
: Colors.transparent, ],
) ),
], SizedBox(
), width: 20,
SizedBox( ),
width: 20, Column(
), children: [
Column( FlatButton(
children: [ onPressed: () async {
FlatButton( if(widget.product.approvedTotalReviews>0) {
onPressed: () { GifLoaderDialogUtils.showMyDialog(
setState(() { context);
isDetails = false; await model.getProductReviewsData(
isReviews = true; widget.product.id);
isAvailability = false; GifLoaderDialogUtils.hideDialog(context);
}); }
}, setState(() {
child: Text( isDetails = false;
TranslationBase.of(context).reviews, isReviews = true;
style: TextStyle( isAvailability = false;
fontSize: 16, });
fontWeight: FontWeight.bold), },
child: Text(
TranslationBase.of(context).reviews,
style: TextStyle(
fontSize: 16,
fontWeight: FontWeight.bold),
),
color: Colors.white,
), ),
color: Colors.white, CustomDivider(
), color: isReviews
CustomDivider( ? Colors.green
color: isReviews : Colors.transparent,
? Colors.green
: Colors.transparent,
),
],
),
SizedBox(
width: 20,
),
Column(
children: [
FlatButton(
onPressed: () {
setState(() {
isDetails = false;
isReviews = false;
isAvailability = true;
});
},
child: Text(
TranslationBase.of(context).availability,
style: TextStyle(
fontSize: 16,
fontWeight: FontWeight.bold),
), ),
color: Colors.white, ],
), ),
CustomDivider( SizedBox(
color: isAvailability width: 20,
? Colors.green ),
: Colors.transparent, Column(
), children: [
], FlatButton(
), onPressed: () async {
], GifLoaderDialogUtils.showMyDialog(
), context);
SizedBox( await model.getProductLocationData();
height: 10, GifLoaderDialogUtils.hideDialog(context);
),
isDetails
? DetailsInfo(
product: widget.product,
)
: isReviews
? ReviewsInfo(
product: widget.product,
)
: isAvailability
? AvailabilityInfo()
: Container(),
],
),
),
///TODO Elham* check if we need recommanded
// Row(
// children: [
// customerId != null
// ? Container(
// width: 410,
// height: 50,
// color: Colors.white,
// child: Texts(
// TranslationBase.of(context).recommended,
// bold: true,
// ),
// )
// : Container(),
// ],
// ),
// RecommendedProducts(product: widget.product)
SizedBox( setState(() {
height: 80, isDetails = false;
) isReviews = false;
], isAvailability = true;
});
},
child: Text(
TranslationBase.of(context).availability,
style: TextStyle(
fontSize: 16,
fontWeight: FontWeight.bold),
),
color: Colors.white,
),
CustomDivider(
color: isAvailability
? Colors.green
: Colors.transparent,
),
],
),
],
),
SizedBox(
height: 10,
),
isDetails
? DetailsInfo(
product: widget.product,
)
: isReviews
? ReviewsInfo(
product: widget.product,
previousModel: model,
)
: isAvailability
? AvailabilityInfo(
previousModel: model,
)
: Container(),
],
),
),
SizedBox(
height: 80,
)
],
),
), ),
), bottomSheet: FooterWidget(
bottomSheet: FooterWidget( widget.product.stockAvailability != 'Out of stock',
widget.product.stockAvailability != 'Out of stock', widget.product.orderMaximumQuantity,
widget.product.orderMaximumQuantity, widget.product.orderMinimumQuantity,
widget.product.orderMinimumQuantity, widget.product.stockQuantity,
widget.product.stockQuantity, widget.product,
widget.product, quantity: quantity,
price: price, isOverQuantity: isOverQuantity,
isOverQuantity: isOverQuantity, addToCartFunction: addToCartFunction,
addToCartFunction: addToCartFunction, ),
), ));
);
} }
}
class CustomDivider extends StatelessWidget { addToWishlistFunction({itemID, ProductDetailViewModel model}) async {
const CustomDivider({ isInWishList = true;
Key key, await model.addToWishlistData(itemID);
this.color, }
}) : super(key: key);
final Color color;
@override deleteFromWishlistFunction({itemID, ProductDetailViewModel model}) async {
Widget build(BuildContext context) { isInWishList = false;
return Container( await model.deletWishlistData(itemID);
width: 120,
height: 2,
color: color,
);
} }
} }
convertCityName(txt) {
String stringTxt;
String newTxt;
stringTxt = txt.toString();
newTxt = stringTxt.split('.')[1];
return newTxt;
}
addToCartFunction(quantity, itemID, BuildContext context) async { addToCartFunction({quantity, itemID, BuildContext context,ProductDetailViewModel model}) async {
GifLoaderDialogUtils.showMyDialog(context); GifLoaderDialogUtils.showMyDialog(context);
ProductDetailViewModel x = new ProductDetailViewModel(); await model.addToCartData(quantity, itemID);
await x.addToCartData(quantity, itemID).then((value) { GifLoaderDialogUtils.hideDialog(context);
GifLoaderDialogUtils.hideDialog(context);
});
} }
notifyMeWhenAvailable(context, itemId) async { notifyMeWhenAvailable({itemId, customerId,ProductDetailViewModel model }) async {
ProductDetailViewModel x = new ProductDetailViewModel(); await model.notifyMe(customerId, itemId);
await x.notifyMe(customerId, itemId);
} }
addToWishlistFunction(itemID) async {
ProductDetailViewModel x = new ProductDetailViewModel();
isInWishList = true;
await x.addToWishlistData(itemID);
}
deleteFromWishlistFunction(itemID) async {
ProductDetailViewModel x = new ProductDetailViewModel();
isInWishList = false;
await x.deletWishlistData(itemID);
}
//TODO Elham* move to file
Widget tabWidget(
Size screenSize,
bool isActive,
String title,
) {
return Center(
child: Container(
height: screenSize.height * 0.070,
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
AppText(
title,
fontSize: SizeConfig.textMultiplier * 1.5,
// color: Color(0xFF2B353E),
fontWeight: FontWeight.w700,
),
],
),
),
);
}

@ -10,7 +10,7 @@ import 'package:provider/provider.dart';
import 'package:rating_bar/rating_bar.dart'; import 'package:rating_bar/rating_bar.dart';
import '../../../../locator.dart'; import '../../../../locator.dart';
import 'CustomIcon.dart'; import 'shared/icon_with_bg.dart';
class ProductNameAndPrice extends StatefulWidget { class ProductNameAndPrice extends StatefulWidget {
BuildContext context; BuildContext context;

@ -1,6 +1,7 @@
import 'package:diplomaticquarterapp/core/model/pharmacies/PharmacyProduct.dart'; import 'package:diplomaticquarterapp/core/model/pharmacies/PharmacyProduct.dart';
import 'package:diplomaticquarterapp/core/model/pharmacies/recommendedProduct_model.dart'; import 'package:diplomaticquarterapp/core/model/pharmacies/recommendedProduct_model.dart';
import 'package:diplomaticquarterapp/core/viewModels/pharmacyModule/pharmacy_module_view_model.dart'; import 'package:diplomaticquarterapp/core/viewModels/pharmacyModule/pharmacy_module_view_model.dart';
import 'package:diplomaticquarterapp/core/viewModels/pharmacyModule/product_detail_view_model.dart';
import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart';
import 'package:diplomaticquarterapp/pages/base/base_view.dart'; import 'package:diplomaticquarterapp/pages/base/base_view.dart';
import 'package:diplomaticquarterapp/pages/pharmacies/screens/product-details/product-detail.dart'; import 'package:diplomaticquarterapp/pages/pharmacies/screens/product-details/product-detail.dart';
@ -14,8 +15,23 @@ import 'package:rating_bar/rating_bar.dart';
class RecommendedProducts extends StatefulWidget { class RecommendedProducts extends StatefulWidget {
final PharmacyProduct product; final PharmacyProduct product;
final String customerId;
final ProductDetailViewModel productDetailViewModel;
final bool isOverQuantity;
final bool isInWishList;
final Function addToWishlistFunction;
final Function deleteFromWishlistFunction;
const RecommendedProducts({Key key, this.product}) : super(key: key); RecommendedProducts(
{Key key,
this.product,
this.productDetailViewModel,
this.customerId,
this.isOverQuantity = false,
this.isInWishList = false,
this.addToWishlistFunction,
this.deleteFromWishlistFunction})
: super(key: key);
@override @override
_RecommendedProductsState createState() => _RecommendedProductsState(); _RecommendedProductsState createState() => _RecommendedProductsState();
@ -39,273 +55,235 @@ class _RecommendedProductsState extends State<RecommendedProducts> {
padding: EdgeInsets.only(bottom: 5), padding: EdgeInsets.only(bottom: 5),
// margin: EdgeInsets.symmetric(horizontal: 6, vertical: 4), // margin: EdgeInsets.symmetric(horizontal: 6, vertical: 4),
child: BaseView<PharmacyModuleViewModel>( child: BaseView<PharmacyModuleViewModel>(
onModelReady: (model) => model onModelReady: (model) =>
.getRecommendedProducts(widget.product.id), model.getRecommendedProducts(widget.product.id),
builder: (_, model, wi) => Container( builder: (_, model, wi) => Container(
child: child: model.recommendedProductList.length != null
model.recommendedProductList.length != null
? ListView.builder( ? ListView.builder(
scrollDirection: scrollDirection: Axis.horizontal,
Axis.horizontal,
shrinkWrap: true, shrinkWrap: true,
physics: ScrollPhysics(), physics: ScrollPhysics(),
// physics: NeverScrollableScrollPhysics(), // physics: NeverScrollableScrollPhysics(),
itemCount: model itemCount: model.recommendedProductList.length,
.recommendedProductList
.length,
itemBuilder: (context, index) { itemBuilder: (context, index) {
return InkWell( return InkWell(
onTap: () async { onTap: () async {
GifLoaderDialogUtils GifLoaderDialogUtils.showMyDialog(context);
.showMyDialog( RecommendedProductModel data =
context); model.recommendedProductList[index];
RecommendedProductModel
data =
model.recommendedProductList[
index];
var json = data.toJson(); var json = data.toJson();
PharmacyProduct product = PharmacyProduct product =
new PharmacyProduct new PharmacyProduct.fromJson(json);
.fromJson(json); await Navigator.pushReplacement(
await Navigator
.pushReplacement(
context, context,
FadePage( FadePage(
page: page: ProductDetailPage(product),
ProductDetailPage(
product),
), ),
); );
GifLoaderDialogUtils GifLoaderDialogUtils.hideDialog(context);
.hideDialog(context);
}, },
child: Card( child: Card(
elevation: 2, elevation: 2,
shape: shape: RoundedRectangleBorder(
RoundedRectangleBorder(
side: BorderSide( side: BorderSide(
color: Colors color: Colors.grey[300], width: 2),
.grey[300], borderRadius: BorderRadius.circular(10),
width: 2),
borderRadius:
BorderRadius
.circular(10),
), ),
margin: margin: EdgeInsets.symmetric(
EdgeInsets.symmetric(
horizontal: 8, horizontal: 8,
vertical: 0, vertical: 0,
), ),
child: Container( child: Container(
decoration: decoration: BoxDecoration(
BoxDecoration( borderRadius: BorderRadius.all(
borderRadius:
BorderRadius.all(
Radius.circular(15), Radius.circular(15),
), ),
), ),
padding: EdgeInsets padding: EdgeInsets.symmetric(horizontal: 4),
.symmetric( width: MediaQuery.of(context).size.width / 3,
horizontal: 4),
width: MediaQuery.of(
context)
.size
.width /
3,
child: Column( child: Column(
crossAxisAlignment: crossAxisAlignment:
CrossAxisAlignment CrossAxisAlignment.start,
.start,
children: [ children: [
Stack(children: [ Stack(children: [
Container( Container(
child: Align( child: Align(
alignment: alignment: Alignment.topRight,
Alignment child: IconButton(
.topRight, icon: Icon(model
child: .recommendedProductList[
IconButton( index]
icon: Icon(model.recommendedProductList[index].isinwishlist != .isinwishlist !=
true true
? Icons ? Icons.favorite_border
.favorite_border : Icons.favorite),
: Icons color: model
.favorite), .recommendedProductList[
color: model.recommendedProductList[index].isinwishlist != index]
true .isinwishlist !=
? Colors true
.grey ? Colors.grey
: Colors : Colors.red,
.red, onPressed: () async {
onPressed: if (widget.customerId != null) {
() async { if (!widget.isInWishList &&
if (customerId != model
null) { .recommendedProductList[
if (!isInWishList && index]
model.recommendedProductList[index].isinwishlist != .isinwishlist !=
true) { true) {
GifLoaderDialogUtils.showMyDialog( GifLoaderDialogUtils
context); .showMyDialog(context);
await addToWishlistFunction(model await widget.addToWishlistFunction(
.recommendedProductList[index] itemID: model
.id); .recommendedProductList[
index]
.id,
model: widget
.productDetailViewModel);
// checkWishlist(); // checkWishlist();
GifLoaderDialogUtils.hideDialog( GifLoaderDialogUtils
context); .hideDialog(context);
setState( setState(() {
() { model
model.recommendedProductList[index].isinwishlist = .recommendedProductList[
true; index]
}); .isinwishlist = true;
});
} else { } else {
GifLoaderDialogUtils.showMyDialog( GifLoaderDialogUtils
context); .showMyDialog(context);
await deleteFromWishlistFunction(model await widget.deleteFromWishlistFunction(
.recommendedProductList[index] itemID: model
.id); .recommendedProductList[
GifLoaderDialogUtils.hideDialog( index]
context); .id,
setState( model: widget
() { .productDetailViewModel);
model.recommendedProductList[index].isinwishlist = GifLoaderDialogUtils
false; .hideDialog(context);
}); setState(() {
model
.recommendedProductList[
index]
.isinwishlist = false;
});
} }
} else { } else {
return; return;
} }
setState( setState(() {
() { // checkWishlist();
// checkWishlist(); });
});
}, },
), ),
), ),
), ),
Container( Container(
margin: EdgeInsets margin: EdgeInsets.fromLTRB(
.fromLTRB( 0, 16, 10, 16),
0, alignment: Alignment.center,
16, child: (model
10, .recommendedProductList[
16), index]
alignment: .images !=
Alignment null &&
.center, model
child: (model.recommendedProductList[index].images != .recommendedProductList[
null && index]
model.recommendedProductList[index].images.length > .images
0) .length >
? Image 0)
.network( ? Image.network(
model model
.recommendedProductList[index] .recommendedProductList[
.images[0] index]
.src .images[0]
.toString(), .src
fit: BoxFit .toString(),
.cover, fit: BoxFit.cover,
height: height: 60,
60, )
) : Image.asset(
: Image "assets/images/no_image.png",
.asset( fit: BoxFit.cover,
"assets/images/no_image.png", height: 60,
fit: BoxFit ),
.cover,
height:
60,
),
), ),
Container( Container(
width: model width: model
.recommendedProductList[ .recommendedProductList[
index] index]
.rxMessage != .rxMessage !=
null null
? MediaQuery.of(context) ? MediaQuery.of(context)
.size .size
.width / .width /
5 5
: 0, : 0,
padding: padding: EdgeInsets.all(4),
EdgeInsets decoration: BoxDecoration(
.all(4), color: Color(0xffb23838),
decoration: borderRadius: BorderRadius.only(
BoxDecoration( topLeft: Radius.circular(6),
color: Color(
0xffb23838),
borderRadius:
BorderRadius
.only(
topLeft: Radius
.circular(
6),
), ),
), ),
child: model.recommendedProductList[index] child: model
.rxMessage != .recommendedProductList[
null index]
.rxMessage !=
null
? Texts( ? Texts(
projectViewModel.isArabic projectViewModel.isArabic
? model.recommendedProductList[index].rxMessagen ? model
: model.recommendedProductList[index].rxMessage, .recommendedProductList[
color: Colors index]
.white, .rxMessagen
regular: : model
true, .recommendedProductList[
fontSize: index]
10, .rxMessage,
fontWeight: color: Colors.white,
FontWeight.w400, regular: true,
) fontSize: 10,
fontWeight: FontWeight.w400,
)
: Texts(""), : Texts(""),
), ),
]), ]),
Container( Container(
margin: EdgeInsets margin: EdgeInsets.symmetric(
.symmetric(
horizontal: 6, horizontal: 6,
vertical: 0, vertical: 0,
), ),
child: Column( child: Column(
crossAxisAlignment: crossAxisAlignment:
CrossAxisAlignment CrossAxisAlignment.start,
.start,
children: [ children: [
Text( Text(
projectViewModel projectViewModel.isArabic
.isArabic
? model ? model
.recommendedProductList[ .recommendedProductList[
index] index]
.namen .namen
: model : model
.recommendedProductList[index] .recommendedProductList[
.name, index]
style: .name,
TextStyle( style: TextStyle(
color: Colors color: Colors.black,
.black, fontSize: 13.0,
fontSize:
13.0,
// fontWeight: FontWeight.bold, // fontWeight: FontWeight.bold,
), ),
), ),
Padding( Padding(
// padding: const EdgeInsets.only(top: 15, bottom: 10), // padding: const EdgeInsets.only(top: 15, bottom: 10),
padding: const EdgeInsets padding: const EdgeInsets.only(
.only( top: 10, bottom: 5),
top: 10, child: Texts(
bottom:
5),
child:
Texts(
"SAR ${model.recommendedProductList[index].price}", "SAR ${model.recommendedProductList[index].price}",
bold: bold: true,
true, fontSize: 14,
fontSize:
14,
), ),
), ),
], ],
@ -313,47 +291,35 @@ class _RecommendedProductsState extends State<RecommendedProducts> {
), ),
Row( Row(
crossAxisAlignment: crossAxisAlignment:
CrossAxisAlignment CrossAxisAlignment.start,
.start, children: <Widget>[
children: <
Widget>[
Container( Container(
padding: EdgeInsets.only( padding:
right: EdgeInsets.only(right: 10),
10), child: Align(
child: alignment: Alignment.topLeft,
Align( child: RatingBar.readOnly(
alignment:
Alignment
.topLeft,
child: RatingBar
.readOnly(
initialRating: model initialRating: model
.recommendedProductList[index] .recommendedProductList[
index]
.approvedRatingSum .approvedRatingSum
.toDouble(), .toDouble(),
size: size: 13.0,
13.0,
filledColor: filledColor:
Colors.yellow[700], Colors.yellow[700],
emptyColor: emptyColor: Colors.grey[500],
Colors.grey[500], isHalfAllowed: true,
isHalfAllowed:
true,
halfFilledIcon: halfFilledIcon:
Icons.star_half, Icons.star_half,
filledIcon: filledIcon: Icons.star,
Icons.star, emptyIcon: Icons.star,
emptyIcon:
Icons.star,
), ),
), ),
), ),
Texts( Texts(
"(${model.recommendedProductList[index].notApprovedTotalReviews.toString()})", "(${model.recommendedProductList[index].notApprovedTotalReviews.toString()})",
// bold: true, // bold: true,
fontSize: fontSize: 12,
12,
), ),
]), ]),
], ],
@ -363,20 +329,18 @@ class _RecommendedProductsState extends State<RecommendedProducts> {
); );
}) })
: Container( : Container(
// color: Colors.white, // color: Colors.white,
child: Row( child: Row(
mainAxisAlignment: mainAxisAlignment: MainAxisAlignment.center,
MainAxisAlignment.center, // crossAxisAlignment: CrossAxisAlignment.center,
// crossAxisAlignment: CrossAxisAlignment.center, children: [
children: [ Texts(
Texts( TranslationBase.of(context).nonRecommended,
TranslationBase.of(context) color: Colors.black,
.nonRecommended, ),
color: Colors.black, ],
),
), ),
],
),
),
), ),
), ),
), ),

@ -1,97 +1,89 @@
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
allowAny: true, ? ListView.builder(
builder: (_, model, wi) => NetworkBaseView( physics: ScrollPhysics(),
baseViewModel:model , itemCount: previousModel.productDetailService[0].reviews.length,
child: model.productDetailService.length != 0 && scrollDirection: Axis.vertical,
model.productDetailService[0].reviews.length != 0 shrinkWrap: true,
? ListView.builder( itemBuilder: (BuildContext context, int index) {
physics: ScrollPhysics(), return Padding(
itemCount: model.productDetailService[0].reviews.length, padding: EdgeInsets.all(8.0),
scrollDirection: Axis.vertical, child: Column(
shrinkWrap: true, mainAxisAlignment: MainAxisAlignment.start,
itemBuilder: (BuildContext context, int index) { crossAxisAlignment: CrossAxisAlignment.start,
return Padding( children: [
padding: EdgeInsets.all(8.0), Container(
child: Column( child: Row(
mainAxisAlignment: MainAxisAlignment.start, children: [
crossAxisAlignment: CrossAxisAlignment.start, Container(
children: [ child: Text(
Container( previousModel.productDetailService[0].reviews[index]
child: Row( .customerId
children: [ .toString(),
Container( style: TextStyle(
child: Text( fontSize: 17,
model.productDetailService[0].reviews[index] color: Colors.grey,
.customerId fontWeight: FontWeight.w600),
.toString(), ),
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,
),
),
],
),
),
SizedBox(
height: 10,
),
Container(
child: Text(
model.productDetailService[0].reviews[index]
.reviewText,
style: TextStyle(fontSize: 20),
),
),
SizedBox(
height: 50,
),
Divider(height: 1, color: Colors.grey),
],
), ),
); Container(
}, margin: EdgeInsets.only(left: 210),
) child: RatingBar.readOnly(
: Container( initialRating: previousModel.productDetailService[0]
padding: EdgeInsets.all(15), .reviews[index].rating
alignment: Alignment.center, .toDouble(),
size: 15.0,
filledColor: Colors.yellow[700],
emptyColor: Colors.grey[500],
isHalfAllowed: true,
halfFilledIcon: Icons.star_half,
filledIcon: Icons.star,
emptyIcon: Icons.star,
),
),
],
),
),
SizedBox(
height: 10,
),
Container(
child: Text( child: Text(
TranslationBase.of(context).noReviewsAvailable, previousModel.productDetailService[0].reviews[index]
.reviewText,
style: TextStyle(fontSize: 20),
), ),
// Text('No Reviews Available'),
), ),
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'),
); );
} }
} }

@ -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,7 +11,6 @@ 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(

@ -1,5 +1,6 @@
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/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/pages/pharmacies/screens/product-details/product-detail.dart';
import 'package:diplomaticquarterapp/uitl/app_toast.dart'; import 'package:diplomaticquarterapp/uitl/app_toast.dart';
import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart';
@ -7,25 +8,28 @@ import 'package:flutter/material.dart';
import 'package:font_awesome_flutter/font_awesome_flutter.dart'; import 'package:font_awesome_flutter/font_awesome_flutter.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
import '../../../../locator.dart'; import '../../../../../locator.dart';
import '../../compare-list.dart'; import '../../../compare-list.dart';
import '../cart-order-page.dart'; import '../../cart-order-page.dart';
import 'CustomIcon.dart'; import 'icon_with_bg.dart';
class ProductAppBar extends StatelessWidget with PreferredSizeWidget { class ProductAppBar extends StatelessWidget with PreferredSizeWidget {
final PharmacyProduct product; final PharmacyProduct product;
ProductAppBar({Key key, this.product}) : super(key: key); final ProductDetailViewModel model;
final Function addToWishlistFunction;
final int quantity;
ProductAppBar({Key key, this.product, this.model, this.addToWishlistFunction, this.quantity})
: super(key: key);
AuthenticatedUserObject authenticatedUserObject = AuthenticatedUserObject authenticatedUserObject =
locator<AuthenticatedUserObject>(); locator<AuthenticatedUserObject>();
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Container( return Container(
color: Colors.white, color: Colors.white,
child: FractionallySizedBox( child: FractionallySizedBox(
widthFactor: 0.95, widthFactor: 0.95,
child: Column( child: Column(
@ -47,29 +51,31 @@ class ProductAppBar extends StatelessWidget with PreferredSizeWidget {
), ),
], ],
), ),
if(authenticatedUserObject.isLogin) if (authenticatedUserObject.isLogin)
Row( Row(
children: [ children: [
IconWithBg( IconWithBg(
icon: Icons.shopping_cart, icon: Icons.shopping_cart,
color: Colors.grey,
onPress: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => CartOrderPage()),
);
}),
SizedBox(
width: 10,
),
IconWithBg(
icon: FontAwesomeIcons.ellipsisV,
color: Colors.grey, color: Colors.grey,
onPress: () { onPress: () {
Navigator.push( settingModalBottomSheet(context);
context, },
MaterialPageRoute( ),
builder: (context) => CartOrderPage()), ],
); )
}),
SizedBox(width: 10,),
IconWithBg(
icon: FontAwesomeIcons.ellipsisV,
color: Colors.grey,
onPress: () {
settingModalBottomSheet(context);
},
),
],
)
], ],
), ),
], ],
@ -78,10 +84,7 @@ class ProductAppBar extends StatelessWidget with PreferredSizeWidget {
); );
} }
@override @override
// TODO: implement preferredSize
@override @override
Size get preferredSize => Size(double.maxFinite, 50); Size get preferredSize => Size(double.maxFinite, 50);
@ -92,27 +95,34 @@ class ProductAppBar extends StatelessWidget with PreferredSizeWidget {
return Container( return Container(
child: new Wrap( child: new Wrap(
children: <Widget>[ children: <Widget>[
if( product.stockAvailability != 'Out of stock') if (product.stockAvailability != 'Out of stock')
new ListTile( new ListTile(
leading: Icon(Icons.shopping_cart), leading: Icon(Icons.shopping_cart),
title: Text( title: Text(
TranslationBase.of(context).addToCart, TranslationBase.of(context).addToCart,
), ),
onTap: () => { onTap: () => {
if (price > 0) if (quantity > 0)
{addToCartFunction(price, itemID, context)} {
else addToCartFunction(
{ quantity: quantity,
AppToast.showErrorToast( itemID: itemID,
message: "you should add quantity") context: context,
} model: model)
}), }
else
{
AppToast.showErrorToast(
message: "you should add quantity")
}
}),
ListTile( ListTile(
leading: Icon(Icons.favorite_border), leading: Icon(Icons.favorite_border),
title: Text( title: Text(
TranslationBase.of(context).addToWishlist, TranslationBase.of(context).addToWishlist,
), ),
onTap: () => {addToWishlistFunction(itemID)}, onTap: () =>
{addToWishlistFunction(itemID: itemID, model: model)},
), ),
ListTile( ListTile(
leading: Icon(Icons.compare), leading: Icon(Icons.compare),
@ -130,5 +140,3 @@ class ProductAppBar extends StatelessWidget with PreferredSizeWidget {
}); });
} }
} }

@ -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,

@ -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