Merge branch 'ZohaibIqbalKambrani' of https://gitlab.com/Cloud_Solution/driver-app into development

 Conflicts:
	pubspec.yaml
development
Elham Rababh 3 years ago
commit 7b20f789f6

@ -43,6 +43,8 @@ android {
targetSdkVersion 30
versionCode flutterVersionCode.toInteger()
versionName flutterVersionName
multiDexEnabled true
}
buildTypes {

@ -24,8 +24,7 @@
to determine the Window background behind the Flutter UI. -->
<meta-data
android:name="io.flutter.embedding.android.NormalTheme"
android:resource="@style/NormalTheme"
/>
android:resource="@style/NormalTheme" />
<!-- Displays an Android View that continues showing the launch screen
Drawable until Flutter paints its first frame, then this splash
screen fades out. A splash screen is useful to avoid any visual

@ -0,0 +1 @@
include ':app'

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 919 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 54 KiB

@ -2,26 +2,27 @@ import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
/// End points
const BASE_URL = 'https://hmgwebservices.com/Services';
const GET_PROJECT = '/Lists.svc/REST/GetProject';
const LOGIN = "/Authentication.svc/REST/CheckDriverAuthentication";
const GET_OPT =
"/Patients.svc/REST/PatientER_Delivery_SendSMSForForgetPassword";
const CHECK_ACTIVATION_CODE =
"/Patients.svc/REST/PatientER_Delivery_CheckActivationCodeForForgetPassword";
const CHANGE_FORGOT_PASSWORD =
"/Patients.svc/REST/PatientER_Delivery_ChangeForgetedPasswordForDriver";
const GET_ALL_ORDERS = '/Patients.svc/REST/PatientER_Delivery_GetAllOrder';
const SCAN_QR = '/Patients.svc/REST/PatientER_Delivery_OrderInsert';
const UPDATE_ORDER_STATUS =
'/Patients.svc/REST/PatientER_Delivery_UpdateOrderStatus';
const NEXT_ORDER = "/Patients.svc/REST/PatientER_Delivery_NextOrder";
const GET_ALL_DELIVERD_ORDER =
'/Patients.svc/REST/PatientER_Delivery_GetAllDeliverdOrder';
const GET_ALL_ORDERS_STATUS =
'/Patients.svc/REST/PatientER_Delivery_GetAllOrderstatus';
const isUAT = true;
const BASE_URL = 'https://${isUAT ? "uat." : ""}hmgwebservices.com/';
const PING_SERVICE = '/Services/Weather.svc/REST/CheckConnectivity';
const GET_PROJECT = '/Services/Lists.svc/REST/GetProject';
const LOGIN = "/Services/Authentication.svc/REST/CheckDriverAuthentication";
const GET_OPT = "/Services/Patients.svc/REST/PatientER_Delivery_SendSMSForForgetPassword";
const CHECK_ACTIVATION_CODE = "/Services/Patients.svc/REST/PatientER_Delivery_CheckActivationCodeForForgetPassword";
const CHANGE_FORGOT_PASSWORD = "/Services/Patients.svc/REST/PatientER_Delivery_ChangeForgetedPasswordForDriver";
const GET_ALL_ORDERS = '/Services/Patients.svc/REST/PatientER_Delivery_GetAllOrder';
const SCAN_QR = '/Services/Patients.svc/REST/PatientER_Delivery_OrderInsert';
const UPDATE_ORDER_STATUS = '/Services/Patients.svc/REST/PatientER_Delivery_UpdateOrderStatus';
const NEXT_ORDER = "/Services/Patients.svc/REST/PatientER_Delivery_NextOrder";
const UPDATE_DRIVER_LOCATION = "/Services/Patients.svc/REST/PatientER_DriverLocation_Insert";
const INITIATE_DELIVERY = "/epharmacy/api/sendsmstocustomerfordriver";
const VERIFY_DELIVERY = "/Services/Patients.svc/REST/PatientER_ValidateSentOutForDeliveryOTPCode";
const GET_ALL_DELIVERD_ORDER = '/Services/Patients.svc/REST/PatientER_Delivery_GetAllDeliverdOrder';
const GET_ALL_ORDERS_STATUS = '/Services/Patients.svc/REST/PatientER_Delivery_GetAllOrderstatus';
/// Body Constant
const CHANNEL = 9;
@ -41,3 +42,11 @@ const LINEAR_GRADIENT = LinearGradient(
],
// stops: [0.0, 1.0],
);
abstract class DeliveryStatus{
static final int pending = 1;
static final int delivered = 2;
static final int rejected = 3;
static final int cancel = 4;
}

@ -82,4 +82,45 @@ const Map<String, Map<String, String>> localizedValues = {
'en': 'Please Enter your OPT code sent to your phone',
'ar': 'الرجاء إدخال رمز OPT الخاص بك المرسل إلى هاتفك'
},
'enterCustomerVerificationCodeMsg': {
'en': 'Please enter OTP sent to customer phone',
'ar': 'Please enter OTP sent to customer phone'
},
'startDelivery': {
'en': 'Start Delivery',
'ar': 'Start Delivery'
},
'deliveryOption': {
'en': 'Delivery Option',
'ar': 'Delivery Option'
},
'selectReason': {
'en': 'Select Reason',
'ar': 'Select Reason'
},
'accident': {
'en': 'Got accident',
'ar': 'Got accident'
},
'notReachableOnPhoneCall': {
'en': 'Not reachable on phone call',
'ar': 'Not reachable on phone call'
},
'notAvailableAtlocation': {
'en': 'Not available at location',
'ar': 'Not available at location'
},
'deliverLater': {
'en': 'Deliver later',
'ar': 'Deliver later'
},
'other': {
'en': 'Other...',
'ar': 'Other...'
},
};

@ -1,5 +1,6 @@
const TOKEN = 'token';
const APP_LANGUAGE = 'language';
const USER_PROFILE = 'user-profile';
const ACTIVE_DELIVERIES = 'active-order-deliveries';

@ -0,0 +1,11 @@
class ResponseModel<T>{
bool isSuccessful = false;
String message;
T data;
isSuccessfull(Function(bool) callback){
callback(isSuccessful);
}
ResponseModel({this.message, this.isSuccessful, this.data});
}

@ -0,0 +1,12 @@
class RequestInitiateOrderDelivery{
int orderNo = 0;
String mobileNumber = "";
RequestInitiateOrderDelivery({this.orderNo, this.mobileNumber});
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['OrderNo'] = this.orderNo;
data['MobileNumber'] = this.mobileNumber;
return data;
}
}

@ -0,0 +1,12 @@
class RequestValidateDelivery{
String pinCode;
int orderNo;
RequestValidateDelivery({this.orderNo,this.pinCode});
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['Password'] = this.pinCode;
data['OrderNo'] = this.orderNo;
return data;
}
}

@ -0,0 +1,3 @@
class ResponseInitiateOrderDelivery{
}

