Compare commits

...

32 Commits

Author SHA1 Message Date
Elham Rababh 7b20f789f6 Merge branch 'ZohaibIqbalKambrani' of https://gitlab.com/Cloud_Solution/driver-app into development
 Conflicts:
	pubspec.yaml
5 years ago
Elham Rababh e772873379 fix hexcolor lib 5 years ago
Zohaib Iqbal Kambrani 07e22546b5 . . . 5 years ago
Zohaib Iqbal Kambrani 9d10eda89c Driver location update on order deliver in progress... 5 years ago
Elham 0522cb4dcb Merge branch 'fix_some_issue' into 'master'
add launcher icon on android

See merge request Cloud_Solution/driver-app!129
5 years ago
Elham Rababah 786f974bfc add launcher icon on android 5 years ago
Elham a0328b6fdf Merge branch 'fix_some_issue' into 'master'
Fix some issue

See merge request Cloud_Solution/driver-app!128
5 years ago
Elham Rababah 6916cc974a ES-185:fix scroll issue 5 years ago
Elham Rababah 02763d89d5 ES-185:fix scroll issue 5 years ago
Elham b3598c5e09 Merge branch 'fix_some_issue' into 'master'
ES-185:Handel no item in the list

See merge request Cloud_Solution/driver-app!127
5 years ago
Elham Rababah 937b73f45f ES-185:Handel no item in the list 5 years ago
Elham c4a1791815 Merge branch 'fix_some_issue' into 'master'
Fix some issue

See merge request Cloud_Solution/driver-app!126
5 years ago
Elham Rababah 2bc2fb4770 ES-185:fix showModalBottomSheet height 5 years ago
Elham Rababah deb42d4215 ES-185:fix margin 5 years ago
Elham Rababah 3bc9b4e64a ES-185:fix issues 5 years ago
Elham Rababah 9b14359cb2 ES-185:fix distance 5 years ago
Elham Rababah 1356709c66 ES-185:add pharmacy order id 5 years ago
Elham a7b300327d Merge branch 'ES-185' into 'master'
Es 185

See merge request Cloud_Solution/driver-app!125
5 years ago
Elham Rababah 45927ed8f1 ES-185:fix resend opt 5 years ago
Elham Rababah 7cd74cbda5 ES-185:fix on tap issue 5 years ago
Elham Rababah c2cae941e6 ES-185:remove add note and payment, date 5 years ago
Elham Rababah e6b79e9684 ES-185:fix focus issue 5 years ago
Elham Rababah e40bd96418 ES-185:forget password function works 5 years ago
Elham f117eb64a0 Merge branch 'ES-179' into 'master'
ES-187: Fix orders List

See merge request Cloud_Solution/driver-app!124
5 years ago
Elham Rababah af43ec86ae ES-187: Fix orders List 5 years ago
Elham 371187cbd9 Merge branch 'ES-179' into 'master'
get the pending orders after insert new one

See merge request Cloud_Solution/driver-app!123
5 years ago
Elham Rababah 451bd8315e get the pending orders after insert new one 5 years ago
Elham a6de42dd05 Merge branch 'nav_issue' into 'master'
remove unused button in information_page.dart

See merge request Cloud_Solution/driver-app!122
5 years ago
Elham Rababah 7fe3677d1e remove unused button in information_page.dart 5 years ago
Elham 3b54d4c13c Merge branch 'barcode_scanner' into 'master'
fix order number

See merge request Cloud_Solution/driver-app!121
5 years ago
Elham 3f6b4a2aae Merge branch 'barcode_scanner' into 'master'
Barcode scanner

See merge request Cloud_Solution/driver-app!120
5 years ago
Elham 38a57ad7c4 Merge branch 'barcode_scanner' into 'master'
Barcode scanner

See merge request Cloud_Solution/driver-app!119
5 years ago

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

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

Binary file not shown.

Before

Width:  |  Height:  |  Size: 544 B

After

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 442 B

After

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 721 B

After

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.0 KiB

After

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 4.0 KiB

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

@ -0,0 +1 @@
5fbd1cb9b58728098d7578fb656a1766

@ -0,0 +1,203 @@
PODS:
- "app_settings (3.0.0+1)":
- Flutter
- barcode_scan (0.0.1):
- Flutter
- MTBBarcodeScanner
- SwiftProtobuf
- connectivity (0.0.1):
- Flutter
- Reachability
- connectivity_for_web (0.1.0):
- Flutter
- connectivity_macos (0.0.1):
- Flutter
- device_info (0.0.1):
- Flutter
- Flutter (1.0.0)
- flutter_flexible_toast (0.0.1):
- Flutter
- flutter_local_notifications (0.0.1):
- Flutter
- flutter_plugin_android_lifecycle (0.0.1):
- Flutter
- hexcolor (0.0.1):
- Flutter
- image_cropper (0.0.3):
- Flutter
- TOCropViewController (~> 2.5.4)
- image_picker (0.0.1):
- Flutter
- local_auth (0.0.1):
- Flutter
- location (0.0.1):
- Flutter
- location_web (0.0.1):
- Flutter
- map_launcher (0.0.1):
- Flutter
- maps_launcher (0.0.1):
- Flutter
- MTBBarcodeScanner (5.0.11)
- path_provider_linux (0.0.1):
- Flutter
- "permission_handler (5.0.1+1)":
- Flutter
- Reachability (3.2)
- shared_preferences (0.0.1):
- Flutter
- shared_preferences_linux (0.0.1):
- Flutter
- shared_preferences_macos (0.0.1):
- Flutter
- shared_preferences_web (0.0.1):
- Flutter
- SwiftProtobuf (1.11.0)
- TOCropViewController (2.5.4)
- url_launcher (0.0.1):
- Flutter
- url_launcher_linux (0.0.1):
- Flutter
- url_launcher_macos (0.0.1):
- Flutter
- url_launcher_web (0.0.1):
- Flutter
- url_launcher_windows (0.0.1):
- Flutter
DEPENDENCIES:
- app_settings (from `.symlinks/plugins/app_settings/ios`)
- barcode_scan (from `.symlinks/plugins/barcode_scan/ios`)
- connectivity (from `.symlinks/plugins/connectivity/ios`)
- connectivity_for_web (from `.symlinks/plugins/connectivity_for_web/ios`)
- connectivity_macos (from `.symlinks/plugins/connectivity_macos/ios`)
- device_info (from `.symlinks/plugins/device_info/ios`)
- Flutter (from `Flutter`)
- flutter_flexible_toast (from `.symlinks/plugins/flutter_flexible_toast/ios`)
- flutter_local_notifications (from `.symlinks/plugins/flutter_local_notifications/ios`)
- flutter_plugin_android_lifecycle (from `.symlinks/plugins/flutter_plugin_android_lifecycle/ios`)
- hexcolor (from `.symlinks/plugins/hexcolor/ios`)
- image_cropper (from `.symlinks/plugins/image_cropper/ios`)
- image_picker (from `.symlinks/plugins/image_picker/ios`)
- local_auth (from `.symlinks/plugins/local_auth/ios`)
- location (from `.symlinks/plugins/location/ios`)
- location_web (from `.symlinks/plugins/location_web/ios`)
- map_launcher (from `.symlinks/plugins/map_launcher/ios`)
- maps_launcher (from `.symlinks/plugins/maps_launcher/ios`)
- path_provider_linux (from `.symlinks/plugins/path_provider_linux/ios`)
- permission_handler (from `.symlinks/plugins/permission_handler/ios`)
- shared_preferences (from `.symlinks/plugins/shared_preferences/ios`)
- shared_preferences_linux (from `.symlinks/plugins/shared_preferences_linux/ios`)
- shared_preferences_macos (from `.symlinks/plugins/shared_preferences_macos/ios`)
- shared_preferences_web (from `.symlinks/plugins/shared_preferences_web/ios`)
- url_launcher (from `.symlinks/plugins/url_launcher/ios`)
- url_launcher_linux (from `.symlinks/plugins/url_launcher_linux/ios`)
- url_launcher_macos (from `.symlinks/plugins/url_launcher_macos/ios`)
- url_launcher_web (from `.symlinks/plugins/url_launcher_web/ios`)
- url_launcher_windows (from `.symlinks/plugins/url_launcher_windows/ios`)
SPEC REPOS:
trunk:
- MTBBarcodeScanner
- Reachability
- SwiftProtobuf
- TOCropViewController
EXTERNAL SOURCES:
app_settings:
:path: ".symlinks/plugins/app_settings/ios"
barcode_scan:
:path: ".symlinks/plugins/barcode_scan/ios"
connectivity:
:path: ".symlinks/plugins/connectivity/ios"
connectivity_for_web:
:path: ".symlinks/plugins/connectivity_for_web/ios"
connectivity_macos:
:path: ".symlinks/plugins/connectivity_macos/ios"
device_info:
:path: ".symlinks/plugins/device_info/ios"
Flutter:
:path: Flutter
flutter_flexible_toast:
:path: ".symlinks/plugins/flutter_flexible_toast/ios"
flutter_local_notifications:
:path: ".symlinks/plugins/flutter_local_notifications/ios"
flutter_plugin_android_lifecycle:
:path: ".symlinks/plugins/flutter_plugin_android_lifecycle/ios"
hexcolor:
:path: ".symlinks/plugins/hexcolor/ios"
image_cropper:
:path: ".symlinks/plugins/image_cropper/ios"
image_picker:
:path: ".symlinks/plugins/image_picker/ios"
local_auth:
:path: ".symlinks/plugins/local_auth/ios"
location:
:path: ".symlinks/plugins/location/ios"
location_web:
:path: ".symlinks/plugins/location_web/ios"
map_launcher:
:path: ".symlinks/plugins/map_launcher/ios"
maps_launcher:
:path: ".symlinks/plugins/maps_launcher/ios"
path_provider_linux:
:path: ".symlinks/plugins/path_provider_linux/ios"
permission_handler:
:path: ".symlinks/plugins/permission_handler/ios"
shared_preferences:
:path: ".symlinks/plugins/shared_preferences/ios"
shared_preferences_linux:
:path: ".symlinks/plugins/shared_preferences_linux/ios"
shared_preferences_macos:
:path: ".symlinks/plugins/shared_preferences_macos/ios"
shared_preferences_web:
:path: ".symlinks/plugins/shared_preferences_web/ios"
url_launcher:
:path: ".symlinks/plugins/url_launcher/ios"
url_launcher_linux:
:path: ".symlinks/plugins/url_launcher_linux/ios"
url_launcher_macos:
:path: ".symlinks/plugins/url_launcher_macos/ios"
url_launcher_web:
:path: ".symlinks/plugins/url_launcher_web/ios"
url_launcher_windows:
:path: ".symlinks/plugins/url_launcher_windows/ios"
SPEC CHECKSUMS:
app_settings: d103828c9f5d515c4df9ee754dabd443f7cedcf3
barcode_scan: a5c27959edfafaa0c771905bad0b29d6d39e4479
connectivity: c4130b2985d4ef6fd26f9702e886bd5260681467
connectivity_for_web: 2b8584556930d4bd490d82b836bcf45067ce345b
connectivity_macos: e2e9731b6b22dda39eb1b128f6969d574460e191
device_info: d7d233b645a32c40dfdc212de5cf646ca482f175
Flutter: 0e3d915762c693b495b44d77113d4970485de6ec
flutter_flexible_toast: 0547e740cae0c33bb7c51bcd931233f4584e1143
flutter_local_notifications: 9e4738ce2471c5af910d961a6b7eadcf57c50186
flutter_plugin_android_lifecycle: dc0b544e129eebb77a6bfb1239d4d1c673a60a35
hexcolor: fdfb9c4258ad96e949c2dbcdf790a62194b8aa89
image_cropper: c8f9b4157933c7bb965a66d1c5e6c8fd408c6eb4
image_picker: 9c3312491f862b28d21ecd8fdf0ee14e601b3f09
local_auth: 25938960984c3a7f6e3253e3f8d962fdd16852bd
location: 3a2eed4dd2fab25e7b7baf2a9efefe82b512d740
location_web: b94e7433cfe28c0f7c8923c2ee482824b32e55a7
map_launcher: e325db1261d029ff33e08e03baccffe09593ffea
maps_launcher: eae38ee13a9c3f210fa04e04bb4c073fa4c6ed92
MTBBarcodeScanner: f453b33c4b7dfe545d8c6484ed744d55671788cb
path_provider_linux: 4d630dc393e1f20364f3e3b4a2ff41d9674a84e4
permission_handler: eac8e15b4a1a3fba55b761d19f3f4e6b005d15b6
Reachability: 33e18b67625424e47b6cde6d202dce689ad7af96
shared_preferences: af6bfa751691cdc24be3045c43ec037377ada40d
shared_preferences_linux: afefbfe8d921e207f01ede8b60373d9e3b566b78
shared_preferences_macos: f3f29b71ccbb56bf40c9dd6396c9acf15e214087
shared_preferences_web: 141cce0c3ed1a1c5bf2a0e44f52d31eeb66e5ea9
SwiftProtobuf: f889fe5772f90ef7d7b8aac352d1fddf39650713
TOCropViewController: 2a1ae1242600b1f2d996fd91a5268b2309a33b5c
url_launcher: 6fef411d543ceb26efce54b05a0a40bfd74cbbef
url_launcher_linux: ac237cb7a8058736e4aae38bdbcc748a4b394cc0
url_launcher_macos: fd7894421cd39320dce5f292fc99ea9270b2a313
url_launcher_web: e5527357f037c87560776e36436bf2b0288b965c
url_launcher_windows: 683d7c283894db8d1914d3ab2223b20cc1ad95d5
PODFILE CHECKSUM: c34e2287a9ccaa606aeceab922830efb9a6ff69a
COCOAPODS: 1.10.0.rc.1

