Merge branch 'development_new_design_2.0' into mirza_home_page

# Conflicts:
#	lib/config/localized_values.dart
#	lib/pages/AlHabibMedicalService/health_calculator/bmr_calculator/bmr_calculator.dart
#	lib/pages/AlHabibMedicalService/health_calculator/bmr_calculator/bmr_result_page.dart
#	lib/pages/AlHabibMedicalService/health_calculator/body_fat/body_fat.dart
#	lib/pages/AlHabibMedicalService/health_calculator/calorie_calculator/calorie_calculator.dart
#	lib/pages/AlHabibMedicalService/health_calculator/calorie_calculator/calorie_result_page.dart
#	lib/pages/AlHabibMedicalService/health_calculator/ideal_body/ideal_body.dart
#	lib/uitl/translations_delegate_base.dart
merge-update-with-lab-changes
devmirza121 4 years ago
commit a131f24952

@ -1037,6 +1037,7 @@ const Map localizedValues = {
"no-data": {"en": "No data found", "ar": "لاتوجد بيانات"}, "no-data": {"en": "No data found", "ar": "لاتوجد بيانات"},
"insurance-details": {"en": "Insurance Details", "ar": "تفاصيل التأمين"}, "insurance-details": {"en": "Insurance Details", "ar": "تفاصيل التأمين"},
"nearest-hospital": {"en": "Nearest Hospital", "ar": "أقرب مستشفى"}, "nearest-hospital": {"en": "Nearest Hospital", "ar": "أقرب مستشفى"},
"submitReview": {"en": "Your review has been Submitted successfully", "ar": "تم إرسال التقييم بنجاح"},
"request-sent": {"en": "Request sent successfully", "ar": "تم إرسال الطلب بنجاح"}, "request-sent": {"en": "Request sent successfully", "ar": "تم إرسال الطلب بنجاح"},
"message-sent": {"en": "Message sent successfully", "ar": "تم إرسال الرسالة بنجاح"}, "message-sent": {"en": "Message sent successfully", "ar": "تم إرسال الرسالة بنجاح"},
"sent-on": {"en": "Sent on", "ar": "أرسلت في"}, "sent-on": {"en": "Sent on", "ar": "أرسلت في"},
@ -1674,5 +1675,36 @@ const Map localizedValues = {
"estimates": {"en": "Estimates the total body fat based on\nthe size", "ar": "تقدير إجمالي الدهون في الجسم بناءً على \ n الحجم"}, "estimates": {"en": "Estimates the total body fat based on\nthe size", "ar": "تقدير إجمالي الدهون في الجسم بناءً على \ n الحجم"},
"myCart": {"en": "Cart", "ar": "عربة التسوق"},
"browseOffers": {"en": "Browse offers by clinic", "ar": "تصفح العروض حسب العيادة"},
"inactiveAct":{"en":"Almost inactive (little or no exercise)","ar":"غير نشط تقريبا (ممارسة الرياضة قليلة أو منعدمة)"},
"light":{"en":"Lightly active (1-3) days per week","ar":"خفيف النشاط (1-3 أيام في الأسبوع)"},
"moderate":{"en":"Moderately active (3-5) days per week)","ar":"معتدل النشاط (3-5 أيام في الأسبوع)"},
"very":{"en":"Very active (6-7) days per week)","ar":"نشط جداُ (6-7 أيام في الأسبوع)"},
"super":{"en":"Super active (very hard exercise)","ar":"عالي النشاط (ممارسة الرياضة الصعبة)"},
"resultCalories": {"en": "Daily intake is (#) calories", "ar": "الإحتياج اليومي (#) سعرة حرارية"},
"bmrDesc": {"en": "Calculates the amount of energy that the persons body expends in a day", "ar": "معدل الأيض القاعدي: هو حساب كمية الطاقة التي يحتاجها الجسم في اليوم الواحد"},
"idealWeightDesc": {"en": "Calculates the ideal body weight based on height, Weight, and Body Size", "ar": "حساب الوزن المثالي والوزن الصحي للجسم على أساس الطول، والوزن ،والجسم"},
"bodyFrame": {"en": "Body Frame Size", "ar": "مقاس هيكل الجسم"},
"bodyFrameSmall": {"en": "Small (fingers overlap)", "ar": "رفيع (الأصابع تتداخل)"},
"bodyFrameMedium": {"en": "Medium (fingers touch)", "ar": "متوسط (الأصابع تتلامس)"},
"bodyFrameLarge": {"en": "Large (fingers don't touch)", "ar": "عريض (الأصابع لا تتلامس)"},
"bodyFatDesc": {"en": "Estimates the total body fat based on the size", "ar": "حساب الدهون في الجسم بناءاً على الحجم"},
"essential":{"en":"The category falls under Essential Fat.","ar":"تندرج تحت فئة دهون أساسية"},
"athlete":{"en":" The category falls under Athlete.","ar":"تندرج تحت فئة دهون جسم رياضي"},
"fitness":{"en":" The category falls under Fitness.","ar":"تندرج تحت فئة دهون جسم صحي"},
"acceptable":{"en":"The category falls under Acceptable","ar":"تندرج تحت فئة دهون مقبولة"},
"obeseBodyFat":{"en":"The category falls under Obese.","ar":"تندرج تحت فئة دهون جسم سمين"},
"invalid":{"en":"Invalid input for calculation.","ar":"البيانات المدخلة غير صالحة للحساب"},
"more":{"en":"Please check the value you have entered, since the body fat percentage has crossed the limits.","ar":"يرجى التحقق من القيمة التي أدخلتها ، نظرًا لأن نسبة الدهون في الجسم قد تجاوزت الحدود"},
"less":{"en":"Please check the value you have entered, since the body fat percentage cannot be this low.","ar":"يرجى التحقق من القيمة التي أدخلتها ، نظرًا لأن نسبة الدهون في الجسم لا يمكن أن تكون منخفضة"},
"carbProteinDesc": {"en": "Calculates carbohydrate protein and fat ratio in calories and grams according to a pre-set ratio", "ar": "حساب نسب الكربوهيدرات و البروتينات و الدهون بالسعرات الحرارية والغرامات وفقا لنسب محددة مسبقا"},
"calDay": {"en": "Calories Per Day", "ar": "السعرات الحرارية في اليوم الواحد"},
"notSure": {"en": "Not sure? click here", "ar": "غير متأكد؟ اضغط هنا"},
"selectDiet": {"en": "Select Diet Type", "ar": "حدد نوع النظام الغذائي"},
"dietVeryLow":{"en":"Very Low Carb","ar":"حمية منخفضة جدا في الكربوهيدرات"},
"dietLow":{"en":"Low Carb","ar":"حمية منخفضة الكربوهيدرات"},
"dietModerate":{"en":"Moderate Carb","ar":"حمية معتدلة الكربوهيدرات"},
"dietUSDA":{"en":"USDA Guidelines","ar":"ارشادات وزارة الزراعة الأمريكية"},
"dietZone":{"en":"Zone Diet","ar":"حمية زون"},
}; };

