Merge branch 'haroon-new-design' into 'development_new_design_2.0'

Haroon new design

See merge request Cloud_Solution/diplomatic-quarter!493
merge-requests/494/merge
haroon amjad 4 years ago
commit f7aafcda1a

@ -1636,4 +1636,6 @@ const Map localizedValues = {
"waist": {"en": "Waist", "ar": "وسط"},
"hip": {"en": "Hip", "ar": "ورك او نتوء"},
"carbsProtin": {"en": "Carbs, Protein and Fat", "ar": "الكربوهيدرات والبروتينات والدهون"},
"myCart": {"en": "Cart", "ar": "عربة التسوق"},
"browseOffers": {"en": "Browse offers by clinic", "ar": "تصفح العروض حسب العيادة"},
};

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

@ -514,7 +514,6 @@ class BaseAppClient {
simpleGet(String fullUrl,
{Function(dynamic response, int statusCode) onSuccess, Function(String error, int statusCode) onFailure, Map<String, String> queryParams, Map<String, String> headers}) async {
String url = fullUrl;
print("URL Query String: $url");
var haveParams = (queryParams != null);
if (haveParams) {

@ -21,7 +21,8 @@ import 'package:diplomaticquarterapp/uitl/gif_loader_dialog_utils.dart';
import 'package:diplomaticquarterapp/uitl/utils.dart';
import 'package:flutter/cupertino.dart';
var packagesAuthHeader = <String,String>{'Authorization' : ''};
var packagesAuthHeader = <String, String>{'Authorization': ''};
class OffersAndPackagesServices extends BaseService {
AuthenticatedUser patientUser;
List<PackagesCategoriesResponseModel> categoryList = List();
@ -33,52 +34,62 @@ class OffersAndPackagesServices extends BaseService {
List<PackagesCartItemsResponseModel> cartItemList = List();
String cartItemCount = "";
PackagesCustomerResponseModel customer;
Future<List<PackagesCategoriesResponseModel>> getAllCategories(OffersCategoriesRequestModel request) async {
Future<List<PackagesCategoriesResponseModel>> getAllCategories(
OffersCategoriesRequestModel request) async {
Future errorThrow;
var url = EXA_CART_API_BASE_URL + PACKAGES_CATEGORIES;
await baseAppClient.simpleGet(url, headers: packagesAuthHeader, onSuccess: (dynamic stringResponse, int statusCode) {
await baseAppClient.simpleGet(url, headers: packagesAuthHeader,
onSuccess: (dynamic stringResponse, int statusCode) {
if (statusCode == 200) {
var jsonResponse = json.decode(stringResponse);
jsonResponse['categories'].forEach((json) {
categoryList.add(PackagesCategoriesResponseModel().fromJson(json));
});
}
}, onFailure: (String error, int statusCode) {
}, queryParams: request.toFlatMap());
},
onFailure: (String error, int statusCode) {},
queryParams: request.toFlatMap());
return categoryList;
}
Future<List<PackagesResponseModel>> getAllProducts({@required OffersProductsRequestModel request, @required BuildContext context, @required bool showLoading = true}) async {
Future<List<PackagesResponseModel>> getAllProducts(
{@required OffersProductsRequestModel request,
@required BuildContext context,
@required bool showLoading = true}) async {
Future errorThrow;
request.sinceId = (productList.isNotEmpty) ? productList.last.id : 0;
productList = List();
var url = EXA_CART_API_BASE_URL + PACKAGES_PRODUCTS;
await baseAppClient.simpleGet(url, headers: packagesAuthHeader, onSuccess: (dynamic stringResponse, int statusCode) {
await baseAppClient.simpleGet(url, headers: packagesAuthHeader,
onSuccess: (dynamic stringResponse, int statusCode) {
if (statusCode == 200) {
var jsonResponse = json.decode(stringResponse);
jsonResponse['products'].forEach((json) {
productList.add(PackagesResponseModel().fromJson(json));
});
}
}, onFailure: (String error, int statusCode) {
}, queryParams: request.toFlatMap());
},
onFailure: (String error, int statusCode) {},
queryParams: request.toFlatMap());
return productList;
}
Future<List<TamaraPaymentOption>> getTamaraOptions({@required BuildContext context, @required bool showLoading = true}) async {
if(tamaraPaymentOptions != null && tamaraPaymentOptions.isNotEmpty)
Future<List<TamaraPaymentOption>> getTamaraOptions(
{@required BuildContext context,
@required bool showLoading = true}) async {
if (tamaraPaymentOptions != null && tamaraPaymentOptions.isNotEmpty)
return tamaraPaymentOptions;
var url = EXA_CART_API_BASE_URL + PACKAGES_TAMARA_OPT;
await baseAppClient.simpleGet(url, headers: packagesAuthHeader, onSuccess: (dynamic stringResponse, int statusCode) {
await baseAppClient.simpleGet(url, headers: packagesAuthHeader,
onSuccess: (dynamic stringResponse, int statusCode) {
if (statusCode == 200) {
var jsonResponse = json.decode(stringResponse);
jsonResponse['payment_option'].forEach((json) {
@ -92,10 +103,14 @@ class OffersAndPackagesServices extends BaseService {
return tamaraPaymentOptions;
}
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;
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) {
var jsonResponse = json.decode(stringResponse);
jsonResponse['products'].forEach((json) {
@ -109,10 +124,14 @@ class OffersAndPackagesServices extends BaseService {
return latestOffersList;
}
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;
await baseAppClient.simpleGet(url, headers: packagesAuthHeader, onSuccess: (dynamic stringResponse, int statusCode) {
await baseAppClient.simpleGet(url, headers: packagesAuthHeader,
onSuccess: (dynamic stringResponse, int statusCode) {
bestSellerList.clear();
if (statusCode == 200) {
var jsonResponse = json.decode(stringResponse);
jsonResponse['products'].forEach((json) {
@ -126,10 +145,13 @@ class OffersAndPackagesServices extends BaseService {
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;
await baseAppClient.simpleGet(url, headers: packagesAuthHeader, onSuccess: (dynamic stringResponse, int statusCode) {
await baseAppClient.simpleGet(url, headers: packagesAuthHeader,
onSuccess: (dynamic stringResponse, int statusCode) {
if (statusCode == 200) {
var jsonResponse = json.decode(stringResponse);
jsonResponse['products'].forEach((json) {
@ -143,15 +165,16 @@ class OffersAndPackagesServices extends BaseService {
return bannersList;
}
Future loadOffersPackagesDataForMainPage({@required BuildContext context, bool showLoading = true, Function completion }) async {
Future loadOffersPackagesDataForMainPage(
{@required BuildContext context,
bool showLoading = true,
Function completion}) async {
var finished = 0;
var totalCalls = 3;
completedAll(){
var totalCalls = 2;
completedAll() {
finished++;
if(completion != null && finished == totalCalls) {
if (completion != null && finished == totalCalls) {
_hideLoading(context, showLoading);
completion();
}
@ -160,57 +183,71 @@ class OffersAndPackagesServices extends BaseService {
_showLoading(context, showLoading);
final auth_token = await baseAppClient.generatePackagesToken();
if(auth_token == null){
if (auth_token == null) {
throw 'Something went wrong while authentication, Please try again letter';
}
packagesAuthHeader["Authorization"] = 'Bearer $auth_token';
// Check and Create Customer
if(patientUser != null){
customer = await getCurrentCustomer(context: context, showLoading: showLoading);
if(customer == null){
createCustomer(PackagesCustomerRequestModel.fromUser(patientUser), context: context);
if (patientUser != null) {
customer =
await getCurrentCustomer(context: context, showLoading: showLoading);
if (customer == null) {
createCustomer(PackagesCustomerRequestModel.fromUser(patientUser),
context: context);
}
}
// Performing Parallel Request on same time
// # 1
getBestSellers(request: OffersProductsRequestModel(), context: context, showLoading: false).then((value){
completedAll();
getBestSellers(
request: OffersProductsRequestModel(),
context: context,
showLoading: false)
.then((value) {
completedAll();
});
// # 2
getLatestOffers(request: OffersProductsRequestModel(), context: context, showLoading: false).then((value){
getLatestOffers(
request: OffersProductsRequestModel(),
context: context,
showLoading: false)
.then((value) {
completedAll();
});
// # 3
getBanners(request: OffersProductsRequestModel(), context: context, showLoading: false).then((value){
completedAll();
});
// getBanners(
// request: OffersProductsRequestModel(),
// context: context,
// showLoading: false)
// .then((value) {
// completedAll();
// });
}
// --------------------
// Create Customer
// --------------------
Future createCustomer(PackagesCustomerRequestModel request, {@required BuildContext context, bool showLoading = true, Function(bool) completion }) async{
if(customer != null)
return Future.value(customer);
Future createCustomer(PackagesCustomerRequestModel request,
{@required BuildContext context,
bool showLoading = true,
Function(bool) completion}) async {
if (customer != null) return Future.value(customer);
customer = null;
Future errorThrow;
_showLoading(context, showLoading);
var url = EXA_CART_API_BASE_URL + PACKAGES_CUSTOMER;
await baseAppClient.simplePost(url, headers: packagesAuthHeader, body: request.json(), onSuccess: (dynamic stringResponse, int statusCode){
await baseAppClient
.simplePost(url, headers: packagesAuthHeader, body: request.json(),
onSuccess: (dynamic stringResponse, int statusCode) {
var jsonResponse = json.decode(stringResponse);
var customerJson = jsonResponse['customers'].first;
customer = PackagesCustomerResponseModel.fromJson(customerJson);
}, onFailure: (String error, int statusCode){
}, onFailure: (String error, int statusCode) {
errorThrow = Future.error(error);
log(error);
});
@ -221,55 +258,60 @@ class OffersAndPackagesServices extends BaseService {
return errorThrow ?? customer;
}
Future<PackagesCustomerResponseModel> getCurrentCustomer({@required BuildContext context, bool showLoading = true}) async{
if(customer != null)
return Future.value(customer);
Future<PackagesCustomerResponseModel> getCurrentCustomer(
{@required BuildContext context, bool showLoading = true}) async {
if (customer != null) return Future.value(customer);
_showLoading(context, showLoading);
var url = EXA_CART_API_BASE_URL + PACKAGES_CUSTOMER + "/username/${patientUser.patientID}";
await baseAppClient.simpleGet(url, headers: packagesAuthHeader, onSuccess: (dynamic stringResponse, int statusCode){
var url = EXA_CART_API_BASE_URL +
PACKAGES_CUSTOMER +
"/username/${patientUser.patientID}";
await baseAppClient.simpleGet(url, headers: packagesAuthHeader,
onSuccess: (dynamic stringResponse, int statusCode) {
var jsonResponse = json.decode(stringResponse);
var customerJson = jsonResponse['customers'].first;
customer = PackagesCustomerResponseModel.fromJson(customerJson);
}, onFailure: (String error, int statusCode){
}, onFailure: (String error, int statusCode) {
log(error);
});
_hideLoading(context, showLoading);
return customer;
return customer;
}
// --------------------
// Shopping Cart
// --------------------
Future<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;
cartItemList.clear();
_showLoading(context, showLoading);
var url = EXA_CART_API_BASE_URL + PACKAGES_SHOPPING_CART + '/${customer.id}';
Map<String,dynamic> jsonResponse;
await baseAppClient.simpleGet(url, headers: packagesAuthHeader, onSuccess: (dynamic stringResponse, int statusCode) {
var url =
EXA_CART_API_BASE_URL + PACKAGES_SHOPPING_CART + '/${customer.id}';
Map<String, dynamic> jsonResponse;
await baseAppClient.simpleGet(url, headers: packagesAuthHeader,
onSuccess: (dynamic stringResponse, int statusCode) {
_hideLoading(context, showLoading);
jsonResponse = json.decode(stringResponse);
jsonResponse['shopping_carts'].forEach((json) {
cartItemList.add(PackagesCartItemsResponseModel.fromJson(json));
});
}, onFailure: (String error, int statusCode) {
_hideLoading(context, showLoading);
log(error);
errorThrow = Future.error({"error":error, "statusCode":statusCode});
errorThrow = Future.error({"error": error, "statusCode": statusCode});
}, queryParams: null);
return errorThrow ?? jsonResponse;
}
Future<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;
ResponseModel<PackagesCartItemsResponseModel> response;
@ -277,55 +319,64 @@ class OffersAndPackagesServices extends BaseService {
_showLoading(context, showLoading);
var url = EXA_CART_API_BASE_URL + PACKAGES_SHOPPING_CART;
await baseAppClient.simplePost(url, headers: packagesAuthHeader, body: request.json(), onSuccess: (dynamic stringResponse, int statusCode){
await baseAppClient
.simplePost(url, headers: packagesAuthHeader, body: request.json(),
onSuccess: (dynamic stringResponse, int statusCode) {
_hideLoading(context, showLoading);
var jsonResponse = json.decode(stringResponse);
var jsonCartItem = jsonResponse["shopping_carts"][0];
response = ResponseModel(status: true, data: PackagesCartItemsResponseModel.fromJson(jsonCartItem), error: null);
response = ResponseModel(
status: true,
data: PackagesCartItemsResponseModel.fromJson(jsonCartItem),
error: null);
cartItemCount = (jsonResponse['count'] ?? 0).toString();
}, onFailure: (String error, int statusCode){
}, onFailure: (String error, int statusCode) {
_hideLoading(context, showLoading);
errorThrow = Future.error(ResponseModel(status: true, data: null, error: error));
errorThrow =
Future.error(ResponseModel(status: true, data: null, error: error));
});
return errorThrow ?? response;
}
Future updateProductToCart(int cartItemID, {UpdateProductToCartRequestModel request, @required BuildContext context, bool showLoading = true}) async{
Future updateProductToCart(int cartItemID,
{UpdateProductToCartRequestModel request,
@required BuildContext context,
bool showLoading = true}) async {
Future errorThrow;
_showLoading(context, showLoading);
var url = EXA_CART_API_BASE_URL + PACKAGES_SHOPPING_CART + '/$cartItemID';
await baseAppClient.simplePut(url, headers: packagesAuthHeader, body: request.json(), onSuccess: (dynamic stringResponse, int statusCode){
await baseAppClient
.simplePut(url, headers: packagesAuthHeader, body: request.json(),
onSuccess: (dynamic stringResponse, int statusCode) {
_hideLoading(context, showLoading);
var jsonResponse = json.decode(stringResponse);
}, onFailure: (String error, int statusCode){
}, onFailure: (String error, int statusCode) {
_hideLoading(context, showLoading);
log(error);
errorThrow = Future.error({"error":error, "statusCode":statusCode});
errorThrow = Future.error({"error": error, "statusCode": statusCode});
});
return errorThrow ?? bannersList;
}
Future<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;
_showLoading(context, showLoading);
var url = EXA_CART_API_BASE_URL + PACKAGES_SHOPPING_CART + '/$cartItemID';
await baseAppClient.simpleDelete(url, headers: packagesAuthHeader, onSuccess: (dynamic stringResponse, int statusCode){
await baseAppClient.simpleDelete(url, headers: packagesAuthHeader,
onSuccess: (dynamic stringResponse, int statusCode) {
_hideLoading(context, showLoading);
// var jsonResponse = json.decode(stringResponse);
}, onFailure: (String error, int statusCode){
}, onFailure: (String error, int statusCode) {
_hideLoading(context, showLoading);
log(error);
errorThrow = Future.error({"error":error, "statusCode":statusCode});
errorThrow = Future.error({"error": error, "statusCode": statusCode});
});
return errorThrow ?? true;
@ -334,29 +385,33 @@ class OffersAndPackagesServices extends BaseService {
// --------------------
// Place Order
// --------------------
Future placeOrder({@required Map<dynamic,dynamic> paymentParams, @required BuildContext context, bool showLoading = true}) async{
Future placeOrder(
{@required Map<dynamic, dynamic> paymentParams,
@required BuildContext context,
bool showLoading = true}) async {
Future errorThrow;
Map<dynamic,dynamic> jsonBody = {
"customer_id" : customer.id,
Map<dynamic, dynamic> jsonBody = {
"customer_id": customer.id,
"billing_address": {
"email": patientUser.emailAddress,
"phone_number": patientUser.mobileNumber
},
};
jsonBody.addAll(paymentParams);
jsonBody = {'order' : jsonBody};
jsonBody = {'order': jsonBody};
int order_id;
_showLoading(context, showLoading);
var url = EXA_CART_API_BASE_URL + PACKAGES_ORDERS;
await baseAppClient.simplePost(url, headers: packagesAuthHeader, body: jsonBody, onSuccess: (dynamic stringResponse, int statusCode){
await baseAppClient.simplePost(url,
headers: packagesAuthHeader,
body: jsonBody, onSuccess: (dynamic stringResponse, int statusCode) {
_hideLoading(context, showLoading);
var jsonResponse = json.decode(stringResponse);
order_id = jsonResponse['orders'][0]['id'];
}, onFailure: (String error, int statusCode){
}, onFailure: (String error, int statusCode) {
_hideLoading(context, showLoading);
log(error);
errorThrow = Future.error(error);
@ -365,35 +420,34 @@ class OffersAndPackagesServices extends BaseService {
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;
ResponseModel<PackagesOrderResponseModel> response;
_showLoading(context, showLoading);
var url = EXA_CART_API_BASE_URL + PACKAGES_ORDERS + '/$id';
await baseAppClient.simpleGet(url, headers: packagesAuthHeader, onSuccess: (dynamic stringResponse, int statusCode) {
await baseAppClient.simpleGet(url, headers: packagesAuthHeader,
onSuccess: (dynamic stringResponse, int statusCode) {
_hideLoading(context, showLoading);
var jsonResponse = json.decode(stringResponse);
var jsonOrder = jsonResponse['orders'][0];
response = ResponseModel(status: true, data: PackagesOrderResponseModel.fromJson(jsonOrder));
response = ResponseModel(
status: true, data: PackagesOrderResponseModel.fromJson(jsonOrder));
}, onFailure: (String error, int statusCode) {
_hideLoading(context, showLoading);
errorThrow = Future.error(ResponseModel(status: false,error: error));
errorThrow = Future.error(ResponseModel(status: false, error: error));
}, queryParams: null);
return errorThrow ?? response;
}
}
_showLoading(BuildContext context, bool flag){
if(flag)
GifLoaderDialogUtils.showMyDialog(context);
_showLoading(BuildContext context, bool flag) {
if (flag) GifLoaderDialogUtils.showMyDialog(context);
}
_hideLoading(BuildContext context, bool flag){
if(flag)
GifLoaderDialogUtils.hideDialog(context);
}
_hideLoading(BuildContext context, bool flag) {
if (flag) GifLoaderDialogUtils.hideDialog(context);
}

@ -313,6 +313,12 @@ offerProductsResponseModelFromJson(PackagesResponseModel data, Map<String, dynam
data.storeIds = new List<dynamic>();
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) {
data.manufacturerIds = json['manufacturer_ids']?.map((v) => v?.toInt())?.toList()?.cast<int>();
}

@ -99,23 +99,9 @@ class _BMICalculatorState extends State<BMICalculator> {
return AppScaffold(
isShowAppBar: true,
isShowDecPage: false,
showHomeAppBarIcon: false,
showHomeAppBarIcon: true,
showNewAppBar: 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}",
body: Column(
children: [

@ -1,49 +1,58 @@
import 'dart:collection';
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/BookAppointment/SearchResults.dart';
import 'package:diplomaticquarterapp/services/appointment_services/GetDoctorsList.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/utils_new.dart';
import 'package:diplomaticquarterapp/widgets/buttons/borderedButton.dart';
import 'package:diplomaticquarterapp/widgets/buttons/secondary_button.dart';
import 'package:diplomaticquarterapp/widgets/data_display/text.dart';
import 'package:diplomaticquarterapp/widgets/buttons/defaultButton.dart';
import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart';
import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart';
import 'package:flutter/material.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 String textResult;
final String msg;
ResultPage({this.finalResult, this.textResult, this.msg});
@override
_ResultPageState createState() => _ResultPageState();
}
class _ResultPageState extends State<ResultPage> {
Color inductorColor;
double percent;
Color colorInductor() {
if (finalResult >= 30) {
if (widget.finalResult >= 30) {
inductorColor = Color(0xffC70D00);
} else if (finalResult < 30 && finalResult >= 25) {
} else if (widget.finalResult < 30 && widget.finalResult >= 25) {
inductorColor = Color(0xffC25400);
} else if (finalResult < 25 && finalResult >= 18.5) {
} else if (widget.finalResult < 25 && widget.finalResult >= 18.5) {
inductorColor = Color(0xff36D600);
} else if (finalResult < 18.5) {
} else if (widget.finalResult < 18.5) {
inductorColor = Color(0xff1BE0EE);
}
return inductorColor;
}
double percentInductor() {
if (finalResult >= 30) {
if (widget.finalResult >= 30) {
percent = 1.0;
} else if (finalResult < 30 && finalResult >= 25) {
} else if (widget.finalResult < 30 && widget.finalResult >= 25) {
percent = 0.73;
} else if (finalResult < 25 && finalResult >= 18.5) {
} else if (widget.finalResult < 25 && widget.finalResult >= 18.5) {
percent = 0.5;
} else if (finalResult < 18.5) {
} else if (widget.finalResult < 18.5) {
percent = 0.25;
}
return percent;
@ -69,7 +78,7 @@ class ResultPage extends StatelessWidget {
mainAxisSize: MainAxisSize.min,
children: [
Text(
TranslationBase.of(context).bodyMassIndex + finalResult.toString(),
TranslationBase.of(context).bodyMassIndex + widget.finalResult.toString(),
style: TextStyle(
fontSize: 16,
letterSpacing: -0.64,
@ -81,21 +90,21 @@ class ResultPage extends StatelessWidget {
height: MediaQuery.of(context).size.width / 2.8,
child: Row(
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),
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),
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),
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),
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),
Text(
textResult,
widget.textResult,
style: TextStyle(
fontSize: 16.0,
fontWeight: FontWeight.w600,
@ -104,7 +113,7 @@ class ResultPage extends StatelessWidget {
),
mHeight(4),
Text(
msg,
widget.msg,
style: TextStyle(fontSize: 14.0, fontWeight: FontWeight.w600, letterSpacing: -0.56, color: CustomColors.textColor),
),
],
@ -115,14 +124,10 @@ class ResultPage extends StatelessWidget {
Container(
color: Colors.white,
padding: EdgeInsets.all(16),
child: SecondaryButton(
label: TranslationBase.of(context).seeListOfDoctor,
color: CustomColors.accentColor,
onTap: () {
Navigator.push(
context,
FadePage(page: BariatricsPage(1, 1, finalResult)),
);
child: DefaultButton(
TranslationBase.of(context).seeListOfDoctor,
() {
callDoctorsSearchAPI();
},
),
),
@ -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) {
return Expanded(
flex: 1,

@ -2,8 +2,7 @@ import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart';
import 'package:diplomaticquarterapp/theme/colors.dart';
import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart';
import 'package:diplomaticquarterapp/uitl/utils_new.dart';
import 'package:diplomaticquarterapp/widgets/buttons/secondary_button.dart';
import 'package:diplomaticquarterapp/widgets/data_display/text.dart';
import 'package:diplomaticquarterapp/widgets/buttons/defaultButton.dart';
import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart';
import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart';
import 'package:flutter/material.dart';
@ -148,16 +147,7 @@ class _BmrCalculatorState extends State<BmrCalculator> {
showNewAppBarTitle: true,
showNewAppBar: true,
appBarTitle: TranslationBase.of(context).bmr,
showHomeAppBarIcon: false,
appBarIcons: [
Padding(
padding: const EdgeInsets.symmetric(horizontal: 10.0, vertical: 7.0),
child: Icon(
Icons.info_outline,
color: Colors.white,
),
)
],
showHomeAppBarIcon: true,
body: Container(
height: double.infinity,
width: double.infinity,
@ -406,22 +396,20 @@ class _BmrCalculatorState extends State<BmrCalculator> {
Container(
margin: EdgeInsets.symmetric(horizontal: 16.0, vertical: 16.0),
color: Colors.white,
child: SecondaryButton(
label: TranslationBase.of(context).calculate,
color: CustomColors.accentColor,
onTap: () {
child: DefaultButton(
TranslationBase.of(context).calculate,
() {
setState(() {
calculateBmr();
calculateCalories();
{
Navigator.push(
context,
FadePage(
page: BmrResultPage(
bmrResult: bmrResult,
calories: calories,
)),
bmrResult: bmrResult,
calories: calories,
)),
);
}
});
@ -661,5 +649,3 @@ class CommonDropDownView extends StatelessWidget {
);
}
}

@ -5,9 +5,7 @@ import 'package:diplomaticquarterapp/theme/colors.dart';
import 'package:diplomaticquarterapp/uitl/gif_loader_dialog_utils.dart';
import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart';
import 'package:diplomaticquarterapp/uitl/utils_new.dart';
import 'package:diplomaticquarterapp/widgets/buttons/button.dart';
import 'package:diplomaticquarterapp/widgets/buttons/secondary_button.dart';
import 'package:diplomaticquarterapp/widgets/data_display/text.dart';
import 'package:diplomaticquarterapp/widgets/buttons/defaultButton.dart';
import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart';
import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart';
import 'package:flutter/material.dart';
@ -26,6 +24,7 @@ class BmrResultPage extends StatelessWidget {
isShowDecPage: false,
showNewAppBarTitle: true,
showNewAppBar: true,
showHomeAppBarIcon: true,
appBarTitle: TranslationBase.of(context).bmr,
body: Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
@ -80,31 +79,23 @@ class BmrResultPage extends StatelessWidget {
),
mHeight(20),
Text(
'This means the body will burn ( ${bmrResult.toStringAsFixed(1)} ) calories each day, if engaged in no activity for the entire day.. Note: Daily calorie requirement is ( ${calories.toStringAsFixed(1)} ) calories, to maintain the current weight.',
style: TextStyle(
fontSize: 14,
letterSpacing: -0.56,
fontWeight: FontWeight.w600,
color: CustomColors.textColor
),
'This means the body will burn (${bmrResult.toStringAsFixed(1)}) calories each day, if engaged in no activity for the entire day.. Note: Daily calorie requirement is (${calories.toStringAsFixed(1)}) calories, to maintain the current weight.',
style: TextStyle(fontSize: 14, letterSpacing: -0.56, fontWeight: FontWeight.w600, color: CustomColors.textColor),
),
],
).withBorderedContainer,
),
mFlex(1),
Container(
margin: EdgeInsets.symmetric(horizontal: 16.0, vertical: 16.0),
color: Colors.white,
child: SecondaryButton(
label: TranslationBase.of(context).viewDocList,
color: CustomColors.accentColor,
onTap: () {
child: DefaultButton(
TranslationBase.of(context).viewDocList,
() {
getDoctorsList(context);
},
),
),
],
),
);
@ -163,18 +154,19 @@ class BmrResultPage extends StatelessWidget {
});
}
}
extension BorderedContainer on Widget {
Widget get withBorderedContainer => Container(
padding: EdgeInsets.only(left: 16, right: 16, bottom: 15, top: 15),
alignment: Alignment.center,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(15),
color: Colors.white,
border: Border.all(
color: Color(0xffefefef),
width: 1,
),
),
child: this,
);
}
padding: EdgeInsets.only(left: 16, right: 16, bottom: 15, top: 15),
alignment: Alignment.center,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(15),
color: Colors.white,
border: Border.all(
color: Color(0xffefefef),
width: 1,
),
),
child: this,
);
}

@ -227,16 +227,8 @@ class _BodyFatState extends State<BodyFat> {
isShowDecPage: false,
showNewAppBarTitle: true,
showNewAppBar: true,
showHomeAppBarIcon: true,
appBarTitle: TranslationBase.of(context).bodyFatTitle,
appBarIcons: [
Padding(
padding: const EdgeInsets.symmetric(horizontal: 10.0, vertical: 7.0),
child: Icon(
Icons.info_outline,
color: Colors.white,
),
)
],
body: Column(
children: [
Expanded(

@ -2,8 +2,8 @@ import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart';
import 'package:diplomaticquarterapp/theme/colors.dart';
import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart';
import 'package:diplomaticquarterapp/uitl/utils_new.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/transitions/fade_page.dart';
import 'package:flutter/material.dart';
@ -85,16 +85,8 @@ class _CalorieCalculatorState extends State<CalorieCalculator> {
isShowDecPage: false,
showNewAppBar: true,
showNewAppBarTitle: true,
showHomeAppBarIcon: true,
appBarTitle: "${TranslationBase.of(context).calories} ${TranslationBase.of(context).calcHealth}",
appBarIcons: [
Padding(
padding: const EdgeInsets.symmetric(horizontal: 10.0, vertical: 7.0),
child: Icon(
Icons.info_outline,
color: Colors.black,
),
)
],
body: Column(
children: [
Expanded(
@ -261,7 +253,6 @@ class _CalorieCalculatorState extends State<CalorieCalculator> {
SizedBox(
height: 12.0,
),
InkWell(
onTap: () {
// dropdownKey.currentState;
@ -337,10 +328,9 @@ class _CalorieCalculatorState extends State<CalorieCalculator> {
Container(
margin: EdgeInsets.symmetric(horizontal: 16.0, vertical: 16.0),
color: Colors.white,
child: SecondaryButton(
label: TranslationBase.of(context).calculate,
color: CustomColors.accentColor,
onTap: () {
child: DefaultButton(
TranslationBase.of(context).calculate,
() {
setState(() {
calculateCalories();
print(calories);

@ -5,9 +5,7 @@ import 'package:diplomaticquarterapp/theme/colors.dart';
import 'package:diplomaticquarterapp/uitl/gif_loader_dialog_utils.dart';
import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart';
import 'package:diplomaticquarterapp/uitl/utils_new.dart';
import 'package:diplomaticquarterapp/widgets/buttons/button.dart';
import 'package:diplomaticquarterapp/widgets/buttons/secondary_button.dart';
import 'package:diplomaticquarterapp/widgets/data_display/text.dart';
import 'package:diplomaticquarterapp/widgets/buttons/defaultButton.dart';
import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart';
import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart';
import 'package:flutter/material.dart';
@ -75,18 +73,13 @@ class CalorieResultPage extends StatelessWidget {
],
),
progressColor: CustomColors.accentColor,
backgroundColor: Colors.white,
backgroundColor: CustomColors.darkGreyColor,
),
),
mHeight(20),
Text(
'Daily intake is ${calorie.toStringAsFixed(1)} calories',
style: TextStyle(
fontSize: 14,
letterSpacing: -0.56,
fontWeight: FontWeight.w600,
color: CustomColors.textColor
),
style: TextStyle(fontSize: 14, letterSpacing: -0.56, fontWeight: FontWeight.w600, color: CustomColors.textColor),
),
],
).withBorderedContainer,
@ -95,15 +88,13 @@ class CalorieResultPage extends StatelessWidget {
Container(
margin: EdgeInsets.symmetric(horizontal: 16.0, vertical: 16.0),
color: Colors.white,
child: SecondaryButton(
label: TranslationBase.of(context).viewDocList,
color: CustomColors.accentColor,
onTap: () {
child: DefaultButton(
TranslationBase.of(context).viewDocList,
() {
getDoctorsList(context);
},
),
),
],
),
);

@ -84,16 +84,7 @@ class _IdealBodyState extends State<IdealBody> {
showNewAppBarTitle: true,
showNewAppBar: true,
appBarTitle: TranslationBase.of(context).idealBody,
showHomeAppBarIcon: false,
appBarIcons: [
Padding(
padding: const EdgeInsets.symmetric(horizontal: 10.0, vertical: 7.0),
child: Icon(
Icons.info_outline,
color: Colors.white,
),
)
],
showHomeAppBarIcon: true,
body: Column(
children: [
Expanded(

@ -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/models/Appointments/AppoimentAllHistoryResultList.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/hmg_services.dart';
import 'package:diplomaticquarterapp/models/slider_data.dart';
@ -282,7 +283,7 @@ class _HomePageFragment2State extends State<HomePageFragment2> {
flex: 1,
child: InkWell(
onTap: () {
final user = projectViewModel.user;
AuthenticatedUser user = projectViewModel.user;
Navigator.of(context).push(MaterialPageRoute(builder: (context) => PackagesHomePage(user)));
},
child: Container(

@ -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/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/utils.dart' as utils;
import 'package:diplomaticquarterapp/widgets/data_display/text.dart';
import 'package:diplomaticquarterapp/widgets/others/StarRating.dart';
import 'package:diplomaticquarterapp/uitl/utils_new.dart';
import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart';
import 'package:expandable/expandable.dart';
import 'package:flutter/cupertino.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{
final dynamic model;
class OfferAndPackagesDetail extends StatefulWidget {
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
State<StatefulWidget> createState() => OfferAndPackagesDetailState();
}
class OfferAndPackagesDetailState extends State<OfferAndPackagesDetail>{
class OfferAndPackagesDetailState extends State<OfferAndPackagesDetail> {
PackagesViewModel viewModel;
bool expandFlag = false;
var controller = new ExpandableController();
@override
Widget build(BuildContext context) {
return BaseView<PackagesViewModel>(
onModelReady: (model){
onModelReady: (model) {
viewModel = model;
},
builder: (_, model, wi) => AppScaffold(
appBarTitle: TranslationBase.of(context).offerAndPackages,
isShowAppBar: true,
isPharmacy: false,
showPharmacyCart: false,
showHomeAppBarIcon: false,
isOfferPackages: true,
showOfferPackagesCart: true,
isShowDecPage: false,
body: Stack(
appBarTitle: TranslationBase.of(context).offerAndPackages,
isShowAppBar: true,
isPharmacy: false,
showPharmacyCart: false,
showHomeAppBarIcon: false,
isOfferPackages: true,
showOfferPackagesCart: true,
isShowDecPage: false,
showNewAppBar: true,
showNewAppBarTitle: true,
body: SingleChildScrollView(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Padding(
padding: const EdgeInsets.only(bottom: 60),
child: ListView(
children: [
Padding(
padding: const EdgeInsets.all(5),
child: Stack(
children: [
Padding(
padding: const EdgeInsets.all(10),
child: AspectRatio(
aspectRatio: 1/1,
child: utils.applyShadow(
child: ClipRRect(
borderRadius: BorderRadius.circular(10),
child: utils.Utils.loadNetworkImage(url: "https://wallpaperaccess.com/full/30103.jpg",)
),
)
),
),
Align(
alignment: Alignment.topLeft,
child: Image.asset(
'assets/images/discount_${'en'}.png',
height: 70,
width: 70,
),
),
],
),
Container(
color: Colors.white,
padding: const EdgeInsets.all(21.0),
child: ClipRRect(
borderRadius: BorderRadius.circular(15.0),
child: Image.network("https://mdlaboratories.com/offersdiscounts/images/thumbs/0000162_dermatology-testing.jpeg", fit: BoxFit.fill),
),
),
Container(
padding: const EdgeInsets.only(left: 21.0, right: 21.0, top: 21.0),
child: Text(widget.itemModel.name, maxLines: 1, style: TextStyle(fontSize: 19.0, fontWeight: FontWeight.bold, letterSpacing: -1.14))),
Container(
padding: const EdgeInsets.only(left: 21.0, right: 21.0),
child: Text(widget.itemModel.shortDescription,
maxLines: 2, style: TextStyle(fontSize: 14.0, fontWeight: FontWeight.w600, letterSpacing: -0.56, color: CustomColors.textColor), overflow: TextOverflow.clip)),
Row(
children: [
Container(
padding: const EdgeInsets.only(left: 21.0, right: 21.0, top: 12.0),
child: RatingBar.readOnly(
initialRating: 4.5,
size: 18.0,
filledColor: Color(0XFFD02127),
emptyColor: Color(0XFFD02127),
isHalfAllowed: true,
halfFilledIcon: Icons.star_half,
filledIcon: Icons.star,
emptyIcon: Icons.star_border,
),
Padding(
padding: const EdgeInsets.only(left: 20, right: 20, bottom: 20),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Texts(
"Child Dental Offer",
fontSize: 25,
fontWeight: FontWeight.normal,
color: Colors.black,
),
Stack(
children: [
Texts(
"200 SAR",
fontWeight: FontWeight.normal,
decoration: TextDecoration.lineThrough,
color: Colors.grey,
fontSize: 12
),
Padding(
padding: const EdgeInsets.only(top: 15),
child: Texts(
"894.99 SAR",
fontWeight: FontWeight.bold,
color: Colors.green,
fontSize: 18
),
],
),
Container(
padding: const EdgeInsets.only(left: 21.0, right: 21.0, top: 18.0),
width: double.infinity,
height: 50.0,
child: ListView.separated(
scrollDirection: Axis.horizontal,
shrinkWrap: true,
itemCount: widget.itemModel.storeNames.length,
separatorBuilder: (context, index) {
return mWidth(5.0);
},
itemBuilder: (BuildContext context, int index) {
return contactButton(widget.itemModel.storeNames[index].toString());
},
),
),
Container(
padding: const EdgeInsets.only(top: 18.0),
child: ExpandableNotifier(
initialExpanded: true,
child: Container(
color: Colors.white,
child: Column(
children: <Widget>[
ScrollOnExpand(
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))),
],
),
),
Padding(
padding: const EdgeInsets.all(10),
child: Align(
alignment: Alignment.bottomRight,
child: Row(
children: [
Expanded(
child: RaisedButton.icon(
padding: EdgeInsets.only(top: 5, bottom: 5, left: 0, right: 0),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(8.0),
side: BorderSide(color: Colors.red, width: 0.5)
),
color: Colors.red,
icon: Icon(
Icons.add_shopping_cart_outlined,
size: 25,
color: Colors.white,
),
label: Texts(
"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),
SizedBox(width: 8),
Expanded(
child: SizedBox(
height: 43,
width: double.infinity,
child: FlatButton(
onPressed: () {
// onCartClick();
widget.onCartClick(widget.itemModel);
},
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Padding(
padding: const EdgeInsets.only(left: 8.0, right: 8.0),
child: SvgPicture.asset("assets/images/new/add-to-cart.svg", color: Colors.white),
),
Container(
child: Text(
TranslationBase.of(context).addToCart,
textAlign: TextAlign.center,
style: TextStyle(fontSize: 16, fontWeight: FontWeight.w600, color: Colors.white, letterSpacing: -0.48),
),
color: Colors.white,
icon: Icon(
Icons.favorite_rounded,
size: 25,
color: Colors.red,
),
label: Texts(
"Add to Favorites",
fontSize: 17, color: Colors.red, fontWeight: FontWeight.normal
),
onPressed: (){
},),
),
],
),
],
),
color: const Color(0xffD02127),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(6),
),
),
),
)
),
],
),
),
),
);
}
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,
),
),
);
}
}

@ -32,20 +32,18 @@ class PackagesCartPage extends StatefulWidget {
_PackagesCartPageState createState() => _PackagesCartPageState();
}
class _PackagesCartPageState extends State<PackagesCartPage>
with AfterLayoutMixin<PackagesCartPage>, SingleTickerProviderStateMixin {
class _PackagesCartPageState extends State<PackagesCartPage> with AfterLayoutMixin<PackagesCartPage>, SingleTickerProviderStateMixin {
getLanguageID() async {
languageID = await sharedPref.getString(APP_LANGUAGE);
}
double subtotal,tax, total;
double subtotal, tax, total;
@override
void initState() {
_agreeTerms = false;
_selectedPaymentMethod = null;
_animationController =
AnimationController(vsync: this, duration: Duration(seconds: 500));
_animationController = AnimationController(vsync: this, duration: Duration(seconds: 500));
super.initState();
}
@ -69,22 +67,13 @@ class _PackagesCartPageState extends State<PackagesCartPage>
}
onPayNowClick() async {
await viewModel.service
.placeOrder(
context: context,
paymentParams: _selectedPaymentParams)
.then((orderId) {
await viewModel.service.placeOrder(context: context, paymentParams: _selectedPaymentParams).then((orderId) {
if (orderId.runtimeType == int) {
// result == order_id
var browser = MyInAppBrowser(
context: context,
onExitCallback: (data, isDone) => paymentClosed(
orderId: orderId, withStatus: isDone, data: data));
browser.openPackagesPaymentBrowser(
customer_id: viewModel.service.customer.id, order_id: orderId);
var browser = MyInAppBrowser(context: context, onExitCallback: (data, isDone) => paymentClosed(orderId: orderId, withStatus: isDone, data: data));
browser.openPackagesPaymentBrowser(customer_id: viewModel.service.customer.id, order_id: orderId);
} else {
utils.Utils.showErrorToast(
'Failed to place order, please try again later');
utils.Utils.showErrorToast('Failed to place order, please try again later');
}
}).catchError((error) {
utils.Utils.showErrorToast(error.toString());
@ -111,56 +100,48 @@ class _PackagesCartPageState extends State<PackagesCartPage>
isOfferPackages: true,
showOfferPackagesCart: false,
isShowDecPage: false,
showNewAppBar: true,
showNewAppBarTitle: true,
body: Column(
children: [
Expanded(
child: Padding(
padding: const EdgeInsets.all(5),
child: StaggeredGridView.countBuilder(
crossAxisCount: (_columnCount * _columnCount),
itemCount: viewModel.cartItemList.length,
itemBuilder: (BuildContext context, int index) {
var item = viewModel.cartItemList[index];
return Dismissible(
key: Key(index.toString()),
direction: DismissDirection.startToEnd,
background: _cartItemDeleteContainer(),
secondaryBackground: _cartItemDeleteContainer(),
confirmDismiss: (direction) async {
bool status = await viewModel.service
.deleteProductFromCart(item.id,
context: context, showLoading: false);
return status;
},
onDismissed: (direction) {
debugPrint('Index: $index');
viewModel.cartItemList.removeAt(index);
},
child: PackagesCartItemCard(
itemModel: item,
shouldStepperChangeApply: (apply, total) async {
var request = AddProductToCartRequestModel(
product_id: item.productId,
quantity: apply);
ResponseModel response = await viewModel
.service
.addProductToCart(request,
context: context, showLoading: false)
.catchError((error) {
utils.Utils.showErrorToast(error);
});
if(response.status){
fetchData();
}
return response.status ?? false;
},
));
},
staggeredTileBuilder: (int index) =>
StaggeredTile.fit(_columnCount),
mainAxisSpacing: 0,
crossAxisSpacing: 10,
)),
child: StaggeredGridView.countBuilder(
crossAxisCount: (_columnCount * _columnCount),
itemCount: viewModel.cartItemList.length,
itemBuilder: (BuildContext context, int index) {
var item = viewModel.cartItemList[index];
return Dismissible(
key: Key(index.toString()),
direction: DismissDirection.startToEnd,
background: _cartItemDeleteContainer(),
secondaryBackground: _cartItemDeleteContainer(),
confirmDismiss: (direction) async {
bool status = await viewModel.service.deleteProductFromCart(item.id, context: context, showLoading: false);
return status;
},
onDismissed: (direction) {
viewModel.cartItemList.removeAt(index);
},
child: PackagesCartItemCard(
itemModel: item,
viewModel: viewModel,
getCartItems: fetchData,
shouldStepperChangeApply: (apply, total) async {
var request = AddProductToCartRequestModel(product_id: item.productId, quantity: apply);
ResponseModel response = await viewModel.service.addProductToCart(request, context: context, showLoading: false).catchError((error) {
utils.Utils.showErrorToast(error);
});
if (response.status) {
fetchData();
}
return response.status ?? false;
},
));
},
staggeredTileBuilder: (int index) => StaggeredTile.fit(_columnCount),
mainAxisSpacing: 0,
crossAxisSpacing: 10,
),
),
Container(
height: 0.25,
@ -170,8 +151,7 @@ class _PackagesCartPageState extends State<PackagesCartPage>
color: Colors.white,
child: Column(
children: [
Texts(TranslationBase.of(context).selectPaymentOption,
fontSize: 10, fontWeight: FontWeight.bold),
Texts(TranslationBase.of(context).selectPaymentOption, fontSize: 10, fontWeight: FontWeight.bold),
Container(
height: 0.25,
width: 100,
@ -184,11 +164,7 @@ class _PackagesCartPageState extends State<PackagesCartPage>
height: 0.25,
color: Colors.grey[300],
),
Container(
height: 40,
child: _termsAndCondition(context,
onSelected: onTermsClick,
onInfoClick: onTermsInfoClick)),
Container(height: 40, child: _termsAndCondition(context, onSelected: onTermsClick, onInfoClick: onTermsInfoClick)),
Container(
height: 0.25,
color: Colors.grey[300],
@ -204,7 +180,7 @@ class _PackagesCartPageState extends State<PackagesCartPage>
}
fetchData() async {
await viewModel.service.cartItems(context: context).then((value){
await viewModel.service.cartItems(context: context).then((value) {
subtotal = value['subtotal'] ?? 0.0;
tax = value['tax'] ?? 0.0;
total = value['total'] ?? 0.0;
@ -213,15 +189,12 @@ class _PackagesCartPageState extends State<PackagesCartPage>
setState(() {});
}
paymentClosed(
{@required int orderId, @required bool withStatus, dynamic data}) async {
paymentClosed({@required int orderId, @required bool withStatus, dynamic data}) async {
viewModel.service.getOrderById(orderId, context: context).then((value) {
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}";
Navigator.of(context).pushReplacement(MaterialPageRoute(
builder: (context) => PackageOrderCompletedPage(
heading: heading, title: title, subTitle: subTitle)));
Navigator.of(context).pushReplacement(MaterialPageRoute(builder: (context) => PackageOrderCompletedPage(heading: heading, title: title, subTitle: subTitle)));
}).catchError((error) {
debugPrint(error);
});
@ -231,7 +204,8 @@ class _PackagesCartPageState extends State<PackagesCartPage>
// /* Payment Footer Widgets */
// ---------------------------
String _selectedPaymentMethod;
Map<dynamic,dynamic> _selectedPaymentParams;
Map<dynamic, dynamic> _selectedPaymentParams;
Widget _paymentOptions(BuildContext context, Function(String) onSelected, {PackagesViewModel viewModel}) {
double height = 30;
@ -247,18 +221,17 @@ Widget _paymentOptions(BuildContext context, Function(String) onSelected, {Packa
),
],
borderRadius: BorderRadius.all(Radius.circular(5)),
border: Border.all(
color: isSelected ? Colors.green : Colors.grey,
width: isSelected ? 1 : 0.5)),
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{
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);
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;
}
@ -272,9 +245,9 @@ Widget _paymentOptions(BuildContext context, Function(String) onSelected, {Packa
children: [
InkWell(
child: buttonContent(_selectedPaymentMethod == "tamara", 'tamara.png'),
onTap: () async{
onTap: () async {
final tamara_option = await selectTamaraPaymentOption();
_selectedPaymentParams = {"channel" : "Web", "payment_method_system_name" : "Payments.Tamara", "payment_option" : tamara_option};
_selectedPaymentParams = {"channel": "Web", "payment_method_system_name": "Payments.Tamara", "payment_option": tamara_option};
onSelected("tamara");
},
),
@ -284,7 +257,7 @@ Widget _paymentOptions(BuildContext context, Function(String) onSelected, {Packa
InkWell(
child: buttonContent(_selectedPaymentMethod == "mada", 'mada.png'),
onTap: () {
_selectedPaymentParams = {"payment_method_system_name" : "Payments.PayFort", "payment_option" : "MADA"};
_selectedPaymentParams = {"payment_method_system_name": "Payments.PayFort", "payment_option": "MADA"};
onSelected("mada");
},
),
@ -294,7 +267,7 @@ Widget _paymentOptions(BuildContext context, Function(String) onSelected, {Packa
InkWell(
child: buttonContent(_selectedPaymentMethod == "visa", 'visa.png'),
onTap: () {
_selectedPaymentParams = {"payment_method_system_name" : "Payments.PayFort", "payment_option" : "VISA"};
_selectedPaymentParams = {"payment_method_system_name": "Payments.PayFort", "payment_option": "VISA"};
onSelected("visa");
},
),
@ -304,7 +277,7 @@ Widget _paymentOptions(BuildContext context, Function(String) onSelected, {Packa
InkWell(
child: buttonContent(_selectedPaymentMethod == "mastercard", 'mastercard.png'),
onTap: () {
_selectedPaymentParams = {"payment_method_system_name" : "Payments.PayFort", "payment_option" : "MASTERCARD"};
_selectedPaymentParams = {"payment_method_system_name": "Payments.PayFort", "payment_option": "MASTERCARD"};
onSelected("mastercard");
},
),
@ -326,17 +299,15 @@ Widget _paymentOptions(BuildContext context, Function(String) onSelected, {Packa
}
bool _agreeTerms = false;
Widget _termsAndCondition(BuildContext context,
{@required Function(bool) onSelected, @required VoidCallback onInfoClick}) {
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,
_agreeTerms ? Icons.check_circle : Icons.radio_button_unchecked_sharp,
size: 20,
color: _agreeTerms ? Colors.green[600] : Colors.grey[400],
),
@ -386,18 +357,8 @@ Widget _payNow(BuildContext context, {double subtotal, double tax, double total,
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),
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(
@ -406,12 +367,7 @@ Widget _payNow(BuildContext context, {double subtotal, double tax, double total,
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)
Texts('${TranslationBase.of(context).total}: $_total ${TranslationBase.of(context).sar}', heightFactor: 1.5, fontWeight: FontWeight.bold, color: Colors.black54, fontSize: 15)
],
),
),
@ -425,10 +381,7 @@ Widget _payNow(BuildContext context, {double subtotal, double tax, double total,
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)),
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,
),

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

@ -509,7 +509,7 @@ class TranslationBase {
String get switchUser => localizedValues['switch-login'][locale.languageCode];
String get removeMember => localizedValues['remove-membe'][locale.languageCode];
String get removeMember => localizedValues['remove-member'][locale.languageCode];
String get allowView => localizedValues['allow-view'][locale.languageCode];
@ -2620,6 +2620,10 @@ class TranslationBase {
String get RRTSubTitle => localizedValues["RRTSubTitle"][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 waist => localizedValues["waist"][locale.languageCode];
String get hip => localizedValues["hip"][locale.languageCode];

@ -1,217 +1,136 @@
import 'package:diplomaticquarterapp/core/model/packages_offers/responses/PackagesCartItemsResponseModel.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/utils.dart';
import 'package:diplomaticquarterapp/uitl/utils_new.dart';
import 'package:diplomaticquarterapp/widgets/CounterView.dart';
import 'package:diplomaticquarterapp/widgets/data_display/text.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';
bool wide = true;
class PackagesCartItemCard extends StatefulWidget {
final PackagesCartItemsResponseModel itemModel;
final StepperCallbackFuture shouldStepperChangeApply ;
final StepperCallbackFuture shouldStepperChangeApply;
final PackagesViewModel viewModel;
final Function getCartItems;
const PackagesCartItemCard(
{
@required this.itemModel,
@required this.shouldStepperChangeApply,
Key key})
: super(key: key);
const PackagesCartItemCard({@required this.itemModel, @required this.shouldStepperChangeApply, @required this.viewModel, this.getCartItems, Key key}) : super(key: key);
@override
State<StatefulWidget> createState() => PackagesCartItemCardState();
}
class PackagesCartItemCardState extends State<PackagesCartItemCard> {
@override
Widget build(BuildContext context) {
wide = !wide;
return Container(
color: Colors.transparent,
child: Card(
elevation: 3,
shadowColor: Colors.grey[100],
color: Colors.white,
child: Stack(
children: [
Container(
height: 100,
child: Row(
children: [
_image(widget.itemModel.product),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.center,
decoration: cardRadius(15.0),
margin: EdgeInsets.only(left: 21.0, right: 21.0, top: 12.0),
height: 90,
child: Row(
mainAxisSize: MainAxisSize.max,
children: [
_image(widget.itemModel.product),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
_itemName(widget.itemModel.product.getName()),
_itemDescription(widget.itemModel.product.shortDescription),
Container(
padding: const EdgeInsets.only(top: 12.0),
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: [
_itemName(widget.itemModel.product.getName()),
Row(
children: [
_itemPrice(widget.itemModel.product.price, context: context),
_priceSeperator(),
_itemOldPrice(widget.itemModel.product.oldPrice, context: context),
],
),
Row(
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;
}
Padding(
padding: const EdgeInsets.only(left: 5.0, right: 5.0),
child: Text(
TranslationBase.of(context).removeMember,
style: TextStyle(
fontSize: 10,
color: CustomColors.accentColor,
fontWeight: FontWeight.w600,
letterSpacing: -0.36,
),
],
),
),
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(
aspectRatio: 1/1,
child: Padding(
padding: const EdgeInsets.all(10),
child: Container(
decoration: BoxDecoration(
border: Border.all(color: Colors.grey[300], width: 0.25),
boxShadow: [
BoxShadow(color: Colors.grey[200], blurRadius: 2.0, spreadRadius: 1, offset: Offset(1,1.5))
],
borderRadius: BorderRadius.circular(8),
color: Colors.white,
shape: BoxShape.rectangle,
),
child: ClipRRect(
borderRadius: BorderRadius.circular(8),
child: (model.images.isNotEmpty)
? Utils.loadNetworkImage(url: model.images.first.src, fitting:BoxFit.fill)
: Container(color: Colors.grey[200])
aspectRatio: 1 / 1,
child: Padding(
padding: const EdgeInsets.all(9),
child: Container(
decoration: BoxDecoration(
border: Border.all(color: Colors.grey[300], width: 0.25),
boxShadow: [BoxShadow(color: Colors.grey[200], blurRadius: 2.0, spreadRadius: 1, offset: Offset(1, 1.5))],
borderRadius: BorderRadius.circular(15),
color: Colors.white,
shape: BoxShape.rectangle,
),
child: ClipRRect(
borderRadius: BorderRadius.circular(15),
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(
padding: const EdgeInsets.all(0),
child: Texts(
name,
fontWeight: FontWeight.normal,
color: Colors.black,
fontSize: 15
)
);
padding: const EdgeInsets.only(top: 9.0),
child: Text(name,
style: TextStyle(
fontSize: 14,
fontWeight: FontWeight.bold,
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}) {
final prc = (price ?? 0.0).toStringAsFixed(2);
return Padding(
padding: const EdgeInsets.all(0),
child: Texts(
'${prc} ${TranslationBase.of(context).sar}',
fontWeight: FontWeight.bold,
color: Colors.green,
fontSize: 15
)
);
}
// --------------------
// 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
)
);
child: Text(
'${prc} ${TranslationBase.of(context).sar}',
style: TextStyle(
fontSize: 11,
fontWeight: FontWeight.w600,
letterSpacing: -0.4,
),
),
);
}
// --------------------
// 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/pages/packages_offers/OfferAndPackageDetailPage.dart';
import 'package:diplomaticquarterapp/theme/colors.dart';
import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart';
import 'package:diplomaticquarterapp/uitl/utils.dart';
import 'package:diplomaticquarterapp/uitl/utils_new.dart';
import 'package:diplomaticquarterapp/widgets/data_display/text.dart';
import 'package:diplomaticquarterapp/widgets/others/StarRating.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:rating_bar/rating_bar.dart';
bool wide = true;
@ -15,15 +20,7 @@ class PackagesItemCard extends StatefulWidget {
final PackagesResponseModel itemModel;
final Function(PackagesResponseModel product) onCartClick;
const PackagesItemCard(
{
this.itemWidth,
this.itemHeight,
@required this.itemModel,
@required this.itemContentPadding,
@required this.onCartClick,
Key key})
: super(key: key);
const PackagesItemCard({this.itemWidth, this.itemHeight, @required this.itemModel, @required this.itemContentPadding, @required this.onCartClick, Key key}) : super(key: key);
@override
State<StatefulWidget> createState() => PackagesItemCardState();
@ -35,122 +32,58 @@ class PackagesItemCardState extends State<PackagesItemCard> {
@override
Widget build(BuildContext context) {
wide = !wide;
return Directionality(
textDirection: TextDirection.rtl,
child: Stack(
children: [
Padding(
padding: EdgeInsets.only(
left: widget.itemContentPadding,
right: widget.itemContentPadding,
top: widget.itemContentPadding + 5),
child: Container(
width: widget.itemWidth,
color: Colors.transparent,
child: Stack(
return InkWell(
onTap: () {
Navigator.of(context).push(MaterialPageRoute(builder: (BuildContext context) => OfferAndPackagesDetail(itemModel: widget.itemModel, onCartClick: widget.onCartClick)));
},
child: Container(
// width: widget.itemWidth,
// color: Colors.transparent,
decoration: cardRadius(15.0),
width: MediaQuery.of(context).size.width * 0.46,
padding: const EdgeInsets.all(9.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
ClipRRect(
borderRadius: BorderRadius.circular(15.0),
child: Image.network("https://mdlaboratories.com/offersdiscounts/images/thumbs/0000162_dermatology-testing.jpeg", fit: BoxFit.fill, height: 180.0, width: 180.0),
),
Container(margin: const EdgeInsets.only(top: 8.0), child: Text(widget.itemModel.name, maxLines: 1, style: TextStyle(fontSize: 14.0, fontWeight: FontWeight.bold, letterSpacing: -0.56))),
Container(width: MediaQuery.of(context).size.width * 0.4, child: Text("Special discount for all HMG Employees and their first…", maxLines: 2, style: TextStyle(fontSize: 10.0, fontWeight: FontWeight.w600, letterSpacing: -0.4, color: CustomColors.textColor), overflow: TextOverflow.clip)),
if (widget.itemModel.hasDiscountsApplied) Container(margin: const EdgeInsets.only(top: 19.0), child: Text(widget.itemModel.oldPrice.toString() + " " + TranslationBase.of(context).sar, style: TextStyle(fontSize: 9.0, fontWeight: FontWeight.w600, letterSpacing: -0.36, decoration: TextDecoration.lineThrough, color: CustomColors.grey2))),
Container(
margin: widget.itemModel.hasDiscountsApplied ? const EdgeInsets.only(top: 0.0) : const EdgeInsets.only(top: 19.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Column(
mainAxisSize: MainAxisSize.max,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
AspectRatio(
aspectRatio:1 / 1,
child: applyShadow(
child: ClipRRect(
borderRadius: BorderRadius.circular(10),
child: Utils.loadNetworkImage(
url: imageUrl(),
)),
)),
Texts(
widget.itemModel.getName(),
fontWeight: FontWeight.normal,
color: Colors.black,
fontSize: 15
),
Padding(
padding: const EdgeInsets.only(left: 10, right: 10),
child: Row(
crossAxisAlignment: CrossAxisAlignment.end,
mainAxisSize: MainAxisSize.max,
children: [
Stack(
children: [
Texts(
'${widget.itemModel.oldPrice} ${'SAR'}',
fontWeight: FontWeight.normal,
decoration: TextDecoration.lineThrough,
color: Colors.grey,
fontSize: 12
),
Padding(
padding: const EdgeInsets.only(top: 8),
child: Texts(
'${widget.itemModel.price} ${'SAR'}',
fontWeight: FontWeight.bold,
color: Colors.green,
fontSize: 18
),
),
Padding(
padding: const EdgeInsets.only(top: 35),
child: StarRating(
size: 15,
totalCount: null,
totalAverage: widget.itemModel.approvedRatingSum.toDouble(),
forceStars: true),
)
],
),
Spacer(
flex: 1,
),
InkWell(
child: Icon(
Icons.add_shopping_cart_rounded,
size: 30.0,
color: Colors.grey,
),
onTap: () {
widget.onCartClick(widget.itemModel);
},
),
],
),
Container(margin: const EdgeInsets.only(top: 0.0), child: Text(widget.itemModel.price.toString().trim() + " " + TranslationBase.of(context).sar, style: TextStyle(fontSize: 12.0, fontWeight: FontWeight.bold, letterSpacing: -0.56))),
RatingBar.readOnly(
initialRating: 4.5,
size: 18.0,
filledColor: Color(0XFFD02127),
emptyColor: Color(0XFFD02127),
isHalfAllowed: true,
halfFilledIcon: Icons.star_half,
filledIcon: Icons.star,
emptyIcon: Icons.star_border,
),
],
),
InkWell(
child: 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