├── 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 | 
12 | 
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 |
--------------------------------------------------------------------------------