├── .gitignore ├── .metadata ├── README.md ├── android ├── app │ ├── build.gradle │ └── src │ │ ├── debug │ │ └── AndroidManifest.xml │ │ ├── main │ │ ├── AndroidManifest.xml │ │ ├── java │ │ │ └── com │ │ │ │ └── example │ │ │ │ └── budget_planner │ │ │ │ └── MainActivity.java │ │ └── res │ │ │ ├── drawable │ │ │ └── launch_background.xml │ │ │ ├── mipmap-hdpi │ │ │ └── ic_launcher.png │ │ │ ├── mipmap-mdpi │ │ │ └── ic_launcher.png │ │ │ ├── mipmap-xhdpi │ │ │ └── ic_launcher.png │ │ │ ├── mipmap-xxhdpi │ │ │ └── ic_launcher.png │ │ │ ├── mipmap-xxxhdpi │ │ │ └── ic_launcher.png │ │ │ └── values │ │ │ └── styles.xml │ │ └── profile │ │ └── AndroidManifest.xml ├── build.gradle ├── gradle.properties ├── gradle │ └── wrapper │ │ └── gradle-wrapper.properties └── settings.gradle ├── assets ├── fonts │ ├── bold.OTF │ ├── light.OTF │ ├── medium.OTF │ └── regular.OTF ├── icons │ └── fb.png └── images │ ├── add_circle.png │ ├── bank.png │ ├── confetti.png │ ├── line_down.png │ ├── no_transaction_yet.png │ ├── pill.png │ └── using_phone.png ├── ios ├── Flutter │ ├── AppFrameworkInfo.plist │ ├── Debug.xcconfig │ └── Release.xcconfig ├── Podfile ├── Podfile.lock ├── Runner.xcodeproj │ ├── project.pbxproj │ ├── project.xcworkspace │ │ └── contents.xcworkspacedata │ └── xcshareddata │ │ └── xcschemes │ │ └── Runner.xcscheme ├── Runner.xcworkspace │ ├── contents.xcworkspacedata │ └── xcshareddata │ │ ├── IDEWorkspaceChecks.plist │ │ └── WorkspaceSettings.xcsettings └── Runner │ ├── AppDelegate.swift │ ├── Assets.xcassets │ ├── AppIcon.appiconset │ │ ├── Contents.json │ │ ├── Icon-App-1024x1024@1x.png │ │ ├── Icon-App-20x20@1x.png │ │ ├── Icon-App-20x20@2x.png │ │ ├── Icon-App-20x20@3x.png │ │ ├── Icon-App-29x29@1x.png │ │ ├── Icon-App-29x29@2x.png │ │ ├── Icon-App-29x29@3x.png │ │ ├── Icon-App-40x40@1x.png │ │ ├── Icon-App-40x40@2x.png │ │ ├── Icon-App-40x40@3x.png │ │ ├── Icon-App-60x60@2x.png │ │ ├── Icon-App-60x60@3x.png │ │ ├── Icon-App-76x76@1x.png │ │ ├── Icon-App-76x76@2x.png │ │ └── Icon-App-83.5x83.5@2x.png │ └── LaunchImage.imageset │ │ ├── Contents.json │ │ ├── LaunchImage.png │ │ ├── LaunchImage@2x.png │ │ ├── LaunchImage@3x.png │ │ └── README.md │ ├── Base.lproj │ ├── LaunchScreen.storyboard │ └── Main.storyboard │ ├── Info.plist │ └── Runner-Bridging-Header.h ├── lib ├── config │ └── enums.dart ├── main.dart ├── screens │ ├── add_bank.dart │ ├── add_bank_success.dart │ ├── add_transaction │ │ ├── details.dart │ │ └── type.dart │ ├── budget.dart │ ├── budget │ │ ├── add_transaction.dart │ │ ├── daily_transactions.dart │ │ └── transaction_summary.dart │ ├── login.dart │ └── register.dart └── widgets │ ├── auth_container.dart │ ├── custom_button.dart │ ├── custom_form.dart │ ├── custom_textfield.dart │ ├── rounded_appbar.dart │ ├── route_transitions.dart │ └── zoom_in_out_image.dart ├── pubspec.lock ├── pubspec.yaml ├── screenshots ├── demo.gif ├── screenshot_1.png └── screenshot_2.png └── test └── widget_test.dart /.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 | # Visual Studio Code related 19 | .vscode/ 20 | 21 | # Flutter/Dart/Pub related 22 | **/doc/api/ 23 | .dart_tool/ 24 | .flutter-plugins 25 | .packages 26 | .pub-cache/ 27 | .pub/ 28 | /build/ 29 | 30 | # Android related 31 | **/android/**/gradle-wrapper.jar 32 | **/android/.gradle 33 | **/android/captures/ 34 | **/android/gradlew 35 | **/android/gradlew.bat 36 | **/android/local.properties 37 | **/android/**/GeneratedPluginRegistrant.java 38 | 39 | # iOS/XCode related 40 | **/ios/**/*.mode1v3 41 | **/ios/**/*.mode2v3 42 | **/ios/**/*.moved-aside 43 | **/ios/**/*.pbxuser 44 | **/ios/**/*.perspectivev3 45 | **/ios/**/*sync/ 46 | **/ios/**/.sconsign.dblite 47 | **/ios/**/.tags* 48 | **/ios/**/.vagrant/ 49 | **/ios/**/DerivedData/ 50 | **/ios/**/Icon? 51 | **/ios/**/Pods/ 52 | **/ios/**/.symlinks/ 53 | **/ios/**/profile 54 | **/ios/**/xcuserdata 55 | **/ios/.generated/ 56 | **/ios/Flutter/App.framework 57 | **/ios/Flutter/Flutter.framework 58 | **/ios/Flutter/Generated.xcconfig 59 | **/ios/Flutter/app.flx 60 | **/ios/Flutter/app.zip 61 | **/ios/Flutter/flutter_assets/ 62 | **/ios/ServiceDefinitions.json 63 | **/ios/Runner/GeneratedPluginRegistrant.* 64 | 65 | # Exceptions to above rules. 66 | !**/ios/**/default.mode1v3 67 | !**/ios/**/default.mode2v3 68 | !**/ios/**/default.pbxuser 69 | !**/ios/**/default.perspectivev3 70 | !/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages 71 | -------------------------------------------------------------------------------- /.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: 7a4c33425ddd78c54aba07d86f3f9a4a0051769b 8 | channel: stable 9 | 10 | project_type: app 11 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # budget_planner 2 | 3 | A budget planner app made with flutter. 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /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 from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" 26 | 27 | android { 28 | compileSdkVersion 28 29 | 30 | lintOptions { 31 | disable 'InvalidPackage' 32 | } 33 | 34 | defaultConfig { 35 | // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). 36 | applicationId "com.example.budget_planner" 37 | minSdkVersion 16 38 | targetSdkVersion 28 39 | versionCode flutterVersionCode.toInteger() 40 | versionName flutterVersionName 41 | testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" 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 | testImplementation 'junit:junit:4.12' 59 | androidTestImplementation 'com.android.support.test:runner:1.0.2' 60 | androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2' 61 | } 62 | -------------------------------------------------------------------------------- /android/app/src/debug/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /android/app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | 9 | 13 | 20 | 24 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /android/app/src/main/java/com/example/budget_planner/MainActivity.java: -------------------------------------------------------------------------------- 1 | package com.example.budget_planner; 2 | 3 | import android.os.Bundle; 4 | import io.flutter.app.FlutterActivity; 5 | import io.flutter.plugins.GeneratedPluginRegistrant; 6 | 7 | public class MainActivity extends FlutterActivity { 8 | @Override 9 | protected void onCreate(Bundle savedInstanceState) { 10 | super.onCreate(savedInstanceState); 11 | GeneratedPluginRegistrant.registerWith(this); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /android/app/src/main/res/drawable/launch_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 12 | 13 | -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fluttertraining/Life-Monitor/cf1fd57dd476b48a81311f8a1d1bcd94d94b1986/android/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fluttertraining/Life-Monitor/cf1fd57dd476b48a81311f8a1d1bcd94d94b1986/android/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fluttertraining/Life-Monitor/cf1fd57dd476b48a81311f8a1d1bcd94d94b1986/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fluttertraining/Life-Monitor/cf1fd57dd476b48a81311f8a1d1bcd94d94b1986/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fluttertraining/Life-Monitor/cf1fd57dd476b48a81311f8a1d1bcd94d94b1986/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 8 | 9 | -------------------------------------------------------------------------------- /android/app/src/profile/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /android/build.gradle: -------------------------------------------------------------------------------- 1 | buildscript { 2 | repositories { 3 | google() 4 | jcenter() 5 | } 6 | 7 | dependencies { 8 | classpath 'com.android.tools.build:gradle:3.2.1' 9 | } 10 | } 11 | 12 | allprojects { 13 | repositories { 14 | google() 15 | jcenter() 16 | } 17 | } 18 | 19 | rootProject.buildDir = '../build' 20 | subprojects { 21 | project.buildDir = "${rootProject.buildDir}/${project.name}" 22 | } 23 | subprojects { 24 | project.evaluationDependsOn(':app') 25 | } 26 | 27 | task clean(type: Delete) { 28 | delete rootProject.buildDir 29 | } 30 | -------------------------------------------------------------------------------- /android/gradle.properties: -------------------------------------------------------------------------------- 1 | org.gradle.jvmargs=-Xmx1536M 2 | -------------------------------------------------------------------------------- /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-4.10.2-all.zip 7 | -------------------------------------------------------------------------------- /android/settings.gradle: -------------------------------------------------------------------------------- 1 | include ':app' 2 | 3 | def flutterProjectRoot = rootProject.projectDir.parentFile.toPath() 4 | 5 | def plugins = new Properties() 6 | def pluginsFile = new File(flutterProjectRoot.toFile(), '.flutter-plugins') 7 | if (pluginsFile.exists()) { 8 | pluginsFile.withReader('UTF-8') { reader -> plugins.load(reader) } 9 | } 10 | 11 | plugins.each { name, path -> 12 | def pluginDirectory = flutterProjectRoot.resolve(path).resolve('android').toFile() 13 | include ":$name" 14 | project(":$name").projectDir = pluginDirectory 15 | } 16 | -------------------------------------------------------------------------------- /assets/fonts/bold.OTF: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fluttertraining/Life-Monitor/cf1fd57dd476b48a81311f8a1d1bcd94d94b1986/assets/fonts/bold.OTF -------------------------------------------------------------------------------- /assets/fonts/light.OTF: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fluttertraining/Life-Monitor/cf1fd57dd476b48a81311f8a1d1bcd94d94b1986/assets/fonts/light.OTF -------------------------------------------------------------------------------- /assets/fonts/medium.OTF: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fluttertraining/Life-Monitor/cf1fd57dd476b48a81311f8a1d1bcd94d94b1986/assets/fonts/medium.OTF -------------------------------------------------------------------------------- /assets/fonts/regular.OTF: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fluttertraining/Life-Monitor/cf1fd57dd476b48a81311f8a1d1bcd94d94b1986/assets/fonts/regular.OTF -------------------------------------------------------------------------------- /assets/icons/fb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fluttertraining/Life-Monitor/cf1fd57dd476b48a81311f8a1d1bcd94d94b1986/assets/icons/fb.png -------------------------------------------------------------------------------- /assets/images/add_circle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fluttertraining/Life-Monitor/cf1fd57dd476b48a81311f8a1d1bcd94d94b1986/assets/images/add_circle.png -------------------------------------------------------------------------------- /assets/images/bank.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fluttertraining/Life-Monitor/cf1fd57dd476b48a81311f8a1d1bcd94d94b1986/assets/images/bank.png -------------------------------------------------------------------------------- /assets/images/confetti.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fluttertraining/Life-Monitor/cf1fd57dd476b48a81311f8a1d1bcd94d94b1986/assets/images/confetti.png -------------------------------------------------------------------------------- /assets/images/line_down.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fluttertraining/Life-Monitor/cf1fd57dd476b48a81311f8a1d1bcd94d94b1986/assets/images/line_down.png -------------------------------------------------------------------------------- /assets/images/no_transaction_yet.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fluttertraining/Life-Monitor/cf1fd57dd476b48a81311f8a1d1bcd94d94b1986/assets/images/no_transaction_yet.png -------------------------------------------------------------------------------- /assets/images/pill.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fluttertraining/Life-Monitor/cf1fd57dd476b48a81311f8a1d1bcd94d94b1986/assets/images/pill.png -------------------------------------------------------------------------------- /assets/images/using_phone.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fluttertraining/Life-Monitor/cf1fd57dd476b48a81311f8a1d1bcd94d94b1986/assets/images/using_phone.png -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /ios/Flutter/Debug.xcconfig: -------------------------------------------------------------------------------- 1 | #include "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig" 2 | #include "Generated.xcconfig" 3 | -------------------------------------------------------------------------------- /ios/Flutter/Release.xcconfig: -------------------------------------------------------------------------------- 1 | #include "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig" 2 | #include "Generated.xcconfig" 3 | -------------------------------------------------------------------------------- /ios/Podfile: -------------------------------------------------------------------------------- 1 | # Uncomment this line to define a global platform for your project 2 | # platform :ios, '9.0' 3 | 4 | # CocoaPods analytics sends network stats synchronously affecting flutter build latency. 5 | ENV['COCOAPODS_DISABLE_STATS'] = 'true' 6 | 7 | project 'Runner', { 8 | 'Debug' => :debug, 9 | 'Profile' => :release, 10 | 'Release' => :release, 11 | } 12 | 13 | def parse_KV_file(file, separator='=') 14 | file_abs_path = File.expand_path(file) 15 | if !File.exists? file_abs_path 16 | return []; 17 | end 18 | pods_ary = [] 19 | skip_line_start_symbols = ["#", "/"] 20 | File.foreach(file_abs_path) { |line| 21 | next if skip_line_start_symbols.any? { |symbol| line =~ /^\s*#{symbol}/ } 22 | plugin = line.split(pattern=separator) 23 | if plugin.length == 2 24 | podname = plugin[0].strip() 25 | path = plugin[1].strip() 26 | podpath = File.expand_path("#{path}", file_abs_path) 27 | pods_ary.push({:name => podname, :path => podpath}); 28 | else 29 | puts "Invalid plugin specification: #{line}" 30 | end 31 | } 32 | return pods_ary 33 | end 34 | 35 | target 'Runner' do 36 | use_frameworks! 37 | 38 | # Prepare symlinks folder. We use symlinks to avoid having Podfile.lock 39 | # referring to absolute paths on developers' machines. 40 | system('rm -rf .symlinks') 41 | system('mkdir -p .symlinks/plugins') 42 | 43 | # Flutter Pods 44 | generated_xcode_build_settings = parse_KV_file('./Flutter/Generated.xcconfig') 45 | if generated_xcode_build_settings.empty? 46 | puts "Generated.xcconfig must exist. If you're running pod install manually, make sure flutter packages get is executed first." 47 | end 48 | generated_xcode_build_settings.map { |p| 49 | if p[:name] == 'FLUTTER_FRAMEWORK_DIR' 50 | symlink = File.join('.symlinks', 'flutter') 51 | File.symlink(File.dirname(p[:path]), symlink) 52 | pod 'Flutter', :path => File.join(symlink, File.basename(p[:path])) 53 | end 54 | } 55 | 56 | # Plugin Pods 57 | plugin_pods = parse_KV_file('../.flutter-plugins') 58 | plugin_pods.map { |p| 59 | symlink = File.join('.symlinks', 'plugins', p[:name]) 60 | File.symlink(p[:path], symlink) 61 | pod p[:name], :path => File.join(symlink, 'ios') 62 | } 63 | end 64 | 65 | post_install do |installer| 66 | installer.pods_project.targets.each do |target| 67 | target.build_configurations.each do |config| 68 | config.build_settings['ENABLE_BITCODE'] = 'NO' 69 | end 70 | end 71 | end 72 | -------------------------------------------------------------------------------- /ios/Podfile.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - Flutter (1.0.0) 3 | - keyboard_visibility (0.5.0): 4 | - Flutter 5 | - Reachability 6 | - Reachability (3.2) 7 | 8 | DEPENDENCIES: 9 | - Flutter (from `.symlinks/flutter/ios`) 10 | - keyboard_visibility (from `.symlinks/plugins/keyboard_visibility/ios`) 11 | 12 | SPEC REPOS: 13 | https://github.com/cocoapods/specs.git: 14 | - Reachability 15 | 16 | EXTERNAL SOURCES: 17 | Flutter: 18 | :path: ".symlinks/flutter/ios" 19 | keyboard_visibility: 20 | :path: ".symlinks/plugins/keyboard_visibility/ios" 21 | 22 | SPEC CHECKSUMS: 23 | Flutter: 58dd7d1b27887414a370fcccb9e645c08ffd7a6a 24 | keyboard_visibility: 96a24de806fe6823c3ad956c01ba2ec6d056616f 25 | Reachability: 33e18b67625424e47b6cde6d202dce689ad7af96 26 | 27 | PODFILE CHECKSUM: ebd43b443038e611b86ede96e613bd6033c49497 28 | 29 | COCOAPODS: 1.6.0 30 | -------------------------------------------------------------------------------- /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 | 21153C3CCB5F86ABCCD52CB0 /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 50B2CCF85C15DA5733A27996 /* Pods_Runner.framework */; }; 12 | 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; }; 13 | 3B80C3941E831B6300D905FE /* App.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3B80C3931E831B6300D905FE /* App.framework */; }; 14 | 3B80C3951E831B6300D905FE /* App.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 3B80C3931E831B6300D905FE /* App.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 15 | 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; }; 16 | 9705A1C61CF904A100538489 /* Flutter.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9740EEBA1CF902C7004384FC /* Flutter.framework */; }; 17 | 9705A1C71CF904A300538489 /* Flutter.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 9740EEBA1CF902C7004384FC /* Flutter.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 18 | 9740EEB41CF90195004384FC /* Debug.xcconfig in Resources */ = {isa = PBXBuildFile; fileRef = 9740EEB21CF90195004384FC /* Debug.xcconfig */; }; 19 | 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; }; 20 | 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; }; 21 | 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; }; 22 | /* End PBXBuildFile section */ 23 | 24 | /* Begin PBXCopyFilesBuildPhase section */ 25 | 9705A1C41CF9048500538489 /* Embed Frameworks */ = { 26 | isa = PBXCopyFilesBuildPhase; 27 | buildActionMask = 2147483647; 28 | dstPath = ""; 29 | dstSubfolderSpec = 10; 30 | files = ( 31 | 3B80C3951E831B6300D905FE /* App.framework in Embed Frameworks */, 32 | 9705A1C71CF904A300538489 /* Flutter.framework in Embed Frameworks */, 33 | ); 34 | name = "Embed Frameworks"; 35 | runOnlyForDeploymentPostprocessing = 0; 36 | }; 37 | /* End PBXCopyFilesBuildPhase section */ 38 | 39 | /* Begin PBXFileReference section */ 40 | 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = ""; }; 41 | 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = ""; }; 42 | 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; }; 43 | 3B80C3931E831B6300D905FE /* App.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = App.framework; path = Flutter/App.framework; sourceTree = ""; }; 44 | 50B2CCF85C15DA5733A27996 /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 45 | 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = ""; }; 46 | 74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 47 | 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; }; 48 | 85C8E974C34F191459EF30D9 /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = ""; }; 49 | 8DEC6F9879010C64C45A3A5A /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = ""; }; 50 | 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = ""; }; 51 | 9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = ""; }; 52 | 9740EEBA1CF902C7004384FC /* Flutter.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Flutter.framework; path = Flutter/Flutter.framework; sourceTree = ""; }; 53 | 97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; }; 54 | 97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 55 | 97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 56 | 97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 57 | 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 58 | DF6A9B72A8E43B33239EF1C5 /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = ""; }; 59 | /* End PBXFileReference section */ 60 | 61 | /* Begin PBXFrameworksBuildPhase section */ 62 | 97C146EB1CF9000F007C117D /* Frameworks */ = { 63 | isa = PBXFrameworksBuildPhase; 64 | buildActionMask = 2147483647; 65 | files = ( 66 | 9705A1C61CF904A100538489 /* Flutter.framework in Frameworks */, 67 | 3B80C3941E831B6300D905FE /* App.framework in Frameworks */, 68 | 21153C3CCB5F86ABCCD52CB0 /* Pods_Runner.framework in Frameworks */, 69 | ); 70 | runOnlyForDeploymentPostprocessing = 0; 71 | }; 72 | /* End PBXFrameworksBuildPhase section */ 73 | 74 | /* Begin PBXGroup section */ 75 | 16EEBFFC90BC341F7B8DECBF /* Frameworks */ = { 76 | isa = PBXGroup; 77 | children = ( 78 | 50B2CCF85C15DA5733A27996 /* Pods_Runner.framework */, 79 | ); 80 | name = Frameworks; 81 | sourceTree = ""; 82 | }; 83 | 9740EEB11CF90186004384FC /* Flutter */ = { 84 | isa = PBXGroup; 85 | children = ( 86 | 3B80C3931E831B6300D905FE /* App.framework */, 87 | 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */, 88 | 9740EEBA1CF902C7004384FC /* Flutter.framework */, 89 | 9740EEB21CF90195004384FC /* Debug.xcconfig */, 90 | 7AFA3C8E1D35360C0083082E /* Release.xcconfig */, 91 | 9740EEB31CF90195004384FC /* Generated.xcconfig */, 92 | ); 93 | name = Flutter; 94 | sourceTree = ""; 95 | }; 96 | 97C146E51CF9000F007C117D = { 97 | isa = PBXGroup; 98 | children = ( 99 | 9740EEB11CF90186004384FC /* Flutter */, 100 | 97C146F01CF9000F007C117D /* Runner */, 101 | 97C146EF1CF9000F007C117D /* Products */, 102 | C0DDA03B2C31CCCEE11AD21D /* Pods */, 103 | 16EEBFFC90BC341F7B8DECBF /* Frameworks */, 104 | ); 105 | sourceTree = ""; 106 | }; 107 | 97C146EF1CF9000F007C117D /* Products */ = { 108 | isa = PBXGroup; 109 | children = ( 110 | 97C146EE1CF9000F007C117D /* Runner.app */, 111 | ); 112 | name = Products; 113 | sourceTree = ""; 114 | }; 115 | 97C146F01CF9000F007C117D /* Runner */ = { 116 | isa = PBXGroup; 117 | children = ( 118 | 97C146FA1CF9000F007C117D /* Main.storyboard */, 119 | 97C146FD1CF9000F007C117D /* Assets.xcassets */, 120 | 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */, 121 | 97C147021CF9000F007C117D /* Info.plist */, 122 | 97C146F11CF9000F007C117D /* Supporting Files */, 123 | 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */, 124 | 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */, 125 | 74858FAE1ED2DC5600515810 /* AppDelegate.swift */, 126 | 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */, 127 | ); 128 | path = Runner; 129 | sourceTree = ""; 130 | }; 131 | 97C146F11CF9000F007C117D /* Supporting Files */ = { 132 | isa = PBXGroup; 133 | children = ( 134 | ); 135 | name = "Supporting Files"; 136 | sourceTree = ""; 137 | }; 138 | C0DDA03B2C31CCCEE11AD21D /* Pods */ = { 139 | isa = PBXGroup; 140 | children = ( 141 | 85C8E974C34F191459EF30D9 /* Pods-Runner.debug.xcconfig */, 142 | DF6A9B72A8E43B33239EF1C5 /* Pods-Runner.release.xcconfig */, 143 | 8DEC6F9879010C64C45A3A5A /* Pods-Runner.profile.xcconfig */, 144 | ); 145 | path = Pods; 146 | sourceTree = ""; 147 | }; 148 | /* End PBXGroup section */ 149 | 150 | /* Begin PBXNativeTarget section */ 151 | 97C146ED1CF9000F007C117D /* Runner */ = { 152 | isa = PBXNativeTarget; 153 | buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */; 154 | buildPhases = ( 155 | 627D147BBDAC06D7B693E778 /* [CP] Check Pods Manifest.lock */, 156 | 9740EEB61CF901F6004384FC /* Run Script */, 157 | 97C146EA1CF9000F007C117D /* Sources */, 158 | 97C146EB1CF9000F007C117D /* Frameworks */, 159 | 97C146EC1CF9000F007C117D /* Resources */, 160 | 9705A1C41CF9048500538489 /* Embed Frameworks */, 161 | 3B06AD1E1E4923F5004D2608 /* Thin Binary */, 162 | 6E99111C159A84302A2E8A9A /* [CP] Embed Pods Frameworks */, 163 | ); 164 | buildRules = ( 165 | ); 166 | dependencies = ( 167 | ); 168 | name = Runner; 169 | productName = Runner; 170 | productReference = 97C146EE1CF9000F007C117D /* Runner.app */; 171 | productType = "com.apple.product-type.application"; 172 | }; 173 | /* End PBXNativeTarget section */ 174 | 175 | /* Begin PBXProject section */ 176 | 97C146E61CF9000F007C117D /* Project object */ = { 177 | isa = PBXProject; 178 | attributes = { 179 | LastUpgradeCheck = 0910; 180 | ORGANIZATIONNAME = "The Chromium Authors"; 181 | TargetAttributes = { 182 | 97C146ED1CF9000F007C117D = { 183 | CreatedOnToolsVersion = 7.3.1; 184 | DevelopmentTeam = G73M4N3655; 185 | LastSwiftMigration = 0910; 186 | }; 187 | }; 188 | }; 189 | buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */; 190 | compatibilityVersion = "Xcode 3.2"; 191 | developmentRegion = English; 192 | hasScannedForEncodings = 0; 193 | knownRegions = ( 194 | en, 195 | Base, 196 | ); 197 | mainGroup = 97C146E51CF9000F007C117D; 198 | productRefGroup = 97C146EF1CF9000F007C117D /* Products */; 199 | projectDirPath = ""; 200 | projectRoot = ""; 201 | targets = ( 202 | 97C146ED1CF9000F007C117D /* Runner */, 203 | ); 204 | }; 205 | /* End PBXProject section */ 206 | 207 | /* Begin PBXResourcesBuildPhase section */ 208 | 97C146EC1CF9000F007C117D /* Resources */ = { 209 | isa = PBXResourcesBuildPhase; 210 | buildActionMask = 2147483647; 211 | files = ( 212 | 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */, 213 | 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */, 214 | 9740EEB41CF90195004384FC /* Debug.xcconfig in Resources */, 215 | 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */, 216 | 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */, 217 | ); 218 | runOnlyForDeploymentPostprocessing = 0; 219 | }; 220 | /* End PBXResourcesBuildPhase section */ 221 | 222 | /* Begin PBXShellScriptBuildPhase section */ 223 | 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = { 224 | isa = PBXShellScriptBuildPhase; 225 | buildActionMask = 2147483647; 226 | files = ( 227 | ); 228 | inputPaths = ( 229 | ); 230 | name = "Thin Binary"; 231 | outputPaths = ( 232 | ); 233 | runOnlyForDeploymentPostprocessing = 0; 234 | shellPath = /bin/sh; 235 | shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" thin"; 236 | }; 237 | 627D147BBDAC06D7B693E778 /* [CP] Check Pods Manifest.lock */ = { 238 | isa = PBXShellScriptBuildPhase; 239 | buildActionMask = 2147483647; 240 | files = ( 241 | ); 242 | inputFileListPaths = ( 243 | ); 244 | inputPaths = ( 245 | "${PODS_PODFILE_DIR_PATH}/Podfile.lock", 246 | "${PODS_ROOT}/Manifest.lock", 247 | ); 248 | name = "[CP] Check Pods Manifest.lock"; 249 | outputFileListPaths = ( 250 | ); 251 | outputPaths = ( 252 | "$(DERIVED_FILE_DIR)/Pods-Runner-checkManifestLockResult.txt", 253 | ); 254 | runOnlyForDeploymentPostprocessing = 0; 255 | shellPath = /bin/sh; 256 | shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; 257 | showEnvVarsInLog = 0; 258 | }; 259 | 6E99111C159A84302A2E8A9A /* [CP] Embed Pods Frameworks */ = { 260 | isa = PBXShellScriptBuildPhase; 261 | buildActionMask = 2147483647; 262 | files = ( 263 | ); 264 | inputFileListPaths = ( 265 | ); 266 | inputPaths = ( 267 | "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh", 268 | "${PODS_ROOT}/../.symlinks/flutter/ios/Flutter.framework", 269 | "${BUILT_PRODUCTS_DIR}/Reachability/Reachability.framework", 270 | "${BUILT_PRODUCTS_DIR}/keyboard_visibility/keyboard_visibility.framework", 271 | ); 272 | name = "[CP] Embed Pods Frameworks"; 273 | outputFileListPaths = ( 274 | ); 275 | outputPaths = ( 276 | "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Flutter.framework", 277 | "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Reachability.framework", 278 | "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/keyboard_visibility.framework", 279 | ); 280 | runOnlyForDeploymentPostprocessing = 0; 281 | shellPath = /bin/sh; 282 | shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n"; 283 | showEnvVarsInLog = 0; 284 | }; 285 | 9740EEB61CF901F6004384FC /* Run Script */ = { 286 | isa = PBXShellScriptBuildPhase; 287 | buildActionMask = 2147483647; 288 | files = ( 289 | ); 290 | inputPaths = ( 291 | ); 292 | name = "Run Script"; 293 | outputPaths = ( 294 | ); 295 | runOnlyForDeploymentPostprocessing = 0; 296 | shellPath = /bin/sh; 297 | shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build"; 298 | }; 299 | /* End PBXShellScriptBuildPhase section */ 300 | 301 | /* Begin PBXSourcesBuildPhase section */ 302 | 97C146EA1CF9000F007C117D /* Sources */ = { 303 | isa = PBXSourcesBuildPhase; 304 | buildActionMask = 2147483647; 305 | files = ( 306 | 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */, 307 | 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */, 308 | ); 309 | runOnlyForDeploymentPostprocessing = 0; 310 | }; 311 | /* End PBXSourcesBuildPhase section */ 312 | 313 | /* Begin PBXVariantGroup section */ 314 | 97C146FA1CF9000F007C117D /* Main.storyboard */ = { 315 | isa = PBXVariantGroup; 316 | children = ( 317 | 97C146FB1CF9000F007C117D /* Base */, 318 | ); 319 | name = Main.storyboard; 320 | sourceTree = ""; 321 | }; 322 | 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */ = { 323 | isa = PBXVariantGroup; 324 | children = ( 325 | 97C147001CF9000F007C117D /* Base */, 326 | ); 327 | name = LaunchScreen.storyboard; 328 | sourceTree = ""; 329 | }; 330 | /* End PBXVariantGroup section */ 331 | 332 | /* Begin XCBuildConfiguration section */ 333 | 249021D3217E4FDB00AE95B9 /* Profile */ = { 334 | isa = XCBuildConfiguration; 335 | baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; 336 | buildSettings = { 337 | ALWAYS_SEARCH_USER_PATHS = NO; 338 | CLANG_ANALYZER_NONNULL = YES; 339 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 340 | CLANG_CXX_LIBRARY = "libc++"; 341 | CLANG_ENABLE_MODULES = YES; 342 | CLANG_ENABLE_OBJC_ARC = YES; 343 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 344 | CLANG_WARN_BOOL_CONVERSION = YES; 345 | CLANG_WARN_COMMA = YES; 346 | CLANG_WARN_CONSTANT_CONVERSION = YES; 347 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 348 | CLANG_WARN_EMPTY_BODY = YES; 349 | CLANG_WARN_ENUM_CONVERSION = YES; 350 | CLANG_WARN_INFINITE_RECURSION = YES; 351 | CLANG_WARN_INT_CONVERSION = YES; 352 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 353 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 354 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 355 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 356 | CLANG_WARN_STRICT_PROTOTYPES = YES; 357 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 358 | CLANG_WARN_UNREACHABLE_CODE = YES; 359 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 360 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 361 | COPY_PHASE_STRIP = NO; 362 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 363 | ENABLE_NS_ASSERTIONS = NO; 364 | ENABLE_STRICT_OBJC_MSGSEND = YES; 365 | GCC_C_LANGUAGE_STANDARD = gnu99; 366 | GCC_NO_COMMON_BLOCKS = YES; 367 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 368 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 369 | GCC_WARN_UNDECLARED_SELECTOR = YES; 370 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 371 | GCC_WARN_UNUSED_FUNCTION = YES; 372 | GCC_WARN_UNUSED_VARIABLE = YES; 373 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 374 | MTL_ENABLE_DEBUG_INFO = NO; 375 | SDKROOT = iphoneos; 376 | TARGETED_DEVICE_FAMILY = "1,2"; 377 | VALIDATE_PRODUCT = YES; 378 | }; 379 | name = Profile; 380 | }; 381 | 249021D4217E4FDB00AE95B9 /* Profile */ = { 382 | isa = XCBuildConfiguration; 383 | baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; 384 | buildSettings = { 385 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 386 | CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; 387 | DEVELOPMENT_TEAM = G73M4N3655; 388 | ENABLE_BITCODE = NO; 389 | FRAMEWORK_SEARCH_PATHS = ( 390 | "$(inherited)", 391 | "$(PROJECT_DIR)/Flutter", 392 | ); 393 | INFOPLIST_FILE = Runner/Info.plist; 394 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 395 | LIBRARY_SEARCH_PATHS = ( 396 | "$(inherited)", 397 | "$(PROJECT_DIR)/Flutter", 398 | ); 399 | PRODUCT_BUNDLE_IDENTIFIER = com.seanurgel.lifeMonitor; 400 | PRODUCT_NAME = "$(TARGET_NAME)"; 401 | SWIFT_VERSION = 4.0; 402 | VERSIONING_SYSTEM = "apple-generic"; 403 | }; 404 | name = Profile; 405 | }; 406 | 97C147031CF9000F007C117D /* Debug */ = { 407 | isa = XCBuildConfiguration; 408 | baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; 409 | buildSettings = { 410 | ALWAYS_SEARCH_USER_PATHS = NO; 411 | CLANG_ANALYZER_NONNULL = YES; 412 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 413 | CLANG_CXX_LIBRARY = "libc++"; 414 | CLANG_ENABLE_MODULES = YES; 415 | CLANG_ENABLE_OBJC_ARC = YES; 416 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 417 | CLANG_WARN_BOOL_CONVERSION = YES; 418 | CLANG_WARN_COMMA = YES; 419 | CLANG_WARN_CONSTANT_CONVERSION = YES; 420 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 421 | CLANG_WARN_EMPTY_BODY = YES; 422 | CLANG_WARN_ENUM_CONVERSION = YES; 423 | CLANG_WARN_INFINITE_RECURSION = YES; 424 | CLANG_WARN_INT_CONVERSION = YES; 425 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 426 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 427 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 428 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 429 | CLANG_WARN_STRICT_PROTOTYPES = YES; 430 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 431 | CLANG_WARN_UNREACHABLE_CODE = YES; 432 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 433 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 434 | COPY_PHASE_STRIP = NO; 435 | DEBUG_INFORMATION_FORMAT = dwarf; 436 | ENABLE_STRICT_OBJC_MSGSEND = YES; 437 | ENABLE_TESTABILITY = YES; 438 | GCC_C_LANGUAGE_STANDARD = gnu99; 439 | GCC_DYNAMIC_NO_PIC = NO; 440 | GCC_NO_COMMON_BLOCKS = YES; 441 | GCC_OPTIMIZATION_LEVEL = 0; 442 | GCC_PREPROCESSOR_DEFINITIONS = ( 443 | "DEBUG=1", 444 | "$(inherited)", 445 | ); 446 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 447 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 448 | GCC_WARN_UNDECLARED_SELECTOR = YES; 449 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 450 | GCC_WARN_UNUSED_FUNCTION = YES; 451 | GCC_WARN_UNUSED_VARIABLE = YES; 452 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 453 | MTL_ENABLE_DEBUG_INFO = YES; 454 | ONLY_ACTIVE_ARCH = YES; 455 | SDKROOT = iphoneos; 456 | TARGETED_DEVICE_FAMILY = "1,2"; 457 | }; 458 | name = Debug; 459 | }; 460 | 97C147041CF9000F007C117D /* Release */ = { 461 | isa = XCBuildConfiguration; 462 | baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; 463 | buildSettings = { 464 | ALWAYS_SEARCH_USER_PATHS = NO; 465 | CLANG_ANALYZER_NONNULL = YES; 466 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 467 | CLANG_CXX_LIBRARY = "libc++"; 468 | CLANG_ENABLE_MODULES = YES; 469 | CLANG_ENABLE_OBJC_ARC = YES; 470 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 471 | CLANG_WARN_BOOL_CONVERSION = YES; 472 | CLANG_WARN_COMMA = YES; 473 | CLANG_WARN_CONSTANT_CONVERSION = YES; 474 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 475 | CLANG_WARN_EMPTY_BODY = YES; 476 | CLANG_WARN_ENUM_CONVERSION = YES; 477 | CLANG_WARN_INFINITE_RECURSION = YES; 478 | CLANG_WARN_INT_CONVERSION = YES; 479 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 480 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 481 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 482 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 483 | CLANG_WARN_STRICT_PROTOTYPES = YES; 484 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 485 | CLANG_WARN_UNREACHABLE_CODE = YES; 486 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 487 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 488 | COPY_PHASE_STRIP = NO; 489 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 490 | ENABLE_NS_ASSERTIONS = NO; 491 | ENABLE_STRICT_OBJC_MSGSEND = YES; 492 | GCC_C_LANGUAGE_STANDARD = gnu99; 493 | GCC_NO_COMMON_BLOCKS = YES; 494 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 495 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 496 | GCC_WARN_UNDECLARED_SELECTOR = YES; 497 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 498 | GCC_WARN_UNUSED_FUNCTION = YES; 499 | GCC_WARN_UNUSED_VARIABLE = YES; 500 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 501 | MTL_ENABLE_DEBUG_INFO = NO; 502 | SDKROOT = iphoneos; 503 | SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; 504 | TARGETED_DEVICE_FAMILY = "1,2"; 505 | VALIDATE_PRODUCT = YES; 506 | }; 507 | name = Release; 508 | }; 509 | 97C147061CF9000F007C117D /* Debug */ = { 510 | isa = XCBuildConfiguration; 511 | baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; 512 | buildSettings = { 513 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 514 | CLANG_ENABLE_MODULES = YES; 515 | CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; 516 | DEVELOPMENT_TEAM = G73M4N3655; 517 | ENABLE_BITCODE = NO; 518 | FRAMEWORK_SEARCH_PATHS = ( 519 | "$(inherited)", 520 | "$(PROJECT_DIR)/Flutter", 521 | ); 522 | INFOPLIST_FILE = Runner/Info.plist; 523 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 524 | LIBRARY_SEARCH_PATHS = ( 525 | "$(inherited)", 526 | "$(PROJECT_DIR)/Flutter", 527 | ); 528 | PRODUCT_BUNDLE_IDENTIFIER = com.seanurgel.lifeMonitor; 529 | PRODUCT_NAME = "$(TARGET_NAME)"; 530 | SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; 531 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 532 | SWIFT_SWIFT3_OBJC_INFERENCE = On; 533 | SWIFT_VERSION = 4.0; 534 | VERSIONING_SYSTEM = "apple-generic"; 535 | }; 536 | name = Debug; 537 | }; 538 | 97C147071CF9000F007C117D /* Release */ = { 539 | isa = XCBuildConfiguration; 540 | baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; 541 | buildSettings = { 542 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 543 | CLANG_ENABLE_MODULES = YES; 544 | CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; 545 | DEVELOPMENT_TEAM = G73M4N3655; 546 | ENABLE_BITCODE = NO; 547 | FRAMEWORK_SEARCH_PATHS = ( 548 | "$(inherited)", 549 | "$(PROJECT_DIR)/Flutter", 550 | ); 551 | INFOPLIST_FILE = Runner/Info.plist; 552 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 553 | LIBRARY_SEARCH_PATHS = ( 554 | "$(inherited)", 555 | "$(PROJECT_DIR)/Flutter", 556 | ); 557 | PRODUCT_BUNDLE_IDENTIFIER = com.seanurgel.lifeMonitor; 558 | PRODUCT_NAME = "$(TARGET_NAME)"; 559 | SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; 560 | SWIFT_SWIFT3_OBJC_INFERENCE = On; 561 | SWIFT_VERSION = 4.0; 562 | VERSIONING_SYSTEM = "apple-generic"; 563 | }; 564 | name = Release; 565 | }; 566 | /* End XCBuildConfiguration section */ 567 | 568 | /* Begin XCConfigurationList section */ 569 | 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */ = { 570 | isa = XCConfigurationList; 571 | buildConfigurations = ( 572 | 97C147031CF9000F007C117D /* Debug */, 573 | 97C147041CF9000F007C117D /* Release */, 574 | 249021D3217E4FDB00AE95B9 /* Profile */, 575 | ); 576 | defaultConfigurationIsVisible = 0; 577 | defaultConfigurationName = Release; 578 | }; 579 | 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */ = { 580 | isa = XCConfigurationList; 581 | buildConfigurations = ( 582 | 97C147061CF9000F007C117D /* Debug */, 583 | 97C147071CF9000F007C117D /* Release */, 584 | 249021D4217E4FDB00AE95B9 /* Profile */, 585 | ); 586 | defaultConfigurationIsVisible = 0; 587 | defaultConfigurationName = Release; 588 | }; 589 | /* End XCConfigurationList section */ 590 | }; 591 | rootObject = 97C146E61CF9000F007C117D /* Project object */; 592 | } 593 | -------------------------------------------------------------------------------- /ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 31 | 32 | 33 | 34 | 40 | 41 | 42 | 43 | 44 | 45 | 56 | 58 | 64 | 65 | 66 | 67 | 68 | 69 | 75 | 77 | 83 | 84 | 85 | 86 | 88 | 89 | 92 | 93 | 94 | -------------------------------------------------------------------------------- /ios/Runner.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | BuildSystemType 6 | Original 7 | 8 | 9 | -------------------------------------------------------------------------------- /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: [UIApplicationLaunchOptionsKey: Any]? 9 | ) -> Bool { 10 | GeneratedPluginRegistrant.register(with: self) 11 | return super.application(application, didFinishLaunchingWithOptions: launchOptions) 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /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/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fluttertraining/Life-Monitor/cf1fd57dd476b48a81311f8a1d1bcd94d94b1986/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fluttertraining/Life-Monitor/cf1fd57dd476b48a81311f8a1d1bcd94d94b1986/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/fluttertraining/Life-Monitor/cf1fd57dd476b48a81311f8a1d1bcd94d94b1986/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/fluttertraining/Life-Monitor/cf1fd57dd476b48a81311f8a1d1bcd94d94b1986/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/fluttertraining/Life-Monitor/cf1fd57dd476b48a81311f8a1d1bcd94d94b1986/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/fluttertraining/Life-Monitor/cf1fd57dd476b48a81311f8a1d1bcd94d94b1986/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/fluttertraining/Life-Monitor/cf1fd57dd476b48a81311f8a1d1bcd94d94b1986/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/fluttertraining/Life-Monitor/cf1fd57dd476b48a81311f8a1d1bcd94d94b1986/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/fluttertraining/Life-Monitor/cf1fd57dd476b48a81311f8a1d1bcd94d94b1986/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/fluttertraining/Life-Monitor/cf1fd57dd476b48a81311f8a1d1bcd94d94b1986/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/fluttertraining/Life-Monitor/cf1fd57dd476b48a81311f8a1d1bcd94d94b1986/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/fluttertraining/Life-Monitor/cf1fd57dd476b48a81311f8a1d1bcd94d94b1986/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/fluttertraining/Life-Monitor/cf1fd57dd476b48a81311f8a1d1bcd94d94b1986/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/fluttertraining/Life-Monitor/cf1fd57dd476b48a81311f8a1d1bcd94d94b1986/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fluttertraining/Life-Monitor/cf1fd57dd476b48a81311f8a1d1bcd94d94b1986/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fluttertraining/Life-Monitor/cf1fd57dd476b48a81311f8a1d1bcd94d94b1986/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fluttertraining/Life-Monitor/cf1fd57dd476b48a81311f8a1d1bcd94d94b1986/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fluttertraining/Life-Monitor/cf1fd57dd476b48a81311f8a1d1bcd94d94b1986/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png -------------------------------------------------------------------------------- /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. -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | en 7 | CFBundleDisplayName 8 | Life Monitor 9 | CFBundleExecutable 10 | $(EXECUTABLE_NAME) 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | budget_planner 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | $(FLUTTER_BUILD_NAME) 21 | CFBundleSignature 22 | ???? 23 | CFBundleVersion 24 | $(FLUTTER_BUILD_NUMBER) 25 | LSRequiresIPhoneOS 26 | 27 | UILaunchStoryboardName 28 | LaunchScreen 29 | UIMainStoryboardFile 30 | Main 31 | UISupportedInterfaceOrientations 32 | 33 | UIInterfaceOrientationPortrait 34 | UIInterfaceOrientationLandscapeLeft 35 | UIInterfaceOrientationLandscapeRight 36 | 37 | UISupportedInterfaceOrientations~ipad 38 | 39 | UIInterfaceOrientationPortrait 40 | UIInterfaceOrientationPortraitUpsideDown 41 | UIInterfaceOrientationLandscapeLeft 42 | UIInterfaceOrientationLandscapeRight 43 | 44 | UIViewControllerBasedStatusBarAppearance 45 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /ios/Runner/Runner-Bridging-Header.h: -------------------------------------------------------------------------------- 1 | #import "GeneratedPluginRegistrant.h" -------------------------------------------------------------------------------- /lib/config/enums.dart: -------------------------------------------------------------------------------- 1 | enum TransactionTypes { Income, Expense } 2 | -------------------------------------------------------------------------------- /lib/main.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/cupertino.dart'; 2 | import 'package:flutter/material.dart'; 3 | 4 | import 'package:budget_planner/screens/add_bank.dart'; 5 | import 'package:budget_planner/screens/add_bank_success.dart'; 6 | import 'package:budget_planner/screens/budget.dart'; 7 | import 'package:budget_planner/screens/login.dart'; 8 | import 'package:budget_planner/screens/register.dart'; 9 | 10 | import 'package:budget_planner/screens/budget/add_transaction.dart'; 11 | 12 | void main() => runApp(MyApp()); 13 | 14 | class MyApp extends StatelessWidget { 15 | @override 16 | Widget build(BuildContext context) { 17 | return MaterialApp( 18 | title: 'Flutter Demo', 19 | initialRoute: '/', 20 | onUnknownRoute: (any) { 21 | print('in the inital [onUnknowRoute]'); 22 | }, 23 | onGenerateRoute: (RouteSettings settings) { 24 | switch (settings.name) { 25 | case '/': 26 | return CupertinoPageRoute( 27 | builder: (_) => LoginScreen(), settings: settings); 28 | case '/register': 29 | return CupertinoPageRoute( 30 | builder: (_) => RegisterScreen(), settings: settings); 31 | case '/add-bank': 32 | return CupertinoPageRoute( 33 | builder: (_) => AddBankScreen(), settings: settings); 34 | case '/add-bank-success': 35 | return CupertinoPageRoute( 36 | builder: (_) => AddBankSuccessScreen(), 37 | settings: settings, 38 | fullscreenDialog: true, 39 | ); 40 | case '/budget-screen': 41 | return CupertinoPageRoute( 42 | builder: (_) => BudgetScreen(), 43 | settings: settings, 44 | ); 45 | 46 | case '/add-transaction': 47 | return CupertinoPageRoute( 48 | builder: (_) => AddTransactionScreen(), 49 | settings: settings, 50 | fullscreenDialog: true, 51 | ); 52 | } 53 | }, 54 | theme: ThemeData( 55 | primaryColor: Color.fromRGBO(255, 51, 120, 1), 56 | fontFamily: 'GT-Walshiem-Pro', 57 | scaffoldBackgroundColor: Color.fromRGBO(242, 242, 242, 1), 58 | textTheme: TextTheme( 59 | subtitle: TextStyle( 60 | fontSize: 12, 61 | ), 62 | title: TextStyle( 63 | fontSize: 26, 64 | fontWeight: FontWeight.w700, 65 | ), 66 | ), 67 | ), 68 | ); 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /lib/screens/add_bank.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:keyboard_visibility/keyboard_visibility.dart'; 3 | 4 | import 'package:budget_planner/widgets/custom_textfield.dart'; 5 | import 'package:budget_planner/widgets/custom_form.dart'; 6 | import 'package:budget_planner/widgets/rounded_appbar.dart'; 7 | import 'package:budget_planner/widgets/zoom_in_out_image.dart'; 8 | 9 | class AddBankScreen extends StatefulWidget { 10 | @override 11 | _AddBankScreenState createState() => _AddBankScreenState(); 12 | } 13 | 14 | class _AddBankScreenState extends State { 15 | bool _isKeyboardOpen = false; 16 | 17 | @override 18 | void initState() { 19 | super.initState(); 20 | 21 | KeyboardVisibilityNotification().addNewListener( 22 | onChange: (bool visible) { 23 | setState(() { 24 | _isKeyboardOpen = visible; 25 | }); 26 | }, 27 | ); 28 | } 29 | 30 | @override 31 | Widget build(BuildContext context) { 32 | return Scaffold( 33 | appBar: PreferredSize( 34 | preferredSize: Size(MediaQuery.of(context).size.width, 0), 35 | child: Container(color: Colors.white), 36 | ), 37 | body: Column( 38 | children: [ 39 | new _AppBar(), 40 | Expanded( 41 | child: Container( 42 | padding: EdgeInsets.only(left: 32, right: 32), 43 | child: ListView( 44 | children: [ 45 | ZoomInOutImage( 46 | height: 175, 47 | child: new _AddBankImage(isKeyboardOpen: _isKeyboardOpen), 48 | ), 49 | Container( 50 | margin: EdgeInsets.only(top: 50, bottom: 50), 51 | padding: EdgeInsets.only(right: 25), 52 | child: Text( 53 | 'Add primary bank account', 54 | style: Theme.of(context).textTheme.title, 55 | ), 56 | ), 57 | new _AddBankForm( 58 | onSubmit: () { 59 | Navigator.of(context).pushNamed('/add-bank-success'); 60 | }, 61 | ), 62 | ], 63 | ), 64 | ), 65 | ) 66 | ], 67 | ), 68 | ); 69 | } 70 | } 71 | 72 | class _AddBankImage extends StatelessWidget { 73 | const _AddBankImage({ 74 | Key key, 75 | @required bool isKeyboardOpen, 76 | }) : _isKeyboardOpen = isKeyboardOpen, 77 | super(key: key); 78 | 79 | final bool _isKeyboardOpen; 80 | 81 | @override 82 | Widget build(BuildContext context) { 83 | return Stack( 84 | overflow: Overflow.visible, 85 | children: [ 86 | Image.asset( 87 | 'assets/images/bank.png', 88 | height: 200, 89 | filterQuality: FilterQuality.high, 90 | ), 91 | AnimatedPositioned( 92 | duration: Duration(milliseconds: 500), 93 | curve: Curves.easeInOutExpo, 94 | top: _isKeyboardOpen ? -10 : -25, 95 | right: _isKeyboardOpen ? -25 : -50, 96 | child: Image.asset( 97 | 'assets/images/add_circle.png', 98 | height: _isKeyboardOpen ? 50 : 115, 99 | width: _isKeyboardOpen ? 50 : 115, 100 | filterQuality: FilterQuality.high, 101 | ), 102 | ) 103 | ], 104 | ); 105 | } 106 | } 107 | 108 | class _AddBankForm extends StatelessWidget { 109 | const _AddBankForm({ 110 | Key key, 111 | @required this.onSubmit, 112 | }) : super(key: key); 113 | 114 | final Function onSubmit; 115 | 116 | @override 117 | Widget build(BuildContext context) { 118 | return Container( 119 | height: 115, 120 | child: CustomForm( 121 | onPressed: this.onSubmit, 122 | textFields: [ 123 | new CustomTextField( 124 | placeholder: 'Account name here', 125 | label: 'Account Name', 126 | ), 127 | new CustomTextField( 128 | placeholder: '\$0,000', 129 | label: 'Starter Amount', 130 | keyboardType: TextInputType.number, 131 | ), 132 | ], 133 | ), 134 | ); 135 | } 136 | } 137 | 138 | class _AppBar extends StatelessWidget { 139 | const _AppBar({ 140 | Key key, 141 | }) : super(key: key); 142 | 143 | @override 144 | Widget build(BuildContext context) { 145 | return Column( 146 | children: [ 147 | RoundedAppBar( 148 | padding: EdgeInsets.symmetric(horizontal: 6.0), 149 | height: 85, 150 | child: Row( 151 | children: [ 152 | IconButton( 153 | icon: Icon(Icons.arrow_back), 154 | onPressed: () => Navigator.of(context).pop(), 155 | ), 156 | SizedBox(width: 10), 157 | Text( 158 | 'Add account', 159 | style: Theme.of(context).textTheme.title.copyWith(fontSize: 22), 160 | ), 161 | ], 162 | ), 163 | ), 164 | ], 165 | ); 166 | } 167 | } 168 | -------------------------------------------------------------------------------- /lib/screens/add_bank_success.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | import 'package:budget_planner/widgets/custom_button.dart'; 4 | 5 | class AddBankSuccessScreen extends StatelessWidget { 6 | @override 7 | Widget build(BuildContext context) { 8 | return Scaffold( 9 | body: Container( 10 | height: MediaQuery.of(context).size.height, 11 | child: Column( 12 | mainAxisAlignment: MainAxisAlignment.center, 13 | children: [ 14 | Image.asset( 15 | 'assets/images/confetti.png', 16 | height: 175, 17 | width: MediaQuery.of(context).size.width, 18 | filterQuality: FilterQuality.high, 19 | ), 20 | SizedBox(height: 40), 21 | Text( 22 | 'Congratulations!', 23 | style: Theme.of(context).textTheme.title, 24 | ), 25 | SizedBox(height: 20), 26 | Container( 27 | width: MediaQuery.of(context).size.width * .8, 28 | child: Text( 29 | 'Your bank account is added successfully to the app!', 30 | style: TextStyle( 31 | fontSize: 16, 32 | fontWeight: FontWeight.w300, 33 | ), 34 | textAlign: TextAlign.center, 35 | ), 36 | ), 37 | SizedBox(height: 40), 38 | CustomButton( 39 | child: Text( 40 | 'Get Started', 41 | style: TextStyle( 42 | color: Colors.white, 43 | fontSize: 16, 44 | ), 45 | ), 46 | width: MediaQuery.of(context).size.width * .8, 47 | height: 60, 48 | onTap: () { 49 | Navigator.of(context).pushNamedAndRemoveUntil( 50 | '/budget-screen', 51 | (Route route) => false, 52 | ); 53 | }, 54 | ), 55 | ], 56 | ), 57 | ), 58 | ); 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /lib/screens/add_transaction/details.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | import 'package:budget_planner/config/enums.dart'; 4 | import 'package:budget_planner/widgets/custom_form.dart'; 5 | import 'package:budget_planner/widgets/custom_textfield.dart'; 6 | 7 | class TransactionDetails extends StatefulWidget { 8 | TransactionDetails({ 9 | Key key, 10 | @required this.transactionType, 11 | }) : super(key: key); 12 | 13 | final TransactionTypes transactionType; 14 | 15 | @override 16 | _TransactionDetailsState createState() => _TransactionDetailsState(); 17 | } 18 | 19 | class _TransactionDetailsState extends State { 20 | FocusNode focusNode; 21 | bool hasBeenFocused = false; 22 | 23 | @override 24 | void initState() { 25 | super.initState(); 26 | 27 | this.focusNode = FocusNode(); 28 | } 29 | 30 | @override 31 | void dispose() { 32 | focusNode.dispose(); 33 | 34 | super.dispose(); 35 | } 36 | 37 | @override 38 | Widget build(BuildContext context) { 39 | String type; 40 | IconData icon; 41 | Color iconColor; 42 | 43 | if (!hasBeenFocused) { 44 | FocusScope.of(context).requestFocus(focusNode); 45 | 46 | setState(() { 47 | hasBeenFocused = true; 48 | }); 49 | } 50 | 51 | if (this.widget.transactionType == TransactionTypes.Expense) { 52 | type = 'Expense'; 53 | icon = Icons.fast_forward; 54 | iconColor = Theme.of(context).primaryColor; 55 | } else { 56 | type = 'Income'; 57 | icon = Icons.fast_rewind; 58 | iconColor = Color.fromRGBO(51, 201, 255, 1); 59 | } 60 | 61 | return Container( 62 | margin: EdgeInsets.only( 63 | top: 24, 64 | bottom: 50, 65 | ), 66 | child: Column( 67 | mainAxisAlignment: MainAxisAlignment.spaceBetween, 68 | children: [ 69 | Column( 70 | children: [ 71 | new _TransactionType( 72 | icon: icon, 73 | iconColor: iconColor, 74 | type: type, 75 | ), 76 | ], 77 | ), 78 | CustomForm( 79 | onPressed: () {}, 80 | textFields: [ 81 | CustomTextField( 82 | label: 'Payee Name', 83 | placeholder: 'Cereal & Milk', 84 | focusNode: this.focusNode, 85 | ), 86 | ], 87 | ), 88 | ], 89 | ), 90 | ); 91 | } 92 | } 93 | 94 | class _TransactionType extends StatelessWidget { 95 | const _TransactionType({ 96 | Key key, 97 | @required this.icon, 98 | @required this.iconColor, 99 | @required this.type, 100 | }) : super(key: key); 101 | 102 | final IconData icon; 103 | final Color iconColor; 104 | final String type; 105 | 106 | @override 107 | Widget build(BuildContext context) { 108 | return Row( 109 | children: [ 110 | CircleAvatar( 111 | child: Icon( 112 | icon, 113 | color: Colors.white, 114 | ), 115 | backgroundColor: iconColor, 116 | ), 117 | SizedBox(width: 15), 118 | SizedBox( 119 | height: 45, 120 | child: Column( 121 | mainAxisAlignment: MainAxisAlignment.spaceBetween, 122 | crossAxisAlignment: CrossAxisAlignment.start, 123 | children: [ 124 | Text('Transaction Type'), 125 | Text( 126 | type, 127 | style: TextStyle( 128 | fontSize: 20, 129 | fontWeight: FontWeight.w800, 130 | ), 131 | ), 132 | ], 133 | ), 134 | ) 135 | ], 136 | ); 137 | } 138 | } 139 | -------------------------------------------------------------------------------- /lib/screens/add_transaction/type.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | import 'package:budget_planner/config/enums.dart'; 4 | 5 | class TransactionType extends StatelessWidget { 6 | const TransactionType({ 7 | Key key, 8 | @required this.onTransactionTypePressed, 9 | }) : super(key: key); 10 | 11 | final Function(TransactionTypes type) onTransactionTypePressed; 12 | 13 | @override 14 | Widget build(BuildContext context) { 15 | return ListView( 16 | // crossAxisAlignment: CrossAxisAlignment.start, 17 | children: [ 18 | SizedBox(height: 50), 19 | Container( 20 | alignment: Alignment.center, 21 | child: Image.asset( 22 | 'assets/images/using_phone.png', 23 | height: MediaQuery.of(context).size.height * .3, 24 | ), 25 | ), 26 | Container( 27 | margin: EdgeInsets.only( 28 | top: 45, 29 | bottom: 25, 30 | ), 31 | alignment: Alignment.centerLeft, 32 | width: MediaQuery.of(context).size.width * .65, 33 | child: Text( 34 | 'What kind of transaction is it?', 35 | style: Theme.of(context).textTheme.title, 36 | ), 37 | ), 38 | LayoutBuilder(builder: (BuildContext context, BoxConstraints size) { 39 | return Row( 40 | mainAxisAlignment: MainAxisAlignment.spaceAround, 41 | children: [ 42 | new _CategoryCard( 43 | width: size.maxWidth * .45, 44 | iconBgColor: Color.fromRGBO(51, 201, 255, 1), 45 | transactionType: TransactionTypes.Income, 46 | onPressed: () => 47 | this.onTransactionTypePressed(TransactionTypes.Income), 48 | ), 49 | new _CategoryCard( 50 | width: size.maxWidth * .45, 51 | iconBgColor: Theme.of(context).primaryColor, 52 | transactionType: TransactionTypes.Expense, 53 | onPressed: () => 54 | this.onTransactionTypePressed(TransactionTypes.Expense), 55 | ), 56 | ], 57 | ); 58 | }), 59 | ], 60 | ); 61 | } 62 | } 63 | 64 | class _CategoryCard extends StatelessWidget { 65 | const _CategoryCard({ 66 | Key key, 67 | @required this.width, 68 | @required this.iconBgColor, 69 | @required this.transactionType, 70 | @required this.onPressed, 71 | }) : super(key: key); 72 | 73 | final double width; 74 | final Color iconBgColor; 75 | final TransactionTypes transactionType; 76 | final Function onPressed; 77 | 78 | @override 79 | Widget build(BuildContext context) { 80 | return Material( 81 | color: Colors.white, 82 | borderRadius: BorderRadius.circular(12.0), 83 | elevation: 2, 84 | child: InkWell( 85 | onTap: this.onPressed, 86 | child: Container( 87 | width: this.width, 88 | height: 150, 89 | padding: EdgeInsets.symmetric(vertical: 24, horizontal: 24), 90 | child: Column( 91 | crossAxisAlignment: CrossAxisAlignment.start, 92 | mainAxisAlignment: MainAxisAlignment.spaceBetween, 93 | children: [ 94 | CircleAvatar( 95 | backgroundColor: this.iconBgColor, 96 | child: Icon( 97 | this.transactionType == TransactionTypes.Expense 98 | ? Icons.fast_forward 99 | : Icons.fast_rewind, 100 | color: Colors.white, 101 | ), 102 | ), 103 | Text( 104 | this.transactionType == TransactionTypes.Expense 105 | ? 'Expense' 106 | : 'Income', 107 | style: TextStyle( 108 | fontWeight: FontWeight.w800, 109 | fontSize: 20, 110 | ), 111 | ), 112 | ], 113 | ), 114 | decoration: BoxDecoration( 115 | borderRadius: BorderRadius.circular(12.0), 116 | ), 117 | ), 118 | ), 119 | ); 120 | } 121 | } 122 | -------------------------------------------------------------------------------- /lib/screens/budget.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/cupertino.dart'; 2 | import 'package:flutter/material.dart'; 3 | 4 | import 'package:budget_planner/screens/budget/daily_transactions.dart'; 5 | import 'package:budget_planner/screens/budget/transaction_summary.dart'; 6 | 7 | class BudgetScreen extends StatefulWidget { 8 | @override 9 | _BudgetScreenState createState() => _BudgetScreenState(); 10 | } 11 | 12 | class _BudgetScreenState extends State { 13 | int _selectedIndex = 0; 14 | 15 | final dailyTransactionsPage = Navigator( 16 | initialRoute: '/', 17 | onUnknownRoute: (any) { 18 | print('unknown route'); 19 | }, 20 | onGenerateRoute: (RouteSettings settings) { 21 | switch (settings.name) { 22 | case '/': 23 | return CupertinoPageRoute( 24 | builder: (_) => DailyTransactionsScreen(), 25 | settings: settings, 26 | ); 27 | 28 | case '/transaction-summary': 29 | return CupertinoPageRoute( 30 | builder: (_) => TransactionSummary(), 31 | settings: settings, 32 | ); 33 | } 34 | }, 35 | ); 36 | 37 | void _onItemTapped(int index) { 38 | setState(() { 39 | _selectedIndex = index; 40 | // controller.animateTo(index); 41 | }); 42 | } 43 | 44 | @override 45 | Widget build(BuildContext context) { 46 | return Scaffold( 47 | body: Stack( 48 | children: [ 49 | Offstage( 50 | offstage: _selectedIndex != 0, 51 | child: dailyTransactionsPage, 52 | ), 53 | Offstage( 54 | offstage: _selectedIndex != 1, 55 | child: Text('Page'), 56 | ), 57 | Offstage( 58 | offstage: _selectedIndex != 2, 59 | child: Text('Page'), 60 | ), 61 | Offstage( 62 | offstage: _selectedIndex != 3, 63 | child: Text('Page'), 64 | ), 65 | ], 66 | ), 67 | floatingActionButton: FloatingActionButton( 68 | elevation: 0, 69 | backgroundColor: Theme.of(context).primaryColor, 70 | child: Icon( 71 | Icons.add, 72 | size: 32, 73 | ), 74 | onPressed: () { 75 | Navigator.of(context).pushNamed('/add-transaction'); 76 | }, 77 | ), 78 | floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked, 79 | bottomNavigationBar: BottomNavigationBar( 80 | elevation: 0, 81 | unselectedItemColor: Colors.grey, 82 | selectedItemColor: Colors.black, 83 | type: BottomNavigationBarType.fixed, 84 | items: [ 85 | BottomNavigationBarItem( 86 | icon: Icon(Icons.calendar_today), 87 | title: Text('Daily'), 88 | ), 89 | BottomNavigationBarItem( 90 | icon: Icon(Icons.insert_chart), 91 | title: Text('Stats'), 92 | ), 93 | BottomNavigationBarItem( 94 | icon: Icon(Icons.account_balance_wallet), 95 | title: Text('Budget'), 96 | ), 97 | BottomNavigationBarItem( 98 | icon: Icon(Icons.person), 99 | title: Text('Profile'), 100 | ), 101 | ], 102 | currentIndex: _selectedIndex, 103 | onTap: _onItemTapped, 104 | ), 105 | ); 106 | } 107 | } 108 | -------------------------------------------------------------------------------- /lib/screens/budget/add_transaction.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | import 'package:budget_planner/config/enums.dart'; 4 | import 'package:budget_planner/screens/add_transaction/details.dart'; 5 | import 'package:budget_planner/screens/add_transaction/type.dart'; 6 | import 'package:budget_planner/widgets/rounded_appbar.dart'; 7 | 8 | class AddTransactionScreen extends StatefulWidget { 9 | @override 10 | _AddTransactionScreenState createState() => _AddTransactionScreenState(); 11 | } 12 | 13 | class _AddTransactionScreenState extends State { 14 | TransactionTypes transactionType; 15 | 16 | void _onTransactionTypePressed(TransactionTypes selectedType) { 17 | _pageController.animateToPage( 18 | 1, 19 | duration: Duration(milliseconds: 300), 20 | curve: Curves.easeIn, 21 | ); 22 | 23 | setState(() { 24 | transactionType = selectedType; 25 | print('Updated transactionType to $transactionType'); 26 | }); 27 | } 28 | 29 | @override 30 | void initState() { 31 | super.initState(); 32 | } 33 | 34 | final _pageController = PageController( 35 | initialPage: 0, 36 | ); 37 | 38 | @override 39 | Widget build(BuildContext context) { 40 | return Scaffold( 41 | appBar: PreferredSize( 42 | preferredSize: Size(MediaQuery.of(context).size.width, 0), 43 | child: Container(color: Colors.white), 44 | ), 45 | body: Container( 46 | child: Column( 47 | children: [ 48 | new _AppBar(), 49 | Expanded( 50 | child: Padding( 51 | padding: const EdgeInsets.symmetric(horizontal: 30), 52 | child: PageView( 53 | physics: transactionType == null 54 | ? NeverScrollableScrollPhysics() 55 | : null, 56 | controller: _pageController, 57 | children: [ 58 | new TransactionType( 59 | onTransactionTypePressed: this._onTransactionTypePressed, 60 | ), 61 | new TransactionDetails( 62 | transactionType: this.transactionType, 63 | ), 64 | ], 65 | ), 66 | ), 67 | ) 68 | ], 69 | ), 70 | ), 71 | ); 72 | } 73 | } 74 | 75 | class _AppBar extends StatelessWidget { 76 | const _AppBar({ 77 | Key key, 78 | }) : super(key: key); 79 | 80 | @override 81 | Widget build(BuildContext context) { 82 | return RoundedAppBar( 83 | height: 80, 84 | padding: EdgeInsets.symmetric(horizontal: 12), 85 | child: Row( 86 | children: [ 87 | IconButton( 88 | icon: Icon(Icons.clear), 89 | onPressed: () => Navigator.of(context).pop(), 90 | ), 91 | Text( 92 | 'Add Transaction', 93 | style: Theme.of(context).textTheme.title.copyWith( 94 | fontSize: 20, 95 | ), 96 | ), 97 | ], 98 | ), 99 | ); 100 | } 101 | } 102 | -------------------------------------------------------------------------------- /lib/screens/budget/daily_transactions.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutter_calendar_carousel/flutter_calendar_carousel.dart' 3 | show CalendarCarousel; 4 | 5 | import 'package:budget_planner/widgets/rounded_appbar.dart'; 6 | 7 | class DailyTransactionsScreen extends StatefulWidget { 8 | @override 9 | _DailyTransactionsScreenState createState() => 10 | _DailyTransactionsScreenState(); 11 | } 12 | 13 | class _DailyTransactionsScreenState extends State { 14 | DateTime _currentDate; 15 | int _day; 16 | bool _isSelecting = false; 17 | 18 | void _onDayPressed(DateTime date, _) { 19 | this.setState(() { 20 | _currentDate = date; 21 | _day = date.day; 22 | _isSelecting = true; 23 | }); 24 | } 25 | 26 | void _onHeaderTitlePressed() { 27 | this.setState(() { 28 | _isSelecting = !_isSelecting; 29 | }); 30 | } 31 | 32 | @override 33 | Widget build(BuildContext context) { 34 | final textStyle = TextStyle( 35 | fontFamily: 'GT-Walshiem-Pro', 36 | ); 37 | 38 | return Scaffold( 39 | appBar: AppBar( 40 | backgroundColor: Colors.white, 41 | title: Text( 42 | 'Daily Transactions', 43 | style: TextStyle( 44 | color: Colors.black, 45 | fontSize: 22, 46 | fontWeight: FontWeight.w800, 47 | ), 48 | ), 49 | actions: [ 50 | IconButton( 51 | icon: Icon(Icons.search, color: Colors.black, size: 28), 52 | onPressed: () {}, 53 | ), 54 | ], 55 | centerTitle: false, 56 | elevation: 0, 57 | ), 58 | body: Column( 59 | children: [ 60 | RoundedAppBar( 61 | padding: EdgeInsets.symmetric(horizontal: 10), 62 | isAnimated: true, 63 | height: _isSelecting ? 400 : 120, 64 | child: CalendarCarousel( 65 | onDayPressed: _onDayPressed, 66 | isScrollable: false, 67 | height: _isSelecting ? 450 : 120, 68 | onHeaderTitlePressed: _onHeaderTitlePressed, 69 | weekendTextStyle: TextStyle( 70 | color: Colors.black, 71 | ), 72 | headerTitleTouchable: true, 73 | iconColor: Theme.of(context).primaryColor, 74 | weekFormat: !_isSelecting, 75 | selectedDateTime: _currentDate, 76 | todayButtonColor: Colors.grey[100], 77 | todayTextStyle: textStyle.copyWith(color: Colors.black), 78 | selectedDayButtonColor: Theme.of(context).primaryColor, 79 | selectedDayTextStyle: textStyle.copyWith(color: Colors.white), 80 | daysTextStyle: textStyle, 81 | weekdayTextStyle: textStyle.copyWith(color: Colors.grey[400]), 82 | nextDaysTextStyle: textStyle, 83 | headerTextStyle: textStyle.copyWith(color: Colors.black), 84 | showHeader: _isSelecting, 85 | weekDayMargin: EdgeInsets.only( 86 | top: _isSelecting ? 0 : 20, 87 | ), 88 | ), 89 | ), 90 | Expanded( 91 | child: GestureDetector( 92 | onTap: () { 93 | setState(() { 94 | _isSelecting = false; 95 | }); 96 | }, 97 | child: Container( 98 | padding: EdgeInsets.symmetric(horizontal: 28), 99 | child: _day == 23 100 | ? new _TransactionList() 101 | : new _EmptyState(isSelecting: _isSelecting), 102 | ), 103 | ), 104 | ) 105 | ], 106 | ), 107 | ); 108 | } 109 | } 110 | 111 | class _TransactionList extends StatelessWidget { 112 | const _TransactionList({ 113 | Key key, 114 | }) : super(key: key); 115 | 116 | @override 117 | Widget build(BuildContext context) { 118 | return ListView.builder( 119 | padding: EdgeInsets.only(top: 32), 120 | itemCount: 7, 121 | itemBuilder: (BuildContext context, int ndx) { 122 | return new _TransactionItem(); 123 | }, 124 | ); 125 | } 126 | } 127 | 128 | class _TransactionItem extends StatelessWidget { 129 | const _TransactionItem({ 130 | Key key, 131 | }) : super(key: key); 132 | 133 | @override 134 | Widget build(BuildContext context) { 135 | return Container( 136 | margin: EdgeInsets.only(bottom: 20), 137 | child: Material( 138 | color: Colors.transparent, 139 | child: InkWell( 140 | onTap: () { 141 | Navigator.of(context).pushNamed('/transaction-summary'); 142 | }, 143 | child: Row( 144 | crossAxisAlignment: CrossAxisAlignment.start, 145 | children: [ 146 | Image.asset( 147 | 'assets/images/pill.png', 148 | height: 50, 149 | filterQuality: FilterQuality.high, 150 | fit: BoxFit.cover, 151 | ), 152 | SizedBox(width: 15), 153 | Expanded( 154 | child: LayoutBuilder( 155 | builder: (BuildContext context, BoxConstraints size) { 156 | return Container( 157 | child: Column( 158 | crossAxisAlignment: CrossAxisAlignment.start, 159 | children: [ 160 | Row( 161 | mainAxisAlignment: MainAxisAlignment.spaceBetween, 162 | children: [ 163 | Text( 164 | 'Paper Bags', 165 | style: TextStyle( 166 | fontWeight: FontWeight.w500, 167 | fontSize: 16, 168 | ), 169 | ), 170 | Text( 171 | "\$340.40", 172 | style: TextStyle( 173 | color: Color.fromRGBO(25, 234, 37, 1), 174 | fontWeight: FontWeight.w500, 175 | fontSize: 16, 176 | ), 177 | ), 178 | ], 179 | ), 180 | SizedBox(height: 7.5), 181 | Text( 182 | 'Fri 10AM', 183 | style: TextStyle( 184 | color: Colors.grey[500], 185 | ), 186 | ), 187 | Container( 188 | padding: EdgeInsets.only(bottom: 15), 189 | width: size.maxWidth, 190 | decoration: BoxDecoration( 191 | border: Border( 192 | bottom: BorderSide( 193 | color: Colors.grey[300], 194 | ), 195 | ), 196 | ), 197 | ) 198 | ], 199 | ), 200 | ); 201 | }, 202 | ), 203 | ), 204 | ], 205 | ), 206 | ), 207 | ), 208 | ); 209 | } 210 | } 211 | 212 | class _EmptyState extends StatelessWidget { 213 | const _EmptyState({ 214 | Key key, 215 | @required this.isSelecting, 216 | }) : super(key: key); 217 | 218 | final bool isSelecting; 219 | 220 | @override 221 | Widget build(BuildContext context) { 222 | return ListView( 223 | physics: !isSelecting ? null : NeverScrollableScrollPhysics(), 224 | padding: EdgeInsets.only(top: 25), 225 | children: [ 226 | Image.asset( 227 | 'assets/images/no_transaction_yet.png', 228 | height: MediaQuery.of(context).size.height * .30, 229 | filterQuality: FilterQuality.high, 230 | ), 231 | Column( 232 | children: [ 233 | Text( 234 | 'No transaction yet', 235 | style: Theme.of(context).textTheme.title, 236 | ), 237 | SizedBox(height: 17.5), 238 | Text( 239 | 'You can add transaction by tapping the', 240 | style: TextStyle( 241 | fontSize: 15, 242 | ), 243 | ), 244 | SizedBox(height: 7.5), 245 | Text( 246 | '+ button below', 247 | style: TextStyle( 248 | fontSize: 15, 249 | ), 250 | ), 251 | SizedBox(height: 25.5), 252 | Image.asset( 253 | 'assets/images/line_down.png', 254 | height: 65, 255 | filterQuality: FilterQuality.high, 256 | ), 257 | ], 258 | ) 259 | ], 260 | ); 261 | } 262 | } 263 | -------------------------------------------------------------------------------- /lib/screens/budget/transaction_summary.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | class TransactionSummary extends StatefulWidget { 4 | @override 5 | _TransactionSummaryState createState() => _TransactionSummaryState(); 6 | } 7 | 8 | class _TransactionSummaryState extends State { 9 | @override 10 | Widget build(BuildContext context) { 11 | return Scaffold( 12 | appBar: AppBar( 13 | title: Text('Trasaction Summary Screen'), 14 | ), 15 | body: Center( 16 | child: Text('Trasaction Summary Screen'), 17 | ), 18 | ); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /lib/screens/login.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/cupertino.dart'; 2 | import 'package:flutter/material.dart'; 3 | 4 | import 'package:budget_planner/widgets/auth_container.dart'; 5 | import 'package:budget_planner/widgets/custom_form.dart'; 6 | import 'package:budget_planner/widgets/custom_textfield.dart'; 7 | 8 | class LoginScreen extends StatefulWidget { 9 | @override 10 | _LoginScreenState createState() => _LoginScreenState(); 11 | } 12 | 13 | class _LoginScreenState extends State { 14 | @override 15 | Widget build(BuildContext context) { 16 | return AuthContainer( 17 | isLogin: true, 18 | onTapHeaderAction: () { 19 | Navigator.of(context).pushReplacementNamed('/register'); 20 | }, 21 | child: Column( 22 | crossAxisAlignment: CrossAxisAlignment.start, 23 | children: [ 24 | Text( 25 | 'Login to your account', 26 | style: Theme.of(context).textTheme.title, 27 | textAlign: TextAlign.start, 28 | ), 29 | SizedBox(height: 20), 30 | new _LoginForm( 31 | onTapSubmit: () { 32 | Navigator.of(context).pushNamed('/add-bank'); 33 | }, 34 | ), 35 | ], 36 | ), 37 | ); 38 | } 39 | } 40 | 41 | class _LoginForm extends StatelessWidget { 42 | final Function onTapSubmit; 43 | 44 | const _LoginForm({ 45 | Key key, 46 | @required this.onTapSubmit, 47 | }) : super(key: key); 48 | 49 | @override 50 | Widget build(BuildContext context) { 51 | return SizedBox( 52 | height: 110, 53 | child: CustomForm( 54 | onPressed: onTapSubmit, 55 | textFields: [ 56 | new CustomTextField( 57 | placeholder: 'name@domain.com', 58 | label: 'Email', 59 | ), 60 | new CustomTextField( 61 | placeholder: '************', 62 | label: 'Password', 63 | password: true, 64 | ), 65 | ], 66 | ), 67 | ); 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /lib/screens/register.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | import 'package:budget_planner/widgets/auth_container.dart'; 4 | import 'package:budget_planner/widgets/custom_form.dart'; 5 | import 'package:budget_planner/widgets/custom_textfield.dart'; 6 | 7 | class RegisterScreen extends StatelessWidget { 8 | @override 9 | Widget build(BuildContext context) { 10 | return AuthContainer( 11 | onTapHeaderAction: () { 12 | Navigator.of(context).pushReplacementNamed('/'); 13 | }, 14 | child: Column( 15 | crossAxisAlignment: CrossAxisAlignment.start, 16 | children: [ 17 | Text( 18 | 'Sign up to Budget tracker', 19 | style: Theme.of(context).textTheme.title, 20 | ), 21 | SizedBox(height: 20), 22 | Text( 23 | 'Keep your finantial data store to our server so that you can access from anywhere you want', 24 | style: TextStyle(fontSize: 16, fontWeight: FontWeight.w300), 25 | ), 26 | SizedBox(height: 25), 27 | new _RegisterForm(), 28 | ], 29 | ), 30 | ); 31 | } 32 | } 33 | 34 | class _RegisterForm extends StatelessWidget { 35 | const _RegisterForm({ 36 | Key key, 37 | }) : super(key: key); 38 | 39 | @override 40 | Widget build(BuildContext context) { 41 | return Container( 42 | height: 200, 43 | child: CustomForm( 44 | onPressed: () {}, 45 | textFields: [ 46 | new CustomTextField( 47 | placeholder: 'Your name', 48 | label: 'Your name', 49 | ), 50 | new CustomTextField( 51 | placeholder: 'name@domain.com', 52 | label: 'Email', 53 | ), 54 | new CustomTextField( 55 | placeholder: '************', 56 | label: 'Password', 57 | password: true, 58 | ), 59 | ], 60 | ), 61 | ); 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /lib/widgets/auth_container.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/cupertino.dart'; 2 | import 'package:flutter/material.dart'; 3 | 4 | import 'package:budget_planner/widgets/rounded_appbar.dart'; 5 | import 'package:budget_planner/widgets/zoom_in_out_image.dart'; 6 | 7 | class AuthContainer extends StatefulWidget { 8 | /// A widget that wraps the [LoginScreen] and [RegisterScreen] 9 | /// The [child] usually contains the text and form elements 10 | AuthContainer({ 11 | Key key, 12 | @required this.child, 13 | @required this.onTapHeaderAction, 14 | this.isLogin = false, 15 | }); 16 | 17 | /// Determines the if the facebook button and header 18 | /// should say signup / sign in 19 | final bool isLogin; 20 | 21 | final Widget child; 22 | 23 | final Function onTapHeaderAction; 24 | 25 | @override 26 | _AuthContainerState createState() => _AuthContainerState(); 27 | } 28 | 29 | class _AuthContainerState extends State { 30 | @override 31 | Widget build(BuildContext context) { 32 | return Scaffold( 33 | appBar: PreferredSize( 34 | preferredSize: Size(MediaQuery.of(context).size.width, 0), 35 | child: Container(color: Colors.white), 36 | ), 37 | body: Column( 38 | crossAxisAlignment: CrossAxisAlignment.start, 39 | children: [ 40 | new RoundedAppBar( 41 | child: Row( 42 | mainAxisAlignment: MainAxisAlignment.spaceBetween, 43 | crossAxisAlignment: CrossAxisAlignment.center, 44 | children: [ 45 | Text('Budget Tracker', style: TextStyle(fontSize: 16)), 46 | GestureDetector( 47 | onTap: widget.onTapHeaderAction, 48 | child: Container( 49 | height: 60, 50 | width: 60, 51 | alignment: Alignment.center, 52 | child: Text( 53 | widget.isLogin ? 'Sign Up' : 'Login', 54 | style: TextStyle( 55 | fontSize: 12.5, 56 | color: Theme.of(context).primaryColor, 57 | ), 58 | ), 59 | ), 60 | ) 61 | ], 62 | ), 63 | ), 64 | Expanded( 65 | child: Container( 66 | padding: EdgeInsets.symmetric(horizontal: 28), 67 | child: ListView( 68 | children: [ 69 | new ZoomInOutImage( 70 | assetName: 'assets/images/using_phone.png', 71 | ), 72 | SizedBox(height: 40), 73 | widget.child, 74 | Container( 75 | margin: EdgeInsets.only(top: 25), 76 | padding: EdgeInsets.only(bottom: 40), 77 | height: 160, 78 | width: MediaQuery.of(context).size.width, 79 | child: Column( 80 | mainAxisAlignment: MainAxisAlignment.spaceBetween, 81 | children: [ 82 | Text( 83 | 'or', 84 | style: TextStyle( 85 | color: Colors.grey[500], 86 | fontWeight: FontWeight.w300, 87 | ), 88 | ), 89 | new _FacebookButton(isLogin: widget.isLogin), 90 | Text('Forgot Password?') 91 | ], 92 | ), 93 | ) 94 | ], 95 | ), 96 | ), 97 | ), 98 | ], 99 | ), 100 | ); 101 | } 102 | } 103 | 104 | class _FacebookButton extends StatelessWidget { 105 | final bool isLogin; 106 | 107 | const _FacebookButton({Key key, this.isLogin}) : super(key: key); 108 | 109 | @override 110 | Widget build(BuildContext context) { 111 | return Container( 112 | padding: EdgeInsets.symmetric( 113 | vertical: 12.0, 114 | horizontal: 12.0, 115 | ), 116 | decoration: BoxDecoration( 117 | border: Border.all( 118 | color: Color.fromRGBO(59, 89, 152, 1.0), 119 | ), 120 | borderRadius: BorderRadius.circular(6.0), 121 | ), 122 | child: Row( 123 | mainAxisAlignment: MainAxisAlignment.spaceBetween, 124 | children: [ 125 | SizedBox( 126 | height: 20, 127 | width: 20, 128 | child: Image.asset('assets/icons/fb.png'), 129 | ), 130 | Text( 131 | this.isLogin ? 'Login with facebook' : 'Signup with facebook', 132 | style: TextStyle( 133 | color: Color.fromRGBO(59, 89, 152, 1.0), 134 | fontWeight: FontWeight.w500, 135 | ), 136 | ), 137 | Container() 138 | ], 139 | ), 140 | ); 141 | } 142 | } 143 | -------------------------------------------------------------------------------- /lib/widgets/custom_button.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | class CustomButton extends StatelessWidget { 4 | /// The app's custom implementation on how a button should 5 | /// look like 6 | CustomButton({ 7 | Key key, 8 | @required this.onTap, 9 | @required this.width, 10 | @required this.height, 11 | @required this.child, 12 | }) : super(key: key); 13 | 14 | final Function onTap; 15 | final double height; 16 | final double width; 17 | final Widget child; 18 | 19 | @override 20 | Widget build(BuildContext context) { 21 | return Material( 22 | color: Theme.of(context).primaryColor, 23 | borderRadius: BorderRadius.circular(12.0), 24 | child: InkWell( 25 | onTap: this.onTap, 26 | child: Container( 27 | width: this.width, 28 | height: this.height, 29 | child: Center( 30 | child: this.child, 31 | ), 32 | ), 33 | ), 34 | ); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /lib/widgets/custom_form.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | import 'package:budget_planner/widgets/custom_button.dart'; 4 | 5 | class CustomForm extends StatelessWidget { 6 | /// A widget that transforms a list of renders the list 7 | /// of [CustomTextField] but the last textField gets wrapped in a 8 | /// a row with a button 9 | CustomForm({ 10 | Key key, 11 | @required this.textFields, 12 | @required this.onPressed, 13 | }) : super(key: key); 14 | 15 | final List textFields; 16 | final Function onPressed; 17 | 18 | @override 19 | Widget build(BuildContext context) { 20 | final lastTextField = textFields.removeAt(textFields.length - 1); 21 | 22 | return Column( 23 | children: [ 24 | for (Widget textField in textFields) textField, 25 | Row( 26 | children: [ 27 | lastTextField, 28 | SizedBox(width: 40), 29 | CustomButton( 30 | onTap: this.onPressed, 31 | height: 45, 32 | width: 45, 33 | child: Icon( 34 | Icons.keyboard_arrow_right, 35 | color: Colors.white, 36 | size: 36, 37 | ), 38 | ), 39 | ], 40 | ) 41 | ], 42 | ); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /lib/widgets/custom_textfield.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutter/cupertino.dart'; 3 | 4 | class CustomTextField extends StatelessWidget { 5 | const CustomTextField({ 6 | Key key, 7 | @required this.placeholder, 8 | @required this.label, 9 | this.password = false, 10 | this.keyboardType, 11 | this.focusNode, 12 | }) : super(key: key); 13 | 14 | final String placeholder; 15 | final String label; 16 | final bool password; 17 | final TextInputType keyboardType; 18 | final FocusNode focusNode; 19 | 20 | @override 21 | Widget build(BuildContext context) { 22 | return Expanded( 23 | child: Column( 24 | crossAxisAlignment: CrossAxisAlignment.start, 25 | children: [ 26 | Text( 27 | this.label, 28 | style: Theme.of(context).textTheme.subtitle.copyWith( 29 | color: Colors.grey[500], 30 | fontWeight: FontWeight.w400, 31 | ), 32 | ), 33 | CupertinoTextField( 34 | padding: EdgeInsets.symmetric( 35 | vertical: 6, 36 | horizontal: 0, 37 | ), 38 | decoration: BoxDecoration( 39 | border: Border( 40 | bottom: BorderSide( 41 | color: Colors.black, 42 | width: 0.25, 43 | ), 44 | ), 45 | ), 46 | placeholder: this.placeholder, 47 | placeholderStyle: TextStyle( 48 | fontWeight: FontWeight.w700, 49 | color: Colors.grey[400], 50 | ), 51 | style: TextStyle( 52 | fontFamily: 'GT-Walshiem-Pro', 53 | fontSize: 20, 54 | fontWeight: FontWeight.bold, 55 | ), 56 | obscureText: this.password, 57 | keyboardType: this.keyboardType, 58 | focusNode: this.focusNode, 59 | ), 60 | ], 61 | ), 62 | ); 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /lib/widgets/rounded_appbar.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | class RoundedAppBar extends StatelessWidget { 4 | final Widget child; 5 | final EdgeInsetsGeometry padding; 6 | final double height; 7 | final bool isAnimated; 8 | 9 | const RoundedAppBar({ 10 | Key key, 11 | @required this.child, 12 | this.padding, 13 | this.height, 14 | this.isAnimated = false, 15 | }) : super(key: key); 16 | 17 | @override 18 | Widget build(BuildContext context) { 19 | Widget _buildContainer(Widget child) { 20 | return this.isAnimated 21 | ? AnimatedContainer( 22 | duration: Duration(milliseconds: 500), 23 | curve: Curves.easeInOutExpo, 24 | height: height != null ? height : 75, 25 | alignment: Alignment.center, 26 | width: MediaQuery.of(context).size.width, 27 | padding: padding != null 28 | ? padding 29 | : EdgeInsets.only(left: 28.0, right: 28.0), 30 | child: child, 31 | ) 32 | : Container( 33 | height: height != null ? height : 75, 34 | alignment: Alignment.center, 35 | width: MediaQuery.of(context).size.width, 36 | padding: padding != null 37 | ? padding 38 | : EdgeInsets.only(left: 28.0, right: 28.0), 39 | child: child, 40 | ); 41 | } 42 | 43 | return Material( 44 | color: Colors.white, 45 | elevation: 2.0, 46 | shadowColor: Colors.grey[100], 47 | borderRadius: BorderRadius.only( 48 | bottomLeft: Radius.circular(20.0), 49 | bottomRight: Radius.circular(20.0), 50 | ), 51 | child: _buildContainer(this.child), 52 | ); 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /lib/widgets/route_transitions.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | class FadeRoute extends PageRouteBuilder { 4 | final Widget page; 5 | FadeRoute({this.page}) 6 | : super( 7 | pageBuilder: ( 8 | BuildContext context, 9 | Animation animation, 10 | Animation secondaryAnimation, 11 | ) => 12 | page, 13 | transitionsBuilder: ( 14 | BuildContext context, 15 | Animation animation, 16 | Animation secondaryAnimation, 17 | Widget child, 18 | ) => 19 | FadeTransition( 20 | opacity: animation, 21 | child: child, 22 | ), 23 | ); 24 | } 25 | -------------------------------------------------------------------------------- /lib/widgets/zoom_in_out_image.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/cupertino.dart'; 2 | import 'package:keyboard_visibility/keyboard_visibility.dart'; 3 | 4 | class ZoomInOutImage extends StatefulWidget { 5 | /// Takes an image and changes the size depending on the 6 | /// keyboard state 7 | const ZoomInOutImage({ 8 | Key key, 9 | this.assetName, 10 | this.child, 11 | this.height, 12 | this.width, 13 | }) : super(key: key); 14 | 15 | final String assetName; 16 | final double height; 17 | final double width; 18 | final Widget child; 19 | 20 | @override 21 | _ZoomInOutImageState createState() => _ZoomInOutImageState(); 22 | } 23 | 24 | class _ZoomInOutImageState extends State { 25 | bool _isKeyboardOpen = false; 26 | 27 | @override 28 | void initState() { 29 | super.initState(); 30 | 31 | if (widget.assetName != null && widget.child != null) { 32 | throw Exception("[assetName] and [child] cannot coexist!"); 33 | } 34 | 35 | KeyboardVisibilityNotification().addNewListener( 36 | onChange: (bool visible) { 37 | setState(() { 38 | _isKeyboardOpen = visible; 39 | }); 40 | }, 41 | ); 42 | } 43 | 44 | @override 45 | Widget build(BuildContext context) { 46 | double _height = 200; 47 | double _width = MediaQuery.of(context).size.width; 48 | 49 | if (widget.height != null) { 50 | setState(() { 51 | _height = widget.height; 52 | }); 53 | } 54 | 55 | if (widget.width != null) { 56 | setState(() { 57 | _width = widget.width; 58 | }); 59 | } 60 | 61 | return AnimatedContainer( 62 | curve: Curves.easeInOutExpo, 63 | duration: Duration(milliseconds: 500), 64 | alignment: _isKeyboardOpen ? Alignment.centerLeft : Alignment.center, 65 | margin: EdgeInsets.only(top: _isKeyboardOpen ? 75 : 40), 66 | height: _isKeyboardOpen ? 75 : _height, 67 | width: _isKeyboardOpen ? _width : 100, 68 | child: widget.child == null 69 | ? Image.asset( 70 | widget.assetName, 71 | filterQuality: FilterQuality.high, 72 | ) 73 | : widget.child, 74 | ); 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /pubspec.lock: -------------------------------------------------------------------------------- 1 | # Generated by pub 2 | # See https://www.dartlang.org/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.1.0" 11 | boolean_selector: 12 | dependency: transitive 13 | description: 14 | name: boolean_selector 15 | url: "https://pub.dartlang.org" 16 | source: hosted 17 | version: "1.0.4" 18 | charcode: 19 | dependency: transitive 20 | description: 21 | name: charcode 22 | url: "https://pub.dartlang.org" 23 | source: hosted 24 | version: "1.1.2" 25 | collection: 26 | dependency: transitive 27 | description: 28 | name: collection 29 | url: "https://pub.dartlang.org" 30 | source: hosted 31 | version: "1.14.11" 32 | cupertino_icons: 33 | dependency: "direct main" 34 | description: 35 | name: cupertino_icons 36 | url: "https://pub.dartlang.org" 37 | source: hosted 38 | version: "0.1.2" 39 | date_utils: 40 | dependency: transitive 41 | description: 42 | name: date_utils 43 | url: "https://pub.dartlang.org" 44 | source: hosted 45 | version: "0.1.0+2" 46 | flutter: 47 | dependency: "direct main" 48 | description: flutter 49 | source: sdk 50 | version: "0.0.0" 51 | flutter_calendar_carousel: 52 | dependency: "direct main" 53 | description: 54 | name: flutter_calendar_carousel 55 | url: "https://pub.dartlang.org" 56 | source: hosted 57 | version: "1.3.17" 58 | flutter_platform_widgets: 59 | dependency: "direct main" 60 | description: 61 | name: flutter_platform_widgets 62 | url: "https://pub.dartlang.org" 63 | source: hosted 64 | version: "0.10.0" 65 | flutter_test: 66 | dependency: "direct dev" 67 | description: flutter 68 | source: sdk 69 | version: "0.0.0" 70 | intl: 71 | dependency: transitive 72 | description: 73 | name: intl 74 | url: "https://pub.dartlang.org" 75 | source: hosted 76 | version: "0.15.8" 77 | keyboard_visibility: 78 | dependency: "direct main" 79 | description: 80 | name: keyboard_visibility 81 | url: "https://pub.dartlang.org" 82 | source: hosted 83 | version: "0.5.6" 84 | matcher: 85 | dependency: transitive 86 | description: 87 | name: matcher 88 | url: "https://pub.dartlang.org" 89 | source: hosted 90 | version: "0.12.5" 91 | meta: 92 | dependency: transitive 93 | description: 94 | name: meta 95 | url: "https://pub.dartlang.org" 96 | source: hosted 97 | version: "1.1.6" 98 | path: 99 | dependency: transitive 100 | description: 101 | name: path 102 | url: "https://pub.dartlang.org" 103 | source: hosted 104 | version: "1.6.2" 105 | pedantic: 106 | dependency: transitive 107 | description: 108 | name: pedantic 109 | url: "https://pub.dartlang.org" 110 | source: hosted 111 | version: "1.5.0" 112 | provider: 113 | dependency: "direct main" 114 | description: 115 | name: provider 116 | url: "https://pub.dartlang.org" 117 | source: hosted 118 | version: "2.0.1" 119 | quiver: 120 | dependency: transitive 121 | description: 122 | name: quiver 123 | url: "https://pub.dartlang.org" 124 | source: hosted 125 | version: "2.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.5.5" 138 | stack_trace: 139 | dependency: transitive 140 | description: 141 | name: stack_trace 142 | url: "https://pub.dartlang.org" 143 | source: hosted 144 | version: "1.9.3" 145 | stream_channel: 146 | dependency: transitive 147 | description: 148 | name: stream_channel 149 | url: "https://pub.dartlang.org" 150 | source: hosted 151 | version: "2.0.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.0.4" 159 | term_glyph: 160 | dependency: transitive 161 | description: 162 | name: term_glyph 163 | url: "https://pub.dartlang.org" 164 | source: hosted 165 | version: "1.1.0" 166 | test_api: 167 | dependency: transitive 168 | description: 169 | name: test_api 170 | url: "https://pub.dartlang.org" 171 | source: hosted 172 | version: "0.2.4" 173 | typed_data: 174 | dependency: transitive 175 | description: 176 | name: typed_data 177 | url: "https://pub.dartlang.org" 178 | source: hosted 179 | version: "1.1.6" 180 | vector_math: 181 | dependency: transitive 182 | description: 183 | name: vector_math 184 | url: "https://pub.dartlang.org" 185 | source: hosted 186 | version: "2.0.8" 187 | sdks: 188 | dart: ">=2.2.2 <3.0.0" 189 | flutter: ">=0.1.4 <2.0.0" 190 | -------------------------------------------------------------------------------- /pubspec.yaml: -------------------------------------------------------------------------------- 1 | name: budget_planner 2 | description: A new Flutter project. 3 | 4 | # The following defines the version and build number for your application. 5 | # A version number is three numbers separated by dots, like 1.2.43 6 | # followed by an optional build number separated by a +. 7 | # Both the version and the builder number may be overridden in flutter 8 | # build by specifying --build-name and --build-number, respectively. 9 | # In Android, build-name is used as versionName while build-number used as versionCode. 10 | # Read more about Android versioning at https://developer.android.com/studio/publish/versioning 11 | # In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion. 12 | # Read more about iOS versioning at 13 | # https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html 14 | version: 1.0.0+1 15 | 16 | environment: 17 | sdk: ">=2.2.2 <3.0.0" 18 | 19 | dependencies: 20 | flutter: 21 | sdk: flutter 22 | 23 | cupertino_icons: ^0.1.2 24 | flutter_platform_widgets: ^0.10.0 25 | provider: ^2.0.1 26 | keyboard_visibility: ^0.5.6 27 | flutter_calendar_carousel: ^1.3.17 28 | 29 | dev_dependencies: 30 | flutter_test: 31 | sdk: flutter 32 | 33 | flutter: 34 | uses-material-design: true 35 | 36 | assets: 37 | - assets/images/ 38 | - assets/icons/ 39 | 40 | fonts: 41 | - family: GT-Walshiem-Pro 42 | fonts: 43 | - asset: assets/fonts/light.OTF 44 | weight: 300 45 | - asset: assets/fonts/regular.OTF 46 | - asset: assets/fonts/medium.OTF 47 | weight: 500 48 | - asset: assets/fonts/bold.OTF 49 | weight: 700 50 | -------------------------------------------------------------------------------- /screenshots/demo.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fluttertraining/Life-Monitor/cf1fd57dd476b48a81311f8a1d1bcd94d94b1986/screenshots/demo.gif -------------------------------------------------------------------------------- /screenshots/screenshot_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fluttertraining/Life-Monitor/cf1fd57dd476b48a81311f8a1d1bcd94d94b1986/screenshots/screenshot_1.png -------------------------------------------------------------------------------- /screenshots/screenshot_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fluttertraining/Life-Monitor/cf1fd57dd476b48a81311f8a1d1bcd94d94b1986/screenshots/screenshot_2.png -------------------------------------------------------------------------------- /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:budget_planner/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 | --------------------------------------------------------------------------------