@ -192,6 +192,8 @@ class PackagesResponseModel with JsonConvert<PackagesResponseModel> {
List<dynamic> discountIds; List<dynamic> discountIds;
@JSONField(name: "store_ids") @JSONField(name: "store_ids")
List<dynamic> storeIds; List<dynamic> storeIds;
@JSONField(name: "store_names")
List<dynamic> storeNames;
@JSONField(name: "manufacturer_ids") @JSONField(name: "manufacturer_ids")
List<int> manufacturerIds; List<int> manufacturerIds;
List<dynamic> reviews; List<dynamic> reviews;
@ -207,12 +209,10 @@ class PackagesResponseModel with JsonConvert<PackagesResponseModel> {
String seName; String seName;
String getName() { String getName() {
if(localizedNames.length == 2){ if (localizedNames.length == 2) {
if(localizedNames.first.languageId == 2) if (localizedNames.first.languageId == 2)
return localizedNames.first.localizedName ?? name; return localizedNames.first.localizedName ?? name;
else if (localizedNames.first.languageId == 1) return localizedNames.last.localizedName ?? name;
else if(localizedNames.first.languageId == 1)
return localizedNames.last.localizedName ?? name;
} }
return name; return name;
} }

@ -481,7 +481,7 @@ class BaseAppClient {
simplePost( simplePost(
String fullUrl, { String fullUrl, {
Map<String, dynamic> body, Map<dynamic, dynamic> body,
Map<String, String> headers, Map<String, String> headers,
Function(dynamic response, int statusCode) onSuccess, Function(dynamic response, int statusCode) onSuccess,
Function(String error, int statusCode) onFailure, Function(String error, int statusCode) onFailure,
@ -496,7 +496,6 @@ class BaseAppClient {
body: json.encode(body), body: json.encode(body),
headers: headers, headers: headers,
); );
final int statusCode = response.statusCode; final int statusCode = response.statusCode;
print("statusCode :$statusCode"); print("statusCode :$statusCode");
if (await handleUnauthorized(statusCode, forUrl: fullUrl)) simplePost(fullUrl, onFailure: onFailure, onSuccess: onSuccess, body: body, headers: headers); if (await handleUnauthorized(statusCode, forUrl: fullUrl)) simplePost(fullUrl, onFailure: onFailure, onSuccess: onSuccess, body: body, headers: headers);
@ -514,7 +513,6 @@ class BaseAppClient {
simpleGet(String fullUrl, simpleGet(String fullUrl,
{Function(dynamic response, int statusCode) onSuccess, Function(String error, int statusCode) onFailure, Map<String, String> queryParams, Map<String, String> headers}) async { {Function(dynamic response, int statusCode) onSuccess, Function(String error, int statusCode) onFailure, Map<String, String> queryParams, Map<String, String> headers}) async {
String url = fullUrl; String url = fullUrl;
print("URL Query String: $url");
var haveParams = (queryParams != null); var haveParams = (queryParams != null);
if (haveParams) { if (haveParams) {

@ -4,6 +4,7 @@ import 'dart:developer';
import 'package:diplomaticquarterapp/config/config.dart'; import 'package:diplomaticquarterapp/config/config.dart';
import 'package:diplomaticquarterapp/config/shared_pref_kay.dart'; import 'package:diplomaticquarterapp/config/shared_pref_kay.dart';
import 'package:diplomaticquarterapp/core/model/ResponseModel.dart'; import 'package:diplomaticquarterapp/core/model/ResponseModel.dart';
import 'package:diplomaticquarterapp/core/model/hospitals/hospitals_model.dart';
import 'package:diplomaticquarterapp/core/model/packages_offers/requests/AddProductToCartRequestModel.dart'; import 'package:diplomaticquarterapp/core/model/packages_offers/requests/AddProductToCartRequestModel.dart';
import 'package:diplomaticquarterapp/core/model/packages_offers/requests/CreateCustomerRequestModel.dart'; import 'package:diplomaticquarterapp/core/model/packages_offers/requests/CreateCustomerRequestModel.dart';
import 'package:diplomaticquarterapp/core/model/packages_offers/requests/OffersCategoriesRequestModel.dart'; import 'package:diplomaticquarterapp/core/model/packages_offers/requests/OffersCategoriesRequestModel.dart';
@ -15,13 +16,12 @@ import 'package:diplomaticquarterapp/core/model/packages_offers/responses/Packag
import 'package:diplomaticquarterapp/core/model/packages_offers/responses/order_response_model.dart'; import 'package:diplomaticquarterapp/core/model/packages_offers/responses/order_response_model.dart';
import 'package:diplomaticquarterapp/core/model/packages_offers/responses/tamara_payment_option.dart'; import 'package:diplomaticquarterapp/core/model/packages_offers/responses/tamara_payment_option.dart';
import 'package:diplomaticquarterapp/core/service/base_service.dart'; import 'package:diplomaticquarterapp/core/service/base_service.dart';
import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart';
import 'package:diplomaticquarterapp/models/Authentication/authenticated_user.dart'; import 'package:diplomaticquarterapp/models/Authentication/authenticated_user.dart';
import 'package:diplomaticquarterapp/uitl/gif_loader_dialog_utils.dart'; import 'package:diplomaticquarterapp/uitl/gif_loader_dialog_utils.dart';
import 'package:diplomaticquarterapp/uitl/utils.dart';
import 'package:flutter/cupertino.dart'; import 'package:flutter/cupertino.dart';
var packagesAuthHeader = <String,String>{'Authorization' : ''}; Map<String, String> packagesAuthHeader = {};
class OffersAndPackagesServices extends BaseService { class OffersAndPackagesServices extends BaseService {
AuthenticatedUser patientUser; AuthenticatedUser patientUser;
List<PackagesCategoriesResponseModel> categoryList = List(); List<PackagesCategoriesResponseModel> categoryList = List();
@ -31,9 +31,10 @@ class OffersAndPackagesServices extends BaseService {
List<PackagesResponseModel> bestSellerList = List(); List<PackagesResponseModel> bestSellerList = List();
List<PackagesResponseModel> bannersList = List(); List<PackagesResponseModel> bannersList = List();
List<PackagesCartItemsResponseModel> cartItemList = List(); List<PackagesCartItemsResponseModel> cartItemList = List();
List<HospitalsModel> _hospitals = List();
List<HospitalsModel> get hospitals => _hospitals;
String cartItemCount = ""; String cartItemCount = "";
PackagesCustomerResponseModel customer; PackagesCustomerResponseModel customer;
Future<List<PackagesCategoriesResponseModel>> getAllCategories(OffersCategoriesRequestModel request) async { Future<List<PackagesCategoriesResponseModel>> getAllCategories(OffersCategoriesRequestModel request) async {
@ -47,8 +48,7 @@ class OffersAndPackagesServices extends BaseService {
categoryList.add(PackagesCategoriesResponseModel().fromJson(json)); categoryList.add(PackagesCategoriesResponseModel().fromJson(json));
}); });
} }
}, onFailure: (String error, int statusCode) { }, onFailure: (String error, int statusCode) {}, queryParams: request.toFlatMap());
}, queryParams: request.toFlatMap());
return categoryList; return categoryList;
} }
@ -57,7 +57,7 @@ class OffersAndPackagesServices extends BaseService {
Future errorThrow; Future errorThrow;
request.sinceId = (productList.isNotEmpty) ? productList.last.id : 0; request.sinceId = (productList.isNotEmpty) ? productList.last.id : 0;
productList = List(); productList = List();
var url = EXA_CART_API_BASE_URL + PACKAGES_PRODUCTS; var url = EXA_CART_API_BASE_URL + PACKAGES_PRODUCTS;
await baseAppClient.simpleGet(url, headers: packagesAuthHeader, onSuccess: (dynamic stringResponse, int statusCode) { await baseAppClient.simpleGet(url, headers: packagesAuthHeader, onSuccess: (dynamic stringResponse, int statusCode) {
@ -67,15 +67,13 @@ class OffersAndPackagesServices extends BaseService {
productList.add(PackagesResponseModel().fromJson(json)); productList.add(PackagesResponseModel().fromJson(json));
}); });
} }
}, onFailure: (String error, int statusCode) { }, onFailure: (String error, int statusCode) {}, queryParams: request.toFlatMap());
}, queryParams: request.toFlatMap());
return productList; return productList;
} }
Future<List<TamaraPaymentOption>> getTamaraOptions({@required BuildContext context, @required bool showLoading = true}) async { Future<List<TamaraPaymentOption>> getTamaraOptions({@required BuildContext context, @required bool showLoading = true}) async {
if(tamaraPaymentOptions != null && tamaraPaymentOptions.isNotEmpty) if (tamaraPaymentOptions != null && tamaraPaymentOptions.isNotEmpty) return tamaraPaymentOptions;
return tamaraPaymentOptions;
var url = EXA_CART_API_BASE_URL + PACKAGES_TAMARA_OPT; var url = EXA_CART_API_BASE_URL + PACKAGES_TAMARA_OPT;
await baseAppClient.simpleGet(url, headers: packagesAuthHeader, onSuccess: (dynamic stringResponse, int statusCode) { await baseAppClient.simpleGet(url, headers: packagesAuthHeader, onSuccess: (dynamic stringResponse, int statusCode) {
@ -93,9 +91,9 @@ class OffersAndPackagesServices extends BaseService {
} }
Future<List<PackagesResponseModel>> getLatestOffers({@required OffersProductsRequestModel request, @required BuildContext context, @required bool showLoading = true}) async { Future<List<PackagesResponseModel>> getLatestOffers({@required OffersProductsRequestModel request, @required BuildContext context, @required bool showLoading = true}) async {
var url = EXA_CART_API_BASE_URL + PACKAGES_PRODUCTS; var url = EXA_CART_API_BASE_URL + PACKAGES_PRODUCTS;
await baseAppClient.simpleGet(url, headers: packagesAuthHeader, onSuccess: (dynamic stringResponse, int statusCode) { await baseAppClient.simpleGet(url, headers: packagesAuthHeader, onSuccess: (dynamic stringResponse, int statusCode) {
latestOffersList.clear();
if (statusCode == 200) { if (statusCode == 200) {
var jsonResponse = json.decode(stringResponse); var jsonResponse = json.decode(stringResponse);
jsonResponse['products'].forEach((json) { jsonResponse['products'].forEach((json) {
@ -110,9 +108,9 @@ class OffersAndPackagesServices extends BaseService {
} }
Future<List<PackagesResponseModel>> getBestSellers({@required OffersProductsRequestModel request, @required BuildContext context, @required bool showLoading = true}) async { Future<List<PackagesResponseModel>> getBestSellers({@required OffersProductsRequestModel request, @required BuildContext context, @required bool showLoading = true}) async {
var url = EXA_CART_API_BASE_URL + PACKAGES_PRODUCTS; var url = EXA_CART_API_BASE_URL + PACKAGES_PRODUCTS;
await baseAppClient.simpleGet(url, headers: packagesAuthHeader, onSuccess: (dynamic stringResponse, int statusCode) { await baseAppClient.simpleGet(url, headers: packagesAuthHeader, onSuccess: (dynamic stringResponse, int statusCode) {
bestSellerList.clear();
if (statusCode == 200) { if (statusCode == 200) {
var jsonResponse = json.decode(stringResponse); var jsonResponse = json.decode(stringResponse);
jsonResponse['products'].forEach((json) { jsonResponse['products'].forEach((json) {
@ -126,7 +124,6 @@ class OffersAndPackagesServices extends BaseService {
return bestSellerList; return bestSellerList;
} }
Future<List<PackagesResponseModel>> getBanners({@required OffersProductsRequestModel request, @required BuildContext context, @required bool showLoading = true}) async { Future<List<PackagesResponseModel>> getBanners({@required OffersProductsRequestModel request, @required BuildContext context, @required bool showLoading = true}) async {
var url = EXA_CART_API_BASE_URL + PACKAGES_PRODUCTS; var url = EXA_CART_API_BASE_URL + PACKAGES_PRODUCTS;
await baseAppClient.simpleGet(url, headers: packagesAuthHeader, onSuccess: (dynamic stringResponse, int statusCode) { await baseAppClient.simpleGet(url, headers: packagesAuthHeader, onSuccess: (dynamic stringResponse, int statusCode) {
@ -143,15 +140,13 @@ class OffersAndPackagesServices extends BaseService {
return bannersList; return bannersList;
} }
Future loadOffersPackagesDataForMainPage({@required BuildContext context, bool showLoading = true, Function completion }) async { Future loadOffersPackagesDataForMainPage({@required BuildContext context, bool showLoading = true, Function completion}) async {
var finished = 0; var finished = 0;
var totalCalls = 3; var totalCalls = 2;
completedAll(){
completedAll() {
finished++; finished++;
if(completion != null && finished == totalCalls) { if (completion != null && finished == totalCalls) {
_hideLoading(context, showLoading); _hideLoading(context, showLoading);
completion(); completion();
} }
@ -160,57 +155,56 @@ class OffersAndPackagesServices extends BaseService {
_showLoading(context, showLoading); _showLoading(context, showLoading);
final auth_token = await baseAppClient.generatePackagesToken(); final auth_token = await baseAppClient.generatePackagesToken();
if(auth_token == null){ if (auth_token == null) {
throw 'Something went wrong while authentication, Please try again letter'; throw 'Something went wrong while authentication, Please try again letter';
} }
packagesAuthHeader["Authorization"] = 'Bearer $auth_token'; packagesAuthHeader["Authorization"] = 'Bearer $auth_token';
// Check and Create Customer // Check and Create Customer
if(patientUser != null){ if (patientUser != null) {
customer = await getCurrentCustomer(context: context, showLoading: showLoading); customer = await getCurrentCustomer(context: context, showLoading: showLoading);
if(customer == null){ if (customer == null) {
createCustomer(PackagesCustomerRequestModel.fromUser(patientUser), context: context); createCustomer(PackagesCustomerRequestModel.fromUser(patientUser), context: context);
} }
} }
// Performing Parallel Request on same time // Performing Parallel Request on same time
// # 1 // # 1
getBestSellers(request: OffersProductsRequestModel(), context: context, showLoading: false).then((value){ getBestSellers(request: OffersProductsRequestModel(), context: context, showLoading: false).then((value) {
completedAll(); completedAll();
}); });
// # 2 // # 2
getLatestOffers(request: OffersProductsRequestModel(), context: context, showLoading: false).then((value){ getLatestOffers(request: OffersProductsRequestModel(), context: context, showLoading: false).then((value) {
completedAll(); completedAll();
}); });
// # 3 // # 3
getBanners(request: OffersProductsRequestModel(), context: context, showLoading: false).then((value){ // getBanners(
completedAll(); // request: OffersProductsRequestModel(),
}); // context: context,
// showLoading: false)
// .then((value) {
// completedAll();
// });
} }
// -------------------- // --------------------
// Create Customer // Create Customer
// -------------------- // --------------------
Future createCustomer(PackagesCustomerRequestModel request, {@required BuildContext context, bool showLoading = true, Function(bool) completion }) async{ Future createCustomer(PackagesCustomerRequestModel request, {@required BuildContext context, bool showLoading = true, Function(bool) completion}) async {
if(customer != null) if (customer != null) return Future.value(customer);
return Future.value(customer);
customer = null; customer = null;
Future errorThrow; Future errorThrow;
_showLoading(context, showLoading); _showLoading(context, showLoading);
var url = EXA_CART_API_BASE_URL + PACKAGES_CUSTOMER; var url = EXA_CART_API_BASE_URL + PACKAGES_CUSTOMER;
await baseAppClient.simplePost(url, headers: packagesAuthHeader, body: request.json(), onSuccess: (dynamic stringResponse, int statusCode){ await baseAppClient.simplePost(url, headers: packagesAuthHeader, body: request.json(), onSuccess: (dynamic stringResponse, int statusCode) {
var jsonResponse = json.decode(stringResponse); var jsonResponse = json.decode(stringResponse);
var customerJson = jsonResponse['customers'].first; var customerJson = jsonResponse['customers'].first;
customer = PackagesCustomerResponseModel.fromJson(customerJson); customer = PackagesCustomerResponseModel.fromJson(customerJson);
}, onFailure: (String error, int statusCode) {
}, onFailure: (String error, int statusCode){
errorThrow = Future.error(error); errorThrow = Future.error(error);
log(error); log(error);
}); });
@ -221,37 +215,33 @@ class OffersAndPackagesServices extends BaseService {
return errorThrow ?? customer; return errorThrow ?? customer;
} }
Future<PackagesCustomerResponseModel> getCurrentCustomer({@required BuildContext context, bool showLoading = true}) async{ Future<PackagesCustomerResponseModel> getCurrentCustomer({@required BuildContext context, bool showLoading = true}) async {
if(customer != null) if (customer != null) return Future.value(customer);
return Future.value(customer);
_showLoading(context, showLoading); _showLoading(context, showLoading);
var url = EXA_CART_API_BASE_URL + PACKAGES_CUSTOMER + "/username/${patientUser.patientID}"; var url = EXA_CART_API_BASE_URL + PACKAGES_CUSTOMER + "/username/${patientUser.patientID}";
await baseAppClient.simpleGet(url, headers: packagesAuthHeader, onSuccess: (dynamic stringResponse, int statusCode){ await baseAppClient.simpleGet(url, headers: packagesAuthHeader, onSuccess: (dynamic stringResponse, int statusCode) {
var jsonResponse = json.decode(stringResponse); var jsonResponse = json.decode(stringResponse);
var customerJson = jsonResponse['customers'].first; var customerJson = jsonResponse['customers'].first;
customer = PackagesCustomerResponseModel.fromJson(customerJson); customer = PackagesCustomerResponseModel.fromJson(customerJson);
}, onFailure: (String error, int statusCode) {
}, onFailure: (String error, int statusCode){
log(error); log(error);
}); });
_hideLoading(context, showLoading); _hideLoading(context, showLoading);
return customer; return customer;
} }
// -------------------- // --------------------
// Shopping Cart // Shopping Cart
// -------------------- // --------------------
Future<Map<String,dynamic>> cartItems({@required BuildContext context, bool showLoading = true}) async{ Future<Map<String, dynamic>> cartItems({@required BuildContext context, bool showLoading = true}) async {
Future errorThrow; Future errorThrow;
cartItemList.clear(); cartItemList.clear();
_showLoading(context, showLoading); _showLoading(context, showLoading);
var url = EXA_CART_API_BASE_URL + PACKAGES_SHOPPING_CART + '/${customer.id}'; var url = EXA_CART_API_BASE_URL + PACKAGES_SHOPPING_CART + '/${customer.id}';
Map<String,dynamic> jsonResponse; Map<String, dynamic> jsonResponse;
await baseAppClient.simpleGet(url, headers: packagesAuthHeader, onSuccess: (dynamic stringResponse, int statusCode) { await baseAppClient.simpleGet(url, headers: packagesAuthHeader, onSuccess: (dynamic stringResponse, int statusCode) {
_hideLoading(context, showLoading); _hideLoading(context, showLoading);
@ -259,17 +249,16 @@ class OffersAndPackagesServices extends BaseService {
jsonResponse['shopping_carts'].forEach((json) { jsonResponse['shopping_carts'].forEach((json) {
cartItemList.add(PackagesCartItemsResponseModel.fromJson(json)); cartItemList.add(PackagesCartItemsResponseModel.fromJson(json));
}); });
}, onFailure: (String error, int statusCode) { }, onFailure: (String error, int statusCode) {
_hideLoading(context, showLoading); _hideLoading(context, showLoading);
log(error); log(error);
errorThrow = Future.error({"error":error, "statusCode":statusCode}); errorThrow = Future.error({"error": error, "statusCode": statusCode});
}, queryParams: null); }, queryParams: null);
return errorThrow ?? jsonResponse; return errorThrow ?? jsonResponse;
} }
Future<ResponseModel<PackagesCartItemsResponseModel>> addProductToCart(AddProductToCartRequestModel request, {@required BuildContext context, bool showLoading = true}) async{ Future<ResponseModel<PackagesCartItemsResponseModel>> addProductToCart(AddProductToCartRequestModel request, {@required BuildContext context, bool showLoading = true}) async {
Future errorThrow; Future errorThrow;
ResponseModel<PackagesCartItemsResponseModel> response; ResponseModel<PackagesCartItemsResponseModel> response;
@ -277,15 +266,14 @@ class OffersAndPackagesServices extends BaseService {
_showLoading(context, showLoading); _showLoading(context, showLoading);
var url = EXA_CART_API_BASE_URL + PACKAGES_SHOPPING_CART; var url = EXA_CART_API_BASE_URL + PACKAGES_SHOPPING_CART;
await baseAppClient.simplePost(url, headers: packagesAuthHeader, body: request.json(), onSuccess: (dynamic stringResponse, int statusCode){ await baseAppClient.simplePost(url, headers: packagesAuthHeader, body: request.json(), onSuccess: (dynamic stringResponse, int statusCode) {
_hideLoading(context, showLoading); _hideLoading(context, showLoading);
var jsonResponse = json.decode(stringResponse); var jsonResponse = json.decode(stringResponse);
var jsonCartItem = jsonResponse["shopping_carts"][0]; var jsonCartItem = jsonResponse["shopping_carts"][0];
response = ResponseModel(status: true, data: PackagesCartItemsResponseModel.fromJson(jsonCartItem), error: null); response = ResponseModel(status: true, data: PackagesCartItemsResponseModel.fromJson(jsonCartItem), error: null);
cartItemCount = (jsonResponse['count'] ?? 0).toString(); cartItemCount = (jsonResponse['count'] ?? 0).toString();
}, onFailure: (String error, int statusCode) {
}, onFailure: (String error, int statusCode){
_hideLoading(context, showLoading); _hideLoading(context, showLoading);
errorThrow = Future.error(ResponseModel(status: true, data: null, error: error)); errorThrow = Future.error(ResponseModel(status: true, data: null, error: error));
}); });
@ -293,39 +281,35 @@ class OffersAndPackagesServices extends BaseService {
return errorThrow ?? response; return errorThrow ?? response;
} }
Future updateProductToCart(int cartItemID, {UpdateProductToCartRequestModel request, @required BuildContext context, bool showLoading = true}) async{ Future updateProductToCart(int cartItemID, {UpdateProductToCartRequestModel request, @required BuildContext context, bool showLoading = true}) async {
Future errorThrow; Future errorThrow;
_showLoading(context, showLoading); _showLoading(context, showLoading);
var url = EXA_CART_API_BASE_URL + PACKAGES_SHOPPING_CART + '/$cartItemID'; var url = EXA_CART_API_BASE_URL + PACKAGES_SHOPPING_CART + '/$cartItemID';
await baseAppClient.simplePut(url, headers: packagesAuthHeader, body: request.json(), onSuccess: (dynamic stringResponse, int statusCode){ await baseAppClient.simplePut(url, headers: packagesAuthHeader, body: request.json(), onSuccess: (dynamic stringResponse, int statusCode) {
_hideLoading(context, showLoading); _hideLoading(context, showLoading);
var jsonResponse = json.decode(stringResponse); var jsonResponse = json.decode(stringResponse);
}, onFailure: (String error, int statusCode) {
}, onFailure: (String error, int statusCode){
_hideLoading(context, showLoading); _hideLoading(context, showLoading);
log(error); log(error);
errorThrow = Future.error({"error":error, "statusCode":statusCode}); errorThrow = Future.error({"error": error, "statusCode": statusCode});
}); });
return errorThrow ?? bannersList; return errorThrow ?? bannersList;
} }
Future<bool> deleteProductFromCart(int cartItemID, {@required BuildContext context, bool showLoading = true}) async {
Future<bool> deleteProductFromCart(int cartItemID, {@required BuildContext context, bool showLoading = true}) async{
Future errorThrow; Future errorThrow;
_showLoading(context, showLoading); _showLoading(context, showLoading);
var url = EXA_CART_API_BASE_URL + PACKAGES_SHOPPING_CART + '/$cartItemID'; var url = EXA_CART_API_BASE_URL + PACKAGES_SHOPPING_CART + '/$cartItemID';
await baseAppClient.simpleDelete(url, headers: packagesAuthHeader, onSuccess: (dynamic stringResponse, int statusCode){ await baseAppClient.simpleDelete(url, headers: packagesAuthHeader, onSuccess: (dynamic stringResponse, int statusCode) {
_hideLoading(context, showLoading); _hideLoading(context, showLoading);
// var jsonResponse = json.decode(stringResponse); }, onFailure: (String error, int statusCode) {
}, onFailure: (String error, int statusCode){
_hideLoading(context, showLoading); _hideLoading(context, showLoading);
log(error); log(error);
errorThrow = Future.error({"error":error, "statusCode":statusCode}); errorThrow = Future.error({"error": error, "statusCode": statusCode});
}); });
return errorThrow ?? true; return errorThrow ?? true;
@ -334,29 +318,28 @@ class OffersAndPackagesServices extends BaseService {
// -------------------- // --------------------
// Place Order // Place Order
// -------------------- // --------------------
Future placeOrder({@required Map<dynamic,dynamic> paymentParams, @required BuildContext context, bool showLoading = true}) async{ Future placeOrder({@required Map<dynamic, dynamic> paymentParams, @required int projectID, @required BuildContext context, bool showLoading = true}) async {
Future errorThrow; Future errorThrow;
Map<dynamic,dynamic> jsonBody = { Map<dynamic, dynamic> jsonBody = {
"customer_id" : customer.id, "customer_id": customer.id,
"billing_address": { "project_id": projectID,
"email": patientUser.emailAddress, "billing_address": {"email": patientUser.emailAddress, "phone_number": patientUser.mobileNumber},
"phone_number": patientUser.mobileNumber
},
}; };
jsonBody.addAll(paymentParams); jsonBody.addAll(paymentParams);
jsonBody = {'order' : jsonBody}; jsonBody = {'order': jsonBody};
print(jsonBody);
int order_id; int order_id;
_showLoading(context, showLoading); _showLoading(context, showLoading);
var url = EXA_CART_API_BASE_URL + PACKAGES_ORDERS; var url = EXA_CART_API_BASE_URL + PACKAGES_ORDERS;
await baseAppClient.simplePost(url, headers: packagesAuthHeader, body: jsonBody, onSuccess: (dynamic stringResponse, int statusCode){ await baseAppClient.simplePost(url, headers: packagesAuthHeader, body: jsonBody, onSuccess: (dynamic stringResponse, int statusCode) {
_hideLoading(context, showLoading); _hideLoading(context, showLoading);
var jsonResponse = json.decode(stringResponse); var jsonResponse = json.decode(stringResponse);
order_id = jsonResponse['orders'][0]['id']; order_id = jsonResponse['orders'][0]['id'];
}, onFailure: (String error, int statusCode) {
}, onFailure: (String error, int statusCode){
_hideLoading(context, showLoading); _hideLoading(context, showLoading);
log(error); log(error);
errorThrow = Future.error(error); errorThrow = Future.error(error);
@ -365,7 +348,7 @@ class OffersAndPackagesServices extends BaseService {
return errorThrow ?? order_id; return errorThrow ?? order_id;
} }
Future<ResponseModel<PackagesOrderResponseModel>> getOrderById(int id, {@required BuildContext context, bool showLoading = true}) async{ Future<ResponseModel<PackagesOrderResponseModel>> getOrderById(int id, {@required BuildContext context, bool showLoading = true}) async {
Future errorThrow; Future errorThrow;
ResponseModel<PackagesOrderResponseModel> response; ResponseModel<PackagesOrderResponseModel> response;
@ -377,23 +360,39 @@ class OffersAndPackagesServices extends BaseService {
var jsonResponse = json.decode(stringResponse); var jsonResponse = json.decode(stringResponse);
var jsonOrder = jsonResponse['orders'][0]; var jsonOrder = jsonResponse['orders'][0];
response = ResponseModel(status: true, data: PackagesOrderResponseModel.fromJson(jsonOrder)); response = ResponseModel(status: true, data: PackagesOrderResponseModel.fromJson(jsonOrder));
}, onFailure: (String error, int statusCode) { }, onFailure: (String error, int statusCode) {
_hideLoading(context, showLoading); _hideLoading(context, showLoading);
errorThrow = Future.error(ResponseModel(status: false,error: error)); errorThrow = Future.error(ResponseModel(status: false, error: error));
}, queryParams: null); }, queryParams: null);
return errorThrow ?? response; return errorThrow ?? response;
} }
Future getHospitals({bool isResBasedOnLoc = true}) async {
Map<String, dynamic> body = Map();
body['Latitude'] = await this.sharedPref.getDouble(USER_LAT);
body['Longitude'] = await this.sharedPref.getDouble(USER_LONG);
body['IsOnlineCheckIn'] = isResBasedOnLoc;
body['PatientOutSA'] = 0;
await baseAppClient.post(GET_PROJECT,
onSuccess: (dynamic response, int statusCode) {
_hospitals.clear();
response['ListProject'].forEach((hospital) {
_hospitals.add(HospitalsModel.fromJson(hospital));
});
}, onFailure: (String error, int statusCode) {
hasError = true;
super.error = error;
}, body: body);
}
} }
_showLoading(BuildContext context, bool flag){ _showLoading(BuildContext context, bool flag) {
if(flag) if (flag) GifLoaderDialogUtils.showMyDialog(context);
GifLoaderDialogUtils.showMyDialog(context);
} }
_hideLoading(BuildContext context, bool flag){ _hideLoading(BuildContext context, bool flag) {
if(flag) if (flag) GifLoaderDialogUtils.hideDialog(context);
GifLoaderDialogUtils.hideDialog(context); }
}

@ -1,3 +1,4 @@
import 'package:diplomaticquarterapp/core/model/hospitals/hospitals_model.dart';
import 'package:diplomaticquarterapp/core/model/packages_offers/responses/PackagesCartItemsResponseModel.dart'; import 'package:diplomaticquarterapp/core/model/packages_offers/responses/PackagesCartItemsResponseModel.dart';
import 'package:diplomaticquarterapp/core/model/packages_offers/responses/PackagesCategoriesResponseModel.dart'; import 'package:diplomaticquarterapp/core/model/packages_offers/responses/PackagesCategoriesResponseModel.dart';
import 'package:diplomaticquarterapp/core/model/packages_offers/responses/PackagesResponseModel.dart'; import 'package:diplomaticquarterapp/core/model/packages_offers/responses/PackagesResponseModel.dart';
@ -22,6 +23,7 @@ class PackagesViewModel extends BaseViewModel {
List<PackagesResponseModel> get bestSellerList => service.bestSellerList; List<PackagesResponseModel> get bestSellerList => service.bestSellerList;
List<PackagesResponseModel> get bannersList => service.bannersList; List<PackagesResponseModel> get bannersList => service.bannersList;
List<PackagesCartItemsResponseModel> get cartItemList => service.cartItemList; List<PackagesCartItemsResponseModel> get cartItemList => service.cartItemList;
List<HospitalsModel> get hospitals => service.hospitals;
String _cartItemCount = ""; String _cartItemCount = "";

@ -11,6 +11,7 @@ import 'package:diplomaticquarterapp/services/pharmacy_services/cancelOrder_serv
import 'package:diplomaticquarterapp/services/pharmacy_services/orderDetails_service.dart'; import 'package:diplomaticquarterapp/services/pharmacy_services/orderDetails_service.dart';
import 'package:diplomaticquarterapp/services/pharmacy_services/order_service.dart'; import 'package:diplomaticquarterapp/services/pharmacy_services/order_service.dart';
import 'package:diplomaticquarterapp/uitl/app_toast.dart'; import 'package:diplomaticquarterapp/uitl/app_toast.dart';
import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart';
import '../../../locator.dart'; import '../../../locator.dart';
import '../base_view_model.dart'; import '../base_view_model.dart';
@ -77,7 +78,8 @@ class OrderModelViewModel extends BaseViewModel {
dynamic res; dynamic res;
await _cancelOrderService.getCanceledOrder(order).then((value) { await _cancelOrderService.getCanceledOrder(order).then((value) {
res = value['success']['SuccessEndUserMsg']; res = value['success']['SuccessEndUserMsg'];
AppToast.showSuccessToast(message: "Request Sent Successfully"); // AppToast.showSuccessToast(message: "Request Sent Successfully");
AppToast.showSuccessToast(message: TranslationBase.of(context).requestSent);
// Navigator.pop(context); // Navigator.pop(context);
}); });
if (_cancelOrderService.hasError) { if (_cancelOrderService.hasError) {
@ -95,7 +97,7 @@ class OrderModelViewModel extends BaseViewModel {
return res; return res;
} }
Future makeReview(PharmacyProduct product, double rating, String reviewText) async { Future makeReview(PharmacyProduct product, double rating, String reviewText, context) async {
setState(ViewState.Busy); setState(ViewState.Busy);
await _orderDetailsService.makeReview(product, rating, reviewText); await _orderDetailsService.makeReview(product, rating, reviewText);
if (_orderDetailsService.hasError) { if (_orderDetailsService.hasError) {
@ -104,8 +106,9 @@ class OrderModelViewModel extends BaseViewModel {
AppToast.showErrorToast(message: error); AppToast.showErrorToast(message: error);
} else { } else {
setState(ViewState.Idle); setState(ViewState.Idle);
AppToast.showSuccessToast( AppToast.showSuccessToast(message: TranslationBase.of(context).submitReview);
message: "Your review has been Submitted successfully"); // AppToast.showSuccessToast(
// message: "Your review has been Submitted successfully");
} }
} }

@ -1,21 +1,20 @@
import 'package:diplomaticquarterapp/core/enum/viewstate.dart'; import 'package:diplomaticquarterapp/core/enum/viewstate.dart';
import 'package:diplomaticquarterapp/core/model/pharmacies/ShoppingCart.dart';
import 'package:diplomaticquarterapp/core/model/pharmacies/ShoppingCartResponse.dart';
import 'package:diplomaticquarterapp/core/viewModels/base_view_model.dart'; import 'package:diplomaticquarterapp/core/viewModels/base_view_model.dart';
import 'package:diplomaticquarterapp/core/viewModels/pharmacyModule/OrderPreviewViewModel.dart'; import 'package:diplomaticquarterapp/core/viewModels/pharmacyModule/OrderPreviewViewModel.dart';
import 'package:diplomaticquarterapp/models/pharmacy/Wishlist.dart'; import 'package:diplomaticquarterapp/models/pharmacy/Wishlist.dart';
import 'package:diplomaticquarterapp/models/pharmacy/locationModel.dart'; 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/models/pharmacy/specification.dart'; import 'package:diplomaticquarterapp/models/pharmacy/specification.dart';
import 'package:diplomaticquarterapp/services/pharmacy_services/product_detail_service.dart';
import 'package:diplomaticquarterapp/uitl/gif_loader_dialog_utils.dart'; import 'package:diplomaticquarterapp/uitl/gif_loader_dialog_utils.dart';
import 'package:diplomaticquarterapp/uitl/navigation_service.dart'; import 'package:diplomaticquarterapp/uitl/navigation_service.dart';
import 'package:diplomaticquarterapp/core/model/pharmacies/ShoppingCart.dart';
import 'package:diplomaticquarterapp/core/model/pharmacies/ShoppingCartResponse.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
import '../../../locator.dart'; import '../../../locator.dart';
class ProductDetailViewModel extends BaseViewModel{ class ProductDetailViewModel extends BaseViewModel {
ProductDetailService _productDetailService = locator<ProductDetailService>(); ProductDetailService _productDetailService = locator<ProductDetailService>();
List<ProductDetail> get productDetailService => _productDetailService.productDetailList; List<ProductDetail> get productDetailService => _productDetailService.productDetailList;
@ -28,6 +27,11 @@ class ProductDetailViewModel extends BaseViewModel{
bool hasError = false; bool hasError = false;
num get stockQuantity => _productDetailService.stockQuantity;
String get stockAvailability => _productDetailService.stockAvailability;
bool get isStockAvailable => _productDetailService.isStockAvailable;
Future getProductReviewsData(productID) async { Future getProductReviewsData(productID) async {
hasError = false; hasError = false;
@ -72,8 +76,7 @@ class ProductDetailViewModel extends BaseViewModel{
setState(ViewState.ErrorLocal); setState(ViewState.ErrorLocal);
} else { } else {
setState(ViewState.Idle); setState(ViewState.Idle);
Provider.of<OrderPreviewViewModel>(locator<NavigationService>().navigatorKey.currentContext, listen: false) Provider.of<OrderPreviewViewModel>(locator<NavigationService>().navigatorKey.currentContext, listen: false).setShoppingCartResponse(object);
.setShoppingCartResponse( object);
} }
} }
@ -103,11 +106,9 @@ class ProductDetailViewModel extends BaseViewModel{
Future addToWishlistData(itemID) async { Future addToWishlistData(itemID) async {
hasError = false; hasError = false;
setState(ViewState.BusyLocal); setState(ViewState.BusyLocal);
GifLoaderDialogUtils.showMyDialog( GifLoaderDialogUtils.showMyDialog(locator<NavigationService>().navigatorKey.currentContext);
locator<NavigationService>().navigatorKey.currentContext);
await _productDetailService.addToWishlist(itemID); await _productDetailService.addToWishlist(itemID);
GifLoaderDialogUtils.hideDialog( GifLoaderDialogUtils.hideDialog(locator<NavigationService>().navigatorKey.currentContext);
locator<NavigationService>().navigatorKey.currentContext);
if (_productDetailService.hasError) { if (_productDetailService.hasError) {
error = _productDetailService.error; error = _productDetailService.error;
@ -127,15 +128,12 @@ class ProductDetailViewModel extends BaseViewModel{
setState(ViewState.Idle); setState(ViewState.Idle);
} }
Future deleteWishlistData(itemID) async { Future deleteWishlistData(itemID) async {
hasError = false; hasError = false;
setState(ViewState.BusyLocal); setState(ViewState.BusyLocal);
GifLoaderDialogUtils.showMyDialog( GifLoaderDialogUtils.showMyDialog(locator<NavigationService>().navigatorKey.currentContext);
locator<NavigationService>().navigatorKey.currentContext);
await _productDetailService.deleteItemFromWishlist(itemID); await _productDetailService.deleteItemFromWishlist(itemID);
GifLoaderDialogUtils.hideDialog( GifLoaderDialogUtils.hideDialog(locator<NavigationService>().navigatorKey.currentContext);
locator<NavigationService>().navigatorKey.currentContext);
if (_productDetailService.hasError) { if (_productDetailService.hasError) {
error = _productDetailService.error; error = _productDetailService.error;
@ -144,7 +142,6 @@ class ProductDetailViewModel extends BaseViewModel{
setState(ViewState.Idle); setState(ViewState.Idle);
} }
Future productSpecificationData(itemID) async { Future productSpecificationData(itemID) async {
hasError = false; hasError = false;
setState(ViewState.Busy); setState(ViewState.Busy);
@ -156,10 +153,7 @@ class ProductDetailViewModel extends BaseViewModel{
setState(ViewState.Idle); setState(ViewState.Idle);
} }
clearReview(){ clearReview() {
productDetailService.clear(); productDetailService.clear();
} }
}
}

@ -313,6 +313,12 @@ offerProductsResponseModelFromJson(PackagesResponseModel data, Map<String, dynam
data.storeIds = new List<dynamic>(); data.storeIds = new List<dynamic>();
data.storeIds.addAll(json['store_ids']); data.storeIds.addAll(json['store_ids']);
} }
if (json['store_names'] != null) {
data.storeNames = new List<dynamic>();
data.storeNames.addAll(json['store_names']);
}
if (json['manufacturer_ids'] != null) { if (json['manufacturer_ids'] != null) {
data.manufacturerIds = json['manufacturer_ids']?.map((v) => v?.toInt())?.toList()?.cast<int>(); data.manufacturerIds = json['manufacturer_ids']?.map((v) => v?.toInt())?.toList()?.cast<int>();
} }

@ -1,7 +1,3 @@
// To parse this JSON data, do
//
// final productDetail = productDetailFromJson(jsonString);
import 'dart:convert'; import 'dart:convert';
List<ProductDetail> productDetailFromJson(String str) => List<ProductDetail>.from(json.decode(str).map((x) => ProductDetail.fromJson(x))); List<ProductDetail> productDetailFromJson(String str) => List<ProductDetail>.from(json.decode(str).map((x) => ProductDetail.fromJson(x)));
@ -16,12 +12,12 @@ class ProductDetail {
List<Review> reviews; List<Review> reviews;
factory ProductDetail.fromJson(Map<String, dynamic> json) => ProductDetail( factory ProductDetail.fromJson(Map<String, dynamic> json) => ProductDetail(
reviews: List<Review>.from(json["reviews"].map((x) => Review.fromJson(x))), reviews: List<Review>.from(json["reviews"].map((x) => Review.fromJson(x))),
); );
Map<String, dynamic> toJson() => { Map<String, dynamic> toJson() => {
"reviews": List<dynamic>.from(reviews.map((x) => x.toJson())), "reviews": List<dynamic>.from(reviews.map((x) => x.toJson())),
}; };
} }
class Review { class Review {
@ -62,42 +58,42 @@ class Review {
dynamic product; dynamic product;
factory Review.fromJson(Map<String, dynamic> json) => Review( factory Review.fromJson(Map<String, dynamic> json) => Review(
id: json["id"], id: json["id"],
position: json["position"], position: json["position"],
reviewId: json["review_id"], reviewId: json["review_id"],
customerId: json["customer_id"], customerId: json["customer_id"],
productId: json["product_id"], productId: json["product_id"],
storeId: json["store_id"], storeId: json["store_id"],
isApproved: json["is_approved"], isApproved: json["is_approved"],
title: json["title"], title: json["title"],
reviewText: json["review_text"], reviewText: json["review_text"],
replyText: json["reply_text"], replyText: json["reply_text"],
rating: json["rating"], rating: json["rating"],
helpfulYesTotal: json["helpful_yes_total"], helpfulYesTotal: json["helpful_yes_total"],
helpfulNoTotal: json["helpful_no_total"], helpfulNoTotal: json["helpful_no_total"],
createdOnUtc: DateTime.parse(json["created_on_utc"]), createdOnUtc: DateTime.parse(json["created_on_utc"]),
customer: Customer.fromJson(json["customer"]), customer: Customer.fromJson(json["customer"]),
product: json["product"], product: json["product"],
); );
Map<String, dynamic> toJson() => { Map<String, dynamic> toJson() => {
"id": id, "id": id,
"position": position, "position": position,
"review_id": reviewId, "review_id": reviewId,
"customer_id": customerId, "customer_id": customerId,
"product_id": productId, "product_id": productId,
"store_id": storeId, "store_id": storeId,
"is_approved": isApproved, "is_approved": isApproved,
"title": title, "title": title,
"review_text": reviewText, "review_text": reviewText,
"reply_text": replyText, "reply_text": replyText,
"rating": rating, "rating": rating,
"helpful_yes_total": helpfulYesTotal, "helpful_yes_total": helpfulYesTotal,
"helpful_no_total": helpfulNoTotal, "helpful_no_total": helpfulNoTotal,
"created_on_utc": createdOnUtc.toIso8601String(), "created_on_utc": createdOnUtc.toIso8601String(),
"customer": customer.toJson(), "customer": customer.toJson(),
"product": product, "product": product,
}; };
} }
class Customer { class Customer {
@ -164,75 +160,73 @@ class Customer {
dynamic registeredInStoreId; dynamic registeredInStoreId;
factory Customer.fromJson(Map<String, dynamic> json) => Customer( factory Customer.fromJson(Map<String, dynamic> json) => Customer(
fileNumber: json["file_number"], fileNumber: json["file_number"],
iqamaNumber: json["iqama_number"], iqamaNumber: json["iqama_number"],
isOutSa: json["is_out_sa"], isOutSa: json["is_out_sa"],
patientType: json["patient_type"], patientType: json["patient_type"],
gender: json["gender"], gender: json["gender"],
birthDate: DateTime.parse(json["birth_date"]), birthDate: DateTime.parse(json["birth_date"]),
phone: json["phone"], phone: json["phone"],
countryCode: json["country_code"], countryCode: json["country_code"],
yahalaAccountno: json["yahala_accountno"], yahalaAccountno: json["yahala_accountno"],
billingAddress: json["billing_address"], billingAddress: json["billing_address"],
shippingAddress: json["shipping_address"], shippingAddress: json["shipping_address"],
id: json["id"], id: json["id"],
username: emailValues.map[json["username"]], username: emailValues.map[json["username"]],
email: emailValues.map[json["email"]], email: emailValues.map[json["email"]],
firstName: json["first_name"], firstName: json["first_name"],
lastName: json["last_name"], lastName: json["last_name"],
languageId: json["language_id"], languageId: json["language_id"],
adminComment: json["admin_comment"], adminComment: json["admin_comment"],
isTaxExempt: json["is_tax_exempt"], isTaxExempt: json["is_tax_exempt"],
hasShoppingCartItems: json["has_shopping_cart_items"], hasShoppingCartItems: json["has_shopping_cart_items"],
active: json["active"], active: json["active"],
deleted: json["deleted"], deleted: json["deleted"],
isSystemAccount: json["is_system_account"], isSystemAccount: json["is_system_account"],
systemName: json["system_name"], systemName: json["system_name"],
lastIpAddress: json["last_ip_address"], lastIpAddress: json["last_ip_address"],
createdOnUtc: json["created_on_utc"], createdOnUtc: json["created_on_utc"],
lastLoginDateUtc: json["last_login_date_utc"], lastLoginDateUtc: json["last_login_date_utc"],
lastActivityDateUtc: json["last_activity_date_utc"], lastActivityDateUtc: json["last_activity_date_utc"],
registeredInStoreId: json["registered_in_store_id"], registeredInStoreId: json["registered_in_store_id"],
); );
Map<String, dynamic> toJson() => { Map<String, dynamic> toJson() => {
"file_number": fileNumber, "file_number": fileNumber,
"iqama_number": iqamaNumber, "iqama_number": iqamaNumber,
"is_out_sa": isOutSa, "is_out_sa": isOutSa,
"patient_type": patientType, "patient_type": patientType,
"gender": gender, "gender": gender,
"birth_date": birthDate.toIso8601String(), "birth_date": birthDate.toIso8601String(),
"phone": phone, "phone": phone,
"country_code": countryCode, "country_code": countryCode,
"yahala_accountno": yahalaAccountno, "yahala_accountno": yahalaAccountno,
"billing_address": billingAddress, "billing_address": billingAddress,
"shipping_address": shippingAddress, "shipping_address": shippingAddress,
"id": id, "id": id,
"username": emailValues.reverse[username], "username": emailValues.reverse[username],
"email": emailValues.reverse[email], "email": emailValues.reverse[email],
"first_name": firstName, "first_name": firstName,
"last_name": lastName, "last_name": lastName,
"language_id": languageId, "language_id": languageId,
"admin_comment": adminComment, "admin_comment": adminComment,
"is_tax_exempt": isTaxExempt, "is_tax_exempt": isTaxExempt,
"has_shopping_cart_items": hasShoppingCartItems, "has_shopping_cart_items": hasShoppingCartItems,
"active": active, "active": active,
"deleted": deleted, "deleted": deleted,
"is_system_account": isSystemAccount, "is_system_account": isSystemAccount,
"system_name": systemName, "system_name": systemName,
"last_ip_address": lastIpAddress, "last_ip_address": lastIpAddress,
"created_on_utc": createdOnUtc, "created_on_utc": createdOnUtc,
"last_login_date_utc": lastLoginDateUtc, "last_login_date_utc": lastLoginDateUtc,
"last_activity_date_utc": lastActivityDateUtc, "last_activity_date_utc": lastActivityDateUtc,
"registered_in_store_id": registeredInStoreId, "registered_in_store_id": registeredInStoreId,
}; };
} }
enum Email { STEVE_GATES_NOP_COMMERCE_COM } enum Email { STEVE_GATES_NOP_COMMERCE_COM }
final emailValues = EnumValues({ final emailValues = EnumValues({"steve_gates@nopCommerce.com": Email.STEVE_GATES_NOP_COMMERCE_COM});
"steve_gates@nopCommerce.com": Email.STEVE_GATES_NOP_COMMERCE_COM
});
class EnumValues<T> { class EnumValues<T> {
Map<String, T> map; Map<String, T> map;

@ -4,13 +4,11 @@ import 'package:diplomaticquarterapp/theme/colors.dart';
import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart';
import 'package:diplomaticquarterapp/uitl/utils_new.dart'; import 'package:diplomaticquarterapp/uitl/utils_new.dart';
import 'package:diplomaticquarterapp/widgets/buttons/secondary_button.dart'; import 'package:diplomaticquarterapp/widgets/buttons/secondary_button.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/transitions/fade_page.dart'; import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
import '../health_calc_desc.dart';
import 'result_page.dart'; import 'result_page.dart';
const activeCardColor = Color(0xff70777A); const activeCardColor = Color(0xff70777A);
@ -47,9 +45,10 @@ class _BMICalculatorState extends State<BMICalculator> {
} }
double calculateBMI() { double calculateBMI() {
if (_isHeightCM) { if (!_isHeightCM) _heightValue = convertToCm(_heightValue.toDouble());
convertToCm(_heightValue.toDouble());
} if (!_isWeightKG) _weightValue = convertToKg(_weightValue);
bmiResult = _weightValue / pow(_heightValue / 100, 2); bmiResult = _weightValue / pow(_heightValue / 100, 2);
return bmiResult; return bmiResult;
@ -99,23 +98,9 @@ class _BMICalculatorState extends State<BMICalculator> {
return AppScaffold( return AppScaffold(
isShowAppBar: true, isShowAppBar: true,
isShowDecPage: false, isShowDecPage: false,
showHomeAppBarIcon: false, showHomeAppBarIcon: true,
showNewAppBar: true, showNewAppBar: true,
showNewAppBarTitle: true, showNewAppBarTitle: true,
appBarIcons: [
IconButton(
icon: Icon(Icons.info_outline),
color: Colors.black,
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => HealthDescPage("${TranslationBase.of(context).bmi} ${TranslationBase.of(context).calcHealth}", TranslationBase.of(context).bmiCalcDesc,
"assets/images/AlHabibMedicalService/health_calculator/bmi.png")),
);
},
)
],
appBarTitle: "${TranslationBase.of(context).bmi} ${TranslationBase.of(context).calcHealth}", appBarTitle: "${TranslationBase.of(context).bmi} ${TranslationBase.of(context).calcHealth}",
body: Column( body: Column(
children: [ children: [

@ -1,49 +1,58 @@
import 'dart:collection';
import 'package:auto_size_text/auto_size_text.dart'; import 'package:auto_size_text/auto_size_text.dart';
import 'package:diplomaticquarterapp/config/size_config.dart'; import 'package:diplomaticquarterapp/models/Appointments/DoctorListResponse.dart';
import 'package:diplomaticquarterapp/pages/AlHabibMedicalService/health_calculator/bmi_calculator/bariatrics-screen.dart'; import 'package:diplomaticquarterapp/pages/AlHabibMedicalService/health_calculator/bmi_calculator/bariatrics-screen.dart';
import 'package:diplomaticquarterapp/pages/BookAppointment/SearchResults.dart';
import 'package:diplomaticquarterapp/services/appointment_services/GetDoctorsList.dart';
import 'package:diplomaticquarterapp/theme/colors.dart'; import 'package:diplomaticquarterapp/theme/colors.dart';
import 'package:diplomaticquarterapp/uitl/app_toast.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/uitl/utils_new.dart'; import 'package:diplomaticquarterapp/uitl/utils_new.dart';
import 'package:diplomaticquarterapp/widgets/buttons/borderedButton.dart'; import 'package:diplomaticquarterapp/widgets/buttons/defaultButton.dart';
import 'package:diplomaticquarterapp/widgets/buttons/secondary_button.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/transitions/fade_page.dart'; import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_svg/svg.dart'; import 'package:flutter_svg/svg.dart';
import 'package:percent_indicator/percent_indicator.dart';
class ResultPage extends StatelessWidget { class ResultPage extends StatefulWidget {
final double finalResult; final double finalResult;
final String textResult; final String textResult;
final String msg; final String msg;
ResultPage({this.finalResult, this.textResult, this.msg}); ResultPage({this.finalResult, this.textResult, this.msg});
@override
_ResultPageState createState() => _ResultPageState();
}
class _ResultPageState extends State<ResultPage> {
Color inductorColor; Color inductorColor;
double percent; double percent;
Color colorInductor() { Color colorInductor() {
if (finalResult >= 30) { if (widget.finalResult >= 30) {
inductorColor = Color(0xffC70D00); inductorColor = Color(0xffC70D00);
} else if (finalResult < 30 && finalResult >= 25) { } else if (widget.finalResult < 30 && widget.finalResult >= 25) {
inductorColor = Color(0xffC25400); inductorColor = Color(0xffC25400);
} else if (finalResult < 25 && finalResult >= 18.5) { } else if (widget.finalResult < 25 && widget.finalResult >= 18.5) {
inductorColor = Color(0xff36D600); inductorColor = Color(0xff36D600);
} else if (finalResult < 18.5) { } else if (widget.finalResult < 18.5) {
inductorColor = Color(0xff1BE0EE); inductorColor = Color(0xff1BE0EE);
} }
return inductorColor; return inductorColor;
} }
double percentInductor() { double percentInductor() {
if (finalResult >= 30) { if (widget.finalResult >= 30) {
percent = 1.0; percent = 1.0;
} else if (finalResult < 30 && finalResult >= 25) { } else if (widget.finalResult < 30 && widget.finalResult >= 25) {
percent = 0.73; percent = 0.73;
} else if (finalResult < 25 && finalResult >= 18.5) { } else if (widget.finalResult < 25 && widget.finalResult >= 18.5) {
percent = 0.5; percent = 0.5;
} else if (finalResult < 18.5) { } else if (widget.finalResult < 18.5) {
percent = 0.25; percent = 0.25;
} }
return percent; return percent;
@ -69,7 +78,7 @@ class ResultPage extends StatelessWidget {
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
children: [ children: [
Text( Text(
TranslationBase.of(context).bodyMassIndex + finalResult.toString(), TranslationBase.of(context).bodyMassIndex + widget.finalResult.toStringAsFixed(2),
style: TextStyle( style: TextStyle(
fontSize: 16, fontSize: 16,
letterSpacing: -0.64, letterSpacing: -0.64,
@ -81,21 +90,21 @@ class ResultPage extends StatelessWidget {
height: MediaQuery.of(context).size.width / 2.8, height: MediaQuery.of(context).size.width / 2.8,
child: Row( child: Row(
children: [ children: [
showMass(context, TranslationBase.of(context).underWeight, "< 18.5", finalResult <= 18.5 ? Colors.red : Colors.black, 8), showMass(context, TranslationBase.of(context).underWeight, "< 18.5", widget.finalResult <= 18.5 ? Colors.red : Colors.black, 8),
mWidth(12), mWidth(12),
showMass(context, TranslationBase.of(context).healthy, "18.5 - 24.9", (finalResult > 18.5 && finalResult < 25) ? Colors.red : Colors.black, 6), showMass(context, TranslationBase.of(context).healthy, "18.5 - 24.9", (widget.finalResult > 18.5 && widget.finalResult < 25) ? Colors.red : Colors.black, 6),
mWidth(12), mWidth(12),
showMass(context, TranslationBase.of(context).overWeight, "25 - 29.9", (finalResult >= 25 && finalResult < 30) ? Colors.red : Colors.black, 4), showMass(context, TranslationBase.of(context).overWeight, "25 - 29.9", (widget.finalResult >= 25 && widget.finalResult < 30) ? Colors.red : Colors.black, 4),
mWidth(12), mWidth(12),
showMass(context, TranslationBase.of(context).obese, "30 - 34.9", (finalResult >= 30 && finalResult < 35) ? Colors.red : Colors.black, 2), showMass(context, TranslationBase.of(context).obese, "30 - 34.9", (widget.finalResult >= 30 && widget.finalResult < 35) ? Colors.red : Colors.black, 2),
mWidth(12), mWidth(12),
showMass(context, TranslationBase.of(context).extremeObese, "> 35", (finalResult >= 35) ? Colors.red : Colors.black, 0), showMass(context, TranslationBase.of(context).extremeObese, "> 35", (widget.finalResult >= 35) ? Colors.red : Colors.black, 0),
], ],
), ),
), ),
mHeight(20), mHeight(20),
Text( Text(
textResult, widget.textResult,
style: TextStyle( style: TextStyle(
fontSize: 16.0, fontSize: 16.0,
fontWeight: FontWeight.w600, fontWeight: FontWeight.w600,
@ -104,7 +113,7 @@ class ResultPage extends StatelessWidget {
), ),
mHeight(4), mHeight(4),
Text( Text(
msg, widget.msg,
style: TextStyle(fontSize: 14.0, fontWeight: FontWeight.w600, letterSpacing: -0.56, color: CustomColors.textColor), style: TextStyle(fontSize: 14.0, fontWeight: FontWeight.w600, letterSpacing: -0.56, color: CustomColors.textColor),
), ),
], ],
@ -115,14 +124,10 @@ class ResultPage extends StatelessWidget {
Container( Container(
color: Colors.white, color: Colors.white,
padding: EdgeInsets.all(16), padding: EdgeInsets.all(16),
child: SecondaryButton( child: DefaultButton(
label: TranslationBase.of(context).seeListOfDoctor, TranslationBase.of(context).seeListOfDoctor,
color: CustomColors.accentColor, () {
onTap: () { callDoctorsSearchAPI();
Navigator.push(
context,
FadePage(page: BariatricsPage(1, 1, finalResult)),
);
}, },
), ),
), ),
@ -131,6 +136,65 @@ class ResultPage extends StatelessWidget {
); );
} }
callDoctorsSearchAPI() {
GifLoaderDialogUtils.showMyDialog(context);
List<DoctorList> doctorsList = [];
List<String> arr = [];
List<String> arrDistance = [];
List<String> result;
int numAll;
List<PatientDoctorAppointmentList> _patientDoctorAppointmentListHospital = List();
DoctorsListService service = new DoctorsListService();
service.getDoctorsList(108, 0, false, context).then((res) {
GifLoaderDialogUtils.hideDialog(context);
if (res['MessageStatus'] == 1) {
setState(() {
if (res['DoctorList'].length != 0) {
doctorsList.clear();
res['DoctorList'].forEach((v) {
doctorsList.add(new DoctorList.fromJson(v));
});
doctorsList.forEach((element) {
List<PatientDoctorAppointmentList> doctorByHospital = _patientDoctorAppointmentListHospital
.where(
(elementClinic) => elementClinic.filterName == element.projectName,
)
.toList();
if (doctorByHospital.length != 0) {
_patientDoctorAppointmentListHospital[_patientDoctorAppointmentListHospital.indexOf(doctorByHospital[0])].patientDoctorAppointmentList.add(element);
} else {
_patientDoctorAppointmentListHospital
.add(PatientDoctorAppointmentList(filterName: element.projectName, distanceInKMs: element.projectDistanceInKiloMeters.toString(), patientDoctorAppointment: element));
}
});
} else {}
});
result = LinkedHashSet<String>.from(arr).toList();
numAll = result.length;
navigateToSearchResults(context, doctorsList, _patientDoctorAppointmentListHospital);
} else {
AppToast.showErrorToast(message: res['ErrorEndUserMessage']);
}
}).catchError((err) {
GifLoaderDialogUtils.hideDialog(context);
print(err);
AppToast.showErrorToast(message: err);
});
}
Future navigateToSearchResults(context, List<DoctorList> docList, List<PatientDoctorAppointmentList> patientDoctorAppointmentListHospital) async {
Navigator.push(context, FadePage(page: SearchResults(isLiveCareAppointment: false, doctorsList: docList, patientDoctorAppointmentListHospital: patientDoctorAppointmentListHospital)))
.then((value) {
setState(() {
// dropdownValue = null;
});
// getProjectsList();
});
}
Widget showMass(BuildContext context, String title, String weight, Color color, int f) { Widget showMass(BuildContext context, String title, String weight, Color color, int f) {
return Expanded( return Expanded(
flex: 1, flex: 1,

@ -1,13 +1,13 @@
import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart';
import 'package:diplomaticquarterapp/pages/AlHabibMedicalService/health_calculator/calorie_calculator/calorie_calculator.dart'; import 'package:diplomaticquarterapp/pages/AlHabibMedicalService/health_calculator/calorie_calculator/calorie_calculator.dart';
import 'package:diplomaticquarterapp/theme/colors.dart'; import 'package:diplomaticquarterapp/theme/colors.dart';
import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart';
import 'package:diplomaticquarterapp/widgets/buttons/button.dart';
import 'package:diplomaticquarterapp/widgets/buttons/secondary_button.dart'; import 'package:diplomaticquarterapp/widgets/buttons/secondary_button.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/transitions/fade_page.dart'; import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
import 'package:provider/provider.dart';
import 'carbs_result_page.dart'; import 'carbs_result_page.dart';
@ -38,27 +38,27 @@ class _CarbsState extends State<Carbs> {
double fCalMeal; double fCalMeal;
void calculateDietRatios() { void calculateDietRatios() {
if (dropdownValue == 'Very Low Carb') { if (dropdownValue == TranslationBase.of(context).dietVeryLow) {
meals = 3; meals = 3;
protein = 45; protein = 45;
carbs = 10; carbs = 10;
fat = 45; fat = 45;
} else if (dropdownValue == 'Low Carb') { } else if (dropdownValue == TranslationBase.of(context).dietLow) {
meals = 3; meals = 3;
protein = 40; protein = 40;
carbs = 30; carbs = 30;
fat = 30; fat = 30;
} else if (dropdownValue == 'Moderate Carb') { } else if (dropdownValue == TranslationBase.of(context).dietModerate) {
meals = 3; meals = 3;
protein = 25; protein = 25;
carbs = 50; carbs = 50;
fat = 25; fat = 25;
} else if (dropdownValue == 'USDA Gudilines') { } else if (dropdownValue == TranslationBase.of(context).dietUSDA) {
meals = 3; meals = 3;
protein = 15; protein = 15;
carbs = 55; carbs = 55;
fat = 30; fat = 30;
} else if (dropdownValue == 'Zone Diet') { } else if (dropdownValue == TranslationBase.of(context).dietZone) {
meals = 3; meals = 3;
protein = 30; protein = 30;
carbs = 40; carbs = 40;
@ -82,6 +82,7 @@ class _CarbsState extends State<Carbs> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
ProjectViewModel projectViewModel = Provider.of(context);
return AppScaffold( return AppScaffold(
isShowAppBar: true, isShowAppBar: true,
isShowDecPage: false, isShowDecPage: false,
@ -107,7 +108,7 @@ class _CarbsState extends State<Carbs> {
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
Text( Text(
'Calculates carbohydrate protein and fat ratio in calories and grams according to a pre-set ratio', TranslationBase.of(context).carbProteinDesc,
style: TextStyle( style: TextStyle(
fontSize: 14, fontSize: 14,
fontWeight: FontWeight.w600, fontWeight: FontWeight.w600,
@ -122,7 +123,7 @@ class _CarbsState extends State<Carbs> {
mainAxisAlignment: MainAxisAlignment.end, mainAxisAlignment: MainAxisAlignment.end,
crossAxisAlignment: CrossAxisAlignment.end, crossAxisAlignment: CrossAxisAlignment.end,
children: [ children: [
inputWidget("The Calories per day", "0", textController), inputWidget(TranslationBase.of(context).calDay, "0", textController),
InkWell( InkWell(
onTap: () { onTap: () {
Navigator.push( Navigator.push(
@ -133,7 +134,7 @@ class _CarbsState extends State<Carbs> {
child: Padding( child: Padding(
padding: const EdgeInsets.all(12.0), padding: const EdgeInsets.all(12.0),
child: Text( child: Text(
'NOT SURE? CLICK HERE', TranslationBase.of(context).notSure,
style: TextStyle(fontSize: 12, fontWeight: FontWeight.w600, letterSpacing: -0.56, color: CustomColors.accentColor, decoration: TextDecoration.underline), style: TextStyle(fontSize: 12, fontWeight: FontWeight.w600, letterSpacing: -0.56, color: CustomColors.accentColor, decoration: TextDecoration.underline),
), ),
), ),
@ -159,7 +160,7 @@ class _CarbsState extends State<Carbs> {
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
Text( Text(
"Select Diet Type", TranslationBase.of(context).selectDiet,
style: TextStyle( style: TextStyle(
fontSize: 11, fontSize: 11,
letterSpacing: -0.44, letterSpacing: -0.44,
@ -186,10 +187,16 @@ class _CarbsState extends State<Carbs> {
calculateDietRatios(); calculateDietRatios();
}); });
}, },
items: <String>['Very Low Carb', 'Low Carb', 'Moderate Carb', 'USDA Gudilines', 'Zone Diet'].map<DropdownMenuItem<String>>((String value) { items: <String>[
TranslationBase.of(context).dietVeryLow,
TranslationBase.of(context).dietLow,
TranslationBase.of(context).dietModerate,
TranslationBase.of(context).dietUSDA,
TranslationBase.of(context).dietZone
].map<DropdownMenuItem<String>>((String value) {
return DropdownMenuItem<String>( return DropdownMenuItem<String>(
value: value, value: value,
child: Text(value), child: Text(value, style: TextStyle(fontFamily: projectViewModel.isArabic ? 'Cairo' : 'Poppins', fontSize: 11, letterSpacing: -0.44, fontWeight: FontWeight.w600)),
); );
}).toList(), }).toList(),
), ),

@ -59,13 +59,6 @@ class _BillAmountState extends State<BillAmount> {
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
// Text(TranslationBase.of(context).testFee,
// style: TextStyle(
// color: Colors.black,
// fontSize: 16.0,
// fontWeight: FontWeight.w600,
// letterSpacing: -0.64,
// )),
Container( Container(
width: double.infinity, width: double.infinity,
padding: EdgeInsets.only(top: 10, bottom: 3), padding: EdgeInsets.only(top: 10, bottom: 3),

@ -15,6 +15,7 @@ import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart';
import 'package:diplomaticquarterapp/widgets/others/network_base_view.dart'; import 'package:diplomaticquarterapp/widgets/others/network_base_view.dart';
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 'package:rating_bar/rating_bar.dart';
import 'base/base_view.dart'; import 'base/base_view.dart';
@ -274,11 +275,21 @@ class _FinalProductsPageState extends State<FinalProductsPage> {
), ),
Row( Row(
children: [ children: [
StarRating( // StarRating(
totalAverage: model.finalProducts[index].approvedRatingSum > 0 // totalAverage: model.finalProducts[index].approvedRatingSum > 0
? (model.finalProducts[index].approvedRatingSum.toDouble() / model.finalProducts[index].approvedRatingSum.toDouble()).toDouble() // ? (model.finalProducts[index].approvedRatingSum.toDouble() / model.finalProducts[index].approvedRatingSum.toDouble()).toDouble()
: 0, // : 0,
forceStars: true), // forceStars: true),
RatingBar.readOnly(
initialRating: model.finalProducts[index].approvedRatingSum.toDouble(),
size: 15.0,
filledColor: Colors.yellow[700],
emptyColor: Colors.grey[500],
isHalfAllowed: true,
halfFilledIcon: Icons.star_half,
filledIcon: Icons.star,
emptyIcon: Icons.star,
),
Texts( Texts(
"(${model.finalProducts[index].approvedTotalReviews})", "(${model.finalProducts[index].approvedTotalReviews})",
regular: true, regular: true,
@ -424,11 +435,21 @@ class _FinalProductsPageState extends State<FinalProductsPage> {
), ),
Row( Row(
children: [ children: [
StarRating( // StarRating(
totalAverage: model.finalProducts[index].approvedRatingSum > 0 // totalAverage: model.finalProducts[index].approvedRatingSum > 0
? (model.finalProducts[index].approvedRatingSum.toDouble() / model.finalProducts[index].approvedRatingSum.toDouble()).toDouble() // ? (model.finalProducts[index].approvedRatingSum.toDouble() / model.finalProducts[index].approvedRatingSum.toDouble()).toDouble()
: 0, // : 0,
forceStars: true), // forceStars: true),
RatingBar.readOnly(
initialRating: model.finalProducts[index].approvedRatingSum.toDouble(),
size: 15.0,
filledColor: Colors.yellow[700],
emptyColor: Colors.grey[500],
isHalfAllowed: true,
halfFilledIcon: Icons.star_half,
filledIcon: Icons.star,
emptyIcon: Icons.star,
),
Texts( Texts(
"(${model.finalProducts[index].approvedTotalReviews})", "(${model.finalProducts[index].approvedTotalReviews})",
regular: true, regular: true,

@ -5,6 +5,7 @@ import 'package:diplomaticquarterapp/core/viewModels/dashboard_view_model.dart';
import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart';
import 'package:diplomaticquarterapp/models/Appointments/AppoimentAllHistoryResultList.dart'; import 'package:diplomaticquarterapp/models/Appointments/AppoimentAllHistoryResultList.dart';
import 'package:diplomaticquarterapp/models/Appointments/toDoCountProviderModel.dart'; import 'package:diplomaticquarterapp/models/Appointments/toDoCountProviderModel.dart';
import 'package:diplomaticquarterapp/models/Authentication/authenticated_user.dart';
import 'package:diplomaticquarterapp/models/gradient_color.dart'; import 'package:diplomaticquarterapp/models/gradient_color.dart';
import 'package:diplomaticquarterapp/models/hmg_services.dart'; import 'package:diplomaticquarterapp/models/hmg_services.dart';
import 'package:diplomaticquarterapp/models/slider_data.dart'; import 'package:diplomaticquarterapp/models/slider_data.dart';
@ -282,7 +283,7 @@ class _HomePageFragment2State extends State<HomePageFragment2> {
flex: 1, flex: 1,
child: InkWell( child: InkWell(
onTap: () { onTap: () {
final user = projectViewModel.user; AuthenticatedUser user = projectViewModel.user;
Navigator.of(context).push(MaterialPageRoute(builder: (context) => PackagesHomePage(user))); Navigator.of(context).push(MaterialPageRoute(builder: (context) => PackagesHomePage(user)));
}, },
child: Container( child: Container(

@ -7,6 +7,7 @@ import 'package:diplomaticquarterapp/widgets/others/app_scaffold_pharmacy_widget
import 'package:diplomaticquarterapp/widgets/others/network_base_view.dart'; import 'package:diplomaticquarterapp/widgets/others/network_base_view.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
import 'package:rating_bar/rating_bar.dart';
import 'base/base_view.dart'; import 'base/base_view.dart';
@ -428,14 +429,24 @@ class _OffersCategorisePageState extends State<OffersCategorisePage> {
), ),
Row( Row(
children: [ children: [
StarRating( // StarRating(
totalAverage: model.products[index].approvedRatingSum > // totalAverage: model.products[index].approvedRatingSum >
0 // 0
? (model.products[index].approvedRatingSum.toDouble() / model.products[index].approvedRatingSum.toDouble()) // ? (model.products[index].approvedRatingSum.toDouble() / model.products[index].approvedRatingSum.toDouble())
.toDouble() // .toDouble()
: 0, // : 0,
forceStars: // forceStars:
true), // true),
RatingBar.readOnly(
initialRating: model.products[index].approvedRatingSum.toDouble(),
size: 15.0,
filledColor: Colors.yellow[700],
emptyColor: Colors.grey[500],
isHalfAllowed: true,
halfFilledIcon: Icons.star_half,
filledIcon: Icons.star,
emptyIcon: Icons.star,
),
Texts( Texts(
"(${model.products[index].approvedTotalReviews})", "(${model.products[index].approvedTotalReviews})",
regular: true, regular: true,
@ -663,19 +674,29 @@ class _OffersCategorisePageState extends State<OffersCategorisePage> {
), ),
Row( Row(
children: [ children: [
StarRating( // StarRating(
totalAverage: model // totalAverage: model
.products[ // .products[
index] // index]
.approvedRatingSum > // .approvedRatingSum >
0 // 0
? (model.products[index].approvedRatingSum.toDouble() / // ? (model.products[index].approvedRatingSum.toDouble() /
model.products[index].approvedRatingSum // model.products[index].approvedRatingSum
.toDouble()) // .toDouble())
.toDouble() // .toDouble()
: 0, // : 0,
forceStars: // forceStars:
true), // true),
RatingBar.readOnly(
initialRating: model.products[index].approvedRatingSum.toDouble(),
size: 15.0,
filledColor: Colors.yellow[700],
emptyColor: Colors.grey[500],
isHalfAllowed: true,
halfFilledIcon: Icons.star_half,
filledIcon: Icons.star,
emptyIcon: Icons.star,
),
Texts( Texts(
"(${model.products[index].approvedTotalReviews})", "(${model.products[index].approvedTotalReviews})",
regular: true, regular: true,

@ -1,213 +1,254 @@
import 'package:diplomaticquarterapp/core/model/packages_offers/responses/PackagesResponseModel.dart';
import 'package:diplomaticquarterapp/core/viewModels/packages_offers/PackagesOffersViewModel.dart'; import 'package:diplomaticquarterapp/core/viewModels/packages_offers/PackagesOffersViewModel.dart';
import 'package:diplomaticquarterapp/pages/base/base_view.dart'; import 'package:diplomaticquarterapp/pages/base/base_view.dart';
import 'package:diplomaticquarterapp/pages/pharmacies/ProductCheckTypeWidget.dart'; import 'package:diplomaticquarterapp/theme/colors.dart';
import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart';
import 'package:diplomaticquarterapp/uitl/utils.dart' as utils; import 'package:diplomaticquarterapp/uitl/utils_new.dart';
import 'package:diplomaticquarterapp/widgets/data_display/text.dart';
import 'package:diplomaticquarterapp/widgets/others/StarRating.dart';
import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart';
import 'package:expandable/expandable.dart';
import 'package:flutter/cupertino.dart'; import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:html/parser.dart';
import 'package:rating_bar/rating_bar.dart';
class OfferAndPackagesDetail extends StatefulWidget{ class OfferAndPackagesDetail extends StatefulWidget {
final dynamic model; final PackagesResponseModel itemModel;
final Function(PackagesResponseModel product) onCartClick;
const OfferAndPackagesDetail({@required this.model, Key key}) : super(key: key); const OfferAndPackagesDetail({@required this.itemModel, @required this.onCartClick, Key key}) : super(key: key);
@override @override
State<StatefulWidget> createState() => OfferAndPackagesDetailState(); State<StatefulWidget> createState() => OfferAndPackagesDetailState();
} }
class OfferAndPackagesDetailState extends State<OfferAndPackagesDetail> {
class OfferAndPackagesDetailState extends State<OfferAndPackagesDetail>{
PackagesViewModel viewModel; PackagesViewModel viewModel;
bool expandFlag = false;
var controller = new ExpandableController();
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return BaseView<PackagesViewModel>( return BaseView<PackagesViewModel>(
onModelReady: (model){ onModelReady: (model) {
viewModel = model; viewModel = model;
}, },
builder: (_, model, wi) => AppScaffold( builder: (_, model, wi) => AppScaffold(
appBarTitle: TranslationBase.of(context).offerAndPackages, appBarTitle: TranslationBase.of(context).offerAndPackages,
isShowAppBar: true, isShowAppBar: true,
isPharmacy: false, isPharmacy: false,
showPharmacyCart: false, showPharmacyCart: false,
showHomeAppBarIcon: false, showHomeAppBarIcon: false,
isOfferPackages: true, isOfferPackages: true,
showOfferPackagesCart: true, showOfferPackagesCart: true,
isShowDecPage: false, isShowDecPage: false,
body: Stack( showNewAppBar: true,
showNewAppBarTitle: true,
body: SingleChildScrollView(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
Padding( Container(
padding: const EdgeInsets.only(bottom: 60), color: Colors.white,
child: ListView( padding: const EdgeInsets.all(21.0),
children: [ child: ClipRRect(
Padding( borderRadius: BorderRadius.circular(15.0),
padding: const EdgeInsets.all(5), child: Image.network("https://mdlaboratories.com/offersdiscounts/images/thumbs/0000162_dermatology-testing.jpeg", fit: BoxFit.fill),
child: Stack( ),
children: [ ),
Padding( Container(
padding: const EdgeInsets.all(10), padding: const EdgeInsets.only(left: 21.0, right: 21.0, top: 21.0),
child: AspectRatio( child: Text(widget.itemModel.name, maxLines: 1, style: TextStyle(fontSize: 19.0, fontWeight: FontWeight.bold, letterSpacing: -1.14))),
aspectRatio: 1/1, Container(
child: utils.applyShadow( padding: const EdgeInsets.only(left: 21.0, right: 21.0),
child: ClipRRect( child: Text(widget.itemModel.shortDescription,
borderRadius: BorderRadius.circular(10), maxLines: 2, style: TextStyle(fontSize: 14.0, fontWeight: FontWeight.w600, letterSpacing: -0.56, color: CustomColors.textColor), overflow: TextOverflow.clip)),
child: utils.Utils.loadNetworkImage(url: "https://wallpaperaccess.com/full/30103.jpg",) Row(
), children: [
) Container(
), padding: const EdgeInsets.only(left: 21.0, right: 21.0, top: 12.0),
), child: RatingBar.readOnly(
Align( initialRating: 4.5,
alignment: Alignment.topLeft, size: 18.0,
child: Image.asset( filledColor: Color(0XFFD02127),
'assets/images/discount_${'en'}.png', emptyColor: Color(0XFFD02127),
height: 70, isHalfAllowed: true,
width: 70, halfFilledIcon: Icons.star_half,
), filledIcon: Icons.star,
), emptyIcon: Icons.star_border,
],
),
), ),
),
Padding( ],
padding: const EdgeInsets.only(left: 20, right: 20, bottom: 20), ),
child: Column( Container(
crossAxisAlignment: CrossAxisAlignment.start, padding: const EdgeInsets.only(left: 21.0, right: 21.0, top: 18.0),
children: [ width: double.infinity,
Texts( height: 50.0,
"Child Dental Offer", child: ListView.separated(
fontSize: 25, scrollDirection: Axis.horizontal,
fontWeight: FontWeight.normal, shrinkWrap: true,
color: Colors.black, itemCount: widget.itemModel.storeNames.length,
), separatorBuilder: (context, index) {
return mWidth(5.0);
Stack( },
children: [ itemBuilder: (BuildContext context, int index) {
Texts( return contactButton(widget.itemModel.storeNames[index].toString());
"200 SAR", },
fontWeight: FontWeight.normal, ),
decoration: TextDecoration.lineThrough, ),
color: Colors.grey, Container(
fontSize: 12 padding: const EdgeInsets.only(top: 18.0),
), child: ExpandableNotifier(
Padding( initialExpanded: true,
padding: const EdgeInsets.only(top: 15), child: Container(
child: Texts( color: Colors.white,
"894.99 SAR", child: Column(
fontWeight: FontWeight.bold, children: <Widget>[
color: Colors.green, ScrollOnExpand(
fontSize: 18 scrollOnExpand: true,
scrollOnCollapse: false,
child: ExpandablePanel(
hasIcon: false,
theme: const ExpandableThemeData(
headerAlignment: ExpandablePanelHeaderAlignment.center,
tapBodyToCollapse: true,
),
header: Padding(
padding: const EdgeInsets.only(top: 20, bottom: 20, left: 21, right: 21),
child: InkWell(
onTap: () {
setState(() {
expandFlag = !expandFlag;
controller.expanded = expandFlag;
});
},
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Expanded(
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
TranslationBase.of(context).description,
maxLines: 1,
style: TextStyle(fontSize: 19.0, fontWeight: FontWeight.bold, letterSpacing: -1.14),
),
],
),
),
Icon(
expandFlag ? Icons.keyboard_arrow_up : Icons.keyboard_arrow_down,
color: Color(0xff2E303A),
),
],
), ),
), ),
],
),
StarRating(
size: 20,
totalCount: null,
totalAverage: 5,
forceStars: true),
SizedBox(height: 20,),
Texts(
"Details",
fontWeight: FontWeight.bold,
color: Colors.grey,
fontSize: 20
),
AspectRatio(
aspectRatio: 2/1,
child: Container(
color: Colors.grey[300],
child: Padding(
padding: const EdgeInsets.all(10),
child: Texts("Detail of offers written here"),
)
), ),
builder: (_, collapsed, expanded) {
return Expandable(
controller: controller,
collapsed: collapsed,
expanded: Container(
padding: const EdgeInsets.only(left: 21.0, right: 21.0, bottom: 21.0),
child: Text(parseHtmlString(widget.itemModel.fullDescription),
style: TextStyle(fontSize: 14.0, fontWeight: FontWeight.w600, letterSpacing: -0.56, color: CustomColors.textColor), overflow: TextOverflow.clip)),
theme: const ExpandableThemeData(crossFadePoint: 0),
);
},
), ),
),
],
SizedBox(height: 10,),
],
),
), ),
),
),
),
],
),
),
bottomSheet: Container(
padding: const EdgeInsets.only(top: 16, bottom: 16, left: 21, right: 21),
color: Colors.white,
child: Row(
children: [
Expanded(
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
if(widget.itemModel.hasDiscountsApplied) Container(
margin: const EdgeInsets.only(top: 0.0),
child: Text(widget.itemModel.oldPrice.toString() + " " + TranslationBase.of(context).sar,
style: TextStyle(fontSize: 15.0, fontWeight: FontWeight.w600, letterSpacing: -0.6, decoration: TextDecoration.lineThrough, color: CustomColors.grey2))),
Container(
margin: const EdgeInsets.only(top: 0.0),
child: Text(widget.itemModel.price.toString().trim() + " " + TranslationBase.of(context).sar,
style: TextStyle(fontSize: 19.0, fontWeight: FontWeight.bold, letterSpacing: -0.56))),
], ],
), ),
), ),
SizedBox(width: 8),
Padding( Expanded(
padding: const EdgeInsets.all(10), child: SizedBox(
child: Align( height: 43,
alignment: Alignment.bottomRight, width: double.infinity,
child: Row( child: FlatButton(
children: [ onPressed: () {
// onCartClick();
Expanded( widget.onCartClick(widget.itemModel);
child: RaisedButton.icon( },
padding: EdgeInsets.only(top: 5, bottom: 5, left: 0, right: 0), child: Row(
shape: RoundedRectangleBorder( mainAxisAlignment: MainAxisAlignment.center,
borderRadius: BorderRadius.circular(8.0), children: [
side: BorderSide(color: Colors.red, width: 0.5) Padding(
), padding: const EdgeInsets.only(left: 8.0, right: 8.0),
color: Colors.red, child: SvgPicture.asset("assets/images/new/add-to-cart.svg", color: Colors.white),
icon: Icon( ),
Icons.add_shopping_cart_outlined, Container(
size: 25, child: Text(
color: Colors.white, TranslationBase.of(context).addToCart,
), textAlign: TextAlign.center,
label: Texts( style: TextStyle(fontSize: 16, fontWeight: FontWeight.w600, color: Colors.white, letterSpacing: -0.48),
"Add to Cart",
fontSize: 17, color: Colors.white, fontWeight: FontWeight.normal,
),
onPressed: (){},),
),
SizedBox(width: 15,),
Expanded(
child: OutlineButton.icon(
padding: EdgeInsets.only(top: 5, bottom: 5, left: 0, right: 0),
borderSide: BorderSide(width: 1.0, color: Colors.red),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(8.0),
), ),
color: Colors.white, ),
icon: Icon( ],
Icons.favorite_rounded, ),
size: 25, color: const Color(0xffD02127),
color: Colors.red, shape: RoundedRectangleBorder(
), borderRadius: BorderRadius.circular(6),
label: Texts( ),
"Add to Favorites",
fontSize: 17, color: Colors.red, fontWeight: FontWeight.normal
),
onPressed: (){
},),
),
],
), ),
), ),
) ),
],
),
),
),
);
}
String parseHtmlString(String htmlString) {
var document = parse(htmlString);
String parsedString = parse(document.body.text).documentElement.text;
return parsedString;
}
], Widget contactButton(String title) {
) return SizedBox(
height: 32,
width: 80.0,
child: FlatButton(
onPressed: () {},
color: Colors.white,
shape: StadiumBorder(side: BorderSide(color: CustomColors.devider, width: 1)),
child: Text(
title,
style: TextStyle(fontSize: 10, letterSpacing: -0.4, color: CustomColors.textColor),
maxLines: 1,
),
), ),
); );
} }
} }

@ -1,19 +1,23 @@
import 'package:after_layout/after_layout.dart'; import 'package:after_layout/after_layout.dart';
import 'package:diplomaticquarterapp/config/shared_pref_kay.dart'; import 'package:diplomaticquarterapp/config/shared_pref_kay.dart';
import 'package:diplomaticquarterapp/core/model/ResponseModel.dart'; import 'package:diplomaticquarterapp/core/model/ResponseModel.dart';
import 'package:diplomaticquarterapp/core/model/hospitals/hospitals_model.dart';
import 'package:diplomaticquarterapp/core/model/packages_offers/requests/AddProductToCartRequestModel.dart'; import 'package:diplomaticquarterapp/core/model/packages_offers/requests/AddProductToCartRequestModel.dart';
import 'package:diplomaticquarterapp/core/model/packages_offers/responses/tamara_payment_option.dart';
import 'package:diplomaticquarterapp/core/viewModels/packages_offers/PackagesOffersViewModel.dart'; import 'package:diplomaticquarterapp/core/viewModels/packages_offers/PackagesOffersViewModel.dart';
import 'package:diplomaticquarterapp/pages/ToDoList/payment_method_select.dart';
import 'package:diplomaticquarterapp/pages/base/base_view.dart'; import 'package:diplomaticquarterapp/pages/base/base_view.dart';
import 'package:diplomaticquarterapp/pages/packages_offers/PackageOrderCompletedPage.dart'; import 'package:diplomaticquarterapp/pages/packages_offers/PackageOrderCompletedPage.dart';
import 'package:diplomaticquarterapp/pages/pharmacies/screens/pharmacy-terms-conditions-page.dart'; import 'package:diplomaticquarterapp/pages/pharmacies/screens/pharmacy-terms-conditions-page.dart';
import 'package:diplomaticquarterapp/theme/colors.dart';
import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart';
import 'package:diplomaticquarterapp/uitl/utils.dart' as utils; import 'package:diplomaticquarterapp/uitl/utils.dart' as utils;
import 'package:diplomaticquarterapp/uitl/utils_new.dart';
import 'package:diplomaticquarterapp/widgets/buttons/defaultButton.dart';
import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; import 'package:diplomaticquarterapp/widgets/data_display/text.dart';
import 'package:diplomaticquarterapp/widgets/dialogs/radio_selection_dialog.dart';
import 'package:diplomaticquarterapp/widgets/in_app_browser/InAppBrowser.dart'; import 'package:diplomaticquarterapp/widgets/in_app_browser/InAppBrowser.dart';
import 'package:diplomaticquarterapp/widgets/offers_packages/PackagesCartItemCard.dart'; import 'package:diplomaticquarterapp/widgets/offers_packages/PackagesCartItemCard.dart';
import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart';
import 'package:diplomaticquarterapp/widgets/single_selection_dialog.dart';
import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart';
import 'package:flutter/cupertino.dart'; import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
@ -22,6 +26,9 @@ import 'package:flutter_staggered_grid_view/flutter_staggered_grid_view.dart';
dynamic languageID; dynamic languageID;
const _columnCount = 1; const _columnCount = 1;
bool _agreeTerms = false;
String _selectedPaymentMethod;
Map<dynamic, dynamic> _selectedPaymentParams;
AnimationController _animationController; AnimationController _animationController;
@ -32,20 +39,20 @@ class PackagesCartPage extends StatefulWidget {
_PackagesCartPageState createState() => _PackagesCartPageState(); _PackagesCartPageState createState() => _PackagesCartPageState();
} }
class _PackagesCartPageState extends State<PackagesCartPage> class _PackagesCartPageState extends State<PackagesCartPage> with AfterLayoutMixin<PackagesCartPage>, SingleTickerProviderStateMixin {
with AfterLayoutMixin<PackagesCartPage>, SingleTickerProviderStateMixin {
getLanguageID() async { getLanguageID() async {
languageID = await sharedPref.getString(APP_LANGUAGE); languageID = await sharedPref.getString(APP_LANGUAGE);
} }
double subtotal,tax, total; double subtotal, tax, total;
int _selectedHospitalIndex = -1;
HospitalsModel _selectedHospital;
@override @override
void initState() { void initState() {
_agreeTerms = false; _agreeTerms = false;
_selectedPaymentMethod = null; _selectedPaymentMethod = null;
_animationController = _animationController = AnimationController(vsync: this, duration: Duration(seconds: 500));
AnimationController(vsync: this, duration: Duration(seconds: 500));
super.initState(); super.initState();
} }
@ -69,22 +76,12 @@ class _PackagesCartPageState extends State<PackagesCartPage>
} }
onPayNowClick() async { onPayNowClick() async {
await viewModel.service await viewModel.service.placeOrder(context: context, projectID: _selectedHospital.iD, paymentParams: _selectedPaymentParams).then((orderId) {
.placeOrder(
context: context,
paymentParams: _selectedPaymentParams)
.then((orderId) {
if (orderId.runtimeType == int) { if (orderId.runtimeType == int) {
// result == order_id var browser = MyInAppBrowser(context: context, onExitCallback: (data, isDone) => paymentClosed(orderId: orderId, withStatus: isDone, data: data));
var browser = MyInAppBrowser( browser.openPackagesPaymentBrowser(customer_id: viewModel.service.customer.id, order_id: orderId);
context: context,
onExitCallback: (data, isDone) => paymentClosed(
orderId: orderId, withStatus: isDone, data: data));
browser.openPackagesPaymentBrowser(
customer_id: viewModel.service.customer.id, order_id: orderId);
} else { } else {
utils.Utils.showErrorToast( utils.Utils.showErrorToast('Failed to place order, please try again later');
'Failed to place order, please try again later');
} }
}).catchError((error) { }).catchError((error) {
utils.Utils.showErrorToast(error.toString()); utils.Utils.showErrorToast(error.toString());
@ -94,28 +91,30 @@ class _PackagesCartPageState extends State<PackagesCartPage>
@override @override
void afterFirstLayout(BuildContext context) { void afterFirstLayout(BuildContext context) {
fetchData(); fetchData();
viewModel.service.getHospitals();
} }
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return BaseView<PackagesViewModel>( return BaseView<PackagesViewModel>(
allowAny: true, allowAny: true,
onModelReady: (model) => viewModel = model, onModelReady: (model) => viewModel = model,
builder: (_, model, wi) { builder: (_, model, wi) {
return AppScaffold( return AppScaffold(
appBarTitle: TranslationBase.of(context).offerAndPackages, appBarTitle: TranslationBase.of(context).offerAndPackages,
isShowAppBar: true, isShowAppBar: true,
isPharmacy: false, isPharmacy: false,
showPharmacyCart: false, showPharmacyCart: false,
showHomeAppBarIcon: false, showHomeAppBarIcon: false,
isOfferPackages: true, isOfferPackages: true,
showOfferPackagesCart: false, showOfferPackagesCart: false,
isShowDecPage: false, isShowDecPage: false,
body: Column( showNewAppBar: true,
children: [ showNewAppBarTitle: true,
Expanded( body: viewModel.cartItemList.length > 0
child: Padding( ? Column(
padding: const EdgeInsets.all(5), children: [
Expanded(
child: StaggeredGridView.countBuilder( child: StaggeredGridView.countBuilder(
crossAxisCount: (_columnCount * _columnCount), crossAxisCount: (_columnCount * _columnCount),
itemCount: viewModel.cartItemList.length, itemCount: viewModel.cartItemList.length,
@ -127,84 +126,217 @@ class _PackagesCartPageState extends State<PackagesCartPage>
background: _cartItemDeleteContainer(), background: _cartItemDeleteContainer(),
secondaryBackground: _cartItemDeleteContainer(), secondaryBackground: _cartItemDeleteContainer(),
confirmDismiss: (direction) async { confirmDismiss: (direction) async {
bool status = await viewModel.service bool status = await viewModel.service.deleteProductFromCart(item.id, context: context, showLoading: false);
.deleteProductFromCart(item.id,
context: context, showLoading: false);
return status; return status;
}, },
onDismissed: (direction) { onDismissed: (direction) {
debugPrint('Index: $index');
viewModel.cartItemList.removeAt(index); viewModel.cartItemList.removeAt(index);
}, },
child: PackagesCartItemCard( child: PackagesCartItemCard(
itemModel: item, itemModel: item,
viewModel: viewModel,
getCartItems: fetchData,
shouldStepperChangeApply: (apply, total) async { shouldStepperChangeApply: (apply, total) async {
var request = AddProductToCartRequestModel( var request = AddProductToCartRequestModel(product_id: item.productId, quantity: apply);
product_id: item.productId, ResponseModel response = await viewModel.service.addProductToCart(request, context: context, showLoading: false).catchError((error) {
quantity: apply);
ResponseModel response = await viewModel
.service
.addProductToCart(request,
context: context, showLoading: false)
.catchError((error) {
utils.Utils.showErrorToast(error); utils.Utils.showErrorToast(error);
}); });
if(response.status){ if (response.status) {
fetchData(); fetchData();
} }
return response.status ?? false; return response.status ?? false;
}, },
)); ));
}, },
staggeredTileBuilder: (int index) => staggeredTileBuilder: (int index) => StaggeredTile.fit(_columnCount),
StaggeredTile.fit(_columnCount),
mainAxisSpacing: 0, mainAxisSpacing: 0,
crossAxisSpacing: 10, crossAxisSpacing: 10,
)), ),
), ),
Container( Container(
height: 0.25, height: 0.25,
color: Theme.of(context).primaryColor, color: Theme.of(context).primaryColor,
), ),
Container( ],
)
: getNoDataWidget(context),
bottomSheet: viewModel.cartItemList.length > 0
? Container(
padding: EdgeInsets.all(21.0),
width: double.infinity,
color: Colors.white, color: Colors.white,
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: [ children: [
Texts(TranslationBase.of(context).selectPaymentOption,
fontSize: 10, fontWeight: FontWeight.bold),
Container( Container(
height: 0.25, margin: EdgeInsets.only(bottom: 12.0),
width: 100, child: InkWell(
color: Colors.grey[300], onTap: () => confirmSelectHospitalDialog(model.hospitals),
child: Container(
padding: EdgeInsets.all(12),
width: double.infinity,
height: 50,
decoration: BoxDecoration(borderRadius: BorderRadius.circular(12), border: Border.all(color: CustomColors.devider), color: Colors.white),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
getHospitalName(),
style: TextStyle(
fontSize: 14,
fontWeight: FontWeight.w600,
letterSpacing: -0.46,
),
),
Icon(Icons.arrow_drop_down),
],
),
),
),
),
Container(
margin: EdgeInsets.fromLTRB(0.0, 0.0, 20.0, 0.0),
child: Text(TranslationBase.of(context).YouCanPayByTheFollowingOptions, style: TextStyle(fontSize: 14.0, fontWeight: FontWeight.w600)),
), ),
_paymentOptions(context, (paymentMethod) {
setState(() => _selectedPaymentMethod = paymentMethod);
}, viewModel: viewModel),
Container( Container(
height: 0.25, width: MediaQuery.of(context).size.width * 0.75,
color: Colors.grey[300], margin: EdgeInsets.fromLTRB(0.0, 8.0, 20.0, 5.0),
child: getPaymentMethods(),
), ),
Container( Container(
height: 40, margin: EdgeInsets.only(top: 14.0),
child: _termsAndCondition(context, child: Row(
onSelected: onTermsClick, mainAxisAlignment: MainAxisAlignment.start,
onInfoClick: onTermsInfoClick)), children: [
SizedBox(
height: 24.0,
width: 24.0,
child: Checkbox(
value: _agreeTerms,
onChanged: (v) {
setState(() => _agreeTerms = v);
}),
),
Expanded(
child: Text(
TranslationBase.of(context).iAcceptTermsConditions,
style: TextStyle(fontSize: 12, fontWeight: FontWeight.w600, color: CustomColors.textColor, letterSpacing: -0.48),
),
),
],
),
),
Container( Container(
height: 0.25, child: Column(
color: Colors.grey[300], crossAxisAlignment: CrossAxisAlignment.start,
children: [
Container(
width: double.infinity,
padding: EdgeInsets.only(top: 12, bottom: 3),
child: Row(
children: [
Expanded(
child: _getNormalText(TranslationBase.of(context).patientShareToDo),
),
Expanded(
child: _getNormalText(TranslationBase.of(context).sar + " " + (subtotal ?? 0.0).toStringAsFixed(2), isBold: true),
)
],
),
),
mDivider(Colors.grey[200]),
Container(
width: double.infinity,
padding: EdgeInsets.only(top: 3, bottom: 3),
child: Row(
children: [
Expanded(
child: _getNormalText(TranslationBase.of(context).patientTaxToDo),
),
Expanded(
child: _getNormalText(TranslationBase.of(context).sar + ' ' + (tax ?? 0.0).toStringAsFixed(2), isBold: true),
)
],
),
),
mDivider(Colors.grey[200]),
Container(
width: double.infinity,
padding: EdgeInsets.only(top: 3, bottom: 3),
child: Row(
children: [
Expanded(
child: _getNormalText(TranslationBase.of(context).patientShareTotalToDo),
),
Expanded(
child: _getNormalText(TranslationBase.of(context).sar + ' ' + (total ?? 0.0).toStringAsFixed(2), isBold: true, isTotal: true),
)
],
),
),
],
),
),
Container(
padding: EdgeInsets.only(top: 21, bottom: 21),
child: DefaultButton(
TranslationBase.of(context).payNow,
(_agreeTerms && _selectedHospital != null)
? () {
Navigator.push(context, FadePage(page: PaymentMethod(onSelectedMethod: (String metohd) {
setState(() {});
}))).then((value) {
print(value);
if (value != null) {
_selectedPaymentMethod = value;
_selectedPaymentParams = {"payment_method_system_name": "Payments.PayFort", "payment_option": value};
onPayNowClick();
}
});
}
: null,
color: CustomColors.green,
disabledColor: CustomColors.grey2,
),
), ),
_payNow(context, subtotal: subtotal, tax: tax, total: total, onPayNowClick: onPayNowClick)
], ],
), ),
) )
], : SizedBox(),
), );
); },
}); );
}
void confirmSelectHospitalDialog(List<HospitalsModel> hospitals) {
List<RadioSelectionDialogModel> list = [
for (int i = 0; i < hospitals.length; i++) RadioSelectionDialogModel(hospitals[i].name + ' ${hospitals[i].distanceInKilometers} ' + TranslationBase.of(context).km, i),
];
showDialog(
context: context,
child: RadioSelectionDialog(
listData: list,
selectedIndex: _selectedHospitalIndex,
isScrollable: true,
onValueSelected: (index) {
_selectedHospitalIndex = index;
_selectedHospital = hospitals[index];
setState(() {});
},
),
);
}
String getHospitalName() {
if (_selectedHospital != null)
return _selectedHospital.name;
else
return TranslationBase.of(context).selectHospital;
} }
fetchData() async { fetchData() async {
await viewModel.service.cartItems(context: context).then((value){ await viewModel.service.cartItems(context: context).then((value) {
subtotal = value['subtotal'] ?? 0.0; subtotal = value['subtotal'] ?? 0.0;
tax = value['tax'] ?? 0.0; tax = value['tax'] ?? 0.0;
total = value['total'] ?? 0.0; total = value['total'] ?? 0.0;
@ -213,231 +345,85 @@ class _PackagesCartPageState extends State<PackagesCartPage>
setState(() {}); setState(() {});
} }
paymentClosed( paymentClosed({@required int orderId, @required bool withStatus, dynamic data}) async {
{@required int orderId, @required bool withStatus, dynamic data}) async {
viewModel.service.getOrderById(orderId, context: context).then((value) { viewModel.service.getOrderById(orderId, context: context).then((value) {
var heading = withStatus ? "Success" : "Failed"; var heading = withStatus ? "Success" : "Failed";
var title = withStatus ? "Your order has been placed successfully" : "Failed to place your order"; var title = withStatus ? "Your order has been placed successfully" : "Failed to place your order";
var subTitle = "Order# ${value.data.customOrderNumber}"; var subTitle = "Order# ${value.data.customOrderNumber}";
Navigator.of(context).pushReplacement(MaterialPageRoute( Navigator.of(context).pushReplacement(MaterialPageRoute(builder: (context) => PackageOrderCompletedPage(heading: heading, title: title, subTitle: subTitle)));
builder: (context) => PackageOrderCompletedPage(
heading: heading, title: title, subTitle: subTitle)));
}).catchError((error) { }).catchError((error) {
debugPrint(error); debugPrint(error);
}); });
} }
} }
// /* Payment Footer Widgets */ // Widget _payNow(BuildContext context, {double subtotal, double tax, double total, @required VoidCallback onPayNowClick}) {
// --------------------------- // bool isPayNowAQctive = (_agreeTerms && (_selectedPaymentMethod != null));
String _selectedPaymentMethod; //
Map<dynamic,dynamic> _selectedPaymentParams; // String _subtotal = (subtotal ?? 0.0).toStringAsFixed(2);
Widget _paymentOptions(BuildContext context, Function(String) onSelected, {PackagesViewModel viewModel}) { // String _tax = (tax ?? 0.0).toStringAsFixed(2);
double height = 30; // String _total = (total ?? 0).toStringAsFixed(2);
//
// return Padding(
// padding: const EdgeInsets.all(5),
// child: Container(
// child: Row(
// crossAxisAlignment: CrossAxisAlignment.end,
// children: [
// Padding(
// padding: const EdgeInsets.all(5),
// child: Column(
// crossAxisAlignment: CrossAxisAlignment.start,
// children: [
// Texts('${TranslationBase.of(context).subtotal}: $_subtotal ${TranslationBase.of(context).sar}', heightFactor: 1.5, fontWeight: FontWeight.bold, color: Colors.grey, fontSize: 8),
// Texts('${TranslationBase.of(context).vat}: $_tax ${TranslationBase.of(context).sar}', heightFactor: 1.5, fontWeight: FontWeight.bold, color: Colors.grey, fontSize: 8),
// Padding(
// padding: const EdgeInsets.all(3),
// child: Container(
// height: 0.25,
// width: 120,
// color: Colors.grey[300],
// ),
// ),
// Texts('${TranslationBase.of(context).total}: $_total ${TranslationBase.of(context).sar}', heightFactor: 1.5, fontWeight: FontWeight.bold, color: Colors.black54, fontSize: 15)
// ],
// ),
// ),
// Expanded(child: Container()),
// RaisedButton(
// elevation: 0,
// child: Texts(
// TranslationBase.of(context).payNow,
// fontSize: 15,
// color: Colors.white,
// fontWeight: FontWeight.bold,
// ),
// padding: EdgeInsets.only(top: 5, bottom: 5, left: 0, right: 0),
// shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(5), side: BorderSide(color: Theme.of(context).primaryColor, width: 0.5)),
// color: Theme.of(context).primaryColor,
// onPressed: isPayNowAQctive ? onPayNowClick : null,
// ),
// ],
// )),
// );
// }
Widget buttonContent(bool isSelected, String imageName) { _getNormalText(text, {bool isBold = false, bool isTotal = false}) {
return Container( return Text(
decoration: BoxDecoration( text,
color: Colors.white, style: TextStyle(
boxShadow: [ fontSize: isBold
BoxShadow( ? isTotal
color: isSelected ? Colors.green[50] : Colors.grey[200], ? 16
blurRadius: 1, : 12
spreadRadius: 2, : 10,
), letterSpacing: -0.5,
], color: isBold ? Colors.black : Colors.grey[700],
borderRadius: BorderRadius.all(Radius.circular(5)), fontWeight: FontWeight.w600,
border: Border.all(
color: isSelected ? Colors.green : Colors.grey,
width: isSelected ? 1 : 0.5)),
child: Padding(
padding: const EdgeInsets.all(4),
child: Image.asset('assets/images/new-design/$imageName'),
));
}
Future<String> selectTamaraPaymentOption() async{
final tamara_options = await viewModel.service.getTamaraOptions(context: context, showLoading: true);
final selected = await SingleSelectionDialog<TamaraPaymentOption>(tamara_options, icon: Image.asset('assets/images/new-design/tamara.png'), title: TranslationBase.of(context).tamaraInstPlan).show(context);
return selected.name;
}
return Padding(
padding: const EdgeInsets.all(5),
child: Container(
height: height,
color: Colors.transparent,
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
InkWell(
child: buttonContent(_selectedPaymentMethod == "tamara", 'tamara.png'),
onTap: () async{
final tamara_option = await selectTamaraPaymentOption();
_selectedPaymentParams = {"channel" : "Web", "payment_method_system_name" : "Payments.Tamara", "payment_option" : tamara_option};
onSelected("tamara");
},
),
SizedBox(
width: 5,
),
InkWell(
child: buttonContent(_selectedPaymentMethod == "mada", 'mada.png'),
onTap: () {
_selectedPaymentParams = {"payment_method_system_name" : "Payments.PayFort", "payment_option" : "MADA"};
onSelected("mada");
},
),
SizedBox(
width: 5,
),
InkWell(
child: buttonContent(_selectedPaymentMethod == "visa", 'visa.png'),
onTap: () {
_selectedPaymentParams = {"payment_method_system_name" : "Payments.PayFort", "payment_option" : "VISA"};
onSelected("visa");
},
),
SizedBox(
width: 5,
),
InkWell(
child: buttonContent(_selectedPaymentMethod == "mastercard", 'mastercard.png'),
onTap: () {
_selectedPaymentParams = {"payment_method_system_name" : "Payments.PayFort", "payment_option" : "MASTERCARD"};
onSelected("mastercard");
},
),
// SizedBox(
// width: 5,
// ),
// InkWell(
// child: buttonContent(
// _selectedPaymentMethod == "installment", 'installment.png'),
// onTap: () {
// _selectedPaymentParams = {"payment_method_system_name" : "Payments.PayFort", "payment_option" : "INSTALLMENT"};
// onSelected("installment");
// },
// ),
],
),
),
);
}
bool _agreeTerms = false;
Widget _termsAndCondition(BuildContext context,
{@required Function(bool) onSelected, @required VoidCallback onInfoClick}) {
return Padding(
padding: const EdgeInsets.all(5),
child: Row(
children: [
InkWell(
child: Icon(
_agreeTerms
? Icons.check_circle
: Icons.radio_button_unchecked_sharp,
size: 20,
color: _agreeTerms ? Colors.green[600] : Colors.grey[400],
),
onTap: () {
onSelected(!_agreeTerms);
},
),
Expanded(
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 8),
child: Texts(
TranslationBase.of(context).pharmacyServiceTermsCondition,
fontWeight: FontWeight.normal,
fontSize: 13,
),
)),
InkWell(
child: Icon(
Icons.info,
size: 20,
color: Colors.grey[600],
),
onTap: () {
onInfoClick();
},
),
],
), ),
); );
} }
Widget _payNow(BuildContext context, {double subtotal, double tax, double total, @required VoidCallback onPayNowClick}) {
bool isPayNowAQctive = (_agreeTerms && (_selectedPaymentMethod != null));
String _subtotal = (subtotal ?? 0.0).toStringAsFixed(2);
String _tax = (tax ?? 0.0).toStringAsFixed(2);
String _total = (total ?? 0).toStringAsFixed(2);
return Padding(
padding: const EdgeInsets.all(5),
child: Container(
child: Row(
crossAxisAlignment: CrossAxisAlignment.end,
children: [
Padding(
padding: const EdgeInsets.all(5),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Texts(
'${TranslationBase.of(context).subtotal}: $_subtotal ${TranslationBase.of(context).sar}',
heightFactor: 1.5,
fontWeight: FontWeight.bold,
color: Colors.grey,
fontSize: 8),
Texts(
'${TranslationBase.of(context).vat}: $_tax ${TranslationBase.of(context).sar}',
heightFactor: 1.5,
fontWeight: FontWeight.bold,
color: Colors.grey,
fontSize: 8),
Padding(
padding: const EdgeInsets.all(3),
child: Container(
height: 0.25,
width: 120,
color: Colors.grey[300],
),
),
Texts(
'${TranslationBase.of(context).total}: $_total ${TranslationBase.of(context).sar}',
heightFactor: 1.5,
fontWeight: FontWeight.bold,
color: Colors.black54,
fontSize: 15)
],
),
),
Expanded(child: Container()),
RaisedButton(
elevation: 0,
child: Texts(
TranslationBase.of(context).payNow,
fontSize: 15,
color: Colors.white,
fontWeight: FontWeight.bold,
),
padding: EdgeInsets.only(top: 5, bottom: 5, left: 0, right: 0),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(5),
side: BorderSide(
color: Theme.of(context).primaryColor, width: 0.5)),
color: Theme.of(context).primaryColor,
onPressed: isPayNowAQctive ? onPayNowClick : null,
),
],
)),
);
}
// -------------------
Widget _cartItemDeleteContainer() { Widget _cartItemDeleteContainer() {
_animationController.duration = Duration(milliseconds: 500); _animationController.duration = Duration(milliseconds: 500);
_animationController.repeat(reverse: true); _animationController.repeat(reverse: true);

@ -1,245 +1,273 @@
import 'package:after_layout/after_layout.dart';
import 'package:carousel_slider/carousel_slider.dart';
import 'package:diplomaticquarterapp/config/config.dart'; import 'package:diplomaticquarterapp/config/config.dart';
import 'package:diplomaticquarterapp/config/shared_pref_kay.dart'; import 'package:diplomaticquarterapp/config/shared_pref_kay.dart';
import 'package:diplomaticquarterapp/core/model/ImagesInfo.dart'; import 'package:diplomaticquarterapp/core/model/ImagesInfo.dart';
import 'package:diplomaticquarterapp/core/model/packages_offers/requests/AddProductToCartRequestModel.dart'; import 'package:diplomaticquarterapp/core/model/packages_offers/requests/AddProductToCartRequestModel.dart';
import 'package:diplomaticquarterapp/core/model/packages_offers/requests/OffersCategoriesRequestModel.dart'; import 'package:diplomaticquarterapp/core/model/packages_offers/requests/OffersCategoriesRequestModel.dart';
import 'package:diplomaticquarterapp/core/model/packages_offers/requests/OffersProductsRequestModel.dart'; import 'package:diplomaticquarterapp/core/model/packages_offers/requests/OffersProductsRequestModel.dart';
import 'package:diplomaticquarterapp/core/model/packages_offers/responses/PackagesCategoriesResponseModel.dart';
import 'package:diplomaticquarterapp/core/model/packages_offers/responses/PackagesResponseModel.dart'; import 'package:diplomaticquarterapp/core/model/packages_offers/responses/PackagesResponseModel.dart';
import 'package:diplomaticquarterapp/core/viewModels/packages_offers/PackagesOffersViewModel.dart'; import 'package:diplomaticquarterapp/core/viewModels/packages_offers/PackagesOffersViewModel.dart';
import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart';
import 'package:diplomaticquarterapp/models/Authentication/authenticated_user.dart'; import 'package:diplomaticquarterapp/models/Authentication/authenticated_user.dart';
import 'package:diplomaticquarterapp/models/Authentication/select_device_imei_res.dart'; import 'package:diplomaticquarterapp/models/Authentication/select_device_imei_res.dart';
import 'package:diplomaticquarterapp/pages/base/base_view.dart'; import 'package:diplomaticquarterapp/pages/base/base_view.dart';
import 'package:diplomaticquarterapp/pages/packages_offers/ClinicOfferAndPackagesPage.dart'; import 'package:diplomaticquarterapp/pages/packages_offers/ClinicOfferAndPackagesPage.dart';
import 'package:diplomaticquarterapp/pages/packages_offers/CreateCustomerDailogPage.dart';
import 'package:diplomaticquarterapp/pages/packages_offers/OfferAndPackageDetailPage.dart';
import 'package:diplomaticquarterapp/pages/packages_offers/OfferAndPackagesCartPage.dart'; import 'package:diplomaticquarterapp/pages/packages_offers/OfferAndPackagesCartPage.dart';
import 'package:diplomaticquarterapp/routes.dart'; import 'package:diplomaticquarterapp/routes.dart';
import 'package:diplomaticquarterapp/services/authentication/auth_provider.dart' as auth; import 'package:diplomaticquarterapp/services/authentication/auth_provider.dart' as auth;
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/uitl/utils.dart' as utils; import 'package:diplomaticquarterapp/uitl/utils.dart' as utils;
import 'package:diplomaticquarterapp/widgets/carousel_indicator/carousel_indicator.dart'; import 'package:diplomaticquarterapp/uitl/utils_new.dart';
import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; import 'package:diplomaticquarterapp/widgets/dialogs/radio_selection_dialog.dart';
import 'package:diplomaticquarterapp/widgets/offers_packages/PackagesOfferCard.dart'; import 'package:diplomaticquarterapp/widgets/offers_packages/PackagesOfferCard.dart';
import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart';
import 'package:flutter/cupertino.dart'; import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart'; import 'package:flutter/rendering.dart';
import 'package:flutter_material_pickers/flutter_material_pickers.dart'; import 'package:flutter_svg/flutter_svg.dart';
import 'package:provider/provider.dart';
dynamic languageID;
class PackagesHomePage extends StatefulWidget { class PackagesHomePage extends StatefulWidget {
final AuthenticatedUser user; final AuthenticatedUser user;
PackagesHomePage(this.user); PackagesHomePage(this.user);
@override @override
_PackagesHomePageState createState() => _PackagesHomePageState(); _PackagesHomePageState createState() => _PackagesHomePageState();
} }
class _PackagesHomePageState extends State<PackagesHomePage> with AfterLayoutMixin<PackagesHomePage>{ class _PackagesHomePageState extends State<PackagesHomePage> {
getLanguageID() async { ProjectViewModel projectViewModel;
languageID = await sharedPref.getString(APP_LANGUAGE);
}
@override @override
void initState() { void initState() {
super.initState(); super.initState();
getLanguageID(); WidgetsBinding.instance.addPostFrameCallback((timeStamp) {
} viewModel.service.patientUser = widget.user;
viewModel.service.loadOffersPackagesDataForMainPage(
@override context: context,
void afterFirstLayout(BuildContext context) async{ completion: () {
viewModel.service.patientUser = widget.user; setState(() {});
viewModel.service.loadOffersPackagesDataForMainPage(context: context, completion: (){ });
setState((){});
}); });
} }
// Controllers // Controllers
var _searchTextController = TextEditingController(); var _searchTextController = TextEditingController();
var _filterTextController = TextEditingController();
var _carouselController = CarouselController();
int carouselIndicatorIndex = 0;
CarouselSlider _bannerCarousel;
TextField _textFieldSearch;
TextField _textFieldFilterSelection;
ListView _listViewLatestOffers; ListView _listViewLatestOffers;
ListView _listViewBestSeller; ListView _listViewBestSeller;
PackagesViewModel viewModel; PackagesViewModel viewModel;
onCartClick(){ onCartClick() {
if (viewModel.service.customer == null){ if (viewModel.service.customer == null) {
utils.Utils.showErrorToast("Cart is empty for your current session"); utils.Utils.showErrorToast("Cart is empty for your current session");
return; return;
} }
Navigator.of(context).push( Navigator.of(context).push(MaterialPageRoute(builder: (BuildContext context) => PackagesCartPage()));
MaterialPageRoute(
builder: (BuildContext context) => PackagesCartPage()
)
);
} }
onProductCartClick(PackagesResponseModel product) async { onProductCartClick(PackagesResponseModel product) async {
if(viewModel.service.customer == null) { if (viewModel.service.customer == null) {
// viewModel.service.customer = await CreateCustomerDialogPage(context: context).show(); // viewModel.service.customer = await CreateCustomerDialogPage(context: context).show();
loginCheck(context); loginCheck(context);
} }
if(viewModel.service.customer != null) { if (viewModel.service.customer != null) {
var request = AddProductToCartRequestModel(product_id: product.id, customer_id: viewModel.service.customer.id); var request = AddProductToCartRequestModel(product_id: product.id, customer_id: viewModel.service.customer.id);
await viewModel.service.addProductToCart(request, context: context).then((response){ await viewModel.service.addProductToCart(request, context: context).then((response) {}).catchError((error) {
// appScaffold.appBar.badgeUpdater(viewModel.service.cartItemCount);
}).catchError((error) {
utils.Utils.showErrorToast(error.toString()); utils.Utils.showErrorToast(error.toString());
}); });
} }
} }
AppScaffold appScaffold; AppScaffold appScaffold;
PackagesCategoriesResponseModel selectedClinic;
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
projectViewModel = Provider.of(context);
return BaseView<PackagesViewModel>( return BaseView<PackagesViewModel>(
allowAny: true, allowAny: true,
onModelReady: (model) => viewModel = model, onModelReady: (model) => viewModel = model,
builder: (_, model, wi){ builder: (_, model, wi) {
return return appScaffold = AppScaffold(
appScaffold = description: TranslationBase.of(context).offerAndPackagesDetails,
AppScaffold( imagesInfo: [ImagesInfo(imageAr: 'https://hmgwebservices.com/Images/MobileApp/CMC/ar/0.png', imageEn: 'https://hmgwebservices.com/Images/MobileApp/CMC/en/0.png')],
description: TranslationBase.of(context).offerAndPackagesDetails, appBarTitle: TranslationBase.of(context).offerAndPackages,
imagesInfo: [ImagesInfo(imageAr: 'https://hmgwebservices.com/Images/MobileApp/CMC/ar/0.png', imageEn: 'https://hmgwebservices.com/Images/MobileApp/CMC/en/0.png')], isShowAppBar: true,
appBarTitle: TranslationBase.of(context).offerAndPackages, isPharmacy: false,
isShowAppBar: true, showPharmacyCart: false,
isPharmacy: false, isOfferPackages: true,
showPharmacyCart: false, showOfferPackagesCart: false,
showHomeAppBarIcon: false, isShowDecPage: false,
isOfferPackages: true, showNewAppBar: true,
showOfferPackagesCart: true, showNewAppBarTitle: true,
isShowDecPage: false, body: SingleChildScrollView(
body: ListView( child: Column(
children: [
Padding(
padding: projectViewModel.isArabic ? const EdgeInsets.only(top: 21, right: 21, bottom: 21) : const EdgeInsets.only(top: 21, left: 21, bottom: 21),
child: Column(
children: [ children: [
inputWidget(TranslationBase.of(context).search, "", _searchTextController, isInputTypeNum: false),
// Top Banner Carousel SizedBox(
AspectRatio( height: 10,
aspectRatio: 2.2/1,
child: bannerCarousel()
), ),
InkWell(
Center( onTap: () => showClinicSelectionList(),
child: CarouselIndicator( child: Container(
activeColor: Theme.of(context).appBarTheme.color, padding: EdgeInsets.all(12),
color: Colors.grey[300], margin: projectViewModel.isArabic ? const EdgeInsets.only(left: 21) : const EdgeInsets.only(right: 21),
cornerRadius: 15, width: double.infinity,
width: 15, height: 15, height: 65,
count: _bannerCarousel.itemCount, decoration: BoxDecoration(
index: carouselIndicatorIndex, borderRadius: BorderRadius.circular(12),
onClick: (index){ border: Border.all(
debugPrint('onClick at ${index}'); color: Color(0xffefefef),
width: 1,
),
color: Colors.white),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
selectedClinic != null ? selectedClinic.name : TranslationBase.of(context).browseOffers,
style: TextStyle(
fontSize: 14,
fontWeight: FontWeight.w600,
letterSpacing: -0.46,
),
),
Icon(Icons.arrow_drop_down),
],
),
),
),
SizedBox(
height: 20,
),
Container(
width: double.infinity,
height: MediaQuery.of(context).size.width * 0.8,
child: ListView.separated(
scrollDirection: Axis.horizontal,
shrinkWrap: true,
itemCount: viewModel.bestSellerList.length,
separatorBuilder: (context, index) {
return mWidth(9.0);
},
itemBuilder: (BuildContext context, int index) {
return PackagesItemCard(
itemModel: viewModel.bestSellerList[index],
onCartClick: onProductCartClick,
);
}, },
), ),
), ),
SizedBox(
SizedBox(height: 10,), height: 21,
),
Padding( // // Best Seller Horizontal Scrollable List
padding: const EdgeInsets.all(15), Container(
child: Column( width: double.infinity,
children: [ height: MediaQuery.of(context).size.width * 0.8,
// Search Textfield child: ListView.separated(
searchTextField(), scrollDirection: Axis.horizontal,
shrinkWrap: true,
SizedBox(height: 10,), itemCount: viewModel.latestOffersList.length,
separatorBuilder: (context, index) {
// Filter Selection return mWidth(9.0);
filterOptionSelection(), },
itemBuilder: (BuildContext context, int index) {
SizedBox(height: 20,), return PackagesItemCard(
itemModel: viewModel.latestOffersList[index],
// Horizontal Scrollable Cards onCartClick: onProductCartClick,
Texts( );
"Latest offers", },
fontWeight: FontWeight.bold, ),
color: Colors.black87,
fontSize: 20
),
// Latest Offers Horizontal Scrollable List
AspectRatio(
aspectRatio: 1.3/1,
child: LayoutBuilder(builder: (context, constraints){
double itemContentPadding = 10;
double itemWidth = (constraints.maxWidth/2) - (itemContentPadding*2);
return latestOfferListView(itemWidth: itemWidth, itemContentPadding: itemContentPadding);
}),
),
SizedBox(height: 10,),
Texts(
"Best sellers",
fontWeight: FontWeight.bold,
color: Colors.black87,
fontSize: 20
),
// Best Seller Horizontal Scrollable List
AspectRatio(
aspectRatio: 1.3/1,
child: LayoutBuilder(builder: (context, constraints){
double itemContentPadding = 10; // 10 is content padding in each item
double itemWidth = (constraints.maxWidth/2) - (itemContentPadding*2 /* 2 = LeftRight */);
return bestSellerListView(itemWidth: itemWidth, itemContentPadding: itemContentPadding);
}),
)
],),
), ),
], ],
), ),
),
SizedBox(
height: 50.0,
) )
.setOnAppBarCartClick(onCartClick); ],
} ),
),
bottomSheet: Container(
color: Colors.white,
padding: const EdgeInsets.all(12.0),
child: SizedBox(
height: 43,
width: double.infinity,
child: FlatButton(
onPressed: () {
onCartClick();
},
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Padding(
padding: const EdgeInsets.only(left: 8.0, right: 8.0),
child: SvgPicture.asset("assets/images/new/cart.svg"),
// child: Icon(
// Icons.add_shopping_cart_rounded,
// size: 30.0,
// color: Colors.white,
// ),
),
Container(
child: Text(
TranslationBase.of(context).myCart,
textAlign: TextAlign.center,
style: TextStyle(fontSize: 16, fontWeight: FontWeight.w600, color: Colors.white, letterSpacing: -0.48),
),
),
],
),
color: const Color(0xffD02127),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(6),
),
),
),
),
);
},
); );
} }
showClinicSelectionList() async { showClinicSelectionList() async {
var clinics = viewModel.service.categoryList; var clinics = viewModel.service.categoryList;
if(clinics.isEmpty) { if (clinics.isEmpty) {
GifLoaderDialogUtils.showMyDialog(context); GifLoaderDialogUtils.showMyDialog(context);
clinics = await viewModel.service.getAllCategories(OffersCategoriesRequestModel()); clinics = await viewModel.service.getAllCategories(OffersCategoriesRequestModel());
GifLoaderDialogUtils.hideDialog(context); GifLoaderDialogUtils.hideDialog(context);
} }
List<String> options = clinics.map((e) => e.toString()).toList(); List<RadioSelectionDialogModel> list = [
for (int i = 0; i < clinics.length; i++) RadioSelectionDialogModel(clinics[i].name, i),
showMaterialSelectionPicker( ];
showDialog(
context: context, context: context,
title: "Select Clinic", child: RadioSelectionDialog(
items: options, listData: list,
selectedItem: options.first, selectedIndex: 0,
onChanged: (value) async { isScrollable: true,
var selectedClinic = clinics.firstWhere((element) => element.toString() == value); onValueSelected: (index) async {
var clinicProducts = await viewModel.service.getAllProducts(request: OffersProductsRequestModel(categoryId: selectedClinic.id), context: context, showLoading: true); selectedClinic = clinics[index];
if(clinicProducts.isNotEmpty) var clinicProducts = await viewModel.service.getAllProducts(request: OffersProductsRequestModel(categoryId: selectedClinic.id), context: context, showLoading: true);
Navigator.of(context).push( if (clinicProducts.isNotEmpty)
MaterialPageRoute( Navigator.of(context).push(MaterialPageRoute(builder: (BuildContext context) => ClinicPackagesPage(products: clinicProducts)));
builder: (BuildContext context) => ClinicPackagesPage(products: clinicProducts) else
) utils.Utils.showErrorToast("No offers available for this clinic");
); setState(() {});
else },
utils.Utils.showErrorToast("No offers available for this clinic"); ),
},
); );
} }
@ -247,182 +275,48 @@ class _PackagesHomePageState extends State<PackagesHomePage> with AfterLayoutMix
// Main Widgets of Page // Main Widgets of Page
//---------------------------------- //----------------------------------
CarouselSlider bannerCarousel(){ Widget latestOfferListView({@required double itemWidth, @required double itemContentPadding}) {
_bannerCarousel = CarouselSlider.builder( return _listViewLatestOffers = ListView.separated(
carouselController: _carouselController, scrollDirection: Axis.horizontal,
itemCount: 10, shrinkWrap: true,
itemBuilder: (BuildContext context, int itemIndex) { itemCount: viewModel.bestSellerList.length,
return Padding( itemBuilder: (BuildContext context, int index) {
padding: const EdgeInsets.only(top: 10, bottom: 10, left: 15, right: 15), return PackagesItemCard(
child: FractionallySizedBox( itemWidth: itemWidth,
widthFactor: 1, itemContentPadding: itemContentPadding,
heightFactor: 1, itemModel: viewModel.bestSellerList[index],
child: utils.applyShadow( onCartClick: onProductCartClick,
spreadRadius: 1,
blurRadius: 5,
child: InkWell(
child: ClipRRect(
borderRadius: BorderRadius.circular(10),
child: utils.Utils.loadNetworkImage(url: "https://wallpaperaccess.com/full/30103.jpg",)
),
onTap: (){
Navigator.of(context).push(
MaterialPageRoute(
builder: (BuildContext context) => OfferAndPackagesDetail(model: "",)
)
);
},
)
),
),
); );
}, },
options: CarouselOptions( separatorBuilder: separator,
autoPlayInterval: Duration(milliseconds: 3500),
enlargeStrategy: CenterPageEnlargeStrategy.scale,
enlargeCenterPage: true,
autoPlay: false,
autoPlayCurve: Curves.fastOutSlowIn,
enableInfiniteScroll: true,
autoPlayAnimationDuration: Duration(milliseconds: 1500),
viewportFraction: 1,
onPageChanged: (page, reason){
setState(() {
carouselIndicatorIndex = page;
});
},
),
); );
return _bannerCarousel;
}
TextField searchTextField(){
return _textFieldSearch =
TextField(
controller: _searchTextController,
decoration: InputDecoration(
contentPadding: EdgeInsets.only(top: 0.0, bottom: 0.0, left: 10, right: 10),
enabledBorder: OutlineInputBorder(
borderSide: BorderSide( width: 0.5, color: Colors.grey),
borderRadius: const BorderRadius.all(
const Radius.circular(10.0),
),
),
focusedBorder: OutlineInputBorder(
borderSide: BorderSide( width: 1, color: Colors.grey),
borderRadius: const BorderRadius.all(
const Radius.circular(10.0),
),
),
filled: true,
fillColor: Colors.white,
hintText: "Search",
hintStyle: TextStyle(color: Colors.grey[350], fontWeight: FontWeight.bold),
suffixIcon: IconButton(
onPressed: (){
// viewModel.search(text: _searchTextController.text);
},
icon: Icon(Icons.search_rounded, size: 35,),
),
),
);
} }
Widget filterOptionSelection(){ Widget bestSellerListView({@required double itemWidth, @required double itemContentPadding}) {
_textFieldFilterSelection = return _listViewLatestOffers = ListView.separated(
TextField( scrollDirection: Axis.horizontal,
enabled: false, itemCount: viewModel.bestSellerList.length,
controller: _searchTextController, itemBuilder: (BuildContext context, int index) {
decoration: InputDecoration( return PackagesItemCard(
contentPadding: EdgeInsets.only(top: 0.0, bottom: 0.0, left: 10, right: 10), itemWidth: itemWidth,
border: OutlineInputBorder( itemContentPadding: itemContentPadding,
borderSide: BorderSide(color: Colors.grey, width: 1), itemModel: viewModel.bestSellerList[index],
borderRadius: const BorderRadius.all( onCartClick: onProductCartClick,
const Radius.circular(10.0),
),
),
disabledBorder: OutlineInputBorder(
borderSide: BorderSide( width: 0.5, color: Colors.grey),
borderRadius: const BorderRadius.all(
const Radius.circular(10.0),
),
),
focusedBorder: OutlineInputBorder(
borderRadius: const BorderRadius.all(
const Radius.circular(10.0),
),
),
filled: true,
fillColor: Colors.white,
hintText: "Browse offers by Clinic",
hintStyle: TextStyle(color: Colors.grey[350], fontWeight: FontWeight.bold),
suffixIcon: IconButton(
onPressed: (){
showClinicSelectionList();
},
icon: Icon(Icons.keyboard_arrow_down_rounded, size: 35, color: Colors.grey,),
),
),
); );
return InkWell(
child: _textFieldFilterSelection,
onTap: (){
showClinicSelectionList();
}, },
separatorBuilder: separator,
); );
} }
Widget latestOfferListView({@required double itemWidth, @required double itemContentPadding}){ Widget separator(BuildContext context, int index) {
return _listViewLatestOffers =
ListView.separated(
scrollDirection: Axis.horizontal,
itemCount: viewModel.bestSellerList.length,
itemBuilder: (BuildContext context, int index) {
return PackagesItemCard(itemWidth: itemWidth, itemContentPadding: itemContentPadding, itemModel: viewModel.bestSellerList[index], onCartClick: onProductCartClick,);
},
separatorBuilder: separator,
);
}
Widget bestSellerListView({@required double itemWidth, @required double itemContentPadding}){
return _listViewLatestOffers =
ListView.separated(
scrollDirection: Axis.horizontal,
itemCount: viewModel.bestSellerList.length,
itemBuilder: (BuildContext context, int index) {
return PackagesItemCard(itemWidth: itemWidth, itemContentPadding: itemContentPadding, itemModel: viewModel.bestSellerList[index], onCartClick: onProductCartClick,);
},
separatorBuilder: separator,
);
}
Widget separator(BuildContext context, int index){
return Container( return Container(
width: 1, width: 1,
decoration: BoxDecoration( decoration: BoxDecoration(
gradient: LinearGradient( gradient:
begin: Alignment(-1.0, -2.0), LinearGradient(begin: Alignment(-1.0, -2.0), end: Alignment(1.0, 4.0), colors: [Colors.grey, Colors.grey[100], Colors.grey[200], Colors.grey[300], Colors.grey[400], Colors.grey[500]])),
end: Alignment(1.0, 4.0),
colors: [
Colors.grey,
Colors.grey[100],
Colors.grey[200],
Colors.grey[300],
Colors.grey[400],
Colors.grey[500]
]
)),
); );
} }
loginCheck(context) async { loginCheck(context) async {
var data = await sharedPref.getObject(IMEI_USER_DATA); var data = await sharedPref.getObject(IMEI_USER_DATA);
sharedPref.remove(REGISTER_DATA_FOR_LOGIIN); sharedPref.remove(REGISTER_DATA_FOR_LOGIIN);
@ -449,4 +343,76 @@ class _PackagesHomePageState extends State<PackagesHomePage> with AfterLayoutMix
}); });
} }
} }
Widget inputWidget(String _labelText, String _hintText, TextEditingController _controller,
{VoidCallback suffixTap, bool isEnable = true, bool hasSelection = false, int lines, bool isInputTypeNum = false}) {
return Container(
padding: EdgeInsets.only(left: 16, right: 16, bottom: 15, top: 15),
margin: projectViewModel.isArabic ? const EdgeInsets.only(left: 21) : const EdgeInsets.only(right: 21),
alignment: Alignment.center,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(15),
color: Colors.white,
border: Border.all(
color: Color(0xffefefef),
width: 1,
),
),
child: InkWell(
onTap: hasSelection ? () {} : null,
child: Row(
children: [
Expanded(
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
_labelText,
style: TextStyle(
fontSize: 11,
fontWeight: FontWeight.w600,
color: Color(0xff2B353E),
letterSpacing: -0.44,
),
),
TextField(
enabled: isEnable,
scrollPadding: EdgeInsets.zero,
keyboardType: isInputTypeNum ? TextInputType.number : TextInputType.text,
controller: _controller,
maxLines: lines,
onChanged: (value) => {setState(() {})},
style: TextStyle(
fontSize: 14,
height: 21 / 14,
fontWeight: FontWeight.w400,
color: Color(0xff2B353E),
letterSpacing: -0.44,
),
decoration: InputDecoration(
isDense: true,
hintText: _hintText,
hintStyle: TextStyle(
fontSize: 14,
height: 21 / 14,
fontWeight: FontWeight.w400,
color: Color(0xff575757),
letterSpacing: -0.56,
),
contentPadding: EdgeInsets.zero,
border: InputBorder.none,
focusedBorder: InputBorder.none,
enabledBorder: InputBorder.none,
),
),
],
),
),
Icon(Icons.search_outlined),
],
),
),
);
}
} }

@ -22,6 +22,7 @@ import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart';
import 'package:flutter/cupertino.dart'; import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
import 'package:rating_bar/rating_bar.dart';
import 'base/base_view.dart'; import 'base/base_view.dart';
@ -714,11 +715,21 @@ class _ParentCategorisePageState extends State<ParentCategorisePage> {
), ),
Row( Row(
children: [ children: [
StarRating( // StarRating(
totalAverage: model.parentProducts[index].approvedRatingSum > 0 // totalAverage: model.parentProducts[index].approvedRatingSum > 0
? (model.parentProducts[index].approvedRatingSum.toDouble() / model.parentProducts[index].approvedRatingSum.toDouble()).toDouble() // ? (model.parentProducts[index].approvedRatingSum.toDouble() / model.parentProducts[index].approvedRatingSum.toDouble()).toDouble()
: 0, // : 0,
forceStars: true), // forceStars: true),
RatingBar.readOnly(
initialRating: model.parentProducts[index].approvedRatingSum.toDouble(),
size: 15.0,
filledColor: Colors.yellow[700],
emptyColor: Colors.grey[500],
isHalfAllowed: true,
halfFilledIcon: Icons.star_half,
filledIcon: Icons.star,
emptyIcon: Icons.star,
),
Texts( Texts(
"(${model.parentProducts[index].approvedTotalReviews})", "(${model.parentProducts[index].approvedTotalReviews})",
regular: true, regular: true,
@ -838,11 +849,21 @@ class _ParentCategorisePageState extends State<ParentCategorisePage> {
), ),
Row( Row(
children: [ children: [
StarRating( // StarRating(
totalAverage: model.parentProducts[index].approvedRatingSum > 0 // totalAverage: model.parentProducts[index].approvedRatingSum > 0
? (model.parentProducts[index].approvedRatingSum.toDouble() / model.parentProducts[index].approvedRatingSum.toDouble()).toDouble() // ? (model.parentProducts[index].approvedRatingSum.toDouble() / model.parentProducts[index].approvedRatingSum.toDouble()).toDouble()
: 0, // : 0,
forceStars: true), // forceStars: true),
RatingBar.readOnly(
initialRating: model.parentProducts[index].approvedRatingSum.toDouble(),
size: 15.0,
filledColor: Colors.yellow[700],
emptyColor: Colors.grey[500],
isHalfAllowed: true,
halfFilledIcon: Icons.star_half,
filledIcon: Icons.star,
emptyIcon: Icons.star,
),
Texts( Texts(
"(${model.parentProducts[index].approvedTotalReviews})", "(${model.parentProducts[index].approvedTotalReviews})",
regular: true, regular: true,

@ -68,7 +68,7 @@ class _FooterWidgetState extends State<FooterWidget> {
Padding( Padding(
padding: const EdgeInsets.all(8.0), padding: const EdgeInsets.all(8.0),
child: Text( child: Text(
"Quantity", TranslationBase.of(context).quantity,
style: TextStyle(fontSize: 15, fontWeight: FontWeight.bold), style: TextStyle(fontSize: 15, fontWeight: FontWeight.bold),
), ),
), ),
@ -157,17 +157,19 @@ class _FooterWidgetState extends State<FooterWidget> {
), ),
], ],
), ),
onPressed: () { onPressed: widget.isAvailable && !widget.item.isRx
setState(() { ? () {
if (showUI) { setState(() {
quantityUI = 80; if (showUI) {
showUI = false; quantityUI = 80;
} else { showUI = false;
quantityUI = 160; } else {
showUI = true; quantityUI = 160;
} showUI = true;
}); }
}, });
}
: null,
), ),
), ),
SizedBox( SizedBox(
@ -207,20 +209,20 @@ class _FooterWidgetState extends State<FooterWidget> {
); );
} else { } else {
await widget.addToShoppingCartFunction(quantity: widget.quantity, itemID: widget.item.id, model: widget.model); await widget.addToShoppingCartFunction(quantity: widget.quantity, itemID: widget.item.id, model: widget.model);
Navigator.of(context).pushNamed( // Navigator.of(context).pushNamed(
CART_ORDER_PAGE, // CART_ORDER_PAGE,
);
// Navigator.push(
// context,
// FadePage(page: CartOrderPage()),
// ); // );
Navigator.push(
context,
FadePage(page: CartOrderPage()),
);
} }
}, },
fontWeight: FontWeight.w600, fontWeight: FontWeight.w600,
borderColor: Colors.grey[800], borderColor: Colors.grey[800],
borderRadius: 3, borderRadius: 3,
disableColor: Colors.grey[700], disableColor: Colors.grey[700],
color: !widget.isAvailable && widget.quantity > 0 || widget.quantity > widget.quantityLimit || widget.item.rxMessage != null ? Colors.grey : Colors.grey[800], color: !widget.isAvailable && widget.quantity > 0 || widget.quantity > widget.quantityLimit || widget.item.isRx ? Colors.grey : Colors.grey[800],
), ),
), ),
], ],

@ -87,6 +87,9 @@ class __ProductDetailPageState extends State<ProductDetailPage> {
Widget build(BuildContext context) { Widget build(BuildContext context) {
return BaseView<ProductDetailViewModel>( return BaseView<ProductDetailViewModel>(
allowAny: true, allowAny: true,
onModelReady: (model) {
model.getProductReviewsData(widget.product.id);
},
builder: (_, model, wi) => AppScaffold( builder: (_, model, wi) => AppScaffold(
appBarTitle: TranslationBase.of(context).productDetails, appBarTitle: TranslationBase.of(context).productDetails,
isShowAppBar: true, isShowAppBar: true,
@ -146,6 +149,7 @@ class __ProductDetailPageState extends State<ProductDetailPage> {
notifyMeWhenAvailable(itemId: itemId, customerId: customerId, model: model); notifyMeWhenAvailable(itemId: itemId, customerId: customerId, model: model);
}, },
isInWishList: isInWishList, isInWishList: isInWishList,
isStockAvailable: model.isStockAvailable,
), ),
), ),
SizedBox( SizedBox(
@ -302,10 +306,10 @@ class __ProductDetailPageState extends State<ProductDetailPage> {
), ),
), ),
bottomSheet: FooterWidget( bottomSheet: FooterWidget(
widget.product.stockAvailability != 'Out of stock', model.isStockAvailable,
widget.product.orderMaximumQuantity, widget.product.orderMaximumQuantity,
widget.product.orderMinimumQuantity, widget.product.orderMinimumQuantity,
widget.product.stockQuantity, model.stockQuantity,
widget.product, widget.product,
quantity: quantity, quantity: quantity,
isOverQuantity: isOverQuantity, isOverQuantity: isOverQuantity,

@ -1,7 +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/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/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:flutter/material.dart'; import 'package:flutter/material.dart';
@ -20,16 +19,12 @@ class ProductNameAndPrice extends StatefulWidget {
final Function notifyMeWhenAvailable; final Function notifyMeWhenAvailable;
final Function addToWishlistFunction; final Function addToWishlistFunction;
final Function deleteFromWishlistFunction; final Function deleteFromWishlistFunction;
final bool isStockAvailable;
AuthenticatedUserObject authenticatedUserObject = AuthenticatedUserObject authenticatedUserObject = locator<AuthenticatedUserObject>();
locator<AuthenticatedUserObject>();
ProductNameAndPrice(this.context, this.item, ProductNameAndPrice(this.context, this.item,
{this.customerId, {this.customerId, this.isInWishList, this.notifyMeWhenAvailable, this.addToWishlistFunction, this.deleteFromWishlistFunction, @required this.isStockAvailable});
this.isInWishList,
this.notifyMeWhenAvailable,
this.addToWishlistFunction,
this.deleteFromWishlistFunction});
@override @override
_ProductNameAndPriceState createState() => _ProductNameAndPriceState(); _ProductNameAndPriceState createState() => _ProductNameAndPriceState();
@ -51,25 +46,18 @@ class _ProductNameAndPriceState extends State<ProductNameAndPrice> {
child: Row( child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween, mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [ children: [
Texts(widget.item.price.toString() + " " + "SR", Texts(widget.item.price.toString() + " " + TranslationBase.of(context).sar, fontWeight: FontWeight.bold, fontSize: 20),
fontWeight: FontWeight.bold, fontSize: 20),
Texts( Texts(
projectViewModel.isArabic projectViewModel.isArabic ? widget.item.stockAvailabilityn : widget.item.stockAvailability,
? widget.item.stockAvailabilityn
: widget.item.stockAvailability,
fontWeight: FontWeight.bold, fontWeight: FontWeight.bold,
fontSize: 15, fontSize: 15,
color: widget.item.stockAvailability == 'Out of stock' color: widget.isStockAvailable ? Colors.green : Colors.red,
? Colors.red
: Colors.green,
), ),
// SizedBox(width: 20), // SizedBox(width: 20),
if (widget.authenticatedUserObject.isLogin) if (widget.authenticatedUserObject.isLogin)
widget.item.stockAvailability == 'Out of stock' && widget.isStockAvailable && widget.customerId != null
widget.customerId != null
? InkWell( ? InkWell(
onTap: () => widget.notifyMeWhenAvailable( onTap: () => widget.notifyMeWhenAvailable(context, widget.item.id),
context, widget.item.id),
child: Row(children: [ child: Row(children: [
Texts( Texts(
TranslationBase.of(context).notifyMe, TranslationBase.of(context).notifyMe,
@ -85,23 +73,15 @@ class _ProductNameAndPriceState extends State<ProductNameAndPrice> {
]), ]),
) )
: IconWithBg( : IconWithBg(
icon: !widget.isInWishList icon: !widget.isInWishList ? Icons.favorite_border : Icons.favorite,
? Icons.favorite_border color: !widget.isInWishList ? Colors.white : Colors.red[800],
: Icons.favorite,
color: !widget.isInWishList
? Colors.white
: Colors.red[800],
onPress: () async { onPress: () async {
{ {
if (widget.customerId != null) { if (widget.customerId != null) {
if (!widget.isInWishList) { if (!widget.isInWishList) {
await widget.addToWishlistFunction(widget.item.id);
await widget
.addToWishlistFunction(widget.item.id);
} else { } else {
await widget await widget.deleteFromWishlistFunction(widget.item.id);
.deleteFromWishlistFunction(widget.item.id);
} }
} else { } else {
return; return;
@ -118,13 +98,9 @@ class _ProductNameAndPriceState extends State<ProductNameAndPrice> {
child: Container( child: Container(
margin: EdgeInsets.only(left: 5), margin: EdgeInsets.only(left: 5),
child: Align( child: Align(
alignment: projectViewModel.isArabic alignment: projectViewModel.isArabic ? Alignment.topRight : Alignment.topLeft,
? Alignment.topRight
: Alignment.topLeft,
child: Text( child: Text(
projectViewModel.isArabic projectViewModel.isArabic ? widget.item.namen : widget.item.name,
? widget.item.namen
: widget.item.name,
style: TextStyle(fontWeight: FontWeight.bold, fontSize: 15), style: TextStyle(fontWeight: FontWeight.bold, fontSize: 15),
), ),
), ),
@ -140,8 +116,7 @@ class _ProductNameAndPriceState extends State<ProductNameAndPrice> {
child: Row( child: Row(
children: [ children: [
RatingBar.readOnly( RatingBar.readOnly(
initialRating: double.parse( initialRating: double.parse(widget.item.approvedRatingSum.toString()),
widget.item.approvedRatingSum.toString()),
size: 15.0, size: 15.0,
filledColor: Colors.yellow[700], filledColor: Colors.yellow[700],
emptyColor: Colors.grey[400], emptyColor: Colors.grey[400],
@ -172,19 +147,9 @@ class _ProductNameAndPriceState extends State<ProductNameAndPrice> {
Row( Row(
children: [ children: [
Text( Text(
projectViewModel.isArabic projectViewModel.isArabic ? widget.item.rxMessagen.toString() : widget.item.rxMessage.toString(),
? widget.item.rxMessagen.toString()
: widget.item.rxMessage.toString(),
style: TextStyle(color: Colors.red, fontSize: 10), style: TextStyle(color: Colors.red, fontSize: 10),
), ),
SizedBox(
width: 5,
),
Icon(
FontAwesomeIcons.questionCircle,
color: Colors.red,
size: 15.0,
)
], ],
) )
], ],

@ -201,7 +201,7 @@ class _ProductReviewPageState extends State<ProductReviewPage> {
? () { ? () {
model model
.makeReview( .makeReview(
widget.product, ratingValue, reviewText) widget.product, ratingValue, reviewText, context)
.then((value) { .then((value) {
setState(() { setState(() {
finishReview = true; finishReview = true;

@ -17,6 +17,7 @@ import 'package:diplomaticquarterapp/widgets/others/entity_checkbox_list.dart';
import 'package:diplomaticquarterapp/widgets/others/network_base_view.dart'; import 'package:diplomaticquarterapp/widgets/others/network_base_view.dart';
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 'package:rating_bar/rating_bar.dart';
import 'base/base_view.dart'; import 'base/base_view.dart';
import 'final_products_page.dart'; import 'final_products_page.dart';
@ -641,11 +642,21 @@ class _SubCategorisePageState extends State<SubCategorisePage> {
), ),
Row( Row(
children: [ children: [
StarRating( // StarRating(
totalAverage: model.subProducts[index].approvedRatingSum > 0 // totalAverage: model.subProducts[index].approvedRatingSum > 0
? (model.subProducts[index].approvedRatingSum.toDouble() / model.subProducts[index].approvedRatingSum.toDouble()).toDouble() // ? (model.subProducts[index].approvedRatingSum.toDouble() / model.subProducts[index].approvedRatingSum.toDouble()).toDouble()
: 0, // : 0,
forceStars: true), // forceStars: true),
RatingBar.readOnly(
initialRating: model.subProducts[index].approvedRatingSum.toDouble(),
size: 15.0,
filledColor: Colors.yellow[700],
emptyColor: Colors.grey[500],
isHalfAllowed: true,
halfFilledIcon: Icons.star_half,
filledIcon: Icons.star,
emptyIcon: Icons.star,
),
Texts( Texts(
"(${model.subProducts[index].approvedTotalReviews})", "(${model.subProducts[index].approvedTotalReviews})",
regular: true, regular: true,
@ -766,11 +777,21 @@ class _SubCategorisePageState extends State<SubCategorisePage> {
), ),
Row( Row(
children: [ children: [
StarRating( // StarRating(
totalAverage: model.subProducts[index].approvedRatingSum > 0 // totalAverage: model.subProducts[index].approvedRatingSum > 0
? (model.subProducts[index].approvedRatingSum.toDouble() / model.subProducts[index].approvedRatingSum.toDouble()).toDouble() // ? (model.subProducts[index].approvedRatingSum.toDouble() / model.subProducts[index].approvedRatingSum.toDouble()).toDouble()
: 0, // : 0,
forceStars: true), // forceStars: true),
RatingBar.readOnly(
initialRating: model.subProducts[index].approvedRatingSum.toDouble(),
size: 15.0,
filledColor: Colors.yellow[700],
emptyColor: Colors.grey[500],
isHalfAllowed: true,
halfFilledIcon: Icons.star_half,
filledIcon: Icons.star,
emptyIcon: Icons.star,
),
Texts( Texts(
"(${model.subProducts[index].approvedTotalReviews})", "(${model.subProducts[index].approvedTotalReviews})",
regular: true, regular: true,

@ -15,36 +15,53 @@ import 'package:diplomaticquarterapp/uitl/app_toast.dart';
class ProductDetailService extends BaseService { class ProductDetailService extends BaseService {
bool isLogin = false; bool isLogin = false;
num _stockQuantity;
num get stockQuantity => _stockQuantity;
String _stockAvailability;
String get stockAvailability => _stockAvailability;
bool _isStockAvailable;
bool get isStockAvailable => _isStockAvailable;
List<ProductDetail> _productDetailList = List(); List<ProductDetail> _productDetailList = List();
List<ProductDetail> get productDetailList => _productDetailList; List<ProductDetail> get productDetailList => _productDetailList;
List<LocationModel> _productLocationList = List(); List<LocationModel> _productLocationList = List();
List<LocationModel> get productLocationList => _productLocationList; List<LocationModel> get productLocationList => _productLocationList;
List<Wishlist> _addToCartModel = List(); List<Wishlist> _addToCartModel = List();
List<Wishlist> get addToCartModel => _addToCartModel; List<Wishlist> get addToCartModel => _addToCartModel;
List<Wishlist> _wishListProducts = List(); List<Wishlist> _wishListProducts = List();
List<Wishlist> get wishListProducts => _wishListProducts; List<Wishlist> get wishListProducts => _wishListProducts;
List<SpecificationModel> _productSpecification = List(); List<SpecificationModel> _productSpecification = List();
List<SpecificationModel> get productSpecification => _productSpecification;
List<SpecificationModel> get productSpecification => _productSpecification;
Future getProductReviews(productID) async { Future getProductReviews(productID) async {
hasError = false; hasError = false;
await baseAppClient.getPharmacy(GET_PRODUCT_DETAIL+productID+"?fields=reviews", await baseAppClient.getPharmacy(GET_PRODUCT_DETAIL + productID + "?fields=reviews,stock_quantity,stock_availability,IsStockAvailable", onSuccess: (dynamic response, int statusCode) {
onSuccess: (dynamic response, int statusCode) { _productDetailList.clear();
_productDetailList.clear(); response['products'].forEach((item) {
response['products'].forEach((item) { _productDetailList.add(ProductDetail.fromJson(item));
_productDetailList.add(ProductDetail.fromJson(item)); print(response);
print(response); });
}); _stockQuantity = response['products'][0]['stock_quantity'];
}, onFailure: (String error, int statusCode) { _stockAvailability = response['products'][0]['stock_availability'];
hasError = true; _isStockAvailable = response['products'][0]['IsStockAvailable'];
super.error = error; }, onFailure: (String error, int statusCode) {
}); hasError = true;
super.error = error;
});
} }
Future getProductAvailabiltyDetail() async { Future getProductAvailabiltyDetail() async {
@ -52,29 +69,28 @@ class ProductDetailService extends BaseService {
Map<String, dynamic> request; Map<String, dynamic> request;
request = { request = {
"Channel": 3, // "Channel": 3,
"DeviceTypeID": 2, // "DeviceTypeID": 2,
"IPAdress": "10.20.10.20", // "IPAdress": "10.20.10.20",
"LanguageID": 2, // "LanguageID": 2,
"PatientOutSA": 0, // "PatientOutSA": 0,
"SKU": "6720020025", // "SKU": "6720020025",
"SessionID": null, // "SessionID": null,
"VersionID": 5.6, // "VersionID": 5.6,
"generalid": "Cs2020@2016\$2958", // "generalid": "Cs2020@2016\$2958",
"isDentalAllowedBackend": false // "isDentalAllowedBackend": false
}; };
await baseAppClient.post(GET_LOCATION, await baseAppClient.post(GET_LOCATION, onSuccess: (dynamic response, int statusCode) {
onSuccess: (dynamic response, int statusCode) { _productLocationList.clear();
_productLocationList.clear(); response['PharmList'].forEach((item) {
response['PharmList'].forEach((item) { _productLocationList.add(LocationModel.fromJson(item));
_productLocationList.add(LocationModel.fromJson(item)); print(_productLocationList);
print(_productLocationList); print(response);
print(response); });
}); }, onFailure: (String error, int statusCode) {
}, onFailure: (String error, int statusCode) { hasError = true;
hasError = true; super.error = error;
super.error = error; }, body: request);
}, body: request);
} }
Future<Map> addToCart(quantity, itemID) async { Future<Map> addToCart(quantity, itemID) async {
@ -83,30 +99,22 @@ class ProductDetailService extends BaseService {
Map<String, dynamic> request; Map<String, dynamic> request;
request = { request = {
"shopping_cart_item": "shopping_cart_item": {"quantity": quantity, "shopping_cart_type": "1", "product_id": itemID, "customer_id": customerId, "language_id": 1}
{
"quantity": quantity,
"shopping_cart_type": "1",
"product_id": itemID,
"customer_id": customerId,
"language_id": 1
}
}; };
dynamic localRes; dynamic localRes;
await baseAppClient.pharmacyPost(GET_SHOPPING_CART, isExternal: false, await baseAppClient.pharmacyPost(GET_SHOPPING_CART, isExternal: false, onSuccess: (dynamic response, int statusCode) {
onSuccess: (dynamic response, int statusCode) { _addToCartModel.clear();
_addToCartModel.clear(); response['shopping_carts'].forEach((item) {
response['shopping_carts'].forEach((item) { _addToCartModel.add(Wishlist.fromJson(item));
_addToCartModel.add(Wishlist.fromJson(item)); });
}); AppToast.showSuccessToast(message: 'You have added a product to the cart');
AppToast.showSuccessToast(message: 'You have added a product to the cart'); localRes = response;
localRes = response; }, onFailure: (String error, int statusCode) {
}, onFailure: (String error, int statusCode) { hasError = true;
hasError = true; super.error = error;
super.error = error; AppToast.showErrorToast(message: error ?? Utils.generateContactAdminMessage());
AppToast.showErrorToast(message: error??Utils.generateContactAdminMessage()); }, body: request);
}, body: request);
return Future.value(localRes); return Future.value(localRes);
} }
@ -118,7 +126,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: error??Utils.generateContactAdminMessage()); AppToast.showErrorToast(message: error ?? Utils.generateContactAdminMessage());
}); });
} }
@ -130,67 +138,61 @@ class ProductDetailService extends BaseService {
request = { request = {
"shopping_cart_item": {"quantity": 1, "shopping_cart_type": "Wishlist", "product_id": itemID, "customer_id": customerId, "language_id": 1} "shopping_cart_item": {"quantity": 1, "shopping_cart_type": "Wishlist", "product_id": itemID, "customer_id": customerId, "language_id": 1}
}; };
await baseAppClient.pharmacyPost(GET_SHOPPING_CART, await baseAppClient.pharmacyPost(GET_SHOPPING_CART, onSuccess: (dynamic response, int statusCode) {
onSuccess: (dynamic response, int statusCode) { _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) {
hasError = true;
}, onFailure: (String error, int statusCode) { super.error = error;
hasError = true; AppToast.showErrorToast(message: error ?? Utils.generateContactAdminMessage());
super.error = error; }, body: request);
AppToast.showErrorToast(message: error??Utils.generateContactAdminMessage());
}, body: request);
} }
Future getWishlistItems() async { Future getWishlistItems() async {
var customerId = await sharedPref.getString(PHARMACY_CUSTOMER_ID); var customerId = await sharedPref.getString(PHARMACY_CUSTOMER_ID);
hasError = false; hasError = false;
await baseAppClient.getPharmacy(GET_WISHLIST+customerId+"?shopping_cart_type=2", await baseAppClient.getPharmacy(GET_WISHLIST + customerId + "?shopping_cart_type=2", onSuccess: (dynamic response, int statusCode) {
onSuccess: (dynamic response, int statusCode) { _wishListProducts.clear();
_wishListProducts.clear(); response['shopping_carts'].forEach((item) {
response['shopping_carts'].forEach((item) { _wishListProducts.add(Wishlist.fromJson(item));
_wishListProducts.add(Wishlist.fromJson(item)); });
}); }, onFailure: (String error, int statusCode) {
}, onFailure: (String error, int statusCode) { hasError = true;
hasError = true; super.error = error;
super.error = error; });
});
} }
Future deleteItemFromWishlist(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", onSuccess: (dynamic response, int statusCode) {
onSuccess: (dynamic response, int statusCode) { _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 removed a product from the Wishlist');
AppToast.showSuccessToast(message: 'You have removed a product from 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: error ?? Utils.generateContactAdminMessage());
AppToast.showErrorToast(message: error??Utils.generateContactAdminMessage()); });
});
} }
Future productSpecificationData(itemID) async { Future productSpecificationData(itemID) async {
hasError = false; hasError = false;
await baseAppClient.getPharmacy(GET_SPECIFICATION+itemID, await baseAppClient.getPharmacy(GET_SPECIFICATION + itemID, onSuccess: (dynamic response, int statusCode) {
onSuccess: (dynamic response, int statusCode) { _productSpecification.clear();
_productSpecification.clear(); response['specification'].forEach((item) {
response['specification'].forEach((item) { _productSpecification.add(SpecificationModel.fromJson(item));
_productSpecification.add(SpecificationModel.fromJson(item)); print(_productSpecification);
print(_productSpecification); });
}); }, onFailure: (String error, int statusCode) {
}, onFailure: (String error, int statusCode) { hasError = true;
hasError = true; super.error = error;
super.error = error; });
});
} }
} }

@ -2618,11 +2618,79 @@ class TranslationBase {
String get RRTSubTitle => localizedValues["RRTSubTitle"][locale.languageCode]; String get RRTSubTitle => localizedValues["RRTSubTitle"][locale.languageCode];
String get transportation => localizedValues["transportation"][locale.languageCode]; String get transportation => localizedValues["transportation"][locale.languageCode];
String get browseOffers => localizedValues["browseOffers"][locale.languageCode];
String get myCart => localizedValues["myCart"][locale.languageCode];
String get neck => localizedValues["neck"][locale.languageCode]; String get neck => localizedValues["neck"][locale.languageCode];
String get waist => localizedValues["waist"][locale.languageCode]; String get waist => localizedValues["waist"][locale.languageCode];
String get hip => localizedValues["hip"][locale.languageCode]; String get hip => localizedValues["hip"][locale.languageCode];
String get carbsProtin => localizedValues["carbsProtin"][locale.languageCode]; String get carbsProtin => localizedValues["carbsProtin"][locale.languageCode];
String get inactiveAct => localizedValues["inactiveAct"][locale.languageCode];
String get light => localizedValues["light"][locale.languageCode];
String get moderate => localizedValues["moderate"][locale.languageCode];
String get very => localizedValues["very"][locale.languageCode];
String get superAct => localizedValues["super"][locale.languageCode];
String get resultCalories => localizedValues["resultCalories"][locale.languageCode];
String get bmrDesc => localizedValues["bmrDesc"][locale.languageCode];
String get idealWeightDesc => localizedValues["idealWeightDesc"][locale.languageCode];
String get bodyFrame => localizedValues["bodyFrame"][locale.languageCode];
String get bodyFrameSmall => localizedValues["bodyFrameSmall"][locale.languageCode];
String get bodyFrameMedium => localizedValues["bodyFrameMedium"][locale.languageCode];
String get bodyFrameLarge => localizedValues["bodyFrameLarge"][locale.languageCode];
String get bodyFatDesc => localizedValues["bodyFatDesc"][locale.languageCode];
String get essential => localizedValues["essential"][locale.languageCode];
String get athlete => localizedValues["athlete"][locale.languageCode];
String get fitness => localizedValues["fitness"][locale.languageCode];
String get acceptable => localizedValues["acceptable"][locale.languageCode];
String get obeseBodyFat => localizedValues["obeseBodyFat"][locale.languageCode];
String get invalid => localizedValues["invalid"][locale.languageCode];
String get more => localizedValues["more"][locale.languageCode];
String get less => localizedValues["less"][locale.languageCode];
String get carbProteinDesc => localizedValues["carbProteinDesc"][locale.languageCode];
String get calDay => localizedValues["calDay"][locale.languageCode];
String get notSure => localizedValues["notSure"][locale.languageCode];
String get selectDiet => localizedValues["selectDiet"][locale.languageCode];
String get dietVeryLow => localizedValues["dietVeryLow"][locale.languageCode];
String get dietLow => localizedValues["dietLow"][locale.languageCode];
String get dietModerate => localizedValues["dietModerate"][locale.languageCode];
String get dietUSDA => localizedValues["dietUSDA"][locale.languageCode];
String get dietZone => localizedValues["dietZone"][locale.languageCode];
String get useFullInfo => localizedValues["usefulInfo"][locale.languageCode]; String get useFullInfo => localizedValues["usefulInfo"][locale.languageCode];
String get babyAge => localizedValues["babyAge"][locale.languageCode]; String get babyAge => localizedValues["babyAge"][locale.languageCode];
String get babyAgeAvail => localizedValues["babyAgeAvail"][locale.languageCode]; String get babyAgeAvail => localizedValues["babyAgeAvail"][locale.languageCode];

@ -1,217 +1,136 @@
import 'package:diplomaticquarterapp/core/model/packages_offers/responses/PackagesCartItemsResponseModel.dart'; import 'package:diplomaticquarterapp/core/model/packages_offers/responses/PackagesCartItemsResponseModel.dart';
import 'package:diplomaticquarterapp/core/model/packages_offers/responses/PackagesResponseModel.dart'; import 'package:diplomaticquarterapp/core/model/packages_offers/responses/PackagesResponseModel.dart';
import 'package:diplomaticquarterapp/core/viewModels/packages_offers/PackagesOffersViewModel.dart';
import 'package:diplomaticquarterapp/theme/colors.dart';
import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart';
import 'package:diplomaticquarterapp/uitl/utils.dart'; import 'package:diplomaticquarterapp/uitl/utils.dart';
import 'package:diplomaticquarterapp/uitl/utils_new.dart';
import 'package:diplomaticquarterapp/widgets/CounterView.dart'; import 'package:diplomaticquarterapp/widgets/CounterView.dart';
import 'package:diplomaticquarterapp/widgets/data_display/text.dart';
import 'package:flutter/cupertino.dart'; import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';
bool wide = true; bool wide = true;
class PackagesCartItemCard extends StatefulWidget { class PackagesCartItemCard extends StatefulWidget {
final PackagesCartItemsResponseModel itemModel; final PackagesCartItemsResponseModel itemModel;
final StepperCallbackFuture shouldStepperChangeApply ; final StepperCallbackFuture shouldStepperChangeApply;
final PackagesViewModel viewModel;
final Function getCartItems;
const PackagesCartItemCard( const PackagesCartItemCard({@required this.itemModel, @required this.shouldStepperChangeApply, @required this.viewModel, this.getCartItems, Key key}) : super(key: key);
{
@required this.itemModel,
@required this.shouldStepperChangeApply,
Key key})
: super(key: key);
@override @override
State<StatefulWidget> createState() => PackagesCartItemCardState(); State<StatefulWidget> createState() => PackagesCartItemCardState();
} }
class PackagesCartItemCardState extends State<PackagesCartItemCard> { class PackagesCartItemCardState extends State<PackagesCartItemCard> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
wide = !wide; wide = !wide;
return Container( return Container(
color: Colors.transparent, decoration: cardRadius(15.0),
child: Card( margin: EdgeInsets.only(left: 21.0, right: 21.0, top: 12.0),
elevation: 3, height: 90,
shadowColor: Colors.grey[100], child: Row(
color: Colors.white, mainAxisSize: MainAxisSize.max,
child: Stack( children: [
children: [ _image(widget.itemModel.product),
Container( Column(
height: 100, crossAxisAlignment: CrossAxisAlignment.start,
child: Row( children: [
children: [ _itemName(widget.itemModel.product.getName()),
_image(widget.itemModel.product), _itemDescription(widget.itemModel.product.shortDescription),
Column( Container(
crossAxisAlignment: CrossAxisAlignment.start, padding: const EdgeInsets.only(top: 12.0),
mainAxisAlignment: MainAxisAlignment.center, width: MediaQuery.of(context).size.width * 0.65,
child: Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
_itemPrice(widget.itemModel.product.price, context: context),
InkWell(
onTap: () async {
await widget.viewModel.service.deleteProductFromCart(widget.itemModel.id, context: context, showLoading: false);
widget.getCartItems();
},
child: Row(
children: [ children: [
_itemName(widget.itemModel.product.getName()), Padding(
Row( padding: const EdgeInsets.only(left: 5.0, right: 5.0),
children: [ child: Text(
_itemPrice(widget.itemModel.product.price, context: context), TranslationBase.of(context).removeMember,
_priceSeperator(), style: TextStyle(
_itemOldPrice(widget.itemModel.product.oldPrice, context: context), fontSize: 10,
], color: CustomColors.accentColor,
), fontWeight: FontWeight.w600,
Row( letterSpacing: -0.36,
children: [
_itemCounter(
widget.itemModel.quantity,
minQuantity: widget.itemModel.product.orderMinimumQuantity,
maxQuantity: widget.itemModel.product.orderMaximumQuantity,
shouldStepperChangeApply: (apply,total) async{
bool success = await widget.shouldStepperChangeApply(apply,total);
if(success == true)
setState(() => widget.itemModel.quantity = total);
return success;
}
), ),
], ),
), ),
SvgPicture.asset("assets/images/new-design/delete.svg", color: CustomColors.accentColor),
], ],
) ),
], ),
), ],
), ),
),
// Positioned( ],
// bottom: 8, )
// left: 10, ],
// child: Row( ),
// children: [
// _totalLabel(context: context),
// _totalPrice((widget.itemModel.product.price * widget.itemModel.quantity), context: context),
// ],
// ),
// )
],
)
)
); );
} }
} }
// --------------------
// Product Image
// --------------------
Widget _image(PackagesResponseModel model) => AspectRatio( Widget _image(PackagesResponseModel model) => AspectRatio(
aspectRatio: 1/1, aspectRatio: 1 / 1,
child: Padding( child: Padding(
padding: const EdgeInsets.all(10), padding: const EdgeInsets.all(9),
child: Container( child: Container(
decoration: BoxDecoration( decoration: BoxDecoration(
border: Border.all(color: Colors.grey[300], width: 0.25), border: Border.all(color: Colors.grey[300], width: 0.25),
boxShadow: [ boxShadow: [BoxShadow(color: Colors.grey[200], blurRadius: 2.0, spreadRadius: 1, offset: Offset(1, 1.5))],
BoxShadow(color: Colors.grey[200], blurRadius: 2.0, spreadRadius: 1, offset: Offset(1,1.5)) borderRadius: BorderRadius.circular(15),
], color: Colors.white,
borderRadius: BorderRadius.circular(8), shape: BoxShape.rectangle,
color: Colors.white, ),
shape: BoxShape.rectangle, child: ClipRRect(
), borderRadius: BorderRadius.circular(15),
child: ClipRRect( child: (model.images.isNotEmpty) ? Utils.loadNetworkImage(url: model.images.first.src, fitting: BoxFit.fill) : Container(color: Colors.grey[200])),
borderRadius: BorderRadius.circular(8), ),
child: (model.images.isNotEmpty)
? Utils.loadNetworkImage(url: model.images.first.src, fitting:BoxFit.fill)
: Container(color: Colors.grey[200])
), ),
), );
),
);
// --------------------
// Product Name
// --------------------
Widget _itemName(String name) => Padding( Widget _itemName(String name) => Padding(
padding: const EdgeInsets.all(0), padding: const EdgeInsets.only(top: 9.0),
child: Texts( child: Text(name,
name, style: TextStyle(
fontWeight: FontWeight.normal, fontSize: 14,
color: Colors.black, fontWeight: FontWeight.bold,
fontSize: 15 letterSpacing: -0.56,
) )));
);
Widget _itemDescription(String desc) => Padding(
padding: const EdgeInsets.only(top: 0.0),
child: Text(desc,
style: TextStyle(
fontSize: 10,
// fontWeight: FontWeight.bold,
letterSpacing: -0.4,
)));
Widget _itemPrice(double price, {@required BuildContext context}) { Widget _itemPrice(double price, {@required BuildContext context}) {
final prc = (price ?? 0.0).toStringAsFixed(2); final prc = (price ?? 0.0).toStringAsFixed(2);
return Padding( return Padding(
padding: const EdgeInsets.all(0), padding: const EdgeInsets.all(0),
child: Texts( child: Text(
'${prc} ${TranslationBase.of(context).sar}', '${prc} ${TranslationBase.of(context).sar}',
fontWeight: FontWeight.bold, style: TextStyle(
color: Colors.green, fontSize: 11,
fontSize: 15 fontWeight: FontWeight.w600,
) letterSpacing: -0.4,
); ),
} ),
);
// --------------------
// Price Seperator
// --------------------
Widget _priceSeperator() => Padding(
padding: const EdgeInsets.only(left: 3, right: 3),
child: Container(height: 0.5, width: 5, color: Colors.grey[100],),
);
// --------------------
// Product Price
// --------------------
Widget _itemOldPrice(double oldPrice, {@required BuildContext context}) {
final prc = (oldPrice ?? 0.0).toStringAsFixed(2);
return Padding(
padding: const EdgeInsets.all(0),
child: Texts(
'${prc} ${TranslationBase.of(context).sar}',
fontWeight: FontWeight.normal,
decoration: TextDecoration.lineThrough,
color: Colors.grey,
fontSize: 10
)
);
} }
// --------------------
// Product Price
// --------------------
Widget _itemCounter(int quantity, {int minQuantity, int maxQuantity, StepperCallbackFuture shouldStepperChangeApply}) => Padding(
padding: const EdgeInsets.all(0),
child: StepperView(
height: 25,
backgroundColor: Colors.grey[300],
foregroundColor: Colors.grey[200],
initialNumber: quantity,
minNumber: minQuantity,
maxNumber: maxQuantity,
counterCallback: shouldStepperChangeApply,
decreaseCallback: (){},
increaseCallback: (){},
)
);
Widget _totalLabel({@required BuildContext context}) => Padding(
padding: const EdgeInsets.all(0),
child: Texts(
'${TranslationBase.of(context).totalWithColonRight}',
fontWeight: FontWeight.bold,
color: Colors.grey[600],
fontSize: 13
)
);
Widget _totalPrice(double totalPrice, {@required BuildContext context}) => Padding(
padding: const EdgeInsets.all(0),
child: Texts(
'${totalPrice.toStringAsFixed(2)} ${TranslationBase.of(context).sar}',
fontWeight: FontWeight.normal,
color: Colors.green,
)
);

@ -1,10 +1,15 @@
import 'package:diplomaticquarterapp/core/model/packages_offers/responses/PackagesResponseModel.dart'; import 'package:diplomaticquarterapp/core/model/packages_offers/responses/PackagesResponseModel.dart';
import 'package:diplomaticquarterapp/pages/packages_offers/OfferAndPackageDetailPage.dart';
import 'package:diplomaticquarterapp/theme/colors.dart';
import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart';
import 'package:diplomaticquarterapp/uitl/utils.dart'; import 'package:diplomaticquarterapp/uitl/utils.dart';
import 'package:diplomaticquarterapp/uitl/utils_new.dart';
import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; import 'package:diplomaticquarterapp/widgets/data_display/text.dart';
import 'package:diplomaticquarterapp/widgets/others/StarRating.dart'; import 'package:diplomaticquarterapp/widgets/others/StarRating.dart';
import 'package:flutter/cupertino.dart'; import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:rating_bar/rating_bar.dart';
bool wide = true; bool wide = true;
@ -15,15 +20,7 @@ class PackagesItemCard extends StatefulWidget {
final PackagesResponseModel itemModel; final PackagesResponseModel itemModel;
final Function(PackagesResponseModel product) onCartClick; final Function(PackagesResponseModel product) onCartClick;
const PackagesItemCard( const PackagesItemCard({this.itemWidth, this.itemHeight, @required this.itemModel, @required this.itemContentPadding, @required this.onCartClick, Key key}) : super(key: key);
{
this.itemWidth,
this.itemHeight,
@required this.itemModel,
@required this.itemContentPadding,
@required this.onCartClick,
Key key})
: super(key: key);
@override @override
State<StatefulWidget> createState() => PackagesItemCardState(); State<StatefulWidget> createState() => PackagesItemCardState();
@ -35,122 +32,58 @@ class PackagesItemCardState extends State<PackagesItemCard> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
wide = !wide; wide = !wide;
return Directionality( return InkWell(
textDirection: TextDirection.rtl, onTap: () {
child: Stack( Navigator.of(context).push(MaterialPageRoute(builder: (BuildContext context) => OfferAndPackagesDetail(itemModel: widget.itemModel, onCartClick: widget.onCartClick)));
children: [ },
Padding( child: Container(
padding: EdgeInsets.only( // width: widget.itemWidth,
left: widget.itemContentPadding, // color: Colors.transparent,
right: widget.itemContentPadding, decoration: cardRadius(15.0),
top: widget.itemContentPadding + 5), width: MediaQuery.of(context).size.width * 0.46,
child: Container( padding: const EdgeInsets.all(9.0),
width: widget.itemWidth, child: Column(
color: Colors.transparent, crossAxisAlignment: CrossAxisAlignment.start,
child: Stack( children: [
ClipRRect(
borderRadius: BorderRadius.circular(15.0),
child: Image.network("https://mdlaboratories.com/offersdiscounts/images/thumbs/0000162_dermatology-testing.jpeg", fit: BoxFit.fill, height: 180.0, width: 180.0),
),
Container(margin: const EdgeInsets.only(top: 8.0), child: Text(widget.itemModel.name, maxLines: 1, style: TextStyle(fontSize: 14.0, fontWeight: FontWeight.bold, letterSpacing: -0.56))),
Container(width: MediaQuery.of(context).size.width * 0.4, child: Text("Special discount for all HMG Employees and their first…", maxLines: 2, style: TextStyle(fontSize: 10.0, fontWeight: FontWeight.w600, letterSpacing: -0.4, color: CustomColors.textColor), overflow: TextOverflow.clip)),
if (widget.itemModel.hasDiscountsApplied) Container(margin: const EdgeInsets.only(top: 19.0), child: Text(widget.itemModel.oldPrice.toString() + " " + TranslationBase.of(context).sar, style: TextStyle(fontSize: 9.0, fontWeight: FontWeight.w600, letterSpacing: -0.36, decoration: TextDecoration.lineThrough, color: CustomColors.grey2))),
Container(
margin: widget.itemModel.hasDiscountsApplied ? const EdgeInsets.only(top: 0.0) : const EdgeInsets.only(top: 19.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [ children: [
Column( Column(
mainAxisSize: MainAxisSize.max, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
AspectRatio( Container(margin: const EdgeInsets.only(top: 0.0), child: Text(widget.itemModel.price.toString().trim() + " " + TranslationBase.of(context).sar, style: TextStyle(fontSize: 12.0, fontWeight: FontWeight.bold, letterSpacing: -0.56))),
aspectRatio:1 / 1, RatingBar.readOnly(
child: applyShadow( initialRating: 4.5,
child: ClipRRect( size: 18.0,
borderRadius: BorderRadius.circular(10), filledColor: Color(0XFFD02127),
child: Utils.loadNetworkImage( emptyColor: Color(0XFFD02127),
url: imageUrl(), isHalfAllowed: true,
)), halfFilledIcon: Icons.star_half,
)), filledIcon: Icons.star,
Texts( emptyIcon: Icons.star_border,
widget.itemModel.getName(),
fontWeight: FontWeight.normal,
color: Colors.black,
fontSize: 15
),
Padding(
padding: const EdgeInsets.only(left: 10, right: 10),
child: Row(
crossAxisAlignment: CrossAxisAlignment.end,
mainAxisSize: MainAxisSize.max,
children: [
Stack(
children: [
Texts(
'${widget.itemModel.oldPrice} ${'SAR'}',
fontWeight: FontWeight.normal,
decoration: TextDecoration.lineThrough,
color: Colors.grey,
fontSize: 12
),
Padding(
padding: const EdgeInsets.only(top: 8),
child: Texts(
'${widget.itemModel.price} ${'SAR'}',
fontWeight: FontWeight.bold,
color: Colors.green,
fontSize: 18
),
),
Padding(
padding: const EdgeInsets.only(top: 35),
child: StarRating(
size: 15,
totalCount: null,
totalAverage: widget.itemModel.approvedRatingSum.toDouble(),
forceStars: true),
)
],
),
Spacer(
flex: 1,
),
InkWell(
child: Icon(
Icons.add_shopping_cart_rounded,
size: 30.0,
color: Colors.grey,
),
onTap: () {
widget.onCartClick(widget.itemModel);
},
),
],
),
), ),
], ],
), ),
InkWell(
child: SvgPicture.asset("assets/images/new/add-to-cart.svg"),
onTap: () {
widget.onCartClick(widget.itemModel);
},
),
], ],
), ),
), ),
), ],
Positioned( ),
top: 0,
right: 0,
child: Visibility(
visible: false,
child: InkWell(
child: Icon(
Icons.favorite,
size: 40.0,
color: Colors.red,
),
onTap: () {
},
),
),
),
Positioned(
top: 7,
left: 2,
child: Image.asset(
'assets/images/discount_${'en'}.png',
height: 60,
width: 60,
),
),
],
), ),
); );
} }

Loading…
Cancel
Save