@ -27,6 +27,11 @@ class PendingOrdersRes {
dynamic distanceInKilometers;
List<ItemsQuantitiesList> itemsQuantitiesList;
String receiverFullName(){
var fullName = "${firstName ?? ''} ${middleName ?? ''} ${lastName ?? ''}";
return fullName;
}
PendingOrdersRes(
{this.rowID,
this.orderID,

@ -0,0 +1,23 @@
import 'package:driverapp/config/shared_pref_kay.dart';
import 'package:driverapp/core/model/authentication/authenticated_user.dart';
import 'package:driverapp/uitl/app_shared_preferences.dart';
import 'package:location/location.dart';
class RequestUpdateDriverLocation{
int orderID = 0;
LocationData location;
RequestUpdateDriverLocation({this.orderID,this.location});
Future<Map<String, dynamic>> toJson() async{
final Map<String, dynamic> data = new Map<String, dynamic>();
data['OrderID'] = this.orderID;
data['Latitude'] = "${this.location.latitude}";
data['Longitude'] = "${this.location.longitude}";
Map profile = await AppSharedPreferences().getObject(USER_PROFILE);
AuthenticatedUser doctorProfile = AuthenticatedUser.fromJson(profile);
data['DriverID'] = doctorProfile?.iD;
data['UserID'] = '${doctorProfile?.iD}';
return data;
}
}

@ -16,21 +16,23 @@ AppSharedPreferences sharedPref = new AppSharedPreferences();
/// body: null);
class BaseAppClient {
post(
String endPoint, {
Map<String, dynamic> body,
Function(dynamic response, int statusCode) onSuccess,
Function(String error, int statusCode) onFailure,
}) async {
String _Statictoken = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9";
post(
String endPoint, {
Map<String, dynamic> body,
Function(dynamic response, int statusCode) onSuccess,
Function(String error, int statusCode) onFailure}) async {
String url = BASE_URL + endPoint;
try {
Map profile = await sharedPref.getObject(USER_PROFILE);
String token = await sharedPref.getString(TOKEN);
if (profile != null) {
AuthenticatedUser doctorProfile = AuthenticatedUser.fromJson(profile);
body['DriverID'] = doctorProfile?.userID;
if(!body.keys.contains('DriverID') || body['DriverID'] == null)
body['DriverID'] = doctorProfile?.userID;
if(!body.keys.contains('UserID') || body['UserID'] == null)
body['UserID'] = '${doctorProfile?.userID}';
body['CreatedBy'] = doctorProfile?.userID;
body['UserID'] = '${doctorProfile?.userID}';
body['TokenID'] = token;
body['MobileNo'] = doctorProfile?.mobileNumber;
}
@ -45,7 +47,8 @@ class BaseAppClient {
body: json.encode(body),
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json'
'Accept': 'application/json',
'Statictoken': _Statictoken
});
final int statusCode = response.statusCode;
if (statusCode < 200 || statusCode >= 400 || json == null) {
@ -56,11 +59,11 @@ class BaseAppClient {
// await helpers.logout();
//helpers.showErrorToast('Your session expired Please login agian');
// TODO create logout fun
onFailure("Unauthorized", 401);
} else if (parsed['MessageStatus'] == 1) {
onSuccess(parsed, statusCode);
} else {
onFailure(parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'],
statusCode);
onFailure(parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'], statusCode);
}
}
} else {
@ -71,4 +74,66 @@ class BaseAppClient {
onFailure(e.toString(), -1);
}
}
get(
String endPoint, {
Map<String, dynamic> body,
Function(dynamic response, int statusCode) onSuccess,
Function(String error, int statusCode) onFailure}) async {
String url = BASE_URL + endPoint;
try {
if (await Utils.checkConnection()) {
final response = await http.get(url,
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json',
'Statictoken': _Statictoken
});
final int statusCode = response.statusCode;
if (statusCode < 200 || statusCode >= 400 || json == null) {
onFailure('Error While Fetching data', statusCode);
} else {
var parsed = json.decode(response.body.toString());
if (parsed['MessageStatus'] == 1) {
onSuccess(parsed, statusCode);
} else {
onFailure(parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'], statusCode);
}
}
} else {
onFailure('Please Check The Internet Connection', -1);
}
} catch (e) {
print(e);
onFailure(e.toString(), -1);
}
}
simpleGet(
String url,
{ Function(dynamic response, int statusCode) onSuccess,
Function(String error, int statusCode) onFailure}) async {
try {
if (await Utils.checkConnection()) {
final response = await http.get(url,
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json',
'Statictoken': _Statictoken
});
final int statusCode = response.statusCode;
if (statusCode < 200 || statusCode >= 400) {
onFailure('Error While Fetching data', statusCode);
} else {
onSuccess(response.body, statusCode);
}
} else {
onFailure('Please Check The Internet Connection', -1);
}
} catch (e) {
print(e);
onFailure(e.toString(), -1);
}
}
}

@ -0,0 +1,141 @@
import 'dart:collection';
import 'dart:math';
import 'package:driverapp/config/config.dart';
import 'package:driverapp/config/shared_pref_kay.dart';
import 'package:driverapp/core/model/StatusModel.dart';
import 'package:driverapp/core/model/order_delivey/request_initiate_order_delivery.dart';
import 'package:driverapp/core/model/order_delivey/request_validate_delivery.dart';
import 'package:driverapp/core/model/orders/pending_orders_res_model.dart';
import 'package:driverapp/core/model/update_driver_location/request_update_driver_location.dart';
import 'package:driverapp/core/service/base_service.dart';
import 'package:driverapp/uitl/app_shared_preferences.dart';
import 'package:driverapp/uitl/utils.dart';
import 'package:flutter/cupertino.dart';
import 'package:latlong/latlong.dart';
import 'package:location/location.dart';
import 'package:shared_preferences/shared_preferences.dart';
class DeliveryTrackingServices extends BaseService {
var _distanceFilter = 20; // [Meters] (Call update API if distance covered from last location is greater then 'value' )
Future<ResponseModel> initiateOrderDelivery(PendingOrdersRes order) async {
hasError = false;
var testNumber = "";
ResponseModel result;
// var orderRequest = RequestInitiateOrderDelivery(orderNo: order.ePharmacyOrderNo, mobileNumber: testNumber == "" ? order.mobileNumber : testNumber);
var fullUrl = BASE_URL + INITIATE_DELIVERY + "/${order.ePharmacyOrderNo}/${user.iD}";
await baseAppClient.simpleGet(fullUrl,
onSuccess: (dynamic response, int statusCode) {
result = ResponseModel(isSuccessful: true,message: null, data: response);
startLocationUpdate(order.ePharmacyOrderNo);
}, onFailure: (String error, int statusCode) {
result = ResponseModel(isSuccessful: false,message: error,data: null);
});
return result;
}
Future<ResponseModel> validateDelivery(PendingOrdersRes order, String pinCode) async{
hasError = false;
var request = RequestValidateDelivery(orderNo: order.ePharmacyOrderNo, pinCode: pinCode);
ResponseModel result;
await baseAppClient.post(VERIFY_DELIVERY,
onSuccess: (dynamic response, int statusCode) {
result = ResponseModel(isSuccessful: true,message: null, data: response);
}, onFailure: (String error, int statusCode) {
result = ResponseModel(isSuccessful: false,message: error,data: null);
}, body: request.toJson());
return result;
}
_updateDriverLocation(int orderID, LocationData location) async {
if(location != null){
debugPrint("Updating driver location");
var jsonBody = await RequestUpdateDriverLocation(orderID: orderID, location: location).toJson();
await baseAppClient.post(UPDATE_DRIVER_LOCATION,
onSuccess: (dynamic response, int statusCode) {
}, onFailure: (String errorMessage, int statusCode) {
if(statusCode == 200){
// Server responded but check failed (stop updating location)
// stopLocationUpdate(orderID);
// Show error message that you received in response
}
}, body: jsonBody);
}
}
Map _currentRunnings = Map<String,Future>();
Future<Object> startLocationUpdate(int orderID, {int frequencyInSeconds = 3}) async {
if (_currentRunnings[orderID.toString()] == null){
_currentRunnings[orderID.toString()] = Future.doWhile(() async{
await Future.delayed(Duration(seconds: frequencyInSeconds));
var valid = _currentRunnings.containsKey(orderID.toString());
if(valid){
Utils.possibleToGetLocation((value) async{
if(value){
var location = await Utils.getLocation();
if (_haveEnoughLocationUpdate(location))
await _updateDriverLocation(orderID, location);
}
});
}
return valid;
});
}
SharedPreferences.getInstance().then((pref){
pref.setStringList(ACTIVE_DELIVERIES, _currentRunnings.keys.toList());
});
}
bool isActiveDeliveringOrder(int ePharmacyOrderNo){
return _currentRunnings.containsKey(ePharmacyOrderNo.toString());
}
List<String> getActiveDeliveringOrders(){
return _currentRunnings.keys.toList(growable: false);
}
setActiveDeliveringOrders(List<String> orders){
orders.forEach((element) {
if(!_currentRunnings.containsKey(element)){
_currentRunnings[element] = null;
}
});
}
clearActiveDeliveringOrders(){
_currentRunnings.clear();
SharedPreferences.getInstance().then((pref){
pref.setStringList(ACTIVE_DELIVERIES, _currentRunnings.keys.toList());
});
}
stopLocationUpdate(int orderID){
_currentRunnings.remove(orderID.toString());
SharedPreferences.getInstance().then((pref){
pref.setStringList(ACTIVE_DELIVERIES, _currentRunnings.keys.toList());
});
}
LocationData _lastLocation;
bool _haveEnoughLocationUpdate(LocationData location){
_lastLocation = _lastLocation ?? location;
var distanceCovered = Utils.distanceBetween(_lastLocation, location, LengthUnit.Meter);
// debugPrint("distance: $distanceCovered");
return (distanceCovered > _distanceFilter);
}
}

@ -79,11 +79,11 @@ class OrdersService extends BaseService {
try {
await baseAppClient.post(GET_ALL_ORDERS_STATUS,
onSuccess: (dynamic response, int statusCode) {
listCountDelivered =
listCountDelivered =
response["PatientER_CountOrderList"][0]["NumberOfDeliveredOrder"];
listCountUnDelivered =
listCountUnDelivered =
response["PatientER_CountOrderList"][0]["NumberOfUnDeliveredOrder"];
}, onFailure: (String error, int statusCode) {
}, onFailure: (String error, int statusCode) {
hasError = true;
super.error = error;
}, body: {});
@ -100,10 +100,9 @@ class OrdersService extends BaseService {
try {
await baseAppClient.post(UPDATE_ORDER_STATUS,
onSuccess: (dynamic response, int statusCode) {
isOrderStatusUpdated =
response["PatientER_Delivery_IsOrderUpdated"];
listCountUnDelivered --;
listCountDelivered ++;
isOrderStatusUpdated = response["PatientER_Delivery_IsOrderUpdated"];
listCountUnDelivered--;
listCountDelivered++;
}, onFailure: (String error, int statusCode) {
hasError = true;
super.error = error;
@ -137,13 +136,12 @@ class OrdersService extends BaseService {
Future getDeliveredList() async {
LocationData loc = await Utils.getLocation();
PendingOrders _requestGetPendingOrders = PendingOrders(
searchKey: "",
pageSize: 0,
pageIndex: 0,
latitude: loc.latitude.toString(),
longitude: loc.longitude.toString(),
driverAppPageID: 0
);
searchKey: "",
pageSize: 0,
pageIndex: 0,
latitude: loc.latitude.toString(),
longitude: loc.longitude.toString(),
driverAppPageID: 0);
if (loc != null) {
hasError = false;
try {

@ -1,16 +1,20 @@
import 'package:driverapp/core/enum/viewstate.dart';
import 'package:driverapp/core/model/StatusModel.dart';
import 'package:driverapp/core/model/orders/deliverd_order_res_model.dart';
import 'package:driverapp/core/model/orders/next_order_request_model.dart';
import 'package:driverapp/core/model/orders/pending_orders_res_model.dart';
import 'package:driverapp/core/model/orders/update_order_status_request_model.dart';
import 'package:driverapp/core/model/scan_qr/scan_qr_request_model.dart';
import 'package:driverapp/core/service/delivery_tracking_services.dart';
import 'package:driverapp/core/service/orders_service.dart';
import 'package:flutter/cupertino.dart';
import '../../locator.dart';
import 'base_view_model.dart';
class OrdersViewModel extends BaseViewModel {
OrdersService _ordersService = locator<OrdersService>();
DeliveryTrackingServices deliveryService = locator<DeliveryTrackingServices>();
List<PendingOrdersRes> get orders => _ordersService.orders;
@ -64,15 +68,37 @@ class OrdersViewModel extends BaseViewModel {
setState(ViewState.Idle);
}
Future updateOrderStatus(
UpdateOrderStatusRequestModel updateOrderStatusRequestModel) async {
Future<ResponseModel> updateOrderStatus({@required int orderNo, @required int status, String rejectionReason}) async {
var updateOrderStatusRequestModel
= UpdateOrderStatusRequestModel(
deliveryOrderID: orderNo,
deliveryOrderStatus: status,
rejectionReason: rejectionReason,
cancleReason: rejectionReason);
setState(ViewState.BusyLocal);
await _ordersService.updateOrderStatus(updateOrderStatusRequestModel);
if (_ordersService.hasError) {
error = _ordersService.error;
setState(ViewState.ErrorLocal);
} else
return ResponseModel(isSuccessful: false, message: error);
} else {
setState(ViewState.Idle);
if(status == 2)
moveOrderFromPendingToDelivered(orderNo);
return ResponseModel(isSuccessful: true, message: "Successful");
}
}
moveOrderFromPendingToDelivered(int orderNo) async{
var idx = orders.indexWhere((element) => element.ePharmacyOrderNo == orderNo);
var order = orders[idx];
orders.removeAt(idx);
var order_delivered = DeliverdOrderResModel.fromJson(order.toJson());
order_delivered.description = "Delivered";
order_delivered.descriptionN = "Delivered";
deliverdOrders.add(order_delivered);
}
Future nextOrder(NextOrderRequestModel nextOrderRequestModel) async {
@ -85,6 +111,31 @@ class OrdersViewModel extends BaseViewModel {
setState(ViewState.Idle);
}
Future initDelivery(PendingOrdersRes order, {Function(@required ResponseModel response) completion}) async{
var response = await deliveryService.initiateOrderDelivery(order);
completion(response ?? ResponseModel(isSuccessful: false,message: "Something went wrong, Please try again later."));
return response;
// (true, response['ErrorEndUserMessage'] ?? response['ErrorMessage'] ?? "Successfully, Please start navigation.")
}
Future<ResponseModel> validateDelivery(PendingOrdersRes order, String pinCode) async{
return await deliveryService.validateDelivery(order, pinCode);
}
Future<ResponseModel> resendOtpToReceiver(PendingOrdersRes order) async{
// return await _deliveryService.validateDelivery(order, pinCode);
}
bool isActiveDeliveringOrder(int index){
return deliveryService.isActiveDeliveringOrder(orders[index].ePharmacyOrderNo);
}
Future<List<String>> getActiveDeliveringOrders() async{
return deliveryService.getActiveDeliveringOrders();
}
showBottomSheet() {
isBottomSheetAppear = true;
setState(ViewState.Idle);

@ -1,3 +1,4 @@
import 'package:driverapp/core/service/delivery_tracking_services.dart';
import 'package:get_it/get_it.dart';
import 'core/service/authentication_service.dart';
@ -15,6 +16,7 @@ void setupLocator() {
locator.registerLazySingleton(() => HospitalService());
locator.registerLazySingleton(() => AuthenticationService());
locator.registerLazySingleton(() => OrdersService());
locator.registerLazySingleton(() => DeliveryTrackingServices());
/// View Model
locator.registerFactory(() => HospitalViewModel());

@ -1,9 +1,14 @@
import 'package:driverapp/core/service/delivery_tracking_services.dart';
import 'package:driverapp/core/viewModels/orders_view_model.dart';
import 'package:driverapp/pages/splash_screen_page.dart';
import 'package:driverapp/uitl/app_shared_preferences.dart';
import 'package:driverapp/uitl/translations_delegate_base.dart';
import 'package:flutter/material.dart';
import 'package:flutter_localizations/flutter_localizations.dart';
import 'package:provider/provider.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'config/shared_pref_kay.dart';
import 'config/size_config.dart';
import 'core/viewModels/authentication_view_model.dart';
import 'core/viewModels/project_view_model.dart';
@ -14,9 +19,30 @@ void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
class MyApp extends StatelessWidget with WidgetsBindingObserver{
@override
void didChangeAppLifecycleState(AppLifecycleState state) {
super.didChangeAppLifecycleState(state);
if(state == AppLifecycleState.paused){
debugPrint("....App paused....");
}else if(state == AppLifecycleState.resumed){
debugPrint("....App resumed....");
}
}
@override
Widget build(BuildContext context) {
WidgetsBinding.instance.addObserver(this);
SharedPreferences.getInstance().then((value){
var activeOrders = value.getStringList(ACTIVE_DELIVERIES) ?? [];
locator<DeliveryTrackingServices>().setActiveDeliveringOrders(activeOrders);
});
return LayoutBuilder(
builder: (context, constraints) {
return OrientationBuilder(
@ -30,6 +56,9 @@ class MyApp extends StatelessWidget {
ChangeNotifierProvider<AuthenticationViewModel>(
create: (context) => AuthenticationViewModel(),
),
ChangeNotifierProvider<OrdersViewModel>(
create: (context) => OrdersViewModel(),
),
],
child: Consumer<ProjectViewModel>(
builder: (context, projectProvider, child) => MaterialApp(

@ -0,0 +1,453 @@
import 'package:driverapp/app-icons/driver_app_icons.dart';
import 'package:driverapp/config/config.dart';
import 'package:driverapp/config/size_config.dart';
import 'package:driverapp/core/model/authentication/login_request.dart';
import 'package:driverapp/core/model/orders/pending_orders_res_model.dart';
import 'package:driverapp/core/service/delivery_tracking_services.dart';
import 'package:driverapp/core/viewModels/authentication_view_model.dart';
import 'package:driverapp/core/viewModels/orders_view_model.dart';
import 'package:driverapp/core/viewModels/project_view_model.dart';
import 'package:driverapp/locator.dart';
import 'package:driverapp/pages/authentication/reset_password_page.dart';
import 'package:driverapp/pages/delivery/delivery_confirmed_page.dart';
import 'package:driverapp/uitl/app_toast.dart';
import 'package:driverapp/uitl/translations_delegate_base.dart';
import 'package:driverapp/uitl/utils.dart';
import 'package:driverapp/widgets/buttons/secondary_button.dart';
import 'package:driverapp/widgets/others/app_scaffold_widget.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
import 'package:flutter/widgets.dart';
import 'package:provider/provider.dart';
import 'package:sweetalert/sweetalert.dart';
import 'forget_password_page.dart';
// ignore: must_be_immutable
class DeliveryVerificationPage extends StatelessWidget {
final PendingOrdersRes order;
DeliveryVerificationPage({this.order});
ProjectViewModel _projectViewModel;
OrdersViewModel _ordersViewModel;
final formKey = GlobalKey<FormState>();
Map formValues = {
'digit1': null,
'digit2': null,
'digit3': null,
'digit4': null,
};
FocusNode focusD1 = FocusNode();
FocusNode focusD2 = FocusNode();
FocusNode focusD3 = FocusNode();
FocusNode focusD4 = FocusNode();
var model;
TextEditingController digit1 = TextEditingController(text: "");
TextEditingController digit2 = TextEditingController(text: "");
TextEditingController digit3 = TextEditingController(text: "");
TextEditingController digit4 = TextEditingController(text: "");
bool _isLoading = false;
SizedBox buildSizedBox([double height = 20]) {
return SizedBox(
height: height,
);
}
BuildContext _context;
@override
Widget build(BuildContext context) {
_context = context;
_projectViewModel = Provider.of(context);
_ordersViewModel = Provider.of(context);
String validateCodeDigit(value) {
if (value.isEmpty) {
return 'Please enter your Password';
}
return null;
}
return AnimatedSwitcher(
duration: Duration(milliseconds: 2000),
child: AppScaffold(
isShowAppBar: false,
body: SingleChildScrollView(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
FractionallySizedBox(
widthFactor: 0.80,
child: Column(
children: <Widget>[
SizedBox(
height: 30,
),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Container(
child: Icon(
DriverApp.deliverd_icon,
size: 150,
color: Theme.of(context).primaryColor,
),
margin: EdgeInsets.only(
top: 20,
),
),
],
),
SizedBox(
height: 20,
),
Column(
children: <Widget>[
Center(
child: Text(
"Verification",
style: TextStyle(
fontSize: 25,
letterSpacing: 1,
fontWeight: FontWeight.w600),
),
),
],
),
SizedBox(
height: 30,
),
SizedBox(
height: 10,
),
Form(
key: formKey,
child: Container(
width: SizeConfig.realScreenWidth * 0.90,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Padding(
padding: const EdgeInsets.symmetric(
horizontal: 20),
child: Row(
mainAxisAlignment:
MainAxisAlignment.end,
children: <Widget>[
Expanded(
child: Text(
TranslationBase.of(context)
.enterCustomerVerificationCodeMsg,
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 13,
color: Colors.grey),
),
),
SizedBox(
height: 10,
)
],
),
),
buildSizedBox(30),
Center(
child: FractionallySizedBox(
widthFactor: 0.80,
child: Row(
mainAxisAlignment:
MainAxisAlignment.spaceAround,
children: <Widget>[
Container(
width: 55,
height: 55,
color: Colors.transparent,
child: Center(
child: TextFormField(
textInputAction:
TextInputAction.next,
style: TextStyle(
fontSize: SizeConfig
.textMultiplier *
3,
),
focusNode: focusD1,
controller: digit1,
enableInteractiveSelection: false,
showCursor: false,
maxLength: 1,
textAlign: TextAlign.center,
keyboardType:
TextInputType.number,
decoration:
buildInputDecoration(
context),
onSaved: (val) {
formValues[
'digit1'] = val;
},
validator: validateCodeDigit,
onFieldSubmitted: (_) {
FocusScope.of(context)
.requestFocus(focusD2);
},
onChanged: (val) => val.isNotEmpty
? FocusScope.of(context).requestFocus(focusD2)
: FocusScope.of(context).requestFocus(focusD1)
),
),
),
Container(
width: 55,
height: 55,
color: Colors.transparent,
child: Center(
child: TextFormField(
focusNode: focusD2,
controller: digit2,
enableInteractiveSelection: false,
showCursor: false,
maxLength: 1,
textInputAction:
TextInputAction.next,
textAlign: TextAlign.center,
style: TextStyle(
fontSize: SizeConfig
.textMultiplier *
3,
),
keyboardType:
TextInputType.number,
decoration:
buildInputDecoration(
context),
validator: validateCodeDigit,
onSaved: (val) {
formValues[
'digit2'] = val;
},
onFieldSubmitted: (_) {
FocusScope.of(context)
.requestFocus(focusD3);
},
onChanged: (val) => val.isNotEmpty
? FocusScope.of(context).requestFocus(focusD3)
: FocusScope.of(context).requestFocus(focusD1)
),
),
),
Container(
width: 55,
height: 55,
color: Colors.transparent,
child: Center(
child: TextFormField(
focusNode: focusD3,
controller: digit3,
enableInteractiveSelection: false,
showCursor: false,
maxLength: 1,
textInputAction: TextInputAction.next,
textAlign: TextAlign.center,
style: TextStyle(
fontSize: SizeConfig
.textMultiplier * 3,
),
keyboardType:
TextInputType.number,
decoration:
buildInputDecoration(
context),
validator: validateCodeDigit,
onSaved: (val) {
formValues[
'digit3'] = val;
},
onFieldSubmitted: (_) {
FocusScope.of(context)
.requestFocus(focusD4);
},
onChanged: (val) => val.isNotEmpty
? FocusScope.of(context).requestFocus(focusD4)
: FocusScope.of(context).requestFocus(focusD2),
),
)),
Container(
width: 55,
height: 55,
color: Colors.transparent,
child: Center(
child: TextFormField(
focusNode: focusD4,
controller: digit4,
enableInteractiveSelection: false,
showCursor: false,
maxLength: 1,
textAlign: TextAlign.center,
style: TextStyle(
fontSize: SizeConfig
.textMultiplier *
3,
),
keyboardType:
TextInputType.number,
decoration:
buildInputDecoration(
context),
validator: validateCodeDigit,
onSaved: (val) {
formValues[
'digit4'] = val;
},
onFieldSubmitted: (_) {
FocusScope.of(context)
.requestFocus(focusD4);
},
onChanged: (val) => val.isNotEmpty
? FocusScope.of(context).requestFocus(focusD4)
: FocusScope.of(context).requestFocus(focusD3)
),
),
)
],
),
),
),
buildSizedBox(20),
// ShowTimerText(model: model),
])))
],
),
),
SizedBox(
height: 20,
),
SizedBox(
height: 10,
),
Container(
margin: EdgeInsets.all(10),
height: MediaQuery.of(context).size.height * 0.22,
child: Column(
children: <Widget>[
SecondaryButton(
label: "Verify Receiver",
onTap: () {
_verifyCustomer();
},
disabled: _isLoading,
loading: _isLoading,
),
SizedBox(
height: 10,
),
// Row(
// mainAxisAlignment: MainAxisAlignment.end,
// children: <Widget>[
// InkWell(
// onTap: () {
// Navigator.pushReplacement(
// context,
// MaterialPageRoute(
// builder: (context) =>
// ForgetPasswordPage()),
// );
// },
// child: InkWell(
// onTap: () async {
// await _ordersViewModel.resendOtpToReceiver(order);
// },
// child: Text(
// "Resend OPT?",
// style: TextStyle(
// fontSize: 14,
// color: Theme.of(context).primaryColor),
// ),
// ),
// ),
// ],
// ),
],
))
],
),
),
),
);
}
TextStyle buildTextStyle() {
return TextStyle(
fontSize: SizeConfig.textMultiplier * 3,
);
}
InputDecoration buildInputDecoration(BuildContext context) {
return InputDecoration(
filled: true,
fillColor: Colors.white,
// ts/images/password_icon.png
contentPadding: EdgeInsets.only(top: 30, bottom: 30),
enabledBorder: OutlineInputBorder(
borderRadius: BorderRadius.all(Radius.circular(10)),
borderSide: BorderSide(color: Colors.grey),
),
focusedBorder: OutlineInputBorder(
borderRadius: BorderRadius.all(Radius.circular(10.0)),
borderSide: BorderSide(color: Theme.of(context).primaryColor, width: 2),
),
errorBorder: OutlineInputBorder(
borderRadius: BorderRadius.all(Radius.circular(10.0)),
borderSide: BorderSide(color: Theme.of(context).errorColor, width: 2),
),
focusedErrorBorder: OutlineInputBorder(
borderRadius: BorderRadius.all(Radius.circular(10.0)),
borderSide: BorderSide(color: Theme.of(context).errorColor, width: 2),
),
counterText: "",
errorStyle: TextStyle(height: 0.0)
);
}
_verifyCustomer() async {
if (formKey.currentState.validate()) {
final pinCode = digit1.text + digit2.text + digit3.text + digit4.text;
formKey.currentState.save();
SweetAlert.show(_context, subtitle: "Please wait...", style: SweetAlertStyle.loading);
var results = await _ordersViewModel.validateDelivery(order, pinCode);
if (results != null && results.isSuccessful) {
results = await _ordersViewModel.updateOrderStatus(orderNo: order.orderID, status: DeliveryStatus.delivered);
popWithDelay(context: _context, seconds: 0.2, callback: (){
if(results.isSuccessful){
_goToDeliveryDoneConfirmation();
}else{
Utils.showErrorToast(results.message);
}
});
}else{
Navigator.of(_context).pop();
Utils.showErrorToast(results.message);
}
}
}
_goToDeliveryDoneConfirmation(){
locator<DeliveryTrackingServices>().stopLocationUpdate(order.ePharmacyOrderNo); // Stop Driver Location update for Order
Navigator.pushReplacement(
_context,
MaterialPageRoute(
builder: (context) => DeliveryConfirmedPage(order),
),
);
}
}

File diff suppressed because it is too large Load Diff

@ -0,0 +1,242 @@
import 'package:driverapp/config/config.dart';
import 'package:driverapp/core/enum/viewstate.dart';
import 'package:driverapp/core/model/orders/next_order_request_model.dart';
import 'package:driverapp/core/model/orders/pending_orders_res_model.dart';
import 'package:driverapp/core/service/orders_service.dart';
import 'package:driverapp/core/viewModels/orders_view_model.dart';
import 'package:driverapp/locator.dart';
import 'package:driverapp/pages/base/base_view.dart';
import 'package:driverapp/root_page.dart';
import 'package:driverapp/uitl/utils.dart';
import 'package:driverapp/widgets/buttons/secondary_button.dart';
import 'package:driverapp/widgets/delivery/customer_brief_card.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:location/location.dart';
import '../../uitl/translations_delegate_base.dart';
import '../../widgets/others/app_scaffold_widget.dart';
import 'information_page.dart';
class DeliveryCancelRejectedPage extends StatelessWidget {
final PendingOrdersRes item;
DeliveryCancelRejectedPage(this.item);
@override
Widget build(BuildContext context) {
return BaseView<OrdersViewModel>(
builder: (_, model, w) => AppScaffold(
isAppBarGradient: true,
isShowAppBar: true,
appBarColor: Theme.of(context).primaryColor,
arrowColor: Colors.white,
titleColor: Colors.white,
body: SafeArea(
child: Container(
//
child: ListView(
children: <Widget>[
Stack(
children: <Widget>[
Container(
decoration: BoxDecoration(gradient: LINEAR_GRADIENT),
height: MediaQuery.of(context).orientation ==
Orientation.portrait
? MediaQuery.of(context).size.width * 1
: MediaQuery.of(context).size.width * 1,
child: Stack(
children: [
Container(
width: MediaQuery.of(context).size.width,
height: MediaQuery.of(context).orientation ==
Orientation.portrait
? MediaQuery.of(context).size.width * 0.7
: MediaQuery.of(context).size.width * 0.5,
padding: EdgeInsets.only(
top: MediaQuery.of(context).size.width * 0.14,
),
decoration: BoxDecoration(
color: Colors.white10, shape: BoxShape.circle),
child: Column(
children: <Widget>[
Icon(
Icons.check_circle,
color: Colors.white,
size: 75,
),
SizedBox(
height:
MediaQuery.of(context).size.width * 0.03,
),
Text(
'Delivery Confirmed',
style: TextStyle(
color: Colors.white,
fontSize: 20,
fontWeight: FontWeight.bold),
),
SizedBox(
height:
MediaQuery.of(context).size.width * 0.01,
),
Text(
TranslationBase.of(context).confirmationSent,
style: TextStyle(
color: Colors.white,
fontSize: 13,
),
),
],
),
),
],
),
),
// Container(
// width: MediaQuery.of(context).size.width,
// height: MediaQuery.of(context).size.width,
// ),
Container(
width: MediaQuery.of(context).size.width,
height: MediaQuery.of(context).orientation ==
Orientation.landscape
? MediaQuery.of(context).size.width * 0.6
: MediaQuery.of(context).size.width * 1.0,
margin: EdgeInsets.only(
top: MediaQuery.of(context).orientation ==
Orientation.portrait
? MediaQuery.of(context).size.width * 0.70
: MediaQuery.of(context).size.width * 0.60,
),
decoration: BoxDecoration(
color: Theme
.of(context)
.scaffoldBackgroundColor,
borderRadius: BorderRadius.only(
topLeft: Radius.circular(80),
topRight: Radius.circular(80)),
),
child: Column(
mainAxisAlignment: MediaQuery.of(context).orientation ==
Orientation.landscape
? MainAxisAlignment.center
: MainAxisAlignment.end,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Container(
margin: EdgeInsets.only(
bottom: MediaQuery.of(context).size.width * 0.00,
),
child: Padding(
padding: MediaQuery.of(context).orientation ==
Orientation.landscape
? EdgeInsets.only(top: 60.0)
: EdgeInsets.only(top: 30.0),
child: Column(
children: <Widget>[
// TODO return add note when its needed
// FlatButton.icon(
// padding: EdgeInsets.all(14.0),
// color: Colors.orangeAccent,
// shape: RoundedRectangleBorder(
// borderRadius: BorderRadius.circular(10.0),
// ),
// label: Text(
// TranslationBase.of(context).addNoteBtn,
// style: TextStyle(
// color: Colors.white, fontSize: 20.0),
// ),
// icon: Icon(
// Icons.mode_edit,
// color: Colors.white,
// ),
// onPressed: () {},
// ),
// SizedBox(
// height: MediaQuery.of(context).size.width *
// 0.00, //20,
// ),
Padding(
padding: const EdgeInsets.only(top: 30.0),
child: Container(
margin: EdgeInsets.all(10),
child: SecondaryButton(
label: TranslationBase.of(context)
.nextDelivery,
loading:
model.state == ViewState.BusyLocal,
onTap: () {
getNextOrder(context, model);
},
),
),
),
],
),
),
),
],
),
),
Container(
margin: EdgeInsets.only(
top: MediaQuery.of(context).orientation ==
Orientation.portrait
? MediaQuery.of(context).size.width * 0.6
: MediaQuery.of(context).size.width * 0.4,
),
child: CustomerBriefCard(
customerOrderId: item.orderID,
pharmacyOrderId: item.ePharmacyOrderNo,
customerFirstName: item.firstName,
customerLastName: item.lastName,
mobileNo: item.mobileNumber,
totalPayment: item.amount,
distanceInKilometers: item.distanceInKilometers,
showDistance: false,
deliveryTime: item.orderCreatedOn),
),
],
),
],
),
),
),
),
);
}
getNextOrder(BuildContext context, OrdersViewModel model) async {
model.setState(ViewState.BusyLocal);
LocationData loc = await Utils.getLocation();
NextOrderRequestModel nextOrderRequestModel = NextOrderRequestModel(
pageIndex: 0,
pageSize: 0,
latitude: loc.latitude.toString(), // "46.621730",
longitude: loc.longitude.toString(), // "24.797682",
searchKey: "");
await model.nextOrder(nextOrderRequestModel);
if (model.state == ViewState.ErrorLocal) {
Utils.showErrorToast(model.error);
} else {
if (model.nextOrdersList != null && model.nextOrdersList.length == 0) {
Utils.showErrorToast("No Items in the list");
Navigator.pushReplacement(
context,
MaterialPageRoute(
builder: (context) => RootPage(),
),
);
} else {
Navigator.pushReplacement(
context,
MaterialPageRoute(
builder: (context) =>
InformationPage(item: model.nextOrdersList[0]),
),
);
}
}
}
}

@ -2,7 +2,9 @@ import 'package:driverapp/config/config.dart';
import 'package:driverapp/core/enum/viewstate.dart';
import 'package:driverapp/core/model/orders/next_order_request_model.dart';
import 'package:driverapp/core/model/orders/pending_orders_res_model.dart';
import 'package:driverapp/core/service/orders_service.dart';
import 'package:driverapp/core/viewModels/orders_view_model.dart';
import 'package:driverapp/locator.dart';
import 'package:driverapp/pages/base/base_view.dart';
import 'package:driverapp/root_page.dart';
import 'package:driverapp/uitl/utils.dart';
@ -211,10 +213,8 @@ class DeliveryConfirmedPage extends StatelessWidget {
NextOrderRequestModel nextOrderRequestModel = NextOrderRequestModel(
pageIndex: 0,
pageSize: 0,
latitude: loc.latitude.toString(),
//"46.621730",
longitude: loc.longitude.toString(),
//"24.797682",
latitude: loc.latitude.toString(), // "46.621730",
longitude: loc.longitude.toString(), // "24.797682",
searchKey: "");
await model.nextOrder(nextOrderRequestModel);
if (model.state == ViewState.ErrorLocal) {

@ -1,10 +1,22 @@
import 'dart:convert';
import 'dart:io';
import 'package:android_intent/android_intent.dart';
import 'package:driverapp/app-icons/driver_app_icons.dart';
import 'package:driverapp/config/config.dart';
import 'package:driverapp/core/enum/viewstate.dart';
import 'package:driverapp/core/model/StatusModel.dart';
import 'package:driverapp/core/model/orders/pending_orders_req_model.dart';
import 'package:driverapp/core/model/orders/pending_orders_res_model.dart';
import 'package:driverapp/core/model/orders/update_order_status_request_model.dart';
import 'package:driverapp/core/service/delivery_tracking_services.dart';
import 'package:driverapp/core/viewModels/orders_view_model.dart';
import 'package:driverapp/locator.dart';
import 'package:driverapp/pages/authentication/delivery_verification_page.dart';
import 'package:driverapp/pages/authentication/verification_page.dart';
import 'package:driverapp/pages/base/base_view.dart';
import 'package:driverapp/uitl/app_shared_preferences.dart';
import 'package:driverapp/uitl/app_toast.dart';
import 'package:driverapp/uitl/translations_delegate_base.dart';
import 'package:driverapp/uitl/utils.dart';
import 'package:driverapp/widgets/bottom_sheet/action_sheet_button.dart';
@ -17,140 +29,44 @@ import 'package:driverapp/widgets/delivery/package_content.dart';
import 'package:driverapp/widgets/others/app_scaffold_widget.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_material_pickers/flutter_material_pickers.dart';
import 'package:hexcolor/hexcolor.dart';
import 'package:maps_launcher/maps_launcher.dart';
import 'package:map_launcher/map_launcher.dart';
import 'package:sweetalert/sweetalert.dart';
import 'package:url_launcher/url_launcher.dart';
import 'delivery_cancel_page.dart';
import 'delivery_confirmed_page.dart';
// ignore: must_be_immutable
class InformationPage extends StatelessWidget {
final PendingOrdersRes item;
int _orderStatus;
class InformationPage extends StatefulWidget {
final PendingOrdersRes item;
InformationPage({this.item});
@override
State<StatefulWidget> createState() => _InformationPageState();
}
// ignore: must_be_immutable
class _InformationPageState extends State<InformationPage> {
var _deliveryService = locator<DeliveryTrackingServices>();
PendingOrdersRes _item;
bool _isDeliveryStarted;
OrdersViewModel _viewModel;
@override
void initState() {
super.initState();
_item = widget.item;
_isDeliveryStarted = _deliveryService.getActiveDeliveringOrders().contains(_item.ePharmacyOrderNo.toString());
}
@override
Widget build(BuildContext context) {
showDeliveryOptions(OrdersViewModel model) {
showModalBottomSheet(
backgroundColor: Colors.white,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(50.0),
topRight: Radius.circular(50.0),
),
),
isScrollControlled: true,
context: context,
builder: (BuildContext bc) {
return FractionallySizedBox(
heightFactor: 0.35,
child: ListView(
children: <Widget>[
Container(
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.only(
topLeft: Radius.circular(50.0),
topRight: Radius.circular(50.0),
),
),
child: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
SizedBox(
height: 10,
),
Center(
child: Texts(
TranslationBase.of(context).selectAction,
color: Colors.black,
fontSize: 22,
),
),
SizedBox(
height: 10,
),
FractionallySizedBox(
widthFactor: MediaQuery.of(context).orientation ==
Orientation.portrait
? 0.9
: 0.98,
child: Container(
height: MediaQuery.of(context).size.height * 0.45,
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.only(
topLeft: Radius.circular(50.0),
topRight: Radius.circular(50.0),
),
),
width: double.infinity,
child: ListView(
children: <Widget>[
Column(
children: <Widget>[
SizedBox(
height: 3,
child: Container(
color: Hexcolor("#D5D5D5"),
),
),
SizedBox(
height: 15,
),
ActionSheetButton(
label:
TranslationBase.of(context).delivered,
icon: DriverApp.deliverd_icon,
onTap: () {
selectAction(context, 2, model);
},
),
SizedBox(height: 15),
// ActionSheetButton(
// label: TranslationBase.of(context)
// .deliveredAccepted,
// icon: DriverApp.not_available,
// onTap: () {
// selectAction(context, 4, model);
// },
// ),
// SizedBox(height: 15),
ActionSheetButton(
label: TranslationBase.of(context)
.deliveredRejected,
icon: DriverApp.rejected_icon,
onTap: () {
selectAction(context, 3, model);
},
),
SizedBox(height: 15),
// ActionSheetButton(
// label: TranslationBase.of(context).canceled,
// icon: DriverApp.not_reachable_icon,
// onTap: () {
// selectAction(context, 6, model);
// },
// ),
// SizedBox(height: 15),
],
),
],
),
),
)
],
),
),
],
),
);
});
}
return BaseView<OrdersViewModel>(
onModelReady: (model) => _viewModel = model,
builder: (_, model, w) => AppScaffold(
isShowAppBar: true,
isShowHomeIcon: true,
@ -175,12 +91,12 @@ class InformationPage extends StatelessWidget {
child: Container(
width: MediaQuery.of(context).size.width * 1.0,
height: MediaQuery.of(context).orientation ==
Orientation.portrait
Orientation.portrait
? MediaQuery.of(context).size.height * 0.70
: MediaQuery.of(context).size.height * 1.7,
margin: EdgeInsets.only(
top: MediaQuery.of(context).orientation ==
Orientation.portrait
Orientation.portrait
? MediaQuery.of(context).size.width * 0.23
: MediaQuery.of(context).size.width * 0.13),
decoration: BoxDecoration(
@ -192,88 +108,53 @@ class InformationPage extends StatelessWidget {
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
SizedBox(
height: MediaQuery.of(context).orientation ==
Orientation.portrait
? MediaQuery.of(context).size.height * 0.10
: MediaQuery.of(context).size.height * 0.29,
//MediaQuery.of(context).size.width * 0.005,
),
Padding(
padding: MediaQuery.of(context).orientation ==
Orientation.portrait
? EdgeInsets.only(top: 60.0)
: EdgeInsets.only(top: 15.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
DeliveryInfoButton(
btnColor: Colors.white, //Color(0xffED1C24),
btnIcon: Icon(DriverApp.location_1,
size: MediaQuery.of(context)
.orientation ==
Orientation.portrait
? 50
: 90,
color: Color(0xffED1C24)),
btnName:
TranslationBase.of(context).location,
btnFunction: () {
MapsLauncher.launchCoordinates(
item.latitude, item.longitude);
},
),
//TODO: return it back when it needed
// DeliveryInfoButton(
// btnColor: Colors.white, //Color(0xFF61B260),
// btnIcon: Icon(
// DriverApp.whatsapp,
// size:
// MediaQuery.of(context).orientation ==
// Orientation.portrait
// ? 50
// : 90,
// color: Color(0xFF5EA34A),
// ),
// btnName: 'Whatsapp',
// btnFunction: () {},
// ),
// DeliveryInfoButton(
// btnColor: Colors.white, //Color(0xFFFCB657),
// btnIcon: Icon(
// DriverApp.message,
// size:
// MediaQuery.of(context).orientation ==
// Orientation.portrait
// ? 50
// : 90,
// color: Color(0xffFFA540),
// ),
// btnName: TranslationBase.of(context).sms,
// btnFunction: () {},
// ),
DeliveryInfoButton(
btnColor: Colors.white,
//Theme.of(context).primaryColor,
btnIcon: Icon(
DriverApp.call,
size:
MediaQuery.of(context).orientation ==
Orientation.portrait
Visibility(
visible: _isDeliveryStarted,
child: Padding(
padding: MediaQuery.of(context).orientation ==
Orientation.portrait
? EdgeInsets.only(top: 60.0)
: EdgeInsets.only(top: 15.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
DeliveryInfoButton(
btnColor: Colors.white, //Color(0xffED1C24),
btnIcon: Icon(DriverApp.location_1,
size: MediaQuery.of(context)
.orientation ==
Orientation.portrait
? 50
: 90,
color: Theme.of(context).primaryColor,
color: Color(0xffED1C24)),
btnName:
TranslationBase.of(context).location,
btnFunction: () {
_openMapDirection(_item);
// MapsLauncher.launchCoordinates(
// _item.latitude, _item.longitude);
},
),
btnName: TranslationBase.of(context).call,
btnFunction: () =>
launch("tel://" + item.mobileNumber),
),
],
DeliveryInfoButton(
btnColor: Colors.white,
//Theme.of(context).primaryColor,
btnIcon: Icon(
DriverApp.call,
size:
MediaQuery.of(context).orientation ==
Orientation.portrait
? 50
: 90,
color: Theme.of(context).primaryColor,
),
btnName: TranslationBase.of(context).call,
btnFunction: () =>
launch("tel://" + _item.mobileNumber),
),
],
),
),
),
SizedBox(
height: MediaQuery.of(context).size.width * 0.08,
),
Container(
margin: EdgeInsets.only(
left: MediaQuery.of(context).size.width * 0.05,
@ -300,15 +181,15 @@ class InformationPage extends StatelessWidget {
padding: const EdgeInsets.only(left: 10),
child: Column(
children: List.generate(
item.itemsQuantitiesList != null
? item.itemsQuantitiesList.length
_item.itemsQuantitiesList != null
? _item.itemsQuantitiesList.length
: 0, (index) {
return packageContent(
packageName: item
packageName: _item
.itemsQuantitiesList[index]
.itemName
.toString(),
packageCount: item
packageCount: _item
.itemsQuantitiesList[index]
.quantity
.toString(),
@ -324,14 +205,15 @@ class InformationPage extends StatelessWidget {
),
Container(
margin: MediaQuery.of(context).orientation ==
Orientation.portrait
Orientation.portrait
? EdgeInsets.all(8.0)
: EdgeInsets.symmetric(horizontal: 12.0),
child: SecondaryButton(
label:
TranslationBase.of(context).clientReached,
label: _isDeliveryStarted
? TranslationBase.of(context).deliveryOption
: TranslationBase.of(context).startDelivery,
onTap: () {
showDeliveryOptions(model);
takeAction();
},
),
),
@ -340,16 +222,16 @@ class InformationPage extends StatelessWidget {
),
),
CustomerBriefCard(
customerOrderId: item.orderID,
pharmacyOrderId: item.ePharmacyOrderNo,
customerFirstName: item.firstName,
customerLastName: item.lastName,
mobileNo: item.mobileNumber,
totalPayment: item.amount,
deliveryTime: item.orderCreatedOn,
longitude: item.longitude,
latitude: item.latitude,
distanceInKilometers: item.distanceInKilometers,
customerOrderId: _item.orderID,
pharmacyOrderId: _item.ePharmacyOrderNo,
customerFirstName: _item.firstName,
customerLastName: _item.lastName,
mobileNo: _item.mobileNumber,
totalPayment: _item.amount,
deliveryTime: _item.orderCreatedOn,
longitude: _item.longitude,
latitude: _item.latitude,
distanceInKilometers: _item.distanceInKilometers,
),
],
),
@ -361,68 +243,236 @@ class InformationPage extends StatelessWidget {
);
}
selectAction(BuildContext context, orderStatus, OrdersViewModel model) {
String orderStatusText;
this._orderStatus = orderStatus;
switch (orderStatus) {
case 2:
orderStatusText = TranslationBase
.of(context)
.delivered;
break;
// case 4:
// orderStatusText = TranslationBase.of(context).deliveredAccepted;
// break;
case 3:
orderStatusText = TranslationBase
.of(context)
.deliveredRejected;
break;
// case 6:
// orderStatusText = TranslationBase.of(context).canceled;
// break;
}
showDialog(
void takeAction(){
if(_isDeliveryStarted) {
showDeliveryOptions(_viewModel);
}else{
if(_deliveryService.getActiveDeliveringOrders().isEmpty){
SweetAlert.show(context,subtitle: "Initializing delivery...", style: SweetAlertStyle.loading);
_viewModel.initDelivery(_item, completion: (response) {
if (response.isSuccessful) {
setState(() => _isDeliveryStarted = true);
Navigator.pop(context);
AppToast.showSuccessToast(message: "Start navigation by clicking icon [${response.data}]");
}else{
SweetAlert.show(context,subtitle: response.message, style: SweetAlertStyle.error);
}
});
}else{
SweetAlert.show(context,subtitle: "Complete the last delivery first.",style: SweetAlertStyle.error);
}
}
}
cancelDelivery() {
List<String> speedOptions = <String>[
TranslationBase.of(context).notReachableOnPhoneCall,
TranslationBase.of(context).notAvailableAtlocation,
TranslationBase.of(context).accident,
TranslationBase.of(context).deliverLater,
// TranslationBase.of(context).other,
];
List<Icon> speedIcons = <Icon>[
Icon(IconData(0xe901, fontFamily: 'HMGIcon1')),
Icon(IconData(0xe900, fontFamily: 'HMGIcon1')),
Icon(IconData(0xe902, fontFamily: 'HMGIcon1')),
Icon(IconData(0xe903, fontFamily: 'HMGIcon1')),
];
showMaterialSelectionPicker(
context: context,
title: TranslationBase.of(context).selectReason,
items: speedOptions,
selectedItem: speedOptions.first,
icons: speedIcons,
onChanged: (value) async {
SweetAlert.show(context,subtitle: "Canceling delivery...", style: SweetAlertStyle.loading);
var result = await _viewModel.updateOrderStatus(orderNo: _item.orderID, status: DeliveryStatus.cancel);
Navigator.pop(context);
if(result.isSuccessful){
_viewModel.deliveryService.stopLocationUpdate(_item.ePharmacyOrderNo);
Navigator.pushReplacement(
context,
MaterialPageRoute(
builder: (context) => DeliveryCancelRejectedPage(_item), // Replace with Delivery Cancel Screen
),
);
}else{
SweetAlert.show(context,subtitle: result.message,style: SweetAlertStyle.error);
}
},
);
}
showDeliveryOptions(OrdersViewModel model) {
showModalBottomSheet(
backgroundColor: Colors.white,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(50.0),
topRight: Radius.circular(50.0),
),
),
isScrollControlled: true,
context: context,
builder: (BuildContext context) {
return CustomDialog(
orderStatusText: orderStatusText,
callService: () {
updateOrderStatus(context, model);
},
model: model,
builder: (BuildContext bc) {
return FractionallySizedBox(
heightFactor: 0.40,
child: ListView(
children: <Widget>[
Container(
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.only(
topLeft: Radius.circular(50.0),
topRight: Radius.circular(50.0),
),
),
child: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
SizedBox(
height: 10,
),
Center(
child: Texts(
TranslationBase.of(context).selectAction,
color: Colors.black,
fontSize: 22,
),
),
SizedBox(
height: 10,
),
FractionallySizedBox(
widthFactor: MediaQuery.of(context).orientation == Orientation.portrait
? 0.9
: 0.98,
child: Container(
height: MediaQuery.of(context).size.height * 0.45,
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.only(
topLeft: Radius.circular(50.0),
topRight: Radius.circular(50.0),
),
),
width: double.infinity,
child: ListView(
children: <Widget>[
Column(
children: <Widget>[
SizedBox(
height: 3,
child: Container(
color: HexColor("#D5D5D5"),
),
),
SizedBox(
height: 15,
),
ActionSheetButton(
label:
TranslationBase.of(context).delivered,
icon: DriverApp.deliverd_icon,
onTap: () {
Navigator.of(context).pop(); // Pop Bottom Action Sheet
Navigator.pushReplacement(
context,
MaterialPageRoute(builder: (context) => DeliveryVerificationPage(order: _item)),
);
},
),
SizedBox(height: 15),
// ActionSheetButton(
// label: TranslationBase.of(context)
// .deliveredAccepted,
// icon: DriverApp.not_available,
// onTap: () {
// selectAction(context, 4, model);
// },
// ),
// SizedBox(height: 15),
ActionSheetButton(
label: TranslationBase.of(context)
.deliveredRejected,
icon: DriverApp.rejected_icon,
onTap: () {
Navigator.of(context).pop(); // Pop Bottom Action Sheet
rejectDelivery();
}
),
SizedBox(height: 15),
ActionSheetButton(
label: TranslationBase.of(context).cancel,
icon: DriverApp.not_reachable_icon,
onTap: () {
cancelDelivery();
},
),
SizedBox(height: 15),
],
),
],
),
),
)
],
),
),
],
),
);
});
}
updateOrderStatus(BuildContext context, OrdersViewModel model) async {
UpdateOrderStatusRequestModel updateOrderStatusRequestModel =
UpdateOrderStatusRequestModel(
deliveryOrderID: item.orderID,
deliveryOrderStatus: _orderStatus,
rejectionReason: "NO Reason",
cancleReason: "");
await model.updateOrderStatus(updateOrderStatusRequestModel);
if (model.state == ViewState.ErrorLocal) {
Utils.showErrorToast(model.error);
Navigator.of(context).pop();
model.hideBottomSheet();
} else {
/// to hide the dialog
Navigator.of(context).pop();
model.hideBottomSheet();
rejectDelivery(){
SweetAlert.show(context,title: "Are you sure?",style: SweetAlertStyle.confirm, showCancelButton: true,onPress: (bool isConfirm) {
if (isConfirm) {
_viewModel.updateOrderStatus(orderNo: _item.orderID, status: DeliveryStatus.rejected).then((results){
/// to remove this page from the stack please no one remove this line.
Navigator.of(context).pop();
});
}
return true;
});
}
_openMapDirection(PendingOrdersRes order) async{
Utils.getLocation().then((locationData){
if(locationData != null){
// MapLauncher.isMapAvailable(MapType.google).then((value){
// if (value) {
// MapLauncher.showDirections(
// mapType: MapType.google,
// destination: Coords(order.latitude, order.longitude),
// directionsMode: DirectionsMode.driving,
// destinationTitle: order.receiverFullName())
// .then((value) {
//
// });
// }else{
// // Google Map Not installed show error
// }
// });
Navigator.pushReplacement(
context,
MaterialPageRoute(
builder: (context) =>
DeliveryConfirmedPage(item),
),
);
}
/* Directly start navigation */
MapLauncher.isMapAvailable(MapType.google).then((value){
var url = "https://www.google.com/maps/dir/?api=1&destination=${order.latitude},${order.longitude}&travelmode=driving&dir_action=navigate";
if (Platform.isAndroid) {
var intent = AndroidIntent(action: 'action_view',data: url,package: 'com.google.android.apps.maps');
intent.launch();
}else if (Platform.isIOS) {
launch(url);
}
});
// Start updating server wit your current location
_deliveryService.startLocationUpdate(order.ePharmacyOrderNo);
}
});
}
}

@ -0,0 +1,14 @@
import 'dart:convert';
import 'package:shared_preferences/shared_preferences.dart';
class Logs{
static save(String log){
SharedPreferences.getInstance().then((_prefs) async{
var jsonString = _prefs.getString("LOG") ?? "[]";
var list = json.decode(jsonString) as List;
list.add("Running... ${DateTime.now()}");
_prefs.setString("LOG", json.encode(list));
});
}
}

@ -62,6 +62,9 @@ class TranslationBase {
String get enterVerificationMsg =>
localizedValues['enterVerificationMsg'][locale.languageCode];
String get enterCustomerVerificationCodeMsg =>
localizedValues['enterCustomerVerificationCodeMsg'][locale.languageCode];
String get forgotPassword =>
localizedValues['forgotPassword'][locale.languageCode];
@ -108,6 +111,13 @@ class TranslationBase {
String get clientReached =>
localizedValues['clientReached'][locale.languageCode];
String get startDelivery =>
localizedValues['startDelivery'][locale.languageCode];
String get deliveryOption =>
localizedValues['deliveryOption'][locale.languageCode];
String get addNoteBtn => localizedValues['addNoteBtn'][locale.languageCode];
String get nextDelivery =>
@ -133,6 +143,24 @@ class TranslationBase {
String get selectAction =>
localizedValues['selectAction'][locale.languageCode];
String get selectReason =>
localizedValues['selectReason'][locale.languageCode];
String get other =>
localizedValues['other'][locale.languageCode];
String get notReachableOnPhoneCall =>
localizedValues['notReachableOnPhoneCall'][locale.languageCode];
String get deliverLater =>
localizedValues['deliverLater'][locale.languageCode];
String get notAvailableAtlocation =>
localizedValues['notAvailableAtlocation'][locale.languageCode];
String get accident =>
localizedValues['accident'][locale.languageCode];
String get youHaveSelected =>
localizedValues['youHaveSelected'][locale.languageCode];

@ -5,6 +5,7 @@ import 'package:driverapp/pages/setting/request_permission_page.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:latlong/latlong.dart';
import 'package:location/location.dart';
import 'app_shared_preferences.dart';
@ -12,6 +13,22 @@ import 'app_toast.dart';
AppSharedPreferences sharedPref = new AppSharedPreferences();
popWithDelay({@required BuildContext context, @required num seconds, @required VoidCallback callback}){
Navigator.of(context).pop();
Future.delayed(Duration(milliseconds: (seconds*1000).toInt())).then((value){
callback();
});
}
pop(BuildContext context, VoidCallback callBack){
Navigator.of(context).pop();
callBack();
}
delay(int milliseconds, VoidCallback callback){
Future.delayed(Duration(milliseconds: milliseconds)).then((value) => callback());
}
class Utils {
///show custom Error Toast
/// [message] to show for user
@ -48,8 +65,25 @@ class Utils {
static hideKeyboard(BuildContext context) {
FocusScope.of(context).unfocus();
}
static double distanceBetween(LocationData point1, LocationData point2, LengthUnit unit){
var distance = Distance();
num dist = distance.as(
unit,
LatLng(point1.latitude,point1.longitude),
LatLng(point2.latitude,point2.longitude)
);
return dist;
}
static getLocation() async {
static possibleToGetLocation(Function(bool) completion) async{
Location location = new Location();
var serviceEnabled = await location.serviceEnabled();
var hasPermission = await location.hasPermission() == PermissionStatus.granted;
completion(serviceEnabled && hasPermission);
}
static Future<LocationData> getLocation() async {
Location location = new Location();
LocationData currentLocation;
bool _serviceEnabled;
@ -104,8 +138,8 @@ class Utils {
// open setting page
} else {
currentLocation = await location.getLocation();
return currentLocation;
}
return currentLocation;
}
static formatStringToPascalCase(String name) {
@ -120,3 +154,4 @@ class Utils {
return formattedNamesList.join(' ');
}
}

@ -19,7 +19,7 @@ class ActionSheetButton extends StatelessWidget {
: MediaQuery.of(context).size.height * 0.14,
decoration: BoxDecoration(boxShadow: [
BoxShadow(
color: Hexcolor("#DBE5E6"),
color: HexColor("#DBE5E6"),
spreadRadius: 15,
blurRadius: 15,
offset: Offset(0, 7),
@ -66,7 +66,7 @@ class ActionSheetButton extends StatelessWidget {
style: TextStyle(
fontSize: 22.0,
fontFamily: "Metropolis-Bold",
color: Hexcolor("##1A1818")),
color: HexColor("##1A1818")),
),
)
],

@ -25,7 +25,7 @@ class CustomBottomSheet extends StatelessWidget {
children: <Widget>[
Container(
decoration: BoxDecoration(
color: Hexcolor("#D5D5D5"),
color: HexColor("#D5D5D5"),
borderRadius: BorderRadius.circular(3.0)),
width: 200,
height: 7.0,

@ -103,7 +103,7 @@ class _ButtonState extends State<Button> with TickerProviderStateMixin {
: 19),
decoration: BoxDecoration(
borderRadius: BorderRadius.all(Radius.circular(10.0)),
color: Hexcolor('#515b5d'),
color: HexColor('#515b5d'),
boxShadow: [
BoxShadow(
color: Color.fromRGBO(

@ -194,7 +194,7 @@ class _SecondaryButtonState extends State<SecondaryButton>
widget.color != null ? null : LINEAR_GRADIENT,
color: widget.color != null
? widget.color
: Hexcolor("#000000"),
: HexColor("#000000"),
),
),
),

@ -25,7 +25,7 @@ class CircleContainer extends StatelessWidget {
shape: BoxShape.circle,
color: color,
border: Border.all(
color: borderColor ?? Hexcolor("#707070"), width: borderWidth)),
color: borderColor ?? HexColor("#707070"), width: borderWidth)),
height: 80,
width: 80,
),

@ -61,7 +61,7 @@ class CustomerBriefCard extends StatelessWidget {
],
),
child: Container(
padding: EdgeInsets.only(left: 30, top: 20, right: 30),
padding: EdgeInsets.only(left: 20, top: 20, right: 20),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start,

@ -6,140 +6,157 @@ import 'package:hexcolor/hexcolor.dart';
class OrderInfoCard extends StatelessWidget {
const OrderInfoCard(
{Key key, this.order, this.onTap, this.showStatus = false})
{Key key, this.order, this.onTap, this.showStatus = false, this.isActiveToDeliver = false})
: super(key: key);
final dynamic order;
final Function onTap;
final bool showStatus;
final bool isActiveToDeliver;
@override
Widget build(BuildContext context) {
return InkWell(
child: Container(
child:
Container(
child: RoundedContainer(
showShadow: true,
raduis: 25.0,
height: MediaQuery.of(context).orientation == Orientation.portrait
? MediaQuery.of(context).size.height * (showStatus ? 0.22 : 0.160)
: MediaQuery.of(context).size.height *
(showStatus ? 0.359 : 0.269),
(showStatus ? 0.359 : 0.269),
child: FractionallySizedBox(
widthFactor: 0.98,
child: Column(
// mainAxisAlignment: MainAxisAlignment.start,
child: Stack(
children:[
if(isActiveToDeliver)
Padding(
padding: const EdgeInsets.all(10.0),
child: Align(
alignment: Alignment.bottomRight,
child:Image.asset(
'assets/images/check.png',
height: 20,
width: 20,
),
),
),
Column(
// mainAxisAlignment: MainAxisAlignment.start,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Column(
children: [
Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Padding(
padding:
EdgeInsets.only(left: 15.0, top: 14.0),
child: Image.asset(
'assets/images/location.png',
height: MediaQuery.of(context)
.orientation ==
Orientation.portrait
? MediaQuery.of(context).size.height *
0.06
: MediaQuery.of(context).size.height *
0.11,
width: MediaQuery.of(context).orientation ==
Orientation.portrait
? MediaQuery.of(context).size.width *
0.05
: MediaQuery.of(context).size.width *
0.09,
),
),
SizedBox(
width: 13,
),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Padding(
padding: EdgeInsets.only(top: 20.0),
child: Text(
Utils.formatStringToPascalCase(
order.firstName +
' ' +
order.lastName),
style: TextStyle(
fontSize: 18.0,
color: Hexcolor("#343333"),
fontWeight: FontWeight.bold),
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Column(
children: [
Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Padding(
padding:
EdgeInsets.only(left: 15.0, top: 14.0),
child: Image.asset(
'assets/images/location.png',
height: MediaQuery.of(context)
.orientation ==
Orientation.portrait
? MediaQuery.of(context).size.height *
0.06
: MediaQuery.of(context).size.height *
0.11,
width: MediaQuery.of(context).orientation ==
Orientation.portrait
? MediaQuery.of(context).size.width *
0.05
: MediaQuery.of(context).size.width *
0.09,
),
),
),
Text(
order.mobileNumber,
style: TextStyle(
color: Color(0xff30B7B9),
fontWeight: FontWeight.w600,
fontSize: 15.0,
SizedBox(
width: 13,
),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Padding(
padding: EdgeInsets.only(top: 20.0),
child: Text(
Utils.formatStringToPascalCase(
order.firstName +
' ' +
order.lastName),
style: TextStyle(
fontSize: 18.0,
color: HexColor("#343333"),
fontWeight: FontWeight.bold),
),
),
Text(
order.mobileNumber,
style: TextStyle(
color: Color(0xff30B7B9),
fontWeight: FontWeight.w600,
fontSize: 15.0,
),
),
Text(
order.orderID.toString(),
style: TextStyle(
fontSize: 15.0,
fontWeight: FontWeight.w400,
letterSpacing: 8.0),
),
],
),
],
),
],
)
],
),
Padding(
padding: EdgeInsets.all(8.0),
child: DistanceInKilometers(
distanceInKilometers: order.distanceInKilometers,
),
),
],
),
if (showStatus)
Row(
children: [
Container(
margin: EdgeInsets.only(bottom: 12, left: 10),
child: RoundedContainer(
margin: 4,
showShadow: false,
backgroundColor:
order.statusID == 2 ? Colors.green : Colors.red,
child: Padding(
padding: const EdgeInsets.symmetric(
vertical: 5, horizontal: 15),
child: Text(
order.description,
style: TextStyle(
color: Colors.white,
fontWeight: FontWeight.w600,
fontSize: 15.0,
),
Text(
order.orderID.toString(),
style: TextStyle(
fontSize: 15.0,
fontWeight: FontWeight.w400,
letterSpacing: 8.0),
),
],
),
),
],
),
),
],
)
],
),
Padding(
padding: EdgeInsets.all(8.0),
child: DistanceInKilometers(
distanceInKilometers: order.distanceInKilometers,
),
),
],
),
if (showStatus)
Row(
children: [
Container(
margin: EdgeInsets.only(bottom: 12, left: 10),
child: RoundedContainer(
margin: 4,
showShadow: false,
backgroundColor:
order.statusID == 2 ? Colors.green : Colors.red,
child: Padding(
padding: const EdgeInsets.symmetric(
vertical: 5, horizontal: 15),
child: Text(
order.description,
style: TextStyle(
color: Colors.white,
fontWeight: FontWeight.w600,
fontSize: 15.0,
),
),
),
),
),
],
)
],
),
),
]),
),
),
),

@ -67,7 +67,7 @@ class _RoundedContainerState extends State<RoundedContainer> {
boxShadow: widget.showShadow ? [
BoxShadow(
color: Hexcolor("#DBE5E6"),
color: HexColor("#DBE5E6"),
spreadRadius: 15,
blurRadius: 15,
offset: Offset(0, 7), // changes position of shadow

@ -56,7 +56,7 @@ dependencies:
# UI Reqs
dotted_border: 1.0.5
expandable: ^4.1.4
hexcolor: 1.0.1
hexcolor: ^1.0.6
# Notification Banner
dropdown_banner: ^1.4.0
@ -72,6 +72,10 @@ dependencies:
# location
location: ^3.0.2
# latlong tools
latlong: any
#gradient
gradient_app_bar: ^0.1.3
@ -79,11 +83,14 @@ dependencies:
#Barcode Scanner
flutter_barcode_scanner: ^1.0.1
#android_intent
android_intent: any
# Alerts Dailogs
sweetalert: any
# flutter_material_pickers
flutter_material_pickers: 1.7.4
@ -119,3 +126,7 @@ flutter:
- asset: assets/fonts/Metropolis/Metropolis-Regular.otf
- asset: assets/fonts/Metropolis/Metropolis-Bold.otf
- asset: assets/fonts/Metropolis/Metropolis-Light.otf
- family: HMGIcon1
fonts:
- asset: assets/fonts/icomoon.ttf

Loading…
Cancel
Save