diff --git a/.gitignore b/.gitignore index fd4aca5a..cff0e374 100644 --- a/.gitignore +++ b/.gitignore @@ -25,6 +25,7 @@ .dart_tool/ .flutter-plugins pubspec.lock +/ios/Podfile.lock .flutter-plugins-dependencies .packages .pub-cache/ diff --git a/GoogleService-Info_DQ.plist b/GoogleService-Info_DQ.plist new file mode 100644 index 00000000..0c093a2a --- /dev/null +++ b/GoogleService-Info_DQ.plist @@ -0,0 +1,36 @@ + + + + + CLIENT_ID + 864393916058-ekeb4s8tgfo58dutv0l54399t7ivr06r.apps.googleusercontent.com + REVERSED_CLIENT_ID + com.googleusercontent.apps.864393916058-ekeb4s8tgfo58dutv0l54399t7ivr06r + API_KEY + AIzaSyA_6ayGCk4fly7o7eTVBrj9kuHBYHMAOfs + GCM_SENDER_ID + 864393916058 + PLIST_VERSION + 1 + BUNDLE_ID + com.cloud.diplomaticquarterapp + PROJECT_ID + diplomaticquarter-d2385 + STORAGE_BUCKET + diplomaticquarter-d2385.appspot.com + IS_ADS_ENABLED + + IS_ANALYTICS_ENABLED + + IS_APPINVITE_ENABLED + + IS_GCM_ENABLED + + IS_SIGNIN_ENABLED + + GOOGLE_APP_ID + 1:864393916058:ios:13f787bbfe6051f8b97923 + DATABASE_URL + https://diplomaticquarter-d2385.firebaseio.com + + \ No newline at end of file diff --git a/GoogleService-Info_HMG.plist b/GoogleService-Info_HMG.plist new file mode 100644 index 00000000..153aa2c6 --- /dev/null +++ b/GoogleService-Info_HMG.plist @@ -0,0 +1,38 @@ + + + + + CLIENT_ID + 815750722565-da8p56le8bd6apsbm9eft0jjl1rtpgkt.apps.googleusercontent.com + REVERSED_CLIENT_ID + com.googleusercontent.apps.815750722565-da8p56le8bd6apsbm9eft0jjl1rtpgkt + ANDROID_CLIENT_ID + 815750722565-m14h8mkosm7cnq6uh6rhqr54dn02d705.apps.googleusercontent.com + API_KEY + AIzaSyDiXnCO00li4V7Ioa2YZ_M4ECxRsu_P9tA + GCM_SENDER_ID + 815750722565 + PLIST_VERSION + 1 + BUNDLE_ID + com.HMG.Smartphone + PROJECT_ID + api-project-815750722565 + STORAGE_BUCKET + api-project-815750722565.appspot.com + IS_ADS_ENABLED + + IS_ANALYTICS_ENABLED + + IS_APPINVITE_ENABLED + + IS_GCM_ENABLED + + IS_SIGNIN_ENABLED + + GOOGLE_APP_ID + 1:815750722565:ios:328ec247a81a2ca23c186c + DATABASE_URL + https://api-project-815750722565.firebaseio.com + + \ No newline at end of file diff --git a/assets/images/discount_ar.png b/assets/images/discount_ar.png new file mode 100644 index 00000000..854d1c1f Binary files /dev/null and b/assets/images/discount_ar.png differ diff --git a/assets/images/discount_en.png b/assets/images/discount_en.png new file mode 100644 index 00000000..2af52865 Binary files /dev/null and b/assets/images/discount_en.png differ diff --git a/assets/images/logo_HMG.png b/assets/images/logo_HMG.png new file mode 100644 index 00000000..0d9e4a56 Binary files /dev/null and b/assets/images/logo_HMG.png differ diff --git a/assets/images/svg/discount_ar.svg b/assets/images/svg/discount_ar.svg new file mode 100644 index 00000000..d9d6ec27 --- /dev/null +++ b/assets/images/svg/discount_ar.svg @@ -0,0 +1,37 @@ + + + + + + + + + + + + + + + مصخ + + + + diff --git a/assets/images/svg/discount_en.svg b/assets/images/svg/discount_en.svg new file mode 100644 index 00000000..294cf19c --- /dev/null +++ b/assets/images/svg/discount_en.svg @@ -0,0 +1,43 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/images/svg/robort_svg.svg b/assets/images/svg/robort_svg.svg index 07d3d4b4..8b4875a1 100644 --- a/assets/images/svg/robort_svg.svg +++ b/assets/images/svg/robort_svg.svg @@ -1,3 +1,4 @@ + diff --git a/assets/images/svg/success.svg b/assets/images/svg/success.svg new file mode 100644 index 00000000..343589bd --- /dev/null +++ b/assets/images/svg/success.svg @@ -0,0 +1,67 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/ios/Flutter/.last_build_id b/ios/Flutter/.last_build_id index b8024672..3b4ea73f 100644 --- a/ios/Flutter/.last_build_id +++ b/ios/Flutter/.last_build_id @@ -1 +1 @@ -59a6c452ee075b50114918f17f1ad8f5 \ No newline at end of file +45a7d43b55124e1b314759554f9a14d3 \ No newline at end of file diff --git a/ios/Podfile.lock b/ios/Podfile.lock index fdb971fd..b09a4a0c 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -1,9 +1,235 @@ PODS: + - abseil/algorithm (0.20200225.0): + - abseil/algorithm/algorithm (= 0.20200225.0) + - abseil/algorithm/container (= 0.20200225.0) + - abseil/algorithm/algorithm (0.20200225.0): + - abseil/base/config + - abseil/algorithm/container (0.20200225.0): + - abseil/algorithm/algorithm + - abseil/base/core_headers + - abseil/meta/type_traits + - abseil/base (0.20200225.0): + - abseil/base/atomic_hook (= 0.20200225.0) + - abseil/base/base (= 0.20200225.0) + - abseil/base/base_internal (= 0.20200225.0) + - abseil/base/bits (= 0.20200225.0) + - abseil/base/config (= 0.20200225.0) + - abseil/base/core_headers (= 0.20200225.0) + - abseil/base/dynamic_annotations (= 0.20200225.0) + - abseil/base/endian (= 0.20200225.0) + - abseil/base/errno_saver (= 0.20200225.0) + - abseil/base/exponential_biased (= 0.20200225.0) + - abseil/base/log_severity (= 0.20200225.0) + - abseil/base/malloc_internal (= 0.20200225.0) + - abseil/base/periodic_sampler (= 0.20200225.0) + - abseil/base/pretty_function (= 0.20200225.0) + - abseil/base/raw_logging_internal (= 0.20200225.0) + - abseil/base/spinlock_wait (= 0.20200225.0) + - abseil/base/throw_delegate (= 0.20200225.0) + - abseil/base/atomic_hook (0.20200225.0): + - abseil/base/config + - abseil/base/core_headers + - abseil/base/base (0.20200225.0): + - abseil/base/atomic_hook + - abseil/base/base_internal + - abseil/base/config + - abseil/base/core_headers + - abseil/base/dynamic_annotations + - abseil/base/log_severity + - abseil/base/raw_logging_internal + - abseil/base/spinlock_wait + - abseil/meta/type_traits + - abseil/base/base_internal (0.20200225.0): + - abseil/base/config + - abseil/meta/type_traits + - abseil/base/bits (0.20200225.0): + - abseil/base/config + - abseil/base/core_headers + - abseil/base/config (0.20200225.0) + - abseil/base/core_headers (0.20200225.0): + - abseil/base/config + - abseil/base/dynamic_annotations (0.20200225.0) + - abseil/base/endian (0.20200225.0): + - abseil/base/config + - abseil/base/core_headers + - abseil/base/errno_saver (0.20200225.0): + - abseil/base/config + - abseil/base/exponential_biased (0.20200225.0): + - abseil/base/config + - abseil/base/core_headers + - abseil/base/log_severity (0.20200225.0): + - abseil/base/config + - abseil/base/core_headers + - abseil/base/malloc_internal (0.20200225.0): + - abseil/base/base + - abseil/base/base_internal + - abseil/base/config + - abseil/base/core_headers + - abseil/base/dynamic_annotations + - abseil/base/raw_logging_internal + - abseil/base/periodic_sampler (0.20200225.0): + - abseil/base/core_headers + - abseil/base/exponential_biased + - abseil/base/pretty_function (0.20200225.0) + - abseil/base/raw_logging_internal (0.20200225.0): + - abseil/base/atomic_hook + - abseil/base/config + - abseil/base/core_headers + - abseil/base/log_severity + - abseil/base/spinlock_wait (0.20200225.0): + - abseil/base/base_internal + - abseil/base/core_headers + - abseil/base/errno_saver + - abseil/base/throw_delegate (0.20200225.0): + - abseil/base/config + - abseil/base/raw_logging_internal + - abseil/container/compressed_tuple (0.20200225.0): + - abseil/utility/utility + - abseil/container/inlined_vector (0.20200225.0): + - abseil/algorithm/algorithm + - abseil/base/core_headers + - abseil/base/throw_delegate + - abseil/container/inlined_vector_internal + - abseil/memory/memory + - abseil/container/inlined_vector_internal (0.20200225.0): + - abseil/base/core_headers + - abseil/container/compressed_tuple + - abseil/memory/memory + - abseil/meta/type_traits + - abseil/types/span + - abseil/memory (0.20200225.0): + - abseil/memory/memory (= 0.20200225.0) + - abseil/memory/memory (0.20200225.0): + - abseil/base/core_headers + - abseil/meta/type_traits + - abseil/meta (0.20200225.0): + - abseil/meta/type_traits (= 0.20200225.0) + - abseil/meta/type_traits (0.20200225.0): + - abseil/base/config + - abseil/numeric/int128 (0.20200225.0): + - abseil/base/config + - abseil/base/core_headers + - abseil/strings/internal (0.20200225.0): + - abseil/base/config + - abseil/base/core_headers + - abseil/base/endian + - abseil/base/raw_logging_internal + - abseil/meta/type_traits + - abseil/strings/str_format (0.20200225.0): + - abseil/strings/str_format_internal + - abseil/strings/str_format_internal (0.20200225.0): + - abseil/base/config + - abseil/base/core_headers + - abseil/meta/type_traits + - abseil/numeric/int128 + - abseil/strings/strings + - abseil/types/span + - abseil/strings/strings (0.20200225.0): + - abseil/base/base + - abseil/base/bits + - abseil/base/config + - abseil/base/core_headers + - abseil/base/endian + - abseil/base/raw_logging_internal + - abseil/base/throw_delegate + - abseil/memory/memory + - abseil/meta/type_traits + - abseil/numeric/int128 + - abseil/strings/internal + - abseil/time (0.20200225.0): + - abseil/time/internal (= 0.20200225.0) + - abseil/time/time (= 0.20200225.0) + - abseil/time/internal (0.20200225.0): + - abseil/time/internal/cctz (= 0.20200225.0) + - abseil/time/internal/cctz (0.20200225.0): + - abseil/time/internal/cctz/civil_time (= 0.20200225.0) + - abseil/time/internal/cctz/time_zone (= 0.20200225.0) + - abseil/time/internal/cctz/civil_time (0.20200225.0): + - abseil/base/config + - abseil/time/internal/cctz/time_zone (0.20200225.0): + - abseil/base/config + - abseil/time/internal/cctz/civil_time + - abseil/time/time (0.20200225.0): + - abseil/base/base + - abseil/base/core_headers + - abseil/base/raw_logging_internal + - abseil/numeric/int128 + - abseil/strings/strings + - abseil/time/internal/cctz/civil_time + - abseil/time/internal/cctz/time_zone + - abseil/types (0.20200225.0): + - abseil/types/any (= 0.20200225.0) + - abseil/types/bad_any_cast (= 0.20200225.0) + - abseil/types/bad_any_cast_impl (= 0.20200225.0) + - abseil/types/bad_optional_access (= 0.20200225.0) + - abseil/types/bad_variant_access (= 0.20200225.0) + - abseil/types/compare (= 0.20200225.0) + - abseil/types/optional (= 0.20200225.0) + - abseil/types/span (= 0.20200225.0) + - abseil/types/variant (= 0.20200225.0) + - abseil/types/any (0.20200225.0): + - abseil/base/config + - abseil/base/core_headers + - abseil/meta/type_traits + - abseil/types/bad_any_cast + - abseil/utility/utility + - abseil/types/bad_any_cast (0.20200225.0): + - abseil/base/config + - abseil/types/bad_any_cast_impl + - abseil/types/bad_any_cast_impl (0.20200225.0): + - abseil/base/config + - abseil/base/raw_logging_internal + - abseil/types/bad_optional_access (0.20200225.0): + - abseil/base/config + - abseil/base/raw_logging_internal + - abseil/types/bad_variant_access (0.20200225.0): + - abseil/base/config + - abseil/base/raw_logging_internal + - abseil/types/compare (0.20200225.0): + - abseil/base/core_headers + - abseil/meta/type_traits + - abseil/types/optional (0.20200225.0): + - abseil/base/base_internal + - abseil/base/config + - abseil/base/core_headers + - abseil/memory/memory + - abseil/meta/type_traits + - abseil/types/bad_optional_access + - abseil/utility/utility + - abseil/types/span (0.20200225.0): + - abseil/algorithm/algorithm + - abseil/base/core_headers + - abseil/base/throw_delegate + - abseil/meta/type_traits + - abseil/types/variant (0.20200225.0): + - abseil/base/base_internal + - abseil/base/config + - abseil/base/core_headers + - abseil/meta/type_traits + - abseil/types/bad_variant_access + - abseil/utility/utility + - abseil/utility/utility (0.20200225.0): + - abseil/base/base_internal + - abseil/base/config + - abseil/meta/type_traits - android_intent (0.0.1): - Flutter - barcode_scan_fix (0.0.1): - Flutter - MTBBarcodeScanner + - BoringSSL-GRPC (0.0.7): + - BoringSSL-GRPC/Implementation (= 0.0.7) + - BoringSSL-GRPC/Interface (= 0.0.7) + - BoringSSL-GRPC/Implementation (0.0.7): + - BoringSSL-GRPC/Interface (= 0.0.7) + - BoringSSL-GRPC/Interface (0.0.7) + - cloud_firestore (0.14.4): + - Firebase/CoreOnly (~> 6.33.0) + - Firebase/Firestore (~> 6.33.0) + - firebase_core + - Flutter + - cloud_firestore_web (0.1.0): + - Flutter - connectivity (0.0.1): - Flutter - Reachability @@ -15,8 +241,47 @@ PODS: - Flutter - device_info (0.0.1): - Flutter + - DKImagePickerController/Core (4.3.2): + - DKImagePickerController/ImageDataManager + - DKImagePickerController/Resource + - DKImagePickerController/ImageDataManager (4.3.2) + - DKImagePickerController/PhotoGallery (4.3.2): + - DKImagePickerController/Core + - DKPhotoGallery + - DKImagePickerController/Resource (4.3.2) + - DKPhotoGallery (0.0.17): + - DKPhotoGallery/Core (= 0.0.17) + - DKPhotoGallery/Model (= 0.0.17) + - DKPhotoGallery/Preview (= 0.0.17) + - DKPhotoGallery/Resource (= 0.0.17) + - SDWebImage + - SwiftyGif + - DKPhotoGallery/Core (0.0.17): + - DKPhotoGallery/Model + - DKPhotoGallery/Preview + - SDWebImage + - SwiftyGif + - DKPhotoGallery/Model (0.0.17): + - SDWebImage + - SwiftyGif + - DKPhotoGallery/Preview (0.0.17): + - DKPhotoGallery/Model + - DKPhotoGallery/Resource + - SDWebImage + - SwiftyGif + - DKPhotoGallery/Resource (0.0.17): + - SDWebImage + - SwiftyGif + - file_picker (0.0.1): + - DKImagePickerController/PhotoGallery + - Flutter + - file_picker_web (0.0.1): + - Flutter - Firebase/CoreOnly (6.33.0): - FirebaseCore (= 6.10.3) + - Firebase/Firestore (6.33.0): + - Firebase/CoreOnly + - FirebaseFirestore (~> 1.18.0) - Firebase/Messaging (6.33.0): - Firebase/CoreOnly - FirebaseMessaging (~> 4.7.0) @@ -39,6 +304,18 @@ PODS: - GoogleUtilities/Environment (~> 6.7) - GoogleUtilities/Logger (~> 6.7) - nanopb (~> 1.30906.0) + - FirebaseFirestore (1.18.0): + - abseil/algorithm (= 0.20200225.0) + - abseil/base (= 0.20200225.0) + - abseil/memory (= 0.20200225.0) + - abseil/meta (= 0.20200225.0) + - abseil/strings/strings (= 0.20200225.0) + - abseil/time (= 0.20200225.0) + - abseil/types (= 0.20200225.0) + - FirebaseCore (~> 6.10) + - "gRPC-C++ (~> 1.28.0)" + - leveldb-library (~> 1.22) + - nanopb (~> 1.30906.0) - FirebaseInstallations (1.7.0): - FirebaseCore (~> 6.10) - GoogleUtilities/Environment (~> 6.7) @@ -70,7 +347,10 @@ PODS: - Flutter - flutter_tts (0.0.1): - Flutter - - geolocator (6.1.9): + - FMDB (2.7.5): + - FMDB/standard (= 2.7.5) + - FMDB/standard (2.7.5) + - geolocator (6.2.0): - Flutter - google_maps_flutter (0.0.1): - Flutter @@ -99,6 +379,30 @@ PODS: - GoogleUtilities/Logger - GoogleUtilities/UserDefaults (6.7.2): - GoogleUtilities/Logger + - "gRPC-C++ (1.28.2)": + - "gRPC-C++/Implementation (= 1.28.2)" + - "gRPC-C++/Interface (= 1.28.2)" + - "gRPC-C++/Implementation (1.28.2)": + - abseil/container/inlined_vector (= 0.20200225.0) + - abseil/memory/memory (= 0.20200225.0) + - abseil/strings/str_format (= 0.20200225.0) + - abseil/strings/strings (= 0.20200225.0) + - abseil/types/optional (= 0.20200225.0) + - "gRPC-C++/Interface (= 1.28.2)" + - gRPC-Core (= 1.28.2) + - "gRPC-C++/Interface (1.28.2)" + - gRPC-Core (1.28.2): + - gRPC-Core/Implementation (= 1.28.2) + - gRPC-Core/Interface (= 1.28.2) + - gRPC-Core/Implementation (1.28.2): + - abseil/container/inlined_vector (= 0.20200225.0) + - abseil/memory/memory (= 0.20200225.0) + - abseil/strings/str_format (= 0.20200225.0) + - abseil/strings/strings (= 0.20200225.0) + - abseil/types/optional (= 0.20200225.0) + - BoringSSL-GRPC (= 0.0.7) + - gRPC-Core/Interface (= 1.28.2) + - gRPC-Core/Interface (1.28.2) - hexcolor (0.0.1): - Flutter - image_cropper (0.0.3): @@ -108,6 +412,7 @@ PODS: - Flutter - just_audio (0.0.1): - Flutter + - leveldb-library (1.22) - local_auth (0.0.1): - Flutter - location (0.0.1): @@ -126,8 +431,6 @@ PODS: - nanopb/encode (1.30906.0) - native_device_orientation (0.0.1): - Flutter - - native_progress_hud (0.0.1): - - Flutter - NVActivityIndicatorView (5.1.1): - NVActivityIndicatorView/Base (= 5.1.1) - NVActivityIndicatorView/Base (5.1.1) @@ -139,13 +442,16 @@ PODS: - Flutter - path_provider_windows (0.0.1): - Flutter - - "permission_handler (5.0.1+1)": + - "permission_handler (5.1.0+2)": - Flutter - - PromisesObjC (1.2.11) - - Protobuf (3.13.0) + - PromisesObjC (1.2.12) + - Protobuf (3.14.0) - Reachability (3.2) - screen (0.0.1): - Flutter + - SDWebImage (5.10.4): + - SDWebImage/Core (= 5.10.4) + - SDWebImage/Core (5.10.4) - shared_preferences (0.0.1): - Flutter - shared_preferences_linux (0.0.1): @@ -156,9 +462,15 @@ PODS: - Flutter - shared_preferences_windows (0.0.1): - Flutter + - sms_otp_auto_verify (0.0.1): + - Flutter - speech_to_text (0.0.1): - Flutter - Try + - sqflite (0.0.2): + - Flutter + - FMDB (>= 2.7.5) + - SwiftyGif (5.4.0) - TOCropViewController (2.5.5) - Try (2.1.1) - "twilio_programmable_video (0.5.0+4)": @@ -193,11 +505,15 @@ PODS: DEPENDENCIES: - android_intent (from `.symlinks/plugins/android_intent/ios`) - barcode_scan_fix (from `.symlinks/plugins/barcode_scan_fix/ios`) + - cloud_firestore (from `.symlinks/plugins/cloud_firestore/ios`) + - cloud_firestore_web (from `.symlinks/plugins/cloud_firestore_web/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_calendar (from `.symlinks/plugins/device_calendar/ios`) - device_info (from `.symlinks/plugins/device_info/ios`) + - file_picker (from `.symlinks/plugins/file_picker/ios`) + - file_picker_web (from `.symlinks/plugins/file_picker_web/ios`) - firebase_core (from `.symlinks/plugins/firebase_core/ios`) - firebase_core_web (from `.symlinks/plugins/firebase_core_web/ios`) - firebase_messaging (from `.symlinks/plugins/firebase_messaging/ios`) @@ -220,7 +536,6 @@ DEPENDENCIES: - map_launcher (from `.symlinks/plugins/map_launcher/ios`) - maps_launcher (from `.symlinks/plugins/maps_launcher/ios`) - native_device_orientation (from `.symlinks/plugins/native_device_orientation/ios`) - - native_progress_hud (from `.symlinks/plugins/native_progress_hud/ios`) - NVActivityIndicatorView - path_provider (from `.symlinks/plugins/path_provider/ios`) - path_provider_linux (from `.symlinks/plugins/path_provider_linux/ios`) @@ -233,7 +548,9 @@ DEPENDENCIES: - shared_preferences_macos (from `.symlinks/plugins/shared_preferences_macos/ios`) - shared_preferences_web (from `.symlinks/plugins/shared_preferences_web/ios`) - shared_preferences_windows (from `.symlinks/plugins/shared_preferences_windows/ios`) + - sms_otp_auto_verify (from `.symlinks/plugins/sms_otp_auto_verify/ios`) - speech_to_text (from `.symlinks/plugins/speech_to_text/ios`) + - sqflite (from `.symlinks/plugins/sqflite/ios`) - twilio_programmable_video (from `.symlinks/plugins/twilio_programmable_video/ios`) - url_launcher (from `.symlinks/plugins/url_launcher/ios`) - url_launcher_linux (from `.symlinks/plugins/url_launcher_linux/ios`) @@ -250,21 +567,32 @@ DEPENDENCIES: SPEC REPOS: trunk: + - abseil + - BoringSSL-GRPC + - DKImagePickerController + - DKPhotoGallery - Firebase - FirebaseCore - FirebaseCoreDiagnostics + - FirebaseFirestore - FirebaseInstallations - FirebaseInstanceID - FirebaseMessaging + - FMDB - GoogleDataTransport - GoogleMaps - GoogleUtilities + - "gRPC-C++" + - gRPC-Core + - leveldb-library - MTBBarcodeScanner - nanopb - NVActivityIndicatorView - PromisesObjC - Protobuf - Reachability + - SDWebImage + - SwiftyGif - TOCropViewController - Try - TwilioVideo @@ -274,6 +602,10 @@ EXTERNAL SOURCES: :path: ".symlinks/plugins/android_intent/ios" barcode_scan_fix: :path: ".symlinks/plugins/barcode_scan_fix/ios" + cloud_firestore: + :path: ".symlinks/plugins/cloud_firestore/ios" + cloud_firestore_web: + :path: ".symlinks/plugins/cloud_firestore_web/ios" connectivity: :path: ".symlinks/plugins/connectivity/ios" connectivity_for_web: @@ -284,6 +616,10 @@ EXTERNAL SOURCES: :path: ".symlinks/plugins/device_calendar/ios" device_info: :path: ".symlinks/plugins/device_info/ios" + file_picker: + :path: ".symlinks/plugins/file_picker/ios" + file_picker_web: + :path: ".symlinks/plugins/file_picker_web/ios" firebase_core: :path: ".symlinks/plugins/firebase_core/ios" firebase_core_web: @@ -328,8 +664,6 @@ EXTERNAL SOURCES: :path: ".symlinks/plugins/maps_launcher/ios" native_device_orientation: :path: ".symlinks/plugins/native_device_orientation/ios" - native_progress_hud: - :path: ".symlinks/plugins/native_progress_hud/ios" path_provider: :path: ".symlinks/plugins/path_provider/ios" path_provider_linux: @@ -352,8 +686,12 @@ EXTERNAL SOURCES: :path: ".symlinks/plugins/shared_preferences_web/ios" shared_preferences_windows: :path: ".symlinks/plugins/shared_preferences_windows/ios" + sms_otp_auto_verify: + :path: ".symlinks/plugins/sms_otp_auto_verify/ios" speech_to_text: :path: ".symlinks/plugins/speech_to_text/ios" + sqflite: + :path: ".symlinks/plugins/sqflite/ios" twilio_programmable_video: :path: ".symlinks/plugins/twilio_programmable_video/ios" url_launcher: @@ -382,19 +720,28 @@ EXTERNAL SOURCES: :path: ".symlinks/plugins/wifi/ios" SPEC CHECKSUMS: + abseil: 6c8eb7892aefa08d929b39f9bb108e5367e3228f android_intent: 367df2f1277a74e4a90e14a8ab3df3112d087052 barcode_scan_fix: 80dd65de55f27eec6591dd077c8b85f2b79e31f1 + BoringSSL-GRPC: 8edf627ee524575e2f8d19d56f068b448eea3879 + cloud_firestore: b8c0e15fa49dfff87c2817d288b577e5dca2df13 + cloud_firestore_web: 9ec3dc7f5f98de5129339802d491c1204462bfec connectivity: c4130b2985d4ef6fd26f9702e886bd5260681467 connectivity_for_web: 2b8584556930d4bd490d82b836bcf45067ce345b connectivity_macos: e2e9731b6b22dda39eb1b128f6969d574460e191 device_calendar: 23b28a5f1ab3bf77e34542fb1167e1b8b29a98f5 device_info: d7d233b645a32c40dfdc212de5cf646ca482f175 + DKImagePickerController: b5eb7f7a388e4643264105d648d01f727110fc3d + DKPhotoGallery: fdfad5125a9fdda9cc57df834d49df790dbb4179 + file_picker: 3e6c3790de664ccf9b882732d9db5eaf6b8d4eb1 + file_picker_web: 37b10786e88885124fac99dc899866e78a132ef3 Firebase: 8db6f2d1b2c5e2984efba4949a145875a8f65fe5 firebase_core: 5d6a02f3d85acd5f8321c2d6d62877626a670659 firebase_core_web: d501d8b946b60c8af265428ce483b0fff5ad52d1 firebase_messaging: 0aea2cd5885b65e19ede58ee3507f485c992cc75 FirebaseCore: d889d9e12535b7f36ac8bfbf1713a0836a3012cd FirebaseCoreDiagnostics: 770ac5958e1372ce67959ae4b4f31d8e127c3ac1 + FirebaseFirestore: adff4877869ca91a11250cc0989a6cd56bad163f FirebaseInstallations: 466c7b4d1f58fe16707693091da253726a731ed2 FirebaseInstanceID: bd3ffc24367f901a43c063b36c640b345a4a5dd1 FirebaseMessaging: 5eca4ef173de76253352511aafef774caa1cba2a @@ -405,15 +752,19 @@ SPEC CHECKSUMS: flutter_local_notifications: 9e4738ce2471c5af910d961a6b7eadcf57c50186 flutter_plugin_android_lifecycle: dc0b544e129eebb77a6bfb1239d4d1c673a60a35 flutter_tts: 0f492aab6accf87059b72354fcb4ba934304771d - geolocator: 057a0c63a43e9c5296d8ad845a3ac8e6df23d899 + FMDB: 2ce00b547f966261cd18927a3ddb07cb6f3db82a + geolocator: f5e3de65e241caba7ce3e8a618803387bda73384 google_maps_flutter: c7f9c73576de1fbe152a227bfd6e6c4ae8088619 GoogleDataTransport: f56af7caa4ed338dc8e138a5d7c5973e66440833 GoogleMaps: 4b5346bddfe6911bb89155d43c903020170523ac GoogleUtilities: 7f2f5a07f888cdb145101d6042bc4422f57e70b3 + "gRPC-C++": 13d8ccef97d5c3c441b7e3c529ef28ebee86fad2 + gRPC-Core: 4afa11bfbedf7cdecd04de535a9e046893404ed5 hexcolor: fdfb9c4258ad96e949c2dbcdf790a62194b8aa89 image_cropper: c8f9b4157933c7bb965a66d1c5e6c8fd408c6eb4 image_picker: 9c3312491f862b28d21ecd8fdf0ee14e601b3f09 just_audio: baa7252489dbcf47a4c7cc9ca663e9661c99aafa + leveldb-library: 55d93ee664b4007aac644a782d11da33fba316f7 local_auth: 25938960984c3a7f6e3253e3f8d962fdd16852bd location: 3a2eed4dd2fab25e7b7baf2a9efefe82b512d740 manage_calendar_events: 0338d505ea26cdfd20cd883279bc28afa11eca34 @@ -422,23 +773,26 @@ SPEC CHECKSUMS: MTBBarcodeScanner: f453b33c4b7dfe545d8c6484ed744d55671788cb nanopb: 59317e09cf1f1a0af72f12af412d54edf52603fc native_device_orientation: e24d00be281de72996640885d80e706142707660 - native_progress_hud: f95f5529742b36a3c7fdecfa88dc018319e39bf9 NVActivityIndicatorView: 1f6c5687f1171810aa27a3296814dc2d7dec3667 path_provider: abfe2b5c733d04e238b0d8691db0cfd63a27a93c path_provider_linux: 4d630dc393e1f20364f3e3b4a2ff41d9674a84e4 path_provider_macos: f760a3c5b04357c380e2fddb6f9db6f3015897e0 path_provider_windows: a2b81600c677ac1959367280991971cb9a1edb3b - permission_handler: eac8e15b4a1a3fba55b761d19f3f4e6b005d15b6 - PromisesObjC: 8c196f5a328c2cba3e74624585467a557dcb482f - Protobuf: 3dac39b34a08151c6d949560efe3f86134a3f748 + permission_handler: ccb20a9fad0ee9b1314a52b70b76b473c5f8dab0 + PromisesObjC: 3113f7f76903778cf4a0586bd1ab89329a0b7b97 + Protobuf: 0cde852566359049847168e51bd1c690e0f70056 Reachability: 33e18b67625424e47b6cde6d202dce689ad7af96 screen: abd91ca7bf3426e1cc3646d27e9b2358d6bf07b0 + SDWebImage: c666b97e1fa9c64b4909816a903322018f0a9c84 shared_preferences: af6bfa751691cdc24be3045c43ec037377ada40d shared_preferences_linux: afefbfe8d921e207f01ede8b60373d9e3b566b78 shared_preferences_macos: f3f29b71ccbb56bf40c9dd6396c9acf15e214087 shared_preferences_web: 141cce0c3ed1a1c5bf2a0e44f52d31eeb66e5ea9 shared_preferences_windows: 36b76d6f54e76ead957e60b49e2f124b4cd3e6ae + sms_otp_auto_verify: 201803ac25e13feedaae96eda8b70b10c55b3338 speech_to_text: b43a7d99aef037bd758ed8e45d79bbac035d2dfe + sqflite: 6d358c025f5b867b29ed92fc697fd34924e11904 + SwiftyGif: 5d4af95df24caf1c570dbbcb32a3b8a0763bc6d7 TOCropViewController: da59f531f8ac8a94ef6d6c0fc34009350f9e8bfe Try: 5ef669ae832617b3cee58cb2c6f99fb767a4ff96 twilio_programmable_video: 6a41593640f3d86af60b22541fd457b22deaae7f @@ -456,6 +810,6 @@ SPEC CHECKSUMS: webview_flutter: d2b4d6c66968ad042ad94cbb791f5b72b4678a96 wifi: d7d77c94109e36c4175d845f0a5964eadba71060 -PODFILE CHECKSUM: 5a17be3f8af73a757fa4439c77cf6ab2db29a6e7 +PODFILE CHECKSUM: ac5efa1ac3c9555d0008dc18004313c84746da62 -COCOAPODS: 1.10.0 +COCOAPODS: 1.10.1 diff --git a/ios/Runner.xcodeproj/project.pbxproj b/ios/Runner.xcodeproj/project.pbxproj index 366647c0..a48231b2 100644 --- a/ios/Runner.xcodeproj/project.pbxproj +++ b/ios/Runner.xcodeproj/project.pbxproj @@ -220,6 +220,7 @@ 9705A1C41CF9048500538489 /* Embed Frameworks */, 3B06AD1E1E4923F5004D2608 /* Thin Binary */, EFDAD5E1235DCA1DB6187148 /* [CP] Embed Pods Frameworks */, + A22727229BC544AD6D5B2B5F /* [CP] Copy Pods Resources */, ); buildRules = ( ); @@ -333,6 +334,23 @@ shellPath = /bin/sh; shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build"; }; + A22727229BC544AD6D5B2B5F /* [CP] Copy Pods Resources */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources-${CONFIGURATION}-input-files.xcfilelist", + ); + name = "[CP] Copy Pods Resources"; + outputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources-${CONFIGURATION}-output-files.xcfilelist", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources.sh\"\n"; + showEnvVarsInLog = 0; + }; EFDAD5E1235DCA1DB6187148 /* [CP] Embed Pods Frameworks */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; diff --git a/ios/Runner/AppDelegate.swift b/ios/Runner/AppDelegate.swift index 2dc828d1..c4a74c80 100644 --- a/ios/Runner/AppDelegate.swift +++ b/ios/Runner/AppDelegate.swift @@ -11,7 +11,7 @@ var userNotificationCenterDelegate:UNUserNotificationCenterDelegate? = nil override func application( _ application: UIApplication,didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { - GMSServices.provideAPIKey("AIzaSyCiiJiHkocPbcziHt9O8rGWavDrxHRQys8") + GMSServices.provideAPIKey("AIzaSyCmevVlr2Bh-c8W1VUzo8gt8JRY7n5PANw") GeneratedPluginRegistrant.register(with: self) initializePlatformChannel() diff --git a/ios/Runner/WifiConnect/GoogleService-Info.plist b/ios/Runner/WifiConnect/GoogleService-Info.plist new file mode 100644 index 00000000..633037cb --- /dev/null +++ b/ios/Runner/WifiConnect/GoogleService-Info.plist @@ -0,0 +1,38 @@ + + + + + CLIENT_ID + 815750722565-da8p56le8bd6apsbm9eft0jjl1rtpgkt.apps.googleusercontent.com + REVERSED_CLIENT_ID + com.googleusercontent.apps.815750722565-da8p56le8bd6apsbm9eft0jjl1rtpgkt + ANDROID_CLIENT_ID + 815750722565-m14h8mkosm7cnq6uh6rhqr54dn02d705.apps.googleusercontent.com + API_KEY + AIzaSyDiXnCO00li4V7Ioa2YZ_M4ECxRsu_P9tA + GCM_SENDER_ID + 815750722565 + PLIST_VERSION + 1 + BUNDLE_ID + com.HMG.HMG-Smartphone + PROJECT_ID + api-project-815750722565 + STORAGE_BUCKET + api-project-815750722565.appspot.com + IS_ADS_ENABLED + + IS_ANALYTICS_ENABLED + + IS_APPINVITE_ENABLED + + IS_GCM_ENABLED + + IS_SIGNIN_ENABLED + + GOOGLE_APP_ID + 1:815750722565:ios:328ec247a81a2ca23c186c + DATABASE_URL + https://api-project-815750722565.firebaseio.com + + \ No newline at end of file diff --git a/key b/key new file mode 100644 index 00000000..15b9f5d1 Binary files /dev/null and b/key differ diff --git a/lib/config/config.dart b/lib/config/config.dart index d95c2f0a..1ea16a37 100644 --- a/lib/config/config.dart +++ b/lib/config/config.dart @@ -1,23 +1,29 @@ import 'dart:io'; -import 'package:diplomaticquarterapp/core/service/geofencing/GeofencingServices.dart'; import 'package:diplomaticquarterapp/models/Request.dart'; import 'package:diplomaticquarterapp/uitl/app_shared_preferences.dart'; -import 'package:diplomaticquarterapp/widgets/mobile-no/mobile_no.dart'; const MAX_SMALL_SCREEN = 660; // PACKAGES and OFFERS -const EXA_CART_API_BASE_URL = 'https://mdlaboratories.com/exacartapi'; +const EXA_CART_API_BASE_URL = 'http://10.200.101.75:9000'; const PACKAGES_CATEGORIES = '/api/categories'; const PACKAGES_PRODUCTS = '/api/products'; +const PACKAGES_CUSTOMER = '/api/customers'; +const PACKAGES_SHOPPING_CART = '/api/shopping_cart_items'; +const PACKAGES_ORDERS = '/api/orders'; const BASE_URL = 'https://uat.hmgwebservices.com/'; -//const BASE_URL = 'https://.hmgwebservices.com/'; +// const BASE_URL = 'https://hmgwebservices.com/'; -//const BASE_PHARMACY_URL = 'http://swd-pharapp-01:7200/api/'; +// Pharmacy UAT URLs const BASE_PHARMACY_URL = 'https://uat.hmgwebservices.com/epharmacy/api/'; const PHARMACY_BASE_URL = 'https://uat.hmgwebservices.com/epharmacy/api/'; + +// Pharmacy Production URLs +// const BASE_PHARMACY_URL = 'https://mdlaboratories.com/exacartapi/api/'; +// const PHARMACY_BASE_URL = 'https://mdlaboratories.com/exacartapi/api/'; + const PING_SERVICE = 'Services/Weather.svc/REST/CheckConnectivity'; const GET_PROJECT = 'Services/Lists.svc/REST/GetProject'; @@ -25,6 +31,10 @@ const GET_PROJECT = 'Services/Lists.svc/REST/GetProject'; ///Geofencing const GET_GEO_ZONES = 'Services/Patients.svc/REST/GeoF_GetAllPoints'; const LOG_GEO_ZONES = 'Services/Patients.svc/REST/GeoF_InsertPatientFileInfo'; + +// Delivery Driver +const DRIVER_LOCATION = 'Services/Patients.svc/REST/PatientER_GetDriverLocation'; + //weather const WEATHER_INDICATOR = 'Services/Weather.svc/REST/GetCityInfo'; @@ -92,9 +102,12 @@ const GET_NEAREST_HOSPITAL = 'Services/Patients.svc/REST/Patient_GetProjectAvgERWaitingTime'; ///ED Online -const ER_GET_VISUAL_TRIAGE_QUESTIONS = "services/Doctors.svc/REST/ER_GetVisualTriageQuestions"; -const ER_SAVE_TRIAGE_INFORMATION = "services/Doctors.svc/REST/ER_SaveTriageInformation"; -const ER_GetPatientPaymentInformationForERClinic = "services/Doctors.svc/REST/ER_GetPatientPaymentInformationForERClinic"; +const ER_GET_VISUAL_TRIAGE_QUESTIONS = + "services/Doctors.svc/REST/ER_GetVisualTriageQuestions"; +const ER_SAVE_TRIAGE_INFORMATION = + "services/Doctors.svc/REST/ER_SaveTriageInformation"; +const ER_GetPatientPaymentInformationForERClinic = + "services/Doctors.svc/REST/ER_GetPatientPaymentInformationForERClinic"; ///Er Nearest const GET_AMBULANCE_REQUEST = @@ -207,6 +220,10 @@ const GET_PATIENT_SHARE = const GET_PATIENT_APPOINTMENT_HISTORY = "Services/Doctors.svc/REST/PateintHasAppoimentHistory"; +const SEND_REPORT_EYE_EMAIL = "Services/Notifications.svc/REST/SendGlassesPrescriptionEmail"; + +const SEND_CONTACT_LENS_PRESCRIPTION_EMAIL = "Services/Notifications.svc/REST/SendContactLensPrescriptionEmail"; + //URL to get patient appointment curfew history const GET_PATIENT_APPOINTMENT_CURFEW_HISTORY = "Services/Doctors.svc/REST/AppoimentHistoryForCurfew"; @@ -309,7 +326,7 @@ var DEVICE_TOKEN = ""; var IS_VOICE_COMMAND_CLOSED = false; var IS_TEXT_COMPLETED = false; var DeviceTypeID = Platform.isIOS ? 1 : 2; -const LANGUAGE_ID = 1; +const LANGUAGE_ID = 2; const GET_PHARMCY_ITEMS = "Services/Lists.svc/REST/GetPharmcyItems_Region"; const GET_PHARMACY_LIST = "Services/Patients.svc/REST/GetPharmcyList"; const GET_PAtIENTS_INSURANCE = @@ -445,11 +462,14 @@ const GET_E_REFERRALS = "Services/Patients.svc/REST/GetEReferrals"; const GET_ANCILLARY_ORDERS = 'Services/Doctors.svc/REST/GetOnlineAncillaryOrderList'; +const GET_ANCILLARY_ORDERS_DETAILS = + 'Services/Doctors.svc/REST/GetOnlineAncillaryOrderProcList'; + //Pharmacy wishlist // const GET_WISHLIST = "http://swd-pharapp-01:7200/api/shopping_cart_items/"; // pharmacy -const PHARMACY_AUTORZIE_CUSTOMER = "epharmacy/api/AutorizeCustomer"; +const PHARMACY_AUTORZIE_CUSTOMER = "AutorizeCustomer"; const PHARMACY_VERIFY_CUSTOMER = "VerifyCustomer"; const PHARMACY_GET_COUNTRY = "countries"; const PHARMACY_CREATE_CUSTOMER = "epharmacy/api/CreateCustomer"; @@ -470,9 +490,9 @@ const GET_Cancel_ORDER = "cancelorder/"; const WRITE_REVIEW = "Content-Type" + "text/plain; charset=utf-8"; const GET_SHOPPING_CART = "shopping_cart_items/"; const GET_SHIPPING_OPTIONS = "get_shipping_option/"; -const DELETE_SHOPPING_CART = "epharmacy/api/delete_shopping_cart_items/"; +const DELETE_SHOPPING_CART = "delete_shopping_cart_items/"; const DELETE_SHOPPING_CART_ALL = "delete_shopping_cart_item_by_customer/"; -const ORDER_SHOPPING_CART = "epharmacy/api/orders"; +const ORDER_SHOPPING_CART = "orders"; const GET_LACUM_ACCOUNT_INFORMATION = "Services/Patients.svc/REST/GetLakumAccountInformation"; const GET_LACUM_GROUP_INFORMATION = @@ -489,6 +509,8 @@ const LAKUM_GET_USER_TERMS_AND_CONDITIONS = "Services/ERP.svc/REST/GetUserTermsAndConditionsForEPharmcy"; const PRESCRIPTION = 'Services/Patients.svc/REST/GetPrescriptionApptList'; const GET_RECOMMENDED_PRODUCT = 'alsoProduct/'; +const GET_MOST_VIEWED_PRODUCTS ="mostview?"; +const GET_NEW_PRODUCTS = "newproducts?"; // Home Health Care const HHC_GET_ALL_SERVICES = @@ -528,12 +550,9 @@ const GET_SPECIFICATION = "productspecification/"; const GET_BRAND_ITEMS = "products"; // External API -const ADD_ADDRESS_INFO = - "https://mdlaboratories.com/exacartapi/api/addcustomeraddress"; -const GET_CUSTOMER_ADDRESSES = - "https://mdlaboratories.com/exacartapi/api/Customers/"; -const GET_CUSTOMER_INFO = - "https://mdlaboratories.com/exacartapi/api/VerifyCustomer"; +const ADD_ADDRESS_INFO = "addcustomeraddress"; +const GET_CUSTOMER_ADDRESSES = "Customers/"; +const GET_CUSTOMER_INFO = "VerifyCustomer"; //Pharmacy diff --git a/lib/config/localized_values.dart b/lib/config/localized_values.dart index 2229fe55..2987e621a 100644 --- a/lib/config/localized_values.dart +++ b/lib/config/localized_values.dart @@ -365,7 +365,7 @@ const Map localizedValues = { 'painScale': {'en': 'Pain Scale', 'ar': 'مقياس الألم'}, 'weight': {'en': 'Weight', 'ar': 'الوزن'}, 'height': {'en': 'Height', 'ar': 'الطول'}, - 'heart': {'en': 'Heart', 'ar': 'قلب'}, + 'heart': {'en': 'Heart Rate', 'ar': 'معدل النبض'}, "heightUnit": {"en": "height unit", "ar": "وحدة الطول"}, "weightUnit": {"en": "Weight Unit", "ar": "وحدة الوزن"}, "request": {"en": "Request", "ar": "طلبات الاضافة"}, @@ -546,6 +546,9 @@ const Map localizedValues = { "History": {"en": "History", "ar": "السجلات"}, "OrderNo": {"en": "Order No", "ar": "رقم الطلب"}, "OrderDetails": {"en": "Order Details", "ar": "تفاصيل الطلب"}, + "DeliveryDriverTrack": {"en": "Driver Tracking", "ar": "تتبع السائق"}, + "DeliveryLocation": {"en": "Delivery Location", "ar": "موقع التسليم"}, + "Driver": {"en": "Driver", "ar": "السائق"}, "VitalSign": {"en": "Vital Sign", "ar": "العلامة حيوية"}, "MonthlyReports": {"en": "Monthly Reports", "ar": "تقارير شهرية"}, "km": {"en": "KMs:", "ar": "كم"}, @@ -643,8 +646,8 @@ const Map localizedValues = { "Remarks": {"en": "Remarks", "ar": "ملاحضات"}, "ActiveMedications": {"en": "Active Medications", "ar": "ادويتي النشطة"}, "ExpDate": {"en": "Active Exp Date :", "VA": "تاريخ الإنتهاء"}, - "Route": {"en": "Route :", "ar": "الطريقة"}, - "Frequency": {"en": "Frequency :", "ar": "المعدل"}, + "Route": {"en": "Route", "ar": "الطريقة"}, + "Frequency": {"en": "Frequency", "ar": "المعدل"}, "DailyQuantity": {"en": "Daily Quantity :", "ar": "جرعات يومية"}, "AddReminder": {"en": "Add Reminder", "ar": "إضافة تذكير"}, "reminderDes": { @@ -836,6 +839,7 @@ const Map localizedValues = { "bestSellers": {"en": "Best Sellers", "ar": "أفضل البائعين"}, "deleteAllItems": {"en": "Delete All Items", "ar": "حذف كافة العناصر"}, "total": {"en": "Total", "ar": "المجموع"}, + "totalWithColonRight": {"en": "Total:", "ar": ":المجموع"}, "selectAddress": {"en": "Select Address", "ar": "حدد العنوان"}, "shippingAddress": {"en": "SHIPPING ADDRESS", "ar": "عنوان الشحن"}, "changeAddress": {"en": "Change Address", "ar": "تغيير العنوان"}, @@ -1084,6 +1088,7 @@ const Map localizedValues = { "Average": {"en": "Average", "ar": "المعدل"}, "DailyDoses": {"en": "Daily Doses", "ar": "جرعات يومية"}, "Period": {"en": "Period", "ar": "الفترة"}, + "duration": {"en": "Duration", "ar": "المدة"}, "cm": {"en": "CM", "ar": "سم"}, "ft": {"en": "ft", "ar": "قدم"}, "kg": {"en": "kg", "ar": "كجم"}, @@ -1159,7 +1164,7 @@ const Map localizedValues = { "ar": "Connected with HMG Network,\n\nBut failed to access HMG services" }, "offerAndPackages": {"en": "Offers And Packages", "ar": "العروض والباقات"}, - "InvoiceNo": {"en": " Invoice No", "ar": "رقم الفاتورة"}, + "InvoiceNo": {"en": "Invoice No", "ar": "رقم الفاتورة"}, "SpecialResult": {"en": " Special Result", "ar": "نتيجة خاصة"}, "GeneralResult": {"en": "General Result", "ar": "نتيجة عامة"}, "show-more-btn": {"en": "Flow Chart", "ar": "النتائج التراكمية"}, @@ -1652,7 +1657,10 @@ const Map localizedValues = { "enterReadingValue": {"en": "Enter the reading value", "ar": "ادخل القيمة"}, "result": {"en": "Result", "ar": "النتيجة"}, "sort": {"en": "Sort", "ar": "فرز"}, - "bloodSugarConversion": {"en": "Blood Sugar Conversion", "ar": "السكر في الدم"}, + "bloodSugarConversion": { + "en": "Blood Sugar Conversion", + "ar": "السكر في الدم" + }, "convertBloodSugarStatement": { "en": "Convert blood sugar/glucose from mmol/l (UK standard) to mg/dlt (US standard) and vice versa.", @@ -1954,13 +1962,38 @@ const Map localizedValues = { }, "order-overview": {"en": "Order Overview", "ar": "ملخص الطلب"}, "shipping-address": {"en": "Delivery Address", "ar": "عنوان التوصيل"}, - "ancillary-orders": {"en": "Ancillary Orders", "ar": "الأوامر التبعية"}, + "pharmacy-relogin": { + "en": "Your session has timed out, Please try again", + "ar": "انتهت مهلة جلسة الخاص بها. يرجى المحاولة مرة أخرى" + }, + "ancillary-orders": {"en": "Ancillary Orders", "ar": "الأوامر التبعية"}, - "onlineCheckInAgreement": {"en": "The online check-in is for non-life threatening situationCall the red crescent (number) or go to the nearest emergency department if there are:signs of stroke or heart attack history of seizure or syncope there is limb or life threatening injury picture of severe injuries​", - "ar": "تسجيل الذهاب الى الطوارئ عبر الإنترنت هو فقط للحالات  التي لا تهدد الحياة يجب الاتصل بالهلال الأحمر (رقم) أو الذهاب إلى أقرب قسم طوارئ إذا كان هناك علامات السكتة الدماغية أو النوبة القلبية او هناك نوبة تشنج او حالة فقدان الوعي او وجود إصابة تهدد أحد الأطراف او تهدد الحياة او وجود إصابات خطيرة"}, + "onlineCheckInAgreement": { + "en": + "The online check-in is for non-life threatening situationCall the red crescent (number) or go to the nearest emergency department if there are:signs of stroke or heart attack history of seizure or syncope there is limb or life threatening injury picture of severe injuries​", + "ar": + "تسجيل الذهاب الى الطوارئ عبر الإنترنت هو فقط للحالات  التي لا تهدد الحياة يجب الاتصل بالهلال الأحمر (رقم) أو الذهاب إلى أقرب قسم طوارئ إذا كان هناك علامات السكتة الدماغية أو النوبة القلبية او هناك نوبة تشنج او حالة فقدان الوعي او وجود إصابة تهدد أحد الأطراف او تهدد الحياة او وجود إصابات خطيرة" + }, + "MRN": {"en": "MRN", "ar": "ایم آر این"}, + "appointment-date": {"en": "Appointment Date", "ar": "تقرری کی تاریخ"}, + "appointment-no": {"en": "Appointment No", "ar": "تقرری نمبر"}, + "insurance-id": {"en": "Insurance ID", "ar": "انشورنس ID"}, "chiefComplaints": {"en": "Chief Complaints", "ar": "الشكوى الرئيسة"}, - "errorChiefComplaints": {"en": "Please Chief Complaints", "ar": "يرجى ادخال الشكوى الرئيسة"}, - "errorExpectedArrivalTimes": {"en": "Please Expected arrival time", "ar": "يرجى ادخال الوقت المتوقع للوصول"}, - "expectedArrivalTime": {"en": "Expected arrival time", "ar": "الوقت المتوقع للوصول"}, - + "errorChiefComplaints": { + "en": "Please Chief Complaints", + "ar": "يرجى ادخال الشكوى الرئيسة" + }, + "errorExpectedArrivalTimes": { + "en": "Please Expected arrival time", + "ar": "يرجى ادخال الوقت المتوقع للوصول" + }, + "expectedArrivalTime": { + "en": "Expected arrival time", + "ar": "الوقت المتوقع للوصول" + }, + "add-address": {"en": "Add new address", "ar": "اضف عنوان جديد"}, + "enter-file": { + "en": "Please enter the mobile number and the medical file number", + "ar": "الرجاء إدخال رقم الجوال ورقم الملف الطبي" + } }; diff --git a/lib/core/enum/PaymentOptions.dart b/lib/core/enum/PaymentOptions.dart new file mode 100644 index 00000000..bbf43cb2 --- /dev/null +++ b/lib/core/enum/PaymentOptions.dart @@ -0,0 +1,34 @@ +enum PaymentOptions { + VISA, + MASTERCARD, + MADA, + INSTALLMENT, + APPLEPAY +} + +extension PaymentOptions_ on PaymentOptions{ + String value(){ + switch(this){ + case PaymentOptions.VISA: + return "VISA"; + break; + + case PaymentOptions.MASTERCARD: + return "MASTERCARD"; + break; + + case PaymentOptions.MADA: + return "MADA"; + break; + + case PaymentOptions.INSTALLMENT: + return "INSTALLMENT"; + break; + case PaymentOptions.APPLEPAY: + return "APPLEPAY"; + break; + } + + return null; + } +} diff --git a/lib/core/model/ResponseModel.dart b/lib/core/model/ResponseModel.dart new file mode 100644 index 00000000..f34abf7d --- /dev/null +++ b/lib/core/model/ResponseModel.dart @@ -0,0 +1,7 @@ +class ResponseModel{ + final bool status; + final String error; + final T data; + + ResponseModel({this.status, this.data, this.error}); +} \ No newline at end of file diff --git a/lib/core/model/packages_offers/requests/AddProductToCartRequestModel.dart b/lib/core/model/packages_offers/requests/AddProductToCartRequestModel.dart new file mode 100644 index 00000000..69e56ad7 --- /dev/null +++ b/lib/core/model/packages_offers/requests/AddProductToCartRequestModel.dart @@ -0,0 +1,26 @@ +import 'package:flutter/cupertino.dart'; + +class AddProductToCartRequestModel { + int quantity; + int product_id; + String shopping_cart_type; + int customer_id; + + AddProductToCartRequestModel({@required this.product_id, this.customer_id, this.shopping_cart_type = "ShoppingCart", this.quantity = 1}); + + Map json() { + return { + "shopping_cart_item" : { + "quantity": quantity, + "product_id": product_id, + "shopping_cart_type": shopping_cart_type, + "customer_id": customer_id + } + }; + } +} + +class UpdateProductToCartRequestModel extends AddProductToCartRequestModel{ + UpdateProductToCartRequestModel({@required int product_id, @required int customer_id, String shopping_cart_type = "ShoppingCart", int quantity = 1}) + : super(customer_id: customer_id, product_id: product_id, quantity: quantity, shopping_cart_type: shopping_cart_type); +} diff --git a/lib/core/model/packages_offers/requests/CreateCustomerRequestModel.dart b/lib/core/model/packages_offers/requests/CreateCustomerRequestModel.dart new file mode 100644 index 00000000..116545bd --- /dev/null +++ b/lib/core/model/packages_offers/requests/CreateCustomerRequestModel.dart @@ -0,0 +1,21 @@ +import 'package:flutter/cupertino.dart'; + +class PackagesCustomerRequestModel { + + String email; + String phoneNumber; + + PackagesCustomerRequestModel({@required this.email, @required this.phoneNumber}); + + Map json() { + return { + "customer" : { + "email": email, + "addresses": [{ + "email": email, + "phone_number": phoneNumber + }] + } + }; + } +} \ No newline at end of file diff --git a/lib/core/model/packages_offers/requests/OffersCategoriesRequestModel.dart b/lib/core/model/packages_offers/requests/OffersCategoriesRequestModel.dart index f2f4af11..13dba945 100644 --- a/lib/core/model/packages_offers/requests/OffersCategoriesRequestModel.dart +++ b/lib/core/model/packages_offers/requests/OffersCategoriesRequestModel.dart @@ -6,6 +6,12 @@ class OffersCategoriesRequestModel { OffersCategoriesRequestModel({this.limit, this.page, this.sinceId}); Map toFlatMap() { - return {"limit": limit.toString(), "page": page.toString(), "sinceId": sinceId.toString()}; + return { + if(limit != null && limit > 0) + "limit": limit.toString(), + + if(page != null && page > 0) + "page": page.toString(), + }; } } diff --git a/lib/core/model/packages_offers/requests/OffersProductsRequestModel.dart b/lib/core/model/packages_offers/requests/OffersProductsRequestModel.dart index 84862568..583932bb 100644 --- a/lib/core/model/packages_offers/requests/OffersProductsRequestModel.dart +++ b/lib/core/model/packages_offers/requests/OffersProductsRequestModel.dart @@ -1,12 +1,24 @@ class OffersProductsRequestModel { final int categoryId; final int limit; - final int page; - final int sinceId; + // final int page; + int sinceId; - OffersProductsRequestModel({this.categoryId, this.limit, this.page, this.sinceId}); + OffersProductsRequestModel({this.categoryId, this.limit = 50}); Map toFlatMap() { - return {"limit": limit.toString(), "page": page.toString(), "sinceId": sinceId.toString(), "categoryId": categoryId.toString()}; + return { + + if(limit != null && limit > 0) + "limit": limit.toString(), + + // if(page != null && page > 0) + // "page": page.toString(), + + if(categoryId != null && categoryId > 0) + "categoryId": categoryId.toString(), + + "sinceId": sinceId != null ? sinceId.toString() : "0", + }; } } diff --git a/lib/core/model/packages_offers/responses/PackagesCartItemsResponseModel.dart b/lib/core/model/packages_offers/responses/PackagesCartItemsResponseModel.dart new file mode 100644 index 00000000..99c8a8b4 --- /dev/null +++ b/lib/core/model/packages_offers/responses/PackagesCartItemsResponseModel.dart @@ -0,0 +1,132 @@ + +import 'package:diplomaticquarterapp/core/model/packages_offers/responses/PackagesResponseModel.dart'; + +class PackagesCartItemsResponseModel { + int _quantity; + + set quantity(int value) { + _quantity = value; + } + + String _shoppingCartType; + int _productId; + PackagesResponseModel _product; + int _id; + + int get quantity => _quantity; + String get shoppingCartType => _shoppingCartType; + int get productId => _productId; + PackagesResponseModel get product => _product; + int get id => _id; + + PackagesCartItemsResponseModel({ + int quantity, + String shoppingCartType, + int productId, + PackagesResponseModel product, + int id}){ + _quantity = quantity; + _shoppingCartType = shoppingCartType; + _productId = productId; + _product = product; + _id = id; +} + + PackagesCartItemsResponseModel.fromJson(dynamic json) { + _quantity = json["quantity"]; + _shoppingCartType = json["shopping_cart_type"]; + _productId = json["product_id"]; + _product = json["product"] != null ? PackagesResponseModel().fromJson(json["product"]) : null; + _id = json["id"]; + } + + Map toJson() { + var map = {}; + map["quantity"] = _quantity; + map["shopping_cart_type"] = _shoppingCartType; + map["product_id"] = _productId; + if (_product != null) { + map["product"] = _product.toJson(); + } + map["id"] = _id; + return map; + } + +} + +class Images { + int _id; + int _pictureId; + int _position; + String _src; + dynamic _attachment; + + int get id => _id; + int get pictureId => _pictureId; + int get position => _position; + String get src => _src; + dynamic get attachment => _attachment; + + Images({ + int id, + int pictureId, + int position, + String src, + dynamic attachment}){ + _id = id; + _pictureId = pictureId; + _position = position; + _src = src; + _attachment = attachment; +} + + Images.fromJson(dynamic json) { + _id = json["id"]; + _pictureId = json["picture_id"]; + _position = json["position"]; + _src = json["src"]; + _attachment = json["attachment"]; + } + + Map toJson() { + var map = {}; + map["id"] = _id; + map["picture_id"] = _pictureId; + map["position"] = _position; + map["src"] = _src; + map["attachment"] = _attachment; + return map; + } + +} + +/// language_id : 1 +/// localized_name : "Dermatology testing" + +class Localized_names { + int _languageId; + String _localizedName; + + int get languageId => _languageId; + String get localizedName => _localizedName; + + Localized_names({ + int languageId, + String localizedName}){ + _languageId = languageId; + _localizedName = localizedName; +} + + Localized_names.fromJson(dynamic json) { + _languageId = json["language_id"]; + _localizedName = json["localized_name"]; + } + + Map toJson() { + var map = {}; + map["language_id"] = _languageId; + map["localized_name"] = _localizedName; + return map; + } + +} \ No newline at end of file diff --git a/lib/core/model/packages_offers/responses/OfferCategoriesResponseModel.dart b/lib/core/model/packages_offers/responses/PackagesCategoriesResponseModel.dart similarity index 82% rename from lib/core/model/packages_offers/responses/OfferCategoriesResponseModel.dart rename to lib/core/model/packages_offers/responses/PackagesCategoriesResponseModel.dart index 087f1961..292022c0 100644 --- a/lib/core/model/packages_offers/responses/OfferCategoriesResponseModel.dart +++ b/lib/core/model/packages_offers/responses/PackagesCategoriesResponseModel.dart @@ -1,8 +1,8 @@ import 'package:diplomaticquarterapp/generated/json/base/json_convert_content.dart'; import 'package:diplomaticquarterapp/generated/json/base/json_field.dart'; -class OfferCategoriesResponseModel with JsonConvert { - String id; +class PackagesCategoriesResponseModel with JsonConvert { + int id; String name; String namen; @JSONField(name: "localized_names") @@ -49,6 +49,18 @@ class OfferCategoriesResponseModel with JsonConvert { diff --git a/lib/core/model/packages_offers/responses/PackagesCustomerResponseModel.dart b/lib/core/model/packages_offers/responses/PackagesCustomerResponseModel.dart new file mode 100644 index 00000000..245973dd --- /dev/null +++ b/lib/core/model/packages_offers/responses/PackagesCustomerResponseModel.dart @@ -0,0 +1,367 @@ +import 'PackagesCartItemsResponseModel.dart'; + +/// shopping_cart_items : [] +/// billing_address : null +/// shipping_address : null +/// addresses : [{"first_name":null,"last_name":null,"email":"a2zzuhaib@gmil.com","company":null,"country_id":null,"country":null,"state_province_id":null,"city":null,"address1":null,"address2":null,"zip_postal_code":null,"phone_number":"0500409598","fax_number":null,"customer_attributes":null,"created_on_utc":"2021-03-11T09:40:23.8091261Z","province":null,"id":0}] +/// customer_guid : "1367e5c7-be3b-43cc-ad81-ff1fc8d3b130" +/// username : null +/// email : "a2zzuhaib@gmil.com" +/// first_name : null +/// last_name : null +/// language_id : null +/// date_of_birth : null +/// gender : null +/// admin_comment : null +/// is_tax_exempt : false +/// has_shopping_cart_items : false +/// active : true +/// deleted : false +/// is_system_account : false +/// system_name : null +/// last_ip_address : null +/// created_on_utc : "2021-03-11T09:40:23.7535859Z" +/// last_login_date_utc : null +/// last_activity_date_utc : "2021-03-11T09:40:23.7535892Z" +/// registered_in_store_id : 0 +/// subscribed_to_newsletter : false +/// role_ids : [] +/// id : 76823 + +class PackagesCustomerResponseModel { + List _shoppingCartItems; + dynamic _billingAddress; + dynamic _shippingAddress; + List _addresses; + String _customerGuid; + dynamic _username; + String _email; + dynamic _firstName; + dynamic _lastName; + dynamic _languageId; + dynamic _dateOfBirth; + dynamic _gender; + dynamic _adminComment; + bool _isTaxExempt; + bool _hasShoppingCartItems; + bool _active; + bool _deleted; + bool _isSystemAccount; + dynamic _systemName; + dynamic _lastIpAddress; + String _createdOnUtc; + dynamic _lastLoginDateUtc; + String _lastActivityDateUtc; + int _registeredInStoreId; + bool _subscribedToNewsletter; + List _roleIds; + int _id; + + List get shoppingCartItems => _shoppingCartItems; + dynamic get billingAddress => _billingAddress; + dynamic get shippingAddress => _shippingAddress; + List get addresses => _addresses; + String get customerGuid => _customerGuid; + dynamic get username => _username; + String get email => _email; + dynamic get firstName => _firstName; + dynamic get lastName => _lastName; + dynamic get languageId => _languageId; + dynamic get dateOfBirth => _dateOfBirth; + dynamic get gender => _gender; + dynamic get adminComment => _adminComment; + bool get isTaxExempt => _isTaxExempt; + bool get hasShoppingCartItems => _hasShoppingCartItems; + bool get active => _active; + bool get deleted => _deleted; + bool get isSystemAccount => _isSystemAccount; + dynamic get systemName => _systemName; + dynamic get lastIpAddress => _lastIpAddress; + String get createdOnUtc => _createdOnUtc; + dynamic get lastLoginDateUtc => _lastLoginDateUtc; + String get lastActivityDateUtc => _lastActivityDateUtc; + int get registeredInStoreId => _registeredInStoreId; + bool get subscribedToNewsletter => _subscribedToNewsletter; + List get roleIds => _roleIds; + int get id => _id; + + PackagesCustomerResponseModel({ + List shoppingCartItems, + dynamic billingAddress, + dynamic shippingAddress, + List addresses, + String customerGuid, + dynamic username, + String email, + dynamic firstName, + dynamic lastName, + dynamic languageId, + dynamic dateOfBirth, + dynamic gender, + dynamic adminComment, + bool isTaxExempt, + bool hasShoppingCartItems, + bool active, + bool deleted, + bool isSystemAccount, + dynamic systemName, + dynamic lastIpAddress, + String createdOnUtc, + dynamic lastLoginDateUtc, + String lastActivityDateUtc, + int registeredInStoreId, + bool subscribedToNewsletter, + List roleIds, + int id}){ + _shoppingCartItems = shoppingCartItems; + _billingAddress = billingAddress; + _shippingAddress = shippingAddress; + _addresses = addresses; + _customerGuid = customerGuid; + _username = username; + _email = email; + _firstName = firstName; + _lastName = lastName; + _languageId = languageId; + _dateOfBirth = dateOfBirth; + _gender = gender; + _adminComment = adminComment; + _isTaxExempt = isTaxExempt; + _hasShoppingCartItems = hasShoppingCartItems; + _active = active; + _deleted = deleted; + _isSystemAccount = isSystemAccount; + _systemName = systemName; + _lastIpAddress = lastIpAddress; + _createdOnUtc = createdOnUtc; + _lastLoginDateUtc = lastLoginDateUtc; + _lastActivityDateUtc = lastActivityDateUtc; + _registeredInStoreId = registeredInStoreId; + _subscribedToNewsletter = subscribedToNewsletter; + _roleIds = roleIds; + _id = id; +} + + PackagesCustomerResponseModel.fromJson(dynamic json) { + _billingAddress = json["billing_address"]; + _shippingAddress = json["shipping_address"]; + if (json["addresses"] != null) { + _addresses = []; + json["addresses"].forEach((v) { + _addresses.add(Addresses.fromJson(v)); + }); + } + _customerGuid = json["customer_guid"]; + _username = json["username"]; + _email = json["email"]; + _firstName = json["first_name"]; + _lastName = json["last_name"]; + _languageId = json["language_id"]; + _dateOfBirth = json["date_of_birth"]; + _gender = json["gender"]; + _adminComment = json["admin_comment"]; + _isTaxExempt = json["is_tax_exempt"]; + _hasShoppingCartItems = json["has_shopping_cart_items"]; + _active = json["active"]; + _deleted = json["deleted"]; + _isSystemAccount = json["is_system_account"]; + _systemName = json["system_name"]; + _lastIpAddress = json["last_ip_address"]; + _createdOnUtc = json["created_on_utc"]; + _lastLoginDateUtc = json["last_login_date_utc"]; + _lastActivityDateUtc = json["last_activity_date_utc"]; + _registeredInStoreId = json["registered_in_store_id"]; + _subscribedToNewsletter = json["subscribed_to_newsletter"]; + + if (json["role_ids"] != null) { + _roleIds = []; + json["role_ids"].forEach((v) { + _roleIds.add(v); + }); + } + + if (json["shopping_cart_items"] != null) { + _shoppingCartItems = []; + json["shopping_cart_items"].forEach((v) { + _shoppingCartItems.add(PackagesCartItemsResponseModel.fromJson(v)); + }); + } + + _id = json["id"]; + } + + Map toJson() { + var map = {}; + if (_shoppingCartItems != null) { + map["shopping_cart_items"] = _shoppingCartItems.map((v) => v.toJson()).toList(); + } + map["billing_address"] = _billingAddress; + map["shipping_address"] = _shippingAddress; + if (_addresses != null) { + map["addresses"] = _addresses.map((v) => v.toJson()).toList(); + } + map["customer_guid"] = _customerGuid; + map["username"] = _username; + map["email"] = _email; + map["first_name"] = _firstName; + map["last_name"] = _lastName; + map["language_id"] = _languageId; + map["date_of_birth"] = _dateOfBirth; + map["gender"] = _gender; + map["admin_comment"] = _adminComment; + map["is_tax_exempt"] = _isTaxExempt; + map["has_shopping_cart_items"] = _hasShoppingCartItems; + map["active"] = _active; + map["deleted"] = _deleted; + map["is_system_account"] = _isSystemAccount; + map["system_name"] = _systemName; + map["last_ip_address"] = _lastIpAddress; + map["created_on_utc"] = _createdOnUtc; + map["last_login_date_utc"] = _lastLoginDateUtc; + map["last_activity_date_utc"] = _lastActivityDateUtc; + map["registered_in_store_id"] = _registeredInStoreId; + map["subscribed_to_newsletter"] = _subscribedToNewsletter; + if (_roleIds != null) { + map["role_ids"] = _roleIds.map((v) => v).toList(); + } + map["id"] = _id; + return map; + } + +} + +/// first_name : null +/// last_name : null +/// email : "a2zzuhaib@gmil.com" +/// company : null +/// country_id : null +/// country : null +/// state_province_id : null +/// city : null +/// address1 : null +/// address2 : null +/// zip_postal_code : null +/// phone_number : "0500409598" +/// fax_number : null +/// customer_attributes : null +/// created_on_utc : "2021-03-11T09:40:23.8091261Z" +/// province : null +/// id : 0 + +class Addresses { + dynamic _firstName; + dynamic _lastName; + String _email; + dynamic _company; + dynamic _countryId; + dynamic _country; + dynamic _stateProvinceId; + dynamic _city; + dynamic _address1; + dynamic _address2; + dynamic _zipPostalCode; + String _phoneNumber; + dynamic _faxNumber; + dynamic _customerAttributes; + String _createdOnUtc; + dynamic _province; + int _id; + + dynamic get firstName => _firstName; + dynamic get lastName => _lastName; + String get email => _email; + dynamic get company => _company; + dynamic get countryId => _countryId; + dynamic get country => _country; + dynamic get stateProvinceId => _stateProvinceId; + dynamic get city => _city; + dynamic get address1 => _address1; + dynamic get address2 => _address2; + dynamic get zipPostalCode => _zipPostalCode; + String get phoneNumber => _phoneNumber; + dynamic get faxNumber => _faxNumber; + dynamic get customerAttributes => _customerAttributes; + String get createdOnUtc => _createdOnUtc; + dynamic get province => _province; + int get id => _id; + + Addresses({ + dynamic firstName, + dynamic lastName, + String email, + dynamic company, + dynamic countryId, + dynamic country, + dynamic stateProvinceId, + dynamic city, + dynamic address1, + dynamic address2, + dynamic zipPostalCode, + String phoneNumber, + dynamic faxNumber, + dynamic customerAttributes, + String createdOnUtc, + dynamic province, + int id}){ + _firstName = firstName; + _lastName = lastName; + _email = email; + _company = company; + _countryId = countryId; + _country = country; + _stateProvinceId = stateProvinceId; + _city = city; + _address1 = address1; + _address2 = address2; + _zipPostalCode = zipPostalCode; + _phoneNumber = phoneNumber; + _faxNumber = faxNumber; + _customerAttributes = customerAttributes; + _createdOnUtc = createdOnUtc; + _province = province; + _id = id; +} + + Addresses.fromJson(dynamic json) { + _firstName = json["first_name"]; + _lastName = json["last_name"]; + _email = json["email"]; + _company = json["company"]; + _countryId = json["country_id"]; + _country = json["country"]; + _stateProvinceId = json["state_province_id"]; + _city = json["city"]; + _address1 = json["address1"]; + _address2 = json["address2"]; + _zipPostalCode = json["zip_postal_code"]; + _phoneNumber = json["phone_number"]; + _faxNumber = json["fax_number"]; + _customerAttributes = json["customer_attributes"]; + _createdOnUtc = json["created_on_utc"]; + _province = json["province"]; + _id = json["id"]; + } + + Map toJson() { + var map = {}; + map["first_name"] = _firstName; + map["last_name"] = _lastName; + map["email"] = _email; + map["company"] = _company; + map["country_id"] = _countryId; + map["country"] = _country; + map["state_province_id"] = _stateProvinceId; + map["city"] = _city; + map["address1"] = _address1; + map["address2"] = _address2; + map["zip_postal_code"] = _zipPostalCode; + map["phone_number"] = _phoneNumber; + map["fax_number"] = _faxNumber; + map["customer_attributes"] = _customerAttributes; + map["created_on_utc"] = _createdOnUtc; + map["province"] = _province; + map["id"] = _id; + return map; + } + +} \ No newline at end of file diff --git a/lib/core/model/packages_offers/responses/OfferProductsResponseModel.dart b/lib/core/model/packages_offers/responses/PackagesResponseModel.dart similarity index 95% rename from lib/core/model/packages_offers/responses/OfferProductsResponseModel.dart rename to lib/core/model/packages_offers/responses/PackagesResponseModel.dart index 58481a8b..7297a20a 100644 --- a/lib/core/model/packages_offers/responses/OfferProductsResponseModel.dart +++ b/lib/core/model/packages_offers/responses/PackagesResponseModel.dart @@ -1,8 +1,8 @@ import 'package:diplomaticquarterapp/generated/json/base/json_convert_content.dart'; import 'package:diplomaticquarterapp/generated/json/base/json_field.dart'; -class OfferProductsResponseModel with JsonConvert { - String id; +class PackagesResponseModel with JsonConvert { + int id; @JSONField(name: "visible_individually") bool visibleIndividually; String name; @@ -205,6 +205,17 @@ class OfferProductsResponseModel with JsonConvert { int vendorId; @JSONField(name: "se_name") String seName; + + String getName() { + if(localizedNames.length == 2){ + if(localizedNames.first.languageId == 2) + return localizedNames.first.localizedName ?? name; + + else if(localizedNames.first.languageId == 1) + return localizedNames.last.localizedName ?? name; + } + return name; + } } class OfferProductsResponseModelLocalizedName with JsonConvert { diff --git a/lib/core/model/packages_offers/responses/order_response_model.dart b/lib/core/model/packages_offers/responses/order_response_model.dart new file mode 100644 index 00000000..ed53a765 --- /dev/null +++ b/lib/core/model/packages_offers/responses/order_response_model.dart @@ -0,0 +1,323 @@ + + +import 'package:diplomaticquarterapp/core/model/packages_offers/responses/PackagesCustomerResponseModel.dart'; +import 'PackagesCartItemsResponseModel.dart'; + +class PackagesOrderResponseModel { + String _customOrderNumber; + int _storeId; + dynamic _pickUpInStore; + String _paymentMethodSystemName; + String _customerCurrencyCode; + double _currencyRate; + int _customerTaxDisplayTypeId; + dynamic _vatNumber; + double _orderSubtotalInclTax; + double _orderSubtotalExclTax; + double _orderSubTotalDiscountInclTax; + double _orderSubTotalDiscountExclTax; + double _orderShippingInclTax; + double _orderShippingExclTax; + double _paymentMethodAdditionalFeeInclTax; + double _paymentMethodAdditionalFeeExclTax; + String _taxRates; + double _orderTax; + double _orderDiscount; + double _orderTotal; + double _refundedAmount; + dynamic _rewardPointsWereAdded; + String _checkoutAttributeDescription; + int _customerLanguageId; + int _affiliateId; + String _customerIp; + dynamic _authorizationTransactionId; + dynamic _authorizationTransactionCode; + dynamic _authorizationTransactionResult; + dynamic _captureTransactionId; + dynamic _captureTransactionResult; + dynamic _subscriptionTransactionId; + dynamic _paidDateUtc; + dynamic _shippingMethod; + dynamic _shippingRateComputationMethodSystemName; + String _customValuesXml; + dynamic _paymentOption; + bool _deleted; + String _createdOnUtc; + PackagesCustomerResponseModel _customer; + int _customerId; + dynamic _billingAddress; + dynamic _shippingAddress; + List _orderItems; + String _orderStatus; + String _paymentStatus; + String _shippingStatus; + String _customerTaxDisplayType; + int _id; + + String get customOrderNumber => _customOrderNumber; + int get storeId => _storeId; + dynamic get pickUpInStore => _pickUpInStore; + String get paymentMethodSystemName => _paymentMethodSystemName; + String get customerCurrencyCode => _customerCurrencyCode; + double get currencyRate => _currencyRate; + int get customerTaxDisplayTypeId => _customerTaxDisplayTypeId; + dynamic get vatNumber => _vatNumber; + double get orderSubtotalInclTax => _orderSubtotalInclTax; + double get orderSubtotalExclTax => _orderSubtotalExclTax; + double get orderSubTotalDiscountInclTax => _orderSubTotalDiscountInclTax; + double get orderSubTotalDiscountExclTax => _orderSubTotalDiscountExclTax; + double get orderShippingInclTax => _orderShippingInclTax; + double get orderShippingExclTax => _orderShippingExclTax; + double get paymentMethodAdditionalFeeInclTax => _paymentMethodAdditionalFeeInclTax; + double get paymentMethodAdditionalFeeExclTax => _paymentMethodAdditionalFeeExclTax; + String get taxRates => _taxRates; + double get orderTax => _orderTax; + double get orderDiscount => _orderDiscount; + double get orderTotal => _orderTotal; + double get refundedAmount => _refundedAmount; + dynamic get rewardPointsWereAdded => _rewardPointsWereAdded; + String get checkoutAttributeDescription => _checkoutAttributeDescription; + int get customerLanguageId => _customerLanguageId; + int get affiliateId => _affiliateId; + String get customerIp => _customerIp; + dynamic get authorizationTransactionId => _authorizationTransactionId; + dynamic get authorizationTransactionCode => _authorizationTransactionCode; + dynamic get authorizationTransactionResult => _authorizationTransactionResult; + dynamic get captureTransactionId => _captureTransactionId; + dynamic get captureTransactionResult => _captureTransactionResult; + dynamic get subscriptionTransactionId => _subscriptionTransactionId; + dynamic get paidDateUtc => _paidDateUtc; + dynamic get shippingMethod => _shippingMethod; + dynamic get shippingRateComputationMethodSystemName => _shippingRateComputationMethodSystemName; + String get customValuesXml => _customValuesXml; + dynamic get paymentOption => _paymentOption; + bool get deleted => _deleted; + String get createdOnUtc => _createdOnUtc; + PackagesCustomerResponseModel get customer => _customer; + int get customerId => _customerId; + dynamic get billingAddress => _billingAddress; + dynamic get shippingAddress => _shippingAddress; + List get orderItems => _orderItems; + String get orderStatus => _orderStatus; + String get paymentStatus => _paymentStatus; + String get shippingStatus => _shippingStatus; + String get customerTaxDisplayType => _customerTaxDisplayType; + int get id => _id; + + OrderResponseModel({ + String customOrderNumber, + int storeId, + dynamic pickUpInStore, + String paymentMethodSystemName, + String customerCurrencyCode, + double currencyRate, + int customerTaxDisplayTypeId, + dynamic vatNumber, + double orderSubtotalInclTax, + double orderSubtotalExclTax, + double orderSubTotalDiscountInclTax, + double orderSubTotalDiscountExclTax, + double orderShippingInclTax, + double orderShippingExclTax, + double paymentMethodAdditionalFeeInclTax, + double paymentMethodAdditionalFeeExclTax, + String taxRates, + double orderTax, + double orderDiscount, + double orderTotal, + double refundedAmount, + dynamic rewardPointsWereAdded, + String checkoutAttributeDescription, + int customerLanguageId, + int affiliateId, + String customerIp, + dynamic authorizationTransactionId, + dynamic authorizationTransactionCode, + dynamic authorizationTransactionResult, + dynamic captureTransactionId, + dynamic captureTransactionResult, + dynamic subscriptionTransactionId, + dynamic paidDateUtc, + dynamic shippingMethod, + dynamic shippingRateComputationMethodSystemName, + String customValuesXml, + dynamic paymentOption, + bool deleted, + String createdOnUtc, + PackagesCustomerResponseModel customer, + int customerId, + dynamic billingAddress, + dynamic shippingAddress, + List orderItems, + String orderStatus, + String paymentStatus, + String shippingStatus, + String customerTaxDisplayType, + int id}){ + _customOrderNumber = customOrderNumber; + _storeId = storeId; + _pickUpInStore = pickUpInStore; + _paymentMethodSystemName = paymentMethodSystemName; + _customerCurrencyCode = customerCurrencyCode; + _currencyRate = currencyRate; + _customerTaxDisplayTypeId = customerTaxDisplayTypeId; + _vatNumber = vatNumber; + _orderSubtotalInclTax = orderSubtotalInclTax; + _orderSubtotalExclTax = orderSubtotalExclTax; + _orderSubTotalDiscountInclTax = orderSubTotalDiscountInclTax; + _orderSubTotalDiscountExclTax = orderSubTotalDiscountExclTax; + _orderShippingInclTax = orderShippingInclTax; + _orderShippingExclTax = orderShippingExclTax; + _paymentMethodAdditionalFeeInclTax = paymentMethodAdditionalFeeInclTax; + _paymentMethodAdditionalFeeExclTax = paymentMethodAdditionalFeeExclTax; + _taxRates = taxRates; + _orderTax = orderTax; + _orderDiscount = orderDiscount; + _orderTotal = orderTotal; + _refundedAmount = refundedAmount; + _rewardPointsWereAdded = rewardPointsWereAdded; + _checkoutAttributeDescription = checkoutAttributeDescription; + _customerLanguageId = customerLanguageId; + _affiliateId = affiliateId; + _customerIp = customerIp; + _authorizationTransactionId = authorizationTransactionId; + _authorizationTransactionCode = authorizationTransactionCode; + _authorizationTransactionResult = authorizationTransactionResult; + _captureTransactionId = captureTransactionId; + _captureTransactionResult = captureTransactionResult; + _subscriptionTransactionId = subscriptionTransactionId; + _paidDateUtc = paidDateUtc; + _shippingMethod = shippingMethod; + _shippingRateComputationMethodSystemName = shippingRateComputationMethodSystemName; + _customValuesXml = customValuesXml; + _paymentOption = paymentOption; + _deleted = deleted; + _createdOnUtc = createdOnUtc; + _customer = customer; + _customerId = customerId; + _billingAddress = billingAddress; + _shippingAddress = shippingAddress; + _orderItems = orderItems; + _orderStatus = orderStatus; + _paymentStatus = paymentStatus; + _shippingStatus = shippingStatus; + _customerTaxDisplayType = customerTaxDisplayType; + _id = id; +} + + PackagesOrderResponseModel.fromJson(dynamic json) { + _customOrderNumber = json["custom_order_number"]; + _storeId = json["store_id"]; + _pickUpInStore = json["pick_up_in_store"]; + _paymentMethodSystemName = json["payment_method_system_name"]; + _customerCurrencyCode = json["customer_currency_code"]; + _currencyRate = json["currency_rate"]; + _customerTaxDisplayTypeId = json["customer_tax_display_type_id"]; + _vatNumber = json["vat_number"]; + _orderSubtotalInclTax = json["order_subtotal_incl_tax"]; + _orderSubtotalExclTax = json["order_subtotal_excl_tax"]; + _orderSubTotalDiscountInclTax = json["order_sub_total_discount_incl_tax"]; + _orderSubTotalDiscountExclTax = json["order_sub_total_discount_excl_tax"]; + _orderShippingInclTax = json["order_shipping_incl_tax"]; + _orderShippingExclTax = json["order_shipping_excl_tax"]; + _paymentMethodAdditionalFeeInclTax = json["payment_method_additional_fee_incl_tax"]; + _paymentMethodAdditionalFeeExclTax = json["payment_method_additional_fee_excl_tax"]; + _taxRates = json["tax_rates"]; + _orderTax = json["order_tax"]; + _orderDiscount = json["order_discount"]; + _orderTotal = json["order_total"]; + _refundedAmount = json["refunded_amount"]; + _rewardPointsWereAdded = json["reward_points_were_added"]; + _checkoutAttributeDescription = json["checkout_attribute_description"]; + _customerLanguageId = json["customer_language_id"]; + _affiliateId = json["affiliate_id"]; + _customerIp = json["customer_ip"]; + _authorizationTransactionId = json["authorization_transaction_id"]; + _authorizationTransactionCode = json["authorization_transaction_code"]; + _authorizationTransactionResult = json["authorization_transaction_result"]; + _captureTransactionId = json["capture_transaction_id"]; + _captureTransactionResult = json["capture_transaction_result"]; + _subscriptionTransactionId = json["subscription_transaction_id"]; + _paidDateUtc = json["paid_date_utc"]; + _shippingMethod = json["shipping_method"]; + _shippingRateComputationMethodSystemName = json["shipping_rate_computation_method_system_name"]; + _customValuesXml = json["custom_values_xml"]; + _paymentOption = json["payment_option"]; + _deleted = json["deleted"]; + _createdOnUtc = json["created_on_utc"]; + _customer = json["customer"] != null ? PackagesCustomerResponseModel.fromJson(json["customer"]) : null; + _customerId = json["customer_id"]; + _billingAddress = json["billing_address"]; + _shippingAddress = json["shipping_address"]; + if (json["order_items"] != null) { + _orderItems = []; + json["order_items"].forEach((v) { + _orderItems.add(PackagesCartItemsResponseModel.fromJson(v)); + }); + } + _orderStatus = json["order_status"]; + _paymentStatus = json["payment_status"]; + _shippingStatus = json["shipping_status"]; + _customerTaxDisplayType = json["customer_tax_display_type"]; + _id = json["id"]; + } + + Map toJson() { + var map = {}; + map["custom_order_number"] = _customOrderNumber; + map["store_id"] = _storeId; + map["pick_up_in_store"] = _pickUpInStore; + map["payment_method_system_name"] = _paymentMethodSystemName; + map["customer_currency_code"] = _customerCurrencyCode; + map["currency_rate"] = _currencyRate; + map["customer_tax_display_type_id"] = _customerTaxDisplayTypeId; + map["vat_number"] = _vatNumber; + map["order_subtotal_incl_tax"] = _orderSubtotalInclTax; + map["order_subtotal_excl_tax"] = _orderSubtotalExclTax; + map["order_sub_total_discount_incl_tax"] = _orderSubTotalDiscountInclTax; + map["order_sub_total_discount_excl_tax"] = _orderSubTotalDiscountExclTax; + map["order_shipping_incl_tax"] = _orderShippingInclTax; + map["order_shipping_excl_tax"] = _orderShippingExclTax; + map["payment_method_additional_fee_incl_tax"] = _paymentMethodAdditionalFeeInclTax; + map["payment_method_additional_fee_excl_tax"] = _paymentMethodAdditionalFeeExclTax; + map["tax_rates"] = _taxRates; + map["order_tax"] = _orderTax; + map["order_discount"] = _orderDiscount; + map["order_total"] = _orderTotal; + map["refunded_amount"] = _refundedAmount; + map["reward_points_were_added"] = _rewardPointsWereAdded; + map["checkout_attribute_description"] = _checkoutAttributeDescription; + map["customer_language_id"] = _customerLanguageId; + map["affiliate_id"] = _affiliateId; + map["customer_ip"] = _customerIp; + map["authorization_transaction_id"] = _authorizationTransactionId; + map["authorization_transaction_code"] = _authorizationTransactionCode; + map["authorization_transaction_result"] = _authorizationTransactionResult; + map["capture_transaction_id"] = _captureTransactionId; + map["capture_transaction_result"] = _captureTransactionResult; + map["subscription_transaction_id"] = _subscriptionTransactionId; + map["paid_date_utc"] = _paidDateUtc; + map["shipping_method"] = _shippingMethod; + map["shipping_rate_computation_method_system_name"] = _shippingRateComputationMethodSystemName; + map["custom_values_xml"] = _customValuesXml; + map["payment_option"] = _paymentOption; + map["deleted"] = _deleted; + map["created_on_utc"] = _createdOnUtc; + if (_customer != null) { + map["customer"] = _customer.toJson(); + } + map["customer_id"] = _customerId; + map["billing_address"] = _billingAddress; + map["shipping_address"] = _shippingAddress; + if (_orderItems != null) { + map["order_items"] = _orderItems.map((v) => v.toJson()).toList(); + } + map["order_status"] = _orderStatus; + map["payment_status"] = _paymentStatus; + map["shipping_status"] = _shippingStatus; + map["customer_tax_display_type"] = _customerTaxDisplayType; + map["id"] = _id; + return map; + } + +} diff --git a/lib/core/model/pharmacies/order_detail.dart b/lib/core/model/pharmacies/order_detail.dart index cd53af92..74e89295 100644 --- a/lib/core/model/pharmacies/order_detail.dart +++ b/lib/core/model/pharmacies/order_detail.dart @@ -66,6 +66,8 @@ class OrderDetailModel { String preferDeliveryDate; String preferDeliveryTime; String preferDeliveryTimen; + String driverOTP; + String driverID; OrderDetailModel( {this.id, @@ -130,7 +132,9 @@ class OrderDetailModel { this.lakumAmount, this.preferDeliveryDate, this.preferDeliveryTime, - this.preferDeliveryTimen}); + this.preferDeliveryTimen, + this.driverID, + this.driverOTP,}); OrderDetailModel.fromJson(Map json) { id = json['id']; @@ -210,6 +214,10 @@ class OrderDetailModel { preferDeliveryDate = json['prefer_delivery_date']; preferDeliveryTime = json['prefer_delivery_time']; preferDeliveryTimen = json['prefer_delivery_timen']; + + // Driver Detail + driverID: json["DriverID"]; + driverOTP: json["DriverOTP"]; } Map toJson() { diff --git a/lib/core/model/pharmacies/order_model.dart b/lib/core/model/pharmacies/order_model.dart index 92f4a729..d025faa6 100644 --- a/lib/core/model/pharmacies/order_model.dart +++ b/lib/core/model/pharmacies/order_model.dart @@ -73,6 +73,8 @@ class OrderModel { DateTime preferDeliveryDate; PreferDeliveryTime preferDeliveryTime; PreferDeliveryTimen preferDeliveryTimen; + String driverOTP; + String driverID; OrderModel({ this.id, @@ -138,6 +140,8 @@ class OrderModel { this.preferDeliveryDate, this.preferDeliveryTime, this.preferDeliveryTimen, + this.driverID, + this.driverOTP, }); factory OrderModel.fromJson(Map json) => OrderModel( @@ -204,6 +208,11 @@ class OrderModel { preferDeliveryDate: json["prefer_delivery_date"] == null ? null : DateTime.parse(json["prefer_delivery_date"]), preferDeliveryTime: json["prefer_delivery_time"] == null ? null : preferDeliveryTimeValues.map[json["prefer_delivery_time"]], preferDeliveryTimen: json["prefer_delivery_timen"] == null ? null : preferDeliveryTimenValues.map[json["prefer_delivery_timen"]], + + // Driver Detail + driverID: json["DriverID"], + driverOTP: json["DriverOTP"], + ); Map toJson() => { @@ -1366,7 +1375,7 @@ final titleValues = EnumValues({ "ممتاز": Title.TITLE }); -enum OrderStatus { ORDER_SUBMITTED, PENDING, ORDER_IN_PROGRESS, ORDER_COMPLETED, CANCELLED, PROCESSING, ORDER_REFUNDED, COMPLETE } +enum OrderStatus { ORDER_SUBMITTED, PENDING, ORDER_IN_PROGRESS,ORDER_SENT_FOR_DELIVERY, ORDER_COMPLETED, CANCELLED, PROCESSING, ORDER_REFUNDED, COMPLETE } final orderStatusValues = EnumValues({ "Cancelled": OrderStatus.CANCELLED, @@ -1376,7 +1385,8 @@ final orderStatusValues = EnumValues({ "OrderRefunded": OrderStatus.ORDER_REFUNDED, "OrderSubmitted": OrderStatus.ORDER_SUBMITTED, "Pending": OrderStatus.PENDING, - "Processing": OrderStatus.PROCESSING + "Processing": OrderStatus.PROCESSING, + "orderSentForDelivery": OrderStatus.ORDER_SENT_FOR_DELIVERY }); enum OrderStatusn { ORDER_SUBMITTED, EMPTY, ORDER_IN_PROGRESS, ORDER_COMPLETED, ORDER_STATUSN, PURPLE, FLUFFY, TENTACLED } @@ -1389,6 +1399,7 @@ final orderStatusnValues = EnumValues({ "ملغي": OrderStatusn.ORDER_STATUSN, "Order Submitted": OrderStatusn.ORDER_SUBMITTED, "قيد التنفيذ": OrderStatusn.PURPLE, + "مكتمل": OrderStatusn.TENTACLED, "مكتمل": OrderStatusn.TENTACLED }); diff --git a/lib/core/model/prescriptions/prescription_report.dart b/lib/core/model/prescriptions/prescription_report.dart index 51f5750f..8c18df62 100644 --- a/lib/core/model/prescriptions/prescription_report.dart +++ b/lib/core/model/prescriptions/prescription_report.dart @@ -1,127 +1,193 @@ import 'package:diplomaticquarterapp/uitl/date_uitl.dart'; class PrescriptionReport { + String address; + int appointmentNo; + String clinic; + String companyName; + int days; + String doctorName; + var doseDailyQuantity; + String frequency; + int frequencyNumber; + String image; + String imageExtension; + String imageSRCUrl; + String imageString; + String imageThumbUrl; + String isCovered; + String itemDescription; + int itemID; + String orderDate; int patientID; String patientName; + String phoneOffice1; + String prescriptionQR; + int prescriptionTimes; + String productImage; + String productImageBase64; + String productImageString; + int projectID; + String projectName; + String remarks; + String route; + String sKU; + int scaleOffset; + String startDate; + String patientAge; String patientGender; - String address; String phoneOffice; - String itemDescription; int doseTimingID; int frequencyID; int routeID; - String clinic; - String doctorName; - String route; - String frequency; - String remarks; String name; - int days; - String startDate; - String orderDate; - int doseDailyQuantity; - int itemID; - Null productImage; - String sKU; String itemDescriptionN; String routeN; String frequencyN; - String imageSRCUrl; - String imageThumbUrl; - PrescriptionReport( - {this.patientID, - this.patientName, - this.patientAge, - this.patientGender, - this.address, - this.phoneOffice, - this.itemDescription, - this.doseTimingID, - this.frequencyID, - this.routeID, - this.clinic, - this.doctorName, - this.route, - this.frequency, - this.remarks, - this.name, - this.days, - this.startDate, - this.orderDate, - this.doseDailyQuantity, - this.itemID, - this.productImage, - this.sKU, - this.itemDescriptionN, - this.routeN, - this.frequencyN, - this.imageSRCUrl, - this.imageThumbUrl}); + PrescriptionReport({ + this.address, + this.appointmentNo, + this.clinic, + this.companyName, + this.days, + this.doctorName, + this.doseDailyQuantity, + this.frequency, + this.frequencyNumber, + this.image, + this.imageExtension, + this.imageSRCUrl, + this.imageString, + this.imageThumbUrl, + this.isCovered, + this.itemDescription, + this.itemID, + this.orderDate, + this.patientID, + this.patientName, + this.phoneOffice1, + this.prescriptionQR, + this.prescriptionTimes, + this.productImage, + this.productImageBase64, + this.productImageString, + this.projectID, + this.projectName, + this.remarks, + this.route, + this.sKU, + this.scaleOffset, + this.startDate, + this.patientAge, + this.patientGender, + this.phoneOffice, + this.doseTimingID, + this.frequencyID, + this.routeID, + this.name, + this.itemDescriptionN, + this.routeN, + this.frequencyN, + }); PrescriptionReport.fromJson(Map json) { - patientID = json['PatientID']; - patientName = json['PatientName']; - patientAge = json['PatientAge']; - patientGender = json['PatientGender']; address = json['Address']; - phoneOffice = json['PhoneOffice']; - itemDescription = json['ItemDescription']; - doseTimingID = json['DoseTimingID']; - frequencyID = json['FrequencyID']; - routeID = json['RouteID']; + appointmentNo = json['AppointmentNo']; clinic = json['Clinic']; - doctorName = json['DoctorName']; - route = json['Route']; - frequency = json['Frequency']; - remarks = json['Remarks']; - name = json['Name']; + companyName = json['CompanyName']; days = json['Days']; - startDate = json['StartDate']; - orderDate = json['OrderDate']; + doctorName = json['DoctorName']; doseDailyQuantity = json['DoseDailyQuantity']; + frequency = json['Frequency']; + frequencyNumber = json['FrequencyNumber']; + image = json['Image']; + imageExtension = json['ImageExtension']; + imageSRCUrl = json['ImageSRCUrl']; + imageString = json['ImageString']; + imageThumbUrl = json['ImageThumbUrl']; + isCovered = json['IsCovered']; + itemDescription = json['ItemDescription']; itemID = json['ItemID']; + orderDate = json['OrderDate']; + patientID = json['PatientID']; + patientName = json['PatientName']; + phoneOffice1 = json['PhoneOffice1']; + prescriptionQR = json['PrescriptionQR']; + prescriptionTimes = json['PrescriptionTimes']; productImage = json['ProductImage']; + productImageBase64 = json['ProductImageBase64']; + productImageString = json['ProductImageString']; + projectID = json['ProjectID']; + projectName = json['ProjectName']; + remarks = json['Remarks']; + route = json['Route']; sKU = json['SKU']; - itemDescriptionN = json['ItemDescriptionN']; - routeN = json['RouteN']; - frequencyN = json['FrequencyN']; - imageSRCUrl = json['ImageSRCUrl']; - imageThumbUrl = json['ImageThumbUrl']; + scaleOffset = json['ScaleOffset']; + startDate = json['StartDate']; + + patientAge = json['patientAge']; + patientGender = json['patientGender']; + phoneOffice = json['phoneOffice']; + doseTimingID = json['doseTimingID']; + frequencyID = json['frequencyID']; + routeID = json['routeID']; + name = json['name']; + itemDescriptionN = json['itemDescriptionN']; + routeN = json['routeN']; + frequencyN = json['frequencyN']; } Map toJson() { final Map data = new Map(); + + data['Address'] = this.address; + data['AppointmentNo'] = this.appointmentNo; + data['Clinic'] = this.clinic; + data['CompanyName'] = this.companyName; + data['Days'] = this.days; + data['DoctorName'] = this.doctorName; + data['DoseDailyQuantity'] = this.doseDailyQuantity; + data['Frequency'] = this.frequency; + data['FrequencyNumber'] = this.frequencyNumber; + data['Image'] = this.image; + data['ImageExtension'] = this.imageExtension; + data['ImageSRCUrl'] = this.imageSRCUrl; + data['ImageString'] = this.imageString; + data['ImageThumbUrl'] = this.imageThumbUrl; + data['IsCovered'] = this.isCovered; + data['ItemDescription'] = this.itemDescription; + data['ItemID'] = this.itemID; + data['OrderDate'] = this.orderDate; data['PatientID'] = this.patientID; data['PatientName'] = this.patientName; + data['PhoneOffice1'] = this.phoneOffice1; + data['PrescriptionQR'] = this.prescriptionQR; + data['PrescriptionTimes'] = this.prescriptionTimes; + data['ProductImage'] = this.productImage; + data['ProductImageBase64'] = this.productImageBase64; + data['ProductImageString'] = this.productImageString; + data['ProjectID'] = this.projectID; + data['ProjectName'] = this.projectName; + data['Remarks'] = this.remarks; + data['Route'] = this.route; + data['SKU'] = this.sKU; + data['ScaleOffset'] = this.scaleOffset; + data['StartDate'] = this.startDate; + data['PatientAge'] = this.patientAge; data['PatientGender'] = this.patientGender; - data['Address'] = this.address; data['PhoneOffice'] = this.phoneOffice; - data['ItemDescription'] = this.itemDescription; data['DoseTimingID'] = this.doseTimingID; data['FrequencyID'] = this.frequencyID; data['RouteID'] = this.routeID; - data['Clinic'] = this.clinic; - data['DoctorName'] = this.doctorName; - data['Route'] = this.route; - data['Frequency'] = this.frequency; - data['Remarks'] = this.remarks; data['Name'] = this.name; - data['Days'] = this.days; - data['StartDate'] = this.startDate; - data['OrderDate'] = this.orderDate; - data['DoseDailyQuantity'] = this.doseDailyQuantity; - data['ItemID'] = this.itemID; - data['ProductImage'] = this.productImage; - data['SKU'] = this.sKU; data['ItemDescriptionN'] = this.itemDescriptionN; data['RouteN'] = this.routeN; data['FrequencyN'] = this.frequencyN; - data['ImageSRCUrl'] = this.imageSRCUrl; - data['ImageThumbUrl'] = this.imageThumbUrl; data['hasPlan'] = false; + return data; } } diff --git a/lib/core/service/AlHabibMedicalService/customer_addresses_service.dart b/lib/core/service/AlHabibMedicalService/customer_addresses_service.dart index 34fa4bbb..ea5d03ca 100644 --- a/lib/core/service/AlHabibMedicalService/customer_addresses_service.dart +++ b/lib/core/service/AlHabibMedicalService/customer_addresses_service.dart @@ -1,7 +1,9 @@ import 'package:diplomaticquarterapp/config/config.dart'; import 'package:diplomaticquarterapp/core/viewModels/AlHabibMedicalService/add_new_address_Request_Model.dart'; +import 'package:diplomaticquarterapp/core/viewModels/pharmacyModule/pharmacy_module_view_model.dart'; import 'package:intl/intl.dart'; +import '../../../locator.dart'; import '../base_service.dart'; class CustomerAddressesService extends BaseService { @@ -9,6 +11,7 @@ class CustomerAddressesService extends BaseService { List addressesList = List(); CustomerInfo customerInfo; + Future addAddressInfo({ AddNewAddressRequestModel addNewAddressRequestModel }) async { @@ -25,7 +28,7 @@ class CustomerAddressesService extends BaseService { var date = f.format(DateTime.now().toUtc()) + " GMT"; addNewAddressRequestModel.customer.addresses[0].createdOnUtc = date; hasError = false; - await baseAppClient.post(BASE_PHARMACY_URL+ADD_ADDRESS_INFO, + await baseAppClient.post(ADD_CUSTOMER_ADDRESS, onSuccess: (dynamic response, int statusCode) { addressesList.clear(); response["customers"][0]["addresses"].forEach((data) { @@ -35,7 +38,7 @@ class CustomerAddressesService extends BaseService { }, onFailure: (String error, int statusCode) { hasError = true; super.error = error; - }, body: addNewAddressRequestModel.toJson(), isExternal: true, isAllowAny: true); + }, body: addNewAddressRequestModel.toJson(), isAllowAny: true); } Future getCustomerAddresses() async { diff --git a/lib/core/service/ancillary_orders_service.dart b/lib/core/service/ancillary_orders_service.dart index 5adf5305..b9d14a06 100644 --- a/lib/core/service/ancillary_orders_service.dart +++ b/lib/core/service/ancillary_orders_service.dart @@ -1,10 +1,14 @@ import 'package:diplomaticquarterapp/config/config.dart'; import 'package:diplomaticquarterapp/core/service/base_service.dart'; import 'package:diplomaticquarterapp/models/anicllary-orders/ancillary_order_list_model.dart'; +import 'package:diplomaticquarterapp/models/anicllary-orders/ancillary_order_proc_model.dart'; class AncillaryOrdersService extends BaseService { List _ancillaryLists = List(); List get ancillaryLists => _ancillaryLists; + List _ancillaryProcLists = List(); + List get ancillaryProcLists => + _ancillaryProcLists; Future getOrders() async { Map body = Map(); @@ -13,6 +17,7 @@ class AncillaryOrdersService extends BaseService { await baseAppClient.post(GET_ANCILLARY_ORDERS, onSuccess: (dynamic response, int statusCode) { + _ancillaryLists = []; response['AncillaryOrderList'].forEach((item) { ancillaryLists.add(AncillaryOrdersListModel.fromJson(item)); }); @@ -21,4 +26,179 @@ class AncillaryOrdersService extends BaseService { super.error = error; }, body: body); } + + Future getOrdersDetails(appointmentNo, orderNo) async { + Map body = Map(); + + hasError = false; + + await baseAppClient.post(GET_ANCILLARY_ORDERS_DETAILS, + onSuccess: (dynamic response, int statusCode) { + _ancillaryProcLists = []; + response['AncillaryOrderProcList'] = [ + { + "AncillaryOrderProcList": [ + { + "ApprovalLineItemNo": 0, + "ApprovalNo": 0, + "ApprovalStatus": "", + "ApprovalStatusID": 0, + "CompanyShare": 501.3, + "CompanyShareWithTax": 576.5, + "CompanyTaxAmount": 75.19, + "DiscountAmount": 55.7, + "DiscountCategory": 1, + "DiscountType": "P", + "DiscountTypeValue": 10, + "IsApprovalCreated": false, + "IsApprovalRequired": false, + "IsCovered": false, + "OrderDate": "/Date(1601758800000+0300)/", + "OrderLineItemNo": 1, + "OrderNo": 2020000001, + "PartnerID": 0, + "PartnerShare": 0, + "PartnerShareType": "P", + "PatientShare": 0, + "PatientShareWithTax": 0, + "PatientTaxAmount": 0, + "ProcPrice": 557, + "ProcedureCategoryID": 2, + "ProcedureCategoryName": "LABORATORY", + "ProcedureID": "02013001", + "ProcedureName": "11-DESOXYCORTISOL (COMPOUND S) - S.O", + "TaxAmount": 75.19, + "TaxPct": 15 + }, + { + "ApprovalLineItemNo": 0, + "ApprovalNo": 0, + "ApprovalStatus": "", + "ApprovalStatusID": 0, + "CompanyShare": 90, + "CompanyShareWithTax": 103.5, + "CompanyTaxAmount": 13.5, + "DiscountAmount": 10, + "DiscountCategory": 1, + "DiscountType": "P", + "DiscountTypeValue": 10, + "IsApprovalCreated": false, + "IsApprovalRequired": true, + "IsCovered": false, + "OrderDate": "/Date(1601758800000+0300)/", + "OrderLineItemNo": 4, + "OrderNo": 2020000001, + "PartnerID": 0, + "PartnerShare": 0, + "PartnerShareType": "P", + "PatientShare": 0, + "PatientShareWithTax": 0, + "PatientTaxAmount": 0, + "ProcPrice": 100, + "ProcedureCategoryID": 2, + "ProcedureCategoryName": "LABORATORY", + "ProcedureID": "02014011", + "ProcedureName": "CBC (COMPLETE BLOOD COUNT PROFILE)", + "TaxAmount": 13.5, + "TaxPct": 15 + }, + { + "ApprovalLineItemNo": 0, + "ApprovalNo": 0, + "ApprovalStatus": "", + "ApprovalStatusID": 0, + "CompanyShare": 347.76, + "CompanyShareWithTax": 399.92, + "CompanyTaxAmount": 52.16, + "DiscountAmount": 38.64, + "DiscountCategory": 1, + "DiscountType": "P", + "DiscountTypeValue": 10, + "IsApprovalCreated": false, + "IsApprovalRequired": false, + "IsCovered": false, + "OrderDate": "/Date(1601758800000+0300)/", + "OrderLineItemNo": 3, + "OrderNo": 2020000001, + "PartnerID": 0, + "PartnerShare": 0, + "PartnerShareType": "P", + "PatientShare": 0, + "PatientShareWithTax": 0, + "PatientTaxAmount": 0, + "ProcPrice": 386.4, + "ProcedureCategoryID": 2, + "ProcedureCategoryName": "LABORATORY", + "ProcedureID": "02019302", + "ProcedureName": "21-HYDROXYLASE ABS - S.O", + "TaxAmount": 52.16, + "TaxPct": 15 + }, + { + "ApprovalLineItemNo": 0, + "ApprovalNo": 0, + "ApprovalStatus": "", + "ApprovalStatusID": 0, + "CompanyShare": 1323, + "CompanyShareWithTax": 1521.45, + "CompanyTaxAmount": 198.45, + "DiscountAmount": 147, + "DiscountCategory": 1, + "DiscountType": "P", + "DiscountTypeValue": 10, + "IsApprovalCreated": false, + "IsApprovalRequired": true, + "IsCovered": false, + "OrderDate": "/Date(1601758800000+0300)/", + "OrderLineItemNo": 5, + "OrderNo": 2020000001, + "PartnerID": 0, + "PartnerShare": 0, + "PartnerShareType": "P", + "PatientShare": 0, + "PatientShareWithTax": 0, + "PatientTaxAmount": 0, + "ProcPrice": 1470, + "ProcedureCategoryID": 3, + "ProcedureCategoryName": "RADIOLOGY", + "ProcedureID": "03033065", + "ProcedureName": "CT SCAN - ABDOMEN (WITH CONTRAST)", + "TaxAmount": 198.45, + "TaxPct": 15 + } + ], + "AppointmentDate": "/Date(1601499600000+0300)/", + "AppointmentNo": 2016053756, + "ClinicID": 1, + "ClinicName": "INTERNAL MEDICINE CLINIC", + "CompanyID": 0, + "CompanyName": "Blood Donation Investigation", + "DoctorID": 1485, + "DoctorName": "ANAS ABDULLAH", + "ErrCode": null, + "GroupID": 2, + "InsurancePolicyNo": "45976500", + "Message": "Success", + "PatientCardID": "232332323", + "PatientID": 3072055, + "PatientName": "MAYA KHALED SADDIQ", + "PatientType": 1, + "PolicyID": 2, + "PolicyName": "Test", + "ProjectID": 15, + "SetupID": "010266", + "StatusCode": 1, + "SubCategoryID": 2, + "SubPolicyNo": "234234" + } + ]; + + response['AncillaryOrderProcList'].forEach((item) { + ancillaryProcLists.add(AncillaryOrdersListProcListModel.fromJson(item)); + }); + }, onFailure: (String error, int statusCode) { + hasError = true; + super.error = error; + }, body: body); + } } diff --git a/lib/core/service/client/base_app_client.dart b/lib/core/service/client/base_app_client.dart index abfa7594..4081ff24 100644 --- a/lib/core/service/client/base_app_client.dart +++ b/lib/core/service/client/base_app_client.dart @@ -7,6 +7,8 @@ import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; import 'package:diplomaticquarterapp/models/Appointments/toDoCountProviderModel.dart'; import 'package:diplomaticquarterapp/pages/appUpdatePage/app_update_page.dart'; import 'package:diplomaticquarterapp/uitl/app_shared_preferences.dart'; +import 'package:diplomaticquarterapp/uitl/app_toast.dart'; +import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/uitl/utils.dart'; import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; import 'package:flutter/cupertino.dart'; @@ -86,6 +88,197 @@ class BaseAppClient { body['DeviceTypeID'] = DeviceTypeID; + if (!body.containsKey('IsPublicRequest')) { + body['PatientType'] = body.containsKey('PatientType') + ? body['PatientType'] != null + ? body['PatientType'] + : user['PatientType'] != null + ? user['PatientType'] + : PATIENT_TYPE + : PATIENT_TYPE; + + body['PatientTypeID'] = body.containsKey('PatientTypeID') + ? body['PatientTypeID'] != null + ? body['PatientTypeID'] + : user['PatientType'] != null + ? user['PatientType'] + : PATIENT_TYPE_ID + : PATIENT_TYPE_ID; + if (user != null) { + body['TokenID'] = token; + body['PatientID'] = body['PatientID'] != null + ? body['PatientID'] + : user['PatientID']; + body['PatientOutSA'] = user['OutSA']; + body['SessionID'] = SESSION_ID; //getSe + headers = { + 'Content-Type': 'application/json', + 'Accept': 'application/json', + 'Authorization': pharmacyToken, + 'Mobilenumber': user != null + ? Utils.getPhoneNumberWithoutZero(user['MobileNumber'].toString()) + : "", + 'Statictoken': 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9', + 'Username': user['PatientID'].toString(), + }; + } + } + } + + print("URL : $url"); + print("Body : ${json.encode(body)}"); + + if (await Utils.checkConnection()) { + final response = await http.post(url.trim(), + body: json.encode(body), headers: headers); + final int statusCode = response.statusCode; + print("statusCode :$statusCode"); + if (statusCode < 200 || statusCode >= 400 || json == null) { + onFailure('Error While Fetching data', statusCode); + } else { + // var parsed = json.decode(response.body.toString()); + var parsed = json.decode(utf8.decode(response.bodyBytes)); + if (parsed['Response_Message'] != null) { + onSuccess(parsed, statusCode); + } else { + if (parsed['ErrorType'] == 4) { + navigateToAppUpdate( + AppGlobal.context, parsed['ErrorEndUserMessage']); + } + if (isAllowAny) { + onSuccess(parsed, statusCode); + } else if (parsed['IsAuthenticated'] == null) { + if (parsed['isSMSSent'] == true) { + onSuccess(parsed, statusCode); + } else if (parsed['MessageStatus'] == 1) { + onSuccess(parsed, statusCode); + } else if (parsed['Result'] == 'OK') { + onSuccess(parsed, statusCode); + } else { + if (parsed != null) { + onSuccess(parsed, statusCode); + } else { + onFailure( + parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'], + statusCode); + logout(); + } + } + } else if (parsed['MessageStatus'] == 1 || + parsed['SMSLoginRequired'] == true) { + onSuccess(parsed, statusCode); + } else if (parsed['MessageStatus'] == 2 && + parsed['IsAuthenticated']) { + if (parsed['SameClinicApptList'] != null) { + onSuccess(parsed, statusCode); + } else { + if (parsed['message'] == null && + parsed['ErrorEndUserMessage'] == null) { + if (parsed['ErrorSearchMsg'] == null) { + onFailure("Server Error found with no available message", + statusCode); + } else { + onFailure(parsed['ErrorSearchMsg'], statusCode); + } + } else { + onFailure( + parsed['message'] ?? + parsed['ErrorEndUserMessage'] ?? + parsed['ErrorMessage'], + statusCode); + } + } + } else if (!parsed['IsAuthenticated']) { + await logout(); + + //helpers.showErrorToast('Your session expired Please login agian'); + } else { + if (parsed['SameClinicApptList'] != null) { + onSuccess(parsed, statusCode); + } else { + if (parsed['message'] != null) { + onFailure(parsed['message'] ?? parsed['message'], statusCode); + } else { + onFailure( + parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'], + statusCode); + } + } + } + } + } + } else { + onFailure('Please Check The Internet Connection', -1); + } + } catch (e) { + print(e); + onFailure(e.toString(), -1); + } + } + + postPharmacy(String endPoint, + {Map body, + Function(dynamic response, int statusCode) onSuccess, + Function(String error, int statusCode) onFailure, + bool isAllowAny = false, + bool isExternal = false}) async { + var token = await sharedPref.getString(PHARMACY_AUTORZIE_TOKEN); + var user = await sharedPref.getObject(USER_PROFILE); + String url; + if (isExternal) { + url = endPoint; + } else { + url = PHARMACY_BASE_URL + endPoint; + } + try { + //Map profile = await sharedPref.getObj(DOCTOR_PROFILE); + var pharmacyToken = await sharedPref.getString(PHARMACY_AUTORZIE_TOKEN); + var user = await sharedPref.getObject(USER_PROFILE); + Map headers = { + 'Content-Type': 'application/json', + 'Accept': 'application/json', + 'Authorization': token ?? '', + 'Mobilenumber': user != null + ? Utils.getPhoneNumberWithoutZero(user['MobileNumber'].toString()) + : "", + 'Statictoken': 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9', + 'Username': user != null ? user['PatientID'].toString() : "", + }; + if (!isExternal) { + String token = await sharedPref.getString(TOKEN); + var languageID = + await sharedPref.getStringWithDefaultValue(APP_LANGUAGE, 'ar'); + if (body.containsKey('SetupID')) { + body['SetupID'] = body.containsKey('SetupID') + ? body['SetupID'] != null + ? body['SetupID'] + : SETUP_ID + : SETUP_ID; + } + + body['VersionID'] = VERSION_ID; + body['Channel'] = CHANNEL; + body['LanguageID'] = languageID == 'ar' ? 1 : 2; + + body['IPAdress'] = IP_ADDRESS; + body['generalid'] = GENERAL_ID; + body['PatientOutSA'] = body.containsKey('PatientOutSA') + ? body['PatientOutSA'] != null + ? body['PatientOutSA'] + : PATIENT_OUT_SA + : PATIENT_OUT_SA; + + if (body.containsKey('isDentalAllowedBackend')) { + body['isDentalAllowedBackend'] = + body.containsKey('isDentalAllowedBackend') + ? body['isDentalAllowedBackend'] != null + ? body['isDentalAllowedBackend'] + : IS_DENTAL_ALLOWED_BACKEND + : IS_DENTAL_ALLOWED_BACKEND; + } + + body['DeviceTypeID'] = DeviceTypeID; + if (!body.containsKey('IsPublicRequest')) { body['PatientType'] = body.containsKey('PatientType') ? body['PatientType'] != null @@ -132,7 +325,8 @@ class BaseAppClient { if (statusCode < 200 || statusCode >= 400 || json == null) { onFailure('Error While Fetching data', statusCode); } else { - var parsed = json.decode(response.body.toString()); + // var parsed = json.decode(response.body.toString()); + var parsed = json.decode(utf8.decode(response.bodyBytes)); if (parsed['Response_Message'] != null) { onSuccess(parsed, statusCode); } else { @@ -248,7 +442,8 @@ class BaseAppClient { if (statusCode < 200 || statusCode >= 400 || json == null) { onFailure('Error While Fetching data', statusCode); } else { - var parsed = json.decode(response.body.toString()); + // var parsed = json.decode(response.body.toString()); + var parsed = json.decode(utf8.decode(response.bodyBytes)); onSuccess(parsed, statusCode); } } else { @@ -280,11 +475,11 @@ class BaseAppClient { if (await Utils.checkConnection()) { final response = await http.get(url.trim(), headers: { - 'Content-Type': 'application/json', + 'Content-Type': 'text/html; charset=utf-8', 'Accept': 'application/json', 'Authorization': token ?? '', 'Mobilenumber': user != null - ? getPhoneNumberWithoutZero(user['MobileNumber'].toString()) + ? Utils.getPhoneNumberWithoutZero(user['MobileNumber'].toString()) : "", 'Statictoken': 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9', 'Username': user != null ? user['PatientID'].toString() : "", @@ -293,29 +488,61 @@ class BaseAppClient { print("statusCode :$statusCode"); if (statusCode < 200 || statusCode >= 400 || json == null) { - onFailure('Error While Fetching data', statusCode); + if (statusCode == 401) { + AppToast.showErrorToast( + message: TranslationBase.of(AppGlobal.context).pharmacyRelogin); + Navigator.of(AppGlobal.context).pushNamed(HOME); + } else { + onFailure('Error While Fetching data', statusCode); + } } else { - var parsed = json.decode(response.body.toString()); - onSuccess(parsed, statusCode); + // var parsed = json.decode(response.body.toString()); + var bodyUtf = json.decode(utf8.decode(response.bodyBytes)); + onSuccess(bodyUtf, statusCode); } } else { onFailure('Please Check The Internet Connection', -1); } } - getPhoneNumberWithoutZero(String number) { - String newNumber = number; - if (number.startsWith('0')) { - newNumber = number.substring(1); + simplePost(String fullUrl, + { Map body, + Function(dynamic response, int statusCode) onSuccess, + Function(String error, int statusCode) onFailure,}) async { + String url = fullUrl; + print("URL Query String: $url"); + + if (await Utils.checkConnection()) { + final response = await http.post( + url.trim(), + body: json.encode(body), + headers: { + 'Content-Type': 'application/json', + 'Accept': 'application/json' + }, + ); + + final int statusCode = response.statusCode; + print("statusCode :$statusCode"); + + if (statusCode < 200 || statusCode >= 400 || json == null) { + onFailure('Error While Fetching data', statusCode); + } else { + onSuccess(response.body.toString(), statusCode); + } + } else { + onFailure('Please Check The Internet Connection', -1); } - return newNumber; } simpleGet(String fullUrl, {Function(dynamic response, int statusCode) onSuccess, - Function(String error, int statusCode) onFailure, - Map queryParams}) async { + Function(String error, int statusCode) onFailure, + Map queryParams}) async { + String url = fullUrl; + print("URL Query String: $url"); + var haveParams = (queryParams != null); if (haveParams) { String queryString = Uri(queryParameters: queryParams).query; @@ -345,6 +572,75 @@ class BaseAppClient { } } + + simplePut(String fullUrl, + { Map body, + Function(dynamic response, int statusCode) onSuccess, + Function(String error, int statusCode) onFailure}) async { + + String url = fullUrl; + print("URL Query String: $url"); + + if (await Utils.checkConnection()) { + final response = await http.put( + url.trim(), + body: json.encode(body), + headers: { + 'Content-Type': 'application/json', + 'Accept': 'application/json' + }, + ); + + final int statusCode = response.statusCode; + print("statusCode :$statusCode"); + + if (statusCode < 200 || statusCode >= 400 || json == null) { + onFailure('Error While Fetching data', statusCode); + } else { + onSuccess(response.body.toString(), statusCode); + } + } else { + onFailure('Please Check The Internet Connection', -1); + } + } + + simpleDelete(String fullUrl, + {Function(dynamic response, int statusCode) onSuccess, + Function(String error, int statusCode) onFailure, + Map queryParams}) async { + + String url = fullUrl; + print("URL Query String: $url"); + + var haveParams = (queryParams != null); + if (haveParams) { + String queryString = Uri(queryParameters: queryParams).query; + url += '?' + queryString; + print("URL Query String: $url"); + } + + if (await Utils.checkConnection()) { + final response = await http.delete( + url.trim(), + headers: { + 'Content-Type': 'application/json', + 'Accept': 'application/json' + }, + ); + + final int statusCode = response.statusCode; + print("statusCode :$statusCode"); + + if (statusCode < 200 || statusCode >= 400 || json == null) { + onFailure('Error While Fetching data', statusCode); + } else { + onSuccess(response.body.toString(), statusCode); + } + } else { + onFailure('Please Check The Internet Connection', -1); + } + } + logout() async { await sharedPref.remove(LOGIN_TOKEN_ID); await sharedPref.remove(PHARMACY_CUSTOMER_ID); @@ -386,13 +682,14 @@ class BaseAppClient { return params; } - pharmacyPost(String endPoint, {Map body, - Function(dynamic response, int statusCode) onSuccess, - Function(String error, int statusCode) onFailure, - bool isAllowAny = false, - bool isExternal = false}) async { + Function(dynamic response, int statusCode) onSuccess, + Function(String error, int statusCode) onFailure, + bool isAllowAny = false, + bool isExternal = false}) async { + var token = await sharedPref.getString(PHARMACY_AUTORZIE_TOKEN); + var user = await sharedPref.getObject(USER_PROFILE); String url; if (isExternal) { url = endPoint; @@ -400,17 +697,16 @@ class BaseAppClient { url = BASE_PHARMACY_URL + endPoint; } try { - //Map profile = await sharedPref.getObj(DOCTOR_PROFILE); - if (!isExternal) { + if (isExternal) { String token = await sharedPref.getString(TOKEN); var languageID = - await sharedPref.getStringWithDefaultValue(APP_LANGUAGE, 'ar'); + await sharedPref.getStringWithDefaultValue(APP_LANGUAGE, 'ar'); var user = await sharedPref.getObject(USER_PROFILE); if (body.containsKey('SetupID')) { body['SetupID'] = body.containsKey('SetupID') ? body['SetupID'] != null - ? body['SetupID'] - : SETUP_ID + ? body['SetupID'] + : SETUP_ID : SETUP_ID; } @@ -422,17 +718,17 @@ class BaseAppClient { body['generalid'] = GENERAL_ID; body['PatientOutSA'] = body.containsKey('PatientOutSA') ? body['PatientOutSA'] != null - ? body['PatientOutSA'] - : PATIENT_OUT_SA + ? body['PatientOutSA'] + : PATIENT_OUT_SA : PATIENT_OUT_SA; if (body.containsKey('isDentalAllowedBackend')) { body['isDentalAllowedBackend'] = - body.containsKey('isDentalAllowedBackend') - ? body['isDentalAllowedBackend'] != null - ? body['isDentalAllowedBackend'] - : IS_DENTAL_ALLOWED_BACKEND - : IS_DENTAL_ALLOWED_BACKEND; + body.containsKey('isDentalAllowedBackend') + ? body['isDentalAllowedBackend'] != null + ? body['isDentalAllowedBackend'] + : IS_DENTAL_ALLOWED_BACKEND + : IS_DENTAL_ALLOWED_BACKEND; } body['DeviceTypeID'] = DeviceTypeID; @@ -440,18 +736,18 @@ class BaseAppClient { if (!body.containsKey('IsPublicRequest')) { body['PatientType'] = body.containsKey('PatientType') ? body['PatientType'] != null - ? body['PatientType'] - : user['PatientType'] != null - ? user['PatientType'] - : PATIENT_TYPE + ? body['PatientType'] + : user['PatientType'] != null + ? user['PatientType'] + : PATIENT_TYPE : PATIENT_TYPE; body['PatientTypeID'] = body.containsKey('PatientTypeID') ? body['PatientTypeID'] != null - ? body['PatientTypeID'] - : user['PatientType'] != null - ? user['PatientType'] - : PATIENT_TYPE_ID + ? body['PatientTypeID'] + : user['PatientType'] != null + ? user['PatientType'] + : PATIENT_TYPE_ID : PATIENT_TYPE_ID; if (user != null) { body['TokenID'] = token; @@ -469,19 +765,27 @@ class BaseAppClient { var ss = json.encode(body); if (await Utils.checkConnection()) { - final response = await http.post(url.trim(), - body: json.encode(body), - headers: { - 'Content-Type': 'application/json', - 'Accept': 'application/json', - 'Statictoken': 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9', - }); + final response = + await http.post(url.trim(), body: json.encode(body), headers: { + // 'Content-Type': 'application/json', + // 'Accept': 'application/json', + // 'Statictoken': 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9', + 'Content-Type': 'application/json', + 'Accept': 'application/json', + 'Authorization': token ?? '', + 'Mobilenumber': user != null + ? Utils.getPhoneNumberWithoutZero(user['MobileNumber'].toString()) + : "", + 'Statictoken': 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9', + 'Username': user != null ? user['PatientID'].toString() : "", + }); final int statusCode = response.statusCode; print("statusCode :$statusCode"); if (statusCode < 200 || statusCode >= 400 || json == null) { onFailure('Error While Fetching data', statusCode); } else { - var parsed = json.decode(response.body.toString()); + // var parsed = json.decode(response.body.toString()); + var parsed = json.decode(utf8.decode(response.bodyBytes)); if (parsed['Response_Message'] != null) { onSuccess(parsed, statusCode); } else { @@ -515,12 +819,11 @@ class BaseAppClient { parsed['IsAuthenticated']) { if (parsed['message'] == null && parsed['ErrorEndUserMessage'] == null) { - if(parsed['ErrorSearchMsg'] == null ){ + if (parsed['ErrorSearchMsg'] == null) { onFailure("Server Error found with no available message", statusCode); - }else { - onFailure(parsed['ErrorSearchMsg'], - statusCode); + } else { + onFailure(parsed['ErrorSearchMsg'], statusCode); } } else { onFailure( diff --git a/lib/core/service/medical/EyeService.dart b/lib/core/service/medical/EyeService.dart index 879acbbf..937f89e3 100644 --- a/lib/core/service/medical/EyeService.dart +++ b/lib/core/service/medical/EyeService.dart @@ -1,6 +1,7 @@ import 'package:diplomaticquarterapp/config/config.dart'; import 'package:diplomaticquarterapp/core/model/eye/AppoimentAllHistoryResult.dart'; import 'package:diplomaticquarterapp/core/service/base_service.dart'; +import 'package:diplomaticquarterapp/uitl/utils.dart'; class EyeService extends BaseService { List appoimentAllHistoryResultList = List(); @@ -23,4 +24,53 @@ class EyeService extends BaseService { super.error = error; }, body: body); } + + sendGlassesPrescriptionEmail({int appointmentNo,String projectName,int projectID}) async { + hasError = false; + super.error = ""; + Map body = Map(); + body['isDentalAllowedBackend'] = false; + body['PatientIditificationNum'] = user.patientIdentificationNo; + body['PatientName'] = user.firstName+" "+user.lastName; + body['To'] = user.emailAddress; + body['SetupID'] = user.setupID; + body['DateofBirth'] = user.dateofBirth; + body['ProjectID'] = projectID; + body['AppointmentNo'] = appointmentNo; + body['ProjectName'] = projectName; + body['PatientID'] = user.patientID; + body['PatientMobileNumber'] = Utils.getPhoneNumberWithoutZero(user.mobileNumber); + await baseAppClient.post(SEND_REPORT_EYE_EMAIL, + onSuccess: (response, statusCode) async { + + }, onFailure: (String error, int statusCode) { + hasError = true; + super.error = error; + }, body: body); + } + + sendContactLensPrescriptionEmail({int appointmentNo,String projectName,int projectID}) async { + hasError = false; + super.error = ""; + Map body = Map(); + body['isDentalAllowedBackend'] = false; + body['AppointmentNo'] = appointmentNo; + body['PatientIditificationNum'] = user.patientIdentificationNo; + body['PatientName'] = user.firstName+" "+user.lastName; + body['To'] = user.emailAddress; + body['SetupID'] = user.setupID; + body['DateofBirth'] = user.dateofBirth; + body['ProjectID'] = projectID; + body['AppointmentNo'] = appointmentNo; + body['ProjectName'] = projectName; + body['PatientID'] = user.patientID; + body['PatientMobileNumber'] = Utils.getPhoneNumberWithoutZero(user.mobileNumber); + await baseAppClient.post(SEND_CONTACT_LENS_PRESCRIPTION_EMAIL, + onSuccess: (response, statusCode) async { + + }, onFailure: (String error, int statusCode) { + hasError = true; + super.error = error; + }, body: body); + } } diff --git a/lib/core/service/medical/radiology_service.dart b/lib/core/service/medical/radiology_service.dart index 965fa752..b0b96e71 100644 --- a/lib/core/service/medical/radiology_service.dart +++ b/lib/core/service/medical/radiology_service.dart @@ -11,7 +11,7 @@ class RadiologyService extends BaseService { hasError = false; final Map body = new Map(); body['InvoiceNo'] = invoiceNo; - body['LineItemNo'] = lineItem; + body['LineIt emNo'] = lineItem; body['ProjectID'] = projectId; await baseAppClient.post(GET_RAD_IMAGE_URL, diff --git a/lib/core/service/packages_offers/PackagesOffersServices.dart b/lib/core/service/packages_offers/PackagesOffersServices.dart index e58c3fa3..15811b82 100644 --- a/lib/core/service/packages_offers/PackagesOffersServices.dart +++ b/lib/core/service/packages_offers/PackagesOffersServices.dart @@ -1,27 +1,46 @@ import 'dart:convert'; import 'dart:developer'; +import 'dart:ui'; import 'package:diplomaticquarterapp/config/config.dart'; +import 'package:diplomaticquarterapp/core/enum/PaymentOptions.dart'; +import 'package:diplomaticquarterapp/core/model/ResponseModel.dart'; +import 'package:diplomaticquarterapp/core/model/packages_offers/requests/AddProductToCartRequestModel.dart'; +import 'package:diplomaticquarterapp/core/model/packages_offers/requests/CreateCustomerRequestModel.dart'; import 'package:diplomaticquarterapp/core/model/packages_offers/requests/OffersCategoriesRequestModel.dart'; import 'package:diplomaticquarterapp/core/model/packages_offers/requests/OffersProductsRequestModel.dart'; -import 'package:diplomaticquarterapp/core/model/packages_offers/responses/OfferCategoriesResponseModel.dart'; -import 'package:diplomaticquarterapp/core/model/packages_offers/responses/OfferProductsResponseModel.dart'; +import 'package:diplomaticquarterapp/core/model/packages_offers/responses/PackagesCartItemsResponseModel.dart'; +import 'package:diplomaticquarterapp/core/model/packages_offers/responses/PackagesCategoriesResponseModel.dart'; +import 'package:diplomaticquarterapp/core/model/packages_offers/responses/PackagesResponseModel.dart'; +import 'package:diplomaticquarterapp/core/model/packages_offers/responses/PackagesCustomerResponseModel.dart'; +import 'package:diplomaticquarterapp/core/model/packages_offers/responses/order_response_model.dart'; import 'package:diplomaticquarterapp/core/service/base_service.dart'; import 'package:diplomaticquarterapp/core/service/client/base_app_client.dart'; +import 'package:diplomaticquarterapp/uitl/gif_loader_dialog_utils.dart'; +import 'package:flutter/cupertino.dart'; import '../../../locator.dart'; class OffersAndPackagesServices extends BaseService { - List categoryList = List(); + List categoryList = List(); + List productList = List(); + List latestOffersList = List(); + List bestSellerList = List(); + List bannersList = List(); + List cartItemList = List(); + String cartItemCount = ""; + + PackagesCustomerResponseModel customer; + + Future> getAllCategories(OffersCategoriesRequestModel request) async { + Future errorThrow; - Future> getAllCategories(OffersCategoriesRequestModel request) async { - hasError = false; var url = EXA_CART_API_BASE_URL + PACKAGES_CATEGORIES; await baseAppClient.simpleGet(url, onSuccess: (dynamic stringResponse, int statusCode) { if (statusCode == 200) { var jsonResponse = json.decode(stringResponse); jsonResponse['categories'].forEach((json) { - categoryList.add(OfferCategoriesResponseModel().fromJson(json)); + categoryList.add(PackagesCategoriesResponseModel().fromJson(json)); }); } }, onFailure: (String error, int statusCode) { @@ -31,15 +50,18 @@ class OffersAndPackagesServices extends BaseService { return categoryList; } - List productList = List(); - Future> getAllProducts(OffersProductsRequestModel request) async { - hasError = false; + Future> getAllProducts({@required OffersProductsRequestModel request, @required BuildContext context, @required bool showLoading = true}) async { + Future errorThrow; + + request.sinceId = (productList.isNotEmpty) ? productList.last.id : 0; + + productList = List(); var url = EXA_CART_API_BASE_URL + PACKAGES_PRODUCTS; await baseAppClient.simpleGet(url, onSuccess: (dynamic stringResponse, int statusCode) { if (statusCode == 200) { var jsonResponse = json.decode(stringResponse); jsonResponse['products'].forEach((json) { - productList.add(OfferProductsResponseModel().fromJson(json)); + productList.add(PackagesResponseModel().fromJson(json)); }); } }, onFailure: (String error, int statusCode) { @@ -48,4 +70,276 @@ class OffersAndPackagesServices extends BaseService { return productList; } + + Future> getLatestOffers({@required OffersProductsRequestModel request, @required BuildContext context, @required bool showLoading = true}) async { + + var url = EXA_CART_API_BASE_URL + PACKAGES_PRODUCTS; + await baseAppClient.simpleGet(url, onSuccess: (dynamic stringResponse, int statusCode) { + if (statusCode == 200) { + var jsonResponse = json.decode(stringResponse); + jsonResponse['products'].forEach((json) { + latestOffersList.add(PackagesResponseModel().fromJson(json)); + }); + } + }, onFailure: (String error, int statusCode) { + log(error); + }, queryParams: request.toFlatMap()); + + return latestOffersList; + } + + Future> getBestSellers({@required OffersProductsRequestModel request, @required BuildContext context, @required bool showLoading = true}) async { + + var url = EXA_CART_API_BASE_URL + PACKAGES_PRODUCTS; + await baseAppClient.simpleGet(url, onSuccess: (dynamic stringResponse, int statusCode) { + if (statusCode == 200) { + var jsonResponse = json.decode(stringResponse); + jsonResponse['products'].forEach((json) { + bestSellerList.add(PackagesResponseModel().fromJson(json)); + }); + } + }, onFailure: (String error, int statusCode) { + log(error); + }, queryParams: request.toFlatMap()); + + return bestSellerList; + } + + + Future> getBanners({@required OffersProductsRequestModel request, @required BuildContext context, @required bool showLoading = true}) async { + var url = EXA_CART_API_BASE_URL + PACKAGES_PRODUCTS; + await baseAppClient.simpleGet(url, onSuccess: (dynamic stringResponse, int statusCode) { + if (statusCode == 200) { + var jsonResponse = json.decode(stringResponse); + jsonResponse['products'].forEach((json) { + bannersList.add(PackagesResponseModel().fromJson(json)); + }); + } + }, onFailure: (String error, int statusCode) { + log(error); + }, queryParams: request.toFlatMap()); + + return bannersList; + } + + Future loadOffersPackagesDataForMainPage({@required BuildContext context, bool showLoading = true, Function completion }) async { + var finished = 0; + var totalCalls = 3; + + completedAll(){ + + finished++; + if(completion != null && finished == totalCalls) { + _hideLoading(context, showLoading); + completion(); + } + } + + _showLoading(context, showLoading); + + // Performing Parallel Request on same time + // # 1 + getBestSellers(request: OffersProductsRequestModel(), context: context, showLoading: false).then((value){ + completedAll(); + }); + + // # 2 + getLatestOffers(request: OffersProductsRequestModel(), context: context, showLoading: false).then((value){ + completedAll(); + }); + + // # 3 + getBanners(request: OffersProductsRequestModel(), context: context, showLoading: false).then((value){ + completedAll(); + }); + + } + + // -------------------- + // Create Customer + // -------------------- + Future createCustomer(PackagesCustomerRequestModel request, {@required BuildContext context, bool showLoading = true, Function(bool) completion }) async{ + if(customer != null) + return Future.value(customer); + + customer = null; + Future errorThrow; + + _showLoading(context, showLoading); + var url = EXA_CART_API_BASE_URL + PACKAGES_CUSTOMER; + await baseAppClient.simplePost(url, body: request.json(), onSuccess: (dynamic stringResponse, int statusCode){ + _hideLoading(context, showLoading); + + var jsonResponse = json.decode(stringResponse); + var customerJson = jsonResponse['customers'].first; + customer = PackagesCustomerResponseModel.fromJson(customerJson); + + }, onFailure: (String error, int statusCode){ + _hideLoading(context, showLoading); + errorThrow = Future.error(error); + log(error); + }); + + await Future.delayed(Duration(seconds: 1)); + + return errorThrow ?? customer; + } + + + + // -------------------- + // Shopping Cart + // -------------------- + Future> cartItems({@required BuildContext context, bool showLoading = true}) async{ + Future errorThrow; + + cartItemList.clear(); + _showLoading(context, showLoading); + var url = EXA_CART_API_BASE_URL + PACKAGES_SHOPPING_CART + '/${customer.id}'; + await baseAppClient.simpleGet(url, onSuccess: (dynamic stringResponse, int statusCode) { + _hideLoading(context, showLoading); + + var jsonResponse = json.decode(stringResponse); + jsonResponse['shopping_carts'].forEach((json) { + cartItemList.add(PackagesCartItemsResponseModel.fromJson(json)); + }); + + }, onFailure: (String error, int statusCode) { + _hideLoading(context, showLoading); + log(error); + errorThrow = Future.error({"error":error, "statusCode":statusCode}); + }, queryParams: null); + + return errorThrow ?? cartItemList; + } + + Future> addProductToCart(AddProductToCartRequestModel request, {@required BuildContext context, bool showLoading = true}) async{ + Future errorThrow; + ResponseModel response; + + request.customer_id = customer.id; + + _showLoading(context, showLoading); + var url = EXA_CART_API_BASE_URL + PACKAGES_SHOPPING_CART; + await baseAppClient.simplePost(url, body: request.json(), onSuccess: (dynamic stringResponse, int statusCode){ + _hideLoading(context, showLoading); + + var jsonResponse = json.decode(stringResponse); + var jsonCartItem = jsonResponse["shopping_carts"][0]; + response = ResponseModel(status: true, data: PackagesCartItemsResponseModel.fromJson(jsonCartItem), error: null); + cartItemCount = response.data.quantity.toString(); + + }, onFailure: (String error, int statusCode){ + _hideLoading(context, showLoading); + errorThrow = Future.error(ResponseModel(status: true, data: null, error: error)); + }); + + return errorThrow ?? response; + } + + Future updateProductToCart(int cartItemID, {UpdateProductToCartRequestModel request, @required BuildContext context, bool showLoading = true}) async{ + Future errorThrow; + + _showLoading(context, showLoading); + var url = EXA_CART_API_BASE_URL + PACKAGES_SHOPPING_CART + '/$cartItemID'; + await baseAppClient.simplePut(url, body: request.json(), onSuccess: (dynamic stringResponse, int statusCode){ + _hideLoading(context, showLoading); + + var jsonResponse = json.decode(stringResponse); + + }, onFailure: (String error, int statusCode){ + _hideLoading(context, showLoading); + log(error); + errorThrow = Future.error({"error":error, "statusCode":statusCode}); + }); + + return errorThrow ?? bannersList; + } + + + Future deleteProductFromCart(int cartItemID, {@required BuildContext context, bool showLoading = true}) async{ + Future errorThrow; + + _showLoading(context, showLoading); + var url = EXA_CART_API_BASE_URL + PACKAGES_SHOPPING_CART + '/$cartItemID'; + await baseAppClient.simpleDelete(url, onSuccess: (dynamic stringResponse, int statusCode){ + _hideLoading(context, showLoading); + // var jsonResponse = json.decode(stringResponse); + + }, onFailure: (String error, int statusCode){ + _hideLoading(context, showLoading); + log(error); + errorThrow = Future.error({"error":error, "statusCode":statusCode}); + }); + + return errorThrow ?? true; + } + + // -------------------- + // Place Order + // -------------------- + Future placeOrder({@required String paymentOption, @required BuildContext context, bool showLoading = true}) async{ + Future errorThrow; + + var jsonBody = { + "order": { + "customer_id" : customer.id, + "billing_address": { + "email": customer.email, + "phone_number": customer.addresses.first.phoneNumber + }, + "payment_method_system_name": "Payments.PayFort", + "payment_option": paymentOption + } + }; + + int order_id; + _showLoading(context, showLoading); + var url = EXA_CART_API_BASE_URL + PACKAGES_ORDERS; + await baseAppClient.simplePost(url, body: jsonBody, onSuccess: (dynamic stringResponse, int statusCode){ + _hideLoading(context, showLoading); + + var jsonResponse = json.decode(stringResponse); + order_id = jsonResponse['orders'][0]['id']; + + }, onFailure: (String error, int statusCode){ + _hideLoading(context, showLoading); + log(error); + errorThrow = Future.error(error); + }); + + return errorThrow ?? order_id; + } + + Future> getOrderById(int id, {@required BuildContext context, bool showLoading = true}) async{ + Future errorThrow; + ResponseModel response; + + _showLoading(context, showLoading); + var url = EXA_CART_API_BASE_URL + PACKAGES_ORDERS + '/$id'; + await baseAppClient.simpleGet(url, onSuccess: (dynamic stringResponse, int statusCode) { + _hideLoading(context, showLoading); + + var jsonResponse = json.decode(stringResponse); + var jsonOrder = jsonResponse['orders'][0]; + response = ResponseModel(status: true, data: PackagesOrderResponseModel.fromJson(jsonOrder)); + + }, onFailure: (String error, int statusCode) { + _hideLoading(context, showLoading); + errorThrow = Future.error(ResponseModel(status: false,error: error)); + }, queryParams: null); + + return errorThrow ?? response; + } + } + +_showLoading(BuildContext context, bool flag){ + if(flag) + GifLoaderDialogUtils.showMyDialog(context); +} + +_hideLoading(BuildContext context, bool flag){ + if(flag) + GifLoaderDialogUtils.hideDialog(context); +} \ No newline at end of file diff --git a/lib/core/service/parmacyModule/order-preview-service.dart b/lib/core/service/parmacyModule/order-preview-service.dart index 18cfa87e..0ada84e7 100644 --- a/lib/core/service/parmacyModule/order-preview-service.dart +++ b/lib/core/service/parmacyModule/order-preview-service.dart @@ -3,9 +3,12 @@ import 'package:diplomaticquarterapp/config/shared_pref_kay.dart'; import 'package:diplomaticquarterapp/core/model/pharmacies/Addresses.dart'; import 'package:diplomaticquarterapp/core/model/pharmacies/LacumAccountInformation.dart'; import 'package:diplomaticquarterapp/core/model/pharmacies/ShoppingCart.dart'; +import 'package:diplomaticquarterapp/core/model/pharmacies/order_detail.dart'; import 'package:diplomaticquarterapp/core/model/pharmacies/payment-checkout-data.dart'; import 'package:diplomaticquarterapp/core/service/base_service.dart'; import 'package:diplomaticquarterapp/core/viewModels/pharmacyModule/OrderPreviewViewModel.dart'; +import 'package:flutter/cupertino.dart'; +import 'package:google_maps_flutter/google_maps_flutter.dart'; class OrderPreviewService extends BaseService { bool isFinished = true; @@ -15,6 +18,7 @@ class OrderPreviewService extends BaseService { List addresses = List(); LacumAccountInformation lacumInformation; LacumAccountInformation lacumGroupInformation; + List orderList = List(); Future getAddresses() async { var customerId = await sharedPref.getString(PHARMACY_CUSTOMER_ID); @@ -42,13 +46,14 @@ class OrderPreviewService extends BaseService { dynamic localRes; hasError = false; try { - await baseAppClient.getPharmacy("$GET_SHIPPING_OPTIONS$customerId/${selectedAddress.id}", - onSuccess: (dynamic response, int statusCode) { - localRes = response['shipping_option'][0]; - }, onFailure: (String error, int statusCode) { - hasError = true; - super.error = error; - }, queryParams: queryParams); + await baseAppClient + .getPharmacy("$GET_SHIPPING_OPTIONS$customerId/${selectedAddress.id}", + onSuccess: (dynamic response, int statusCode) { + localRes = response['shipping_option'][0]; + }, onFailure: (String error, int statusCode) { + hasError = true; + super.error = error; + }, queryParams: queryParams); } catch (error) { throw error; } @@ -89,7 +94,7 @@ class OrderPreviewService extends BaseService { Map body = Map(); body["shopping_cart_item"] = choppingCartObject; - await baseAppClient.post("$GET_SHOPPING_CART$productId", + await baseAppClient.pharmacyPost("$GET_SHOPPING_CART$productId", isExternal: false, onSuccess: (response, statusCode) async { localRes = response; }, onFailure: (String error, int statusCode) { @@ -107,7 +112,7 @@ class OrderPreviewService extends BaseService { Map body = Map(); - await baseAppClient.post("$DELETE_SHOPPING_CART$productId", + await baseAppClient.pharmacyPost("$DELETE_SHOPPING_CART$productId", isExternal: false, onSuccess: (response, statusCode) async { localRes = response; }, onFailure: (String error, int statusCode) { @@ -125,8 +130,9 @@ class OrderPreviewService extends BaseService { super.error = ""; dynamic localRes; - await baseAppClient.getPharmacy("$DELETE_SHOPPING_CART_ALL$customerId/ShoppingCart", - onSuccess: (response, statusCode) async { + await baseAppClient + .getPharmacy("$DELETE_SHOPPING_CART_ALL$customerId/ShoppingCart", + onSuccess: (response, statusCode) async { localRes = response; }, onFailure: (String error, int statusCode) { hasError = true; @@ -167,23 +173,24 @@ class OrderPreviewService extends BaseService { try { await baseAppClient.post(GET_LACUM_GROUP_INFORMATION, onSuccess: (response, statusCode) async { - lacumGroupInformation = LacumAccountInformation.fromJson(response); - }, onFailure: (String error, int statusCode) { - hasError = true; - super.error = error; - }, body: body); + lacumGroupInformation = LacumAccountInformation.fromJson(response); + }, onFailure: (String error, int statusCode) { + hasError = true; + super.error = error; + }, body: body); } catch (error) { throw error; } } - Future makeOrder(PaymentCheckoutData paymentCheckoutData, List shoppingCarts) async { + Future makeOrder(PaymentCheckoutData paymentCheckoutData, + List shoppingCarts) async { paymentCheckoutData.address.isChecked = true; hasError = false; super.error = ""; var languageID = - await sharedPref.getStringWithDefaultValue(APP_LANGUAGE, 'en'); + await sharedPref.getStringWithDefaultValue(APP_LANGUAGE, 'en'); var customerId = await sharedPref.getString(PHARMACY_CUSTOMER_ID); Map orderBody = Map(); @@ -192,10 +199,15 @@ class OrderPreviewService extends BaseService { orderBody['billing_address'] = paymentCheckoutData.address; orderBody['pick_up_in_store'] = false; orderBody['payment_method_system_name'] = "Payments.PayFort"; - orderBody['shipping_method'] = languageID == 'ar' ? paymentCheckoutData.shippingOption.namen : paymentCheckoutData.shippingOption.name ; - orderBody['shipping_rate_computation_method_system_name'] = paymentCheckoutData.shippingOption.shippingRateComputationMethodSystemName; - orderBody['customer_id'] = customerId; - orderBody['custom_values_xml'] = "PaymentOption:${getPaymentOptionName(paymentCheckoutData.paymentOption)}"; + orderBody['shipping_method'] = languageID == 'ar' + ? paymentCheckoutData.shippingOption.namen + : paymentCheckoutData.shippingOption.name; + orderBody['shipping_rate_computation_method_system_name'] = + paymentCheckoutData + .shippingOption.shippingRateComputationMethodSystemName; + orderBody['customer_id'] = int.parse(customerId); + orderBody['custom_values_xml'] = + "PaymentOption:${getPaymentOptionName(paymentCheckoutData.paymentOption)}"; orderBody['shippingOption'] = paymentCheckoutData.shippingOption; orderBody['shipping_address'] = paymentCheckoutData.address; orderBody['lakum_amount'] = paymentCheckoutData.usedLakumPoints; @@ -213,12 +225,17 @@ class OrderPreviewService extends BaseService { body['order'] = orderBody; try { - await baseAppClient.post(ORDER_SHOPPING_CART, + await baseAppClient.pharmacyPost(ORDER_SHOPPING_CART, isExternal: false, isAllowAny: true, onSuccess: (response, statusCode) async { - }, onFailure: (String error, int statusCode) { - hasError = true; - super.error = error; - }, body: body); + orderList.clear(); + response['orders'].forEach((item) { + orderList.add(OrderDetailModel.fromJson(item)); + print(response); + }); + }, onFailure: (String error, int statusCode) { + hasError = true; + super.error = error; + }, body: body); } catch (error) { throw error; } @@ -245,4 +262,26 @@ class OrderPreviewService extends BaseService { return ""; } } + + Future getDriverLocation(dynamic driverId) async{ + Map jsonBody = Map(); + jsonBody['DriverID'] = driverId; + + LatLng coordinates; + await baseAppClient.post(DRIVER_LOCATION, + onSuccess: (response, statusCode) async { + if(statusCode == 200){ + dynamic locationObject = response['PatientER_GetDriverLocationList'][0]; + double lat = locationObject['Latitude']; + double lon = locationObject['Longitude']; + if(lat != null && lon != null){ + coordinates = LatLng(lat,lon); + } + } + }, onFailure: (String error, int statusCode) { + + }, body: jsonBody); + + return coordinates; + } } diff --git a/lib/core/service/parmacyModule/parmacy_module_service.dart b/lib/core/service/parmacyModule/parmacy_module_service.dart index 9d2b2f6b..7fa095ca 100644 --- a/lib/core/service/parmacyModule/parmacy_module_service.dart +++ b/lib/core/service/parmacyModule/parmacy_module_service.dart @@ -80,7 +80,7 @@ class PharmacyModuleService extends BaseService { }; hasError = false; try { - await baseAppClient.get(PHARMACY_AUTORZIE_CUSTOMER, + await baseAppClient.getPharmacy(PHARMACY_AUTORZIE_CUSTOMER, onSuccess: (dynamic response, int statusCode) async { if (response['Status'] == 200) { await sharedPref.setString( diff --git a/lib/core/service/pharmacy_categorise_service.dart b/lib/core/service/pharmacy_categorise_service.dart index 5ef3c1d1..58f58ddb 100644 --- a/lib/core/service/pharmacy_categorise_service.dart +++ b/lib/core/service/pharmacy_categorise_service.dart @@ -316,4 +316,50 @@ class PharmacyCategoriseService extends BaseService { }, ); } + + Future getMostViewedProducts() async { + Map queryParams = { + 'fields': + 'id,discount_ids,name,reviews,namen,localized_names,display_order,short_description,full_description,full_descriptionn,sku,order_minimum_quantity,order_maximum_quantity,price,old_price,images,is_rx,rx_message,rx_messagen,discount_name,discount_namen,approved_rating_sum,approved_total_reviews,allow_back_in_stock_subscriptions,stock_quantity,stock_availability,stock_availabilityn,discount_percentage', + }; + try { + await baseAppClient.getPharmacy(GET_MOST_VIEWED_PRODUCTS, + onSuccess: (dynamic response, int statusCode) { + _finalProducts.clear(); + response['products'].forEach((item) { + _finalProducts.add(PharmacyProduct.fromJson(item)); + }); + print("most viewed products ---------"); + print(response); + }, onFailure: (String error, int statusCode) { + hasError = true; + super.error = error; + }, queryParams: queryParams); + } catch (error) { + throw error; + } + } + + Future getNewProducts() async { + Map queryParams = { + 'fields': + 'Id,name,namen,localized_names,price,images,sku,stock_availability,published', + }; + try { + await baseAppClient.getPharmacy(GET_NEW_PRODUCTS, + onSuccess: (dynamic response, int statusCode) { + _finalProducts.clear(); + response['products'].forEach((item) { + _finalProducts.add(PharmacyProduct.fromJson(item)); + }); + print("new products ---------"); + print(response); + }, onFailure: (String error, int statusCode) { + hasError = true; + super.error = error; + }, queryParams: queryParams); + } catch (error) { + throw error; + } + } } diff --git a/lib/core/service/weather_service.dart b/lib/core/service/weather_service.dart index 10ab1adf..ea7d65bf 100644 --- a/lib/core/service/weather_service.dart +++ b/lib/core/service/weather_service.dart @@ -18,10 +18,9 @@ class WeatherService extends BaseService { var long = await sharedPref.getDouble(USER_LONG); body['Latitude'] = lat ?? 0; body['Longitude'] = long ?? 0; - + weatherIndicatorData = []; await baseAppClient.post(WEATHER_INDICATOR, onSuccess: (dynamic response, int statusCode) { - weatherIndicatorData = []; response['GetCityInfo_List'].forEach((data) { weatherIndicatorData.add(GetCityInfoList.fromJson(data)); }); diff --git a/lib/core/viewModels/AlHabibMedicalService/add_new_address_Request_Model.dart b/lib/core/viewModels/AlHabibMedicalService/add_new_address_Request_Model.dart index 5bde5a5f..23329a89 100644 --- a/lib/core/viewModels/AlHabibMedicalService/add_new_address_Request_Model.dart +++ b/lib/core/viewModels/AlHabibMedicalService/add_new_address_Request_Model.dart @@ -55,7 +55,7 @@ class Addresses { String firstName; String lastName; String email; - Null company; + dynamic company; int countryId; String country; Null stateProvinceId; @@ -64,7 +64,7 @@ class Addresses { String address2; String zipPostalCode; String phoneNumber; - Null faxNumber; + dynamic faxNumber; String customerAttributes; String createdOnUtc; Null province; diff --git a/lib/core/viewModels/AlHabibMedicalService/home_health_care_view_model.dart b/lib/core/viewModels/AlHabibMedicalService/home_health_care_view_model.dart index 5bab0df5..32644fd4 100644 --- a/lib/core/viewModels/AlHabibMedicalService/home_health_care_view_model.dart +++ b/lib/core/viewModels/AlHabibMedicalService/home_health_care_view_model.dart @@ -40,6 +40,8 @@ class HomeHealthCareViewModel extends BaseViewModel { PharmacyModuleService _pharmacyModuleService = locator(); + + bool get isOrderUpdated => _homeHealthCareService.isOrderUpdated; GetHHCAllPresOrdersResponseModel pendingOrder; @@ -136,9 +138,13 @@ class HomeHealthCareViewModel extends BaseViewModel { {AddNewAddressRequestModel addNewAddressRequestModel}) async { setState(ViewState.Busy); - await _customerAddressesService.addAddressInfo( - addNewAddressRequestModel: addNewAddressRequestModel - ); + + await _pharmacyModuleService.generatePharmacyToken().then((value) async{ + await _customerAddressesService.addAddressInfo( + addNewAddressRequestModel: addNewAddressRequestModel + ); + }); + if (_customerAddressesService.hasError) { error = _customerAddressesService.error; setState(ViewState.ErrorLocal); diff --git a/lib/core/viewModels/ancillary_orders_view_model.dart b/lib/core/viewModels/ancillary_orders_view_model.dart index 2d92a402..77eb4237 100644 --- a/lib/core/viewModels/ancillary_orders_view_model.dart +++ b/lib/core/viewModels/ancillary_orders_view_model.dart @@ -1,4 +1,6 @@ import 'package:diplomaticquarterapp/core/service/ancillary_orders_service.dart'; +import 'package:diplomaticquarterapp/models/anicllary-orders/ancillary_order_list_model.dart'; +import 'package:diplomaticquarterapp/models/anicllary-orders/ancillary_order_proc_model.dart'; import 'base_view_model.dart'; import '../../locator.dart'; @@ -8,7 +10,10 @@ class AnciallryOrdersViewModel extends BaseViewModel { bool hasError = false; AncillaryOrdersService _ancillaryService = locator(); - + List get ancillaryLists => + _ancillaryService.ancillaryLists; + List get ancillaryListsDetails => + _ancillaryService.ancillaryProcLists; Future getOrders() async { hasError = false; setState(ViewState.Busy); @@ -19,4 +24,15 @@ class AnciallryOrdersViewModel extends BaseViewModel { } else setState(ViewState.Idle); } + + Future getOrdersDetails(appointmentNo, orderNo) async { + hasError = false; + setState(ViewState.Busy); + await _ancillaryService.getOrdersDetails(appointmentNo, orderNo); + if (_ancillaryService.hasError) { + error = _ancillaryService.error; + setState(ViewState.ErrorLocal); + } else + setState(ViewState.Idle); + } } diff --git a/lib/core/viewModels/medical/EyeViewModel.dart b/lib/core/viewModels/medical/EyeViewModel.dart index d6c3bf80..ab76b94f 100644 --- a/lib/core/viewModels/medical/EyeViewModel.dart +++ b/lib/core/viewModels/medical/EyeViewModel.dart @@ -43,4 +43,34 @@ class EyeViewModel extends BaseViewModel { setState(ViewState.Idle); } } + + sendGlassesPrescriptionEmail({int appointmentNo, String projectName, int projectID}) async { + setState(ViewState.Busy); + await _eyeService.sendGlassesPrescriptionEmail( + appointmentNo: appointmentNo, + projectID: projectID, + projectName: projectName); + if (_eyeService.hasError) { + error = _eyeService.error; + setState(ViewState.Error); + } else { + setState(ViewState.Idle); + } + } + + sendContactLensPrescriptionEmail({int appointmentNo, String projectName, int projectID}) async { + setState(ViewState.Busy); + await _eyeService.sendContactLensPrescriptionEmail( + appointmentNo: appointmentNo, + projectID: projectID, + projectName: projectName); + if (_eyeService.hasError) { + error = _eyeService.error; + setState(ViewState.Error); + } else { + setState(ViewState.Idle); + } + } + + } diff --git a/lib/core/viewModels/packages_offers/PackagesOffersViewModel.dart b/lib/core/viewModels/packages_offers/PackagesOffersViewModel.dart index 21df52bc..1029ed4d 100644 --- a/lib/core/viewModels/packages_offers/PackagesOffersViewModel.dart +++ b/lib/core/viewModels/packages_offers/PackagesOffersViewModel.dart @@ -1,6 +1,7 @@ import 'package:diplomaticquarterapp/core/enum/viewstate.dart'; -import 'package:diplomaticquarterapp/core/model/packages_offers/responses/OfferCategoriesResponseModel.dart'; -import 'package:diplomaticquarterapp/core/model/packages_offers/responses/OfferProductsResponseModel.dart'; +import 'package:diplomaticquarterapp/core/model/packages_offers/responses/PackagesCartItemsResponseModel.dart'; +import 'package:diplomaticquarterapp/core/model/packages_offers/responses/PackagesCategoriesResponseModel.dart'; +import 'package:diplomaticquarterapp/core/model/packages_offers/responses/PackagesResponseModel.dart'; import 'package:diplomaticquarterapp/core/service/base_service.dart'; import 'package:diplomaticquarterapp/core/service/client/base_app_client.dart'; import 'package:diplomaticquarterapp/core/service/packages_offers/PackagesOffersServices.dart'; @@ -8,12 +9,29 @@ import 'package:diplomaticquarterapp/core/viewModels/base_view_model.dart'; import 'package:flutter/cupertino.dart'; import 'package:diplomaticquarterapp/locator.dart'; -class OfferCategoriesViewModel extends BaseViewModel { +class OfferCategoriesViewModel extends BaseViewModel{ OffersAndPackagesServices service = locator(); - List get list => service.categoryList; + get categoryList => service.categoryList; + get productList => service.categoryList; + } -class OfferProductsViewModel extends BaseViewModel { +class PackagesViewModel extends BaseViewModel { OffersAndPackagesServices service = locator(); - List get list => service.productList; + List get categoryList => service.categoryList; + List get productList => service.productList; + List get latestOffersList => service.latestOffersList; + List get bestSellerList => service.bestSellerList; + List get bannersList => service.bannersList; + List get cartItemList => service.cartItemList; + + + String _cartItemCount = ""; + + String get cartItemCount => _cartItemCount; + + set cartItemCount(String value) { + _cartItemCount = value; + notifyListeners(); + } } diff --git a/lib/core/viewModels/pharmacyModule/OrderPreviewViewModel.dart b/lib/core/viewModels/pharmacyModule/OrderPreviewViewModel.dart index 7272969b..1fa34ee2 100644 --- a/lib/core/viewModels/pharmacyModule/OrderPreviewViewModel.dart +++ b/lib/core/viewModels/pharmacyModule/OrderPreviewViewModel.dart @@ -5,8 +5,10 @@ import 'package:diplomaticquarterapp/core/model/pharmacies/LacumAccountInformati import 'package:diplomaticquarterapp/core/model/pharmacies/ShippingOption.dart'; import 'package:diplomaticquarterapp/core/model/pharmacies/ShoppingCart.dart'; import 'package:diplomaticquarterapp/core/model/pharmacies/ShoppingCartResponse.dart'; +import 'package:diplomaticquarterapp/core/model/pharmacies/order_detail.dart'; import 'package:diplomaticquarterapp/core/model/pharmacies/payment-checkout-data.dart'; import 'package:diplomaticquarterapp/core/service/parmacyModule/order-preview-service.dart'; +import 'package:diplomaticquarterapp/core/viewModels/pharmacyModule/pharmacy_module_view_model.dart'; import '../../../locator.dart'; import '../base_view_model.dart'; @@ -17,6 +19,11 @@ class OrderPreviewViewModel extends BaseViewModel { List get addresses => _orderService.addresses; LacumAccountInformation get lacumInformation => _orderService.lacumInformation; + List get orderListModel => _orderService.orderList; + + PharmacyModuleViewModel pharmacyModuleViewModel = + locator(); + ShoppingCartResponse cartResponse = ShoppingCartResponse(); PaymentCheckoutData paymentCheckoutData = PaymentCheckoutData(); double totalAdditionalShippingCharge = 0; @@ -32,7 +39,7 @@ class OrderPreviewViewModel extends BaseViewModel { } } - getShoppingCart() async { + Future getShoppingCart() async { setState(ViewState.Busy); await _orderService.getShoppingCart().then((res) { _handleGetShoppingCartResponse(res); @@ -48,20 +55,20 @@ class OrderPreviewViewModel extends BaseViewModel { } } - changeProductQuantity(ShoppingCart product) async { + Future changeProductQuantity(ShoppingCart product) async { setState(ViewState.Busy); await _orderService.changeProductQuantity(product.id, product).then((res) { _handleGetShoppingCartResponse(res); }); if (_orderService.hasError) { error = _orderService.error; - setState(ViewState.Error); + setState(ViewState.ErrorLocal); } else { setState(ViewState.Idle); } } - deleteProduct(ShoppingCart product) async { + Future deleteProduct(ShoppingCart product) async { setState(ViewState.Busy); await _orderService.deleteProduct(product.id).then((res) { _handleGetShoppingCartResponse(res); @@ -74,7 +81,7 @@ class OrderPreviewViewModel extends BaseViewModel { } } - deleteShoppingCart() async { + Future deleteShoppingCart() async { setState(ViewState.Busy); await _orderService.deleteShoppingCart().then((res) { _handleGetShoppingCartResponse(res); @@ -182,6 +189,8 @@ class OrderPreviewViewModel extends BaseViewModel { Future makeOrder() async { setState(ViewState.Busy); + await pharmacyModuleViewModel.generatePharmacyToken(); + await _orderService.makeOrder(paymentCheckoutData, cartResponse.shoppingCarts); if (_orderService.hasError) { error = _orderService.error; diff --git a/lib/core/viewModels/pharmacyModule/order_model_view_model.dart b/lib/core/viewModels/pharmacyModule/order_model_view_model.dart index 62bf00f4..5b1c67f2 100644 --- a/lib/core/viewModels/pharmacyModule/order_model_view_model.dart +++ b/lib/core/viewModels/pharmacyModule/order_model_view_model.dart @@ -49,7 +49,7 @@ class OrderModelViewModel extends BaseViewModel { } } - Future getOrderDetails(OrderId) async { + Future getOrderDetails(OrderId) async { setState(ViewState.Busy); await _orderDetailsService.getOrderDetails(OrderId); if (_orderDetailsService.hasError) { @@ -58,6 +58,7 @@ class OrderModelViewModel extends BaseViewModel { } else { setState(ViewState.Idle); } + return _orderDetailsService.orderList.first; } Future getProductReview() async { @@ -110,15 +111,16 @@ class OrderModelViewModel extends BaseViewModel { message: "Your review has been Submitted successfully"); } } + Future makeOrder() async { - setState(ViewState.Busy); + /* setState(ViewState.Busy); await _orderServices.makeOrder(paymentCheckoutData, cartResponse.shoppingCarts); if (_orderServices.hasError) { error = _orderServices.error; setState(ViewState.Error); } else { setState(ViewState.Idle); - } + }*/ } } diff --git a/lib/core/viewModels/pharmacyModule/pharmacy_module_view_model.dart b/lib/core/viewModels/pharmacyModule/pharmacy_module_view_model.dart index f38237e3..833735bb 100644 --- a/lib/core/viewModels/pharmacyModule/pharmacy_module_view_model.dart +++ b/lib/core/viewModels/pharmacyModule/pharmacy_module_view_model.dart @@ -44,13 +44,15 @@ class PharmacyModuleViewModel extends BaseViewModel { // List get pharmacyPrescriptionsList => PharmacyProduct.pharmacyPrescriptionsList ; Future getPharmacyHomeData() async { - setState(ViewState.Busy); + if(authenticatedUserObject.isLogin) + await generatePharmacyToken(); + var data = await sharedPref.getObject(USER_PROFILE); var customerId = await sharedPref.getString(PHARMACY_CUSTOMER_ID); + setState(ViewState.Busy); if (authenticatedUserObject.isLogin && data != null && customerId == null) { await _pharmacyService.makeVerifyCustomer(data); - // here must call getShoppingCard() if (_pharmacyService.hasError) { error = _pharmacyService.error; setState(ViewState.Error); diff --git a/lib/core/viewModels/pharmacy_categorise_view_model.dart b/lib/core/viewModels/pharmacy_categorise_view_model.dart index 47f64688..e48329ba 100644 --- a/lib/core/viewModels/pharmacy_categorise_view_model.dart +++ b/lib/core/viewModels/pharmacy_categorise_view_model.dart @@ -203,4 +203,26 @@ class PharmacyCategoriseViewModel extends BaseViewModel { setState(ViewState.Idle); } } + + Future getMostViewedProducts() async { + setState(ViewState.Busy); + await _pharmacyCategoriseService.getMostViewedProducts(); + if (_pharmacyCategoriseService.hasError) { + error = _pharmacyCategoriseService.error; + setState(ViewState.Error); + } else { + setState(ViewState.Idle); + } + } + + Future getNewProducts() async { + setState(ViewState.Busy); + await _pharmacyCategoriseService.getNewProducts(); + if (_pharmacyCategoriseService.hasError) { + error = _pharmacyCategoriseService.error; + setState(ViewState.Error); + } else { + setState(ViewState.Idle); + } + } } diff --git a/lib/generated/json/OfferCategoriesResponseModel_helper.dart b/lib/generated/json/OfferCategoriesResponseModel_helper.dart index e5ebc914..1a28d179 100644 --- a/lib/generated/json/OfferCategoriesResponseModel_helper.dart +++ b/lib/generated/json/OfferCategoriesResponseModel_helper.dart @@ -1,8 +1,8 @@ -import 'package:diplomaticquarterapp/core/model/packages_offers/responses/OfferCategoriesResponseModel.dart'; +import 'package:diplomaticquarterapp/core/model/packages_offers/responses/PackagesCategoriesResponseModel.dart'; -offerCategoriesResponseModelFromJson(OfferCategoriesResponseModel data, Map json) { +offerCategoriesResponseModelFromJson(PackagesCategoriesResponseModel data, Map json) { if (json['id'] != null) { - data.id = json['id']?.toString(); + data.id = json['id']; } if (json['name'] != null) { data.name = json['name']?.toString(); @@ -91,7 +91,7 @@ offerCategoriesResponseModelFromJson(OfferCategoriesResponseModel data, Map offerCategoriesResponseModelToJson(OfferCategoriesResponseModel entity) { +Map offerCategoriesResponseModelToJson(PackagesCategoriesResponseModel entity) { final Map data = new Map(); data['id'] = entity.id; data['name'] = entity.name; diff --git a/lib/generated/json/OfferProductsResponseModel_helper.dart b/lib/generated/json/OfferProductsResponseModel_helper.dart index dc0edeca..d180af67 100644 --- a/lib/generated/json/OfferProductsResponseModel_helper.dart +++ b/lib/generated/json/OfferProductsResponseModel_helper.dart @@ -1,8 +1,8 @@ -import 'package:diplomaticquarterapp/core/model/packages_offers/responses/OfferProductsResponseModel.dart'; +import 'package:diplomaticquarterapp/core/model/packages_offers/responses/PackagesResponseModel.dart'; -offerProductsResponseModelFromJson(OfferProductsResponseModel data, Map json) { +offerProductsResponseModelFromJson(PackagesResponseModel data, Map json) { if (json['id'] != null) { - data.id = json['id']?.toString(); + data.id = json['id']; } if (json['visible_individually'] != null) { data.visibleIndividually = json['visible_individually']; @@ -353,7 +353,7 @@ offerProductsResponseModelFromJson(OfferProductsResponseModel data, Map offerProductsResponseModelToJson(OfferProductsResponseModel entity) { +Map offerProductsResponseModelToJson(PackagesResponseModel entity) { final Map data = new Map(); data['id'] = entity.id; data['visible_individually'] = entity.visibleIndividually; diff --git a/lib/generated/json/base/json_convert_content.dart b/lib/generated/json/base/json_convert_content.dart index 9fab946e..ae4eadeb 100644 --- a/lib/generated/json/base/json_convert_content.dart +++ b/lib/generated/json/base/json_convert_content.dart @@ -3,11 +3,11 @@ // ignore_for_file: prefer_single_quotes // This file is automatically generated. DO NOT EDIT, all your changes would be lost. -import 'package:diplomaticquarterapp/core/model/packages_offers/responses/OfferCategoriesResponseModel.dart'; +import 'package:diplomaticquarterapp/core/model/packages_offers/responses/PackagesCategoriesResponseModel.dart'; import 'package:diplomaticquarterapp/generated/json/OfferCategoriesResponseModel_helper.dart'; import 'package:diplomaticquarterapp/core/model/geofencing/responses/LogGeoZoneResponseModel.dart'; import 'package:diplomaticquarterapp/generated/json/log_geo_zone_response_model_entity_helper.dart'; -import 'package:diplomaticquarterapp/core/model/packages_offers/responses/OfferProductsResponseModel.dart'; +import 'package:diplomaticquarterapp/core/model/packages_offers/responses/PackagesResponseModel.dart'; import 'package:diplomaticquarterapp/generated/json/OfferProductsResponseModel_helper.dart'; import 'package:diplomaticquarterapp/core/model/geofencing/responses/GeoZonesResponseModel.dart'; import 'package:diplomaticquarterapp/generated/json/GeoZonesResponseModel_helper.dart'; @@ -23,16 +23,16 @@ class JsonConvert { static _getFromJson(Type type, data, json) { switch (type) { - case OfferCategoriesResponseModel: - return offerCategoriesResponseModelFromJson(data as OfferCategoriesResponseModel, json) as T; + case PackagesCategoriesResponseModel: + return offerCategoriesResponseModelFromJson(data as PackagesCategoriesResponseModel, json) as T; case OfferCategoriesResponseModelLocalizedName: return offerCategoriesResponseModelLocalizedNameFromJson(data as OfferCategoriesResponseModelLocalizedName, json) as T; case OfferCategoriesResponseModelImage: return offerCategoriesResponseModelImageFromJson(data as OfferCategoriesResponseModelImage, json) as T; case LogGeoZoneResponseModel: return logGeoZoneResponseModelEntityFromJson(data as LogGeoZoneResponseModel, json) as T; - case OfferProductsResponseModel: - return offerProductsResponseModelFromJson(data as OfferProductsResponseModel, json) as T; + case PackagesResponseModel: + return offerProductsResponseModelFromJson(data as PackagesResponseModel, json) as T; case OfferProductsResponseModelLocalizedName: return offerProductsResponseModelLocalizedNameFromJson(data as OfferProductsResponseModelLocalizedName, json) as T; case OfferProductsResponseModelImage: @@ -47,16 +47,16 @@ class JsonConvert { static _getToJson(Type type, data) { switch (type) { - case OfferCategoriesResponseModel: - return offerCategoriesResponseModelToJson(data as OfferCategoriesResponseModel); + case PackagesCategoriesResponseModel: + return offerCategoriesResponseModelToJson(data as PackagesCategoriesResponseModel); case OfferCategoriesResponseModelLocalizedName: return offerCategoriesResponseModelLocalizedNameToJson(data as OfferCategoriesResponseModelLocalizedName); case OfferCategoriesResponseModelImage: return offerCategoriesResponseModelImageToJson(data as OfferCategoriesResponseModelImage); case LogGeoZoneResponseModel: return logGeoZoneResponseModelEntityToJson(data as LogGeoZoneResponseModel); - case OfferProductsResponseModel: - return offerProductsResponseModelToJson(data as OfferProductsResponseModel); + case PackagesResponseModel: + return offerProductsResponseModelToJson(data as PackagesResponseModel); case OfferProductsResponseModelLocalizedName: return offerProductsResponseModelLocalizedNameToJson(data as OfferProductsResponseModelLocalizedName); case OfferProductsResponseModelImage: @@ -72,16 +72,16 @@ class JsonConvert { //Go back to a single instance by type static _fromJsonSingle(json) { String type = M.toString(); - if (type == (OfferCategoriesResponseModel).toString()) { - return OfferCategoriesResponseModel().fromJson(json); + if (type == (PackagesCategoriesResponseModel).toString()) { + return PackagesCategoriesResponseModel().fromJson(json); } else if (type == (OfferCategoriesResponseModelLocalizedName).toString()) { return OfferCategoriesResponseModelLocalizedName().fromJson(json); } else if (type == (OfferCategoriesResponseModelImage).toString()) { return OfferCategoriesResponseModelImage().fromJson(json); } else if (type == (LogGeoZoneResponseModel).toString()) { return LogGeoZoneResponseModel().fromJson(json); - } else if (type == (OfferProductsResponseModel).toString()) { - return OfferProductsResponseModel().fromJson(json); + } else if (type == (PackagesResponseModel).toString()) { + return PackagesResponseModel().fromJson(json); } else if (type == (OfferProductsResponseModelLocalizedName).toString()) { return OfferProductsResponseModelLocalizedName().fromJson(json); } else if (type == (OfferProductsResponseModelImage).toString()) { @@ -96,16 +96,16 @@ class JsonConvert { //list is returned by type static M _getListChildType(List data) { - if (List() is M) { - return data.map((e) => OfferCategoriesResponseModel().fromJson(e)).toList() as M; + if (List() is M) { + return data.map((e) => PackagesCategoriesResponseModel().fromJson(e)).toList() as M; } else if (List() is M) { return data.map((e) => OfferCategoriesResponseModelLocalizedName().fromJson(e)).toList() as M; } else if (List() is M) { return data.map((e) => OfferCategoriesResponseModelImage().fromJson(e)).toList() as M; } else if (List() is M) { return data.map((e) => LogGeoZoneResponseModel().fromJson(e)).toList() as M; - } else if (List() is M) { - return data.map((e) => OfferProductsResponseModel().fromJson(e)).toList() as M; + } else if (List() is M) { + return data.map((e) => PackagesResponseModel().fromJson(e)).toList() as M; } else if (List() is M) { return data.map((e) => OfferProductsResponseModelLocalizedName().fromJson(e)).toList() as M; } else if (List() is M) { diff --git a/lib/locator.dart b/lib/locator.dart index 39c828ad..1acaf1af 100644 --- a/lib/locator.dart +++ b/lib/locator.dart @@ -1,7 +1,9 @@ import 'package:diplomaticquarterapp/core/service/AlHabibMedicalService/H2O_service.dart'; +import 'package:diplomaticquarterapp/core/service/ancillary_orders_service.dart'; import 'package:diplomaticquarterapp/core/service/parmacyModule/prescription_service.dart'; import 'package:diplomaticquarterapp/core/service/qr_service.dart'; import 'package:diplomaticquarterapp/core/viewModels/AlHabibMedicalService/H2O_view_model.dart'; +import 'package:diplomaticquarterapp/core/viewModels/ancillary_orders_view_model.dart'; import 'package:diplomaticquarterapp/core/viewModels/child_vaccines/user_information_view_model.dart'; import 'package:diplomaticquarterapp/core/viewModels/AlHabibMedicalService/home_health_care_view_model.dart'; import 'package:diplomaticquarterapp/core/viewModels/dashboard_view_model.dart'; @@ -194,6 +196,7 @@ void setupLocator() { locator.registerLazySingleton(() => DeleteBabyService()); locator.registerLazySingleton(() => VaccinationTableService()); + locator.registerLazySingleton(() => AncillaryOrdersService()); locator.registerLazySingleton(() => EdOnlineServices()); //pharmacy @@ -223,7 +226,6 @@ void setupLocator() { locator.registerLazySingleton(() => PrescriptionService()); locator.registerLazySingleton(() => RecommendedProductService()); - locator.registerLazySingleton(() => PrivilegeService()); locator.registerLazySingleton(() => WeatherService()); locator.registerLazySingleton(() => TermsConditionsService()); @@ -298,12 +300,9 @@ void setupLocator() { // Offer And Packages //---------------------- - locator.registerLazySingleton( - () => OffersAndPackagesServices()); // offerPackagesServices Service - locator.registerFactory( - () => OfferCategoriesViewModel()); // Categories View Model - locator - .registerFactory(() => OfferProductsViewModel()); // Products View Model + locator.registerLazySingleton(() => OffersAndPackagesServices()); // offerPackagesServices Service + locator.registerFactory(() => OfferCategoriesViewModel()); // Categories View Model + locator.registerFactory(() => PackagesViewModel()); // Products View Model //pharmacy // locator.registerFactory(() => PharmacyCategoriseViewModel()); @@ -313,4 +312,5 @@ void setupLocator() { locator.registerLazySingleton( () => GeofencingServices()); // Geofencing Services locator.registerFactory(() => TermsConditionsViewModel()); + locator.registerFactory(() => AnciallryOrdersViewModel()); } diff --git a/lib/main.dart b/lib/main.dart index 4a07edba..2412e4d1 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -7,6 +7,7 @@ import 'package:diplomaticquarterapp/theme/theme_value.dart'; import 'package:diplomaticquarterapp/uitl/HMG_Geofence.dart'; import 'package:diplomaticquarterapp/uitl/LocalNotification.dart'; import 'package:diplomaticquarterapp/uitl/PlatformBridge.dart'; +import 'package:diplomaticquarterapp/uitl/app_shared_preferences.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; @@ -15,6 +16,7 @@ import 'package:hexcolor/hexcolor.dart'; import 'package:provider/provider.dart'; import 'Constants.dart'; +import 'config/shared_pref_kay.dart'; import 'config/size_config.dart'; import 'core/model/geofencing/requests/GeoZonesRequestModel.dart'; import 'core/service/geofencing/GeofencingServices.dart'; @@ -34,7 +36,7 @@ class MyApp extends StatefulWidget { class _MyApp extends State { @override - void initState() { + void initState(){ // ProjectViewModel projectProvider; // projectProvider = Provider.of(context); // var font = projectProvider.isArabic ? 'Cairo' : 'WorkSans'; @@ -70,7 +72,10 @@ class _MyApp extends State { value: SearchProvider(), ), ChangeNotifierProvider( - create: (context) => ThemeNotifier(defaultTheme())), + create: (context) => ThemeNotifier( + defaultTheme() + ) + ), StreamProvider.value( value: RobotProvider().intStream(), initialData: RobotProvider().setValue({}), @@ -138,6 +143,8 @@ class _MyApp extends State { // ), // ), initialRoute: SPLASH, + // initialRoute: PACKAGES_OFFERS, + // initialRoute: PACKAGES_ORDER_COMPLETED, routes: routes, debugShowCheckedModeBanner: false, ), diff --git a/lib/models/anicllary-orders/ancillary_order_proc_model.dart b/lib/models/anicllary-orders/ancillary_order_proc_model.dart new file mode 100644 index 00000000..7322d11a --- /dev/null +++ b/lib/models/anicllary-orders/ancillary_order_proc_model.dart @@ -0,0 +1,249 @@ +class AncillaryOrdersListProcListModel { + List ancillaryOrderProcList; + String appointmentDate; + dynamic appointmentNo; + dynamic clinicID; + String clinicName; + dynamic companyID; + String companyName; + dynamic doctorID; + String doctorName; + Null errCode; + dynamic groupID; + String insurancePolicyNo; + String message; + String patientCardID; + dynamic patientID; + String patientName; + dynamic patientType; + dynamic policyID; + String policyName; + dynamic projectID; + String setupID; + dynamic statusCode; + dynamic subCategoryID; + String subPolicyNo; + + AncillaryOrdersListProcListModel( + {this.ancillaryOrderProcList, + this.appointmentDate, + this.appointmentNo, + this.clinicID, + this.clinicName, + this.companyID, + this.companyName, + this.doctorID, + this.doctorName, + this.errCode, + this.groupID, + this.insurancePolicyNo, + this.message, + this.patientCardID, + this.patientID, + this.patientName, + this.patientType, + this.policyID, + this.policyName, + this.projectID, + this.setupID, + this.statusCode, + this.subCategoryID, + this.subPolicyNo}); + + AncillaryOrdersListProcListModel.fromJson(Map json) { + if (json['AncillaryOrderProcList'] != null) { + ancillaryOrderProcList = new List(); + json['AncillaryOrderProcList'].forEach((v) { + ancillaryOrderProcList.add(new AncillaryOrderProcList.fromJson(v)); + }); + } + appointmentDate = json['AppointmentDate']; + appointmentNo = json['AppointmentNo']; + clinicID = json['ClinicID']; + clinicName = json['ClinicName']; + companyID = json['CompanyID']; + companyName = json['CompanyName']; + doctorID = json['DoctorID']; + doctorName = json['DoctorName']; + errCode = json['ErrCode']; + groupID = json['GroupID']; + insurancePolicyNo = json['InsurancePolicyNo']; + message = json['Message']; + patientCardID = json['PatientCardID']; + patientID = json['PatientID']; + patientName = json['PatientName']; + patientType = json['PatientType']; + policyID = json['PolicyID']; + policyName = json['PolicyName']; + projectID = json['ProjectID']; + setupID = json['SetupID']; + statusCode = json['StatusCode']; + subCategoryID = json['SubCategoryID']; + subPolicyNo = json['SubPolicyNo']; + } + + Map toJson() { + final Map data = new Map(); + if (this.ancillaryOrderProcList != null) { + data['AncillaryOrderProcList'] = + this.ancillaryOrderProcList.map((v) => v.toJson()).toList(); + } + data['AppointmentDate'] = this.appointmentDate; + data['AppointmentNo'] = this.appointmentNo; + data['ClinicID'] = this.clinicID; + data['ClinicName'] = this.clinicName; + data['CompanyID'] = this.companyID; + data['CompanyName'] = this.companyName; + data['DoctorID'] = this.doctorID; + data['DoctorName'] = this.doctorName; + data['ErrCode'] = this.errCode; + data['GroupID'] = this.groupID; + data['InsurancePolicyNo'] = this.insurancePolicyNo; + data['Message'] = this.message; + data['PatientCardID'] = this.patientCardID; + data['PatientID'] = this.patientID; + data['PatientName'] = this.patientName; + data['PatientType'] = this.patientType; + data['PolicyID'] = this.policyID; + data['PolicyName'] = this.policyName; + data['ProjectID'] = this.projectID; + data['SetupID'] = this.setupID; + data['StatusCode'] = this.statusCode; + data['SubCategoryID'] = this.subCategoryID; + data['SubPolicyNo'] = this.subPolicyNo; + return data; + } +} + +class AncillaryOrderProcList { + dynamic approvalLineItemNo; + dynamic approvalNo; + String approvalStatus; + dynamic approvalStatusID; + dynamic companyShare; + dynamic companyShareWithTax; + dynamic companyTaxAmount; + dynamic discountAmount; + dynamic discountCategory; + String discountType; + dynamic discountTypeValue; + bool isApprovalCreated; + bool isApprovalRequired; + bool isCovered; + String orderDate; + dynamic orderLineItemNo; + dynamic orderNo; + dynamic partnerID; + dynamic partnerShare; + String partnerShareType; + dynamic patientShare; + dynamic patientShareWithTax; + dynamic patientTaxAmount; + dynamic procPrice; + dynamic procedureCategoryID; + String procedureCategoryName; + String procedureID; + String procedureName; + dynamic taxAmount; + dynamic taxPct; + + AncillaryOrderProcList( + {this.approvalLineItemNo, + this.approvalNo, + this.approvalStatus, + this.approvalStatusID, + this.companyShare, + this.companyShareWithTax, + this.companyTaxAmount, + this.discountAmount, + this.discountCategory, + this.discountType, + this.discountTypeValue, + this.isApprovalCreated, + this.isApprovalRequired, + this.isCovered, + this.orderDate, + this.orderLineItemNo, + this.orderNo, + this.partnerID, + this.partnerShare, + this.partnerShareType, + this.patientShare, + this.patientShareWithTax, + this.patientTaxAmount, + this.procPrice, + this.procedureCategoryID, + this.procedureCategoryName, + this.procedureID, + this.procedureName, + this.taxAmount, + this.taxPct}); + + AncillaryOrderProcList.fromJson(Map json) { + approvalLineItemNo = json['ApprovalLineItemNo']; + approvalNo = json['ApprovalNo']; + approvalStatus = json['ApprovalStatus']; + approvalStatusID = json['ApprovalStatusID']; + companyShare = json['CompanyShare']; + companyShareWithTax = json['CompanyShareWithTax']; + companyTaxAmount = json['CompanyTaxAmount']; + discountAmount = json['DiscountAmount']; + discountCategory = json['DiscountCategory']; + discountType = json['DiscountType']; + discountTypeValue = json['DiscountTypeValue']; + isApprovalCreated = json['IsApprovalCreated']; + isApprovalRequired = json['IsApprovalRequired']; + isCovered = json['IsCovered']; + orderDate = json['OrderDate']; + orderLineItemNo = json['OrderLineItemNo']; + orderNo = json['OrderNo']; + partnerID = json['PartnerID']; + partnerShare = json['PartnerShare']; + partnerShareType = json['PartnerShareType']; + patientShare = json['PatientShare']; + patientShareWithTax = json['PatientShareWithTax']; + patientTaxAmount = json['PatientTaxAmount']; + procPrice = json['ProcPrice']; + procedureCategoryID = json['ProcedureCategoryID']; + procedureCategoryName = json['ProcedureCategoryName']; + procedureID = json['ProcedureID']; + procedureName = json['ProcedureName']; + taxAmount = json['TaxAmount']; + taxPct = json['TaxPct']; + } + + Map toJson() { + final Map data = new Map(); + data['ApprovalLineItemNo'] = this.approvalLineItemNo; + data['ApprovalNo'] = this.approvalNo; + data['ApprovalStatus'] = this.approvalStatus; + data['ApprovalStatusID'] = this.approvalStatusID; + data['CompanyShare'] = this.companyShare; + data['CompanyShareWithTax'] = this.companyShareWithTax; + data['CompanyTaxAmount'] = this.companyTaxAmount; + data['DiscountAmount'] = this.discountAmount; + data['DiscountCategory'] = this.discountCategory; + data['DiscountType'] = this.discountType; + data['DiscountTypeValue'] = this.discountTypeValue; + data['IsApprovalCreated'] = this.isApprovalCreated; + data['IsApprovalRequired'] = this.isApprovalRequired; + data['IsCovered'] = this.isCovered; + data['OrderDate'] = this.orderDate; + data['OrderLineItemNo'] = this.orderLineItemNo; + data['OrderNo'] = this.orderNo; + data['PartnerID'] = this.partnerID; + data['PartnerShare'] = this.partnerShare; + data['PartnerShareType'] = this.partnerShareType; + data['PatientShare'] = this.patientShare; + data['PatientShareWithTax'] = this.patientShareWithTax; + data['PatientTaxAmount'] = this.patientTaxAmount; + data['ProcPrice'] = this.procPrice; + data['ProcedureCategoryID'] = this.procedureCategoryID; + data['ProcedureCategoryName'] = this.procedureCategoryName; + data['ProcedureID'] = this.procedureID; + data['ProcedureName'] = this.procedureName; + data['TaxAmount'] = this.taxAmount; + data['TaxPct'] = this.taxPct; + return data; + } +} diff --git a/lib/pages/AlHabibMedicalService/HomeHealthCare/NewHomeHealthCare/location_page.dart b/lib/pages/AlHabibMedicalService/HomeHealthCare/NewHomeHealthCare/location_page.dart index 4bf3a762..c87a3eb5 100644 --- a/lib/pages/AlHabibMedicalService/HomeHealthCare/NewHomeHealthCare/location_page.dart +++ b/lib/pages/AlHabibMedicalService/HomeHealthCare/NewHomeHealthCare/location_page.dart @@ -49,6 +49,7 @@ class _LocationPageState return BaseView( onModelReady: (model) {}, builder: (_, model, widget) => AppScaffold( + appBarTitle: TranslationBase.of(context).addAddress, isShowDecPage: false, isShowAppBar: true, baseViewModel: model, @@ -121,6 +122,7 @@ class _LocationPageState } }); + await model.addAddressInfo( addNewAddressRequestModel: addNewAddressRequestModel); if (model.state == ViewState.ErrorLocal) { @@ -129,7 +131,7 @@ class _LocationPageState AppToast.showSuccessToast( message: "Address Added Successfully"); } - Navigator.of(context).pop(); + Navigator.of(context).pop(addNewAddressRequestModel); }, label: TranslationBase.of(context).addNewAddress, ), diff --git a/lib/pages/AlHabibMedicalService/all_habib_medical_service_page.dart b/lib/pages/AlHabibMedicalService/all_habib_medical_service_page.dart index fe8f73f6..877f9fb7 100644 --- a/lib/pages/AlHabibMedicalService/all_habib_medical_service_page.dart +++ b/lib/pages/AlHabibMedicalService/all_habib_medical_service_page.dart @@ -5,6 +5,7 @@ import 'package:diplomaticquarterapp/models/Authentication/authenticated_user.da import 'package:diplomaticquarterapp/pages/AlHabibMedicalService/%E2%80%8B%20health_calculators.dart'; import 'package:diplomaticquarterapp/pages/AlHabibMedicalService/E-Referral/e_referral_index_page.dart'; import 'package:diplomaticquarterapp/pages/AlHabibMedicalService/E-Referral/e_referral_page.dart'; +import 'package:diplomaticquarterapp/pages/AlHabibMedicalService/ancillary-orders/ancillaryOrders.dart'; import 'package:diplomaticquarterapp/pages/AlHabibMedicalService/h2o/h2o_index_page.dart'; import 'package:diplomaticquarterapp/pages/AlHabibMedicalService/health-weather/health-weather-indicator.dart'; import 'package:diplomaticquarterapp/pages/AlHabibMedicalService/health_converter.dart'; @@ -203,7 +204,7 @@ class _AllHabibMedicalServiceState extends State { onTap: () => Navigator.push( context, FadePage( - page: PaymentService(), + page: AnicllaryOrders(), ), ), imageLocation: diff --git a/lib/pages/AlHabibMedicalService/ancillary-orders/ancillaryOrders.dart b/lib/pages/AlHabibMedicalService/ancillary-orders/ancillaryOrders.dart index 57b134bf..eccc1309 100644 --- a/lib/pages/AlHabibMedicalService/ancillary-orders/ancillaryOrders.dart +++ b/lib/pages/AlHabibMedicalService/ancillary-orders/ancillaryOrders.dart @@ -1,16 +1,13 @@ import 'package:diplomaticquarterapp/core/viewModels/ancillary_orders_view_model.dart'; -import 'package:diplomaticquarterapp/pages/AlHabibMedicalService/health_calculator/body_fat/body_fat.dart'; -import 'package:diplomaticquarterapp/pages/AlHabibMedicalService/health_calculator/bmi_calculator/bmi_calculator.dart'; +import 'package:diplomaticquarterapp/pages/AlHabibMedicalService/ancillary-orders/ancillaryOrdersDetails.dart'; import 'package:diplomaticquarterapp/pages/AlHabibMedicalService/health_calculator/calorie_calculator/calorie_calculator.dart'; -import 'package:diplomaticquarterapp/pages/AlHabibMedicalService/health_calculator/carbs/carbs.dart'; -import 'package:diplomaticquarterapp/pages/AlHabibMedicalService/health_calculator/ovulation_period/ovulation_period.dart'; import 'package:diplomaticquarterapp/pages/base/base_view.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; -import 'package:diplomaticquarterapp/widgets/data_display/medical/medical_profile_item.dart'; import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; import 'package:flutter/material.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; +import 'package:diplomaticquarterapp/uitl/date_uitl.dart'; class AnicllaryOrders extends StatefulWidget { @override @@ -36,8 +33,145 @@ class _AnicllaryOrdersState extends State onModelReady: (model) => model.getOrders(), builder: (_, model, widget) => AppScaffold( isShowAppBar: true, - appBarTitle: TranslationBase.of(context).parking, + baseViewModel: model, + appBarTitle: TranslationBase.of(context).anicllaryOrders, body: SingleChildScrollView( - padding: EdgeInsets.all(12), child: Container()))); + padding: EdgeInsets.all(12), + child: model.ancillaryLists.length > 0 + ? Column(children: [ + getPatientInfo(model), + getAncillaryOrdersList(model) + ]) + : SizedBox()))); + } + + Widget getPatientInfo(AnciallryOrdersViewModel model) { + print(model.ancillaryLists); + return Padding( + child: Column( + children: [ + Row( + children: [ + Texts( + TranslationBase.of(context).mrn, + fontWeight: FontWeight.bold, + fontSize: 22, + ), + Texts( + " : ", + fontSize: 20, + ), + Texts( + model.ancillaryLists[0].patientID.toString(), + ) + ], + ), + Row( + children: [ + Texts( + TranslationBase.of(context).patientName, + fontWeight: FontWeight.bold, + fontSize: 20, + ), + Texts( + " : ", + fontSize: 20, + ), + Texts( + model.ancillaryLists[0].patientName, + ) + ], + ), + Divider() + ], + ), + padding: EdgeInsets.only(top: 5.0, bottom: 10.0), + ); + } + + Widget getAncillaryOrdersList(AnciallryOrdersViewModel model) { + return Column( + children: model.ancillaryLists[0].ancillaryOrderList + .map( + (item) => InkWell( + onTap: () { + ancillaryOrdersDetails(item); + }, + child: Container( + decoration: BoxDecoration( + border: Border( + bottom: BorderSide( + width: 0.5, + ))), + padding: EdgeInsets.all(15), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Padding( + padding: EdgeInsets.all(3), + child: Row( + mainAxisAlignment: + MainAxisAlignment.start, + children: [ + Texts( + TranslationBase.of(context) + .appointmentNo + + ' : ', + fontWeight: FontWeight.bold, + ), + Texts(item.appointmentNo.toString()) + ], + )), + Padding( + padding: EdgeInsets.all(3), + child: Row( + children: [ + Texts( + TranslationBase.of(context) + .appointmentDate + + ' : ', + fontWeight: FontWeight.bold), + Texts(DateUtil.getFormattedDate( + DateUtil.convertStringToDate( + item.appointmentDate), + "MMM dd,yyyy")) + ], + )), + Padding( + padding: EdgeInsets.all(3), + child: Row( + children: [ + Texts( + TranslationBase.of(context) + .doctorName + + ' : ', + fontWeight: FontWeight.bold), + Texts(item.doctorName.toString()) + ], + )), + Divider( + color: Colors.black12, + height: 1, + ) + ]), + Icon( + Icons.arrow_right, + size: 25, + ) + ]))), + ) + .toList()); + } + + ancillaryOrdersDetails(item) { + Navigator.push( + context, + FadePage( + page: AnicllaryOrdersDetails(item.appointmentNo, item.orderNo), + ), + ); } } diff --git a/lib/pages/AlHabibMedicalService/ancillary-orders/ancillaryOrdersDetails.dart b/lib/pages/AlHabibMedicalService/ancillary-orders/ancillaryOrdersDetails.dart new file mode 100644 index 00000000..20d2966b --- /dev/null +++ b/lib/pages/AlHabibMedicalService/ancillary-orders/ancillaryOrdersDetails.dart @@ -0,0 +1,280 @@ +import 'package:diplomaticquarterapp/core/viewModels/ancillary_orders_view_model.dart'; +import 'package:diplomaticquarterapp/pages/base/base_view.dart'; +import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; +import 'package:diplomaticquarterapp/widgets/buttons/button.dart'; +import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; +import 'package:flutter/material.dart'; +import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; +import 'package:diplomaticquarterapp/uitl/date_uitl.dart'; +import "package:collection/collection.dart"; +import 'package:diplomaticquarterapp/widgets/text/app_texts_widget.dart'; + +class AnicllaryOrdersDetails extends StatefulWidget { + final dynamic appoNo; + final dynamic orderNo; + AnicllaryOrdersDetails(this.appoNo, this.orderNo); + @override + _AnicllaryOrdersState createState() => _AnicllaryOrdersState(); +} + +class _AnicllaryOrdersState extends State + with SingleTickerProviderStateMixin { + void initState() { + super.initState(); + } + + void dispose() { + super.dispose(); + } + + @override + Widget build(BuildContext context) { + return BaseView( + onModelReady: (model) => + model.getOrdersDetails(widget.appoNo, widget.orderNo), + builder: (_, model, widget) => AppScaffold( + isShowAppBar: true, + baseViewModel: model, + appBarTitle: TranslationBase.of(context).anicllaryOrders, + body: SingleChildScrollView( + padding: EdgeInsets.all(12), + child: model.ancillaryListsDetails.length > 0 + ? Column(children: [ + getPatientInfo(model), + getInvoiceDetails(model), + getInsuranceDetails(model), + getAncillaryDetails(model), + Row( + mainAxisAlignment: MainAxisAlignment.spaceAround, + children: [ + Texts( + TranslationBase.of(context).total, + fontSize: 20, + fontWeight: FontWeight.bold, + ), + Texts( + getTotalValue(model), + fontSize: 20, + fontWeight: FontWeight.bold, + ) + ], + ), + Row( + mainAxisAlignment: MainAxisAlignment.end, + children: [ + Button( + label: TranslationBase.of(context).payNow, + onTap: () {}, + ) + ], + ) + ]) + : SizedBox()))); + } + + Widget getPatientInfo(AnciallryOrdersViewModel model) { + print(model.ancillaryListsDetails); + return Padding( + child: Column( + children: [ + Row( + children: [ + Texts( + TranslationBase.of(context).mrn, + fontWeight: FontWeight.bold, + fontSize: 22, + ), + Texts( + " : ", + fontSize: 20, + ), + Texts( + model.ancillaryListsDetails[0].patientID.toString(), + ) + ], + ), + Row( + children: [ + Texts( + TranslationBase.of(context).patientName, + fontWeight: FontWeight.bold, + fontSize: 20, + ), + Texts( + " : ", + fontSize: 20, + ), + Texts( + model.ancillaryLists[0].patientName, + ) + ], + ), + Divider( + color: Colors.black26, + ) + ], + ), + padding: EdgeInsets.only(top: 5.0, bottom: 5.0), + ); + } + + Widget getInvoiceDetails(model) { + return Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + children: [ + Texts( + TranslationBase.of(context).invoiceNo, + fontWeight: FontWeight.bold, + ), + Texts(" : "), + Texts( + model.ancillaryListsDetails[0].appointmentNo.toString(), + ) + ], + ), + Row( + children: [ + Texts( + TranslationBase.of(context).date, + fontWeight: FontWeight.bold, + ), + Texts(" : "), + Texts( + DateUtil.getFormattedDate( + DateUtil.convertStringToDate( + model.ancillaryListsDetails[0].appointmentDate), + "MMM dd,yyyy"), + ) + ], + ), + Row( + children: [ + Texts( + TranslationBase.of(context).date, + fontWeight: FontWeight.bold, + ), + Texts(" : "), + Texts( + model.ancillaryListsDetails[0].doctorName, + ), + ], + ), + SizedBox( + height: 10, + ), + Divider( + color: Colors.black26, + ) + ], + ); + } + + Widget getInsuranceDetails(model) { + return Padding( + padding: EdgeInsets.only(top: 10, bottom: 10), + child: Column( + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.spaceAround, + children: [ + Texts( + TranslationBase.of(context).insurance, + fontWeight: FontWeight.bold, + ), + Texts( + TranslationBase.of(context).insuranceID, + fontWeight: FontWeight.bold, + ) + ], + ), + Row( + mainAxisAlignment: MainAxisAlignment.spaceAround, + children: [ + Texts( + model.ancillaryListsDetails[0].policyName, + ), + Texts( + model.ancillaryListsDetails[0].insurancePolicyNo, + ) + ], + ), + SizedBox( + height: 15, + ), + Divider( + color: Colors.red[800], + thickness: 3, + ) + ], + )); + } + + Widget getAncillaryDetails(model) { + Map newMap = groupBy(model.ancillaryListsDetails[0].ancillaryOrderProcList, + (obj) => obj.procedureCategoryName); + print(newMap); + + return Padding( + padding: EdgeInsets.only(top: 10, bottom: 10), + child: getHeaderDetails(newMap)); + } + + Widget getHeaderDetails(newMap) { + List list = new List(); + + newMap.forEach((key, value) { + list.add( + Texts( + key, + fontWeight: FontWeight.bold, + ), + ); + list.add(Row( + mainAxisAlignment: MainAxisAlignment.start, + children: [ + getLabDetails(value), + ], + )); + }); + + return Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: list, + ); + } + + String getTotalValue(value) { + double total = 0.0; + value.ancillaryListsDetails[0].ancillaryOrderProcList + .forEach((result) => {total += result.companyShareWithTax}); + return total.toStringAsFixed(2); + } + + getLabDetails(value) { + return Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: value.map((result) { + return Container( + width: MediaQuery.of(context).size.width * .9, + padding: EdgeInsets.all(10), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceAround, + children: [ + Expanded( + flex: 3, + child: Text(result.procedureName.toString(), + overflow: TextOverflow.ellipsis)), + Expanded(child: AppText(result.companyShare.toString())), + Expanded(child: AppText(result.companyTaxAmount.toString())), + Expanded( + child: AppText( + result.companyShareWithTax.toString(), + )) + ], + )); + }).toList(), + ); + } +} diff --git a/lib/pages/DrawerPages/family/my-family.dart b/lib/pages/DrawerPages/family/my-family.dart index a2312220..07f99b16 100644 --- a/lib/pages/DrawerPages/family/my-family.dart +++ b/lib/pages/DrawerPages/family/my-family.dart @@ -57,7 +57,8 @@ class _MyFamily extends State with TickerProviderStateMixin { ProjectViewModel projectViewModel; AuthenticatedUser user; VitalSignService _vitalSignService = locator(); - PharmacyModuleViewModel pharmacyModuleViewModel = locator(); + PharmacyModuleViewModel pharmacyModuleViewModel = + locator(); var isVaiable = false; @override @@ -659,14 +660,15 @@ class _MyFamily extends State with TickerProviderStateMixin { okText: TranslationBase.of(context).confirm, cancelText: TranslationBase.of(context).cancel_nocaps, okFunction: () => { - removeFamily(family, context), - ConfirmDialog.closeAlertDialog(context) + ConfirmDialog.closeAlertDialog(context), + removeFamily(family, context) }, cancelFunction: () => {}); dialog.showAlertDialog(context); } removeFamily(GetAllSharedRecordsByStatusList family, context) { + GifLoaderDialogUtils.showMyDialog(context); this.userID = family.iD; Map request = {}; request['ID'] = this.userID; @@ -678,7 +680,7 @@ class _MyFamily extends State with TickerProviderStateMixin { } refreshFamily(context) { - //sharedPref.remove(FAMILY_FILE); + GifLoaderDialogUtils.hideDialog(context); setState(() { sharedPref.remove(FAMILY_FILE); }); @@ -707,10 +709,11 @@ class _MyFamily extends State with TickerProviderStateMixin { loginAfter(result, context) async { GifLoaderDialogUtils.hideDialog(context); var currentLang = await sharedPref.getString(APP_LANGUAGE); - result = list.CheckActivationCode.fromJson(result); - var familyFile = await sharedPref.getObject(FAMILY_FILE); Provider.of(context, listen: false) .setPrivilege(privilegeList: result, isLoginChild: true); + result = list.CheckActivationCode.fromJson(result); + var familyFile = await sharedPref.getObject(FAMILY_FILE); + result = list.CheckActivationCode.fromJson(result); var mainUser = await sharedPref.getObject(MAIN_USER); var bloodType = await sharedPref.getString(BLOOD_TYPE); @@ -731,8 +734,8 @@ class _MyFamily extends State with TickerProviderStateMixin { Provider.of(context, listen: false) .setUser(authenticatedUserObject.user); - await pharmacyModuleViewModel.generatePharmacyToken().then((value) async { - if(pharmacyModuleViewModel.error.isNotEmpty) + await pharmacyModuleViewModel.generatePharmacyToken().then((value) async { + if (pharmacyModuleViewModel.error.isNotEmpty) await pharmacyModuleViewModel.createUser(); }); diff --git a/lib/pages/ErService/AmbulanceRequestIndexPages/AmbulanceRequestIndex.dart b/lib/pages/ErService/AmbulanceRequestIndexPages/AmbulanceRequestIndex.dart index 1fb47cec..f36eadc5 100644 --- a/lib/pages/ErService/AmbulanceRequestIndexPages/AmbulanceRequestIndex.dart +++ b/lib/pages/ErService/AmbulanceRequestIndexPages/AmbulanceRequestIndex.dart @@ -124,7 +124,7 @@ class _AmbulanceRequestIndexPageState extends State { : Column( children: [ SizedBox( - height: 80, + height: 20, ), Container( margin: EdgeInsets.only(left: 12, right: 12), diff --git a/lib/pages/ErService/AmbulanceRequestIndexPages/SelectTransportationMethod.dart b/lib/pages/ErService/AmbulanceRequestIndexPages/SelectTransportationMethod.dart index 0770448e..63d915d1 100644 --- a/lib/pages/ErService/AmbulanceRequestIndexPages/SelectTransportationMethod.dart +++ b/lib/pages/ErService/AmbulanceRequestIndexPages/SelectTransportationMethod.dart @@ -210,71 +210,77 @@ class _SelectTransportationMethodState SizedBox( height: 5, ), - Row( - children: [ - Expanded( - child: InkWell( - onTap: () { - setState(() { - _way = Way.OneWay; - }); - }, - child: Container( - decoration: BoxDecoration( - shape: BoxShape.rectangle, - borderRadius: BorderRadius.circular(8), - border: - Border.all(color: Colors.grey, width: 0.5), - color: Colors.white, - ), - child: ListTile( - title: - Texts(TranslationBase.of(context).oneDirec), - leading: Radio( - value: Way.OneWay, - groupValue: _way, - onChanged: (value) { - setState(() { - _way = value; - }); - }, + Container( + margin: EdgeInsets.only(bottom:65 ), + child: Row( + children: [ + Expanded( + child: InkWell( + onTap: () { + setState(() { + _way = Way.OneWay; + }); + }, + child: Container( + decoration: BoxDecoration( + shape: BoxShape.rectangle, + borderRadius: BorderRadius.circular(8), + border: + Border.all(color: Colors.grey, width: 0.5), + color: Colors.white, + ), + child: ListTile( + title: + Texts(TranslationBase.of(context).oneDirec), + leading: Radio( + value: Way.OneWay, + groupValue: _way, + onChanged: (value) { + setState(() { + _way = value; + }); + }, + ), ), ), ), ), - ), - Expanded( - child: InkWell( - onTap: () { - setState(() { - _way = Way.TwoWays; - }); - }, - child: Container( - decoration: BoxDecoration( - shape: BoxShape.rectangle, - borderRadius: BorderRadius.circular(8), - border: - Border.all(color: Colors.grey, width: 0.5), - color: Colors.white, - ), - child: ListTile( - title: - Texts(TranslationBase.of(context).twoDirec), - leading: Radio( - value: Way.TwoWays, - groupValue: _way, - onChanged: (value) { - setState(() { - _way = value; - }); - }, + Expanded( + child: InkWell( + onTap: () { + setState(() { + _way = Way.TwoWays; + }); + }, + child: Container( + decoration: BoxDecoration( + shape: BoxShape.rectangle, + borderRadius: BorderRadius.circular(8), + border: + Border.all(color: Colors.grey, width: 0.5), + color: Colors.white, + ), + child: ListTile( + title: + Texts(TranslationBase.of(context).twoDirec), + leading: Radio( + value: Way.TwoWays, + groupValue: _way, + onChanged: (value) { + setState(() { + _way = value; + }); + }, + ), ), ), ), ), - ), - ], + ], + ), + ), + SizedBox( + height: 30, ), ], ), diff --git a/lib/pages/ErService/AmbulanceRequestIndexPages/Summary.dart b/lib/pages/ErService/AmbulanceRequestIndexPages/Summary.dart index 6140dc62..f8bb9e8e 100644 --- a/lib/pages/ErService/AmbulanceRequestIndexPages/Summary.dart +++ b/lib/pages/ErService/AmbulanceRequestIndexPages/Summary.dart @@ -73,6 +73,7 @@ class _SummaryState extends State { Texts(TranslationBase.of(context).billAmount,textAlign: TextAlign.start,), SizedBox(height: 5,), Container( + height: 55, padding: EdgeInsets.all(10), decoration: BoxDecoration( @@ -87,8 +88,8 @@ class _SummaryState extends State { ], ), ), + SizedBox(height: 250), - SizedBox(height: 45,), ], ), diff --git a/lib/pages/MyAppointments/widgets/AppointmentActions.dart b/lib/pages/MyAppointments/widgets/AppointmentActions.dart index 51eefe1a..b335c740 100644 --- a/lib/pages/MyAppointments/widgets/AppointmentActions.dart +++ b/lib/pages/MyAppointments/widgets/AppointmentActions.dart @@ -509,8 +509,7 @@ class _AppointmentActionsState extends State { Navigator.push( context, FadePage( - page: - LaboratoryResultPage(patientLabOrders: patientLabOrders))) + page: LaboratoryResultPage(patientLabOrders: patientLabOrders))) .then((value) {}); } @@ -518,8 +517,7 @@ class _AppointmentActionsState extends State { Navigator.push( context, FadePage( - page: - RadiologyDetailsPage(finalRadiology: finalRadiology))) + page: RadiologyDetailsPage(finalRadiology: finalRadiology))) .then((value) {}); } @@ -542,7 +540,17 @@ class _AppointmentActionsState extends State { transform: Matrix4.translationValues(0.0, curvedValue * 200, 0.0), child: Opacity( opacity: a1.value, - child: ReminderDialog(appo: appo), + child: ReminderDialog( + eventId: appo.appointmentNo.toString(), + title: "Doctor Appointment", + description: "You have an appointment with " + + appo.doctorTitle + + " " + + appo.doctorNameObj, + startDate: appo.appointmentDate, + endDate: appo.appointmentDate, + location: appo.projectName, + ), ), ); }, @@ -668,7 +676,10 @@ class _AppointmentActionsState extends State { context, FadePage( page: VitalSignDetailsScreen( - appointmentNo: appoNo, projectID: projectID,isNotOneAppointment: false,))); + appointmentNo: appoNo, + projectID: projectID, + isNotOneAppointment: false, + ))); } navigateToInsertComplaint() { diff --git a/lib/pages/MyAppointments/widgets/reminder_dialog.dart b/lib/pages/MyAppointments/widgets/reminder_dialog.dart index b8803469..0db8cda4 100644 --- a/lib/pages/MyAppointments/widgets/reminder_dialog.dart +++ b/lib/pages/MyAppointments/widgets/reminder_dialog.dart @@ -9,9 +9,14 @@ import 'package:manage_calendar_events/manage_calendar_events.dart'; class ReminderDialog extends StatefulWidget { static var selectedDuration; - AppoitmentAllHistoryResultList appo; + final String eventId; + final String title; + final String description; + final String startDate; + final String endDate; + final String location; - ReminderDialog({@required this.appo}); + ReminderDialog({@required this.eventId, @required this.title, @required this.description, @required this.startDate, @required this.endDate, @required this.location}); @override _ReminderDialogState createState() => _ReminderDialogState(); @@ -98,17 +103,14 @@ class _ReminderDialogState extends State { }); CalendarEvent calendarEvent = new CalendarEvent( - eventId: widget.appo.appointmentNo.toString(), - title: "Doctor Appointment", - description: "You have an appointment with " + - widget.appo.doctorTitle + - " " + - widget.appo.doctorNameObj, - startDate: DateUtil.convertStringToDate(widget.appo.appointmentDate) + eventId: widget.eventId, + title: widget.title, + description: widget.description, + startDate: DateUtil.convertStringToDate(widget.startDate) .subtract( new Duration(microseconds: ReminderDialog.selectedDuration)), - endDate: DateUtil.convertStringToDate(widget.appo.appointmentDate), - location: widget.appo.projectName, + endDate: DateUtil.convertStringToDate(widget.endDate), + location: widget.location, duration: new Duration(minutes: 15).inMinutes, isAllDay: false, hasAlarm: true); @@ -118,7 +120,7 @@ class _ReminderDialogState extends State { .then((value) { print("Cal event"); print(value); - if (int.parse(value) == widget.appo.appointmentNo) { + if (int.parse(value) == int.parse(widget.eventId)) { AppToast.showSuccessToast(message: TranslationBase.of(context).reminderSuccess); } Navigator.of(context).pop(); diff --git a/lib/pages/final_products_page.dart b/lib/pages/final_products_page.dart index 4820689a..66969331 100644 --- a/lib/pages/final_products_page.dart +++ b/lib/pages/final_products_page.dart @@ -41,6 +41,10 @@ class _FinalProductsPageState extends State { model.getManufacturerProducts(id); } else if (widget.productType == 3) { model.getLastVisitedProducts(); + } else if (widget.productType == 4){ + model.getMostViewedProducts(); + } else if (widget.productType == 5){ + model.getNewProducts(); } else { model.getBestSellerProducts(); } diff --git a/lib/pages/insurance/insurance_card_screen.dart b/lib/pages/insurance/insurance_card_screen.dart index 42efc179..da66c572 100644 --- a/lib/pages/insurance/insurance_card_screen.dart +++ b/lib/pages/insurance/insurance_card_screen.dart @@ -109,58 +109,92 @@ class _InsuranceCardState extends State { ), Column( crossAxisAlignment: - CrossAxisAlignment.stretch, + CrossAxisAlignment.start, children: [ - Texts( - TranslationBase.of(context).category +": "+ - model.insurance[index] - .subCategoryDesc, - fontSize: 18.5, + Row( + mainAxisAlignment: + MainAxisAlignment.spaceBetween, + children: [ + Texts( + TranslationBase.of(context) + .category, + fontSize: 18.5), + Texts( + model.insurance[index] + .subCategoryDesc, + fontSize: 18.5) + ], ), Row( + mainAxisAlignment: + MainAxisAlignment.spaceBetween, children: [ Texts( - TranslationBase.of(context) - .expirationDate +": "+ - convertDateFormat(model - .insurance[index].cardValidTo), - fontSize: 18.5, - ), - Expanded( - child: Column( - children: [ - model.insurance[index].isActive == true - ? Texts( - TranslationBase.of(context) - .activeInsurence, - color: Colors.green, - fontWeight: FontWeight.w900, - fontSize: 17.9) - : Texts( - TranslationBase.of(context) - .notActive, - color: Colors.red, - fontWeight: FontWeight.w900, - fontSize: 17.9) - ], - ), - ), + TranslationBase.of(context) + .expirationDate, + fontSize: 18.5), + Texts( + convertDateFormat( + model.insurance[index] + .cardValidTo, + ), + fontSize: 18.5), ], ), - Texts( - TranslationBase.of(context) - .patientCard +": "+ - model - .insurance[index].patientCardID, - fontSize: 18.5, + Row( + mainAxisAlignment: + MainAxisAlignment.spaceBetween, + children: [ + Texts( + TranslationBase.of(context) + .status + + ": ", + fontSize: 18.5), + model.insurance[index].isActive == + true + ? Texts( + TranslationBase.of(context) + .activeInsurence, + color: Colors.green, + fontWeight: FontWeight.w900, + fontSize: 17.9) + : Texts( + TranslationBase.of(context) + .notActive, + color: Colors.red, + fontWeight: FontWeight.w900, + fontSize: 17.9) + ], ), - Texts( - TranslationBase.of(context) - .policyNumber +" "+ - model.insurance[index] - .insurancePolicyNumber, - fontSize: 18.5, + Row( + mainAxisAlignment: + MainAxisAlignment.spaceBetween, + children: [ + Texts( + TranslationBase.of(context) + .patientCard, + fontSize: 18.5), + Texts( + model.insurance[index] + .patientCardID, + fontSize: 18.5) + ], ), + Row( + mainAxisAlignment: + MainAxisAlignment.spaceBetween, + children: [ + Texts( + TranslationBase.of(context) + .policyNumber, + fontSize: 18.5, + ), + Texts( + model.insurance[index] + .insurancePolicyNumber, + fontSize: 18.5, + ) + ]), ], ), SizedBox( diff --git a/lib/pages/insurance/insurance_page.dart b/lib/pages/insurance/insurance_page.dart index f938d9e5..a391f554 100644 --- a/lib/pages/insurance/insurance_page.dart +++ b/lib/pages/insurance/insurance_page.dart @@ -16,7 +16,7 @@ class InsurancePage extends StatelessWidget { final InsuranceViewModel model; InsuranceCardService _insuranceCardService = locator(); - InsurancePage({Key key, this.model}) : super(key: key); + InsurancePage({Key key, this.model}) : super(key: key); @override Widget build(BuildContext context) { return SingleChildScrollView( @@ -31,24 +31,20 @@ class InsurancePage extends StatelessWidget { width: MediaQuery.of(context).size.width, padding: EdgeInsets.all(10.0), child: Row( - crossAxisAlignment: - CrossAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.start, mainAxisSize: MainAxisSize.max, children: [ if (model.user != null) Expanded( flex: 3, child: Container( - margin: EdgeInsets.only( - top: 2.0, - left: 10.0, - right: 20.0), + margin: + EdgeInsets.only(top: 2.0, left: 10.0, right: 20.0), child: Column( - crossAxisAlignment: - CrossAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.start, children: [ Texts( - model.user.firstName ?? '' + " " + model.user.lastName ?? '', + model.user.firstName + " " + model.user.lastName, fontSize: 14, color: Colors.black, fontWeight: FontWeight.w500, @@ -57,11 +53,9 @@ class InsurancePage extends StatelessWidget { height: 8, ), Texts( - TranslationBase.of(context) - .fileno + + TranslationBase.of(context).fileno + ": " + - model.user.patientID - .toString(), + model.user.patientID.toString(), fontSize: 14, color: Colors.black, fontWeight: FontWeight.w500, @@ -78,9 +72,7 @@ class InsurancePage extends StatelessWidget { children: [ Container( child: SecondaryButton( - label: TranslationBase.of( - context) - .fetchData, + label: TranslationBase.of(context).fetchData, small: true, textColor: Colors.white, onTap: () { @@ -88,15 +80,12 @@ class InsurancePage extends StatelessWidget { setupID: '010266', projectID: 15, patientIdentificationID: - model.user - .patientIdentificationNo, - patientID: model - .user.patientID, - name: model.user - .firstName + + model.user.patientIdentificationNo, + patientID: model.user.patientID, + name: model.user.firstName + " " + - model - .user.lastName,context: context); + model.user.lastName, + context: context); }, ), ), @@ -107,122 +96,115 @@ class InsurancePage extends StatelessWidget { ], ), ), - if(model.getAllSharedRecordsByStatusResponse.getAllSharedRecordsByStatusList != null ?? false) - ...List.generate(model.getAllSharedRecordsByStatusResponse.getAllSharedRecordsByStatusList.length, (index) => - model.getAllSharedRecordsByStatusResponse.getAllSharedRecordsByStatusList[index].status == 3 - ? Container( - margin: EdgeInsets.all(10.0), - child: Card( - margin: EdgeInsets.fromLTRB( - 8.0, 16.0, 8.0, 8.0), - color: Colors.white, - shape: RoundedRectangleBorder( - borderRadius: - BorderRadius.circular(10), - ), - child: Container( - width: MediaQuery.of(context).size.width, - padding: EdgeInsets.all(10.0), - child: Row( - crossAxisAlignment: - CrossAxisAlignment.start, - mainAxisSize: MainAxisSize.max, - children: [ - Expanded( - flex: 3, - child: Container( - margin: EdgeInsets.only( - top: 2.0, - left: 10.0, - right: 20.0), - child: Column( - crossAxisAlignment: - CrossAxisAlignment - .start, - children: [ - Texts( - model - .getAllSharedRecordsByStatusResponse - .getAllSharedRecordsByStatusList[ - index] - .patientName, - fontSize: 14, - color: Colors.black, - fontWeight: - FontWeight.w500, - ), - SizedBox( - height: 8, - ), - Texts( - TranslationBase.of( - context) - .fileno + - ": " + - model - .getAllSharedRecordsByStatusResponse - .getAllSharedRecordsByStatusList[ - index] - .patientID - .toString(), - fontSize: 14, - color: Colors.black, - fontWeight: - FontWeight.w500, - ) - ], - ), - ), - ), - Expanded( - flex: 2, - child: Container( - margin: - EdgeInsets.only(top: 2.0), - child: Column( - children: [ - Container( - child: SecondaryButton( - label: TranslationBase - .of(context) - .fetchData, - small: true, - textColor: - Colors.white, - onTap: () { - getDetails( - projectID: 15, - patientIdentificationID: model - .getAllSharedRecordsByStatusResponse - .getAllSharedRecordsByStatusList[ - index] - .patientIdenficationNumber, - setupID: - '010266', - patientID: model - .getAllSharedRecordsByStatusResponse - .getAllSharedRecordsByStatusList[ - index] - .responseID, - name: model - .getAllSharedRecordsByStatusResponse - .getAllSharedRecordsByStatusList[ - index].patientName,context: context); - }, - ), + if (model.getAllSharedRecordsByStatusResponse + .getAllSharedRecordsByStatusList != + null ?? + false) + ...List.generate( + model.getAllSharedRecordsByStatusResponse + .getAllSharedRecordsByStatusList.length, + (index) => model.getAllSharedRecordsByStatusResponse + .getAllSharedRecordsByStatusList[index].status == + 3 + ? Container( + margin: EdgeInsets.all(10.0), + child: Card( + margin: EdgeInsets.fromLTRB(8.0, 16.0, 8.0, 8.0), + color: Colors.white, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(10), + ), + child: Container( + width: MediaQuery.of(context).size.width, + padding: EdgeInsets.all(10.0), + child: Row( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisSize: MainAxisSize.max, + children: [ + Expanded( + flex: 3, + child: Container( + margin: EdgeInsets.only( + top: 2.0, left: 10.0, right: 20.0), + child: Column( + crossAxisAlignment: + CrossAxisAlignment.start, + children: [ + Texts( + model + .getAllSharedRecordsByStatusResponse + .getAllSharedRecordsByStatusList[ + index] + .patientName, + fontSize: 14, + color: Colors.black, + fontWeight: FontWeight.w500, + ), + SizedBox( + height: 8, + ), + Texts( + TranslationBase.of(context).fileno + + ": " + + model + .getAllSharedRecordsByStatusResponse + .getAllSharedRecordsByStatusList[ + index] + .patientID + .toString(), + fontSize: 14, + color: Colors.black, + fontWeight: FontWeight.w500, + ) + ], + ), + ), + ), + Expanded( + flex: 2, + child: Container( + margin: EdgeInsets.only(top: 2.0), + child: Column( + children: [ + Container( + child: SecondaryButton( + label: TranslationBase.of(context) + .fetchData, + small: true, + textColor: Colors.white, + onTap: () { + getDetails( + projectID: 15, + patientIdentificationID: model + .getAllSharedRecordsByStatusResponse + .getAllSharedRecordsByStatusList[ + index] + .patientIdenficationNumber, + setupID: '010266', + patientID: model + .getAllSharedRecordsByStatusResponse + .getAllSharedRecordsByStatusList[ + index] + .responseID, + name: model + .getAllSharedRecordsByStatusResponse + .getAllSharedRecordsByStatusList[ + index] + .patientName, + context: context); + }, + ), + ), + ], + ), + ), + ) + ], ), - ], + ), ), - ), - ) - ], - ), - ), - ), - ) - : Container() - ), - + ) + : Container()), ], ), ); @@ -230,29 +212,32 @@ class InsurancePage extends StatelessWidget { getDetails( {String setupID, - int projectID, - String patientIdentificationID, - int patientID, - String name,BuildContext context}) { + int projectID, + String patientIdentificationID, + int patientID, + String name, + BuildContext context}) { GifLoaderDialogUtils.showMyDialog(context); _insuranceCardService .getPatientInsuranceDetails( - setupID: setupID, - projectID: projectID, - patientID: patientID, - patientIdentificationID: patientIdentificationID) + setupID: setupID, + projectID: projectID, + patientID: patientID, + patientIdentificationID: patientIdentificationID) .then((value) { GifLoaderDialogUtils.hideDialog(context); - if (!_insuranceCardService.hasError && _insuranceCardService.isHaveInsuranceCard) { + if (!_insuranceCardService.hasError && + _insuranceCardService.isHaveInsuranceCard) { Navigator.push( context, FadePage( page: InsuranceCardUpdateDetails( - insuranceCardDetailsModel: _insuranceCardService.insuranceCardDetailsList, - patientID: patientID, - patientIdentificationID: patientIdentificationID, - name: name, - ))); + insuranceCardDetailsModel: + _insuranceCardService.insuranceCardDetailsList, + patientID: patientID, + patientIdentificationID: patientIdentificationID, + name: name, + ))); } else { AppToast.showErrorToast(message: _insuranceCardService.error); } diff --git a/lib/pages/insurance/insurance_update_screen.dart b/lib/pages/insurance/insurance_update_screen.dart index 36b424a8..6c3ee61c 100644 --- a/lib/pages/insurance/insurance_update_screen.dart +++ b/lib/pages/insurance/insurance_update_screen.dart @@ -32,7 +32,11 @@ class _InsuranceUpdateState extends State super.initState(); _tabController = TabController(length: 2, vsync: this); - imagesInfo.add(ImagesInfo(imageEn: 'https://hmgwebservices.com/Images/MobileApp/imges-info/insurance-card/en/0.png',imageAr: 'https://hmgwebservices.com/Images/MobileApp/imges-info/insurance-card/ar/0.png')); + imagesInfo.add(ImagesInfo( + imageEn: + 'https://hmgwebservices.com/Images/MobileApp/imges-info/insurance-card/en/0.png', + imageAr: + 'https://hmgwebservices.com/Images/MobileApp/imges-info/insurance-card/ar/0.png')); } void dispose() { @@ -111,7 +115,7 @@ class _InsuranceUpdateState extends State physics: BouncingScrollPhysics(), controller: _tabController, children: [ - InsurancePage(model:model), + InsurancePage(model: model), Container( child: ListView.builder( itemCount: model.insuranceUpdate == null @@ -227,6 +231,4 @@ class _InsuranceUpdateState extends State ), ); } - - } diff --git a/lib/pages/landing/home_page.dart b/lib/pages/landing/home_page.dart index 452c315c..ef38ae9c 100644 --- a/lib/pages/landing/home_page.dart +++ b/lib/pages/landing/home_page.dart @@ -1,6 +1,8 @@ import 'package:diplomaticquarterapp/config/size_config.dart'; import 'package:diplomaticquarterapp/core/viewModels/dashboard_view_model.dart'; +import 'package:diplomaticquarterapp/core/viewModels/pharmacyModule/pharmacy_module_view_model.dart'; import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; +import 'package:diplomaticquarterapp/locator.dart'; import 'package:diplomaticquarterapp/pages/AlHabibMedicalService/ComprehensiveMedicalCheckup/cmc_page.dart'; import 'package:diplomaticquarterapp/pages/AlHabibMedicalService/HomeHealthCare/home_health_care_page.dart'; import 'package:diplomaticquarterapp/pages/AlHabibMedicalService/all_habib_medical_service_page.dart'; @@ -9,8 +11,10 @@ import 'package:diplomaticquarterapp/pages/Covid-DriveThru/covid-drivethru-locat import 'package:diplomaticquarterapp/pages/ErService/ErOptions.dart'; import 'package:diplomaticquarterapp/pages/base/base_view.dart'; import 'package:diplomaticquarterapp/pages/livecare/livecare_home.dart'; +import 'package:diplomaticquarterapp/pages/packages_offers/OfferAndPackagesPage.dart'; import 'package:diplomaticquarterapp/pages/paymentService/payment_service.dart'; import 'package:diplomaticquarterapp/uitl/date_uitl.dart'; +import 'package:diplomaticquarterapp/uitl/gif_loader_dialog_utils.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; @@ -33,6 +37,9 @@ class HomePage extends StatefulWidget { } class _HomePageState extends State { + PharmacyModuleViewModel pharmacyModuleViewModel = + locator(); + @override Widget build(BuildContext context) { ProjectViewModel projectViewModel = Provider.of(context); @@ -453,6 +460,33 @@ class _HomePageState extends State { ), ], ), + Padding( + padding: const EdgeInsets.only(bottom: 15, right: 15, left: 15), + child: InkWell( + onTap: (){ + Navigator.of(context).push(MaterialPageRoute(builder: (context) => PackagesHomePage())); + }, + child: Container( + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(10), + color: Color(0xffB8382C), + ), + child: Padding( + padding: const EdgeInsets.all(8), + child: Row( + children: [ + Texts( + TranslationBase.of(context).offerAndPackages, + color: Colors.white, fontSize: 20, fontWeight: FontWeight.normal, + ), + Spacer(), + Image.asset("assets/images/offer_icon.png"), + ], + ), + ), + ), + ), + ), if (projectViewModel.havePrivilege(64) || projectViewModel.havePrivilege(65) || projectViewModel.havePrivilege(67)) @@ -503,8 +537,7 @@ class _HomePageState extends State { ), if (projectViewModel.havePrivilege(65)) DashboardItem( - onTap: () => Navigator.push( - context, FadePage(page: LandingPagePharmacy())), + onTap: () => getPharmacyToken(model), child: Center( child: Padding( padding: const EdgeInsets.all(15.0), @@ -799,10 +832,24 @@ class _HomePageState extends State { ); } - // openBrowser() { - // InAppBrowser browser = new InAppBrowser(); - // browser.openUrl(url: "https://uat.hmgwebservices.com/epharmacy/checkout/OpcCompleteRedirectionPaymentClientbyOrder?orderID=ca9dd276-0a20-4924-a768-fafa9a855ef1&&CustomerId=1367368"); - // } + getPharmacyToken(DashboardViewModel model) async { + if(!model.isLogin) { + Navigator.push(context, FadePage(page: LandingPagePharmacy())); + } else { + GifLoaderDialogUtils.showMyDialog(context); + await pharmacyModuleViewModel.generatePharmacyToken().then((value) async { + if (pharmacyModuleViewModel.error.isNotEmpty) { + await pharmacyModuleViewModel.createUser().then((value) { + GifLoaderDialogUtils.hideDialog(context); + Navigator.push(context, FadePage(page: LandingPagePharmacy())); + }); + } else { + GifLoaderDialogUtils.hideDialog(context); + Navigator.push(context, FadePage(page: LandingPagePharmacy())); + } + }); + } + } navigateToCovidDriveThru() { Navigator.push(context, FadePage(page: CovidDrivethruLocation())); diff --git a/lib/pages/landing/landing_page.dart b/lib/pages/landing/landing_page.dart index 704aef54..c99930aa 100644 --- a/lib/pages/landing/landing_page.dart +++ b/lib/pages/landing/landing_page.dart @@ -185,7 +185,7 @@ class _LandingPageState extends State with WidgetsBindingObserver { if (results[Permission.camera].isGranted) ; if (results[Permission.photos].isGranted) ; if (results[Permission.accessMediaLocation].isGranted) ; - if (results[Permission.calendar].isGranted) ; + // if (results[Permission.calendar].isGranted) ; }); requestPermissions(); // }); @@ -327,15 +327,15 @@ class _LandingPageState extends State with WidgetsBindingObserver { Permission.photos, Permission.notification, Permission.accessMediaLocation, - Permission.calendar, + // Permission.calendar, Permission.activityRecognition ].request(); - var permissionsGranted = await deviceCalendarPlugin.hasPermissions(); - if (permissionsGranted.isSuccess && !permissionsGranted.data) { - permissionsGranted = await deviceCalendarPlugin.requestPermissions(); - if (!permissionsGranted.isSuccess || !permissionsGranted.data) {} - } + // var permissionsGranted = await deviceCalendarPlugin.hasPermissions(); + // if (permissionsGranted.isSuccess && !permissionsGranted.data) { + // permissionsGranted = await deviceCalendarPlugin.requestPermissions(); + // if (!permissionsGranted.isSuccess || !permissionsGranted.data) {} + // } return permissionResults; } diff --git a/lib/pages/login/login.dart b/lib/pages/login/login.dart index 6bc99be5..8d655f76 100644 --- a/lib/pages/login/login.dart +++ b/lib/pages/login/login.dart @@ -88,7 +88,9 @@ class _Login extends State { Expanded( flex: 2, child: Texts( - TranslationBase.of(context).enterNationalId, + loginType == 1 + ? TranslationBase.of(context).enterNationalId + : TranslationBase.of(context).enterFile, fontSize: SizeConfig.textMultiplier * 3.5, textAlign: TextAlign.start, )), diff --git a/lib/pages/login/welcome.dart b/lib/pages/login/welcome.dart index b2250f5c..6a007e0a 100644 --- a/lib/pages/login/welcome.dart +++ b/lib/pages/login/welcome.dart @@ -5,6 +5,7 @@ import 'package:diplomaticquarterapp/routes.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/widgets/buttons/defaultButton.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; +import 'package:diplomaticquarterapp/widgets/text/app_texts_widget.dart'; import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; @@ -41,20 +42,19 @@ class _WelcomeLogin extends State { children: [ Image.asset('assets/images/DQ/logo.png', height: 90, width: 90), - Text( + AppText( TranslationBase.of(context).welcome, - style: TextStyle( - fontSize: 30, fontWeight: FontWeight.bold), - textAlign: TextAlign.start, + fontSize: 30, + fontWeight: FontWeight.bold, ), - Text( + AppText( TranslationBase.of(context).welcomeText, - style: TextStyle(fontSize: 24), + fontSize: 24, textAlign: TextAlign.start, ), - Text( + AppText( TranslationBase.of(context).welcomeText2, - style: TextStyle(fontSize: 24), + fontSize: 24, textAlign: TextAlign.start, ), SizedBox( diff --git a/lib/pages/medical/balance/advance_payment_page.dart b/lib/pages/medical/balance/advance_payment_page.dart index 6611c779..5b2b5d56 100644 --- a/lib/pages/medical/balance/advance_payment_page.dart +++ b/lib/pages/medical/balance/advance_payment_page.dart @@ -237,7 +237,7 @@ class _AdvancePaymentPageState extends State { ), ), bottomSheet: Container( - height: MediaQuery.of(context).size.height * 0.10, + height: 90, width: double.infinity, padding: EdgeInsets.all(18), child: SecondaryButton( diff --git a/lib/pages/medical/balance/my_balance_page.dart b/lib/pages/medical/balance/my_balance_page.dart index 8f80eeeb..7639bb2f 100644 --- a/lib/pages/medical/balance/my_balance_page.dart +++ b/lib/pages/medical/balance/my_balance_page.dart @@ -49,7 +49,7 @@ class MyBalancePage extends StatelessWidget { width: double.infinity, height: 65, decoration: BoxDecoration( - color: Theme.of(context).primaryColor, + color: Colors.red[700], shape: BoxShape.rectangle, borderRadius: BorderRadius.circular(7), ), @@ -79,7 +79,7 @@ class MyBalancePage extends StatelessWidget { height: 65, margin: EdgeInsets.only(top: 8), decoration: BoxDecoration( - color: Theme.of(context).primaryColor, + color: Colors.white, shape: BoxShape.rectangle, borderRadius: BorderRadius.circular(7), ), diff --git a/lib/pages/medical/eye/ClassesPage.dart b/lib/pages/medical/eye/ClassesPage.dart index 7904178c..21a07d23 100644 --- a/lib/pages/medical/eye/ClassesPage.dart +++ b/lib/pages/medical/eye/ClassesPage.dart @@ -1,17 +1,28 @@ import 'package:diplomaticquarterapp/core/model/eye/AppoimentAllHistoryResult.dart'; import 'package:diplomaticquarterapp/core/viewModels/medical/EyeViewModel.dart'; import 'package:diplomaticquarterapp/pages/base/base_view.dart'; +import 'package:diplomaticquarterapp/uitl/gif_loader_dialog_utils.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/widgets/buttons/secondary_button.dart'; import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; +import 'package:diplomaticquarterapp/widgets/dialogs/confirm_send_email_dialog.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; class ClassesPage extends StatelessWidget { final ListHISGetGlassPerscription glassPerscription; + final int appointmentNo; + final String projectName; + final int projectID; - const ClassesPage({Key key, this.glassPerscription}) : super(key: key); + const ClassesPage( + {Key key, + this.glassPerscription, + this.appointmentNo, + this.projectName, + this.projectID}) + : super(key: key); @override Widget build(BuildContext context) { @@ -38,11 +49,16 @@ class ClassesPage extends StatelessWidget { bold: true, ), ), - getRow(TranslationBase.of(context).sphere, '${glassPerscription.rightEyeSpherical}', '-'), - getRow(TranslationBase.of(context).cylinder, '${glassPerscription.rightEyeCylinder}', '-'), - getRow(TranslationBase.of(context).axis, '${glassPerscription.rightEyeAxis}', '-'), - getRow(TranslationBase.of(context).prism, '${glassPerscription.rightEyePrism}', '-'), - getRow(TranslationBase.of(context).va, '${glassPerscription.rightEyeVA}', '-'), + getRow(TranslationBase.of(context).sphere, + '${glassPerscription.rightEyeSpherical}', '-'), + getRow(TranslationBase.of(context).cylinder, + '${glassPerscription.rightEyeCylinder}', '-'), + getRow(TranslationBase.of(context).axis, + '${glassPerscription.rightEyeAxis}', '-'), + getRow(TranslationBase.of(context).prism, + '${glassPerscription.rightEyePrism}', '-'), + getRow(TranslationBase.of(context).va, + '${glassPerscription.rightEyeVA}', '-'), ], ), ), @@ -65,11 +81,16 @@ class ClassesPage extends StatelessWidget { bold: true, ), ), - getRow(TranslationBase.of(context).sphere, '${glassPerscription.leftEyeSpherical}', '-'), - getRow(TranslationBase.of(context).cylinder, '${glassPerscription.leftEyeCylinder}', '-'), - getRow(TranslationBase.of(context).axis, '${glassPerscription.leftEyeAxis}', '-'), - getRow(TranslationBase.of(context).prism, '${glassPerscription.leftEyePrism}', '-'), - getRow(TranslationBase.of(context).va, '${glassPerscription.leftEyeVA}', '-'), + getRow(TranslationBase.of(context).sphere, + '${glassPerscription.leftEyeSpherical}', '-'), + getRow(TranslationBase.of(context).cylinder, + '${glassPerscription.leftEyeCylinder}', '-'), + getRow(TranslationBase.of(context).axis, + '${glassPerscription.leftEyeAxis}', '-'), + getRow(TranslationBase.of(context).prism, + '${glassPerscription.leftEyePrism}', '-'), + getRow(TranslationBase.of(context).va, + '${glassPerscription.leftEyeVA}', '-'), ], ), ), @@ -80,6 +101,16 @@ class ClassesPage extends StatelessWidget { width: double.infinity, child: SecondaryButton( label: TranslationBase.of(context).sendEmail, + onTap: () { + showConfirmMessage(context, () async { + GifLoaderDialogUtils.showMyDialog(context); + await model.sendGlassesPrescriptionEmail( + appointmentNo: appointmentNo, + projectName: projectName, + projectID: projectID); + GifLoaderDialogUtils.hideDialog(context); + }, model.user.emailAddress); + }, textColor: Colors.white, color: Colors.red[700], icon: Icon( @@ -96,6 +127,19 @@ class ClassesPage extends StatelessWidget { ); } + void showConfirmMessage( + BuildContext context, GestureTapCallback onTap, String email) { + showDialog( + context: context, + child: ConfirmSendEmailDialog( + email: email, + onTapSendEmail: () { + onTap(); + }, + ), + ); + } + Widget getRow(String title, String val1, String val2) => Padding( padding: const EdgeInsets.all(8.0), child: Column( @@ -113,7 +157,7 @@ class ClassesPage extends StatelessWidget { mainAxisAlignment: MainAxisAlignment.spaceAround, children: [ Texts(val1 == 'null' ? '-' : val1), - Texts(val2 != 'null' ? '-' :val2), + Texts(val2 != 'null' ? '-' : val2), ], ), ) diff --git a/lib/pages/medical/eye/ContactLensPage.dart b/lib/pages/medical/eye/ContactLensPage.dart index 373c3c79..b70b9c09 100644 --- a/lib/pages/medical/eye/ContactLensPage.dart +++ b/lib/pages/medical/eye/ContactLensPage.dart @@ -1,8 +1,12 @@ import 'package:diplomaticquarterapp/core/model/eye/AppoimentAllHistoryResult.dart'; +import 'package:diplomaticquarterapp/core/viewModels/medical/EyeViewModel.dart'; import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; +import 'package:diplomaticquarterapp/pages/base/base_view.dart'; +import 'package:diplomaticquarterapp/uitl/gif_loader_dialog_utils.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/widgets/buttons/secondary_button.dart'; import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; +import 'package:diplomaticquarterapp/widgets/dialogs/confirm_send_email_dialog.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; @@ -10,95 +14,126 @@ import 'package:provider/provider.dart'; class ContactLensPage extends StatelessWidget { final ListHISGetContactLensPerscription listHISGetContactLensPerscription; + final int appointmentNo; + final String projectName; + final int projectID; - const ContactLensPage({Key key, this.listHISGetContactLensPerscription}) + const ContactLensPage( + {Key key, + this.listHISGetContactLensPerscription, + this.appointmentNo, + this.projectName, + this.projectID}) : super(key: key); @override Widget build(BuildContext context) { ProjectViewModel projectViewModel = Provider.of(context); - return AppScaffold( - body: SingleChildScrollView( - child: Container( - margin: EdgeInsets.only(top: 70, left: 15, right: 15, bottom: 15), - child: Column( - children: [ - Container( - decoration: BoxDecoration( - shape: BoxShape.rectangle, - borderRadius: BorderRadius.all(Radius.circular(8)), - color: Colors.white), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Padding( - padding: const EdgeInsets.all(8.0), - child: Texts( - TranslationBase.of(context).rightEye, - fontSize: 23, - bold: true, + return BaseView( + builder: (_,model,w)=> + AppScaffold( + body: SingleChildScrollView( + child: Container( + margin: EdgeInsets.only(top: 70, left: 15, right: 15, bottom: 15), + child: Column( + children: [ + Container( + decoration: BoxDecoration( + shape: BoxShape.rectangle, + borderRadius: BorderRadius.all(Radius.circular(8)), + color: Colors.white), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Padding( + padding: const EdgeInsets.all(8.0), + child: Texts( + TranslationBase.of(context).rightEye, + fontSize: 23, + bold: true, + ), ), - ), - getRow(TranslationBase.of(context).brand, '${listHISGetContactLensPerscription.brand}'), - getRow('B.C', '${listHISGetContactLensPerscription.baseCurve}'), - getRow(TranslationBase.of(context).power, '${listHISGetContactLensPerscription.power}'), - getRow(TranslationBase.of(context).diameter, '${listHISGetContactLensPerscription.diameter}'), - getRow('OZ', '${listHISGetContactLensPerscription.oZ}'), - getRow('CT', '${listHISGetContactLensPerscription.cT}'), - getRow('Blend', '${listHISGetContactLensPerscription.blend}'), - getRow(TranslationBase.of(context).reminder, '${listHISGetContactLensPerscription.remarks}'), - - - ], + getRow(TranslationBase.of(context).brand, + '${listHISGetContactLensPerscription.brand}'), + getRow('B.C', + '${listHISGetContactLensPerscription.baseCurve}'), + getRow(TranslationBase.of(context).power, + '${listHISGetContactLensPerscription.power}'), + getRow(TranslationBase.of(context).diameter, + '${listHISGetContactLensPerscription.diameter}'), + getRow('OZ', '${listHISGetContactLensPerscription.oZ}'), + getRow('CT', '${listHISGetContactLensPerscription.cT}'), + getRow( + 'Blend', '${listHISGetContactLensPerscription.blend}'), + getRow(TranslationBase.of(context).reminder, + '${listHISGetContactLensPerscription.remarks}'), + ], + ), ), - ), - SizedBox( - height: 17, - ), - Container( - decoration: BoxDecoration( - shape: BoxShape.rectangle, - borderRadius: BorderRadius.all(Radius.circular(8)), - color: Colors.white), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Padding( - padding: const EdgeInsets.all(8.0), - child: Texts( - TranslationBase.of(context).leftEye, - fontSize: 23, - bold: true, - ), - ), - getRow(TranslationBase.of(context).brand, '${listHISGetContactLensPerscription.brand}'), - getRow('B.C', '${listHISGetContactLensPerscription.baseCurve}'), - getRow(TranslationBase.of(context).power, '${listHISGetContactLensPerscription.power}'), - getRow(TranslationBase.of(context).diameter, '${listHISGetContactLensPerscription.diameter}'), - getRow('OZ', '${listHISGetContactLensPerscription.oZ}'), - getRow('CT', '${listHISGetContactLensPerscription.cT}'), - getRow('Blend', '${listHISGetContactLensPerscription.blend}'), - getRow(TranslationBase.of(context).reminder, '${listHISGetContactLensPerscription.remarks}'), - ], + SizedBox( + height: 17, ), - ), - SizedBox( - height: 17, - ), - if(projectViewModel.havePrivilege(15)) - Container( - width: double.infinity, - child: SecondaryButton( - label: TranslationBase.of(context).sendEmail, - textColor: Colors.white, - color: Colors.red[700], - icon: Icon( - Icons.email, - color: Colors.white, + Container( + decoration: BoxDecoration( + shape: BoxShape.rectangle, + borderRadius: BorderRadius.all(Radius.circular(8)), + color: Colors.white), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Padding( + padding: const EdgeInsets.all(8.0), + child: Texts( + TranslationBase.of(context).leftEye, + fontSize: 23, + bold: true, + ), + ), + getRow(TranslationBase.of(context).brand, + '${listHISGetContactLensPerscription.brand}'), + getRow('B.C', + '${listHISGetContactLensPerscription.baseCurve}'), + getRow(TranslationBase.of(context).power, + '${listHISGetContactLensPerscription.power}'), + getRow(TranslationBase.of(context).diameter, + '${listHISGetContactLensPerscription.diameter}'), + getRow('OZ', '${listHISGetContactLensPerscription.oZ}'), + getRow('CT', '${listHISGetContactLensPerscription.cT}'), + getRow( + 'Blend', '${listHISGetContactLensPerscription.blend}'), + getRow(TranslationBase.of(context).reminder, + '${listHISGetContactLensPerscription.remarks}'), + ], ), ), - ) - ], + SizedBox( + height: 17, + ), + if (projectViewModel.havePrivilege(15)) + Container( + width: double.infinity, + child: SecondaryButton( + label: TranslationBase.of(context).sendEmail, + textColor: Colors.white, + color: Colors.red[700], + onTap: (){ + showConfirmMessage(context, () async { + GifLoaderDialogUtils.showMyDialog(context); + await model.sendContactLensPrescriptionEmail( + appointmentNo: appointmentNo, + projectName: projectName, + projectID: projectID); + GifLoaderDialogUtils.hideDialog(context); + }, model.user.emailAddress); + }, + icon: Icon( + Icons.email, + color: Colors.white, + ), + ), + ) + ], + ), ), ), ), @@ -130,4 +165,18 @@ class ContactLensPage extends StatelessWidget { ], ), ); + + + void showConfirmMessage( + BuildContext context, GestureTapCallback onTap, String email) { + showDialog( + context: context, + child: ConfirmSendEmailDialog( + email: email, + onTapSendEmail: () { + onTap(); + }, + ), + ); + } } diff --git a/lib/pages/medical/eye/EyeHomePage.dart b/lib/pages/medical/eye/EyeHomePage.dart index bce778b8..3af2279e 100644 --- a/lib/pages/medical/eye/EyeHomePage.dart +++ b/lib/pages/medical/eye/EyeHomePage.dart @@ -43,6 +43,7 @@ class _EyeHomePageState extends State Widget build(BuildContext context) { return AppScaffold( isShowAppBar: true, + isShowDecPage: false, appBarTitle: TranslationBase.of(context).measurements, body: Scaffold( extendBodyBehindAppBar: true, @@ -81,13 +82,13 @@ class _EyeHomePageState extends State unselectedLabelColor: Colors.grey[800], tabs: [ Container( - width: MediaQuery.of(context).size.width * 0.27, + width: MediaQuery.of(context).size.width * 0.40, child: Center( child: Texts(TranslationBase.of(context).classes), ), ), Container( - width: MediaQuery.of(context).size.width * 0.27, + width: MediaQuery.of(context).size.width * 0.40, child: Center( child: Texts(TranslationBase.of(context).contactLens), ), @@ -110,11 +111,15 @@ class _EyeHomePageState extends State ClassesPage( glassPerscription: widget.appointmentAllHistoryResultList .listHISGetGlassPerscription[0], + appointmentNo: widget.appointmentAllHistoryResultList.appointmentNo, + projectName: widget.appointmentAllHistoryResultList.projectName, + projectID: widget.appointmentAllHistoryResultList.projectID, ), ContactLensPage( - listHISGetContactLensPerscription: widget - .appointmentAllHistoryResultList - .listHISGetContactLensPerscription[0], + listHISGetContactLensPerscription: widget.appointmentAllHistoryResultList.listHISGetContactLensPerscription[0], + appointmentNo: widget.appointmentAllHistoryResultList.appointmentNo, + projectName: widget.appointmentAllHistoryResultList.projectName, + projectID: widget.appointmentAllHistoryResultList.projectID, ) ], ), diff --git a/lib/pages/medical/prescriptions/PrescriptionIDeliveryAddressPage.dart b/lib/pages/medical/prescriptions/PrescriptionIDeliveryAddressPage.dart index 88234fe5..8f04d3a0 100644 --- a/lib/pages/medical/prescriptions/PrescriptionIDeliveryAddressPage.dart +++ b/lib/pages/medical/prescriptions/PrescriptionIDeliveryAddressPage.dart @@ -4,6 +4,7 @@ import 'package:diplomaticquarterapp/core/model/prescriptions/Prescriptions.dart import 'package:diplomaticquarterapp/core/model/prescriptions/prescription_report.dart'; import 'package:diplomaticquarterapp/core/model/prescriptions/prescription_report_enh.dart'; import 'package:diplomaticquarterapp/core/service/AlHabibMedicalService/customer_addresses_service.dart'; +import 'package:diplomaticquarterapp/core/viewModels/AlHabibMedicalService/add_new_address_Request_Model.dart'; import 'package:diplomaticquarterapp/core/viewModels/medical/PrescriptionDeliveryViewModel.dart'; import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; import 'package:diplomaticquarterapp/pages/AlHabibMedicalService/HomeHealthCare/NewHomeHealthCare/location_page.dart'; @@ -212,7 +213,51 @@ class _PrescriptionDeliveryAddressPageState latitude: latitude, longitude: longitude, )), - ); + ).then((value) { + if (value != null && + value is AddNewAddressRequestModel) { + setState(() { + _selectedAddress = AddressInfo( + id: value.customer.id.toString(), + email: value.customer.email, + firstName: value.customer.addresses[0].firstName, + lastName: value.customer.addresses[0].lastName, + address1: value.customer.addresses[0].address1, + address2: value.customer.addresses[0].address2, + city: value.customer.addresses[0].city, + country: value.customer.addresses[0].country, + phoneNumber: value.customer.addresses[0].phoneNumber, + latLong: value.customer.addresses[0].latLong, + company: value.customer.addresses[0].company, + countryId: value.customer.addresses[0].countryId, + createdOnUtc: value.customer.addresses[0].createdOnUtc, + customerAttributes: value.customer.addresses[0].customerAttributes, + faxNumber: value.customer.addresses[0].faxNumber, + province: value.customer.addresses[0].province, + stateProvinceId: value.customer.addresses[0].stateProvinceId, + zipPostalCode: value.customer.addresses[0].zipPostalCode, + + ); + List latLongArr = _selectedAddress.latLong.split(','); + + latitude = double.parse(latLongArr[0]); + longitude = double.parse(latLongArr[1]); + markers = Set(); + markers.add( + Marker( + markerId: MarkerId( + _selectedAddress.latLong.hashCode.toString(), + ), + position: LatLng(latitude, longitude), + ), + ); + _kGooglePlex = CameraPosition( + target: LatLng(latitude, longitude), + zoom: 14.4746, + ); + }); + } + }); }, ), ), diff --git a/lib/pages/medical/prescriptions/pharmacy_for_prescriptions_page.dart b/lib/pages/medical/prescriptions/pharmacy_for_prescriptions_page.dart index 1b1eaf3f..96227fba 100644 --- a/lib/pages/medical/prescriptions/pharmacy_for_prescriptions_page.dart +++ b/lib/pages/medical/prescriptions/pharmacy_for_prescriptions_page.dart @@ -20,7 +20,7 @@ class PharmacyForPrescriptionsPage extends StatelessWidget { onModelReady: (model) => model.getListPharmacyForPrescriptions(itemId: prescriptionReport.itemID), builder: (_, model, widget) => AppScaffold( isShowAppBar: true, - appBarTitle: TranslationBase.of(context).ports, + appBarTitle: TranslationBase.of(context).availability, baseViewModel: model, body: ListView.builder( itemBuilder: (context, index) => Container( diff --git a/lib/pages/medical/prescriptions/prescription_details_page.dart b/lib/pages/medical/prescriptions/prescription_details_page.dart index d59bc06d..f40999c2 100644 --- a/lib/pages/medical/prescriptions/prescription_details_page.dart +++ b/lib/pages/medical/prescriptions/prescription_details_page.dart @@ -1,4 +1,6 @@ import 'package:diplomaticquarterapp/core/model/prescriptions/prescription_report.dart'; +import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; +import 'package:diplomaticquarterapp/pages/MyAppointments/widgets/reminder_dialog.dart'; import 'package:diplomaticquarterapp/pages/medical/prescriptions/pharmacy_for_prescriptions_page.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; @@ -6,6 +8,7 @@ import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; +import 'package:provider/provider.dart'; class PrescriptionDetailsPage extends StatelessWidget { final PrescriptionReport prescriptionReport; @@ -59,40 +62,49 @@ class PrescriptionDetailsPage extends StatelessWidget { ), Container( margin: EdgeInsets.all(8), - child: InkWell( - onTap: () => Navigator.push( - context, - FadePage( - page: PharmacyForPrescriptionsPage( - prescriptionReport: prescriptionReport), - ), - ), - child: Center( - child: Column( - children: [ - Container( - width: 50, - decoration: BoxDecoration( - color: Colors.white, shape: BoxShape.rectangle), + child: Row( + children: [ + Expanded( + child: InkWell( + onTap: () => Navigator.push( + context, + FadePage( + page: PharmacyForPrescriptionsPage( + prescriptionReport: prescriptionReport), + ), + ), + child: Center( child: Column( children: [ - Icon( - Icons.pin_drop, - color: Colors.red[800], - size: 55, + Container( + width: 50, + decoration: BoxDecoration( + color: Colors.white, + shape: BoxShape.rectangle), + child: Column( + children: [ + Icon( + Icons.pin_drop, + color: Colors.red[800], + size: 55, + ), + ], + ), + ), + SizedBox( + height: 5, ), + Texts(TranslationBase.of(context).availability) ], ), - ), - SizedBox( - height: 5, - ), - Texts(TranslationBase.of(context).ports) - ], - ), - )), + )), + ), + _addReminderButton(context) + ], + ), ), Container( + color: Colors.white, margin: EdgeInsets.only(top: 10, left: 10, right: 10), child: Table( border: TableBorder.symmetric( @@ -106,28 +118,28 @@ class PrescriptionDetailsPage extends StatelessWidget { height: 30, width: double.infinity, child: Center( - child: Texts(TranslationBase.of(context).way))), + child: Texts(TranslationBase.of(context).route, fontSize: 14,))), Container( color: Colors.white, height: 30, width: double.infinity, child: Center( child: - Texts(TranslationBase.of(context).average))), + Texts(TranslationBase.of(context).frequency, fontSize: 14,))), Container( color: Colors.white, - height: 30, width: double.infinity, + padding: EdgeInsets.symmetric(horizontal: 4), child: Center( child: Texts( - TranslationBase.of(context).dailyDoses))), + "${TranslationBase.of(context).dailyDoses}", fontSize: 14,))), Container( color: Colors.white, height: 30, width: double.infinity, child: Center( child: - Texts(TranslationBase.of(context).period))), + Texts(TranslationBase.of(context).duration, fontSize: 14,))), ], ), TableRow( @@ -192,4 +204,96 @@ class PrescriptionDetailsPage extends StatelessWidget { ), ); } + + Widget _addReminderButton(BuildContext context) { + ProjectViewModel projectViewModel = Provider.of(context); + + return GestureDetector( + onTap: () { + DateTime startDate = DateTime.now(); + DateTime endDate = DateTime(startDate.year, startDate.month, + startDate.day + prescriptionReport.days); + + print(prescriptionReport); + showGeneralDialog( + barrierColor: Colors.black.withOpacity(0.5), + transitionBuilder: (context, a1, a2, widget) { + final curvedValue = + Curves.easeInOutBack.transform(a1.value) - 1.0; + return Transform( + transform: + Matrix4.translationValues(0.0, curvedValue * 200, 0.0), + child: Opacity( + opacity: a1.value, + child: ReminderDialog( + eventId: prescriptionReport.itemID.toString(), + title: "Prescription Reminder", + description: + "${prescriptionReport.itemDescriptionN} ${prescriptionReport.frequencyN} ${prescriptionReport.routeN} ", + startDate: + "/Date(${startDate.millisecondsSinceEpoch}+0300)/", + endDate: "/Date(${endDate.millisecondsSinceEpoch}+0300)/", + location: prescriptionReport.remarks, + ), + ), + ); + }, + transitionDuration: Duration(milliseconds: 500), + barrierDismissible: true, + barrierLabel: '', + context: context, + pageBuilder: (context, animation1, animation2) {}); + }, + child: Column( + mainAxisSize: MainAxisSize.max, + children: [ + Container( + // height: 100.0, + margin: EdgeInsets.all(7.0), + padding: EdgeInsets.only(bottom: 4.0), + decoration: BoxDecoration(boxShadow: [ + BoxShadow( + color: Colors.grey[400], blurRadius: 2.0, spreadRadius: 0.0) + ], borderRadius: BorderRadius.circular(10), color: Colors.white), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisSize: MainAxisSize.max, + children: [ + Container( + margin: EdgeInsets.fromLTRB(5.0, 5.0, 5.0, 0.0), + child: Text("add", + overflow: TextOverflow.clip, + style: TextStyle( + color: new Color(0xffB8382C), + letterSpacing: 1.0, + fontSize: 18.0)), + ), + Container( + margin: EdgeInsets.fromLTRB(5.0, 0.0, 5.0, 0.0), + child: Text("reminder", + overflow: TextOverflow.clip, + style: TextStyle( + color: Colors.black, + letterSpacing: 1.0, + fontSize: 15.0)), + ), + Container( + alignment: projectViewModel.isArabic + ? Alignment.bottomLeft + : Alignment.bottomRight, + margin: projectViewModel.isArabic + ? EdgeInsets.fromLTRB(10.0, 7.0, 0.0, 8.0) + : EdgeInsets.fromLTRB(0.0, 7.0, 10.0, 8.0), + child: Image.asset( + "assets/images/new-design/reminder_icon.png", + width: 45.0, + height: 45.0), + ), + ], + ), + ), + ], + ), + ); + } } diff --git a/lib/pages/medical/reports/report_home_page.dart b/lib/pages/medical/reports/report_home_page.dart index 42dcf40a..f9efb1a1 100644 --- a/lib/pages/medical/reports/report_home_page.dart +++ b/lib/pages/medical/reports/report_home_page.dart @@ -106,26 +106,26 @@ class _HomeReportPageState extends State unselectedLabelColor: Colors.grey[800], tabs: [ Container( - width: MediaQuery.of(context).size.width * 0.15, + width: MediaQuery.of(context).size.width * 0.20, child: Center( child: Texts(TranslationBase.of(context).requested,fontSize: 11,), ), ), Container( - width: MediaQuery.of(context).size.width * 0.15, + width: MediaQuery.of(context).size.width * 0.20, child: Center( child: Texts(TranslationBase.of(context).ready,fontSize: 11,), ), ), Container( - width: MediaQuery.of(context).size.width * 0.15, + width: MediaQuery.of(context).size.width * 0.20, child: Center( child: Texts(TranslationBase.of(context).completed,fontSize: 11,), ), ), Container( - width: MediaQuery.of(context).size.width * 0.15, + width: MediaQuery.of(context).size.width * 0.20, child: Center( child: Texts(TranslationBase.of(context).cancelled,fontSize: 11,), diff --git a/lib/pages/medical/reports/reports_page.dart b/lib/pages/medical/reports/reports_page.dart index d8cb2ca0..11d5fc82 100644 --- a/lib/pages/medical/reports/reports_page.dart +++ b/lib/pages/medical/reports/reports_page.dart @@ -48,16 +48,13 @@ class MedicalReports extends StatelessWidget { )), child: Row( children: [ - Expanded( - flex: 1, - child: Container( - margin: EdgeInsets.only(left: 5, right: 5), - child: LargeAvatar( - width: 50, - height: 50, - name: model.appointHistoryList[index].doctorNameObj, - url: model.appointHistoryList[index].doctorImageURL, - ), + Container( + margin: EdgeInsets.only(left: 5, right: 5), + child: LargeAvatar( + width: 50, + height: 50, + name: model.appointHistoryList[index].doctorNameObj, + url: model.appointHistoryList[index].doctorImageURL, ), ), Expanded( @@ -85,29 +82,26 @@ class MedicalReports extends StatelessWidget { ), ), ), - Expanded( - flex: 1, - child: InkWell( - onTap: () => - confirmBox(model.appointHistoryList[index], model), - child: Container( - width: 85, - height: 50, - decoration: BoxDecoration( - color: Colors.black54, - border: - Border.all(color: Colors.transparent, width: 2), - shape: BoxShape.rectangle, - borderRadius: BorderRadius.all( - Radius.circular(8.0), - ), + InkWell( + onTap: () => + confirmBox(model.appointHistoryList[index], model), + child: Container( + width: 120, + height: 50, + decoration: BoxDecoration( + color: Colors.black54, + border: + Border.all(color: Colors.transparent, width: 2), + shape: BoxShape.rectangle, + borderRadius: BorderRadius.all( + Radius.circular(8.0), ), - child: Center( - child: Texts( - TranslationBase.of(context).requestReport, - fontSize: 12, - color: Colors.white, - ), + ), + child: Center( + child: Texts( + TranslationBase.of(context).requestReport, + fontSize: 12, + color: Colors.white, ), ), ), diff --git a/lib/pages/medical/vital_sign/LineChartCurved.dart b/lib/pages/medical/vital_sign/LineChartCurved.dart index f2bc3d5f..fe112767 100644 --- a/lib/pages/medical/vital_sign/LineChartCurved.dart +++ b/lib/pages/medical/vital_sign/LineChartCurved.dart @@ -14,10 +14,18 @@ class LineChartCurved extends StatelessWidget { List xAxixs = List(); List yAxixs = List(); + double minY = 0; + double maxY = 0; + + double minX = 0; + double maxX = 0; + double increasingY = 0; + @override Widget build(BuildContext context) { getXaxix(); getYaxix(); + calculateMaxAndMin(); return AspectRatio( aspectRatio: 1.1, child: Container( @@ -70,10 +78,18 @@ class LineChartCurved extends StatelessWidget { } } } + getYaxix() { - int indexess= (timeSeries.length*0.30).toInt(); + // int indexess= (timeSeries.length*0.30).toInt(); + // for (int index = 0; index < timeSeries.length; index++) { + // int mIndex = indexess * index; + // if (mIndex < timeSeries.length) { + // yAxixs.add(timeSeries[mIndex].sales); + // } + // } + for (int index = 0; index < timeSeries.length; index++) { - int mIndex = indexess * index; + int mIndex = indexes * index; if (mIndex < timeSeries.length) { yAxixs.add(timeSeries[mIndex].sales); } @@ -100,7 +116,6 @@ class LineChartCurved extends StatelessWidget { fontSize: 10, ), rotateAngle:-65, - //rotateAngle:-65, margin: 22, getTitles: (value) { if (timeSeries.length < 15) { @@ -128,18 +143,18 @@ class LineChartCurved extends StatelessWidget { fontSize: 10, ), getTitles: (value) { - // if (timeSeries.length < 10) { - // return '${value.toInt()}'; - // } else { - // if (value == getMinY()) - // return '${value.toInt()}'; - // if (value == getMaxY()) - // return '${value.toInt()}'; - // if (yAxixs.contains(value)) { - // return '${value.toInt()}'; - // } - // return ''; - // } + if (timeSeries.length < 15) { + return '${value.toInt()}'; + } else { + if (value == minY) + return '${value.toInt()}'; + if (value == getMaxY()) + return '${value.toInt()}'; + //if (yAxixs.contains(value)) { + return '${value.toInt()}'; + + return ''; + } return '${value.toInt()}'; }, margin: 12, @@ -163,31 +178,55 @@ class LineChartCurved extends StatelessWidget { ), ), ), - minX: 0, - maxX: (timeSeries.length - 1).toDouble(), - maxY: getMaxY()+0.3, - minY: getMinY(), + minX: minX, + maxX: maxX, + maxY: maxY, + minY: minY, lineBarsData: getData(context), ); } + calculateMaxAndMin(){ + getMaxY(); + getMaxX(); + getMin(); + getMinY(); + increasingY = ((maxY-minY)/timeSeries.length - 1)*15; + maxY += increasingY.abs(); + minY -= increasingY.abs(); + } + double getMaxY() { - double max = 0; + maxY = 0; + timeSeries.forEach((element) { + double resultValueDouble = element.sales; + if (resultValueDouble > maxY) maxY = resultValueDouble; + }); + + return maxY.roundToDouble() ; + } + + getMaxX(){ + maxX = (timeSeries.length - 1).toDouble(); + } + + double getMin(){ + minX = 0; timeSeries.forEach((element) { double resultValueDouble = element.sales; - if (resultValueDouble > max) max = resultValueDouble; + if (resultValueDouble < minX) minX = resultValueDouble; }); - return max.roundToDouble() ; + return minX.roundToDouble() ; } double getMinY() { - double min = timeSeries[0].sales; + minY = 0; timeSeries.forEach((element) { double resultValueDouble = element.sales; - if (resultValueDouble < min) min = resultValueDouble; + if (resultValueDouble < minY) minY = resultValueDouble; }); - int value = min.toInt(); + int value = minY.toInt(); return value.toDouble(); } @@ -202,7 +241,7 @@ class LineChartCurved extends StatelessWidget { spots: spots, isCurved: true, colors: [secondaryColor], - barWidth: 5, + barWidth: 3, isStrokeCapRound: true, dotData: FlDotData( show: false, diff --git a/lib/pages/medical/vital_sign/LineChartCurvedBloodPressure.dart b/lib/pages/medical/vital_sign/LineChartCurvedBloodPressure.dart index fa177b1a..2d95f08c 100644 --- a/lib/pages/medical/vital_sign/LineChartCurvedBloodPressure.dart +++ b/lib/pages/medical/vital_sign/LineChartCurvedBloodPressure.dart @@ -81,7 +81,7 @@ class LineChartCurvedBloodPressure extends StatelessWidget { height: 20, decoration: BoxDecoration( shape: BoxShape.rectangle, - color: Colors.grey), + color: Colors.red), ), SizedBox(width: 5,), Texts(TranslationBase.of(context).diastolicLng) @@ -125,7 +125,6 @@ class LineChartCurvedBloodPressure extends StatelessWidget { fontSize: 10, ), rotateAngle: -65, - //rotateAngle:-65, margin: 22, getTitles: (value) { if (timeSeries1.length < 15) { @@ -178,8 +177,8 @@ class LineChartCurvedBloodPressure extends StatelessWidget { ), minX: 0, maxX: (timeSeries1.length - 1).toDouble(), - maxY: getMaxY() + 0.3, - minY: getMinY(), + maxY: getMaxY() + 15, + minY: getMinY()-15, lineBarsData: getData(context), ); } diff --git a/lib/pages/packages_offers/ClinicOfferAndPackagesPage.dart b/lib/pages/packages_offers/ClinicOfferAndPackagesPage.dart new file mode 100644 index 00000000..76688606 --- /dev/null +++ b/lib/pages/packages_offers/ClinicOfferAndPackagesPage.dart @@ -0,0 +1,108 @@ +import 'package:after_layout/after_layout.dart'; +import 'package:carousel_slider/carousel_slider.dart'; +import 'package:diplomaticquarterapp/core/model/packages_offers/requests/AddProductToCartRequestModel.dart'; +import 'package:diplomaticquarterapp/core/model/packages_offers/requests/OffersCategoriesRequestModel.dart'; +import 'package:diplomaticquarterapp/core/model/packages_offers/requests/OffersProductsRequestModel.dart'; +import 'package:diplomaticquarterapp/core/model/packages_offers/responses/PackagesCategoriesResponseModel.dart'; +import 'package:diplomaticquarterapp/core/model/packages_offers/responses/PackagesResponseModel.dart'; +import 'package:diplomaticquarterapp/core/viewModels/packages_offers/PackagesOffersViewModel.dart'; +import 'package:diplomaticquarterapp/core/viewModels/pharmacyModule/order_model_view_model.dart'; +import 'package:diplomaticquarterapp/locator.dart'; +import 'package:diplomaticquarterapp/pages/base/base_view.dart'; +import 'package:diplomaticquarterapp/pages/packages_offers/OfferAndPackageDetailPage.dart'; +import 'package:diplomaticquarterapp/uitl/gif_loader_dialog_utils.dart'; +import 'package:diplomaticquarterapp/uitl/utils.dart' as utils; +import 'package:diplomaticquarterapp/widgets/loadings/ShimmerLoading.dart'; +import 'package:diplomaticquarterapp/widgets/offers_packages/PackagesOfferCard.dart'; +import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; +import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import 'package:diplomaticquarterapp/config/shared_pref_kay.dart'; +import 'package:flutter/rendering.dart'; +import 'package:flutter_material_pickers/flutter_material_pickers.dart'; +import 'package:flutter_staggered_grid_view/flutter_staggered_grid_view.dart'; + +import 'CreateCustomerDailogPage.dart'; + +dynamic languageID; + +class ClinicPackagesPage extends StatefulWidget { + List products; + ClinicPackagesPage({@required this.products}); + + @override + _ClinicPackagesPageState createState() => _ClinicPackagesPageState(); + + +} + +class _ClinicPackagesPageState extends State with AfterLayoutMixin{ + AppScaffold appScaffold; + + List get _products => widget.products; + PackagesViewModel viewModel; + + + onProductCartClick(PackagesResponseModel product) async { + if(viewModel.service.customer == null) + viewModel.service.customer = await CreateCustomerDialogPage(context: context).show(); + + if(viewModel.service.customer != null) { + var request = AddProductToCartRequestModel(product_id: product.id, customer_id: viewModel.service.customer.id); + await viewModel.service.addProductToCart(request, context: context).then((response){ + appScaffold.appBar.badgeUpdater(viewModel.service.cartItemCount); + }).catchError((error) { + utils.Utils.showErrorToast(error); + }); + } + } + + + @override + void afterFirstLayout(BuildContext context) async{ + appScaffold.appBar.badgeUpdater(viewModel.service.cartItemCount); + } + + @override + void initState() { + super.initState(); + } + + + @override + Widget build(BuildContext context) { + + return BaseView( + allowAny: true, + onModelReady: (model){ + viewModel = model; + }, + builder: (_, model, wi) => appScaffold = AppScaffold( + appBarTitle: TranslationBase.of(context).offerAndPackages, + isShowAppBar: true, + isPharmacy: false, + showPharmacyCart: false, + showHomeAppBarIcon: false, + isOfferPackages: true, + showOfferPackagesCart: true, + isShowDecPage: false, + body: Padding( + padding: const EdgeInsets.all(5), + child: StaggeredGridView.countBuilder( + crossAxisCount:4, + itemCount: _products.length, + itemBuilder: (BuildContext context, int index) => new Container( + color: Colors.transparent, + child: PackagesItemCard( itemContentPadding: 10,itemModel: _products[index], onCartClick: onProductCartClick,) + ), + staggeredTileBuilder: (int index) => StaggeredTile.fit(2), + mainAxisSpacing: 20, + crossAxisSpacing: 10, + ) + ), + ), + ); + } + +} diff --git a/lib/pages/packages_offers/CreateCustomerDailogPage.dart b/lib/pages/packages_offers/CreateCustomerDailogPage.dart new file mode 100644 index 00000000..73e95d09 --- /dev/null +++ b/lib/pages/packages_offers/CreateCustomerDailogPage.dart @@ -0,0 +1,198 @@ +import 'package:after_layout/after_layout.dart'; +import 'package:carousel_slider/carousel_slider.dart'; +import 'package:diplomaticquarterapp/config/size_config.dart'; +import 'package:diplomaticquarterapp/core/model/packages_offers/requests/AddProductToCartRequestModel.dart'; +import 'package:diplomaticquarterapp/core/model/packages_offers/requests/CreateCustomerRequestModel.dart'; +import 'package:diplomaticquarterapp/core/model/packages_offers/requests/OffersCategoriesRequestModel.dart'; +import 'package:diplomaticquarterapp/core/model/packages_offers/requests/OffersProductsRequestModel.dart'; +import 'package:diplomaticquarterapp/core/model/packages_offers/responses/PackagesCustomerResponseModel.dart'; +import 'package:diplomaticquarterapp/core/model/packages_offers/responses/PackagesResponseModel.dart'; +import 'package:diplomaticquarterapp/core/viewModels/packages_offers/PackagesOffersViewModel.dart'; +import 'package:diplomaticquarterapp/core/viewModels/pharmacyModule/order_model_view_model.dart'; +import 'package:diplomaticquarterapp/locator.dart'; +import 'package:diplomaticquarterapp/pages/base/base_view.dart'; +import 'package:diplomaticquarterapp/pages/packages_offers/ClinicOfferAndPackagesPage.dart'; +import 'package:diplomaticquarterapp/pages/packages_offers/OfferAndPackageDetailPage.dart'; +import 'package:diplomaticquarterapp/pages/packages_offers/OfferAndPackagesCartPage.dart'; +import 'package:diplomaticquarterapp/uitl/gif_loader_dialog_utils.dart'; +import 'package:diplomaticquarterapp/uitl/utils.dart' as utils; +import 'package:diplomaticquarterapp/widgets/AnimatedTextFields.dart'; +import 'package:diplomaticquarterapp/widgets/Loader/gif_loader_container.dart'; +import 'package:diplomaticquarterapp/widgets/LoadingButton.dart'; +import 'package:diplomaticquarterapp/widgets/carousel_indicator/carousel_indicator.dart'; +import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; +import 'package:diplomaticquarterapp/widgets/loadings/ShimmerLoading.dart'; +import 'package:diplomaticquarterapp/widgets/offers_packages/PackagesOfferCard.dart'; +import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; +import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import 'package:diplomaticquarterapp/config/shared_pref_kay.dart'; +import 'package:flutter/rendering.dart'; +import 'package:flutter_material_pickers/flutter_material_pickers.dart'; + +dynamic languageID; +var emailRegex = RegExp(r'^[^\s@]+@[^\s@]+\.[^\s@]+$'); + +class CreateCustomerDialogPage extends StatefulWidget { + final BuildContext context; + CreateCustomerDialogPage({this.context}); + PackagesViewModel viewModel; + + Future show() async{ + await showDialog(context: context, builder: (context ){ + return AlertDialog(content: this, shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(20) + ), elevation: 5, ); + }); + return viewModel.service.customer; + } + + @override + _CreateCustomerDialogPageState createState() => _CreateCustomerDialogPageState(); + +} + +class _CreateCustomerDialogPageState extends State with AfterLayoutMixin, TickerProviderStateMixin{ + AnimationController _loadingController; + AnimationController _submitController; + bool _enableInput = true; + + Interval _nameTextFieldLoadingAnimationInterval = const Interval(0, .85); + + final _phoneFocusNode = FocusNode(); + + @override + void initState() { + _submitController = AnimationController(vsync: this, duration: Duration(milliseconds: 1000),); + super.initState(); + } + + @override + void afterFirstLayout(BuildContext context) async{ + } + + // Controllers + TextEditingController _emailTextController = TextEditingController(); + TextEditingController _phoneTextController = TextEditingController(); + TextEditingController _emailPinTextController = TextEditingController(); + TextEditingController _phonePinTextController = TextEditingController(); + + bool verifyPin = false; + + PackagesViewModel viewModel() => widget.viewModel; + + @override + Widget build(BuildContext context) { + + return BaseView( + allowAny: true, + onModelReady: (model) => widget.viewModel = model, + builder: (_, model, wi) => verifyPin ? verifyPinWidget() : userDetailWidget() + ); + } + + Widget verifyPinWidget(){ + + } + + + Widget userDetailWidget(){ + return + Container( + width: SizeConfig.realScreenWidth * 0.8, + height: 270, + child: Column( + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + Align( + alignment: Alignment.center, + child: Texts("Create Guest Customer", textAlign: TextAlign.center, fontSize: 18, fontWeight: FontWeight.bold,) + ), + SizedBox(height: 30,), + AnimatedTextFormField( + enabled: _enableInput, + controller: _emailTextController, + width: 100, + loadingController: _loadingController, + interval: _nameTextFieldLoadingAnimationInterval, + labelText: "Email", + prefixIcon: Icon(Icons.email), + keyboardType: TextInputType.emailAddress, + textInputAction: TextInputAction.next, + onFieldSubmitted: (value) { + FocusScope.of(context).requestFocus(_phoneFocusNode); + }, + validator: (value){ + return (value.isEmpty || !emailRegex.hasMatch(value)) + ? 'Invalid email!' + : null; + }, + ), + + SizedBox(height: 30,), + AnimatedTextFormField( + enabled: _enableInput, + controller: _phoneTextController, + width: 100, + loadingController: _loadingController, + interval: _nameTextFieldLoadingAnimationInterval, + labelText: "Mobile Number", + prefixIcon: Icon(Icons.phone_android), + keyboardType: TextInputType.phone, + textInputAction: TextInputAction.next, + onFieldSubmitted: (value) { + FocusScope.of(context).requestFocus(_phoneFocusNode); + }, + validator: (value){ + return (value.isEmpty || !emailRegex.hasMatch(value)) + ? 'Invalid email!' + : null; + }, + ), + Spacer(flex: 1,), + + AnimatedButton( + color: Theme.of(context).primaryColor, + loadingColor: Theme.of(context).primaryColor, + controller: _submitController, + text: TranslationBase.of(context).done, + onPressed: (){ + createCustomer(); + }, + ) + + , + ], + ), + ); + } + + createCustomer() async{ + setState(() => _enableInput = false); + + loading(true); + var request = PackagesCustomerRequestModel(email: _emailTextController.text, phoneNumber: _phoneTextController.text); + viewModel().service + .createCustomer(request, context: context, showLoading: false) + .then((value) => success()) + .catchError((error) => showError(error)); + + } + + success() async{ + loading(false); + await Future.delayed(Duration(seconds: 2)); + Navigator.of(context).pop(); + } + + showError(String errorMessage) async{ + loading(false); + setState(() => _enableInput = true); + } + + loading(bool can){ + can ? _submitController.forward() : _submitController.reverse(); + } + +} diff --git a/lib/pages/packages_offers/OfferAndPackageDetailPage.dart b/lib/pages/packages_offers/OfferAndPackageDetailPage.dart new file mode 100644 index 00000000..d0e69d14 --- /dev/null +++ b/lib/pages/packages_offers/OfferAndPackageDetailPage.dart @@ -0,0 +1,221 @@ +import 'package:diplomaticquarterapp/config/shared_pref_kay.dart'; +import 'package:diplomaticquarterapp/core/model/packages_offers/responses/PackagesCategoriesResponseModel.dart'; +import 'package:diplomaticquarterapp/core/viewModels/packages_offers/PackagesOffersViewModel.dart'; +import 'package:diplomaticquarterapp/core/viewModels/pharmacyModule/order_model_view_model.dart'; +import 'package:diplomaticquarterapp/pages/base/base_view.dart'; +import 'package:diplomaticquarterapp/pages/pharmacies/ProductCheckTypeWidget.dart'; +import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; +import 'package:diplomaticquarterapp/uitl/utils.dart' as utils; +import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; +import 'package:diplomaticquarterapp/widgets/others/StarRating.dart'; +import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_svg/flutter_svg.dart'; + +import 'ClinicOfferAndPackagesPage.dart'; + +class OfferAndPackagesDetail extends StatefulWidget{ + final dynamic model; + + const OfferAndPackagesDetail({@required this.model, Key key}) : super(key: key); + + @override + State createState() => OfferAndPackagesDetailState(); +} + + +class OfferAndPackagesDetailState extends State{ + + PackagesViewModel viewModel; + + @override + Widget build(BuildContext context) { + getLanguageID(); + + return BaseView( + onModelReady: (model){ + viewModel = model; + }, + builder: (_, model, wi) => AppScaffold( + appBarTitle: TranslationBase.of(context).offerAndPackages, + isShowAppBar: true, + isPharmacy: false, + showPharmacyCart: false, + showHomeAppBarIcon: false, + isOfferPackages: true, + showOfferPackagesCart: true, + isShowDecPage: false, + body: Stack( + children: [ + Padding( + padding: const EdgeInsets.only(bottom: 60), + child: ListView( + children: [ + Padding( + padding: const EdgeInsets.all(5), + child: Stack( + children: [ + Padding( + padding: const EdgeInsets.all(10), + child: AspectRatio( + aspectRatio: 1/1, + child: utils.applyShadow( + child: ClipRRect( + borderRadius: BorderRadius.circular(10), + child: utils.Utils.loadNetworkImage(url: "https://wallpaperaccess.com/full/30103.jpg",) + ), + ) + ), + ), + Align( + alignment: Alignment.topLeft, + child: Image.asset( + 'assets/images/discount_${'en'}.png', + height: 70, + width: 70, + ), + ), + + ], + + ), + ), + + Padding( + padding: const EdgeInsets.only(left: 20, right: 20, bottom: 20), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Texts( + "Child Dental Offer", + fontSize: 25, + fontWeight: FontWeight.normal, + color: Colors.black, + ), + + Stack( + children: [ + Texts( + "200 SAR", + fontWeight: FontWeight.normal, + decoration: TextDecoration.lineThrough, + color: Colors.grey, + fontSize: 12 + ), + Padding( + padding: const EdgeInsets.only(top: 15), + child: Texts( + "894.99 SAR", + fontWeight: FontWeight.bold, + color: Colors.green, + fontSize: 18 + ), + ), + ], + ), + + StarRating( + size: 20, + totalCount: null, + totalAverage: 5, + forceStars: true), + + + SizedBox(height: 20,), + + + Texts( + "Details", + fontWeight: FontWeight.bold, + color: Colors.grey, + fontSize: 20 + ), + + + + AspectRatio( + aspectRatio: 2/1, + child: Container( + color: Colors.grey[300], + child: Padding( + padding: const EdgeInsets.all(10), + child: Texts("Detail of offers written here"), + ) + ), + ), + + + SizedBox(height: 10,), + ], + ), + ), + ], + ), + ), + + Padding( + padding: const EdgeInsets.all(10), + child: Align( + alignment: Alignment.bottomRight, + child: Row( + children: [ + + Expanded( + child: RaisedButton.icon( + padding: EdgeInsets.only(top: 5, bottom: 5, left: 0, right: 0), + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(8.0), + side: BorderSide(color: Colors.red, width: 0.5) + ), + color: Colors.red, + icon: Icon( + Icons.add_shopping_cart_outlined, + size: 25, + color: Colors.white, + ), + label: Texts( + "Add to Cart", + fontSize: 17, color: Colors.white, fontWeight: FontWeight.normal, + ), + onPressed: (){},), + ), + + SizedBox(width: 15,), + + Expanded( + child: OutlineButton.icon( + padding: EdgeInsets.only(top: 5, bottom: 5, left: 0, right: 0), + borderSide: BorderSide(width: 1.0, color: Colors.red), + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(8.0), + ), + color: Colors.white, + icon: Icon( + Icons.favorite_rounded, + size: 25, + color: Colors.red, + ), + label: Texts( + "Add to Favorites", + fontSize: 17, color: Colors.red, fontWeight: FontWeight.normal + ), + onPressed: (){ + + },), + ), + + ], + ), + ), + ) + + + + ], + ) + ), + ); + } +} + diff --git a/lib/pages/packages_offers/OfferAndPackagesCartPage.dart b/lib/pages/packages_offers/OfferAndPackagesCartPage.dart new file mode 100644 index 00000000..d39f726d --- /dev/null +++ b/lib/pages/packages_offers/OfferAndPackagesCartPage.dart @@ -0,0 +1,405 @@ +import 'package:after_layout/after_layout.dart'; +import 'package:carousel_slider/carousel_slider.dart'; +import 'package:diplomaticquarterapp/core/enum/PaymentOptions.dart'; +import 'package:diplomaticquarterapp/core/model/ResponseModel.dart'; +import 'package:diplomaticquarterapp/core/model/packages_offers/requests/AddProductToCartRequestModel.dart'; +import 'package:diplomaticquarterapp/core/model/packages_offers/requests/OffersCategoriesRequestModel.dart'; +import 'package:diplomaticquarterapp/core/model/packages_offers/requests/OffersProductsRequestModel.dart'; +import 'package:diplomaticquarterapp/core/viewModels/packages_offers/PackagesOffersViewModel.dart'; +import 'package:diplomaticquarterapp/core/viewModels/pharmacyModule/order_model_view_model.dart'; +import 'package:diplomaticquarterapp/locator.dart'; +import 'package:diplomaticquarterapp/pages/base/base_view.dart'; +import 'package:diplomaticquarterapp/pages/packages_offers/ClinicOfferAndPackagesPage.dart'; +import 'package:diplomaticquarterapp/pages/packages_offers/OfferAndPackageDetailPage.dart'; +import 'package:diplomaticquarterapp/pages/packages_offers/PackageOrderCompletedPage.dart'; +import 'package:diplomaticquarterapp/pages/pharmacies/screens/pharmacy-terms-conditions-page.dart'; +import 'package:diplomaticquarterapp/uitl/gif_loader_dialog_utils.dart'; +import 'package:diplomaticquarterapp/uitl/utils.dart' as utils; +import 'package:diplomaticquarterapp/widgets/Loader/gif_loader_container.dart'; +import 'package:diplomaticquarterapp/widgets/carousel_indicator/carousel_indicator.dart'; +import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; +import 'package:diplomaticquarterapp/widgets/in_app_browser/InAppBrowser.dart'; +import 'package:diplomaticquarterapp/widgets/loadings/ShimmerLoading.dart'; +import 'package:diplomaticquarterapp/widgets/offers_packages/PackagesCartItemCard.dart'; +import 'package:diplomaticquarterapp/widgets/offers_packages/PackagesOfferCard.dart'; +import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; +import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; +import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import 'package:diplomaticquarterapp/config/shared_pref_kay.dart'; +import 'package:flutter/rendering.dart'; +import 'package:flutter_material_pickers/flutter_material_pickers.dart'; +import 'package:flutter_staggered_grid_view/flutter_staggered_grid_view.dart'; +import 'package:font_awesome_flutter/font_awesome_flutter.dart'; + +dynamic languageID; +const _columnCount = 1; + +AnimationController _animationController; + +class PackagesCartPage extends StatefulWidget { + PackagesCartPage(); + + @override + _PackagesCartPageState createState() => _PackagesCartPageState(); +} + +class _PackagesCartPageState extends State with AfterLayoutMixin, SingleTickerProviderStateMixin { + getLanguageID() async { + languageID = await sharedPref.getString(APP_LANGUAGE); + } + + @override + void initState() { + _agreeTerms = false; + _selectedPaymentMethod = null; + _animationController = AnimationController(vsync: this, duration: Duration(seconds: 500)); + super.initState(); + } + + @override + void dispose() { + _animationController.dispose(); + viewModel.cartItemList.clear(); + super.dispose(); + } + + PackagesViewModel viewModel; + + bool loadWidgets = false; + + onTermsClick(bool isAgree) { + setState(() => _agreeTerms = isAgree); + } + + onTermsInfoClick() { + Navigator.push(context, FadePage(page: PharmacyTermsConditions())); + } + + onPayNowClick() async{ + await viewModel.service.placeOrder(context: context,paymentOption: _selectedPaymentMethod.toUpperCase()).then((orderId){ + if(orderId.runtimeType == int){ // result == order_id + var browser = MyInAppBrowser( + context: context, + onExitCallback: (data, isDone) => paymentClosed(orderId: orderId, withStatus: isDone, data: data) + ); + browser.openPackagesPaymentBrowser(customer_id: viewModel.service.customer.id, order_id: orderId); + + }else{ + utils.Utils.showErrorToast('Failed to place order, please try again later'); + } + + }).catchError((error){ + utils.Utils.showErrorToast(error); + }); + } + + @override + void afterFirstLayout(BuildContext context) { + fetchData(); + } + + @override + Widget build(BuildContext context) { + return BaseView( + allowAny: true, + onModelReady: (model) => viewModel = model, + builder: (_, model, wi) { + return AppScaffold( + appBarTitle: TranslationBase.of(context).offerAndPackages, + isShowAppBar: true, + isPharmacy: false, + showPharmacyCart: false, + showHomeAppBarIcon: false, + isOfferPackages: true, + showOfferPackagesCart: false, + isShowDecPage: false, + body: Column( + children: [ + Expanded( + child: Padding( + padding: const EdgeInsets.all(5), + child: StaggeredGridView.countBuilder( + crossAxisCount: (_columnCount * _columnCount), + itemCount: viewModel.cartItemList.length, + itemBuilder: (BuildContext context, int index) { + + var item = viewModel.cartItemList[index]; + return Dismissible( + key: Key(index.toString()), + direction: DismissDirection.startToEnd, + background: _cartItemDeleteContainer(), + secondaryBackground: _cartItemDeleteContainer(), + confirmDismiss: (direction) async { + bool status = await viewModel.service.deleteProductFromCart(item.id, context: context, showLoading: false); + return status; + }, + onDismissed: (direction) { + debugPrint('Index: $index'); + viewModel.cartItemList.removeAt(index); + }, + child: PackagesCartItemCard( + itemModel: item, + shouldStepperChangeApply: (apply,total) async{ + var request = AddProductToCartRequestModel(product_id: item.productId, quantity: apply); + ResponseModel response = await viewModel.service.addProductToCart(request, context: context, showLoading: false).catchError((error){ + utils.Utils.showErrorToast(error); + }); + return response.status ?? false; + }, + ) + ); + }, + staggeredTileBuilder: (int index) => StaggeredTile.fit(_columnCount), + mainAxisSpacing: 0, + crossAxisSpacing: 10, + )), + ), + Container( + height: 0.25, + color: Theme.of(context).primaryColor, + ), + Container( + color: Colors.white, + child: Column( + children: [ + Texts( + TranslationBase.of(context).selectPaymentOption, + fontSize: 10, + fontWeight: FontWeight.bold + ), + + Container(height: 0.25, width: 100, color: Colors.grey[300],), + + _paymentOptions(context, (paymentMethod) { + setState(() => _selectedPaymentMethod = paymentMethod); + }), + + Container(height: 0.25, color: Colors.grey[300],), + + Container(height: 40, + child: _termsAndCondition(context, onSelected: onTermsClick, onInfoClick: onTermsInfoClick) + ), + + Container(height: 0.25, color: Colors.grey[300],), + _payNow(context, onPayNowClick: onPayNowClick) + ], + ), + ) + ], + ), + ); + }); + } + + fetchData() async { + await viewModel.service.cartItems(context: context).catchError((error) {}); + setState((){}); + } + + paymentClosed({@required int orderId, @required bool withStatus, dynamic data}) async{ + viewModel.service.getOrderById(orderId, context: context).then((value){ + var heading = withStatus ? "Success" : "Failed"; + var title = "Your order has been placed successfully"; + var subTitle = "Order# ${value.data.customOrderNumber}"; + Navigator.of(context).pushReplacement( + MaterialPageRoute(builder: (context) => PackageOrderCompletedPage(heading: heading, title: title, subTitle: subTitle)) + ); + + }).catchError((error){ + debugPrint(error); + }); + } +} + +// /* Payment Footer Widgets */ +// --------------------------- +String _selectedPaymentMethod; +Widget _paymentOptions(BuildContext context, Function(String) onSelected) { + double height = 30; + + Widget buttonContent(bool isSelected, String imageName) { + return Container( + decoration: BoxDecoration( + color: Colors.white, + boxShadow: [ + BoxShadow( + color: isSelected ? Colors.green[50] : Colors.grey[200], + blurRadius: 1, + spreadRadius: 2, + ), + ], + borderRadius: BorderRadius.all(Radius.circular(5)), + border: Border.all(color: isSelected ? Colors.green : Colors.grey, width: isSelected ? 1 : 0.5) + ), + child: Padding( + padding: const EdgeInsets.all(4), + child: Image.asset('assets/images/new-design/$imageName'), + ) + ); + } + + return Padding( + padding: const EdgeInsets.all(5), + child: Container( + height: height, + color: Colors.transparent, + child: Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + InkWell( + child: buttonContent(_selectedPaymentMethod == "mada", 'mada.png'), + onTap: () { + onSelected("mada"); + }, + ), + SizedBox( + width: 5, + ), + InkWell( + child: buttonContent(_selectedPaymentMethod == "visa", 'visa.png'), + onTap: () { + onSelected("visa"); + }, + ), + SizedBox( + width: 5, + ), + InkWell( + child: buttonContent(_selectedPaymentMethod == "mastercard", 'mastercard.png'), + onTap: () { + onSelected("mastercard"); + }, + ), + SizedBox( + width: 5, + ), + InkWell( + child: buttonContent(_selectedPaymentMethod == "installment", 'installment.png'), + onTap: () { + onSelected("installment"); + }, + ), + ], + ), + ), + ); +} + +bool _agreeTerms = false; +Widget _termsAndCondition(BuildContext context, {@required Function(bool) onSelected, @required VoidCallback onInfoClick}) { + return Padding( + padding: const EdgeInsets.all(5), + child: Row( + children: [ + InkWell( + child: Icon( + _agreeTerms ? Icons.check_circle : Icons.radio_button_unchecked_sharp, + size: 20, + color: _agreeTerms ? Colors.green[600] : Colors.grey[400], + ), + onTap: () { + onSelected(!_agreeTerms); + }, + ), + Expanded( + child: Padding( + padding: const EdgeInsets.symmetric(horizontal: 8), + child: Texts( + TranslationBase.of(context).pharmacyServiceTermsCondition, + fontWeight: FontWeight.normal, fontSize: 13, + ), + )), + InkWell( + child: Icon( + Icons.info, + size: 20, + color: Colors.grey[600], + ), + onTap: () { + onInfoClick(); + }, + ), + ], + ), + ); +} + +Widget _payNow(BuildContext context, {@required VoidCallback onPayNowClick}) { + bool isPayNowAQctive = (_agreeTerms && (_selectedPaymentMethod != null)); + + return Padding( + padding: const EdgeInsets.all(5), + child: Container( + child: Row( + crossAxisAlignment: CrossAxisAlignment.end, + children: [ + Padding( + padding: const EdgeInsets.all(5), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Texts('${TranslationBase.of(context).subtotal}: ${'999.9'} ${TranslationBase.of(context).sar}', + heightFactor: 1.5, fontWeight: FontWeight.bold, color: Colors.grey, fontSize: 8), + Texts('${TranslationBase.of(context).vat}: ${'14.9'} ${TranslationBase.of(context).sar}', heightFactor: 1.5, fontWeight: FontWeight.bold, color: Colors.grey, fontSize: 8), + Padding( + padding: const EdgeInsets.all(3), + child: Container( + height: 0.25, + width: 120, + color: Colors.grey[300], + ), + ), + Texts('${TranslationBase.of(context).total}: 999.99 ${TranslationBase.of(context).sar}', + heightFactor: 1.5, fontWeight: FontWeight.bold, color: Colors.black54, fontSize: 15) + ], + ), + ), + Expanded(child: Container()), + RaisedButton( + child: Texts( + TranslationBase.of(context).payNow, + fontSize: 15, color: Colors.white, fontWeight: FontWeight.bold, + ), + padding: EdgeInsets.only(top: 5, bottom: 5, left: 0, right: 0), + shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(5), side: BorderSide(color: Theme.of(context).primaryColor, width: 0.5)), + color: Theme.of(context).primaryColor, + onPressed: isPayNowAQctive ? onPayNowClick : null, + ), + ], + )), + ); +} +// ------------------- + +Widget _cartItemDeleteContainer() { + _animationController.duration = Duration(milliseconds: 500); + _animationController.repeat(reverse: true); + return FadeTransition( + opacity: _animationController, + child: Padding( + padding: const EdgeInsets.all(5), + child: Container( + decoration: BoxDecoration( + color: Colors.red, + boxShadow: [ + BoxShadow( + color: Colors.grey[500], + blurRadius: 2, + spreadRadius: 1, + ), + ], + borderRadius: BorderRadius.all(Radius.circular(5)), + ), + child: Center( + child: Texts( + "Deleting...", + fontWeight: FontWeight.normal, + fontSize: 15, + color: Colors.white, + )), + ), + ), + ); +} diff --git a/lib/pages/packages_offers/OfferAndPackagesPage.dart b/lib/pages/packages_offers/OfferAndPackagesPage.dart new file mode 100644 index 00000000..c09e10ea --- /dev/null +++ b/lib/pages/packages_offers/OfferAndPackagesPage.dart @@ -0,0 +1,418 @@ +import 'package:after_layout/after_layout.dart'; +import 'package:carousel_slider/carousel_slider.dart'; +import 'package:diplomaticquarterapp/core/model/packages_offers/requests/AddProductToCartRequestModel.dart'; +import 'package:diplomaticquarterapp/core/model/packages_offers/requests/CreateCustomerRequestModel.dart'; +import 'package:diplomaticquarterapp/core/model/packages_offers/requests/OffersCategoriesRequestModel.dart'; +import 'package:diplomaticquarterapp/core/model/packages_offers/requests/OffersProductsRequestModel.dart'; +import 'package:diplomaticquarterapp/core/model/packages_offers/responses/PackagesCustomerResponseModel.dart'; +import 'package:diplomaticquarterapp/core/model/packages_offers/responses/PackagesResponseModel.dart'; +import 'package:diplomaticquarterapp/core/viewModels/packages_offers/PackagesOffersViewModel.dart'; +import 'package:diplomaticquarterapp/core/viewModels/pharmacyModule/order_model_view_model.dart'; +import 'package:diplomaticquarterapp/locator.dart'; +import 'package:diplomaticquarterapp/pages/base/base_view.dart'; +import 'package:diplomaticquarterapp/pages/packages_offers/ClinicOfferAndPackagesPage.dart'; +import 'package:diplomaticquarterapp/pages/packages_offers/CreateCustomerDailogPage.dart'; +import 'package:diplomaticquarterapp/pages/packages_offers/OfferAndPackageDetailPage.dart'; +import 'package:diplomaticquarterapp/pages/packages_offers/OfferAndPackagesCartPage.dart'; +import 'package:diplomaticquarterapp/uitl/gif_loader_dialog_utils.dart'; +import 'package:diplomaticquarterapp/uitl/utils.dart' as utils; +import 'package:diplomaticquarterapp/widgets/Loader/gif_loader_container.dart'; +import 'package:diplomaticquarterapp/widgets/carousel_indicator/carousel_indicator.dart'; +import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; +import 'package:diplomaticquarterapp/widgets/loadings/ShimmerLoading.dart'; +import 'package:diplomaticquarterapp/widgets/offers_packages/PackagesOfferCard.dart'; +import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; +import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import 'package:diplomaticquarterapp/config/shared_pref_kay.dart'; +import 'package:flutter/rendering.dart'; +import 'package:flutter_material_pickers/flutter_material_pickers.dart'; + +dynamic languageID; + +class PackagesHomePage extends StatefulWidget { + dynamic offersModel; + PackagesHomePage({@required this.offersModel}); + + @override + _PackagesHomePageState createState() => _PackagesHomePageState(); + +} + +class _PackagesHomePageState extends State with AfterLayoutMixin{ + getLanguageID() async { + languageID = await sharedPref.getString(APP_LANGUAGE); + } + + @override + void initState() { + super.initState(); + getLanguageID(); + } + + @override + void afterFirstLayout(BuildContext context) async{ + viewModel.service.loadOffersPackagesDataForMainPage(context: context, completion: (){ + setState((){}); + }); + } + + // Controllers + var _searchTextController = TextEditingController(); + var _filterTextController = TextEditingController(); + var _carouselController = CarouselController(); + + + int carouselIndicatorIndex = 0; + CarouselSlider _bannerCarousel; + TextField _textFieldSearch; + TextField _textFieldFilterSelection; + + ListView _listViewLatestOffers; + ListView _listViewBestSeller; + + PackagesViewModel viewModel; + + onCartClick(){ + if (viewModel.service.customer == null){ + utils.Utils.showErrorToast("Cart is empty for your current session"); + return; + } + Navigator.of(context).push( + MaterialPageRoute( + builder: (BuildContext context) => PackagesCartPage() + ) + ); + } + + onProductCartClick(PackagesResponseModel product) async { + if(viewModel.service.customer == null) + viewModel.service.customer = await CreateCustomerDialogPage(context: context).show(); + + if(viewModel.service.customer != null) { + var request = AddProductToCartRequestModel(product_id: product.id, customer_id: viewModel.service.customer.id); + await viewModel.service.addProductToCart(request, context: context).then((response){ + appScaffold.appBar.badgeUpdater(viewModel.service.cartItemCount); + }).catchError((error) { + utils.Utils.showErrorToast(error); + }); + } + } + + AppScaffold appScaffold; + @override + Widget build(BuildContext context) { + return BaseView( + allowAny: true, + onModelReady: (model) => viewModel = model, + builder: (_, model, wi){ + return + appScaffold = + AppScaffold( + appBarTitle: TranslationBase.of(context).offerAndPackages, + isShowAppBar: true, + isPharmacy: false, + showPharmacyCart: false, + showHomeAppBarIcon: false, + isOfferPackages: true, + showOfferPackagesCart: true, + isShowDecPage: false, + body: ListView( + children: [ + + // Top Banner Carousel + AspectRatio( + aspectRatio: 2.2/1, + child: bannerCarousel() + ), + + Center( + child: CarouselIndicator( + activeColor: Theme.of(context).appBarTheme.color, + color: Colors.grey[300], + cornerRadius: 15, + width: 15, height: 15, + count: _bannerCarousel.itemCount, + index: carouselIndicatorIndex, + onClick: (index){ + debugPrint('onClick at ${index}'); + }, + ), + ), + + SizedBox(height: 10,), + + Padding( + padding: const EdgeInsets.all(15), + child: Column( + children: [ + // Search Textfield + searchTextField(), + + SizedBox(height: 10,), + + // Filter Selection + filterOptionSelection(), + + SizedBox(height: 20,), + + // Horizontal Scrollable Cards + Texts( + "Latest offers", + fontWeight: FontWeight.bold, + color: Colors.black87, + fontSize: 20 + ), + + // Latest Offers Horizontal Scrollable List + AspectRatio( + aspectRatio: 1.3/1, + child: LayoutBuilder(builder: (context, constraints){ + double itemContentPadding = 10; + double itemWidth = (constraints.maxWidth/2) - (itemContentPadding*2); + return latestOfferListView(itemWidth: itemWidth, itemContentPadding: itemContentPadding); + }), + ), + + SizedBox(height: 10,), + + Texts( + "Best sellers", + fontWeight: FontWeight.bold, + color: Colors.black87, + fontSize: 20 + ), + + + // Best Seller Horizontal Scrollable List + AspectRatio( + aspectRatio: 1.3/1, + child: LayoutBuilder(builder: (context, constraints){ + double itemContentPadding = 10; // 10 is content padding in each item + double itemWidth = (constraints.maxWidth/2) - (itemContentPadding*2 /* 2 = LeftRight */); + return bestSellerListView(itemWidth: itemWidth, itemContentPadding: itemContentPadding); + }), + ) + + ],), + ), + ], + ), + ) + .setOnAppBarCartClick(onCartClick); + } + ); + } + + + + + showClinicSelectionList() async { + var clinics = viewModel.service.categoryList; + if(clinics.isEmpty) { + GifLoaderDialogUtils.showMyDialog(context); + clinics = await viewModel.service.getAllCategories(OffersCategoriesRequestModel()); + GifLoaderDialogUtils.hideDialog(context); + } + + List options = clinics.map((e) => e.toString()).toList(); + + showMaterialSelectionPicker( + context: context, + title: "Select Clinic", + items: options, + selectedItem: options.first, + onChanged: (value) async { + var selectedClinic = clinics.firstWhere((element) => element.toString() == value); + var clinicProducts = await viewModel.service.getAllProducts(request: OffersProductsRequestModel(categoryId: selectedClinic.id), context: context, showLoading: true); + if(clinicProducts.isNotEmpty) + Navigator.of(context).push( + MaterialPageRoute( + builder: (BuildContext context) => ClinicPackagesPage(products: clinicProducts) + ) + ); + else + utils.Utils.showErrorToast("No offers available for this clinic"); + }, + ); + } + + //---------------------------------- + // Main Widgets of Page + //---------------------------------- + + CarouselSlider bannerCarousel(){ + _bannerCarousel = CarouselSlider.builder( + carouselController: _carouselController, + itemCount: 10, + itemBuilder: (BuildContext context, int itemIndex) { + return Padding( + padding: const EdgeInsets.only(top: 10, bottom: 10, left: 15, right: 15), + child: FractionallySizedBox( + widthFactor: 1, + heightFactor: 1, + child: utils.applyShadow( + spreadRadius: 1, + blurRadius: 5, + child: InkWell( + child: ClipRRect( + borderRadius: BorderRadius.circular(10), + child: utils.Utils.loadNetworkImage(url: "https://wallpaperaccess.com/full/30103.jpg",) + ), + onTap: (){ + Navigator.of(context).push( + MaterialPageRoute( + builder: (BuildContext context) => OfferAndPackagesDetail(model: "",) + ) + ); + }, + ) + ), + ), + ); + }, + options: CarouselOptions( + autoPlayInterval: Duration(milliseconds: 3500), + enlargeStrategy: CenterPageEnlargeStrategy.scale, + enlargeCenterPage: true, + autoPlay: false, + autoPlayCurve: Curves.fastOutSlowIn, + enableInfiniteScroll: true, + autoPlayAnimationDuration: Duration(milliseconds: 1500), + viewportFraction: 1, + onPageChanged: (page, reason){ + setState(() { + carouselIndicatorIndex = page; + }); + }, + ), + ); + return _bannerCarousel; + } + + TextField searchTextField(){ + return _textFieldSearch = + TextField( + controller: _searchTextController, + decoration: InputDecoration( + contentPadding: EdgeInsets.only(top: 0.0, bottom: 0.0, left: 10, right: 10), + enabledBorder: OutlineInputBorder( + borderSide: BorderSide( width: 0.5, color: Colors.grey), + borderRadius: const BorderRadius.all( + const Radius.circular(10.0), + ), + ), + focusedBorder: OutlineInputBorder( + borderSide: BorderSide( width: 1, color: Colors.grey), + borderRadius: const BorderRadius.all( + const Radius.circular(10.0), + ), + ), + filled: true, + fillColor: Colors.white, + hintText: "Search", + hintStyle: TextStyle(color: Colors.grey[350], fontWeight: FontWeight.bold), + suffixIcon: IconButton( + onPressed: (){ + // viewModel.search(text: _searchTextController.text); + }, + icon: Icon(Icons.search_rounded, size: 35,), + ), + ), + ); + + } + + Widget filterOptionSelection(){ + _textFieldFilterSelection = + TextField( + enabled: false, + controller: _searchTextController, + decoration: InputDecoration( + contentPadding: EdgeInsets.only(top: 0.0, bottom: 0.0, left: 10, right: 10), + border: OutlineInputBorder( + borderSide: BorderSide(color: Colors.grey, width: 1), + borderRadius: const BorderRadius.all( + const Radius.circular(10.0), + ), + ), + disabledBorder: OutlineInputBorder( + borderSide: BorderSide( width: 0.5, color: Colors.grey), + borderRadius: const BorderRadius.all( + const Radius.circular(10.0), + ), + ), + focusedBorder: OutlineInputBorder( + borderRadius: const BorderRadius.all( + const Radius.circular(10.0), + ), + ), + filled: true, + fillColor: Colors.white, + hintText: "Browse offers by Clinic", + hintStyle: TextStyle(color: Colors.grey[350], fontWeight: FontWeight.bold), + suffixIcon: IconButton( + onPressed: (){ + showClinicSelectionList(); + }, + icon: Icon(Icons.keyboard_arrow_down_rounded, size: 35, color: Colors.grey,), + ), + ), + ); + + return InkWell( + child: _textFieldFilterSelection, + onTap: (){ + showClinicSelectionList(); + }, + ); + + } + + Widget latestOfferListView({@required double itemWidth, @required double itemContentPadding}){ + return _listViewLatestOffers = + ListView.separated( + scrollDirection: Axis.horizontal, + itemCount: viewModel.bestSellerList.length, + itemBuilder: (BuildContext context, int index) { + return PackagesItemCard(itemWidth: itemWidth, itemContentPadding: itemContentPadding, itemModel: viewModel.bestSellerList[index], onCartClick: onProductCartClick,); + }, + separatorBuilder: separator, + ); + + } + + Widget bestSellerListView({@required double itemWidth, @required double itemContentPadding}){ + return _listViewLatestOffers = + ListView.separated( + scrollDirection: Axis.horizontal, + itemCount: viewModel.bestSellerList.length, + itemBuilder: (BuildContext context, int index) { + return PackagesItemCard(itemWidth: itemWidth, itemContentPadding: itemContentPadding, itemModel: viewModel.bestSellerList[index], onCartClick: onProductCartClick,); + }, + separatorBuilder: separator, + ); + + } + + + Widget separator(BuildContext context, int index){ + return Container( + width: 1, + decoration: BoxDecoration( + gradient: LinearGradient( + begin: Alignment(-1.0, -2.0), + end: Alignment(1.0, 4.0), + colors: [ + Colors.grey, + Colors.grey[100], + Colors.grey[200], + Colors.grey[300], + Colors.grey[400], + Colors.grey[500] + ] + )), + ); + } +} diff --git a/lib/pages/packages_offers/PackageOrderCompletedPage.dart b/lib/pages/packages_offers/PackageOrderCompletedPage.dart new file mode 100644 index 00000000..73baca4b --- /dev/null +++ b/lib/pages/packages_offers/PackageOrderCompletedPage.dart @@ -0,0 +1,136 @@ +import 'package:diplomaticquarterapp/core/viewModels/packages_offers/PackagesOffersViewModel.dart'; +import 'package:diplomaticquarterapp/pages/base/base_view.dart'; +import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; +import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter/rendering.dart'; +import 'package:flutter_svg/svg.dart'; + +dynamic languageID; + +class PackageOrderCompletedPage extends StatelessWidget{ + double buttonHeight; + double buttonWidth; + Widget icon; + String heading; + String title; + String subTitle; + String actionTitle; + + PackageOrderCompletedPage({this.buttonWidth, this.buttonHeight, @required this.heading, @required this.title, @required this.subTitle, this.actionTitle }); + + @override + Widget build(BuildContext context) { + assert((heading != null || title != null || subTitle != null), "Data missing in properties"); + + buttonWidth = buttonWidth ?? MediaQuery.of(context).size.width/2; + buttonHeight = buttonHeight ?? 40; + actionTitle = actionTitle ?? TranslationBase.of(context).done; + + return BaseView( + allowAny: true, + onModelReady: (model){}, + builder: (_, model, wi){ + return Container( + color: Colors.white, + child: Padding( + padding: const EdgeInsets.all(15), + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + + AspectRatio( + aspectRatio: 1.2/1, + child: + iconWidget(context), + ), + + headingWidget(context), + + + AspectRatio( + aspectRatio: 1/1, + child: Center( + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + titleWidget(context), + SizedBox(height: 20,), + subTitleWidget(context), + SizedBox(height: 50,), + actionWidget(context) + ], + ), + ), + ) + + ], + ), + ), + ); + } + ); + } + + Widget iconWidget(BuildContext context){ + return Padding( + padding: const EdgeInsets.all(50), + child: icon ?? SvgPicture.asset( + "assets/images/svg/success.svg", + semanticsLabel: 'icon' + ), + ); + } + + Widget headingWidget(BuildContext context) => Texts( + heading, + textAlign: TextAlign.center, + maxLines: 1, + color: Theme.of(context).primaryColor, + fontSize: 35.0, + fontWeight: FontWeight.bold, + ); + + Widget titleWidget(BuildContext context) => Texts( + title, + textAlign: TextAlign.center, + maxLines: 2, + color: Theme.of(context).primaryColor, + fontSize: 25.0, + fontWeight: FontWeight.w200, + ); + + Widget subTitleWidget(BuildContext context) => Texts( + subTitle, + textAlign: TextAlign.center, + maxLines: 2, + color: Theme.of(context).primaryColor, + fontSize: 15.0, + fontWeight: FontWeight.normal, + ); + + + Widget actionWidget(BuildContext context) => Container( + height: buttonHeight, + width: buttonWidth, + child: ElevatedButton( + style: ElevatedButton.styleFrom( + + shape:RoundedRectangleBorder( + borderRadius: new BorderRadius.circular(buttonHeight/2), + ) + ), + child: Texts( + actionTitle, + color: Colors.white, + fontSize: 18.0, + fontWeight: FontWeight.normal, + ), + onPressed: (){ + Navigator.of(context).pop(); + }, + ), + ); + +} diff --git a/lib/pages/paymentService/payment_service.dart b/lib/pages/paymentService/payment_service.dart index cca506ec..1b221454 100644 --- a/lib/pages/paymentService/payment_service.dart +++ b/lib/pages/paymentService/payment_service.dart @@ -117,7 +117,7 @@ class PaymentService extends StatelessWidget { ) ], ), - // if(!projectViewModel.havePrivilege(33)) + //if(!projectViewModel.havePrivilege(33)) Row( crossAxisAlignment: CrossAxisAlignment.start, children: [ diff --git a/lib/pages/pharmacies/product-brands.dart b/lib/pages/pharmacies/product-brands.dart index 945fbda1..e2fefab0 100644 --- a/lib/pages/pharmacies/product-brands.dart +++ b/lib/pages/pharmacies/product-brands.dart @@ -28,6 +28,7 @@ class _ProductBrandsPageState extends State { @override Widget build(BuildContext context) { return BaseView( + allowAny: true, onModelReady: (model) => model.getBrandsData(), builder: (_, model, wi) => AppScaffold( appBarTitle: 'Brands page', @@ -142,6 +143,7 @@ class _ProductBrandsPageState extends State { topBrand(BuildContext context) { return BaseView( + allowAny: true, onModelReady: (model) => model.getTopBrandsData(), builder: (_, model, wi) => GridView.count( crossAxisCount: 4, diff --git a/lib/pages/pharmacies/product_detail.dart b/lib/pages/pharmacies/product_detail.dart index c119f468..bd776355 100644 --- a/lib/pages/pharmacies/product_detail.dart +++ b/lib/pages/pharmacies/product_detail.dart @@ -1,23 +1,22 @@ import 'package:diplomaticquarterapp/config/shared_pref_kay.dart'; import 'package:diplomaticquarterapp/core/model/pharmacies/PharmacyProduct.dart'; -import 'package:diplomaticquarterapp/core/model/pharmacies/recommendedProduct_model.dart'; import 'package:diplomaticquarterapp/core/viewModels/pharmacyModule/pharmacy_module_view_model.dart'; import 'package:diplomaticquarterapp/core/viewModels/pharmacyModule/product_detail_view_model.dart'; import 'package:diplomaticquarterapp/pages/base/base_view.dart'; -import 'package:diplomaticquarterapp/pages/login/welcome.dart'; +import 'package:diplomaticquarterapp/pages/pharmacies/compare-list.dart'; +import 'package:diplomaticquarterapp/uitl/app_toast.dart'; import 'package:diplomaticquarterapp/uitl/gif_loader_dialog_utils.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; +import 'package:diplomaticquarterapp/widgets/others/app_scafold_detail_page.dart'; import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; import 'package:flutter/material.dart'; -import 'package:diplomaticquarterapp/widgets/others/app_scafold_detail_page.dart'; import 'package:font_awesome_flutter/font_awesome_flutter.dart'; import 'package:provider/provider.dart'; import 'package:rating_bar/rating_bar.dart'; -import 'package:diplomaticquarterapp/uitl/app_toast.dart'; + import 'screens/cart-order-page.dart'; -import 'package:diplomaticquarterapp/pages/pharmacies/compare-list.dart'; int price = 0; var languageID; @@ -30,7 +29,9 @@ PharmacyProduct specificationData; class ProductDetailPage extends StatefulWidget { final PharmacyProduct product; + ProductDetailPage(this.product); + @override __ProductDetailPageState createState() => __ProductDetailPageState(); } @@ -42,8 +43,10 @@ class __ProductDetailPageState extends State { bool isAvailabilty = false; dynamic wishlistItems; var model; + // String ProductId="4561"; String productId = ""; + checkWishlist() async { GifLoaderDialogUtils.showMyDialog(context); ProductDetailViewModel x = new ProductDetailViewModel(); @@ -62,6 +65,7 @@ class __ProductDetailPageState extends State { GifLoaderDialogUtils.hideDialog(context); setState(() {}); } + void initState() { price = 1; specificationData = widget.product; @@ -613,21 +617,20 @@ class __ProductDetailPageState extends State { Container( width: 410, height: 50, - // margin: EdgeInsets.only(bottom: 5), + // margin: EdgeInsets.only(bottom: 5), color: Colors.white, child: Texts( TranslationBase.of(context).recommended, bold: true, ), ), - ], ), SingleChildScrollView( child: Container( color: Colors.white, child: Column( - // crossAxisAlignment: CrossAxisAlignment.start, + // crossAxisAlignment: CrossAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.start, // mainAxisSize: MainAxisSize.min, children: [ @@ -636,208 +639,252 @@ class __ProductDetailPageState extends State { height: 210, margin: EdgeInsets.only(bottom: 75), padding: EdgeInsets.only(bottom: 5), - // margin: EdgeInsets.symmetric(horizontal: 6, vertical: 4), + // margin: EdgeInsets.symmetric(horizontal: 6, vertical: 4), child: BaseView( onModelReady: (model) => - model.getRecommendedProducts(widget.product.id.toString()), - builder: (_, model, wi) => - Container( + model.getRecommendedProducts( + widget.product.id.toString()), + builder: (_, model, wi) => Container( child: // Text(model.recommendedProductList[0].id), - model.recommendedProductList.length != null - ? Expanded( - child: ListView.builder( - scrollDirection: Axis.horizontal, - shrinkWrap: true, - physics: ScrollPhysics(), - // physics: NeverScrollableScrollPhysics(), - itemCount: model.recommendedProductList.length, - itemBuilder: (context, index) { - return Card( - elevation: 2, - shape: RoundedRectangleBorder( - side: BorderSide( - color: Colors.grey[300], width: 2), - borderRadius: BorderRadius.circular(10)), - margin: EdgeInsets.symmetric( - horizontal: 8, - vertical: 0, - ), - child: Container( - decoration: BoxDecoration( - borderRadius: BorderRadius.all( - Radius.circular(15), - ), - ), - padding: EdgeInsets.symmetric(horizontal: 4), - width: MediaQuery.of(context).size.width / 3, - child: Column( - crossAxisAlignment: - CrossAxisAlignment.start, - children: [ - Stack(children: [ - Container( - child: Align( - alignment: Alignment.topRight, - child: //true - itemID.contains(model.recommendedProductList[index].id) - // !isInWishlist - ? IconButton( - icon: Icon(Icons - .favorite_border), - color: Colors.grey, - iconSize: 30, - onPressed: () { - setState(() { - addToWishlistFunction(itemID); - }); - }, - ) - : IconButton( - icon: Icon( - Icons.favorite), - color: Colors.red, - iconSize: 30, - onPressed: () { - setState(() { - deleteFromWishlistFunction(itemID); - }); - }, - ) -// + model.recommendedProductList.length != + null + ? Expanded( + child: ListView.builder( + scrollDirection: + Axis.horizontal, + shrinkWrap: true, + physics: ScrollPhysics(), + // physics: NeverScrollableScrollPhysics(), + itemCount: model + .recommendedProductList + .length, + itemBuilder: + (context, index) { + return Card( + elevation: 2, + shape: RoundedRectangleBorder( + side: BorderSide( + color: Colors + .grey[ + 300], + width: 2), + borderRadius: + BorderRadius + .circular( + 10)), + margin: EdgeInsets + .symmetric( + horizontal: 8, + vertical: 0, ), - ), - Container( - margin: EdgeInsets.fromLTRB( - 0, 16, 10, 16), - alignment: Alignment.center, + child: Container( + decoration: + BoxDecoration( + borderRadius: + BorderRadius + .all( + Radius.circular( + 15), + ), + ), + padding: EdgeInsets + .symmetric( + horizontal: + 4), + width: MediaQuery.of( + context) + .size + .width / + 3, + child: Column( + crossAxisAlignment: + CrossAxisAlignment + .start, + children: [ + Stack( + children: [ + Container( + child: Align( + alignment: Alignment.topRight, + child: //true + itemID.contains(model.recommendedProductList[index].id) + // !isInWishlist + ? IconButton( + icon: Icon(Icons.favorite_border), + color: Colors.grey, + iconSize: 30, + onPressed: () { + setState(() { + addToWishlistFunction(itemID); + }); + }, + ) + : IconButton( + icon: Icon(Icons.favorite), + color: Colors.red, + iconSize: 30, + onPressed: () { + setState(() { + deleteFromWishlistFunction(itemID); + }); + }, + ) +// + ), + ), + Container( + margin: EdgeInsets.fromLTRB( + 0, + 16, + 10, + 16), + alignment: + Alignment.center, // padding: EdgeInsets.only(left: 25, bottom: 20), - child: (model.recommendedProductList[index].images != null && - model.recommendedProductList[index].images.length > 0) - ? Image.network( - model.recommendedProductList[index].images[0].src.toString(), + child: (model.recommendedProductList[index].images != null && + model.recommendedProductList[index].images.length > 0) + ? Image.network( + model.recommendedProductList[index].images[0].src.toString(), // item.images[0].src, - fit: BoxFit.cover, - height: 60, - ) - : Image.asset( - "assets/images/no_image.png", - fit: BoxFit.cover, - height: 60, - ), - ), - Container( - width: model - .recommendedProductList[ - index] - .rxMessage != - null - ? MediaQuery.of(context) - .size - .width / - 5 - : 0, - padding: EdgeInsets.all(4), - decoration: BoxDecoration( - color: Color(0xffb23838), - borderRadius: BorderRadius.only( - topLeft: Radius.circular(6)), - ), - child: Texts( - model.recommendedProductList[index] - .rxMessage != - null - ? model - .recommendedProductList[ - index] - .rxMessage - : "", - color: Colors.white, - regular: true, - fontSize: 10, - fontWeight: FontWeight.w400, - ), - ), - ]), - Container( - margin: EdgeInsets.symmetric( - horizontal: 6, - vertical: 0, - ), - child: Column( - crossAxisAlignment: - CrossAxisAlignment.start, - children: [ - Text( - languageID == "ar" - ? model.recommendedProductList[index].namen - : model.recommendedProductList[index].name, - style: TextStyle( - color: Colors.black, - fontSize: 13.0, + fit: BoxFit.cover, + height: 60, + ) + : Image.asset( + "assets/images/no_image.png", + fit: BoxFit.cover, + height: 60, + ), + ), + Container( + width: model.recommendedProductList[index].rxMessage != + null + ? MediaQuery.of(context).size.width / + 5 + : 0, + padding: + EdgeInsets.all(4), + decoration: + BoxDecoration( + color: + Color(0xffb23838), + borderRadius: + BorderRadius.only(topLeft: Radius.circular(6)), + ), + child: + Texts( + model.recommendedProductList[index].rxMessage != null + ? model.recommendedProductList[index].rxMessage + : "", + color: + Colors.white, + regular: + true, + fontSize: + 10, + fontWeight: + FontWeight.w400, + ), + ), + ]), + Container( + margin: EdgeInsets + .symmetric( + horizontal: + 6, + vertical: 0, + ), + child: Column( + crossAxisAlignment: + CrossAxisAlignment + .start, + children: [ + Text( + languageID == + "ar" + ? model.recommendedProductList[index].namen + : model.recommendedProductList[index].name, + style: + TextStyle( + color: + Colors.black, + fontSize: + 13.0, // fontWeight: FontWeight.bold, - ), - ), - Padding( + ), + ), + Padding( // padding: const EdgeInsets.only(top: 15, bottom: 10), - padding: const EdgeInsets.only( - top: 10, bottom: 5), - child: Texts( - "SAR ${model.recommendedProductList[index].price}", - bold: true, - fontSize: 14, - ), - ), - ], - ), - ), - Row( - crossAxisAlignment: - CrossAxisAlignment.start, - children: [ - Container( - padding: - EdgeInsets.only(right: 10), + padding: const EdgeInsets.only( + top: + 10, + bottom: + 5), + child: + Texts( + "SAR ${model.recommendedProductList[index].price}", + bold: + true, + fontSize: + 14, + ), + ), + ], + ), + ), + Row( + crossAxisAlignment: + CrossAxisAlignment + .start, + children: < + Widget>[ + Container( + padding: + EdgeInsets.only(right: 10), // margin: EdgeInsets.only(left: 5), - child: Align( - alignment: Alignment.topLeft, - child: RatingBar.readOnly( - initialRating: model - .recommendedProductList[ - index] - .approvedRatingSum - .toDouble(), + child: + Align( + alignment: + Alignment.topLeft, + child: + RatingBar.readOnly( + initialRating: + model.recommendedProductList[index].approvedRatingSum.toDouble(), // initialRating: productRate, - size: 13.0, - filledColor: - Colors.yellow[700], - emptyColor: Colors.grey[500], - isHalfAllowed: true, - halfFilledIcon: - Icons.star_half, - filledIcon: Icons.star, - emptyIcon: Icons.star, - ), - ), - ), - Texts( - "(${model.recommendedProductList[index].approvedTotalReviews.toString()})", + size: + 13.0, + filledColor: + Colors.yellow[700], + emptyColor: + Colors.grey[500], + isHalfAllowed: + true, + halfFilledIcon: + Icons.star_half, + filledIcon: + Icons.star, + emptyIcon: + Icons.star, + ), + ), + ), + Texts( + "(${model.recommendedProductList[index].approvedTotalReviews.toString()})", // bold: true, - fontSize: 12, + fontSize: + 12, + ), + ]), + ], ), - ]), - ], - ), - ), - ); - }), - ) - : Container( + ), + ); + }), + ) + : Container( // child: Text("NO DATA"), - ), - ) - - ), + ), + )), ), ], ), @@ -1341,8 +1388,10 @@ class footerWidget extends StatefulWidget { final int minQuantity; final int quantityLimit; final PharmacyProduct item; + footerWidget(this.isAvailble, this.maxQuantity, this.minQuantity, this.quantityLimit, this.item); + @override _footerWidgetState createState() => _footerWidgetState(); } @@ -1350,6 +1399,7 @@ class footerWidget extends StatefulWidget { class _footerWidgetState extends State { double quantityUI = 70; bool showUI = false; + @override Widget build(BuildContext context) { return Container( @@ -1752,7 +1802,7 @@ class _footerWidgetState extends State { ) : InkWell( onTap: () { - addToCartFunction(price, widget.item.id); + addToCartFunction(price, widget.item.id, context); }, child: Container( alignment: Alignment.center, @@ -1792,11 +1842,10 @@ class _footerWidgetState extends State { : InkWell( onTap: () { print('buy now'); - addToCartFunction(price, widget.item.id); + addToCartFunction(price, widget.item.id, context); Navigator.push( context, - FadePage(page: - CartOrderPage()), + FadePage(page: CartOrderPage()), ); }, child: Container( @@ -1824,7 +1873,9 @@ class _footerWidgetState extends State { class productNameAndPrice extends StatefulWidget { BuildContext context; PharmacyProduct item; + productNameAndPrice(this.context, this.item); + @override _productNameAndPriceState createState() => _productNameAndPriceState(); } @@ -2014,9 +2065,12 @@ getSpecificationData(itemID) async { specificationData = await x.productSpecificationData(itemID); } -addToCartFunction(quantity, itemID) async { +addToCartFunction(quantity, itemID, BuildContext context) async { + GifLoaderDialogUtils.showMyDialog(context); ProductDetailViewModel x = new ProductDetailViewModel(); - await x.addToCartData(quantity, itemID); + await x.addToCartData(quantity, itemID).then((value) { + GifLoaderDialogUtils.hideDialog(context); + }); } notifyMeWhenAvailable(context, itemId) async { @@ -2071,7 +2125,7 @@ settingModalBottomSheet(context) { title: Text('Add to cart'), onTap: () => { if (price > 0) - {addToCartFunction(price, itemID)} + {addToCartFunction(price, itemID, context)} else { AppToast.showErrorToast( diff --git a/lib/pages/pharmacies/screens/cart-order-page.dart b/lib/pages/pharmacies/screens/cart-order-page.dart index cca6c1df..f672cc66 100644 --- a/lib/pages/pharmacies/screens/cart-order-page.dart +++ b/lib/pages/pharmacies/screens/cart-order-page.dart @@ -1,3 +1,4 @@ +import 'package:diplomaticquarterapp/core/enum/viewstate.dart'; import 'package:diplomaticquarterapp/core/model/pharmacies/Addresses.dart'; import 'package:diplomaticquarterapp/core/model/pharmacies/ShoppingCartResponse.dart'; import 'package:diplomaticquarterapp/core/viewModels/pharmacyModule/OrderPreviewViewModel.dart'; @@ -7,6 +8,7 @@ import 'package:diplomaticquarterapp/pages/pharmacies/screens/cart-order-preview import 'package:diplomaticquarterapp/pages/pharmacies/screens/pharmacy-terms-conditions-page.dart'; import 'package:diplomaticquarterapp/pages/pharmacies/widgets/ProductOrderItem.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; +import 'package:diplomaticquarterapp/uitl/utils.dart'; import 'package:diplomaticquarterapp/widgets/buttons/GestureIconButton.dart'; import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; @@ -32,7 +34,7 @@ class CartOrderPage extends StatelessWidget { baseViewModel: model, backgroundColor: Colors.white, body: !(model.cartResponse.shoppingCarts == null || - model.cartResponse.shoppingCarts.length == 0) + model.cartResponse.shoppingCarts.length == 0) ? Container( height: height * 0.85, width: double.infinity, @@ -70,8 +72,16 @@ class CartOrderPage extends StatelessWidget { cart.shoppingCarts[index], () { print(cart.shoppingCarts[index] .quantity); - model.changeProductQuantity( - cart.shoppingCarts[index]); + model + .changeProductQuantity( + cart.shoppingCarts[index]) + .then((value) { + if (model.state == + ViewState.ErrorLocal) { + Utils.showErrorToast( + model.error); + } + }); }, () => model.deleteProduct( cart.shoppingCarts[index]))) @@ -246,64 +256,62 @@ class _OrderBottomWidgetState extends State { height: widget.height * 0.070, color: Color(0xffe6ffe0), padding: EdgeInsets.symmetric(horizontal: 4), - child: Expanded( - child: Row( - children: [ - InkWell( - onTap: () { - setState(() { - isAgree = !isAgree; - }); - }, - child: Container( - width: 25.0, - height: widget.height * 0.070, - decoration: new BoxDecoration( - color: !isAgree - ? Color(0xffeeeeee) - : Colors.green, - shape: BoxShape.circle, + child: Row( + children: [ + InkWell( + onTap: () { + setState(() { + isAgree = !isAgree; + }); + }, + child: Container( + width: 25.0, + height: widget.height * 0.070, + decoration: new BoxDecoration( + color: !isAgree + ? Color(0xffeeeeee) + : Colors.green, + shape: BoxShape.circle, + ), + child: !isAgree + ? null + : Padding( + padding: const EdgeInsets.all(0.0), + child: Icon( + Icons.check, + color: Colors.white, + size: 25, ), - child: !isAgree - ? null - : Padding( - padding: const EdgeInsets.all(0.0), - child: Icon( - Icons.check, - color: Colors.white, - size: 25, - ), - ), ), ), - Expanded( - child: Container( - padding: EdgeInsets.symmetric(horizontal: 4), - margin: const EdgeInsets.symmetric(vertical: 4), - child: Texts( - TranslationBase.of(context) - .pharmacyServiceTermsCondition, - fontSize: 13, - color: Colors.grey.shade800, - fontWeight: FontWeight.normal, - ), + ), + Expanded( + child: Container( + padding: EdgeInsets.symmetric(horizontal: 4), + margin: const EdgeInsets.symmetric(vertical: 4), + child: Texts( + TranslationBase.of(context) + .pharmacyServiceTermsCondition, + fontSize: 13, + color: Colors.grey.shade800, + fontWeight: FontWeight.normal, ), ), - InkWell( - onTap: () => { - Navigator.push(context, - FadePage(page: PharmacyTermsConditions())) - }, - child: Container( - child: Icon( - Icons.info, - size: 25, - color: Color(0xff005aff), - ), + ), + InkWell( + onTap: () => { + Navigator.push(context, + FadePage(page: PharmacyTermsConditions())) + }, + child: Container( + child: Icon( + Icons.info, + size: 25, + color: Color(0xff005aff), ), ), - ], - ), + ), + ], ), ), Container( diff --git a/lib/pages/pharmacies/screens/cart-order-preview.dart b/lib/pages/pharmacies/screens/cart-order-preview.dart index e0c062fa..5d271a1a 100644 --- a/lib/pages/pharmacies/screens/cart-order-preview.dart +++ b/lib/pages/pharmacies/screens/cart-order-preview.dart @@ -1,28 +1,31 @@ import 'package:diplomaticquarterapp/core/enum/viewstate.dart'; import 'package:diplomaticquarterapp/core/model/pharmacies/Addresses.dart'; +import 'package:diplomaticquarterapp/core/model/pharmacies/order_detail.dart'; import 'package:diplomaticquarterapp/core/model/pharmacies/payment-checkout-data.dart'; import 'package:diplomaticquarterapp/core/viewModels/pharmacyModule/OrderPreviewViewModel.dart'; import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; +import 'package:diplomaticquarterapp/models/Appointments/AppoimentAllHistoryResultList.dart'; +import 'package:diplomaticquarterapp/models/Authentication/authenticated_user.dart'; import 'package:diplomaticquarterapp/pages/base/base_view.dart'; -import 'package:diplomaticquarterapp/pages/pharmacies/screens/address-select-page.dart'; import 'package:diplomaticquarterapp/pages/pharmacies/screens/payment-method-select-page.dart'; -import 'package:diplomaticquarterapp/pages/pharmacies/screens/pharmacy_module_page.dart'; import 'package:diplomaticquarterapp/pages/pharmacies/widgets/ProductOrderPreviewItem.dart'; import 'package:diplomaticquarterapp/pages/pharmacy/pharmacyAddresses/PharmacyAddresses.dart'; import 'package:diplomaticquarterapp/uitl/app_toast.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; +import 'package:diplomaticquarterapp/widgets/in_app_browser/InAppBrowser.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; -import 'package:flutter/scheduler.dart'; class OrderPreviewPage extends StatelessWidget { final List addresses; OrderPreviewPage(this.addresses); + MyInAppBrowser browser; + @override Widget build(BuildContext context) { final mediaQuery = MediaQuery.of(context); @@ -56,18 +59,18 @@ class OrderPreviewPage extends StatelessWidget { ), Consumer( builder: (ctx, paymentData, _) => - paymentData.lacumInformation != null - ? Container( - child: Column( - children: [ - LakumWidget(model), - SizedBox( - height: 10, - ), - ], - ), - ) - : Container()), + paymentData.lacumInformation != null + ? Container( + child: Column( + children: [ + LakumWidget(model), + SizedBox( + height: 10, + ), + ], + ), + ) + : Container()), Container( color: Colors.white, width: double.infinity, @@ -76,7 +79,9 @@ class OrderPreviewPage extends StatelessWidget { crossAxisAlignment: CrossAxisAlignment.start, children: [ Texts( - TranslationBase.of(context).reviewOrder, + TranslationBase + .of(context) + .reviewOrder, fontSize: 14, fontWeight: FontWeight.bold, color: Colors.black, @@ -85,8 +90,10 @@ class OrderPreviewPage extends StatelessWidget { model.cartResponse.shoppingCarts != null ? model.cartResponse.shoppingCarts.length : 0, - (index) => ProductOrderPreviewItem( - model.cartResponse.shoppingCarts[index]), + (index) => + ProductOrderPreviewItem( + model.cartResponse + .shoppingCarts[index]), ), ], ), @@ -96,117 +103,140 @@ class OrderPreviewPage extends StatelessWidget { padding: EdgeInsets.all(8), child: model.cartResponse.subtotal != null ? Column( - crossAxisAlignment: - CrossAxisAlignment.start, - children: [ - Texts( - TranslationBase.of(context) - .orderSummary, - fontSize: 14, - fontWeight: FontWeight.bold, - color: Colors.black, - ), - SizedBox( - height: 20, - ), - Row( - mainAxisAlignment: - MainAxisAlignment.spaceBetween, - children: [ - Texts( - "${TranslationBase.of(context).subtotal}", - fontSize: 14, - color: Colors.black, - fontWeight: FontWeight.w500, - ), - Texts( - "${TranslationBase.of(context).sar} ${(model.cartResponse.subtotal).toStringAsFixed(2)}", - fontSize: 14, - color: Colors.black, - fontWeight: FontWeight.w500, - ), - ], - ), - const Divider( - color: Color(0xFFD6D6D6), - height: 20, - thickness: 1, - indent: 0, - endIndent: 0, - ), - Row( - mainAxisAlignment: - MainAxisAlignment.spaceBetween, - children: [ - Texts( - "${TranslationBase.of(context).shipping}", - fontSize: 14, - color: Colors.black, - fontWeight: FontWeight.w500, - ), - Texts( - "${TranslationBase.of(context).sar} ${(model.totalAdditionalShippingCharge).toStringAsFixed(2)}", - fontSize: 14, - color: Colors.black, - fontWeight: FontWeight.w500, - ), - ], - ), - const Divider( - color: Color(0xFFD6D6D6), - height: 20, - thickness: 1, - indent: 0, - endIndent: 0, - ), - Row( - mainAxisAlignment: - MainAxisAlignment.spaceBetween, - children: [ - Texts( - "${TranslationBase.of(context).vat}", - fontSize: 14, - color: Colors.black, - fontWeight: FontWeight.w500, - ), - Texts( - "${TranslationBase.of(context).sar} ${(model.cartResponse.subtotalVatAmount).toStringAsFixed(2)}", - fontSize: 14, - color: Colors.black, - fontWeight: FontWeight.w500, - ), - ], - ), - const Divider( - color: Color(0xFFD6D6D6), - height: 20, - thickness: 1, - indent: 0, - endIndent: 0, - ), - Row( - mainAxisAlignment: - MainAxisAlignment.spaceBetween, - children: [ - Texts( - TranslationBase.of(context).total, - fontSize: 14, - color: Colors.black, - fontWeight: FontWeight.bold, - ), - Texts( - "${TranslationBase.of(context).sar} ${(model.cartResponse.subtotal).toStringAsFixed(2)}", - fontSize: 14, - color: Colors.black, - fontWeight: FontWeight.bold, - ), - ], - ), - SizedBox( - height: 10, - ), - ], - ) + crossAxisAlignment: + CrossAxisAlignment.start, + children: [ + Texts( + TranslationBase + .of(context) + .orderSummary, + fontSize: 14, + fontWeight: FontWeight.bold, + color: Colors.black, + ), + SizedBox( + height: 20, + ), + Row( + mainAxisAlignment: + MainAxisAlignment.spaceBetween, + children: [ + Texts( + "${TranslationBase + .of(context) + .subtotal}", + fontSize: 14, + color: Colors.black, + fontWeight: FontWeight.w500, + ), + Texts( + "${TranslationBase + .of(context) + .sar} ${(model.cartResponse.subtotal) + .toStringAsFixed(2)}", + fontSize: 14, + color: Colors.black, + fontWeight: FontWeight.w500, + ), + ], + ), + const Divider( + color: Color(0xFFD6D6D6), + height: 20, + thickness: 1, + indent: 0, + endIndent: 0, + ), + Row( + mainAxisAlignment: + MainAxisAlignment.spaceBetween, + children: [ + Texts( + "${TranslationBase + .of(context) + .shipping}", + fontSize: 14, + color: Colors.black, + fontWeight: FontWeight.w500, + ), + Texts( + "${TranslationBase + .of(context) + .sar} ${(model + .totalAdditionalShippingCharge) + .toStringAsFixed(2)}", + fontSize: 14, + color: Colors.black, + fontWeight: FontWeight.w500, + ), + ], + ), + const Divider( + color: Color(0xFFD6D6D6), + height: 20, + thickness: 1, + indent: 0, + endIndent: 0, + ), + Row( + mainAxisAlignment: + MainAxisAlignment.spaceBetween, + children: [ + Texts( + "${TranslationBase + .of(context) + .vat}", + fontSize: 14, + color: Colors.black, + fontWeight: FontWeight.w500, + ), + Texts( + "${TranslationBase + .of(context) + .sar} ${(model.cartResponse + .subtotalVatAmount).toStringAsFixed( + 2)}", + fontSize: 14, + color: Colors.black, + fontWeight: FontWeight.w500, + ), + ], + ), + const Divider( + color: Color(0xFFD6D6D6), + height: 20, + thickness: 1, + indent: 0, + endIndent: 0, + ), + Row( + mainAxisAlignment: + MainAxisAlignment.spaceBetween, + children: [ + Texts( + TranslationBase + .of(context) + .total, + fontSize: 14, + color: Colors.black, + fontWeight: FontWeight.bold, + ), + Texts( + "${TranslationBase + .of(context) + .sar} ${(model.cartResponse.subtotal) + .toStringAsFixed(2)}", + fontSize: 14, + color: Colors.black, + fontWeight: FontWeight.bold, + ), + ], + ), + SizedBox( + height: 10, + ), + ], + ) : Container(), ) ], @@ -269,161 +299,172 @@ class _SelectAddressWidgetState extends State { @override Widget build(BuildContext context) { return Consumer( - builder: (ctx, paymentData, _) => Container( - color: Colors.white, - child: address == null - ? InkWell( - onTap: () => {_navigateToAddressPage()}, - child: Container( - margin: EdgeInsets.symmetric(vertical: 12, horizontal: 12), - child: Row( - children: [ - Image.asset( - "assets/images/pharmacy_module/ic_shipping_address.png", - width: 30.0, - height: 30.0, - fit: BoxFit.scaleDown, + builder: (ctx, paymentData, _) => + Container( + color: Colors.white, + child: address == null + ? InkWell( + onTap: () => {_navigateToAddressPage()}, + child: Container( + margin: EdgeInsets.symmetric(vertical: 12, horizontal: 12), + child: Row( + children: [ + Image.asset( + "assets/images/pharmacy_module/ic_shipping_address.png", + width: 30.0, + height: 30.0, + fit: BoxFit.scaleDown, + ), + Expanded( + child: Container( + padding: + EdgeInsets.symmetric(vertical: 0, horizontal: 6), + child: Texts( + TranslationBase + .of(context) + .selectAddress, + fontSize: 14, + fontWeight: FontWeight.bold, + color: Color(0xff0000ff), + ), ), - Expanded( - child: Container( - padding: - EdgeInsets.symmetric(vertical: 0, horizontal: 6), + ), + Icon( + Icons.arrow_forward_ios, + size: 20, + color: Colors.grey.shade400, + ), + ], + ), + ), + ) + : Container( + child: Container( + margin: EdgeInsets.symmetric(vertical: 12, horizontal: 12), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + children: [ + Image.asset( + "assets/images/pharmacy_module/ic_shipping_mark.png", + width: 30.0, + height: 30.0, + fit: BoxFit.scaleDown, + ), + Expanded( + child: Container( + padding: EdgeInsets.symmetric( + vertical: 0, horizontal: 6), + child: Texts( + TranslationBase + .of(context) + .shippingAddress, + fontSize: 14, + fontWeight: FontWeight.bold, + color: Colors.black, + ), + ), + ), + InkWell( + onTap: () => {_navigateToAddressPage()}, child: Texts( - TranslationBase.of(context).selectAddress, - fontSize: 14, - fontWeight: FontWeight.bold, + TranslationBase + .of(context) + .changeAddress, + fontSize: 12, + fontWeight: FontWeight.normal, color: Color(0xff0000ff), ), ), + ], + ), + Padding( + padding: const EdgeInsets.symmetric(vertical: 8), + child: Texts( + "${address.firstName} ${address.lastName}", + fontSize: 14, + fontWeight: FontWeight.bold, + color: Colors.black, ), - Icon( - Icons.arrow_forward_ios, - size: 20, - color: Colors.grey.shade400, + ), + Padding( + padding: const EdgeInsets.symmetric(vertical: 8), + child: Texts( + "${address.address1} ${address.address2} ${address + .address2},, ${address.city}, ${address + .country} ${address.zipPostalCode}", + fontSize: 12, + fontWeight: FontWeight.normal, + color: Colors.grey.shade500, ), - ], - ), - ), - ) - : Container( - child: Container( - margin: EdgeInsets.symmetric(vertical: 12, horizontal: 12), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Row( - children: [ - Image.asset( - "assets/images/pharmacy_module/ic_shipping_mark.png", - width: 30.0, - height: 30.0, - fit: BoxFit.scaleDown, - ), - Expanded( - child: Container( - padding: EdgeInsets.symmetric( - vertical: 0, horizontal: 6), - child: Texts( - TranslationBase.of(context).shippingAddress, - fontSize: 14, - fontWeight: FontWeight.bold, - color: Colors.black, - ), - ), - ), - InkWell( - onTap: () => {_navigateToAddressPage()}, - child: Texts( - TranslationBase.of(context).changeAddress, - fontSize: 12, - fontWeight: FontWeight.normal, - color: Color(0xff0000ff), - ), + ), + Row( + children: [ + Container( + margin: const EdgeInsets.only(right: 8), + child: Icon( + Icons.phone, + size: 20, + color: Colors.black, ), - ], - ), - Padding( - padding: const EdgeInsets.symmetric(vertical: 8), - child: Texts( - "${address.firstName} ${address.lastName}", + ), + Texts( + "${address.phoneNumber}", fontSize: 14, fontWeight: FontWeight.bold, - color: Colors.black, + color: Colors.grey, ), - ), - Padding( - padding: const EdgeInsets.symmetric(vertical: 8), - child: Texts( - "${address.address1} ${address.address2} ${address.address2},, ${address.city}, ${address.country} ${address.zipPostalCode}", - fontSize: 12, - fontWeight: FontWeight.normal, - color: Colors.grey.shade500, + ], + ), + Container( + margin: EdgeInsets.symmetric(vertical: 8), + child: SizedBox( + height: 2, + width: double.infinity, + child: Container( + color: Color(0xffefefef), ), ), - Row( - children: [ - Container( - margin: const EdgeInsets.only(right: 8), - child: Icon( - Icons.phone, - size: 20, - color: Colors.black, - ), - ), - Texts( - "${address.phoneNumber}", - fontSize: 14, + ), + Row( + children: [ + Image.asset( + "assets/images/pharmacy_module/ic_shipping_truck.png", + width: 30.0, + height: 30.0, + fit: BoxFit.scaleDown, + ), + Container( + padding: EdgeInsets.symmetric( + vertical: 0, horizontal: 6), + child: Texts( + "${TranslationBase + .of(context) + .shipBy}", + fontSize: 12, fontWeight: FontWeight.bold, - color: Colors.grey, - ), - ], - ), - Container( - margin: EdgeInsets.symmetric(vertical: 8), - child: SizedBox( - height: 2, - width: double.infinity, - child: Container( - color: Color(0xffefefef), + color: Colors.black, ), ), - ), - Row( - children: [ - Image.asset( - "assets/images/pharmacy_module/ic_shipping_truck.png", - width: 30.0, - height: 30.0, - fit: BoxFit.scaleDown, - ), - Container( - padding: EdgeInsets.symmetric( - vertical: 0, horizontal: 6), - child: Texts( - "${TranslationBase.of(context).shipBy}", - fontSize: 12, - fontWeight: FontWeight.bold, - color: Colors.black, - ), - ), - Container( - child: Image.asset( - paymentData.shippingOption - .shippingRateComputationMethodSystemName == - "Shipping.FixedOrByWeight" - ? "assets/images/pharmacy_module/payment/hmg_shipping_logo.png" - : "assets/images/pharmacy_module/payment/aramex_shipping_logo.png", - fit: BoxFit.contain, - ), - margin: EdgeInsets.symmetric(horizontal: 8), + Container( + child: Image.asset( + paymentData.shippingOption + .shippingRateComputationMethodSystemName == + "Shipping.FixedOrByWeight" + ? "assets/images/pharmacy_module/payment/hmg_shipping_logo.png" + : "assets/images/pharmacy_module/payment/aramex_shipping_logo.png", + fit: BoxFit.contain, ), - ], - ), - ], - ), + margin: EdgeInsets.symmetric(horizontal: 8), + ), + ], + ), + ], ), - ), // ic_shipping_mark.png - ), + ), + ), // ic_shipping_mark.png + ), ); } } @@ -443,16 +484,17 @@ class _SelectPaymentOptionWidgetState extends State { _navigateToPaymentOption() { Navigator.push(context, FadePage(page: PaymentMethodSelectPage())) - .then((result) => { - setState(() { - if (result != null) { - paymentOption = result; - widget.model.paymentCheckoutData.paymentOption = - paymentOption; - widget.model.paymentCheckoutData.updateData(); - } - }) - }); + .then((result) => + { + setState(() { + if (result != null) { + paymentOption = result; + widget.model.paymentCheckoutData.paymentOption = + paymentOption; + widget.model.paymentCheckoutData.updateData(); + } + }) + }); } @override @@ -469,85 +511,89 @@ class _SelectPaymentOptionWidgetState extends State { color: Colors.white, child: paymentOption == null ? InkWell( - onTap: () => {_navigateToPaymentOption()}, - child: Container( - margin: EdgeInsets.symmetric(vertical: 12, horizontal: 12), - child: Row( - children: [ - Image.asset( - "assets/images/pharmacy_module/ic_payment_option.png", - width: 30.0, - height: 30.0, - fit: BoxFit.scaleDown, - ), - Expanded( - child: Container( - padding: - EdgeInsets.symmetric(vertical: 0, horizontal: 6), - child: Texts( - TranslationBase.of(context).selectPaymentOption, - fontSize: 14, - fontWeight: FontWeight.bold, - color: Color(0xff0000ff), - ), - ), - ), - Icon( - Icons.arrow_forward_ios, - size: 20, - color: Colors.grey.shade400, - ), - ], + onTap: () => {_navigateToPaymentOption()}, + child: Container( + margin: EdgeInsets.symmetric(vertical: 12, horizontal: 12), + child: Row( + children: [ + Image.asset( + "assets/images/pharmacy_module/ic_payment_option.png", + width: 30.0, + height: 30.0, + fit: BoxFit.scaleDown, + ), + Expanded( + child: Container( + padding: + EdgeInsets.symmetric(vertical: 0, horizontal: 6), + child: Texts( + TranslationBase + .of(context) + .selectPaymentOption, + fontSize: 14, + fontWeight: FontWeight.bold, + color: Color(0xff0000ff), + ), ), ), - ) + Icon( + Icons.arrow_forward_ios, + size: 20, + color: Colors.grey.shade400, + ), + ], + ), + ), + ) : Container( - margin: EdgeInsets.symmetric(vertical: 12, horizontal: 12), - child: Row( - children: [ - Image.asset( - "assets/images/pharmacy_module/ic_payment_option.png", - width: 30.0, - height: 30.0, - fit: BoxFit.scaleDown, - ), - Container( - margin: EdgeInsets.symmetric(horizontal: 8), - padding: EdgeInsets.symmetric(horizontal: 4, vertical: 0), - decoration: new BoxDecoration( - color: Colors.grey.shade100, - shape: BoxShape.rectangle, - ), - child: Image.asset( - widget.model.getPaymentOptionImage(paymentOption), - width: 30.0, - height: 30.0, - fit: BoxFit.scaleDown, - ), - ), - Expanded( - child: Container( - padding: EdgeInsets.symmetric(vertical: 0, horizontal: 6), - child: Texts( - widget.model.getPaymentOptionName(paymentOption), - fontSize: 14, - fontWeight: FontWeight.bold, - color: Colors.black, - ), - ), - ), - InkWell( - onTap: () => {_navigateToPaymentOption()}, - child: Texts( - TranslationBase.of(context).changeMethod, - fontSize: 12, - fontWeight: FontWeight.normal, - color: Color(0xff0000ff), - ), - ), - ], + margin: EdgeInsets.symmetric(vertical: 12, horizontal: 12), + child: Row( + children: [ + Image.asset( + "assets/images/pharmacy_module/ic_payment_option.png", + width: 30.0, + height: 30.0, + fit: BoxFit.scaleDown, + ), + Container( + margin: EdgeInsets.symmetric(horizontal: 8), + padding: EdgeInsets.symmetric(horizontal: 4, vertical: 0), + decoration: new BoxDecoration( + color: Colors.grey.shade100, + shape: BoxShape.rectangle, + ), + child: Image.asset( + widget.model.getPaymentOptionImage(paymentOption), + width: 30.0, + height: 30.0, + fit: BoxFit.scaleDown, ), ), + Expanded( + child: Container( + padding: EdgeInsets.symmetric(vertical: 0, horizontal: 6), + child: Texts( + widget.model.getPaymentOptionName(paymentOption), + fontSize: 14, + fontWeight: FontWeight.bold, + color: Colors.black, + ), + ), + ), + InkWell( + onTap: () => {_navigateToPaymentOption()}, + child: Texts( + TranslationBase + .of(context) + .changeMethod, + fontSize: 12, + fontWeight: FontWeight.normal, + color: Color(0xff0000ff), + ), + ), + ], + ), + ), ); } } @@ -585,12 +631,15 @@ class _LakumWidgetState extends State { crossAxisAlignment: CrossAxisAlignment.start, children: [ Texts( - "${TranslationBase.of(context).lakumPoints}", + "${TranslationBase + .of(context) + .lakumPoints}", fontSize: 12, fontWeight: FontWeight.bold, ), Texts( - "${widget.model.paymentCheckoutData.lacumInformation.lakumInquiryInformationObjVersion.pointsBalanceAmount}", + "${widget.model.paymentCheckoutData.lacumInformation + .lakumInquiryInformationObjVersion.pointsBalanceAmount}", fontSize: 12, fontWeight: FontWeight.normal, ), @@ -605,7 +654,9 @@ class _LakumWidgetState extends State { mainAxisAlignment: MainAxisAlignment.end, children: [ Texts( - "${TranslationBase.of(context).riyal}", + "${TranslationBase + .of(context) + .riyal}", fontSize: 12, fontWeight: FontWeight.bold, ), @@ -619,19 +670,19 @@ class _LakumWidgetState extends State { decoration: InputDecoration( border: OutlineInputBorder( borderSide: - BorderSide(color: Colors.black, width: 0.2), + BorderSide(color: Colors.black, width: 0.2), gapPadding: 0, borderRadius: projectProvider.isArabic ? BorderRadius.only( - topRight: Radius.circular(8), - bottomRight: Radius.circular(8)) + topRight: Radius.circular(8), + bottomRight: Radius.circular(8)) : BorderRadius.only( - topLeft: Radius.circular(8), - bottomLeft: Radius.circular(8)), + topLeft: Radius.circular(8), + bottomLeft: Radius.circular(8)), ), disabledBorder: OutlineInputBorder( borderSide: - BorderSide(color: Colors.black, width: 0.4), + BorderSide(color: Colors.black, width: 0.4), gapPadding: 0, borderRadius: BorderRadius.only( topLeft: Radius.circular(8), @@ -643,22 +694,22 @@ class _LakumWidgetState extends State { style: TextStyle( fontSize: 14, color: widget - .model - .paymentCheckoutData - .lacumInformation - .lakumInquiryInformationObjVersion - .pointsBalanceAmount > - 0 + .model + .paymentCheckoutData + .lacumInformation + .lakumInquiryInformationObjVersion + .pointsBalanceAmount > + 0 ? Colors.black : Colors.grey, ), enabled: widget - .model - .paymentCheckoutData - .lacumInformation - .lakumInquiryInformationObjVersion - .pointsBalanceAmount == - 0 + .model + .paymentCheckoutData + .lacumInformation + .lakumInquiryInformationObjVersion + .pointsBalanceAmount == + 0 ? false : true, onChanged: (val) { @@ -677,7 +728,7 @@ class _LakumWidgetState extends State { widget.model.paymentCheckoutData.usedLakumPoints = 0; } _pointsController.text = - "${widget.model.paymentCheckoutData.usedLakumPoints}"; + "${widget.model.paymentCheckoutData.usedLakumPoints}"; }, ), ), @@ -689,18 +740,20 @@ class _LakumWidgetState extends State { shape: BoxShape.rectangle, borderRadius: projectProvider.isArabic ? BorderRadius.only( - topLeft: Radius.circular(6), - bottomLeft: Radius.circular(6)) + topLeft: Radius.circular(6), + bottomLeft: Radius.circular(6)) : BorderRadius.only( - topRight: Radius.circular(6), - bottomRight: Radius.circular(6)), + topRight: Radius.circular(6), + bottomRight: Radius.circular(6)), border: Border.fromBorderSide(BorderSide( color: Color(0xff3666E0), width: 0.8, )), ), child: Texts( - "${TranslationBase.of(context).use}", + "${TranslationBase + .of(context) + .use}", fontSize: 12, color: Colors.white, fontWeight: FontWeight.bold, @@ -719,106 +772,176 @@ class _LakumWidgetState extends State { class PaymentBottomWidget extends StatelessWidget { final OrderPreviewViewModel model; + BuildContext context; + MyInAppBrowser browser; + PaymentBottomWidget(this.model); @override Widget build(BuildContext context) { final scaffold = Scaffold.of(context); + this.context = context; return Container( margin: EdgeInsets.symmetric(horizontal: 10, vertical: 0), child: Consumer( - builder: (ctx, paymentData, _) => paymentData.cartDataVisible + builder: (ctx, paymentData, _) => + paymentData.cartDataVisible ? Container( - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Column( - crossAxisAlignment: CrossAxisAlignment.start, - mainAxisAlignment: MainAxisAlignment.spaceEvenly, + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + Container( + margin: + EdgeInsets.symmetric(horizontal: 0, vertical: 4), + child: Row( children: [ - Container( - margin: - EdgeInsets.symmetric(horizontal: 0, vertical: 4), - child: Row( - children: [ - Texts( - "${TranslationBase.of(context).sar} ${(model.cartResponse.subtotal).toStringAsFixed(2)}", - fontSize: 14, - fontWeight: FontWeight.bold, - color: Color(0xff929295), - ), - Padding( - padding: - const EdgeInsets.symmetric(horizontal: 4), - child: Texts( - "${TranslationBase.of(context).inclusiveVat}", - fontSize: 8, - color: Color(0xff929295), - fontWeight: FontWeight.w600, - ), - ), - ], - ), - ), Texts( - "${model.cartResponse.quantityCount} ${TranslationBase.of(context).items}", - fontSize: 10, - color: Colors.grey, + "${TranslationBase + .of(context) + .sar} ${(model.cartResponse.subtotal) + .toStringAsFixed(2)}", + fontSize: 14, fontWeight: FontWeight.bold, + color: Color(0xff929295), ), - ], - ), - Container( - child: RaisedButton( - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(8), - side: BorderSide( + Padding( + padding: + const EdgeInsets.symmetric(horizontal: 4), + child: Texts( + "${TranslationBase + .of(context) + .inclusiveVat}", + fontSize: 8, color: Color(0xff929295), - width: 1, + fontWeight: FontWeight.w600, ), ), - onPressed: (paymentData.address != null && - paymentData.paymentOption != null) - ? () async { - await model.makeOrder(); - if (model.state != ViewState.Idle) { - AppToast.showSuccessToast(message: "Order has been placed successfully!!"); - } else { - AppToast.showErrorToast(message: model.error); - } - Navigator.pop(context); - Navigator.pop(context); - } - : null, - child: Padding( - padding: const EdgeInsets.symmetric(vertical: 16), - child: new Text( - "${TranslationBase.of(context).proceedPay}", - style: new TextStyle( - color: (paymentData.address != null && - paymentData.paymentOption != null) - ? Colors.white - : Colors.grey.shade400, - fontWeight: FontWeight.bold, - fontSize: 12), - ), - ), - color: (paymentData.address != null && - paymentData.paymentOption != null) - ? Colors.green - : Color(0xff929295), - disabledColor: (paymentData.address != null && - paymentData.paymentOption != null) - ? Colors.green - : Color(0xff929295), - ), + ], ), - ], + ), + Texts( + "${model.cartResponse.quantityCount} ${TranslationBase + .of(context) + .items}", + fontSize: 10, + color: Colors.grey, + fontWeight: FontWeight.bold, + ), + ], + ), + Container( + child: RaisedButton( + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(8), + side: BorderSide( + color: Color(0xff929295), + width: 1, + ), + ), + onPressed: (paymentData.address != null && + paymentData.paymentOption != null) + ? () async { + await model.makeOrder(); + if (model.state == ViewState.Idle) { + AppToast.showSuccessToast( + message: "Order has been placed successfully!!"); + openPayment(model.orderListModel[0], model.user); + } else { + AppToast.showErrorToast(message: model.error); + } + Navigator.pop(context); + Navigator.pop(context); + } + : null, + child: Padding( + padding: const EdgeInsets.symmetric(vertical: 16), + child: new Text( + "${TranslationBase + .of(context) + .proceedPay}", + style: new TextStyle( + color: (paymentData.address != null && + paymentData.paymentOption != null) + ? Colors.white + : Colors.grey.shade400, + fontWeight: FontWeight.bold, + fontSize: 12), + ), + ), + color: (paymentData.address != null && + paymentData.paymentOption != null) + ? Colors.green + : Color(0xff929295), + disabledColor: (paymentData.address != null && + paymentData.paymentOption != null) + ? Colors.green + : Color(0xff929295), ), - ) + ), + ], + ), + ) : Container(), ), ); } + + openPayment(OrderDetailModel order, + AuthenticatedUser authenticatedUser,) { + browser = new MyInAppBrowser( + onExitCallback: onBrowserExit, onLoadStartCallback: onBrowserLoadStart); + + browser.openPharmacyPaymentBrowser( + order, + order.orderTotal, + 'ePharmacy Order', + order.id, + order.billingAddress.email, + order.customValuesXml, + "${authenticatedUser.firstName} ${authenticatedUser + .middleName} ${authenticatedUser.lastName}", + authenticatedUser.patientID, + authenticatedUser, + browser); + } + + onBrowserLoadStart(String url) { + print("onBrowserLoadStart"); + print(url); + + MyInAppBrowser.successURLS.forEach((element) { + if (url.contains(element)) { + if (browser.isOpened()) browser.close(); + MyInAppBrowser.isPaymentDone = true; + return; + } + }); + + MyInAppBrowser.errorURLS.forEach((element) { + if (url.contains(element)) { + if (browser.isOpened()) browser.close(); + MyInAppBrowser.isPaymentDone = false; + return; + } + }); + } + + onBrowserExit(AppoitmentAllHistoryResultList appo, bool isPaymentMade) { + print("onBrowserExit Called!!!!"); + if (isPaymentMade) { + AppToast.showSuccessToast( + message: "شكراً\nPayment status for your order is Paid"); + Navigator.pop(context); + Navigator.pop(context); + } else { + AppToast.showErrorToast( + message: + "Transaction Failed!\Your transaction is field to some reason please try again or contact to the administration"); + } + } } diff --git a/lib/pages/pharmacies/widgets/ProductOrderItem.dart b/lib/pages/pharmacies/widgets/ProductOrderItem.dart index 92e2c39d..d7a82cc6 100644 --- a/lib/pages/pharmacies/widgets/ProductOrderItem.dart +++ b/lib/pages/pharmacies/widgets/ProductOrderItem.dart @@ -72,7 +72,7 @@ class _ProductOrderItemState extends State { child: Texts( projectProvider.isArabic ? widget.item.product.namen - : widget.item.product.name, + : "${widget.item.product.name}", regular: true, textAlign: TextAlign.justify, fontSize: 12, @@ -88,91 +88,90 @@ class _ProductOrderItemState extends State { ), margin: const EdgeInsets.only(bottom: 4), ), - Row( - children: [ - InkWell( - onTap: () => - {_quantityOnChangeClick(Operation.dec)}, - child: Container( - width: 25, - height: 25, - child: Center( - child: Texts( - "-", - color: Colors.grey.shade400, - )), - decoration: BoxDecoration( - border: Border.all( - color: Colors.grey.shade400, - width: 1.0, + Container( + margin: EdgeInsets.symmetric(vertical: 4), + child: Row( + children: [ + InkWell( + onTap: () => + {_quantityOnChangeClick(Operation.dec)}, + child: Container( + width: 25, + height: 25, + child: Icon( + Icons.remove, color: Colors.grey.shade400, size: 20, + ), + decoration: BoxDecoration( + border: Border.all( + color: Colors.grey.shade400, + width: 1.0, + ), ), ), ), - ), - Container( - margin: - const EdgeInsets.symmetric(horizontal: 4), - width: 25, - height: 25, - color: Colors.grey.shade300, - child: Center( - child: TextField( - cursorColor: Colors.black, - keyboardType: TextInputType.number, - controller: _quantityController, - textAlign: TextAlign.center, - onChanged: (text) { - setState(() { - var value = int.tryParse(text); - if (value == null) { - widget.item.quantity = 0; - } else { - widget.item.quantity = int.parse(text); - } - _totalPrice = - "${(widget.item.product.price * widget.item.quantity).toStringAsFixed(2)}"; - }); - }, - )), - ), - InkWell( - onTap: () => - {_quantityOnChangeClick(Operation.inc)}, - child: Container( + Container( + margin: + const EdgeInsets.symmetric(horizontal: 4), width: 25, height: 25, + color: Colors.grey.shade300, child: Center( - child: Texts( - "+", - color: Colors.grey.shade400, + child: TextField( + cursorColor: Colors.black, + keyboardType: TextInputType.number, + controller: _quantityController, + textAlign: TextAlign.center, + onChanged: (text) { + setState(() { + var value = int.tryParse(text); + if (value == null) { + widget.item.quantity = 0; + } else { + widget.item.quantity = int.parse(text); + } + _totalPrice = + "${(widget.item.product.price * widget.item.quantity).toStringAsFixed(2)}"; + }); + }, )), - decoration: BoxDecoration( - border: Border.all( - color: Colors.grey.shade400, - width: 1.0, - ), - ), ), - ), - Expanded( - child: Column( - crossAxisAlignment: CrossAxisAlignment.end, - children: [ - Texts( - TranslationBase.of(context).total, - color: Colors.grey.shade500, - fontWeight: FontWeight.bold, - fontSize: 12, + InkWell( + onTap: () => + {_quantityOnChangeClick(Operation.inc)}, + child: Container( + width: 25, + height: 25, + child: Icon( + Icons.add, color: Colors.grey.shade400, size: 20, + ), + decoration: BoxDecoration( + border: Border.all( + color: Colors.grey.shade400, + width: 1.0, + ), ), - Texts( - "$_totalPrice ${projectProvider.isArabic ? widget.item.currencyn : widget.item.currency}", - fontSize: 12, - fontWeight: FontWeight.bold, - ) - ], + ), ), - ) - ], + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.end, + children: [ + Texts( + TranslationBase.of(context).total, + color: Colors.grey.shade500, + fontWeight: FontWeight.bold, + fontSize: 12, + ), + Texts( + "$_totalPrice ${projectProvider.isArabic ? widget.item.currencyn : widget.item.currency}", + fontSize: 12, + fontWeight: FontWeight.bold, + ) + ], + ), + ) + ], + ), ) ], ), diff --git a/lib/pages/pharmacy/order/TrackDriver.dart b/lib/pages/pharmacy/order/TrackDriver.dart index 63dc0ace..587ba9a6 100644 --- a/lib/pages/pharmacy/order/TrackDriver.dart +++ b/lib/pages/pharmacy/order/TrackDriver.dart @@ -1,13 +1,26 @@ import 'dart:async'; +import 'dart:typed_data'; +import 'dart:ui' as ui; +import 'package:async/async.dart'; import 'package:diplomaticquarterapp/config/config.dart'; import 'package:diplomaticquarterapp/core/model/pharmacies/order_detail.dart'; import 'package:diplomaticquarterapp/core/model/pharmacies/order_model.dart'; +import 'package:diplomaticquarterapp/core/service/parmacyModule/order-preview-service.dart'; +import 'package:diplomaticquarterapp/locator.dart'; +import 'package:diplomaticquarterapp/uitl/gif_loader_dialog_utils.dart'; +import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; +import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; +import 'package:flutter_animarker/lat_lng_interpolation.dart'; +import 'package:flutter_animarker/models/lat_lng_delta.dart'; +import 'package:flutter_animarker/models/lat_lng_info.dart'; import 'package:flutter_polyline_points/flutter_polyline_points.dart'; +import 'package:geolocator/geolocator.dart'; import 'package:google_maps_flutter/google_maps_flutter.dart'; import 'package:location/location.dart'; - +import 'package:flutter_animarker/streams/lat_lng_stream.dart'; class TrackDriver extends StatefulWidget { final OrderDetailModel order; @@ -18,12 +31,13 @@ class TrackDriver extends StatefulWidget { } class _TrackDriverState extends State { + OrderPreviewService _orderServices = locator(); OrderDetailModel _order; Completer _controller = Completer(); - double CAMERA_ZOOM = 16; + double CAMERA_ZOOM = 14; double CAMERA_TILT = 0; double CAMERA_BEARING = 30; LatLng SOURCE_LOCATION = null; @@ -40,66 +54,120 @@ class _TrackDriverState extends State { BitmapDescriptor destinationIcon; // for my custom marker pins Location location;// wrapper around the location API + + int locationUpdateFreq = 2; + LatLngInterpolationStream _latLngStream; + StreamGroup subscriptions; + @override void initState() { + super.initState(); + _order = widget.order; DEST_LOCATION = _order.shippingAddress.getLocation(); location = new Location(); polylinePoints = PolylinePoints(); setSourceAndDestinationIcons(); + + initMarkerUpdateStream(); + startUpdatingDriverLocation(); + + } + + @override + void dispose() { + super.dispose(); + subscriptions.close(); + _latLngStream.cancel(); + stopUpdatingDriverLocation(); + } + + initMarkerUpdateStream(){ + _latLngStream = LatLngInterpolationStream(movementDuration: Duration(seconds: locationUpdateFreq+1)); + subscriptions = StreamGroup(); + + subscriptions.add(_latLngStream.getAnimatedPosition('sourcePin')); + subscriptions.stream.listen((LatLngDelta delta) { + //Update the marker with animation + setState(() { + //Get the marker Id for this animation + var markerId = MarkerId(delta.markerId); + Marker sourceMarker = Marker( + markerId: markerId, + // rotation: delta.rotation, + icon: sourceIcon, + position: LatLng( + delta.from.latitude, + delta.from.longitude, + ), + onTap: onSourceMarkerTap + ); + + _markers.removeWhere((m) => m.markerId.value == 'sourcePin'); + _markers.add(sourceMarker); + }); + }); } @override Widget build(BuildContext context) { - return new Scaffold( + + return AppScaffold( + appBarTitle: TranslationBase.of(context).deliveryDriverTrack, + isShowAppBar: true, + isPharmacy: true, + showPharmacyCart: false, + showHomeAppBarIcon: false, body: GoogleMap( myLocationEnabled: true, compassEnabled: true, markers: _markers, polylines: _polylines, mapType: MapType.normal, - initialCameraPosition: _orderDeliveryLocationCamera(), + initialCameraPosition: CameraPosition(target: DEST_LOCATION, zoom: 4), onMapCreated: (GoogleMapController controller) { _controller.complete(controller); - showPinsOnMap(); + // showPinsOnMap(); }, ), - floatingActionButton: FloatingActionButton.extended( - onPressed: _goToDriver, - label: Text('To the lake!'), - icon: Icon(Icons.directions_boat), - ), + // floatingActionButton: FloatingActionButton.extended( + // onPressed: _goToDriver, + // label: Text('To the lake!'), + // icon: Icon(Icons.directions_boat), + // ), ); } void setSourceAndDestinationIcons() async { - sourceIcon = await BitmapDescriptor.fromAssetImage( - ImageConfiguration(devicePixelRatio: 2.5), - 'assets/images/map_markers/source_map_marker.png'); - - destinationIcon = await BitmapDescriptor.fromAssetImage( - ImageConfiguration(devicePixelRatio: 2.5), - 'assets/images/map_markers/destination_map_marker.png'); + final Uint8List srcMarkerBytes = await getBytesFromAsset('assets/images/map_markers/source_map_marker.png', getMarkerIconSize()); + final Uint8List destMarkerBytes = await getBytesFromAsset('assets/images/map_markers/destination_map_marker.png', getMarkerIconSize()); + sourceIcon = await BitmapDescriptor.fromBytes(srcMarkerBytes); + destinationIcon = await BitmapDescriptor.fromBytes(destMarkerBytes); } CameraPosition _orderDeliveryLocationCamera(){ - - final CameraPosition orderDeliveryLocCamera = CameraPosition( - bearing: CAMERA_BEARING, - target: DEST_LOCATION, - tilt: CAMERA_TILT, - zoom: CAMERA_ZOOM); - return orderDeliveryLocCamera; + if(DEST_LOCATION != null){ + final CameraPosition orderDeliveryLocCamera = CameraPosition( + bearing: CAMERA_BEARING, + target: DEST_LOCATION, + tilt: CAMERA_TILT, + zoom: CAMERA_ZOOM); + return orderDeliveryLocCamera; + } + return null; } CameraPosition _driverLocationCamera(){ - final CameraPosition driverLocCamera = CameraPosition( - bearing: CAMERA_BEARING, - target: SOURCE_LOCATION, - tilt: CAMERA_TILT, - zoom: CAMERA_ZOOM); - return driverLocCamera; + if(DEST_LOCATION != null) { + final CameraPosition driverLocCamera = CameraPosition( + bearing: CAMERA_BEARING, + target: SOURCE_LOCATION, + tilt: CAMERA_TILT, + zoom: CAMERA_ZOOM); + return driverLocCamera; + } + return null; } @@ -116,25 +184,18 @@ class _TrackDriverState extends State { } - Future _fitCameraBetweenBothPoints() async { - final GoogleMapController controller = await _controller.future; - final CameraPosition driverLocCamera = CameraPosition( - bearing: CAMERA_BEARING, - target: SOURCE_LOCATION, - tilt: CAMERA_TILT, - zoom: CAMERA_ZOOM); - controller.animateCamera(CameraUpdate.newCameraPosition(driverLocCamera)); - } - void showPinsOnMap() { // source pin if(SOURCE_LOCATION != null){ setState(() { var pinPosition = SOURCE_LOCATION; + _markers.removeWhere((m) => m.markerId.value == 'sourcePin'); _markers.add(Marker( markerId: MarkerId('sourcePin'), position: pinPosition, - icon: sourceIcon + icon: sourceIcon, + infoWindow: InfoWindow(title: TranslationBase.of(context).driver), + onTap: onSourceMarkerTap )); }); } @@ -143,10 +204,13 @@ class _TrackDriverState extends State { if(DEST_LOCATION != null){ setState(() { var destPosition = DEST_LOCATION; + _markers.removeWhere((m) => m.markerId.value == 'destPin'); _markers.add(Marker( markerId: MarkerId('destPin'), position: destPosition, - icon: destinationIcon + icon: destinationIcon, + infoWindow: InfoWindow(title: TranslationBase.of(context).deliveryLocation), + onTap: onDestinationMarkerTap )); }); } @@ -156,32 +220,8 @@ class _TrackDriverState extends State { } void updatePinOnMap() async { - // create a new CameraPosition instance - // every time the location changes, so the camera - // follows the pin as it moves with an animation - CameraPosition cPosition = CameraPosition( - zoom: CAMERA_ZOOM, - tilt: CAMERA_TILT, - bearing: CAMERA_BEARING, - target: SOURCE_LOCATION, - ); - final GoogleMapController controller = await _controller.future; - controller.animateCamera(CameraUpdate.newCameraPosition(cPosition)); - // do this inside the setState() so Flutter gets notified - // that a widget update is due - setState(() { - // updated position - var pinPosition = SOURCE_LOCATION; - - // the trick is to remove the marker (by id) - // and add it again at the updated location - _markers.removeWhere((m) => m.markerId.value == 'sourcePin'); - _markers.add(Marker( - markerId: MarkerId('sourcePin'), - position: pinPosition, // updated position - icon: sourceIcon - )); - }); + _latLngStream.addLatLng(LatLngInfo(SOURCE_LOCATION.latitude, SOURCE_LOCATION.longitude, "sourcePin")); + drawRoute(); } void drawRoute() async { @@ -209,4 +249,96 @@ class _TrackDriverState extends State { }); } } -} \ No newline at end of file + + bool isLocationUpdating = false; + startUpdatingDriverLocation({int frequencyInSeconds = 2}) async{ + isLocationUpdating = true; + int driverId = int.tryParse(_order.driverID); + + Future.doWhile(() async{ + if(isLocationUpdating){ + + await Future.delayed(Duration(seconds: frequencyInSeconds)); + + showLoading(); + LatLng driverLocation = (await _orderServices.getDriverLocation(driverId)); + hideLoading(); + + if(driverLocation != null){ + if(SOURCE_LOCATION == null || DEST_LOCATION == null){ + SOURCE_LOCATION = driverLocation; + DEST_LOCATION = _order.shippingAddress.getLocation(); + showPinsOnMap(); + } + SOURCE_LOCATION = driverLocation; + updatePinOnMap(); + updateMapCamera(); + }else{ + GifLoaderDialogUtils.hideDialog(context); + } + } + return isLocationUpdating; + + }); + } + + showLoading(){ + if(SOURCE_LOCATION == null){ + GifLoaderDialogUtils.showMyDialog(context); + } + } + + hideLoading(){ + if(SOURCE_LOCATION == null){ + GifLoaderDialogUtils.hideDialog(context); + } + } + + stopUpdatingDriverLocation(){ + isLocationUpdating = false; + } + + Future getBytesFromAsset(String path, int width) async { + ByteData data = await rootBundle.load(path); + ui.Codec codec = await ui.instantiateImageCodec(data.buffer.asUint8List(), targetWidth: width); + ui.FrameInfo fi = await codec.getNextFrame(); + return (await fi.image.toByteData(format: ui.ImageByteFormat.png)).buffer.asUint8List(); + } + + int getMarkerIconSize(){ + return 140; + } + + updateMapCamera() async{ + if(SOURCE_LOCATION != null && DEST_LOCATION != null){ + + // 'package:google_maps_flutter_platform_interface/src/types/location.dart': Failed assertion: line 72 pos 16: 'southwest.latitude <= northeast.latitude': is not true. + LatLngBounds bound; + if(SOURCE_LOCATION.latitude <= DEST_LOCATION.latitude){ + bound = LatLngBounds(southwest: SOURCE_LOCATION, northeast: DEST_LOCATION); + }else{ + bound = LatLngBounds(southwest: DEST_LOCATION, northeast: SOURCE_LOCATION); + } + + if(bound == null) + return; + + CameraUpdate camera = CameraUpdate.newLatLngBounds(bound, 50); + final GoogleMapController controller = await _controller.future; + controller.animateCamera(camera); + } + } + + bool showSrcMarkerTitle = false; + onSourceMarkerTap() async{ + // showSrcMarkerTitle = !showSrcMarkerTitle; + } + + bool showDestMarkerTitle = false; + onDestinationMarkerTap() async{ + // showDestMarkerTitle = !showDestMarkerTitle; + // Marker m = _markers.firstWhere((m) => m.markerId.value == 'destPin'); + // if(showDestMarkerTitle){ + // } + } +} diff --git a/lib/pages/pharmacy/pharmacyAddresses/PharmacyAddresses.dart b/lib/pages/pharmacy/pharmacyAddresses/PharmacyAddresses.dart index 340e2bd8..51256e11 100644 --- a/lib/pages/pharmacy/pharmacyAddresses/PharmacyAddresses.dart +++ b/lib/pages/pharmacy/pharmacyAddresses/PharmacyAddresses.dart @@ -104,7 +104,7 @@ class _PharmacyAddressesState extends State { fontWeight: FontWeight.bold, backgroundColor: Color(0xFF5AB145), fontSize: 14, - vPadding: 12, + vPadding: 8, handler: () { model.saveSelectedAddressLocally( model.addresses[model.selectedAddressIndex]); diff --git a/lib/pages/pharmacy_categorise.dart b/lib/pages/pharmacy_categorise.dart index c89a7db4..ff1920dc 100644 --- a/lib/pages/pharmacy_categorise.dart +++ b/lib/pages/pharmacy_categorise.dart @@ -35,10 +35,10 @@ class _PharmacyCategorisePageState extends State { AppScaffold( isShowDecPage: false, baseViewModel: model, - body: SingleChildScrollView( - child: Column( - children: [ - Container( + body: Column( + children: [ + Expanded( + child: Container( height: 400, margin: EdgeInsets.only(bottom: 22), child: GridView.builder( @@ -88,174 +88,176 @@ class _PharmacyCategorisePageState extends State { }, ), ), - Container( - height: 140, - child: Column( - children: [ - Divider( - height: 2.0, - thickness: 1.0, - color: Colors.black12.withOpacity(0.14)), - SizedBox( - height: 10.0, - ), - Row( - children: [ - Expanded( - child: Padding( - padding: EdgeInsets.all(4.0), - child: InkWell( - onTap: () { - Navigator.push( - context, - FadePage( - page: FinalProductsPage( - id: "", - productType: 4, - ), + ), + Container( + height: 140, + child: Column( + children: [ + Divider( + height: 2.0, + thickness: 1.0, + color: Colors.black12.withOpacity(0.14)), + SizedBox( + height: 10.0, + ), + Row( + children: [ + Expanded( + child: Padding( + padding: EdgeInsets.all(4.0), + child: InkWell( + onTap: () { + Navigator.push( + context, + FadePage( + page: FinalProductsPage( + id: "", + productType: 6, ), - ); - }, - child: Container( - height: 50.0, - width: 55.0, - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(5.0), - color: - Colors.green.shade300.withOpacity(0.34), ), - child: Padding( - padding: - EdgeInsets.symmetric(horizontal: 10.0), - child: Texts( - projectViewModel.isArabic - ? 'الاكثر مبيعا' - : 'Best Sellers', - fontWeight: FontWeight.w600, - ), + ); + }, + child: Container( + height: 50.0, + width: 55.0, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(5.0), + color: + Colors.green.shade300.withOpacity(0.34), + ), + child: Padding( + padding: + EdgeInsets.symmetric(horizontal: 10.0), + child: Texts( + projectViewModel.isArabic + ? 'الاكثر مبيعا' + : 'Best Sellers', + fontWeight: FontWeight.w600, ), ), ), ), ), - Expanded( - child: Padding( - padding: EdgeInsets.all(4.0), - child: InkWell( - onTap: () { - Navigator.push( - context, - FadePage( - page: FinalProductsPage( - id: "", - productType: 2, - ), + ), + Expanded( + child: Padding( + padding: EdgeInsets.all(4.0), + child: InkWell( + onTap: () { + Navigator.push( + context, + FadePage( + page: FinalProductsPage( + id: "", + productType: 4, ), - ); - }, - child: Container( - height: 50.0, - width: 55.0, - decoration: BoxDecoration( - color: Colors.orangeAccent.shade200 - .withOpacity(0.34), - borderRadius: BorderRadius.circular(5.0), ), - child: Padding( - padding: EdgeInsets.symmetric(horizontal: 10.0), - child: Texts( - projectViewModel.isArabic - ? 'الاكثر مشاهدة' - : 'Most Viewed', - fontWeight: FontWeight.w600, - ), + ); + }, + child: Container( + height: 50.0, + width: 55.0, + decoration: BoxDecoration( + color: Colors.orangeAccent.shade200 + .withOpacity(0.34), + borderRadius: BorderRadius.circular(5.0), + ), + child: Padding( + padding: + EdgeInsets.symmetric(horizontal: 10.0), + child: Texts( + projectViewModel.isArabic + ? 'الاكثر مشاهدة' + : 'Most Viewed', + fontWeight: FontWeight.w600, ), ), ), ), ), - ], - ), - Row( - children: [ - Expanded( - child: Padding( - padding: EdgeInsets.all(4.0), - child: InkWell( - onTap: () { - Navigator.push( - context, - FadePage( - page: FinalProductsPage( - id: "", - productType: 1, - ), + ), + ], + ), + Row( + children: [ + Expanded( + child: Padding( + padding: EdgeInsets.all(4.0), + child: InkWell( + onTap: () { + Navigator.push( + context, + FadePage( + page: FinalProductsPage( + id: "", + productType: 5, ), - ); - }, - child: Container( - height: 50.0, - width: 55.0, - decoration: BoxDecoration( - color: Colors.blue.shade200.withOpacity(0.34), - borderRadius: BorderRadius.circular(5.0), ), - child: Padding( - padding: EdgeInsets.symmetric(horizontal: 10.0), - child: Texts( - projectViewModel.isArabic - ? 'منتجات جديدة' - : 'New Products', - fontWeight: FontWeight.w600, - ), + ); + }, + child: Container( + height: 50.0, + width: 55.0, + decoration: BoxDecoration( + color: Colors.blue.shade200.withOpacity(0.34), + borderRadius: BorderRadius.circular(5.0), + ), + child: Padding( + padding: + EdgeInsets.symmetric(horizontal: 10.0), + child: Texts( + projectViewModel.isArabic + ? 'منتجات جديدة' + : 'New Products', + fontWeight: FontWeight.w600, ), ), ), ), ), - Expanded( - child: Padding( - padding: EdgeInsets.all(4.0), - child: InkWell( - onTap: () { - Navigator.push( - context, - FadePage( - page: FinalProductsPage( - id: "", - productType: 3, - ), + ), + Expanded( + child: Padding( + padding: EdgeInsets.all(4.0), + child: InkWell( + onTap: () { + Navigator.push( + context, + FadePage( + page: FinalProductsPage( + id: "", + productType: 3, ), - ); - }, - child: Container( - height: 50.0, - width: 55.0, - decoration: BoxDecoration( - color: - Colors.purple.shade200.withOpacity(0.34), - borderRadius: BorderRadius.circular(5.0), ), - child: Padding( - padding: - EdgeInsets.symmetric(horizontal: 10.0), - child: Texts( - projectViewModel.isArabic - ? 'شوهد مؤخرا' - : 'Recently Viewed', - fontWeight: FontWeight.w600, - ), + ); + }, + child: Container( + height: 50.0, + width: 55.0, + decoration: BoxDecoration( + color: + Colors.purple.shade200.withOpacity(0.34), + borderRadius: BorderRadius.circular(5.0), + ), + child: Padding( + padding: + EdgeInsets.symmetric(horizontal: 10.0), + child: Texts( + projectViewModel.isArabic + ? 'شوهد مؤخرا' + : 'Recently Viewed', + fontWeight: FontWeight.w600, ), ), ), ), ), - ], - ), - ], - )), - ], - ), + ), + ], + ), + ], + )), + ], ), ), ); diff --git a/lib/pages/settings/general_setting.dart b/lib/pages/settings/general_setting.dart index 14f24181..0a6b0e73 100644 --- a/lib/pages/settings/general_setting.dart +++ b/lib/pages/settings/general_setting.dart @@ -40,7 +40,7 @@ class _GeneralSettings extends State return Container( child: ListView(scrollDirection: Axis.vertical, children: [ Container( - color: Theme.of(context).primaryColor, + color: Theme.of(context).scaffoldBackgroundColor, padding: EdgeInsets.all(10), child: AppText( TranslationBase.of(context).modes, @@ -48,7 +48,7 @@ class _GeneralSettings extends State ), ), Container( - color: Theme.of(context).primaryColor, + color: Theme.of(context).scaffoldBackgroundColor, padding: EdgeInsets.all(10), child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, @@ -68,7 +68,7 @@ class _GeneralSettings extends State ], )), Container( - color: Theme.of(context).primaryColor, + color: Theme.of(context).scaffoldBackgroundColor, padding: EdgeInsets.all(10), child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, @@ -88,7 +88,7 @@ class _GeneralSettings extends State ], )), Container( - color: Theme.of(context).primaryColor, + color: Theme.of(context).scaffoldBackgroundColor, padding: EdgeInsets.all(10), child: AppText( TranslationBase.of(context).blindMode, @@ -96,7 +96,7 @@ class _GeneralSettings extends State ), ), new Container( - color: Theme.of(context).primaryColor, + color: Theme.of(context).scaffoldBackgroundColor, padding: EdgeInsets.all(8.0), child: new Column( mainAxisAlignment: MainAxisAlignment.center, @@ -179,7 +179,7 @@ class _GeneralSettings extends State ) ])), Container( - color: Theme.of(context).primaryColor, + color: Theme.of(context).scaffoldBackgroundColor, padding: EdgeInsets.all(10), child: AppText( TranslationBase.of(context).permissions, @@ -187,7 +187,7 @@ class _GeneralSettings extends State ), ), Container( - color: Theme.of(context).primaryColor, + color: Theme.of(context).scaffoldBackgroundColor, padding: EdgeInsets.all(10), child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, @@ -206,7 +206,7 @@ class _GeneralSettings extends State ], )), Container( - color: Theme.of(context).primaryColor, + color: Theme.of(context).scaffoldBackgroundColor, padding: EdgeInsets.all(10), child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, @@ -284,9 +284,13 @@ class _GeneralSettings extends State getTheme(value) async { if (value == 1) { - return invertThemes(); + return invertThemes( + fontName: Provider.of(context, listen: false).isArabic ? 'Cairo' : 'WorkSans' + ); } else if (value == 3) { - return bwThemes(); + return bwThemes( + fontName: Provider.of(context, listen: false).isArabic ? 'Cairo' : 'WorkSans' + ); } else { return defaultTheme( fontName: diff --git a/lib/pages/vaccine/my_vaccines_screen.dart b/lib/pages/vaccine/my_vaccines_screen.dart index 169e5cd5..fb723a1f 100644 --- a/lib/pages/vaccine/my_vaccines_screen.dart +++ b/lib/pages/vaccine/my_vaccines_screen.dart @@ -169,29 +169,30 @@ class _MyVaccinesState extends State { width: double.infinity, // height: 80.0, child: Button( + disabled: true, label: TranslationBase.of(context).checkVaccineAvailability, backgroundColor: Color(0xff9EA3A4), - onTap: () => - Navigator.push(context, FadePage(page: MyVaccinesItemPage())), + onTap: () => Navigator.push( + context, FadePage(page: MyVaccinesItemPage())), ), ), - if(projectViewModel.havePrivilege(27)) - Container( - width: double.infinity, - // height: 80.0, - child: SecondaryButton( - label: TranslationBase.of(context).sendEmail, - color: Color(0xffF62426), - textColor: Colors.white, - disabled: model.vaccineList.length == 0, - loading: model.state == ViewState.BusyLocal, - onTap: () async { - model.sendEmail( - message: - TranslationBase.of(context).emailSentSuccessfully); - }, + if (projectViewModel.havePrivilege(27)) + Container( + width: double.infinity, + // height: 80.0, + child: SecondaryButton( + label: TranslationBase.of(context).sendEmail, + color: Color(0xffF62426), + textColor: Colors.white, + disabled: model.vaccineList.length == 0, + loading: model.state == ViewState.BusyLocal, + onTap: () async { + model.sendEmail( + message: TranslationBase.of(context) + .emailSentSuccessfully); + }, + ), ), - ), ], ), ), diff --git a/lib/routes.dart b/lib/routes.dart index 97d506c5..738a00e9 100644 --- a/lib/routes.dart +++ b/lib/routes.dart @@ -12,6 +12,9 @@ import 'package:diplomaticquarterapp/pages/login/welcome.dart'; import 'package:diplomaticquarterapp/pages/login/login-type.dart'; import 'package:diplomaticquarterapp/pages/login/login.dart'; import 'package:diplomaticquarterapp/pages/login/register.dart'; +import 'package:diplomaticquarterapp/pages/packages_offers/OfferAndPackagesCartPage.dart'; +import 'package:diplomaticquarterapp/pages/packages_offers/OfferAndPackagesPage.dart'; +import 'package:diplomaticquarterapp/pages/packages_offers/PackageOrderCompletedPage.dart'; import 'package:diplomaticquarterapp/pages/settings/settings.dart'; import 'package:diplomaticquarterapp/pages/symptom-checker/info.dart'; import 'package:diplomaticquarterapp/pages/symptom-checker/select-gender.dart'; @@ -37,6 +40,10 @@ const String SYMPTOM_CHECKER = 'symptom-checker'; const String SYMPTOM_CHECKER_INFO = 'symptom-checker-info'; const String SELECT_GENDER = 'select-gender'; const String SETTINGS = 'settings'; +const String PACKAGES_OFFERS = 'packages-offers'; +const String PACKAGES_OFFERS_CART = 'packages-offers-cart'; +const String PACKAGES_ORDER_COMPLETED = 'packages-offers-cart'; + const String HEALTH_WEATHER = 'health-weather'; const APP_UPDATE = 'app-update'; var routes = { @@ -57,6 +64,9 @@ var routes = { SYMPTOM_CHECKER_INFO: (_) => SymptomInfo(), SELECT_GENDER: (_) => SelectGender(), SETTINGS: (_) => Settings(), + PACKAGES_OFFERS: (_) => PackagesHomePage(), + PACKAGES_OFFERS_CART: (_) => PackagesCartPage(), + PACKAGES_ORDER_COMPLETED: (_) => PackageOrderCompletedPage(), HEALTH_WEATHER: (_) => HealthWeatherIndicator(), APP_UPDATE: (_) => AppUpdatePage(), SETTINGS: (_) => Settings(), diff --git a/lib/services/authentication/auth_provider.dart b/lib/services/authentication/auth_provider.dart index 8f0ea470..bd2006f8 100644 --- a/lib/services/authentication/auth_provider.dart +++ b/lib/services/authentication/auth_provider.dart @@ -378,24 +378,24 @@ class AuthProvider with ChangeNotifier { Future sendPatientIDSMS(mobileNo, context) async { Map request; - var languageID = - await sharedPref.getStringWithDefaultValue(APP_LANGUAGE, 'ar'); + // var languageID = + // await sharedPref.getStringWithDefaultValue(APP_LANGUAGE, 'ar'); Request req = appGlobal.getPublicRequest(); request = { - "LanguageID": languageID == 'ar' ? 1 : 2, - "IPAdress": "10.20.10.20", - "VersionID": req.VersionID, - "Channel": req.Channel, - "generalid": 'Cs2020@2016\$2958', - "PatientOutSA": 0, - "PatientID": 0, - "TokenID": "", + // "LanguageID": languageID == 'ar' ? 1 : 2, + // "IPAdress": "10.20.10.20", + // "VersionID": req.VersionID, + // "Channel": req.Channel, + // "generalid": 'Cs2020@2016\$2958', + // "PatientOutSA": 0, + // "PatientID": 0, + // "TokenID": "", "PatientMobileNumber": mobileNo, "SearchType": 2, - "ZipCode": "966", - "PatientIdentificationID": "", + // "ZipCode": "966", + // "PatientIdentificationID": "", "DeviceTypeID": req.DeviceTypeID, - "SessionID": null + // "SessionID": null }; dynamic localRes; diff --git a/lib/services/pharmacy_services/product_detail_service.dart b/lib/services/pharmacy_services/product_detail_service.dart index 276151a7..f85faf2c 100644 --- a/lib/services/pharmacy_services/product_detail_service.dart +++ b/lib/services/pharmacy_services/product_detail_service.dart @@ -88,7 +88,7 @@ class ProductDetailService extends BaseService { "language_id": 1 } }; - await baseAppClient.pharmacyPost(GET_SHOPPING_CART, + await baseAppClient.pharmacyPost(GET_SHOPPING_CART, isExternal: false, onSuccess: (dynamic response, int statusCode) { _addToCartModel.clear(); response['shopping_carts'].forEach((item) { diff --git a/lib/theme/theme_notifier.dart b/lib/theme/theme_notifier.dart index 402a7865..e61c73a6 100644 --- a/lib/theme/theme_notifier.dart +++ b/lib/theme/theme_notifier.dart @@ -11,6 +11,8 @@ class ThemeNotifier with ChangeNotifier { getTheme() => _themeData; + getTheme_(String font) => _themeData; + setTheme(ThemeData themeData) async { _themeData = themeData; notifyListeners(); diff --git a/lib/theme/theme_value.dart b/lib/theme/theme_value.dart index 129174ee..65d6f81d 100644 --- a/lib/theme/theme_value.dart +++ b/lib/theme/theme_value.dart @@ -35,7 +35,7 @@ defaultTheme({fontName}) { backgroundColor: Color.fromRGBO(255, 255, 255, 1), highlightColor: Colors.grey[100].withOpacity(0.4), splashColor: Colors.transparent, - primaryColor: Color(0xffffffff), + primaryColor: Color(0xff515A5D), buttonColor: Colors.black, toggleableActiveColor: secondaryColor, indicatorColor: secondaryColor, @@ -45,9 +45,11 @@ defaultTheme({fontName}) { primaryTextTheme: TextTheme(bodyText2: TextStyle(color: Colors.white)), iconTheme: IconThemeData(), textTheme: TextTheme( - bodyText1: TextStyle(color: Colors.black), - headline1: TextStyle(color: Colors.white), - ), + bodyText1: TextStyle(color: Colors.black), + headline1: TextStyle(color: Colors.white), + headline2: TextStyle(color: Colors.white)), + floatingActionButtonTheme: FloatingActionButtonThemeData(highlightElevation: 2, disabledElevation: 0, elevation: 2), + appBarTheme: AppBarTheme( color: Color(0xff515A5D), brightness: Brightness.light, @@ -74,9 +76,9 @@ invertThemes({fontName}) { ), hintColor: Colors.grey[400], textTheme: TextTheme( - bodyText1: TextStyle(color: Colors.white), - headline1: TextStyle(color: Colors.white), - ), + bodyText1: TextStyle(color: Colors.white), + headline1: TextStyle(color: Colors.white), + headline2: TextStyle(color: Colors.white)), disabledColor: Colors.grey[800], errorColor: Color.fromRGBO(235, 80, 60, 1.0), scaffoldBackgroundColor: Color(0xff000000), // Colors.grey[100], @@ -125,6 +127,7 @@ bwThemes({fontName}) { textTheme: TextTheme( bodyText1: TextStyle(color: Colors.red[900]), headline1: TextStyle(color: Colors.red[900]), + headline2: TextStyle(color: Colors.white), bodyText2: TextStyle(color: Colors.red[900]), subtitle1: TextStyle(color: Colors.red[900]), ), diff --git a/lib/uitl/gif_loader_dialog_utils.dart b/lib/uitl/gif_loader_dialog_utils.dart index ac37cdfb..785a6c6c 100644 --- a/lib/uitl/gif_loader_dialog_utils.dart +++ b/lib/uitl/gif_loader_dialog_utils.dart @@ -8,6 +8,10 @@ class GifLoaderDialogUtils { } static hideDialog(BuildContext context) { - Navigator.of(context).pop(); + try{ + Navigator.of(context).pop(); + }catch(error){ + Future.delayed(Duration(milliseconds: 250)).then((value) => Navigator.of(context).pop()); + } } } diff --git a/lib/uitl/translations_delegate_base.dart b/lib/uitl/translations_delegate_base.dart index ec41544e..0e0058f9 100644 --- a/lib/uitl/translations_delegate_base.dart +++ b/lib/uitl/translations_delegate_base.dart @@ -752,6 +752,9 @@ class TranslationBase { String get shippedMethod => localizedValues['shippedMethod'][locale.languageCode]; String get orderDetail => localizedValues['orderDetail'][locale.languageCode]; + String get deliveryDriverTrack => localizedValues['DeliveryDriverTrack'][locale.languageCode]; + String get deliveryLocation => localizedValues['DeliveryLocation'][locale.languageCode]; + String get driver => localizedValues['Driver'][locale.languageCode]; String get subtotal => localizedValues['subtotal'][locale.languageCode]; String get shipping => localizedValues['shipping'][locale.languageCode]; String get shipBy => localizedValues['shipBy'][locale.languageCode]; @@ -985,6 +988,7 @@ class TranslationBase { String get average => localizedValues['Average'][locale.languageCode]; String get dailyDoses => localizedValues['DailyDoses'][locale.languageCode]; String get period => localizedValues['Period'][locale.languageCode]; + String get duration => localizedValues['duration'][locale.languageCode]; String get cm => localizedValues['cm'][locale.languageCode]; String get kg => localizedValues['kg'][locale.languageCode]; String get lb => localizedValues['lb'][locale.languageCode]; @@ -1394,9 +1398,12 @@ class TranslationBase { String get convertFrom => localizedValues["convertFrom"][locale.languageCode]; String get result => localizedValues["result"][locale.languageCode]; String get sort => localizedValues["sort"][locale.languageCode]; - String get bloodSugarConversion => localizedValues["bloodSugarConversion"][locale.languageCode]; - String get convertCholesterolStatement => localizedValues["convertCholesterolStatement"][locale.languageCode]; - String get triglyceridesConvertStatement => localizedValues["triglyceridesConvertStatement"][locale.languageCode]; + String get bloodSugarConversion => + localizedValues["bloodSugarConversion"][locale.languageCode]; + String get convertCholesterolStatement => + localizedValues["convertCholesterolStatement"][locale.languageCode]; + String get triglyceridesConvertStatement => + localizedValues["triglyceridesConvertStatement"][locale.languageCode]; String get bloodDEnterDesc => localizedValues["bloodD-enter-desc"][locale.languageCode]; String get viewTermsConditions => @@ -1550,6 +1557,12 @@ class TranslationBase { String get submitncontinue => localizedValues["submitncontinue"][locale.languageCode]; String get areyousure => localizedValues["areyousure"][locale.languageCode]; + + + // Offer And Packahes + String get subT=> localizedValues['OffersAndPackages'][locale.languageCode]; + String get totalWithColonRight => localizedValues['totalWithColonRight'][locale.languageCode]; + String get preferredunit => localizedValues["preferredunit"][locale.languageCode]; String get trySaying => localizedValues["try-saying"][locale.languageCode]; @@ -1570,13 +1583,28 @@ class TranslationBase { String get shippingAddresss => localizedValues["shipping-address"][locale.languageCode]; String get covidAlert => localizedValues["covid-alert"][locale.languageCode]; - String get onlineCheckInAgreement => localizedValues["onlineCheckInAgreement"][locale.languageCode]; - String get chiefComplaints => localizedValues["chiefComplaints"][locale.languageCode]; - String get errorChiefComplaints => localizedValues["errorChiefComplaints"][locale.languageCode]; - String get expectedArrivalTime => localizedValues["expectedArrivalTime"][locale.languageCode]; - String get errorExpectedArrivalTime => localizedValues["errorExpectedArrivalTimes"][locale.languageCode]; + String get pharmacyRelogin => + localizedValues["pharmacy-relogin"][locale.languageCode]; + String get onlineCheckInAgreement => + localizedValues["onlineCheckInAgreement"][locale.languageCode]; + String get chiefComplaints => + localizedValues["chiefComplaints"][locale.languageCode]; + String get errorChiefComplaints => + localizedValues["errorChiefComplaints"][locale.languageCode]; + String get expectedArrivalTime => + localizedValues["expectedArrivalTime"][locale.languageCode]; + String get errorExpectedArrivalTime => + localizedValues["errorExpectedArrivalTimes"][locale.languageCode]; String get anicllaryOrders => localizedValues["ancillary-orders"][locale.languageCode]; + String get mrn => localizedValues["MRN"][locale.languageCode]; + String get appointmentDate => + localizedValues["appointment-date"][locale.languageCode]; + String get appointmentNo => + localizedValues["appointment-no"][locale.languageCode]; + String get insuranceID => + localizedValues["insurance-id"][locale.languageCode]; + String get enterFile => localizedValues["enter-file"][locale.languageCode]; } class TranslationBaseDelegate extends LocalizationsDelegate { diff --git a/lib/uitl/utils.dart b/lib/uitl/utils.dart index c08d68a4..9d8f5326 100644 --- a/lib/uitl/utils.dart +++ b/lib/uitl/utils.dart @@ -3,6 +3,7 @@ import 'dart:core'; import 'dart:typed_data'; import 'package:badges/badges.dart'; +import 'package:cached_network_image/cached_network_image.dart'; import 'package:connectivity/connectivity.dart'; import 'package:diplomaticquarterapp/config/shared_pref_kay.dart'; import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; @@ -36,7 +37,7 @@ import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:shared_preferences/shared_preferences.dart'; - +import 'package:url_launcher/url_launcher.dart'; import '../Constants.dart'; import 'app_shared_preferences.dart'; import 'app_toast.dart'; @@ -183,10 +184,9 @@ class Utils { // } } - static getPhoneNumberWithoutZero(String number){ - String newNumber=""; - if(number.startsWith('0')) - { + static getPhoneNumberWithoutZero(String number) { + String newNumber = ""; + if (number.startsWith('0')) { newNumber = number.substring(1); } return newNumber; @@ -202,7 +202,11 @@ class Utils { .hasMatch(email); } - static List myMedicalList({ProjectViewModel projectViewModel, BuildContext context, bool isLogin, count}) { + static List myMedicalList( + {ProjectViewModel projectViewModel, + BuildContext context, + bool isLogin, + count}) { List medical = List(); if (projectViewModel.havePrivilege(5)) { medical.add(InkWell( @@ -406,16 +410,16 @@ class Utils { )); } if (projectViewModel.havePrivilege(20)) - medical.add(InkWell( - onTap: () { - Navigator.push(context, FadePage(page: HomeReportPage())); - }, - child: MedicalProfileItem( - title: TranslationBase.of(context).medical, - imagePath: 'medical_reports_icon.png', - subTitle: TranslationBase.of(context).medicalSubtitle, - ), - )); + medical.add(InkWell( + onTap: () { + Navigator.push(context, FadePage(page: HomeReportPage())); + }, + child: MedicalProfileItem( + title: TranslationBase.of(context).medical, + imagePath: 'medical_reports_icon.png', + subTitle: TranslationBase.of(context).medicalSubtitle, + ), + )); if (projectViewModel.havePrivilege(19)) { medical.add(InkWell( @@ -477,16 +481,16 @@ class Utils { )); } if (projectViewModel.havePrivilege(30)) - medical.add(InkWell( - onTap: () { - Navigator.push(context, FadePage(page: SmartWatchInstructions())); - }, - child: MedicalProfileItem( - title: TranslationBase.of(context).smartWatches, - imagePath: 'smartwatch_icon.png', - subTitle: TranslationBase.of(context).smartWatchesSubtitle, - ), - )); + medical.add(InkWell( + onTap: () { + Navigator.push(context, FadePage(page: SmartWatchInstructions())); + }, + child: MedicalProfileItem( + title: TranslationBase.of(context).smartWatches, + imagePath: 'smartwatch_icon.png', + subTitle: TranslationBase.of(context).smartWatchesSubtitle, + ), + )); if (projectViewModel.havePrivilege(28)) { medical.add(InkWell( @@ -500,25 +504,29 @@ class Utils { ), )); } - if (projectViewModel.havePrivilege(32) || true) { + if (projectViewModel.havePrivilege(32) || true) { medical.add(InkWell( - onTap: () { - userData().then((userData_){ - if (projectViewModel.isLogin && userData_ != null) { - String patientID = userData_.patientID.toString(); - GifLoaderDialogUtils.showMyDialog(context); - projectViewModel.platformBridge().connectHMGInternetWifi(patientID).then((value) => {GifLoaderDialogUtils.hideDialog(context)}); - } else { - AlertDialogBox( - context: context, - confirmMessage: "Please login with your account first to use this feature", - okText: "OK", - okFunction: () { - AlertDialogBox.closeAlertDialog(context); - }).showAlertDialog(context); - } - }); - }, + onTap: () { + userData().then((userData_) { + if (projectViewModel.isLogin && userData_ != null) { + String patientID = userData_.patientID.toString(); + GifLoaderDialogUtils.showMyDialog(context); + projectViewModel + .platformBridge() + .connectHMGInternetWifi(patientID) + .then((value) => {GifLoaderDialogUtils.hideDialog(context)}); + } else { + AlertDialogBox( + context: context, + confirmMessage: + "Please login with your account first to use this feature", + okText: "OK", + okFunction: () { + AlertDialogBox.closeAlertDialog(context); + }).showAlertDialog(context); + } + }); + }, child: MedicalProfileItem( title: TranslationBase.of(context).internet, imagePath: 'insurance_card_icon.png', @@ -529,10 +537,9 @@ class Utils { if (projectViewModel.havePrivilege(40)) { medical.add(InkWell( -// onTap: () { -// Navigator.push( -// context, FadePage(page: InsuranceApproval())); -// }, + onTap: () { + launch('whatsapp://send?phone=18885521858&text='); + }, child: MedicalProfileItem( title: TranslationBase.of(context).chatbot, imagePath: 'insurance_approvals_icon.png', @@ -543,14 +550,49 @@ class Utils { return medical; } + + static Widget loadNetworkImage({@required String url, BoxFit fitting = BoxFit.cover}){ + return CachedNetworkImage( + placeholderFadeInDuration: Duration(milliseconds: 250), + fit: fitting, + imageUrl: url, + placeholder: (context, url) => Container( + child: Center( + child: CircularProgressIndicator() + ) + ), + errorWidget: (context, url, error){ + return Icon(Icons.error, color: Colors.red, size: 50,); + } + ); + } } -Future userData() async { - var userData = AuthenticatedUser.fromJson(await AppSharedPreferences().getObject(MAIN_USER)); - return userData; + + + +Widget applyShadow({ Color color = Colors.grey, double shadowOpacity = 0.5, double spreadRadius = 2, double blurRadius = 7, Offset offset = const Offset(2, 2), @required Widget child}){ + return Container( + decoration: BoxDecoration( + boxShadow: [ + BoxShadow( + color: color.withOpacity(shadowOpacity), + spreadRadius: spreadRadius, + blurRadius: blurRadius, + offset: offset, // changes position of shadow + ), + ], + ), + child: child, + ); } +Future userData() async { + var userData = AuthenticatedUser.fromJson( + await AppSharedPreferences().getObject(MAIN_USER)); + return userData; +} // extension function that use in iterations(list.. etc) to iterate items and get index and item it self extension IndexedIterable on Iterable { diff --git a/lib/widgets/AnimatedTextFields.dart b/lib/widgets/AnimatedTextFields.dart new file mode 100644 index 00000000..b4ad5f65 --- /dev/null +++ b/lib/widgets/AnimatedTextFields.dart @@ -0,0 +1,347 @@ +import 'dart:math'; + +import 'package:flutter/gestures.dart'; +import 'package:flutter/material.dart'; + +enum TextFieldInertiaDirection { + left, + right, +} + +Interval _getInternalInterval( + double start, + double end, + double externalStart, + double externalEnd, [ + Curve curve = Curves.linear, + ]) { + return Interval( + start + (end - start) * externalStart, + start + (end - start) * externalEnd, + curve: curve, + ); +} + +class AnimatedTextFormField extends StatefulWidget { + AnimatedTextFormField({ + Key key, + this.interval = const Interval(0.0, 1.0), + @required this.width, + this.loadingController, + this.inertiaController, + this.inertiaDirection, + this.enabled = true, + this.labelText, + this.prefixIcon, + this.suffixIcon, + this.keyboardType, + this.textInputAction, + this.obscureText = false, + this.controller, + this.focusNode, + this.validator, + this.onFieldSubmitted, + this.onSaved, + }) : assert((inertiaController == null && inertiaDirection == null) || + (inertiaController != null && inertiaDirection != null)), + super(key: key); + + final Interval interval; + final AnimationController loadingController; + final AnimationController inertiaController; + final double width; + final bool enabled; + final String labelText; + final Widget prefixIcon; + final Widget suffixIcon; + final TextInputType keyboardType; + final TextInputAction textInputAction; + final bool obscureText; + final TextEditingController controller; + final FocusNode focusNode; + final FormFieldValidator validator; + final ValueChanged onFieldSubmitted; + final FormFieldSetter onSaved; + final TextFieldInertiaDirection inertiaDirection; + + @override + _AnimatedTextFormFieldState createState() => _AnimatedTextFormFieldState(); +} + +class _AnimatedTextFormFieldState extends State { + Animation scaleAnimation; + Animation sizeAnimation; + Animation suffixIconOpacityAnimation; + + Animation fieldTranslateAnimation; + Animation iconRotationAnimation; + Animation iconTranslateAnimation; + + @override + void initState() { + super.initState(); + + widget.inertiaController?.addStatusListener(handleAnimationStatus); + + final interval = widget.interval; + final loadingController = widget.loadingController; + + if (loadingController != null) { + scaleAnimation = Tween( + begin: 0.0, + end: 1.0, + ).animate(CurvedAnimation( + parent: loadingController, + curve: _getInternalInterval( + 0, .2, interval.begin, interval.end, Curves.easeOutBack), + )); + suffixIconOpacityAnimation = + Tween(begin: 0.0, end: 1.0).animate(CurvedAnimation( + parent: loadingController, + curve: _getInternalInterval(.65, 1.0, interval.begin, interval.end), + )); + _updateSizeAnimation(); + } + + final inertiaController = widget.inertiaController; + final inertiaDirection = widget.inertiaDirection; + final sign = inertiaDirection == TextFieldInertiaDirection.right ? 1 : -1; + + if (inertiaController != null) { + fieldTranslateAnimation = Tween( + begin: 0.0, + end: sign * 15.0, + ).animate(CurvedAnimation( + parent: inertiaController, + curve: Interval(0, .5, curve: Curves.easeOut), + reverseCurve: Curves.easeIn, + )); + iconRotationAnimation = + Tween(begin: 0.0, end: sign * pi / 12 /* ~15deg */) + .animate(CurvedAnimation( + parent: inertiaController, + curve: Interval(.5, 1.0, curve: Curves.easeOut), + reverseCurve: Curves.easeIn, + )); + iconTranslateAnimation = + Tween(begin: 0.0, end: 8.0).animate(CurvedAnimation( + parent: inertiaController, + curve: Interval(.5, 1.0, curve: Curves.easeOut), + reverseCurve: Curves.easeIn, + )); + } + } + + void _updateSizeAnimation() { + final interval = widget.interval; + final loadingController = widget.loadingController; + + sizeAnimation = Tween( + begin: 48.0, + end: widget.width, + ).animate(CurvedAnimation( + parent: loadingController, + curve: _getInternalInterval( + .2, 1.0, interval.begin, interval.end, Curves.linearToEaseOut), + reverseCurve: Curves.easeInExpo, + )); + } + + @override + void didUpdateWidget(AnimatedTextFormField oldWidget) { + super.didUpdateWidget(oldWidget); + + if (oldWidget.width != widget.width) { + _updateSizeAnimation(); + } + } + + @override + dispose() { + widget.inertiaController?.removeStatusListener(handleAnimationStatus); + super.dispose(); + } + + void handleAnimationStatus(status) { + if (status == AnimationStatus.completed) { + widget.inertiaController?.reverse(); + } + } + + Widget _buildInertiaAnimation(Widget child) { + if (widget.inertiaController == null) { + return child; + } + + return AnimatedBuilder( + animation: iconTranslateAnimation, + builder: (context, child) => Transform( + alignment: Alignment.center, + transform: Matrix4.identity() + ..translate(iconTranslateAnimation.value) + ..rotateZ(iconRotationAnimation.value), + child: child, + ), + child: child, + ); + } + + InputDecoration _getInputDecoration(ThemeData theme) { + return InputDecoration( + contentPadding: EdgeInsets.fromLTRB(0, 0, 0, 0), + border: OutlineInputBorder( + borderRadius: new BorderRadius.circular(10.0), + borderSide: new BorderSide(), + ), + labelText: widget.labelText, + prefixIcon: _buildInertiaAnimation(widget.prefixIcon), + suffixIcon: _buildInertiaAnimation(widget.loadingController != null + ? FadeTransition( + opacity: suffixIconOpacityAnimation, + child: widget.suffixIcon, + ) + : widget.suffixIcon), + ); + } + + @override + Widget build(BuildContext context) { + final theme = Theme.of(context); + Widget textField = TextFormField( + controller: widget.controller, + focusNode: widget.focusNode, + decoration: _getInputDecoration(theme), + keyboardType: widget.keyboardType, + textInputAction: widget.textInputAction, + obscureText: widget.obscureText, + onFieldSubmitted: widget.onFieldSubmitted, + onSaved: widget.onSaved, + validator: widget.validator, + enabled: widget.enabled, + ); + + if (widget.loadingController != null) { + textField = ScaleTransition( + scale: scaleAnimation, + child: AnimatedBuilder( + animation: sizeAnimation, + builder: (context, child) => ConstrainedBox( + constraints: BoxConstraints.tightFor(width: sizeAnimation.value), + child: child, + ), + child: textField, + ), + ); + } + + if (widget.inertiaController != null) { + textField = AnimatedBuilder( + animation: fieldTranslateAnimation, + builder: (context, child) => Transform.translate( + offset: Offset(fieldTranslateAnimation.value, 0), + child: child, + ), + child: textField, + ); + } + + return textField; + } +} + +class AnimatedPasswordTextFormField extends StatefulWidget { + AnimatedPasswordTextFormField({ + Key key, + this.interval = const Interval(0.0, 1.0), + @required this.animatedWidth, + this.loadingController, + this.inertiaController, + this.inertiaDirection, + this.enabled = true, + this.labelText, + this.keyboardType, + this.textInputAction, + this.controller, + this.focusNode, + this.validator, + this.onFieldSubmitted, + this.onSaved, + }) : assert((inertiaController == null && inertiaDirection == null) || + (inertiaController != null && inertiaDirection != null)), + super(key: key); + + final Interval interval; + final AnimationController loadingController; + final AnimationController inertiaController; + final double animatedWidth; + final bool enabled; + final String labelText; + final TextInputType keyboardType; + final TextInputAction textInputAction; + final TextEditingController controller; + final FocusNode focusNode; + final FormFieldValidator validator; + final ValueChanged onFieldSubmitted; + final FormFieldSetter onSaved; + final TextFieldInertiaDirection inertiaDirection; + + @override + _AnimatedPasswordTextFormFieldState createState() => + _AnimatedPasswordTextFormFieldState(); +} + +class _AnimatedPasswordTextFormFieldState + extends State { + var _obscureText = true; + + @override + Widget build(BuildContext context) { + return AnimatedTextFormField( + interval: widget.interval, + loadingController: widget.loadingController, + inertiaController: widget.inertiaController, + width: widget.animatedWidth, + enabled: widget.enabled, + labelText: widget.labelText, + prefixIcon: Icon(Icons.lock, size: 20), + suffixIcon: GestureDetector( + onTap: () => setState(() => _obscureText = !_obscureText), + dragStartBehavior: DragStartBehavior.down, + child: AnimatedCrossFade( + duration: const Duration(milliseconds: 250), + firstCurve: Curves.easeInOutSine, + secondCurve: Curves.easeInOutSine, + alignment: Alignment.center, + layoutBuilder: (Widget topChild, _, Widget bottomChild, __) { + return Stack( + alignment: Alignment.center, + children: [bottomChild, topChild], + ); + }, + firstChild: Icon( + Icons.visibility, + size: 25.0, + semanticLabel: 'show password', + ), + secondChild: Icon( + Icons.visibility_off, + size: 25.0, + semanticLabel: 'hide password', + ), + crossFadeState: _obscureText + ? CrossFadeState.showFirst + : CrossFadeState.showSecond, + ), + ), + obscureText: _obscureText, + keyboardType: widget.keyboardType, + textInputAction: widget.textInputAction, + controller: widget.controller, + focusNode: widget.focusNode, + validator: widget.validator, + onFieldSubmitted: widget.onFieldSubmitted, + onSaved: widget.onSaved, + inertiaDirection: widget.inertiaDirection, + ); + } +} \ No newline at end of file diff --git a/lib/widgets/CounterView.dart b/lib/widgets/CounterView.dart new file mode 100644 index 00000000..6ba77c15 --- /dev/null +++ b/lib/widgets/CounterView.dart @@ -0,0 +1,188 @@ +import 'package:flutter/material.dart'; + +typedef StepperCallbackFuture = Future Function(int apply, int total); + +class StepperView extends StatefulWidget { + final double height; + final Color foregroundColor; + final Color backgroundColor; + final double buttonPadding; + + final int initialNumber; + final int maxNumber; + final int minNumber; + final StepperCallbackFuture counterCallback; + final Function increaseCallback; + final Function decreaseCallback; + + StepperView({this.initialNumber = 1, this.minNumber = 1, this.maxNumber, @required this.counterCallback, this.increaseCallback, this.decreaseCallback, this.height = 25, @required this.foregroundColor, @required this.backgroundColor, this.buttonPadding = 1}){ + assert((this.initialNumber >= this.minNumber && this.initialNumber <= this.maxNumber)); + } + @override + _StepperViewState createState() => _StepperViewState(); +} + +class _StepperViewState extends State { + int _currentCount; + StepperCallbackFuture _counterCallback; + Function _increaseCallback; + Function _decreaseCallback; + + @override + void initState() { + _currentCount = widget.initialNumber ?? 1; + _counterCallback = widget.counterCallback; + _increaseCallback = widget.increaseCallback ?? () {}; + _decreaseCallback = widget.decreaseCallback ?? () {}; + super.initState(); + } + + bool loadingInc = false; + bool loadingDec = false; + + @override + Widget build(BuildContext context) { + return Container( + padding: EdgeInsets.all(widget.buttonPadding), + decoration: BoxDecoration( + borderRadius: BorderRadius.circular((widget.height/2) + (widget.buttonPadding*2)), + color: widget.backgroundColor, + ), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + _createDecrementButton( + (_currentCount > widget.minNumber) ? () => _decrement() : null, + ), + Container( + width: 25, + child: Center( + child: Text( + _currentCount.toString(), + style: TextStyle( + fontSize: 12, + fontWeight: FontWeight.normal, + height: 1.5, + color: Colors.black, + ) + ), + ) + ), + _createIncrementButton( + (_currentCount < widget.maxNumber) ? () => _increment() : null + ), + ], + ), + ); + } + + void _increment() async{ + doInc({@required bool can}){ + if(can) + setState(() { + _currentCount++; + _increaseCallback(); + }); + } + + if (_currentCount < widget.maxNumber){ + if(_counterCallback == null) + doInc(can: true); + else { + setState(() => loadingInc = true); + var result = (await _counterCallback(1,_currentCount)); + doInc(can: result); + setState(() => loadingInc = false); + } + } + } + + void _decrement() async{ + doDec({@required bool can}){ + if(can) + setState(() { + _currentCount--; + _decreaseCallback(); + }); + } + if (_currentCount > widget.minNumber) { + if(_counterCallback == null) + doDec(can: true); + else { + setState(() => loadingDec = true); + var result = (await _counterCallback(-1,_currentCount)); + doDec(can: result); + setState(() => loadingDec = false); + } + } + } + + Widget _createIncrementButton(Function onPressed,) { + return Stack( + children: [ + RawMaterialButton( + materialTapTargetSize: MaterialTapTargetSize.shrinkWrap, + constraints: BoxConstraints(minWidth: widget.height, minHeight: widget.height), + onPressed: onPressed, + elevation: 2.0, + fillColor: widget.foregroundColor, + child: + Icon( + Icons.add, + color: (_currentCount < widget.maxNumber) ? Colors.grey[700] : Colors.grey[400], + size: 12.0, + ), + shape: CircleBorder(), + ), + + if(loadingInc) + Container( + decoration: BoxDecoration( + color: Colors.white.withOpacity(0.8), + borderRadius: BorderRadius.circular(widget.height/2), + ), + height: widget.height, + width: widget.height, + child: CircularProgressIndicator( + strokeWidth: 3, + valueColor: AlwaysStoppedAnimation(Colors.green) + ) + ) + ], + ); + } + + Widget _createDecrementButton(Function onPressed) { + return Stack( + children: [ + RawMaterialButton( + materialTapTargetSize: MaterialTapTargetSize.shrinkWrap, + constraints: BoxConstraints(minWidth: widget.height, minHeight: widget.height), + onPressed: onPressed, + elevation: 2.0, + fillColor: widget.foregroundColor, + child: Icon( + Icons.remove, + color: (_currentCount > widget.minNumber) ? Colors.grey[700] : Colors.grey[400], + size: 12.0, + ), + shape: CircleBorder(), + ), + + if(loadingDec) + Container( + decoration: BoxDecoration( + color: Colors.white.withOpacity(0.8), + borderRadius: BorderRadius.circular(widget.height/2), + ), + height: widget.height, + width: widget.height, + child: CircularProgressIndicator( + strokeWidth: 3, + valueColor: AlwaysStoppedAnimation(Colors.red) + ) + ) + ], + ); + } +} diff --git a/lib/widgets/LoadingButton.dart b/lib/widgets/LoadingButton.dart new file mode 100644 index 00000000..46983903 --- /dev/null +++ b/lib/widgets/LoadingButton.dart @@ -0,0 +1,463 @@ +import 'package:flutter/foundation.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter/rendering.dart'; +import 'dart:math'; + +import 'data_display/text.dart'; + +class AnimatedButton extends StatefulWidget { + AnimatedButton({ + Key key, + @required this.text, + @required this.onPressed, + @required this.controller, + this.textColor, + this.loadingColor, + this.color, + }) : super(key: key); + + final String text; + final Color color; + final Color textColor; + final Color loadingColor; + final Function onPressed; + final AnimationController controller; + + @override + _AnimatedButtonState createState() => _AnimatedButtonState(); +} + +class _AnimatedButtonState extends State + with SingleTickerProviderStateMixin { + Animation _sizeAnimation; + Animation _textOpacityAnimation; + Animation _buttonOpacityAnimation; + Animation _ringThicknessAnimation; + Animation _ringOpacityAnimation; + Animation _colorAnimation; + var _isLoading = false; + var _hover = false; + var _width = 120.0; + + Color _color; + Color _loadingColor; + + static const _height = 40.0; + static const _loadingCircleRadius = _height / 2; + static const _loadingCircleThickness = 4.0; + + @override + void initState() { + super.initState(); + + _textOpacityAnimation = Tween(begin: 1.0, end: 0.0).animate( + CurvedAnimation( + parent: widget.controller, + curve: Interval(0.0, .25), + ), + ); + + // _colorAnimation + // _width, _sizeAnimation + + _buttonOpacityAnimation = + Tween(begin: 1.0, end: 0.0).animate(CurvedAnimation( + parent: widget.controller, + curve: Threshold(.65), + )); + + _ringThicknessAnimation = + Tween(begin: _loadingCircleRadius, end: _loadingCircleThickness) + .animate(CurvedAnimation( + parent: widget.controller, + curve: Interval(.65, .85), + )); + _ringOpacityAnimation = + Tween(begin: 1.0, end: 0.0).animate(CurvedAnimation( + parent: widget.controller, + curve: Interval(.85, 1.0), + )); + + widget.controller.addStatusListener(handleStatusChanged); + } + + @override + void didChangeDependencies() { + _updateColorAnimation(); + _updateWidth(); + super.didChangeDependencies(); + } + + void _updateColorAnimation() { + final theme = Theme.of(context); + final buttonTheme = theme.floatingActionButtonTheme; + + _color = widget.color ?? buttonTheme.backgroundColor; + _loadingColor = widget.loadingColor ?? theme.accentColor; + + _colorAnimation = ColorTween( + begin: _color, + end: _loadingColor, + ).animate( + CurvedAnimation( + parent: widget.controller, + curve: const Interval(0.0, .65, curve: Curves.fastOutSlowIn), + ), + ); + } + + @override + void didUpdateWidget(AnimatedButton oldWidget) { + super.didUpdateWidget(oldWidget); + + if (oldWidget.color != widget.color || + oldWidget.loadingColor != widget.loadingColor) { + _updateColorAnimation(); + } + + if (oldWidget.text != widget.text) { + _updateWidth(); + } + } + + @override + void dispose() { + super.dispose(); + widget.controller.removeStatusListener(handleStatusChanged); + } + + void handleStatusChanged(status) { + if (status == AnimationStatus.forward) { + setState(() => _isLoading = true); + } + if (status == AnimationStatus.dismissed) { + setState(() => _isLoading = false); + } + } + + /// sets width and size animation + void _updateWidth() { + final theme = Theme.of(context); + final fontSize = theme.textTheme.button.fontSize; + final renderParagraph = RenderParagraph( + TextSpan( + text: widget.text, + style: TextStyle( + fontSize: fontSize, + fontWeight: theme.textTheme.button.fontWeight, + letterSpacing: theme.textTheme.button.letterSpacing, + ), + ), + textDirection: TextDirection.ltr, + maxLines: 1, + ); + + renderParagraph.layout(BoxConstraints(minWidth: 120.0)); + + // text width based on fontSize, plus 45.0 for padding + var textWidth = + renderParagraph.getMinIntrinsicWidth(fontSize).ceilToDouble() + 45.0; + + // button width is min 120.0 and max 240.0 + _width = textWidth > 120.0 && textWidth < 240.0 + ? textWidth + : textWidth >= 240.0 ? 240.0 : 120.0; + + _sizeAnimation = Tween(begin: 1.0, end: _height / _width) + .animate(CurvedAnimation( + parent: widget.controller, + curve: Interval(0.0, .65, curve: Curves.fastOutSlowIn), + )); + } + + Widget _buildButtonText(ThemeData theme) { + return FadeTransition( + opacity: _textOpacityAnimation, + child: AnimatedText( + text: widget.text, + style: TextStyle(color: widget.textColor ?? Colors.white), + ), + ); + } + + Widget _buildButton(ThemeData theme) { + final buttonTheme = theme.floatingActionButtonTheme; + + return FadeTransition( + opacity: _buttonOpacityAnimation, + child: AnimatedContainer( + duration: Duration(milliseconds: 300), + child: AnimatedBuilder( + animation: _colorAnimation, + builder: (context, child) => Material( + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(_height/2) + ), + color: _colorAnimation.value, + child: child, + shadowColor: _color, + elevation: !_isLoading + ? (_hover ? buttonTheme.highlightElevation : buttonTheme.elevation) + : 0, + ), + child: InkWell( + onTap: !_isLoading ? widget.onPressed : null, + splashColor: buttonTheme.splashColor, + customBorder: buttonTheme.shape, + onHighlightChanged: (value) => setState(() => _hover = value), + child: SizeTransition( + sizeFactor: _sizeAnimation, + axis: Axis.horizontal, + child: Container( + width: _width, + height: _height, + alignment: Alignment.center, + child: _buildButtonText(theme), + ), + ), + ), + ), + ), + ); + } + + @override + Widget build(BuildContext context) { + final theme = Theme.of(context); + + return Stack( + alignment: Alignment.center, + children: [ + FadeTransition( + opacity: _ringOpacityAnimation, + child: AnimatedBuilder( + animation: _ringThicknessAnimation, + builder: (context, child) => Ring( + color: widget.loadingColor, + size: _height, + thickness: _ringThicknessAnimation.value, + ), + ), + ), + if (_isLoading) + SizedBox( + width: _height - _loadingCircleThickness, + height: _height - _loadingCircleThickness, + child: CircularProgressIndicator( + valueColor: AlwaysStoppedAnimation(widget.loadingColor), + // backgroundColor: Colors.red, + strokeWidth: _loadingCircleThickness, + ), + ), + _buildButton(theme), + ], + ); + } +} + +class Ring extends StatelessWidget { + Ring({ + Key key, + this.color, + this.size = 40.0, + this.thickness = 2.0, + this.value = 1.0, + }) : assert(size - thickness > 0), + assert(thickness >= 0), + super(key: key); + + final Color color; + final double size; + final double thickness; + final double value; + + @override + Widget build(BuildContext context) { + return SizedBox( + width: size - thickness, + height: size - thickness, + child: thickness == 0 + ? null + : CircularProgressIndicator( + valueColor: AlwaysStoppedAnimation(color), + strokeWidth: thickness, + value: value, + ), + ); + } +} + + +enum AnimatedTextRotation { up, down } + +/// https://medium.com/flutter-community/flutter-challenge-3d-bottom-navigation-bar-48952a5fd996 +class AnimatedText extends StatefulWidget { + AnimatedText({ + Key key, + @required this.text, + this.style, + this.textRotation = AnimatedTextRotation.up, + }) : super(key: key); + + final String text; + final TextStyle style; + final AnimatedTextRotation textRotation; + + @override + _AnimatedTextState createState() => _AnimatedTextState(); +} + +class _AnimatedTextState extends State + with SingleTickerProviderStateMixin { + var _newText = ''; + var _oldText = ''; + var _layoutHeight = 0.0; + final _textKey = GlobalKey(); + + Animation _animation; + AnimationController _controller; + + double get radius => _layoutHeight / 2; + + + @override + void initState() { + super.initState(); + + _controller = AnimationController( + vsync: this, + duration: const Duration(milliseconds: 500), + ); + + _animation = Tween(begin: 0.0, end: pi / 2).animate(CurvedAnimation( + parent: _controller, + curve: Curves.easeOutBack, + )); + + _oldText = widget.text; + + WidgetsBinding.instance.addPostFrameCallback((_) { + setState(() => _layoutHeight = getWidgetSize(_textKey)?.height); + }); + } + + @override + void didUpdateWidget(AnimatedText oldWidget) { + super.didUpdateWidget(oldWidget); + + if (widget.text != oldWidget.text) { + _oldText = oldWidget.text; + _newText = widget.text; + _controller.forward().then((_) { + setState(() { + final t = _oldText; + _oldText = _newText; + _newText = t; + }); + _controller.reset(); + }); + } + } + + @override + void dispose() { + super.dispose(); + _controller.dispose(); + } + + Matrix4 get _matrix { + // Fix: The text is not centered after applying perspective effect in the web build. Idk why + if (kIsWeb) { + return Matrix4.identity(); + } + return Matrix4.identity()..setEntry(3, 2, .006); + } + + Matrix4 _getFrontSideUp(double value) { + return _matrix + ..translate( + 0.0, + -radius * sin(_animation.value), + -radius * cos(_animation.value), + ) + ..rotateX(-_animation.value); // 0 -> -pi/2 + } + + Matrix4 _getBackSideUp(double value) { + return _matrix + ..translate( + 0.0, + radius * cos(_animation.value), + -radius * sin(_animation.value), + ) + ..rotateX((pi / 2) - _animation.value); // pi/2 -> 0 + } + + Matrix4 _getFrontSideDown(double value) { + return _matrix + ..translate( + 0.0, + radius * sin(_animation.value), + -radius * cos(_animation.value), + ) + ..rotateX(_animation.value); // 0 -> pi/2 + } + + Matrix4 _getBackSideDown(double value) { + return _matrix + ..translate( + 0.0, + -radius * cos(_animation.value), + -radius * sin(_animation.value), + ) + ..rotateX(_animation.value - pi / 2); // -pi/2 -> 0 + } + + @override + Widget build(BuildContext context) { + final rollUp = widget.textRotation == AnimatedTextRotation.up; + final oldText = Text( + _oldText, + key: _textKey, + style: widget.style, + ); + final newText = Text( + _newText, + style: widget.style, + ); + + return AnimatedBuilder( + animation: _animation, + builder: (context, child) => Stack( + alignment: Alignment.center, + children: [ + if (_animation.value <= toRadian(85)) + Transform( + alignment: Alignment.center, + transform: rollUp + ? _getFrontSideUp(_animation.value) + : _getFrontSideDown(_animation.value), + child: oldText, + ), + if (_animation.value >= toRadian(5)) + Transform( + alignment: Alignment.center, + transform: rollUp + ? _getBackSideUp(_animation.value) + : _getBackSideDown(_animation.value), + child: newText, + ), + ], + ), + ); + } + + +// Helpers + double toRadian(double degree) => degree * pi / 180; + double lerp(double start, double end, double percent) => (start + percent * (end - start)); + Size getWidgetSize(GlobalKey key) { + final RenderBox renderBox = key.currentContext?.findRenderObject(); + return renderBox?.size; + } +} \ No newline at end of file diff --git a/lib/widgets/TextFieldInertiaDirection.java b/lib/widgets/TextFieldInertiaDirection.java new file mode 100644 index 00000000..627bf406 --- /dev/null +++ b/lib/widgets/TextFieldInertiaDirection.java @@ -0,0 +1,343 @@ +import 'dart:math'; + +import 'package:flutter/gestures.dart'; +import 'package:flutter/material.dart'; +import 'package:font_awesome_flutter/font_awesome_flutter.dart'; + +enum TextFieldInertiaDirection { + left, + right, +} + +Interval _getInternalInterval( + double start, + double end, + double externalStart, + double externalEnd, [ + Curve curve = Curves.linear, +]) { + return Interval( + start + (end - start) * externalStart, + start + (end - start) * externalEnd, + curve: curve, + ); +} + +class AnimatedTextFormField extends StatefulWidget { + AnimatedTextFormField({ + Key key, + this.interval = const Interval(0.0, 1.0), + @required this.width, + this.loadingController, + this.inertiaController, + this.inertiaDirection, + this.enabled = true, + this.labelText, + this.prefixIcon, + this.suffixIcon, + this.keyboardType, + this.textInputAction, + this.obscureText = false, + this.controller, + this.focusNode, + this.validator, + this.onFieldSubmitted, + this.onSaved, + }) : assert((inertiaController == null && inertiaDirection == null) || + (inertiaController != null && inertiaDirection != null)), + super(key: key); + + final Interval interval; + final AnimationController loadingController; + final AnimationController inertiaController; + final double width; + final bool enabled; + final String labelText; + final Widget prefixIcon; + final Widget suffixIcon; + final TextInputType keyboardType; + final TextInputAction textInputAction; + final bool obscureText; + final TextEditingController controller; + final FocusNode focusNode; + final FormFieldValidator validator; + final ValueChanged onFieldSubmitted; + final FormFieldSetter onSaved; + final TextFieldInertiaDirection inertiaDirection; + + @override + _AnimatedTextFormFieldState createState() => _AnimatedTextFormFieldState(); +} + +class _AnimatedTextFormFieldState extends State { + Animation scaleAnimation; + Animation sizeAnimation; + Animation suffixIconOpacityAnimation; + + Animation fieldTranslateAnimation; + Animation iconRotationAnimation; + Animation iconTranslateAnimation; + + @override + void initState() { + super.initState(); + + widget.inertiaController?.addStatusListener(handleAnimationStatus); + + final interval = widget.interval; + final loadingController = widget.loadingController; + + if (loadingController != null) { + scaleAnimation = Tween( + begin: 0.0, + end: 1.0, + ).animate(CurvedAnimation( + parent: loadingController, + curve: _getInternalInterval( + 0, .2, interval.begin, interval.end, Curves.easeOutBack), + )); + suffixIconOpacityAnimation = + Tween(begin: 0.0, end: 1.0).animate(CurvedAnimation( + parent: loadingController, + curve: _getInternalInterval(.65, 1.0, interval.begin, interval.end), + )); + _updateSizeAnimation(); + } + + final inertiaController = widget.inertiaController; + final inertiaDirection = widget.inertiaDirection; + final sign = inertiaDirection == TextFieldInertiaDirection.right ? 1 : -1; + + if (inertiaController != null) { + fieldTranslateAnimation = Tween( + begin: 0.0, + end: sign * 15.0, + ).animate(CurvedAnimation( + parent: inertiaController, + curve: Interval(0, .5, curve: Curves.easeOut), + reverseCurve: Curves.easeIn, + )); + iconRotationAnimation = + Tween(begin: 0.0, end: sign * pi / 12 /* ~15deg */) + .animate(CurvedAnimation( + parent: inertiaController, + curve: Interval(.5, 1.0, curve: Curves.easeOut), + reverseCurve: Curves.easeIn, + )); + iconTranslateAnimation = + Tween(begin: 0.0, end: 8.0).animate(CurvedAnimation( + parent: inertiaController, + curve: Interval(.5, 1.0, curve: Curves.easeOut), + reverseCurve: Curves.easeIn, + )); + } + } + + void _updateSizeAnimation() { + final interval = widget.interval; + final loadingController = widget.loadingController; + + sizeAnimation = Tween( + begin: 48.0, + end: widget.width, + ).animate(CurvedAnimation( + parent: loadingController, + curve: _getInternalInterval( + .2, 1.0, interval.begin, interval.end, Curves.linearToEaseOut), + reverseCurve: Curves.easeInExpo, + )); + } + + @override + void didUpdateWidget(AnimatedTextFormField oldWidget) { + super.didUpdateWidget(oldWidget); + + if (oldWidget.width != widget.width) { + _updateSizeAnimation(); + } + } + + @override + dispose() { + widget.inertiaController?.removeStatusListener(handleAnimationStatus); + super.dispose(); + } + + void handleAnimationStatus(status) { + if (status == AnimationStatus.completed) { + widget.inertiaController?.reverse(); + } + } + + Widget _buildInertiaAnimation(Widget child) { + if (widget.inertiaController == null) { + return child; + } + + return AnimatedBuilder( + animation: iconTranslateAnimation, + builder: (context, child) => Transform( + alignment: Alignment.center, + transform: Matrix4.identity() + ..translate(iconTranslateAnimation.value) + ..rotateZ(iconRotationAnimation.value), + child: child, + ), + child: child, + ); + } + + InputDecoration _getInputDecoration(ThemeData theme) { + return InputDecoration( + labelText: widget.labelText, + prefixIcon: _buildInertiaAnimation(widget.prefixIcon), + suffixIcon: _buildInertiaAnimation(widget.loadingController != null + ? FadeTransition( + opacity: suffixIconOpacityAnimation, + child: widget.suffixIcon, + ) + : widget.suffixIcon), + ); + } + + @override + Widget build(BuildContext context) { + final theme = Theme.of(context); + Widget textField = TextFormField( + controller: widget.controller, + focusNode: widget.focusNode, + decoration: _getInputDecoration(theme), + keyboardType: widget.keyboardType, + textInputAction: widget.textInputAction, + obscureText: widget.obscureText, + onFieldSubmitted: widget.onFieldSubmitted, + onSaved: widget.onSaved, + validator: widget.validator, + enabled: widget.enabled, + ); + + if (widget.loadingController != null) { + textField = ScaleTransition( + scale: scaleAnimation, + child: AnimatedBuilder( + animation: sizeAnimation, + builder: (context, child) => ConstrainedBox( + constraints: BoxConstraints.tightFor(width: sizeAnimation.value), + child: child, + ), + child: textField, + ), + ); + } + + if (widget.inertiaController != null) { + textField = AnimatedBuilder( + animation: fieldTranslateAnimation, + builder: (context, child) => Transform.translate( + offset: Offset(fieldTranslateAnimation.value, 0), + child: child, + ), + child: textField, + ); + } + + return textField; + } +} + +class AnimatedPasswordTextFormField extends StatefulWidget { + AnimatedPasswordTextFormField({ + Key key, + this.interval = const Interval(0.0, 1.0), + @required this.animatedWidth, + this.loadingController, + this.inertiaController, + this.inertiaDirection, + this.enabled = true, + this.labelText, + this.keyboardType, + this.textInputAction, + this.controller, + this.focusNode, + this.validator, + this.onFieldSubmitted, + this.onSaved, + }) : assert((inertiaController == null && inertiaDirection == null) || + (inertiaController != null && inertiaDirection != null)), + super(key: key); + + final Interval interval; + final AnimationController loadingController; + final AnimationController inertiaController; + final double animatedWidth; + final bool enabled; + final String labelText; + final TextInputType keyboardType; + final TextInputAction textInputAction; + final TextEditingController controller; + final FocusNode focusNode; + final FormFieldValidator validator; + final ValueChanged onFieldSubmitted; + final FormFieldSetter onSaved; + final TextFieldInertiaDirection inertiaDirection; + + @override + _AnimatedPasswordTextFormFieldState createState() => + _AnimatedPasswordTextFormFieldState(); +} + +class _AnimatedPasswordTextFormFieldState + extends State { + var _obscureText = true; + + @override + Widget build(BuildContext context) { + return AnimatedTextFormField( + interval: widget.interval, + loadingController: widget.loadingController, + inertiaController: widget.inertiaController, + width: widget.animatedWidth, + enabled: widget.enabled, + labelText: widget.labelText, + prefixIcon: Icon(FontAwesomeIcons.lock, size: 20), + suffixIcon: GestureDetector( + onTap: () => setState(() => _obscureText = !_obscureText), + dragStartBehavior: DragStartBehavior.down, + child: AnimatedCrossFade( + duration: const Duration(milliseconds: 250), + firstCurve: Curves.easeInOutSine, + secondCurve: Curves.easeInOutSine, + alignment: Alignment.center, + layoutBuilder: (Widget topChild, _, Widget bottomChild, __) { + return Stack( + alignment: Alignment.center, + children: [bottomChild, topChild], + ); + }, + firstChild: Icon( + Icons.visibility, + size: 25.0, + semanticLabel: 'show password', + ), + secondChild: Icon( + Icons.visibility_off, + size: 25.0, + semanticLabel: 'hide password', + ), + crossFadeState: _obscureText + ? CrossFadeState.showFirst + : CrossFadeState.showSecond, + ), + ), + obscureText: _obscureText, + keyboardType: widget.keyboardType, + textInputAction: widget.textInputAction, + controller: widget.controller, + focusNode: widget.focusNode, + validator: widget.validator, + onFieldSubmitted: widget.onFieldSubmitted, + onSaved: widget.onSaved, + inertiaDirection: widget.inertiaDirection, + ); + } +} \ No newline at end of file diff --git a/lib/widgets/carousel_indicator/carousel_indicator.dart b/lib/widgets/carousel_indicator/carousel_indicator.dart new file mode 100644 index 00000000..020c44d8 --- /dev/null +++ b/lib/widgets/carousel_indicator/carousel_indicator.dart @@ -0,0 +1,197 @@ +import 'package:flutter/material.dart'; +import 'package:flutter/widgets.dart'; + + +class CarouselIndicator extends StatefulWidget { + /// width of the indicator + final double width; + + /// height of the indicator + final double height; + + /// space between indicators. + final double space; + + /// count of indicator + final int count; + + /// active color + final Color activeColor; + + /// normal color + final Color color; + + /// use this to give some radius to the corner indicator + final double cornerRadius; + + /// duration for slide animation + final int animationDuration; + + final int index; + + final Function(int index) onClick; + + CarouselIndicator({ + Key key, + this.width: 20.0, + this.height: 6, + this.space: 5.0, + this.count, + this.cornerRadius: 6, + this.animationDuration: 300, + this.color: Colors.white30, + this.index, + this.activeColor: Colors.white, + this.onClick + }) : assert(count != null && count != 0), + assert(index != null && index >= 0), + super(key: key); + + @override + State createState() { + return new _CarouselIndicatorState(); + } +} + +class _CarouselIndicatorState extends State + with TickerProviderStateMixin { + /// [Tween] object of type double + Tween _tween; + + /// [AnimationController] object + AnimationController _animationController; + + /// [Aniamtion] object + Animation _animation; + + /// [Paint] object to paint our indicator + Paint _paint = new Paint(); + + /// Method to initilize [BasePainter] to paint indicators. + BasePainter _createPainer() { + return SlidePainter(widget, _animation.value, _paint); + } + + @override + Widget build(BuildContext context) { + Widget child = new SizedBox( + width: widget.count * widget.width + (widget.count - 1) * widget.space, + height: widget.height, + child: CustomPaint( + painter: _createPainer(), + ), + ); + + return InkWell( + child: child, + onTap: (){ + if(widget.onClick != null) + widget.onClick(0); + }, + ); + } + + @override + void initState() { + /// for initial index=0 we do not want to change any value so setting [_tween] to (0.0,0.0), + createAnimation(0.0, 0.0); + super.initState(); + } + + @override + void didUpdateWidget(CarouselIndicator oldWidget) { + if (widget.index != oldWidget.index) { + if (widget.index != 0) { + _animationController.reset(); + + /// for each new index we want to change value so setting [_tween] to (oldWidget.index,widget.index) so animation tween from old position to new position rather not start from 0.0 again and again. + createAnimation(oldWidget.index.toDouble(), widget.index.toDouble()); + _animationController.forward(); + } else { + _animationController.reset(); + createAnimation(oldWidget.index.toDouble(), 0.0); + _animationController.forward(); + } + } + super.didUpdateWidget(oldWidget); + } + + @override + void dispose() { + _animationController.dispose(); + super.dispose(); + } + + void createAnimation(double begin, double end) { + _tween = Tween(begin: begin, end: end); + _animationController = AnimationController( + vsync: this, + duration: Duration(milliseconds: widget.animationDuration)); + _animation = _tween.animate(_animationController) + ..addListener(() { + setState(() {}); + }); + } +} + + +/// Base Painter class to draw indicator +abstract class BasePainter extends CustomPainter { + final CarouselIndicator widget; + final double page; + final Paint _paint; + + BasePainter(this.widget, this.page, this._paint); + + /// This method will get body to class extending [BasePainter] and this method will draw the sliding indicator which slide over changing index. + void draw(Canvas canvas, double space, double width, double height, + double radius, double cornerRadius); + + @override + void paint(Canvas canvas, Size size) { + _paint.color = widget.color; + double space = widget.space; + double width = widget.width; + double height = widget.height; + double distance = width + space; + double radius = width / 2; + for (int i = 0, c = widget.count; i < c; ++i) { + canvas.drawRRect( + RRect.fromRectAndRadius( + Rect.fromCenter( + center: Offset((i * distance) + radius, radius), + width: width, + height: height), + Radius.circular(widget.cornerRadius)), + _paint); + } + + _paint.color = widget.activeColor; + draw(canvas, space, width, height, radius, widget.cornerRadius); + } + + @override + bool shouldRepaint(BasePainter oldDelegate) { + return oldDelegate.page != page; + } +} + +/// This class we draw the indicator which slides. +class SlidePainter extends BasePainter { + SlidePainter(CarouselIndicator widget, double page, Paint paint) + : super(widget, page, paint); + + @override + void draw(Canvas canvas, double space, double width, double height, + double radius, double cornerRadius) { + canvas.drawRRect( + RRect.fromRectAndRadius( + Rect.fromCenter( + center: Offset(radius + (page * (width + space)), radius), + width: width, + height: height), + Radius.circular(cornerRadius)), + _paint); + } +} + diff --git a/lib/widgets/data_display/medical/LabResult/FlowChartPage.dart b/lib/widgets/data_display/medical/LabResult/FlowChartPage.dart index fde78169..2cc9acd6 100644 --- a/lib/widgets/data_display/medical/LabResult/FlowChartPage.dart +++ b/lib/widgets/data_display/medical/LabResult/FlowChartPage.dart @@ -23,18 +23,21 @@ class FlowChartPage extends StatelessWidget { appBarTitle: filterName, baseViewModel: model, body: SingleChildScrollView( - child: model.labOrdersResultsList.isNotEmpty + child: model. labOrdersResultsList.isNotEmpty ? Container( child: LabResultChartAndDetails( name: filterName, labResult: model.labOrdersResultsList, ), ) - : Container( - child: Center( - child: Texts('no Data'), + : Center( + child: Container( + padding: EdgeInsets.only(top: MediaQuery.of(context).size.height *0.42), + child: Center( + child: Texts('No Data'), + ), ), - ), + ), ), ), ); diff --git a/lib/widgets/data_display/services)contaniner.dart b/lib/widgets/data_display/services)contaniner.dart index cb0b3774..e435539f 100644 --- a/lib/widgets/data_display/services)contaniner.dart +++ b/lib/widgets/data_display/services)contaniner.dart @@ -15,7 +15,7 @@ class ServicesContainer extends StatelessWidget { height: 60, margin: EdgeInsets.all(8), decoration: BoxDecoration( - color: Theme.of(context).primaryColor, + color: Theme.of(context).textTheme.headline2.color, shape: BoxShape.rectangle, borderRadius: BorderRadius.circular(7), ), @@ -38,6 +38,7 @@ class ServicesContainer extends StatelessWidget { Texts( title, fontSize: 16, + color: Colors.black, ), ], ), diff --git a/lib/widgets/data_display/text.dart b/lib/widgets/data_display/text.dart index 40aabfe3..d759190e 100644 --- a/lib/widgets/data_display/text.dart +++ b/lib/widgets/data_display/text.dart @@ -24,6 +24,7 @@ class Texts extends StatefulWidget { final double marginBottom; final double marginLeft; final TextDecoration decoration; + final double heightFactor; Texts(this.text, {Key key, @@ -46,7 +47,8 @@ class Texts extends StatefulWidget { this.marginLeft, this.marginRight, this.marginTop, - this.decoration}) + this.decoration, + this.heightFactor,}) : super(key: key); @override @@ -226,6 +228,7 @@ class _TextsState extends State { fontWeight: widget.fontWeight ?? _getFontWeight(), ) : TextStyle( + height: widget.heightFactor, decoration: widget.decoration, fontStyle: widget.italic ? FontStyle.italic : null, color: widget.color ?? diff --git a/lib/widgets/drawer/app_drawer_widget.dart b/lib/widgets/drawer/app_drawer_widget.dart index 83b0df5f..c4a7d8d0 100644 --- a/lib/widgets/drawer/app_drawer_widget.dart +++ b/lib/widgets/drawer/app_drawer_widget.dart @@ -61,394 +61,417 @@ class _AppDrawerState extends State { @override Widget build(BuildContext context) { projectProvider = Provider.of(context); - return SizedBox( - width: MediaQuery.of(context).size.width * 0.75, - child: Container( - color: Colors.white, - child: Drawer( - child: Column( - children: [ - Expanded( - flex: 4, - child: ListView( - padding: EdgeInsets.zero, - children: [ - Container( - height: SizeConfig.screenHeight * .30, - child: InkWell( - child: DrawerHeader( - child: Column( - children: [ - Container( - child: - Image.asset('assets/images/DQ/DQ_logo.png'), - margin: EdgeInsets.all( - SizeConfig.imageSizeMultiplier * 4), - ), - (user != null && projectProvider.isLogin) - ? Padding( - padding: EdgeInsets.all(15), - child: Column( - mainAxisAlignment: - MainAxisAlignment.start, - children: [ - Row( + return Container( + width: MediaQuery.of(context).size.width * 0.75, + color: Theme.of(context).scaffoldBackgroundColor, + child: Container( + // color: Colors.white, + child: Theme( + data: Theme.of(context).copyWith( + canvasColor: Theme.of(context).scaffoldBackgroundColor), + child: Drawer( + child: Column( + children: [ + Expanded( + flex: 4, + child: ListView( + padding: EdgeInsets.zero, + children: [ + Container( + height: SizeConfig.screenHeight * .30, + child: InkWell( + child: DrawerHeader( + child: Column( + children: [ + Container( + child: Image.asset( + 'assets/images/logo_HMG.png'), + margin: EdgeInsets.all( + SizeConfig.imageSizeMultiplier * 4), + ), + (user != null && projectProvider.isLogin) + ? Padding( + padding: EdgeInsets.all(15), + child: Column( + mainAxisAlignment: + MainAxisAlignment.start, children: [ - Padding( - padding: EdgeInsets.only( - right: 5), - child: Icon( - Icons.account_circle, + Row( + children: [ + Padding( + padding: + EdgeInsets.only( + right: 5), + child: Icon( + Icons.account_circle, + color: + Color(0xFF40ACC9), + )), + AppText( + user.firstName + + ' ' + + user.lastName, color: Color(0xFF40ACC9), + ) + ], + ), + Row(children: [ + Padding( + padding: EdgeInsets.only( + left: 30, top: 5), + child: Column( + children: [ + AppText( + TranslationBase.of( + context) + .fileno + + ": " + + user.patientID + .toString(), + color: Color( + 0xFF40ACC9), + fontSize: SizeConfig + .textMultiplier * + 1.5, + ), + AppText( + user.bloodGroup != + null + ? 'Blood Group: ' + + user.bloodGroup + : '', + fontSize: SizeConfig + .textMultiplier * + 1.5, + ), + ], + )) + ]) + ])) + : SizedBox(), + ], + ), + ), + ), + ), + Container( + child: Column( + mainAxisAlignment: MainAxisAlignment.start, + children: [ + InkWell( + child: DrawerItem( + TranslationBase.of(context).arabicChange, + Icons.translate), + onTap: () { + sharedPref.setBool(IS_ROBOT_INIT, null); + if (projectProvider.isArabic) { + projectProvider.changeLanguage('en'); + } else { + projectProvider.changeLanguage('ar'); + } + }, + ), + (user != null && projectProvider.isLogin) + ? Column( + mainAxisAlignment: MainAxisAlignment.start, + children: [ + (user.isFamily == null || + user.isFamily == false) && + projectProvider.havePrivilege(2) + ? InkWell( + child: DrawerItem( + TranslationBase.of(context) + .family, + Icons.group, + textColor: Theme.of(context) + .textTheme + .bodyText1 + .color, + iconColor: Theme.of(context) + .textTheme + .bodyText1 + .color, + bottomLine: false, + sideArrow: true, + ), + onTap: () { + Navigator.of(context).pop(); + Navigator.of(context).pushNamed( + MY_FAMILIY, + ); + }, + ) + : SizedBox(), + FutureBuilder( + future: getFamilyFiles(), // async work + builder: (BuildContext context, + AsyncSnapshot< + GetAllSharedRecordsByStatusResponse> + snapshot) { + switch (snapshot.connectionState) { + case ConnectionState.waiting: + return Padding( + padding: EdgeInsets.all(10), + child: Text('')); + default: + if (snapshot.hasError) + return Padding( + padding: EdgeInsets.all(10), + child: + Text(snapshot.error)); + else + return Container( + decoration: BoxDecoration( + border: Border( + bottom: BorderSide( + // <--- left side + color: Colors.grey[200], + width: 1.0, + ), )), - AppText( - user.firstName + - ' ' + - user.lastName, - color: Color(0xFF40ACC9), - ) - ], - ), - Row(children: [ - Padding( - padding: EdgeInsets.only( - left: 30, top: 5), - child: Column( - children: [ - AppText( - TranslationBase.of( - context) - .fileno + - ": " + - user.patientID - .toString(), - color: - Color(0xFF40ACC9), - fontSize: SizeConfig - .textMultiplier * - 1.5, + child: Column( + children: [ + user.isFamily == true + ? Container( + padding: EdgeInsets + .only( + bottom: + 5), + child: InkWell( + onTap: () { + switchUser( + mainUser, + context); + }, + child: Row( + crossAxisAlignment: + CrossAxisAlignment + .start, + children: < + Widget>[ + Expanded( + child: + Icon(Icons.person), + ), + Expanded( + flex: + 7, + child: + Column(crossAxisAlignment: CrossAxisAlignment.start, children: [ + AppText(mainUser.firstName + ' ' + mainUser.lastName, color: Theme.of(context).textTheme.bodyText1.color), + AppText( + TranslationBase.of(context).fileno + ": " + mainUser.patientID.toString(), + color: Theme.of(context).textTheme.bodyText1.color, + ), + ])), + ], + ))) + : SizedBox(), + Column( + mainAxisAlignment: + MainAxisAlignment + .start, + mainAxisSize: + MainAxisSize + .min, + children: snapshot + .data + .getAllSharedRecordsByStatusList + .map( + (result) { + return result + .status == + 3 + ? Container( + padding: EdgeInsets.only( + bottom: + 5), + child: InkWell( + onTap: () { + switchUser(result, + context); + }, + child: Row( + crossAxisAlignment: + CrossAxisAlignment.start, + children: [ + Expanded( + child: Icon(Icons.person, color: result.responseID == user.patientID ? Color(0xFF40ACC9) : Colors.black), + ), + Expanded( + flex: 7, + child: Padding( + padding: EdgeInsets.only(left: 5, right: 5), + child: Column(crossAxisAlignment: CrossAxisAlignment.start, children: [ + AppText(result.patientName, color: result.responseID == user.patientID ? Color(0xFF40ACC9) : Colors.black), + AppText(TranslationBase.of(context).fileno + ": " + result.iD.toString(), color: result.responseID == user.patientID ? Color(0xFF40ACC9) : Colors.black), + ]))), + ], + ))) + : SizedBox(); + }).toList()) + ], + )); + } + }, + ), + InkWell( + child: Stack( + children: [ + DrawerItem( + TranslationBase.of(context) + .notification, + Icons.notifications, + count: notificationCount != null + ? new Container( + padding: + EdgeInsets.all(4), + margin: EdgeInsets.all(2), + decoration: + new BoxDecoration( + color: Colors.red, + borderRadius: + BorderRadius + .circular(20), ), - AppText( - user.bloodGroup != null - ? 'Blood Group: ' + - user.bloodGroup - : '', - fontSize: SizeConfig - .textMultiplier * - 1.5, + constraints: + BoxConstraints( + minWidth: 20, + minHeight: 20, ), - ], - )) - ]) - ])) - : SizedBox(), - ], - ), - ), - ), - ), - Column( - mainAxisAlignment: MainAxisAlignment.start, - children: [ - InkWell( - child: DrawerItem( - TranslationBase.of(context).arabicChange, - Icons.translate), - onTap: () { - sharedPref.setBool(IS_ROBOT_INIT, null); - if (projectProvider.isArabic) { - projectProvider.changeLanguage('en'); - } else { - projectProvider.changeLanguage('ar'); - } - }, - ), - (user != null && projectProvider.isLogin) - ? Column( - mainAxisAlignment: MainAxisAlignment.start, - children: [ - (user.isFamily == null || - user.isFamily == false) && - projectProvider.havePrivilege(2) - ? InkWell( + child: new Text( + notificationCount, + style: new TextStyle( + color: Colors.white, + fontSize: + projectProvider + .isArabic + ? 8 + : 9, + ), + textAlign: + TextAlign.center, + ), + // ), + ) + : SizedBox(), + ), + ], + ), + onTap: () { + //NotificationsPage + Navigator.of(context).pop(); + Navigator.push( + context, + FadePage( + page: NotificationsPage())); + }, + ), + if (projectProvider.havePrivilege(3)) + InkWell( child: DrawerItem( - TranslationBase.of(context).family, - Icons.group, - textColor: Theme.of(context) - .textTheme - .bodyText1 - .color, - iconColor: Theme.of(context) - .textTheme - .bodyText1 - .color, - bottomLine: false, - sideArrow: true, - ), + TranslationBase.of(context) + .appsetting, + Icons.settings_input_composite), onTap: () { Navigator.of(context).pushNamed( - MY_FAMILIY, + SETTINGS, ); }, - ) - : SizedBox(), - FutureBuilder( - future: getFamilyFiles(), // async work - builder: (BuildContext context, - AsyncSnapshot< - GetAllSharedRecordsByStatusResponse> - snapshot) { - switch (snapshot.connectionState) { - case ConnectionState.waiting: - return Padding( - padding: EdgeInsets.all(10), - child: Text('')); - default: - if (snapshot.hasError) - return Padding( - padding: EdgeInsets.all(10), - child: Text(snapshot.error)); - else - return Container( - decoration: BoxDecoration( - border: Border( - bottom: BorderSide( - // <--- left side - color: Colors.grey[200], - width: 1.0, - ), - )), - child: Column( - children: [ - user.isFamily == true - ? Container( - padding: - EdgeInsets.only( - bottom: 5), - child: InkWell( - onTap: () { - switchUser( - mainUser, - context); - }, - child: Row( - crossAxisAlignment: - CrossAxisAlignment - .start, - children: < - Widget>[ - Expanded( - child: Icon( - Icons - .person), - ), - Expanded( - flex: 7, - child: Column( - crossAxisAlignment: - CrossAxisAlignment.start, - children: [ - AppText(mainUser.firstName + ' ' + mainUser.lastName), - AppText(TranslationBase.of(context).fileno + ": " + mainUser.patientID.toString()), - ])), - ], - ))) - : SizedBox(), - Column( - mainAxisAlignment: - MainAxisAlignment - .start, - mainAxisSize: - MainAxisSize.min, - children: snapshot.data - .getAllSharedRecordsByStatusList - .map( - (result) { - return result - .status == - 3 - ? Container( - padding: EdgeInsets - .only( - bottom: - 5), - child: InkWell( - onTap: () { - switchUser( - result, - context); - }, - child: Row( - crossAxisAlignment: - CrossAxisAlignment.start, - children: < - Widget>[ - Expanded( - child: - Icon(Icons.person, color: result.responseID == user.patientID ? Color(0xFF40ACC9) : Colors.black), - ), - Expanded( - flex: 7, - child: Padding( - padding: EdgeInsets.only(left: 5, right: 5), - child: Column(crossAxisAlignment: CrossAxisAlignment.start, children: [ - AppText(result.patientName, color: result.responseID == user.patientID ? Color(0xFF40ACC9) : Colors.black), - AppText(TranslationBase.of(context).fileno + ": " + result.iD.toString(), color: result.responseID == user.patientID ? Color(0xFF40ACC9) : Colors.black), - ]))), - ], - ))) - : SizedBox(); - }).toList()) - ], - )); - } - }, - ), - InkWell( - child: Stack( - children: [ - DrawerItem( - TranslationBase.of(context) - .notification, - Icons.notifications, - count: notificationCount != null - ? new Container( - padding: EdgeInsets.all(4), - margin: EdgeInsets.all(2), - decoration: new BoxDecoration( - color: Colors.red, - borderRadius: - BorderRadius.circular( - 20), - ), - constraints: BoxConstraints( - minWidth: 20, - minHeight: 20, - ), - child: new Text( - notificationCount, - style: new TextStyle( - color: Colors.white, - fontSize: projectProvider - .isArabic - ? 8 - : 9, - ), - textAlign: TextAlign.center, - ), - // ), - ) - : SizedBox(), ), - ], - ), - onTap: () { - //NotificationsPage - Navigator.of(context).pop(); - Navigator.push(context, - FadePage(page: NotificationsPage())); - }, - ), - if (projectProvider.havePrivilege(3)) - InkWell( - child: DrawerItem( - TranslationBase.of(context) - .appsetting, - Icons.settings_input_composite), - onTap: () { - Navigator.of(context).pushNamed( - SETTINGS, - ); - }, - ), - InkWell( - child: DrawerItem( - TranslationBase.of(context).rateApp, - Icons.star), - onTap: () { - if (Platform.isIOS) { - launch( - "https://apps.apple.com/sa/app/dr-suliaman-alhabib/id733503978"); - } else { - launch( - "https://play.google.com/store/apps/details?id=com.ejada.hmg&hl=en"); - } - }, - ), - InkWell( + InkWell( + child: DrawerItem( + TranslationBase.of(context).rateApp, + Icons.star), + onTap: () { + if (Platform.isIOS) { + launch( + "https://apps.apple.com/sa/app/dr-suliaman-alhabib/id733503978"); + } else { + launch( + "https://play.google.com/store/apps/details?id=com.ejada.hmg&hl=en"); + } + }, + ), + InkWell( + child: DrawerItem( + TranslationBase.of(context).logout, + Icons.lock_open), + onTap: () { + logout(); + }, + ) + ], + ) + : InkWell( child: DrawerItem( - TranslationBase.of(context).logout, + TranslationBase.of(context) + .loginregister, Icons.lock_open), onTap: () { - logout(); + login(); }, - ) - ], - ) - : InkWell( - child: DrawerItem( - TranslationBase.of(context).loginregister, - Icons.lock_open), - onTap: () { - login(); - }, - ), - // InkWell( - // child: DrawerItem( - // TranslationBase.of(context).appsetting, - // Icons.settings_input_composite), - // onTap: () { - // Navigator.of(context).pushNamed( - // SETTINGS, - // ); - // }, - // ) + ), + // InkWell( + // child: DrawerItem( + // TranslationBase.of(context).appsetting, + // Icons.settings_input_composite), + // onTap: () { + // Navigator.of(context).pushNamed( + // SETTINGS, + // ); + // }, + // ) + ], + )) ], - ) - ], - ), - ), - Expanded( - flex: 1, - child: Column( - children: [ - Container( - child: Align( - alignment: FractionalOffset.bottomCenter, - child: Container( - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceEvenly, - children: [ - Column( - children: [ - Text(TranslationBase.of(context).poweredBy), - Image.asset( - 'assets/images/cs_logo_container.png', - width: SizeConfig.imageSizeMultiplier * 30, - ) - ], - ), - Column( - children: [ - Image.asset( - 'assets/images/new-design/vidamobile.png', - width: SizeConfig.imageSizeMultiplier * 25, - ) + ), + ), + Expanded( + flex: 1, + child: Column( + children: [ + Container( + child: Align( + alignment: FractionalOffset.bottomCenter, + child: Container( + child: Row( + mainAxisAlignment: + MainAxisAlignment.spaceEvenly, + children: [ + Column( + children: [ + Text(TranslationBase.of(context) + .poweredBy), + Image.asset( + 'assets/images/cs_logo_container.png', + width: + SizeConfig.imageSizeMultiplier * 30, + ) + ], + ), + Column( + children: [ + Image.asset( + 'assets/images/new-design/vidamobile.png', + width: + SizeConfig.imageSizeMultiplier * 25, + ) + ], + ), ], ), - ], + ), ), - ), - ), - ) - ], - ), - ) - ], + ) + ], + ), + ) + ], + ), + ), ), - ), - ), - ); + )); } drawerNavigator(context, routeName) { @@ -525,9 +548,10 @@ class _AppDrawerState extends State { loginAfter(result, context) async { Utils.hideProgressDialog(); - result = CheckActivationCode.fromJson(result); Provider.of(context, listen: false) .setPrivilege(privilegeList: result, isLoginChild: true); + result = CheckActivationCode.fromJson(result); + var familyFile = await sharedPref.getObject(FAMILY_FILE); var currentLang = await sharedPref.getString(APP_LANGUAGE); var mainUser = await sharedPref.getObject(MAIN_USER); diff --git a/lib/widgets/in_app_browser/InAppBrowser.dart b/lib/widgets/in_app_browser/InAppBrowser.dart index 19da88e7..63509b7c 100644 --- a/lib/widgets/in_app_browser/InAppBrowser.dart +++ b/lib/widgets/in_app_browser/InAppBrowser.dart @@ -1,28 +1,48 @@ import 'dart:convert'; +import 'package:diplomaticquarterapp/config/config.dart'; import 'package:diplomaticquarterapp/config/shared_pref_kay.dart'; import 'package:diplomaticquarterapp/core/model/pharmacies/order_detail.dart'; import 'package:diplomaticquarterapp/models/Appointments/AppoimentAllHistoryResultList.dart'; import 'package:diplomaticquarterapp/models/Authentication/authenticated_user.dart'; import 'package:diplomaticquarterapp/services/authentication/auth_provider.dart'; import 'package:diplomaticquarterapp/uitl/app_shared_preferences.dart'; +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter/widgets.dart'; import 'package:flutter_inappwebview/flutter_inappwebview.dart'; +enum _PAYMENT_TYPE{PACKAGES, PHARMACY, PATIENT} +var _InAppBrowserOptions = InAppBrowserClassOptions( + inAppWebViewGroupOptions: InAppWebViewGroupOptions(crossPlatform: InAppWebViewOptions(useShouldOverrideUrlLoading: true)), + crossPlatform: InAppBrowserOptions(hideUrlBar: true), + ios: IOSInAppBrowserOptions(toolbarBottom: false,) +); + class MyInAppBrowser extends InAppBrowser { + _PAYMENT_TYPE paymentType; + // static String SERVICE_URL = + // 'https://hmgwebservices.com/PayFortWeb/pages/SendPayFortRequest.aspx'; // Payfort Payment Gateway URL UAT + static String SERVICE_URL = - 'https://hmgwebservices.com/PayFortWeb/pages/SendPayFortRequest.aspx'; // Payfort Payment Gateway URL UAT + 'https://hmgwebservices.com/PayFortWebLive/pages/SendPayFortRequest.aspx'; //Payfort Payment Gateway URL LIVE - // static String SERVICE_URL = - // 'https://hmgwebservices.com/PayFortWebLive/pages/SendPayFortRequest.aspx'; //Payfort Payment Gateway URL LIVE + // static String PREAUTH_SERVICE_URL = + // 'https://hmgwebservices.com/PayFortWeb/pages/SendPayFortRequest.aspx'; // Payfort PreAuth Payment Gateway URL UAT static String PREAUTH_SERVICE_URL = - 'https://hmgwebservices.com/PayFortWeb/pages/SendPayFortRequest.aspx'; // Payfort PreAuth Payment Gateway URL UAT + 'https://hmgwebservices.com/PayFortWebLive/pages/SendPayFortRequest.aspx'; //Payfort PreAuth Payment Gateway URL Live Store - // static String PREAUTH_SERVICE_URL = - // 'https://hmgwebservices.com/PayFortWebLive/pages/SendPayFortRequest.aspx'; //Payfort PreAuth Payment Gateway URL Live Store + // static String PRESCRIPTION_PAYMENT_WITH_ORDERID = + // 'https://uat.hmgwebservices.com/epharmacy/checkout/OpcCompleteRedirectionPaymentClientbyOrder?orderID='; static String PRESCRIPTION_PAYMENT_WITH_ORDERID = - 'https://uat.hmgwebservices.com/epharmacy/checkout/OpcCompleteRedirectionPaymentClientbyOrder?orderID='; + 'https://mdlaboratories.com/exacartapi/checkout/OpcCompleteRedirectionPaymentClientbyOrder?orderID='; //Live + + // Packages + static String PACKAGES_REQUEST_PAYMENT_URL = '$EXA_CART_API_BASE_URL/checkout/OpcCompleteRedirectionPayment1'; + static String PACKAGES_PAYMENT_SUCCESS_URL = '$EXA_CART_API_BASE_URL/Checkout/MobilePaymentSuccess'; + static String PACKAGES_PAYMENT_FAIL_URL = '$EXA_CART_API_BASE_URL/Checkout/MobilePaymentFailed'; static List successURLS = [ 'success', @@ -35,6 +55,7 @@ class MyInAppBrowser extends InAppBrowser { final Function onExitCallback; final Function onLoadStartCallback; + final BuildContext context; AppSharedPreferences sharedPref = AppSharedPreferences(); AuthProvider authProvider = new AuthProvider(); @@ -50,7 +71,7 @@ class MyInAppBrowser extends InAppBrowser { static bool isPaymentDone = false; - MyInAppBrowser({this.onExitCallback, this.appo, this.onLoadStartCallback}); + MyInAppBrowser({this.onExitCallback, this.appo, this.onLoadStartCallback, this.context}); Future onBrowserCreated() async { print("\n\nBrowser Created!\n\n"); @@ -58,7 +79,8 @@ class MyInAppBrowser extends InAppBrowser { @override Future onLoadStart(String url) async { - onLoadStartCallback(url); + if(onLoadStartCallback != null) + onLoadStartCallback(url); } @override @@ -79,13 +101,20 @@ class MyInAppBrowser extends InAppBrowser { @override void onExit() { print("\n\nBrowser closed!\n\n"); - onExitCallback(appo, isPaymentDone); + if(onExitCallback != null) + onExitCallback(appo, isPaymentDone); } @override - Future shouldOverrideUrlLoading( - ShouldOverrideUrlLoadingRequest shouldOverrideUrlLoadingRequest) async { - print("\n\n override ${shouldOverrideUrlLoadingRequest.url}\n\n"); + Future shouldOverrideUrlLoading(ShouldOverrideUrlLoadingRequest shouldOverrideUrlLoadingRequest) async { + var url = shouldOverrideUrlLoadingRequest.url; + debugPrint("redirecting/overriding to: $url"); + + if(paymentType == _PAYMENT_TYPE.PACKAGES && [PACKAGES_PAYMENT_SUCCESS_URL,PACKAGES_PAYMENT_FAIL_URL].contains(url)){ + isPaymentDone = (url == PACKAGES_PAYMENT_SUCCESS_URL); + close(); + } + return ShouldOverrideUrlLoadingAction.ALLOW; } @@ -111,6 +140,12 @@ class MyInAppBrowser extends InAppBrowser { } } + openPackagesPaymentBrowser({@required int customer_id, @required int order_id}){ + paymentType = _PAYMENT_TYPE.PACKAGES; + var full_url = '$PACKAGES_REQUEST_PAYMENT_URL?customer_id=$customer_id&order_id=$order_id'; + this.openUrl(url: full_url, options: _InAppBrowserOptions); + } + openPaymentBrowser( double amount, String orderDesc, @@ -147,7 +182,9 @@ class MyInAppBrowser extends InAppBrowser { clinicID, doctorID) .then((value) { - this.browser.openUrl(url: value); + + paymentType = _PAYMENT_TYPE.PATIENT; + this.browser.openUrl(url: value, options: _InAppBrowserOptions); }); } @@ -173,7 +210,7 @@ class MyInAppBrowser extends InAppBrowser { openBrowser(String url) { this.browser = browser; - this.browser.openUrl(url: url); + this.browser.openUrl(url: url, options: _InAppBrowserOptions); } Future generateURL( @@ -260,7 +297,6 @@ class MyInAppBrowser extends InAppBrowser { String patientName, dynamic patientID, AuthenticatedUser authUser) async { - String pharmacyURL = PRESCRIPTION_PAYMENT_WITH_ORDERID + order.orderGuid + '&&CustomerId=' + @@ -336,7 +372,6 @@ class MyInAppBrowser extends InAppBrowser { '' + ''; } - } class MyChromeSafariBrowser extends ChromeSafariBrowser { @@ -356,4 +391,4 @@ class MyChromeSafariBrowser extends ChromeSafariBrowser { void onClosed() { print("ChromeSafari browser closed"); } -} +} \ No newline at end of file diff --git a/lib/widgets/offers_packages/PackagesCartItemCard.dart b/lib/widgets/offers_packages/PackagesCartItemCard.dart new file mode 100644 index 00000000..12a49d2e --- /dev/null +++ b/lib/widgets/offers_packages/PackagesCartItemCard.dart @@ -0,0 +1,213 @@ +import 'package:cached_network_image/cached_network_image.dart'; +import 'package:diplomaticquarterapp/core/model/packages_offers/responses/PackagesCartItemsResponseModel.dart'; +import 'package:diplomaticquarterapp/core/model/packages_offers/responses/PackagesResponseModel.dart'; +import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; +import 'package:diplomaticquarterapp/uitl/utils.dart'; +import 'package:diplomaticquarterapp/widgets/CounterView.dart'; +import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; +import 'package:diplomaticquarterapp/widgets/others/StarRating.dart'; +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; + + +bool wide = true; + +class PackagesCartItemCard extends StatefulWidget { + final PackagesCartItemsResponseModel itemModel; + final StepperCallbackFuture shouldStepperChangeApply ; + + const PackagesCartItemCard( + { + @required this.itemModel, + @required this.shouldStepperChangeApply, + Key key}) + : super(key: key); + + @override + State createState() => PackagesCartItemCardState(); +} + +class PackagesCartItemCardState extends State { + + @override + Widget build(BuildContext context) { + + wide = !wide; + return Container( + color: Colors.transparent, + child: Card( + elevation: 3, + shadowColor: Colors.grey[100], + color: Colors.white, + child: Stack( + children: [ + Container( + height: 100, + child: Row( + children: [ + _image(widget.itemModel.product), + Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.center, + children: [ + _itemName(widget.itemModel.product.getName()), + Row( + children: [ + _itemPrice(widget.itemModel.product.price, context: context), + _priceSeperator(), + _itemOldPrice(widget.itemModel.product.oldPrice, context: context), + ], + ), + Row( + children: [ + _itemCounter( + widget.itemModel.quantity, + minQuantity: widget.itemModel.product.orderMinimumQuantity, + maxQuantity: widget.itemModel.product.orderMaximumQuantity, + shouldStepperChangeApply: (apply,total) async{ + bool success = await widget.shouldStepperChangeApply(apply,total); + if(success == true) + setState(() => widget.itemModel.quantity = total); + return success; + } + ), + ], + ), + ], + ) + ], + ), + ), + + Positioned( + bottom: 8, + left: 10, + child: Row( + children: [ + _totalPrice((widget.itemModel.product.price * widget.itemModel.quantity), context: context), + _totalLabel(context: context), + ], + ), + ) + ], + ) + ) + ); + } +} + + +// -------------------- +// Product Image +// -------------------- +Widget _image(PackagesResponseModel model) => AspectRatio( + aspectRatio: 1/1, + child: Padding( + padding: const EdgeInsets.all(10), + child: Container( + decoration: BoxDecoration( + border: Border.all(color: Colors.grey[300], width: 0.25), + boxShadow: [ + BoxShadow(color: Colors.grey[200], blurRadius: 2.0, spreadRadius: 1, offset: Offset(1,1.5)) + ], + borderRadius: BorderRadius.circular(8), + color: Colors.white, + shape: BoxShape.rectangle, + ), + child: ClipRRect( + borderRadius: BorderRadius.circular(8), + child: (model.images.isNotEmpty) + ? Utils.loadNetworkImage(url: model.images.first.src, fitting:BoxFit.fill) + : Container(color: Colors.grey[200]) + ), + ), + ), +); + +// -------------------- +// Product Name +// -------------------- +Widget _itemName(String name) => Padding( + padding: const EdgeInsets.all(0), + child: Texts( + name, + fontWeight: FontWeight.normal, + color: Colors.black, + fontSize: 15 + ) +); + + +Widget _itemPrice(double price, {@required BuildContext context}) => Padding( + padding: const EdgeInsets.all(0), + child: Texts( + '${price} ${TranslationBase.of(context).sar}', + fontWeight: FontWeight.bold, + color: Colors.green, + fontSize: 15 + ) +); + + +// -------------------- +// Price Seperator +// -------------------- +Widget _priceSeperator() => Padding( + padding: const EdgeInsets.only(left: 3, right: 3), + child: Container(height: 0.5, width: 5, color: Colors.grey[100],), +); + + +// -------------------- +// Product Price +// -------------------- +Widget _itemOldPrice(double oldPrice, {@required BuildContext context}) => Padding( + padding: const EdgeInsets.all(0), + child: Texts( + '${oldPrice} ${TranslationBase.of(context).sar}', + fontWeight: FontWeight.normal, + decoration: TextDecoration.lineThrough, + color: Colors.grey, + fontSize: 10 + ) +); + +// -------------------- +// Product Price +// -------------------- +Widget _itemCounter(int quantity, {int minQuantity, int maxQuantity, StepperCallbackFuture shouldStepperChangeApply}) => Padding( + padding: const EdgeInsets.all(0), + child: StepperView( + height: 25, + backgroundColor: Colors.grey[300], + foregroundColor: Colors.grey[200], + initialNumber: quantity, + minNumber: minQuantity, + maxNumber: maxQuantity, + counterCallback: shouldStepperChangeApply, + decreaseCallback: (){}, + increaseCallback: (){}, + ) +); + + +Widget _totalLabel({@required BuildContext context}) => Padding( + padding: const EdgeInsets.all(0), + child: Texts( + '${TranslationBase.of(context).totalWithColonRight}', + fontWeight: FontWeight.bold, + color: Colors.grey[600], + fontSize: 13 + ) +); + + +Widget _totalPrice(double totalPrice, {@required BuildContext context}) => Padding( + padding: const EdgeInsets.all(0), + child: Texts( + '${totalPrice.toStringAsFixed(2)} ${TranslationBase.of(context).sar}', + fontWeight: FontWeight.normal, + color: Colors.green, + ) +); + diff --git a/lib/widgets/offers_packages/PackagesOfferCard.dart b/lib/widgets/offers_packages/PackagesOfferCard.dart new file mode 100644 index 00000000..9738400e --- /dev/null +++ b/lib/widgets/offers_packages/PackagesOfferCard.dart @@ -0,0 +1,158 @@ +import 'package:cached_network_image/cached_network_image.dart'; +import 'package:diplomaticquarterapp/core/model/packages_offers/responses/PackagesResponseModel.dart'; +import 'package:diplomaticquarterapp/uitl/utils.dart'; +import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; +import 'package:diplomaticquarterapp/widgets/others/StarRating.dart'; +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; + + +bool wide = true; + +class PackagesItemCard extends StatefulWidget { + final double itemWidth; + final double itemHeight; + final double itemContentPadding; + final PackagesResponseModel itemModel; + final Function(PackagesResponseModel product) onCartClick; + + const PackagesItemCard( + { + this.itemWidth, + this.itemHeight, + @required this.itemModel, + @required this.itemContentPadding, + @required this.onCartClick, + Key key}) + : super(key: key); + + @override + State createState() => PackagesItemCardState(); +} + +class PackagesItemCardState extends State { + imageUrl() => widget.itemModel.images.isNotEmpty ? widget.itemModel.images.first.src : "https://wallpaperaccess.com/full/30103.jpg"; + + @override + Widget build(BuildContext context) { + wide = !wide; + return Directionality( + textDirection: TextDirection.rtl, + child: Stack( + children: [ + Padding( + padding: EdgeInsets.only( + left: widget.itemContentPadding, + right: widget.itemContentPadding, + top: widget.itemContentPadding + 5), + child: Container( + width: widget.itemWidth, + color: Colors.transparent, + child: Stack( + children: [ + Column( + mainAxisSize: MainAxisSize.max, + children: [ + AspectRatio( + aspectRatio:1 / 1, + child: applyShadow( + child: ClipRRect( + borderRadius: BorderRadius.circular(10), + child: Utils.loadNetworkImage( + url: imageUrl(), + )), + )), + Texts( + widget.itemModel.getName(), + fontWeight: FontWeight.normal, + color: Colors.black, + fontSize: 15 + ), + Padding( + padding: const EdgeInsets.only(left: 10, right: 10), + child: Row( + crossAxisAlignment: CrossAxisAlignment.end, + mainAxisSize: MainAxisSize.max, + children: [ + Stack( + children: [ + Texts( + '${widget.itemModel.oldPrice} ${'SAR'}', + fontWeight: FontWeight.normal, + decoration: TextDecoration.lineThrough, + color: Colors.grey, + fontSize: 12 + ), + Padding( + padding: const EdgeInsets.only(top: 8), + child: Texts( + '${widget.itemModel.price} ${'SAR'}', + fontWeight: FontWeight.bold, + color: Colors.green, + fontSize: 18 + ), + ), + Padding( + padding: const EdgeInsets.only(top: 35), + child: StarRating( + size: 15, + totalCount: null, + totalAverage: widget.itemModel.approvedRatingSum.toDouble(), + forceStars: true), + ) + ], + ), + Spacer( + flex: 1, + ), + InkWell( + child: Icon( + Icons.add_shopping_cart_rounded, + size: 30.0, + color: Colors.grey, + ), + onTap: () { + widget.onCartClick(widget.itemModel); + }, + ), + ], + ), + ), + ], + ), + ], + ), + ), + ), + Positioned( + top: 0, + right: 0, + child: Visibility( + visible: false, + child: InkWell( + child: Icon( + Icons.favorite, + size: 40.0, + color: Colors.red, + ), + onTap: () { + + }, + ), + ), + ), + + Positioned( + top: 7, + left: 2, + child: Image.asset( + 'assets/images/discount_${'en'}.png', + height: 60, + width: 60, + ), + ), + ], + ), + ); + } +} diff --git a/lib/widgets/offers_packages/offers_packages.dart b/lib/widgets/offers_packages/offers_packages.dart index 6834d516..a9fcf99d 100644 --- a/lib/widgets/offers_packages/offers_packages.dart +++ b/lib/widgets/offers_packages/offers_packages.dart @@ -1,6 +1,5 @@ import 'dart:developer'; -import 'package:carousel_pro/carousel_pro.dart'; import 'package:carousel_slider/carousel_slider.dart'; import 'package:diplomaticquarterapp/core/model/packages_offers/requests/OffersCategoriesRequestModel.dart'; import 'package:diplomaticquarterapp/core/model/packages_offers/requests/OffersProductsRequestModel.dart'; @@ -264,8 +263,8 @@ class OfferPackagesItemModel { print(value.toString()); }); - var vm_products = locator(); - vm_products.service.getAllProducts(OffersProductsRequestModel(categoryId: 125, limit: 100, page: 1, sinceId: 0)).then((value) { + var vm_products = locator(); + vm_products.service.getAllProducts(request: OffersProductsRequestModel(categoryId: 125, limit: 100)).then((value) { print(value.toString()); print(value.toString()); }); diff --git a/lib/widgets/others/StarRating.dart b/lib/widgets/others/StarRating.dart index 2eaa7f91..5620b21a 100644 --- a/lib/widgets/others/StarRating.dart +++ b/lib/widgets/others/StarRating.dart @@ -14,26 +14,26 @@ class StarRating extends StatelessWidget { @override Widget build(BuildContext context) { return Row( - mainAxisAlignment: MainAxisAlignment.start, - children: [ - if (!forceStars && (totalAverage==null || totalAverage==0)) - Texts("New", style: "caption"), - if (forceStars || (totalAverage!=null && totalAverage>0)) - ...List.generate(5, (index) => - Padding( - padding: EdgeInsets.only(right: 1.0), - child: Icon( - (index+1) <= (totalAverage ?? 0) ? EvaIcons.star : EvaIcons.starOutline, - size: size, - color: (index+1) <= (totalAverage ?? 0) ? Color.fromRGBO(255, 186, 0, 1.0) : Theme.of(context).hintColor + mainAxisAlignment: MainAxisAlignment.start, + children: [ + if (!forceStars && (totalAverage==null || totalAverage==0)) + Texts("New", style: "caption"), + if (forceStars || (totalAverage!=null && totalAverage>0)) + ...List.generate(5, (index) => + Padding( + padding: EdgeInsets.only(right: 1.0), + child: Icon( + (index+1) <= (totalAverage ?? 0) ? EvaIcons.star : EvaIcons.starOutline, + size: size, + color: (index+1) <= (totalAverage ?? 0) ? Color.fromRGBO(255, 186, 0, 1.0) : Theme.of(context).hintColor + ), + ) ), - ) - ), - if (totalCount!=null) - SizedBox(width: 9.0), - if (totalCount!=null) - Texts("("+totalCount.toString()+")", style: "overline", color: Colors.grey[400],) - ] + if (totalCount!=null) + SizedBox(width: 9.0), + if (totalCount!=null) + Texts("("+totalCount.toString()+")", style: "overline", color: Colors.grey[400],) + ] ); } } \ No newline at end of file diff --git a/lib/widgets/others/app_scaffold_widget.dart b/lib/widgets/others/app_scaffold_widget.dart index 6619de79..ca72e267 100644 --- a/lib/widgets/others/app_scaffold_widget.dart +++ b/lib/widgets/others/app_scaffold_widget.dart @@ -1,3 +1,4 @@ +import 'package:badges/badges.dart'; import 'package:diplomaticquarterapp/config/config.dart'; import 'package:diplomaticquarterapp/config/size_config.dart'; import 'package:diplomaticquarterapp/config/size_config.dart'; @@ -31,6 +32,8 @@ import 'not_auh_page.dart'; import 'package:diplomaticquarterapp/services/authentication/auth_provider.dart'; import 'package:diplomaticquarterapp/config/shared_pref_kay.dart'; +VoidCallback _onCartClick; + class AppScaffold extends StatelessWidget { final String appBarTitle; final Widget body; @@ -42,6 +45,9 @@ class AppScaffold extends StatelessWidget { final bool isBottomBar; final Widget floatingActionButton; final bool isPharmacy; + final bool isOfferPackages; + final bool showPharmacyCart; + final bool showOfferPackagesCart; final String title; final String description; final bool isShowDecPage; @@ -55,6 +61,7 @@ class AppScaffold extends StatelessWidget { AuthenticatedUserObject authenticatedUserObject = locator(); + AppBarWidget appBar; AppScaffold( {@required this.body, this.appBarTitle = '', @@ -65,6 +72,9 @@ class AppScaffold extends StatelessWidget { this.baseViewModel, this.floatingActionButton, this.isPharmacy = false, + this.showPharmacyCart = true, + this.isOfferPackages = false, + this.showOfferPackagesCart = false, this.title, this.description, this.isShowDecPage = true, @@ -77,6 +87,11 @@ class AppScaffold extends StatelessWidget { this.showHomeAppBarIcon = true, this.imagesInfo}); + AppScaffold setOnAppBarCartClick(VoidCallback onClick) { + _onCartClick = onClick; + return this; + } + @override Widget build(BuildContext context) { AppGlobal.context = context; @@ -84,29 +99,37 @@ class AppScaffold extends StatelessWidget { backgroundColor: backgroundColor ?? Theme.of(context).scaffoldBackgroundColor, appBar: isShowAppBar - ? AppBarWidget( + ? appBar = AppBarWidget( appBarTitle: appBarTitle, appBarIcons: appBarIcons, showHomeAppBarIcon: showHomeAppBarIcon, isPharmacy: isPharmacy, + showPharmacyCart: showPharmacyCart, + isOfferPackages: isOfferPackages, + showOfferPackagesCart: showOfferPackagesCart, isShowDecPage: isShowDecPage, ) : null, bottomSheet: bottomSheet, - body: (!Provider.of(context, listen: false).isLogin && - isShowDecPage) - ? NotAutPage( - title: title ?? appBarTitle, - description: description, - infoList: infoList, - imagesInfo: imagesInfo, - ) - : baseViewModel != null - ? NetworkBaseView( - child: buildBodyWidget(context), - baseViewModel: baseViewModel, - ) - : buildBodyWidget(context), + body: SafeArea( + top: true, + bottom: true, + child: + (!Provider.of(context, listen: false).isLogin && + isShowDecPage) + ? NotAutPage( + title: title ?? appBarTitle, + description: description, + infoList: infoList, + imagesInfo: imagesInfo, + ) + : baseViewModel != null + ? NetworkBaseView( + child: buildBodyWidget(context), + baseViewModel: baseViewModel, + ) + : buildBodyWidget(context), + ), ); } @@ -120,7 +143,7 @@ class AppScaffold extends StatelessWidget { } } -class AppBarWidget extends StatelessWidget with PreferredSizeWidget { +class AppBarWidget extends StatefulWidget with PreferredSizeWidget { final AuthenticatedUserObject authenticatedUserObject = locator(); @@ -128,34 +151,59 @@ class AppBarWidget extends StatelessWidget with PreferredSizeWidget { final bool showHomeAppBarIcon; final List appBarIcons; final bool isPharmacy; + final bool isOfferPackages; + final bool showPharmacyCart; + final bool showOfferPackagesCart; final bool isShowDecPage; + Function(String) badgeUpdater; + AppBarWidget( {this.appBarTitle, this.showHomeAppBarIcon, this.appBarIcons, this.isPharmacy = true, + this.showPharmacyCart = true, + this.isOfferPackages = false, + this.showOfferPackagesCart = false, this.isShowDecPage = true}); + @override + State createState() => AppBarWidgetState(); + + @override + Size get preferredSize => Size(double.maxFinite, 60); +} + +class AppBarWidgetState extends State { + String badgeText = "0"; @override Widget build(BuildContext context) { + widget.badgeUpdater = badgeUpdateBlock; return buildAppBar(context); } + badgeUpdateBlock(String value) { + setState(() { + badgeText = value; + }); + } + Widget buildAppBar(BuildContext context) { ProjectViewModel projectViewModel = Provider.of(context); return AppBar( elevation: 0, - backgroundColor: - isPharmacy ? Colors.green : Theme.of(context).appBarTheme.color, + backgroundColor: widget.isPharmacy + ? Colors.green + : Theme.of(context).appBarTheme.color, textTheme: TextTheme( headline6: TextStyle( color: Theme.of(context).textTheme.headline1.color, fontWeight: FontWeight.bold), ), title: Text( - authenticatedUserObject.isLogin || !isShowDecPage - ? appBarTitle.toUpperCase() + widget.authenticatedUserObject.isLogin || !widget.isShowDecPage + ? widget.appBarTitle.toUpperCase() : TranslationBase.of(context).serviceInformationTitle, style: TextStyle( fontWeight: FontWeight.bold, @@ -168,28 +216,49 @@ class AppBarWidget extends StatelessWidget with PreferredSizeWidget { ), centerTitle: true, actions: [ - isPharmacy + (widget.isPharmacy && widget.showPharmacyCart) ? IconButton( - icon: Icon(Icons.shopping_cart), - color: Theme.of(context).textTheme.headline1.color, + icon: Badge( + badgeContent: Text(badgeText), + child: Icon(Icons.shopping_cart)), + color: Colors.white, onPressed: () { - Navigator.push( - context, - MaterialPageRoute(builder: (context) => CartOrderPage()), - ); + Navigator.of(context).popUntil(ModalRoute.withName('/')); }) : Container(), - IconButton( - icon: Icon(FontAwesomeIcons.home), - color: Theme.of(context).textTheme.headline1.color, - onPressed: () { - Navigator.pushAndRemoveUntil( - context, - MaterialPageRoute(builder: (context) => LandingPage()), - (Route r) => false); - }, - ), - if (appBarIcons != null) ...appBarIcons + (widget.isOfferPackages && widget.showOfferPackagesCart) + ? IconButton( + icon: Badge( + position: BadgePosition.topStart(top: -15, start: -10), + badgeContent: Text( + badgeText, + style: TextStyle( + fontSize: 9, + color: Colors.white, + fontWeight: FontWeight.normal), + ), + child: Icon(Icons.shopping_cart)), + color: Colors.white, + onPressed: () { + // Cart Click Event + if (_onCartClick != null) _onCartClick(); + }) + : Container(), + if (widget.showHomeAppBarIcon) + IconButton( + icon: Icon(FontAwesomeIcons.home), + color: Colors.white, + onPressed: () { + Navigator.pushAndRemoveUntil( + context, + MaterialPageRoute(builder: (context) => LandingPage()), + (Route r) => false); + + // Cart Click Event + if (_onCartClick != null) _onCartClick(); + }, + ), + if (widget.appBarIcons != null) ...widget.appBarIcons ], ); } @@ -282,7 +351,7 @@ class _RobotIcon extends State { ], ), right: -30, - bottom: 50); + bottom: -15); } // setAnimation() async { diff --git a/lib/widgets/others/floating_button_search.dart b/lib/widgets/others/floating_button_search.dart index 3e3bae5a..69251773 100644 --- a/lib/widgets/others/floating_button_search.dart +++ b/lib/widgets/others/floating_button_search.dart @@ -834,11 +834,13 @@ class _FloatingSearchButton extends State if (isInit == true) { event.setValue({"animationEnable": 'true'}); } - if (isArabic == false && results['ReturnMessage'] != null) { + if (isArabic == false && + results['ReturnMessage'] != null && + isInit == false) { await flutterTts .setVoice({"name": "en-au-x-aub-network", "locale": "en-AU"}); await flutterTts.speak(results['ReturnMessage']); - } else if (results['ReturnMessage_Ar'] != null) { + } else if (results['ReturnMessage_Ar'] != null && isInit == false) { await flutterTts .setVoice({"name": "ar-xa-x-ard-network", "locale": "ar"}); await flutterTts.speak(results['ReturnMessage_Ar']); @@ -889,6 +891,21 @@ class _FloatingSearchButton extends State stopAnimation({isInit}) async { if (isInit == true) { IS_TEXT_COMPLETED = true; + Future.delayed(const Duration(seconds: 10), () { + event.setValue({"animationEnable": 'false'}); + setState(() { + this.networkImage = null; + this.isAnimationEnable = false; + }); + }); + } else { + flutterTts.setCompletionHandler(() async { + event.setValue({"animationEnable": 'false'}); + setState(() { + this.networkImage = null; + this.isAnimationEnable = false; + }); + }); } flutterTts.setCompletionHandler(() async { event.setValue({"animationEnable": 'false'}); diff --git a/pubspec.yaml b/pubspec.yaml index d84fb953..80cd9941 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -21,6 +21,8 @@ dependencies: # http client http: ^0.12.1 connectivity: ^0.4.9+3 + async: ^2.4.2 + audio_wave: ^0.0.3 # State Management provider: ^4.3.2+2 @@ -87,7 +89,6 @@ dependencies: # Qr code Scanner TODO fix it # barcode_scanner: ^1.0.1 - barcode_scan: ^2.0.0 flutter_polyline_points: ^0.1.0 location: ^2.3.5 # Qr code Scanner @@ -105,9 +106,6 @@ dependencies: # Location Helper map_launcher: ^0.8.1 - #carousel slider - carousel_slider: ^2.3.1 - #Calendar Events manage_calendar_events: ^1.0.2 @@ -181,6 +179,12 @@ dependencies: # Dep by Zohaib shimmer: ^1.1.2 + carousel_slider: ^2.3.1 + flutter_material_pickers: 1.7.4 + flutter_staggered_grid_view: 0.3.4 + + # Marker Animation + flutter_animarker: ^1.0.0 dev_dependencies: flutter_test: