├── .github
└── workflows
│ ├── appcenter_android.yml
│ └── main.yml
├── .gitignore
├── LICENSE
├── README.md
├── design_sources
├── assets
│ ├── black_shoes.png
│ ├── credit_card.png
│ ├── dress_image_cotton.png
│ ├── dress_image_cotton2.png
│ ├── dress_image_floral.png
│ ├── dress_image_floral2.png
│ ├── dress_image_pattern.png
│ ├── dress_image_pattern2.png
│ ├── girl1_image.png
│ ├── girl2_image.png
│ ├── girl3_image.png
│ ├── gold_shoes.png
│ ├── green_backpack.png
│ ├── launch_icon_android.png
│ ├── launch_icon_ios.png
│ ├── pink_shoes.png
│ ├── product_backpack.png
│ ├── product_scarf.png
│ ├── product_shirt.png
│ ├── red_shoes.png
│ ├── rose_red_shoes.png
│ ├── sale.png
│ ├── silver_shoes.png
│ ├── white_shoes.png
│ └── yellow_shoes.png
├── poster.jpg
└── xd-resources-ecommerce-ui.zip
└── ecommers
├── .gitignore
├── .metadata
├── .vs
├── ProjectSettings.json
├── VSWorkspaceState.json
├── ecommers
│ └── v16
│ │ ├── .suo
│ │ └── Browse.VC.db
└── slnx.sqlite
├── .vscode
└── launch.json
├── analysis_options.yaml
├── android
├── .gitignore
├── app
│ ├── build.gradle
│ └── src
│ │ ├── debug
│ │ └── AndroidManifest.xml
│ │ ├── main
│ │ ├── AndroidManifest.xml
│ │ ├── kotlin
│ │ │ └── com
│ │ │ │ └── example
│ │ │ │ └── ecommers
│ │ │ │ └── MainActivity.kt
│ │ └── res
│ │ │ ├── drawable
│ │ │ └── launch_background.xml
│ │ │ ├── mipmap-hdpi
│ │ │ └── ic_launcher.png
│ │ │ ├── mipmap-mdpi
│ │ │ └── ic_launcher.png
│ │ │ ├── mipmap-xhdpi
│ │ │ └── ic_launcher.png
│ │ │ ├── mipmap-xxhdpi
│ │ │ └── ic_launcher.png
│ │ │ ├── mipmap-xxxhdpi
│ │ │ └── ic_launcher.png
│ │ │ └── values
│ │ │ └── styles.xml
│ │ └── profile
│ │ └── AndroidManifest.xml
├── build.gradle
├── gradle.properties
├── gradle
│ └── wrapper
│ │ └── gradle-wrapper.properties
└── settings.gradle
├── assets
├── add.svg
├── all_order.svg
├── apparel.svg
├── arrow_right.svg
├── back_icon.svg
├── bank_card.svg
├── beauty.svg
├── bell.svg
├── big_credit_card.png
├── check_form.svg
├── close_icon.svg
├── credit_card.svg
├── currency.svg
├── discuss_issue.svg
├── electronics.svg
├── filter_icon.svg
├── finished.svg
├── furniture.svg
├── home.svg
├── invite_friends.svg
├── language.svg
├── loader.flr
├── mail_icon.svg
├── menu_arrow.svg
├── messages.svg
├── notification_discount.svg
├── notification_location_pin.svg
├── notification_order.svg
├── notification_tag.svg
├── notifications.svg
├── password_icon.svg
├── payment.svg
├── pending_payment.svg
├── pending_shipments.svg
├── profile_icon.svg
├── rate_app.svg
├── rate_star.svg
├── remove.svg
├── right_icon.svg
├── sale.svg
├── search.svg
├── share_arrow.svg
├── shield.svg
├── shipping.svg
├── shoes.svg
├── splash_loader.flr
├── stationary.svg
├── success.flr
├── success.svg
├── suggest.svg
├── support.svg
└── warning_icon.svg
├── i18n
└── en-US.json
├── i18nconfig.json
├── ios
├── .gitignore
├── Flutter
│ ├── AppFrameworkInfo.plist
│ ├── Debug.xcconfig
│ └── Release.xcconfig
├── Podfile
├── Runner.xcodeproj
│ ├── project.pbxproj
│ ├── project.xcworkspace
│ │ └── contents.xcworkspacedata
│ └── xcshareddata
│ │ └── xcschemes
│ │ └── Runner.xcscheme
├── Runner.xcworkspace
│ ├── contents.xcworkspacedata
│ └── xcshareddata
│ │ └── IDEWorkspaceChecks.plist
└── Runner
│ ├── AppDelegate.swift
│ ├── Assets.xcassets
│ ├── AppIcon.appiconset
│ │ ├── Contents.json
│ │ ├── Icon-App-1024x1024@1x.png
│ │ ├── Icon-App-20x20@1x.png
│ │ ├── Icon-App-20x20@2x.png
│ │ ├── Icon-App-20x20@3x.png
│ │ ├── Icon-App-29x29@1x.png
│ │ ├── Icon-App-29x29@2x.png
│ │ ├── Icon-App-29x29@3x.png
│ │ ├── Icon-App-40x40@1x.png
│ │ ├── Icon-App-40x40@2x.png
│ │ ├── Icon-App-40x40@3x.png
│ │ ├── Icon-App-50x50@1x.png
│ │ ├── Icon-App-50x50@2x.png
│ │ ├── Icon-App-57x57@1x.png
│ │ ├── Icon-App-57x57@2x.png
│ │ ├── Icon-App-60x60@2x.png
│ │ ├── Icon-App-60x60@3x.png
│ │ ├── Icon-App-72x72@1x.png
│ │ ├── Icon-App-72x72@2x.png
│ │ ├── Icon-App-76x76@1x.png
│ │ ├── Icon-App-76x76@2x.png
│ │ └── Icon-App-83.5x83.5@2x.png
│ └── LaunchImage.imageset
│ │ ├── Contents.json
│ │ ├── LaunchImage.png
│ │ ├── LaunchImage@2x.png
│ │ ├── LaunchImage@3x.png
│ │ └── README.md
│ ├── Base.lproj
│ ├── LaunchScreen.storyboard
│ └── Main.storyboard
│ ├── Info.plist
│ └── Runner-Bridging-Header.h
├── lib
├── core
│ ├── app_services
│ │ ├── app_service.dart
│ │ ├── auth_response.dart
│ │ ├── authorization_service.dart
│ │ ├── category_service.dart
│ │ ├── dialog
│ │ │ ├── confirm_phone_registration.dart
│ │ │ ├── confirmation_dialog.dart
│ │ │ ├── dialog_base.dart
│ │ │ └── dialog_service.dart
│ │ ├── index.dart
│ │ ├── note_service.dart
│ │ ├── paginator.dart
│ │ ├── payment_method_service.dart
│ │ ├── product_service.dart
│ │ ├── profile_service.dart
│ │ └── shipping_address_service.dart
│ ├── cache
│ │ ├── cache_database.dart
│ │ └── index.dart
│ ├── common
│ │ ├── api_defines.dart
│ │ ├── api_query_params.dart
│ │ ├── cache_defines.dart
│ │ ├── categories.dart
│ │ ├── file_manager.dart
│ │ ├── index.dart
│ │ ├── json_serializable_converter.dart
│ │ ├── pages.dart
│ │ ├── user_validator.dart
│ │ └── validator
│ │ │ ├── index.dart
│ │ │ └── shipping_address_validator.dart
│ ├── mixins
│ │ ├── busy_notifier.dart
│ │ ├── index.dart
│ │ └── items_loading_notifier.dart
│ ├── models
│ │ ├── auth_rich_text_span_model.dart
│ │ ├── cache_wrappers
│ │ │ ├── categories_cache_wrapper.dart
│ │ │ └── index.dart
│ │ ├── data_models
│ │ │ ├── category.dart
│ │ │ ├── index.dart
│ │ │ ├── note.dart
│ │ │ ├── product.dart
│ │ │ ├── product_color.dart
│ │ │ ├── product_details.dart
│ │ │ ├── product_model.dart
│ │ │ ├── product_review.dart
│ │ │ └── user.dart
│ │ ├── index.dart
│ │ ├── item_base.dart
│ │ ├── login_model.dart
│ │ ├── notification_model.dart
│ │ ├── order_model.dart
│ │ ├── page_arguments.dart
│ │ ├── payment_method_model.dart
│ │ ├── product_color_model.dart
│ │ ├── product_size_model.dart
│ │ ├── product_skuid_model.dart
│ │ ├── shipping_address_model.dart
│ │ ├── sort_type.dart
│ │ └── user_model.dart
│ ├── provider_models
│ │ ├── auth
│ │ │ ├── forgot_password_provider_model.dart
│ │ │ ├── log_in_provider_model.dart
│ │ │ └── sign_up_provider_model.dart
│ │ ├── base_provider_model.dart
│ │ ├── cart_provider.dart
│ │ ├── categories_provider_model.dart
│ │ ├── home_provider_model.dart
│ │ ├── index.dart
│ │ ├── more_provider_model.dart
│ │ ├── payment_method_provider_model.dart
│ │ ├── product_page_provider_model.dart
│ │ ├── product_tab_provider_model.dart
│ │ ├── products_grid_provder_model.dart
│ │ ├── profile_provider_model.dart
│ │ ├── search_page_provider_model.dart
│ │ ├── search_query_provider_model.dart
│ │ ├── shell_provider_model.dart
│ │ └── shipping_address_provider_model.dart
│ ├── repositories
│ │ ├── cart_repository.dart
│ │ ├── category_data_repository.dart
│ │ ├── index.dart
│ │ ├── payment_method_repository.dart
│ │ ├── repository_base.dart
│ │ └── shipping_address_repository.dart
│ └── services
│ │ ├── api_service.dart
│ │ ├── index.dart
│ │ ├── membership_service.dart
│ │ └── navigation
│ │ └── navigation_service.dart
├── data
│ ├── repository
│ │ ├── common.mappings.dart
│ │ └── firebase_repository.dart
│ └── result.dart
├── extensions
│ ├── index.dart
│ ├── json_extension.dart
│ └── string_extension.dart
├── main.dart
├── shared
│ ├── app_logger.dart
│ ├── dependency_service.dart
│ ├── get_it_extension.dart
│ ├── i18n.dart
│ └── logger.dart
├── ui
│ ├── decorations
│ │ ├── assets.dart
│ │ ├── backgrounds_for_notifications.dart
│ │ ├── branding_colors.dart
│ │ ├── dimens
│ │ │ ├── dimens.dart
│ │ │ ├── font_sizes.dart
│ │ │ ├── index.dart
│ │ │ ├── insets.dart
│ │ │ └── radiuses.dart
│ │ ├── index.dart
│ │ └── theme_provider.dart
│ ├── pages
│ │ ├── add_payment_method_page.dart
│ │ ├── add_shipping_address_page.dart
│ │ ├── authorization
│ │ │ ├── authentication_tab_base.dart
│ │ │ ├── authorization_page.dart
│ │ │ ├── forgot_password_page.dart
│ │ │ ├── index.dart
│ │ │ ├── log_in_page.dart
│ │ │ └── sign_up_page.dart
│ │ ├── base_page.dart
│ │ ├── busy_page.dart
│ │ ├── cart_page.dart
│ │ ├── categories_page.dart
│ │ ├── checkout_page.dart
│ │ ├── closeable_page.dart
│ │ ├── home_page.dart
│ │ ├── index.dart
│ │ ├── more_page.dart
│ │ ├── note_page.dart
│ │ ├── notifications_page.dart
│ │ ├── payment_method_page.dart
│ │ ├── product_page.dart
│ │ ├── products_grid_page.dart
│ │ ├── profile_edit_page.dart
│ │ ├── profile_page.dart
│ │ ├── search_page.dart
│ │ ├── shell_page.dart
│ │ ├── shipping_address_page.dart
│ │ └── success_page.dart
│ ├── utils
│ │ ├── formatter.dart
│ │ └── index.dart
│ └── widgets
│ │ ├── address_card.dart
│ │ ├── authorization
│ │ ├── auth_form.dart
│ │ ├── auth_rich_text.dart
│ │ ├── auth_text_field.dart
│ │ └── index.dart
│ │ ├── back_button.dart
│ │ ├── backgrounded_safe_area.dart
│ │ ├── bank_card.dart
│ │ ├── bottom_navigation
│ │ ├── bottom_navigation_item_model.dart
│ │ ├── bottom_navigation_widget.dart
│ │ ├── buttom_bar_item_icon.dart
│ │ └── consts.dart
│ │ ├── button
│ │ ├── button_base_widget.dart
│ │ ├── index.dart
│ │ ├── primary_button_widget.dart
│ │ └── secondary_button_widget.dart
│ │ ├── cached_image.dart
│ │ ├── carousel_widget.dart
│ │ ├── category
│ │ ├── categories_compact_view.dart
│ │ ├── category_item.dart
│ │ └── sub_category_list.dart
│ │ ├── circle_icon.dart
│ │ ├── credit_card_text_field.dart
│ │ ├── hero_image.dart
│ │ ├── icon_with_badge.dart
│ │ ├── image_card.dart
│ │ ├── index.dart
│ │ ├── items_loader.dart
│ │ ├── menu
│ │ ├── index.dart
│ │ ├── menu_item.dart
│ │ ├── menu_item_model.dart
│ │ └── menu_list.dart
│ │ ├── notes_carousel.dart
│ │ ├── notification
│ │ └── notification_widget.dart
│ │ ├── order
│ │ ├── circle_image.dart
│ │ ├── counter.dart
│ │ ├── index.dart
│ │ ├── order_widget.dart
│ │ ├── small_order_widget.dart
│ │ └── total_order_widget.dart
│ │ ├── product_item
│ │ ├── index.dart
│ │ ├── product_item_base.dart
│ │ ├── product_item_normal.dart
│ │ ├── product_item_small.dart
│ │ └── product_item_wide.dart
│ │ ├── product_latest_grid.dart
│ │ ├── product_page
│ │ ├── details_tab.dart
│ │ ├── header.dart
│ │ ├── index.dart
│ │ ├── product_page_bottom_view.dart
│ │ ├── product_tab.dart
│ │ └── reviews_tab.dart
│ │ ├── products_grid.dart
│ │ ├── profile
│ │ └── profile_image.dart
│ │ ├── progress.dart
│ │ ├── rate_widget.dart
│ │ ├── right_menu_bar
│ │ ├── index.dart
│ │ ├── models
│ │ │ ├── carousel_image.dart
│ │ │ ├── index.dart
│ │ │ ├── right_menu_colors_model.dart
│ │ │ ├── right_menu_item_model.dart
│ │ │ ├── right_menu_price_model.dart
│ │ │ └── right_menu_subtitle_model.dart
│ │ ├── right_menu_item.dart
│ │ ├── right_menu_items_list.dart
│ │ ├── right_menu_widget.dart
│ │ └── subtitle_factory.dart
│ │ ├── search
│ │ ├── container_with_action.dart
│ │ ├── index.dart
│ │ ├── recent_product_list.dart
│ │ ├── search_button.dart
│ │ ├── search_recommended_widget.dart
│ │ └── search_text_field.dart
│ │ ├── shipping_address_text_field.dart
│ │ ├── slide_menu.dart
│ │ └── surface_container.dart
└── web_server
│ ├── config.dart
│ ├── data
│ ├── categories.json
│ ├── notes.json
│ └── products.json
│ ├── data_access
│ ├── products_data_access.dart
│ ├── user_data_access.dart
│ └── validation_model.dart
│ ├── local_database.dart
│ ├── local_server.dart
│ ├── query_params
│ ├── index.dart
│ ├── latest_product_query_params.dart
│ └── product_query_params.dart
│ ├── request_handler.dart
│ └── services
│ ├── authorization_service.dart
│ ├── data_provider.dart
│ └── product_comparator.dart
├── pubspec.yaml
├── runner
└── test
└── widget_test.dart
/.github/workflows/appcenter_android.yml:
--------------------------------------------------------------------------------
1 | name: Build and push Android
2 |
3 | on:
4 | push:
5 | branches:
6 | - master
7 |
8 | jobs:
9 | build:
10 |
11 | runs-on: ubuntu-latest
12 |
13 | steps:
14 | - uses: actions/checkout@v1
15 | - uses: actions/setup-java@v1
16 | with:
17 | java-version: '12.x'
18 | - name: Cache Flutter Dependencies
19 | uses: actions/cache@v1
20 | with:
21 | path: /opt/hostedtoolcache/flutter
22 | key: ${{ runner.os }}-flutter
23 | - uses: subosito/flutter-action@v1
24 | with:
25 | channel: 'dev' # or: 'dev' or 'beta'
26 | - name: Install dependencies
27 | run: flutter pub get
28 | working-directory: ecommers
29 | - name: generate files
30 | run: flutter packages pub run build_runner build --delete-conflicting-outputs
31 | working-directory: ecommers
32 | - name: Build Android app
33 | run: flutter build apk --target-platform android-arm
34 | working-directory: ecommers
35 | - name: upload artefact to App Center
36 | uses: wzieba/AppCenter-Github-Action@v1.0.0
37 | with:
38 | appName: EPAM/Flutter-eCom-Android
39 | token: ${{secrets.AM_android_appcenter}}
40 | group: Testers
41 | file: ecommers/build/app/outputs/apk/release/app-release.apk
42 |
--------------------------------------------------------------------------------
/.github/workflows/main.yml:
--------------------------------------------------------------------------------
1 | name: build and check Android
2 |
3 | on:
4 | pull_request:
5 | branches:
6 | - dev
7 | - master
8 |
9 | jobs:
10 | build:
11 |
12 | runs-on: ubuntu-latest
13 |
14 | steps:
15 | - uses: actions/checkout@v2.1.0
16 | - name: setup google services json
17 | uses: DamianReeves/write-file-action@v1.0
18 | with:
19 | path: /home/runner/work/flutter-ecommers-sample/flutter-ecommers-sample/ecommers/android/app/google-services.json
20 | contents:
21 | ${{secrets.android_google_services}}
22 | write-mode: overwrite
23 | - uses: actions/setup-java@v1
24 | with:
25 | java-version: '12.x'
26 | - name: Cache Flutter Dependencies
27 | uses: actions/cache@v1
28 | with:
29 | path: /opt/hostedtoolcache/flutter
30 | key: ${{ runner.os }}-flutter
31 | - uses: subosito/flutter-action@v1
32 | with:
33 | channel: 'dev' # or: 'dev' or 'beta'
34 | - name: Install dependencies
35 | run: flutter pub get
36 | working-directory: ecommers
37 | - name: generate files
38 | run: flutter packages pub run build_runner build --delete-conflicting-outputs
39 | working-directory: ecommers
40 | - name: Build Android app
41 | run: flutter build apk --target-platform android-arm
42 | working-directory: ecommers
43 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | [](https://github.com/epam-cross-platform-lab/flutter-ecommers-sample)
2 |
3 | # Cloth Shop - Flutter [](https://github.com/epam-cross-platform-lab/flutter-ecommers-sample) [](https://github.com/mkiisoft/FlutterMovieTrends)
4 |
5 | Cloth Shop it's an example using Flutter for Android and iOS.
6 |
7 | ## About
8 |
9 | This repository serves the source code for the Ecommers sample mobile app for iOS and Android.
10 |
11 | ## Getting Started
12 |
13 | 1. Ensure Flutter SDK is installed correctly, ``flutter doctor``
14 | 2. Fetch dependent Dart/Flutter packages, ``flutter pub get``
15 | 3. Due to we use compile-time JSON serialization and API client *code generation*, run ``flutter packages pub run build_runner build --delete-conflicting-outputs`` which recreates all necessary files
16 | 4. Install https://marketplace.visualstudio.com/items?itemName=esskar.vscode-flutter-i18n-json extension for updating json strings
17 | 5. Add GoogleService-info.plist to ios/Runner and update CFBundleURLTypes *id* in Info.plist
18 | 6. Add Google-Service.json to android/app
19 |
20 | # Features
21 |
22 | * Firebase (under development)
23 | * Login Screen
24 | * Loading Screen
25 | * Grid and List views
26 | * Nested Scroll views
27 | * Pagination (under development)
28 | * Local http server
29 | * Async tasks
30 | * Custom Views
31 | * Intent Uri launcher (under development)
32 |
33 | ## Getting Started
34 |
35 | For help getting started with Flutter, view our online
36 | [documentation](https://flutter.io/).
37 |
38 | # © 2020 Epam Systems
39 |
--------------------------------------------------------------------------------
/design_sources/assets/black_shoes.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/epam-cross-platform-lab/flutter-ecommers-sample/ad9fac52e53d22514834aee447b602cc0b775148/design_sources/assets/black_shoes.png
--------------------------------------------------------------------------------
/design_sources/assets/credit_card.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/epam-cross-platform-lab/flutter-ecommers-sample/ad9fac52e53d22514834aee447b602cc0b775148/design_sources/assets/credit_card.png
--------------------------------------------------------------------------------
/design_sources/assets/dress_image_cotton.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/epam-cross-platform-lab/flutter-ecommers-sample/ad9fac52e53d22514834aee447b602cc0b775148/design_sources/assets/dress_image_cotton.png
--------------------------------------------------------------------------------
/design_sources/assets/dress_image_cotton2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/epam-cross-platform-lab/flutter-ecommers-sample/ad9fac52e53d22514834aee447b602cc0b775148/design_sources/assets/dress_image_cotton2.png
--------------------------------------------------------------------------------
/design_sources/assets/dress_image_floral.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/epam-cross-platform-lab/flutter-ecommers-sample/ad9fac52e53d22514834aee447b602cc0b775148/design_sources/assets/dress_image_floral.png
--------------------------------------------------------------------------------
/design_sources/assets/dress_image_floral2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/epam-cross-platform-lab/flutter-ecommers-sample/ad9fac52e53d22514834aee447b602cc0b775148/design_sources/assets/dress_image_floral2.png
--------------------------------------------------------------------------------
/design_sources/assets/dress_image_pattern.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/epam-cross-platform-lab/flutter-ecommers-sample/ad9fac52e53d22514834aee447b602cc0b775148/design_sources/assets/dress_image_pattern.png
--------------------------------------------------------------------------------
/design_sources/assets/dress_image_pattern2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/epam-cross-platform-lab/flutter-ecommers-sample/ad9fac52e53d22514834aee447b602cc0b775148/design_sources/assets/dress_image_pattern2.png
--------------------------------------------------------------------------------
/design_sources/assets/girl1_image.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/epam-cross-platform-lab/flutter-ecommers-sample/ad9fac52e53d22514834aee447b602cc0b775148/design_sources/assets/girl1_image.png
--------------------------------------------------------------------------------
/design_sources/assets/girl2_image.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/epam-cross-platform-lab/flutter-ecommers-sample/ad9fac52e53d22514834aee447b602cc0b775148/design_sources/assets/girl2_image.png
--------------------------------------------------------------------------------
/design_sources/assets/girl3_image.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/epam-cross-platform-lab/flutter-ecommers-sample/ad9fac52e53d22514834aee447b602cc0b775148/design_sources/assets/girl3_image.png
--------------------------------------------------------------------------------
/design_sources/assets/gold_shoes.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/epam-cross-platform-lab/flutter-ecommers-sample/ad9fac52e53d22514834aee447b602cc0b775148/design_sources/assets/gold_shoes.png
--------------------------------------------------------------------------------
/design_sources/assets/green_backpack.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/epam-cross-platform-lab/flutter-ecommers-sample/ad9fac52e53d22514834aee447b602cc0b775148/design_sources/assets/green_backpack.png
--------------------------------------------------------------------------------
/design_sources/assets/launch_icon_android.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/epam-cross-platform-lab/flutter-ecommers-sample/ad9fac52e53d22514834aee447b602cc0b775148/design_sources/assets/launch_icon_android.png
--------------------------------------------------------------------------------
/design_sources/assets/launch_icon_ios.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/epam-cross-platform-lab/flutter-ecommers-sample/ad9fac52e53d22514834aee447b602cc0b775148/design_sources/assets/launch_icon_ios.png
--------------------------------------------------------------------------------
/design_sources/assets/pink_shoes.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/epam-cross-platform-lab/flutter-ecommers-sample/ad9fac52e53d22514834aee447b602cc0b775148/design_sources/assets/pink_shoes.png
--------------------------------------------------------------------------------
/design_sources/assets/product_backpack.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/epam-cross-platform-lab/flutter-ecommers-sample/ad9fac52e53d22514834aee447b602cc0b775148/design_sources/assets/product_backpack.png
--------------------------------------------------------------------------------
/design_sources/assets/product_scarf.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/epam-cross-platform-lab/flutter-ecommers-sample/ad9fac52e53d22514834aee447b602cc0b775148/design_sources/assets/product_scarf.png
--------------------------------------------------------------------------------
/design_sources/assets/product_shirt.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/epam-cross-platform-lab/flutter-ecommers-sample/ad9fac52e53d22514834aee447b602cc0b775148/design_sources/assets/product_shirt.png
--------------------------------------------------------------------------------
/design_sources/assets/red_shoes.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/epam-cross-platform-lab/flutter-ecommers-sample/ad9fac52e53d22514834aee447b602cc0b775148/design_sources/assets/red_shoes.png
--------------------------------------------------------------------------------
/design_sources/assets/rose_red_shoes.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/epam-cross-platform-lab/flutter-ecommers-sample/ad9fac52e53d22514834aee447b602cc0b775148/design_sources/assets/rose_red_shoes.png
--------------------------------------------------------------------------------
/design_sources/assets/sale.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/epam-cross-platform-lab/flutter-ecommers-sample/ad9fac52e53d22514834aee447b602cc0b775148/design_sources/assets/sale.png
--------------------------------------------------------------------------------
/design_sources/assets/silver_shoes.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/epam-cross-platform-lab/flutter-ecommers-sample/ad9fac52e53d22514834aee447b602cc0b775148/design_sources/assets/silver_shoes.png
--------------------------------------------------------------------------------
/design_sources/assets/white_shoes.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/epam-cross-platform-lab/flutter-ecommers-sample/ad9fac52e53d22514834aee447b602cc0b775148/design_sources/assets/white_shoes.png
--------------------------------------------------------------------------------
/design_sources/assets/yellow_shoes.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/epam-cross-platform-lab/flutter-ecommers-sample/ad9fac52e53d22514834aee447b602cc0b775148/design_sources/assets/yellow_shoes.png
--------------------------------------------------------------------------------
/design_sources/poster.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/epam-cross-platform-lab/flutter-ecommers-sample/ad9fac52e53d22514834aee447b602cc0b775148/design_sources/poster.jpg
--------------------------------------------------------------------------------
/design_sources/xd-resources-ecommerce-ui.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/epam-cross-platform-lab/flutter-ecommers-sample/ad9fac52e53d22514834aee447b602cc0b775148/design_sources/xd-resources-ecommerce-ui.zip
--------------------------------------------------------------------------------
/ecommers/.gitignore:
--------------------------------------------------------------------------------
1 | # Miscellaneous
2 | *.class
3 | *.log
4 | *.pyc
5 | *.swp
6 | .DS_Store
7 | .atom/
8 | .buildlog/
9 | .history
10 | .svn/
11 |
12 | # IntelliJ related
13 | *.iml
14 | *.ipr
15 | *.iws
16 | .idea/
17 |
18 | # The .vscode folder contains launch configuration and tasks you configure in
19 | # VS Code which you may wish to be included in version control, so this line
20 | # is commented out by default.
21 | #.vscode/
22 |
23 | # Flutter/Dart/Pub related
24 | **/doc/api/
25 | .dart_tool/
26 | .flutter-plugins
27 | .flutter-plugins-dependencies
28 | .packages
29 | .pub-cache/
30 | .pub/
31 | /build/
32 |
33 | # Web related
34 | lib/generated_plugin_registrant.dart
35 |
36 | # Exceptions to above rules.
37 | !/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages
38 |
--------------------------------------------------------------------------------
/ecommers/.metadata:
--------------------------------------------------------------------------------
1 | # This file tracks properties of this Flutter project.
2 | # Used by Flutter tool to assess capabilities and perform upgrades etc.
3 | #
4 | # This file should be version controlled and should not be manually edited.
5 |
6 | version:
7 | revision: fabf4e3d0d311181178d2c601d29a2f739ea543a
8 | channel: master
9 |
10 | project_type: app
11 |
--------------------------------------------------------------------------------
/ecommers/.vs/ProjectSettings.json:
--------------------------------------------------------------------------------
1 | {
2 | "CurrentProjectSetting": "No Configurations"
3 | }
--------------------------------------------------------------------------------
/ecommers/.vs/VSWorkspaceState.json:
--------------------------------------------------------------------------------
1 | {
2 | "ExpandedNodes": [
3 | ""
4 | ],
5 | "PreviewInSolutionExplorer": false
6 | }
--------------------------------------------------------------------------------
/ecommers/.vs/ecommers/v16/.suo:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/epam-cross-platform-lab/flutter-ecommers-sample/ad9fac52e53d22514834aee447b602cc0b775148/ecommers/.vs/ecommers/v16/.suo
--------------------------------------------------------------------------------
/ecommers/.vs/ecommers/v16/Browse.VC.db:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/epam-cross-platform-lab/flutter-ecommers-sample/ad9fac52e53d22514834aee447b602cc0b775148/ecommers/.vs/ecommers/v16/Browse.VC.db
--------------------------------------------------------------------------------
/ecommers/.vs/slnx.sqlite:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/epam-cross-platform-lab/flutter-ecommers-sample/ad9fac52e53d22514834aee447b602cc0b775148/ecommers/.vs/slnx.sqlite
--------------------------------------------------------------------------------
/ecommers/.vscode/launch.json:
--------------------------------------------------------------------------------
1 | {
2 | // Use IntelliSense to learn about possible attributes.
3 | // Hover to view descriptions of existing attributes.
4 | // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
5 | "version": "0.2.0",
6 | "configurations": [
7 | {
8 | "name": "Flutter",
9 | "request": "launch",
10 | "type": "dart"
11 | }
12 | ]
13 | }
--------------------------------------------------------------------------------
/ecommers/analysis_options.yaml:
--------------------------------------------------------------------------------
1 | include: package:lint/analysis_options.yaml
2 |
3 | analyzer:
4 | exclude:
5 | - lib/generated/i18n.dart
6 | - lib/**.g.dart
7 | - lib/**.chopper.dart
8 | errors:
9 | todo: warning
10 |
11 | linter:
12 | rules:
13 | prefer_single_quotes: true
14 | avoid_classes_with_only_static_members: false
--------------------------------------------------------------------------------
/ecommers/android/.gitignore:
--------------------------------------------------------------------------------
1 | gradle-wrapper.jar
2 | /.gradle
3 | /captures/
4 | /gradlew
5 | /gradlew.bat
6 | /local.properties
7 | GeneratedPluginRegistrant.java
8 |
--------------------------------------------------------------------------------
/ecommers/android/app/src/debug/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/ecommers/android/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
8 |
12 |
19 |
20 |
21 |
22 |
23 |
24 |
26 |
29 |
30 |
31 |
--------------------------------------------------------------------------------
/ecommers/android/app/src/main/kotlin/com/example/ecommers/MainActivity.kt:
--------------------------------------------------------------------------------
1 | package com.ecommers.sample
2 |
3 | import androidx.annotation.NonNull;
4 | import io.flutter.embedding.android.FlutterActivity
5 | import io.flutter.embedding.engine.FlutterEngine
6 | import io.flutter.plugins.GeneratedPluginRegistrant
7 |
8 | class MainActivity: FlutterActivity() {
9 | override fun configureFlutterEngine(@NonNull flutterEngine: FlutterEngine) {
10 | GeneratedPluginRegistrant.registerWith(flutterEngine);
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/ecommers/android/app/src/main/res/drawable/launch_background.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
12 |
13 |
--------------------------------------------------------------------------------
/ecommers/android/app/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/epam-cross-platform-lab/flutter-ecommers-sample/ad9fac52e53d22514834aee447b602cc0b775148/ecommers/android/app/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/ecommers/android/app/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/epam-cross-platform-lab/flutter-ecommers-sample/ad9fac52e53d22514834aee447b602cc0b775148/ecommers/android/app/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/ecommers/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/epam-cross-platform-lab/flutter-ecommers-sample/ad9fac52e53d22514834aee447b602cc0b775148/ecommers/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/ecommers/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/epam-cross-platform-lab/flutter-ecommers-sample/ad9fac52e53d22514834aee447b602cc0b775148/ecommers/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/ecommers/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/epam-cross-platform-lab/flutter-ecommers-sample/ad9fac52e53d22514834aee447b602cc0b775148/ecommers/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/ecommers/android/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
8 |
9 |
--------------------------------------------------------------------------------
/ecommers/android/app/src/profile/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/ecommers/android/build.gradle:
--------------------------------------------------------------------------------
1 | buildscript {
2 | ext.kotlin_version = '1.3.50'
3 | repositories {
4 | google()
5 | jcenter()
6 | maven {
7 | url 'https://maven.fabric.io/public'
8 | }
9 | }
10 |
11 | dependencies {
12 | classpath 'com.android.tools.build:gradle:3.5.3'
13 | classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
14 | classpath 'com.google.gms:google-services:4.3.3'
15 | classpath 'io.fabric.tools:gradle:1.26.1'
16 | }
17 | }
18 |
19 | allprojects {
20 | repositories {
21 | google()
22 | jcenter()
23 | }
24 | }
25 |
26 | rootProject.buildDir = '../build'
27 | subprojects {
28 | project.buildDir = "${rootProject.buildDir}/${project.name}"
29 | }
30 | subprojects {
31 | project.evaluationDependsOn(':app')
32 | }
33 |
34 | task clean(type: Delete) {
35 | delete rootProject.buildDir
36 | }
37 |
--------------------------------------------------------------------------------
/ecommers/android/gradle.properties:
--------------------------------------------------------------------------------
1 | org.gradle.jvmargs=-Xmx1536M
2 | android.enableR8=true
3 | android.useAndroidX=true
4 | android.enableJetifier=true
5 |
--------------------------------------------------------------------------------
/ecommers/android/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Fri Jun 23 08:50:38 CEST 2017
2 | distributionBase=GRADLE_USER_HOME
3 | distributionPath=wrapper/dists
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 | distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.2-all.zip
7 |
--------------------------------------------------------------------------------
/ecommers/android/settings.gradle:
--------------------------------------------------------------------------------
1 | include ':app'
2 |
3 | def flutterProjectRoot = rootProject.projectDir.parentFile.toPath()
4 |
5 | def plugins = new Properties()
6 | def pluginsFile = new File(flutterProjectRoot.toFile(), '.flutter-plugins')
7 | if (pluginsFile.exists()) {
8 | pluginsFile.withReader('UTF-8') { reader -> plugins.load(reader) }
9 | }
10 |
11 | plugins.each { name, path ->
12 | def pluginDirectory = flutterProjectRoot.resolve(path).resolve('android').toFile()
13 | include ":$name"
14 | project(":$name").projectDir = pluginDirectory
15 | }
16 |
--------------------------------------------------------------------------------
/ecommers/assets/all_order.svg:
--------------------------------------------------------------------------------
1 |
13 |
--------------------------------------------------------------------------------
/ecommers/assets/apparel.svg:
--------------------------------------------------------------------------------
1 |
10 |
--------------------------------------------------------------------------------
/ecommers/assets/arrow_right.svg:
--------------------------------------------------------------------------------
1 |
10 |
--------------------------------------------------------------------------------
/ecommers/assets/back_icon.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/ecommers/assets/beauty.svg:
--------------------------------------------------------------------------------
1 |
10 |
--------------------------------------------------------------------------------
/ecommers/assets/bell.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/ecommers/assets/big_credit_card.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/epam-cross-platform-lab/flutter-ecommers-sample/ad9fac52e53d22514834aee447b602cc0b775148/ecommers/assets/big_credit_card.png
--------------------------------------------------------------------------------
/ecommers/assets/check_form.svg:
--------------------------------------------------------------------------------
1 |
6 |
--------------------------------------------------------------------------------
/ecommers/assets/close_icon.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/ecommers/assets/credit_card.svg:
--------------------------------------------------------------------------------
1 |
10 |
--------------------------------------------------------------------------------
/ecommers/assets/currency.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/ecommers/assets/discuss_issue.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/ecommers/assets/electronics.svg:
--------------------------------------------------------------------------------
1 |
10 |
--------------------------------------------------------------------------------
/ecommers/assets/filter_icon.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/ecommers/assets/finished.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/ecommers/assets/furniture.svg:
--------------------------------------------------------------------------------
1 |
13 |
--------------------------------------------------------------------------------
/ecommers/assets/home.svg:
--------------------------------------------------------------------------------
1 |
10 |
--------------------------------------------------------------------------------
/ecommers/assets/invite_friends.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/ecommers/assets/language.svg:
--------------------------------------------------------------------------------
1 |
5 |
--------------------------------------------------------------------------------
/ecommers/assets/loader.flr:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/epam-cross-platform-lab/flutter-ecommers-sample/ad9fac52e53d22514834aee447b602cc0b775148/ecommers/assets/loader.flr
--------------------------------------------------------------------------------
/ecommers/assets/mail_icon.svg:
--------------------------------------------------------------------------------
1 |
15 |
--------------------------------------------------------------------------------
/ecommers/assets/notification_location_pin.svg:
--------------------------------------------------------------------------------
1 |
6 |
--------------------------------------------------------------------------------
/ecommers/assets/notification_order.svg:
--------------------------------------------------------------------------------
1 |
15 |
--------------------------------------------------------------------------------
/ecommers/assets/notification_tag.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/ecommers/assets/notifications.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/ecommers/assets/password_icon.svg:
--------------------------------------------------------------------------------
1 |
14 |
--------------------------------------------------------------------------------
/ecommers/assets/pending_payment.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/ecommers/assets/pending_shipments.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/ecommers/assets/profile_icon.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/ecommers/assets/rate_app.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/ecommers/assets/rate_star.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/ecommers/assets/remove.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/ecommers/assets/right_icon.svg:
--------------------------------------------------------------------------------
1 |
13 |
--------------------------------------------------------------------------------
/ecommers/assets/sale.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/ecommers/assets/search.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/ecommers/assets/share_arrow.svg:
--------------------------------------------------------------------------------
1 |
8 |
--------------------------------------------------------------------------------
/ecommers/assets/shield.svg:
--------------------------------------------------------------------------------
1 |
8 |
--------------------------------------------------------------------------------
/ecommers/assets/shipping.svg:
--------------------------------------------------------------------------------
1 |
8 |
--------------------------------------------------------------------------------
/ecommers/assets/shoes.svg:
--------------------------------------------------------------------------------
1 |
10 |
--------------------------------------------------------------------------------
/ecommers/assets/splash_loader.flr:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/epam-cross-platform-lab/flutter-ecommers-sample/ad9fac52e53d22514834aee447b602cc0b775148/ecommers/assets/splash_loader.flr
--------------------------------------------------------------------------------
/ecommers/assets/stationary.svg:
--------------------------------------------------------------------------------
1 |
10 |
--------------------------------------------------------------------------------
/ecommers/assets/success.flr:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/epam-cross-platform-lab/flutter-ecommers-sample/ad9fac52e53d22514834aee447b602cc0b775148/ecommers/assets/success.flr
--------------------------------------------------------------------------------
/ecommers/assets/success.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/ecommers/assets/suggest.svg:
--------------------------------------------------------------------------------
1 |
15 |
--------------------------------------------------------------------------------
/ecommers/assets/support.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/ecommers/assets/warning_icon.svg:
--------------------------------------------------------------------------------
1 |
2 |
15 |
--------------------------------------------------------------------------------
/ecommers/i18nconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "defaultLocale": "en-US",
3 | "locales": [
4 | "en-US"
5 | ],
6 | "localePath": "i18n",
7 | "generatedPath": "lib/shared",
8 | "ltr": [
9 | "en-US"
10 | ],
11 | "rtl": []
12 | }
--------------------------------------------------------------------------------
/ecommers/ios/.gitignore:
--------------------------------------------------------------------------------
1 | *.mode1v3
2 | *.mode2v3
3 | *.moved-aside
4 | *.pbxuser
5 | *.perspectivev3
6 | **/*sync/
7 | .sconsign.dblite
8 | .tags*
9 | **/.vagrant/
10 | **/DerivedData/
11 | Icon?
12 | **/Pods/
13 | **/.symlinks/
14 | profile
15 | xcuserdata
16 | **/.generated/
17 | Flutter/App.framework
18 | Flutter/Flutter.framework
19 | Flutter/Flutter.podspec
20 | Flutter/Generated.xcconfig
21 | Flutter/app.flx
22 | Flutter/app.zip
23 | Flutter/flutter_assets/
24 | Flutter/flutter_export_environment.sh
25 | ServiceDefinitions.json
26 | Runner/GeneratedPluginRegistrant.*
27 |
28 | # Exceptions to above rules.
29 | !default.mode1v3
30 | !default.mode2v3
31 | !default.pbxuser
32 | !default.perspectivev3
33 |
--------------------------------------------------------------------------------
/ecommers/ios/Flutter/AppFrameworkInfo.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | $(DEVELOPMENT_LANGUAGE)
7 | CFBundleExecutable
8 | App
9 | CFBundleIdentifier
10 | io.flutter.flutter.app
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | App
15 | CFBundlePackageType
16 | FMWK
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | 1.0
23 | MinimumOSVersion
24 | 8.0
25 |
26 |
27 |
--------------------------------------------------------------------------------
/ecommers/ios/Flutter/Debug.xcconfig:
--------------------------------------------------------------------------------
1 | #include "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"
2 | #include "Generated.xcconfig"
3 |
--------------------------------------------------------------------------------
/ecommers/ios/Flutter/Release.xcconfig:
--------------------------------------------------------------------------------
1 | #include "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"
2 | #include "Generated.xcconfig"
3 |
--------------------------------------------------------------------------------
/ecommers/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/ecommers/ios/Runner.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/ecommers/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/ecommers/ios/Runner/AppDelegate.swift:
--------------------------------------------------------------------------------
1 | import UIKit
2 | import Flutter
3 |
4 | @UIApplicationMain
5 | @objc class AppDelegate: FlutterAppDelegate {
6 | override func application(
7 | _ application: UIApplication,
8 | didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
9 | ) -> Bool {
10 | GeneratedPluginRegistrant.register(with: self)
11 | return super.application(application, didFinishLaunchingWithOptions: launchOptions)
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/ecommers/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/epam-cross-platform-lab/flutter-ecommers-sample/ad9fac52e53d22514834aee447b602cc0b775148/ecommers/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png
--------------------------------------------------------------------------------
/ecommers/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/epam-cross-platform-lab/flutter-ecommers-sample/ad9fac52e53d22514834aee447b602cc0b775148/ecommers/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png
--------------------------------------------------------------------------------
/ecommers/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/epam-cross-platform-lab/flutter-ecommers-sample/ad9fac52e53d22514834aee447b602cc0b775148/ecommers/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png
--------------------------------------------------------------------------------
/ecommers/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/epam-cross-platform-lab/flutter-ecommers-sample/ad9fac52e53d22514834aee447b602cc0b775148/ecommers/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png
--------------------------------------------------------------------------------
/ecommers/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/epam-cross-platform-lab/flutter-ecommers-sample/ad9fac52e53d22514834aee447b602cc0b775148/ecommers/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png
--------------------------------------------------------------------------------
/ecommers/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/epam-cross-platform-lab/flutter-ecommers-sample/ad9fac52e53d22514834aee447b602cc0b775148/ecommers/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png
--------------------------------------------------------------------------------
/ecommers/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/epam-cross-platform-lab/flutter-ecommers-sample/ad9fac52e53d22514834aee447b602cc0b775148/ecommers/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png
--------------------------------------------------------------------------------
/ecommers/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/epam-cross-platform-lab/flutter-ecommers-sample/ad9fac52e53d22514834aee447b602cc0b775148/ecommers/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png
--------------------------------------------------------------------------------
/ecommers/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/epam-cross-platform-lab/flutter-ecommers-sample/ad9fac52e53d22514834aee447b602cc0b775148/ecommers/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png
--------------------------------------------------------------------------------
/ecommers/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/epam-cross-platform-lab/flutter-ecommers-sample/ad9fac52e53d22514834aee447b602cc0b775148/ecommers/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png
--------------------------------------------------------------------------------
/ecommers/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-50x50@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/epam-cross-platform-lab/flutter-ecommers-sample/ad9fac52e53d22514834aee447b602cc0b775148/ecommers/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-50x50@1x.png
--------------------------------------------------------------------------------
/ecommers/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-50x50@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/epam-cross-platform-lab/flutter-ecommers-sample/ad9fac52e53d22514834aee447b602cc0b775148/ecommers/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-50x50@2x.png
--------------------------------------------------------------------------------
/ecommers/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-57x57@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/epam-cross-platform-lab/flutter-ecommers-sample/ad9fac52e53d22514834aee447b602cc0b775148/ecommers/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-57x57@1x.png
--------------------------------------------------------------------------------
/ecommers/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-57x57@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/epam-cross-platform-lab/flutter-ecommers-sample/ad9fac52e53d22514834aee447b602cc0b775148/ecommers/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-57x57@2x.png
--------------------------------------------------------------------------------
/ecommers/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/epam-cross-platform-lab/flutter-ecommers-sample/ad9fac52e53d22514834aee447b602cc0b775148/ecommers/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png
--------------------------------------------------------------------------------
/ecommers/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/epam-cross-platform-lab/flutter-ecommers-sample/ad9fac52e53d22514834aee447b602cc0b775148/ecommers/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png
--------------------------------------------------------------------------------
/ecommers/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-72x72@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/epam-cross-platform-lab/flutter-ecommers-sample/ad9fac52e53d22514834aee447b602cc0b775148/ecommers/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-72x72@1x.png
--------------------------------------------------------------------------------
/ecommers/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-72x72@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/epam-cross-platform-lab/flutter-ecommers-sample/ad9fac52e53d22514834aee447b602cc0b775148/ecommers/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-72x72@2x.png
--------------------------------------------------------------------------------
/ecommers/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/epam-cross-platform-lab/flutter-ecommers-sample/ad9fac52e53d22514834aee447b602cc0b775148/ecommers/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png
--------------------------------------------------------------------------------
/ecommers/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/epam-cross-platform-lab/flutter-ecommers-sample/ad9fac52e53d22514834aee447b602cc0b775148/ecommers/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png
--------------------------------------------------------------------------------
/ecommers/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/epam-cross-platform-lab/flutter-ecommers-sample/ad9fac52e53d22514834aee447b602cc0b775148/ecommers/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png
--------------------------------------------------------------------------------
/ecommers/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "LaunchImage.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "filename" : "LaunchImage@2x.png",
11 | "scale" : "2x"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "filename" : "LaunchImage@3x.png",
16 | "scale" : "3x"
17 | }
18 | ],
19 | "info" : {
20 | "version" : 1,
21 | "author" : "xcode"
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/ecommers/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/epam-cross-platform-lab/flutter-ecommers-sample/ad9fac52e53d22514834aee447b602cc0b775148/ecommers/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png
--------------------------------------------------------------------------------
/ecommers/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/epam-cross-platform-lab/flutter-ecommers-sample/ad9fac52e53d22514834aee447b602cc0b775148/ecommers/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png
--------------------------------------------------------------------------------
/ecommers/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/epam-cross-platform-lab/flutter-ecommers-sample/ad9fac52e53d22514834aee447b602cc0b775148/ecommers/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png
--------------------------------------------------------------------------------
/ecommers/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md:
--------------------------------------------------------------------------------
1 | # Launch Screen Assets
2 |
3 | You can customize the launch screen with your own desired assets by replacing the image files in this directory.
4 |
5 | You can also do it by opening your Flutter project's Xcode project with `open ios/Runner.xcworkspace`, selecting `Runner/Assets.xcassets` in the Project Navigator and dropping in the desired images.
--------------------------------------------------------------------------------
/ecommers/ios/Runner/Base.lproj/Main.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/ecommers/ios/Runner/Runner-Bridging-Header.h:
--------------------------------------------------------------------------------
1 | #import "GeneratedPluginRegistrant.h"
2 |
--------------------------------------------------------------------------------
/ecommers/lib/core/app_services/app_service.dart:
--------------------------------------------------------------------------------
1 | import 'package:chopper/chopper.dart';
2 |
3 | class AppService {
4 | Future fetchData(
5 | Future> Function() requestFunction) async {
6 | final response = await requestFunction();
7 |
8 | if (response.isSuccessful) {
9 | return response.body;
10 | }
11 |
12 | return null;
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/ecommers/lib/core/app_services/auth_response.dart:
--------------------------------------------------------------------------------
1 | class AuthResponse {
2 | final bool isSuccessful;
3 | final String error;
4 |
5 | AuthResponse({this.isSuccessful, this.error});
6 | }
7 |
--------------------------------------------------------------------------------
/ecommers/lib/core/app_services/authorization_service.dart:
--------------------------------------------------------------------------------
1 | import 'dart:async';
2 |
3 | import 'package:ecommers/data/repository/firebase_repository.dart';
4 | import 'package:ecommers/shared/dependency_service.dart';
5 |
6 | class AuthorizationService {
7 | Future signInWithEmailAndPassword(
8 | String email, String password) async {
9 | final result =
10 | await authRepository.signInWithEmailAndPassword(email, password);
11 |
12 | if (result.status == AuthStatus.success) {
13 | membershipService.refresh(result.data);
14 | }
15 |
16 | return result.status;
17 | }
18 |
19 | Future updateUserName(String username) {
20 | return authRepository.updateUsername(username);
21 | }
22 |
23 | Future signInWithPhone(String phone) async {
24 | final result = await authRepository.signInWithPhoneNumber(phone);
25 | if (result.status == AuthStatus.success) {
26 | membershipService.refresh(result.data);
27 | }
28 |
29 | return result.status;
30 | }
31 |
32 | Future createUserWithEmailAndPassword(
33 | String email, String password) async {
34 | final result =
35 | await authRepository.registerWithEmailAndPassword(email, password);
36 | if (result.status == AuthStatus.success) {
37 | membershipService.refresh(result.data);
38 | }
39 |
40 | return result.status;
41 | }
42 |
43 | Future restorePassword(String email) async {
44 | return authRepository.restorePassword(email);
45 | }
46 |
47 | Future logOut() async {
48 | membershipService.clear();
49 | await authRepository.logout();
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/ecommers/lib/core/app_services/category_service.dart:
--------------------------------------------------------------------------------
1 | import 'package:ecommers/core/models/data_models/index.dart';
2 | import 'package:ecommers/shared/dependency_service.dart';
3 |
4 | class CategoryService {
5 | Future> fetchCategoryList() async => categoryDataRepository.getCategories();
6 | }
7 |
--------------------------------------------------------------------------------
/ecommers/lib/core/app_services/dialog/confirm_phone_registration.dart:
--------------------------------------------------------------------------------
1 | import 'package:ecommers/core/app_services/dialog/dialog_base.dart';
2 | import 'package:ecommers/shared/dependency_service.dart';
3 | import 'package:ecommers/ui/decorations/index.dart';
4 | import 'package:flutter/material.dart';
5 |
6 | class ConfirmPhoneRegistration extends DialogBase {
7 | @override
8 | String get defaultValue => null;
9 |
10 | Future showDialog() {
11 | final codeController = TextEditingController();
12 |
13 | return showInternally(AlertDialog(
14 | title: Text(
15 | localization.enter_sms_code_dialogTitle,
16 | style: textTheme.headline5,
17 | ),
18 | content: Column(
19 | mainAxisSize: MainAxisSize.min,
20 | children: [
21 | TextField(controller: codeController),
22 | ],
23 | ),
24 | actions: [
25 | FlatButton(
26 | textColor: Colors.white,
27 | color: BrandingColors.primary,
28 | onPressed: () => dismissDialog(codeController.text),
29 | child: Text(localization.enter_sms_code_dialogPrimary_button),
30 | )
31 | ],
32 | ));
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/ecommers/lib/core/app_services/dialog/confirmation_dialog.dart:
--------------------------------------------------------------------------------
1 | import 'dart:async';
2 |
3 | import 'package:ecommers/core/app_services/dialog/dialog_base.dart';
4 | import 'package:ecommers/shared/dependency_service.dart';
5 | import 'package:flutter/material.dart';
6 | import 'package:flutter/widgets.dart';
7 |
8 | class ConfirmationDialog extends DialogBase {
9 | @override
10 | bool get defaultValue => false;
11 |
12 | Future show(String header, String body, String confirmText,
13 | String declineText) async {
14 | return showInternally(AlertDialog(
15 | title: Text(
16 | header,
17 | style: textTheme.headline5,
18 | ),
19 | content: Text(body,
20 | style: textTheme.subtitle1,
21 | textAlign: TextAlign.start),
22 | actions: [
23 | if (declineText?.isNotEmpty ?? false)
24 | FlatButton(
25 | onPressed: () => dismissDialog(false),
26 | child: Text(
27 | declineText,
28 | style: textTheme.subtitle1,
29 | ),
30 | ),
31 | FlatButton(
32 | onPressed: () => dismissDialog(false),
33 | child: Text(
34 | confirmText,
35 | style: textTheme.subtitle1,
36 | ),
37 | ),
38 | ],
39 | ));
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/ecommers/lib/core/app_services/dialog/dialog_base.dart:
--------------------------------------------------------------------------------
1 | import 'dart:async';
2 |
3 | import 'package:flutter/material.dart';
4 | import 'package:flutter/widgets.dart';
5 | import 'package:get/get.dart';
6 |
7 | abstract class DialogBase {
8 | Completer _completer;
9 |
10 | T get defaultValue;
11 |
12 | @protected
13 | Future showInternally(Widget body) {
14 | _completer = Completer();
15 | _showDialog(body);
16 | return _completer.future;
17 | }
18 |
19 | @protected
20 | void _showDialog(Widget body) {
21 | Get.dialog(
22 | WillPopScope(
23 | onWillPop: () {
24 | dismissDialog(defaultValue);
25 | return Future.value(false);
26 | },
27 | child: body),
28 | barrierDismissible: true);
29 | }
30 |
31 | @protected
32 | void dismissDialog(T result) {
33 | Get.close(1);
34 | _trySetResult(result);
35 | }
36 |
37 | void _trySetResult(T result) {
38 | if (_completer != null) {
39 | _completer.complete(result);
40 | _completer = null;
41 | }
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/ecommers/lib/core/app_services/dialog/dialog_service.dart:
--------------------------------------------------------------------------------
1 | import 'package:ecommers/core/app_services/dialog/confirmation_dialog.dart';
2 | import 'package:ecommers/shared/dependency_service.dart';
3 | import 'package:flutter/widgets.dart';
4 |
5 | import 'confirm_phone_registration.dart';
6 |
7 | class DialogService {
8 | Future showDialog(
9 | {@required String header,
10 | @required String body,
11 | @required String confirmText,
12 | String declineText}) {
13 | return ConfirmationDialog().show(header, body, confirmText, declineText);
14 | }
15 |
16 | Future confirmPhoneRegistration() {
17 | return ConfirmPhoneRegistration().showDialog();
18 | }
19 |
20 | Future somethingWentWrong() {
21 | return showDialog(
22 | header: localization.something_went_wrongTitle,
23 | body: localization.something_went_wrongDescription,
24 | confirmText: localization.something_went_wrongPrimary_button);
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/ecommers/lib/core/app_services/index.dart:
--------------------------------------------------------------------------------
1 | export 'app_service.dart';
2 | export 'auth_response.dart';
3 | export 'authorization_service.dart';
4 | export 'category_service.dart';
5 | export 'note_service.dart';
6 | export 'paginator.dart';
7 | export 'payment_method_service.dart';
8 | export 'product_service.dart';
9 | export 'profile_service.dart';
10 | export 'shipping_address_service.dart';
--------------------------------------------------------------------------------
/ecommers/lib/core/app_services/note_service.dart:
--------------------------------------------------------------------------------
1 | import 'package:ecommers/core/models/data_models/index.dart';
2 | import 'package:ecommers/shared/dependency_service.dart';
3 |
4 | class NoteService {
5 | Future> fetchLatestNotes() async =>
6 | appService.fetchData(apiService.notes);
7 | }
8 |
--------------------------------------------------------------------------------
/ecommers/lib/core/app_services/paginator.dart:
--------------------------------------------------------------------------------
1 | import 'package:ecommers/core/models/data_models/index.dart';
2 |
3 | class Paginator {
4 | static const int _pageSize = 20;
5 |
6 | int _currentPosition = 0;
7 | bool _hasMore = true;
8 |
9 | int get currentPosition => _currentPosition;
10 | bool get hasMore => _hasMore;
11 |
12 | Future> loadNextPage(
13 | Future> Function(int, int) request) async {
14 | final List portion =
15 | await request(currentPosition, currentPosition + _pageSize);
16 |
17 | if (portion == null || portion.length < _pageSize) {
18 | _hasMore = false;
19 | } else {
20 | _currentPosition += _pageSize;
21 | }
22 |
23 | return portion ?? [];
24 | }
25 |
26 | void reset() {
27 | _hasMore = true;
28 | _currentPosition = 0;
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/ecommers/lib/core/app_services/payment_method_service.dart:
--------------------------------------------------------------------------------
1 | import 'package:ecommers/core/models/payment_method_model.dart';
2 | import 'package:ecommers/shared/dependency_service.dart';
3 | import 'package:stripe_payment/stripe_payment.dart';
4 |
5 | class PaymentMethodService {
6 | static const String testPublishableKey =
7 | 'pk_test_O4MySLvZlQMSIVMEJPCQjbIv00CnR4Bawc';
8 | static const String testMerchantId = 'Test';
9 | static const String testandroidPayMode = 'test';
10 |
11 | PaymentMethodService() {
12 | _initialize();
13 | }
14 |
15 | Future _initialize() async {
16 | StripePayment.setOptions(StripeOptions(
17 | publishableKey: testPublishableKey,
18 | merchantId: testMerchantId,
19 | androidPayMode: testandroidPayMode,
20 | ));
21 | }
22 |
23 | Future> getPaymentMethods() async {
24 | return paymentMethodRepository.getAllOPaymentMethods();
25 | }
26 |
27 | Future createPyamentMethod(CreditCard card) async {
28 | try {
29 | final paymentMethod = await StripePayment.createPaymentMethod(
30 | PaymentMethodRequest(card: card),
31 | );
32 | final paymentMethodModel =
33 | PaymentMethodModel.fromStripePaymentMethod(paymentMethod);
34 |
35 | await paymentMethodRepository.add(paymentMethodModel);
36 |
37 | return paymentMethodModel;
38 | } catch (ex) {
39 | return null;
40 | }
41 | }
42 |
43 | Future removePaymentMethod(PaymentMethodModel paymentMethodModel) async {
44 | return paymentMethodRepository.remove(paymentMethodModel);
45 | }
46 |
47 | Future editPaymentMethod(PaymentMethodModel paymentMethodModel) async {
48 | return paymentMethodRepository.edit(paymentMethodModel);
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/ecommers/lib/core/app_services/product_service.dart:
--------------------------------------------------------------------------------
1 | import 'package:ecommers/shared/dependency_service.dart';
2 | import 'package:enum_to_string/enum_to_string.dart';
3 |
4 | import 'package:ecommers/core/common/index.dart';
5 | import 'package:ecommers/core/models/data_models/index.dart';
6 | import 'package:ecommers/core/models/sort_type.dart';
7 |
8 | class ProductService {
9 | Future> fetchProducts({
10 | Categories category,
11 | String subCategory,
12 | int from,
13 | int to,
14 | String searchQuery,
15 | SortType sortType,
16 | }) async {
17 | final response = await apiService.products(
18 | category: EnumToString.parse(category),
19 | subCategory: subCategory,
20 | from: from,
21 | to: to,
22 | searchQuery: searchQuery,
23 | sortType: EnumToString.parse(sortType),
24 | );
25 |
26 | if (response.isSuccessful) {
27 | return response.body;
28 | }
29 |
30 | return null;
31 | }
32 |
33 | Future> fetchLatestProducts(int from, int to) async {
34 | final response = await apiService.productsLatest(from, to);
35 |
36 | if (response.isSuccessful) {
37 | return response.body;
38 | }
39 |
40 | return null;
41 | }
42 |
43 | Future> fetchRecentProducts() async =>
44 | appService.fetchData(apiService.productsRecent);
45 |
46 | Future recentProductsDelete() async {
47 | final response = await apiService.productsRecentDelete();
48 |
49 | return response.isSuccessful;
50 | }
51 |
52 | Future> fetchRecommendedProducts() async =>
53 | appService.fetchData(apiService.productRecommended);
54 |
55 | Future trySaveRecentProduct(Map product) async {
56 | final response = await apiService.productsRecentPost(product);
57 | return response.isSuccessful;
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/ecommers/lib/core/app_services/profile_service.dart:
--------------------------------------------------------------------------------
1 | import 'package:firebase_auth/firebase_auth.dart';
2 |
3 | class ProfileService {
4 | FirebaseUser _user;
5 | FirebaseUser get user => _user;
6 |
7 | Future updateUserInfo() async {
8 | _user = await FirebaseAuth.instance.currentUser();
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/ecommers/lib/core/app_services/shipping_address_service.dart:
--------------------------------------------------------------------------------
1 | import 'package:ecommers/core/models/index.dart';
2 | import 'package:ecommers/shared/dependency_service.dart';
3 | import 'package:uuid/uuid.dart';
4 |
5 | class ShippingAddressService {
6 | Future> getShippingAddresses() async {
7 | return shippingAddressRepository.getAllShippingAdderess();
8 | }
9 |
10 | Future> getSelectedShippingAddress() async {
11 | return shippingAddressRepository.getSelectedShippingAddress();
12 | }
13 |
14 | Future addSelectedShippingAddress(ShippingAddressModel item) async {
15 | return shippingAddressRepository.addSelectedShippingAddress(item);
16 | }
17 |
18 | Future updateSelectedShippingAddress(ShippingAddressModel item) async {
19 | return shippingAddressRepository.updateSelectedShippingAddress(item);
20 | }
21 |
22 | Future removeSelectedShippingAddress(ShippingAddressModel item) async {
23 | return shippingAddressRepository.removeSelectedShippingAddress(item);
24 | }
25 |
26 | Future createShippingAddress(
27 | ShippingAddressModel shippingAddressModel) async {
28 | try {
29 | final uuid = Uuid();
30 | shippingAddressModel.id = uuid.v1();
31 | await shippingAddressRepository.add(
32 | shippingAddressModel,
33 | );
34 |
35 | return shippingAddressModel;
36 | } catch (ex) {
37 | logger.ex(ex);
38 | }
39 | }
40 |
41 | Future removeShippingAddresses(
42 | ShippingAddressModel shippingAddressModel) async {
43 | return shippingAddressRepository.remove(shippingAddressModel);
44 | }
45 |
46 | Future editShippingAddresses(
47 | ShippingAddressModel shippingAddressModel) async {
48 | return shippingAddressRepository.edit(shippingAddressModel);
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/ecommers/lib/core/cache/index.dart:
--------------------------------------------------------------------------------
1 | export 'cache_database.dart';
2 |
--------------------------------------------------------------------------------
/ecommers/lib/core/common/api_defines.dart:
--------------------------------------------------------------------------------
1 | class ApiDefines {
2 | static const String login = '/login';
3 | static const String auth = '/auth';
4 |
5 | static const String products = '/products';
6 | static const String productsLatest = '/products/latest';
7 | static const String productsRecent = '/products/recent';
8 | static const String productsRecommended = '/products/recommended';
9 |
10 | static const String categories = '/categories';
11 |
12 | static const String notes = '/notes';
13 |
14 | static const String profile = '/profile';
15 | static const String profileOrders = '/profile/orders';
16 | static const String profilePendingShipment = '/profile/pending/shipment';
17 | static const String profilePendingPayment = '/profile/pending/payment';
18 | }
--------------------------------------------------------------------------------
/ecommers/lib/core/common/api_query_params.dart:
--------------------------------------------------------------------------------
1 | class ApiQueryParams {
2 | static const String category = 'category';
3 | static const String subCategory = 'subCategory';
4 | static const String rangeFrom = 'from';
5 | static const String rangeTo = 'to';
6 | static const String searchQuery = 'searchQuery';
7 | static const String sortType = 'sortType';
8 | }
--------------------------------------------------------------------------------
/ecommers/lib/core/common/cache_defines.dart:
--------------------------------------------------------------------------------
1 | class CacheDefines {
2 | static const String categories = 'categories';
3 | static const String latestProducts = 'latestProducts';
4 | static const String paymentMethods = 'paymentMethods';
5 | static const String shippingAddress = 'shippingAddress';
6 | static const String orders = 'orders';
7 | static const String selectedShippingAddressId = 'selectedShippingAddressId';
8 | }
9 |
--------------------------------------------------------------------------------
/ecommers/lib/core/common/categories.dart:
--------------------------------------------------------------------------------
1 | enum Categories {
2 | apparel,
3 | beauty,
4 | electronics,
5 | furniture,
6 | home,
7 | shoes,
8 | stationary,
9 | seeAll
10 | }
11 |
--------------------------------------------------------------------------------
/ecommers/lib/core/common/file_manager.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/services.dart';
2 |
3 | class FileManager {
4 | static const String jsonPath = 'lib/web_server/data/';
5 |
6 | static Future readJson(String fileName) async {
7 | final fullPath = jsonPath + fileName;
8 | return rootBundle.loadString(fullPath);
9 | }
10 | }
--------------------------------------------------------------------------------
/ecommers/lib/core/common/index.dart:
--------------------------------------------------------------------------------
1 | export 'api_defines.dart';
2 | export 'api_query_params.dart';
3 | export 'cache_defines.dart';
4 | export 'categories.dart';
5 | export 'file_manager.dart';
6 | export 'json_serializable_converter.dart';
7 | export 'pages.dart';
8 | export 'user_validator.dart';
9 |
--------------------------------------------------------------------------------
/ecommers/lib/core/common/json_serializable_converter.dart:
--------------------------------------------------------------------------------
1 | import 'package:chopper/chopper.dart';
2 |
3 | typedef JsonFactory = T Function(Map json);
4 |
5 | class JsonSerializableConverter extends JsonConverter {
6 | final Map _factories;
7 |
8 | const JsonSerializableConverter({Map factories})
9 | : _factories = factories;
10 |
11 | T _decodeMap(Map values) {
12 | final jsonFactory = _factories[T];
13 | if (jsonFactory == null || jsonFactory is! JsonFactory) {
14 | return throw 'not found factory';
15 | }
16 |
17 | return jsonFactory(values) as T;
18 | }
19 |
20 | List _decodeList(List values) =>
21 | values.where((v) => v != null).map((v) => _decode(v) as T).toList();
22 |
23 | dynamic _decode(entity) {
24 | if (entity is Iterable) {
25 | return _decodeList(entity as List);
26 | }
27 |
28 | if (entity is Map) {
29 | return _decodeMap(entity as Map);
30 | }
31 |
32 | return entity;
33 | }
34 |
35 | @override
36 | Response convertResponse(Response response) {
37 | final jsonRes = super.convertResponse(response);
38 |
39 | return jsonRes.copyWith(
40 | body: _decode- (jsonRes.body) as ResultType);
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/ecommers/lib/core/common/pages.dart:
--------------------------------------------------------------------------------
1 | enum Pages {
2 | shell,
3 | home,
4 | search,
5 | cart,
6 | profile,
7 | profileEdit,
8 | more,
9 | categories,
10 | productsGrid,
11 | authorization,
12 | checkout,
13 | success,
14 | product,
15 | notifications,
16 | note,
17 | paymentMethod,
18 | addPaymentMethod,
19 | shippingAddress,
20 | addShippingAddress,
21 | }
22 |
--------------------------------------------------------------------------------
/ecommers/lib/core/common/user_validator.dart:
--------------------------------------------------------------------------------
1 | class UserValidator {
2 | static const int _minPasswordLength = 4;
3 | static const _emailPattern =
4 | r"^[a-zA-Z0-9.a-zA-Z0-9.!#$%&'*+-/=?^_`{|}~]+@[a-zA-Z0-9]+\.[a-zA-Z]+";
5 |
6 | static bool isEmail(String email) {
7 | final regexp = RegExp(_emailPattern);
8 |
9 | return regexp.hasMatch(email);
10 | }
11 |
12 | static bool isPhoneNumber(String phone) {
13 | const _phoneNumber = r'^[0-9]{12}$';
14 | final regexp = RegExp(_phoneNumber);
15 |
16 | return regexp.hasMatch(phone);
17 | }
18 |
19 | static bool isPasswordValid(String password) {
20 | return password.length >= _minPasswordLength;
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/ecommers/lib/core/common/validator/index.dart:
--------------------------------------------------------------------------------
1 | export 'shipping_address_validator.dart';
--------------------------------------------------------------------------------
/ecommers/lib/core/common/validator/shipping_address_validator.dart:
--------------------------------------------------------------------------------
1 | class ShippingValidator{
2 |
3 | static bool isFullNameValid(String fullName) =>
4 | fullName != null && fullName.length > 3;
5 |
6 | static bool isAddressValid(String address) =>
7 | address != null && address.length > 2;
8 |
9 | static bool isCityValid(String city) =>
10 | city != null && city.length > 2;
11 |
12 | static bool isStateValid(String state) =>
13 | state != null && state.length > 3;
14 |
15 | static bool isZipCodeValid(String zipCode) =>
16 | zipCode != null && zipCode.length > 2;
17 |
18 | static bool isCountryValid(String country) =>
19 | country != null && country.length > 3;
20 | }
--------------------------------------------------------------------------------
/ecommers/lib/core/mixins/busy_notifier.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 |
3 | mixin BusyNotifier on ChangeNotifier {
4 | bool _hasDisposed = false;
5 | bool _isBusy = false;
6 |
7 | bool get isBusy => _isBusy;
8 |
9 | set isBusy(bool isBusy) {
10 | _isBusy = isBusy;
11 |
12 | if (!_hasDisposed) notifyListeners();
13 | }
14 |
15 | @override
16 | void dispose() {
17 | _hasDisposed = true;
18 | super.dispose();
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/ecommers/lib/core/mixins/index.dart:
--------------------------------------------------------------------------------
1 | export 'busy_notifier.dart';
2 | export 'items_loading_notifier.dart';
3 |
--------------------------------------------------------------------------------
/ecommers/lib/core/mixins/items_loading_notifier.dart:
--------------------------------------------------------------------------------
1 | import 'dart:async';
2 |
3 | import 'package:flutter/material.dart';
4 |
5 | import 'package:ecommers/core/app_services/index.dart';
6 | import 'package:ecommers/shared/dependency_service.dart';
7 |
8 | mixin ItemsLoadingNotifier on ChangeNotifier {
9 | @protected
10 | final Paginator paginator = createPaginator();
11 |
12 | bool _hasDisposed = false;
13 | bool _isItemsLoading = false;
14 |
15 | bool get isItemsLoading => _isItemsLoading;
16 | bool get hasMoreItems => paginator.hasMore;
17 |
18 | set isItemsLoading(bool isitemsLoading) {
19 | _isItemsLoading = isitemsLoading;
20 |
21 | if (!_hasDisposed) notifyListeners();
22 | }
23 |
24 | FutureOr loadMoreProducts() {}
25 |
26 | @override
27 | void dispose() {
28 | _hasDisposed = true;
29 | super.dispose();
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/ecommers/lib/core/models/auth_rich_text_span_model.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/widgets.dart';
2 |
3 | class AuthRichTextSpanModel {
4 | final String text;
5 | final bool isTappable;
6 | final Function() onTap;
7 | final UniqueKey id = UniqueKey();
8 |
9 | AuthRichTextSpanModel({
10 | this.text = '',
11 | this.isTappable = false,
12 | this.onTap,
13 | });
14 | }
15 |
--------------------------------------------------------------------------------
/ecommers/lib/core/models/cache_wrappers/categories_cache_wrapper.dart:
--------------------------------------------------------------------------------
1 | import 'package:ecommers/core/models/data_models/index.dart';
2 | import 'package:json_annotation/json_annotation.dart';
3 |
4 | part 'categories_cache_wrapper.g.dart';
5 |
6 | @JsonSerializable()
7 | class CategoriesCacheWrapper {
8 | @JsonKey(name: 'key')
9 | final String key;
10 | @JsonKey(name: 'lastUpdatedDate')
11 | final DateTime lastUpdatedDate;
12 | @JsonKey(name: 'categories')
13 | final List categories;
14 |
15 | CategoriesCacheWrapper(this.key, this.lastUpdatedDate, this.categories);
16 |
17 | static const fromJson = _$CategoriesCacheWrapperFromJson;
18 |
19 | Map toJson() => _$CategoriesCacheWrapperToJson(this);
20 | }
--------------------------------------------------------------------------------
/ecommers/lib/core/models/cache_wrappers/index.dart:
--------------------------------------------------------------------------------
1 | export 'categories_cache_wrapper.dart';
--------------------------------------------------------------------------------
/ecommers/lib/core/models/data_models/category.dart:
--------------------------------------------------------------------------------
1 | import 'package:ecommers/core/common/categories.dart';
2 | import 'package:json_annotation/json_annotation.dart';
3 |
4 | part 'category.g.dart';
5 |
6 | @JsonSerializable()
7 | class Category {
8 | final int id;
9 | final String title;
10 | final Categories type;
11 | @JsonKey(name: 'color1')
12 | final String gradientColor1;
13 | @JsonKey(name: 'color2')
14 | final String gradientColor2;
15 | final String shadowColor;
16 | final List subCategories;
17 |
18 | Category({
19 | this.id,
20 | this.title,
21 | this.subCategories,
22 | this.type,
23 | this.gradientColor1,
24 | this.gradientColor2,
25 | this.shadowColor,
26 | });
27 |
28 | static const fromJsonFactory = _$CategoryFromJson;
29 |
30 | factory Category.fromJson(Map json) =>
31 | _$CategoryFromJson(json);
32 |
33 | Map toJson() => _$CategoryToJson(this);
34 | }
35 |
--------------------------------------------------------------------------------
/ecommers/lib/core/models/data_models/index.dart:
--------------------------------------------------------------------------------
1 | export 'category.dart';
2 | export 'note.dart';
3 | export 'product.dart';
4 | export 'product_details.dart';
5 | export 'product_model.dart';
6 | export 'product_review.dart';
7 | export 'user.dart';
--------------------------------------------------------------------------------
/ecommers/lib/core/models/data_models/note.dart:
--------------------------------------------------------------------------------
1 | import 'package:json_annotation/json_annotation.dart';
2 |
3 | part 'note.g.dart';
4 |
5 | @JsonSerializable()
6 | class Note {
7 | final int id;
8 | final String title;
9 | final String imageUrl;
10 | final String commandText;
11 | final String description;
12 | final String shortDescription;
13 |
14 | Note(
15 | this.id,
16 | this.title,
17 | this.imageUrl,
18 | this.commandText,
19 | this.description,
20 | this.shortDescription,
21 | );
22 |
23 | static const fromJsonFactory = _$NoteFromJson;
24 |
25 | factory Note.fromJson(Map json) => _$NoteFromJson(json);
26 |
27 | Map toJson() => _$NoteToJson(this);
28 | }
29 |
--------------------------------------------------------------------------------
/ecommers/lib/core/models/data_models/product.dart:
--------------------------------------------------------------------------------
1 | import 'package:json_annotation/json_annotation.dart';
2 |
3 | import 'product_color.dart';
4 | import 'product_details.dart';
5 | import 'product_model.dart';
6 | import 'product_review.dart';
7 |
8 | part 'product.g.dart';
9 |
10 | @JsonSerializable()
11 | class Product {
12 | final int id;
13 | final String gender;
14 | final String category;
15 | final String subCategory;
16 | final String title;
17 | final double price;
18 | final ProductColor baseColor;
19 | final int catalogAddDate;
20 | final String previewImage;
21 |
22 | @JsonKey(name: 'styleImages')
23 | final List images;
24 |
25 | final double rate;
26 | final List models;
27 | final ProductDetails details;
28 | final List reviews;
29 |
30 | Product(
31 | this.id,
32 | this.gender,
33 | this.category,
34 | this.title,
35 | this.price,
36 | this.baseColor,
37 | this.images,
38 | this.rate,
39 | this.models,
40 | this.details,
41 | this.reviews,
42 | this.subCategory,
43 | this.catalogAddDate,
44 | this.previewImage,
45 | );
46 |
47 | static const fromJsonFactory = _$ProductFromJson;
48 |
49 | factory Product.fromJson(Map json) =>
50 | _$ProductFromJson(json);
51 |
52 | Map toJson() => _$ProductToJson(this);
53 | }
54 |
--------------------------------------------------------------------------------
/ecommers/lib/core/models/data_models/product_color.dart:
--------------------------------------------------------------------------------
1 | import 'package:json_annotation/json_annotation.dart';
2 |
3 | part 'product_color.g.dart';
4 |
5 | @JsonSerializable()
6 | class ProductColor {
7 | final String title;
8 | final int argb;
9 |
10 | ProductColor(
11 | this.title,
12 | this.argb
13 | );
14 |
15 | static const fromJsonFactory = _$ProductColorFromJson;
16 |
17 | factory ProductColor.fromJson(Map json) =>
18 | _$ProductColorFromJson(json);
19 |
20 | Map toJson() => _$ProductColorToJson(this);
21 | }
22 |
--------------------------------------------------------------------------------
/ecommers/lib/core/models/data_models/product_details.dart:
--------------------------------------------------------------------------------
1 | import 'package:json_annotation/json_annotation.dart';
2 |
3 | part 'product_details.g.dart';
4 |
5 | @JsonSerializable()
6 | class ProductDetails {
7 | final String brand;
8 | final String condition;
9 | final String category;
10 | final String material;
11 | final String fitting;
12 |
13 | ProductDetails(
14 | this.brand,
15 | this.condition,
16 | this.category,
17 | this.material,
18 | this.fitting,
19 | );
20 |
21 | static const fromJsonFactory = _$ProductDetailsFromJson;
22 |
23 | factory ProductDetails.fromJson(Map json) =>
24 | _$ProductDetailsFromJson(json);
25 |
26 | Map toJson() => _$ProductDetailsToJson(this);
27 | }
28 |
--------------------------------------------------------------------------------
/ecommers/lib/core/models/data_models/product_model.dart:
--------------------------------------------------------------------------------
1 | import 'package:json_annotation/json_annotation.dart';
2 |
3 | import 'product_color.dart';
4 |
5 | part 'product_model.g.dart';
6 |
7 | @JsonSerializable()
8 | class ProductModel {
9 | final String size;
10 | final ProductColor color;
11 | final int skuId;
12 | final List imageUrls;
13 | final bool isAvailable;
14 | final int totalCount;
15 |
16 | ProductModel({
17 | this.size,
18 | this.color,
19 | this.skuId,
20 | this.imageUrls,
21 | this.isAvailable,
22 | this.totalCount,
23 | });
24 |
25 | static const fromJsonFactory = _$ProductModelFromJson;
26 |
27 | factory ProductModel.fromJson(Map json) =>
28 | _$ProductModelFromJson(json);
29 |
30 | Map toJson() => _$ProductModelToJson(this);
31 | }
32 |
33 |
--------------------------------------------------------------------------------
/ecommers/lib/core/models/data_models/product_review.dart:
--------------------------------------------------------------------------------
1 | import 'package:json_annotation/json_annotation.dart';
2 |
3 | import 'user.dart';
4 |
5 | part 'product_review.g.dart';
6 |
7 | @JsonSerializable()
8 | class ProductReview {
9 | final User user;
10 | final DateTime date;
11 | final String comment;
12 | final List imageUrls;
13 | final int rate;
14 |
15 | ProductReview(
16 | this.user,
17 | this.date,
18 | this.comment,
19 | this.imageUrls,
20 | this.rate,
21 | );
22 |
23 | static const fromJsonFactory = _$ProductReviewFromJson;
24 |
25 | factory ProductReview.fromJson(Map json) =>
26 | _$ProductReviewFromJson(json);
27 |
28 | Map toJson() => _$ProductReviewToJson(this);
29 | }
30 |
--------------------------------------------------------------------------------
/ecommers/lib/core/models/data_models/user.dart:
--------------------------------------------------------------------------------
1 | import 'package:json_annotation/json_annotation.dart';
2 |
3 | part 'user.g.dart';
4 |
5 | @JsonSerializable()
6 | class User {
7 | final String username;
8 | final String email;
9 | final String password;
10 | final String firstName;
11 | final String lastName;
12 | final String avatar;
13 | final String address;
14 |
15 | User(
16 | this.username,
17 | this.email,
18 | this.password,
19 | this.firstName,
20 | this.lastName,
21 | this.avatar,
22 | this.address,
23 | );
24 |
25 | static const fromJsonFactory = _$UserFromJson;
26 |
27 | factory User.fromJson(Map json) => _$UserFromJson(json);
28 |
29 | Map toJson() => _$UserToJson(this);
30 | }
31 |
--------------------------------------------------------------------------------
/ecommers/lib/core/models/index.dart:
--------------------------------------------------------------------------------
1 | export 'auth_rich_text_span_model.dart';
2 | export 'item_base.dart';
3 | export 'login_model.dart';
4 | export 'notification_model.dart';
5 | export 'order_model.dart';
6 | export 'page_arguments.dart';
7 | export 'payment_method_model.dart';
8 | export 'product_color_model.dart';
9 | export 'product_size_model.dart';
10 | export 'product_skuid_model.dart';
11 | export 'sort_type.dart';
12 | export 'shipping_address_model.dart';
13 | export 'user_model.dart';
14 |
--------------------------------------------------------------------------------
/ecommers/lib/core/models/item_base.dart:
--------------------------------------------------------------------------------
1 | class ItemBase {
2 | final dynamic id;
3 |
4 | ItemBase(this.id);
5 | }
--------------------------------------------------------------------------------
/ecommers/lib/core/models/login_model.dart:
--------------------------------------------------------------------------------
1 | import 'package:json_annotation/json_annotation.dart';
2 |
3 | part 'login_model.g.dart';
4 |
5 | @JsonSerializable()
6 | class LoginModel {
7 | @JsonKey(name: 'access_token')
8 | final String token;
9 |
10 | @JsonKey(name: 'refresh_token')
11 | final String refreshToken;
12 |
13 | @JsonKey(name: 'expiration_date')
14 | final String expirationDate;
15 |
16 | LoginModel(this.token, this.refreshToken, this.expirationDate);
17 |
18 | static const fromJsonFactory = _$LoginModelFromJson;
19 |
20 | Map toJson() => _$LoginModelToJson(this);
21 | }
22 |
--------------------------------------------------------------------------------
/ecommers/lib/core/models/notification_model.dart:
--------------------------------------------------------------------------------
1 | import 'dart:ui';
2 |
3 | class NotificationModel {
4 | final String orderNumber;
5 | final String notificationUsualText;
6 | final String statusText;
7 | final bool isCheckedItem;
8 | final Color backgroundColor;
9 | final Color shadowColor;
10 | final String imgPath;
11 | final DateTime day;
12 |
13 | NotificationModel({
14 | this.orderNumber,
15 | this.notificationUsualText,
16 | this.isCheckedItem,
17 | this.statusText,
18 | this.backgroundColor,
19 | this.shadowColor,
20 | this.imgPath,
21 | this.day,
22 | });
23 | }
24 |
--------------------------------------------------------------------------------
/ecommers/lib/core/models/order_model.dart:
--------------------------------------------------------------------------------
1 | import 'package:ecommers/core/models/index.dart';
2 | import 'package:json_annotation/json_annotation.dart';
3 | import 'data_models/index.dart';
4 |
5 | part 'order_model.g.dart';
6 |
7 | @JsonSerializable()
8 | class OrderModel implements ItemBase{
9 | @override
10 | final int id;
11 | final Product product;
12 | final String characteristics;
13 | int count;
14 |
15 | OrderModel({
16 | this.id,
17 | this.product,
18 | this.characteristics,
19 | this.count = 1,
20 | });
21 |
22 | static const fromJson = _$OrderModelFromJson;
23 |
24 | factory OrderModel.fromProduct({Product product, String size, String color}) {
25 | return OrderModel(
26 | id: product.id,
27 | product: product,
28 | characteristics: '$size, $color',
29 | count: 1,
30 | );
31 | }
32 |
33 | Map toJson() => _$OrderModelToJson(this);
34 | }
35 |
--------------------------------------------------------------------------------
/ecommers/lib/core/models/page_arguments.dart:
--------------------------------------------------------------------------------
1 | class PageArguments {
2 | final Object arg1;
3 | final Object arg2;
4 |
5 | PageArguments({this.arg1, this.arg2});
6 | }
7 |
--------------------------------------------------------------------------------
/ecommers/lib/core/models/payment_method_model.dart:
--------------------------------------------------------------------------------
1 | import 'package:ecommers/core/models/index.dart';
2 | import 'package:json_annotation/json_annotation.dart';
3 | import 'package:stripe_payment/stripe_payment.dart';
4 |
5 | part 'payment_method_model.g.dart';
6 |
7 | @JsonSerializable()
8 | class PaymentMethodModel implements ItemBase {
9 | @override
10 | final String id;
11 | final String cardCountry;
12 | final int cardExpMonth;
13 | final int cardExpYear;
14 | final String cardNumberLast4;
15 | final String cardBrand;
16 | bool isSelected;
17 |
18 | PaymentMethodModel({
19 | this.id,
20 | this.cardCountry,
21 | this.cardExpMonth,
22 | this.cardExpYear,
23 | this.cardNumberLast4,
24 | this.cardBrand,
25 | this.isSelected = false,
26 | });
27 |
28 | factory PaymentMethodModel.fromStripePaymentMethod(PaymentMethod paymentMethod) {
29 | return PaymentMethodModel(
30 | id: paymentMethod.id,
31 | isSelected: false,
32 | cardBrand: paymentMethod.card.brand,
33 | cardCountry: paymentMethod.card.country,
34 | cardExpMonth: paymentMethod.card.expMonth,
35 | cardExpYear: paymentMethod.card.expYear,
36 | cardNumberLast4: paymentMethod.card.last4,
37 | );
38 | }
39 |
40 | static const fromJson = _$PaymentMethodModelFromJson;
41 |
42 | Map toJson() => _$PaymentMethodModelToJson(this);
43 | }
44 |
--------------------------------------------------------------------------------
/ecommers/lib/core/models/product_color_model.dart:
--------------------------------------------------------------------------------
1 | import 'package:ecommers/ui/widgets/right_menu_bar/models/index.dart';
2 | import 'package:meta/meta.dart';
3 |
4 | class ProductColorModel {
5 | bool isSelected;
6 | final int color;
7 | final String title;
8 | final List images;
9 |
10 | ProductColorModel({
11 | @required this.color,
12 | @required this.images,
13 | this.isSelected = false,
14 | this.title,
15 | });
16 | }
17 |
--------------------------------------------------------------------------------
/ecommers/lib/core/models/product_size_model.dart:
--------------------------------------------------------------------------------
1 | import 'package:meta/meta.dart';
2 |
3 | class ProductSizeModel {
4 | bool isSelected;
5 | final String size;
6 |
7 | ProductSizeModel({
8 | @required this.size,
9 | this.isSelected = false,
10 | });
11 | }
--------------------------------------------------------------------------------
/ecommers/lib/core/models/product_skuid_model.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/widgets.dart';
2 |
3 | class ProductSkuIdModel {
4 | final int color;
5 | final String size;
6 |
7 | ProductSkuIdModel({
8 | @required this.size,
9 | @required this.color,
10 | });
11 | }
--------------------------------------------------------------------------------
/ecommers/lib/core/models/shipping_address_model.dart:
--------------------------------------------------------------------------------
1 | import 'package:ecommers/core/models/index.dart';
2 | import 'package:json_annotation/json_annotation.dart';
3 |
4 | part 'shipping_address_model.g.dart';
5 |
6 | @JsonSerializable()
7 | class ShippingAddressModel implements ItemBase {
8 | @override
9 | String id;
10 | String fullName;
11 | String address;
12 | String city;
13 | String state;
14 | String zipCode;
15 | String country;
16 |
17 | ShippingAddressModel({
18 | this.id,
19 | this.fullName,
20 | this.address,
21 | this.city,
22 | this.state,
23 | this.zipCode,
24 | this.country,
25 | });
26 |
27 | static const fromJson = _$ShippingAddressModelFromJson;
28 |
29 | Map toJson() => _$ShippingAddressModelToJson(this);
30 | }
31 |
--------------------------------------------------------------------------------
/ecommers/lib/core/models/sort_type.dart:
--------------------------------------------------------------------------------
1 | enum SortType {
2 | rate,
3 | cost,
4 | costDesc
5 | }
--------------------------------------------------------------------------------
/ecommers/lib/core/models/user_model.dart:
--------------------------------------------------------------------------------
1 | import 'package:json_annotation/json_annotation.dart';
2 |
3 | part 'user_model.g.dart';
4 |
5 | @JsonSerializable()
6 | class UserModel {
7 | final String username;
8 |
9 | final String email;
10 |
11 | UserModel(this.username, this.email);
12 | }
--------------------------------------------------------------------------------
/ecommers/lib/core/provider_models/auth/forgot_password_provider_model.dart:
--------------------------------------------------------------------------------
1 | import 'package:ecommers/core/mixins/index.dart';
2 | import 'package:ecommers/shared/dependency_service.dart';
3 | import 'package:flutter/material.dart';
4 |
5 | class ForgotPasswordProviderModel extends ChangeNotifier with BusyNotifier {
6 | Future resetPassword(String email) async {
7 | isBusy = true;
8 | final result = await authorizationService.restorePassword(email);
9 | isBusy = false;
10 |
11 | if (result) {
12 | dialogService.showDialog(
13 | header: localization.password_restoration_dialogTitle,
14 | body: localization.password_restoration_dialogDescription,
15 | confirmText: localization.password_restoration_dialogPrimary_button);
16 | } else {
17 | dialogService.somethingWentWrong();
18 | }
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/ecommers/lib/core/provider_models/base_provider_model.dart:
--------------------------------------------------------------------------------
1 | import 'package:ecommers/core/mixins/busy_notifier.dart';
2 | import 'package:flutter/material.dart';
3 |
4 | class BusyProviderModel extends ChangeNotifier with BusyNotifier {}
5 |
--------------------------------------------------------------------------------
/ecommers/lib/core/provider_models/categories_provider_model.dart:
--------------------------------------------------------------------------------
1 | import 'package:ecommers/core/mixins/index.dart';
2 | import 'package:ecommers/core/models/data_models/category.dart';
3 | import 'package:flutter/material.dart';
4 |
5 | class CategoriesProviderModel extends ChangeNotifier with BusyNotifier {
6 | final List categoryList;
7 | int _selectedCategoryIndex = 0;
8 |
9 | Category get selectedCategory => categoryList[_selectedCategoryIndex];
10 |
11 | int get selectedCategoryIndex => _selectedCategoryIndex;
12 | set selectedCategoryIndex(int index) {
13 | if (selectedCategoryIndex == index) return;
14 |
15 | _selectedCategoryIndex = index;
16 |
17 | notifyListeners();
18 | }
19 |
20 | CategoriesProviderModel(this.categoryList);
21 | }
22 |
--------------------------------------------------------------------------------
/ecommers/lib/core/provider_models/home_provider_model.dart:
--------------------------------------------------------------------------------
1 | import 'dart:async';
2 |
3 | import 'package:ecommers/core/mixins/index.dart';
4 | import 'package:ecommers/shared/dependency_service.dart';
5 | import 'package:flutter/material.dart';
6 |
7 | import 'package:ecommers/core/mixins/items_loading_notifier.dart';
8 | import 'package:ecommers/core/models/data_models/index.dart';
9 |
10 | class HomeProviderModel extends ChangeNotifier
11 | with ItemsLoadingNotifier, BusyNotifier {
12 | List _categoryList;
13 | List _productsLatest;
14 | List _notesLatest;
15 |
16 | List get categoryList => _categoryList;
17 | List get productsLatest => _productsLatest;
18 | List get notesLatest => _notesLatest;
19 |
20 | HomeProviderModel() {
21 | fetchAllData();
22 | }
23 |
24 | Future fetchAllData() async {
25 | isBusy = true;
26 |
27 | await Future.wait({
28 | _fetchCategories(),
29 | _fetchLatestProducts(),
30 | _fetchLatestNotes(),
31 | });
32 |
33 | isBusy = false;
34 | }
35 |
36 | Future _fetchCategories() async {
37 | _categoryList = await categoryService.fetchCategoryList();
38 | }
39 |
40 | Future _fetchLatestProducts() async {
41 | _productsLatest =
42 | await paginator.loadNextPage(productService.fetchLatestProducts);
43 | }
44 |
45 | Future _fetchLatestNotes() async {
46 | _notesLatest = await noteService.fetchLatestNotes();
47 | }
48 |
49 | @override
50 | FutureOr loadMoreProducts() async {
51 | isItemsLoading = true;
52 |
53 | final products =
54 | await paginator.loadNextPage(productService.fetchLatestProducts);
55 |
56 | _productsLatest.addAll(products);
57 |
58 | isItemsLoading = false;
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/ecommers/lib/core/provider_models/index.dart:
--------------------------------------------------------------------------------
1 | export 'base_provider_model.dart';
2 | export 'cart_provider.dart';
3 | export 'categories_provider_model.dart';
4 | export 'home_provider_model.dart';
5 | export 'more_provider_model.dart';
6 | export 'payment_method_provider_model.dart';
7 | export 'product_page_provider_model.dart';
8 | export 'product_tab_provider_model.dart';
9 | export 'products_grid_provder_model.dart';
10 | export 'profile_provider_model.dart';
11 | export 'search_page_provider_model.dart';
12 | export 'search_query_provider_model.dart';
13 | export 'shell_provider_model.dart';
14 | export 'shipping_address_provider_model.dart';
15 |
--------------------------------------------------------------------------------
/ecommers/lib/core/provider_models/more_provider_model.dart:
--------------------------------------------------------------------------------
1 | import 'package:ecommers/core/common/index.dart';
2 | import 'package:ecommers/core/mixins/index.dart';
3 | import 'package:ecommers/shared/dependency_service.dart';
4 | import 'package:flutter/material.dart';
5 |
6 | class MoreProviderModel extends ChangeNotifier with BusyNotifier {
7 |
8 | Future logOutPressHandler() async {
9 | await cacheDatabase.dropDataBase();
10 | authorizationService.logOut();
11 | await navigationService.navigateWithReplacementTo(Pages.authorization);
12 | }
13 | }
--------------------------------------------------------------------------------
/ecommers/lib/core/provider_models/product_tab_provider_model.dart:
--------------------------------------------------------------------------------
1 | import 'package:ecommers/core/mixins/index.dart';
2 | import 'package:ecommers/core/models/index.dart';
3 | import 'package:flutter/widgets.dart';
4 |
5 | class ProductTabProviderModel extends ChangeNotifier with BusyNotifier {
6 | List _colors;
7 | List _sizes;
8 |
9 | List get sizes => _sizes;
10 | set sizes(List sizes) => _sizes = sizes ?? [];
11 |
12 | List get colors => _colors;
13 | set colors(List colors) => _colors = colors ?? [];
14 |
15 | ProductTabProviderModel(this._colors, this._sizes);
16 |
17 | void selectSize(int index) {
18 | sizes.forEach(_unselectSizes);
19 | sizes[index].isSelected = true;
20 |
21 | notifyListeners();
22 | }
23 |
24 | void selectColor(int index) {
25 | colors.forEach(_unselectColors);
26 | colors[index].isSelected = true;
27 |
28 | notifyListeners();
29 | }
30 |
31 | void _unselectSizes(ProductSizeModel size) {
32 | size.isSelected = false;
33 | }
34 |
35 | void _unselectColors(ProductColorModel color) {
36 | color.isSelected = false;
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/ecommers/lib/core/provider_models/profile_provider_model.dart:
--------------------------------------------------------------------------------
1 | import 'package:ecommers/core/mixins/busy_notifier.dart';
2 | import 'package:ecommers/shared/dependency_service.dart';
3 | import 'package:flutter/cupertino.dart';
4 |
5 | class ProfileProviderModel extends ChangeNotifier with BusyNotifier {
6 | String get email => profileService.user.email;
7 |
8 | String get emailOrPhone =>
9 | profileService.user.email ?? profileService.user.phoneNumber;
10 |
11 | String get name => profileService.user.displayName ?? emailOrPhone;
12 |
13 | String get phone => profileService.user.phoneNumber;
14 |
15 | Future saveChanges(String name) async {
16 | if (profileService.user.displayName != name) {
17 | isBusy = true;
18 | await authorizationService.updateUserName(name);
19 | await profileService.updateUserInfo();
20 | isBusy = false;
21 |
22 | notifyListeners();
23 | }
24 |
25 | navigationService.goBack();
26 | }
27 |
28 | Future resetPassword(String email) async {
29 | isBusy = true;
30 | final result = await authorizationService.restorePassword(email);
31 | isBusy = false;
32 |
33 | if (result) {
34 | dialogService.showDialog(
35 | header: localization.password_reset_dialogTitle,
36 | body: localization.password_reset_dialogDescription,
37 | confirmText: localization.password_reset_dialogPrimary_button);
38 | } else {
39 | dialogService.somethingWentWrong();
40 | }
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/ecommers/lib/core/provider_models/search_page_provider_model.dart:
--------------------------------------------------------------------------------
1 | import 'package:ecommers/core/mixins/index.dart';
2 | import 'package:ecommers/core/models/data_models/index.dart';
3 | import 'package:ecommers/shared/dependency_service.dart';
4 | import 'package:flutter/material.dart';
5 |
6 | class SearchPageProviderModel extends ChangeNotifier with BusyNotifier {
7 | List _recentProducts;
8 | List _recommendedProducts;
9 |
10 | List get recentProducts => _recentProducts;
11 | List get recommendedProducts => _recommendedProducts;
12 |
13 | SearchPageProviderModel() {
14 | fetchAllData();
15 | }
16 |
17 | Future fetchAllData() async {
18 | isBusy = true;
19 |
20 | await Future.wait({
21 | _fetchRecentProducts(),
22 | _fetchRecommendedProducts(),
23 | });
24 |
25 | isBusy = false;
26 | }
27 |
28 | void clearRecentProducts() {
29 | productService.recentProductsDelete();
30 | _recentProducts.clear();
31 | notifyListeners();
32 | }
33 |
34 | Future updateRecentProducts() async {
35 | isBusy = true;
36 |
37 | await _fetchRecentProducts();
38 |
39 | isBusy = false;
40 | }
41 |
42 | Future refreshRecommendedProducts() async {
43 | isBusy = true;
44 |
45 | await _fetchRecommendedProducts();
46 | notifyListeners();
47 |
48 | isBusy = false;
49 | }
50 |
51 | Future _fetchRecentProducts() async {
52 | _recentProducts = await productService.fetchRecentProducts();
53 | }
54 |
55 | Future _fetchRecommendedProducts() async {
56 | _recommendedProducts = await productService.fetchRecommendedProducts();
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/ecommers/lib/core/provider_models/search_query_provider_model.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 |
3 | class SearchQueryProviderModel extends ChangeNotifier {
4 | String _searchQuery;
5 |
6 | String get searchQuery => _searchQuery;
7 | set searchQuery(String query) {
8 | if (_searchQuery == query) return;
9 |
10 | _searchQuery = query;
11 |
12 | notifyListeners();
13 | }
14 | }
--------------------------------------------------------------------------------
/ecommers/lib/core/provider_models/shell_provider_model.dart:
--------------------------------------------------------------------------------
1 | import 'package:ecommers/core/common/index.dart';
2 | import 'package:ecommers/core/mixins/index.dart';
3 | import 'package:flutter/material.dart';
4 |
5 | class ShellProviderModel extends ChangeNotifier with BusyNotifier {
6 | final List pages = [
7 | Pages.home,
8 | Pages.search,
9 | Pages.cart,
10 | Pages.profile,
11 | Pages.more
12 | ];
13 |
14 | int selectedItemIndex = 0;
15 |
16 | Pages get selectedPage => pages[selectedItemIndex];
17 |
18 | void onTappedItem(int index) {
19 | selectedItemIndex = index;
20 | notifyListeners();
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/ecommers/lib/core/repositories/cart_repository.dart:
--------------------------------------------------------------------------------
1 | import 'package:ecommers/core/common/index.dart';
2 | import 'package:ecommers/core/models/index.dart';
3 | import 'package:ecommers/core/repositories/index.dart';
4 | import 'package:ecommers/shared/dependency_service.dart';
5 |
6 | class CartRepository extends RepositoryBase {
7 | static const filterFieldOrderId = 'id';
8 | CartRepository()
9 | : super(
10 | filterFieldForItem: filterFieldOrderId,
11 | repositoryKey: CacheDefines.orders,
12 | );
13 |
14 | Future
> getAllOrders() async {
15 | return cacheDatabase.getAll(
16 | repositoryKey,
17 | OrderModel.fromJson);
18 |
19 | }
20 |
21 | Future dropOrders() async {
22 | await cacheDatabase.dropData(repositoryKey);
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/ecommers/lib/core/repositories/index.dart:
--------------------------------------------------------------------------------
1 | export 'cart_repository.dart';
2 | export 'category_data_repository.dart';
3 | export 'payment_method_repository.dart';
4 | export 'repository_base.dart';
5 | export 'shipping_address_repository.dart';
--------------------------------------------------------------------------------
/ecommers/lib/core/repositories/payment_method_repository.dart:
--------------------------------------------------------------------------------
1 | import 'package:ecommers/core/common/index.dart';
2 | import 'package:ecommers/core/models/index.dart';
3 | import 'package:ecommers/shared/dependency_service.dart';
4 | import 'package:ecommers/core/repositories/index.dart';
5 |
6 | class PaymentMethodRepository extends RepositoryBase {
7 | static const filterFieldId = 'id';
8 |
9 | PaymentMethodRepository()
10 | : super(
11 | filterFieldForItem: filterFieldId,
12 | repositoryKey: CacheDefines.paymentMethods,
13 | );
14 |
15 | Future> getAllOPaymentMethods() async {
16 | return cacheDatabase.getAll(repositoryKey, PaymentMethodModel.fromJson);
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/ecommers/lib/core/repositories/repository_base.dart:
--------------------------------------------------------------------------------
1 | import 'dart:convert';
2 | import 'package:ecommers/core/models/index.dart';
3 | import 'package:ecommers/shared/dependency_service.dart';
4 |
5 | class RepositoryBase {
6 | final String filterFieldForItem;
7 | final String repositoryKey;
8 |
9 | RepositoryBase({
10 | this.filterFieldForItem,
11 | this.repositoryKey,
12 | });
13 |
14 | Future edit(T item) async {
15 | return cacheDatabase.updateByEqualsFilter(
16 | repositoryKey, json.decode(json.encode(item)) as Map, {
17 | filterFieldForItem: item.id,
18 | });
19 | }
20 |
21 | Future add(T item) async {
22 | return cacheDatabase.saveMap(
23 | repositoryKey, json.decode(json.encode(item)) as Map);
24 | }
25 |
26 | Future remove(T item) async {
27 | return cacheDatabase.deleteDataByFilter(repositoryKey, {
28 | filterFieldForItem: item.id,
29 | });
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/ecommers/lib/core/repositories/shipping_address_repository.dart:
--------------------------------------------------------------------------------
1 | import 'dart:convert';
2 |
3 | import 'package:ecommers/core/common/index.dart';
4 | import 'package:ecommers/core/models/index.dart';
5 | import 'package:ecommers/core/repositories/index.dart';
6 | import 'package:ecommers/shared/dependency_service.dart';
7 |
8 | class ShippingAddressRepository extends RepositoryBase {
9 | static const filterFieldId = 'id';
10 |
11 | ShippingAddressRepository()
12 | : super(
13 | filterFieldForItem: filterFieldId,
14 | repositoryKey: CacheDefines.shippingAddress,
15 | );
16 |
17 | Future> getSelectedShippingAddress() {
18 | return cacheDatabase.getAll(
19 | CacheDefines.selectedShippingAddressId, ShippingAddressModel.fromJson);
20 | }
21 |
22 | Future addSelectedShippingAddress(ShippingAddressModel item) {
23 | return cacheDatabase.saveMap(CacheDefines.selectedShippingAddressId,
24 | json.decode(json.encode(item)) as Map);
25 | }
26 |
27 | Future updateSelectedShippingAddress(ShippingAddressModel item) async {
28 | return cacheDatabase.updateByEqualsFilter(
29 | repositoryKey, json.decode(json.encode(item)) as Map, {
30 | filterFieldForItem: item.id,
31 | });
32 | }
33 |
34 | Future removeSelectedShippingAddress(ShippingAddressModel item) {
35 | return cacheDatabase
36 | .deleteDataByFilter(CacheDefines.selectedShippingAddressId, {
37 | filterFieldForItem: item.id,
38 | });
39 | }
40 |
41 | Future> getAllShippingAdderess() async {
42 | return cacheDatabase.getAll(repositoryKey, ShippingAddressModel.fromJson);
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/ecommers/lib/core/services/index.dart:
--------------------------------------------------------------------------------
1 | export 'api_service.dart';
2 | export 'membership_service.dart';
3 |
--------------------------------------------------------------------------------
/ecommers/lib/data/repository/common.mappings.dart:
--------------------------------------------------------------------------------
1 | import 'package:ecommers/core/models/index.dart';
2 | import 'package:firebase_auth/firebase_auth.dart';
3 |
4 | extension AuthExt on AuthResult {
5 | LoginModel toLoginModel() {
6 | //firebase auth do not has tokens
7 | return LoginModel('token', 'refreshToken',
8 | DateTime.now().add(const Duration(days: 180)).toString());
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/ecommers/lib/data/result.dart:
--------------------------------------------------------------------------------
1 | class Result {
2 | final TResult data;
3 | final TStatus status;
4 |
5 | Result(this.data, this.status);
6 |
7 | factory Result.submit(TResult data, TStatus status) {
8 | return Result(data, status);
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/ecommers/lib/extensions/index.dart:
--------------------------------------------------------------------------------
1 | export 'json_extension.dart';
2 | export 'string_extension.dart';
3 |
--------------------------------------------------------------------------------
/ecommers/lib/extensions/json_extension.dart:
--------------------------------------------------------------------------------
1 | import 'dart:convert';
2 |
3 | extension JsonExtension on JsonCodec {
4 | List decodeList(String json, T Function(Map) fromMap) {
5 | final jsonMap =
6 | (jsonDecode(json) as List).cast