├── ios ├── Flutter │ ├── Debug.xcconfig │ ├── Release.xcconfig │ └── AppFrameworkInfo.plist ├── Runner │ ├── Runner-Bridging-Header.h │ ├── Assets.xcassets │ │ ├── LaunchImage.imageset │ │ │ ├── LaunchImage.png │ │ │ ├── LaunchImage@2x.png │ │ │ ├── LaunchImage@3x.png │ │ │ ├── README.md │ │ │ └── Contents.json │ │ └── AppIcon.appiconset │ │ │ ├── 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-1024x1024@1x.png │ │ │ ├── Icon-App-83.5x83.5@2x.png │ │ │ └── Contents.json │ ├── AppDelegate.swift │ ├── Base.lproj │ │ ├── Main.storyboard │ │ └── LaunchScreen.storyboard │ └── Info.plist ├── Runner.xcodeproj │ ├── project.xcworkspace │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata │ │ │ ├── WorkspaceSettings.xcsettings │ │ │ └── IDEWorkspaceChecks.plist │ ├── xcshareddata │ │ └── xcschemes │ │ │ └── Runner.xcscheme │ └── project.pbxproj ├── Runner.xcworkspace │ ├── contents.xcworkspacedata │ └── xcshareddata │ │ ├── WorkspaceSettings.xcsettings │ │ └── IDEWorkspaceChecks.plist └── .gitignore ├── web ├── favicon.png ├── icons │ ├── Icon-192.png │ └── Icon-512.png ├── manifest.json └── index.html ├── lib ├── app │ ├── utils │ │ ├── helpers │ │ │ ├── string_helper.dart │ │ │ ├── app_helpers.dart │ │ │ └── type.dart │ │ ├── ui │ │ │ ├── app_dialog.dart │ │ │ ├── app_bottomshet.dart │ │ │ ├── ui_utils.dart │ │ │ └── app_snackbar.dart │ │ ├── mixins │ │ │ ├── app_mixins.dart │ │ │ ├── navigation_mixin.dart │ │ │ └── validation_input_mixin.dart │ │ └── services │ │ │ ├── model │ │ │ ├── user.dart │ │ │ └── product.dart │ │ │ ├── rest_api_services.dart │ │ │ ├── local_storage_services.dart │ │ │ ├── native_api_services.dart │ │ │ └── src │ │ │ ├── user_service.dart │ │ │ └── product_service.dart │ ├── features │ │ ├── dashboard │ │ │ ├── explore │ │ │ │ ├── bindings │ │ │ │ │ └── explore_binding.dart │ │ │ │ ├── controllers │ │ │ │ │ └── explore_controller.dart │ │ │ │ └── views │ │ │ │ │ ├── components │ │ │ │ │ ├── tab_bar_content.dart │ │ │ │ │ └── product_content.dart │ │ │ │ │ └── screens │ │ │ │ │ └── explore_screen.dart │ │ │ └── index │ │ │ │ ├── bindings │ │ │ │ └── dashboard_binding.dart │ │ │ │ ├── controllers │ │ │ │ └── dashboard_controller.dart │ │ │ │ └── views │ │ │ │ └── screens │ │ │ │ └── dashboard_screen.dart │ │ └── product │ │ │ └── product_detail │ │ │ ├── bindings │ │ │ └── product_detail_binding.dart │ │ │ ├── views │ │ │ ├── components │ │ │ │ ├── views_text.dart │ │ │ │ ├── description_text.dart │ │ │ │ ├── review_text.dart │ │ │ │ ├── buy_button.dart │ │ │ │ ├── name_text.dart │ │ │ │ ├── share_button.dart │ │ │ │ ├── back_button.dart │ │ │ │ ├── chat_button.dart │ │ │ │ ├── price_text.dart │ │ │ │ ├── rating.dart │ │ │ │ ├── favorite_button.dart │ │ │ │ ├── product_image.dart │ │ │ │ └── body_content.dart │ │ │ └── screens │ │ │ │ └── product_detail_screen.dart │ │ │ └── controllers │ │ │ └── product_detail_controller.dart │ ├── constans │ │ ├── api_path.dart │ │ ├── app_constants.dart │ │ └── assets_path.dart │ ├── config │ │ ├── routes │ │ │ ├── app_routes.dart │ │ │ └── app_pages.dart │ │ └── themes │ │ │ └── app_theme.dart │ └── shared_components │ │ ├── filter_button.dart │ │ ├── search_field.dart │ │ ├── custom_icon_button.dart │ │ ├── indicator.dart │ │ └── product_card.dart └── main.dart ├── assets └── images │ └── raster │ ├── bag.png │ ├── vr.png │ ├── shoes.png │ ├── cardigan.png │ ├── market-2.png │ ├── market.png │ ├── shoes-2.png │ ├── cardigan-2.png │ ├── orange-blouse.png │ ├── pink-jacket.png │ └── blue-midi-dress.png ├── android ├── gradle.properties ├── app │ ├── src │ │ ├── main │ │ │ ├── res │ │ │ │ ├── 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 │ │ │ │ ├── drawable │ │ │ │ │ └── launch_background.xml │ │ │ │ ├── drawable-v21 │ │ │ │ │ └── launch_background.xml │ │ │ │ ├── values │ │ │ │ │ └── styles.xml │ │ │ │ └── values-night │ │ │ │ │ └── styles.xml │ │ │ ├── kotlin │ │ │ │ └── com │ │ │ │ │ └── example │ │ │ │ │ └── marketplace │ │ │ │ │ └── MainActivity.kt │ │ │ └── AndroidManifest.xml │ │ ├── debug │ │ │ └── AndroidManifest.xml │ │ └── profile │ │ │ └── AndroidManifest.xml │ └── build.gradle ├── gradle │ └── wrapper │ │ └── gradle-wrapper.properties ├── .gitignore ├── settings.gradle └── build.gradle ├── .metadata ├── .gitignore ├── test └── widget_test.dart ├── README.md ├── pubspec.yaml └── pubspec.lock /ios/Flutter/Debug.xcconfig: -------------------------------------------------------------------------------- 1 | #include "Generated.xcconfig" 2 | -------------------------------------------------------------------------------- /ios/Flutter/Release.xcconfig: -------------------------------------------------------------------------------- 1 | #include "Generated.xcconfig" 2 | -------------------------------------------------------------------------------- /ios/Runner/Runner-Bridging-Header.h: -------------------------------------------------------------------------------- 1 | #import "GeneratedPluginRegistrant.h" 2 | -------------------------------------------------------------------------------- /web/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/firgia/FD-Marketplace/HEAD/web/favicon.png -------------------------------------------------------------------------------- /lib/app/utils/helpers/string_helper.dart: -------------------------------------------------------------------------------- 1 | part of app_helpers; 2 | 3 | class StringHelper {} 4 | -------------------------------------------------------------------------------- /web/icons/Icon-192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/firgia/FD-Marketplace/HEAD/web/icons/Icon-192.png -------------------------------------------------------------------------------- /web/icons/Icon-512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/firgia/FD-Marketplace/HEAD/web/icons/Icon-512.png -------------------------------------------------------------------------------- /assets/images/raster/bag.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/firgia/FD-Marketplace/HEAD/assets/images/raster/bag.png -------------------------------------------------------------------------------- /assets/images/raster/vr.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/firgia/FD-Marketplace/HEAD/assets/images/raster/vr.png -------------------------------------------------------------------------------- /assets/images/raster/shoes.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/firgia/FD-Marketplace/HEAD/assets/images/raster/shoes.png -------------------------------------------------------------------------------- /android/gradle.properties: -------------------------------------------------------------------------------- 1 | org.gradle.jvmargs=-Xmx1536M 2 | android.useAndroidX=true 3 | android.enableJetifier=true 4 | -------------------------------------------------------------------------------- /assets/images/raster/cardigan.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/firgia/FD-Marketplace/HEAD/assets/images/raster/cardigan.png -------------------------------------------------------------------------------- /assets/images/raster/market-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/firgia/FD-Marketplace/HEAD/assets/images/raster/market-2.png -------------------------------------------------------------------------------- /assets/images/raster/market.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/firgia/FD-Marketplace/HEAD/assets/images/raster/market.png -------------------------------------------------------------------------------- /assets/images/raster/shoes-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/firgia/FD-Marketplace/HEAD/assets/images/raster/shoes-2.png -------------------------------------------------------------------------------- /lib/app/utils/helpers/app_helpers.dart: -------------------------------------------------------------------------------- 1 | library app_helpers; 2 | 3 | part 'string_helper.dart'; 4 | part 'type.dart'; 5 | -------------------------------------------------------------------------------- /lib/app/utils/ui/app_dialog.dart: -------------------------------------------------------------------------------- 1 | part of ui_utils; 2 | 3 | // contains all dialog templates 4 | class AppDialog {} 5 | -------------------------------------------------------------------------------- /assets/images/raster/cardigan-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/firgia/FD-Marketplace/HEAD/assets/images/raster/cardigan-2.png -------------------------------------------------------------------------------- /assets/images/raster/orange-blouse.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/firgia/FD-Marketplace/HEAD/assets/images/raster/orange-blouse.png -------------------------------------------------------------------------------- /assets/images/raster/pink-jacket.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/firgia/FD-Marketplace/HEAD/assets/images/raster/pink-jacket.png -------------------------------------------------------------------------------- /lib/app/utils/ui/app_bottomshet.dart: -------------------------------------------------------------------------------- 1 | part of ui_utils; 2 | 3 | // contains all bottomsheet templates 4 | class AppBottomSheet {} 5 | -------------------------------------------------------------------------------- /assets/images/raster/blue-midi-dress.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/firgia/FD-Marketplace/HEAD/assets/images/raster/blue-midi-dress.png -------------------------------------------------------------------------------- /lib/app/utils/mixins/app_mixins.dart: -------------------------------------------------------------------------------- 1 | library app_mixins; 2 | 3 | part 'navigation_mixin.dart'; 4 | part 'validation_input_mixin.dart'; 5 | -------------------------------------------------------------------------------- /lib/app/utils/helpers/type.dart: -------------------------------------------------------------------------------- 1 | part of app_helpers; 2 | 3 | // this file focused on enum data 4 | 5 | // Example: 6 | // enum userType{admin, member} -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/firgia/FD-Marketplace/HEAD/android/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/firgia/FD-Marketplace/HEAD/android/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/firgia/FD-Marketplace/HEAD/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/firgia/FD-Marketplace/HEAD/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/firgia/FD-Marketplace/HEAD/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/firgia/FD-Marketplace/HEAD/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/firgia/FD-Marketplace/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/firgia/FD-Marketplace/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/firgia/FD-Marketplace/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/firgia/FD-Marketplace/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/firgia/FD-Marketplace/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/firgia/FD-Marketplace/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/firgia/FD-Marketplace/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/firgia/FD-Marketplace/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/firgia/FD-Marketplace/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/firgia/FD-Marketplace/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/firgia/FD-Marketplace/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/firgia/FD-Marketplace/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/firgia/FD-Marketplace/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/firgia/FD-Marketplace/HEAD/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/firgia/FD-Marketplace/HEAD/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/firgia/FD-Marketplace/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/firgia/FD-Marketplace/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png -------------------------------------------------------------------------------- /android/app/src/main/kotlin/com/example/marketplace/MainActivity.kt: -------------------------------------------------------------------------------- 1 | package com.example.marketplace 2 | 3 | import io.flutter.embedding.android.FlutterActivity 4 | 5 | class MainActivity: FlutterActivity() { 6 | } 7 | -------------------------------------------------------------------------------- /ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /ios/Runner.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /lib/app/features/dashboard/explore/bindings/explore_binding.dart: -------------------------------------------------------------------------------- 1 | part of explore; 2 | 3 | class ExploreBinding extends Bindings { 4 | @override 5 | void dependencies() { 6 | Get.lazyPut(() => ExploreController()); 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /lib/app/constans/api_path.dart: -------------------------------------------------------------------------------- 1 | part of app_constants; 2 | 3 | /// all endpoint api 4 | class ApiPath { 5 | // Example : 6 | // static const _BASE_URL = "https://api.nitrogia.com"; 7 | // static const product = "$_BASE_URL/product"; 8 | } 9 | -------------------------------------------------------------------------------- /lib/app/features/dashboard/index/bindings/dashboard_binding.dart: -------------------------------------------------------------------------------- 1 | part of dashboard; 2 | 3 | class DashboardBinding extends Bindings { 4 | @override 5 | void dependencies() { 6 | Get.lazyPut(() => DashboardController()); 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /lib/app/features/dashboard/index/controllers/dashboard_controller.dart: -------------------------------------------------------------------------------- 1 | part of dashboard; 2 | 3 | class DashboardController extends GetxController { 4 | PersistentTabController persistentTab = 5 | PersistentTabController(initialIndex: 0); 6 | } 7 | -------------------------------------------------------------------------------- /lib/app/features/product/product_detail/bindings/product_detail_binding.dart: -------------------------------------------------------------------------------- 1 | part of product_detail; 2 | 3 | class ProductDetailBinding extends Bindings { 4 | @override 5 | void dependencies() { 6 | Get.lazyPut(() => ProductDetailController()); 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /lib/app/utils/mixins/navigation_mixin.dart: -------------------------------------------------------------------------------- 1 | part of app_mixins; 2 | 3 | /// Contains all instants routing 4 | mixin NavigationMixin { 5 | /// Example : 6 | // void goToDetailProduct(int id) { 7 | // Get.toNamed(Routes.product, parameters: {"id": "$id"}); 8 | // } 9 | } 10 | -------------------------------------------------------------------------------- /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-6.7-all.zip 7 | -------------------------------------------------------------------------------- /ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | PreviewsEnabled 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /android/.gitignore: -------------------------------------------------------------------------------- 1 | gradle-wrapper.jar 2 | /.gradle 3 | /captures/ 4 | /gradlew 5 | /gradlew.bat 6 | /local.properties 7 | GeneratedPluginRegistrant.java 8 | 9 | # Remember to never publicly share your keystore. 10 | # See https://flutter.dev/docs/deployment/android#reference-the-keystore-from-the-app 11 | key.properties 12 | -------------------------------------------------------------------------------- /ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | PreviewsEnabled 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /.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: f4abaa0735eba4dfd8f33f73363911d63931fe03 8 | channel: stable 9 | 10 | project_type: app 11 | -------------------------------------------------------------------------------- /android/app/src/debug/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /android/app/src/profile/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /lib/app/constans/app_constants.dart: -------------------------------------------------------------------------------- 1 | library app_constants; 2 | 3 | import 'package:flutter/material.dart'; 4 | 5 | part 'api_path.dart'; 6 | part 'assets_path.dart'; 7 | 8 | const kBorderRadius = 15.0; 9 | const kSpacing = 15.0; 10 | const kFontColorPallets = [ 11 | Color.fromRGBO(84, 82, 91, 1), 12 | Color.fromRGBO(108, 107, 112, 1), 13 | Color.fromRGBO(173, 178, 188, 1), 14 | ]; 15 | -------------------------------------------------------------------------------- /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. -------------------------------------------------------------------------------- /lib/app/utils/services/model/user.dart: -------------------------------------------------------------------------------- 1 | part of rest_api_service; 2 | 3 | class User { 4 | final String id; 5 | final ImageProvider profilImage; 6 | final String name; 7 | final String country; 8 | final String city; 9 | 10 | const User({ 11 | required this.id, 12 | required this.profilImage, 13 | required this.name, 14 | required this.country, 15 | required this.city, 16 | }); 17 | } 18 | -------------------------------------------------------------------------------- /lib/app/features/dashboard/explore/controllers/explore_controller.dart: -------------------------------------------------------------------------------- 1 | part of explore; 2 | 3 | class ExploreController extends GetxController { 4 | final productService = ProductService(); 5 | 6 | List getAllProduct() => productService.getAll(); 7 | List getFashionProduct() => productService.getFashion(); 8 | 9 | void goToDetailProduct(Product product) { 10 | Get.toNamed(Routes.product + "/${product.id}"); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /lib/app/features/product/product_detail/views/components/views_text.dart: -------------------------------------------------------------------------------- 1 | part of product_detail; 2 | 3 | class _ViewsText extends StatelessWidget { 4 | const _ViewsText(this.data, {Key? key}) : super(key: key); 5 | 6 | final String data; 7 | 8 | @override 9 | Widget build(BuildContext context) { 10 | return Text( 11 | data, 12 | textAlign: TextAlign.right, 13 | style: Theme.of(context).textTheme.caption?.copyWith(fontSize: 16), 14 | ); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /lib/app/features/product/product_detail/views/components/description_text.dart: -------------------------------------------------------------------------------- 1 | part of product_detail; 2 | 3 | class _DescriptionText extends StatelessWidget { 4 | const _DescriptionText(this.data, {Key? key}) : super(key: key); 5 | 6 | final String data; 7 | @override 8 | Widget build(BuildContext context) { 9 | return Text( 10 | data, 11 | style: TextStyle( 12 | color: kFontColorPallets[2], 13 | fontSize: 15, 14 | ), 15 | ); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /lib/app/features/product/product_detail/views/components/review_text.dart: -------------------------------------------------------------------------------- 1 | part of product_detail; 2 | 3 | class _ReviewsText extends StatelessWidget { 4 | const _ReviewsText(this.data, {Key? key}) : super(key: key); 5 | 6 | final String data; 7 | 8 | @override 9 | Widget build(BuildContext context) { 10 | return Text( 11 | data, 12 | textAlign: TextAlign.right, 13 | style: Theme.of(context).textTheme.caption?.copyWith(fontSize: 16), 14 | ); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /lib/app/features/product/product_detail/views/components/buy_button.dart: -------------------------------------------------------------------------------- 1 | part of product_detail; 2 | 3 | class _BuyButton extends StatelessWidget { 4 | const _BuyButton({required this.onPressed, Key? key}) : super(key: key); 5 | 6 | final Function() onPressed; 7 | 8 | @override 9 | Widget build(BuildContext context) { 10 | return Expanded( 11 | child: ElevatedButton( 12 | onPressed: onPressed, 13 | child: Text("Buy Now"), 14 | ), 15 | ); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /android/settings.gradle: -------------------------------------------------------------------------------- 1 | include ':app' 2 | 3 | def localPropertiesFile = new File(rootProject.projectDir, "local.properties") 4 | def properties = new Properties() 5 | 6 | assert localPropertiesFile.exists() 7 | localPropertiesFile.withReader("UTF-8") { reader -> properties.load(reader) } 8 | 9 | def flutterSdkPath = properties.getProperty("flutter.sdk") 10 | assert flutterSdkPath != null, "flutter.sdk not set in local.properties" 11 | apply from: "$flutterSdkPath/packages/flutter_tools/gradle/app_plugin_loader.gradle" 12 | -------------------------------------------------------------------------------- /android/app/src/main/res/drawable/launch_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 12 | 13 | -------------------------------------------------------------------------------- /android/app/src/main/res/drawable-v21/launch_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 12 | 13 | -------------------------------------------------------------------------------- /lib/app/utils/mixins/validation_input_mixin.dart: -------------------------------------------------------------------------------- 1 | part of app_mixins; 2 | 3 | /// use this mixin for all form field 4 | mixin ValidatorMixin { 5 | // example : 6 | // String? validateTextFieldIsRequired(String? value) { 7 | // if (value == null || value.trim().isEmpty) return "this field is required"; 8 | // return null; 9 | // } 10 | 11 | // String? validateDropdownIsRequired(String? value) { 12 | // if (value == null || value.trim().isEmpty) return "please select item"; 13 | // return null; 14 | // } 15 | } 16 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /lib/main.dart: -------------------------------------------------------------------------------- 1 | import 'app/config/routes/app_pages.dart'; 2 | import 'app/config/themes/app_theme.dart'; 3 | import 'package:flutter/material.dart'; 4 | import 'package:get/get.dart'; 5 | 6 | void main() { 7 | runApp(MyApp()); 8 | } 9 | 10 | class MyApp extends StatelessWidget { 11 | @override 12 | Widget build(BuildContext context) { 13 | return GetMaterialApp( 14 | title: 'Flutter Demo', 15 | theme: AppTheme.basic, 16 | initialRoute: AppPages.initial, 17 | getPages: AppPages.routes, 18 | ); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /lib/app/features/product/product_detail/views/components/name_text.dart: -------------------------------------------------------------------------------- 1 | part of product_detail; 2 | 3 | class _NameText extends StatelessWidget { 4 | const _NameText(this.data, {Key? key}) : super(key: key); 5 | 6 | final String data; 7 | @override 8 | Widget build(BuildContext context) { 9 | return Text( 10 | data, 11 | style: TextStyle( 12 | fontWeight: FontWeight.w500, 13 | color: kFontColorPallets[0], 14 | fontSize: 20, 15 | ), 16 | textAlign: TextAlign.left, 17 | ); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /lib/app/utils/services/rest_api_services.dart: -------------------------------------------------------------------------------- 1 | library rest_api_service; 2 | 3 | import 'package:flutter/material.dart'; 4 | import 'package:marketplace/app/constans/app_constants.dart'; 5 | 6 | // model 7 | part 'model/product.dart'; 8 | part 'model/user.dart'; 9 | 10 | // src 11 | part 'src/product_service.dart'; 12 | part 'src/user_service.dart'; 13 | 14 | /// custom setup for request api 15 | class RestApiServices { 16 | // to get data from server, you can use Http for simple feature 17 | // or Dio for more complex feature 18 | 19 | Duration get timeOut => Duration(seconds: 30); 20 | } 21 | -------------------------------------------------------------------------------- /lib/app/features/product/product_detail/views/components/share_button.dart: -------------------------------------------------------------------------------- 1 | part of product_detail; 2 | 3 | class _ShareButton extends StatelessWidget { 4 | const _ShareButton({required this.onPressed, Key? key}) : super(key: key); 5 | 6 | final Function() onPressed; 7 | 8 | @override 9 | Widget build(BuildContext context) { 10 | return CustomIconButton( 11 | icon: Icon( 12 | FontAwesomeIcons.share, 13 | color: Theme.of(context).iconTheme.color, 14 | ), 15 | onPressed: onPressed, 16 | size: 40, 17 | borderRadius: 10, 18 | tooltip: "Share", 19 | ); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /lib/app/features/product/product_detail/views/components/back_button.dart: -------------------------------------------------------------------------------- 1 | part of product_detail; 2 | 3 | class _BackButton extends StatelessWidget { 4 | const _BackButton({required this.onPressed, Key? key}) : super(key: key); 5 | 6 | final Function() onPressed; 7 | 8 | @override 9 | Widget build(BuildContext context) { 10 | return CustomIconButton( 11 | icon: Icon( 12 | FontAwesomeIcons.chevronLeft, 13 | color: Theme.of(context).iconTheme.color, 14 | ), 15 | onPressed: onPressed, 16 | size: 40, 17 | borderRadius: 10, 18 | tooltip: "Back", 19 | ); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /web/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "marketplace", 3 | "short_name": "marketplace", 4 | "start_url": ".", 5 | "display": "standalone", 6 | "background_color": "#0175C2", 7 | "theme_color": "#0175C2", 8 | "description": "A new Flutter project.", 9 | "orientation": "portrait-primary", 10 | "prefer_related_applications": false, 11 | "icons": [ 12 | { 13 | "src": "icons/Icon-192.png", 14 | "sizes": "192x192", 15 | "type": "image/png" 16 | }, 17 | { 18 | "src": "icons/Icon-512.png", 19 | "sizes": "512x512", 20 | "type": "image/png" 21 | } 22 | ] 23 | } 24 | -------------------------------------------------------------------------------- /lib/app/features/product/product_detail/views/components/chat_button.dart: -------------------------------------------------------------------------------- 1 | part of product_detail; 2 | 3 | class _ChatButton extends StatelessWidget { 4 | const _ChatButton({required this.onPressed, Key? key}) : super(key: key); 5 | 6 | final Function() onPressed; 7 | 8 | @override 9 | Widget build(BuildContext context) { 10 | return CustomIconButton( 11 | icon: Icon( 12 | FontAwesomeIcons.commentAlt, 13 | color: Theme.of(context).primaryColor, 14 | ), 15 | onPressed: onPressed, 16 | size: 40, 17 | borderRadius: 10, 18 | color: Theme.of(context).primaryColor.withOpacity(.2), 19 | tooltip: "chat", 20 | ); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /lib/app/utils/ui/ui_utils.dart: -------------------------------------------------------------------------------- 1 | library ui_utils; 2 | 3 | import 'package:flutter/cupertino.dart'; 4 | import 'package:flutter/material.dart'; 5 | import 'package:get/get.dart'; 6 | import 'package:marketplace/app/constans/app_constants.dart'; 7 | 8 | part 'app_bottomshet.dart'; 9 | part 'app_dialog.dart'; 10 | part 'app_snackbar.dart'; 11 | 12 | 13 | // in this file focused on adding extension for some widget 14 | 15 | // Example : 16 | // extension TextStyleExtension on TextStyle { 17 | // TextStyle inputHeader() { 18 | // return this.copyWith( 19 | // fontWeight: FontWeight.bold, 20 | // fontSize: 16, 21 | // color: AppTheme.fontPrimaryColorLight); 22 | // } 23 | // } -------------------------------------------------------------------------------- /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:4.1.0' 10 | classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" 11 | } 12 | } 13 | 14 | allprojects { 15 | repositories { 16 | google() 17 | jcenter() 18 | } 19 | } 20 | 21 | rootProject.buildDir = '../build' 22 | subprojects { 23 | project.buildDir = "${rootProject.buildDir}/${project.name}" 24 | project.evaluationDependsOn(':app') 25 | } 26 | 27 | task clean(type: Delete) { 28 | delete rootProject.buildDir 29 | } 30 | -------------------------------------------------------------------------------- /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/ephemeral/ 22 | Flutter/app.flx 23 | Flutter/app.zip 24 | Flutter/flutter_assets/ 25 | Flutter/flutter_export_environment.sh 26 | ServiceDefinitions.json 27 | Runner/GeneratedPluginRegistrant.* 28 | 29 | # Exceptions to above rules. 30 | !default.mode1v3 31 | !default.mode2v3 32 | !default.pbxuser 33 | !default.perspectivev3 34 | -------------------------------------------------------------------------------- /lib/app/utils/services/model/product.dart: -------------------------------------------------------------------------------- 1 | part of rest_api_service; 2 | 3 | class Product { 4 | final String id; 5 | final String idUser; 6 | final List images; 7 | final String name; 8 | final double price; 9 | final bool isFavorite; 10 | final String description; 11 | final int totalViews; 12 | final int totalReview; 13 | final double rating; 14 | 15 | const Product({ 16 | required this.id, 17 | required this.idUser, 18 | required this.images, 19 | required this.name, 20 | required this.price, 21 | required this.isFavorite, 22 | required this.description, 23 | required this.totalViews, 24 | required this.totalReview, 25 | required this.rating, 26 | }); 27 | } 28 | -------------------------------------------------------------------------------- /lib/app/config/routes/app_routes.dart: -------------------------------------------------------------------------------- 1 | part of 'app_pages.dart'; 2 | 3 | /// used to switch pages 4 | class Routes { 5 | static const dashboard = _Paths.dashboard; 6 | static const product = _Paths.product; 7 | } 8 | 9 | /// contains a list of route names. 10 | // made separately to make it easier to manage route naming 11 | class _Paths { 12 | static const dashboard = '/dashboard'; 13 | static const product = '/product'; 14 | 15 | // Example : 16 | // static const index = '/'; 17 | // static const splash = '/splash'; 18 | // static const product = '/product'; 19 | // static const productEdit = '/product/edit'; 20 | // static const productDetail = '/product/detail'; 21 | // static const productAdd = '/product/add'; 22 | } 23 | -------------------------------------------------------------------------------- /lib/app/shared_components/filter_button.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:font_awesome_flutter/font_awesome_flutter.dart'; 3 | import 'package:marketplace/app/shared_components/custom_icon_button.dart'; 4 | 5 | class FilterButton extends StatelessWidget { 6 | const FilterButton({required this.onPressed, this.size = 60, Key? key}) 7 | : super(key: key); 8 | 9 | final Function() onPressed; 10 | final double size; 11 | 12 | @override 13 | Widget build(BuildContext context) { 14 | return CustomIconButton( 15 | icon: Icon( 16 | FontAwesomeIcons.slidersH, 17 | color: Theme.of(context).iconTheme.color, 18 | ), 19 | onPressed: onPressed, 20 | size: size, 21 | tooltip: "Filter", 22 | ); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /lib/app/utils/ui/app_snackbar.dart: -------------------------------------------------------------------------------- 1 | part of ui_utils; 2 | 3 | /// contains all snackbar templates 4 | class AppSnackbar { 5 | static void showStatusFavoriteProduct({ 6 | required ImageProvider productImage, 7 | required String productName, 8 | required bool isFavorite, 9 | }) { 10 | Get.snackbar( 11 | (isFavorite) ? "add to favorites" : "removed from favorites", 12 | productName, 13 | icon: Padding( 14 | padding: EdgeInsets.symmetric(horizontal: 5), 15 | child: Image( 16 | image: productImage, 17 | fit: BoxFit.cover, 18 | ), 19 | ), 20 | colorText: kFontColorPallets[0], 21 | duration: Duration(seconds: 1), 22 | isDismissible: true, 23 | backgroundColor: Colors.white, 24 | ); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /lib/app/features/product/product_detail/views/components/price_text.dart: -------------------------------------------------------------------------------- 1 | part of product_detail; 2 | 3 | class _PriceText extends StatelessWidget { 4 | const _PriceText(this.data, {Key? key}) : super(key: key); 5 | 6 | final String data; 7 | @override 8 | Widget build(BuildContext context) { 9 | return Row( 10 | children: [ 11 | Icon( 12 | FontAwesomeIcons.dollarSign, 13 | color: Theme.of(context).primaryColor, 14 | size: 25, 15 | ), 16 | Expanded( 17 | child: Text( 18 | data, 19 | style: TextStyle( 20 | color: Theme.of(context).primaryColor, 21 | fontSize: 25, 22 | fontWeight: FontWeight.bold, 23 | ), 24 | )), 25 | ], 26 | ); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /lib/app/utils/services/local_storage_services.dart: -------------------------------------------------------------------------------- 1 | /// contains all service to get data from local 2 | class LocalStorageServices { 3 | static final LocalStorageServices _localStorageServices = 4 | LocalStorageServices._internal(); 5 | 6 | factory LocalStorageServices() { 7 | return _localStorageServices; 8 | } 9 | LocalStorageServices._internal(); 10 | 11 | // to save data in local, you can use SharedPreferences for simple data 12 | // or Sqflite for more complex data 13 | 14 | /// example : 15 | // Future saveToken(String token) async { 16 | // SharedPreferences prefs = await SharedPreferences.getInstance(); 17 | // prefs.setString('token', token); 18 | // } 19 | 20 | // Future getToken() async { 21 | // SharedPreferences prefs = await SharedPreferences.getInstance(); 22 | // return prefs.getString('token'); 23 | // } 24 | } 25 | -------------------------------------------------------------------------------- /ios/Flutter/AppFrameworkInfo.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 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 | -------------------------------------------------------------------------------- /lib/app/utils/services/native_api_services.dart: -------------------------------------------------------------------------------- 1 | /// contains all service to get feature from native 2 | /// 3 | /// Example: 4 | /// * Get image from gallery 5 | /// * Get status connection 6 | /// etc... 7 | class NativeApiServices { 8 | static final NativeApiServices _nativeApiServices = 9 | NativeApiServices._internal(); 10 | 11 | factory NativeApiServices() { 12 | return _nativeApiServices; 13 | } 14 | NativeApiServices._internal(); 15 | 16 | // Example 17 | // final _imagePicker = ImagePicker(); 18 | // Future getImage(ImageSource source, 19 | // {int maxHeight = 800, int maxWidth = 800}) async { 20 | // final image = await _imagePicker.pickImage( 21 | // source: source, 22 | // maxHeight: maxHeight.toDouble(), 23 | // maxWidth: maxWidth.toDouble()); 24 | 25 | // if (image != null) return File(image.path); 26 | // return null; 27 | // } 28 | } 29 | -------------------------------------------------------------------------------- /.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 | **/ios/Flutter/.last_build_id 26 | .dart_tool/ 27 | .flutter-plugins 28 | .flutter-plugins-dependencies 29 | .packages 30 | .pub-cache/ 31 | .pub/ 32 | /build/ 33 | 34 | # Web related 35 | lib/generated_plugin_registrant.dart 36 | 37 | # Symbolication related 38 | app.*.symbols 39 | 40 | # Obfuscation related 41 | app.*.map.json 42 | 43 | # Android Studio will place build artifacts here 44 | /android/app/debug 45 | /android/app/profile 46 | /android/app/release 47 | -------------------------------------------------------------------------------- /lib/app/features/product/product_detail/views/components/rating.dart: -------------------------------------------------------------------------------- 1 | part of product_detail; 2 | 3 | class _Rating extends StatelessWidget { 4 | const _Rating(this.data, {Key? key}) : super(key: key); 5 | 6 | final double data; 7 | 8 | @override 9 | Widget build(BuildContext context) { 10 | return Row( 11 | children: [ 12 | RatingBarIndicator( 13 | rating: data, 14 | itemBuilder: (context, index) => Icon( 15 | FontAwesomeIcons.solidStar, 16 | color: Colors.amber, 17 | ), 18 | itemPadding: EdgeInsets.all(3), 19 | unratedColor: Colors.grey, 20 | itemCount: 5, 21 | itemSize: 15, 22 | direction: Axis.horizontal, 23 | ), 24 | SizedBox(width: 5), 25 | Text( 26 | "($data)", 27 | style: Theme.of(context).textTheme.caption, 28 | ), 29 | ], 30 | ); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /lib/app/config/themes/app_theme.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | /// all custom application theme 4 | class AppTheme { 5 | /// default application theme 6 | static ThemeData get basic => ThemeData( 7 | primaryColor: Colors.redAccent, 8 | primarySwatch: Colors.red, 9 | canvasColor: Colors.white, 10 | appBarTheme: AppBarTheme(backgroundColor: Colors.white), 11 | inputDecorationTheme: InputDecorationTheme( 12 | fillColor: Color.fromRGBO(246, 246, 246, 1), 13 | ), 14 | iconTheme: IconThemeData( 15 | color: Color.fromRGBO(187, 193, 202, 1), 16 | ), 17 | ); 18 | 19 | // you can add other custom theme in this class like light theme, dark theme ,etc. 20 | 21 | // example : 22 | // static ThemeData get light => ThemeData(); 23 | // static ThemeData get dark => ThemeData(); 24 | 25 | // Suggestion: to make managing themes easier, create a separate class for each theme. 26 | } 27 | -------------------------------------------------------------------------------- /lib/app/config/routes/app_pages.dart: -------------------------------------------------------------------------------- 1 | import 'package:get/get.dart'; 2 | import 'package:marketplace/app/features/dashboard/explore/views/screens/explore_screen.dart'; 3 | import 'package:marketplace/app/features/dashboard/index/views/screens/dashboard_screen.dart'; 4 | import 'package:marketplace/app/features/product/product_detail/views/screens/product_detail_screen.dart'; 5 | 6 | part 'app_routes.dart'; 7 | 8 | /// contains all configuration pages 9 | class AppPages { 10 | /// when the app is opened this page will be the first to be shown 11 | static const initial = Routes.dashboard; 12 | 13 | static final routes = [ 14 | GetPage( 15 | name: _Paths.dashboard, 16 | page: () => DashboardScreen(), 17 | bindings: [ 18 | DashboardBinding(), 19 | ExploreBinding(), 20 | ], 21 | ), 22 | GetPage( 23 | name: _Paths.product + "/:id", 24 | page: () => ProductDetailScreen(), 25 | binding: ProductDetailBinding(), 26 | transition: Transition.downToUp, 27 | ) 28 | ]; 29 | } 30 | -------------------------------------------------------------------------------- /lib/app/utils/services/src/user_service.dart: -------------------------------------------------------------------------------- 1 | part of rest_api_service; 2 | 3 | /// FAKE USER SERVICE 4 | // put all custom setup in RestApiService (duration timeout, exception handling , etc..) 5 | // and extend restApiService, if you need custom service provider 6 | class UserService extends RestApiServices { 7 | static final UserService _singleton = UserService._internal(); 8 | 9 | factory UserService() { 10 | return _singleton; 11 | } 12 | UserService._internal(); 13 | 14 | User getUserByID(String id) { 15 | if (_userA.id == id) { 16 | return _userA; 17 | } else { 18 | return _userB; 19 | } 20 | } 21 | 22 | final _userA = User( 23 | id: "fwg123", 24 | name: "Gia Store", 25 | country: "Indonesia", 26 | city: "Bandung", 27 | profilImage: AssetImage(ImageRasterPath.market), 28 | ); 29 | 30 | final _userB = User( 31 | id: "fwg345", 32 | profilImage: AssetImage(ImageRasterPath.market2), 33 | name: "Fashion Store", 34 | country: "USA", 35 | city: "New York", 36 | ); 37 | } 38 | -------------------------------------------------------------------------------- /lib/app/features/product/product_detail/views/components/favorite_button.dart: -------------------------------------------------------------------------------- 1 | part of product_detail; 2 | 3 | class _FavoriteButton extends StatelessWidget { 4 | const _FavoriteButton( 5 | {required this.initial, required this.onChanged, Key? key}) 6 | : super(key: key); 7 | 8 | final bool initial; 9 | final Function(bool favorite) onChanged; 10 | 11 | @override 12 | Widget build(BuildContext context) { 13 | final RxBool isFavorite = RxBool(initial); 14 | 15 | return Obx( 16 | () => CustomIconButton( 17 | icon: Icon( 18 | FontAwesomeIcons.solidStar, 19 | color: isFavorite.value 20 | ? Colors.white 21 | : Theme.of(context).iconTheme.color, 22 | ), 23 | onPressed: () { 24 | isFavorite.toggle(); 25 | onChanged(isFavorite.value); 26 | }, 27 | color: isFavorite.value ? Theme.of(context).primaryColor : null, 28 | size: 40, 29 | borderRadius: 10, 30 | tooltip: "Favorite", 31 | ), 32 | ); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /android/app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 9 | 15 | 18 | 19 | -------------------------------------------------------------------------------- /android/app/src/main/res/values-night/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 9 | 15 | 18 | 19 | -------------------------------------------------------------------------------- /lib/app/shared_components/search_field.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:marketplace/app/constans/app_constants.dart'; 3 | 4 | class SearchField extends StatelessWidget { 5 | SearchField({this.onSearch, Key? key}) : super(key: key); 6 | 7 | final controller = TextEditingController(); 8 | final Function(String value)? onSearch; 9 | 10 | @override 11 | Widget build(BuildContext context) { 12 | return TextField( 13 | controller: controller, 14 | decoration: InputDecoration( 15 | filled: true, 16 | border: OutlineInputBorder( 17 | borderRadius: BorderRadius.circular(kBorderRadius), 18 | borderSide: BorderSide.none, 19 | ), 20 | prefixIcon: Icon(Icons.search), 21 | hintText: "what are you looking for", 22 | ), 23 | onEditingComplete: () { 24 | FocusScope.of(context).unfocus(); 25 | if (onSearch != null) onSearch!(controller.text); 26 | }, 27 | textInputAction: TextInputAction.search, 28 | style: TextStyle(color: Colors.grey[800]), 29 | ); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /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:marketplace/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 | -------------------------------------------------------------------------------- /lib/app/shared_components/custom_icon_button.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:marketplace/app/constans/app_constants.dart'; 3 | 4 | class CustomIconButton extends StatelessWidget { 5 | const CustomIconButton({ 6 | required this.icon, 7 | required this.onPressed, 8 | this.color, 9 | this.tooltip, 10 | this.size = 30, 11 | this.borderRadius = kBorderRadius, 12 | Key? key, 13 | }) : super(key: key); 14 | 15 | final Function() onPressed; 16 | final double size; 17 | final Color? color; 18 | final double borderRadius; 19 | 20 | final Icon icon; 21 | final String? tooltip; 22 | 23 | @override 24 | Widget build(BuildContext context) { 25 | return SizedBox( 26 | height: size, 27 | width: size, 28 | child: ClipRRect( 29 | borderRadius: BorderRadius.circular(borderRadius), 30 | child: Material( 31 | color: color ?? Theme.of(context).inputDecorationTheme.fillColor, 32 | child: IconButton( 33 | icon: icon, 34 | onPressed: onPressed, 35 | tooltip: tooltip, 36 | iconSize: size * .4, 37 | ), 38 | ), 39 | ), 40 | ); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Mobile Marketplace 2 | 3 | ## [Watch it on YouTube](https://youtu.be/VAIwqG7e3n8) 4 | 5 | ### Explore & Product Detail Screen 6 | 7 | On this Marketplace Design has two pages one for the product page which has a horizontal list of categories then a list of our products. Then on the details page, it shows the price, rating, total view, and description of the product with the Buy Now button. 8 | 9 | Learn File Structure for Big Projects, hero animation, rating widget, scroll controller, dynamic url, and more. 10 | 11 | ![thumbnail](https://user-images.githubusercontent.com/84274595/135741435-35f40322-6c50-4027-a649-816b763da914.png) 12 | ![marketplace - demo](https://user-images.githubusercontent.com/84274595/135741429-31616ad4-5dbf-4e86-85d0-37cd121f7df4.gif) 13 | 14 | 15 | **Dependencies:** 16 | 17 | - [flutter_rating_bar](https://pub.dev/packages/flutter_rating_bar) 18 | - [flutter_staggered_grid_view](https://pub.dev/packages/flutter_staggered_grid_view) 19 | - [font_awesome_flutter](https://pub.dev/packages/font_awesome_flutter) 20 | - [get](https://pub.dev/packages/get) 21 | - [persistent_bottom_nav_bar](https://pub.dev/packages/persistent_bottom_nav_bar) 22 | - [tab_indicator_styler](https://pub.dev/packages/tab_indicator_styler) 23 | -------------------------------------------------------------------------------- /lib/app/features/dashboard/explore/views/components/tab_bar_content.dart: -------------------------------------------------------------------------------- 1 | part of explore; 2 | 3 | class _TabBarContent extends StatelessWidget { 4 | const _TabBarContent({required this.tabs, required this.children, Key? key}) 5 | : super(key: key); 6 | 7 | final List tabs; 8 | final List children; 9 | 10 | @override 11 | Widget build(BuildContext context) { 12 | return DefaultTabController( 13 | length: tabs.length, 14 | child: Column( 15 | children: [ 16 | SizedBox( 17 | height: 40, 18 | child: TabBar( 19 | tabs: tabs, 20 | indicator: DotIndicator( 21 | color: Theme.of(context).primaryColor, 22 | distanceFromCenter: kSpacing, 23 | radius: 3, 24 | paintingStyle: PaintingStyle.fill, 25 | ), 26 | unselectedLabelColor: kFontColorPallets[1], 27 | labelColor: Theme.of(context).primaryColor, 28 | isScrollable: true, 29 | ), 30 | ), 31 | SizedBox(height: kSpacing), 32 | Expanded( 33 | child: TabBarView(children: children), 34 | ), 35 | ], 36 | ), 37 | ); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /lib/app/features/dashboard/explore/views/components/product_content.dart: -------------------------------------------------------------------------------- 1 | part of explore; 2 | 3 | class _ProductContent extends StatelessWidget { 4 | const _ProductContent(this.data, {required this.onPressed, Key? key}) 5 | : super(key: key); 6 | 7 | final List data; 8 | final Function(Product product) onPressed; 9 | 10 | @override 11 | Widget build(BuildContext context) { 12 | return Padding( 13 | padding: const EdgeInsets.symmetric(horizontal: kSpacing), 14 | child: StaggeredGridView.countBuilder( 15 | physics: BouncingScrollPhysics(), 16 | crossAxisCount: 4, 17 | itemCount: data.length, 18 | itemBuilder: (BuildContext context, int index) => ProductCard( 19 | heroTag: data[index].id, 20 | data: ProductCardData( 21 | image: data[index].images[0], 22 | initialFavorite: data[index].isFavorite, 23 | name: data[index].name, 24 | price: data[index].price, 25 | ), 26 | onTap: () { 27 | onPressed(data[index]); 28 | }, 29 | ), 30 | staggeredTileBuilder: (int index) => StaggeredTile.fit(2), 31 | mainAxisSpacing: 20, 32 | crossAxisSpacing: 20, 33 | ), 34 | ); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /lib/app/features/product/product_detail/views/components/product_image.dart: -------------------------------------------------------------------------------- 1 | part of product_detail; 2 | 3 | class _ProductImage extends StatelessWidget { 4 | _ProductImage(this.images, {Key? key}) : super(key: key); 5 | 6 | final List images; 7 | final _index = 0.obs; 8 | 9 | @override 10 | Widget build(BuildContext context) { 11 | return Stack( 12 | alignment: Alignment.bottomCenter, 13 | children: [ 14 | AspectRatio( 15 | aspectRatio: 1, 16 | child: PageView.builder( 17 | itemCount: images.length, 18 | itemBuilder: (context, index) { 19 | return Image( 20 | image: images[index], 21 | fit: BoxFit.fitWidth, 22 | alignment: Alignment.topCenter, 23 | ); 24 | }, 25 | onPageChanged: (value) { 26 | print(value); 27 | _index.value = value; 28 | }, 29 | ), 30 | ), 31 | if (images.length > 1) 32 | Padding( 33 | padding: const EdgeInsets.only(bottom: 50), 34 | child: Indicator( 35 | controller: _index, 36 | totalIndicator: images.length, 37 | ), 38 | ), 39 | ], 40 | ); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /lib/app/shared_components/indicator.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:get/get.dart'; 3 | 4 | class Indicator extends StatelessWidget { 5 | const Indicator({ 6 | required this.controller, 7 | required this.totalIndicator, 8 | this.color, 9 | Key? key, 10 | }) : super(key: key); 11 | 12 | final Rx controller; 13 | final Color? color; 14 | final int totalIndicator; 15 | 16 | @override 17 | Widget build(BuildContext context) { 18 | return Obx( 19 | () => Row( 20 | mainAxisAlignment: MainAxisAlignment.center, 21 | children: List.generate( 22 | totalIndicator, 23 | (index) => _dot( 24 | index == controller.value, 25 | color ?? Theme.of(context).primaryColor, 26 | ), 27 | ).toList(), 28 | ), 29 | ); 30 | } 31 | 32 | Widget _dot(bool isActive, Color color) { 33 | return AnimatedContainer( 34 | margin: const EdgeInsets.all(5), 35 | duration: Duration(milliseconds: 200), 36 | height: 10, 37 | width: isActive ? 25 : 10, 38 | decoration: BoxDecoration( 39 | borderRadius: BorderRadius.circular(10), 40 | color: color, 41 | border: Border.all( 42 | color: Colors.white, 43 | width: .5, 44 | ), 45 | ), 46 | ); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /lib/app/constans/assets_path.dart: -------------------------------------------------------------------------------- 1 | part of app_constants; 2 | 3 | class FontPath { 4 | // Example: 5 | // static const roboto = 'roboto'; 6 | // static const arial = 'arial'; 7 | } 8 | 9 | class ImageAnimationPath { 10 | // you can get free animation image from rive or lottiefiles 11 | 12 | // Example: 13 | // static const _folderPath = "assets/images/animation"; 14 | // static const myAnim = "$_folderPath/my_anim.json"; 15 | } 16 | 17 | class ImageRasterPath { 18 | static const _folderPath = "assets/images/raster"; 19 | 20 | static const bag = "$_folderPath/bag.png"; 21 | static const blueMidiDress = "$_folderPath/blue-midi-dress.png"; 22 | static const cardigan = "$_folderPath/cardigan.png"; 23 | static const cardigan2 = "$_folderPath/cardigan-2.png"; 24 | static const orangeBlouse = "$_folderPath/orange-blouse.png"; 25 | static const pinkJacket = "$_folderPath/pink-jacket.png"; 26 | static const shoes = "$_folderPath/shoes.png"; 27 | static const shoes2 = "$_folderPath/shoes-2.png"; 28 | static const vr = "$_folderPath/vr.png"; 29 | static const market = "$_folderPath/market.png"; 30 | static const market2 = "$_folderPath/market-2.png"; 31 | } 32 | 33 | class ImageVectorPath { 34 | // Example: 35 | // static const _folderPath = "assets/images/vector"; 36 | // static const myVector = "$_folderPath/vector/my_vector.svg"; 37 | } 38 | -------------------------------------------------------------------------------- /lib/app/features/product/product_detail/views/components/body_content.dart: -------------------------------------------------------------------------------- 1 | part of product_detail; 2 | 3 | class _BodyContent extends StatelessWidget { 4 | const _BodyContent({required this.child, Key? key}) : super(key: key); 5 | 6 | final Widget child; 7 | 8 | @override 9 | Widget build(BuildContext context) { 10 | return Container( 11 | margin: EdgeInsets.only(top: Get.width - 40), 12 | padding: EdgeInsets.all(kSpacing), 13 | constraints: BoxConstraints( 14 | maxHeight: Get.height - 100, 15 | maxWidth: Get.width, 16 | ), 17 | decoration: BoxDecoration( 18 | color: Colors.white, 19 | borderRadius: BorderRadius.only( 20 | topLeft: Radius.circular(20), 21 | topRight: Radius.circular(20), 22 | ), 23 | ), 24 | child: Stack( 25 | alignment: Alignment.topCenter, 26 | children: [ 27 | Padding( 28 | padding: const EdgeInsets.only(top: 20), 29 | child: SingleChildScrollView( 30 | physics: BouncingScrollPhysics(), 31 | child: child, 32 | ), 33 | ), 34 | Container( 35 | height: 5, 36 | width: Get.width * .3, 37 | decoration: BoxDecoration( 38 | color: Theme.of(Get.context!).iconTheme.color, 39 | borderRadius: BorderRadius.circular(5), 40 | ), 41 | ), 42 | ], 43 | ), 44 | ); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | marketplace 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 | -------------------------------------------------------------------------------- /lib/app/features/product/product_detail/controllers/product_detail_controller.dart: -------------------------------------------------------------------------------- 1 | part of product_detail; 2 | 3 | class ProductDetailController extends GetxController { 4 | final productService = ProductService(); 5 | final userService = UserService(); 6 | 7 | final scroll = ScrollController(); 8 | final opacityActionButton = 1.0.obs; 9 | final isVisibleActionButton = true.obs; 10 | 11 | final Rx data = Rx(null); 12 | final Rx dataUser = Rx(null); 13 | 14 | @override 15 | void onInit() { 16 | super.onInit(); 17 | data.value = _getProduct(); 18 | dataUser.value = _getUser(); 19 | 20 | scroll.addListener(onScroll); 21 | } 22 | 23 | Product? _getProduct() { 24 | String? id = Get.parameters['id']; 25 | 26 | Product? product; 27 | 28 | if (id != null) { 29 | product = productService.getProductByID(id); 30 | } 31 | 32 | return product; 33 | } 34 | 35 | User? _getUser() { 36 | String? id = data.value?.idUser; 37 | 38 | User? user; 39 | 40 | if (id != null) { 41 | user = userService.getUserByID(id); 42 | } 43 | 44 | return user; 45 | } 46 | 47 | void onScroll() { 48 | if (scroll.position.pixels > 100 && opacityActionButton.value == 1) { 49 | opacityActionButton.value = 0; 50 | } else if (scroll.position.pixels < 100 && opacityActionButton.value == 0) { 51 | isVisibleActionButton.value = true; 52 | opacityActionButton.value = 1; 53 | } 54 | } 55 | 56 | void onEndAnimationActionButton() { 57 | if (opacityActionButton.value == 0) { 58 | isVisibleActionButton.value = false; 59 | } 60 | } 61 | 62 | void back() => Get.back(); 63 | 64 | void changeFavoriteProduct(Product product, bool favorite) { 65 | AppSnackbar.showStatusFavoriteProduct( 66 | productImage: product.images[0], 67 | productName: product.name, 68 | isFavorite: favorite, 69 | ); 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /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 from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" 27 | 28 | android { 29 | compileSdkVersion 30 30 | 31 | sourceSets { 32 | main.java.srcDirs += 'src/main/kotlin' 33 | } 34 | 35 | defaultConfig { 36 | // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). 37 | applicationId "com.example.marketplace" 38 | minSdkVersion 16 39 | targetSdkVersion 30 40 | versionCode flutterVersionCode.toInteger() 41 | versionName flutterVersionName 42 | } 43 | 44 | buildTypes { 45 | release { 46 | // TODO: Add your own signing config for the release build. 47 | // Signing with the debug keys for now, so `flutter run --release` works. 48 | signingConfig signingConfigs.debug 49 | } 50 | } 51 | } 52 | 53 | flutter { 54 | source '../..' 55 | } 56 | 57 | dependencies { 58 | implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" 59 | } 60 | -------------------------------------------------------------------------------- /android/app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 6 | 13 | 17 | 21 | 26 | 30 | 31 | 32 | 33 | 34 | 35 | 37 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /lib/app/features/dashboard/index/views/screens/dashboard_screen.dart: -------------------------------------------------------------------------------- 1 | library dashboard; 2 | 3 | import 'package:flutter/material.dart'; 4 | import 'package:font_awesome_flutter/font_awesome_flutter.dart'; 5 | import 'package:get/get.dart'; 6 | import 'package:marketplace/app/features/dashboard/explore/views/screens/explore_screen.dart'; 7 | import 'package:persistent_bottom_nav_bar/persistent-tab-view.dart'; 8 | 9 | // binding 10 | part '../../bindings/dashboard_binding.dart'; 11 | 12 | // controller 13 | part '../../controllers/dashboard_controller.dart'; 14 | 15 | // model 16 | 17 | // component 18 | 19 | class DashboardScreen extends GetView { 20 | const DashboardScreen({Key? key}) : super(key: key); 21 | 22 | @override 23 | Widget build(BuildContext context) { 24 | return PersistentTabView( 25 | context, 26 | controller: controller.persistentTab, 27 | screens: _buildScreens(), 28 | items: _buildNavBarsItems(), 29 | backgroundColor: Colors.white, // Default is Colors.white. 30 | decoration: NavBarDecoration( 31 | borderRadius: BorderRadius.circular(10.0), 32 | colorBehindNavBar: Colors.white, 33 | ), 34 | itemAnimationProperties: ItemAnimationProperties( 35 | // Navigation Bar's items animation properties. 36 | duration: Duration(milliseconds: 200), 37 | curve: Curves.ease, 38 | ), 39 | screenTransitionAnimation: ScreenTransitionAnimation( 40 | // Screen transition animation on change of selected tab. 41 | animateTabTransition: true, 42 | curve: Curves.ease, 43 | duration: Duration(milliseconds: 200), 44 | ), 45 | navBarHeight: 70, 46 | navBarStyle: NavBarStyle.style10, 47 | ); 48 | } 49 | 50 | List _buildScreens() { 51 | return [ 52 | ExploreScreen(), 53 | Center(child: Text("Favorite Screen")), 54 | Center(child: Text("Messages Screen")), 55 | Center(child: Text("Profil Screen")), 56 | ]; 57 | } 58 | 59 | List _buildNavBarsItems() { 60 | return [ 61 | _navbarItem(iconData: FontAwesomeIcons.thLarge, title: "Explore"), 62 | _navbarItem(iconData: FontAwesomeIcons.solidStar, title: "Favorite"), 63 | _navbarItem( 64 | iconData: FontAwesomeIcons.solidCommentAlt, title: "Messages"), 65 | _navbarItem(iconData: FontAwesomeIcons.userAlt, title: "Profil"), 66 | ]; 67 | } 68 | 69 | PersistentBottomNavBarItem _navbarItem({ 70 | required IconData iconData, 71 | required String title, 72 | }) { 73 | return PersistentBottomNavBarItem( 74 | icon: Icon(iconData, size: 22), 75 | title: (title), 76 | activeColorPrimary: Color.fromRGBO(246, 246, 246, 1), 77 | inactiveColorPrimary: Color.fromRGBO(187, 193, 202, 1), 78 | activeColorSecondary: Theme.of(Get.context!).primaryColor, 79 | textStyle: TextStyle(fontWeight: FontWeight.bold), 80 | ); 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /lib/app/features/dashboard/explore/views/screens/explore_screen.dart: -------------------------------------------------------------------------------- 1 | library explore; 2 | 3 | import 'package:flutter/material.dart'; 4 | import 'package:flutter_staggered_grid_view/flutter_staggered_grid_view.dart'; 5 | import 'package:get/get.dart'; 6 | import 'package:marketplace/app/config/routes/app_pages.dart'; 7 | import 'package:marketplace/app/constans/app_constants.dart'; 8 | import 'package:marketplace/app/shared_components/filter_button.dart'; 9 | import 'package:marketplace/app/shared_components/product_card.dart'; 10 | import 'package:marketplace/app/shared_components/search_field.dart'; 11 | import 'package:marketplace/app/utils/services/rest_api_services.dart'; 12 | import 'package:tab_indicator_styler/tab_indicator_styler.dart'; 13 | 14 | // binding 15 | part '../../bindings/explore_binding.dart'; 16 | 17 | // controller 18 | part '../../controllers/explore_controller.dart'; 19 | 20 | // component 21 | part '../components/product_content.dart'; 22 | part '../components/tab_bar_content.dart'; 23 | 24 | class ExploreScreen extends GetView { 25 | const ExploreScreen({Key? key}) : super(key: key); 26 | 27 | @override 28 | Widget build(BuildContext context) { 29 | return SafeArea( 30 | child: NestedScrollView( 31 | physics: BouncingScrollPhysics(), 32 | headerSliverBuilder: (context, innerBoxIsScrolled) { 33 | return [ 34 | SliverAppBar( 35 | toolbarHeight: 100, 36 | title: Row( 37 | children: [ 38 | Expanded( 39 | child: SearchField( 40 | onSearch: (value) { 41 | print("search : $value"); 42 | }, 43 | ), 44 | ), 45 | SizedBox(width: kSpacing), 46 | FilterButton( 47 | onPressed: () {}, 48 | ), 49 | ], 50 | ), 51 | ) 52 | ]; 53 | }, 54 | body: _TabBarContent( 55 | tabs: [ 56 | Text("All"), 57 | Text("Fashion"), 58 | Text("Electronic"), 59 | Text("Toys & Hobbies"), 60 | Text("Art"), 61 | Text("Sporting Goods"), 62 | Text("Home & Garden"), 63 | ], 64 | children: [ 65 | _ProductContent( 66 | controller.getAllProduct(), 67 | onPressed: (product) => controller.goToDetailProduct(product), 68 | ), 69 | _ProductContent( 70 | controller.getFashionProduct(), 71 | onPressed: (product) => controller.goToDetailProduct(product), 72 | ), 73 | Center(child: Text("Electronic")), 74 | Center(child: Text("Toys & Hobbies")), 75 | Center(child: Text("Art")), 76 | Center(child: Text("Sporting Goods")), 77 | Center(child: Text("Home & Garden")), 78 | ], 79 | ), 80 | ), 81 | ); 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /pubspec.yaml: -------------------------------------------------------------------------------- 1 | name: marketplace 2 | description: A new Flutter project. 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.12.0 <3.0.0" 22 | 23 | dependencies: 24 | cupertino_icons: ^1.0.2 25 | flutter: 26 | sdk: flutter 27 | flutter_rating_bar: ^4.0.0 28 | flutter_staggered_grid_view: ^0.4.0 29 | font_awesome_flutter: ^9.1.0 30 | get: ^4.3.8 31 | persistent_bottom_nav_bar: ^4.0.2 32 | tab_indicator_styler: ^2.0.0 33 | 34 | dev_dependencies: 35 | flutter_test: 36 | sdk: flutter 37 | 38 | # For information on the generic Dart part of this file, see the 39 | # following page: https://dart.dev/tools/pub/pubspec 40 | # The following section is specific to Flutter. 41 | flutter: 42 | # The following line ensures that the Material Icons font is 43 | # included with your application, so that you can use the icons in 44 | # the material Icons class. 45 | uses-material-design: true 46 | # To add assets to your application, add an assets section, like this: 47 | assets: 48 | - assets/images/raster/. 49 | # - images/a_dot_ham.jpeg 50 | # An image asset can refer to one or more resolution-specific "variants", see 51 | # https://flutter.dev/assets-and-images/#resolution-aware. 52 | # For details regarding adding assets from package dependencies, see 53 | # https://flutter.dev/assets-and-images/#from-packages 54 | # To add custom fonts to your application, add a fonts section here, 55 | # in this "flutter" section. Each entry in this list should have a 56 | # "family" key with the font family name, and a "fonts" key with a 57 | # list giving the asset and other descriptors for the font. For 58 | # example: 59 | # fonts: 60 | # - family: Schyler 61 | # fonts: 62 | # - asset: fonts/Schyler-Regular.ttf 63 | # - asset: fonts/Schyler-Italic.ttf 64 | # style: italic 65 | # - family: Trajan Pro 66 | # fonts: 67 | # - asset: fonts/TrajanPro.ttf 68 | # - asset: fonts/TrajanPro_Bold.ttf 69 | # weight: 700 70 | # 71 | # For details regarding fonts from package dependencies, 72 | # see https://flutter.dev/custom-fonts/#from-packages 73 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /web/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | marketplace 27 | 28 | 29 | 30 | 33 | 97 | 98 | 99 | -------------------------------------------------------------------------------- /lib/app/shared_components/product_card.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:font_awesome_flutter/font_awesome_flutter.dart'; 3 | import 'package:get/get.dart'; 4 | import 'package:marketplace/app/constans/app_constants.dart'; 5 | import 'package:marketplace/app/utils/ui/ui_utils.dart'; 6 | 7 | class ProductCardData { 8 | final ImageProvider image; 9 | final double price; 10 | final String name; 11 | final bool initialFavorite; 12 | 13 | const ProductCardData({ 14 | required this.image, 15 | required this.price, 16 | required this.name, 17 | required this.initialFavorite, 18 | }); 19 | } 20 | 21 | class ProductCard extends StatelessWidget { 22 | const ProductCard({ 23 | required this.data, 24 | required this.heroTag, 25 | this.onTap, 26 | this.onFavoriteChanged, 27 | Key? key, 28 | }) : super(key: key); 29 | 30 | final String heroTag; 31 | final ProductCardData data; 32 | final Function()? onTap; 33 | final Function(bool isFavorite)? onFavoriteChanged; 34 | 35 | @override 36 | Widget build(BuildContext context) { 37 | return Column( 38 | crossAxisAlignment: CrossAxisAlignment.start, 39 | children: [ 40 | Hero( 41 | tag: heroTag, 42 | child: GestureDetector( 43 | onTap: onTap, 44 | child: ClipRRect( 45 | borderRadius: BorderRadius.circular(kBorderRadius), 46 | child: Stack( 47 | alignment: AlignmentDirectional.bottomEnd, 48 | children: [ 49 | _buildImage(data.image), 50 | _buildFavoriteIcon( 51 | data.initialFavorite, 52 | onTap: (isFavorite) { 53 | if (onFavoriteChanged != null) { 54 | onFavoriteChanged!(isFavorite); 55 | } 56 | AppSnackbar.showStatusFavoriteProduct( 57 | isFavorite: isFavorite, 58 | productImage: data.image, 59 | productName: data.name, 60 | ); 61 | }, 62 | ), 63 | ], 64 | ), 65 | ), 66 | ), 67 | ), 68 | SizedBox(height: kSpacing), 69 | _buildPriceText(data.price), 70 | _buildNameProduct(data.name), 71 | ], 72 | ); 73 | } 74 | 75 | Widget _buildImage(ImageProvider image) { 76 | return Image( 77 | image: image, 78 | fit: BoxFit.cover, 79 | ); 80 | } 81 | 82 | Widget _buildFavoriteIcon( 83 | bool initialFavorite, { 84 | required Function(bool isFavorite) onTap, 85 | }) { 86 | RxBool isFavorite = RxBool(initialFavorite); 87 | 88 | Color activeColor = Theme.of(Get.context!).primaryColor; 89 | Color? passiveColor = Theme.of(Get.context!).iconTheme.color; 90 | 91 | return Obx( 92 | () => Material( 93 | color: isFavorite.value ? activeColor : passiveColor, 94 | borderRadius: BorderRadius.only( 95 | topLeft: Radius.circular(kBorderRadius), 96 | ), 97 | child: Container( 98 | height: 40, 99 | width: 40, 100 | child: InkWell( 101 | onTap: () { 102 | isFavorite.toggle(); 103 | onTap(isFavorite.value); 104 | }, 105 | child: Icon( 106 | FontAwesomeIcons.solidStar, 107 | color: Colors.white, 108 | size: 20, 109 | ), 110 | ), 111 | ), 112 | ), 113 | ); 114 | } 115 | 116 | Widget _buildPriceText(double price) { 117 | return Row( 118 | children: [ 119 | Icon( 120 | FontAwesomeIcons.dollarSign, 121 | size: 14, 122 | color: kFontColorPallets[0], 123 | ), 124 | Expanded( 125 | child: Text( 126 | "$price", 127 | style: TextStyle( 128 | color: kFontColorPallets[0], 129 | fontWeight: FontWeight.bold, 130 | fontSize: 17, 131 | ), 132 | maxLines: 1, 133 | overflow: TextOverflow.ellipsis, 134 | ), 135 | ) 136 | ], 137 | ); 138 | } 139 | 140 | Widget _buildNameProduct(String name) { 141 | return Text( 142 | name, 143 | style: TextStyle( 144 | color: kFontColorPallets[2], 145 | ), 146 | textAlign: TextAlign.left, 147 | maxLines: 1, 148 | overflow: TextOverflow.ellipsis, 149 | ); 150 | } 151 | } 152 | -------------------------------------------------------------------------------- /pubspec.lock: -------------------------------------------------------------------------------- 1 | # Generated by pub 2 | # See https://dart.dev/tools/pub/glossary#lockfile 3 | packages: 4 | async: 5 | dependency: transitive 6 | description: 7 | name: async 8 | url: "https://pub.dartlang.org" 9 | source: hosted 10 | version: "2.6.1" 11 | boolean_selector: 12 | dependency: transitive 13 | description: 14 | name: boolean_selector 15 | url: "https://pub.dartlang.org" 16 | source: hosted 17 | version: "2.1.0" 18 | characters: 19 | dependency: transitive 20 | description: 21 | name: characters 22 | url: "https://pub.dartlang.org" 23 | source: hosted 24 | version: "1.1.0" 25 | charcode: 26 | dependency: transitive 27 | description: 28 | name: charcode 29 | url: "https://pub.dartlang.org" 30 | source: hosted 31 | version: "1.2.0" 32 | clock: 33 | dependency: transitive 34 | description: 35 | name: clock 36 | url: "https://pub.dartlang.org" 37 | source: hosted 38 | version: "1.1.0" 39 | collection: 40 | dependency: transitive 41 | description: 42 | name: collection 43 | url: "https://pub.dartlang.org" 44 | source: hosted 45 | version: "1.15.0" 46 | cupertino_icons: 47 | dependency: "direct main" 48 | description: 49 | name: cupertino_icons 50 | url: "https://pub.dartlang.org" 51 | source: hosted 52 | version: "1.0.3" 53 | fake_async: 54 | dependency: transitive 55 | description: 56 | name: fake_async 57 | url: "https://pub.dartlang.org" 58 | source: hosted 59 | version: "1.2.0" 60 | flutter: 61 | dependency: "direct main" 62 | description: flutter 63 | source: sdk 64 | version: "0.0.0" 65 | flutter_rating_bar: 66 | dependency: "direct main" 67 | description: 68 | name: flutter_rating_bar 69 | url: "https://pub.dartlang.org" 70 | source: hosted 71 | version: "4.0.0" 72 | flutter_staggered_grid_view: 73 | dependency: "direct main" 74 | description: 75 | name: flutter_staggered_grid_view 76 | url: "https://pub.dartlang.org" 77 | source: hosted 78 | version: "0.4.0" 79 | flutter_test: 80 | dependency: "direct dev" 81 | description: flutter 82 | source: sdk 83 | version: "0.0.0" 84 | font_awesome_flutter: 85 | dependency: "direct main" 86 | description: 87 | name: font_awesome_flutter 88 | url: "https://pub.dartlang.org" 89 | source: hosted 90 | version: "9.1.0" 91 | get: 92 | dependency: "direct main" 93 | description: 94 | name: get 95 | url: "https://pub.dartlang.org" 96 | source: hosted 97 | version: "4.3.8" 98 | matcher: 99 | dependency: transitive 100 | description: 101 | name: matcher 102 | url: "https://pub.dartlang.org" 103 | source: hosted 104 | version: "0.12.10" 105 | meta: 106 | dependency: transitive 107 | description: 108 | name: meta 109 | url: "https://pub.dartlang.org" 110 | source: hosted 111 | version: "1.3.0" 112 | path: 113 | dependency: transitive 114 | description: 115 | name: path 116 | url: "https://pub.dartlang.org" 117 | source: hosted 118 | version: "1.8.0" 119 | persistent_bottom_nav_bar: 120 | dependency: "direct main" 121 | description: 122 | name: persistent_bottom_nav_bar 123 | url: "https://pub.dartlang.org" 124 | source: hosted 125 | version: "4.0.2" 126 | sky_engine: 127 | dependency: transitive 128 | description: flutter 129 | source: sdk 130 | version: "0.0.99" 131 | source_span: 132 | dependency: transitive 133 | description: 134 | name: source_span 135 | url: "https://pub.dartlang.org" 136 | source: hosted 137 | version: "1.8.1" 138 | stack_trace: 139 | dependency: transitive 140 | description: 141 | name: stack_trace 142 | url: "https://pub.dartlang.org" 143 | source: hosted 144 | version: "1.10.0" 145 | stream_channel: 146 | dependency: transitive 147 | description: 148 | name: stream_channel 149 | url: "https://pub.dartlang.org" 150 | source: hosted 151 | version: "2.1.0" 152 | string_scanner: 153 | dependency: transitive 154 | description: 155 | name: string_scanner 156 | url: "https://pub.dartlang.org" 157 | source: hosted 158 | version: "1.1.0" 159 | tab_indicator_styler: 160 | dependency: "direct main" 161 | description: 162 | name: tab_indicator_styler 163 | url: "https://pub.dartlang.org" 164 | source: hosted 165 | version: "2.0.0" 166 | term_glyph: 167 | dependency: transitive 168 | description: 169 | name: term_glyph 170 | url: "https://pub.dartlang.org" 171 | source: hosted 172 | version: "1.2.0" 173 | test_api: 174 | dependency: transitive 175 | description: 176 | name: test_api 177 | url: "https://pub.dartlang.org" 178 | source: hosted 179 | version: "0.3.0" 180 | typed_data: 181 | dependency: transitive 182 | description: 183 | name: typed_data 184 | url: "https://pub.dartlang.org" 185 | source: hosted 186 | version: "1.3.0" 187 | vector_math: 188 | dependency: transitive 189 | description: 190 | name: vector_math 191 | url: "https://pub.dartlang.org" 192 | source: hosted 193 | version: "2.1.0" 194 | sdks: 195 | dart: ">=2.12.0 <3.0.0" 196 | flutter: ">=1.24.0-6.0.pre" 197 | -------------------------------------------------------------------------------- /lib/app/features/product/product_detail/views/screens/product_detail_screen.dart: -------------------------------------------------------------------------------- 1 | library product_detail; 2 | 3 | import 'package:flutter/material.dart'; 4 | import 'package:font_awesome_flutter/font_awesome_flutter.dart'; 5 | import 'package:get/get.dart'; 6 | import 'package:marketplace/app/constans/app_constants.dart'; 7 | import 'package:marketplace/app/shared_components/custom_icon_button.dart'; 8 | import 'package:marketplace/app/shared_components/indicator.dart'; 9 | import 'package:marketplace/app/utils/services/rest_api_services.dart'; 10 | import 'package:marketplace/app/utils/ui/ui_utils.dart'; 11 | import 'package:flutter_rating_bar/flutter_rating_bar.dart'; 12 | 13 | // binding 14 | part '../../bindings/product_detail_binding.dart'; 15 | 16 | // controller 17 | part '../../controllers/product_detail_controller.dart'; 18 | 19 | // component 20 | part '../components/back_button.dart'; 21 | part '../components/favorite_button.dart'; 22 | part '../components/buy_button.dart'; 23 | part '../components/chat_button.dart'; 24 | part '../components/name_text.dart'; 25 | part '../components/body_content.dart'; 26 | part '../components/description_text.dart'; 27 | part '../components/price_text.dart'; 28 | part '../components/product_image.dart'; 29 | part '../components/rating.dart'; 30 | part '../components/review_text.dart'; 31 | part '../components/share_button.dart'; 32 | part '../components/views_text.dart'; 33 | 34 | class ProductDetailScreen extends GetView { 35 | const ProductDetailScreen({Key? key}) : super(key: key); 36 | 37 | @override 38 | Widget build(BuildContext context) { 39 | return Scaffold( 40 | body: Obx( 41 | () => 42 | (controller.data.value == null || controller.dataUser.value == null) 43 | ? Center(child: Text("Product or User Not Found")) 44 | : _buildProductDetail( 45 | product: controller.data.value!, 46 | user: controller.dataUser.value!, 47 | ), 48 | ), 49 | bottomNavigationBar: Padding( 50 | padding: const EdgeInsets.all(kSpacing / 2), 51 | child: Row( 52 | children: [ 53 | SizedBox(width: kSpacing / 2), 54 | _ChatButton(onPressed: () {}), 55 | SizedBox(width: kSpacing), 56 | _BuyButton(onPressed: () {}), 57 | SizedBox(width: kSpacing / 2), 58 | ], 59 | ), 60 | ), 61 | ); 62 | } 63 | 64 | Widget _buildProductDetail({required Product product, required User user}) { 65 | return Stack( 66 | children: [ 67 | // DETAIL CONTENT 68 | SingleChildScrollView( 69 | controller: controller.scroll, 70 | child: Column( 71 | children: [ 72 | Stack( 73 | children: [ 74 | // BACKGROUND IMAGES 75 | Hero(tag: product.id, child: _ProductImage(product.images)), 76 | 77 | // BODY 78 | _BodyContent( 79 | child: Column( 80 | crossAxisAlignment: CrossAxisAlignment.start, 81 | children: [ 82 | Row( 83 | mainAxisAlignment: MainAxisAlignment.spaceBetween, 84 | children: [ 85 | Flexible( 86 | flex: 2, 87 | child: _PriceText(product.price.toString()), 88 | ), 89 | Flexible( 90 | flex: 1, 91 | child: _ViewsText("${product.totalViews} Views"), 92 | ), 93 | ], 94 | ), 95 | SizedBox(height: kSpacing), 96 | _NameText(product.name), 97 | SizedBox(height: kSpacing), 98 | Row( 99 | children: [ 100 | _Rating(product.rating), 101 | SizedBox(width: kSpacing), 102 | CircleAvatar( 103 | radius: 3, backgroundColor: Colors.grey), 104 | SizedBox(width: 5), 105 | _ReviewsText("${product.totalReview} Review") 106 | ], 107 | ), 108 | SizedBox(height: kSpacing * 2), 109 | _DescriptionText(product.description), 110 | SizedBox(height: kSpacing), 111 | Material( 112 | child: ListTile( 113 | leading: 114 | CircleAvatar(backgroundImage: user.profilImage), 115 | title: Text(user.name), 116 | subtitle: Text("${user.country} (${user.city})"), 117 | trailing: Icon(Icons.keyboard_arrow_right_rounded), 118 | onTap: () {}, 119 | ), 120 | ) 121 | ], 122 | ), 123 | ), 124 | ], 125 | ) 126 | ], 127 | ), 128 | ), 129 | 130 | // HEADER BUTTON 131 | Obx( 132 | () => AnimatedOpacity( 133 | opacity: controller.opacityActionButton.value, 134 | duration: Duration(milliseconds: 200), 135 | onEnd: () => controller.onEndAnimationActionButton(), 136 | child: Visibility( 137 | visible: controller.isVisibleActionButton.value, 138 | child: Padding( 139 | padding: const EdgeInsets.symmetric( 140 | horizontal: 15, 141 | vertical: 40, 142 | ), 143 | child: Row( 144 | children: [ 145 | _BackButton(onPressed: () => controller.back()), 146 | Spacer(), 147 | _FavoriteButton( 148 | initial: product.isFavorite, 149 | onChanged: (favorite) { 150 | controller.changeFavoriteProduct(product, favorite); 151 | }, 152 | ), 153 | SizedBox(width: 15), 154 | _ShareButton(onPressed: () {}), 155 | ], 156 | ), 157 | ), 158 | ), 159 | ), 160 | ), 161 | ], 162 | ); 163 | } 164 | } 165 | -------------------------------------------------------------------------------- /lib/app/utils/services/src/product_service.dart: -------------------------------------------------------------------------------- 1 | part of rest_api_service; 2 | 3 | /// FAKE PRODUCT SERVICE 4 | // put all custom setup in RestApiService (duration timeout, exception handling , etc..) 5 | // and extend restApiService, if you need custom service provider 6 | class ProductService extends RestApiServices { 7 | static final ProductService _singleton = ProductService._internal(); 8 | 9 | factory ProductService() { 10 | return _singleton; 11 | } 12 | ProductService._internal(); 13 | 14 | Product? getProductByID(String id) { 15 | final allProduct = getAll(); 16 | final result = allProduct.where((product) => product.id == id).toList(); 17 | return (result.length > 0) ? result[0] : null; 18 | } 19 | 20 | List getAll() { 21 | return [ 22 | _vr, 23 | _orangeBlouse, 24 | _cardigan, 25 | _shoes, 26 | _blueMidiDress, 27 | _bag, 28 | _pinkJacket, 29 | _shoes2, 30 | ]; 31 | } 32 | 33 | List getFashion() { 34 | return [ 35 | _pinkJacket, 36 | _shoes2, 37 | _orangeBlouse, 38 | _cardigan, 39 | _shoes, 40 | _blueMidiDress, 41 | ]; 42 | } 43 | 44 | final _bag = Product( 45 | id: "35366", 46 | idUser: "fwg123", 47 | images: [AssetImage(ImageRasterPath.bag)], 48 | name: 49 | "12 Colors Men Women Rope Bags Waterproof Drawstring Backpack Travel Hiking Bag ", 50 | price: 5, 51 | isFavorite: false, 52 | description: 53 | "Lorem ipsum At vero eos et accusamus et iusto odio dignissimos ducimus qui blanditiis praesentium voluptatum deleniti atque corrupti quos dolores et quas molestias excepturi sint occaecati cupiditate non provident, similique sunt in culpa qui officia deserunt mollitia animi, id est laborum et dolorum fuga. Et harum quidem rerum facilis est et expedita distinctio. Nam libero tempore, cum soluta nobis est eligendi optio cumque nihil impedit quo minus id quod maxime placeat facere possimus, omnis voluptas assumenda est, omnis dolor repellendus. Temporibus autem quibusdam et aut officiis debitis aut rerum necessitatibus saepe eveniet ut et voluptates repudiandae sint et molestiae non recusandae. Itaque earum rerum hic tenetur a sapiente delectus, ut aut reiciendis voluptatibus maiores alias consequatur aut perferendis doloribus asperiores repellat.", 54 | totalViews: 20, 55 | totalReview: 3, 56 | rating: 4.5, 57 | ); 58 | 59 | final _blueMidiDress = Product( 60 | id: "23515", 61 | idUser: "fwg123", 62 | images: [AssetImage(ImageRasterPath.blueMidiDress)], 63 | name: 64 | "Summer Womens Shirt Drees Loose Dress V-Neck Embroidered Midi Long Cotton Dress ", 65 | price: 15.2, 66 | isFavorite: true, 67 | description: 68 | "Lorem ipsum At vero eos et accusamus et iusto odio dignissimos ducimus qui blanditiis praesentium voluptatum deleniti atque corrupti quos dolores et quas molestias excepturi sint occaecati cupiditate non provident, similique sunt in culpa qui officia deserunt mollitia animi, id est laborum et dolorum fuga. Et harum quidem rerum facilis est et expedita distinctio. Nam libero tempore, cum soluta nobis est eligendi optio cumque nihil impedit quo minus id quod maxime placeat facere possimus, omnis voluptas assumenda est, omnis dolor repellendus. Temporibus autem quibusdam et aut officiis debitis aut rerum necessitatibus saepe eveniet ut et voluptates repudiandae sint et molestiae non recusandae. Itaque earum rerum hic tenetur a sapiente delectus, ut aut reiciendis voluptatibus maiores alias consequatur aut perferendis doloribus asperiores repellat.", 69 | totalViews: 100, 70 | totalReview: 0, 71 | rating: 0, 72 | ); 73 | 74 | final _cardigan = Product( 75 | id: "54647", 76 | idUser: "fwg345", 77 | images: [ 78 | AssetImage(ImageRasterPath.cardigan), 79 | AssetImage(ImageRasterPath.cardigan2), 80 | ], 81 | name: 82 | "Women Knitted Sweater Open Front Pocket Coat Long Cardigan Coat/Jacket Winter", 83 | price: 10.1, 84 | isFavorite: true, 85 | description: 86 | "Lorem ipsum At vero eos et accusamus et iusto odio dignissimos ducimus qui blanditiis praesentium voluptatum deleniti atque corrupti quos dolores et quas molestias excepturi sint occaecati cupiditate non provident, similique sunt in culpa qui officia deserunt mollitia animi, id est laborum et dolorum fuga. Et harum quidem rerum facilis est et expedita distinctio. Nam libero tempore, cum soluta nobis est eligendi optio cumque nihil impedit quo minus id quod maxime placeat facere possimus, omnis voluptas assumenda est, omnis dolor repellendus. Temporibus autem quibusdam et aut officiis debitis aut rerum necessitatibus saepe eveniet ut et voluptates repudiandae sint et molestiae non recusandae. Itaque earum rerum hic tenetur a sapiente delectus, ut aut reiciendis voluptatibus maiores alias consequatur aut perferendis doloribus asperiores repellat.", 87 | totalViews: 1135, 88 | totalReview: 140, 89 | rating: 4.8, 90 | ); 91 | 92 | final _orangeBlouse = Product( 93 | id: "23455", 94 | idUser: "fwg345", 95 | images: [AssetImage(ImageRasterPath.orangeBlouse)], 96 | name: 97 | "Womens Loose Fit Short Sleeve T-Shirt V-Neck Casual Basic Tunic Top Long Blouse ", 98 | price: 5.9, 99 | isFavorite: false, 100 | description: 101 | "Lorem ipsum At vero eos et accusamus et iusto odio dignissimos ducimus qui blanditiis praesentium voluptatum deleniti atque corrupti quos dolores et quas molestias excepturi sint occaecati cupiditate non provident, similique sunt in culpa qui officia deserunt mollitia animi, id est laborum et dolorum fuga. Et harum quidem rerum facilis est et expedita distinctio. Nam libero tempore, cum soluta nobis est eligendi optio cumque nihil impedit quo minus id quod maxime placeat facere possimus, omnis voluptas assumenda est, omnis dolor repellendus. Temporibus autem quibusdam et aut officiis debitis aut rerum necessitatibus saepe eveniet ut et voluptates repudiandae sint et molestiae non recusandae. Itaque earum rerum hic tenetur a sapiente delectus, ut aut reiciendis voluptatibus maiores alias consequatur aut perferendis doloribus asperiores repellat.", 102 | totalViews: 10, 103 | totalReview: 20, 104 | rating: 5, 105 | ); 106 | 107 | final _pinkJacket = Product( 108 | id: "77532", 109 | idUser: "fwg345", 110 | images: [AssetImage(ImageRasterPath.pinkJacket)], 111 | name: "Barbour Women's Ladies Wax Biker Style Jacket Pink size 10", 112 | price: 30.2, 113 | isFavorite: true, 114 | description: 115 | "Lorem ipsum At vero eos et accusamus et iusto odio dignissimos ducimus qui blanditiis praesentium voluptatum deleniti atque corrupti quos dolores et quas molestias excepturi sint occaecati cupiditate non provident, similique sunt in culpa qui officia deserunt mollitia animi, id est laborum et dolorum fuga. Et harum quidem rerum facilis est et expedita distinctio. Nam libero tempore, cum soluta nobis est eligendi optio cumque nihil impedit quo minus id quod maxime placeat facere possimus, omnis voluptas assumenda est, omnis dolor repellendus. Temporibus autem quibusdam et aut officiis debitis aut rerum necessitatibus saepe eveniet ut et voluptates repudiandae sint et molestiae non recusandae. Itaque earum rerum hic tenetur a sapiente delectus, ut aut reiciendis voluptatibus maiores alias consequatur aut perferendis doloribus asperiores repellat.", 116 | totalViews: 120, 117 | totalReview: 10, 118 | rating: 4.6, 119 | ); 120 | 121 | final _shoes = Product( 122 | id: "56621", 123 | idUser: "fwg345", 124 | images: [AssetImage(ImageRasterPath.shoes)], 125 | name: "DC Shoes Pure Men's Leather Low Top Classic Skateboarding Sneakers", 126 | price: 12.0, 127 | isFavorite: false, 128 | description: 129 | "Lorem ipsum At vero eos et accusamus et iusto odio dignissimos ducimus qui blanditiis praesentium voluptatum deleniti atque corrupti quos dolores et quas molestias excepturi sint occaecati cupiditate non provident, similique sunt in culpa qui officia deserunt mollitia animi, id est laborum et dolorum fuga. Et harum quidem rerum facilis est et expedita distinctio. Nam libero tempore, cum soluta nobis est eligendi optio cumque nihil impedit quo minus id quod maxime placeat facere possimus, omnis voluptas assumenda est, omnis dolor repellendus. Temporibus autem quibusdam et aut officiis debitis aut rerum necessitatibus saepe eveniet ut et voluptates repudiandae sint et molestiae non recusandae. Itaque earum rerum hic tenetur a sapiente delectus, ut aut reiciendis voluptatibus maiores alias consequatur aut perferendis doloribus asperiores repellat.", 130 | totalViews: 12, 131 | totalReview: 1, 132 | rating: 5, 133 | ); 134 | 135 | final _shoes2 = Product( 136 | id: "45612", 137 | idUser: "fwg345", 138 | images: [AssetImage(ImageRasterPath.shoes2)], 139 | name: 140 | "Brooks Mens Glycerin 18 1103291D064 Black Blue Running Shoes Lace Up Size 11.5 D ", 141 | price: 12.2, 142 | isFavorite: false, 143 | description: 144 | "Lorem ipsum At vero eos et accusamus et iusto odio dignissimos ducimus qui blanditiis praesentium voluptatum deleniti atque corrupti quos dolores et quas molestias excepturi sint occaecati cupiditate non provident, similique sunt in culpa qui officia deserunt mollitia animi, id est laborum et dolorum fuga. Et harum quidem rerum facilis est et expedita distinctio. Nam libero tempore, cum soluta nobis est eligendi optio cumque nihil impedit quo minus id quod maxime placeat facere possimus, omnis voluptas assumenda est, omnis dolor repellendus. Temporibus autem quibusdam et aut officiis debitis aut rerum necessitatibus saepe eveniet ut et voluptates repudiandae sint et molestiae non recusandae. Itaque earum rerum hic tenetur a sapiente delectus, ut aut reiciendis voluptatibus maiores alias consequatur aut perferendis doloribus asperiores repellat.", 145 | totalViews: 100, 146 | totalReview: 5, 147 | rating: 4.5, 148 | ); 149 | 150 | final _vr = Product( 151 | id: "99010", 152 | idUser: "fwg123", 153 | images: [AssetImage(ImageRasterPath.vr)], 154 | name: "Oculus Quest All-in-One VR Gaming System 64GB (301-00174-01)", 155 | price: 200, 156 | isFavorite: false, 157 | description: 158 | "Lorem ipsum At vero eos et accusamus et iusto odio dignissimos ducimus qui blanditiis praesentium voluptatum deleniti atque corrupti quos dolores et quas molestias excepturi sint occaecati cupiditate non provident, similique sunt in culpa qui officia deserunt mollitia animi, id est laborum et dolorum fuga. Et harum quidem rerum facilis est et expedita distinctio. Nam libero tempore, cum soluta nobis est eligendi optio cumque nihil impedit quo minus id quod maxime placeat facere possimus, omnis voluptas assumenda est, omnis dolor repellendus. Temporibus autem quibusdam et aut officiis debitis aut rerum necessitatibus saepe eveniet ut et voluptates repudiandae sint et molestiae non recusandae. Itaque earum rerum hic tenetur a sapiente delectus, ut aut reiciendis voluptatibus maiores alias consequatur aut perferendis doloribus asperiores repellat.", 159 | totalViews: 100, 160 | totalReview: 300, 161 | rating: 4.5, 162 | ); 163 | } 164 | -------------------------------------------------------------------------------- /ios/Runner.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; }; 11 | 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; }; 12 | 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; }; 13 | 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; }; 14 | 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; }; 15 | 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; }; 16 | /* End PBXBuildFile section */ 17 | 18 | /* Begin PBXCopyFilesBuildPhase section */ 19 | 9705A1C41CF9048500538489 /* Embed Frameworks */ = { 20 | isa = PBXCopyFilesBuildPhase; 21 | buildActionMask = 2147483647; 22 | dstPath = ""; 23 | dstSubfolderSpec = 10; 24 | files = ( 25 | ); 26 | name = "Embed Frameworks"; 27 | runOnlyForDeploymentPostprocessing = 0; 28 | }; 29 | /* End PBXCopyFilesBuildPhase section */ 30 | 31 | /* Begin PBXFileReference section */ 32 | 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = ""; }; 33 | 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = ""; }; 34 | 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; }; 35 | 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = ""; }; 36 | 74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 37 | 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; }; 38 | 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = ""; }; 39 | 9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = ""; }; 40 | 97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; }; 41 | 97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 42 | 97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 43 | 97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 44 | 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 45 | /* End PBXFileReference section */ 46 | 47 | /* Begin PBXFrameworksBuildPhase section */ 48 | 97C146EB1CF9000F007C117D /* Frameworks */ = { 49 | isa = PBXFrameworksBuildPhase; 50 | buildActionMask = 2147483647; 51 | files = ( 52 | ); 53 | runOnlyForDeploymentPostprocessing = 0; 54 | }; 55 | /* End PBXFrameworksBuildPhase section */ 56 | 57 | /* Begin PBXGroup section */ 58 | 9740EEB11CF90186004384FC /* Flutter */ = { 59 | isa = PBXGroup; 60 | children = ( 61 | 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */, 62 | 9740EEB21CF90195004384FC /* Debug.xcconfig */, 63 | 7AFA3C8E1D35360C0083082E /* Release.xcconfig */, 64 | 9740EEB31CF90195004384FC /* Generated.xcconfig */, 65 | ); 66 | name = Flutter; 67 | sourceTree = ""; 68 | }; 69 | 97C146E51CF9000F007C117D = { 70 | isa = PBXGroup; 71 | children = ( 72 | 9740EEB11CF90186004384FC /* Flutter */, 73 | 97C146F01CF9000F007C117D /* Runner */, 74 | 97C146EF1CF9000F007C117D /* Products */, 75 | ); 76 | sourceTree = ""; 77 | }; 78 | 97C146EF1CF9000F007C117D /* Products */ = { 79 | isa = PBXGroup; 80 | children = ( 81 | 97C146EE1CF9000F007C117D /* Runner.app */, 82 | ); 83 | name = Products; 84 | sourceTree = ""; 85 | }; 86 | 97C146F01CF9000F007C117D /* Runner */ = { 87 | isa = PBXGroup; 88 | children = ( 89 | 97C146FA1CF9000F007C117D /* Main.storyboard */, 90 | 97C146FD1CF9000F007C117D /* Assets.xcassets */, 91 | 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */, 92 | 97C147021CF9000F007C117D /* Info.plist */, 93 | 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */, 94 | 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */, 95 | 74858FAE1ED2DC5600515810 /* AppDelegate.swift */, 96 | 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */, 97 | ); 98 | path = Runner; 99 | sourceTree = ""; 100 | }; 101 | /* End PBXGroup section */ 102 | 103 | /* Begin PBXNativeTarget section */ 104 | 97C146ED1CF9000F007C117D /* Runner */ = { 105 | isa = PBXNativeTarget; 106 | buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */; 107 | buildPhases = ( 108 | 9740EEB61CF901F6004384FC /* Run Script */, 109 | 97C146EA1CF9000F007C117D /* Sources */, 110 | 97C146EB1CF9000F007C117D /* Frameworks */, 111 | 97C146EC1CF9000F007C117D /* Resources */, 112 | 9705A1C41CF9048500538489 /* Embed Frameworks */, 113 | 3B06AD1E1E4923F5004D2608 /* Thin Binary */, 114 | ); 115 | buildRules = ( 116 | ); 117 | dependencies = ( 118 | ); 119 | name = Runner; 120 | productName = Runner; 121 | productReference = 97C146EE1CF9000F007C117D /* Runner.app */; 122 | productType = "com.apple.product-type.application"; 123 | }; 124 | /* End PBXNativeTarget section */ 125 | 126 | /* Begin PBXProject section */ 127 | 97C146E61CF9000F007C117D /* Project object */ = { 128 | isa = PBXProject; 129 | attributes = { 130 | LastUpgradeCheck = 1020; 131 | ORGANIZATIONNAME = ""; 132 | TargetAttributes = { 133 | 97C146ED1CF9000F007C117D = { 134 | CreatedOnToolsVersion = 7.3.1; 135 | LastSwiftMigration = 1100; 136 | }; 137 | }; 138 | }; 139 | buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */; 140 | compatibilityVersion = "Xcode 9.3"; 141 | developmentRegion = en; 142 | hasScannedForEncodings = 0; 143 | knownRegions = ( 144 | en, 145 | Base, 146 | ); 147 | mainGroup = 97C146E51CF9000F007C117D; 148 | productRefGroup = 97C146EF1CF9000F007C117D /* Products */; 149 | projectDirPath = ""; 150 | projectRoot = ""; 151 | targets = ( 152 | 97C146ED1CF9000F007C117D /* Runner */, 153 | ); 154 | }; 155 | /* End PBXProject section */ 156 | 157 | /* Begin PBXResourcesBuildPhase section */ 158 | 97C146EC1CF9000F007C117D /* Resources */ = { 159 | isa = PBXResourcesBuildPhase; 160 | buildActionMask = 2147483647; 161 | files = ( 162 | 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */, 163 | 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */, 164 | 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */, 165 | 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */, 166 | ); 167 | runOnlyForDeploymentPostprocessing = 0; 168 | }; 169 | /* End PBXResourcesBuildPhase section */ 170 | 171 | /* Begin PBXShellScriptBuildPhase section */ 172 | 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = { 173 | isa = PBXShellScriptBuildPhase; 174 | buildActionMask = 2147483647; 175 | files = ( 176 | ); 177 | inputPaths = ( 178 | ); 179 | name = "Thin Binary"; 180 | outputPaths = ( 181 | ); 182 | runOnlyForDeploymentPostprocessing = 0; 183 | shellPath = /bin/sh; 184 | shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin"; 185 | }; 186 | 9740EEB61CF901F6004384FC /* Run Script */ = { 187 | isa = PBXShellScriptBuildPhase; 188 | buildActionMask = 2147483647; 189 | files = ( 190 | ); 191 | inputPaths = ( 192 | ); 193 | name = "Run Script"; 194 | outputPaths = ( 195 | ); 196 | runOnlyForDeploymentPostprocessing = 0; 197 | shellPath = /bin/sh; 198 | shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build"; 199 | }; 200 | /* End PBXShellScriptBuildPhase section */ 201 | 202 | /* Begin PBXSourcesBuildPhase section */ 203 | 97C146EA1CF9000F007C117D /* Sources */ = { 204 | isa = PBXSourcesBuildPhase; 205 | buildActionMask = 2147483647; 206 | files = ( 207 | 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */, 208 | 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */, 209 | ); 210 | runOnlyForDeploymentPostprocessing = 0; 211 | }; 212 | /* End PBXSourcesBuildPhase section */ 213 | 214 | /* Begin PBXVariantGroup section */ 215 | 97C146FA1CF9000F007C117D /* Main.storyboard */ = { 216 | isa = PBXVariantGroup; 217 | children = ( 218 | 97C146FB1CF9000F007C117D /* Base */, 219 | ); 220 | name = Main.storyboard; 221 | sourceTree = ""; 222 | }; 223 | 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */ = { 224 | isa = PBXVariantGroup; 225 | children = ( 226 | 97C147001CF9000F007C117D /* Base */, 227 | ); 228 | name = LaunchScreen.storyboard; 229 | sourceTree = ""; 230 | }; 231 | /* End PBXVariantGroup section */ 232 | 233 | /* Begin XCBuildConfiguration section */ 234 | 249021D3217E4FDB00AE95B9 /* Profile */ = { 235 | isa = XCBuildConfiguration; 236 | buildSettings = { 237 | ALWAYS_SEARCH_USER_PATHS = NO; 238 | CLANG_ANALYZER_NONNULL = YES; 239 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 240 | CLANG_CXX_LIBRARY = "libc++"; 241 | CLANG_ENABLE_MODULES = YES; 242 | CLANG_ENABLE_OBJC_ARC = YES; 243 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 244 | CLANG_WARN_BOOL_CONVERSION = YES; 245 | CLANG_WARN_COMMA = YES; 246 | CLANG_WARN_CONSTANT_CONVERSION = YES; 247 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 248 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 249 | CLANG_WARN_EMPTY_BODY = YES; 250 | CLANG_WARN_ENUM_CONVERSION = YES; 251 | CLANG_WARN_INFINITE_RECURSION = YES; 252 | CLANG_WARN_INT_CONVERSION = YES; 253 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 254 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 255 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 256 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 257 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 258 | CLANG_WARN_STRICT_PROTOTYPES = YES; 259 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 260 | CLANG_WARN_UNREACHABLE_CODE = YES; 261 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 262 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 263 | COPY_PHASE_STRIP = NO; 264 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 265 | ENABLE_NS_ASSERTIONS = NO; 266 | ENABLE_STRICT_OBJC_MSGSEND = YES; 267 | GCC_C_LANGUAGE_STANDARD = gnu99; 268 | GCC_NO_COMMON_BLOCKS = YES; 269 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 270 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 271 | GCC_WARN_UNDECLARED_SELECTOR = YES; 272 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 273 | GCC_WARN_UNUSED_FUNCTION = YES; 274 | GCC_WARN_UNUSED_VARIABLE = YES; 275 | IPHONEOS_DEPLOYMENT_TARGET = 9.0; 276 | MTL_ENABLE_DEBUG_INFO = NO; 277 | SDKROOT = iphoneos; 278 | SUPPORTED_PLATFORMS = iphoneos; 279 | TARGETED_DEVICE_FAMILY = "1,2"; 280 | VALIDATE_PRODUCT = YES; 281 | }; 282 | name = Profile; 283 | }; 284 | 249021D4217E4FDB00AE95B9 /* Profile */ = { 285 | isa = XCBuildConfiguration; 286 | baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; 287 | buildSettings = { 288 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 289 | CLANG_ENABLE_MODULES = YES; 290 | CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; 291 | ENABLE_BITCODE = NO; 292 | INFOPLIST_FILE = Runner/Info.plist; 293 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 294 | PRODUCT_BUNDLE_IDENTIFIER = com.example.marketplace; 295 | PRODUCT_NAME = "$(TARGET_NAME)"; 296 | SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; 297 | SWIFT_VERSION = 5.0; 298 | VERSIONING_SYSTEM = "apple-generic"; 299 | }; 300 | name = Profile; 301 | }; 302 | 97C147031CF9000F007C117D /* Debug */ = { 303 | isa = XCBuildConfiguration; 304 | buildSettings = { 305 | ALWAYS_SEARCH_USER_PATHS = NO; 306 | CLANG_ANALYZER_NONNULL = YES; 307 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 308 | CLANG_CXX_LIBRARY = "libc++"; 309 | CLANG_ENABLE_MODULES = YES; 310 | CLANG_ENABLE_OBJC_ARC = YES; 311 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 312 | CLANG_WARN_BOOL_CONVERSION = YES; 313 | CLANG_WARN_COMMA = YES; 314 | CLANG_WARN_CONSTANT_CONVERSION = YES; 315 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 316 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 317 | CLANG_WARN_EMPTY_BODY = YES; 318 | CLANG_WARN_ENUM_CONVERSION = YES; 319 | CLANG_WARN_INFINITE_RECURSION = YES; 320 | CLANG_WARN_INT_CONVERSION = YES; 321 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 322 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 323 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 324 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 325 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 326 | CLANG_WARN_STRICT_PROTOTYPES = YES; 327 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 328 | CLANG_WARN_UNREACHABLE_CODE = YES; 329 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 330 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 331 | COPY_PHASE_STRIP = NO; 332 | DEBUG_INFORMATION_FORMAT = dwarf; 333 | ENABLE_STRICT_OBJC_MSGSEND = YES; 334 | ENABLE_TESTABILITY = YES; 335 | GCC_C_LANGUAGE_STANDARD = gnu99; 336 | GCC_DYNAMIC_NO_PIC = NO; 337 | GCC_NO_COMMON_BLOCKS = YES; 338 | GCC_OPTIMIZATION_LEVEL = 0; 339 | GCC_PREPROCESSOR_DEFINITIONS = ( 340 | "DEBUG=1", 341 | "$(inherited)", 342 | ); 343 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 344 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 345 | GCC_WARN_UNDECLARED_SELECTOR = YES; 346 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 347 | GCC_WARN_UNUSED_FUNCTION = YES; 348 | GCC_WARN_UNUSED_VARIABLE = YES; 349 | IPHONEOS_DEPLOYMENT_TARGET = 9.0; 350 | MTL_ENABLE_DEBUG_INFO = YES; 351 | ONLY_ACTIVE_ARCH = YES; 352 | SDKROOT = iphoneos; 353 | TARGETED_DEVICE_FAMILY = "1,2"; 354 | }; 355 | name = Debug; 356 | }; 357 | 97C147041CF9000F007C117D /* Release */ = { 358 | isa = XCBuildConfiguration; 359 | buildSettings = { 360 | ALWAYS_SEARCH_USER_PATHS = NO; 361 | CLANG_ANALYZER_NONNULL = YES; 362 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 363 | CLANG_CXX_LIBRARY = "libc++"; 364 | CLANG_ENABLE_MODULES = YES; 365 | CLANG_ENABLE_OBJC_ARC = YES; 366 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 367 | CLANG_WARN_BOOL_CONVERSION = YES; 368 | CLANG_WARN_COMMA = YES; 369 | CLANG_WARN_CONSTANT_CONVERSION = YES; 370 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 371 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 372 | CLANG_WARN_EMPTY_BODY = YES; 373 | CLANG_WARN_ENUM_CONVERSION = YES; 374 | CLANG_WARN_INFINITE_RECURSION = YES; 375 | CLANG_WARN_INT_CONVERSION = YES; 376 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 377 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 378 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 379 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 380 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 381 | CLANG_WARN_STRICT_PROTOTYPES = YES; 382 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 383 | CLANG_WARN_UNREACHABLE_CODE = YES; 384 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 385 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 386 | COPY_PHASE_STRIP = NO; 387 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 388 | ENABLE_NS_ASSERTIONS = NO; 389 | ENABLE_STRICT_OBJC_MSGSEND = YES; 390 | GCC_C_LANGUAGE_STANDARD = gnu99; 391 | GCC_NO_COMMON_BLOCKS = YES; 392 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 393 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 394 | GCC_WARN_UNDECLARED_SELECTOR = YES; 395 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 396 | GCC_WARN_UNUSED_FUNCTION = YES; 397 | GCC_WARN_UNUSED_VARIABLE = YES; 398 | IPHONEOS_DEPLOYMENT_TARGET = 9.0; 399 | MTL_ENABLE_DEBUG_INFO = NO; 400 | SDKROOT = iphoneos; 401 | SUPPORTED_PLATFORMS = iphoneos; 402 | SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; 403 | TARGETED_DEVICE_FAMILY = "1,2"; 404 | VALIDATE_PRODUCT = YES; 405 | }; 406 | name = Release; 407 | }; 408 | 97C147061CF9000F007C117D /* Debug */ = { 409 | isa = XCBuildConfiguration; 410 | baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; 411 | buildSettings = { 412 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 413 | CLANG_ENABLE_MODULES = YES; 414 | CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; 415 | ENABLE_BITCODE = NO; 416 | INFOPLIST_FILE = Runner/Info.plist; 417 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 418 | PRODUCT_BUNDLE_IDENTIFIER = com.example.marketplace; 419 | PRODUCT_NAME = "$(TARGET_NAME)"; 420 | SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; 421 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 422 | SWIFT_VERSION = 5.0; 423 | VERSIONING_SYSTEM = "apple-generic"; 424 | }; 425 | name = Debug; 426 | }; 427 | 97C147071CF9000F007C117D /* Release */ = { 428 | isa = XCBuildConfiguration; 429 | baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; 430 | buildSettings = { 431 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 432 | CLANG_ENABLE_MODULES = YES; 433 | CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; 434 | ENABLE_BITCODE = NO; 435 | INFOPLIST_FILE = Runner/Info.plist; 436 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 437 | PRODUCT_BUNDLE_IDENTIFIER = com.example.marketplace; 438 | PRODUCT_NAME = "$(TARGET_NAME)"; 439 | SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; 440 | SWIFT_VERSION = 5.0; 441 | VERSIONING_SYSTEM = "apple-generic"; 442 | }; 443 | name = Release; 444 | }; 445 | /* End XCBuildConfiguration section */ 446 | 447 | /* Begin XCConfigurationList section */ 448 | 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */ = { 449 | isa = XCConfigurationList; 450 | buildConfigurations = ( 451 | 97C147031CF9000F007C117D /* Debug */, 452 | 97C147041CF9000F007C117D /* Release */, 453 | 249021D3217E4FDB00AE95B9 /* Profile */, 454 | ); 455 | defaultConfigurationIsVisible = 0; 456 | defaultConfigurationName = Release; 457 | }; 458 | 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */ = { 459 | isa = XCConfigurationList; 460 | buildConfigurations = ( 461 | 97C147061CF9000F007C117D /* Debug */, 462 | 97C147071CF9000F007C117D /* Release */, 463 | 249021D4217E4FDB00AE95B9 /* Profile */, 464 | ); 465 | defaultConfigurationIsVisible = 0; 466 | defaultConfigurationName = Release; 467 | }; 468 | /* End XCConfigurationList section */ 469 | }; 470 | rootObject = 97C146E61CF9000F007C117D /* Project object */; 471 | } 472 | --------------------------------------------------------------------------------