├── .gitattributes ├── .gitignore ├── README.md ├── Screenshots ├── add_to_cart.png ├── cart.png ├── categories.png ├── checkout.png ├── home.png ├── login.png ├── orders.png ├── orders_detail.png ├── product_detail.png ├── profile.png └── store_info.png ├── ankii_shopii ├── .gitignore ├── .metadata ├── README.md ├── android │ ├── .gitignore │ ├── app │ │ ├── build.gradle │ │ ├── google-services.json │ │ └── src │ │ │ ├── debug │ │ │ └── AndroidManifest.xml │ │ │ ├── main │ │ │ ├── AndroidManifest.xml │ │ │ ├── kotlin │ │ │ │ └── com │ │ │ │ │ └── ankii │ │ │ │ │ └── ankiishopii │ │ │ │ │ └── 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 │ ├── cliparts │ │ └── cart_empty.png │ └── fonts │ │ ├── IconFont.ttf │ │ └── Jura.ttf ├── ios │ ├── .gitignore │ ├── Flutter │ │ ├── AppFrameworkInfo.plist │ │ ├── Debug.xcconfig │ │ └── Release.xcconfig │ ├── Runner.xcodeproj │ │ ├── project.pbxproj │ │ ├── project.xcworkspace │ │ │ ├── contents.xcworkspacedata │ │ │ └── xcshareddata │ │ │ │ ├── IDEWorkspaceChecks.plist │ │ │ │ └── WorkspaceSettings.xcsettings │ │ └── xcshareddata │ │ │ └── xcschemes │ │ │ └── Runner.xcscheme │ ├── Runner.xcworkspace │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata │ │ │ ├── IDEWorkspaceChecks.plist │ │ │ └── WorkspaceSettings.xcsettings │ └── 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-60x60@2x.png │ │ │ ├── Icon-App-60x60@3x.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 │ ├── blocs │ │ ├── account_bloc │ │ │ ├── bloc.dart │ │ │ ├── event.dart │ │ │ ├── service.dart │ │ │ └── state.dart │ │ ├── bloc_service.dart │ │ ├── cart_bloc │ │ │ ├── bloc.dart │ │ │ ├── event.dart │ │ │ ├── service.dart │ │ │ └── state.dart │ │ ├── category_bloc │ │ │ ├── bloc.dart │ │ │ ├── event.dart │ │ │ ├── service.dart │ │ │ └── state.dart │ │ ├── checkout_bloc │ │ │ ├── bloc.dart │ │ │ ├── event.dart │ │ │ ├── service.dart │ │ │ └── state.dart │ │ ├── delivery_address_bloc │ │ │ ├── bloc.dart │ │ │ ├── event.dart │ │ │ ├── service.dart │ │ │ └── state.dart │ │ ├── favorite_bloc │ │ │ ├── bloc.dart │ │ │ ├── event.dart │ │ │ ├── service.dart │ │ │ └── state.dart │ │ ├── login_bloc │ │ │ ├── bloc.dart │ │ │ ├── event.dart │ │ │ ├── service.dart │ │ │ └── state.dart │ │ ├── ordering_bloc │ │ │ ├── bloc.dart │ │ │ ├── event.dart │ │ │ ├── service.dart │ │ │ └── state.dart │ │ ├── product_bloc │ │ │ ├── bloc.dart │ │ │ ├── event.dart │ │ │ ├── service.dart │ │ │ └── state.dart │ │ └── shop_bloc │ │ │ ├── bloc.dart │ │ │ ├── event.dart │ │ │ ├── service.dart │ │ │ └── state.dart │ ├── global │ │ ├── global_function.dart │ │ └── global_variable.dart │ ├── helpers │ │ ├── http_helper.dart │ │ ├── media_query_helper.dart │ │ ├── shared_preferences_helper.dart │ │ └── string_helper.dart │ ├── main.dart │ ├── models │ │ ├── account_model.dart │ │ ├── category_model.dart │ │ ├── favorite_model.dart │ │ ├── login_model.dart │ │ ├── ordering_model.dart │ │ ├── product_model.dart │ │ └── shop_account_model.dart │ ├── pages │ │ ├── account │ │ │ ├── account_page.dart │ │ │ └── login_page.dart │ │ ├── cart │ │ │ └── cart_page.dart │ │ ├── categories │ │ │ └── categories_page.dart │ │ ├── checkout │ │ │ └── check_out_page.dart │ │ ├── delivery_address │ │ │ ├── add_delivery_address_page.dart │ │ │ └── delivery_address_page.dart │ │ ├── favorite │ │ │ └── favorite_page.dart │ │ ├── home │ │ │ └── home_page.dart │ │ ├── navigator │ │ │ └── navigator_page.dart │ │ ├── notification │ │ │ └── notification_page.dart │ │ ├── ordering │ │ │ ├── ordering_detail_page.dart │ │ │ └── ordering_page.dart │ │ ├── product │ │ │ ├── product_detail_page.dart │ │ │ └── product_page.dart │ │ ├── search │ │ │ └── search_page.dart │ │ └── shop_account │ │ │ └── shop_account_detail_page.dart │ ├── routes.dart │ ├── themes │ │ ├── app_icon.dart │ │ └── constant.dart │ └── widgets │ │ ├── add_to_cart_effect.dart │ │ ├── app_bar.dart │ │ ├── base │ │ ├── animated_button.dart │ │ └── custom_ontap_widget.dart │ │ ├── bottom_navigation_bar.dart │ │ ├── custom_sliver_appbar.dart │ │ ├── debug_widget.dart │ │ ├── google_map │ │ └── custom_google_map.dart │ │ ├── graphic_widget.dart │ │ ├── image_viewer.dart │ │ ├── loading_dialog.dart │ │ ├── notification_item.dart │ │ ├── product_item.dart │ │ └── tab_view.dart ├── pubspec.lock ├── pubspec.yaml └── test │ └── widget_test.dart ├── api_SHOPii ├── .vs │ └── SHOPii │ │ ├── DesignTimeBuild │ │ ├── .dtbcache │ │ └── .dtbcache.v2 │ │ ├── config │ │ └── applicationhost.config │ │ └── v16 │ │ ├── .suo │ │ └── Server │ │ └── sqlite3 │ │ ├── db.lock │ │ └── storage.ide ├── SHOPii.sln └── SHOPii │ ├── .config │ └── dotnet-tools.json │ ├── .vscode │ ├── launch.json │ └── tasks.json │ ├── Controllers │ └── API │ │ ├── AccountsController.cs │ │ ├── CategoriesController.cs │ │ ├── DeliveryAddressesController.cs │ │ ├── FavoritesController.cs │ │ ├── OrderingDetailsController.cs │ │ ├── OrderingsController.cs │ │ ├── ProductImagesController.cs │ │ ├── ProductsController.cs │ │ └── ShopAccountsController.cs │ ├── Helpers │ └── QueryHelper.cs │ ├── Models │ ├── Account.cs │ ├── Category.cs │ ├── DeliveryAddress.cs │ ├── Favorite.cs │ ├── Ordering.cs │ ├── OrderingDetail.cs │ ├── Product.cs │ ├── ProductImage.cs │ ├── SHOPIIContext.cs │ └── ShopAccount.cs │ ├── Program.cs │ ├── Properties │ ├── PublishProfiles │ │ ├── IISProfile.pubxml │ │ └── IISProfile.pubxml.user │ └── launchSettings.json │ ├── SHOPii.csproj │ ├── SHOPii.csproj.user │ ├── Services │ └── UserService.cs │ ├── Startup.cs │ ├── appsettings.Development.json │ ├── appsettings.json │ └── obj │ └── Debug │ └── netcoreapp3.1 │ ├── .NETCoreApp,Version=v3.1.AssemblyAttributes.cs │ ├── SHOPii.AssemblyInfo.cs │ ├── SHOPii.AssemblyInfoInputs.cache │ └── SHOPii.csprojAssemblyReference.cache ├── sql_SHOPii └── sqlserver_backup /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | 2 | api_SHOPii/.vs/SHOPii/DesignTimeBuild/.dtbcache.v2 3 | api_SHOPii/.vs/SHOPii/v16/.suo 4 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # flutter_SHOPii - Ecommerce App with Flutter and ASP .NET Core 2 | 3 | ## Example Account to Login: 4 | ```bash 5 | ankiimation - 123456 6 | ``` 7 | 8 | ## Usage 9 | - If you dont care about ASP .net Core, just play with Flutter, the API was deployed ^^ 10 | - If you play with ASP .net Core or wanna use this project offline (for faster loading): 11 | + Open the API Project and run it with Visual Studio 12 | + Change the DOMAIN in http_helper.dart 13 | 14 | ## Images 15 | ![Login](https://github.com/ankiimation/flutter_SHOPii/blob/master/Screenshots/login.png) 16 | ![Home](https://github.com/ankiimation/flutter_SHOPii/blob/master/Screenshots/home.png) 17 | ![Cart](https://github.com/ankiimation/flutter_SHOPii/blob/master/Screenshots/cart.png) 18 | ![Checkout](https://github.com/ankiimation/flutter_SHOPii/blob/master/Screenshots/checkout.png) 19 | 20 | 21 | -------------------------------------------------------------------------------- /Screenshots/add_to_cart.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ankiimation/flutter_SHOPii/2c2a45bbcade33ea97f13302092b044b62a09fc6/Screenshots/add_to_cart.png -------------------------------------------------------------------------------- /Screenshots/cart.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ankiimation/flutter_SHOPii/2c2a45bbcade33ea97f13302092b044b62a09fc6/Screenshots/cart.png -------------------------------------------------------------------------------- /Screenshots/categories.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ankiimation/flutter_SHOPii/2c2a45bbcade33ea97f13302092b044b62a09fc6/Screenshots/categories.png -------------------------------------------------------------------------------- /Screenshots/checkout.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ankiimation/flutter_SHOPii/2c2a45bbcade33ea97f13302092b044b62a09fc6/Screenshots/checkout.png -------------------------------------------------------------------------------- /Screenshots/home.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ankiimation/flutter_SHOPii/2c2a45bbcade33ea97f13302092b044b62a09fc6/Screenshots/home.png -------------------------------------------------------------------------------- /Screenshots/login.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ankiimation/flutter_SHOPii/2c2a45bbcade33ea97f13302092b044b62a09fc6/Screenshots/login.png -------------------------------------------------------------------------------- /Screenshots/orders.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ankiimation/flutter_SHOPii/2c2a45bbcade33ea97f13302092b044b62a09fc6/Screenshots/orders.png -------------------------------------------------------------------------------- /Screenshots/orders_detail.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ankiimation/flutter_SHOPii/2c2a45bbcade33ea97f13302092b044b62a09fc6/Screenshots/orders_detail.png -------------------------------------------------------------------------------- /Screenshots/product_detail.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ankiimation/flutter_SHOPii/2c2a45bbcade33ea97f13302092b044b62a09fc6/Screenshots/product_detail.png -------------------------------------------------------------------------------- /Screenshots/profile.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ankiimation/flutter_SHOPii/2c2a45bbcade33ea97f13302092b044b62a09fc6/Screenshots/profile.png -------------------------------------------------------------------------------- /Screenshots/store_info.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ankiimation/flutter_SHOPii/2c2a45bbcade33ea97f13302092b044b62a09fc6/Screenshots/store_info.png -------------------------------------------------------------------------------- /ankii_shopii/.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 | # Symbolication related 37 | app.*.symbols 38 | 39 | # Obfuscation related 40 | app.*.map.json 41 | 42 | # Exceptions to above rules. 43 | !/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages 44 | -------------------------------------------------------------------------------- /ankii_shopii/.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: 1ad9baa8b99a2897c20f9e6e54d3b9b359ade314 8 | channel: stable 9 | 10 | project_type: app 11 | -------------------------------------------------------------------------------- /ankii_shopii/README.md: -------------------------------------------------------------------------------- 1 | # ankiishopii 2 | 3 | Simple Ecommerce App 4 | 5 | ## Getting Started 6 | 7 | This project is a starting point for a Flutter application. 8 | 9 | A few resources to get you started if this is your first Flutter project: 10 | 11 | - [Lab: Write your first Flutter app](https://flutter.dev/docs/get-started/codelab) 12 | - [Cookbook: Useful Flutter samples](https://flutter.dev/docs/cookbook) 13 | 14 | For help getting started with Flutter, view our 15 | [online documentation](https://flutter.dev/docs), which offers tutorials, 16 | samples, guidance on mobile development, and a full API reference. 17 | -------------------------------------------------------------------------------- /ankii_shopii/android/.gitignore: -------------------------------------------------------------------------------- 1 | gradle-wrapper.jar 2 | /.gradle 3 | /captures/ 4 | /gradlew 5 | /gradlew.bat 6 | /local.properties 7 | GeneratedPluginRegistrant.java 8 | -------------------------------------------------------------------------------- /ankii_shopii/android/app/build.gradle: -------------------------------------------------------------------------------- 1 | def localProperties = new Properties() 2 | def localPropertiesFile = rootProject.file('local.properties') 3 | if (localPropertiesFile.exists()) { 4 | localPropertiesFile.withReader('UTF-8') { reader -> 5 | localProperties.load(reader) 6 | } 7 | } 8 | 9 | def flutterRoot = localProperties.getProperty('flutter.sdk') 10 | if (flutterRoot == null) { 11 | throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.") 12 | } 13 | 14 | def flutterVersionCode = localProperties.getProperty('flutter.versionCode') 15 | if (flutterVersionCode == null) { 16 | flutterVersionCode = '1' 17 | } 18 | 19 | def flutterVersionName = localProperties.getProperty('flutter.versionName') 20 | if (flutterVersionName == null) { 21 | flutterVersionName = '1.0' 22 | } 23 | 24 | apply plugin: 'com.android.application' 25 | apply plugin: 'kotlin-android' 26 | apply plugin: 'com.google.gms.google-services' 27 | apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" 28 | 29 | android { 30 | compileSdkVersion 29 31 | 32 | sourceSets { 33 | main.java.srcDirs += 'src/main/kotlin' 34 | } 35 | 36 | lintOptions { 37 | disable 'InvalidPackage' 38 | } 39 | 40 | defaultConfig { 41 | // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). 42 | applicationId "com.ankii.shopii" 43 | minSdkVersion 21 44 | targetSdkVersion 29 45 | versionCode flutterVersionCode.toInteger() 46 | versionName flutterVersionName 47 | } 48 | 49 | buildTypes { 50 | release { 51 | // TODO: Add your own signing config for the release build. 52 | // Signing with the debug keys for now, so `flutter run --release` works. 53 | signingConfig signingConfigs.debug 54 | } 55 | } 56 | } 57 | 58 | flutter { 59 | source '../..' 60 | } 61 | 62 | dependencies { 63 | 64 | implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" 65 | } 66 | -------------------------------------------------------------------------------- /ankii_shopii/android/app/google-services.json: -------------------------------------------------------------------------------- 1 | { 2 | "project_info": { 3 | "project_number": "203210645878", 4 | "firebase_url": "https://shopii-c06aa.firebaseio.com", 5 | "project_id": "shopii-c06aa", 6 | "storage_bucket": "shopii-c06aa.appspot.com" 7 | }, 8 | "client": [ 9 | { 10 | "client_info": { 11 | "mobilesdk_app_id": "1:203210645878:android:7479e5bd34303b28ad9a57", 12 | "android_client_info": { 13 | "package_name": "com.ankii.shopii" 14 | } 15 | }, 16 | "oauth_client": [ 17 | { 18 | "client_id": "203210645878-rn430dfeiugpn0d5a2iei1314jvjq7kl.apps.googleusercontent.com", 19 | "client_type": 3 20 | } 21 | ], 22 | "api_key": [ 23 | { 24 | "current_key": "AIzaSyBztRkdhFSUrQRjpr3E7SwyBpEC-9xKqa4" 25 | } 26 | ], 27 | "services": { 28 | "appinvite_service": { 29 | "other_platform_oauth_client": [ 30 | { 31 | "client_id": "203210645878-rn430dfeiugpn0d5a2iei1314jvjq7kl.apps.googleusercontent.com", 32 | "client_type": 3 33 | } 34 | ] 35 | } 36 | } 37 | } 38 | ], 39 | "configuration_version": "1" 40 | } -------------------------------------------------------------------------------- /ankii_shopii/android/app/src/debug/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /ankii_shopii/android/app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 8 | 12 | 14 | 15 | 16 | 23 | 27 | 31 | 32 | 37 | 41 | 42 | 43 | 44 | 45 | 46 | 48 | 51 | 52 | 53 | 54 | -------------------------------------------------------------------------------- /ankii_shopii/android/app/src/main/kotlin/com/ankii/ankiishopii/MainActivity.kt: -------------------------------------------------------------------------------- 1 | package com.ankii.shopii 2 | 3 | import io.flutter.embedding.android.FlutterActivity 4 | 5 | class MainActivity: FlutterActivity() { 6 | } 7 | -------------------------------------------------------------------------------- /ankii_shopii/android/app/src/main/res/drawable/launch_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 12 | 13 | -------------------------------------------------------------------------------- /ankii_shopii/android/app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ankiimation/flutter_SHOPii/2c2a45bbcade33ea97f13302092b044b62a09fc6/ankii_shopii/android/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /ankii_shopii/android/app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ankiimation/flutter_SHOPii/2c2a45bbcade33ea97f13302092b044b62a09fc6/ankii_shopii/android/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /ankii_shopii/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ankiimation/flutter_SHOPii/2c2a45bbcade33ea97f13302092b044b62a09fc6/ankii_shopii/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /ankii_shopii/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ankiimation/flutter_SHOPii/2c2a45bbcade33ea97f13302092b044b62a09fc6/ankii_shopii/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /ankii_shopii/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ankiimation/flutter_SHOPii/2c2a45bbcade33ea97f13302092b044b62a09fc6/ankii_shopii/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /ankii_shopii/android/app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 9 | 15 | 18 | 19 | -------------------------------------------------------------------------------- /ankii_shopii/android/app/src/profile/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /ankii_shopii/android/build.gradle: -------------------------------------------------------------------------------- 1 | buildscript { 2 | ext.kotlin_version = '1.3.50' 3 | repositories { 4 | google() 5 | jcenter() 6 | } 7 | 8 | dependencies { 9 | classpath 'com.android.tools.build:gradle:3.5.0' 10 | classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" 11 | classpath 'com.google.gms:google-services:4.3.3' 12 | } 13 | } 14 | 15 | allprojects { 16 | repositories { 17 | google() 18 | jcenter() 19 | } 20 | } 21 | 22 | rootProject.buildDir = '../build' 23 | subprojects { 24 | project.buildDir = "${rootProject.buildDir}/${project.name}" 25 | } 26 | subprojects { 27 | project.evaluationDependsOn(':app') 28 | } 29 | 30 | task clean(type: Delete) { 31 | delete rootProject.buildDir 32 | } 33 | -------------------------------------------------------------------------------- /ankii_shopii/android/gradle.properties: -------------------------------------------------------------------------------- 1 | org.gradle.jvmargs=-Xmx1536M 2 | android.enableR8=true 3 | android.useAndroidX=true 4 | android.enableJetifier=true 5 | -------------------------------------------------------------------------------- /ankii_shopii/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 | -------------------------------------------------------------------------------- /ankii_shopii/android/settings.gradle: -------------------------------------------------------------------------------- 1 | // Copyright 2014 The Flutter Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | include ':app' 6 | 7 | def localPropertiesFile = new File(rootProject.projectDir, "local.properties") 8 | def properties = new Properties() 9 | 10 | assert localPropertiesFile.exists() 11 | localPropertiesFile.withReader("UTF-8") { reader -> properties.load(reader) } 12 | 13 | def flutterSdkPath = properties.getProperty("flutter.sdk") 14 | assert flutterSdkPath != null, "flutter.sdk not set in local.properties" 15 | apply from: "$flutterSdkPath/packages/flutter_tools/gradle/app_plugin_loader.gradle" 16 | -------------------------------------------------------------------------------- /ankii_shopii/assets/cliparts/cart_empty.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ankiimation/flutter_SHOPii/2c2a45bbcade33ea97f13302092b044b62a09fc6/ankii_shopii/assets/cliparts/cart_empty.png -------------------------------------------------------------------------------- /ankii_shopii/assets/fonts/IconFont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ankiimation/flutter_SHOPii/2c2a45bbcade33ea97f13302092b044b62a09fc6/ankii_shopii/assets/fonts/IconFont.ttf -------------------------------------------------------------------------------- /ankii_shopii/assets/fonts/Jura.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ankiimation/flutter_SHOPii/2c2a45bbcade33ea97f13302092b044b62a09fc6/ankii_shopii/assets/fonts/Jura.ttf -------------------------------------------------------------------------------- /ankii_shopii/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 | -------------------------------------------------------------------------------- /ankii_shopii/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 | -------------------------------------------------------------------------------- /ankii_shopii/ios/Flutter/Debug.xcconfig: -------------------------------------------------------------------------------- 1 | #include "Generated.xcconfig" 2 | -------------------------------------------------------------------------------- /ankii_shopii/ios/Flutter/Release.xcconfig: -------------------------------------------------------------------------------- 1 | #include "Generated.xcconfig" 2 | -------------------------------------------------------------------------------- /ankii_shopii/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /ankii_shopii/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /ankii_shopii/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | PreviewsEnabled 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /ankii_shopii/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 39 | 40 | 41 | 42 | 43 | 44 | 54 | 56 | 62 | 63 | 64 | 65 | 66 | 67 | 73 | 75 | 81 | 82 | 83 | 84 | 86 | 87 | 90 | 91 | 92 | -------------------------------------------------------------------------------- /ankii_shopii/ios/Runner.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /ankii_shopii/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /ankii_shopii/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | PreviewsEnabled 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /ankii_shopii/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 | -------------------------------------------------------------------------------- /ankii_shopii/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "size" : "20x20", 5 | "idiom" : "iphone", 6 | "filename" : "Icon-App-20x20@2x.png", 7 | "scale" : "2x" 8 | }, 9 | { 10 | "size" : "20x20", 11 | "idiom" : "iphone", 12 | "filename" : "Icon-App-20x20@3x.png", 13 | "scale" : "3x" 14 | }, 15 | { 16 | "size" : "29x29", 17 | "idiom" : "iphone", 18 | "filename" : "Icon-App-29x29@1x.png", 19 | "scale" : "1x" 20 | }, 21 | { 22 | "size" : "29x29", 23 | "idiom" : "iphone", 24 | "filename" : "Icon-App-29x29@2x.png", 25 | "scale" : "2x" 26 | }, 27 | { 28 | "size" : "29x29", 29 | "idiom" : "iphone", 30 | "filename" : "Icon-App-29x29@3x.png", 31 | "scale" : "3x" 32 | }, 33 | { 34 | "size" : "40x40", 35 | "idiom" : "iphone", 36 | "filename" : "Icon-App-40x40@2x.png", 37 | "scale" : "2x" 38 | }, 39 | { 40 | "size" : "40x40", 41 | "idiom" : "iphone", 42 | "filename" : "Icon-App-40x40@3x.png", 43 | "scale" : "3x" 44 | }, 45 | { 46 | "size" : "60x60", 47 | "idiom" : "iphone", 48 | "filename" : "Icon-App-60x60@2x.png", 49 | "scale" : "2x" 50 | }, 51 | { 52 | "size" : "60x60", 53 | "idiom" : "iphone", 54 | "filename" : "Icon-App-60x60@3x.png", 55 | "scale" : "3x" 56 | }, 57 | { 58 | "size" : "20x20", 59 | "idiom" : "ipad", 60 | "filename" : "Icon-App-20x20@1x.png", 61 | "scale" : "1x" 62 | }, 63 | { 64 | "size" : "20x20", 65 | "idiom" : "ipad", 66 | "filename" : "Icon-App-20x20@2x.png", 67 | "scale" : "2x" 68 | }, 69 | { 70 | "size" : "29x29", 71 | "idiom" : "ipad", 72 | "filename" : "Icon-App-29x29@1x.png", 73 | "scale" : "1x" 74 | }, 75 | { 76 | "size" : "29x29", 77 | "idiom" : "ipad", 78 | "filename" : "Icon-App-29x29@2x.png", 79 | "scale" : "2x" 80 | }, 81 | { 82 | "size" : "40x40", 83 | "idiom" : "ipad", 84 | "filename" : "Icon-App-40x40@1x.png", 85 | "scale" : "1x" 86 | }, 87 | { 88 | "size" : "40x40", 89 | "idiom" : "ipad", 90 | "filename" : "Icon-App-40x40@2x.png", 91 | "scale" : "2x" 92 | }, 93 | { 94 | "size" : "76x76", 95 | "idiom" : "ipad", 96 | "filename" : "Icon-App-76x76@1x.png", 97 | "scale" : "1x" 98 | }, 99 | { 100 | "size" : "76x76", 101 | "idiom" : "ipad", 102 | "filename" : "Icon-App-76x76@2x.png", 103 | "scale" : "2x" 104 | }, 105 | { 106 | "size" : "83.5x83.5", 107 | "idiom" : "ipad", 108 | "filename" : "Icon-App-83.5x83.5@2x.png", 109 | "scale" : "2x" 110 | }, 111 | { 112 | "size" : "1024x1024", 113 | "idiom" : "ios-marketing", 114 | "filename" : "Icon-App-1024x1024@1x.png", 115 | "scale" : "1x" 116 | } 117 | ], 118 | "info" : { 119 | "version" : 1, 120 | "author" : "xcode" 121 | } 122 | } 123 | -------------------------------------------------------------------------------- /ankii_shopii/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ankiimation/flutter_SHOPii/2c2a45bbcade33ea97f13302092b044b62a09fc6/ankii_shopii/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png -------------------------------------------------------------------------------- /ankii_shopii/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ankiimation/flutter_SHOPii/2c2a45bbcade33ea97f13302092b044b62a09fc6/ankii_shopii/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png -------------------------------------------------------------------------------- /ankii_shopii/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ankiimation/flutter_SHOPii/2c2a45bbcade33ea97f13302092b044b62a09fc6/ankii_shopii/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png -------------------------------------------------------------------------------- /ankii_shopii/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ankiimation/flutter_SHOPii/2c2a45bbcade33ea97f13302092b044b62a09fc6/ankii_shopii/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png -------------------------------------------------------------------------------- /ankii_shopii/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ankiimation/flutter_SHOPii/2c2a45bbcade33ea97f13302092b044b62a09fc6/ankii_shopii/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png -------------------------------------------------------------------------------- /ankii_shopii/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ankiimation/flutter_SHOPii/2c2a45bbcade33ea97f13302092b044b62a09fc6/ankii_shopii/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png -------------------------------------------------------------------------------- /ankii_shopii/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ankiimation/flutter_SHOPii/2c2a45bbcade33ea97f13302092b044b62a09fc6/ankii_shopii/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png -------------------------------------------------------------------------------- /ankii_shopii/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ankiimation/flutter_SHOPii/2c2a45bbcade33ea97f13302092b044b62a09fc6/ankii_shopii/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png -------------------------------------------------------------------------------- /ankii_shopii/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ankiimation/flutter_SHOPii/2c2a45bbcade33ea97f13302092b044b62a09fc6/ankii_shopii/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png -------------------------------------------------------------------------------- /ankii_shopii/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ankiimation/flutter_SHOPii/2c2a45bbcade33ea97f13302092b044b62a09fc6/ankii_shopii/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png -------------------------------------------------------------------------------- /ankii_shopii/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ankiimation/flutter_SHOPii/2c2a45bbcade33ea97f13302092b044b62a09fc6/ankii_shopii/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png -------------------------------------------------------------------------------- /ankii_shopii/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ankiimation/flutter_SHOPii/2c2a45bbcade33ea97f13302092b044b62a09fc6/ankii_shopii/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png -------------------------------------------------------------------------------- /ankii_shopii/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ankiimation/flutter_SHOPii/2c2a45bbcade33ea97f13302092b044b62a09fc6/ankii_shopii/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png -------------------------------------------------------------------------------- /ankii_shopii/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ankiimation/flutter_SHOPii/2c2a45bbcade33ea97f13302092b044b62a09fc6/ankii_shopii/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png -------------------------------------------------------------------------------- /ankii_shopii/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ankiimation/flutter_SHOPii/2c2a45bbcade33ea97f13302092b044b62a09fc6/ankii_shopii/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png -------------------------------------------------------------------------------- /ankii_shopii/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 | -------------------------------------------------------------------------------- /ankii_shopii/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ankiimation/flutter_SHOPii/2c2a45bbcade33ea97f13302092b044b62a09fc6/ankii_shopii/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png -------------------------------------------------------------------------------- /ankii_shopii/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ankiimation/flutter_SHOPii/2c2a45bbcade33ea97f13302092b044b62a09fc6/ankii_shopii/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png -------------------------------------------------------------------------------- /ankii_shopii/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ankiimation/flutter_SHOPii/2c2a45bbcade33ea97f13302092b044b62a09fc6/ankii_shopii/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png -------------------------------------------------------------------------------- /ankii_shopii/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. -------------------------------------------------------------------------------- /ankii_shopii/ios/Runner/Base.lproj/LaunchScreen.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 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /ankii_shopii/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 | -------------------------------------------------------------------------------- /ankii_shopii/ios/Runner/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | ankiishopii 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | $(FLUTTER_BUILD_NAME) 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | $(FLUTTER_BUILD_NUMBER) 23 | LSRequiresIPhoneOS 24 | 25 | UILaunchStoryboardName 26 | LaunchScreen 27 | UIMainStoryboardFile 28 | Main 29 | UISupportedInterfaceOrientations 30 | 31 | UIInterfaceOrientationPortrait 32 | UIInterfaceOrientationLandscapeLeft 33 | UIInterfaceOrientationLandscapeRight 34 | 35 | UISupportedInterfaceOrientations~ipad 36 | 37 | UIInterfaceOrientationPortrait 38 | UIInterfaceOrientationPortraitUpsideDown 39 | UIInterfaceOrientationLandscapeLeft 40 | UIInterfaceOrientationLandscapeRight 41 | 42 | UIViewControllerBasedStatusBarAppearance 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /ankii_shopii/ios/Runner/Runner-Bridging-Header.h: -------------------------------------------------------------------------------- 1 | #import "GeneratedPluginRegistrant.h" 2 | -------------------------------------------------------------------------------- /ankii_shopii/lib/blocs/account_bloc/bloc.dart: -------------------------------------------------------------------------------- 1 | import 'package:ankiishopii/blocs/account_bloc/event.dart'; 2 | import 'package:ankiishopii/blocs/account_bloc/service.dart'; 3 | import 'package:ankiishopii/blocs/account_bloc/state.dart'; 4 | import 'package:flutter_bloc/flutter_bloc.dart'; 5 | 6 | class AccountBloc extends Bloc { 7 | AccountBloc(AccountState initialState) : super(initialState); 8 | 9 | @override 10 | Stream mapEventToState(AccountEvent event) async* { 11 | // TODO: implement mapEventToState 12 | if (event is GetLocalAccount) { 13 | yield* mapLoginEventToState(event); 14 | } 15 | } 16 | 17 | Stream mapLoginEventToState(GetLocalAccount event) async* { 18 | var rs = await AccountService().getAccountFromLocal(); 19 | if (rs != null) { 20 | yield AccountLoaded(rs); 21 | } else { 22 | yield AccountLoadingFailed(); 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /ankii_shopii/lib/blocs/account_bloc/event.dart: -------------------------------------------------------------------------------- 1 | import 'package:equatable/equatable.dart'; 2 | 3 | class AccountEvent extends Equatable { 4 | @override 5 | // TODO: implement props 6 | List get props => []; 7 | } 8 | 9 | class GetLocalAccount extends AccountEvent { 10 | } 11 | -------------------------------------------------------------------------------- /ankii_shopii/lib/blocs/account_bloc/service.dart: -------------------------------------------------------------------------------- 1 | import 'dart:convert'; 2 | 3 | import 'package:ankiishopii/blocs/bloc_service.dart'; 4 | import 'package:ankiishopii/global/global_variable.dart'; 5 | import 'package:ankiishopii/helpers/http_helper.dart'; 6 | import 'package:ankiishopii/helpers/shared_preferences_helper.dart'; 7 | import 'package:ankiishopii/models/account_model.dart'; 8 | import 'package:ankiishopii/models/login_model.dart'; 9 | 10 | class AccountService extends BlocService { 11 | @override 12 | Future get(int id) { 13 | // TODO: implement get 14 | throw UnimplementedError(); 15 | } 16 | 17 | @override 18 | Future> getAll({int from = 0, int limit}) async { 19 | // TODO: implement getAll 20 | throw UnimplementedError(); 21 | } 22 | 23 | Future getAccountFromLocal() async { 24 | var login = await LocalHelper.getAccountFromLocal(); 25 | currentLogin = login; 26 | if (login != null) return login.account; 27 | return null; 28 | } 29 | 30 | Future _updateAccountInfoToLocal(AccountModel accountModel) async { 31 | var login = await LocalHelper.getAccountFromLocal(); 32 | login.account = accountModel; 33 | var account = await LocalHelper.saveAccountToLocal(login); 34 | currentLogin = login; 35 | return account; 36 | } 37 | 38 | Future updateDefaultDeliveryId(int deliveryId) async { 39 | var rs = await HttpHelper.put(ACCOUNT_ENDPOINT + "/defaultDeliveryId", {"deliveryId": deliveryId}, bearerToken: currentLogin.token); 40 | if (rs.statusCode == 200) { 41 | var jsonObject = jsonDecode(rs.body); 42 | var currentAccount = AccountModel.fromJson(jsonObject); 43 | return await _updateAccountInfoToLocal(currentAccount); 44 | } 45 | return null; 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /ankii_shopii/lib/blocs/account_bloc/state.dart: -------------------------------------------------------------------------------- 1 | import 'package:ankiishopii/models/account_model.dart'; 2 | import 'package:equatable/equatable.dart'; 3 | 4 | class AccountState extends Equatable{ 5 | @override 6 | // TODO: implement props 7 | List get props => []; 8 | 9 | } 10 | 11 | class AccountLoaded extends AccountState{ 12 | final AccountModel account; 13 | 14 | AccountLoaded(this.account); 15 | @override 16 | // TODO: implement props 17 | List get props => [account]; 18 | } 19 | class AccountLoadingFailed extends AccountState{} 20 | class AccountLoading extends AccountState{} -------------------------------------------------------------------------------- /ankii_shopii/lib/blocs/bloc_service.dart: -------------------------------------------------------------------------------- 1 | import 'dart:core'; 2 | 3 | abstract class BlocService { 4 | String getQueryString(Map condition) { 5 | String result = ''; 6 | for (var key in condition.keys) { 7 | String value = 8 | condition[key] == null ? '' : '${condition[key].toString()}'; 9 | result += '&$key=$value'; 10 | } 11 | //remove first & 12 | result = result.replaceFirst('&', ''); 13 | return result; 14 | } 15 | 16 | Future> getAll({int from = 0, int limit}); 17 | 18 | Future get(int id); 19 | } 20 | -------------------------------------------------------------------------------- /ankii_shopii/lib/blocs/cart_bloc/bloc.dart: -------------------------------------------------------------------------------- 1 | import 'dart:async'; 2 | 3 | import 'package:ankiishopii/blocs/cart_bloc/event.dart'; 4 | import 'package:ankiishopii/blocs/cart_bloc/service.dart'; 5 | import 'package:ankiishopii/blocs/cart_bloc/state.dart'; 6 | import 'package:ankiishopii/main.dart'; 7 | import 'package:ankiishopii/widgets/loading_dialog.dart'; 8 | import 'package:flutter/cupertino.dart'; 9 | import 'package:flutter_bloc/flutter_bloc.dart'; 10 | 11 | Timer _cartChangingTimer; 12 | 13 | onCartChange(Function onAddToCart) { 14 | if (_cartChangingTimer != null) _cartChangingTimer.cancel(); 15 | _cartChangingTimer = Timer(Duration(seconds: 2), onAddToCart); 16 | } 17 | 18 | class CartBloc extends Bloc { 19 | CartBloc() : super(CartLoading()); 20 | 21 | @override 22 | Stream mapEventToState(CartEvent event) async* { 23 | // TODO: implement mapEventToState 24 | if (event is LoadCart) { 25 | yield* mapLoadCartEventToState(event); 26 | } else if (event is AddToCart) { 27 | yield* mapAddToCartCartEventToState(event); 28 | } 29 | } 30 | 31 | Stream mapLoadCartEventToState(LoadCart event) async* { 32 | var rs = await CartService().getCurrentCart(); 33 | if (rs != null) { 34 | yield CartLoaded(rs); 35 | } else { 36 | yield CartError(); 37 | } 38 | } 39 | 40 | Stream mapAddToCartCartEventToState(AddToCart event) async* { 41 | await Future.delayed(Duration(seconds: 2)); 42 | var rs = await CartService().addToCart(event.productID, event.count); 43 | var refreshCart = await CartService().getCurrentCart(); 44 | if (rs != null) { 45 | yield CartLoaded(refreshCart); 46 | } else { 47 | yield CartError(); 48 | } 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /ankii_shopii/lib/blocs/cart_bloc/event.dart: -------------------------------------------------------------------------------- 1 | import 'package:equatable/equatable.dart'; 2 | import 'package:flutter/cupertino.dart'; 3 | 4 | class CartEvent extends Equatable { 5 | @override 6 | // TODO: implement props 7 | List get props => []; 8 | } 9 | 10 | class LoadCart extends CartEvent {} 11 | 12 | class AddToCart extends CartEvent { 13 | final int productID; 14 | final int count; 15 | 16 | AddToCart({@required this.productID, this.count = 1}); 17 | 18 | @override 19 | // TODO: implement props 20 | List get props => [productID, count]; 21 | } 22 | -------------------------------------------------------------------------------- /ankii_shopii/lib/blocs/cart_bloc/service.dart: -------------------------------------------------------------------------------- 1 | import 'dart:convert'; 2 | 3 | import 'package:ankiishopii/blocs/bloc_service.dart'; 4 | import 'package:ankiishopii/global/global_variable.dart'; 5 | import 'package:ankiishopii/helpers/http_helper.dart'; 6 | import 'package:ankiishopii/models/ordering_model.dart'; 7 | 8 | class CartService extends BlocService { 9 | @override 10 | Future get(int id) { 11 | // TODO: implement get 12 | throw UnimplementedError(); 13 | } 14 | 15 | @override 16 | Future> getAll({int from = 0, int limit}) { 17 | // TODO: implement getAll 18 | throw UnimplementedError(); 19 | } 20 | 21 | Future> getCurrentCart() async { 22 | var rs = await HttpHelper.get(CART_ENDPOINT, bearerToken: currentLogin.token); 23 | if (rs.statusCode == 200) { 24 | var jsonArray = jsonDecode(rs.body) as List; 25 | return jsonArray.map((json) => OrderingModel.fromJson(json)).toList(); 26 | } 27 | return null; 28 | } 29 | 30 | Future addToCart(int productId, int count) async { 31 | var rs = await HttpHelper.post(ORDERING_ENDPOINT + "/cart", {"productID": productId, "count": count}, 32 | bearerToken: currentLogin.token); 33 | if (rs.statusCode == 200) { 34 | var json = jsonDecode(rs.body); 35 | return OrderingModel.fromJson(json); 36 | } 37 | return null; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /ankii_shopii/lib/blocs/cart_bloc/state.dart: -------------------------------------------------------------------------------- 1 | import 'package:ankiishopii/models/ordering_model.dart'; 2 | import 'package:equatable/equatable.dart'; 3 | 4 | class CartState extends Equatable { 5 | @override 6 | // TODO: implement props 7 | List get props => []; 8 | } 9 | 10 | class CartLoaded extends CartState { 11 | List cart; 12 | 13 | CartLoaded(List cart) { 14 | List cartTemp = []; 15 | for (var ordering in cart) { 16 | if (!_isEmpty(ordering)) { 17 | ordering.orderingDetail = ordering.orderingDetail.where((od) => od.count > 0).toList(); 18 | cartTemp.add(ordering); 19 | } 20 | } 21 | this.cart = cartTemp; 22 | } 23 | 24 | @override 25 | // TODO: implement props 26 | List get props => [cart]; 27 | 28 | bool _isEmpty(OrderingModel orderingModel) { 29 | int totalQuantity = 0; 30 | for (var item in orderingModel.orderingDetail) { 31 | totalQuantity += item.count; 32 | } 33 | if (totalQuantity > 0) return false; 34 | return true; 35 | } 36 | } 37 | 38 | class CartError extends CartState {} 39 | 40 | class CartLoading extends CartState {} 41 | -------------------------------------------------------------------------------- /ankii_shopii/lib/blocs/category_bloc/bloc.dart: -------------------------------------------------------------------------------- 1 | import 'package:ankiishopii/blocs/category_bloc/event.dart'; 2 | import 'package:ankiishopii/blocs/category_bloc/service.dart'; 3 | import 'package:ankiishopii/blocs/category_bloc/state.dart'; 4 | import 'package:flutter_bloc/flutter_bloc.dart'; 5 | 6 | class CategoryBloc extends Bloc { 7 | CategoryBloc(CategoryState initialState) : super(initialState); 8 | 9 | @override 10 | Stream mapEventToState(CategoryEvent event) async* { 11 | // TODO: implement mapEventToState 12 | if (event is GetCategories) { 13 | yield* mapLoadEventToState(event); 14 | } 15 | } 16 | 17 | Stream mapLoadEventToState(GetCategories event) async* { 18 | // try { 19 | var rs = await CategoryService().getAll(); 20 | if (rs != null) { 21 | rs = rs.reversed.toList(); 22 | yield CategoriesLoaded(rs); 23 | } else { 24 | yield CategoriesLoadingError('List Null'); 25 | } 26 | // } catch (e) { 27 | // yield CategoriesLoadingError(e.toString()); 28 | // } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /ankii_shopii/lib/blocs/category_bloc/event.dart: -------------------------------------------------------------------------------- 1 | import 'package:equatable/equatable.dart'; 2 | 3 | class CategoryEvent extends Equatable{ 4 | @override 5 | // TODO: implement props 6 | List get props => []; 7 | 8 | } 9 | 10 | class GetCategories extends CategoryEvent{ 11 | } -------------------------------------------------------------------------------- /ankii_shopii/lib/blocs/category_bloc/service.dart: -------------------------------------------------------------------------------- 1 | import 'dart:convert'; 2 | import 'dart:io'; 3 | import 'package:ankiishopii/blocs/bloc_service.dart'; 4 | import 'package:ankiishopii/helpers/http_helper.dart'; 5 | import 'package:ankiishopii/models/category_model.dart'; 6 | 7 | class CategoryService extends BlocService { 8 | CategoryService._(); 9 | 10 | static CategoryService _instance; 11 | 12 | factory CategoryService() { 13 | if (_instance == null) { 14 | _instance = CategoryService._(); 15 | } 16 | return _instance; 17 | } 18 | 19 | @override 20 | Future get(int id) async { 21 | // TODO: implement get 22 | var rs = await HttpHelper.get(CATEGORY_ENDPOINT + "/$id"); 23 | if (rs.statusCode == 200) { 24 | var json = jsonDecode(rs.body); 25 | // print(jsonList.toList()); 26 | return CategoryModel.fromJson(json); 27 | } 28 | return null; 29 | } 30 | 31 | @override 32 | Future> getAll({int from = 0, int limit}) async { 33 | // TODO: implement getAll 34 | var rs = await HttpHelper.get(CATEGORY_ENDPOINT); 35 | if (rs.statusCode == 200) { 36 | var jsonList = jsonDecode(rs.body) as List; 37 | // print(jsonList.toList()); 38 | return jsonList.map((j) => CategoryModel.fromJson(j)).toList(); 39 | } 40 | return null; 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /ankii_shopii/lib/blocs/category_bloc/state.dart: -------------------------------------------------------------------------------- 1 | import 'package:ankiishopii/models/category_model.dart'; 2 | import 'package:equatable/equatable.dart'; 3 | 4 | class CategoryState extends Equatable { 5 | @override 6 | // TODO: implement props 7 | List get props => []; 8 | } 9 | 10 | class CategoriesLoaded extends CategoryState { 11 | final List categories; 12 | 13 | CategoriesLoaded(this.categories); 14 | 15 | @override 16 | // TODO: implement props 17 | List get props => [categories]; 18 | } 19 | 20 | class CategoriesLoading extends CategoryState {} 21 | 22 | class CategoriesLoadingError extends CategoryState { 23 | final String error; 24 | 25 | CategoriesLoadingError(this.error); 26 | @override 27 | // TODO: implement props 28 | List get props => [error]; 29 | } 30 | -------------------------------------------------------------------------------- /ankii_shopii/lib/blocs/checkout_bloc/bloc.dart: -------------------------------------------------------------------------------- 1 | import 'package:ankiishopii/blocs/checkout_bloc/event.dart'; 2 | import 'package:ankiishopii/blocs/checkout_bloc/service.dart'; 3 | import 'package:ankiishopii/blocs/checkout_bloc/state.dart'; 4 | import 'package:flutter_bloc/flutter_bloc.dart'; 5 | 6 | class CheckoutBloc extends Bloc { 7 | CheckoutBloc() : super(CheckoutLoading()); 8 | 9 | @override 10 | Stream mapEventToState(CheckoutEvent event) async* { 11 | // TODO: implement mapEventToState 12 | if (event is GetCheckout) { 13 | yield* mapGetCheckoutToState(event); 14 | } 15 | if (event is DoCheckout) { 16 | yield* mapDoCheckoutToState(event); 17 | } 18 | } 19 | 20 | Stream mapGetCheckoutToState(GetCheckout event) async* { 21 | var rs = await CheckoutService().get(event.orderingModel.id); 22 | if (rs != null) { 23 | rs.orderingDetail = rs.orderingDetail.where((od) => od.count > 0).toList(); 24 | yield CheckoutLoaded(rs); 25 | } else { 26 | yield CheckoutLoadError(); 27 | } 28 | } 29 | 30 | Stream mapDoCheckoutToState(DoCheckout event) async* { 31 | var rs = await CheckoutService().checkOut(event.orderingModel, status: event.status, deliveryId: event.deliveryId); 32 | if (rs != null) { 33 | rs.orderingDetail = rs.orderingDetail.where((od) => od.count > 0).toList(); 34 | yield DoCheckoutSuccessfully(); 35 | } else { 36 | yield DoCheckoutFailed(); 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /ankii_shopii/lib/blocs/checkout_bloc/event.dart: -------------------------------------------------------------------------------- 1 | import 'package:ankiishopii/models/account_model.dart'; 2 | import 'package:ankiishopii/models/ordering_model.dart'; 3 | import 'package:equatable/equatable.dart'; 4 | import 'package:flutter/cupertino.dart'; 5 | 6 | class CheckoutEvent extends Equatable { 7 | @override 8 | // TODO: implement props 9 | List get props => []; 10 | } 11 | 12 | 13 | class GetCheckout extends CheckoutEvent{ 14 | final OrderingModel orderingModel; 15 | 16 | GetCheckout(this.orderingModel); 17 | @override 18 | // TODO: implement props 19 | List get props => [orderingModel]; 20 | } 21 | class DoCheckout extends CheckoutEvent { 22 | final OrderingModel orderingModel; 23 | final int status; 24 | final int deliveryId; 25 | 26 | DoCheckout({@required this.orderingModel, this.status = 0, this.deliveryId = -1}); 27 | 28 | @override 29 | // TODO: implement props 30 | List get props => [orderingModel, status, deliveryId]; 31 | } 32 | -------------------------------------------------------------------------------- /ankii_shopii/lib/blocs/checkout_bloc/service.dart: -------------------------------------------------------------------------------- 1 | import 'dart:convert'; 2 | 3 | import 'package:ankiishopii/blocs/bloc_service.dart'; 4 | import 'package:ankiishopii/global/global_variable.dart'; 5 | import 'package:ankiishopii/helpers/http_helper.dart'; 6 | import 'package:ankiishopii/models/ordering_model.dart'; 7 | 8 | class CheckoutService extends BlocService { 9 | @override 10 | Future get(int id) async { 11 | // TODO: implement get 12 | var rs = await HttpHelper.get('$ORDERING_ENDPOINT/$id', bearerToken: currentLogin.token); 13 | if (rs.statusCode == 200) { 14 | var json = jsonDecode(rs.body); 15 | return OrderingModel.fromJson(json); 16 | } 17 | return null; 18 | } 19 | 20 | @override 21 | Future> getAll({int from = 0, int limit}) async { 22 | // TODO: implement getAll 23 | var rs = await HttpHelper.get(ORDERING_ENDPOINT, bearerToken: currentLogin.token); 24 | if (rs.statusCode == 200) { 25 | var jsonArray = jsonDecode(rs.body) as List; 26 | return jsonArray.map((j) => OrderingModel.fromJson(j)).toList(); 27 | } 28 | return null; 29 | } 30 | 31 | // Future> getCheckOut(List orderingModels) async { 32 | // var rs = await HttpHelper.get(ORDERING_ENDPOINT, bearerToken: currentLogin.token); 33 | // if (rs.statusCode == 200) { 34 | // var jsonArray = jsonDecode(rs.body) as List; 35 | // return jsonArray 36 | // .map((j) => OrderingModel.fromJson(j)) 37 | // .where((orderingModel) => orderingModel.status == 0) 38 | // .toList(); 39 | // } 40 | // return null; 41 | // } 42 | 43 | Future checkOut(OrderingModel orderingModel, {int status, int deliveryId}) async { 44 | var rs = await HttpHelper.post( 45 | CHECKOUT_ENDPOINT, 46 | { 47 | "orderingId": orderingModel.id, 48 | "deliveryId": deliveryId ?? orderingModel.deliveryId, 49 | "status": status ?? orderingModel.status 50 | }, 51 | bearerToken: currentLogin.token); 52 | if (rs.statusCode == 200) { 53 | var json = jsonDecode(rs.body); 54 | return OrderingModel.fromJson(json); 55 | } 56 | return null; 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /ankii_shopii/lib/blocs/checkout_bloc/state.dart: -------------------------------------------------------------------------------- 1 | import 'package:ankiishopii/models/ordering_model.dart'; 2 | import 'package:equatable/equatable.dart'; 3 | 4 | class CheckoutState extends Equatable { 5 | @override 6 | // TODO: implement props 7 | List get props => []; 8 | } 9 | 10 | class CheckoutLoaded extends CheckoutState { 11 | final OrderingModel checkoutModel; 12 | 13 | CheckoutLoaded(this.checkoutModel); 14 | 15 | @override 16 | // TODO: implement props 17 | List get props => [checkoutModel]; 18 | } 19 | 20 | class DoCheckoutSuccessfully extends CheckoutState {} 21 | 22 | class DoCheckoutLoading extends CheckoutState {} 23 | 24 | class DoCheckoutFailed extends CheckoutState {} 25 | 26 | class CheckoutLoading extends CheckoutState {} 27 | 28 | class CheckoutLoadError extends CheckoutState {} 29 | 30 | class CheckoutFailed extends CheckoutState {} 31 | -------------------------------------------------------------------------------- /ankii_shopii/lib/blocs/delivery_address_bloc/bloc.dart: -------------------------------------------------------------------------------- 1 | import 'dart:convert'; 2 | 3 | import 'package:ankiishopii/blocs/account_bloc/service.dart'; 4 | import 'package:ankiishopii/blocs/delivery_address_bloc/event.dart'; 5 | import 'package:ankiishopii/blocs/delivery_address_bloc/service.dart'; 6 | import 'package:ankiishopii/blocs/delivery_address_bloc/state.dart'; 7 | import 'package:ankiishopii/global/global_variable.dart'; 8 | import 'package:ankiishopii/models/account_model.dart'; 9 | import 'package:flutter_bloc/flutter_bloc.dart'; 10 | 11 | class DeliveryAddressBloc 12 | extends Bloc { 13 | DeliveryAddressBloc() : super(DeliveryAddressLoading()); 14 | 15 | @override 16 | Stream mapEventToState( 17 | DeliveryAddressEvent event) async* { 18 | // TODO: implement mapEventToState 19 | if (event is GetAllDeliveryAddresses) { 20 | yield* mapGetAllDeliveryAddressesToState(event); 21 | } else if (event is GetDeliveryAddress) { 22 | yield* mapGetDeliveryAddressToState(event); 23 | } else if (event is SetDefaultDeliveryAddress) { 24 | yield* mapSetDefaultDeliveryAddressToState(event); 25 | } 26 | } 27 | 28 | Stream mapGetAllDeliveryAddressesToState( 29 | GetAllDeliveryAddresses event) async* { 30 | var rs = await DeliveryAddressService().getAll(); 31 | if (rs != null) { 32 | yield AllDeliveryAddressesLoaded(rs); 33 | } else { 34 | yield DeliveryAddressLoadFailed(); 35 | } 36 | } 37 | 38 | Stream mapGetDeliveryAddressToState( 39 | GetDeliveryAddress event) async* { 40 | var rs = await DeliveryAddressService().get(event.id); 41 | if (rs != null) { 42 | yield DeliveryAddressLoaded(rs); 43 | } else { 44 | yield DeliveryAddressLoadFailed(); 45 | } 46 | } 47 | 48 | Stream mapSetDefaultDeliveryAddressToState( 49 | SetDefaultDeliveryAddress event) async* { 50 | await Future.delayed(Duration(seconds: 2)); 51 | await AccountService().updateDefaultDeliveryId(event.id); 52 | var rs = await DeliveryAddressService().getAll(); 53 | if (rs != null) { 54 | yield AllDeliveryAddressesLoaded(rs); 55 | } else { 56 | yield DeliveryAddressLoadFailed(); 57 | } 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /ankii_shopii/lib/blocs/delivery_address_bloc/event.dart: -------------------------------------------------------------------------------- 1 | import 'package:ankiishopii/models/account_model.dart'; 2 | import 'package:equatable/equatable.dart'; 3 | 4 | class DeliveryAddressEvent extends Equatable { 5 | @override 6 | // TODO: implement props 7 | List get props => []; 8 | } 9 | 10 | class GetAllDeliveryAddresses extends DeliveryAddressEvent {} 11 | 12 | class GetDeliveryAddress extends DeliveryAddressEvent { 13 | final int id; 14 | 15 | GetDeliveryAddress(this.id); 16 | 17 | @override 18 | // TODO: implement props 19 | 20 | List get props => [id]; 21 | } 22 | 23 | class SetDefaultDeliveryAddress extends DeliveryAddressEvent { 24 | final int id; 25 | 26 | SetDefaultDeliveryAddress(this.id); 27 | 28 | @override 29 | // TODO: implement props 30 | List get props => [id]; 31 | } 32 | 33 | class AddDeliveryAddress extends DeliveryAddressEvent { 34 | final DeliveryAddressModel deliveryAddressModel; 35 | 36 | AddDeliveryAddress(this.deliveryAddressModel); 37 | 38 | @override 39 | // TODO: implement props 40 | List get props => [deliveryAddressModel]; 41 | } 42 | -------------------------------------------------------------------------------- /ankii_shopii/lib/blocs/delivery_address_bloc/service.dart: -------------------------------------------------------------------------------- 1 | import 'dart:convert'; 2 | 3 | import 'package:ankiishopii/blocs/bloc_service.dart'; 4 | import 'package:ankiishopii/global/global_variable.dart'; 5 | import 'package:ankiishopii/helpers/http_helper.dart'; 6 | import 'package:ankiishopii/models/account_model.dart'; 7 | 8 | class DeliveryAddressService extends BlocService { 9 | @override 10 | Future get(int id) async { 11 | // TODO: implement get 12 | var rs = await HttpHelper.get('$DELIVERY_ADDRESS_ENDPOINT/$id', bearerToken: currentLogin.token); 13 | if (rs.statusCode == 200) { 14 | var json = jsonDecode(rs.body); 15 | return DeliveryAddressModel.fromJson(json); 16 | } 17 | return null; 18 | } 19 | 20 | @override 21 | Future> getAll({int from = 0, int limit}) async { 22 | // TODO: implement getAll 23 | var rs = await HttpHelper.get(DELIVERY_ADDRESS_ENDPOINT, bearerToken: currentLogin.token); 24 | if (rs.statusCode == 200) { 25 | var jsonArray = jsonDecode(rs.body) as List; 26 | return jsonArray.map((j) => DeliveryAddressModel.fromJson(j)).toList(); 27 | } 28 | return null; 29 | } 30 | 31 | Future addDeliveryAddress(DeliveryAddressModel deliveryAddressModel) async { 32 | var rs = await HttpHelper.post( 33 | DELIVERY_ADDRESS_ENDPOINT, 34 | { 35 | "fullname": deliveryAddressModel.fullname, 36 | "address": deliveryAddressModel.address, 37 | "phoneNumber": deliveryAddressModel.phoneNumber, 38 | "latitude": deliveryAddressModel.latitude, 39 | "longitude": deliveryAddressModel.longitude 40 | }, 41 | bearerToken: currentLogin.token); 42 | print(rs.body); 43 | if (rs.statusCode == 200) { 44 | var jsonObject = jsonDecode(rs.body); 45 | return DeliveryAddressModel.fromJson(jsonObject); 46 | } 47 | return null; 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /ankii_shopii/lib/blocs/delivery_address_bloc/state.dart: -------------------------------------------------------------------------------- 1 | import 'package:ankiishopii/models/account_model.dart'; 2 | import 'package:equatable/equatable.dart'; 3 | 4 | class DeliveryAddressState extends Equatable { 5 | @override 6 | // TODO: implement props 7 | List get props => []; 8 | } 9 | 10 | class AllDeliveryAddressesLoaded extends DeliveryAddressState { 11 | final List deliveryAddresses; 12 | 13 | AllDeliveryAddressesLoaded(this.deliveryAddresses); 14 | 15 | @override 16 | // TODO: implement props 17 | List get props => [deliveryAddresses]; 18 | } 19 | 20 | class DeliveryAddressLoaded extends DeliveryAddressState { 21 | final DeliveryAddressModel deliveryAddress; 22 | 23 | DeliveryAddressLoaded(this.deliveryAddress); 24 | 25 | @override 26 | // TODO: implement props 27 | List get props => [deliveryAddress]; 28 | } 29 | 30 | class DeliveryAddressLoading extends DeliveryAddressState {} 31 | 32 | class DeliveryAddressLoadFailed extends DeliveryAddressState {} 33 | -------------------------------------------------------------------------------- /ankii_shopii/lib/blocs/favorite_bloc/bloc.dart: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ankiimation/flutter_SHOPii/2c2a45bbcade33ea97f13302092b044b62a09fc6/ankii_shopii/lib/blocs/favorite_bloc/bloc.dart -------------------------------------------------------------------------------- /ankii_shopii/lib/blocs/favorite_bloc/event.dart: -------------------------------------------------------------------------------- 1 | import 'package:equatable/equatable.dart'; 2 | 3 | class FavoriteEvent extends Equatable{ 4 | @override 5 | // TODO: implement props 6 | List get props => []; 7 | 8 | } 9 | class GetCurrentFavoriteFromProductId extends FavoriteEvent{ 10 | final int productID; 11 | 12 | GetCurrentFavoriteFromProductId(this.productID); 13 | @override 14 | // TODO: implement props 15 | List get props => [productID]; 16 | } -------------------------------------------------------------------------------- /ankii_shopii/lib/blocs/favorite_bloc/service.dart: -------------------------------------------------------------------------------- 1 | import 'dart:convert'; 2 | 3 | import 'package:ankiishopii/blocs/bloc_service.dart'; 4 | import 'package:ankiishopii/global/global_variable.dart'; 5 | import 'package:ankiishopii/helpers/http_helper.dart'; 6 | import 'package:ankiishopii/helpers/shared_preferences_helper.dart'; 7 | import 'package:ankiishopii/models/favorite_model.dart'; 8 | import 'package:flutter/material.dart'; 9 | 10 | class FavoriteService extends BlocService { 11 | @override 12 | Future get(int id) async { 13 | // TODO: implement get 14 | var rs = await HttpHelper.get(FAVORITE_ENDPOINT + '/$id', bearerToken: currentLogin.token); 15 | if (rs.statusCode == 200 || rs.statusCode == 201) { 16 | var jsonObject = jsonDecode(rs.body); 17 | var favorite = FavoriteModel.fromJson(jsonObject); 18 | _updateCurrentAccountFavorite(favorite); 19 | return favorite; 20 | } 21 | return null; 22 | } 23 | 24 | @override 25 | Future> getAll({int from = 0, int limit}) async { 26 | // TODO: implement getAll 27 | var rs = await HttpHelper.get(FAVORITE_ENDPOINT, bearerToken: currentLogin.token); 28 | if (rs.statusCode == 200 || rs.statusCode == 201) { 29 | var jsonArray = jsonDecode(rs.body) as List; 30 | var favorites = jsonArray.map((json) => FavoriteModel.fromJson(json)).toList(); 31 | await _updateCurrentAccountFavorites(favorites); 32 | return favorites; 33 | } 34 | return null; 35 | } 36 | 37 | Future _updateCurrentAccountFavorites(List favorites) async { 38 | currentLogin.account.favorite = favorites; 39 | await LocalHelper.saveAccountToLocal(currentLogin); 40 | } 41 | 42 | Future _updateCurrentAccountFavorite(FavoriteModel favorite) async { 43 | var currentFavorite = 44 | currentLogin.account.favorite.firstWhere((favoriteTemp) => favoriteTemp.id == favorite.id, orElse: () => null); 45 | if (currentFavorite != null) { 46 | currentLogin.account.favorite.remove(currentFavorite); 47 | } 48 | currentLogin.account.favorite.add(favorite); 49 | await LocalHelper.saveAccountToLocal(currentLogin); 50 | } 51 | 52 | Future doFavorite({@required int productID}) async { 53 | var rs = await HttpHelper.post(FAVORITE_ENDPOINT, {'productID': productID}, bearerToken: currentLogin.token); 54 | if (rs.statusCode == 200 || rs.statusCode == 201) { 55 | // print(rs.body); 56 | var jsonObject = jsonDecode(rs.body); 57 | var favorite = FavoriteModel.fromJson(jsonObject); 58 | await _updateCurrentAccountFavorite(favorite); 59 | return favorite; 60 | } 61 | return null; 62 | } 63 | 64 | FavoriteModel getFavoriteFromLocalByProductId(int productID) { 65 | // print(currentLogin.account.favorite.map((e) => e.productId).toList()); 66 | if (currentLogin == null) { 67 | return null; 68 | } 69 | return currentLogin.account.favorite.firstWhere((favorite) => favorite.productId == productID, orElse: () => null); 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /ankii_shopii/lib/blocs/favorite_bloc/state.dart: -------------------------------------------------------------------------------- 1 | import 'package:equatable/equatable.dart'; 2 | 3 | class FavoriteState extends Equatable { 4 | @override 5 | // TODO: implement props 6 | List get props => []; 7 | } 8 | 9 | class FavoriteLoaded extends FavoriteState {} 10 | -------------------------------------------------------------------------------- /ankii_shopii/lib/blocs/login_bloc/bloc.dart: -------------------------------------------------------------------------------- 1 | import 'package:ankiishopii/blocs/login_bloc/event.dart'; 2 | import 'package:ankiishopii/blocs/login_bloc/service.dart'; 3 | import 'package:ankiishopii/blocs/login_bloc/state.dart'; 4 | import 'package:ankiishopii/global/global_variable.dart'; 5 | import 'package:flutter_bloc/flutter_bloc.dart'; 6 | 7 | class LoginBloc extends Bloc { 8 | LoginBloc() : super(LoginInit()); 9 | 10 | @override 11 | Stream mapEventToState(LoginEvent event) async* { 12 | // TODO: implement mapEventToState 13 | if (event is LoginNow) { 14 | yield* mapLoginNowToState(event); 15 | } else if (event is GetCurrentLogin) { 16 | yield* mapGetCurrentLoginToState(event); 17 | } 18 | } 19 | 20 | Stream mapLoginNowToState(LoginNow event) async* { 21 | var rs = await LoginService().logIn(event.username, event.password); 22 | if (rs != null) { 23 | yield LoginSuccessfully(rs); 24 | } else { 25 | yield LoginFailed(); 26 | } 27 | } 28 | 29 | Stream mapGetCurrentLoginToState(GetCurrentLogin event) async* { 30 | var rs = await LoginService().getCurrentLogin(); 31 | if (rs != null) { 32 | yield LoginSuccessfully(rs); 33 | } else { 34 | yield LoginFailed(); 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /ankii_shopii/lib/blocs/login_bloc/event.dart: -------------------------------------------------------------------------------- 1 | import 'package:equatable/equatable.dart'; 2 | 3 | class LoginEvent extends Equatable { 4 | @override 5 | // TODO: implement props 6 | List get props => []; 7 | } 8 | 9 | class LoginNow extends LoginEvent { 10 | final String username; 11 | final String password; 12 | 13 | LoginNow(this.username, this.password); 14 | 15 | @override 16 | // TODO: implement props 17 | List get props => [username, password]; 18 | } 19 | 20 | class GetCurrentLogin extends LoginEvent{} 21 | 22 | class LogOutNow extends LoginEvent{ 23 | } 24 | -------------------------------------------------------------------------------- /ankii_shopii/lib/blocs/login_bloc/service.dart: -------------------------------------------------------------------------------- 1 | import 'dart:convert'; 2 | 3 | import 'package:ankiishopii/blocs/account_bloc/service.dart'; 4 | import 'package:ankiishopii/blocs/bloc_service.dart'; 5 | import 'package:ankiishopii/global/global_variable.dart'; 6 | import 'package:ankiishopii/helpers/http_helper.dart'; 7 | import 'package:ankiishopii/helpers/shared_preferences_helper.dart'; 8 | import 'package:ankiishopii/models/account_model.dart'; 9 | import 'package:ankiishopii/models/login_model.dart'; 10 | 11 | class LoginService extends BlocService { 12 | @override 13 | Future get(int id) { 14 | // TODO: implement get 15 | throw UnimplementedError(); 16 | } 17 | 18 | @override 19 | Future> getAll({int from = 0, int limit}) { 20 | // TODO: implement getAll 21 | throw UnimplementedError(); 22 | } 23 | 24 | Future getCurrentLogin() async { 25 | var rs = await LocalHelper.getAccountFromLocal(); 26 | currentLogin = rs; 27 | return currentLogin; 28 | } 29 | 30 | Future logIn(String username, String password) async { 31 | Map accountInput = {"username": username, "password": password}; 32 | var rs = await HttpHelper.post(LOGIN_ENDPOINT, accountInput); 33 | print(rs.statusCode); 34 | if (rs.statusCode == 200) { 35 | var jsonObject = jsonDecode(rs.body); 36 | var account = LoginModel.fromJson(jsonObject); 37 | currentLogin = account; 38 | LocalHelper.saveAccountToLocal(account); 39 | 40 | return account; 41 | } 42 | return null; 43 | } 44 | 45 | Future logOut() async { 46 | currentLogin = null; 47 | return await LocalHelper.deleteAccountFromLocal(); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /ankii_shopii/lib/blocs/login_bloc/state.dart: -------------------------------------------------------------------------------- 1 | import 'package:ankiishopii/models/account_model.dart'; 2 | import 'package:ankiishopii/models/login_model.dart'; 3 | import 'package:equatable/equatable.dart'; 4 | 5 | class LoginState extends Equatable { 6 | @override 7 | // TODO: implement props 8 | List get props => []; 9 | } 10 | class LoginSuccessfully extends LoginState{ 11 | final LoginModel accountModel; 12 | 13 | LoginSuccessfully(this.accountModel); 14 | @override 15 | // TODO: implement props 16 | List get props => [accountModel]; 17 | } 18 | 19 | class LoginFailed extends LoginState{} 20 | class LoginLoading extends LoginState{} 21 | class LoginInit extends LoginState{} -------------------------------------------------------------------------------- /ankii_shopii/lib/blocs/ordering_bloc/bloc.dart: -------------------------------------------------------------------------------- 1 | import 'package:ankiishopii/blocs/checkout_bloc/service.dart'; 2 | import 'package:ankiishopii/blocs/ordering_bloc/event.dart'; 3 | import 'package:ankiishopii/blocs/ordering_bloc/service.dart'; 4 | import 'package:ankiishopii/blocs/ordering_bloc/state.dart'; 5 | import 'package:ankiishopii/models/ordering_model.dart'; 6 | import 'package:flutter_bloc/flutter_bloc.dart'; 7 | 8 | class OrderingBloc extends Bloc { 9 | OrderingBloc(OrderingState initialState) : super(initialState); 10 | 11 | @override 12 | Stream mapEventToState(OrderingEvent event) async* { 13 | // TODO: implement mapEventToState 14 | if (event is GetOrdering) { 15 | yield* mapGetOrderingToState(event); 16 | } else if (event is GetAllOrdering) { 17 | yield* mapGetAllOrderingToState(event); 18 | } 19 | } 20 | 21 | Stream mapGetOrderingToState(GetOrdering event) async* { 22 | var rs = await OrderingService().get(event.id); 23 | if (rs != null) { 24 | rs.orderingDetail = rs.orderingDetail.where((od) => od.count > 0).toList(); 25 | yield OrderingLoaded(rs); 26 | } else { 27 | yield OrderingLoadError(); 28 | } 29 | } 30 | 31 | Stream mapGetAllOrderingToState(GetAllOrdering event) async* { 32 | try { 33 | var rs = await OrderingService().getAll(); 34 | if (rs != null) { 35 | yield AllOrderingLoaded(rs); 36 | } else { 37 | yield AllOrderingLoadError('Null'); 38 | } 39 | } catch (e) { 40 | yield AllOrderingLoadError('Not Logged In'); 41 | } 42 | } 43 | 44 | cancelOrdering(int orderingId) async { 45 | await OrderingService().cancelOrdering(orderingId); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /ankii_shopii/lib/blocs/ordering_bloc/event.dart: -------------------------------------------------------------------------------- 1 | import 'package:equatable/equatable.dart'; 2 | 3 | class OrderingEvent extends Equatable { 4 | @override 5 | // TODO: implement props 6 | List get props => []; 7 | } 8 | 9 | class GetAllOrdering extends OrderingEvent{} 10 | class GetOrdering extends OrderingEvent { 11 | final int id; 12 | 13 | GetOrdering(this.id); 14 | 15 | @override 16 | // TODO: implement props 17 | List get props => [id]; 18 | } 19 | -------------------------------------------------------------------------------- /ankii_shopii/lib/blocs/ordering_bloc/service.dart: -------------------------------------------------------------------------------- 1 | import 'dart:convert'; 2 | 3 | import 'package:ankiishopii/blocs/bloc_service.dart'; 4 | import 'package:ankiishopii/blocs/product_bloc/service.dart'; 5 | import 'package:ankiishopii/global/global_variable.dart'; 6 | import 'package:ankiishopii/helpers/http_helper.dart'; 7 | import 'package:ankiishopii/models/ordering_model.dart'; 8 | 9 | class OrderingService extends BlocService { 10 | @override 11 | Future get(int id) async { 12 | // TODO: implement get 13 | var rs = await HttpHelper.get('$ORDERING_ENDPOINT/$id', bearerToken: currentLogin.token); 14 | if (rs.statusCode == 200) { 15 | var json = jsonDecode(rs.body); 16 | return OrderingModel.fromJson(json); 17 | } 18 | return null; 19 | } 20 | 21 | @override 22 | Future> getAll({int from = 0, int limit}) async { 23 | // TODO: implement getAll 24 | var rs = await HttpHelper.get(ORDERING_ENDPOINT, bearerToken: currentLogin.token); 25 | if (rs.statusCode == 200) { 26 | var jsonArray = jsonDecode(rs.body) as List; 27 | var orderings = jsonArray.map((json) => OrderingModel.fromJson(json)).toList(); 28 | orderings = orderings.where((o) => o.status != 0).toList(); 29 | for (var order in orderings) { 30 | var ods = order.orderingDetail; 31 | for (var od in ods) { 32 | if (od.product == null) { 33 | od.product = await ProductService().get(od.productId); 34 | } 35 | } 36 | } 37 | return orderings; 38 | } 39 | return null; 40 | } 41 | 42 | Future cancelOrdering(int orderingId) async { 43 | var rs = await HttpHelper.post(ORDERING_ENDPOINT + "/cancel", {"orderingId": orderingId}, 44 | bearerToken: currentLogin.token); 45 | if (rs.statusCode == 200) { 46 | var json = jsonDecode(rs.body); 47 | return OrderingModel.fromJson(json); 48 | } 49 | return null; 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /ankii_shopii/lib/blocs/ordering_bloc/state.dart: -------------------------------------------------------------------------------- 1 | import 'package:ankiishopii/models/ordering_model.dart'; 2 | import 'package:equatable/equatable.dart'; 3 | 4 | class OrderingState extends Equatable { 5 | @override 6 | // TODO: implement props 7 | List get props => []; 8 | } 9 | 10 | class OrderingLoaded extends OrderingState { 11 | final OrderingModel orderingModel; 12 | 13 | OrderingLoaded(this.orderingModel); 14 | 15 | @override 16 | // TODO: implement props 17 | List get props => [orderingModel]; 18 | } 19 | 20 | class OrderingLoadError extends OrderingState{ 21 | 22 | } 23 | class OrderingLoading extends OrderingState{ 24 | 25 | } 26 | 27 | 28 | class AllOrderingLoaded extends OrderingState { 29 | final List orderings; 30 | 31 | AllOrderingLoaded(this.orderings); 32 | 33 | @override 34 | // TODO: implement props 35 | List get props => [orderings]; 36 | } 37 | 38 | class AllOrderingLoadError extends OrderingState{ 39 | final String error; 40 | 41 | AllOrderingLoadError(this.error); 42 | @override 43 | // TODO: implement props 44 | List get props => [error]; 45 | } 46 | class AllOrderingLoading extends OrderingState{ 47 | 48 | } 49 | -------------------------------------------------------------------------------- /ankii_shopii/lib/blocs/product_bloc/bloc.dart: -------------------------------------------------------------------------------- 1 | import 'package:ankiishopii/blocs/product_bloc/event.dart'; 2 | import 'package:ankiishopii/blocs/product_bloc/service.dart'; 3 | import 'package:ankiishopii/blocs/product_bloc/state.dart'; 4 | import 'package:flutter_bloc/flutter_bloc.dart'; 5 | 6 | class ProductBloc extends Bloc { 7 | ProductBloc(ProductState initialState) : super(initialState); 8 | 9 | @override 10 | Stream mapEventToState(ProductEvent event) async* { 11 | // TODO: implement mapEventToState 12 | if (event is GetAllProducts) { 13 | yield* mapGetAppProductsToState(event); 14 | } else if (event is GetAllProductsByCategoryId) { 15 | yield* mapGetAppProductsViaCategoryIdToState(event); 16 | } else if (event is GetProductById) { 17 | yield* mapGetProductByIdToState(event); 18 | } else if (event is DoFavorite) { 19 | yield* mapDoFavoriteByIdToState(event); 20 | } else if (event is GetProductsForYou) { 21 | yield* mapGetProductsForYouToState(event); 22 | } else if (event is SearchProduct) { 23 | yield* mapSearchProductToState(event); 24 | } 25 | } 26 | 27 | Stream mapGetAppProductsToState(GetAllProducts event) async* { 28 | var rs = await ProductService().getAll(); 29 | if (rs != null) { 30 | yield ListProductsLoaded(rs); 31 | } else { 32 | yield ProductLoadingError(); 33 | } 34 | } 35 | 36 | Stream mapGetAppProductsViaCategoryIdToState( 37 | GetAllProductsByCategoryId event) async* { 38 | await Future.delayed(Duration(seconds: 2)); 39 | var rs = await ProductService().getAllWithCategoryId(event.categoryID); 40 | if (rs != null) { 41 | yield ListProductsLoaded(rs); 42 | } else { 43 | yield ProductLoadingError(); 44 | } 45 | } 46 | 47 | Stream mapGetProductByIdToState(GetProductById event) async* { 48 | var rs = await ProductService().get(event.productID); 49 | if (rs != null) { 50 | yield ProductLoaded(rs); 51 | } else { 52 | yield ProductLoadingError(); 53 | } 54 | } 55 | 56 | Stream mapDoFavoriteByIdToState(DoFavorite event) async* { 57 | // rs = await ProductService().get(event.product.id); 58 | var rs = await ProductService().doFavorite(event.product); 59 | // print(rs.isFavoriteByCurrentUser); 60 | // yield ProductLoaded(rs); 61 | } 62 | 63 | Stream mapGetProductsForYouToState( 64 | GetProductsForYou event) async* { 65 | var rs = await ProductService().getProductsForYou(); 66 | if (rs != null) { 67 | yield ListProductsLoaded(rs); 68 | } else { 69 | yield ProductLoadingError(); 70 | } 71 | } 72 | 73 | Stream mapSearchProductToState(SearchProduct event) async* { 74 | var rs = await ProductService().searchProduct(event.keyword); 75 | if (rs != null) { 76 | yield ListProductsLoaded(rs); 77 | } else { 78 | yield ProductLoadingError(); 79 | } 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /ankii_shopii/lib/blocs/product_bloc/event.dart: -------------------------------------------------------------------------------- 1 | import 'package:ankiishopii/models/product_model.dart'; 2 | import 'package:equatable/equatable.dart'; 3 | 4 | class ProductEvent extends Equatable { 5 | @override 6 | // TODO: implement props 7 | List get props => []; 8 | } 9 | 10 | class GetAllProducts extends ProductEvent {} 11 | 12 | class GetAllProductsByCategoryId extends ProductEvent { 13 | final int categoryID; 14 | 15 | GetAllProductsByCategoryId(this.categoryID); 16 | } 17 | 18 | 19 | class GetProductsForYou extends ProductEvent{} 20 | 21 | class GetProductById extends ProductEvent { 22 | final int productID; 23 | 24 | GetProductById(this.productID); 25 | } 26 | 27 | class SearchProduct extends ProductEvent{ 28 | final String keyword; 29 | 30 | SearchProduct(this.keyword); 31 | } 32 | 33 | class DoFavorite extends ProductEvent { 34 | final ProductModel product; 35 | final bool isDoFromListProducts; 36 | 37 | DoFavorite(this.product, {this.isDoFromListProducts = true}); 38 | } 39 | -------------------------------------------------------------------------------- /ankii_shopii/lib/blocs/product_bloc/state.dart: -------------------------------------------------------------------------------- 1 | import 'package:ankiishopii/models/product_model.dart'; 2 | import 'package:equatable/equatable.dart'; 3 | 4 | class ProductState extends Equatable { 5 | @override 6 | // TODO: implement props 7 | List get props => []; 8 | } 9 | 10 | class ListProductsLoaded extends ProductState { 11 | final List products; 12 | 13 | ListProductsLoaded(this.products); 14 | @override 15 | // TODO: implement props 16 | List get props => [products]; 17 | } 18 | 19 | class ProductLoaded extends ProductState{ 20 | final ProductModel product; 21 | 22 | ProductLoaded(this.product); 23 | @override 24 | // TODO: implement props 25 | List get props => [product]; 26 | } 27 | 28 | class ProductLoadingError extends ProductState {} 29 | 30 | class ProductLoading extends ProductState {} 31 | -------------------------------------------------------------------------------- /ankii_shopii/lib/blocs/shop_bloc/bloc.dart: -------------------------------------------------------------------------------- 1 | import 'package:ankiishopii/blocs/shop_bloc/event.dart'; 2 | import 'package:ankiishopii/blocs/shop_bloc/service.dart'; 3 | import 'package:ankiishopii/blocs/shop_bloc/state.dart'; 4 | import 'package:flutter_bloc/flutter_bloc.dart'; 5 | 6 | class ShopAccountBloc extends Bloc { 7 | ShopAccountBloc() : super(ShopAccountLoading()); 8 | 9 | @override 10 | Stream mapEventToState(ShopAccountEvent event) async* { 11 | // TODO: implement mapEventToState 12 | if (event is GetShopAccount) { 13 | yield* mapGetAccountToState(event); 14 | } 15 | } 16 | 17 | Stream mapGetAccountToState(GetShopAccount event) async* { 18 | var rs = await ShopAccountService().getShopAccount(event.username); 19 | if (rs != null) { 20 | yield ShopAccountLoaded(rs); 21 | } else { 22 | yield ShopAccountError(); 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /ankii_shopii/lib/blocs/shop_bloc/event.dart: -------------------------------------------------------------------------------- 1 | import 'package:equatable/equatable.dart'; 2 | 3 | class ShopAccountEvent extends Equatable{ 4 | @override 5 | // TODO: implement props 6 | List get props => []; 7 | 8 | } 9 | 10 | class GetShopAccount extends ShopAccountEvent{ 11 | final String username; 12 | 13 | GetShopAccount(this.username); 14 | @override 15 | // TODO: implement props 16 | List get props => [username]; 17 | } -------------------------------------------------------------------------------- /ankii_shopii/lib/blocs/shop_bloc/service.dart: -------------------------------------------------------------------------------- 1 | import 'dart:convert'; 2 | 3 | import 'package:ankiishopii/blocs/bloc_service.dart'; 4 | import 'package:ankiishopii/helpers/http_helper.dart'; 5 | import 'package:ankiishopii/models/shop_account_model.dart'; 6 | 7 | class ShopAccountService extends BlocService { 8 | @override 9 | Future get(int id) { 10 | // TODO: implement get 11 | throw UnimplementedError(); 12 | } 13 | 14 | @override 15 | Future> getAll({int from = 0, int limit}) { 16 | // TODO: implement getAll 17 | throw UnimplementedError(); 18 | } 19 | 20 | Future getShopAccount(String username) async { 21 | var rs = await HttpHelper.get(SHOP_ACCOUNT_ENDPOINT + "/$username"); 22 | if (rs.statusCode == 200) { 23 | var json = jsonDecode(rs.body); 24 | return ShopAccountModel.fromJson(json); 25 | } 26 | return null; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /ankii_shopii/lib/blocs/shop_bloc/state.dart: -------------------------------------------------------------------------------- 1 | import 'package:ankiishopii/models/shop_account_model.dart'; 2 | import 'package:equatable/equatable.dart'; 3 | 4 | class ShopAccountState extends Equatable { 5 | @override 6 | // TODO: implement props 7 | List get props => []; 8 | } 9 | 10 | class ShopAccountLoaded extends ShopAccountState { 11 | final ShopAccountModel shopAccountModel; 12 | 13 | ShopAccountLoaded(this.shopAccountModel); 14 | 15 | @override 16 | // TODO: implement props 17 | List get props => [shopAccountModel]; 18 | } 19 | 20 | class ShopAccountLoading extends ShopAccountState {} 21 | 22 | class ShopAccountError extends ShopAccountState {} 23 | -------------------------------------------------------------------------------- /ankii_shopii/lib/global/global_function.dart: -------------------------------------------------------------------------------- 1 | import 'package:ankiishopii/blocs/cart_bloc/bloc.dart'; 2 | import 'package:ankiishopii/blocs/cart_bloc/event.dart'; 3 | import 'package:ankiishopii/blocs/cart_bloc/service.dart'; 4 | import 'package:ankiishopii/blocs/login_bloc/bloc.dart'; 5 | import 'package:ankiishopii/blocs/login_bloc/event.dart'; 6 | import 'package:ankiishopii/blocs/product_bloc/service.dart'; 7 | import 'package:ankiishopii/helpers/media_query_helper.dart'; 8 | import 'package:ankiishopii/models/ordering_model.dart'; 9 | import 'package:ankiishopii/themes/constant.dart'; 10 | import 'package:ankiishopii/widgets/add_to_cart_effect.dart'; 11 | import 'package:ankiishopii/widgets/app_bar.dart'; 12 | import 'package:ankiishopii/widgets/loading_dialog.dart'; 13 | import 'package:flutter/cupertino.dart'; 14 | import 'package:flutter/material.dart'; 15 | import 'package:flutter_bloc/flutter_bloc.dart'; 16 | 17 | addToCart(BuildContext context, {@required int productID, int count = 1}) async { 18 | // BlocProvider.of(context).add(AddToCart(productID: productID, count: count)); 19 | LoadingDialog.showLoadingDialog(context); 20 | 21 | // await Future.delayed(Duration(milliseconds: 2000)); 22 | await CartService().addToCart(productID, count); 23 | 24 | LoadingDialog.hideLoadingDialog(context); 25 | // 26 | refreshCart(context); 27 | } 28 | 29 | refreshCart(BuildContext context) async { 30 | BlocProvider.of(context).add(LoadCart()); 31 | } 32 | 33 | refreshLogin(BuildContext context) async { 34 | BlocProvider.of(context).add(GetCurrentLogin()); 35 | } 36 | 37 | countOrderTotal(OrderingModel orderingModel) { 38 | var total = 0; 39 | for (var orderDetail in orderingModel.orderingDetail) { 40 | total += orderDetail.count * orderDetail.product.price; 41 | } 42 | return total; 43 | } 44 | 45 | String getOrderStatus(OrderingModel orderingModel) { 46 | var statusCode = orderingModel.status; 47 | switch (statusCode) { 48 | case 1: 49 | return "Processing"; 50 | break; 51 | case 2: 52 | return "Delivering"; 53 | break; 54 | case 3: 55 | return "Complete"; 56 | break; 57 | case 4: 58 | return "Cancelled"; 59 | break; 60 | default: 61 | return "Unknown"; 62 | } 63 | } 64 | 65 | showAddToCartAnimation(BuildContext context, 66 | {@required CustomPosition start, @required CustomPosition end, Widget overlayWidget, Duration duration}) async { 67 | showGeneralDialog( 68 | transitionDuration: Duration(milliseconds: 100), 69 | barrierDismissible: false, 70 | context: context, 71 | pageBuilder: (_, aniOne, aniTwo) { 72 | return AddToCartAnimationOverlay( 73 | overlayWidget: overlayWidget, 74 | start: start, 75 | end: end, 76 | ); 77 | // 78 | }); 79 | await Future.delayed(duration ?? Duration(milliseconds: 500)); 80 | Navigator.pop(context); 81 | } 82 | 83 | double cartIconPositionDx = 0; 84 | double cartIconPositionDy = 0; 85 | 86 | updateCartIconPosition({GlobalKey cartIconKey, Duration duration}) { 87 | if (cartIconKey != null) { 88 | try { 89 | cartIconKey.currentState.onAddToCart(duration: duration); 90 | final RenderBox box = cartIconKey.currentContext.findRenderObject(); 91 | final Offset position = box.globalToLocal(Offset.zero); 92 | var dx = position.dx * -1; 93 | var dy = position.dy * -1; 94 | // print(dx.toString() + "_" + dy.toString()); 95 | cartIconPositionDx = dx; 96 | cartIconPositionDy = dy; 97 | } catch (e) {} 98 | } else { 99 | cartIconPositionDy = -50; 100 | } 101 | } 102 | -------------------------------------------------------------------------------- /ankii_shopii/lib/global/global_variable.dart: -------------------------------------------------------------------------------- 1 | import 'package:ankiishopii/helpers/shared_preferences_helper.dart'; 2 | import 'package:ankiishopii/models/login_model.dart'; 3 | 4 | const String googleMapAPIKey = 'AIzaSyBvIWwUz2ntI_TidS5I3LNHdTu1rNTp66k'; 5 | 6 | getGlobal() async { 7 | var login = await LocalHelper.getAccountFromLocal(); 8 | currentLogin = login; 9 | } 10 | 11 | LoginModel currentLogin; 12 | -------------------------------------------------------------------------------- /ankii_shopii/lib/helpers/http_helper.dart: -------------------------------------------------------------------------------- 1 | import 'dart:convert'; 2 | import 'dart:io'; 3 | 4 | import 'package:http/http.dart' as http; 5 | 6 | const DOMAIN = 'https://shopii.azurewebsites.net/api/'; 7 | // const DOMAIN = 'http://10.0.3.2:50107/api/'; 8 | const CATEGORY_ENDPOINT = DOMAIN + 'categories'; 9 | const PRODUCT_ENDPOINT = DOMAIN + 'products'; 10 | const LOGIN_ENDPOINT = DOMAIN + 'login'; 11 | const ACCOUNT_ENDPOINT = DOMAIN + 'current'; 12 | const FAVORITE_ENDPOINT = DOMAIN + 'favorites'; 13 | const ORDERING_ENDPOINT = DOMAIN + 'orderings'; 14 | const CART_ENDPOINT = DOMAIN + 'orderings/cart'; 15 | const CHECKOUT_ENDPOINT = DOMAIN + 'orderings/checkout'; 16 | const DELIVERY_ADDRESS_ENDPOINT = DOMAIN + 'deliveryaddresses'; 17 | const SHOP_ACCOUNT_ENDPOINT = DOMAIN + 'shopaccounts'; 18 | 19 | class HttpHelper { 20 | static Future post(String url, Map body, 21 | {String bearerToken}) async { 22 | // print('HTTP POST: $url'); 23 | return (await http.post(url, body: jsonEncode(body), headers: { 24 | HttpHeaders.contentTypeHeader: 'application/json; charset=UTF-8', 25 | HttpHeaders.acceptHeader: 'application/json', 26 | HttpHeaders.authorizationHeader: 'Bearer $bearerToken' 27 | })); 28 | } 29 | 30 | static Future put(String url, Map body, 31 | {String bearerToken}) async { 32 | return (await http.put(url, body: jsonEncode(body), headers: { 33 | HttpHeaders.contentTypeHeader: 'application/json; charset=UTF-8', 34 | HttpHeaders.acceptHeader: 'application/json', 35 | HttpHeaders.authorizationHeader: 'Bearer $bearerToken' 36 | })); 37 | } 38 | 39 | static Future get(String url, {String bearerToken}) async { 40 | return await http.get(url, 41 | headers: {HttpHeaders.authorizationHeader: 'Bearer $bearerToken'}); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /ankii_shopii/lib/helpers/media_query_helper.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | class ScreenHelper{ 4 | static double getHeight(BuildContext context){ 5 | return MediaQuery.of(context).size.height; 6 | } 7 | static double getSafeHeight(BuildContext context){ 8 | return MediaQuery.of(context).size.height - getPaddingTop(context) - 60 - 10; 9 | } 10 | static double getWidth(BuildContext context){ 11 | return MediaQuery.of(context).size.width; 12 | } 13 | static double getPaddingTop(BuildContext context){ 14 | return MediaQuery.of(context).padding.top; 15 | } 16 | } -------------------------------------------------------------------------------- /ankii_shopii/lib/helpers/shared_preferences_helper.dart: -------------------------------------------------------------------------------- 1 | import 'dart:convert'; 2 | 3 | import 'package:ankiishopii/models/account_model.dart'; 4 | import 'package:ankiishopii/models/login_model.dart'; 5 | import 'package:shared_preferences/shared_preferences.dart'; 6 | 7 | class LocalHelper { 8 | static saveAccountToLocal(LoginModel accountModel) async { 9 | SharedPreferences pref = await SharedPreferences.getInstance(); 10 | var rs = await pref.setString('login', jsonEncode(accountModel)); 11 | } 12 | 13 | static deleteAccountFromLocal() async { 14 | SharedPreferences pref = await SharedPreferences.getInstance(); 15 | var rs = await pref.remove('login'); 16 | } 17 | 18 | static Future getAccountFromLocal() async { 19 | SharedPreferences pref = await SharedPreferences.getInstance(); 20 | var account = pref.getString('login'); 21 | if (account != null) { 22 | return LoginModel.fromJson(jsonDecode(account)); 23 | } 24 | return null; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /ankii_shopii/lib/helpers/string_helper.dart: -------------------------------------------------------------------------------- 1 | import 'package:intl/intl.dart'; 2 | 3 | String numberToMoneyString(int price, {String unit = 'đ'}) { 4 | return NumberFormat("#,###", "vi_VN").format(price) + unit; 5 | } 6 | -------------------------------------------------------------------------------- /ankii_shopii/lib/main.dart: -------------------------------------------------------------------------------- 1 | import 'dart:io'; 2 | 3 | import 'package:ankiishopii/blocs/account_bloc/service.dart'; 4 | import 'package:ankiishopii/blocs/cart_bloc/event.dart'; 5 | import 'package:ankiishopii/blocs/login_bloc/bloc.dart'; 6 | import 'package:ankiishopii/blocs/login_bloc/event.dart'; 7 | import 'package:ankiishopii/blocs/login_bloc/service.dart'; 8 | import 'package:ankiishopii/global/global_variable.dart'; 9 | import 'package:ankiishopii/routes.dart'; 10 | import 'package:ankiishopii/themes/constant.dart'; 11 | import 'package:flutter/material.dart'; 12 | import 'package:flutter/services.dart'; 13 | import 'package:flutter_bloc/flutter_bloc.dart'; 14 | import 'package:google_fonts/google_fonts.dart'; 15 | 16 | import 'blocs/cart_bloc/bloc.dart'; 17 | import 'pages/navigator/navigator_page.dart'; 18 | 19 | BuildContext mainContext; 20 | main() { 21 | WidgetsFlutterBinding.ensureInitialized(); 22 | runApp(MyApp()); 23 | } 24 | 25 | GlobalKey navigatorPagedKey = GlobalKey(); 26 | 27 | class MyApp extends StatelessWidget { 28 | // This widget is the root of your application. 29 | @override 30 | Widget build(BuildContext context) { 31 | SystemChrome.setSystemUIOverlayStyle(SystemUiOverlayStyle(statusBarColor: Colors.transparent)); 32 | return MultiBlocProvider( 33 | providers: [ 34 | BlocProvider(create: (context) => CartBloc()..add(LoadCart())), 35 | BlocProvider(create: (context) => LoginBloc()..add(GetCurrentLogin())), 36 | ], 37 | child: MaterialApp( 38 | debugShowCheckedModeBanner: false, 39 | title: 'SHOPii', 40 | theme: ThemeData( 41 | fontFamily: GoogleFonts.aBeeZee().fontFamily, 42 | // This is the theme of your application. 43 | // 44 | // Try running your application with "flutter run". You'll see the 45 | // application has a blue toolbar. Then, without quitting the app, try 46 | // changing the primarySwatch below to Colors.green and then invoke 47 | // "hot reload" (press "r" in the console where you ran "flutter run", 48 | // or simply save your changes to "hot reload" in a Flutter IDE). 49 | // Notice that the counter didn't reset back to zero; the application 50 | // is not restarted. 51 | primarySwatch: Colors.grey, 52 | // This makes the visual density adapt to the platform that you run 53 | // the app on. For desktop platforms, the controls will be smaller and 54 | // closer together (more dense) than on mobile platforms. 55 | visualDensity: VisualDensity.adaptivePlatformDensity, 56 | ), 57 | // onGenerateRoute: Routes.onGenerateRoute, 58 | // navigatorObservers: [MyRouteObserver()], 59 | // initialRoute: MyRouteObserver.currentRoute, 60 | home: LoadingScreen(), 61 | )); 62 | } 63 | } 64 | 65 | class LoadingScreen extends StatefulWidget { 66 | static const routeName = 'loading'; 67 | 68 | @override 69 | _LoadingScreenState createState() => _LoadingScreenState(); 70 | } 71 | 72 | class _LoadingScreenState extends State { 73 | @override 74 | void initState() { 75 | // TODO: implement initState 76 | super.initState(); 77 | load().then((value) { 78 | if (value) { 79 | // Navigator.of(context).pushReplacementNamed('navigatorPage'); 80 | Navigator.pushReplacement( 81 | context, 82 | MaterialPageRoute( 83 | builder: (b) => NavigatorPage( 84 | key: navigatorPagedKey, 85 | ))); 86 | } 87 | }); 88 | } 89 | 90 | @override 91 | Widget build(BuildContext context) { 92 | return Scaffold( 93 | backgroundColor: BACKGROUND_COLOR, 94 | body: Center( 95 | child: Text('Loading...'), 96 | ), 97 | ); 98 | } 99 | 100 | Future load() async { 101 | await getGlobal(); 102 | if (currentLogin == null) { 103 | print('Not Logged In!'); 104 | } 105 | return true; 106 | } 107 | } 108 | -------------------------------------------------------------------------------- /ankii_shopii/lib/models/account_model.dart: -------------------------------------------------------------------------------- 1 | import 'package:ankiishopii/models/favorite_model.dart'; 2 | 3 | class AccountModel { 4 | String username; 5 | String password; 6 | String phoneNumber; 7 | String fullname; 8 | String address; 9 | String image; 10 | int defaultDeliveryId; 11 | List deliveryAddress; 12 | List favorite; 13 | 14 | AccountModel( 15 | {this.favorite, 16 | this.username, 17 | this.password, 18 | this.phoneNumber, 19 | this.fullname, 20 | this.address, 21 | this.image, 22 | this.deliveryAddress, 23 | this.defaultDeliveryId}); 24 | 25 | AccountModel.fromJson(Map json) { 26 | username = json['username']; 27 | password = json['password']; 28 | phoneNumber = json['phoneNumber']; 29 | fullname = json['fullname']; 30 | image = json['image']; 31 | defaultDeliveryId = json['defaultDeliveryId']; 32 | address = json['address']; 33 | if (json['deliveryAddress'] != null) { 34 | deliveryAddress = new List(); 35 | json['deliveryAddress'].forEach((v) { 36 | deliveryAddress.add(new DeliveryAddressModel.fromJson(v)); 37 | }); 38 | } 39 | if (json['favorite'] != null) { 40 | favorite = new List(); 41 | json['favorite'].forEach((v) { 42 | favorite.add(new FavoriteModel.fromJson(v)); 43 | }); 44 | } 45 | } 46 | 47 | Map toJson() { 48 | final Map data = new Map(); 49 | data['username'] = this.username; 50 | data['password'] = this.password; 51 | data['phoneNumber'] = this.phoneNumber; 52 | data['fullname'] = this.fullname; 53 | data['address'] = this.address; 54 | data['image'] = this.image; 55 | data['defaultDeliveryId'] = this.defaultDeliveryId; 56 | if (this.deliveryAddress != null) { 57 | data['deliveryAddress'] = this.deliveryAddress.map((v) => v.toJson()).toList(); 58 | } 59 | if (this.favorite != null) { 60 | data['favorite'] = this.favorite.map((v) => v.toJson()).toList(); 61 | } 62 | return data; 63 | } 64 | } 65 | 66 | class DeliveryAddressModel { 67 | int id; 68 | String username; 69 | String phoneNumber; 70 | String fullname; 71 | String address; 72 | String latitude; 73 | String longitude; 74 | 75 | DeliveryAddressModel( 76 | {this.id, this.username, this.phoneNumber, this.fullname, this.address, this.latitude, this.longitude}); 77 | 78 | DeliveryAddressModel.fromJson(Map json) { 79 | id = json['id']; 80 | username = json['username']; 81 | phoneNumber = json['phoneNumber']; 82 | fullname = json['fullname']; 83 | address = json['address']; 84 | latitude = json['latitude']; 85 | longitude = json['longitude']; 86 | } 87 | 88 | Map toJson() { 89 | final Map data = new Map(); 90 | data['id'] = this.id; 91 | data['username'] = this.username; 92 | data['phoneNumber'] = this.phoneNumber; 93 | data['fullname'] = this.fullname; 94 | data['address'] = this.address; 95 | data['latitude'] = this.latitude; 96 | data['longitude'] = this.longitude; 97 | return data; 98 | } 99 | } 100 | -------------------------------------------------------------------------------- /ankii_shopii/lib/models/category_model.dart: -------------------------------------------------------------------------------- 1 | import 'package:ankiishopii/models/product_model.dart'; 2 | 3 | class CategoryModel { 4 | int id; 5 | String name; 6 | String description; 7 | String image; 8 | List product; 9 | 10 | CategoryModel({this.id, this.name, this.description, this.image, this.product}); 11 | 12 | CategoryModel.fromJson(Map json) { 13 | id = json['id']; 14 | name = json['name']; 15 | description = json['description']; 16 | image = json['image']; 17 | if (json['product'] != null) { 18 | product = new List(); 19 | json['product'].forEach((v) { 20 | product.add(new ProductModel.fromJson(v)); 21 | }); 22 | } 23 | } 24 | 25 | Map toJson() { 26 | final Map data = new Map(); 27 | data['id'] = this.id; 28 | data['name'] = this.name; 29 | data['description'] = this.description; 30 | data['image'] = this.image; 31 | if (this.product != null) { 32 | data['product'] = this.product.map((v) => v.toJson()).toList(); 33 | } 34 | return data; 35 | } 36 | } -------------------------------------------------------------------------------- /ankii_shopii/lib/models/favorite_model.dart: -------------------------------------------------------------------------------- 1 | import 'package:ankiishopii/models/product_model.dart'; 2 | 3 | class FavoriteModel { 4 | int id; 5 | String username; 6 | int productId; 7 | ProductModel product; 8 | bool isfavorite; 9 | 10 | FavoriteModel({this.id, this.username, this.productId,this.isfavorite,this.product}); 11 | 12 | FavoriteModel.fromJson(Map json) { 13 | id = json['id']; 14 | username = json['username']; 15 | productId = json['productId']; 16 | product = 17 | json['product'] != null ? new ProductModel.fromJson(json['product']) : null; 18 | isfavorite = json['isfavorite']; 19 | } 20 | 21 | Map toJson() { 22 | final Map data = new Map(); 23 | data['id'] = this.id; 24 | data['username'] = this.username; 25 | data['productId'] = this.productId; 26 | data['isfavorite'] = this.isfavorite; 27 | if (this.product != null) { 28 | data['product'] = this.product.toJson(); 29 | } 30 | return data; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /ankii_shopii/lib/models/login_model.dart: -------------------------------------------------------------------------------- 1 | import 'package:ankiishopii/models/account_model.dart'; 2 | 3 | class LoginModel { 4 | AccountModel account; 5 | String role; 6 | String token; 7 | 8 | LoginModel({this.account, this.role, this.token}); 9 | 10 | LoginModel.fromJson(Map json) { 11 | account = 12 | json['account'] != null ? new AccountModel.fromJson(json['account']) : null; 13 | role = json['role']; 14 | token = json['token']; 15 | } 16 | 17 | Map toJson() { 18 | final Map data = new Map(); 19 | if (this.account != null) { 20 | data['account'] = this.account.toJson(); 21 | } 22 | data['role'] = this.role; 23 | data['token'] = this.token; 24 | return data; 25 | } 26 | } -------------------------------------------------------------------------------- /ankii_shopii/lib/models/ordering_model.dart: -------------------------------------------------------------------------------- 1 | import 'package:ankiishopii/models/account_model.dart'; 2 | import 'package:ankiishopii/models/product_model.dart'; 3 | 4 | class OrderingModel { 5 | int id; 6 | int deliveryId; 7 | int status; 8 | String username; 9 | String shopUsername; 10 | DeliveryAddressModel delivery; 11 | String createdDate; 12 | List orderingDetail; 13 | 14 | OrderingModel( 15 | {this.id, 16 | this.deliveryId, 17 | this.status, 18 | this.delivery, 19 | this.orderingDetail, 20 | this.shopUsername, 21 | this.username, 22 | this.createdDate}); 23 | 24 | OrderingModel.fromJson(Map json) { 25 | id = json['id']; 26 | deliveryId = json['deliveryId']; 27 | status = json['status']; 28 | username = json['username']; 29 | shopUsername = json['shopUsername']; 30 | createdDate = json['createdDate']; 31 | delivery = json['delivery'] != null ? new DeliveryAddressModel.fromJson(json['delivery']) : null; 32 | if (json['orderingDetail'] != null) { 33 | orderingDetail = new List(); 34 | json['orderingDetail'].forEach((v) { 35 | orderingDetail.add(new OrderingDetailModel.fromJson(v)); 36 | }); 37 | } 38 | } 39 | 40 | Map toJson() { 41 | final Map data = new Map(); 42 | data['id'] = this.id; 43 | data['deliveryId'] = this.deliveryId; 44 | data['status'] = this.status; 45 | data['createdDate'] = this.createdDate; 46 | data['username'] = this.username; 47 | data['shopUsername'] = this.shopUsername; 48 | if (this.delivery != null) { 49 | data['delivery'] = this.delivery.toJson(); 50 | } 51 | if (this.orderingDetail != null) { 52 | data['orderingDetail'] = this.orderingDetail.map((v) => v.toJson()).toList(); 53 | } 54 | return data; 55 | } 56 | } 57 | 58 | class OrderingDetailModel { 59 | int id; 60 | int orderingId; 61 | int productId; 62 | int count; 63 | ProductModel product; 64 | 65 | OrderingDetailModel({this.id, this.orderingId, this.productId, this.product, this.count = 0}); 66 | 67 | OrderingDetailModel.fromJson(Map json) { 68 | id = json['id']; 69 | orderingId = json['orderingId']; 70 | productId = json['productId']; 71 | count = json['count']; 72 | product = json['product'] != null ? new ProductModel.fromJson(json['product']) : null; 73 | } 74 | 75 | Map toJson() { 76 | final Map data = new Map(); 77 | data['id'] = this.id; 78 | data['orderingId'] = this.orderingId; 79 | data['productId'] = this.productId; 80 | data['count'] = this.count; 81 | if (this.product != null) { 82 | data['product'] = this.product.toJson(); 83 | } 84 | return data; 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /ankii_shopii/lib/models/product_model.dart: -------------------------------------------------------------------------------- 1 | import 'package:ankiishopii/models/category_model.dart'; 2 | 3 | import 'favorite_model.dart'; 4 | 5 | class ProductModel { 6 | int id; 7 | String name; 8 | String description; 9 | String image; 10 | int price; 11 | int categoryId; 12 | String shopUsername; 13 | CategoryModel category; 14 | List productImage; 15 | List favorite; 16 | bool isFavoriteByCurrentUser = false; 17 | 18 | ProductModel( 19 | {this.id, 20 | this.name, 21 | this.description, 22 | this.image, 23 | this.price, 24 | this.categoryId, 25 | this.productImage, 26 | this.favorite, 27 | this.shopUsername, 28 | this.category}); 29 | 30 | ProductModel.fromJson(Map json) { 31 | id = json['id']; 32 | name = json['name']; 33 | description = json['description']; 34 | image = json['image']; 35 | price = json['price']; 36 | shopUsername = json['shopUsername']; 37 | categoryId = json['categoryId']; 38 | if (json['productImage'] != null) { 39 | productImage = new List(); 40 | json['productImage'].forEach((v) { 41 | productImage.add(new ProductImageModel.fromJson(v)); 42 | }); 43 | } 44 | if (json['favorite'] != null) { 45 | favorite = new List(); 46 | json['favorite'].forEach((v) { 47 | favorite.add(new FavoriteModel.fromJson(v)); 48 | }); 49 | } 50 | category = json['category'] != null ? new CategoryModel.fromJson(json['category']) : null; 51 | } 52 | 53 | Map toJson() { 54 | final Map data = new Map(); 55 | data['id'] = this.id; 56 | data['name'] = this.name; 57 | data['description'] = this.description; 58 | data['image'] = this.image; 59 | data['price'] = this.price; 60 | data['shopUsername'] = this.shopUsername; 61 | data['categoryId'] = this.categoryId; 62 | if (this.category != null) { 63 | data['category'] = this.category.toJson(); 64 | } 65 | if (this.productImage != null) { 66 | data['productImage'] = this.productImage.map((v) => v.toJson()).toList(); 67 | } 68 | if (this.favorite != null) { 69 | data['favorite'] = this.favorite.map((v) => v.toJson()).toList(); 70 | } 71 | return data; 72 | } 73 | } 74 | 75 | class ProductImageModel { 76 | int id; 77 | int productId; 78 | String image; 79 | 80 | ProductImageModel({this.id, this.productId, this.image}); 81 | 82 | ProductImageModel.fromJson(Map json) { 83 | id = json['id']; 84 | productId = json['productId']; 85 | image = json['image']; 86 | } 87 | 88 | Map toJson() { 89 | final Map data = new Map(); 90 | data['id'] = this.id; 91 | data['productId'] = this.productId; 92 | data['image'] = this.image; 93 | return data; 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /ankii_shopii/lib/models/shop_account_model.dart: -------------------------------------------------------------------------------- 1 | class ShopAccountModel { 2 | String username; 3 | String password; 4 | String name; 5 | String address; 6 | String phoneNumber; 7 | String image; 8 | String coverImage; 9 | String latitude; 10 | String longitude; 11 | 12 | ShopAccountModel( 13 | {this.username, this.password, this.name, this.address, this.phoneNumber, this.image, this.coverImage}); 14 | 15 | ShopAccountModel.fromJson(Map json) { 16 | username = json['username']; 17 | password = json['password']; 18 | name = json['name']; 19 | address = json['address']; 20 | phoneNumber = json['phoneNumber']; 21 | image = json['image']; 22 | coverImage = json['coverImage']; 23 | latitude = json['latitude']; 24 | longitude = json['longitude']; 25 | } 26 | 27 | Map toJson() { 28 | final Map data = new Map(); 29 | data['username'] = this.username; 30 | data['password'] = this.password; 31 | data['name'] = this.name; 32 | data['address'] = this.address; 33 | data['phoneNumber'] = this.phoneNumber; 34 | data['image'] = this.image; 35 | data['coverImage'] = this.coverImage; 36 | data['latitude'] = this.latitude; 37 | data['longitude'] = this.longitude; 38 | return data; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /ankii_shopii/lib/pages/notification/notification_page.dart: -------------------------------------------------------------------------------- 1 | import 'package:ankiishopii/helpers/media_query_helper.dart'; 2 | import 'package:ankiishopii/themes/constant.dart'; 3 | import 'package:ankiishopii/widgets/app_bar.dart'; 4 | import 'package:ankiishopii/widgets/notification_item.dart'; 5 | import 'package:flutter/material.dart'; 6 | 7 | class NotificationPage extends StatefulWidget { 8 | static const String routeName = 'notificationPage'; 9 | final ScrollController scrollController; 10 | 11 | NotificationPage(this.scrollController); 12 | 13 | @override 14 | _NotificationPageState createState() => _NotificationPageState(); 15 | } 16 | 17 | class _NotificationPageState extends State { 18 | @override 19 | Widget build(BuildContext context) { 20 | return Scaffold( 21 | backgroundColor: BACKGROUND_COLOR, 22 | body: SingleChildScrollView( 23 | controller: widget.scrollController, 24 | child: Column( 25 | children: [ 26 | InPageAppBar( 27 | title: 'Notification', 28 | ), 29 | buildNotification(), 30 | ], 31 | )), 32 | ); 33 | } 34 | 35 | Widget buildNotification() { 36 | return Container( 37 | margin: EdgeInsets.only(left: 10, right: 10), 38 | child: Column( 39 | children: List.generate( 40 | 10, 41 | (index) => Container( 42 | width: double.maxFinite, 43 | margin: EdgeInsets.only(top: index == 0 ? 10 : 0, bottom: 10), 44 | child: CustomNotificationListItem( 45 | title: 'Notification' + index.toString(), 46 | description: 47 | 'description description description description description description description description description description', 48 | dateTimeString: DateTime.now().toString(), 49 | ), 50 | )).toList(), 51 | ), 52 | ); 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /ankii_shopii/lib/pages/product/product_page.dart: -------------------------------------------------------------------------------- 1 | import 'dart:async'; 2 | 3 | import 'package:ankiishopii/blocs/product_bloc/bloc.dart'; 4 | import 'package:ankiishopii/blocs/product_bloc/event.dart'; 5 | import 'package:ankiishopii/blocs/product_bloc/service.dart'; 6 | import 'package:ankiishopii/blocs/product_bloc/state.dart'; 7 | import 'package:ankiishopii/global/global_function.dart'; 8 | import 'package:ankiishopii/models/category_model.dart'; 9 | import 'package:ankiishopii/models/product_model.dart'; 10 | import 'package:ankiishopii/pages/product/product_detail_page.dart'; 11 | import 'package:ankiishopii/themes/constant.dart'; 12 | import 'package:ankiishopii/widgets/app_bar.dart'; 13 | import 'package:ankiishopii/widgets/base/custom_ontap_widget.dart'; 14 | import 'package:ankiishopii/widgets/debug_widget.dart'; 15 | import 'package:ankiishopii/widgets/graphic_widget.dart'; 16 | import 'package:ankiishopii/widgets/product_item.dart'; 17 | import 'package:cached_network_image/cached_network_image.dart'; 18 | import 'package:flutter/material.dart'; 19 | import 'package:flutter_bloc/flutter_bloc.dart'; 20 | 21 | class ProductPage extends StatefulWidget { 22 | static const String routeName = 'productPage'; 23 | final CategoryModel category; 24 | 25 | ProductPage({this.category}); 26 | 27 | @override 28 | _ProductPageState createState() => _ProductPageState(); 29 | } 30 | 31 | class _ProductPageState extends State { 32 | GlobalKey cartGlobalKey = GlobalKey(); 33 | ProductBloc bloc = ProductBloc(ProductLoading()); 34 | 35 | void _refresh() { 36 | if (widget.category == null) { 37 | bloc.add(GetAllProducts()); 38 | } else { 39 | bloc.add(GetAllProductsByCategoryId(widget.category.id)); 40 | } 41 | } 42 | 43 | Future _doFavorite(ProductModel product) async { 44 | setState(() { 45 | product.isFavoriteByCurrentUser = !product.isFavoriteByCurrentUser; 46 | }); 47 | await ProductService().doFavorite(product); 48 | _refresh(); 49 | } 50 | 51 | @override 52 | void initState() { 53 | // TODO: implement initState 54 | super.initState(); 55 | _refresh(); 56 | } 57 | 58 | @override 59 | void dispose() { 60 | // TODO: implement dispose 61 | bloc.close(); 62 | super.dispose(); 63 | } 64 | 65 | @override 66 | Widget build(BuildContext context) { 67 | return Scaffold( 68 | backgroundColor: BACKGROUND_COLOR, 69 | body: SingleChildScrollView( 70 | child: Column( 71 | children: [ 72 | InPageAppBar( 73 | cartIconKey: cartGlobalKey, 74 | leading: CustomOnTapWidget( 75 | child: Icon( 76 | Icons.arrow_back_ios, 77 | size: 20, 78 | color: PRIMARY_TEXT_COLOR, 79 | ), 80 | onTap: () { 81 | Navigator.pop(context); 82 | }), 83 | title: widget.category != null ? widget.category.name : 'Tất cả', 84 | ), 85 | BlocBuilder( 86 | cubit: bloc, 87 | builder: (context, state) { 88 | if (state is ProductLoadingError) { 89 | return Center( 90 | child: CustomErrorWidget(), 91 | ); 92 | } else if (state is ListProductsLoaded) { 93 | return buildProducts(state.products); 94 | } else { 95 | return Center( 96 | child: CustomDotLoading(), 97 | ); 98 | } 99 | }), 100 | ], 101 | ), 102 | ), 103 | ); 104 | } 105 | 106 | Widget buildProducts(List products) { 107 | List children = products 108 | .map((product) => CustomProductListItem( 109 | elevation: 10, 110 | cartIconKey: cartGlobalKey, 111 | onTap: () async { 112 | await Navigator.push( 113 | context, 114 | MaterialPageRoute( 115 | builder: (b) => ProductDetailPage(product))); 116 | _refresh(); 117 | }, 118 | product: product, 119 | backgroundColor: FOREGROUND_COLOR, 120 | onFavourite: () async { 121 | _doFavorite(product); 122 | }, 123 | onAddToCart: () { 124 | addToCart(context, productID: product.id); 125 | }, 126 | )) 127 | .toList(); 128 | return Column(children: children); 129 | } 130 | } 131 | -------------------------------------------------------------------------------- /ankii_shopii/lib/routes.dart: -------------------------------------------------------------------------------- 1 | //import 'package:ankiishopii/main.dart'; 2 | //import 'package:ankiishopii/models/category_model.dart'; 3 | //import 'package:ankiishopii/models/product_model.dart'; 4 | //import 'package:ankiishopii/pages/cart/cart_page.dart'; 5 | //import 'package:ankiishopii/pages/home/home_page.dart'; 6 | //import 'package:ankiishopii/pages/navigator/navigator_page.dart'; 7 | //import 'package:ankiishopii/pages/product/product_detail_page.dart'; 8 | //import 'package:ankiishopii/pages/product/product_page.dart'; 9 | //import 'package:ankiishopii/pages/search/search_page.dart'; 10 | //import 'package:flutter/material.dart'; 11 | // 12 | //class Routes { 13 | // static Route onGenerateRoute(RouteSettings settings) { 14 | // switch (settings.name) { 15 | // case NavigatorPage.routeName: 16 | // return MaterialPageRoute(builder: (_) => NavigatorPage(), settings: settings); 17 | // case HomePage.routeName: 18 | // ScrollController scrollController = settings.arguments as ScrollController; 19 | // return MaterialPageRoute(builder: (_) => HomePage(scrollController), settings: settings); 20 | // 21 | // case ProductPage.routeName: 22 | // CategoryModel categoryModel = settings.arguments as CategoryModel; 23 | // return MaterialPageRoute(builder: (_) => ProductPage(category: categoryModel), settings: settings); 24 | // case ProductDetailPage.routeName: 25 | // ProductModel productModel = settings.arguments as ProductModel; 26 | // return MaterialPageRoute(builder: (_) => ProductDetailPage(productModel), settings: settings); 27 | // 28 | // case CartPage.routeName: 29 | // return MaterialPageRoute(builder: (_) => CartPage(), settings: settings); 30 | // 31 | // case CartPage.routeName: 32 | // return MaterialPageRoute(builder: (_) => CartPage(), settings: settings); 33 | // 34 | // case ProductDetailPage.routeName: 35 | // ProductModel productModel = settings.arguments as ProductModel; 36 | // return MaterialPageRoute(builder: (_) => ProductDetailPage(productModel), settings: settings); 37 | // 38 | // case SearchPage.routeName: 39 | // return MaterialPageRoute(builder: (_) => SearchPage(), settings: settings); 40 | // default: 41 | // return MaterialPageRoute(builder: (_) => LoadingScreen(), settings: settings); 42 | // } 43 | // } 44 | //} 45 | // 46 | //class MyRouteObserver extends RouteObserver> { 47 | // static String currentRoute = 'loading'; 48 | // 49 | // static void onRouteChange(PageRoute route) { 50 | // currentRoute = route.settings.name; 51 | // print(currentRoute); 52 | // } 53 | // 54 | // @override 55 | // void didPop(Route route, Route previousRoute) { 56 | // super.didPop(route, previousRoute); 57 | // // TODO: implement didPop 58 | // print('[pop]'); 59 | // onRouteChange(previousRoute); 60 | // } 61 | // 62 | // @override 63 | // void didPush(Route route, Route previousRoute) { 64 | // super.didPush(route, previousRoute); 65 | // // TODO: implement didPush 66 | // print('[push]'); 67 | // onRouteChange(route); 68 | // } 69 | // 70 | // @override 71 | // void didReplace({Route newRoute, Route oldRoute}) { 72 | // super.didReplace(); 73 | // // TODO: implement didReplace 74 | // print('[replace]'); 75 | // onRouteChange(newRoute); 76 | // } 77 | //} 78 | -------------------------------------------------------------------------------- /ankii_shopii/lib/themes/constant.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | // 4 | const Color PRIMARY_COLOR = Color(0xff222831); 5 | const Color BACKGROUND_COLOR = Color(0xffeeeeee); 6 | const Color FOREGROUND_COLOR = Color(0xffC94D49); 7 | const Color PRICE_COLOR_PRIMARY = FOREGROUND_COLOR; 8 | const Color PRICE_COLOR_ON_FORE = Color(0xfffbd46d); 9 | const Color PRIMARY_TEXT_COLOR = PRIMARY_COLOR; 10 | const Color FORE_TEXT_COLOR = BACKGROUND_COLOR; 11 | 12 | //////FOOD 13 | //const Color PRIMARY_COLOR = Color(0xff000000); 14 | //const Color BACKGROUND_COLOR = Color(0xffF7EBE8); 15 | //const Color FOREGROUND_COLOR = Color(0xffFACC6B); 16 | //const Color PRICE_COLOR_PRIMARY = Colors.red; 17 | //const Color PRICE_COLOR_ON_FORE = Colors.red; 18 | //const Color PRIMARY_TEXT_COLOR = PRIMARY_COLOR; 19 | //const Color FORE_TEXT_COLOR = BACKGROUND_COLOR; 20 | 21 | const TextStyle TEXT_STYLE_PRIMARY = TextStyle(color: PRIMARY_TEXT_COLOR); 22 | const TextStyle TEXT_STYLE_ON_FOREGROUND = TextStyle(color: FORE_TEXT_COLOR); 23 | -------------------------------------------------------------------------------- /ankii_shopii/lib/widgets/add_to_cart_effect.dart: -------------------------------------------------------------------------------- 1 | import 'dart:ui'; 2 | 3 | import 'package:ankiishopii/helpers/media_query_helper.dart'; 4 | import 'package:ankiishopii/themes/constant.dart'; 5 | import 'package:flutter/material.dart'; 6 | 7 | class CustomPosition { 8 | double left; 9 | double top; 10 | 11 | CustomPosition(this.left, this.top); 12 | } 13 | 14 | 15 | class AddToCartAnimationOverlay extends StatefulWidget { 16 | final Widget overlayWidget; 17 | final CustomPosition start; 18 | final CustomPosition end; 19 | 20 | AddToCartAnimationOverlay({@required this.start, @required this.end, this.overlayWidget}); 21 | 22 | @override 23 | _AddToCartAnimationOverlayState createState() => _AddToCartAnimationOverlayState(); 24 | } 25 | 26 | class _AddToCartAnimationOverlayState extends State 27 | with SingleTickerProviderStateMixin { 28 | AnimationController _controller; 29 | Animation _animation; 30 | Path _path; 31 | 32 | @override 33 | void initState() { 34 | _controller = AnimationController(vsync: this, duration: Duration(milliseconds: 500)); 35 | super.initState(); 36 | _animation = Tween(begin: 0.0, end: 1.0).animate(_controller) 37 | ..addListener(() { 38 | setState(() {}); 39 | }); 40 | _controller.forward(); 41 | } 42 | 43 | @override 44 | Widget build(BuildContext context) { 45 | _path = drawPath(); 46 | return Scaffold( 47 | backgroundColor: Colors.transparent, 48 | body: Stack( 49 | children: [ 50 | Positioned( 51 | top: 0, 52 | child: CustomPaint( 53 | painter: PathPainter(_path), 54 | ), 55 | ), 56 | Positioned( 57 | top: calculate(_animation.value).dy, 58 | left: calculate(_animation.value).dx, 59 | child: widget.overlayWidget ?? 60 | Icon( 61 | Icons.plus_one, 62 | color: PRIMARY_COLOR, 63 | )), 64 | ], 65 | ), 66 | ); 67 | } 68 | 69 | @override 70 | void dispose() { 71 | _controller.dispose(); 72 | super.dispose(); 73 | } 74 | 75 | Path drawPath() { 76 | Path path = Path(); 77 | path.moveTo(widget.start.left, widget.start.top); 78 | path.quadraticBezierTo(widget.end.left * 0.5, widget.end.top, widget.end.left, widget.end.top); 79 | return path; 80 | } 81 | 82 | Offset calculate(value) { 83 | PathMetrics pathMetrics = _path.computeMetrics(); 84 | PathMetric pathMetric = pathMetrics.elementAt(0); 85 | value = pathMetric.length * value; 86 | Tangent pos = pathMetric.getTangentForOffset(value); 87 | return pos.position; 88 | } 89 | } 90 | 91 | class PathPainter extends CustomPainter { 92 | Path path; 93 | 94 | PathPainter(this.path); 95 | 96 | @override 97 | void paint(Canvas canvas, Size size) { 98 | Paint paint = Paint() 99 | ..color = Colors.transparent 100 | ..style = PaintingStyle.stroke 101 | ..strokeWidth = 3.0; 102 | 103 | canvas.drawPath(this.path, paint); 104 | } 105 | 106 | @override 107 | bool shouldRepaint(CustomPainter oldDelegate) => true; 108 | } 109 | -------------------------------------------------------------------------------- /ankii_shopii/lib/widgets/base/animated_button.dart: -------------------------------------------------------------------------------- 1 | import 'package:ankiishopii/themes/constant.dart'; 2 | import 'package:flutter/material.dart'; 3 | 4 | class CustomAnimatedButton extends StatefulWidget { 5 | final double elevation; 6 | final Widget child; 7 | final Function onTap; 8 | final Color color; 9 | final ShapeBorder shape; 10 | 11 | CustomAnimatedButton( 12 | {this.elevation = 1, 13 | this.child, 14 | this.onTap, 15 | this.color = PRIMARY_COLOR, 16 | this.shape}); 17 | 18 | @override 19 | _CustomAnimatedButtonState createState() => _CustomAnimatedButtonState(); 20 | } 21 | 22 | class _CustomAnimatedButtonState extends State 23 | with SingleTickerProviderStateMixin { 24 | AnimationController animationController; 25 | Animation animation; 26 | 27 | @override 28 | void initState() { 29 | // TODO: implement initState 30 | super.initState(); 31 | animationController = 32 | AnimationController(vsync: this, duration: Duration(milliseconds: 20)); 33 | animation = Tween(begin: widget.elevation, end: 0.0) 34 | .animate(animationController); 35 | animation.addListener(() { 36 | setState(() {}); 37 | }); 38 | } 39 | 40 | @override 41 | Widget build(BuildContext context) { 42 | return GestureDetector( 43 | onTapDown: (down) { 44 | animationController.forward(); 45 | }, 46 | onTapUp: (up) { 47 | animationController.reverse(); 48 | if (widget.onTap != null) { 49 | widget.onTap(); 50 | } 51 | }, 52 | onTapCancel: () { 53 | animationController.reverse(); 54 | }, 55 | child: Card( 56 | color: widget.color, 57 | elevation: animation.value, 58 | shape: widget.shape, 59 | child: widget.child, 60 | ), 61 | ); 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /ankii_shopii/lib/widgets/base/custom_ontap_widget.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | class CustomOnTapWidget extends StatelessWidget { 4 | final Widget child; 5 | final Function onTap; 6 | final GlobalKey key; 7 | 8 | CustomOnTapWidget({this.child, this.onTap, this.key}); 9 | 10 | @override 11 | Widget build(BuildContext context) { 12 | return GestureDetector( 13 | key: key, 14 | // highlightColor: Colors.transparent, 15 | // splashColor: Colors.transparent, 16 | // focusColor: Colors.transparent, 17 | // hoverColor: Colors.transparent, 18 | 19 | onTap: onTap, 20 | child: child, 21 | ); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /ankii_shopii/lib/widgets/bottom_navigation_bar.dart: -------------------------------------------------------------------------------- 1 | import 'package:ankiishopii/themes/constant.dart'; 2 | import 'package:flutter/material.dart'; 3 | 4 | import 'base/custom_ontap_widget.dart'; 5 | 6 | class CustomBottomNavigationBar extends StatefulWidget { 7 | final bool barShadow; 8 | final Color backgroundColor; 9 | final Color itemColor; 10 | final Color selectedItemColor; 11 | final Color overlayColor; 12 | final List children; 13 | final Function(int) onChange; 14 | final int currentIndex; 15 | 16 | CustomBottomNavigationBar( 17 | {this.backgroundColor = BACKGROUND_COLOR, 18 | this.barShadow = false, 19 | this.itemColor = PRIMARY_COLOR, 20 | this.currentIndex = 0, 21 | @required this.children, 22 | this.selectedItemColor = FORE_TEXT_COLOR, 23 | this.overlayColor = PRIMARY_COLOR, 24 | this.onChange}); 25 | 26 | @override 27 | _CustomBottomNavigationBarState createState() => 28 | _CustomBottomNavigationBarState(); 29 | } 30 | 31 | class _CustomBottomNavigationBarState extends State { 32 | void _changeIndex(int index) { 33 | if (widget.onChange != null) { 34 | widget.onChange(index); 35 | } 36 | } 37 | 38 | @override 39 | void initState() { 40 | // TODO: implement initState 41 | super.initState(); 42 | } 43 | 44 | @override 45 | Widget build(BuildContext context) { 46 | return Container( 47 | height: 60, 48 | decoration: BoxDecoration( 49 | color: widget.backgroundColor, 50 | boxShadow: widget.barShadow 51 | ? [ 52 | BoxShadow( 53 | color: Colors.black26, 54 | offset: Offset(0, -2), 55 | blurRadius: 2) 56 | ] 57 | : null), 58 | child: Row( 59 | mainAxisAlignment: MainAxisAlignment.spaceAround, 60 | children: widget.children.map((item) { 61 | var color = item.color ?? widget.itemColor; 62 | var icon = item.icon; 63 | var label = item.label; 64 | int index = widget.children.indexOf(item); 65 | return CustomOnTapWidget( 66 | onTap: () { 67 | _changeIndex(index); 68 | }, 69 | child: AnimatedContainer( 70 | duration: Duration(milliseconds: 300), 71 | width: widget.currentIndex == index 72 | ? MediaQuery.of(context).size.width / widget.children.length + 73 | 20 74 | : 50, 75 | padding: EdgeInsets.only(left: 10, right: 10), 76 | margin: EdgeInsets.only(top: 10, bottom: 10), 77 | alignment: Alignment.center, 78 | decoration: BoxDecoration( 79 | color: widget.currentIndex == index 80 | ? widget.overlayColor 81 | : Colors.transparent, 82 | borderRadius: BorderRadius.circular(5)), 83 | child: Row( 84 | mainAxisAlignment: MainAxisAlignment.spaceAround, 85 | children: [ 86 | Icon( 87 | icon, 88 | size: 20, 89 | color: widget.currentIndex == index 90 | ? widget.selectedItemColor 91 | : color.withOpacity(0.5), 92 | ), 93 | Expanded( 94 | flex: 2, 95 | child: AnimatedSwitcher( 96 | duration: Duration(milliseconds: 200), 97 | child: widget.currentIndex == index 98 | ? Text( 99 | label ?? '', 100 | overflow: TextOverflow.ellipsis, 101 | textAlign: TextAlign.center, 102 | style: 103 | TextStyle(color: widget.selectedItemColor), 104 | ) 105 | : Container(), 106 | )) 107 | ], 108 | ), 109 | ), 110 | ); 111 | }).toList(), 112 | ), 113 | ); 114 | } 115 | } 116 | 117 | class CustomBottomNavigationItem { 118 | final IconData icon; 119 | final String label; 120 | final Color color; 121 | 122 | CustomBottomNavigationItem( 123 | {@required this.icon, @required this.label, this.color}); 124 | } 125 | -------------------------------------------------------------------------------- /ankii_shopii/lib/widgets/custom_sliver_appbar.dart: -------------------------------------------------------------------------------- 1 | import 'package:ankiishopii/helpers/media_query_helper.dart'; 2 | import 'package:ankiishopii/pages/cart/cart_page.dart'; 3 | import 'package:ankiishopii/themes/constant.dart'; 4 | import 'package:ankiishopii/widgets/base/custom_ontap_widget.dart'; 5 | import 'package:cached_network_image/cached_network_image.dart'; 6 | import 'package:flutter/material.dart'; 7 | 8 | import 'app_bar.dart'; 9 | 10 | class CustomSliverAppBar extends SliverPersistentHeaderDelegate { 11 | final double expandedHeight; 12 | final GlobalKey cartIconKey; 13 | 14 | CustomSliverAppBar({@required this.expandedHeight, this.cartIconKey}); 15 | 16 | @override 17 | Widget build( 18 | BuildContext context, double shrinkOffset, bool overlapsContent) { 19 | bool isCollapsed = kToolbarHeight - shrinkOffset <= 0; 20 | return Container( 21 | decoration: BoxDecoration(color: FOREGROUND_COLOR, boxShadow: [ 22 | BoxShadow(color: Colors.black26, offset: Offset(0, 3), blurRadius: 3) 23 | ]), 24 | child: Stack( 25 | fit: StackFit.expand, 26 | overflow: Overflow.visible, 27 | children: [ 28 | AnimatedOpacity( 29 | duration: Duration(milliseconds: 200), 30 | opacity: isCollapsed ? 0 : 1, 31 | child: CachedNetworkImage( 32 | imageUrl: 33 | "https://www.arcgis.com/sharing/rest/content/items/8f762395cd204552bb958ecb1b54339d/resources/1588745514029.jpeg?w=2932", 34 | fit: BoxFit.cover, 35 | ), 36 | ), 37 | // Container( 38 | // margin: EdgeInsets.only(top: kToolbarHeight, left: 10), 39 | // child: AnimatedOpacity( 40 | // duration: Duration(milliseconds: 200), 41 | // opacity: isCollapsed ? 0 : 1, 42 | // child: Text( 43 | // "Commerce", 44 | // style: TEXT_STYLE_PRIMARY.copyWith( 45 | // fontWeight: FontWeight.w700, 46 | // fontSize: 23, 47 | // ), 48 | // ), 49 | // ), 50 | // ), 51 | Positioned( 52 | width: ScreenHelper.getWidth(context), 53 | child: Container( 54 | margin: EdgeInsets.only( 55 | top: expandedHeight / 1.2 - shrinkOffset >= kToolbarHeight 56 | ? expandedHeight / 1.2 - shrinkOffset 57 | : kToolbarHeight, 58 | right: 20, 59 | left: 20), 60 | height: isCollapsed ? 65 : 70, 61 | child: Card( 62 | shape: RoundedRectangleBorder( 63 | borderRadius: BorderRadius.circular(15)), 64 | elevation: 10, 65 | child: Container( 66 | padding: EdgeInsets.symmetric(vertical: 5, horizontal: 10), 67 | child: Row( 68 | mainAxisAlignment: MainAxisAlignment.spaceBetween, 69 | children: [ 70 | Text( 71 | 'SHOPii', 72 | style: 73 | TEXT_STYLE_PRIMARY.copyWith(letterSpacing: 1.2), 74 | ), 75 | CustomOnTapWidget( 76 | onTap: () { 77 | // print('ok'); 78 | Navigator.push(context, 79 | MaterialPageRoute(builder: (b) => CartPage())); 80 | }, 81 | child: CartWidget( 82 | cartIconKey, 83 | size: 25, 84 | ), 85 | ) 86 | ], 87 | )), 88 | ), 89 | ), 90 | ), 91 | ], 92 | ), 93 | ); 94 | } 95 | 96 | @override 97 | double get maxExtent => expandedHeight; 98 | 99 | @override 100 | double get minExtent => kToolbarHeight + 70; 101 | 102 | @override 103 | bool shouldRebuild(SliverPersistentHeaderDelegate oldDelegate) => true; 104 | } 105 | -------------------------------------------------------------------------------- /ankii_shopii/lib/widgets/debug_widget.dart: -------------------------------------------------------------------------------- 1 | import 'package:ankiishopii/themes/constant.dart'; 2 | import 'package:flutter/material.dart'; 3 | 4 | class CustomErrorWidget extends StatelessWidget { 5 | final String error; 6 | 7 | CustomErrorWidget({this.error}); 8 | 9 | @override 10 | Widget build(BuildContext context) { 11 | return Container( 12 | child: Column( 13 | children: [ 14 | Icon( 15 | Icons.error, 16 | color: PRIMARY_COLOR, 17 | ), 18 | Text(error.toString()) 19 | ], 20 | ), 21 | ); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /ankii_shopii/lib/widgets/graphic_widget.dart: -------------------------------------------------------------------------------- 1 | import 'dart:async'; 2 | 3 | import 'package:ankiishopii/helpers/media_query_helper.dart'; 4 | import 'package:ankiishopii/themes/constant.dart'; 5 | import 'package:flutter/cupertino.dart'; 6 | import 'package:flutter/material.dart'; 7 | import 'package:font_awesome_flutter/font_awesome_flutter.dart'; 8 | 9 | const _defaultSpeed = Duration(milliseconds: 500); 10 | 11 | class CustomDotLoading extends StatefulWidget { 12 | final Duration speed; 13 | final Color primaryColor; 14 | final Color secondaryColor; 15 | final double size; 16 | 17 | CustomDotLoading( 18 | {this.speed = _defaultSpeed, 19 | this.primaryColor = PRIMARY_COLOR, 20 | this.secondaryColor = BACKGROUND_COLOR, 21 | this.size = 10}); 22 | 23 | @override 24 | _CustomDotLoadingState createState() => _CustomDotLoadingState(); 25 | } 26 | 27 | class _CustomDotLoadingState extends State with SingleTickerProviderStateMixin { 28 | AnimationController _animationController; 29 | StreamController animationValueStreamController = StreamController(); 30 | 31 | @override 32 | void initState() { 33 | // TODO: implement initState 34 | super.initState(); 35 | _animationController = AnimationController(vsync: this); 36 | _animationController.repeat(period: widget.speed, reverse: true); 37 | _animationController.addListener(() { 38 | animationValueStreamController.sink.add(_animationController.value); 39 | }); 40 | } 41 | 42 | @override 43 | void dispose() { 44 | // TODO: implement dispose 45 | _animationController.dispose(); 46 | animationValueStreamController.close(); 47 | super.dispose(); 48 | } 49 | 50 | @override 51 | Widget build(BuildContext context) { 52 | return StreamBuilder( 53 | stream: animationValueStreamController.stream, 54 | builder: (context, snapshot) { 55 | double value = snapshot.data ?? 0; 56 | return Container( 57 | child: Row( 58 | mainAxisAlignment: MainAxisAlignment.center, 59 | children: [ 60 | CircleAvatar( 61 | radius: widget.size, 62 | backgroundColor: value < 0.3 ? widget.primaryColor : widget.secondaryColor, 63 | ), 64 | SizedBox( 65 | width: 5, 66 | ), 67 | CircleAvatar( 68 | radius: widget.size, 69 | backgroundColor: value > 0.3 && value < 0.7 ? widget.primaryColor : widget.secondaryColor, 70 | ), 71 | SizedBox( 72 | width: 5, 73 | ), 74 | CircleAvatar( 75 | radius: widget.size, 76 | backgroundColor: value > 0.7 ? widget.primaryColor : widget.secondaryColor, 77 | ), 78 | ], 79 | ), 80 | ); 81 | }); 82 | } 83 | } 84 | 85 | class CustomEmptyWidget extends StatelessWidget { 86 | final Color backgroundColor; 87 | final Widget title; 88 | 89 | CustomEmptyWidget({this.backgroundColor = FOREGROUND_COLOR, this.title}); 90 | 91 | @override 92 | Widget build(BuildContext context) { 93 | return Container( 94 | margin: EdgeInsets.all(20), 95 | padding: EdgeInsets.all(20), 96 | decoration: BoxDecoration(color: backgroundColor, borderRadius: BorderRadius.circular(50)), 97 | child: title, 98 | ); 99 | } 100 | } 101 | -------------------------------------------------------------------------------- /ankii_shopii/lib/widgets/image_viewer.dart: -------------------------------------------------------------------------------- 1 | import 'package:ankiishopii/helpers/media_query_helper.dart'; 2 | import 'package:ankiishopii/themes/constant.dart'; 3 | import 'package:carousel_slider/carousel_slider.dart'; 4 | import 'package:flutter/material.dart'; 5 | 6 | class ImagesViewer extends StatelessWidget { 7 | final List images; 8 | 9 | ImagesViewer(this.images); 10 | 11 | @override 12 | Widget build(BuildContext context) { 13 | return Scaffold( 14 | backgroundColor: Colors.black, 15 | body: Container( 16 | padding: EdgeInsets.only(top: ScreenHelper.getPaddingTop(context)), 17 | child: Stack( 18 | children: [ 19 | Center( 20 | child: Container( 21 | height: ScreenHelper.getSafeHeight(context), 22 | child: CarouselSlider(items: images, options: CarouselOptions( 23 | 24 | enlargeCenterPage: true, 25 | )))), 26 | Container( 27 | margin: EdgeInsets.all(20), 28 | child: IconButton( 29 | icon: Icon( 30 | Icons.close, 31 | size: 30, 32 | color: FOREGROUND_COLOR, 33 | ), 34 | onPressed: () { 35 | Navigator.pop(context); 36 | }), 37 | ) 38 | ], 39 | ), 40 | ), 41 | ); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /ankii_shopii/lib/widgets/loading_dialog.dart: -------------------------------------------------------------------------------- 1 | import 'package:ankiishopii/themes/constant.dart'; 2 | import 'package:ankiishopii/widgets/graphic_widget.dart'; 3 | import 'package:flutter/cupertino.dart'; 4 | import 'package:flutter/material.dart'; 5 | 6 | class LoadingDialog { 7 | static bool _isLoadingDialogShowing = false; 8 | 9 | static showLoadingDialog(BuildContext context, 10 | {String text, bool hideOnBackButton = false}) async { 11 | _isLoadingDialogShowing = true; 12 | showDialog( 13 | context: context, 14 | barrierDismissible: false, 15 | child: WillPopScope( 16 | onWillPop: () async { 17 | return hideOnBackButton; 18 | }, 19 | child: AlertDialog( 20 | elevation: 0, 21 | backgroundColor: text == null 22 | ? Colors.transparent 23 | : BACKGROUND_COLOR.withOpacity(0.9), 24 | shape: 25 | RoundedRectangleBorder(borderRadius: BorderRadius.circular(30)), 26 | content: Column( 27 | mainAxisSize: MainAxisSize.min, 28 | children: [ 29 | CustomDotLoading( 30 | primaryColor: FOREGROUND_COLOR, 31 | ), 32 | SizedBox( 33 | height: text == null ? 0 : 10, 34 | ), 35 | text == null 36 | ? Container() 37 | : Text( 38 | text ?? 'Processing...', 39 | style: TEXT_STYLE_PRIMARY.copyWith( 40 | fontWeight: FontWeight.bold), 41 | ) 42 | ], 43 | ), 44 | ), 45 | )); 46 | } 47 | 48 | static hideLoadingDialog(BuildContext context, {String text}) async { 49 | if (_isLoadingDialogShowing) { 50 | Navigator.pop(context); 51 | _isLoadingDialogShowing = false; 52 | } 53 | } 54 | 55 | static showMessage(BuildContext context, {String text}) async { 56 | return await showDialog( 57 | context: context, 58 | child: AlertDialog( 59 | backgroundColor: BACKGROUND_COLOR, 60 | shape: RoundedRectangleBorder( 61 | borderRadius: BorderRadius.circular(30), 62 | ), 63 | content: Text( 64 | text ?? '', 65 | style: TEXT_STYLE_PRIMARY.copyWith(fontWeight: FontWeight.bold), 66 | ), 67 | actions: [ 68 | FlatButton( 69 | onPressed: () { 70 | Navigator.pop(context); 71 | }, 72 | child: Text('OK'), 73 | ) 74 | ], 75 | )); 76 | } 77 | 78 | static showConfirm(BuildContext context, 79 | {String text, @required Function onYes, @required Function onNo}) async { 80 | return await showDialog( 81 | context: context, 82 | child: AlertDialog( 83 | backgroundColor: BACKGROUND_COLOR, 84 | shape: RoundedRectangleBorder( 85 | borderRadius: BorderRadius.circular(30), 86 | ), 87 | content: text == null 88 | ? null 89 | : Text( 90 | text, 91 | style: 92 | TEXT_STYLE_PRIMARY.copyWith(fontWeight: FontWeight.bold), 93 | ), 94 | actions: [ 95 | FlatButton( 96 | color: FOREGROUND_COLOR, 97 | shape: RoundedRectangleBorder( 98 | borderRadius: BorderRadius.circular(20)), 99 | onPressed: () { 100 | Navigator.pop(context); 101 | onNo(); 102 | }, 103 | child: Text('No'), 104 | ), 105 | FlatButton( 106 | color: FOREGROUND_COLOR, 107 | shape: RoundedRectangleBorder( 108 | borderRadius: BorderRadius.circular(20)), 109 | onPressed: () { 110 | Navigator.pop(context); 111 | onYes(); 112 | }, 113 | child: Text('Yes'), 114 | ) 115 | ], 116 | )); 117 | } 118 | } 119 | -------------------------------------------------------------------------------- /ankii_shopii/pubspec.yaml: -------------------------------------------------------------------------------- 1 | name: ankiishopii 2 | description: Simple Ecommerce App 3 | 4 | # The following line prevents the package from being accidentally published to 5 | # pub.dev using `pub publish`. This is preferred for private packages. 6 | publish_to: 'none' # Remove this line if you wish to publish to pub.dev 7 | 8 | # The following defines the version and build number for your application. 9 | # A version number is three numbers separated by dots, like 1.2.43 10 | # followed by an optional build number separated by a +. 11 | # Both the version and the builder number may be overridden in flutter 12 | # build by specifying --build-name and --build-number, respectively. 13 | # In Android, build-name is used as versionName while build-number used as versionCode. 14 | # Read more about Android versioning at https://developer.android.com/studio/publish/versioning 15 | # In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion. 16 | # Read more about iOS versioning at 17 | # https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html 18 | version: 1.0.0+1 19 | 20 | environment: 21 | sdk: ">=2.7.0 <3.0.0" 22 | 23 | dependencies: 24 | flutter: 25 | sdk: flutter 26 | 27 | 28 | # The following adds the Cupertino Icons font to your application. 29 | # Use with the CupertinoIcons class for iOS style icons. 30 | cupertino_icons: ^0.1.3 31 | 32 | flutter_bloc: ^6.1.1 33 | http: ^0.12.2 34 | dio: ^3.0.10 35 | equatable: ^1.2.5 36 | shared_preferences: ^0.5.12+4 37 | rxdart: ^0.25.0 38 | 39 | #map 40 | google_maps_flutter: ^1.0.10 41 | geolocator: 5.3.1 42 | flutter_polyline_points: ^0.2.4 43 | 44 | 45 | #ui 46 | intl: ^0.16.1 47 | google_fonts: ^1.1.1 48 | carousel_slider: ^2.3.1 49 | cached_network_image: ^2.5.0 50 | font_awesome_flutter: ^8.11.0 51 | 52 | #local 53 | 54 | dev_dependencies: 55 | flutter_test: 56 | sdk: flutter 57 | 58 | # For information on the generic Dart part of this file, see the 59 | # following page: https://dart.dev/tools/pub/pubspec 60 | 61 | # The following section is specific to Flutter. 62 | flutter: 63 | 64 | # The following line ensures that the Material Icons font is 65 | # included with your application, so that you can use the icons in 66 | # the material Icons class. 67 | uses-material-design: true 68 | fonts: 69 | - family: MyIcons 70 | fonts: 71 | - asset: assets/fonts/IconFont.ttf 72 | - family: Jura 73 | fonts: 74 | - asset: assets/fonts/Jura.ttf 75 | assets: 76 | - assets/cliparts/ 77 | 78 | # To add assets to your application, add an assets section, like this: 79 | # assets: 80 | # - images/a_dot_burr.jpeg 81 | # - images/a_dot_ham.jpeg 82 | 83 | # An image asset can refer to one or more resolution-specific "variants", see 84 | # https://flutter.dev/assets-and-images/#resolution-aware. 85 | 86 | # For details regarding adding assets from package dependencies, see 87 | # https://flutter.dev/assets-and-images/#from-packages 88 | 89 | # To add custom fonts to your application, add a fonts section here, 90 | # in this "flutter" section. Each entry in this list should have a 91 | # "family" key with the font family name, and a "fonts" key with a 92 | # list giving the asset and other descriptors for the font. For 93 | # example: 94 | # fonts: 95 | # - family: Schyler 96 | # fonts: 97 | # - asset: fonts/Schyler-Regular.ttf 98 | # - asset: fonts/Schyler-Italic.ttf 99 | # style: italic 100 | # - family: Trajan Pro 101 | # fonts: 102 | # - asset: fonts/TrajanPro.ttf 103 | # - asset: fonts/TrajanPro_Bold.ttf 104 | # weight: 700 105 | # 106 | # For details regarding fonts from package dependencies, 107 | # see https://flutter.dev/custom-fonts/#from-packages 108 | -------------------------------------------------------------------------------- /ankii_shopii/test/widget_test.dart: -------------------------------------------------------------------------------- 1 | // This is a basic Flutter widget test. 2 | // 3 | // To perform an interaction with a widget in your test, use the WidgetTester 4 | // utility that Flutter provides. For example, you can send tap and scroll 5 | // gestures. You can also use WidgetTester to find child widgets in the widget 6 | // tree, read text, and verify that the values of widget properties are correct. 7 | 8 | import 'package:flutter/material.dart'; 9 | import 'package:flutter_test/flutter_test.dart'; 10 | 11 | import 'package:ankiishopii/main.dart'; 12 | 13 | void main() { 14 | testWidgets('Counter increments smoke test', (WidgetTester tester) async { 15 | // Build our app and trigger a frame. 16 | await tester.pumpWidget(MyApp()); 17 | 18 | // Verify that our counter starts at 0. 19 | expect(find.text('0'), findsOneWidget); 20 | expect(find.text('1'), findsNothing); 21 | 22 | // Tap the '+' icon and trigger a frame. 23 | await tester.tap(find.byIcon(Icons.add)); 24 | await tester.pump(); 25 | 26 | // Verify that our counter has incremented. 27 | expect(find.text('0'), findsNothing); 28 | expect(find.text('1'), findsOneWidget); 29 | }); 30 | } 31 | -------------------------------------------------------------------------------- /api_SHOPii/.vs/SHOPii/DesignTimeBuild/.dtbcache: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ankiimation/flutter_SHOPii/2c2a45bbcade33ea97f13302092b044b62a09fc6/api_SHOPii/.vs/SHOPii/DesignTimeBuild/.dtbcache -------------------------------------------------------------------------------- /api_SHOPii/.vs/SHOPii/DesignTimeBuild/.dtbcache.v2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ankiimation/flutter_SHOPii/2c2a45bbcade33ea97f13302092b044b62a09fc6/api_SHOPii/.vs/SHOPii/DesignTimeBuild/.dtbcache.v2 -------------------------------------------------------------------------------- /api_SHOPii/.vs/SHOPii/v16/.suo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ankiimation/flutter_SHOPii/2c2a45bbcade33ea97f13302092b044b62a09fc6/api_SHOPii/.vs/SHOPii/v16/.suo -------------------------------------------------------------------------------- /api_SHOPii/.vs/SHOPii/v16/Server/sqlite3/db.lock: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ankiimation/flutter_SHOPii/2c2a45bbcade33ea97f13302092b044b62a09fc6/api_SHOPii/.vs/SHOPii/v16/Server/sqlite3/db.lock -------------------------------------------------------------------------------- /api_SHOPii/.vs/SHOPii/v16/Server/sqlite3/storage.ide: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ankiimation/flutter_SHOPii/2c2a45bbcade33ea97f13302092b044b62a09fc6/api_SHOPii/.vs/SHOPii/v16/Server/sqlite3/storage.ide -------------------------------------------------------------------------------- /api_SHOPii/SHOPii.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 16 4 | VisualStudioVersion = 16.0.30225.117 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SHOPii", "SHOPii\SHOPii.csproj", "{76960710-3EFF-4E9F-B818-5D3652F2E0B1}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Any CPU = Debug|Any CPU 11 | Release|Any CPU = Release|Any CPU 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {76960710-3EFF-4E9F-B818-5D3652F2E0B1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 15 | {76960710-3EFF-4E9F-B818-5D3652F2E0B1}.Debug|Any CPU.Build.0 = Debug|Any CPU 16 | {76960710-3EFF-4E9F-B818-5D3652F2E0B1}.Release|Any CPU.ActiveCfg = Release|Any CPU 17 | {76960710-3EFF-4E9F-B818-5D3652F2E0B1}.Release|Any CPU.Build.0 = Release|Any CPU 18 | EndGlobalSection 19 | GlobalSection(SolutionProperties) = preSolution 20 | HideSolutionNode = FALSE 21 | EndGlobalSection 22 | GlobalSection(ExtensibilityGlobals) = postSolution 23 | SolutionGuid = {716AB562-0BEE-437A-ADF0-ECCCF5F0CF9D} 24 | EndGlobalSection 25 | EndGlobal 26 | -------------------------------------------------------------------------------- /api_SHOPii/SHOPii/.config/dotnet-tools.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": 1, 3 | "isRoot": true, 4 | "tools": { 5 | "dotnet-ef": { 6 | "version": "3.1.6", 7 | "commands": [ 8 | "dotnet-ef" 9 | ] 10 | } 11 | } 12 | } -------------------------------------------------------------------------------- /api_SHOPii/SHOPii/.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | // Use IntelliSense to find out which attributes exist for C# debugging 3 | // Use hover for the description of the existing attributes 4 | // For further information visit https://github.com/OmniSharp/omnisharp-vscode/blob/master/debugger-launchjson.md 5 | "version": "0.2.0", 6 | "configurations": [ 7 | { 8 | "name": ".NET Core Launch (web)", 9 | "type": "coreclr", 10 | "request": "launch", 11 | "preLaunchTask": "build", 12 | // If you have changed target frameworks, make sure to update the program path. 13 | "program": "${workspaceFolder}/bin/Debug/netcoreapp3.1/SHOPii.dll", 14 | "args": [], 15 | "cwd": "${workspaceFolder}", 16 | "stopAtEntry": false, 17 | // Enable launching a web browser when ASP.NET Core starts. For more information: https://aka.ms/VSCode-CS-LaunchJson-WebBrowser 18 | "serverReadyAction": { 19 | "action": "openExternally", 20 | "pattern": "\\bNow listening on:\\s+(https?://\\S+)" 21 | }, 22 | "env": { 23 | "ASPNETCORE_ENVIRONMENT": "Development" 24 | }, 25 | "sourceFileMap": { 26 | "/Views": "${workspaceFolder}/Views" 27 | } 28 | }, 29 | { 30 | "name": ".NET Core Attach", 31 | "type": "coreclr", 32 | "request": "attach", 33 | "processId": "${command:pickProcess}" 34 | } 35 | ] 36 | } -------------------------------------------------------------------------------- /api_SHOPii/SHOPii/.vscode/tasks.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "2.0.0", 3 | "tasks": [ 4 | { 5 | "label": "build", 6 | "command": "dotnet", 7 | "type": "process", 8 | "args": [ 9 | "build", 10 | "${workspaceFolder}/SHOPii.csproj", 11 | "/property:GenerateFullPaths=true", 12 | "/consoleloggerparameters:NoSummary" 13 | ], 14 | "problemMatcher": "$msCompile" 15 | }, 16 | { 17 | "label": "publish", 18 | "command": "dotnet", 19 | "type": "process", 20 | "args": [ 21 | "publish", 22 | "${workspaceFolder}/SHOPii.csproj", 23 | "/property:GenerateFullPaths=true", 24 | "/consoleloggerparameters:NoSummary" 25 | ], 26 | "problemMatcher": "$msCompile" 27 | }, 28 | { 29 | "label": "watch", 30 | "command": "dotnet", 31 | "type": "process", 32 | "args": [ 33 | "watch", 34 | "run", 35 | "${workspaceFolder}/SHOPii.csproj", 36 | "/property:GenerateFullPaths=true", 37 | "/consoleloggerparameters:NoSummary" 38 | ], 39 | "problemMatcher": "$msCompile" 40 | } 41 | ] 42 | } -------------------------------------------------------------------------------- /api_SHOPii/SHOPii/Controllers/API/AccountsController.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | using Microsoft.AspNetCore.Authorization; 6 | using Microsoft.AspNetCore.Http; 7 | using Microsoft.AspNetCore.Mvc; 8 | using Microsoft.EntityFrameworkCore; 9 | using SHOPii.Models; 10 | using SHOPii.Services; 11 | 12 | namespace SHOPii.Controllers 13 | { 14 | [Route("api")] 15 | 16 | [ApiController] 17 | [Authorize] 18 | public class AccountsController : ControllerBase 19 | { 20 | private IUserService userService; 21 | private static SHOPIIContext _context = new SHOPIIContext(); 22 | 23 | public AccountsController(IUserService userService) 24 | { 25 | this.userService = userService; 26 | } 27 | 28 | 29 | public class LoginInputModel 30 | { 31 | public String username; 32 | public String password; 33 | 34 | public LoginInputModel(string username, string password) 35 | { 36 | this.username = username; 37 | this.password = password; 38 | } 39 | } 40 | [AllowAnonymous] 41 | [HttpPost("login")] 42 | public IActionResult login([FromBody] LoginInputModel loginModel) 43 | { 44 | 45 | var userTemp = userService.AuthUser(loginModel.username, loginModel.password); 46 | 47 | if (userTemp == null) 48 | return BadRequest(new { message = "Sai thông tin đăng cmn nhập" }); 49 | return Ok(userTemp); 50 | 51 | } 52 | [HttpGet("current")] 53 | public async Task getCurrentAccount() 54 | { 55 | 56 | var username = User.Identity.Name; 57 | var account = await _context.Account.Include(a => a.DeliveryAddress).Include(a => a.Favorite).ThenInclude(f => f.Product).FirstOrDefaultAsync(a => a.Username.Equals(username)); 58 | if (account != null) 59 | { 60 | account.Password = null; 61 | return Ok(account); 62 | } 63 | return NotFound(); 64 | } 65 | 66 | 67 | public class UpdateDeliveryIdModel 68 | { 69 | public int deliveryId; 70 | } 71 | [HttpPut("current/defaultDeliveryId")] 72 | public async Task updateDefaultDeliveryId([FromBody] UpdateDeliveryIdModel deliveryId) //username only 73 | { 74 | 75 | var currentAccount = _context.Account.Find(User.Identity.Name); 76 | 77 | if(currentAccount!=null) 78 | { 79 | 80 | currentAccount.DefaultDeliveryId = deliveryId.deliveryId; 81 | _context.Account.Update(currentAccount); 82 | await _context.SaveChangesAsync(); 83 | currentAccount = await _context.Account.Include(a => a.DeliveryAddress).Include(a => a.Favorite).ThenInclude(f => f.Product).FirstOrDefaultAsync(a => a.Username.Equals(currentAccount.Username)); 84 | return Ok(currentAccount); 85 | } 86 | return NotFound(); 87 | 88 | 89 | } 90 | //[AllowAnonymous] 91 | //public IActionResult getAllAccount() 92 | //{ 93 | // return Ok((new UserService()).getAllAccounts()); 94 | //} 95 | 96 | } 97 | } 98 | -------------------------------------------------------------------------------- /api_SHOPii/SHOPii/Controllers/API/CategoriesController.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | using Microsoft.AspNetCore.Http; 6 | using Microsoft.AspNetCore.Mvc; 7 | using Microsoft.EntityFrameworkCore; 8 | using SHOPii.Models; 9 | 10 | namespace SHOPii.Controllers 11 | { 12 | [Route("api/[controller]")] 13 | [ApiController] 14 | public class CategoriesController : ControllerBase 15 | { 16 | private readonly SHOPIIContext _context; 17 | 18 | public CategoriesController(SHOPIIContext context) 19 | { 20 | _context = context; 21 | } 22 | 23 | // GET: api/Categories 24 | [HttpGet] 25 | public async Task>> GetCategory() 26 | { 27 | return await _context.Category.Include(c=>c.Product).ToListAsync(); 28 | } 29 | 30 | // GET: api/Categories/5 31 | [HttpGet("{id}")] 32 | public async Task> GetCategory(int id) 33 | { 34 | var category = await _context.Category.Include(c=>c.Product).FirstOrDefaultAsync(c=>c.Id == id); 35 | 36 | if (category == null) 37 | { 38 | return NotFound(); 39 | } 40 | 41 | return category; 42 | } 43 | 44 | // PUT: api/Categories/5 45 | // To protect from overposting attacks, enable the specific properties you want to bind to, for 46 | // more details, see https://go.microsoft.com/fwlink/?linkid=2123754. 47 | [HttpPut("{id}")] 48 | public async Task PutCategory(int id, Category category) 49 | { 50 | if (id != category.Id) 51 | { 52 | return BadRequest(); 53 | } 54 | 55 | _context.Entry(category).State = EntityState.Modified; 56 | 57 | try 58 | { 59 | await _context.SaveChangesAsync(); 60 | } 61 | catch (DbUpdateConcurrencyException) 62 | { 63 | if (!CategoryExists(id)) 64 | { 65 | return NotFound(); 66 | } 67 | else 68 | { 69 | throw; 70 | } 71 | } 72 | 73 | return NoContent(); 74 | } 75 | 76 | // POST: api/Categories 77 | // To protect from overposting attacks, enable the specific properties you want to bind to, for 78 | // more details, see https://go.microsoft.com/fwlink/?linkid=2123754. 79 | [HttpPost] 80 | public async Task> PostCategory(Category category) 81 | { 82 | _context.Category.Add(category); 83 | await _context.SaveChangesAsync(); 84 | 85 | return CreatedAtAction("GetCategory", new { id = category.Id }, category); 86 | } 87 | 88 | // DELETE: api/Categories/5 89 | [HttpDelete("{id}")] 90 | public async Task> DeleteCategory(int id) 91 | { 92 | var category = await _context.Category.FindAsync(id); 93 | if (category == null) 94 | { 95 | return NotFound(); 96 | } 97 | 98 | _context.Category.Remove(category); 99 | await _context.SaveChangesAsync(); 100 | 101 | return category; 102 | } 103 | 104 | private bool CategoryExists(int id) 105 | { 106 | return _context.Category.Any(e => e.Id == id); 107 | } 108 | } 109 | } 110 | -------------------------------------------------------------------------------- /api_SHOPii/SHOPii/Controllers/API/DeliveryAddressesController.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | using Microsoft.AspNetCore.Authorization; 6 | using Microsoft.AspNetCore.Http; 7 | using Microsoft.AspNetCore.Mvc; 8 | using Microsoft.EntityFrameworkCore; 9 | using SHOPii.Models; 10 | 11 | namespace SHOPii.Controllers 12 | { 13 | [Route("api/[controller]")] 14 | [ApiController] 15 | [Authorize] 16 | public class DeliveryAddressesController : ControllerBase 17 | { 18 | private readonly SHOPIIContext _context; 19 | 20 | public DeliveryAddressesController(SHOPIIContext context) 21 | { 22 | _context = context; 23 | } 24 | 25 | // GET: api/DeliveryAddresses 26 | [HttpGet] 27 | public async Task>> GetDeliveryAddress() 28 | { 29 | var username = User.Identity.Name; 30 | return await _context.DeliveryAddress.Where(d => d.Username.Equals(username)).ToListAsync(); 31 | } 32 | 33 | // GET: api/DeliveryAddresses/5 34 | [HttpGet("{id}")] 35 | public async Task> GetDeliveryAddress(int id) 36 | { 37 | var username = User.Identity.Name; 38 | var deliveryAddress = await _context.DeliveryAddress.Where(d => d.Username.Equals(username)).FirstOrDefaultAsync(d => d.Id == id); 39 | 40 | if (deliveryAddress == null) 41 | { 42 | return NotFound(); 43 | } 44 | 45 | return deliveryAddress; 46 | } 47 | 48 | // PUT: api/DeliveryAddresses/5 49 | // To protect from overposting attacks, enable the specific properties you want to bind to, for 50 | // more details, see https://go.microsoft.com/fwlink/?linkid=2123754. 51 | [HttpPut("{id}")] 52 | public async Task PutDeliveryAddress(int id, DeliveryAddress deliveryAddress) 53 | { 54 | if (id != deliveryAddress.Id) 55 | { 56 | return BadRequest(); 57 | } 58 | 59 | _context.Entry(deliveryAddress).State = EntityState.Modified; 60 | 61 | try 62 | { 63 | await _context.SaveChangesAsync(); 64 | } 65 | catch (DbUpdateConcurrencyException) 66 | { 67 | if (!DeliveryAddressExists(id)) 68 | { 69 | return NotFound(); 70 | } 71 | else 72 | { 73 | throw; 74 | } 75 | } 76 | 77 | return NoContent(); 78 | } 79 | 80 | // POST: api/DeliveryAddresses 81 | // To protect from overposting attacks, enable the specific properties you want to bind to, for 82 | // more details, see https://go.microsoft.com/fwlink/?linkid=2123754. 83 | [HttpPost] 84 | public async Task> PostDeliveryAddress(DeliveryAddress deliveryAddress) 85 | { 86 | var username = User.Identity.Name; 87 | deliveryAddress.Username = username; 88 | _context.DeliveryAddress.Add(deliveryAddress); 89 | await _context.SaveChangesAsync(); 90 | 91 | return Ok(deliveryAddress); 92 | } 93 | 94 | // DELETE: api/DeliveryAddresses/5 95 | [HttpDelete("{id}")] 96 | public async Task> DeleteDeliveryAddress(int id) 97 | { 98 | var deliveryAddress = await _context.DeliveryAddress.FindAsync(id); 99 | if (deliveryAddress == null) 100 | { 101 | return NotFound(); 102 | } 103 | 104 | _context.DeliveryAddress.Remove(deliveryAddress); 105 | await _context.SaveChangesAsync(); 106 | 107 | return deliveryAddress; 108 | } 109 | 110 | private bool DeliveryAddressExists(int id) 111 | { 112 | return _context.DeliveryAddress.Any(e => e.Id == id); 113 | } 114 | } 115 | } 116 | -------------------------------------------------------------------------------- /api_SHOPii/SHOPii/Controllers/API/OrderingDetailsController.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | using Microsoft.AspNetCore.Http; 6 | using Microsoft.AspNetCore.Mvc; 7 | using Microsoft.EntityFrameworkCore; 8 | using SHOPii.Models; 9 | 10 | namespace SHOPii.Controllers 11 | { 12 | [Route("api/[controller]")] 13 | [ApiController] 14 | public class OrderingDetailsController : ControllerBase 15 | { 16 | private readonly SHOPIIContext _context; 17 | 18 | public OrderingDetailsController(SHOPIIContext context) 19 | { 20 | _context = context; 21 | } 22 | 23 | // GET: api/OrderingDetails 24 | [HttpGet] 25 | public async Task>> GetOrderingDetail() 26 | { 27 | return await _context.OrderingDetail.Include(od=>od.Product).ToListAsync(); 28 | } 29 | 30 | // GET: api/OrderingDetails/5 31 | [HttpGet("{id}")] 32 | public async Task> GetOrderingDetail(int id) 33 | { 34 | var orderingDetail = await _context.OrderingDetail.FindAsync(id); 35 | 36 | if (orderingDetail == null) 37 | { 38 | return NotFound(); 39 | } 40 | 41 | return orderingDetail; 42 | } 43 | 44 | // PUT: api/OrderingDetails/5 45 | // To protect from overposting attacks, enable the specific properties you want to bind to, for 46 | // more details, see https://go.microsoft.com/fwlink/?linkid=2123754. 47 | [HttpPut("{id}")] 48 | public async Task PutOrderingDetail(int id, OrderingDetail orderingDetail) 49 | { 50 | if (id != orderingDetail.Id) 51 | { 52 | return BadRequest(); 53 | } 54 | 55 | _context.Entry(orderingDetail).State = EntityState.Modified; 56 | 57 | try 58 | { 59 | await _context.SaveChangesAsync(); 60 | } 61 | catch (DbUpdateConcurrencyException) 62 | { 63 | if (!OrderingDetailExists(id)) 64 | { 65 | return NotFound(); 66 | } 67 | else 68 | { 69 | throw; 70 | } 71 | } 72 | 73 | return NoContent(); 74 | } 75 | 76 | // POST: api/OrderingDetails 77 | // To protect from overposting attacks, enable the specific properties you want to bind to, for 78 | // more details, see https://go.microsoft.com/fwlink/?linkid=2123754. 79 | [HttpPost] 80 | public async Task> PostOrderingDetail(OrderingDetail orderingDetail) 81 | { 82 | _context.OrderingDetail.Add(orderingDetail); 83 | await _context.SaveChangesAsync(); 84 | 85 | return CreatedAtAction("GetOrderingDetail", new { id = orderingDetail.Id }, orderingDetail); 86 | } 87 | 88 | // DELETE: api/OrderingDetails/5 89 | [HttpDelete("{id}")] 90 | public async Task> DeleteOrderingDetail(int id) 91 | { 92 | var orderingDetail = await _context.OrderingDetail.FindAsync(id); 93 | if (orderingDetail == null) 94 | { 95 | return NotFound(); 96 | } 97 | 98 | _context.OrderingDetail.Remove(orderingDetail); 99 | await _context.SaveChangesAsync(); 100 | 101 | return orderingDetail; 102 | } 103 | 104 | private bool OrderingDetailExists(int id) 105 | { 106 | return _context.OrderingDetail.Any(e => e.Id == id); 107 | } 108 | } 109 | } 110 | -------------------------------------------------------------------------------- /api_SHOPii/SHOPii/Controllers/API/ProductImagesController.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | using Microsoft.AspNetCore.Http; 6 | using Microsoft.AspNetCore.Mvc; 7 | using Microsoft.EntityFrameworkCore; 8 | using SHOPii.Models; 9 | 10 | namespace SHOPii.Controllers 11 | { 12 | [Route("api/[controller]")] 13 | [ApiController] 14 | public class ProductImagesController : ControllerBase 15 | { 16 | private readonly SHOPIIContext _context; 17 | 18 | public ProductImagesController(SHOPIIContext context) 19 | { 20 | _context = context; 21 | } 22 | 23 | // GET: api/ProductImages 24 | [HttpGet] 25 | public async Task>> GetProductImage() 26 | { 27 | return await _context.ProductImage.ToListAsync(); 28 | } 29 | 30 | // GET: api/ProductImages/5 31 | [HttpGet("{id}")] 32 | public async Task> GetProductImage(int id) 33 | { 34 | var productImage = await _context.ProductImage.FindAsync(id); 35 | 36 | if (productImage == null) 37 | { 38 | return NotFound(); 39 | } 40 | 41 | return productImage; 42 | } 43 | 44 | // PUT: api/ProductImages/5 45 | // To protect from overposting attacks, enable the specific properties you want to bind to, for 46 | // more details, see https://go.microsoft.com/fwlink/?linkid=2123754. 47 | [HttpPut("{id}")] 48 | public async Task PutProductImage(int id, ProductImage productImage) 49 | { 50 | if (id != productImage.Id) 51 | { 52 | return BadRequest(); 53 | } 54 | 55 | _context.Entry(productImage).State = EntityState.Modified; 56 | 57 | try 58 | { 59 | await _context.SaveChangesAsync(); 60 | } 61 | catch (DbUpdateConcurrencyException) 62 | { 63 | if (!ProductImageExists(id)) 64 | { 65 | return NotFound(); 66 | } 67 | else 68 | { 69 | throw; 70 | } 71 | } 72 | 73 | return NoContent(); 74 | } 75 | 76 | // POST: api/ProductImages 77 | // To protect from overposting attacks, enable the specific properties you want to bind to, for 78 | // more details, see https://go.microsoft.com/fwlink/?linkid=2123754. 79 | [HttpPost] 80 | public async Task> PostProductImage(ProductImage productImage) 81 | { 82 | _context.ProductImage.Add(productImage); 83 | await _context.SaveChangesAsync(); 84 | 85 | return CreatedAtAction("GetProductImage", new { id = productImage.Id }, productImage); 86 | } 87 | 88 | // DELETE: api/ProductImages/5 89 | [HttpDelete("{id}")] 90 | public async Task> DeleteProductImage(int id) 91 | { 92 | var productImage = await _context.ProductImage.FindAsync(id); 93 | if (productImage == null) 94 | { 95 | return NotFound(); 96 | } 97 | 98 | _context.ProductImage.Remove(productImage); 99 | await _context.SaveChangesAsync(); 100 | 101 | return productImage; 102 | } 103 | 104 | private bool ProductImageExists(int id) 105 | { 106 | return _context.ProductImage.Any(e => e.Id == id); 107 | } 108 | } 109 | } 110 | -------------------------------------------------------------------------------- /api_SHOPii/SHOPii/Controllers/API/ShopAccountsController.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | using Microsoft.AspNetCore.Http; 6 | using Microsoft.AspNetCore.Mvc; 7 | using Microsoft.EntityFrameworkCore; 8 | using SHOPii.Models; 9 | 10 | namespace SHOPii.Controllers.API 11 | { 12 | [Route("api/[controller]")] 13 | [ApiController] 14 | public class ShopAccountsController : ControllerBase 15 | { 16 | private readonly SHOPIIContext _context; 17 | 18 | public ShopAccountsController(SHOPIIContext context) 19 | { 20 | _context = context; 21 | } 22 | 23 | // GET: api/ShopAccounts 24 | [HttpGet] 25 | public async Task>> GetShopAccount() 26 | { 27 | return await _context.ShopAccount.ToListAsync(); 28 | } 29 | 30 | // GET: api/ShopAccounts/5 31 | [HttpGet("{id}")] 32 | public async Task> GetShopAccount(string id) 33 | { 34 | var shopAccount = await _context.ShopAccount.FindAsync(id); 35 | 36 | if (shopAccount == null) 37 | { 38 | return NotFound(); 39 | } 40 | 41 | return shopAccount; 42 | } 43 | 44 | // PUT: api/ShopAccounts/5 45 | // To protect from overposting attacks, enable the specific properties you want to bind to, for 46 | // more details, see https://go.microsoft.com/fwlink/?linkid=2123754. 47 | [HttpPut("{id}")] 48 | public async Task PutShopAccount(string id, ShopAccount shopAccount) 49 | { 50 | if (id != shopAccount.Username) 51 | { 52 | return BadRequest(); 53 | } 54 | 55 | _context.Entry(shopAccount).State = EntityState.Modified; 56 | 57 | try 58 | { 59 | await _context.SaveChangesAsync(); 60 | } 61 | catch (DbUpdateConcurrencyException) 62 | { 63 | if (!ShopAccountExists(id)) 64 | { 65 | return NotFound(); 66 | } 67 | else 68 | { 69 | throw; 70 | } 71 | } 72 | 73 | return NoContent(); 74 | } 75 | 76 | // POST: api/ShopAccounts 77 | // To protect from overposting attacks, enable the specific properties you want to bind to, for 78 | // more details, see https://go.microsoft.com/fwlink/?linkid=2123754. 79 | [HttpPost] 80 | public async Task> PostShopAccount(ShopAccount shopAccount) 81 | { 82 | _context.ShopAccount.Add(shopAccount); 83 | try 84 | { 85 | await _context.SaveChangesAsync(); 86 | } 87 | catch (DbUpdateException) 88 | { 89 | if (ShopAccountExists(shopAccount.Username)) 90 | { 91 | return Conflict(); 92 | } 93 | else 94 | { 95 | throw; 96 | } 97 | } 98 | 99 | return CreatedAtAction("GetShopAccount", new { id = shopAccount.Username }, shopAccount); 100 | } 101 | 102 | // DELETE: api/ShopAccounts/5 103 | [HttpDelete("{id}")] 104 | public async Task> DeleteShopAccount(string id) 105 | { 106 | var shopAccount = await _context.ShopAccount.FindAsync(id); 107 | if (shopAccount == null) 108 | { 109 | return NotFound(); 110 | } 111 | 112 | _context.ShopAccount.Remove(shopAccount); 113 | await _context.SaveChangesAsync(); 114 | 115 | return shopAccount; 116 | } 117 | 118 | private bool ShopAccountExists(string id) 119 | { 120 | return _context.ShopAccount.Any(e => e.Username == id); 121 | } 122 | } 123 | } 124 | -------------------------------------------------------------------------------- /api_SHOPii/SHOPii/Helpers/QueryHelper.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.EntityFrameworkCore; 2 | using SHOPii.Models; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Globalization; 6 | using System.Linq; 7 | using System.Text; 8 | using System.Threading.Tasks; 9 | 10 | namespace SHOPii.Helpers 11 | { 12 | public class QueryHelper 13 | { 14 | private IQueryable queryable; 15 | public QueryHelper(IQueryable queryable) 16 | { 17 | this.queryable = queryable; 18 | } 19 | public IQueryable pagingQuery(int? from, int? limit) 20 | { 21 | var takeFrom = from ?? 0; 22 | var takeLimit = limit ?? -1; 23 | if (takeLimit < 0) 24 | { 25 | return queryable.Skip(takeFrom); 26 | } 27 | return queryable.Skip(takeFrom).Take(takeLimit); 28 | } 29 | 30 | 31 | public static String removeAccents(String input) 32 | { 33 | var normalizedString = input.Normalize(NormalizationForm.FormD); 34 | var stringBuilder = new StringBuilder(); 35 | 36 | foreach (var c in normalizedString) 37 | { 38 | var unicodeCategory = CharUnicodeInfo.GetUnicodeCategory(c); 39 | if (unicodeCategory != UnicodeCategory.NonSpacingMark) 40 | { 41 | stringBuilder.Append(c); 42 | } 43 | } 44 | 45 | return stringBuilder.ToString().Normalize(NormalizationForm.FormC); 46 | } 47 | 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /api_SHOPii/SHOPii/Models/Account.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | namespace SHOPii.Models 5 | { 6 | public partial class Account 7 | { 8 | public Account() 9 | { 10 | DeliveryAddress = new HashSet(); 11 | Favorite = new HashSet(); 12 | Ordering = new HashSet(); 13 | } 14 | 15 | public string Username { get; set; } 16 | public string Password { get; set; } 17 | public string PhoneNumber { get; set; } 18 | public string Fullname { get; set; } 19 | public string Address { get; set; } 20 | public string Image { get; set; } 21 | public int DefaultDeliveryId { get; set; } 22 | 23 | public virtual ICollection DeliveryAddress { get; set; } 24 | public virtual ICollection Favorite { get; set; } 25 | public virtual ICollection Ordering { get; set; } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /api_SHOPii/SHOPii/Models/Category.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | namespace SHOPii.Models 5 | { 6 | public partial class Category 7 | { 8 | public Category() 9 | { 10 | Product = new HashSet(); 11 | } 12 | 13 | public int Id { get; set; } 14 | public string Name { get; set; } 15 | public string Description { get; set; } 16 | public string Image { get; set; } 17 | 18 | public virtual ICollection Product { get; set; } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /api_SHOPii/SHOPii/Models/DeliveryAddress.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | namespace SHOPii.Models 5 | { 6 | public partial class DeliveryAddress 7 | { 8 | public int Id { get; set; } 9 | public string Username { get; set; } 10 | public string PhoneNumber { get; set; } 11 | public string Fullname { get; set; } 12 | public string Address { get; set; } 13 | public string Latitude { get; set; } 14 | public string Longitude { get; set; } 15 | 16 | public virtual Account UsernameNavigation { get; set; } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /api_SHOPii/SHOPii/Models/Favorite.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | namespace SHOPii.Models 5 | { 6 | public partial class Favorite 7 | { 8 | public int Id { get; set; } 9 | public string Username { get; set; } 10 | public int ProductId { get; set; } 11 | public bool Isfavorite { get; set; } 12 | 13 | public virtual Product Product { get; set; } 14 | public virtual Account UsernameNavigation { get; set; } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /api_SHOPii/SHOPii/Models/Ordering.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | namespace SHOPii.Models 5 | { 6 | public partial class Ordering 7 | { 8 | public Ordering() 9 | { 10 | OrderingDetail = new HashSet(); 11 | } 12 | 13 | public int Id { get; set; } 14 | public int Status { get; set; } 15 | public string Username { get; set; } 16 | public int DeliveryId { get; set; } 17 | public DateTime CreatedDate { get; set; } 18 | public string ShopUsername { get; set; } 19 | 20 | public virtual ShopAccount ShopUsernameNavigation { get; set; } 21 | public virtual Account UsernameNavigation { get; set; } 22 | public virtual ICollection OrderingDetail { get; set; } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /api_SHOPii/SHOPii/Models/OrderingDetail.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | namespace SHOPii.Models 5 | { 6 | public partial class OrderingDetail 7 | { 8 | public long Id { get; set; } 9 | public int? OrderingId { get; set; } 10 | public int? ProductId { get; set; } 11 | public int Count { get; set; } 12 | 13 | public virtual Ordering Ordering { get; set; } 14 | public virtual Product Product { get; set; } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /api_SHOPii/SHOPii/Models/Product.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | namespace SHOPii.Models 5 | { 6 | public partial class Product 7 | { 8 | public Product() 9 | { 10 | Favorite = new HashSet(); 11 | OrderingDetail = new HashSet(); 12 | ProductImage = new HashSet(); 13 | } 14 | 15 | public int Id { get; set; } 16 | public string Name { get; set; } 17 | public string Description { get; set; } 18 | public string Image { get; set; } 19 | public long Price { get; set; } 20 | public int CategoryId { get; set; } 21 | public string ShopUsername { get; set; } 22 | 23 | public virtual Category Category { get; set; } 24 | public virtual ICollection Favorite { get; set; } 25 | public virtual ICollection OrderingDetail { get; set; } 26 | public virtual ICollection ProductImage { get; set; } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /api_SHOPii/SHOPii/Models/ProductImage.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | namespace SHOPii.Models 5 | { 6 | public partial class ProductImage 7 | { 8 | public int Id { get; set; } 9 | public int ProductId { get; set; } 10 | public string Image { get; set; } 11 | 12 | public virtual Product Product { get; set; } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /api_SHOPii/SHOPii/Models/ShopAccount.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | namespace SHOPii.Models 5 | { 6 | public partial class ShopAccount 7 | { 8 | public ShopAccount() 9 | { 10 | Ordering = new HashSet(); 11 | } 12 | 13 | public string Username { get; set; } 14 | public string Password { get; set; } 15 | public string Name { get; set; } 16 | public string Address { get; set; } 17 | public string PhoneNumber { get; set; } 18 | public string Image { get; set; } 19 | public string Latitude { get; set; } 20 | public string Longitude { get; set; } 21 | public string CoverImage { get; set; } 22 | 23 | public virtual ICollection Ordering { get; set; } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /api_SHOPii/SHOPii/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | using Microsoft.AspNetCore.Hosting; 6 | using Microsoft.Extensions.Configuration; 7 | using Microsoft.Extensions.Hosting; 8 | using Microsoft.Extensions.Logging; 9 | 10 | namespace SHOPii 11 | { 12 | public class Program 13 | { 14 | public static void Main(string[] args) 15 | { 16 | CreateHostBuilder(args).Build().Run(); 17 | } 18 | 19 | public static IHostBuilder CreateHostBuilder(string[] args) => 20 | Host.CreateDefaultBuilder(args) 21 | .ConfigureWebHostDefaults(webBuilder => 22 | { 23 | webBuilder.UseStartup(); 24 | }); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /api_SHOPii/SHOPii/Properties/PublishProfiles/IISProfile.pubxml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 8 | FileSystem 9 | Release 10 | Any CPU 11 | 12 | True 13 | False 14 | netcoreapp3.1 15 | 76960710-3eff-4e9f-b818-5d3652f2e0b1 16 | false 17 | D:\Khoa_Projects\_localhost\SHOPii\publish 18 | False 19 | linux-x64 20 | 21 | -------------------------------------------------------------------------------- /api_SHOPii/SHOPii/Properties/PublishProfiles/IISProfile.pubxml.user: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 8 | 9 | 10 | <_PublishTargetUrl>D:\Khoa_Projects\_localhost\SHOPii\publish 11 | 12 | -------------------------------------------------------------------------------- /api_SHOPii/SHOPii/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "iisSettings": { 3 | "windowsAuthentication": false, 4 | "anonymousAuthentication": true, 5 | "iisExpress": { 6 | "applicationUrl": "http://localhost:50107", 7 | "sslPort": 0 8 | } 9 | }, 10 | "$schema": "http://json.schemastore.org/launchsettings.json", 11 | "profiles": { 12 | "IIS Express": { 13 | "commandName": "IISExpress", 14 | "launchBrowser": true, 15 | "environmentVariables": { 16 | "ASPNETCORE_ENVIRONMENT": "Development" 17 | } 18 | }, 19 | "SHOPii": { 20 | "commandName": "Project", 21 | "launchBrowser": true, 22 | "environmentVariables": { 23 | "ASPNETCORE_ENVIRONMENT": "Development" 24 | }, 25 | "applicationUrl": "https://localhost:5001;http://localhost:5000" 26 | } 27 | } 28 | } -------------------------------------------------------------------------------- /api_SHOPii/SHOPii/SHOPii.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | netcoreapp3.1 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | all 15 | runtime; build; native; contentfiles; analyzers; buildtransitive 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /api_SHOPii/SHOPii/SHOPii.csproj.user: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | ApiControllerWithContextScaffolder 5 | root/Controller 6 | 600 7 | True 8 | False 9 | True 10 | 11 | SHOPii.Models.SHOPIIContext 12 | False 13 | True 14 | IISProfile 15 | 16 | -------------------------------------------------------------------------------- /api_SHOPii/SHOPii/Services/UserService.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.EntityFrameworkCore; 2 | using Microsoft.Extensions.Configuration; 3 | using Microsoft.IdentityModel.Tokens; 4 | using SHOPii.Models; 5 | using System; 6 | using System.Collections.Generic; 7 | using System.IdentityModel.Tokens.Jwt; 8 | using System.Linq; 9 | using System.Security.Claims; 10 | using System.Text; 11 | using System.Threading.Tasks; 12 | using static SHOPii.Services.IUserService; 13 | 14 | namespace SHOPii.Services 15 | { 16 | public interface IUserService 17 | { 18 | public UserEntities AuthUser(string username, string password); 19 | public IEnumerable getAll(); 20 | public UserEntities getUser(string username); 21 | 22 | public class UserEntities 23 | { 24 | public Account account; 25 | public String Role; 26 | public string Token { set; get; } 27 | 28 | public UserEntities(Account account) 29 | { 30 | this.account = account; 31 | } 32 | 33 | public UserEntities withOutPassword() 34 | { 35 | UserEntities temp = this; 36 | temp.account.Password = null; 37 | return temp; 38 | } 39 | } 40 | 41 | } 42 | 43 | public class UserService : IUserService 44 | { 45 | public static string KEY = new ConfigurationBuilder().AddJsonFile("appsettings.json").Build().GetSection("SecurityKey")["SymmetricSecurityKey"]; 46 | SHOPIIContext context = new SHOPIIContext(); 47 | 48 | 49 | public UserEntities AuthUser(string username, string password) 50 | { 51 | List LIST_USERS = context.Account.Include(a=>a.Favorite).Include(a=>a.DeliveryAddress).Select(u => new UserEntities(u)).ToList(); 52 | var user = LIST_USERS.FirstOrDefault(u => u.account.Username.Equals(username) && u.account.Password.Equals(password)); 53 | if (user == null) 54 | { 55 | return null; 56 | } 57 | user.Role = "test"; 58 | 59 | 60 | List lstClaim = new List(); //CLAIM USER INFO 61 | lstClaim.Add(new Claim(ClaimTypes.Name, user.account.Username)); 62 | lstClaim.Add(new Claim(ClaimTypes.Role, user.Role)); 63 | 64 | 65 | //CREATE JWT TOKEN 66 | var tokenHandler = new JwtSecurityTokenHandler(); 67 | var key = Encoding.ASCII.GetBytes(KEY); 68 | var tokenDescriptor = new SecurityTokenDescriptor 69 | { 70 | Subject = new ClaimsIdentity(lstClaim.ToArray()), 71 | Expires = DateTime.UtcNow.AddDays(100), 72 | SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(key), SecurityAlgorithms.HmacSha256Signature) 73 | 74 | }; 75 | var token = tokenHandler.CreateToken(tokenDescriptor); 76 | user.Token = tokenHandler.WriteToken(token); 77 | 78 | return user.withOutPassword(); 79 | } 80 | 81 | public List getAllAccounts() 82 | { 83 | return context.Account.ToList(); 84 | } 85 | 86 | public IEnumerable getAll() 87 | { 88 | throw new NotImplementedException(); 89 | } 90 | 91 | public UserEntities getUser(string username) 92 | { 93 | throw new NotImplementedException(); 94 | } 95 | } 96 | } 97 | -------------------------------------------------------------------------------- /api_SHOPii/SHOPii/Startup.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using Microsoft.AspNetCore.Authentication.JwtBearer; 7 | using Microsoft.AspNetCore.Builder; 8 | using Microsoft.AspNetCore.Hosting; 9 | using Microsoft.AspNetCore.HttpsPolicy; 10 | using Microsoft.AspNetCore.Mvc; 11 | using Microsoft.EntityFrameworkCore; 12 | using Microsoft.Extensions.Configuration; 13 | using Microsoft.Extensions.DependencyInjection; 14 | using Microsoft.Extensions.Hosting; 15 | using Microsoft.Extensions.Logging; 16 | using Newtonsoft.Json; 17 | using SHOPii.Models; 18 | using Microsoft.AspNetCore.Mvc.NewtonsoftJson; 19 | using Microsoft.IdentityModel.Tokens; 20 | using SHOPii.Services; 21 | 22 | namespace SHOPii 23 | { 24 | public class Startup 25 | { 26 | public Startup(IConfiguration configuration) 27 | { 28 | Configuration = configuration; 29 | } 30 | 31 | public IConfiguration Configuration { get; } 32 | 33 | // This method gets called by the runtime. Use this method to add services to the container. 34 | public void ConfigureServices(IServiceCollection services) 35 | { 36 | services.AddControllers(); 37 | //Config SQL Database 38 | services.AddDbContext(options => 39 | options.UseSqlServer(new ConfigurationBuilder().AddJsonFile("appsettings.json").Build().GetSection("Database")["ConnectionString"])); 40 | 41 | // services.AddTransient(); 42 | 43 | 44 | //JSON 45 | object p = services.AddControllersWithViews().AddNewtonsoftJson(options => 46 | options.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore 47 | ); 48 | 49 | //Config JWWT 50 | var key = Encoding.ASCII.GetBytes(UserService.KEY); 51 | services.AddAuthentication(x => 52 | { 53 | x.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme; 54 | x.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme; 55 | }) 56 | .AddJwtBearer(x => 57 | { 58 | 59 | x.RequireHttpsMetadata = false; 60 | x.SaveToken = true; 61 | x.TokenValidationParameters = new TokenValidationParameters 62 | { 63 | ValidateIssuerSigningKey = true, 64 | IssuerSigningKey = new SymmetricSecurityKey(key), 65 | ValidateIssuer = false, 66 | ValidateAudience = false 67 | }; 68 | }); 69 | 70 | 71 | //SCOPE USER SERVICE 72 | services.AddScoped(); 73 | } 74 | 75 | // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. 76 | public void Configure(IApplicationBuilder app, IWebHostEnvironment env) 77 | { 78 | if (env.IsDevelopment()) 79 | { 80 | app.UseDeveloperExceptionPage(); 81 | } 82 | 83 | //app.UseHttpsRedirection(); 84 | 85 | app.UseRouting(); 86 | app.UseAuthentication(); 87 | app.UseAuthorization(); 88 | 89 | 90 | app.UseEndpoints(endpoints => 91 | { 92 | endpoints.MapControllers(); 93 | }); 94 | } 95 | } 96 | } 97 | -------------------------------------------------------------------------------- /api_SHOPii/SHOPii/appsettings.Development.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft": "Warning", 6 | "Microsoft.Hosting.Lifetime": "Information" 7 | } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /api_SHOPii/SHOPii/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft": "Warning", 6 | "Microsoft.Hosting.Lifetime": "Information" 7 | } 8 | }, 9 | "AllowedHosts": "*", 10 | "Database": { 11 | "ConnectionString": "workstation id=sqlshopii.mssql.somee.com;packet size=4096;user id=ankiimation_SQLLogin_2;pwd=chpsiqq24s;data source=sqlshopii.mssql.somee.com;persist security info=False;initial catalog=sqlshopii" 12 | }, 13 | "SecurityKey": { 14 | "SymmetricSecurityKey": "asdghasjgasgfsjfgsdkgsdkghdfkghdfkghdfkdhjkl" 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /api_SHOPii/SHOPii/obj/Debug/netcoreapp3.1/.NETCoreApp,Version=v3.1.AssemblyAttributes.cs: -------------------------------------------------------------------------------- 1 | // 2 | using System; 3 | using System.Reflection; 4 | [assembly: global::System.Runtime.Versioning.TargetFrameworkAttribute(".NETCoreApp,Version=v3.1", FrameworkDisplayName = "")] 5 | -------------------------------------------------------------------------------- /api_SHOPii/SHOPii/obj/Debug/netcoreapp3.1/SHOPii.AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // This code was generated by a tool. 4 | // Runtime Version:4.0.30319.42000 5 | // 6 | // Changes to this file may cause incorrect behavior and will be lost if 7 | // the code is regenerated. 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | using System; 12 | using System.Reflection; 13 | 14 | [assembly: System.Reflection.AssemblyCompanyAttribute("SHOPii")] 15 | [assembly: System.Reflection.AssemblyConfigurationAttribute("Debug")] 16 | [assembly: System.Reflection.AssemblyFileVersionAttribute("1.0.0.0")] 17 | [assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0")] 18 | [assembly: System.Reflection.AssemblyProductAttribute("SHOPii")] 19 | [assembly: System.Reflection.AssemblyTitleAttribute("SHOPii")] 20 | [assembly: System.Reflection.AssemblyVersionAttribute("1.0.0.0")] 21 | 22 | // Generated by the MSBuild WriteCodeFragment class. 23 | 24 | -------------------------------------------------------------------------------- /api_SHOPii/SHOPii/obj/Debug/netcoreapp3.1/SHOPii.AssemblyInfoInputs.cache: -------------------------------------------------------------------------------- 1 | e9eca034578034957a3ec41c97ce9b8ee8794b31 2 | -------------------------------------------------------------------------------- /api_SHOPii/SHOPii/obj/Debug/netcoreapp3.1/SHOPii.csprojAssemblyReference.cache: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ankiimation/flutter_SHOPii/2c2a45bbcade33ea97f13302092b044b62a09fc6/api_SHOPii/SHOPii/obj/Debug/netcoreapp3.1/SHOPii.csprojAssemblyReference.cache -------------------------------------------------------------------------------- /sql_SHOPii: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ankiimation/flutter_SHOPii/2c2a45bbcade33ea97f13302092b044b62a09fc6/sql_SHOPii -------------------------------------------------------------------------------- /sqlserver_backup: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ankiimation/flutter_SHOPii/2c2a45bbcade33ea97f13302092b044b62a09fc6/sqlserver_backup --------------------------------------------------------------------------------