@ -261,9 +261,9 @@
{ {
"uid": "d755ac5bb912e95877e670a67bf4528d", "uid": "d755ac5bb912e95877e670a67bf4528d",
"css": "phone_call", "css": "phone_call",
"code": 59398, "code": 59401,
"src": "custom_icons", "src": "custom_icons",
"selected": false, "selected": true,
"svg": { "svg": {
"path": "M907.5 618.9L829.1 540.7A45.6 45.6 0 0 0 764.4 540.7L764.4 540.7 719.7 585.5A9.9 9.9 0 0 1 707 586.6 517.6 517.6 0 0 1 586 467.8 9.9 9.9 0 0 1 586.9 455.1L633 409A45.7 45.7 0 0 0 633 344.4L554.6 265.9A46.7 46.7 0 0 0 489.9 265.9L465.1 290.8A139.5 139.5 0 0 0 430.3 433.2 417.6 417.6 0 0 0 481.3 536.8 544.9 544.9 0 0 0 638.1 690.9 400.4 400.4 0 0 0 754.2 742.5 134.2 134.2 0 0 0 786.7 746.4 141.4 141.4 0 0 0 886.1 704.6L907.4 683.2A45.6 45.6 0 0 0 907.5 618.9Z", "path": "M907.5 618.9L829.1 540.7A45.6 45.6 0 0 0 764.4 540.7L764.4 540.7 719.7 585.5A9.9 9.9 0 0 1 707 586.6 517.6 517.6 0 0 1 586 467.8 9.9 9.9 0 0 1 586.9 455.1L633 409A45.7 45.7 0 0 0 633 344.4L554.6 265.9A46.7 46.7 0 0 0 489.9 265.9L465.1 290.8A139.5 139.5 0 0 0 430.3 433.2 417.6 417.6 0 0 0 481.3 536.8 544.9 544.9 0 0 0 638.1 690.9 400.4 400.4 0 0 0 754.2 742.5 134.2 134.2 0 0 0 786.7 746.4 141.4 141.4 0 0 0 886.1 704.6L907.4 683.2A45.6 45.6 0 0 0 907.5 618.9Z",
"width": 1344 "width": 1344
@ -271,6 +271,34 @@
"search": [ "search": [
"phone_call" "phone_call"
] ]
},
{
"uid": "3ee830f1177337ad723625ace69b886b",
"css": "qustion_mark",
"code": 59411,
"src": "custom_icons",
"selected": true,
"svg": {
"path": "M215.2 420.5C344.6 414.9 436 362.9 436 295.4 436 236.3 381.2 185.6 295.4 185.6 226.4 185.6 163.2 222.2 118.1 272.9L0 151.9C80.1 61.9 191.2 0 330.5 0 517.5 0 646.9 116.7 646.9 275.7 646.9 402.3 542.9 516.2 398 549.9V651.2H215.2ZM175.8 869.2A129.5 129.5 0 0 1 306.6 744 128 128 0 0 1 306.6 1000 130.6 130.6 0 0 1 175.8 869.2Z",
"width": 647
},
"search": [
"group-8"
]
},
{
"uid": "e4101bb9283eee95eea80812a39424cc",
"css": "exclamation_mark",
"code": 59412,
"src": "custom_icons",
"selected": true,
"svg": {
"path": "M0 867A131.7 131.7 0 0 1 133 739.6 130.2 130.2 0 0 1 133 1000 132.8 132.8 0 0 1 0 867ZM15.7 0H251.8L204.6 636.6H63Z",
"width": 260
},
"search": [
"group-14"
]
} }
] ]
} }

@ -21,22 +21,46 @@ class DriverApp {
static const _kFontFam = 'DriverApp'; static const _kFontFam = 'DriverApp';
static const _kFontPkg = null; static const _kFontPkg = null;
static const IconData location_1 = IconData(0xe800, fontFamily: _kFontFam, fontPackage: _kFontPkg); static const IconData location_1 =
static const IconData logo = IconData(0xe801, fontFamily: _kFontFam, fontPackage: _kFontPkg); IconData(0xe800, fontFamily: _kFontFam, fontPackage: _kFontPkg);
static const IconData logout_icon = IconData(0xe802, fontFamily: _kFontFam, fontPackage: _kFontPkg); static const IconData logo =
static const IconData closed_box = IconData(0xe803, fontFamily: _kFontFam, fontPackage: _kFontPkg); IconData(0xe801, fontFamily: _kFontFam, fontPackage: _kFontPkg);
static const IconData location = IconData(0xe804, fontFamily: _kFontFam, fontPackage: _kFontPkg); static const IconData logout_icon =
static const IconData open_box = IconData(0xe805, fontFamily: _kFontFam, fontPackage: _kFontPkg); IconData(0xe802, fontFamily: _kFontFam, fontPackage: _kFontPkg);
static const IconData settings_icon = IconData(0xe806, fontFamily: _kFontFam, fontPackage: _kFontPkg); static const IconData closed_box =
static const IconData qr = IconData(0xe807, fontFamily: _kFontFam, fontPackage: _kFontPkg); IconData(0xe803, fontFamily: _kFontFam, fontPackage: _kFontPkg);
static const IconData language_icon = IconData(0xe808, fontFamily: _kFontFam, fontPackage: _kFontPkg); static const IconData location =
static const IconData not_available = IconData(0xe80a, fontFamily: _kFontFam, fontPackage: _kFontPkg); IconData(0xe804, fontFamily: _kFontFam, fontPackage: _kFontPkg);
static const IconData rejected_icon = IconData(0xe80b, fontFamily: _kFontFam, fontPackage: _kFontPkg); static const IconData open_box =
static const IconData not_reachable_icon = IconData(0xe80c, fontFamily: _kFontFam, fontPackage: _kFontPkg); IconData(0xe805, fontFamily: _kFontFam, fontPackage: _kFontPkg);
static const IconData group_74 = IconData(0xe80d, fontFamily: _kFontFam, fontPackage: _kFontPkg); static const IconData settings_icon =
static const IconData message = IconData(0xe80e, fontFamily: _kFontFam, fontPackage: _kFontPkg); IconData(0xe806, fontFamily: _kFontFam, fontPackage: _kFontPkg);
static const IconData whatsapp = IconData(0xe80f, fontFamily: _kFontFam, fontPackage: _kFontPkg); static const IconData qr =
static const IconData call = IconData(0xe810, fontFamily: _kFontFam, fontPackage: _kFontPkg); IconData(0xe807, fontFamily: _kFontFam, fontPackage: _kFontPkg);
static const IconData bell_icon = IconData(0xe811, fontFamily: _kFontFam, fontPackage: _kFontPkg); static const IconData language_icon =
static const IconData deliverd_icon = IconData(0xe812, fontFamily: _kFontFam, fontPackage: _kFontPkg); IconData(0xe808, fontFamily: _kFontFam, fontPackage: _kFontPkg);
static const IconData phone_call =
IconData(0xe809, fontFamily: _kFontFam, fontPackage: _kFontPkg);
static const IconData not_available =
IconData(0xe80a, fontFamily: _kFontFam, fontPackage: _kFontPkg);
static const IconData rejected_icon =
IconData(0xe80b, fontFamily: _kFontFam, fontPackage: _kFontPkg);
static const IconData not_reachable_icon =
IconData(0xe80c, fontFamily: _kFontFam, fontPackage: _kFontPkg);
static const IconData group_74 =
IconData(0xe80d, fontFamily: _kFontFam, fontPackage: _kFontPkg);
static const IconData message =
IconData(0xe80e, fontFamily: _kFontFam, fontPackage: _kFontPkg);
static const IconData whatsapp =
IconData(0xe80f, fontFamily: _kFontFam, fontPackage: _kFontPkg);
static const IconData call =
IconData(0xe810, fontFamily: _kFontFam, fontPackage: _kFontPkg);
static const IconData bell_icon =
IconData(0xe811, fontFamily: _kFontFam, fontPackage: _kFontPkg);
static const IconData deliverd_icon =
IconData(0xe812, fontFamily: _kFontFam, fontPackage: _kFontPkg);
static const IconData qustion_mark =
IconData(0xe813, fontFamily: _kFontFam, fontPackage: _kFontPkg);
static const IconData exclamation_mark =
IconData(0xe814, fontFamily: _kFontFam, fontPackage: _kFontPkg);
} }

Binary file not shown.

@ -2,19 +2,27 @@ import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
/// End points /// End points
const BASE_URL = 'https://uat.hmgwebservices.com/Services'; const isUAT = true;
const GET_PROJECT = '/Lists.svc/REST/GetProject'; const BASE_URL = 'https://${isUAT ? "uat." : ""}hmgwebservices.com/';
const LOGIN = "/Authentication.svc/REST/CheckDriverAuthentication";
const GET_ALL_ORDERS = '/Patients.svc/REST/PatientER_Delivery_GetAllOrder'; const PING_SERVICE = '/Services/Weather.svc/REST/CheckConnectivity';
const SCAN_QR = '/Patients.svc/REST/PatientER_Delivery_OrderInsert'; const GET_PROJECT = '/Services/Lists.svc/REST/GetProject';
const UPDATE_ORDER_STATUS = const LOGIN = "/Services/Authentication.svc/REST/CheckDriverAuthentication";
'/Patients.svc/REST/PatientER_Delivery_UpdateOrderStatus'; const GET_OPT = "/Services/Patients.svc/REST/PatientER_Delivery_SendSMSForForgetPassword";
const NEXT_ORDER = "/Patients.svc/REST/PatientER_Delivery_NextOrder"; 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_DELIVERD_ORDER =
'/Patients.svc/REST/PatientER_Delivery_GetAllDeliverdOrder'; const GET_ALL_ORDERS = '/Services/Patients.svc/REST/PatientER_Delivery_GetAllOrder';
const GET_ALL_ORDERS_STATUS = const SCAN_QR = '/Services/Patients.svc/REST/PatientER_Delivery_OrderInsert';
'/Patients.svc/REST/PatientER_Delivery_GetAllOrderstatus'; 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 /// Body Constant
const CHANNEL = 9; const CHANNEL = 9;
@ -34,3 +42,11 @@ const LINEAR_GRADIENT = LinearGradient(
], ],
// stops: [0.0, 1.0], // 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;
}

@ -4,7 +4,7 @@ const Map<String, Map<String, String>> localizedValues = {
'language': {'en': 'App Language', 'ar': 'لغة التطبيق'}, 'language': {'en': 'App Language', 'ar': 'لغة التطبيق'},
'lanEnglish': {'en': 'English', 'ar': 'English'}, 'lanEnglish': {'en': 'English', 'ar': 'English'},
'lanArabic': {'en': 'العربية', 'ar': 'العربية'}, 'lanArabic': {'en': 'العربية', 'ar': 'العربية'},
'cancel': {'en': 'CANCEL', 'ar': 'الغاء'}, 'cancel': {'en': 'Cancel', 'ar': 'الغاء'},
'done': {'en': 'DONE', 'ar': 'تأكيد'}, 'done': {'en': 'DONE', 'ar': 'تأكيد'},
'replay2': {'en': 'Replay', 'ar': 'رد الطبيب'}, 'replay2': {'en': 'Replay', 'ar': 'رد الطبيب'},
'home': {'en': 'Home', 'ar': 'الرئيسية'}, 'home': {'en': 'Home', 'ar': 'الرئيسية'},
@ -14,7 +14,7 @@ const Map<String, Map<String, String>> localizedValues = {
'booking': {'en': 'Booking', 'ar': 'حجز'}, 'booking': {'en': 'Booking', 'ar': 'حجز'},
'enterId': {'en': 'User Name', 'ar': 'اسم المستخدم'}, 'enterId': {'en': 'User Name', 'ar': 'اسم المستخدم'},
'pleaseEnterYourID': { 'pleaseEnterYourID': {
'en': 'Please enter your ', 'en': 'Please enter your user name',
'ar': 'الرجاء ادخال اسم المستخدم' 'ar': 'الرجاء ادخال اسم المستخدم'
}, },
'enterPassword': {'en': 'Password', 'ar': 'كلمه السر'}, 'enterPassword': {'en': 'Password', 'ar': 'كلمه السر'},
@ -26,11 +26,17 @@ const Map<String, Map<String, String>> localizedValues = {
'en': 'Please insert username and password to login', 'en': 'Please insert username and password to login',
'ar': 'الرجاء إدخال اسم المستخدم وكلمة المرور لتسجيل الدخول' 'ar': 'الرجاء إدخال اسم المستخدم وكلمة المرور لتسجيل الدخول'
}, },
'enterForgetIdMsg': {
'en':
'We will send a One Time Password (OTP) to your Mobile Number to reset your password.',
'ar':
'سنرسل كلمة مرور لمرة واحدة (OTP) إلى حسابك رقم الهاتف المحمول لإعادة تعيين كلمة المرور الخاصة بك.'
},
'forgotPassword': {'en': 'Forgot Password?', 'ar': 'هل نسيت كلمة المرور ؟'}, 'forgotPassword': {'en': 'Forgot Password?', 'ar': 'هل نسيت كلمة المرور ؟'},
'login': {'en': 'Login', 'ar': 'تسجيل الدخول'}, 'login': {'en': 'Login', 'ar': 'تسجيل الدخول'},
'haveGreatDay': {'en': 'have a great day,', 'ar': 'أتمنى لك يوما جميلا '}, 'haveGreatDay': {'en': 'have a great day,', 'ar': 'أتمنى لك يوما جميلا '},
'youHave': {'en': 'You Have', 'ar': 'يوجد لديك'}, 'youHave': {'en': 'You Have', 'ar': 'يوجد لديك'},
'deliveredPackages': {'en': 'Delivered \nPackages', 'ar': 'الطرود\n المسلمة'}, 'deliveredPackages': {'en': 'Processed \nPackages', 'ar': 'الطرود\n المسلمة'},
'seeAll': {'en': 'See All', 'ar': 'اظهار الكل'}, 'seeAll': {'en': 'See All', 'ar': 'اظهار الكل'},
'nearestDropOffs': {'en': 'Nearest Drop-Offs', 'ar': 'أقرب نقطة إنزال'}, 'nearestDropOffs': {'en': 'Nearest Drop-Offs', 'ar': 'أقرب نقطة إنزال'},
'undeliveredPackages': { 'undeliveredPackages': {
@ -63,7 +69,7 @@ const Map<String, Map<String, String>> localizedValues = {
}, },
'delivered': {'en': 'Delivered', 'ar': 'وصل'}, 'delivered': {'en': 'Delivered', 'ar': 'وصل'},
'deliveredAccepted': {'en': 'Delivered/Accepted', 'ar': 'تم التوصيل/مقبول'}, 'deliveredAccepted': {'en': 'Delivered/Accepted', 'ar': 'تم التوصيل/مقبول'},
'deliveredRejected': {'en': 'Delivered/Rejected', 'ar': 'تم التوصيل/مرفوض'}, 'deliveredRejected': {'en': 'Rejected', 'ar': 'مرفوض'},
'canceled': {'en': 'Canceled', 'ar': 'الغى'}, 'canceled': {'en': 'Canceled', 'ar': 'الغى'},
'selectAction': {'en': 'Select Action', 'ar': 'الرجاء الاختيار'}, 'selectAction': {'en': 'Select Action', 'ar': 'الرجاء الاختيار'},
'youHaveSelected': {'en': 'You have selected:', 'ar': 'لقد قمت باختيار:'}, 'youHaveSelected': {'en': 'You have selected:', 'ar': 'لقد قمت باختيار:'},
@ -71,4 +77,50 @@ const Map<String, Map<String, String>> localizedValues = {
'areYouSure': {'en': 'Are you sure?', 'ar': 'هل أنت واثق؟'}, 'areYouSure': {'en': 'Are you sure?', 'ar': 'هل أنت واثق؟'},
'languageText': {'en': 'Language', 'ar': 'اللغة'}, 'languageText': {'en': 'Language', 'ar': 'اللغة'},
'notification': {'en': 'Notification', 'ar': 'تنبيهات'}, 'notification': {'en': 'Notification', 'ar': 'تنبيهات'},
'getOPT': {'en': 'Get OPT', 'ar': 'OPT الحصول على'},
'enterVerificationMsg': {
'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 TOKEN = 'token';
const APP_LANGUAGE = 'language'; const APP_LANGUAGE = 'language';
const USER_PROFILE = 'user-profile'; 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{
}

@ -25,7 +25,7 @@ class DeliverdOrderResModel {
String patientID; String patientID;
bool patientOutSA; bool patientOutSA;
int channel; int channel;
double distanceInKilometers; dynamic distanceInKilometers;
List<ItemsQuantitiesList> itemsQuantitiesList; List<ItemsQuantitiesList> itemsQuantitiesList;
DeliverdOrderResModel( DeliverdOrderResModel(

@ -9,12 +9,13 @@ class PendingOrders {
String firstName; String firstName;
String lastName; String lastName;
String mobileNumber; String mobileNumber;
int distanceInKilometers; dynamic distanceInKilometers;
String longitude; String longitude;
String latitude; String latitude;
int driverAppPageID;
PendingOrders({ PendingOrders(
this.driverID, {this.driverID,
this.searchKey, this.searchKey,
this.pageSize, this.pageSize,
this.pageIndex, this.pageIndex,
@ -27,6 +28,7 @@ class PendingOrders {
this.distanceInKilometers, this.distanceInKilometers,
this.longitude, this.longitude,
this.latitude, this.latitude,
this.driverAppPageID
}); });
PendingOrders.fromJson(Map<String, dynamic> json) { PendingOrders.fromJson(Map<String, dynamic> json) {
@ -41,6 +43,7 @@ class PendingOrders {
lastName = json['LastName']; lastName = json['LastName'];
mobileNumber = json['MobileNumber']; mobileNumber = json['MobileNumber'];
distanceInKilometers = json['DistanceInKilometers']; distanceInKilometers = json['DistanceInKilometers'];
driverAppPageID = json['DriverAppPageID'];
} }
Map<String, dynamic> toJson() { Map<String, dynamic> toJson() {
@ -54,7 +57,7 @@ class PendingOrders {
data['MobileNo'] = this.mobileNo; data['MobileNo'] = this.mobileNo;
data['Longitude'] = this.longitude; data['Longitude'] = this.longitude;
data['Latitude'] = this.latitude; data['Latitude'] = this.latitude;
data['DriverAppPageID'] = this.driverAppPageID;
return data; return data;
} }
} }

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

@ -9,6 +9,9 @@ class AuthenticationService extends BaseService {
bool isLoading = true; bool isLoading = true;
AuthenticatedUser authenticatedUser; AuthenticatedUser authenticatedUser;
String token; String token;
String loginTokenId;
String tokenID;
int userID;
AuthenticationService() { AuthenticationService() {
// getUserAuthentication(); // getUserAuthentication();
@ -32,4 +35,67 @@ class AuthenticationService extends BaseService {
throw error; throw error;
} }
} }
getOpt(int driverId) async {
hasError = false;
userID = driverId;
try {
await baseAppClient.post(GET_OPT,
onSuccess: (dynamic response, int statusCode) {
loginTokenId = response['LogInTokenID'];
print(response['ActivationCode']);
}, onFailure: (String error, int statusCode) {
hasError = true;
super.error = error;
}, body: {"DriverID": driverId});
} catch (error) {
hasError = true;
super.error = error;
throw error;
}
}
changePassword(String password, String confirmPassword) async {
hasError = false;
try {
await baseAppClient.post(CHANGE_FORGOT_PASSWORD,
onSuccess: (dynamic response, int statusCode) {
loginTokenId = response['LogInTokenID'];
print(response['ActivationCode']);
}, onFailure: (String error, int statusCode) {
hasError = true;
super.error = error;
}, body: {
"TokenID": tokenID,
"NewPassword": password,
"ConfirmPassword": confirmPassword,
"UserID": userID
});
} catch (error) {
hasError = true;
super.error = error;
throw error;
}
}
checkActivationCode(int activationCode) async {
hasError = false;
try {
await baseAppClient.post(CHECK_ACTIVATION_CODE,
onSuccess: (dynamic response, int statusCode) {
tokenID = response['TokenID'];
print(response['ActivationCode']);
}, onFailure: (String error, int statusCode) {
hasError = true;
super.error = error;
}, body: {
"LogInTokenID": loginTokenId,
"activationCode": activationCode
});
} catch (error) {
hasError = true;
super.error = error;
throw error;
}
}
} }

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

@ -21,16 +21,11 @@ class OrdersService extends BaseService {
List<PendingOrdersRes> get nextOrdersList => _nextOrdersList; List<PendingOrdersRes> get nextOrdersList => _nextOrdersList;
bool isOrderInserted; bool isOrderInserted;
bool isOrderStatusUpdated; bool isOrderStatusUpdated;
bool isGetPendingOrdersServices = false;
bool isGetDeliveredOrdersServices = false;
int listCountDelivered; int listCountDelivered;
int listCountUnDelivered; int listCountUnDelivered;
Future getPendingOrders() async { Future getPendingOrders(int driverAppPageID) async {
LocationData loc = await Utils.getLocation(); LocationData loc = await Utils.getLocation();
if (user != null) {
isGetPendingOrdersServices = true;
}
if (loc != null) { if (loc != null) {
PendingOrders _requestGetPendingOrders = PendingOrders( PendingOrders _requestGetPendingOrders = PendingOrders(
searchKey: "", searchKey: "",
@ -38,7 +33,7 @@ class OrdersService extends BaseService {
pageIndex: 0, pageIndex: 0,
latitude: loc.latitude.toString(), latitude: loc.latitude.toString(),
longitude: loc.longitude.toString(), longitude: loc.longitude.toString(),
); driverAppPageID: driverAppPageID);
hasError = false; hasError = false;
try { try {
await baseAppClient.post(GET_ALL_ORDERS, await baseAppClient.post(GET_ALL_ORDERS,
@ -105,8 +100,7 @@ class OrdersService extends BaseService {
try { try {
await baseAppClient.post(UPDATE_ORDER_STATUS, await baseAppClient.post(UPDATE_ORDER_STATUS,
onSuccess: (dynamic response, int statusCode) { onSuccess: (dynamic response, int statusCode) {
isOrderStatusUpdated = isOrderStatusUpdated = response["PatientER_Delivery_IsOrderUpdated"];
response["PatientER_Delivery_IsOrderUpdated"];
listCountUnDelivered--; listCountUnDelivered--;
listCountDelivered++; listCountDelivered++;
}, onFailure: (String error, int statusCode) { }, onFailure: (String error, int statusCode) {
@ -147,10 +141,7 @@ class OrdersService extends BaseService {
pageIndex: 0, pageIndex: 0,
latitude: loc.latitude.toString(), latitude: loc.latitude.toString(),
longitude: loc.longitude.toString(), longitude: loc.longitude.toString(),
); driverAppPageID: 0);
if (user != null) {
isGetDeliveredOrdersServices = true;
}
if (loc != null) { if (loc != null) {
hasError = false; hasError = false;
try { try {

@ -13,6 +13,7 @@ class AuthenticationViewModel with ChangeNotifier {
AuthenticationService _authenticationService = AuthenticationService _authenticationService =
locator<AuthenticationService>(); locator<AuthenticationService>();
AuthenticatedUser user; AuthenticatedUser user;
int get userId => _authenticationService.userID;
bool isLogin = false; bool isLogin = false;
bool isLoading = false; bool isLoading = false;
bool isError = false; bool isError = false;
@ -80,6 +81,54 @@ class AuthenticationViewModel with ChangeNotifier {
} }
} }
getOpt(int driverID) async {
isLoading = true;
notifyListeners();
await _authenticationService.getOpt(driverID);
if (_authenticationService.hasError) {
error = _authenticationService.error;
isLoading = false;
isError = true;
notifyListeners();
} else {
isLoading = false;
isError = false;
notifyListeners();
}
}
changePassword(String password, String confirmPassword) async {
isLoading = true;
notifyListeners();
await _authenticationService.changePassword(password, confirmPassword);
if (_authenticationService.hasError) {
error = _authenticationService.error;
isLoading = false;
isError = true;
notifyListeners();
} else {
isLoading = false;
isError = false;
notifyListeners();
}
}
checkActivationCode(int driverID) async {
isLoading = true;
notifyListeners();
await _authenticationService.checkActivationCode(driverID);
if (_authenticationService.hasError) {
error = _authenticationService.error;
isLoading = false;
isError = true;
notifyListeners();
} else {
isLoading = false;
isError = false;
notifyListeners();
}
}
logout() async { logout() async {
isLoading = false; isLoading = false;
isError = false; isError = false;

@ -1,16 +1,20 @@
import 'package:driverapp/core/enum/viewstate.dart'; 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/deliverd_order_res_model.dart';
import 'package:driverapp/core/model/orders/next_order_request_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/pending_orders_res_model.dart';
import 'package:driverapp/core/model/orders/update_order_status_request_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/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:driverapp/core/service/orders_service.dart';
import 'package:flutter/cupertino.dart';
import '../../locator.dart'; import '../../locator.dart';
import 'base_view_model.dart'; import 'base_view_model.dart';
class OrdersViewModel extends BaseViewModel { class OrdersViewModel extends BaseViewModel {
OrdersService _ordersService = locator<OrdersService>(); OrdersService _ordersService = locator<OrdersService>();
DeliveryTrackingServices deliveryService = locator<DeliveryTrackingServices>();
List<PendingOrdersRes> get orders => _ordersService.orders; List<PendingOrdersRes> get orders => _ordersService.orders;
@ -24,9 +28,9 @@ class OrdersViewModel extends BaseViewModel {
int get listCountUnDelivered => _ordersService.listCountUnDelivered; int get listCountUnDelivered => _ordersService.listCountUnDelivered;
Future getPendingOrders() async { Future getPendingOrders(int driverAppPageID) async {
setState(ViewState.Busy); setState(ViewState.Busy);
await _ordersService.getPendingOrders(); await _ordersService.getPendingOrders(driverAppPageID);
if (_ordersService.hasError) { if (_ordersService.hasError) {
error = _ordersService.error; error = _ordersService.error;
setState(ViewState.Error); setState(ViewState.Error);
@ -64,15 +68,37 @@ class OrdersViewModel extends BaseViewModel {
setState(ViewState.Idle); setState(ViewState.Idle);
} }
Future updateOrderStatus( Future<ResponseModel> updateOrderStatus({@required int orderNo, @required int status, String rejectionReason}) async {
UpdateOrderStatusRequestModel updateOrderStatusRequestModel) async { var updateOrderStatusRequestModel
= UpdateOrderStatusRequestModel(
deliveryOrderID: orderNo,
deliveryOrderStatus: status,
rejectionReason: rejectionReason,
cancleReason: rejectionReason);
setState(ViewState.BusyLocal); setState(ViewState.BusyLocal);
await _ordersService.updateOrderStatus(updateOrderStatusRequestModel); await _ordersService.updateOrderStatus(updateOrderStatusRequestModel);
if (_ordersService.hasError) { if (_ordersService.hasError) {
error = _ordersService.error; error = _ordersService.error;
setState(ViewState.ErrorLocal); setState(ViewState.ErrorLocal);
} else return ResponseModel(isSuccessful: false, message: error);
} else {
setState(ViewState.Idle); 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 { Future nextOrder(NextOrderRequestModel nextOrderRequestModel) async {
@ -85,6 +111,31 @@ class OrdersViewModel extends BaseViewModel {
setState(ViewState.Idle); 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() { showBottomSheet() {
isBottomSheetAppear = true; isBottomSheetAppear = true;
setState(ViewState.Idle); setState(ViewState.Idle);

@ -1,3 +1,4 @@
import 'package:driverapp/core/service/delivery_tracking_services.dart';
import 'package:get_it/get_it.dart'; import 'package:get_it/get_it.dart';
import 'core/service/authentication_service.dart'; import 'core/service/authentication_service.dart';
@ -15,6 +16,7 @@ void setupLocator() {
locator.registerLazySingleton(() => HospitalService()); locator.registerLazySingleton(() => HospitalService());
locator.registerLazySingleton(() => AuthenticationService()); locator.registerLazySingleton(() => AuthenticationService());
locator.registerLazySingleton(() => OrdersService()); locator.registerLazySingleton(() => OrdersService());
locator.registerLazySingleton(() => DeliveryTrackingServices());
/// View Model /// View Model
locator.registerFactory(() => HospitalViewModel()); 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/pages/splash_screen_page.dart';
import 'package:driverapp/uitl/app_shared_preferences.dart';
import 'package:driverapp/uitl/translations_delegate_base.dart'; import 'package:driverapp/uitl/translations_delegate_base.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_localizations/flutter_localizations.dart'; import 'package:flutter_localizations/flutter_localizations.dart';
import 'package:provider/provider.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 'config/size_config.dart';
import 'core/viewModels/authentication_view_model.dart'; import 'core/viewModels/authentication_view_model.dart';
import 'core/viewModels/project_view_model.dart'; import 'core/viewModels/project_view_model.dart';
@ -14,9 +19,30 @@ void main() {
runApp(MyApp()); 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 @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
WidgetsBinding.instance.addObserver(this);
SharedPreferences.getInstance().then((value){
var activeOrders = value.getStringList(ACTIVE_DELIVERIES) ?? [];
locator<DeliveryTrackingServices>().setActiveDeliveringOrders(activeOrders);
});
return LayoutBuilder( return LayoutBuilder(
builder: (context, constraints) { builder: (context, constraints) {
return OrientationBuilder( return OrientationBuilder(
@ -30,6 +56,9 @@ class MyApp extends StatelessWidget {
ChangeNotifierProvider<AuthenticationViewModel>( ChangeNotifierProvider<AuthenticationViewModel>(
create: (context) => AuthenticationViewModel(), create: (context) => AuthenticationViewModel(),
), ),
ChangeNotifierProvider<OrdersViewModel>(
create: (context) => OrdersViewModel(),
),
], ],
child: Consumer<ProjectViewModel>( child: Consumer<ProjectViewModel>(
builder: (context, projectProvider, child) => MaterialApp( builder: (context, projectProvider, child) => MaterialApp(
@ -81,9 +110,9 @@ class MyApp extends StatelessWidget {
), ),
), ),
), ),
home: SplashScreenPage(), // home: SplashScreenPage(),
// initialRoute: '/', initialRoute: '/',
// routes: {'/': (context) => RootPage()}, routes: {'/': (context) => SplashScreenPage()},
debugShowCheckedModeBanner: false, debugShowCheckedModeBanner: false,
), ),
), ),

@ -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),
),
);
}
}

@ -0,0 +1,195 @@
import 'package:driverapp/app-icons/driver_app_icons.dart';
import 'package:driverapp/core/viewModels/authentication_view_model.dart';
import 'package:driverapp/core/viewModels/project_view_model.dart';
import 'package:driverapp/pages/authentication/verification_page.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/input/text_field.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 '../../root_page.dart';
// ignore: must_be_immutable
class ForgetPasswordPage extends StatelessWidget {
final forgetPasswordFormKey = GlobalKey<FormState>();
int driverID;
ProjectViewModel projectViewModel;
AuthenticationViewModel authenticationViewModel;
getOpt(BuildContext context) async {
if (forgetPasswordFormKey.currentState.validate()) {
forgetPasswordFormKey.currentState.save();
await authenticationViewModel.getOpt(driverID);
if (authenticationViewModel.isError) {
Utils.showErrorToast(authenticationViewModel.error);
} else {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => VerificationPage()),
);
}
}
}
@override
Widget build(BuildContext context) {
projectViewModel = Provider.of(context);
authenticationViewModel = Provider.of(context);
return AnimatedSwitcher(
duration: Duration(microseconds: 350),
child: AppScaffold(
isShowAppBar: false,
body: SingleChildScrollView(
child: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
FractionallySizedBox(
widthFactor: 0.80,
child: Column(
children: <Widget>[
SizedBox(
height: MediaQuery.of(context).size.height * 0.25,
),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Container(
child: Icon(
DriverApp.qustion_mark,
size: 150,
color: Theme.of(context).primaryColor,
),
margin: EdgeInsets.only(
top: 20,
),
),
],
),
SizedBox(
height: 20,
),
Column(
children: <Widget>[
Center(
child: Text(
"Forgot Password?",
style: TextStyle(
fontSize: 25,
letterSpacing: 1,
fontWeight: FontWeight.w600),
),
),
],
),
SizedBox(
height: 30,
),
SizedBox(
height: 10,
),
Form(
key: forgetPasswordFormKey,
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
Padding(
padding:
const EdgeInsets.symmetric(horizontal: 20),
child: Row(
mainAxisAlignment: MainAxisAlignment.end,
children: <Widget>[
Expanded(
child: Text(
TranslationBase.of(context)
.enterForgetIdMsg,
style: TextStyle(
fontSize: 13, color: Colors.grey),
),
),
SizedBox(
height: 10,
)
],
),
),
SizedBox(
height: 10,
),
Container(
child: TextFields(
hintText: TranslationBase.of(context).enterId,
keyboardType: TextInputType.number,
validator: (value) {
if (value.isEmpty) {
return TranslationBase.of(context)
.pleaseEnterYourID;
}
return null;
},
onSaved: (value) {
driverID = int.parse(value.trim());
},
),
),
SizedBox(
height: 20,
),
],
),
),
],
),
),
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: TranslationBase.of(context).getOPT,
onTap: () async {
await getOpt(context);
},
disabled: authenticationViewModel.isLoading,
loading: authenticationViewModel.isLoading,
),
SizedBox(
height: 30,
),
SecondaryButton(
label: TranslationBase.of(context).cancel,
onTap: () {
Navigator.pushReplacement(
context,
MaterialPageRoute(
builder: (context) => RootPage()),
);
},
color: Color(0xffE9F1F1),
borderColor: Colors.black54,
textColor: Theme.of(context).primaryColor,
),
],
))
],
),
),
),
),
);
}
}

@ -13,6 +13,8 @@ import 'package:flutter/rendering.dart';
import 'package:flutter/widgets.dart'; import 'package:flutter/widgets.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
import 'forget_password_page.dart';
class LoginPage extends StatelessWidget { class LoginPage extends StatelessWidget {
LoginRequest loginRequest = LoginRequest(); LoginRequest loginRequest = LoginRequest();
final loginFormKey = GlobalKey<FormState>(); final loginFormKey = GlobalKey<FormState>();
@ -60,13 +62,20 @@ class LoginPage extends StatelessWidget {
color: Theme.of(context).primaryColor, color: Theme.of(context).primaryColor,
), ),
margin: EdgeInsets.only( margin: EdgeInsets.only(
top: 20,
right: projectViewModel.isArabic right: projectViewModel.isArabic
? 0 ? 0
: MediaQuery.of(context).size.width * : MediaQuery
.of(context)
.size
.width *
0.15, 0.15,
left: !projectViewModel.isArabic left: !projectViewModel.isArabic
? 0 ? 0
: MediaQuery.of(context).size.width * : MediaQuery
.of(context)
.size
.width *
0.15), 0.15),
), ),
], ],
@ -214,18 +223,32 @@ class LoginPage extends StatelessWidget {
SizedBox( SizedBox(
height: 25, height: 25,
), ),
//ToDo when forget page functions ready Row(
// Row( mainAxisAlignment: MainAxisAlignment.end,
// mainAxisAlignment: MainAxisAlignment.end, children: <Widget>[
// children: <Widget>[ InkWell(
// Text( onTap: () {
// TranslationBase.of(context).forgotPassword, Navigator.pushReplacement(
// style: TextStyle( context,
// fontSize: 14, MaterialPageRoute(
// color: Theme.of(context).primaryColor), builder: (context) =>
// ), ForgetPasswordPage()
// ], ),
// ), );
},
child: Text(
TranslationBase
.of(context)
.forgotPassword,
style: TextStyle(
fontSize: 14,
color: Theme
.of(context)
.primaryColor),
),
),
],
),
], ],
), ),
), ),

@ -0,0 +1,200 @@
import 'package:driverapp/app-icons/driver_app_icons.dart';
import 'package:driverapp/core/viewModels/authentication_view_model.dart';
import 'package:driverapp/core/viewModels/project_view_model.dart';
import 'package:driverapp/root_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/input/text_field.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';
// ignore: must_be_immutable
class RestPasswordPage extends StatelessWidget {
final forgetPasswordFormKey = GlobalKey<FormState>();
// String password;
// String confirmedPassword;
ProjectViewModel projectViewModel;
AuthenticationViewModel authenticationViewModel;
TextEditingController password = TextEditingController(text: "");
TextEditingController confirmedPassword = TextEditingController(text: "");
changePassword(BuildContext context) async {
if (forgetPasswordFormKey.currentState.validate()) {
forgetPasswordFormKey.currentState.save();
await authenticationViewModel.changePassword(
password.text, confirmedPassword.text);
if (authenticationViewModel.isError) {
Utils.showErrorToast(authenticationViewModel.error);
} else {
AppToast.showSuccessToast(
message: "Your Password changed successfully");
Navigator.pushReplacement(
context,
MaterialPageRoute(builder: (context) => RootPage()),
);
}
}
}
@override
Widget build(BuildContext context) {
projectViewModel = Provider.of(context);
authenticationViewModel = Provider.of(context);
return AnimatedSwitcher(
duration: Duration(microseconds: 350),
child: AppScaffold(
isShowAppBar: false,
body: SingleChildScrollView(
child: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
FractionallySizedBox(
widthFactor: 0.80,
child: Column(
children: <Widget>[
SizedBox(
height: MediaQuery.of(context).size.height * 0.25,
),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Container(
child: Icon(
DriverApp.qustion_mark,
size: 150,
color: Theme.of(context).primaryColor,
),
margin: EdgeInsets.only(
top: 20,
),
),
],
),
SizedBox(
height: 20,
),
Column(
children: <Widget>[
Center(
child: Text(
"Rest Password",
style: TextStyle(
fontSize: 25,
letterSpacing: 1,
fontWeight: FontWeight.w600),
),
),
],
),
SizedBox(
height: 30,
),
SizedBox(
height: 10,
),
Form(
key: forgetPasswordFormKey,
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
Container(
child: TextFields(
hintText: "Password",
controller: password,
keyboardType: TextInputType.number,
validator: (value) {
if (value.isEmpty) {
return "Please enter your password";
}
return null;
},
onSaved: (value) {
// password = value;
},
),
),
SizedBox(
height: 20,
),
Container(
child: TextFields(
controller: confirmedPassword,
hintText: "Confirm Password",
keyboardType: TextInputType.text,
validator: (value) {
if (value.isEmpty) {
return "Please enter your confirm password";
}
if (confirmedPassword.text != password.text) {
return "Password your doesn't match your confirm password";
}
return null;
},
onSaved: (value) {
// confirmedPassword = value;
},
),
),
SizedBox(
height: 20,
),
],
),
),
],
),
),
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: "Change Password",
onTap: () async {
await changePassword(context);
},
disabled: authenticationViewModel.isLoading,
loading: authenticationViewModel.isLoading,
),
SizedBox(
height: 30,
),
SecondaryButton(
label: TranslationBase.of(context).cancel,
onTap: () {
Navigator.pushReplacement(
context,
MaterialPageRoute(
builder: (context) => RootPage()),
);
},
color: Color(0xffE9F1F1),
borderColor: Colors.black54,
textColor: Theme.of(context).primaryColor,
),
],
))
],
),
),
),
),
);
}
}

@ -0,0 +1,430 @@
import 'package:driverapp/app-icons/driver_app_icons.dart';
import 'package:driverapp/config/size_config.dart';
import 'package:driverapp/core/model/authentication/login_request.dart';
import 'package:driverapp/core/viewModels/authentication_view_model.dart';
import 'package:driverapp/core/viewModels/project_view_model.dart';
import 'package:driverapp/pages/authentication/reset_password_page.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 'forget_password_page.dart';
// ignore: must_be_immutable
class VerificationPage extends StatelessWidget {
LoginRequest loginRequest = LoginRequest();
final loginFormKey = GlobalKey<FormState>();
ProjectViewModel projectViewModel;
AuthenticationViewModel authenticationViewModel;
final verifyAccountForm = GlobalKey<FormState>();
Map verifyAccountFormValue = {
'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: "");
login() async {
if (loginFormKey.currentState.validate()) {
loginFormKey.currentState.save();
await authenticationViewModel.login(loginRequest);
if (authenticationViewModel.isError) {
Utils.showErrorToast(authenticationViewModel.error);
}
}
}
SizedBox buildSizedBox([double height = 20]) {
return SizedBox(
height: height,
);
}
@override
Widget build(BuildContext context) {
projectViewModel = Provider.of(context);
authenticationViewModel = Provider.of(context);
// focusD1 = FocusNode();
// focusD2 = FocusNode();
// focusD3 = FocusNode();
// focusD4 = FocusNode();
String validateCodeDigit(value) {
if (value.isEmpty) {
return 'Please enter your Password';
}
return null;
}
return AnimatedSwitcher(
duration: Duration(microseconds: 350),
child: AppScaffold(
isShowAppBar: false,
body: SingleChildScrollView(
child: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
FractionallySizedBox(
widthFactor: 0.80,
child: Column(
children: <Widget>[
SizedBox(
height: MediaQuery.of(context).size.height * 0.25,
),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Container(
child: Icon(
DriverApp.exclamation_mark,
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: verifyAccountForm,
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)
.enterVerificationMsg,
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.white,
child: TextFormField(
textInputAction:
TextInputAction.next,
style: TextStyle(
fontSize: SizeConfig
.textMultiplier *
3,
),
focusNode: focusD1,
controller: digit1,
textAlign: TextAlign.center,
keyboardType:
TextInputType.number,
decoration:
buildInputDecoration(
context),
onSaved: (val) {
verifyAccountFormValue[
'digit1'] = val;
},
validator: validateCodeDigit,
onFieldSubmitted: (_) {
FocusScope.of(context)
.requestFocus(focusD2);
},
onChanged: (val) {
if (val.length == 1) {
FocusScope.of(context)
.requestFocus(focusD2);
}
},
),
),
Container(
width: 55,
height: 55,
color: Colors.white,
child: TextFormField(
focusNode: focusD2,
controller: digit2,
textInputAction:
TextInputAction.next,
textAlign: TextAlign.center,
style: TextStyle(
fontSize: SizeConfig
.textMultiplier *
3,
),
keyboardType:
TextInputType.number,
decoration:
buildInputDecoration(
context),
validator: validateCodeDigit,
onSaved: (val) {
verifyAccountFormValue[
'digit2'] = val;
},
onFieldSubmitted: (_) {
FocusScope.of(context)
.requestFocus(focusD3);
},
onChanged: (val) {
if (val.length == 1) {
FocusScope.of(context)
.requestFocus(focusD3);
}
},
),
),
Container(
width: 55,
height: 55,
color: Colors.white,
child: TextFormField(
focusNode: focusD3,
controller: digit3,
textInputAction:
TextInputAction.next,
textAlign: TextAlign.center,
style: TextStyle(
fontSize: SizeConfig
.textMultiplier *
3,
),
keyboardType:
TextInputType.number,
decoration:
buildInputDecoration(
context),
validator: validateCodeDigit,
onSaved: (val) {
verifyAccountFormValue[
'digit3'] = val;
},
onFieldSubmitted: (_) {
FocusScope.of(context)
.requestFocus(focusD4);
},
onChanged: (val) {
if (val.length == 1) {
FocusScope.of(context)
.requestFocus(
focusD4);
}
},
)),
Container(
width: 55,
height: 55,
color: Colors.white,
child: TextFormField(
focusNode: focusD4,
controller: digit4,
textAlign: TextAlign.center,
style: TextStyle(
fontSize: SizeConfig
.textMultiplier *
3,
),
keyboardType:
TextInputType.number,
decoration:
buildInputDecoration(
context),
validator: validateCodeDigit,
onSaved: (val) {
verifyAccountFormValue[
'digit4'] = val;
},
onFieldSubmitted: (_) {
FocusScope.of(context)
.requestFocus(focusD4);
submit(model, context);
},
onChanged: (val) {
if (val.length == 1) {
FocusScope.of(context)
.requestFocus(
focusD4);
submit(model, context);
}
}),
)
],
),
),
),
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",
onTap: () {
submit(model, context);
},
disabled: authenticationViewModel.isLoading,
loading: authenticationViewModel.isLoading,
),
SizedBox(
height: 10,
),
Row(
mainAxisAlignment: MainAxisAlignment.end,
children: <Widget>[
InkWell(
onTap: () {
Navigator.pushReplacement(
context,
MaterialPageRoute(
builder: (context) =>
ForgetPasswordPage()),
);
},
child: InkWell(
onTap: () async {
await authenticationViewModel
.getOpt(authenticationViewModel.userId);
},
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(
// ts/images/password_icon.png
contentPadding: EdgeInsets.only(top: 30, bottom: 30),
enabledBorder: OutlineInputBorder(
borderRadius: BorderRadius.all(Radius.circular(10)),
borderSide: BorderSide(color: Colors.black),
),
focusedBorder: OutlineInputBorder(
borderRadius: BorderRadius.all(Radius.circular(10.0)),
borderSide: BorderSide(color: Theme.of(context).primaryColor),
),
errorBorder: OutlineInputBorder(
borderRadius: BorderRadius.all(Radius.circular(10.0)),
borderSide: BorderSide(color: Theme.of(context).errorColor),
),
focusedErrorBorder: OutlineInputBorder(
borderRadius: BorderRadius.all(Radius.circular(10.0)),
borderSide: BorderSide(color: Theme.of(context).errorColor),
),
);
}
void submit(AuthenticationViewModel model, BuildContext context) async {
if (verifyAccountForm.currentState.validate()) {
final activationCode =
digit1.text + digit2.text + digit3.text + digit4.text;
await authenticationViewModel
.checkActivationCode(int.parse(activationCode));
if (authenticationViewModel.isError) {
Utils.showErrorToast(authenticationViewModel.error);
} else {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => RestPasswordPage()),
);
}
}
}
}

@ -2,8 +2,10 @@ import 'package:driverapp/config/config.dart';
import 'package:driverapp/config/size_config.dart'; import 'package:driverapp/config/size_config.dart';
import 'package:driverapp/core/enum/viewstate.dart'; import 'package:driverapp/core/enum/viewstate.dart';
import 'package:driverapp/core/model/scan_qr/scan_qr_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/viewModels/authentication_view_model.dart'; import 'package:driverapp/core/viewModels/authentication_view_model.dart';
import 'package:driverapp/core/viewModels/orders_view_model.dart'; import 'package:driverapp/core/viewModels/orders_view_model.dart';
import 'package:driverapp/locator.dart';
import 'package:driverapp/pages/delivery/information_page.dart'; import 'package:driverapp/pages/delivery/information_page.dart';
import 'package:driverapp/pages/orders/deliverd_orders_page.dart'; import 'package:driverapp/pages/orders/deliverd_orders_page.dart';
import 'package:driverapp/pages/orders/pending_orders_page.dart'; import 'package:driverapp/pages/orders/pending_orders_page.dart';
@ -20,6 +22,7 @@ import 'package:flutter/services.dart';
import 'package:flutter_barcode_scanner/flutter_barcode_scanner.dart'; import 'package:flutter_barcode_scanner/flutter_barcode_scanner.dart';
import 'package:hexcolor/hexcolor.dart'; import 'package:hexcolor/hexcolor.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
import 'package:sweetalert/sweetalert.dart';
import '../base/base_view.dart'; import '../base/base_view.dart';
@ -31,6 +34,7 @@ class DashboardScreen extends StatefulWidget {
class _DashboardScreenState extends State<DashboardScreen> { class _DashboardScreenState extends State<DashboardScreen> {
bool _isInit = false; bool _isInit = false;
AuthenticationViewModel _authenticationViewModel; AuthenticationViewModel _authenticationViewModel;
OrdersViewModel _ordersViewModel;
@override @override
void didChangeDependencies() { void didChangeDependencies() {
@ -49,13 +53,43 @@ class _DashboardScreenState extends State<DashboardScreen> {
Utils.getLocation(); Utils.getLocation();
} }
checkActiveDelivery() async{
if(_ordersViewModel.orders.isNotEmpty){
await Future.delayed(Duration(milliseconds: 200));
var orderNos = await _ordersViewModel.getActiveDeliveringOrders();
if(orderNos.isEmpty) return;
int orderNo = int.parse(orderNos.first);
var order = _ordersViewModel.orders.firstWhere((element) => element.ePharmacyOrderNo == orderNo, orElse: (){ });
if(order == null){
// clear active deliveries if accidentally mismatched during some activity
_ordersViewModel.deliveryService.clearActiveDeliveringOrders();
return;
}
delay(300, (){
SweetAlert.show(context, subtitle: "You already have active delivery", confirmButtonText: "Continue Delivery", onPress: (isConfirm){
pop(context, (){
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => InformationPage(
item: order,
)));
});
return false;
});
});
}
}
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
int orderId;
return BaseView<OrdersViewModel>( return BaseView<OrdersViewModel>(
onModelReady: (model) async { onModelReady: (model) async {
await model.getPendingOrders(); _ordersViewModel = model;
await model.getPendingOrders(1);
checkActiveDelivery();
}, },
builder: (BuildContext context, OrdersViewModel model, Widget child) => builder: (BuildContext context, OrdersViewModel model, Widget child) =>
AppScaffold( AppScaffold(
@ -91,7 +125,7 @@ class _DashboardScreenState extends State<DashboardScreen> {
_authenticationViewModel.user.userName, _authenticationViewModel.user.userName,
style: TextStyle( style: TextStyle(
fontSize: 22.0, fontSize: 22.0,
color: Hexcolor("#343333"), color: HexColor("#343333"),
fontWeight: FontWeight.bold), fontWeight: FontWeight.bold),
), ),
), ),
@ -308,7 +342,6 @@ class _DashboardScreenState extends State<DashboardScreen> {
), ),
), ),
Text( Text(
model.listCountDelivered model.listCountDelivered
.toString(), .toString(),
style: TextStyle( style: TextStyle(
@ -483,7 +516,7 @@ class _DashboardScreenState extends State<DashboardScreen> {
Text(TranslationBase.of(context).nearestDropOffs, Text(TranslationBase.of(context).nearestDropOffs,
style: TextStyle( style: TextStyle(
fontSize: 18.0, fontSize: 18.0,
color: Hexcolor("#343333"), color: HexColor("#343333"),
fontWeight: FontWeight.bold)), fontWeight: FontWeight.bold)),
], ],
), ),
@ -518,13 +551,16 @@ class _DashboardScreenState extends State<DashboardScreen> {
], ],
), ),
), ),
if (model.state == ViewState.Idle) if (model.state == ViewState.Idle && model.orders.length == 0)
model.orders.length == 0 Padding(padding: EdgeInsets.only(top:20), child: Text("There's No Orders To deliver"),),
? Text("There's No Orders To deliver")
: SizedBox(),
NetworkBaseView( NetworkBaseView(
baseViewModel: model, baseViewModel: model,
child: Expanded( child: Expanded(
child: RefreshIndicator(
onRefresh: () async {
return await _ordersViewModel.getPendingOrders(1);
},
child: ListView.builder( child: ListView.builder(
shrinkWrap: true, shrinkWrap: true,
scrollDirection: Axis.vertical, scrollDirection: Axis.vertical,
@ -538,6 +574,7 @@ class _DashboardScreenState extends State<DashboardScreen> {
padding: EdgeInsets.symmetric(horizontal: 0.2), padding: EdgeInsets.symmetric(horizontal: 0.2),
child: OrderInfoCard( child: OrderInfoCard(
order: model.orders[index], order: model.orders[index],
isActiveToDeliver: _ordersViewModel.isActiveDeliveringOrder(index),
onTap: () { onTap: () {
Navigator.push( Navigator.push(
context, context,
@ -552,6 +589,7 @@ class _DashboardScreenState extends State<DashboardScreen> {
), ),
), ),
), ),
),
], ],
), ),
), ),
@ -574,6 +612,9 @@ class _DashboardScreenState extends State<DashboardScreen> {
if (model.state == ViewState.ErrorLocal) { if (model.state == ViewState.ErrorLocal) {
Utils.showErrorToast(model.error); Utils.showErrorToast(model.error);
} else { } else {
/// we call the service ag
/// ain in order to get them oreder
await model.getPendingOrders(1);
AppToast.showSuccessToast(message: "Order Added"); AppToast.showSuccessToast(message: "Order Added");
} }
} on PlatformException { } on PlatformException {

@ -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,8 +2,11 @@ import 'package:driverapp/config/config.dart';
import 'package:driverapp/core/enum/viewstate.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/next_order_request_model.dart';
import 'package:driverapp/core/model/orders/pending_orders_res_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/core/viewModels/orders_view_model.dart';
import 'package:driverapp/locator.dart';
import 'package:driverapp/pages/base/base_view.dart'; import 'package:driverapp/pages/base/base_view.dart';
import 'package:driverapp/root_page.dart';
import 'package:driverapp/uitl/utils.dart'; import 'package:driverapp/uitl/utils.dart';
import 'package:driverapp/widgets/buttons/secondary_button.dart'; import 'package:driverapp/widgets/buttons/secondary_button.dart';
import 'package:driverapp/widgets/delivery/customer_brief_card.dart'; import 'package:driverapp/widgets/delivery/customer_brief_card.dart';
@ -31,16 +34,19 @@ class DeliveryConfirmedPage extends StatelessWidget {
titleColor: Colors.white, titleColor: Colors.white,
body: SafeArea( body: SafeArea(
child: Container( child: Container(
decoration: BoxDecoration(gradient: LINEAR_GRADIENT), //
child: ListView( child: ListView(
children: <Widget>[ children: <Widget>[
Stack( Stack(
children: <Widget>[
Column(
children: <Widget>[ children: <Widget>[
Container( Container(
child: Column( decoration: BoxDecoration(gradient: LINEAR_GRADIENT),
children: <Widget>[ height: MediaQuery.of(context).orientation ==
Orientation.portrait
? MediaQuery.of(context).size.width * 1
: MediaQuery.of(context).size.width * 1,
child: Stack(
children: [
Container( Container(
width: MediaQuery.of(context).size.width, width: MediaQuery.of(context).size.width,
height: MediaQuery.of(context).orientation == height: MediaQuery.of(context).orientation ==
@ -51,8 +57,7 @@ class DeliveryConfirmedPage extends StatelessWidget {
top: MediaQuery.of(context).size.width * 0.14, top: MediaQuery.of(context).size.width * 0.14,
), ),
decoration: BoxDecoration( decoration: BoxDecoration(
color: Colors.white10, color: Colors.white10, shape: BoxShape.circle),
shape: BoxShape.circle),
child: Column( child: Column(
children: <Widget>[ children: <Widget>[
Icon( Icon(
@ -62,8 +67,7 @@ class DeliveryConfirmedPage extends StatelessWidget {
), ),
SizedBox( SizedBox(
height: height:
MediaQuery.of(context).size.width * MediaQuery.of(context).size.width * 0.03,
0.03,
), ),
Text( Text(
'Delivery Confirmed', 'Delivery Confirmed',
@ -74,12 +78,10 @@ class DeliveryConfirmedPage extends StatelessWidget {
), ),
SizedBox( SizedBox(
height: height:
MediaQuery.of(context).size.width * MediaQuery.of(context).size.width * 0.01,
0.01,
), ),
Text( Text(
TranslationBase.of(context) TranslationBase.of(context).confirmationSent,
.confirmationSent,
style: TextStyle( style: TextStyle(
color: Colors.white, color: Colors.white,
fontSize: 13, fontSize: 13,
@ -91,8 +93,6 @@ class DeliveryConfirmedPage extends StatelessWidget {
], ],
), ),
), ),
],
),
// Container( // Container(
// width: MediaQuery.of(context).size.width, // width: MediaQuery.of(context).size.width,
// height: MediaQuery.of(context).size.width, // height: MediaQuery.of(context).size.width,
@ -110,7 +110,9 @@ class DeliveryConfirmedPage extends StatelessWidget {
: MediaQuery.of(context).size.width * 0.60, : MediaQuery.of(context).size.width * 0.60,
), ),
decoration: BoxDecoration( decoration: BoxDecoration(
color: Colors.white, color: Theme
.of(context)
.scaffoldBackgroundColor,
borderRadius: BorderRadius.only( borderRadius: BorderRadius.only(
topLeft: Radius.circular(80), topLeft: Radius.circular(80),
topRight: Radius.circular(80)), topRight: Radius.circular(80)),
@ -133,27 +135,28 @@ class DeliveryConfirmedPage extends StatelessWidget {
: EdgeInsets.only(top: 30.0), : EdgeInsets.only(top: 30.0),
child: Column( child: Column(
children: <Widget>[ children: <Widget>[
FlatButton.icon( // TODO return add note when its needed
padding: EdgeInsets.all(14.0), // FlatButton.icon(
color: Colors.orangeAccent, // padding: EdgeInsets.all(14.0),
shape: RoundedRectangleBorder( // color: Colors.orangeAccent,
borderRadius: BorderRadius.circular(10.0), // shape: RoundedRectangleBorder(
), // borderRadius: BorderRadius.circular(10.0),
label: Text( // ),
TranslationBase.of(context).addNoteBtn, // label: Text(
style: TextStyle( // TranslationBase.of(context).addNoteBtn,
color: Colors.white, fontSize: 20.0), // style: TextStyle(
), // color: Colors.white, fontSize: 20.0),
icon: Icon( // ),
Icons.mode_edit, // icon: Icon(
color: Colors.white, // Icons.mode_edit,
), // color: Colors.white,
onPressed: () {}, // ),
), // onPressed: () {},
SizedBox( // ),
height: MediaQuery.of(context).size.width * // SizedBox(
0.00, //20, // height: MediaQuery.of(context).size.width *
), // 0.00, //20,
// ),
Padding( Padding(
padding: const EdgeInsets.only(top: 30.0), padding: const EdgeInsets.only(top: 30.0),
child: Container( child: Container(
@ -184,11 +187,13 @@ class DeliveryConfirmedPage extends StatelessWidget {
: MediaQuery.of(context).size.width * 0.4, : MediaQuery.of(context).size.width * 0.4,
), ),
child: CustomerBriefCard( child: CustomerBriefCard(
itemId: item.orderID, customerOrderId: item.orderID,
pharmacyOrderId: item.ePharmacyOrderNo,
customerFirstName: item.firstName, customerFirstName: item.firstName,
customerLastName: item.lastName, customerLastName: item.lastName,
mobileNo: item.mobileNumber, mobileNo: item.mobileNumber,
totalPayment: item.amount, totalPayment: item.amount,
distanceInKilometers: item.distanceInKilometers,
showDistance: false, showDistance: false,
deliveryTime: item.orderCreatedOn), deliveryTime: item.orderCreatedOn),
), ),
@ -208,10 +213,8 @@ class DeliveryConfirmedPage extends StatelessWidget {
NextOrderRequestModel nextOrderRequestModel = NextOrderRequestModel( NextOrderRequestModel nextOrderRequestModel = NextOrderRequestModel(
pageIndex: 0, pageIndex: 0,
pageSize: 0, pageSize: 0,
latitude: loc.latitude.toString(), latitude: loc.latitude.toString(), // "46.621730",
//"46.621730", longitude: loc.longitude.toString(), // "24.797682",
longitude: loc.longitude.toString(),
//"24.797682",
searchKey: ""); searchKey: "");
await model.nextOrder(nextOrderRequestModel); await model.nextOrder(nextOrderRequestModel);
if (model.state == ViewState.ErrorLocal) { if (model.state == ViewState.ErrorLocal) {
@ -219,6 +222,12 @@ class DeliveryConfirmedPage extends StatelessWidget {
} else { } else {
if (model.nextOrdersList != null && model.nextOrdersList.length == 0) { if (model.nextOrdersList != null && model.nextOrdersList.length == 0) {
Utils.showErrorToast("No Items in the list"); Utils.showErrorToast("No Items in the list");
Navigator.pushReplacement(
context,
MaterialPageRoute(
builder: (context) => RootPage(),
),
);
} else { } else {
Navigator.pushReplacement( Navigator.pushReplacement(
context, context,

@ -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/app-icons/driver_app_icons.dart';
import 'package:driverapp/config/config.dart'; import 'package:driverapp/config/config.dart';
import 'package:driverapp/core/enum/viewstate.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/pending_orders_res_model.dart';
import 'package:driverapp/core/model/orders/update_order_status_request_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/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/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/translations_delegate_base.dart';
import 'package:driverapp/uitl/utils.dart'; import 'package:driverapp/uitl/utils.dart';
import 'package:driverapp/widgets/bottom_sheet/action_sheet_button.dart'; import 'package:driverapp/widgets/bottom_sheet/action_sheet_button.dart';
@ -17,138 +29,47 @@ import 'package:driverapp/widgets/delivery/package_content.dart';
import 'package:driverapp/widgets/others/app_scaffold_widget.dart'; import 'package:driverapp/widgets/others/app_scaffold_widget.dart';
import 'package:flutter/cupertino.dart'; import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_material_pickers/flutter_material_pickers.dart';
import 'package:hexcolor/hexcolor.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 'package:url_launcher/url_launcher.dart';
import 'delivery_cancel_page.dart';
import 'delivery_confirmed_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}); InformationPage({this.item});
@override @override
Widget build(BuildContext context) { State<StatefulWidget> createState() => _InformationPageState();
showDeliveryOptions(OrdersViewModel model) {
showModalBottomSheet( }
backgroundColor: Colors.white,
shape: RoundedRectangleBorder( // ignore: must_be_immutable
borderRadius: BorderRadius.only( class _InformationPageState extends State<InformationPage> {
topLeft: Radius.circular(50.0), var _deliveryService = locator<DeliveryTrackingServices>();
topRight: Radius.circular(50.0), PendingOrdersRes _item;
), bool _isDeliveryStarted;
), OrdersViewModel _viewModel;
context: context,
builder: (BuildContext bc) { @override
return ListView( void initState() {
children: <Widget>[ super.initState();
Container( _item = widget.item;
decoration: BoxDecoration( _isDeliveryStarted = _deliveryService.getActiveDeliveringOrders().contains(_item.ePharmacyOrderNo.toString());
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, 3, 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, 5, model);
},
),
SizedBox(height: 15),
ActionSheetButton(
label: TranslationBase.of(context).canceled,
icon: DriverApp.not_reachable_icon,
onTap: () {
selectAction(context, 6, model);
},
),
SizedBox(height: 15),
],
),
],
),
),
)
],
),
),
],
);
});
} }
@override
Widget build(BuildContext context) {
return BaseView<OrdersViewModel>( return BaseView<OrdersViewModel>(
onModelReady: (model) => _viewModel = model,
builder: (_, model, w) => AppScaffold( builder: (_, model, w) => AppScaffold(
isShowAppBar: true, isShowAppBar: true,
isShowHomeIcon: true,
appBarColor: Color(0xff49C1BC), appBarColor: Color(0xff49C1BC),
arrowColor: Colors.white, arrowColor: Colors.white,
titleColor: Colors.white, titleColor: Colors.white,
@ -187,14 +108,9 @@ class InformationPage extends StatelessWidget {
child: Column( child: Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly, mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[ children: <Widget>[
SizedBox( Visibility(
height: MediaQuery.of(context).orientation == visible: _isDeliveryStarted,
Orientation.portrait child: Padding(
? 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 == padding: MediaQuery.of(context).orientation ==
Orientation.portrait Orientation.portrait
? EdgeInsets.only(top: 60.0) ? EdgeInsets.only(top: 60.0)
@ -214,39 +130,11 @@ class InformationPage extends StatelessWidget {
btnName: btnName:
TranslationBase.of(context).location, TranslationBase.of(context).location,
btnFunction: () { btnFunction: () {
MapsLauncher.launchCoordinates( _openMapDirection(_item);
item.latitude, item.longitude); // 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( DeliveryInfoButton(
btnColor: Colors.white, btnColor: Colors.white,
//Theme.of(context).primaryColor, //Theme.of(context).primaryColor,
@ -261,13 +149,11 @@ class InformationPage extends StatelessWidget {
), ),
btnName: TranslationBase.of(context).call, btnName: TranslationBase.of(context).call,
btnFunction: () => btnFunction: () =>
launch("tel://" + item.mobileNumber), launch("tel://" + _item.mobileNumber),
), ),
], ],
), ),
), ),
SizedBox(
height: MediaQuery.of(context).size.width * 0.08,
), ),
Container( Container(
margin: EdgeInsets.only( margin: EdgeInsets.only(
@ -295,15 +181,15 @@ class InformationPage extends StatelessWidget {
padding: const EdgeInsets.only(left: 10), padding: const EdgeInsets.only(left: 10),
child: Column( child: Column(
children: List.generate( children: List.generate(
item.itemsQuantitiesList != null _item.itemsQuantitiesList != null
? item.itemsQuantitiesList.length ? _item.itemsQuantitiesList.length
: 0, (index) { : 0, (index) {
return packageContent( return packageContent(
packageName: item packageName: _item
.itemsQuantitiesList[index] .itemsQuantitiesList[index]
.itemName .itemName
.toString(), .toString(),
packageCount: item packageCount: _item
.itemsQuantitiesList[index] .itemsQuantitiesList[index]
.quantity .quantity
.toString(), .toString(),
@ -323,10 +209,11 @@ class InformationPage extends StatelessWidget {
? EdgeInsets.all(8.0) ? EdgeInsets.all(8.0)
: EdgeInsets.symmetric(horizontal: 12.0), : EdgeInsets.symmetric(horizontal: 12.0),
child: SecondaryButton( child: SecondaryButton(
label: label: _isDeliveryStarted
TranslationBase.of(context).clientReached, ? TranslationBase.of(context).deliveryOption
: TranslationBase.of(context).startDelivery,
onTap: () { onTap: () {
showDeliveryOptions(model); takeAction();
}, },
), ),
), ),
@ -335,15 +222,16 @@ class InformationPage extends StatelessWidget {
), ),
), ),
CustomerBriefCard( CustomerBriefCard(
itemId: item.orderID, customerOrderId: _item.orderID,
customerFirstName: item.firstName, pharmacyOrderId: _item.ePharmacyOrderNo,
customerLastName: item.lastName, customerFirstName: _item.firstName,
mobileNo: item.mobileNumber, customerLastName: _item.lastName,
totalPayment: item.amount, mobileNo: _item.mobileNumber,
deliveryTime: item.orderCreatedOn, totalPayment: _item.amount,
longitude: item.longitude, deliveryTime: _item.orderCreatedOn,
latitude: item.latitude, longitude: _item.longitude,
distanceInKilometers: item.distanceInKilometers, latitude: _item.latitude,
distanceInKilometers: _item.distanceInKilometers,
), ),
], ],
), ),
@ -355,57 +243,236 @@ class InformationPage extends StatelessWidget {
); );
} }
selectAction(BuildContext context, orderStatus, OrdersViewModel model) { void takeAction(){
String orderStatusText; if(_isDeliveryStarted) {
this._orderStatus = orderStatus; showDeliveryOptions(_viewModel);
switch (orderStatus) { }else{
case 3: if(_deliveryService.getActiveDeliveringOrders().isEmpty){
orderStatusText = TranslationBase.of(context).delivered; SweetAlert.show(context,subtitle: "Initializing delivery...", style: SweetAlertStyle.loading);
break; _viewModel.initDelivery(_item, completion: (response) {
case 4: if (response.isSuccessful) {
orderStatusText = TranslationBase.of(context).deliveredAccepted; setState(() => _isDeliveryStarted = true);
break; Navigator.pop(context);
case 5: AppToast.showSuccessToast(message: "Start navigation by clicking icon [${response.data}]");
orderStatusText = TranslationBase.of(context).deliveredRejected;
break; }else{
case 6: SweetAlert.show(context,subtitle: response.message, style: SweetAlertStyle.error);
orderStatusText = TranslationBase.of(context).canceled;
break;
} }
showDialog( });
}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, context: context,
builder: (BuildContext context) { title: TranslationBase.of(context).selectReason,
return CustomDialog( items: speedOptions,
orderStatusText: orderStatusText, selectedItem: speedOptions.first,
callService: () { icons: speedIcons,
updateOrderStatus(context, model); 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);
}
}, },
model: model,
); );
});
} }
updateOrderStatus(BuildContext context, OrdersViewModel model) async { showDeliveryOptions(OrdersViewModel model) {
UpdateOrderStatusRequestModel updateOrderStatusRequestModel = showModalBottomSheet(
UpdateOrderStatusRequestModel( backgroundColor: Colors.white,
deliveryOrderID: item.orderID, shape: RoundedRectangleBorder(
deliveryOrderStatus: _orderStatus, borderRadius: BorderRadius.only(
rejectionReason: "NO Reason", topLeft: Radius.circular(50.0),
cancleReason: ""); topRight: Radius.circular(50.0),
await model.updateOrderStatus(updateOrderStatusRequestModel); ),
if (model.state == ViewState.ErrorLocal) { ),
Utils.showErrorToast(model.error); isScrollControlled: true,
Navigator.of(context).pop(); context: context,
model.hideBottomSheet(); builder: (BuildContext bc) {
} else { return FractionallySizedBox(
Navigator.of(context).pop(); heightFactor: 0.40,
model.hideBottomSheet(); 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( Navigator.pushReplacement(
context, context,
MaterialPageRoute( MaterialPageRoute(builder: (context) => DeliveryVerificationPage(order: _item)),
builder: (context) => DeliveryConfirmedPage(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),
],
),
],
),
),
)
],
),
),
],
), ),
); );
});
}
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){
});
}
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
// }
// });
/* 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);
}
});
} }
} }

@ -23,6 +23,7 @@ class _DeliverdOrdersPageState extends State<DeliverdOrdersPage> {
isShowAppBar: true, isShowAppBar: true,
appBarTitle: 'Delivered List', appBarTitle: 'Delivered List',
baseViewModel: model, baseViewModel: model,
isShowBackIcon: true,
titleColor: Colors.black, titleColor: Colors.black,
body: Column( body: Column(
children: <Widget>[ children: <Widget>[
@ -47,6 +48,8 @@ class _DeliverdOrdersPageState extends State<DeliverdOrdersPage> {
padding: EdgeInsets.symmetric(horizontal: 12.2), padding: EdgeInsets.symmetric(horizontal: 12.2),
child: OrderInfoCard( child: OrderInfoCard(
order: model.deliverdOrders[index], order: model.deliverdOrders[index],
showStatus: true,
onTap: () {},
)); ));
}, },
), ),

@ -18,11 +18,12 @@ class _OrdersListScreenState extends State<OrdersListScreen> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return BaseView<OrdersViewModel>( return BaseView<OrdersViewModel>(
onModelReady: (model) => model.getPendingOrders(), onModelReady: (model) => model.getPendingOrders(2),
builder: (BuildContext context, OrdersViewModel model, Widget child) => builder: (BuildContext context, OrdersViewModel model, Widget child) =>
AppScaffold( AppScaffold(
baseViewModel: model, baseViewModel: model,
isShowAppBar: true, isShowAppBar: true,
isShowBackIcon: true,
appBarTitle: TranslationBase.of(context).yourDeliveryQue, appBarTitle: TranslationBase.of(context).yourDeliveryQue,
titleColor: Colors.black, titleColor: Colors.black,
body: Column( body: Column(

@ -24,6 +24,7 @@ class SettingPage extends StatelessWidget {
arrowColor: Colors.white, arrowColor: Colors.white,
titleColor: Colors.white, titleColor: Colors.white,
isAppBarGradient: true, isAppBarGradient: true,
isShowHomeIcon: true,
body: SingleChildScrollView( body: SingleChildScrollView(
child: Container( child: Container(
height: MediaQuery.of(context).size.height, height: MediaQuery.of(context).size.height,

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

@ -46,7 +46,8 @@ class CupertinoPickerUtils {
mainAxisAlignment: MainAxisAlignment.end, mainAxisAlignment: MainAxisAlignment.end,
children: <Widget>[ children: <Widget>[
CupertinoButton( CupertinoButton(
child: Text(TranslationBase.of(context).cancel, child: Text(
TranslationBase.of(context).cancel.toUpperCase(),
style: style:
TextStyle(color: Theme.of(context).primaryColor)), TextStyle(color: Theme.of(context).primaryColor)),
onPressed: () { onPressed: () {

@ -42,10 +42,13 @@ class TranslationBase {
String get enterId => localizedValues['enterId'][locale.languageCode]; String get enterId => localizedValues['enterId'][locale.languageCode];
String get pleaseEnterYourID => String get pleaseEnterYourID =>
localizedValues['pleaseEnterYourID'][locale.languageCode]; localizedValues['pleaseEnterYourID'][locale.languageCode];
String get enterPassword => String get enterPassword =>
localizedValues['enterPassword'][locale.languageCode]; localizedValues['enterPassword'][locale.languageCode];
String get pleaseEnterPassword => String get pleaseEnterPassword =>
localizedValues['pleaseEnterPassword'][locale.languageCode]; localizedValues['pleaseEnterPassword'][locale.languageCode];
String get english => localizedValues['english'][locale.languageCode]; String get english => localizedValues['english'][locale.languageCode];
String get arabic => localizedValues['arabic'][locale.languageCode]; String get arabic => localizedValues['arabic'][locale.languageCode];
@ -53,10 +56,22 @@ class TranslationBase {
String get enterCredentialsMsg => String get enterCredentialsMsg =>
localizedValues['enterCredentialsMsg'][locale.languageCode]; localizedValues['enterCredentialsMsg'][locale.languageCode];
String get enterForgetIdMsg =>
localizedValues['enterForgetIdMsg'][locale.languageCode];
String get enterVerificationMsg =>
localizedValues['enterVerificationMsg'][locale.languageCode];
String get enterCustomerVerificationCodeMsg =>
localizedValues['enterCustomerVerificationCodeMsg'][locale.languageCode];
String get forgotPassword => String get forgotPassword =>
localizedValues['forgotPassword'][locale.languageCode]; localizedValues['forgotPassword'][locale.languageCode];
String get login => localizedValues['login'][locale.languageCode]; String get login => localizedValues['login'][locale.languageCode];
String get getOPT => localizedValues['getOPT'][locale.languageCode];
String get haveGreatDay => String get haveGreatDay =>
localizedValues['haveGreatDay'][locale.languageCode]; localizedValues['haveGreatDay'][locale.languageCode];
@ -96,6 +111,13 @@ class TranslationBase {
String get clientReached => String get clientReached =>
localizedValues['clientReached'][locale.languageCode]; 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 addNoteBtn => localizedValues['addNoteBtn'][locale.languageCode];
String get nextDelivery => String get nextDelivery =>
@ -121,6 +143,24 @@ class TranslationBase {
String get selectAction => String get selectAction =>
localizedValues['selectAction'][locale.languageCode]; 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 => String get youHaveSelected =>
localizedValues['youHaveSelected'][locale.languageCode]; 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/cupertino.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
import 'package:latlong/latlong.dart';
import 'package:location/location.dart'; import 'package:location/location.dart';
import 'app_shared_preferences.dart'; import 'app_shared_preferences.dart';
@ -12,6 +13,22 @@ import 'app_toast.dart';
AppSharedPreferences sharedPref = new AppSharedPreferences(); 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 { class Utils {
///show custom Error Toast ///show custom Error Toast
/// [message] to show for user /// [message] to show for user
@ -49,7 +66,24 @@ class Utils {
FocusScope.of(context).unfocus(); FocusScope.of(context).unfocus();
} }
static getLocation() async { 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 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(); Location location = new Location();
LocationData currentLocation; LocationData currentLocation;
bool _serviceEnabled; bool _serviceEnabled;
@ -104,8 +138,8 @@ class Utils {
// open setting page // open setting page
} else { } else {
currentLocation = await location.getLocation(); currentLocation = await location.getLocation();
return currentLocation;
} }
return currentLocation;
} }
static formatStringToPascalCase(String name) { static formatStringToPascalCase(String name) {
@ -120,3 +154,4 @@ class Utils {
return formattedNamesList.join(' '); return formattedNamesList.join(' ');
} }
} }

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

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

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

@ -147,8 +147,7 @@ class _SecondaryButtonState extends State<SecondaryButton>
child: Container( child: Container(
decoration: BoxDecoration( decoration: BoxDecoration(
border: widget.borderColor != null border: widget.borderColor != null
? Border.all( ? Border.all(color: widget.borderColor, width: 2.0)
color: widget.borderColor.withOpacity(0.1), width: 2.0)
: null, : null,
borderRadius: BorderRadius.all(Radius.circular(100.0)), borderRadius: BorderRadius.all(Radius.circular(100.0)),
boxShadow: [ boxShadow: [
@ -195,7 +194,7 @@ class _SecondaryButtonState extends State<SecondaryButton>
widget.color != null ? null : LINEAR_GRADIENT, widget.color != null ? null : LINEAR_GRADIENT,
color: widget.color != null color: widget.color != null
? widget.color ? widget.color
: Hexcolor("#000000"), : HexColor("#000000"),
), ),
), ),
), ),

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

@ -2,13 +2,10 @@ import 'package:driverapp/config/size_config.dart';
import 'package:driverapp/uitl/utils.dart'; import 'package:driverapp/uitl/utils.dart';
import 'package:driverapp/widgets/delivery/distance_in_kilometers.dart'; import 'package:driverapp/widgets/delivery/distance_in_kilometers.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:hexcolor/hexcolor.dart';
import '../../uitl/date_uitl.dart';
import '../../uitl/translations_delegate_base.dart';
class CustomerBriefCard extends StatelessWidget { class CustomerBriefCard extends StatelessWidget {
final int itemId; final int customerOrderId;
final int pharmacyOrderId;
final String time; final String time;
final String customerFirstName; final String customerFirstName;
final String customerLastName; final String customerLastName;
@ -22,7 +19,8 @@ class CustomerBriefCard extends StatelessWidget {
final dynamic distanceInKilometers; final dynamic distanceInKilometers;
CustomerBriefCard({ CustomerBriefCard({
this.itemId, this.customerOrderId,
this.pharmacyOrderId,
this.time, this.time,
this.customerFirstName, this.customerFirstName,
this.customerLastName, this.customerLastName,
@ -43,9 +41,9 @@ class CustomerBriefCard extends StatelessWidget {
padding: EdgeInsets.only(bottom: 0.0), padding: EdgeInsets.only(bottom: 0.0),
child: Container( child: Container(
width: MediaQuery.of(context).orientation == Orientation.landscape width: MediaQuery.of(context).orientation == Orientation.landscape
? SizeConfig.widthMultiplier * 125.0 ? MediaQuery.of(context).size.width * 0.9
: SizeConfig.widthMultiplier * 90.0, : MediaQuery.of(context).size.width * 0.9,
height: SizeConfig.heightMultiplier * 33.0, // TODO make it responsive height: SizeConfig.heightMultiplier * 30.0, // TODO make it responsive
decoration: BoxDecoration( decoration: BoxDecoration(
color: Colors.white, color: Colors.white,
borderRadius: BorderRadius.only( borderRadius: BorderRadius.only(
@ -63,7 +61,7 @@ class CustomerBriefCard extends StatelessWidget {
], ],
), ),
child: Container( child: Container(
padding: EdgeInsets.only(left: 30, top: 20, right: 30), padding: EdgeInsets.only(left: 20, top: 20, right: 20),
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.start,
@ -72,13 +70,28 @@ class CustomerBriefCard extends StatelessWidget {
children: <Widget>[ children: <Widget>[
Expanded( Expanded(
flex: 3, flex: 3,
child: Text( child: Column(
'ID: ${itemId}', crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'Customer Order Id: ${customerOrderId}',
style: TextStyle(
color: Color(0xff636363),
fontWeight: FontWeight.w500,
fontSize: 17.5),
),
SizedBox(
height: 10,
),
Text(
'Pharmacy Order Id: ${pharmacyOrderId}',
style: TextStyle( style: TextStyle(
color: Color(0xff636363), color: Color(0xff636363),
fontWeight: FontWeight.w500, fontWeight: FontWeight.w500,
fontSize: 17.5), fontSize: 17.5),
), ),
],
),
), ),
Expanded( Expanded(
child: Padding( child: Padding(
@ -126,64 +139,6 @@ class CustomerBriefCard extends StatelessWidget {
SizedBox( SizedBox(
height: 10, height: 10,
), ),
SizedBox(
height: 10.0,
child: Center(
child: Container(
margin: EdgeInsetsDirectional.only(start: 1.0, end: 1.0),
height: 1.0,
color: Colors.grey,
),
),
),
SizedBox(
height: 20,
),
Column(
children: <Widget>[
Row(
children: <Widget>[
Expanded(
flex: 2,
child: Text(
TranslationBase.of(context).payment,
textAlign: TextAlign.start,
),
),
SizedBox(
width: 170,
),
Expanded(
child: Text(
totalPayment.toString(),
textAlign: TextAlign.end,
style: TextStyle(fontWeight: FontWeight.w400),
),
),
],
),
SizedBox(
height: MediaQuery.of(context).size.width * 0.03,
),
Row(
children: <Widget>[
Expanded(
flex: 1,
child: Text(
TranslationBase.of(context).delivryTime,
textAlign: TextAlign.start,
),
),
Expanded(
child: Text(
'${DateUtil.getMonthDayYearDateFormatted(DateUtil.convertStringToDate(deliveryTime))} ${(DateUtil.convertStringToHours(deliveryTime))}',
textAlign: TextAlign.end,
style: TextStyle(fontWeight: FontWeight.w400)),
),
],
)
],
),
], ],
), ),
), ),

@ -5,60 +5,95 @@ import 'package:flutter/material.dart';
import 'package:hexcolor/hexcolor.dart'; import 'package:hexcolor/hexcolor.dart';
class OrderInfoCard extends StatelessWidget { class OrderInfoCard extends StatelessWidget {
const OrderInfoCard({Key key, this.order, this.onTap}) : super(key: key); const OrderInfoCard(
{Key key, this.order, this.onTap, this.showStatus = false, this.isActiveToDeliver = false})
: super(key: key);
final dynamic order; final dynamic order;
final Function onTap; final Function onTap;
final bool showStatus;
final bool isActiveToDeliver;
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return InkWell( return InkWell(
child: Container( child:
Container(
child: RoundedContainer( child: RoundedContainer(
showShadow: true, showShadow: true,
raduis: 25.0, raduis: 25.0,
height: MediaQuery.of(context).orientation == Orientation.portrait height: MediaQuery.of(context).orientation == Orientation.portrait
? MediaQuery.of(context).size.height * 0.120 ? MediaQuery.of(context).size.height * (showStatus ? 0.22 : 0.160)
: MediaQuery.of(context).size.height * 0.209, : MediaQuery.of(context).size.height *
child: Row( (showStatus ? 0.359 : 0.269),
child: FractionallySizedBox(
widthFactor: 0.98,
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, mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[ children: <Widget>[
Expanded( Column(
flex: 1,
child: Column(
mainAxisAlignment: MainAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[ children: <Widget>[
Column(
children: [
Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Padding( Padding(
padding: EdgeInsets.only(left: 15.0, top: 14.0), padding:
EdgeInsets.only(left: 15.0, top: 14.0),
child: Image.asset( child: Image.asset(
'assets/images/location.png', 'assets/images/location.png',
height: MediaQuery.of(context).orientation == height: MediaQuery.of(context)
.orientation ==
Orientation.portrait Orientation.portrait
? MediaQuery.of(context).size.height * 0.06 ? MediaQuery.of(context).size.height *
: MediaQuery.of(context).size.height * 0.11, 0.06
: MediaQuery.of(context).size.height *
0.11,
width: MediaQuery.of(context).orientation == width: MediaQuery.of(context).orientation ==
Orientation.portrait Orientation.portrait
? MediaQuery.of(context).size.width * 0.05 ? MediaQuery.of(context).size.width *
: MediaQuery.of(context).size.width * 0.09, 0.05
: MediaQuery.of(context).size.width *
0.09,
), ),
)
],
), ),
SizedBox(
width: 13,
), ),
Expanded( Column(
flex: 5,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[ children: <Widget>[
Padding( Padding(
padding: EdgeInsets.only(top: 20.0), padding: EdgeInsets.only(top: 20.0),
child: Text( child: Text(
Utils.formatStringToPascalCase( Utils.formatStringToPascalCase(
order.firstName + ' ' + order.lastName), order.firstName +
' ' +
order.lastName),
style: TextStyle( style: TextStyle(
fontSize: 18.0, fontSize: 18.0,
color: Hexcolor("#343333"), color: HexColor("#343333"),
fontWeight: FontWeight.bold), fontWeight: FontWeight.bold),
), ),
), ),
@ -70,17 +105,20 @@ class OrderInfoCard extends StatelessWidget {
fontSize: 15.0, fontSize: 15.0,
), ),
), ),
Expanded( Text(
child: Text(
order.orderID.toString(), order.orderID.toString(),
style: TextStyle( style: TextStyle(
fontSize: 15.0, fontSize: 15.0,
fontWeight: FontWeight.w400, fontWeight: FontWeight.w400,
letterSpacing: 8.0), letterSpacing: 8.0),
), ),
],
), ),
], ],
), ),
],
)
],
), ),
Padding( Padding(
padding: EdgeInsets.all(8.0), padding: EdgeInsets.all(8.0),
@ -90,6 +128,36 @@ class OrderInfoCard extends StatelessWidget {
), ),
], ],
), ),
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,
),
),
),
),
),
],
)
],
),
]),
),
), ),
), ),
onTap: () { onTap: () {

@ -1,8 +1,10 @@
import 'package:driverapp/config/config.dart'; import 'package:driverapp/config/config.dart';
import 'package:driverapp/core/viewModels/base_view_model.dart'; import 'package:driverapp/core/viewModels/base_view_model.dart';
import 'package:driverapp/pages/dashboard/dashboard_screen.dart';
import 'package:driverapp/uitl/utils.dart'; import 'package:driverapp/uitl/utils.dart';
import 'package:driverapp/widgets/progress_indicator/app_loader_widget.dart'; import 'package:driverapp/widgets/progress_indicator/app_loader_widget.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
import 'package:gradient_app_bar/gradient_app_bar.dart'; import 'package:gradient_app_bar/gradient_app_bar.dart';
import 'arrow_back.dart'; import 'arrow_back.dart';
@ -19,6 +21,8 @@ class AppScaffold extends StatelessWidget {
final Color arrowColor; final Color arrowColor;
final Color appBarColor; final Color appBarColor;
final bool isAppBarGradient; final bool isAppBarGradient;
final bool isShowHomeIcon;
final bool isShowBackIcon;
AppScaffold( AppScaffold(
{@required this.body, {@required this.body,
@ -30,7 +34,9 @@ class AppScaffold extends StatelessWidget {
this.titleColor, this.titleColor,
this.arrowColor, this.arrowColor,
this.appBarColor, this.appBarColor,
this.isAppBarGradient = false}); this.isAppBarGradient = false,
this.isShowHomeIcon = false,
this.isShowBackIcon = false});
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
@ -40,34 +46,43 @@ class AppScaffold extends StatelessWidget {
bottom: false, bottom: false,
child: Scaffold( child: Scaffold(
backgroundColor: backgroundColor:
appBarColor ?? Theme.of(context).scaffoldBackgroundColor, Theme
.of(context)
.scaffoldBackgroundColor,
appBar: isShowAppBar && !isAppBarGradient appBar: isShowAppBar && !isAppBarGradient
? AppBar( ? AppBar(
elevation: 0, elevation: 0,
backgroundColor: Theme.of(context).appBarTheme.color, backgroundColor: Theme
.of(context)
.appBarTheme
.color,
textTheme: TextTheme( textTheme: TextTheme(
headline6: TextStyle( headline6: TextStyle(
color: titleColor ?? Colors.white, color: titleColor ?? Colors.white,
fontWeight: FontWeight.bold), fontWeight: FontWeight.bold),
), ),
title: Text(Utils.formatStringToPascalCase(appBarTitle)), title: Text(Utils.formatStringToPascalCase(appBarTitle)),
leading: Builder( automaticallyImplyLeading: false,
leading: isShowBackIcon ? Builder(
builder: (BuildContext context) { builder: (BuildContext context) {
return ArrowBack( return ArrowBack(
arrowColor: arrowColor, arrowColor: arrowColor,
); );
}, },
), ) : null,
centerTitle: true, centerTitle: true,
// actions: <Widget>[ actions: <Widget>[
// IconButton( if (isShowHomeIcon)
// icon: Icon(FontAwesomeIcons.home), IconButton(
// color: Colors.white, icon: Icon(FontAwesomeIcons.home),
// onPressed: () { color: Colors.white,
// // TODO add navigator to home page onPressed: () {
// },
// ),
// ], },
),
],
) )
: isShowAppBar && isAppBarGradient : isShowAppBar && isAppBarGradient
? GradientAppBar( ? GradientAppBar(
@ -76,14 +91,32 @@ class AppScaffold extends StatelessWidget {
Utils.formatStringToPascalCase(appBarTitle), Utils.formatStringToPascalCase(appBarTitle),
style: TextStyle(color: Colors.white), style: TextStyle(color: Colors.white),
), ),
automaticallyImplyLeading: false,
centerTitle: true, centerTitle: true,
leading: Builder( leading: isShowBackIcon ? Builder(
builder: (BuildContext context) { builder: (BuildContext context) {
return ArrowBack( return ArrowBack(
arrowColor: arrowColor, arrowColor: arrowColor,
); );
}, },
)) ) : null,
actions: <Widget>[
if (isShowHomeIcon)
IconButton(
icon: Icon(FontAwesomeIcons.home),
color: Colors.white,
onPressed: () {
Navigator.pushReplacement(
context,
MaterialPageRoute(
builder: (context) =>
DashboardScreen()
),
);
},
),
],
)
: null, : null,
body: baseViewModel != null body: baseViewModel != null
? NetworkBaseView( ? NetworkBaseView(

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

@ -56,7 +56,7 @@ dependencies:
# UI Reqs # UI Reqs
dotted_border: 1.0.5 dotted_border: 1.0.5
expandable: ^4.1.4 expandable: ^4.1.4
hexcolor: ^1.0.1 hexcolor: ^1.0.6
# Notification Banner # Notification Banner
dropdown_banner: ^1.4.0 dropdown_banner: ^1.4.0
@ -72,6 +72,10 @@ dependencies:
# location # location
location: ^3.0.2 location: ^3.0.2
# latlong tools
latlong: any
#gradient #gradient
gradient_app_bar: ^0.1.3 gradient_app_bar: ^0.1.3
@ -79,11 +83,14 @@ dependencies:
#Barcode Scanner #Barcode Scanner
flutter_barcode_scanner: ^1.0.1 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-Regular.otf
- asset: assets/fonts/Metropolis/Metropolis-Bold.otf - asset: assets/fonts/Metropolis/Metropolis-Bold.otf
- asset: assets/fonts/Metropolis/Metropolis-Light.otf - asset: assets/fonts/Metropolis/Metropolis-Light.otf
- family: HMGIcon1
fonts:
- asset: assets/fonts/icomoon.ttf

Loading…
Cancel
Save