Repository: SinaSys/flutter_ecommerce_app
Branch: master
Commit: a71ea6c45e11
Files: 71
Total size: 105.4 KB
Directory structure:
gitextract_w8uwwxwu/
├── .github/
│ └── workflows/
│ └── main.yml
├── .gitignore
├── .metadata
├── LICENSE
├── README.md
├── analysis_options.yaml
├── android/
│ ├── .gitignore
│ ├── app/
│ │ ├── build.gradle
│ │ └── src/
│ │ ├── debug/
│ │ │ └── AndroidManifest.xml
│ │ ├── main/
│ │ │ ├── AndroidManifest.xml
│ │ │ ├── kotlin/
│ │ │ │ └── com/
│ │ │ │ └── sinasys/
│ │ │ │ └── e_commerce_flutter/
│ │ │ │ └── MainActivity.kt
│ │ │ └── res/
│ │ │ ├── drawable/
│ │ │ │ └── launch_background.xml
│ │ │ ├── drawable-v21/
│ │ │ │ └── launch_background.xml
│ │ │ ├── mipmap-anydpi-v26/
│ │ │ │ └── launcher_icon.xml
│ │ │ ├── values/
│ │ │ │ ├── colors.xml
│ │ │ │ └── styles.xml
│ │ │ └── values-night/
│ │ │ └── styles.xml
│ │ └── profile/
│ │ └── AndroidManifest.xml
│ ├── build.gradle
│ ├── gradle/
│ │ └── wrapper/
│ │ └── gradle-wrapper.properties
│ ├── gradle.properties
│ └── settings.gradle
├── ios/
│ ├── .gitignore
│ ├── Flutter/
│ │ ├── AppFrameworkInfo.plist
│ │ ├── Debug.xcconfig
│ │ └── Release.xcconfig
│ ├── Runner/
│ │ ├── AppDelegate.swift
│ │ ├── Assets.xcassets/
│ │ │ ├── AppIcon.appiconset/
│ │ │ │ └── Contents.json
│ │ │ └── LaunchImage.imageset/
│ │ │ ├── Contents.json
│ │ │ └── README.md
│ │ ├── Base.lproj/
│ │ │ ├── LaunchScreen.storyboard
│ │ │ └── Main.storyboard
│ │ ├── Info.plist
│ │ └── Runner-Bridging-Header.h
│ ├── Runner.xcodeproj/
│ │ ├── project.pbxproj
│ │ ├── project.xcworkspace/
│ │ │ ├── contents.xcworkspacedata
│ │ │ └── xcshareddata/
│ │ │ ├── IDEWorkspaceChecks.plist
│ │ │ └── WorkspaceSettings.xcsettings
│ │ └── xcshareddata/
│ │ └── xcschemes/
│ │ └── Runner.xcscheme
│ └── Runner.xcworkspace/
│ ├── contents.xcworkspacedata
│ └── xcshareddata/
│ ├── IDEWorkspaceChecks.plist
│ └── WorkspaceSettings.xcsettings
├── lib/
│ ├── core/
│ │ ├── app_color.dart
│ │ ├── app_data.dart
│ │ ├── app_theme.dart
│ │ └── extensions.dart
│ ├── main.dart
│ └── src/
│ ├── controller/
│ │ └── product_controller.dart
│ ├── model/
│ │ ├── bottom_nav_bar_item.dart
│ │ ├── categorical.dart
│ │ ├── numerical.dart
│ │ ├── product.dart
│ │ ├── product_category.dart
│ │ ├── product_size_type.dart
│ │ └── recommended_product.dart
│ └── view/
│ ├── animation/
│ │ ├── animated_switcher_wrapper.dart
│ │ ├── open_container_wrapper.dart
│ │ └── page_transition_switcher_wrapper.dart
│ ├── screen/
│ │ ├── cart_screen.dart
│ │ ├── favorite_screen.dart
│ │ ├── home_screen.dart
│ │ ├── product_detail_screen.dart
│ │ ├── product_list_screen.dart
│ │ └── profile_screen.dart
│ └── widget/
│ ├── carousel_slider.dart
│ ├── empty_cart.dart
│ ├── list_item_selector.dart
│ └── product_grid_view.dart
├── pubspec.yaml
└── web/
├── index.html
└── manifest.json
================================================
FILE CONTENTS
================================================
================================================
FILE: .github/workflows/main.yml
================================================
on:
push:
branches:
- master
name: "Build & Release"
jobs:
build:
name: Build & Release
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
- uses: actions/setup-java@v1
with:
java-version: '17.x'
- uses: subosito/flutter-action@v1
with:
flutter-version: '3.27.0'
- run: flutter pub get
- run: flutter analyze
- run: flutter build apk
# - name: Push to Releases
# uses: ncipollo/release-action@v1.12.0
# with:
# artifacts: "build/app/outputs/flutter-apk/app-release.apk"
# tag: v1.2.1
# token: ${{ secrets.TOKEN }}
================================================
FILE: .gitignore
================================================
# Miscellaneous
*.class
*.log
*.pyc
*.swp
.DS_Store
.atom/
.buildlog/
.history
.svn/
migrate_working_dir/
# IntelliJ related
*.iml
*.ipr
*.iws
.idea/
# The .vscode folder contains launch configuration and tasks you configure in
# VS Code which you may wish to be included in version control, so this line
# is commented out by default.
#.vscode/
# Flutter/Dart/Pub related
**/doc/api/
**/ios/Flutter/.last_build_id
.dart_tool/
.flutter-plugins
.flutter-plugins-dependencies
.packages
.pub-cache/
.pub/
/build/
# Web related
lib/generated_plugin_registrant.dart
# Symbolication related
app.*.symbols
# Obfuscation related
app.*.map.json
# Android Studio will place build artifacts here
/android/app/debug
/android/app/profile
/android/app/release
================================================
FILE: .metadata
================================================
# This file tracks properties of this Flutter project.
# Used by Flutter tool to assess capabilities and perform upgrades etc.
#
# This file should be version controlled.
version:
revision: adda8e93881d681680de2f7f33bfc021dac20c9d
channel: master
project_type: app
# Tracks metadata for the flutter migrate command
migration:
platforms:
- platform: root
create_revision: adda8e93881d681680de2f7f33bfc021dac20c9d
base_revision: adda8e93881d681680de2f7f33bfc021dac20c9d
- platform: android
create_revision: adda8e93881d681680de2f7f33bfc021dac20c9d
base_revision: adda8e93881d681680de2f7f33bfc021dac20c9d
- platform: ios
create_revision: adda8e93881d681680de2f7f33bfc021dac20c9d
base_revision: adda8e93881d681680de2f7f33bfc021dac20c9d
- platform: web
create_revision: adda8e93881d681680de2f7f33bfc021dac20c9d
base_revision: adda8e93881d681680de2f7f33bfc021dac20c9d
# User provided section
# List of Local paths (relative to this file) that should be
# ignored by the migrate tool.
#
# Files that are not part of the templates will be ignored by default.
unmanaged_files:
- 'lib/main.dart'
- 'ios/Runner.xcodeproj/project.pbxproj'
================================================
FILE: LICENSE
================================================
BSD 2-Clause License
Copyright (c) 2022, SinaSys
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
================================================
FILE: README.md
================================================
## flutter_ecommerce_app
E-Commerce app is a design implementation of [E-commerce App](https://dribbble.com/shots/15550702-E-commerce-Mobile-App) designed by [Billah](https://dribbble.com/designermasum)

## Screenshots
Preview | Home screen | Product Detail Screen | Cart Screen
:-------------------------:|:-------------------------:|:-------------------------:|:-------------------------:
|||
## Directory Structure
```
📂lib
│───main.dart
│───📂core
| │──app_data.dart
| │──app_theme.dart
| │──app_color.dart
| └──extensions.dart
└───📂src
│────📂model
│ │──product.dart
| │──product_category.dart
| │──product_size_type.dart
| │──recommended_product.dart
| │──categorical.dart
| │──numerical.dart
| └──bottom_nav_bar_item.dart
└────📂view
| │───📂screen
| | |──home_screen.dart
| | |──product_list_screen.dart
| | |──product_detail_screen.dart
| | |──favorite_screen.dart
| | |──cart_screen.dart
| | └──profile_screen.dart
| │───📂widget
| | |──carousel_slider.dart
| | |──product_grid_view.dart
| | |──list_item_selector.dart
| | └──empty_cart.dart
| └───📂animation
| |──animated_switcher_wrapper.dart
| |──open_container_wrapper.dart
| └──page_transition_switcher_wrapper.dart
└────📂controller
└──product_controller.dart
```
## Dependencies
Package Name |
:-------------------------|
|[GetX](https://pub.dev/packages/get)
|[stylish_bottom_bar](https://pub.dev/packages/stylish_bottom_bar)
|[smooth_page_indicator](https://pub.dev/packages/smooth_page_indicator)
|[flutter_rating_bar](https://pub.dev/packages/flutter_rating_bar)
|[font_awesome_flutter](https://pub.dev/packages/font_awesome_flutter)
|[animations](https://pub.dev/packages/animations)
|[flutter_launcher_icons](https://pub.dev/packages/flutter_launcher_icons)
## Created & Maintained By
[SinaSys](https://github.com/SinaSys)
## Contributors
• [mufarrah](https://github.com/mufarrah)
## Other flutter projects
Project Name |Stars
:-------------------------|-------------------------
[Go rest app](https://github.com/SinaSys/flutter_go_rest_app)|
[Japanese restaurant app](https://github.com/SinaSys/flutter_japanese_restaurant_app)| 
|[Office furniture store app](https://github.com/SinaSys/flutter_office_furniture_store_app) |
================================================
FILE: analysis_options.yaml
================================================
# This file configures the analyzer, which statically analyzes Dart code to
# check for errors, warnings, and lints.
#
# The issues identified by the analyzer are surfaced in the UI of Dart-enabled
# IDEs (https://dart.dev/tools#ides-and-editors). The analyzer can also be
# invoked from the command line by running `flutter analyze`.
# The following line activates a set of recommended lints for Flutter apps,
# packages, and plugins designed to encourage good coding practices.
include: package:flutter_lints/flutter.yaml
linter:
# The lint rules applied to this project can be customized in the
# section below to disable rules from the `package:flutter_lints/flutter.yaml`
# included above or to enable additional rules. A list of all available lints
# and their documentation is published at
# https://dart-lang.github.io/linter/lints/index.html.
#
# Instead of disabling a lint rule for the entire project in the
# section below, it can also be suppressed for a single line of code
# or a specific dart file by using the `// ignore: name_of_lint` and
# `// ignore_for_file: name_of_lint` syntax on the line or in the file
# producing the lint.
rules:
# avoid_print: false # Uncomment to disable the `avoid_print` rule
# prefer_single_quotes: true # Uncomment to enable the `prefer_single_quotes` rule
# Additional information about this file can be found at
# https://dart.dev/guides/language/analysis-options
================================================
FILE: android/.gitignore
================================================
gradle-wrapper.jar
/.gradle
/captures/
/gradlew
/gradlew.bat
/local.properties
GeneratedPluginRegistrant.java
# Remember to never publicly share your keystore.
# See https://flutter.dev/docs/deployment/android#reference-the-keystore-from-the-app
key.properties
**/*.keystore
**/*.jks
================================================
FILE: android/app/build.gradle
================================================
def localProperties = new Properties()
def localPropertiesFile = rootProject.file('local.properties')
if (localPropertiesFile.exists()) {
localPropertiesFile.withReader('UTF-8') { reader ->
localProperties.load(reader)
}
}
def flutterRoot = localProperties.getProperty('flutter.sdk')
if (flutterRoot == null) {
throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.")
}
def flutterVersionCode = localProperties.getProperty('flutter.versionCode')
if (flutterVersionCode == null) {
flutterVersionCode = '1'
}
def flutterVersionName = localProperties.getProperty('flutter.versionName')
if (flutterVersionName == null) {
flutterVersionName = '1.0'
}
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"
android {
compileSdkVersion flutter.compileSdkVersion
ndkVersion "23.1.7779620"
namespace = "com.sinasys.e_commerce_flutter"
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
kotlinOptions {
jvmTarget = '1.8'
}
sourceSets {
main.java.srcDirs += 'src/main/kotlin'
}
defaultConfig {
// TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
applicationId "com.sinasys.e_commerce_flutter"
// You can update the following values to match your application needs.
// For more information, see: https://docs.flutter.dev/deployment/android#reviewing-the-build-configuration.
minSdkVersion flutter.minSdkVersion
targetSdkVersion flutter.targetSdkVersion
versionCode flutterVersionCode.toInteger()
versionName flutterVersionName
}
buildTypes {
release {
// TODO: Add your own signing config for the release build.
// Signing with the debug keys for now, so `flutter run --release` works.
signingConfig signingConfigs.debug
}
}
}
flutter {
source '../..'
}
dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
}
================================================
FILE: android/app/src/debug/AndroidManifest.xml
================================================
================================================
FILE: android/app/src/main/AndroidManifest.xml
================================================
================================================
FILE: android/app/src/main/kotlin/com/sinasys/e_commerce_flutter/MainActivity.kt
================================================
package com.sinasys.e_commerce_flutter
import io.flutter.embedding.android.FlutterActivity
class MainActivity: FlutterActivity() {
}
================================================
FILE: android/app/src/main/res/drawable/launch_background.xml
================================================
================================================
FILE: android/app/src/main/res/drawable-v21/launch_background.xml
================================================
================================================
FILE: android/app/src/main/res/mipmap-anydpi-v26/launcher_icon.xml
================================================
================================================
FILE: android/app/src/main/res/values/colors.xml
================================================
#ffffff
================================================
FILE: android/app/src/main/res/values/styles.xml
================================================
================================================
FILE: android/app/src/main/res/values-night/styles.xml
================================================
================================================
FILE: android/app/src/profile/AndroidManifest.xml
================================================
================================================
FILE: android/build.gradle
================================================
buildscript {
ext.kotlin_version = '1.7.21'
repositories {
google()
mavenCentral()
}
dependencies {
classpath 'com.android.tools.build:gradle:8.1.4'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
}
}
allprojects {
repositories {
google()
mavenCentral()
}
}
rootProject.buildDir = '../build'
subprojects {
project.buildDir = "${rootProject.buildDir}/${project.name}"
}
subprojects {
project.evaluationDependsOn(':app')
}
tasks.register("clean", Delete) {
delete rootProject.buildDir
}
================================================
FILE: android/gradle/wrapper/gradle-wrapper.properties
================================================
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.0-all.zip
================================================
FILE: android/gradle.properties
================================================
org.gradle.jvmargs=-Xmx1536M
android.useAndroidX=true
android.enableJetifier=true
================================================
FILE: android/settings.gradle
================================================
include ':app'
def localPropertiesFile = new File(rootProject.projectDir, "local.properties")
def properties = new Properties()
assert localPropertiesFile.exists()
localPropertiesFile.withReader("UTF-8") { reader -> properties.load(reader) }
def flutterSdkPath = properties.getProperty("flutter.sdk")
assert flutterSdkPath != null, "flutter.sdk not set in local.properties"
apply from: "$flutterSdkPath/packages/flutter_tools/gradle/app_plugin_loader.gradle"
================================================
FILE: ios/.gitignore
================================================
**/dgph
*.mode1v3
*.mode2v3
*.moved-aside
*.pbxuser
*.perspectivev3
**/*sync/
.sconsign.dblite
.tags*
**/.vagrant/
**/DerivedData/
Icon?
**/Pods/
**/.symlinks/
profile
xcuserdata
**/.generated/
Flutter/App.framework
Flutter/Flutter.framework
Flutter/Flutter.podspec
Flutter/Generated.xcconfig
Flutter/ephemeral/
Flutter/app.flx
Flutter/app.zip
Flutter/flutter_assets/
Flutter/flutter_export_environment.sh
ServiceDefinitions.json
Runner/GeneratedPluginRegistrant.*
# Exceptions to above rules.
!default.mode1v3
!default.mode2v3
!default.pbxuser
!default.perspectivev3
================================================
FILE: ios/Flutter/AppFrameworkInfo.plist
================================================
CFBundleDevelopmentRegion
en
CFBundleExecutable
App
CFBundleIdentifier
io.flutter.flutter.app
CFBundleInfoDictionaryVersion
6.0
CFBundleName
App
CFBundlePackageType
FMWK
CFBundleShortVersionString
1.0
CFBundleSignature
????
CFBundleVersion
1.0
MinimumOSVersion
9.0
================================================
FILE: ios/Flutter/Debug.xcconfig
================================================
#include "Generated.xcconfig"
================================================
FILE: ios/Flutter/Release.xcconfig
================================================
#include "Generated.xcconfig"
================================================
FILE: ios/Runner/AppDelegate.swift
================================================
import UIKit
import Flutter
@UIApplicationMain
@objc class AppDelegate: FlutterAppDelegate {
override func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
) -> Bool {
GeneratedPluginRegistrant.register(with: self)
return super.application(application, didFinishLaunchingWithOptions: launchOptions)
}
}
================================================
FILE: ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json
================================================
{
"images" : [
{
"size" : "20x20",
"idiom" : "iphone",
"filename" : "Icon-App-20x20@2x.png",
"scale" : "2x"
},
{
"size" : "20x20",
"idiom" : "iphone",
"filename" : "Icon-App-20x20@3x.png",
"scale" : "3x"
},
{
"size" : "29x29",
"idiom" : "iphone",
"filename" : "Icon-App-29x29@1x.png",
"scale" : "1x"
},
{
"size" : "29x29",
"idiom" : "iphone",
"filename" : "Icon-App-29x29@2x.png",
"scale" : "2x"
},
{
"size" : "29x29",
"idiom" : "iphone",
"filename" : "Icon-App-29x29@3x.png",
"scale" : "3x"
},
{
"size" : "40x40",
"idiom" : "iphone",
"filename" : "Icon-App-40x40@2x.png",
"scale" : "2x"
},
{
"size" : "40x40",
"idiom" : "iphone",
"filename" : "Icon-App-40x40@3x.png",
"scale" : "3x"
},
{
"size" : "60x60",
"idiom" : "iphone",
"filename" : "Icon-App-60x60@2x.png",
"scale" : "2x"
},
{
"size" : "60x60",
"idiom" : "iphone",
"filename" : "Icon-App-60x60@3x.png",
"scale" : "3x"
},
{
"size" : "20x20",
"idiom" : "ipad",
"filename" : "Icon-App-20x20@1x.png",
"scale" : "1x"
},
{
"size" : "20x20",
"idiom" : "ipad",
"filename" : "Icon-App-20x20@2x.png",
"scale" : "2x"
},
{
"size" : "29x29",
"idiom" : "ipad",
"filename" : "Icon-App-29x29@1x.png",
"scale" : "1x"
},
{
"size" : "29x29",
"idiom" : "ipad",
"filename" : "Icon-App-29x29@2x.png",
"scale" : "2x"
},
{
"size" : "40x40",
"idiom" : "ipad",
"filename" : "Icon-App-40x40@1x.png",
"scale" : "1x"
},
{
"size" : "40x40",
"idiom" : "ipad",
"filename" : "Icon-App-40x40@2x.png",
"scale" : "2x"
},
{
"size" : "76x76",
"idiom" : "ipad",
"filename" : "Icon-App-76x76@1x.png",
"scale" : "1x"
},
{
"size" : "76x76",
"idiom" : "ipad",
"filename" : "Icon-App-76x76@2x.png",
"scale" : "2x"
},
{
"size" : "83.5x83.5",
"idiom" : "ipad",
"filename" : "Icon-App-83.5x83.5@2x.png",
"scale" : "2x"
},
{
"size" : "1024x1024",
"idiom" : "ios-marketing",
"filename" : "Icon-App-1024x1024@1x.png",
"scale" : "1x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}
================================================
FILE: ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json
================================================
{
"images" : [
{
"idiom" : "universal",
"filename" : "LaunchImage.png",
"scale" : "1x"
},
{
"idiom" : "universal",
"filename" : "LaunchImage@2x.png",
"scale" : "2x"
},
{
"idiom" : "universal",
"filename" : "LaunchImage@3x.png",
"scale" : "3x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}
================================================
FILE: ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md
================================================
# Launch Screen Assets
You can customize the launch screen with your own desired assets by replacing the image files in this directory.
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.
================================================
FILE: ios/Runner/Base.lproj/LaunchScreen.storyboard
================================================
================================================
FILE: ios/Runner/Base.lproj/Main.storyboard
================================================
================================================
FILE: ios/Runner/Info.plist
================================================
CFBundleDevelopmentRegion
$(DEVELOPMENT_LANGUAGE)
CFBundleDisplayName
E Commerce Flutter
CFBundleExecutable
$(EXECUTABLE_NAME)
CFBundleIdentifier
$(PRODUCT_BUNDLE_IDENTIFIER)
CFBundleInfoDictionaryVersion
6.0
CFBundleName
e_commerce_flutter
CFBundlePackageType
APPL
CFBundleShortVersionString
$(FLUTTER_BUILD_NAME)
CFBundleSignature
????
CFBundleVersion
$(FLUTTER_BUILD_NUMBER)
LSRequiresIPhoneOS
UILaunchStoryboardName
LaunchScreen
UIMainStoryboardFile
Main
UISupportedInterfaceOrientations
UIInterfaceOrientationPortrait
UIInterfaceOrientationLandscapeLeft
UIInterfaceOrientationLandscapeRight
UISupportedInterfaceOrientations~ipad
UIInterfaceOrientationPortrait
UIInterfaceOrientationPortraitUpsideDown
UIInterfaceOrientationLandscapeLeft
UIInterfaceOrientationLandscapeRight
UIViewControllerBasedStatusBarAppearance
CADisableMinimumFrameDurationOnPhone
UIApplicationSupportsIndirectInputEvents
================================================
FILE: ios/Runner/Runner-Bridging-Header.h
================================================
#import "GeneratedPluginRegistrant.h"
================================================
FILE: ios/Runner.xcodeproj/project.pbxproj
================================================
// !$*UTF8*$!
{
archiveVersion = 1;
classes = {
};
objectVersion = 50;
objects = {
/* Begin PBXBuildFile section */
1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; };
3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; };
74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; };
97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; };
97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; };
97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; };
/* End PBXBuildFile section */
/* Begin PBXCopyFilesBuildPhase section */
9705A1C41CF9048500538489 /* Embed Frameworks */ = {
isa = PBXCopyFilesBuildPhase;
buildActionMask = 2147483647;
dstPath = "";
dstSubfolderSpec = 10;
files = (
);
name = "Embed Frameworks";
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXCopyFilesBuildPhase section */
/* Begin PBXFileReference section */
1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = ""; };
1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = ""; };
3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; };
74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = ""; };
74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; };
7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; };
9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = ""; };
9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = ""; };
97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; };
97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; };
97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; };
97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; };
97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
97C146EB1CF9000F007C117D /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
9740EEB11CF90186004384FC /* Flutter */ = {
isa = PBXGroup;
children = (
3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */,
9740EEB21CF90195004384FC /* Debug.xcconfig */,
7AFA3C8E1D35360C0083082E /* Release.xcconfig */,
9740EEB31CF90195004384FC /* Generated.xcconfig */,
);
name = Flutter;
sourceTree = "";
};
97C146E51CF9000F007C117D = {
isa = PBXGroup;
children = (
9740EEB11CF90186004384FC /* Flutter */,
97C146F01CF9000F007C117D /* Runner */,
97C146EF1CF9000F007C117D /* Products */,
);
sourceTree = "";
};
97C146EF1CF9000F007C117D /* Products */ = {
isa = PBXGroup;
children = (
97C146EE1CF9000F007C117D /* Runner.app */,
);
name = Products;
sourceTree = "";
};
97C146F01CF9000F007C117D /* Runner */ = {
isa = PBXGroup;
children = (
97C146FA1CF9000F007C117D /* Main.storyboard */,
97C146FD1CF9000F007C117D /* Assets.xcassets */,
97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */,
97C147021CF9000F007C117D /* Info.plist */,
1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */,
1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */,
74858FAE1ED2DC5600515810 /* AppDelegate.swift */,
74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */,
);
path = Runner;
sourceTree = "";
};
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
97C146ED1CF9000F007C117D /* Runner */ = {
isa = PBXNativeTarget;
buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */;
buildPhases = (
9740EEB61CF901F6004384FC /* Run Script */,
97C146EA1CF9000F007C117D /* Sources */,
97C146EB1CF9000F007C117D /* Frameworks */,
97C146EC1CF9000F007C117D /* Resources */,
9705A1C41CF9048500538489 /* Embed Frameworks */,
3B06AD1E1E4923F5004D2608 /* Thin Binary */,
);
buildRules = (
);
dependencies = (
);
name = Runner;
productName = Runner;
productReference = 97C146EE1CF9000F007C117D /* Runner.app */;
productType = "com.apple.product-type.application";
};
/* End PBXNativeTarget section */
/* Begin PBXProject section */
97C146E61CF9000F007C117D /* Project object */ = {
isa = PBXProject;
attributes = {
LastUpgradeCheck = 1300;
ORGANIZATIONNAME = "";
TargetAttributes = {
97C146ED1CF9000F007C117D = {
CreatedOnToolsVersion = 7.3.1;
LastSwiftMigration = 1100;
};
};
};
buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */;
compatibilityVersion = "Xcode 9.3";
developmentRegion = en;
hasScannedForEncodings = 0;
knownRegions = (
en,
Base,
);
mainGroup = 97C146E51CF9000F007C117D;
productRefGroup = 97C146EF1CF9000F007C117D /* Products */;
projectDirPath = "";
projectRoot = "";
targets = (
97C146ED1CF9000F007C117D /* Runner */,
);
};
/* End PBXProject section */
/* Begin PBXResourcesBuildPhase section */
97C146EC1CF9000F007C117D /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */,
3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */,
97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */,
97C146FC1CF9000F007C117D /* Main.storyboard in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXResourcesBuildPhase section */
/* Begin PBXShellScriptBuildPhase section */
3B06AD1E1E4923F5004D2608 /* Thin Binary */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
);
name = "Thin Binary";
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin";
};
9740EEB61CF901F6004384FC /* Run Script */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
);
name = "Run Script";
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build";
};
/* End PBXShellScriptBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
97C146EA1CF9000F007C117D /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */,
1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXSourcesBuildPhase section */
/* Begin PBXVariantGroup section */
97C146FA1CF9000F007C117D /* Main.storyboard */ = {
isa = PBXVariantGroup;
children = (
97C146FB1CF9000F007C117D /* Base */,
);
name = Main.storyboard;
sourceTree = "";
};
97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */ = {
isa = PBXVariantGroup;
children = (
97C147001CF9000F007C117D /* Base */,
);
name = LaunchScreen.storyboard;
sourceTree = "";
};
/* End PBXVariantGroup section */
/* Begin XCBuildConfiguration section */
249021D3217E4FDB00AE95B9 /* Profile */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_NONNULL = YES;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
ENABLE_NS_ASSERTIONS = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_NO_COMMON_BLOCKS = YES;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = iphoneos;
SUPPORTED_PLATFORMS = iphoneos;
TARGETED_DEVICE_FAMILY = "1,2";
VALIDATE_PRODUCT = YES;
};
name = Profile;
};
249021D4217E4FDB00AE95B9 /* Profile */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES;
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
ENABLE_BITCODE = NO;
INFOPLIST_FILE = Runner/Info.plist;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
);
PRODUCT_BUNDLE_IDENTIFIER = com.sinasys.eCommerceFlutter;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
SWIFT_VERSION = 5.0;
VERSIONING_SYSTEM = "apple-generic";
};
name = Profile;
};
97C147031CF9000F007C117D /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_NONNULL = YES;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = dwarf;
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_TESTABILITY = YES;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_DYNAMIC_NO_PIC = NO;
GCC_NO_COMMON_BLOCKS = YES;
GCC_OPTIMIZATION_LEVEL = 0;
GCC_PREPROCESSOR_DEFINITIONS = (
"DEBUG=1",
"$(inherited)",
);
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
MTL_ENABLE_DEBUG_INFO = YES;
ONLY_ACTIVE_ARCH = YES;
SDKROOT = iphoneos;
TARGETED_DEVICE_FAMILY = "1,2";
};
name = Debug;
};
97C147041CF9000F007C117D /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_NONNULL = YES;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
ENABLE_NS_ASSERTIONS = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_NO_COMMON_BLOCKS = YES;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = iphoneos;
SUPPORTED_PLATFORMS = iphoneos;
SWIFT_COMPILATION_MODE = wholemodule;
SWIFT_OPTIMIZATION_LEVEL = "-O";
TARGETED_DEVICE_FAMILY = "1,2";
VALIDATE_PRODUCT = YES;
};
name = Release;
};
97C147061CF9000F007C117D /* Debug */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES;
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
ENABLE_BITCODE = NO;
INFOPLIST_FILE = Runner/Info.plist;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
);
PRODUCT_BUNDLE_IDENTIFIER = com.sinasys.eCommerceFlutter;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_VERSION = 5.0;
VERSIONING_SYSTEM = "apple-generic";
};
name = Debug;
};
97C147071CF9000F007C117D /* Release */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES;
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
ENABLE_BITCODE = NO;
INFOPLIST_FILE = Runner/Info.plist;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
);
PRODUCT_BUNDLE_IDENTIFIER = com.sinasys.eCommerceFlutter;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
SWIFT_VERSION = 5.0;
VERSIONING_SYSTEM = "apple-generic";
};
name = Release;
};
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */ = {
isa = XCConfigurationList;
buildConfigurations = (
97C147031CF9000F007C117D /* Debug */,
97C147041CF9000F007C117D /* Release */,
249021D3217E4FDB00AE95B9 /* Profile */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */ = {
isa = XCConfigurationList;
buildConfigurations = (
97C147061CF9000F007C117D /* Debug */,
97C147071CF9000F007C117D /* Release */,
249021D4217E4FDB00AE95B9 /* Profile */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
/* End XCConfigurationList section */
};
rootObject = 97C146E61CF9000F007C117D /* Project object */;
}
================================================
FILE: ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata
================================================
================================================
FILE: ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
================================================
IDEDidComputeMac32BitWarning
================================================
FILE: ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings
================================================
PreviewsEnabled
================================================
FILE: ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme
================================================
================================================
FILE: ios/Runner.xcworkspace/contents.xcworkspacedata
================================================
================================================
FILE: ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
================================================
IDEDidComputeMac32BitWarning
================================================
FILE: ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings
================================================
PreviewsEnabled
================================================
FILE: lib/core/app_color.dart
================================================
import 'package:flutter/material.dart' show Color;
class AppColor {
const AppColor._();
static const darkOrange = Color(0xFFEC6813);
static const lightOrange = Color(0xFFf8b89a);
static const darkGrey = Color(0xFFA6A3A0);
static const lightGrey = Color(0xFFE5E6E8);
}
================================================
FILE: lib/core/app_data.dart
================================================
import 'package:flutter/material.dart';
import 'package:e_commerce_flutter/src/model/product.dart';
import 'package:e_commerce_flutter/src/model/numerical.dart';
import 'package:e_commerce_flutter/src/model/categorical.dart';
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
import 'package:e_commerce_flutter/src/model/product_category.dart';
import 'package:e_commerce_flutter/src/model/product_size_type.dart';
import 'package:e_commerce_flutter/src/model/recommended_product.dart';
import 'package:e_commerce_flutter/src/model/bottom_nav_bar_item.dart';
class AppData {
const AppData._();
static const String dummyText = 'Lorem Ipsum is simply dummy text of the printing and typesetting'
' industry. Lorem Ipsum has been the industry\'s standard dummy text'
' ever since the 1500s, when an unknown printer took a galley of type'
' and scrambled it to make a type specimen book.';
static List products = [
Product(
name: 'Samsung Galaxy A53 5G',
price: 460,
isAvailable: true,
off: 300,
quantity: 0,
images: [
'assets/images/a53_1.png',
'assets/images/a53_2.png',
'assets/images/a53_3.png',
],
isFavorite: true,
rating: 1,
type: ProductType.mobile,
),
Product(
name: 'Samsung Galaxy Tab S7 FE',
price: 380,
isAvailable: false,
off: 220,
quantity: 0,
images: [
'assets/images/tab_s7_fe_1.png',
'assets/images/tab_s7_fe_2.png',
'assets/images/tab_s7_fe_3.png',
],
isFavorite: false,
rating: 4,
type: ProductType.tablet,
),
Product(
name: 'Samsung Galaxy Tab S8+',
price: 650,
isAvailable: true,
off: null,
quantity: 0,
images: [
'assets/images/tab_s8_1.png',
'assets/images/tab_s8_2.png',
'assets/images/tab_s8_3.png',
],
isFavorite: false,
rating: 3,
type: ProductType.tablet,
),
Product(
name: 'Samsung Galaxy Watch 4',
price: 229,
isAvailable: true,
off: 200,
quantity: 0,
images: [
'assets/images/galaxy_watch_4_1.png',
'assets/images/galaxy_watch_4_2.png',
'assets/images/galaxy_watch_4_3.png',
],
isFavorite: false,
rating: 5,
sizes: ProductSizeType(
categorical: [
Categorical(CategoricalType.small, true),
Categorical(CategoricalType.medium, false),
Categorical(CategoricalType.large, false),
],
),
type: ProductType.watch,
),
Product(
name: 'Apple Watch 7',
price: 330,
isAvailable: true,
off: null,
quantity: 0,
images: [
'assets/images/apple_watch_series_7_1.png',
'assets/images/apple_watch_series_7_2.png',
'assets/images/apple_watch_series_7_3.png',
],
isFavorite: false,
rating: 4,
sizes: ProductSizeType(
numerical: [
Numerical('41', true),
Numerical('45', false),
],
),
type: ProductType.watch,
),
Product(
name: 'Beats studio 3',
price: 230,
isAvailable: true,
off: null,
quantity: 0,
images: [
'assets/images/beats_studio_3-1.png',
'assets/images/beats_studio_3-2.png',
'assets/images/beats_studio_3-3.png',
'assets/images/beats_studio_3-4.png',
],
isFavorite: false,
rating: 2,
type: ProductType.headphone,
),
Product(
name: 'Samsung Q60 A',
price: 497,
isAvailable: true,
off: null,
quantity: 0,
images: [
'assets/images/samsung_q_60_a_1.png',
'assets/images/samsung_q_60_a_2.png',
],
isFavorite: false,
rating: 3,
sizes: ProductSizeType(
numerical: [
Numerical('43', true),
Numerical('50', false),
Numerical('55', false),
],
),
type: ProductType.tv,
),
Product(
name: 'Sony x 80 J',
price: 498,
isAvailable: true,
off: null,
quantity: 0,
images: [
'assets/images/sony_x_80_j_1.png',
'assets/images/sony_x_80_j_2.png',
],
isFavorite: false,
sizes: ProductSizeType(
numerical: [
Numerical('50', true),
Numerical('65', false),
Numerical('85', false),
],
),
rating: 2,
type: ProductType.tv,
),
];
static List categories = [
ProductCategory(
type: ProductType.all,
icon: Icons.all_inclusive,
),
ProductCategory(
type: ProductType.mobile,
icon: FontAwesomeIcons.mobileScreenButton,
),
ProductCategory(
type: ProductType.watch,
icon: Icons.watch,
),
ProductCategory(
type: ProductType.tablet,
icon: FontAwesomeIcons.tablet,
),
ProductCategory(
type: ProductType.headphone,
icon: Icons.headphones,
),
ProductCategory(
type: ProductType.tv,
icon: Icons.tv,
),
];
static List randomColors = [
const Color(0xFFFCE4EC),
const Color(0xFFF3E5F5),
const Color(0xFFEDE7F6),
const Color(0xFFE3F2FD),
const Color(0xFFE0F2F1),
const Color(0xFFF1F8E9),
const Color(0xFFFFF8E1),
const Color(0xFFECEFF1),
];
static const Color lightOrangeColor = Color(0xFFEC6813);
static List bottomNavBarItems = [
const BottomNavBarItem(
"Home",
Icon(Icons.home),
),
const BottomNavBarItem(
"Favorite",
Icon(Icons.favorite),
),
const BottomNavBarItem(
"Cart",
Icon(Icons.shopping_cart),
),
const BottomNavBarItem(
"Profile",
Icon(Icons.person),
),
];
static List recommendedProducts = [
RecommendedProduct(
cardBackgroundColor: const Color(0xFFEC6813),
),
RecommendedProduct(
cardBackgroundColor: const Color(0xFF3081E1),
buttonBackgroundColor: const Color(0xFF9C46FF),
buttonTextColor: Colors.white,
),
];
}
================================================
FILE: lib/core/app_theme.dart
================================================
import 'package:flutter/material.dart';
class AppTheme {
const AppTheme._();
static ThemeData lightAppTheme = ThemeData(
elevatedButtonTheme: ElevatedButtonThemeData(
style: ElevatedButton.styleFrom(
padding: const EdgeInsets.all(12),
backgroundColor: const Color(0xFFf16b26),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(12),
),
),
),
textButtonTheme: TextButtonThemeData(
style: TextButton.styleFrom(foregroundColor: Colors.deepOrange),
),
iconTheme: const IconThemeData(color: Color(0xFFA6A3A0)),
textTheme: const TextTheme(
displayLarge: TextStyle(
fontSize: 20,
fontWeight: FontWeight.bold,
color: Colors.black,
),
displayMedium: TextStyle(
fontSize: 19,
fontWeight: FontWeight.w500,
color: Colors.black,
),
displaySmall: TextStyle(
fontSize: 18,
fontWeight: FontWeight.w500,
color: Colors.black,
),
headlineMedium: TextStyle(
fontSize: 16,
fontWeight: FontWeight.w500,
color: Colors.black,
),
headlineSmall: TextStyle(fontSize: 15, color: Colors.grey),
titleLarge: TextStyle(fontSize: 12),
),
appBarTheme: const AppBarTheme(
backgroundColor: Colors.transparent,
elevation: 0,
centerTitle: true,
),
);
}
================================================
FILE: lib/core/extensions.dart
================================================
import 'dart:math' show Random;
import 'package:flutter/material.dart' show Color;
import 'package:e_commerce_flutter/core/app_data.dart';
extension ColorExtension on Color {
static Color get randomColor {
Random random = Random();
int randNumber = random.nextInt(AppData.randomColors.length);
return AppData.randomColors[randNumber];
}
}
extension IterableExtension on Iterable {
Iterable mapWithIndex(E Function(int index, T value) f) {
return Iterable.generate(length).map((i) => f(i, elementAt(i)));
}
}
extension StringExtension on String {
String get nextLine {
if (length < 15) {
return this;
} else {
return "${substring(0, 15)} \n${substring(15, length)}";
}
}
}
================================================
FILE: lib/main.dart
================================================
import 'package:flutter/material.dart';
import 'dart:ui' show PointerDeviceKind;
import 'package:e_commerce_flutter/core/app_theme.dart';
import 'package:e_commerce_flutter/src/view/screen/home_screen.dart';
void main() => runApp(const MyApp());
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
scrollBehavior: const MaterialScrollBehavior().copyWith(
dragDevices: {
PointerDeviceKind.mouse,
PointerDeviceKind.touch,
},
),
debugShowCheckedModeBanner: false,
home: const HomeScreen(),
theme: AppTheme.lightAppTheme,
);
}
}
================================================
FILE: lib/src/controller/product_controller.dart
================================================
import 'package:get/get_rx/src/rx_types/rx_types.dart';
import 'package:e_commerce_flutter/core/app_data.dart';
import 'package:e_commerce_flutter/src/model/product.dart';
import 'package:e_commerce_flutter/src/model/numerical.dart';
import 'package:get/get_state_manager/get_state_manager.dart';
import 'package:e_commerce_flutter/src/model/product_category.dart';
import 'package:e_commerce_flutter/src/model/product_size_type.dart';
class ProductController extends GetxController {
List allProducts = AppData.products;
RxList filteredProducts = AppData.products.obs;
RxList cartProducts = [].obs;
RxList categories = AppData.categories.obs;
RxInt totalPrice = 0.obs;
void filterItemsByCategory(int index) {
for (ProductCategory element in categories) {
element.isSelected = false;
}
categories[index].isSelected = true;
if (categories[index].type == ProductType.all) {
filteredProducts.assignAll(allProducts);
} else {
filteredProducts.assignAll(allProducts.where((item) {
return item.type == categories[index].type;
}).toList());
}
update();
}
void isFavorite(int index) {
filteredProducts[index].isFavorite = !filteredProducts[index].isFavorite;
update();
}
void addToCart(Product product) {
product.quantity++;
cartProducts.add(product);
cartProducts.assignAll(cartProducts);
calculateTotalPrice();
}
void increaseItemQuantity(Product product) {
product.quantity++;
calculateTotalPrice();
update();
}
void decreaseItemQuantity(Product product) {
product.quantity--;
calculateTotalPrice();
update();
}
bool isPriceOff(Product product) => product.off != null;
bool get isEmptyCart => cartProducts.isEmpty;
bool isNominal(Product product) => product.sizes?.numerical != null;
void calculateTotalPrice() {
totalPrice.value = 0;
for (var element in cartProducts) {
if (isPriceOff(element)) {
totalPrice.value += element.quantity * element.off!;
} else {
totalPrice.value += element.quantity * element.price;
}
}
}
getFavoriteItems() {
filteredProducts.assignAll(
allProducts.where((item) => item.isFavorite),
);
}
getCartItems() {
cartProducts.assignAll(
allProducts.where((item) => item.quantity > 0),
);
}
getAllItems() {
filteredProducts.assignAll(allProducts);
}
List sizeType(Product product) {
ProductSizeType? productSize = product.sizes;
List numericalList = [];
if (productSize?.numerical != null) {
for (var element in productSize!.numerical!) {
numericalList.add(Numerical(element.numerical, element.isSelected));
}
}
if (productSize?.categorical != null) {
for (var element in productSize!.categorical!) {
numericalList.add(
Numerical(
element.categorical.name,
element.isSelected,
),
);
}
}
return numericalList;
}
void switchBetweenProductSizes(Product product, int index) {
sizeType(product).forEach((element) {
element.isSelected = false;
});
if (product.sizes?.categorical != null) {
for (var element in product.sizes!.categorical!) {
element.isSelected = false;
}
product.sizes?.categorical![index].isSelected = true;
}
if (product.sizes?.numerical != null) {
for (var element in product.sizes!.numerical!) {
element.isSelected = false;
}
product.sizes?.numerical![index].isSelected = true;
}
update();
}
String getCurrentSize(Product product) {
String currentSize = "";
if (product.sizes?.categorical != null) {
for (var element in product.sizes!.categorical!) {
if (element.isSelected) {
currentSize = "Size: ${element.categorical.name}";
}
}
}
if (product.sizes?.numerical != null) {
for (var element in product.sizes!.numerical!) {
if (element.isSelected) {
currentSize = "Size: ${element.numerical}";
}
}
}
return currentSize;
}
}
================================================
FILE: lib/src/model/bottom_nav_bar_item.dart
================================================
import 'package:e_commerce_flutter/core/app_data.dart';
import 'package:flutter/foundation.dart' show immutable;
import 'package:flutter/material.dart' show Color, Icon;
@immutable
class BottomNavBarItem {
final String title;
final Icon icon;
final Color activeColor;
const BottomNavBarItem(
this.title,
this.icon, {
this.activeColor = AppData.lightOrangeColor,
});
}
================================================
FILE: lib/src/model/categorical.dart
================================================
enum CategoricalType { small, medium, large }
class Categorical {
CategoricalType categorical;
bool isSelected = false;
Categorical(this.categorical, this.isSelected);
}
================================================
FILE: lib/src/model/numerical.dart
================================================
class Numerical {
String numerical;
bool isSelected = false;
Numerical(this.numerical, this.isSelected);
}
================================================
FILE: lib/src/model/product.dart
================================================
import 'package:e_commerce_flutter/core/app_data.dart';
import 'package:e_commerce_flutter/src/model/product_size_type.dart';
enum ProductType { all, watch, mobile, headphone, tablet, tv }
class Product {
String name;
int price;
int? off;
String about;
bool isAvailable;
ProductSizeType? sizes;
int _quantity;
List images;
bool isFavorite;
double rating;
ProductType type;
int get quantity => _quantity;
set quantity(int newQuantity) {
if (newQuantity >= 0) _quantity = newQuantity;
}
Product({
this.sizes,
this.about = AppData.dummyText,
required this.name,
required this.price,
required this.isAvailable,
required this.off,
required int quantity,
required this.images,
required this.isFavorite,
required this.rating,
required this.type,
}) : _quantity = quantity;
}
================================================
FILE: lib/src/model/product_category.dart
================================================
import 'package:e_commerce_flutter/src/model/product.dart';
import 'package:flutter/material.dart' show IconData;
class ProductCategory {
ProductType type;
bool isSelected;
IconData icon;
ProductCategory({
required this.type,
this.isSelected = false,
required this.icon,
});
}
================================================
FILE: lib/src/model/product_size_type.dart
================================================
import 'package:e_commerce_flutter/src/model/categorical.dart';
import 'package:e_commerce_flutter/src/model/numerical.dart';
class ProductSizeType {
List? numerical;
List? categorical;
ProductSizeType({this.numerical, this.categorical});
}
================================================
FILE: lib/src/model/recommended_product.dart
================================================
import 'package:e_commerce_flutter/core/app_color.dart';
import 'package:flutter/material.dart' show Color, Colors;
class RecommendedProduct {
Color? cardBackgroundColor;
Color? buttonTextColor;
Color? buttonBackgroundColor;
String imagePath;
RecommendedProduct({
this.cardBackgroundColor,
this.buttonTextColor = AppColor.darkOrange,
this.buttonBackgroundColor = Colors.white,
this.imagePath = "assets/images/shopping.png",
});
}
================================================
FILE: lib/src/view/animation/animated_switcher_wrapper.dart
================================================
import 'package:flutter/material.dart';
class AnimatedSwitcherWrapper extends StatelessWidget {
final Widget child;
const AnimatedSwitcherWrapper({
super.key,
required this.child,
});
@override
Widget build(BuildContext context) {
return AnimatedSwitcher(
duration: const Duration(milliseconds: 500),
transitionBuilder: (Widget child, Animation animation) {
return ScaleTransition(scale: animation, child: child);
},
child: child,
);
}
}
================================================
FILE: lib/src/view/animation/open_container_wrapper.dart
================================================
import 'package:flutter/material.dart';
import 'package:animations/animations.dart';
import 'package:e_commerce_flutter/src/model/product.dart';
import 'package:e_commerce_flutter/src/view/screen/product_detail_screen.dart';
class OpenContainerWrapper extends StatelessWidget {
const OpenContainerWrapper({
super.key,
required this.child,
required this.product,
});
final Widget child;
final Product product;
@override
Widget build(BuildContext context) {
return OpenContainer(
closedShape: const RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(25.0)),
),
closedColor: const Color(0xFFE5E6E8),
transitionType: ContainerTransitionType.fade,
transitionDuration: const Duration(milliseconds: 850),
closedBuilder: (_, VoidCallback openContainer) {
return InkWell(onTap: openContainer, child: child);
},
openBuilder: (_, __) => ProductDetailScreen(product),
);
}
}
================================================
FILE: lib/src/view/animation/page_transition_switcher_wrapper.dart
================================================
import 'package:animations/animations.dart';
import 'package:flutter/material.dart';
class PageTransitionSwitcherWrapper extends StatelessWidget {
const PageTransitionSwitcherWrapper({
super.key,
required this.child,
this.duration = const Duration(seconds: 1),
});
final Widget child;
final Duration duration;
@override
Widget build(BuildContext context) {
return PageTransitionSwitcher(
duration: duration,
transitionBuilder: (
Widget child,
Animation animation,
Animation secondaryAnimation,
) {
return FadeThroughTransition(
animation: animation,
secondaryAnimation: secondaryAnimation,
child: child,
);
},
child: child,
);
}
}
================================================
FILE: lib/src/view/screen/cart_screen.dart
================================================
import 'package:get/get.dart';
import 'package:flutter/material.dart';
import 'package:e_commerce_flutter/core/extensions.dart';
import 'package:e_commerce_flutter/src/model/product.dart';
import 'package:e_commerce_flutter/src/view/widget/empty_cart.dart';
import 'package:e_commerce_flutter/src/controller/product_controller.dart';
import 'package:e_commerce_flutter/src/view/animation/animated_switcher_wrapper.dart';
final ProductController controller = Get.put(ProductController());
class CartScreen extends StatelessWidget {
const CartScreen({super.key});
PreferredSizeWidget _appBar(BuildContext context) {
return AppBar(
title: Text(
"My cart",
style: Theme.of(context).textTheme.displayLarge,
),
);
}
Widget cartList() {
return SingleChildScrollView(
child: Column(
children: controller.cartProducts.mapWithIndex((index, _) {
Product product = controller.cartProducts[index];
return Container(
width: double.infinity,
margin: const EdgeInsets.all(15),
padding: const EdgeInsets.symmetric(
vertical: 15,
horizontal: 5,
),
decoration: BoxDecoration(
color: Colors.grey[200]?.withValues(alpha: 0.6),
borderRadius: BorderRadius.circular(10),
),
child: Row(
spacing: 5,
children: [
Expanded(
child: Container(
padding: const EdgeInsets.all(5),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10),
color: ColorExtension.randomColor,
),
child: ClipRRect(
borderRadius: const BorderRadius.all(Radius.circular(20)),
child: ClipRRect(
borderRadius: BorderRadius.circular(10),
child: Padding(
padding: const EdgeInsets.all(5),
child: Image.asset(
product.images[0],
width: 100,
height: 90,
),
),
),
),
),
),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
product.name.nextLine,
maxLines: 3,
overflow: TextOverflow.ellipsis,
style: const TextStyle(
fontWeight: FontWeight.w600,
fontSize: 15,
),
),
const SizedBox(height: 5),
Text(
controller.getCurrentSize(product),
style: TextStyle(
color: Colors.black.withValues(alpha: 0.5),
fontWeight: FontWeight.w400,
),
),
const SizedBox(height: 5),
Text(
controller.isPriceOff(product) ? "\$${product.off}" : "\$${product.price}",
style: const TextStyle(
fontWeight: FontWeight.w900,
fontSize: 23,
),
),
],
),
),
Container(
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(10),
),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
mainAxisSize: MainAxisSize.min,
children: [
IconButton(
splashRadius: 10.0,
onPressed: () => controller.decreaseItemQuantity(product),
icon: const Icon(
Icons.remove,
color: Color(0xFFEC6813),
),
),
GetBuilder(
builder: (ProductController controller) {
return AnimatedSwitcherWrapper(
child: Text(
'${controller.cartProducts[index].quantity}',
key: ValueKey(
controller.cartProducts[index].quantity,
),
style: const TextStyle(
fontSize: 18,
fontWeight: FontWeight.w700,
),
),
);
},
),
IconButton(
splashRadius: 10.0,
onPressed: () => controller.increaseItemQuantity(product),
icon: const Icon(Icons.add, color: Color(0xFFEC6813)),
),
],
),
)
],
),
);
}).toList(),
),
);
}
Widget bottomBarTitle() {
return Container(
margin: const EdgeInsets.only(bottom: 15),
padding: const EdgeInsets.symmetric(horizontal: 30),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
const Text(
"Total",
style: TextStyle(fontSize: 22, fontWeight: FontWeight.w400),
),
Obx(
() {
return AnimatedSwitcherWrapper(
child: Text(
"\$${controller.totalPrice.value}",
key: ValueKey(controller.totalPrice.value),
style: const TextStyle(
fontSize: 25,
fontWeight: FontWeight.w900,
color: Color(0xFFEC6813),
),
),
);
},
)
],
),
);
}
Widget bottomBarButton() {
return SizedBox(
width: double.infinity,
child: Padding(
padding: const EdgeInsets.only(left: 30, right: 30, bottom: 20),
child: ElevatedButton(
style: ElevatedButton.styleFrom(padding: const EdgeInsets.all(20)),
onPressed: controller.isEmptyCart ? null : () {},
child: const Text("Buy Now"),
),
),
);
}
@override
Widget build(BuildContext context) {
controller.getCartItems();
return Scaffold(
appBar: _appBar(context),
body: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Expanded(
child: !controller.isEmptyCart ? cartList() : const EmptyCart(),
),
bottomBarTitle(),
bottomBarButton()
],
),
);
}
}
================================================
FILE: lib/src/view/screen/favorite_screen.dart
================================================
import 'package:get/get.dart';
import 'package:flutter/material.dart';
import 'package:e_commerce_flutter/src/view/screen/cart_screen.dart';
import 'package:e_commerce_flutter/src/controller/product_controller.dart';
import 'package:e_commerce_flutter/src/view/widget/product_grid_view.dart';
class FavoriteScreen extends StatelessWidget {
const FavoriteScreen({super.key});
@override
Widget build(BuildContext context) {
controller.getFavoriteItems();
return Scaffold(
appBar: AppBar(
title: Text(
"Favorites",
style: Theme.of(context).textTheme.displayLarge,
),
),
body: Padding(
padding: const EdgeInsets.all(20),
child: GetBuilder(
builder: (ProductController controller) {
return ProductGridView(
items: controller.filteredProducts,
likeButtonPressed: (index) => controller.isFavorite(index),
isPriceOff: (product) => controller.isPriceOff(product),
);
},
),
),
);
}
}
================================================
FILE: lib/src/view/screen/home_screen.dart
================================================
import 'package:flutter/material.dart';
import 'package:e_commerce_flutter/core/app_data.dart';
import 'package:stylish_bottom_bar/stylish_bottom_bar.dart';
import 'package:e_commerce_flutter/src/view/screen/cart_screen.dart';
import 'package:e_commerce_flutter/src/view/screen/profile_screen.dart';
import 'package:e_commerce_flutter/src/view/screen/favorite_screen.dart';
import 'package:e_commerce_flutter/src/view/screen/product_list_screen.dart';
import 'package:e_commerce_flutter/src/view/animation/page_transition_switcher_wrapper.dart';
class HomeScreen extends StatefulWidget {
const HomeScreen({super.key});
static const List screens = [
ProductListScreen(),
FavoriteScreen(),
CartScreen(),
ProfileScreen(),
];
@override
State createState() => _HomeScreenState();
}
class _HomeScreenState extends State {
int newIndex = 0;
@override
Widget build(BuildContext context) {
return Center(
child: ConstrainedBox(
constraints: const BoxConstraints(maxWidth: 800),
child: Scaffold(
bottomNavigationBar: StylishBottomBar(
currentIndex: newIndex,
onTap: (index) {
newIndex = index;
setState(() {});
},
items: AppData.bottomNavBarItems
.map(
(item) => BottomBarItem(
backgroundColor: item.activeColor,
icon: item.icon,
title: Text(
item.title,
style: TextStyle(
color: item.activeColor,
),
),
),
)
.toList(),
option: BubbleBarOptions(
opacity: 0.3,
unselectedIconColor: Colors.grey,
borderRadius: BorderRadius.circular(
15.0,
),
),
),
body: PageTransitionSwitcherWrapper(
child: HomeScreen.screens[newIndex],
),
),
),
);
}
}
================================================
FILE: lib/src/view/screen/product_detail_screen.dart
================================================
import 'package:get/get.dart';
import 'package:flutter/material.dart';
import 'package:e_commerce_flutter/core/app_color.dart';
import 'package:e_commerce_flutter/src/model/product.dart';
import 'package:flutter_rating_bar/flutter_rating_bar.dart';
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
import 'package:e_commerce_flutter/src/view/widget/carousel_slider.dart';
import 'package:e_commerce_flutter/src/controller/product_controller.dart';
final ProductController controller = Get.put(ProductController());
class ProductDetailScreen extends StatelessWidget {
final Product product;
const ProductDetailScreen(this.product, {super.key});
PreferredSizeWidget _appBar(BuildContext context) {
return AppBar(
backgroundColor: Colors.transparent,
elevation: 0,
leading: IconButton(
onPressed: () => Navigator.pop(context),
icon: const Icon(Icons.arrow_back, color: Colors.black),
),
);
}
Widget productPageView(double width, double height) {
return Container(
height: height * 0.42,
width: width,
decoration: const BoxDecoration(
color: Color(0xFFE5E6E8),
borderRadius: BorderRadius.only(
bottomRight: Radius.circular(200),
bottomLeft: Radius.circular(200),
),
),
child: CarouselSlider(items: product.images),
);
}
Widget _ratingBar(BuildContext context) {
return Wrap(
spacing: 30,
crossAxisAlignment: WrapCrossAlignment.center,
children: [
RatingBar.builder(
initialRating: product.rating,
direction: Axis.horizontal,
itemBuilder: (_, __) => const FaIcon(
FontAwesomeIcons.solidStar,
color: Colors.amber,
),
onRatingUpdate: (_) {},
),
Text(
"(4500 Reviews)",
style: Theme.of(context).textTheme.displaySmall?.copyWith(
fontWeight: FontWeight.w300,
),
)
],
);
}
Widget productSizesListView() {
return ListView.builder(
scrollDirection: Axis.horizontal,
itemCount: controller.sizeType(product).length,
itemBuilder: (_, index) {
return InkWell(
onTap: () => controller.switchBetweenProductSizes(product, index),
child: AnimatedContainer(
margin: const EdgeInsets.only(right: 5, left: 5),
alignment: Alignment.center,
width: controller.isNominal(product) ? 40 : 70,
decoration: BoxDecoration(
color: controller.sizeType(product)[index].isSelected == false ? Colors.white : AppColor.lightOrange,
borderRadius: BorderRadius.circular(10),
border: Border.all(
color: Colors.grey,
width: 0.4,
),
),
duration: const Duration(milliseconds: 300),
child: FittedBox(
child: Text(
controller.sizeType(product)[index].numerical,
style: const TextStyle(
fontWeight: FontWeight.w500,
fontSize: 15,
),
),
),
),
);
},
);
}
@override
Widget build(BuildContext context) {
double height = MediaQuery.of(context).size.height;
double width = MediaQuery.of(context).size.width;
return SafeArea(
child: Scaffold(
extendBodyBehindAppBar: true,
appBar: _appBar(context),
body: SingleChildScrollView(
child: Center(
child: ConstrainedBox(
constraints: const BoxConstraints(maxWidth: 800),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
productPageView(width, height),
const SizedBox(height: 20),
Padding(
padding: const EdgeInsets.all(20),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
product.name,
style: Theme.of(context).textTheme.displayMedium,
),
const SizedBox(height: 10),
_ratingBar(context),
const SizedBox(height: 10),
Row(
children: [
Text(
product.off != null ? "\$${product.off}" : "\$${product.price}",
style: Theme.of(context).textTheme.displayLarge,
),
const SizedBox(width: 3),
Visibility(
visible: product.off != null ? true : false,
child: Text(
"\$${product.price}",
style: const TextStyle(
decoration: TextDecoration.lineThrough,
color: Colors.grey,
fontWeight: FontWeight.w500,
),
),
),
const Spacer(),
Text(
product.isAvailable ? "Available in stock" : "Not available",
style: const TextStyle(fontWeight: FontWeight.w500),
)
],
),
const SizedBox(height: 30),
Text(
"About",
style: Theme.of(context).textTheme.headlineMedium,
),
const SizedBox(height: 10),
Text(product.about),
const SizedBox(height: 20),
SizedBox(
height: 40,
child: GetBuilder(
builder: (_) => productSizesListView(),
),
),
const SizedBox(height: 20),
SizedBox(
width: double.infinity,
child: ElevatedButton(
onPressed: product.isAvailable ? () => controller.addToCart(product) : null,
child: const Text("Add to cart"),
),
)
],
),
)
],
),
),
),
),
),
);
}
}
================================================
FILE: lib/src/view/screen/product_list_screen.dart
================================================
import 'package:get/get.dart';
import 'package:flutter/material.dart';
import 'package:e_commerce_flutter/core/app_data.dart';
import 'package:e_commerce_flutter/core/app_color.dart';
import 'package:e_commerce_flutter/src/controller/product_controller.dart';
import 'package:e_commerce_flutter/src/view/widget/product_grid_view.dart';
import 'package:e_commerce_flutter/src/view/widget/list_item_selector.dart';
enum AppbarActionType { leading, trailing }
final ProductController controller = Get.put(ProductController());
class ProductListScreen extends StatelessWidget {
const ProductListScreen({super.key});
Widget appBarActionButton(AppbarActionType type) {
IconData icon = Icons.ac_unit_outlined;
if (type == AppbarActionType.trailing) {
icon = Icons.search;
}
return Container(
margin: const EdgeInsets.all(8),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10),
color: AppColor.lightGrey,
),
child: IconButton(
padding: const EdgeInsets.all(8),
constraints: const BoxConstraints(),
onPressed: () {},
icon: Icon(icon, color: Colors.black),
),
);
}
PreferredSize get _appBar {
return PreferredSize(
preferredSize: const Size.fromHeight(100),
child: SafeArea(
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 15, vertical: 10),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
appBarActionButton(AppbarActionType.leading),
appBarActionButton(AppbarActionType.trailing),
],
),
),
),
);
}
Widget _recommendedProductListView(BuildContext context) {
return SizedBox(
height: 170,
child: ListView.builder(
padding: const EdgeInsets.symmetric(vertical: 10),
shrinkWrap: true,
scrollDirection: Axis.horizontal,
itemCount: AppData.recommendedProducts.length,
itemBuilder: (_, index) {
return Padding(
padding: const EdgeInsets.only(right: 20),
child: Container(
width: 300,
decoration: BoxDecoration(
color: AppData.recommendedProducts[index].cardBackgroundColor,
borderRadius: BorderRadius.circular(15),
),
child: Row(
children: [
Padding(
padding: const EdgeInsets.only(left: 20),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
'30% OFF DURING \nCOVID 19',
style: Theme.of(context).textTheme.displaySmall?.copyWith(
color: Colors.white,
),
),
const SizedBox(height: 8),
ElevatedButton(
onPressed: () {},
style: ElevatedButton.styleFrom(
backgroundColor: AppData.recommendedProducts[index].buttonBackgroundColor,
elevation: 0,
padding: const EdgeInsets.symmetric(horizontal: 18),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(18),
),
),
child: Text(
"Get Now",
style: TextStyle(
color: AppData.recommendedProducts[index].buttonTextColor!,
),
),
)
],
),
),
const Spacer(),
Image.asset(
AppData.recommendedProducts[index].imagePath,
height: 125,
fit: BoxFit.cover,
)
],
),
),
);
},
),
);
}
Widget _topCategoriesHeader(BuildContext context) {
return Padding(
padding: const EdgeInsets.only(top: 10),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
"Top categories",
style: Theme.of(context).textTheme.headlineMedium,
),
TextButton(
onPressed: () {},
style: TextButton.styleFrom(foregroundColor: AppColor.darkOrange),
child: Text(
"SEE ALL",
style: Theme.of(context).textTheme.titleLarge?.copyWith(
color: Colors.deepOrange.withValues(alpha: 0.7),
),
),
)
],
),
);
}
Widget _topCategoriesListView() {
return ListItemSelector(
categories: controller.categories,
onItemPressed: (index) {
controller.filterItemsByCategory(index);
},
);
}
@override
Widget build(BuildContext context) {
controller.getAllItems();
return Scaffold(
extendBodyBehindAppBar: true,
appBar: _appBar,
body: SafeArea(
child: SingleChildScrollView(
child: Padding(
padding: const EdgeInsets.all(20),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
"Hello Sina",
style: Theme.of(context).textTheme.displayLarge,
),
Text(
"Lets gets somethings?",
style: Theme.of(context).textTheme.headlineSmall,
),
_recommendedProductListView(context),
_topCategoriesHeader(context),
_topCategoriesListView(),
GetBuilder(
builder: (ProductController controller) {
return ProductGridView(
items: controller.filteredProducts,
likeButtonPressed: (index) => controller.isFavorite(index),
isPriceOff: (product) => controller.isPriceOff(product),
);
},
),
],
),
),
),
),
);
}
}
================================================
FILE: lib/src/view/screen/profile_screen.dart
================================================
import 'package:flutter/material.dart';
class ProfileScreen extends StatelessWidget {
const ProfileScreen({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
body: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Expanded(child: Image.asset('assets/images/profile_pic.png')),
const Text(
"Hello Sina!",
style: TextStyle(fontWeight: FontWeight.bold, fontSize: 25),
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Image.asset('assets/images/github.png', width: 60),
const SizedBox(width: 10),
const Text(
"https://github.com/SinaSys",
style: TextStyle(fontSize: 20),
)
],
)
],
),
);
}
}
================================================
FILE: lib/src/view/widget/carousel_slider.dart
================================================
import 'package:flutter/material.dart';
import 'package:e_commerce_flutter/core/app_color.dart';
import 'package:smooth_page_indicator/smooth_page_indicator.dart';
class CarouselSlider extends StatefulWidget {
const CarouselSlider({
super.key,
required this.items,
});
final List items;
@override
State createState() => _CarouselSliderState();
}
class _CarouselSliderState extends State {
int newIndex = 0;
@override
Widget build(BuildContext context) {
var height = MediaQuery.of(context).size.height;
return Column(
children: [
SizedBox(
height: height * 0.32,
child: PageView.builder(
itemCount: widget.items.length,
onPageChanged: (int currentIndex) {
newIndex = currentIndex;
setState(() {});
},
itemBuilder: (_, index) {
return FittedBox(
fit: BoxFit.none,
child: Image.asset(widget.items[index], scale: 3),
);
},
),
),
AnimatedSmoothIndicator(
effect: const WormEffect(
dotColor: Colors.white,
activeDotColor: AppColor.darkOrange,
),
count: widget.items.length,
activeIndex: newIndex,
)
],
);
}
}
================================================
FILE: lib/src/view/widget/empty_cart.dart
================================================
import 'package:flutter/material.dart';
class EmptyCart extends StatelessWidget {
const EmptyCart({super.key});
@override
Widget build(BuildContext context) {
return Column(
children: [
Expanded(
child: Center(
child: Image.asset('assets/images/empty_cart.png'),
),
),
const Text(
"Empty cart",
style: TextStyle(fontWeight: FontWeight.bold, fontSize: 20),
)
],
);
}
}
================================================
FILE: lib/src/view/widget/list_item_selector.dart
================================================
import 'package:get/get.dart';
import 'package:flutter/material.dart';
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
import 'package:e_commerce_flutter/src/model/product_category.dart';
class ListItemSelector extends StatefulWidget {
const ListItemSelector({
super.key,
required this.categories,
required this.onItemPressed,
});
final List categories;
final Function(int) onItemPressed;
@override
State createState() => _ListItemSelectorState();
}
class _ListItemSelectorState extends State {
Widget item(ProductCategory item, int index) {
return Tooltip(
message: item.type.name.capitalizeFirst,
child: AnimatedContainer(
margin: const EdgeInsets.only(left: 5),
duration: const Duration(milliseconds: 500),
width: 50,
height: 100,
decoration: BoxDecoration(
color: item.isSelected == false
? const Color(0xFFE5E6E8)
: const Color(0xFFf16b26),
borderRadius: BorderRadius.circular(10),
),
child: IconButton(
splashRadius: 0.1,
icon: FaIcon(
item.icon,
color: item.isSelected == false
? const Color(0xFFA6A3A0)
: Colors.white,
),
onPressed: () {
widget.onItemPressed(index);
for (var element in widget.categories) {
element.isSelected = false;
}
item.isSelected = true;
setState(() {});
},
),
),
);
}
@override
Widget build(BuildContext context) {
return SizedBox(
height: 50,
child: ListView.builder(
scrollDirection: Axis.horizontal,
itemCount: widget.categories.length,
itemBuilder: (_, index) => item(widget.categories[index], index),
),
);
}
}
================================================
FILE: lib/src/view/widget/product_grid_view.dart
================================================
import 'package:flutter/material.dart';
import 'package:e_commerce_flutter/src/model/product.dart';
import 'package:e_commerce_flutter/src/view/animation/open_container_wrapper.dart';
class ProductGridView extends StatelessWidget {
const ProductGridView({
super.key,
required this.items,
required this.isPriceOff,
required this.likeButtonPressed,
});
final List items;
final bool Function(Product product) isPriceOff;
final void Function(int index) likeButtonPressed;
Widget _gridItemHeader(Product product, int index) {
return Padding(
padding: const EdgeInsets.all(10.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Visibility(
visible: isPriceOff(product),
child: Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(30),
color: Colors.white,
),
width: 80,
height: 30,
alignment: Alignment.center,
child: const Text(
"30% OFF",
style: TextStyle(fontWeight: FontWeight.w600),
),
),
),
IconButton(
icon: Icon(
Icons.favorite,
color: items[index].isFavorite
? Colors.redAccent
: const Color(0xFFA6A3A0),
),
onPressed: () => likeButtonPressed(index),
),
],
),
);
}
Widget _gridItemBody(Product product) {
return Container(
padding: const EdgeInsets.all(15),
decoration: BoxDecoration(
color: const Color(0xFFE5E6E8),
borderRadius: BorderRadius.circular(20),
),
child: Image.asset(product.images[0], scale: 3),
);
}
Widget _gridItemFooter(Product product, BuildContext context) {
return Padding(
padding: const EdgeInsets.all(8.0),
child: Container(
padding: const EdgeInsets.all(10),
height: 70,
decoration: const BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.only(
bottomLeft: Radius.circular(15),
bottomRight: Radius.circular(15),
),
),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
FittedBox(
child: Text(
product.name,
overflow: TextOverflow.ellipsis,
maxLines: 1,
style: const TextStyle(
fontWeight: FontWeight.w500,
color: Colors.grey,
),
),
),
const SizedBox(height: 5),
Row(
children: [
Text(
product.off != null
? "\$${product.off}"
: "\$${product.price}",
style: Theme.of(context).textTheme.headlineMedium,
),
const SizedBox(width: 3),
Visibility(
visible: product.off != null ? true : false,
child: Text(
"\$${product.price}",
style: const TextStyle(
decoration: TextDecoration.lineThrough,
color: Colors.grey,
fontWeight: FontWeight.w500,
),
),
)
],
)
],
),
),
);
}
@override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.only(top: 20),
child: GridView.builder(
itemCount: items.length,
shrinkWrap: true,
physics: const ScrollPhysics(),
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
childAspectRatio: 10 / 16,
crossAxisCount: 2,
mainAxisSpacing: 10,
crossAxisSpacing: 10,
),
itemBuilder: (_, index) {
Product product = items[index];
return OpenContainerWrapper(
product: product,
child: GridTile(
header: _gridItemHeader(product, index),
footer: _gridItemFooter(product, context),
child: _gridItemBody(product),
),
);
},
),
);
}
}
================================================
FILE: pubspec.yaml
================================================
name: e_commerce_flutter
description: E-Commerce App built in flutter using GetX
publish_to: 'none'
version: 1.0.0+1
environment:
sdk: '>=3.0.0 <4.0.0'
dependencies:
flutter:
sdk: flutter
get: ^4.6.6
smooth_page_indicator: ^1.2.0+3
flutter_rating_bar: ^4.0.1
font_awesome_flutter: ^10.8.0
animations: ^2.0.11
stylish_bottom_bar: ^1.1.0
dev_dependencies:
flutter_lints: ^5.0.0
flutter_test:
sdk: flutter
flutter_launcher_icons: ^0.14.2
flutter_launcher_icons:
android: "launcher_icon"
image_path: "assets/images/logo.png"
adaptive_icon_background : "#ffffff"
adaptive_icon_foreground : "assets/images/logo.png"
flutter:
uses-material-design: true
assets:
- assets/images/
================================================
FILE: web/index.html
================================================
e_commerce_flutter
================================================
FILE: web/manifest.json
================================================
{
"name": "e_commerce_flutter",
"short_name": "e_commerce_flutter",
"start_url": ".",
"display": "standalone",
"background_color": "#0175C2",
"theme_color": "#0175C2",
"description": "A new Flutter project.",
"orientation": "portrait-primary",
"prefer_related_applications": false,
"icons": [
{
"src": "icons/Icon-192.png",
"sizes": "192x192",
"type": "image/png"
},
{
"src": "icons/Icon-512.png",
"sizes": "512x512",
"type": "image/png"
},
{
"src": "icons/Icon-maskable-192.png",
"sizes": "192x192",
"type": "image/png",
"purpose": "maskable"
},
{
"src": "icons/Icon-maskable-512.png",
"sizes": "512x512",
"type": "image/png",
"purpose": "maskable"
}
]
}