Packages and Offers in Progress
parent
15ec3ec9b9
commit
f410ce20ca
Binary file not shown.
|
After Width: | Height: | Size: 4.5 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 5.8 KiB |
@ -0,0 +1,37 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 299.19 299.19">
|
||||
<defs>
|
||||
<style>
|
||||
.cls-1 {
|
||||
fill: #a02228;
|
||||
}
|
||||
|
||||
.cls-2 {
|
||||
fill: #c42829;
|
||||
}
|
||||
|
||||
.cls-3, .cls-4 {
|
||||
fill: #fff;
|
||||
}
|
||||
|
||||
.cls-4 {
|
||||
font-size: 63.99px;
|
||||
font-family: GESSTwoMedium-Medium, GE SS Two;
|
||||
font-weight: 500;
|
||||
}
|
||||
</style>
|
||||
</defs>
|
||||
<g id="Layer_2" data-name="Layer 2">
|
||||
<g id="Layer_1-2" data-name="Layer 1">
|
||||
<g>
|
||||
<rect class="cls-1" x="154.78" width="144.13" height="42.56"/>
|
||||
<rect class="cls-1" y="154.77" width="42.56" height="144.13"/>
|
||||
<polygon class="cls-2" points="0 154.31 154.31 0 299.19 0 0 299.19 0 154.31"/>
|
||||
<g>
|
||||
<polygon class="cls-2" points="14.51 160.32 160.32 14.51 264.16 14.51 14.51 264.16 14.51 160.32"/>
|
||||
<path class="cls-3" d="M259.49,16.44l-243,243.05V161.12L161.12,16.44Zm9.34-3.86H159.52L12.58,159.52V268.83L268.83,12.58Z"/>
|
||||
</g>
|
||||
<text class="cls-4" transform="translate(64.37 181.67) rotate(-45)">مصخ</text>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.1 KiB |
@ -0,0 +1,43 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 25.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
viewBox="0 0 312.6 292.7" style="enable-background:new 0 0 312.6 292.7;" xml:space="preserve">
|
||||
<style type="text/css">
|
||||
.st0{fill:#A02228;}
|
||||
.st1{fill:#C42829;}
|
||||
.st2{fill:#FFFFFF;}
|
||||
</style>
|
||||
<g id="Layer_2_1_">
|
||||
<g id="Layer_1-2">
|
||||
<g>
|
||||
<rect x="152.5" y="1" class="st0" width="141.2" height="41.7"/>
|
||||
<rect x="0.9" y="152.6" class="st0" width="41.7" height="141.2"/>
|
||||
<polygon class="st1" points="0.9,152.2 152.1,1 294,1 0.9,294.1 "/>
|
||||
<g>
|
||||
<polygon class="st1" points="15.1,158.1 158,15.2 259.7,15.2 15.1,259.8 "/>
|
||||
<path class="st2" d="M255.1,17.1l-238,238.1v-96.4L158.7,17.1H255.1z M264.3,13.3H157.2L13.2,157.3v107.1
|
||||
C13.2,264.4,264.3,13.3,264.3,13.3z"/>
|
||||
</g>
|
||||
<g>
|
||||
<path class="st2" d="M30.9,176.1l7.3-7.3c6.3-6.3,13.6-6.2,19.3-0.5c5.3,5.3,5.4,12.8-0.7,18.9l-7.4,7.4L30.9,176.1z
|
||||
M49.9,186.6l3-3c3.8-3.8,3.6-7.8,0.4-11c-3.5-3.5-7.5-3.6-11.4,0.3l-2.9,2.9L49.9,186.6z"/>
|
||||
<path class="st2" d="M50.8,156.2L55,152l18.5,18.5l-4.2,4.2L50.8,156.2z"/>
|
||||
<path class="st2" d="M67.9,149.1c1.4,1.4,3.5,0.6,6.3-1.4c5.6-3.8,8.9-4.5,12.4-1c3.3,3.3,2.8,8.5-1.9,13.2
|
||||
c-1.8,1.8-4,3.2-6.5,3.9c-2.6,0.7-5.4,0.4-7.8-0.8l1.3-5.8c3,1.9,7,1.4,9.4-1.2c2-1.9,2.5-3.8,1.4-5c-1.1-1.1-2.7-1.1-6.5,1.7
|
||||
c-4.5,3.4-8.9,4.1-12.4,0.6c-2.9-2.9-2.6-7.9,1.6-12.1c3.5-3.5,7.7-4.5,11.8-2.5l-1.5,5.4c-2.8-1.4-4.9-1.2-6.9,0.8
|
||||
C67.2,146.4,67,148.2,67.9,149.1z"/>
|
||||
<path class="st2" d="M99.9,137c3.1-3.1,3-7,0.5-10.8l5.4-2.3c3.5,5.6,2.9,11.9-2.2,16.9c-5.9,5.9-13.8,5.6-19.2,0.2
|
||||
c-5.3-5.1-5.4-13.6-0.2-18.8c0.1-0.1,0.3-0.3,0.4-0.4c4.9-4.9,10.7-5.3,14.9-2.6l-2.1,5.6c-2.8-2-6.7-1.6-9.1,0.9
|
||||
c-2.9,2.9-3.1,7.6,0.3,11.1c2.8,3.1,7.7,3.4,10.8,0.6C99.7,137.2,99.8,137.1,99.9,137z"/>
|
||||
<path class="st2" d="M125.2,100.4c5.3,5.1,5.2,14.1-0.3,19.3c-5.2,5.4-14.3,5.5-19.3,0.3c-5.3-5.1-5.2-14.1,0.3-19.3
|
||||
C111.1,95.2,120.1,95.1,125.2,100.4z M120.9,104.6c-3.1-3.1-8-3-11.1,0c-3.1,3.1-3,8,0,11.1c3.1,3,8,3,11,0
|
||||
c3.2-2.6,4-7.1,1.3-10.3C121.9,105,121.6,104.6,120.9,104.6z"/>
|
||||
<path class="st2" d="M122.7,84.3l11,11c2.4,2.4,5.2,2.7,7.5,0.4c2.3-2.3,2-5.1-0.4-7.5l-11-11L134,73l11,11
|
||||
c4.8,4.8,4.8,10.8,0,15.6c-4.8,4.8-10.9,4.8-15.6,0l-11-11L122.7,84.3z"/>
|
||||
<path class="st2" d="M160,84l-4.2,4.2l-18.5-18.5l7.2-7.2l22.5,8.9l-15.7-15.7l4.2-4.2L174.1,70l-7.2,7.2l-22.5-8.9L160,84z"/>
|
||||
<path class="st2" d="M178.6,36.1l-6.3,6.3l14.7,14.7l-4.2,4.2L168,46.7l-6.4,6.4l-3.8-3.8l16.9-16.9L178.6,36.1z"/>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.7 KiB |
@ -1 +1 @@
|
||||
59a6c452ee075b50114918f17f1ad8f5
|
||||
45a7d43b55124e1b314759554f9a14d3
|
||||
@ -1,25 +1,809 @@
|
||||
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
|
||||
- connectivity_for_web (0.1.0):
|
||||
- Flutter
|
||||
- connectivity_macos (0.0.1):
|
||||
- Flutter
|
||||
- device_calendar (0.0.1):
|
||||
- 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)
|
||||
- firebase_core (0.5.3):
|
||||
- Firebase/CoreOnly (~> 6.33.0)
|
||||
- Flutter
|
||||
- firebase_core_web (0.1.0):
|
||||
- Flutter
|
||||
- firebase_messaging (7.0.3):
|
||||
- Firebase/CoreOnly (~> 6.33.0)
|
||||
- Firebase/Messaging (~> 6.33.0)
|
||||
- firebase_core
|
||||
- Flutter
|
||||
- FirebaseCore (6.10.3):
|
||||
- FirebaseCoreDiagnostics (~> 1.6)
|
||||
- GoogleUtilities/Environment (~> 6.7)
|
||||
- GoogleUtilities/Logger (~> 6.7)
|
||||
- FirebaseCoreDiagnostics (1.7.0):
|
||||
- GoogleDataTransport (~> 7.4)
|
||||
- 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)
|
||||
- GoogleUtilities/UserDefaults (~> 6.7)
|
||||
- PromisesObjC (~> 1.2)
|
||||
- FirebaseInstanceID (4.8.0):
|
||||
- FirebaseCore (~> 6.10)
|
||||
- FirebaseInstallations (~> 1.6)
|
||||
- GoogleUtilities/Environment (~> 6.7)
|
||||
- GoogleUtilities/UserDefaults (~> 6.7)
|
||||
- FirebaseMessaging (4.7.1):
|
||||
- FirebaseCore (~> 6.10)
|
||||
- FirebaseInstanceID (~> 4.7)
|
||||
- GoogleUtilities/AppDelegateSwizzler (~> 6.7)
|
||||
- GoogleUtilities/Environment (~> 6.7)
|
||||
- GoogleUtilities/Reachability (~> 6.7)
|
||||
- GoogleUtilities/UserDefaults (~> 6.7)
|
||||
- Protobuf (>= 3.9.2, ~> 3.9)
|
||||
- Flutter (1.0.0)
|
||||
- flutter_email_sender (0.0.1):
|
||||
- Flutter
|
||||
- flutter_flexible_toast (0.0.1):
|
||||
- Flutter
|
||||
- flutter_inappwebview (0.0.1):
|
||||
- Flutter
|
||||
- flutter_local_notifications (0.0.1):
|
||||
- Flutter
|
||||
- flutter_plugin_android_lifecycle (0.0.1):
|
||||
- Flutter
|
||||
- flutter_tts (0.0.1):
|
||||
- Flutter
|
||||
- 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
|
||||
- GoogleMaps (< 3.10)
|
||||
- GoogleDataTransport (7.5.1):
|
||||
- nanopb (~> 1.30906.0)
|
||||
- GoogleMaps (3.9.0):
|
||||
- GoogleMaps/Maps (= 3.9.0)
|
||||
- GoogleMaps/Base (3.9.0)
|
||||
- GoogleMaps/Maps (3.9.0):
|
||||
- GoogleMaps/Base
|
||||
- GoogleUtilities/AppDelegateSwizzler (6.7.2):
|
||||
- GoogleUtilities/Environment
|
||||
- GoogleUtilities/Logger
|
||||
- GoogleUtilities/Network
|
||||
- GoogleUtilities/Environment (6.7.2):
|
||||
- PromisesObjC (~> 1.2)
|
||||
- GoogleUtilities/Logger (6.7.2):
|
||||
- GoogleUtilities/Environment
|
||||
- GoogleUtilities/Network (6.7.2):
|
||||
- GoogleUtilities/Logger
|
||||
- "GoogleUtilities/NSData+zlib"
|
||||
- GoogleUtilities/Reachability
|
||||
- "GoogleUtilities/NSData+zlib (6.7.2)"
|
||||
- GoogleUtilities/Reachability (6.7.2):
|
||||
- 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):
|
||||
- Flutter
|
||||
- TOCropViewController (~> 2.5.4)
|
||||
- image_picker (0.0.1):
|
||||
- Flutter
|
||||
- just_audio (0.0.1):
|
||||
- Flutter
|
||||
- leveldb-library (1.22)
|
||||
- local_auth (0.0.1):
|
||||
- Flutter
|
||||
- location (0.0.1):
|
||||
- Flutter
|
||||
- manage_calendar_events (0.0.1):
|
||||
- Flutter
|
||||
- map_launcher (0.0.1):
|
||||
- Flutter
|
||||
- maps_launcher (0.0.1):
|
||||
- Flutter
|
||||
- MTBBarcodeScanner (5.0.11)
|
||||
- nanopb (1.30906.0):
|
||||
- nanopb/decode (= 1.30906.0)
|
||||
- nanopb/encode (= 1.30906.0)
|
||||
- nanopb/decode (1.30906.0)
|
||||
- nanopb/encode (1.30906.0)
|
||||
- native_device_orientation (0.0.1):
|
||||
- Flutter
|
||||
- NVActivityIndicatorView (5.1.1):
|
||||
- NVActivityIndicatorView/Base (= 5.1.1)
|
||||
- NVActivityIndicatorView/Base (5.1.1)
|
||||
- path_provider (0.0.1):
|
||||
- Flutter
|
||||
- path_provider_linux (0.0.1):
|
||||
- Flutter
|
||||
- path_provider_macos (0.0.1):
|
||||
- Flutter
|
||||
- path_provider_windows (0.0.1):
|
||||
- Flutter
|
||||
- "permission_handler (5.1.0+2)":
|
||||
- Flutter
|
||||
- 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):
|
||||
- Flutter
|
||||
- shared_preferences_macos (0.0.1):
|
||||
- Flutter
|
||||
- shared_preferences_web (0.0.1):
|
||||
- Flutter
|
||||
- shared_preferences_windows (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)":
|
||||
- Flutter
|
||||
- TwilioVideo (~> 3.4)
|
||||
- TwilioVideo (3.8.0)
|
||||
- url_launcher (0.0.1):
|
||||
- Flutter
|
||||
- url_launcher_linux (0.0.1):
|
||||
- Flutter
|
||||
- url_launcher_macos (0.0.1):
|
||||
- Flutter
|
||||
- url_launcher_web (0.0.1):
|
||||
- Flutter
|
||||
- url_launcher_windows (0.0.1):
|
||||
- Flutter
|
||||
- vibration (1.7.3):
|
||||
- Flutter
|
||||
- vibration_web (1.6.2):
|
||||
- Flutter
|
||||
- video_player (0.0.1):
|
||||
- Flutter
|
||||
- video_player_web (0.0.1):
|
||||
- Flutter
|
||||
- wakelock (0.0.1):
|
||||
- Flutter
|
||||
- webview_flutter (0.0.1):
|
||||
- Flutter
|
||||
- wifi (0.0.1):
|
||||
- Flutter
|
||||
|
||||
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`)
|
||||
- Flutter (from `Flutter`)
|
||||
- flutter_email_sender (from `.symlinks/plugins/flutter_email_sender/ios`)
|
||||
- flutter_flexible_toast (from `.symlinks/plugins/flutter_flexible_toast/ios`)
|
||||
- flutter_inappwebview (from `.symlinks/plugins/flutter_inappwebview/ios`)
|
||||
- flutter_local_notifications (from `.symlinks/plugins/flutter_local_notifications/ios`)
|
||||
- flutter_plugin_android_lifecycle (from `.symlinks/plugins/flutter_plugin_android_lifecycle/ios`)
|
||||
- flutter_tts (from `.symlinks/plugins/flutter_tts/ios`)
|
||||
- geolocator (from `.symlinks/plugins/geolocator/ios`)
|
||||
- google_maps_flutter (from `.symlinks/plugins/google_maps_flutter/ios`)
|
||||
- hexcolor (from `.symlinks/plugins/hexcolor/ios`)
|
||||
- image_cropper (from `.symlinks/plugins/image_cropper/ios`)
|
||||
- image_picker (from `.symlinks/plugins/image_picker/ios`)
|
||||
- just_audio (from `.symlinks/plugins/just_audio/ios`)
|
||||
- local_auth (from `.symlinks/plugins/local_auth/ios`)
|
||||
- location (from `.symlinks/plugins/location/ios`)
|
||||
- manage_calendar_events (from `.symlinks/plugins/manage_calendar_events/ios`)
|
||||
- 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`)
|
||||
- NVActivityIndicatorView
|
||||
- path_provider (from `.symlinks/plugins/path_provider/ios`)
|
||||
- path_provider_linux (from `.symlinks/plugins/path_provider_linux/ios`)
|
||||
- path_provider_macos (from `.symlinks/plugins/path_provider_macos/ios`)
|
||||
- path_provider_windows (from `.symlinks/plugins/path_provider_windows/ios`)
|
||||
- permission_handler (from `.symlinks/plugins/permission_handler/ios`)
|
||||
- screen (from `.symlinks/plugins/screen/ios`)
|
||||
- shared_preferences (from `.symlinks/plugins/shared_preferences/ios`)
|
||||
- shared_preferences_linux (from `.symlinks/plugins/shared_preferences_linux/ios`)
|
||||
- shared_preferences_macos (from `.symlinks/plugins/shared_preferences_macos/ios`)
|
||||
- shared_preferences_web (from `.symlinks/plugins/shared_preferences_web/ios`)
|
||||
- shared_preferences_windows (from `.symlinks/plugins/shared_preferences_windows/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`)
|
||||
- url_launcher_macos (from `.symlinks/plugins/url_launcher_macos/ios`)
|
||||
- url_launcher_web (from `.symlinks/plugins/url_launcher_web/ios`)
|
||||
- url_launcher_windows (from `.symlinks/plugins/url_launcher_windows/ios`)
|
||||
- vibration (from `.symlinks/plugins/vibration/ios`)
|
||||
- vibration_web (from `.symlinks/plugins/vibration_web/ios`)
|
||||
- video_player (from `.symlinks/plugins/video_player/ios`)
|
||||
- video_player_web (from `.symlinks/plugins/video_player_web/ios`)
|
||||
- wakelock (from `.symlinks/plugins/wakelock/ios`)
|
||||
- webview_flutter (from `.symlinks/plugins/webview_flutter/ios`)
|
||||
- wifi (from `.symlinks/plugins/wifi/ios`)
|
||||
|
||||
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
|
||||
|
||||
EXTERNAL SOURCES:
|
||||
android_intent:
|
||||
: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:
|
||||
:path: ".symlinks/plugins/connectivity_for_web/ios"
|
||||
connectivity_macos:
|
||||
:path: ".symlinks/plugins/connectivity_macos/ios"
|
||||
device_calendar:
|
||||
: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:
|
||||
:path: ".symlinks/plugins/firebase_core_web/ios"
|
||||
firebase_messaging:
|
||||
:path: ".symlinks/plugins/firebase_messaging/ios"
|
||||
Flutter:
|
||||
:path: Flutter
|
||||
flutter_email_sender:
|
||||
:path: ".symlinks/plugins/flutter_email_sender/ios"
|
||||
flutter_flexible_toast:
|
||||
:path: ".symlinks/plugins/flutter_flexible_toast/ios"
|
||||
flutter_inappwebview:
|
||||
:path: ".symlinks/plugins/flutter_inappwebview/ios"
|
||||
flutter_local_notifications:
|
||||
:path: ".symlinks/plugins/flutter_local_notifications/ios"
|
||||
flutter_plugin_android_lifecycle:
|
||||
:path: ".symlinks/plugins/flutter_plugin_android_lifecycle/ios"
|
||||
flutter_tts:
|
||||
:path: ".symlinks/plugins/flutter_tts/ios"
|
||||
geolocator:
|
||||
:path: ".symlinks/plugins/geolocator/ios"
|
||||
google_maps_flutter:
|
||||
:path: ".symlinks/plugins/google_maps_flutter/ios"
|
||||
hexcolor:
|
||||
:path: ".symlinks/plugins/hexcolor/ios"
|
||||
image_cropper:
|
||||
:path: ".symlinks/plugins/image_cropper/ios"
|
||||
image_picker:
|
||||
:path: ".symlinks/plugins/image_picker/ios"
|
||||
just_audio:
|
||||
:path: ".symlinks/plugins/just_audio/ios"
|
||||
local_auth:
|
||||
:path: ".symlinks/plugins/local_auth/ios"
|
||||
location:
|
||||
:path: ".symlinks/plugins/location/ios"
|
||||
manage_calendar_events:
|
||||
:path: ".symlinks/plugins/manage_calendar_events/ios"
|
||||
map_launcher:
|
||||
:path: ".symlinks/plugins/map_launcher/ios"
|
||||
maps_launcher:
|
||||
:path: ".symlinks/plugins/maps_launcher/ios"
|
||||
native_device_orientation:
|
||||
:path: ".symlinks/plugins/native_device_orientation/ios"
|
||||
path_provider:
|
||||
:path: ".symlinks/plugins/path_provider/ios"
|
||||
path_provider_linux:
|
||||
:path: ".symlinks/plugins/path_provider_linux/ios"
|
||||
path_provider_macos:
|
||||
:path: ".symlinks/plugins/path_provider_macos/ios"
|
||||
path_provider_windows:
|
||||
:path: ".symlinks/plugins/path_provider_windows/ios"
|
||||
permission_handler:
|
||||
:path: ".symlinks/plugins/permission_handler/ios"
|
||||
screen:
|
||||
:path: ".symlinks/plugins/screen/ios"
|
||||
shared_preferences:
|
||||
:path: ".symlinks/plugins/shared_preferences/ios"
|
||||
shared_preferences_linux:
|
||||
:path: ".symlinks/plugins/shared_preferences_linux/ios"
|
||||
shared_preferences_macos:
|
||||
:path: ".symlinks/plugins/shared_preferences_macos/ios"
|
||||
shared_preferences_web:
|
||||
:path: ".symlinks/plugins/shared_preferences_web/ios"
|
||||
shared_preferences_windows:
|
||||
:path: ".symlinks/plugins/shared_preferences_windows/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:
|
||||
:path: ".symlinks/plugins/url_launcher/ios"
|
||||
url_launcher_linux:
|
||||
:path: ".symlinks/plugins/url_launcher_linux/ios"
|
||||
url_launcher_macos:
|
||||
:path: ".symlinks/plugins/url_launcher_macos/ios"
|
||||
url_launcher_web:
|
||||
:path: ".symlinks/plugins/url_launcher_web/ios"
|
||||
url_launcher_windows:
|
||||
:path: ".symlinks/plugins/url_launcher_windows/ios"
|
||||
vibration:
|
||||
:path: ".symlinks/plugins/vibration/ios"
|
||||
vibration_web:
|
||||
:path: ".symlinks/plugins/vibration_web/ios"
|
||||
video_player:
|
||||
:path: ".symlinks/plugins/video_player/ios"
|
||||
video_player_web:
|
||||
:path: ".symlinks/plugins/video_player_web/ios"
|
||||
wakelock:
|
||||
:path: ".symlinks/plugins/wakelock/ios"
|
||||
webview_flutter:
|
||||
:path: ".symlinks/plugins/webview_flutter/ios"
|
||||
wifi:
|
||||
: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
|
||||
Flutter: 0e3d915762c693b495b44d77113d4970485de6ec
|
||||
flutter_email_sender: f787522d0e82f50e5766c1213dbffff22fdcf009
|
||||
flutter_flexible_toast: 0547e740cae0c33bb7c51bcd931233f4584e1143
|
||||
flutter_inappwebview: 69dfbac46157b336ffbec19ca6dfd4638c7bf189
|
||||
flutter_local_notifications: 9e4738ce2471c5af910d961a6b7eadcf57c50186
|
||||
flutter_plugin_android_lifecycle: dc0b544e129eebb77a6bfb1239d4d1c673a60a35
|
||||
flutter_tts: 0f492aab6accf87059b72354fcb4ba934304771d
|
||||
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
|
||||
map_launcher: e325db1261d029ff33e08e03baccffe09593ffea
|
||||
maps_launcher: eae38ee13a9c3f210fa04e04bb4c073fa4c6ed92
|
||||
MTBBarcodeScanner: f453b33c4b7dfe545d8c6484ed744d55671788cb
|
||||
nanopb: 59317e09cf1f1a0af72f12af412d54edf52603fc
|
||||
native_device_orientation: e24d00be281de72996640885d80e706142707660
|
||||
NVActivityIndicatorView: 1f6c5687f1171810aa27a3296814dc2d7dec3667
|
||||
path_provider: abfe2b5c733d04e238b0d8691db0cfd63a27a93c
|
||||
path_provider_linux: 4d630dc393e1f20364f3e3b4a2ff41d9674a84e4
|
||||
path_provider_macos: f760a3c5b04357c380e2fddb6f9db6f3015897e0
|
||||
path_provider_windows: a2b81600c677ac1959367280991971cb9a1edb3b
|
||||
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
|
||||
speech_to_text: b43a7d99aef037bd758ed8e45d79bbac035d2dfe
|
||||
sqflite: 6d358c025f5b867b29ed92fc697fd34924e11904
|
||||
SwiftyGif: 5d4af95df24caf1c570dbbcb32a3b8a0763bc6d7
|
||||
TOCropViewController: da59f531f8ac8a94ef6d6c0fc34009350f9e8bfe
|
||||
Try: 5ef669ae832617b3cee58cb2c6f99fb767a4ff96
|
||||
twilio_programmable_video: 6a41593640f3d86af60b22541fd457b22deaae7f
|
||||
TwilioVideo: c13a51ceca375e91620eb7578d2573c90cf53b46
|
||||
url_launcher: 6fef411d543ceb26efce54b05a0a40bfd74cbbef
|
||||
url_launcher_linux: ac237cb7a8058736e4aae38bdbcc748a4b394cc0
|
||||
url_launcher_macos: fd7894421cd39320dce5f292fc99ea9270b2a313
|
||||
url_launcher_web: e5527357f037c87560776e36436bf2b0288b965c
|
||||
url_launcher_windows: 683d7c283894db8d1914d3ab2223b20cc1ad95d5
|
||||
vibration: b5a33e764c3f609a975b9dca73dce20fdde627dc
|
||||
vibration_web: 0ba303d92469ba34d71c612a228b315908d7fcd9
|
||||
video_player: 9cc823b1d9da7e8427ee591e8438bfbcde500e6e
|
||||
video_player_web: da8cadb8274ed4f8dbee8d7171b420dedd437ce7
|
||||
wakelock: 0d4a70faf8950410735e3f61fb15d517c8a6efc4
|
||||
webview_flutter: d2b4d6c66968ad042ad94cbb791f5b72b4678a96
|
||||
wifi: d7d77c94109e36c4175d845f0a5964eadba71060
|
||||
|
||||
PODFILE CHECKSUM: d94bd40f28772938199c67fcced06ffe96096c14
|
||||
PODFILE CHECKSUM: 5a17be3f8af73a757fa4439c77cf6ab2db29a6e7
|
||||
|
||||
COCOAPODS: 1.10.1
|
||||
|
||||
@ -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<String, dynamic> 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);
|
||||
}
|
||||
@ -0,0 +1,21 @@
|
||||
import 'package:flutter/cupertino.dart';
|
||||
|
||||
class PackagesCustomerRequestModel {
|
||||
|
||||
String email;
|
||||
String phoneNumber;
|
||||
|
||||
PackagesCustomerRequestModel({@required this.email, @required this.phoneNumber});
|
||||
|
||||
Map<String, dynamic> json() {
|
||||
return {
|
||||
"customer" : {
|
||||
"email": email,
|
||||
"addresses": [{
|
||||
"email": email,
|
||||
"phone_number": phoneNumber
|
||||
}]
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
@ -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<String, String> 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",
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@ -0,0 +1,132 @@
|
||||
|
||||
import 'package:diplomaticquarterapp/core/model/packages_offers/responses/PackagesResponseModel.dart';
|
||||
|
||||
class CartProductResponseModel {
|
||||
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;
|
||||
|
||||
CartProductResponseModel({
|
||||
int quantity,
|
||||
String shoppingCartType,
|
||||
int productId,
|
||||
PackagesResponseModel product,
|
||||
int id}){
|
||||
_quantity = quantity;
|
||||
_shoppingCartType = shoppingCartType;
|
||||
_productId = productId;
|
||||
_product = product;
|
||||
_id = id;
|
||||
}
|
||||
|
||||
CartProductResponseModel.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<String, dynamic> toJson() {
|
||||
var map = <String, dynamic>{};
|
||||
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<String, dynamic> toJson() {
|
||||
var map = <String, dynamic>{};
|
||||
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<String, dynamic> toJson() {
|
||||
var map = <String, dynamic>{};
|
||||
map["language_id"] = _languageId;
|
||||
map["localized_name"] = _localizedName;
|
||||
return map;
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,199 @@
|
||||
class PackagesCustomerResponseModel {
|
||||
List<dynamic> _shoppingCartItems;
|
||||
dynamic _billingAddress;
|
||||
dynamic _shippingAddress;
|
||||
List<dynamic> _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<dynamic> _roleIds;
|
||||
int _id;
|
||||
|
||||
List<dynamic> get shoppingCartItems => _shoppingCartItems;
|
||||
dynamic get billingAddress => _billingAddress;
|
||||
dynamic get shippingAddress => _shippingAddress;
|
||||
List<dynamic> 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<dynamic> get roleIds => _roleIds;
|
||||
int get id => _id;
|
||||
|
||||
PackagesCustomerResponseModel({
|
||||
List<dynamic> shoppingCartItems,
|
||||
dynamic billingAddress,
|
||||
dynamic shippingAddress,
|
||||
List<dynamic> 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<dynamic> 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"];
|
||||
_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"];
|
||||
_id = json["id"];
|
||||
|
||||
// if (json["role_ids"] != null) {
|
||||
// _roleIds = [];
|
||||
// json["role_ids"].forEach((v) {
|
||||
// _roleIds.add(dynamic.fromJson(v));
|
||||
// });
|
||||
// }
|
||||
// if (json["addresses"] != null) {
|
||||
// _addresses = [];
|
||||
// json["addresses"].forEach((v) {
|
||||
// _addresses.add(dynamic.fromJson(v));
|
||||
// });
|
||||
// }
|
||||
// if (json["shopping_cart_items"] != null) {
|
||||
// _shoppingCartItems = [];
|
||||
// json["shopping_cart_items"].forEach((v) {
|
||||
// _shoppingCartItems.add(dynamic.fromJson(v));
|
||||
// });
|
||||
// }
|
||||
}
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
var map = <String, dynamic>{};
|
||||
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.toJson()).toList();
|
||||
}
|
||||
map["id"] = _id;
|
||||
return map;
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,80 @@
|
||||
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';
|
||||
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';
|
||||
|
||||
dynamic languageID;
|
||||
|
||||
class ClinicPackagesPage extends StatefulWidget {
|
||||
List<PackagesResponseModel> products;
|
||||
ClinicPackagesPage({@required this.products});
|
||||
|
||||
@override
|
||||
_ClinicPackagesPageState createState() => _ClinicPackagesPageState();
|
||||
|
||||
|
||||
}
|
||||
|
||||
class _ClinicPackagesPageState extends State<ClinicPackagesPage> {
|
||||
List<PackagesResponseModel> get _products => widget.products;
|
||||
|
||||
PackagesViewModel viewModel;
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
|
||||
return BaseView<PackagesViewModel>(
|
||||
allowAny: true,
|
||||
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: 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],)
|
||||
),
|
||||
staggeredTileBuilder: (int index) => StaggeredTile.fit(2),
|
||||
mainAxisSpacing: 20,
|
||||
crossAxisSpacing: 10,
|
||||
)
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,228 @@
|
||||
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/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<StatefulWidget> createState() => OfferAndPackagesDetailState();
|
||||
}
|
||||
|
||||
|
||||
class OfferAndPackagesDetailState extends State<OfferAndPackagesDetail>{
|
||||
|
||||
PackagesViewModel viewModel;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
getLanguageID();
|
||||
|
||||
return BaseView<PackagesViewModel>(
|
||||
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: [
|
||||
Text(
|
||||
"Child Dental Offer",
|
||||
style: TextStyle(
|
||||
fontWeight: FontWeight.normal,
|
||||
color: Colors.black,
|
||||
fontSize: 25
|
||||
)
|
||||
),
|
||||
|
||||
Stack(
|
||||
children: [
|
||||
Text(
|
||||
"200 SAR",
|
||||
style: TextStyle(
|
||||
fontWeight: FontWeight.normal,
|
||||
decoration: TextDecoration.lineThrough,
|
||||
color: Colors.grey,
|
||||
fontSize: 12
|
||||
)
|
||||
),
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(top: 15),
|
||||
child: Text(
|
||||
"894.99 SAR",
|
||||
style: TextStyle(
|
||||
fontWeight: FontWeight.bold,
|
||||
color: Colors.green,
|
||||
fontSize: 18
|
||||
)
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
|
||||
StarRating(
|
||||
size: 20,
|
||||
totalCount: null,
|
||||
totalAverage: 5,
|
||||
forceStars: true),
|
||||
|
||||
|
||||
SizedBox(height: 20,),
|
||||
|
||||
|
||||
Text(
|
||||
"Details",
|
||||
style: TextStyle(
|
||||
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: Text("Detail of offers written here ss"),
|
||||
)
|
||||
),
|
||||
),
|
||||
|
||||
|
||||
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: Text(
|
||||
"Add to Cart",
|
||||
style: TextStyle(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: Text(
|
||||
"Add to Favorites",
|
||||
style: TextStyle(fontSize: 17, color: Colors.red, fontWeight: FontWeight.normal),
|
||||
),
|
||||
onPressed: (){
|
||||
|
||||
},),
|
||||
),
|
||||
|
||||
],
|
||||
),
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
|
||||
],
|
||||
)
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ -0,0 +1,376 @@
|
||||
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/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/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/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<PackagesCartPage> with AfterLayoutMixin<PackagesCartPage>, 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);
|
||||
}
|
||||
|
||||
@override
|
||||
void afterFirstLayout(BuildContext context) {
|
||||
fetchData();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return BaseView<PackagesViewModel>(
|
||||
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);
|
||||
bool success = await viewModel.service.addProductToCart(request, context: context, showLoading: false).catchError((error){
|
||||
utils.Utils.showErrorToast(error);
|
||||
});
|
||||
return success ?? 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: [
|
||||
Text(
|
||||
TranslationBase.of(context).selectPaymentOption,
|
||||
style: TextStyle(
|
||||
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((){});
|
||||
}
|
||||
}
|
||||
|
||||
// /* Payment Footer Widgets */
|
||||
// ---------------------------
|
||||
String _selectedPaymentMethod;
|
||||
Widget _paymentOptions(BuildContext context, Function(String) onSelected) {
|
||||
double height = 22;
|
||||
|
||||
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: Text(
|
||||
TranslationBase.of(context).pharmacyServiceTermsCondition,
|
||||
style: TextStyle(height: 1, 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: [
|
||||
Text('${TranslationBase.of(context).subtotal}: ${'999.9'} ${TranslationBase.of(context).sar}',
|
||||
style: TextStyle(height: 1.5, fontWeight: FontWeight.bold, color: Colors.grey, fontSize: 8)),
|
||||
Text('${TranslationBase.of(context).vat}: ${'14.9'} ${TranslationBase.of(context).sar}', style: TextStyle(height: 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],
|
||||
),
|
||||
),
|
||||
Text(' ${TranslationBase.of(context).total}: 999.99 ${TranslationBase.of(context).sar}',
|
||||
style: TextStyle(height: 1.5, fontWeight: FontWeight.bold, color: Colors.black54, fontSize: 15))
|
||||
],
|
||||
),
|
||||
),
|
||||
Expanded(child: Container()),
|
||||
RaisedButton(
|
||||
child: Text(
|
||||
TranslationBase.of(context).payNow,
|
||||
style: TextStyle(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: Text(
|
||||
"Deleting...",
|
||||
style: TextStyle(
|
||||
fontWeight: FontWeight.normal,
|
||||
fontSize: 15,
|
||||
color: Colors.white,
|
||||
),
|
||||
)),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
@ -0,0 +1,416 @@
|
||||
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/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/Loader/gif_loader_container.dart';
|
||||
import 'package:diplomaticquarterapp/widgets/carousel_indicator/carousel_indicator.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<PackagesHomePage> with AfterLayoutMixin<PackagesHomePage>{
|
||||
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)
|
||||
await viewModel.service.createCustomer(PackagesCustomerRequestModel(email: "zikambrani@gmail.com", phoneNumber: "0500409598"), context: context);
|
||||
|
||||
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).catchError((error) {
|
||||
utils.Utils.showErrorToast(error);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
|
||||
return BaseView<PackagesViewModel>(
|
||||
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: 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
|
||||
Text(
|
||||
"Latest offers",
|
||||
style: TextStyle(
|
||||
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,),
|
||||
|
||||
Text(
|
||||
"Best sellers",
|
||||
style: TextStyle(
|
||||
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<String> 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]
|
||||
]
|
||||
)),
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,188 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
typedef StepperCallbackFuture = Future<bool> 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<StepperView> {
|
||||
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<Color>(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<Color>(Colors.red)
|
||||
)
|
||||
)
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -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<StatefulWidget> createState() {
|
||||
return new _CarouselIndicatorState();
|
||||
}
|
||||
}
|
||||
|
||||
class _CarouselIndicatorState extends State<CarouselIndicator>
|
||||
with TickerProviderStateMixin {
|
||||
/// [Tween] object of type double
|
||||
Tween<double> _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);
|
||||
}
|
||||
}
|
||||
|
||||
@ -0,0 +1,217 @@
|
||||
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/others/StarRating.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
|
||||
bool wide = true;
|
||||
|
||||
class PackagesCartItemCard extends StatefulWidget {
|
||||
final CartProductResponseModel itemModel;
|
||||
final StepperCallbackFuture shouldStepperChangeApply ;
|
||||
|
||||
const PackagesCartItemCard(
|
||||
{
|
||||
@required this.itemModel,
|
||||
@required this.shouldStepperChangeApply,
|
||||
Key key})
|
||||
: super(key: key);
|
||||
|
||||
@override
|
||||
State<StatefulWidget> createState() => PackagesCartItemCardState();
|
||||
}
|
||||
|
||||
class PackagesCartItemCardState extends State<PackagesCartItemCard> {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
|
||||
wide = !wide;
|
||||
return Container(
|
||||
color: Colors.transparent,
|
||||
child: Card(
|
||||
elevation: 3,
|
||||
shadowColor: Colors.grey[100],
|
||||
color: Colors.white,
|
||||
child: Stack(
|
||||
children: [
|
||||
Container(
|
||||
height: 100,
|
||||
child: Row(
|
||||
children: [
|
||||
_image(widget.itemModel.product),
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
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: Text(
|
||||
name,
|
||||
style: TextStyle(
|
||||
fontWeight: FontWeight.normal,
|
||||
color: Colors.black,
|
||||
fontSize: 15))
|
||||
);
|
||||
|
||||
|
||||
Widget _itemPrice(double price, {@required BuildContext context}) => Padding(
|
||||
padding: const EdgeInsets.all(0),
|
||||
child: Text(
|
||||
'${price} ${TranslationBase.of(context).sar}',
|
||||
style: TextStyle(
|
||||
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: Text(
|
||||
'${oldPrice} ${TranslationBase.of(context).sar}',
|
||||
style: TextStyle(
|
||||
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: Text(
|
||||
'${TranslationBase.of(context).totalWithColonRight}',
|
||||
style: TextStyle(
|
||||
fontWeight: FontWeight.bold,
|
||||
color: Colors.grey[600],
|
||||
fontSize: 13
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
|
||||
Widget _totalPrice(double totalPrice, {@required BuildContext context}) => Padding(
|
||||
padding: const EdgeInsets.all(0),
|
||||
child: Text(
|
||||
'${totalPrice.toStringAsFixed(2)} ${TranslationBase.of(context).sar}',
|
||||
style: TextStyle(
|
||||
fontWeight: FontWeight.normal,
|
||||
color: Colors.green,
|
||||
fontSize: 12))
|
||||
);
|
||||
|
||||
@ -0,0 +1,157 @@
|
||||
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/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<StatefulWidget> createState() => PackagesItemCardState();
|
||||
}
|
||||
|
||||
class PackagesItemCardState extends State<PackagesItemCard> {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
wide = !wide;
|
||||
return Directionality(
|
||||
textDirection: TextDirection.rtl,
|
||||
child: Stack(
|
||||
children: [
|
||||
Padding(
|
||||
padding: EdgeInsets.only(
|
||||
left: widget.itemContentPadding,
|
||||
right: widget.itemContentPadding,
|
||||
top: widget.itemContentPadding + 5),
|
||||
child: Container(
|
||||
width: widget.itemWidth,
|
||||
color: Colors.transparent,
|
||||
child: Stack(
|
||||
children: [
|
||||
Column(
|
||||
mainAxisSize: MainAxisSize.max,
|
||||
children: [
|
||||
AspectRatio(
|
||||
aspectRatio:1 / 1,
|
||||
child: applyShadow(
|
||||
child: ClipRRect(
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
child: Utils.loadNetworkImage(
|
||||
url:
|
||||
"https://wallpaperaccess.com/full/30103.jpg",
|
||||
)),
|
||||
)),
|
||||
Text(
|
||||
widget.itemModel.getName(),
|
||||
style: TextStyle(
|
||||
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: [
|
||||
Text(
|
||||
'${widget.itemModel.oldPrice} ${'SAR'}',
|
||||
style: TextStyle(
|
||||
fontWeight: FontWeight.normal,
|
||||
decoration: TextDecoration.lineThrough,
|
||||
color: Colors.grey,
|
||||
fontSize: 12)),
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(top: 8),
|
||||
child: Text(
|
||||
'${widget.itemModel.price} ${'SAR'}',
|
||||
style: TextStyle(
|
||||
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,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue