├── ios ├── Runner │ ├── Runner-Bridging-Header.h │ ├── Assets.xcassets │ │ ├── LaunchImage.imageset │ │ │ ├── LaunchImage.png │ │ │ ├── LaunchImage@2x.png │ │ │ ├── LaunchImage@3x.png │ │ │ ├── README.md │ │ │ └── Contents.json │ │ └── AppIcon.appiconset │ │ │ ├── Icon-App-20x20@1x.png │ │ │ ├── Icon-App-20x20@2x.png │ │ │ ├── Icon-App-20x20@3x.png │ │ │ ├── Icon-App-29x29@1x.png │ │ │ ├── Icon-App-29x29@2x.png │ │ │ ├── Icon-App-29x29@3x.png │ │ │ ├── Icon-App-40x40@1x.png │ │ │ ├── Icon-App-40x40@2x.png │ │ │ ├── Icon-App-40x40@3x.png │ │ │ ├── Icon-App-60x60@2x.png │ │ │ ├── Icon-App-60x60@3x.png │ │ │ ├── Icon-App-76x76@1x.png │ │ │ ├── Icon-App-76x76@2x.png │ │ │ ├── Icon-App-1024x1024@1x.png │ │ │ ├── Icon-App-83.5x83.5@2x.png │ │ │ └── Contents.json │ ├── AppDelegate.swift │ ├── GoogleService-Info.plist │ ├── Base.lproj │ │ ├── Main.storyboard │ │ └── LaunchScreen.storyboard │ └── Info.plist ├── Flutter │ ├── Debug.xcconfig │ ├── Release.xcconfig │ └── AppFrameworkInfo.plist ├── Runner.xcodeproj │ ├── project.xcworkspace │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata │ │ │ ├── WorkspaceSettings.xcsettings │ │ │ └── IDEWorkspaceChecks.plist │ ├── xcshareddata │ │ └── xcschemes │ │ │ └── Runner.xcscheme │ └── project.pbxproj ├── Runner.xcworkspace │ ├── contents.xcworkspacedata │ └── xcshareddata │ │ ├── WorkspaceSettings.xcsettings │ │ └── IDEWorkspaceChecks.plist ├── RunnerTests │ └── RunnerTests.swift ├── .gitignore └── Podfile ├── assets └── images │ ├── union.png │ ├── google.png │ ├── logofull.png │ ├── logomini.png │ └── person.png ├── android ├── app │ ├── src │ │ ├── main │ │ │ ├── res │ │ │ │ ├── mipmap-hdpi │ │ │ │ │ └── ic_launcher.png │ │ │ │ ├── mipmap-mdpi │ │ │ │ │ └── ic_launcher.png │ │ │ │ ├── mipmap-xhdpi │ │ │ │ │ └── ic_launcher.png │ │ │ │ ├── mipmap-xxhdpi │ │ │ │ │ └── ic_launcher.png │ │ │ │ ├── mipmap-xxxhdpi │ │ │ │ │ └── ic_launcher.png │ │ │ │ ├── drawable │ │ │ │ │ └── launch_background.xml │ │ │ │ ├── drawable-v21 │ │ │ │ │ └── launch_background.xml │ │ │ │ ├── values │ │ │ │ │ └── styles.xml │ │ │ │ └── values-night │ │ │ │ │ └── styles.xml │ │ │ ├── kotlin │ │ │ │ └── com │ │ │ │ │ └── example │ │ │ │ │ └── payflow │ │ │ │ │ └── MainActivity.kt │ │ │ └── AndroidManifest.xml │ │ ├── debug │ │ │ └── AndroidManifest.xml │ │ └── profile │ │ │ └── AndroidManifest.xml │ ├── build.gradle │ └── google-services.json ├── gradle.properties ├── gradle │ └── wrapper │ │ └── gradle-wrapper.properties ├── .gitignore ├── build.gradle └── settings.gradle ├── lib ├── main.dart ├── shared │ ├── themes │ │ ├── app_images.dart │ │ ├── app_colors.dart │ │ └── app_text_styles.dart │ ├── widgets │ │ ├── divider │ │ │ └── divider_widget.dart │ │ ├── boleto_list │ │ │ ├── boleto_list_controller.dart │ │ │ └── boleto_list_widget.dart │ │ ├── label_button │ │ │ └── label_button.dart │ │ ├── boleto_tile │ │ │ └── boleto_tile_widget.dart │ │ ├── set_label_buttons │ │ │ └── set_label_buttons.dart │ │ ├── social_login_button │ │ │ └── social_login_button.dart │ │ ├── boleto_info │ │ │ └── boleto_info_widget.dart │ │ ├── input_text │ │ │ └── input_text_widget.dart │ │ └── bottom_sheet │ │ │ └── bottom_sheet_widget.dart │ ├── models │ │ ├── user_model.dart │ │ └── boleto_model.dart │ └── auth │ │ └── auth_controller.dart ├── modules │ ├── home │ │ ├── home_controller.dart │ │ └── home_page.dart │ ├── splash │ │ └── splash_page.dart │ ├── login │ │ ├── login_controller.dart │ │ └── login_page.dart │ ├── insert_boleto │ │ ├── insert_boleto_controller.dart │ │ └── insert_boleto_page.dart │ ├── barcode_scanner │ │ ├── barcode_scanner_status.dart │ │ ├── barcode_scanner_page.dart │ │ └── barcode_scanner_controller.dart │ ├── extract │ │ └── extract_page.dart │ └── my_boletos │ │ └── my_boletos_page.dart ├── app_widget.dart ├── payflow_app.dart └── firebase_options.dart ├── analysis_options.yaml ├── firebase.json ├── LICENSE ├── pubspec.yaml ├── .gitignore ├── README.md └── README-pt.md /ios/Runner/Runner-Bridging-Header.h: -------------------------------------------------------------------------------- 1 | #import "GeneratedPluginRegistrant.h" 2 | -------------------------------------------------------------------------------- /assets/images/union.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/felipecastrosales/payflow/HEAD/assets/images/union.png -------------------------------------------------------------------------------- /assets/images/google.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/felipecastrosales/payflow/HEAD/assets/images/google.png -------------------------------------------------------------------------------- /assets/images/logofull.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/felipecastrosales/payflow/HEAD/assets/images/logofull.png -------------------------------------------------------------------------------- /assets/images/logomini.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/felipecastrosales/payflow/HEAD/assets/images/logomini.png -------------------------------------------------------------------------------- /assets/images/person.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/felipecastrosales/payflow/HEAD/assets/images/person.png -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/felipecastrosales/payflow/HEAD/android/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/felipecastrosales/payflow/HEAD/android/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/felipecastrosales/payflow/HEAD/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/felipecastrosales/payflow/HEAD/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/felipecastrosales/payflow/HEAD/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/gradle.properties: -------------------------------------------------------------------------------- 1 | org.gradle.jvmargs=-Xmx4G -XX:MaxMetaspaceSize=2G -XX:+HeapDumpOnOutOfMemoryError 2 | android.useAndroidX=true 3 | android.enableJetifier=true 4 | -------------------------------------------------------------------------------- /lib/main.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | import 'package:payflow/app_widget.dart'; 4 | 5 | void main() { 6 | runApp(const AppWidget()); 7 | } 8 | -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/felipecastrosales/payflow/HEAD/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/felipecastrosales/payflow/HEAD/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/felipecastrosales/payflow/HEAD/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/felipecastrosales/payflow/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/felipecastrosales/payflow/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/felipecastrosales/payflow/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/felipecastrosales/payflow/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/felipecastrosales/payflow/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/felipecastrosales/payflow/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/felipecastrosales/payflow/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/felipecastrosales/payflow/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/felipecastrosales/payflow/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/felipecastrosales/payflow/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/felipecastrosales/payflow/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/felipecastrosales/payflow/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/felipecastrosales/payflow/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png -------------------------------------------------------------------------------- /android/app/src/main/kotlin/com/example/payflow/MainActivity.kt: -------------------------------------------------------------------------------- 1 | package com.example.payflow 2 | 3 | import io.flutter.embedding.android.FlutterActivity 4 | 5 | class MainActivity: FlutterActivity() 6 | -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/felipecastrosales/payflow/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/felipecastrosales/payflow/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png -------------------------------------------------------------------------------- /ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /ios/Runner.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /android/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | zipStoreBase=GRADLE_USER_HOME 4 | zipStorePath=wrapper/dists 5 | distributionUrl=https\://services.gradle.org/distributions/gradle-7.6.3-all.zip 6 | -------------------------------------------------------------------------------- /ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | PreviewsEnabled 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /android/.gitignore: -------------------------------------------------------------------------------- 1 | gradle-wrapper.jar 2 | /.gradle 3 | /captures/ 4 | /gradlew 5 | /gradlew.bat 6 | /local.properties 7 | GeneratedPluginRegistrant.java 8 | 9 | # Remember to never publicly share your keystore. 10 | # See https://flutter.dev/to/reference-keystore 11 | key.properties 12 | **/*.keystore 13 | **/*.jks 14 | -------------------------------------------------------------------------------- /ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | PreviewsEnabled 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /lib/shared/themes/app_images.dart: -------------------------------------------------------------------------------- 1 | class AppImages { 2 | static const logoFull = 'assets/images/logofull.png'; 3 | static const logomini = 'assets/images/logomini.png'; 4 | static const union = 'assets/images/union.png'; 5 | static const person = 'assets/images/person.png'; 6 | static const google = 'assets/images/google.png'; 7 | } 8 | -------------------------------------------------------------------------------- /ios/RunnerTests/RunnerTests.swift: -------------------------------------------------------------------------------- 1 | import Flutter 2 | import UIKit 3 | import XCTest 4 | 5 | class RunnerTests: XCTestCase { 6 | 7 | func testExample() { 8 | // If you add code to the Runner application, consider adding tests here. 9 | // See https://developer.apple.com/documentation/xctest for more information about using XCTest. 10 | } 11 | 12 | } 13 | -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md: -------------------------------------------------------------------------------- 1 | # Launch Screen Assets 2 | 3 | You can customize the launch screen with your own desired assets by replacing the image files in this directory. 4 | 5 | You can also do it by opening your Flutter project's Xcode project with `open ios/Runner.xcworkspace`, selecting `Runner/Assets.xcassets` in the Project Navigator and dropping in the desired images. -------------------------------------------------------------------------------- /lib/modules/home/home_controller.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | class HomeController extends ChangeNotifier { 4 | ValueNotifier currentPage = ValueNotifier(0); 5 | final pageController = PageController(); 6 | 7 | void setPage(int index) { 8 | currentPage.value = index; 9 | pageController.jumpToPage(index); 10 | notifyListeners(); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /android/build.gradle: -------------------------------------------------------------------------------- 1 | allprojects { 2 | repositories { 3 | google() 4 | mavenCentral() 5 | } 6 | } 7 | 8 | rootProject.buildDir = "../build" 9 | subprojects { 10 | project.buildDir = "${rootProject.buildDir}/${project.name}" 11 | } 12 | subprojects { 13 | project.evaluationDependsOn(":app") 14 | } 15 | 16 | tasks.register("clean", Delete) { 17 | delete rootProject.buildDir 18 | } 19 | -------------------------------------------------------------------------------- /android/app/src/debug/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /android/app/src/profile/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /analysis_options.yaml: -------------------------------------------------------------------------------- 1 | include: package:flutter_lints/flutter.yaml 2 | 3 | linter: 4 | rules: 5 | - sort_constructors_first 6 | - prefer_const_constructors 7 | - always_use_package_imports 8 | - use_named_constants 9 | - prefer_const_constructors_in_immutables 10 | - prefer_const_declarations 11 | - prefer_const_literals_to_create_immutables 12 | - prefer_constructors_over_static_methods 13 | - prefer_single_quotes -------------------------------------------------------------------------------- /ios/Runner/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | import Flutter 2 | import UIKit 3 | 4 | @main 5 | @objc class AppDelegate: FlutterAppDelegate { 6 | override func application( 7 | _ application: UIApplication, 8 | didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? 9 | ) -> Bool { 10 | GeneratedPluginRegistrant.register(with: self) 11 | return super.application(application, didFinishLaunchingWithOptions: launchOptions) 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /lib/shared/widgets/divider/divider_widget.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | import 'package:payflow/shared/themes/app_colors.dart'; 4 | 5 | class DividerWidget extends StatelessWidget { 6 | const DividerWidget({ 7 | super.key, 8 | required this.height, 9 | }); 10 | 11 | final double height; 12 | 13 | @override 14 | Widget build(BuildContext context) { 15 | return Container( 16 | color: AppColors.stroke, 17 | height: height, 18 | width: 1, 19 | ); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /android/app/src/main/res/drawable/launch_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 12 | 13 | -------------------------------------------------------------------------------- /android/app/src/main/res/drawable-v21/launch_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 12 | 13 | -------------------------------------------------------------------------------- /firebase.json: -------------------------------------------------------------------------------- 1 | {"flutter":{"platforms":{"android":{"default":{"projectId":"payflow-e9031","appId":"1:729322644360:android:119258b076855540e7903d","fileOutput":"android/app/google-services.json"}},"ios":{"default":{"projectId":"payflow-e9031","appId":"1:729322644360:ios:a9335a23edeed249e7903d","uploadDebugSymbols":false,"fileOutput":"ios/Runner/GoogleService-Info.plist"}},"dart":{"lib/firebase_options.dart":{"projectId":"payflow-e9031","configurations":{"android":"1:729322644360:android:119258b076855540e7903d","ios":"1:729322644360:ios:a9335a23edeed249e7903d"}}}}}} -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "LaunchImage.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "LaunchImage@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "LaunchImage@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /lib/shared/themes/app_colors.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | class AppColors { 4 | static const primary = Color(0xFFFF941A); 5 | static const secondary = Color(0xFF585666); 6 | static const grey = Color(0xFF585666); 7 | static const delete = Color(0xFFE83F5B); 8 | static const heading = Color(0xFF585666); 9 | static const body = Color(0xFF706E7A); 10 | static const stroke = Color(0xFFE3E3E6); 11 | static const shape = Color(0xFFFAFAFC); 12 | static const background = Color(0xFFFFFFFF); 13 | static const input = Color(0xFFB1B0B8); 14 | } 15 | -------------------------------------------------------------------------------- /lib/shared/models/user_model.dart: -------------------------------------------------------------------------------- 1 | import 'dart:convert'; 2 | 3 | class UserModel { 4 | factory UserModel.fromJson(String json) => 5 | UserModel.fromMap(jsonDecode(json)); 6 | 7 | factory UserModel.fromMap(Map map) { 8 | return UserModel( 9 | name: map['name'], 10 | photoURL: map['photoURL'], 11 | ); 12 | } 13 | 14 | UserModel({required this.name, this.photoURL}); 15 | final String name; 16 | final String? photoURL; 17 | 18 | Map toMap() => { 19 | 'name': name, 20 | 'photoURL': photoURL, 21 | }; 22 | 23 | String toJson() => jsonEncode(toMap()); 24 | } 25 | -------------------------------------------------------------------------------- /ios/.gitignore: -------------------------------------------------------------------------------- 1 | **/dgph 2 | *.mode1v3 3 | *.mode2v3 4 | *.moved-aside 5 | *.pbxuser 6 | *.perspectivev3 7 | **/*sync/ 8 | .sconsign.dblite 9 | .tags* 10 | **/.vagrant/ 11 | **/DerivedData/ 12 | Icon? 13 | **/Pods/ 14 | **/.symlinks/ 15 | profile 16 | xcuserdata 17 | **/.generated/ 18 | Flutter/App.framework 19 | Flutter/Flutter.framework 20 | Flutter/Flutter.podspec 21 | Flutter/Generated.xcconfig 22 | Flutter/ephemeral/ 23 | Flutter/app.flx 24 | Flutter/app.zip 25 | Flutter/flutter_assets/ 26 | Flutter/flutter_export_environment.sh 27 | ServiceDefinitions.json 28 | Runner/GeneratedPluginRegistrant.* 29 | 30 | # Exceptions to above rules. 31 | !default.mode1v3 32 | !default.mode2v3 33 | !default.pbxuser 34 | !default.perspectivev3 35 | -------------------------------------------------------------------------------- /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 | 12.0 25 | 26 | 27 | -------------------------------------------------------------------------------- /lib/modules/splash/splash_page.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | import 'package:payflow/shared/auth/auth_controller.dart'; 4 | import 'package:payflow/shared/themes/app_colors.dart'; 5 | import 'package:payflow/shared/themes/app_images.dart'; 6 | 7 | class SplashPage extends StatelessWidget { 8 | const SplashPage({super.key}); 9 | 10 | @override 11 | Widget build(BuildContext context) { 12 | final authController = AuthController(); 13 | authController.currentUser(context); 14 | 15 | return Scaffold( 16 | backgroundColor: AppColors.background, 17 | body: Stack( 18 | alignment: Alignment.center, 19 | children: [ 20 | Center( 21 | child: Image.asset(AppImages.union), 22 | ), 23 | Center( 24 | child: Image.asset(AppImages.logoFull), 25 | ), 26 | ], 27 | ), 28 | ); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /android/settings.gradle: -------------------------------------------------------------------------------- 1 | pluginManagement { 2 | def flutterSdkPath = { 3 | def properties = new Properties() 4 | file("local.properties").withInputStream { properties.load(it) } 5 | def flutterSdkPath = properties.getProperty("flutter.sdk") 6 | assert flutterSdkPath != null, "flutter.sdk not set in local.properties" 7 | return flutterSdkPath 8 | }() 9 | 10 | includeBuild("$flutterSdkPath/packages/flutter_tools/gradle") 11 | 12 | repositories { 13 | google() 14 | mavenCentral() 15 | gradlePluginPortal() 16 | } 17 | } 18 | 19 | plugins { 20 | id "dev.flutter.flutter-plugin-loader" version "1.0.0" 21 | id "com.android.application" version "7.3.0" apply false 22 | // START: FlutterFire Configuration 23 | id "com.google.gms.google-services" version "4.3.15" apply false 24 | // END: FlutterFire Configuration 25 | id "org.jetbrains.kotlin.android" version "1.7.10" apply false 26 | } 27 | 28 | include ":app" 29 | -------------------------------------------------------------------------------- /android/app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 9 | 15 | 18 | 19 | -------------------------------------------------------------------------------- /android/app/src/main/res/values-night/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 9 | 15 | 18 | 19 | -------------------------------------------------------------------------------- /lib/shared/widgets/boleto_list/boleto_list_controller.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | import 'package:shared_preferences/shared_preferences.dart'; 4 | 5 | import 'package:payflow/shared/models/boleto_model.dart'; 6 | 7 | class BoletoListController { 8 | BoletoListController() { 9 | getBoletos(); 10 | } 11 | 12 | final boletosNotifier = ValueNotifier>([]); 13 | List get boletos => boletosNotifier.value; 14 | set boletos(List value) => boletosNotifier.value = value; 15 | 16 | void getBoletos() async { 17 | try { 18 | final instance = await SharedPreferences.getInstance(); 19 | final response = instance.getStringList('boletos'); 20 | boletos = 21 | response?.map((boleto) => BoletoModel.fromJson(boleto)).toList() ?? 22 | []; 23 | } catch (e, s) { 24 | debugPrint('Error when getting boletos ${e.toString()}'); 25 | debugPrint('Stack when getting boletos ${s.toString()}'); 26 | } 27 | } 28 | 29 | void dispose() { 30 | boletosNotifier.dispose(); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /lib/shared/widgets/boleto_list/boleto_list_widget.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | import 'package:payflow/shared/models/boleto_model.dart'; 4 | import 'package:payflow/shared/widgets/boleto_list/boleto_list_controller.dart'; 5 | import 'package:payflow/shared/widgets/boleto_tile/boleto_tile_widget.dart'; 6 | 7 | class BoletoListWidget extends StatefulWidget { 8 | const BoletoListWidget({ 9 | super.key, 10 | required this.controller, 11 | }); 12 | 13 | final BoletoListController controller; 14 | 15 | @override 16 | State createState() => _BoletoListWidgetState(); 17 | } 18 | 19 | class _BoletoListWidgetState extends State { 20 | @override 21 | Widget build(BuildContext context) { 22 | return ValueListenableBuilder>( 23 | valueListenable: widget.controller.boletosNotifier, 24 | builder: (_, boletos, __) => Column( 25 | children: boletos 26 | .map( 27 | (boleto) => BoletoTileWidget(data: boleto), 28 | ) 29 | .toList(), 30 | ), 31 | ); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 Felipe Sales 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /lib/modules/login/login_controller.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | import 'package:google_sign_in/google_sign_in.dart'; 4 | 5 | import 'package:payflow/shared/auth/auth_controller.dart'; 6 | import 'package:payflow/shared/models/user_model.dart'; 7 | 8 | class LoginController { 9 | final authController = AuthController(); 10 | 11 | Future googleSignIn( 12 | BuildContext context, 13 | ) async { 14 | GoogleSignIn googleSignIn = GoogleSignIn( 15 | scopes: [ 16 | 'email', 17 | ], 18 | ); 19 | try { 20 | final response = await googleSignIn.signIn(); 21 | final user = UserModel( 22 | name: response?.displayName as String, 23 | photoURL: response?.photoUrl as String, 24 | ); 25 | if (!context.mounted) return; 26 | authController.setUser(context, user); 27 | debugPrint('Response: $response'); 28 | } catch (e, s) { 29 | if (!context.mounted) return; 30 | authController.setUser(context, null); 31 | debugPrint('Error when signing in with Google: ${e.toString()}'); 32 | debugPrint('Stack when signing in with Google: ${s.toString()}'); 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /pubspec.yaml: -------------------------------------------------------------------------------- 1 | name: payflow 2 | description: PayFlow App 3 | publish_to: 'none' 4 | version: 2.0.1 5 | 6 | environment: 7 | sdk: ">=3.4.4 <4.0.0" 8 | 9 | dependencies: 10 | animated_card: ^2.0.0 11 | camera: ^0.11.0+2 12 | cupertino_icons: ^1.0.8 13 | firebase_core: ^3.3.0 14 | flutter: 15 | sdk: flutter 16 | flutter_launcher_icons: ^0.13.1 17 | flutter_masked_text2: ^0.9.1 18 | font_awesome_flutter: ^10.7.0 19 | google_fonts: ^6.2.1 20 | google_mlkit_barcode_scanning: ^0.12.0 21 | google_sign_in: ^6.2.1 22 | google_sign_in_web: ^0.12.4 23 | image_picker: ^1.1.2 24 | image_picker_for_web: ^3.0.5 25 | shared_preferences: ^2.3.2 26 | 27 | dev_dependencies: 28 | flutter_lints: ^4.0.0 29 | flutter_test: 30 | sdk: flutter 31 | 32 | flutter: 33 | uses-material-design: true 34 | assets: 35 | - assets/images/ 36 | 37 | flutter_icons: 38 | image_path: "assets/images/logofull.png" 39 | image_path_android: "assets/images/logofull.png" 40 | image_path_ios: "assets/images/logofull.png" 41 | android: true 42 | ios: true 43 | remove_alpha_ios: true 44 | web: 45 | generate: true 46 | image_path: "assets/images/icon-1024x1024.png" 47 | background_color: "#hexcode" 48 | theme_color: "#hexcode" 49 | -------------------------------------------------------------------------------- /lib/modules/insert_boleto/insert_boleto_controller.dart: -------------------------------------------------------------------------------- 1 | import 'package:shared_preferences/shared_preferences.dart'; 2 | 3 | import 'package:payflow/shared/models/boleto_model.dart'; 4 | 5 | class InsertBoletoController { 6 | BoletoModel model = BoletoModel.empty(); 7 | 8 | String? validateName(String? value) => 9 | value?.isEmpty ?? true ? 'The name cannot be empty' : null; 10 | 11 | String? validateDueDate(String? value) => 12 | value?.isEmpty ?? true ? 'The due date cannot be empty' : null; 13 | 14 | String? validateValue(double value) => 15 | value == 0 ? 'Enter an amount greater than \$0.00' : null; 16 | 17 | String? validateCode(String? value) => 18 | value?.isEmpty ?? true ? 'Boleto code cannot be empty' : null; 19 | 20 | void onChange({ 21 | String? name, 22 | String? dueDate, 23 | double? value, 24 | String? barcode, 25 | }) => 26 | model = model.copyWith( 27 | name: name, 28 | dueDate: dueDate, 29 | value: value, 30 | barcode: barcode, 31 | ); 32 | 33 | Future saveBoleto() async { 34 | final instance = await SharedPreferences.getInstance(); 35 | final boletos = instance.getStringList('boletos') ?? []; 36 | boletos.add(model.toJson()); 37 | await instance.setStringList('boletos', boletos); 38 | return; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /lib/shared/widgets/label_button/label_button.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | import 'package:payflow/shared/themes/app_text_styles.dart'; 4 | 5 | class LabelButton extends StatelessWidget { 6 | factory LabelButton.primary({ 7 | required String label, 8 | required VoidCallback onPressed, 9 | }) => 10 | LabelButton( 11 | label: label, 12 | onPressed: onPressed, 13 | style: AppTextStyles.buttonPrimary, 14 | ); 15 | 16 | factory LabelButton.heading({ 17 | required String label, 18 | required VoidCallback onPressed, 19 | }) => 20 | LabelButton( 21 | label: label, 22 | onPressed: onPressed, 23 | style: AppTextStyles.buttonHeading, 24 | ); 25 | 26 | const LabelButton({ 27 | super.key, 28 | required this.label, 29 | required this.onPressed, 30 | required this.style, 31 | }); 32 | 33 | final String label; 34 | final VoidCallback onPressed; 35 | final TextStyle style; 36 | 37 | @override 38 | Widget build(BuildContext context) { 39 | return Expanded( 40 | child: SizedBox( 41 | height: 56, 42 | child: TextButton( 43 | onPressed: onPressed, 44 | child: Text( 45 | label, 46 | style: style, 47 | ), 48 | ), 49 | ), 50 | ); 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /ios/Runner/GoogleService-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CLIENT_ID 6 | 729322644360-u5mn7hlr17h5e04piolpf8pshq5b3uc5.apps.googleusercontent.com 7 | REVERSED_CLIENT_ID 8 | com.googleusercontent.apps.729322644360-u5mn7hlr17h5e04piolpf8pshq5b3uc5 9 | ANDROID_CLIENT_ID 10 | 729322644360-llus2au7g894p00i74s1b6ehvfhbhnk5.apps.googleusercontent.com 11 | API_KEY 12 | AIzaSyCqaqkpt-mf3OIYey0FOBloURmGLkxqN7Y 13 | GCM_SENDER_ID 14 | 729322644360 15 | PLIST_VERSION 16 | 1 17 | BUNDLE_ID 18 | com.example.payflow 19 | PROJECT_ID 20 | payflow-e9031 21 | STORAGE_BUCKET 22 | payflow-e9031.appspot.com 23 | IS_ADS_ENABLED 24 | 25 | IS_ANALYTICS_ENABLED 26 | 27 | IS_APPINVITE_ENABLED 28 | 29 | IS_GCM_ENABLED 30 | 31 | IS_SIGNIN_ENABLED 32 | 33 | GOOGLE_APP_ID 34 | 1:729322644360:ios:a9335a23edeed249e7903d 35 | 36 | -------------------------------------------------------------------------------- /lib/modules/barcode_scanner/barcode_scanner_status.dart: -------------------------------------------------------------------------------- 1 | import 'package:camera/camera.dart'; 2 | 3 | class BarcodeScannerStatus { 4 | factory BarcodeScannerStatus.barcode(String barcode) => 5 | BarcodeScannerStatus(barcode: barcode, stopScanner: true); 6 | 7 | factory BarcodeScannerStatus.error(String message) => 8 | BarcodeScannerStatus(error: message, stopScanner: true); 9 | 10 | factory BarcodeScannerStatus.available() => 11 | BarcodeScannerStatus(isAvailable: true, stopScanner: false); 12 | 13 | BarcodeScannerStatus({ 14 | this.isAvailable = false, 15 | this.error = '', 16 | this.barcode = '', 17 | this.stopScanner = false, 18 | }); 19 | 20 | final bool isAvailable; 21 | final String error; 22 | final String barcode; 23 | final bool stopScanner; 24 | 25 | bool get showCamera => isAvailable && error.isEmpty; 26 | bool get hasError => error.isNotEmpty; 27 | bool get hasBarcode => barcode.isNotEmpty; 28 | 29 | BarcodeScannerStatus copyWith({ 30 | bool? isAvailable, 31 | String? error, 32 | String? barcode, 33 | bool? stopScanner, 34 | CameraController? cameraController, 35 | }) { 36 | return BarcodeScannerStatus( 37 | isAvailable: isAvailable ?? this.isAvailable, 38 | error: error ?? this.error, 39 | barcode: barcode ?? this.barcode, 40 | stopScanner: stopScanner ?? this.stopScanner, 41 | ); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /lib/shared/auth/auth_controller.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | import 'package:shared_preferences/shared_preferences.dart'; 4 | 5 | import 'package:payflow/shared/models/user_model.dart'; 6 | 7 | class AuthController { 8 | UserModel? _user; 9 | UserModel get user => _user as UserModel; 10 | 11 | void setUser(BuildContext context, UserModel? user) { 12 | if (user != null) { 13 | saveUser(user); 14 | _user = user; 15 | Navigator.pushReplacementNamed( 16 | context, 17 | '/home', 18 | arguments: user, 19 | ); 20 | } else { 21 | Navigator.pushReplacementNamed(context, '/login'); 22 | } 23 | } 24 | 25 | Future saveUser(UserModel user) async { 26 | final instance = await SharedPreferences.getInstance(); 27 | await instance.setString('user', user.toJson()); 28 | return; 29 | } 30 | 31 | Future currentUser( 32 | BuildContext context, 33 | ) async { 34 | final instance = await SharedPreferences.getInstance(); 35 | await Future.delayed(const Duration(seconds: 2)); 36 | 37 | if (instance.containsKey('user')) { 38 | final json = instance.get('user') as String; 39 | if (!context.mounted) return; 40 | setUser(context, UserModel.fromJson(json)); 41 | return; 42 | } else { 43 | if (!context.mounted) return; 44 | setUser(context, null); 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /lib/shared/widgets/boleto_tile/boleto_tile_widget.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | import 'package:animated_card/animated_card.dart'; 4 | 5 | import 'package:payflow/shared/models/boleto_model.dart'; 6 | import 'package:payflow/shared/themes/app_text_styles.dart'; 7 | 8 | class BoletoTileWidget extends StatelessWidget { 9 | const BoletoTileWidget({ 10 | super.key, 11 | required this.data, 12 | }); 13 | 14 | final BoletoModel data; 15 | 16 | @override 17 | Widget build(BuildContext context) { 18 | return AnimatedCard( 19 | direction: AnimatedCardDirection.top, 20 | child: Padding( 21 | padding: const EdgeInsets.only(bottom: 16), 22 | child: ListTile( 23 | contentPadding: EdgeInsets.zero, 24 | title: Text( 25 | data.name, 26 | style: AppTextStyles.titleListTile, 27 | ), 28 | subtitle: Text( 29 | 'Expires on: ${data.dueDate}', 30 | style: AppTextStyles.captionBody, 31 | ), 32 | trailing: Text.rich(TextSpan( 33 | text: '\$ ', 34 | style: AppTextStyles.trailingRegular, 35 | children: [ 36 | TextSpan( 37 | text: data.value.toStringAsFixed(2), 38 | style: AppTextStyles.trailingBold, 39 | ), 40 | ], 41 | )), 42 | ), 43 | ), 44 | ); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /lib/app_widget.dart: -------------------------------------------------------------------------------- 1 | import 'dart:developer'; 2 | 3 | import 'package:flutter/material.dart'; 4 | 5 | import 'package:firebase_core/firebase_core.dart'; 6 | 7 | import 'package:payflow/payflow_app.dart'; 8 | 9 | class AppWidget extends StatefulWidget { 10 | const AppWidget({super.key}); 11 | 12 | @override 13 | State createState() => _AppWidgetState(); 14 | } 15 | 16 | class _AppWidgetState extends State { 17 | late final Future firebaseInitialize; 18 | 19 | @override 20 | void initState() { 21 | super.initState(); 22 | firebaseInitialize = Firebase.initializeApp(); 23 | } 24 | 25 | @override 26 | Widget build(BuildContext context) { 27 | return FutureBuilder( 28 | future: firebaseInitialize, 29 | builder: (context, snapshot) { 30 | if (snapshot.hasError) { 31 | log('Error when initializing Firebase: ${snapshot.error}'); 32 | return const Material( 33 | child: Center( 34 | child: Text( 35 | 'Oops, Unexpected error! :/', 36 | textDirection: TextDirection.ltr, 37 | ), 38 | ), 39 | ); 40 | } 41 | if (snapshot.connectionState == ConnectionState.done) { 42 | return const PayFlowApp(); 43 | } 44 | return const Material( 45 | child: Center(child: CircularProgressIndicator()), 46 | ); 47 | }, 48 | ); 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /lib/modules/extract/extract_page.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | import 'package:payflow/shared/themes/app_colors.dart'; 4 | import 'package:payflow/shared/themes/app_text_styles.dart'; 5 | import 'package:payflow/shared/widgets/boleto_list/boleto_list_controller.dart'; 6 | import 'package:payflow/shared/widgets/boleto_list/boleto_list_widget.dart'; 7 | 8 | class ExtractPage extends StatefulWidget { 9 | const ExtractPage({super.key}); 10 | 11 | @override 12 | State createState() => _ExtractPageState(); 13 | } 14 | 15 | class _ExtractPageState extends State { 16 | final controller = BoletoListController(); 17 | 18 | @override 19 | Widget build(BuildContext context) { 20 | return SingleChildScrollView( 21 | child: Column( 22 | children: [ 23 | Padding( 24 | padding: const EdgeInsets.symmetric(vertical: 24, horizontal: 24), 25 | child: Row( 26 | children: [ 27 | Text( 28 | 'My extracts', 29 | style: AppTextStyles.titleBoldHeading, 30 | ), 31 | ], 32 | ), 33 | ), 34 | const Padding( 35 | padding: EdgeInsets.symmetric(horizontal: 24), 36 | child: Divider(color: AppColors.stroke), 37 | ), 38 | Padding( 39 | padding: const EdgeInsets.symmetric(horizontal: 24), 40 | child: BoletoListWidget(controller: controller), 41 | ) 42 | ], 43 | ), 44 | ); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /ios/Podfile: -------------------------------------------------------------------------------- 1 | # Uncomment this line to define a global platform for your project 2 | # platform :ios, '12.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 flutter_root 14 | generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'Generated.xcconfig'), __FILE__) 15 | unless File.exist?(generated_xcode_build_settings_path) 16 | raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure flutter pub get is executed first" 17 | end 18 | 19 | File.foreach(generated_xcode_build_settings_path) do |line| 20 | matches = line.match(/FLUTTER_ROOT\=(.*)/) 21 | return matches[1].strip if matches 22 | end 23 | raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Generated.xcconfig, then run flutter pub get" 24 | end 25 | 26 | require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root) 27 | 28 | flutter_ios_podfile_setup 29 | 30 | target 'Runner' do 31 | use_frameworks! 32 | use_modular_headers! 33 | 34 | flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__)) 35 | target 'RunnerTests' do 36 | inherit! :search_paths 37 | end 38 | end 39 | 40 | post_install do |installer| 41 | installer.pods_project.targets.each do |target| 42 | flutter_additional_ios_build_settings(target) 43 | end 44 | end 45 | -------------------------------------------------------------------------------- /android/app/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id "com.android.application" 3 | // START: FlutterFire Configuration 4 | id 'com.google.gms.google-services' 5 | // END: FlutterFire Configuration 6 | id "kotlin-android" 7 | // The Flutter Gradle Plugin must be applied after the Android and Kotlin Gradle plugins. 8 | id "dev.flutter.flutter-gradle-plugin" 9 | } 10 | 11 | android { 12 | namespace = "com.example.payflow" 13 | compileSdk = flutter.compileSdkVersion 14 | ndkVersion = flutter.ndkVersion 15 | 16 | compileOptions { 17 | sourceCompatibility = JavaVersion.VERSION_1_8 18 | targetCompatibility = JavaVersion.VERSION_1_8 19 | } 20 | 21 | kotlinOptions { 22 | jvmTarget = JavaVersion.VERSION_1_8 23 | } 24 | 25 | defaultConfig { 26 | // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). 27 | applicationId = "com.example.payflow" 28 | // You can update the following values to match your application needs. 29 | // For more information, see: https://flutter.dev/to/review-gradle-config. 30 | minSdk = flutter.minSdkVersion 31 | targetSdk = flutter.targetSdkVersion 32 | versionCode = flutter.versionCode 33 | versionName = flutter.versionName 34 | } 35 | 36 | buildTypes { 37 | release { 38 | // TODO: Add your own signing config for the release build. 39 | // Signing with the debug keys for now, so `flutter run --release` works. 40 | signingConfig = signingConfigs.debug 41 | } 42 | } 43 | } 44 | 45 | flutter { 46 | source = "../.." 47 | } 48 | -------------------------------------------------------------------------------- /lib/shared/widgets/set_label_buttons/set_label_buttons.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | import 'package:payflow/shared/themes/app_colors.dart'; 4 | import 'package:payflow/shared/widgets/divider/divider_widget.dart'; 5 | import 'package:payflow/shared/widgets/label_button/label_button.dart'; 6 | 7 | class SetLabelButtons extends StatelessWidget { 8 | const SetLabelButtons({ 9 | super.key, 10 | required this.labelPrimary, 11 | required this.onTapPrimary, 12 | required this.labelSecondary, 13 | required this.onTapSecondary, 14 | this.enablePrimaryColor = false, 15 | this.enableSecondaryColor = false, 16 | }); 17 | 18 | final String labelPrimary; 19 | final VoidCallback onTapPrimary; 20 | final String labelSecondary; 21 | final VoidCallback onTapSecondary; 22 | final bool enablePrimaryColor; 23 | final bool enableSecondaryColor; 24 | 25 | @override 26 | Widget build(BuildContext context) { 27 | return Container( 28 | color: AppColors.background, 29 | height: 56, 30 | child: Row( 31 | children: [ 32 | if (enablePrimaryColor) ...[ 33 | LabelButton.primary( 34 | label: labelPrimary, 35 | onPressed: onTapPrimary, 36 | ), 37 | ] else ...[ 38 | LabelButton.heading( 39 | label: labelPrimary, 40 | onPressed: onTapPrimary, 41 | ), 42 | ], 43 | const DividerWidget(height: 56), 44 | LabelButton.heading( 45 | label: labelSecondary, 46 | onPressed: onTapSecondary, 47 | ) 48 | ], 49 | ), 50 | ); 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /lib/shared/widgets/social_login_button/social_login_button.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | import 'package:payflow/shared/themes/app_colors.dart'; 4 | import 'package:payflow/shared/themes/app_images.dart'; 5 | import 'package:payflow/shared/themes/app_text_styles.dart'; 6 | 7 | class SocialLoginButton extends StatelessWidget { 8 | const SocialLoginButton({ 9 | super.key, 10 | required this.onTap, 11 | }); 12 | 13 | final VoidCallback onTap; 14 | 15 | @override 16 | Widget build(BuildContext context) { 17 | return InkWell( 18 | onTap: onTap, 19 | child: Container( 20 | height: 56, 21 | decoration: BoxDecoration( 22 | color: AppColors.shape, 23 | borderRadius: BorderRadius.circular(5), 24 | border: const Border.fromBorderSide( 25 | BorderSide(color: AppColors.stroke), 26 | ), 27 | ), 28 | child: Row( 29 | children: [ 30 | Container( 31 | height: 56, 32 | decoration: const BoxDecoration( 33 | border: Border( 34 | right: BorderSide(color: AppColors.stroke), 35 | ), 36 | ), 37 | child: Padding( 38 | padding: const EdgeInsets.only(left: 2, right: 2), 39 | child: Image.asset(AppImages.google), 40 | ), 41 | ), 42 | Expanded( 43 | flex: 4, 44 | child: Align( 45 | alignment: Alignment.center, 46 | child: Text( 47 | 'Enter with Google', 48 | style: AppTextStyles.buttonGrey, 49 | ), 50 | ), 51 | ), 52 | ], 53 | ), 54 | ), 55 | ); 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /lib/payflow_app.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutter/services.dart'; 3 | 4 | import 'package:payflow/modules/barcode_scanner/barcode_scanner_page.dart'; 5 | import 'package:payflow/modules/home/home_page.dart'; 6 | import 'package:payflow/modules/insert_boleto/insert_boleto_page.dart'; 7 | import 'package:payflow/modules/login/login_page.dart'; 8 | import 'package:payflow/modules/splash/splash_page.dart'; 9 | import 'package:payflow/shared/models/user_model.dart'; 10 | import 'package:payflow/shared/themes/app_colors.dart'; 11 | 12 | class PayFlowApp extends StatelessWidget { 13 | const PayFlowApp({super.key}); 14 | 15 | @override 16 | Widget build(BuildContext context) { 17 | SystemChrome.setPreferredOrientations([ 18 | DeviceOrientation.portraitUp, 19 | DeviceOrientation.portraitDown, 20 | ]); 21 | 22 | SystemChrome.setSystemUIOverlayStyle( 23 | const SystemUiOverlayStyle(statusBarColor: AppColors.primary), 24 | ); 25 | 26 | return MaterialApp( 27 | title: 'PayFlow', 28 | debugShowCheckedModeBanner: false, 29 | theme: ThemeData( 30 | primarySwatch: Colors.orange, 31 | primaryColor: AppColors.primary, 32 | ), 33 | initialRoute: '/splash', 34 | routes: { 35 | '/splash': (context) => const SplashPage(), 36 | '/home': (context) => HomePage( 37 | user: ModalRoute.of(context)?.settings.arguments as UserModel, 38 | ), 39 | '/login': (context) => const LoginPage(), 40 | '/barcode_scanner': (context) => const BarcodeScannerPage(), 41 | '/insert_boleto': (context) => InsertBoletoPage( 42 | barcode: ModalRoute.of(context)?.settings.arguments.toString() ?? 43 | '123456', 44 | ), 45 | }, 46 | ); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /lib/shared/widgets/boleto_info/boleto_info_widget.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | import 'package:payflow/shared/themes/app_colors.dart'; 4 | import 'package:payflow/shared/themes/app_images.dart'; 5 | import 'package:payflow/shared/themes/app_text_styles.dart'; 6 | 7 | class BoletoInfoWidget extends StatelessWidget { 8 | const BoletoInfoWidget({ 9 | super.key, 10 | required this.size, 11 | }); 12 | 13 | final int size; 14 | 15 | @override 16 | Widget build(BuildContext context) { 17 | return Container( 18 | decoration: BoxDecoration( 19 | color: AppColors.secondary, 20 | borderRadius: BorderRadius.circular(5), 21 | ), 22 | child: Padding( 23 | padding: const EdgeInsets.symmetric(vertical: 24), 24 | child: Row( 25 | mainAxisAlignment: MainAxisAlignment.spaceEvenly, 26 | children: [ 27 | Image.asset( 28 | AppImages.logomini, 29 | color: AppColors.background, 30 | width: 56, 31 | height: 34, 32 | ), 33 | Container( 34 | width: 1, 35 | height: 32, 36 | color: AppColors.background, 37 | ), 38 | Text.rich(TextSpan( 39 | text: 'You have ', 40 | style: AppTextStyles.captionBackground, 41 | children: [ 42 | TextSpan( 43 | text: '$size boletos\n', 44 | style: AppTextStyles.captionBoldBackground, 45 | ), 46 | TextSpan( 47 | text: 'registered to pay', 48 | style: AppTextStyles.captionBackground, 49 | ), 50 | ], 51 | )) 52 | ], 53 | ), 54 | ), 55 | ); 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /ios/Runner/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleDisplayName 8 | Payflow 9 | CFBundleExecutable 10 | $(EXECUTABLE_NAME) 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | payflow 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 | CADisableMinimumFrameDurationOnPhone 45 | 46 | UIApplicationSupportsIndirectInputEvents 47 | 48 | 49 | 50 | -------------------------------------------------------------------------------- /android/app/google-services.json: -------------------------------------------------------------------------------- 1 | { 2 | "project_info": { 3 | "project_number": "729322644360", 4 | "project_id": "payflow-e9031", 5 | "storage_bucket": "payflow-e9031.appspot.com" 6 | }, 7 | "client": [ 8 | { 9 | "client_info": { 10 | "mobilesdk_app_id": "1:729322644360:android:119258b076855540e7903d", 11 | "android_client_info": { 12 | "package_name": "com.example.payflow" 13 | } 14 | }, 15 | "oauth_client": [ 16 | { 17 | "client_id": "729322644360-llus2au7g894p00i74s1b6ehvfhbhnk5.apps.googleusercontent.com", 18 | "client_type": 1, 19 | "android_info": { 20 | "package_name": "com.example.payflow", 21 | "certificate_hash": "75d8a67272b0c9f4976a140d3d715a6fa10e3a8e" 22 | } 23 | }, 24 | { 25 | "client_id": "729322644360-t8prj2nrrs940i6pcv9835p2vqptld1c.apps.googleusercontent.com", 26 | "client_type": 1, 27 | "android_info": { 28 | "package_name": "com.example.payflow", 29 | "certificate_hash": "05fbcd6425dc68ce458bbf8c18c9954d3db598f6" 30 | } 31 | }, 32 | { 33 | "client_id": "729322644360-lbs56tbklg97o8casjv6eaajdvdl7fh7.apps.googleusercontent.com", 34 | "client_type": 3 35 | } 36 | ], 37 | "api_key": [ 38 | { 39 | "current_key": "AIzaSyBpmYKtwuR0i-2z9e0GuklRxK0oCY900EA" 40 | } 41 | ], 42 | "services": { 43 | "appinvite_service": { 44 | "other_platform_oauth_client": [ 45 | { 46 | "client_id": "729322644360-lbs56tbklg97o8casjv6eaajdvdl7fh7.apps.googleusercontent.com", 47 | "client_type": 3 48 | } 49 | ] 50 | } 51 | } 52 | } 53 | ], 54 | "configuration_version": "1" 55 | } -------------------------------------------------------------------------------- /lib/shared/models/boleto_model.dart: -------------------------------------------------------------------------------- 1 | import 'dart:convert'; 2 | 3 | class BoletoModel { 4 | factory BoletoModel.fromJson(String source) => 5 | BoletoModel.fromMap(json.decode(source)); 6 | 7 | factory BoletoModel.fromMap(Map map) { 8 | return BoletoModel( 9 | name: map['name'], 10 | dueDate: map['dueDate'], 11 | value: map['value'], 12 | barcode: map['barcode'], 13 | ); 14 | } 15 | 16 | factory BoletoModel.empty() { 17 | return BoletoModel( 18 | name: '', 19 | dueDate: '', 20 | value: 0, 21 | barcode: '', 22 | ); 23 | } 24 | 25 | BoletoModel({ 26 | required this.name, 27 | required this.dueDate, 28 | required this.value, 29 | required this.barcode, 30 | }); 31 | 32 | final String name; 33 | final String dueDate; 34 | final double value; 35 | final String barcode; 36 | 37 | BoletoModel copyWith({ 38 | String? name, 39 | String? dueDate, 40 | double? value, 41 | String? barcode, 42 | }) { 43 | return BoletoModel( 44 | name: name ?? this.name, 45 | dueDate: dueDate ?? this.dueDate, 46 | value: value ?? this.value, 47 | barcode: barcode ?? this.barcode, 48 | ); 49 | } 50 | 51 | Map toMap() { 52 | return { 53 | 'name': name, 54 | 'dueDate': dueDate, 55 | 'value': value, 56 | 'barcode': barcode, 57 | }; 58 | } 59 | 60 | String toJson() => json.encode(toMap()); 61 | 62 | @override 63 | bool operator ==(Object other) { 64 | if (identical(this, other)) return true; 65 | return other is BoletoModel && 66 | other.name == name && 67 | other.dueDate == dueDate && 68 | other.value == value && 69 | other.barcode == barcode; 70 | } 71 | 72 | @override 73 | int get hashCode { 74 | return name.hashCode ^ dueDate.hashCode ^ value.hashCode ^ barcode.hashCode; 75 | } 76 | 77 | @override 78 | String toString() { 79 | return 'BoletoModel(name: $name, dueDate: $dueDate, value: $value, barcode: $barcode)'; 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /android/app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 15 | 19 | 23 | 24 | 25 | 26 | 27 | 28 | 30 | 33 | 34 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /ios/Runner/Base.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /lib/shared/widgets/input_text/input_text_widget.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | import 'package:animated_card/animated_card.dart'; 4 | 5 | import 'package:payflow/shared/themes/app_colors.dart'; 6 | import 'package:payflow/shared/themes/app_text_styles.dart'; 7 | 8 | class InputTextWidget extends StatelessWidget { 9 | const InputTextWidget({ 10 | super.key, 11 | required this.label, 12 | required this.icon, 13 | required this.onChanged, 14 | this.initalValue, 15 | this.validator, 16 | this.controller, 17 | this.keyboardType = TextInputType.number, 18 | }); 19 | 20 | final String label; 21 | final IconData icon; 22 | final String? initalValue; 23 | final String? Function(String?)? validator; 24 | final TextEditingController? controller; 25 | final void Function(String value) onChanged; 26 | final TextInputType keyboardType; 27 | 28 | @override 29 | Widget build(BuildContext context) { 30 | return AnimatedCard( 31 | direction: AnimatedCardDirection.top, 32 | child: Padding( 33 | padding: const EdgeInsets.only(bottom: 16), 34 | child: Column( 35 | children: [ 36 | TextFormField( 37 | keyboardType: keyboardType, 38 | controller: controller, 39 | initialValue: initalValue, 40 | validator: validator, 41 | onChanged: onChanged, 42 | style: AppTextStyles.input, 43 | decoration: InputDecoration( 44 | contentPadding: EdgeInsets.zero, 45 | labelText: label, 46 | labelStyle: AppTextStyles.input, 47 | border: InputBorder.none, 48 | icon: Row( 49 | mainAxisSize: MainAxisSize.min, 50 | children: [ 51 | Padding( 52 | padding: const EdgeInsets.symmetric(horizontal: 18), 53 | child: Icon( 54 | icon, 55 | color: AppColors.primary, 56 | ), 57 | ), 58 | Container( 59 | width: 1, 60 | height: 48, 61 | color: AppColors.stroke, 62 | ), 63 | ], 64 | ), 65 | ), 66 | ), 67 | const Divider( 68 | height: 1, 69 | thickness: 1, 70 | color: AppColors.stroke, 71 | ), 72 | ], 73 | ), 74 | ), 75 | ); 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /lib/modules/login/login_page.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | import 'package:payflow/modules/login/login_controller.dart'; 4 | import 'package:payflow/shared/themes/app_colors.dart'; 5 | import 'package:payflow/shared/themes/app_images.dart'; 6 | import 'package:payflow/shared/themes/app_text_styles.dart'; 7 | import 'package:payflow/shared/widgets/social_login_button/social_login_button.dart'; 8 | 9 | class LoginPage extends StatefulWidget { 10 | const LoginPage({super.key}); 11 | 12 | @override 13 | State createState() => _LoginPageState(); 14 | } 15 | 16 | class _LoginPageState extends State { 17 | final controller = LoginController(); 18 | 19 | @override 20 | Widget build(BuildContext context) { 21 | final size = MediaQuery.of(context).size; 22 | return Scaffold( 23 | backgroundColor: AppColors.background, 24 | body: SizedBox( 25 | width: size.width, 26 | height: size.height, 27 | child: Stack( 28 | children: [ 29 | Container( 30 | width: size.width, 31 | height: size.height * 0.36, 32 | color: AppColors.primary, 33 | ), 34 | Positioned( 35 | top: 40, 36 | left: 0, 37 | right: 0, 38 | child: Image.asset( 39 | AppImages.person, 40 | width: size.width * 0.5, 41 | height: size.height * 0.5, 42 | ), 43 | ), 44 | Positioned( 45 | bottom: size.height * 0.05, 46 | left: 0, 47 | right: 0, 48 | child: Column( 49 | mainAxisAlignment: MainAxisAlignment.center, 50 | crossAxisAlignment: CrossAxisAlignment.center, 51 | children: [ 52 | Image.asset(AppImages.logomini), 53 | Padding( 54 | padding: const EdgeInsets.fromLTRB(70, 30, 70, 0), 55 | child: Text( 56 | 'Organize your tickets in one place', 57 | textAlign: TextAlign.center, 58 | style: AppTextStyles.titleHome, 59 | ), 60 | ), 61 | Padding( 62 | padding: const EdgeInsets.fromLTRB(40, 40, 40, 0), 63 | child: SocialLoginButton( 64 | onTap: () => controller.googleSignIn(context), 65 | ), 66 | ) 67 | ], 68 | ), 69 | ) 70 | ], 71 | ), 72 | ), 73 | ); 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /lib/modules/my_boletos/my_boletos_page.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | import 'package:animated_card/animated_card.dart'; 4 | 5 | import 'package:payflow/shared/models/boleto_model.dart'; 6 | import 'package:payflow/shared/themes/app_colors.dart'; 7 | import 'package:payflow/shared/themes/app_text_styles.dart'; 8 | import 'package:payflow/shared/widgets/boleto_info/boleto_info_widget.dart'; 9 | import 'package:payflow/shared/widgets/boleto_list/boleto_list_controller.dart'; 10 | import 'package:payflow/shared/widgets/boleto_list/boleto_list_widget.dart'; 11 | 12 | class MyBoletosPage extends StatefulWidget { 13 | const MyBoletosPage({super.key}); 14 | 15 | @override 16 | State createState() => _MyBoletosPageState(); 17 | } 18 | 19 | class _MyBoletosPageState extends State { 20 | final controller = BoletoListController(); 21 | 22 | @override 23 | Widget build(BuildContext context) { 24 | return SingleChildScrollView( 25 | child: Column( 26 | children: [ 27 | SizedBox( 28 | height: 80, 29 | child: Stack( 30 | children: [ 31 | Container( 32 | height: 40, 33 | color: AppColors.primary, 34 | ), 35 | Padding( 36 | padding: const EdgeInsets.symmetric(horizontal: 24), 37 | child: ValueListenableBuilder>( 38 | valueListenable: controller.boletosNotifier, 39 | builder: (_, boletos, __) => AnimatedCard( 40 | direction: AnimatedCardDirection.top, 41 | child: BoletoInfoWidget( 42 | size: boletos.length, 43 | ), 44 | ), 45 | ), 46 | ), 47 | ], 48 | ), 49 | ), 50 | Container( 51 | padding: const EdgeInsets.fromLTRB(24, 24, 24, 0), 52 | alignment: Alignment.centerLeft, 53 | child: Text( 54 | 'My tickets', 55 | style: AppTextStyles.titleBoldHeading, 56 | ), 57 | ), 58 | const Padding( 59 | padding: EdgeInsets.symmetric(horizontal: 24), 60 | child: Divider( 61 | color: AppColors.stroke, 62 | ), 63 | ), 64 | Padding( 65 | padding: const EdgeInsets.symmetric(horizontal: 24), 66 | child: BoletoListWidget( 67 | controller: controller, 68 | ), 69 | ) 70 | ], 71 | ), 72 | ); 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /lib/firebase_options.dart: -------------------------------------------------------------------------------- 1 | // File generated by FlutterFire CLI. 2 | // ignore_for_file: type=lint 3 | import 'package:firebase_core/firebase_core.dart' show FirebaseOptions; 4 | import 'package:flutter/foundation.dart' 5 | show defaultTargetPlatform, kIsWeb, TargetPlatform; 6 | 7 | /// Default [FirebaseOptions] for use with your Firebase apps. 8 | /// 9 | /// Example: 10 | /// ```dart 11 | /// import 'firebase_options.dart'; 12 | /// // ... 13 | /// await Firebase.initializeApp( 14 | /// options: DefaultFirebaseOptions.currentPlatform, 15 | /// ); 16 | /// ``` 17 | class DefaultFirebaseOptions { 18 | static FirebaseOptions get currentPlatform { 19 | if (kIsWeb) { 20 | throw UnsupportedError( 21 | 'DefaultFirebaseOptions have not been configured for web - ' 22 | 'you can reconfigure this by running the FlutterFire CLI again.', 23 | ); 24 | } 25 | switch (defaultTargetPlatform) { 26 | case TargetPlatform.android: 27 | return android; 28 | case TargetPlatform.iOS: 29 | return ios; 30 | case TargetPlatform.macOS: 31 | throw UnsupportedError( 32 | 'DefaultFirebaseOptions have not been configured for macos - ' 33 | 'you can reconfigure this by running the FlutterFire CLI again.', 34 | ); 35 | case TargetPlatform.windows: 36 | throw UnsupportedError( 37 | 'DefaultFirebaseOptions have not been configured for windows - ' 38 | 'you can reconfigure this by running the FlutterFire CLI again.', 39 | ); 40 | case TargetPlatform.linux: 41 | throw UnsupportedError( 42 | 'DefaultFirebaseOptions have not been configured for linux - ' 43 | 'you can reconfigure this by running the FlutterFire CLI again.', 44 | ); 45 | default: 46 | throw UnsupportedError( 47 | 'DefaultFirebaseOptions are not supported for this platform.', 48 | ); 49 | } 50 | } 51 | 52 | static const FirebaseOptions android = FirebaseOptions( 53 | apiKey: 'AIzaSyBpmYKtwuR0i-2z9e0GuklRxK0oCY900EA', 54 | appId: '1:729322644360:android:119258b076855540e7903d', 55 | messagingSenderId: '729322644360', 56 | projectId: 'payflow-e9031', 57 | storageBucket: 'payflow-e9031.appspot.com', 58 | ); 59 | 60 | static const FirebaseOptions ios = FirebaseOptions( 61 | apiKey: 'AIzaSyCqaqkpt-mf3OIYey0FOBloURmGLkxqN7Y', 62 | appId: '1:729322644360:ios:a9335a23edeed249e7903d', 63 | messagingSenderId: '729322644360', 64 | projectId: 'payflow-e9031', 65 | storageBucket: 'payflow-e9031.appspot.com', 66 | androidClientId: '729322644360-llus2au7g894p00i74s1b6ehvfhbhnk5.apps.googleusercontent.com', 67 | iosClientId: '729322644360-u5mn7hlr17h5e04piolpf8pshq5b3uc5.apps.googleusercontent.com', 68 | iosBundleId: 'com.example.payflow', 69 | ); 70 | } 71 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # repository 2 | .metadata 3 | integration_test 4 | 5 | # Miscellaneous 6 | *.class 7 | *.lock 8 | *.log 9 | *.pyc 10 | *.swp 11 | .DS_Store 12 | .atom/ 13 | .buildlog/ 14 | .history 15 | .svn/ 16 | 17 | # IntelliJ related 18 | *.iml 19 | *.ipr 20 | *.iws 21 | .idea/ 22 | 23 | # Visual Studio Code related 24 | .classpath 25 | .project 26 | .settings/ 27 | .vscode/ 28 | 29 | # Flutter repo-specific 30 | /bin/cache/ 31 | /bin/mingit/ 32 | /dev/benchmarks/mega_gallery/ 33 | /dev/bots/.recipe_deps 34 | /dev/bots/android_tools/ 35 | /dev/devicelab/ABresults*.json 36 | /dev/docs/doc/ 37 | /dev/docs/flutter.docs.zip 38 | /dev/docs/lib/ 39 | /dev/docs/pubspec.yaml 40 | /dev/integration_tests/**/xcuserdata 41 | /dev/integration_tests/**/Pods 42 | /packages/flutter/coverage/ 43 | version 44 | analysis_benchmark.json 45 | 46 | # packages file containing multi-root paths 47 | .packages.generated 48 | 49 | # Flutter/Dart/Pub related 50 | **/doc/api/ 51 | .dart_tool/ 52 | .flutter-plugins 53 | .flutter-plugins-dependencies 54 | **/generated_plugin_registrant.dart 55 | .packages 56 | .pub-cache/ 57 | .pub/ 58 | build/ 59 | flutter_*.png 60 | linked_*.ds 61 | unlinked.ds 62 | unlinked_spec.ds 63 | 64 | # Android related 65 | **/android/**/gradle-wrapper.jar 66 | **/android/.gradle 67 | **/android/captures/ 68 | **/android/gradlew 69 | **/android/gradlew.bat 70 | **/android/local.properties 71 | **/android/**/GeneratedPluginRegistrant.java 72 | **/android/key.properties 73 | *.jks 74 | 75 | # iOS/XCode related 76 | **/ios/**/*.mode1v3 77 | **/ios/**/*.mode2v3 78 | **/ios/**/*.moved-aside 79 | **/ios/**/*.pbxuser 80 | **/ios/**/*.perspectivev3 81 | **/ios/**/*sync/ 82 | **/ios/**/.sconsign.dblite 83 | **/ios/**/.tags* 84 | **/ios/**/.vagrant/ 85 | **/ios/**/DerivedData/ 86 | **/ios/**/Icon? 87 | **/ios/**/Pods/ 88 | **/ios/**/.symlinks/ 89 | **/ios/**/profile 90 | **/ios/**/xcuserdata 91 | **/ios/.generated/ 92 | **/ios/Flutter/.last_build_id 93 | **/ios/Flutter/App.framework 94 | **/ios/Flutter/Flutter.framework 95 | **/ios/Flutter/Flutter.podspec 96 | **/ios/Flutter/Generated.xcconfig 97 | **/ios/Flutter/app.flx 98 | **/ios/Flutter/app.zip 99 | **/ios/Flutter/flutter_assets/ 100 | **/ios/Flutter/flutter_export_environment.sh 101 | **/ios/ServiceDefinitions.json 102 | **/ios/Runner/GeneratedPluginRegistrant.* 103 | 104 | # macOS 105 | **/macos/Flutter/GeneratedPluginRegistrant.swift 106 | **/macos/Flutter/Flutter-Debug.xcconfig 107 | **/macos/Flutter/Flutter-Release.xcconfig 108 | **/macos/Flutter/Flutter-Profile.xcconfig 109 | 110 | # Coverage 111 | coverage/ 112 | 113 | # Symbols 114 | app.*.symbols 115 | 116 | # Exceptions to above rules. 117 | !**/ios/**/default.mode1v3 118 | !**/ios/**/default.mode2v3 119 | !**/ios/**/default.pbxuser 120 | !**/ios/**/default.perspectivev3 121 | !/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages 122 | !/dev/ci/**/Gemfile.lock 123 | -------------------------------------------------------------------------------- /lib/shared/widgets/bottom_sheet/bottom_sheet_widget.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | import 'package:payflow/shared/themes/app_colors.dart'; 4 | import 'package:payflow/shared/themes/app_text_styles.dart'; 5 | import 'package:payflow/shared/widgets/set_label_buttons/set_label_buttons.dart'; 6 | 7 | class BottomSheetWidget extends StatelessWidget { 8 | const BottomSheetWidget({ 9 | super.key, 10 | required this.labelPrimary, 11 | required this.onTapPrimary, 12 | required this.labelSecondary, 13 | required this.onTapSecondary, 14 | required this.title, 15 | required this.subtitle, 16 | }); 17 | 18 | final String labelPrimary; 19 | final VoidCallback onTapPrimary; 20 | final String labelSecondary; 21 | final VoidCallback onTapSecondary; 22 | final String title; 23 | final String subtitle; 24 | 25 | @override 26 | Widget build(BuildContext context) { 27 | return SafeArea( 28 | child: RotatedBox( 29 | quarterTurns: 1, 30 | child: Material( 31 | color: Colors.transparent, 32 | child: Column( 33 | children: [ 34 | Expanded( 35 | child: Container( 36 | color: Colors.black.withOpacity(0.5), 37 | ), 38 | ), 39 | Container( 40 | color: AppColors.background, 41 | child: Column( 42 | mainAxisSize: MainAxisSize.min, 43 | children: [ 44 | const SizedBox(height: 40), 45 | Text.rich( 46 | TextSpan( 47 | text: title, 48 | style: AppTextStyles.buttonBoldHeading, 49 | children: [ 50 | TextSpan( 51 | text: '\n$subtitle', 52 | style: AppTextStyles.buttonHeading, 53 | ) 54 | ], 55 | ), 56 | textAlign: TextAlign.center, 57 | ), 58 | const SizedBox(height: 40), 59 | Row( 60 | children: [ 61 | Expanded( 62 | child: Container( 63 | height: 1, 64 | color: AppColors.stroke, 65 | ), 66 | ), 67 | ], 68 | ), 69 | SetLabelButtons( 70 | enablePrimaryColor: true, 71 | labelPrimary: labelPrimary, 72 | onTapPrimary: onTapPrimary, 73 | labelSecondary: labelSecondary, 74 | onTapSecondary: onTapSecondary, 75 | ), 76 | const SizedBox(height: 2), 77 | ], 78 | ), 79 | ), 80 | ], 81 | ), 82 | ), 83 | ), 84 | ); 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /lib/shared/themes/app_text_styles.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | import 'package:google_fonts/google_fonts.dart'; 4 | 5 | import 'package:payflow/shared/themes/app_colors.dart'; 6 | 7 | class AppTextStyles { 8 | static final titleHome = GoogleFonts.lexendDeca( 9 | fontSize: 32, 10 | fontWeight: FontWeight.w600, 11 | color: AppColors.heading, 12 | ); 13 | 14 | static final titleRegular = GoogleFonts.lexendDeca( 15 | fontSize: 20, 16 | fontWeight: FontWeight.w400, 17 | color: AppColors.background, 18 | ); 19 | 20 | static final titleBoldHeading = GoogleFonts.lexendDeca( 21 | fontSize: 20, 22 | fontWeight: FontWeight.w600, 23 | color: AppColors.heading, 24 | ); 25 | 26 | static final titleBoldBackground = GoogleFonts.lexendDeca( 27 | fontSize: 20, 28 | fontWeight: FontWeight.w600, 29 | color: AppColors.background, 30 | ); 31 | 32 | static final titleListTile = GoogleFonts.lexendDeca( 33 | fontSize: 17, 34 | fontWeight: FontWeight.w600, 35 | color: AppColors.heading, 36 | ); 37 | 38 | static final trailingRegular = GoogleFonts.lexendDeca( 39 | fontSize: 16, 40 | fontWeight: FontWeight.w400, 41 | color: AppColors.heading, 42 | ); 43 | 44 | static final trailingBold = GoogleFonts.lexendDeca( 45 | fontSize: 16, 46 | fontWeight: FontWeight.w600, 47 | color: AppColors.heading, 48 | ); 49 | 50 | static final buttonPrimary = GoogleFonts.inter( 51 | fontSize: 15, 52 | fontWeight: FontWeight.w400, 53 | color: AppColors.primary, 54 | ); 55 | 56 | static final buttonHeading = GoogleFonts.inter( 57 | fontSize: 15, 58 | fontWeight: FontWeight.w400, 59 | color: AppColors.heading, 60 | ); 61 | 62 | static final buttonGrey = GoogleFonts.inter( 63 | fontSize: 15, 64 | fontWeight: FontWeight.w400, 65 | color: AppColors.grey, 66 | ); 67 | 68 | static final buttonBackground = GoogleFonts.inter( 69 | fontSize: 15, 70 | fontWeight: FontWeight.w400, 71 | color: AppColors.background, 72 | ); 73 | 74 | static final buttonBoldPrimary = GoogleFonts.inter( 75 | fontSize: 15, 76 | fontWeight: FontWeight.w700, 77 | color: AppColors.primary, 78 | ); 79 | 80 | static final buttonBoldHeading = GoogleFonts.inter( 81 | fontSize: 15, 82 | fontWeight: FontWeight.w700, 83 | color: AppColors.heading, 84 | ); 85 | 86 | static final buttonBoldGrey = GoogleFonts.inter( 87 | fontSize: 15, 88 | fontWeight: FontWeight.w700, 89 | color: AppColors.grey, 90 | ); 91 | 92 | static final buttonBoldBackground = GoogleFonts.inter( 93 | fontSize: 15, 94 | fontWeight: FontWeight.w700, 95 | color: AppColors.background, 96 | ); 97 | 98 | static final input = GoogleFonts.inter( 99 | fontSize: 15, 100 | fontWeight: FontWeight.w400, 101 | color: AppColors.input, 102 | ); 103 | 104 | static final captionBackground = GoogleFonts.inter( 105 | fontSize: 13, 106 | fontWeight: FontWeight.w400, 107 | color: AppColors.background, 108 | ); 109 | 110 | static final captionShape = GoogleFonts.inter( 111 | fontSize: 13, 112 | fontWeight: FontWeight.w400, 113 | color: AppColors.shape, 114 | ); 115 | 116 | static final captionBody = GoogleFonts.inter( 117 | fontSize: 13, 118 | fontWeight: FontWeight.w400, 119 | color: AppColors.body, 120 | ); 121 | 122 | static final captionBoldBackground = GoogleFonts.inter( 123 | fontSize: 13, 124 | fontWeight: FontWeight.w600, 125 | color: AppColors.background, 126 | ); 127 | 128 | static final captionBoldShape = GoogleFonts.inter( 129 | fontSize: 13, 130 | fontWeight: FontWeight.w600, 131 | color: AppColors.shape, 132 | ); 133 | 134 | static final captionBoldBody = GoogleFonts.inter( 135 | fontSize: 13, 136 | fontWeight: FontWeight.w600, 137 | color: AppColors.body, 138 | ); 139 | } 140 | -------------------------------------------------------------------------------- /ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 37 | 38 | 39 | 40 | 43 | 49 | 50 | 51 | 52 | 53 | 63 | 65 | 71 | 72 | 73 | 74 | 80 | 82 | 88 | 89 | 90 | 91 | 93 | 94 | 97 | 98 | 99 | -------------------------------------------------------------------------------- /lib/modules/barcode_scanner/barcode_scanner_page.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | import 'package:payflow/modules/barcode_scanner/barcode_scanner_controller.dart'; 4 | import 'package:payflow/modules/barcode_scanner/barcode_scanner_status.dart'; 5 | import 'package:payflow/shared/themes/app_colors.dart'; 6 | import 'package:payflow/shared/themes/app_text_styles.dart'; 7 | import 'package:payflow/shared/widgets/bottom_sheet/bottom_sheet_widget.dart'; 8 | import 'package:payflow/shared/widgets/set_label_buttons/set_label_buttons.dart'; 9 | 10 | class BarcodeScannerPage extends StatefulWidget { 11 | const BarcodeScannerPage({super.key}); 12 | 13 | @override 14 | State createState() => _BarcodeScannerPageState(); 15 | } 16 | 17 | class _BarcodeScannerPageState extends State { 18 | final controller = BarcodeScannerController(); 19 | 20 | @override 21 | void initState() { 22 | super.initState(); 23 | controller.getAvailableCameras(); 24 | controller.statusNotifier.addListener(() { 25 | if (controller.status.hasBarcode) { 26 | if (mounted) { 27 | Navigator.pushReplacementNamed( 28 | context, 29 | '/insert_boleto', 30 | arguments: controller.status.barcode, 31 | ); 32 | } 33 | } 34 | }); 35 | } 36 | 37 | @override 38 | void dispose() { 39 | controller.dispose(); 40 | super.dispose(); 41 | } 42 | 43 | @override 44 | Widget build(BuildContext context) { 45 | return SafeArea( 46 | child: Stack( 47 | children: [ 48 | ValueListenableBuilder( 49 | valueListenable: controller.statusNotifier, 50 | builder: (_, status, __) { 51 | if (status.showCamera) { 52 | return Container( 53 | color: Colors.red, 54 | height: MediaQuery.of(context).size.height, 55 | width: 800, 56 | child: controller.cameraController?.buildPreview(), 57 | ); 58 | } else { 59 | return const SizedBox(); 60 | } 61 | }, 62 | ), 63 | RotatedBox( 64 | quarterTurns: 1, 65 | child: Scaffold( 66 | backgroundColor: Colors.transparent, 67 | appBar: AppBar( 68 | backgroundColor: Colors.black, 69 | centerTitle: true, 70 | title: Text( 71 | 'Scan the boleto\'s barcode', 72 | style: AppTextStyles.buttonBackground, 73 | ), 74 | leading: const BackButton( 75 | color: AppColors.background, 76 | ), 77 | ), 78 | bottomNavigationBar: SetLabelButtons( 79 | labelPrimary: 'Insert boleto code', 80 | onTapPrimary: () { 81 | Navigator.pushReplacementNamed( 82 | context, 83 | '/insert_boleto', 84 | ); 85 | }, 86 | labelSecondary: 'Add from gallery', 87 | onTapSecondary: controller.scanWithImagePicker, 88 | ), 89 | ), 90 | ), 91 | ValueListenableBuilder( 92 | valueListenable: controller.statusNotifier, 93 | builder: (_, status, __) { 94 | if (status.hasError) { 95 | return Align( 96 | alignment: Alignment.bottomLeft, 97 | child: BottomSheetWidget( 98 | title: 'Unable to identify a barcode.', 99 | subtitle: 100 | 'Try scanning again or enter your bill of exchange code.', 101 | labelPrimary: 'Rescan', 102 | onTapPrimary: () { 103 | controller.scanWithCamera(); 104 | }, 105 | labelSecondary: 'Enter code', 106 | onTapSecondary: () { 107 | Navigator.pushReplacementNamed( 108 | context, 109 | '/insert_boleto', 110 | ); 111 | }, 112 | ), 113 | ); 114 | } else { 115 | return const SizedBox(); 116 | } 117 | }, 118 | ), 119 | ], 120 | ), 121 | ); 122 | } 123 | } 124 | -------------------------------------------------------------------------------- /lib/modules/home/home_page.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:payflow/modules/extract/extract_page.dart'; 3 | 4 | import 'package:payflow/modules/home/home_controller.dart'; 5 | import 'package:payflow/modules/my_boletos/my_boletos_page.dart'; 6 | import 'package:payflow/shared/models/user_model.dart'; 7 | import 'package:payflow/shared/themes/app_colors.dart'; 8 | import 'package:payflow/shared/themes/app_images.dart'; 9 | import 'package:payflow/shared/themes/app_text_styles.dart'; 10 | 11 | class HomePage extends StatefulWidget { 12 | const HomePage({ 13 | super.key, 14 | required this.user, 15 | }); 16 | 17 | final UserModel user; 18 | 19 | @override 20 | State createState() => _HomePageState(); 21 | } 22 | 23 | class _HomePageState extends State { 24 | @override 25 | Widget build(BuildContext context) { 26 | final controller = HomeController(); 27 | 28 | return Scaffold( 29 | appBar: PreferredSize( 30 | preferredSize: const Size.fromHeight(152), 31 | child: Container( 32 | height: 152, 33 | padding: const EdgeInsets.only(top: 40), 34 | color: AppColors.primary, 35 | child: Center( 36 | child: ListTile( 37 | contentPadding: const EdgeInsets.symmetric(horizontal: 24), 38 | title: Text.rich( 39 | TextSpan( 40 | text: 'Hello, ', 41 | style: AppTextStyles.titleRegular, 42 | children: [ 43 | TextSpan( 44 | text: 'Felipe', 45 | style: AppTextStyles.titleBoldBackground, 46 | ), 47 | ], 48 | ), 49 | ), 50 | subtitle: Text( 51 | 'Keep your accounts up to date', 52 | style: AppTextStyles.captionShape, 53 | ), 54 | trailing: Container( 55 | height: 48, 56 | width: 48, 57 | decoration: BoxDecoration( 58 | color: Colors.black, 59 | borderRadius: BorderRadius.circular(5), 60 | image: DecorationImage( 61 | image: NetworkImage( 62 | widget.user.photoURL ?? AppImages.logomini, 63 | ), 64 | ), 65 | ), 66 | ), 67 | ), 68 | ), 69 | ), 70 | ), 71 | body: ValueListenableBuilder( 72 | valueListenable: controller.currentPage, 73 | builder: (_, value, __) { 74 | return PageView( 75 | controller: controller.pageController, 76 | physics: const NeverScrollableScrollPhysics(), 77 | children: const [ 78 | MyBoletosPage(), 79 | ExtractPage(), 80 | ], 81 | ); 82 | }, 83 | ), 84 | bottomNavigationBar: SizedBox( 85 | height: 90, 86 | child: Row( 87 | mainAxisAlignment: MainAxisAlignment.spaceEvenly, 88 | children: [ 89 | IconButton( 90 | onPressed: () { 91 | setState(() { 92 | controller.setPage(0); 93 | }); 94 | }, 95 | icon: const Icon( 96 | Icons.home, 97 | color: AppColors.body, 98 | ), 99 | ), 100 | GestureDetector( 101 | onTap: () async { 102 | await Navigator.pushNamed( 103 | context, 104 | '/barcode_scanner', 105 | ); 106 | setState(() {}); 107 | }, 108 | child: Container( 109 | width: 56, 110 | height: 56, 111 | decoration: BoxDecoration( 112 | color: AppColors.primary, 113 | borderRadius: BorderRadius.circular(5), 114 | ), 115 | child: const Icon( 116 | Icons.add_box_outlined, 117 | color: AppColors.background, 118 | ), 119 | ), 120 | ), 121 | IconButton( 122 | onPressed: () async { 123 | setState(() { 124 | controller.setPage(1); 125 | }); 126 | }, 127 | icon: const Icon( 128 | Icons.description_outlined, 129 | color: AppColors.body, 130 | ), 131 | ), 132 | ], 133 | ), 134 | ), 135 | ); 136 | } 137 | } 138 | -------------------------------------------------------------------------------- /lib/modules/insert_boleto/insert_boleto_page.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | import 'package:flutter_masked_text2/flutter_masked_text2.dart'; 4 | import 'package:font_awesome_flutter/font_awesome_flutter.dart'; 5 | 6 | import 'package:payflow/modules/insert_boleto/insert_boleto_controller.dart'; 7 | import 'package:payflow/shared/themes/app_colors.dart'; 8 | import 'package:payflow/shared/themes/app_text_styles.dart'; 9 | import 'package:payflow/shared/widgets/input_text/input_text_widget.dart'; 10 | import 'package:payflow/shared/widgets/set_label_buttons/set_label_buttons.dart'; 11 | 12 | class InsertBoletoPage extends StatefulWidget { 13 | const InsertBoletoPage({ 14 | super.key, 15 | required this.barcode, 16 | }); 17 | 18 | final String barcode; 19 | 20 | @override 21 | State createState() => _InsertBoletoPageState(); 22 | } 23 | 24 | class _InsertBoletoPageState extends State { 25 | final formKey = GlobalKey(); 26 | final controller = InsertBoletoController(); 27 | final barcodeInputTextController = TextEditingController(); 28 | final dueDateInputTextController = MaskedTextController(mask: '00/00/0000'); 29 | 30 | final moneyInputTextController = MoneyMaskedTextController( 31 | leftSymbol: '\$', 32 | initialValue: 0, 33 | decimalSeparator: ',', 34 | ); 35 | 36 | @override 37 | void initState() { 38 | super.initState(); 39 | } 40 | 41 | @override 42 | Widget build(BuildContext context) { 43 | return Scaffold( 44 | backgroundColor: AppColors.background, 45 | appBar: AppBar( 46 | elevation: 0, 47 | backgroundColor: AppColors.background, 48 | leading: const BackButton(color: AppColors.input), 49 | ), 50 | body: SingleChildScrollView( 51 | child: Padding( 52 | padding: const EdgeInsets.symmetric(horizontal: 24), 53 | child: Column( 54 | crossAxisAlignment: CrossAxisAlignment.center, 55 | children: [ 56 | Padding( 57 | padding: const EdgeInsets.fromLTRB(93, 24, 93, 24), 58 | child: Text( 59 | 'Fill in the payment slip data', 60 | style: AppTextStyles.titleBoldHeading, 61 | textAlign: TextAlign.center, 62 | ), 63 | ), 64 | Form( 65 | key: formKey, 66 | child: Column( 67 | children: [ 68 | InputTextWidget( 69 | label: 'Boleto name', 70 | icon: Icons.description_outlined, 71 | onChanged: (value) => controller.onChange(name: value), 72 | validator: controller.validateName, 73 | keyboardType: TextInputType.name, 74 | ), 75 | InputTextWidget( 76 | controller: dueDateInputTextController, 77 | label: 'Due date', 78 | icon: FontAwesomeIcons.circleXmark, 79 | onChanged: (value) => controller.onChange(dueDate: value), 80 | validator: controller.validateDueDate, 81 | ), 82 | InputTextWidget( 83 | controller: moneyInputTextController, 84 | label: 'Price', 85 | icon: FontAwesomeIcons.wallet, 86 | validator: (_) => controller.validateValue( 87 | moneyInputTextController.numberValue, 88 | ), 89 | onChanged: (value) => controller.onChange( 90 | value: moneyInputTextController.numberValue, 91 | ), 92 | ), 93 | InputTextWidget( 94 | controller: barcodeInputTextController, 95 | label: 'Code', 96 | icon: FontAwesomeIcons.barcode, 97 | validator: controller.validateCode, 98 | onChanged: (value) => controller.onChange(barcode: value), 99 | ), 100 | ], 101 | ), 102 | ) 103 | ], 104 | ), 105 | ), 106 | ), 107 | bottomNavigationBar: Column( 108 | mainAxisSize: MainAxisSize.min, 109 | children: [ 110 | const Divider( 111 | height: 1, 112 | thickness: 1, 113 | color: AppColors.stroke, 114 | ), 115 | SetLabelButtons( 116 | enableSecondaryColor: true, 117 | labelPrimary: 'Cancel', 118 | onTapPrimary: () { 119 | Navigator.pop(context); 120 | }, 121 | labelSecondary: 'Register', 122 | onTapSecondary: () async { 123 | if (formKey.currentState?.validate() ?? false) { 124 | await controller.saveBoleto(); 125 | if (!context.mounted) return; 126 | Navigator.pop(context); 127 | setState(() {}); 128 | } 129 | }, 130 | ), 131 | ], 132 | ), 133 | ); 134 | } 135 | } 136 | -------------------------------------------------------------------------------- /lib/modules/barcode_scanner/barcode_scanner_controller.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/foundation.dart'; 2 | import 'package:flutter/material.dart'; 3 | 4 | import 'package:camera/camera.dart'; 5 | import 'package:google_mlkit_barcode_scanning/google_mlkit_barcode_scanning.dart'; 6 | import 'package:image_picker/image_picker.dart'; 7 | 8 | import 'package:payflow/modules/barcode_scanner/barcode_scanner_status.dart'; 9 | import 'package:payflow/shared/themes/app_images.dart'; 10 | 11 | class BarcodeScannerController extends ChangeNotifier { 12 | final barcodeScanner = BarcodeScanner(); 13 | 14 | final statusNotifier = ValueNotifier( 15 | BarcodeScannerStatus(), 16 | ); 17 | 18 | InputImage? imagePicker; 19 | CameraController? cameraController; 20 | bool _disposed = false; 21 | 22 | BarcodeScannerStatus get status => statusNotifier.value; 23 | set barCodeStatus(BarcodeScannerStatus status) => 24 | statusNotifier.value = status; 25 | 26 | static const defaultSize = 400.0; 27 | 28 | Future getAvailableCameras() async { 29 | try { 30 | final response = await availableCameras(); 31 | final camera = response.firstWhere( 32 | (element) => element.lensDirection == CameraLensDirection.back, 33 | ); 34 | cameraController = CameraController( 35 | camera, 36 | ResolutionPreset.max, 37 | enableAudio: false, 38 | ); 39 | await cameraController?.initialize(); 40 | scanWithCamera(); 41 | listenCamera(); 42 | } catch (e, s) { 43 | barCodeStatus = BarcodeScannerStatus.error(e.toString()); 44 | debugPrint('Error when getting camera ${e.toString()}'); 45 | debugPrint('Stack when getting camera ${s.toString()}'); 46 | } 47 | } 48 | 49 | Future scannerBarCode(InputImage inputImage) async { 50 | try { 51 | final barcodes = await barcodeScanner.processImage(inputImage); 52 | String? barcode; 53 | for (Barcode item in barcodes) { 54 | barcode = item.displayValue; 55 | } 56 | 57 | if (barcode != null && status.barcode.isEmpty) { 58 | barCodeStatus = BarcodeScannerStatus.barcode(barcode); 59 | cameraController?.dispose(); 60 | await barcodeScanner.close(); 61 | } 62 | 63 | return; 64 | } catch (e) { 65 | debugPrint('Error when scanning barcode ${e.toString()}'); 66 | debugPrint('Stack when scanning barcode ${e.toString()}'); 67 | } 68 | } 69 | 70 | void scanWithImagePicker() async { 71 | final response = await ImagePicker().pickImage(source: ImageSource.gallery); 72 | final inputImage = InputImage.fromFilePath( 73 | response?.path ?? AppImages.logomini, 74 | ); 75 | 76 | scannerBarCode(inputImage); 77 | } 78 | 79 | void scanWithCamera() { 80 | barCodeStatus = BarcodeScannerStatus.available(); 81 | Future.delayed( 82 | const Duration(seconds: 10), 83 | () { 84 | barCodeStatus = BarcodeScannerStatus.available(); 85 | if (status.hasBarcode == false) { 86 | barCodeStatus = 87 | BarcodeScannerStatus.error('Timeout de leitura de boleto'); 88 | } 89 | }, 90 | ); 91 | } 92 | 93 | void listenCamera() { 94 | if (cameraController?.value.isStreamingImages == false) { 95 | cameraController?.startImageStream((cameraImage) async { 96 | if (status.stopScanner == false) { 97 | try { 98 | final allBytes = WriteBuffer(); 99 | for (Plane plane in cameraImage.planes) { 100 | allBytes.putUint8List(plane.bytes); 101 | } 102 | final bytes = allBytes.done().buffer.asUint8List(); 103 | final imageSize = Size( 104 | cameraImage.width.toDouble(), 105 | cameraImage.height.toDouble(), 106 | ); 107 | const imageRotation = InputImageRotation.rotation0deg; 108 | final inputImageFormat = 109 | InputImageFormatValue.fromRawValue(cameraImage.format.raw) ?? 110 | InputImageFormat.nv21; 111 | final planeData = cameraImage.planes.map( 112 | (plane) { 113 | return InputImageMetadata( 114 | bytesPerRow: plane.bytesPerRow, 115 | rotation: imageRotation, 116 | format: inputImageFormat, 117 | size: imageSize, 118 | ); 119 | }, 120 | ).toList(); 121 | 122 | final metadata = InputImageMetadata( 123 | size: imageSize, 124 | rotation: imageRotation, 125 | format: inputImageFormat, 126 | bytesPerRow: planeData.first.bytesPerRow, 127 | ); 128 | 129 | final inputImageCamera = InputImage.fromBytes( 130 | bytes: bytes, 131 | metadata: metadata, 132 | ); 133 | 134 | scannerBarCode(inputImageCamera); 135 | } catch (e, s) { 136 | debugPrint('Error when reading camera ${e.toString()}'); 137 | debugPrint('Stack when reading camera ${s.toString()}'); 138 | } 139 | } 140 | }); 141 | } 142 | } 143 | 144 | @override 145 | void dispose() { 146 | _disposed = true; 147 | cameraController?.dispose(); 148 | if (status.showCamera) { 149 | cameraController?.dispose(); 150 | } 151 | if (status.hasBarcode) { 152 | barcodeScanner.close(); 153 | } 154 | super.dispose(); 155 | } 156 | 157 | @override 158 | void notifyListeners() { 159 | if (!_disposed) { 160 | super.notifyListeners(); 161 | } 162 | } 163 | } 164 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

2 | Logo PayFlow 3 |

4 | 5 |

PayFlow

6 | 7 | - ✅ Liftoff 💪 8 | - ✅ Maximum Speed 🏃‍♂️ 9 | - ✅ In Orbit 👨‍🚀 10 | - ✅ Landing 🔥 11 | - ✅ Surface Exploration ⚡ 12 | - ✅ Accelerating your Career 🚀 13 | - ✅ Mission Closure 💜 14 | 15 | --- 16 | 17 |

Topics 📋

18 | 19 |

20 | 21 | - [About 📖](#about-) 22 | - [Layout 🎨](#layout-) 23 | - [Functionalities 🛠️](#functionalities-%EF%B8%8F) 24 | - [Challenges and Learnings along the way 🤯](#challenges-and-learnings-along-the-way-) 25 | - [Notion Files 📋](#notion-file-) 26 | - [How to Use 🤔](#how-to-use-) 27 | - [How to Contribute 💪](#how-to-contribute-) 28 | - [License 📝](#license-) 29 | 30 |

31 | 32 | --- 33 | 34 |

About 📖

35 | 36 |

37 | This project was developed at Next Level Week, an intense week of studies, networking, friendship, group work, accompanied by a sensational project developed by Rocketseat from the 20th to the 27th of June.
38 | This application is a Billet Management, containing several features, which will soon be developed and explained.
39 |

40 | 41 | --- 42 | 43 |

Layout 🎨

44 | 45 |

46 | PayFlow 47 |

48 | 49 |

50 | The Layout was developed by Tiago Luchtenberg, and you can access it on Figma: 51 | 52 | - Mobile 📱 53 |

54 | 55 | --- 56 | 57 |

Functionalities 🛠️

58 | 59 |

60 | 61 | - Payment and Bills Management 62 | - Social login with Google 63 | - Firebase MLKit with QRCode Reading 64 | - Camera Usage 65 | - Boleto Registration 66 | - Ticket name 67 | - Maturity 68 | - Price 69 | - QRCode 70 | - Query Statements 71 | - Among many other amazing things! 72 | 73 |

74 | 75 | --- 76 | 77 |

Challenges and Learnings along the way 🤯

78 | 79 |

80 | This was the most intense week of my life. And this NLW was super special for me, because in addition to always being that amazing week in all aspects, in this edition I had my first experience participating in the Rocketseat team.
81 | In addition to the usual challenge, which was to reconcile the time to take classes, study and take notes, in this edition I had to reconcile all of this, plus my work in helping people in the community and my intention was that my participation was the most fast, active, practical... the best of them all!
82 | The focus was on working my ass off and having an intense week. And that led me to give up a lot of things, but it helped me to have a new perspective on a lot of things, and the main one was that: "you can always do more, you can always be better and become better, success is trainable.". And man, I felt that, and I know I can do all of this, I want to always be better, and prepare myself to be and give my best.
83 | I managed to stand out in the week, being the TOP1 member 🥇 of the entire community, with more messages / answers / help / and other types of help and participation.
84 | Rocketseat provided me and is providing me with an amazing experience! It's amazing to be here. And I will do my best! 💜 85 |

86 | 87 | --- 88 | 89 |

Notion File 📋

90 | 91 | - [Flutter Trail](https://www.notion.so/NLW-Together-Conte-dos-complementares-ae22125e899549efb2d4e360b5ee5ca3) 🚀 92 | 93 | --- 94 | 95 |

How to Use 🤔

96 | 97 | ``` 98 | First of all, correctly configure the Flutter development environment on your machine, see https://flutter.dev/docs/get-started/install 99 | 100 | - Clone this repository: 101 | $ git clone https://github.com/felipecastrosales/payflow payflow 102 | 103 | - Enter in directory: 104 | $ cd payflow 105 | 106 | - For install dependencies: 107 | $ flutter pub get 108 | 109 | - Run the app: 110 | $ flutter run 111 | ``` 112 | 113 | --- 114 | 115 |

How to Contribute 💪

116 | 117 | ``` 118 | - Fork the project 119 | 120 | - Create a new branch with your changes: 121 | $ git checkout -b my-feature 122 | 123 | - Save your changes and create a commit message telling you what you did: 124 | $ git commit -m "feature: My new feature" 125 | 126 | - Submit your changes: 127 | $ git push origin my-feature 128 | ``` 129 | 130 | --- 131 | 132 |

License 📝

133 | 134 |

135 | This repository is under MIT license. You can see the LICENSE file for more details. 😉 136 |

137 | 138 | --- 139 | 140 | >This project was developed with ❤️ by **[@Felipe Sales](https://www.linkedin.com/in/felipecastrosales/)**, with the instructor **[@GabulDev](https://www.linkedin.com/in/gabuldev/)**, in #NextLevelWeek from **[Rocketseat](https://rocketseat.com.br/)**.
141 | If it helped you, give ⭐, contribute, it will help me too 😉 142 | 143 | --- 144 | 145 |
146 | 147 | [![Linkedin Badge](https://img.shields.io/badge/-Felipe%20Sales-292929?style=flat-square&logo=Linkedin&logoColor=white&link=https://www.linkedin.com/in/felipecastrosales/)](https://www.linkedin.com/in/felipecastrosales/) 148 | 149 |
150 | -------------------------------------------------------------------------------- /README-pt.md: -------------------------------------------------------------------------------- 1 |

2 | Logo PayFlow 3 |

4 | 5 |

PayFlow

6 | 7 | - ✅ Liftoff 💪 8 | - ✅ Maximum Speed 🏃‍♂️ 9 | - ✅ In Orbit 👨‍🚀 10 | - ✅ Landing 🔥 11 | - ✅ Surface Exploration ⚡ 12 | - ✅ Acelerando sua Carreira 🚀 13 | - ✅ Encerramento da Missão 💜 14 | 15 | --- 16 | 17 |

Tópicos 📋

18 | 19 |

20 | 21 | - [Sobre 📖](#sobre-) 22 | - [Layout 🎨](#layout-) 23 | - [Funcionalidades 🛠️](#Funcionalidades-%EF%B8%8F) 24 | - [Desafios e Aprendizados no Caminho 🤯](#desafios-e-aprendizados-no-caminho-) 25 | - [Arquivos no Notion 📋](#arquivo-no-notion-) 26 | - [Como Usar 🤔](#como-usar-) 27 | - [Como Contribuir 💪](#como-contribuir-) 28 | - [Licença 📝](#licença-) 29 | 30 |

31 | 32 | --- 33 | 34 |

Sobre 📖

35 | 36 |

37 | Esse projeto foi desenvolvido na Next Level Week, uma semana intensa de estudos, networking, amizade, trabalho em grupo, acompanhado de um projeto sensacional desenvolvido pela Rocketseat do dia 20 ao dia 27 de Junho.
38 | Essa aplicação é um Gerenciamento de Boletos, contendo vários recursos, que em breve serão desenvolvidos e explicados.
39 |

40 | 41 | --- 42 | 43 |

Layout 🎨

44 | 45 |

46 | PayFlow 47 |

48 | 49 |

50 | O Layout foi desenvolvido por Tiago Luchtenberg, e você pode acessá-lo no Figma: 51 | 52 | - Mobile 📱 53 |

54 | 55 | --- 56 | 57 |

Funcionalidades 🛠️

58 | 59 |

60 | 61 | - Gerenciamento de Pagamentos e Boletos 62 | - Login Social com Google 63 | - MLKit do Firebase com Leitura de QRCode 64 | - Uso de Câmera 65 | - Cadastro de Boleto 66 | - Nome do Boleto 67 | - Vencimento 68 | - Valor 69 | - Código do QRCode 70 | - Consulta de Extratos 71 | - Entre várias outras coisas incríveis! 72 | 73 |

74 | 75 | --- 76 | 77 |

Desafios e Aprendizados no Caminho 🤯

78 | 79 |

80 | Essa foi a semana mais intensa da minha vida. E essa NLW foi super especial para mim, pois além de ser sempre aquela semana incrível em todos os quesitos, nessa edição eu tive minha primeira experiência participando do time da Rocketseat.
81 | Além do desafio de sempre, que era conciliar o tempo para fazer as aulas, estudar e realizar anotações, nessa edição eu tive que conciliar tudo isso mais o meu trabalho em ajudar as pessoas da comunidade e meu intuito era que a minha participação fosse a mais rápida, ativa, prática... a melhor de todas!
82 | O foco era trabalhar pra caralho e ter uma semana intensa. E isso me levou a abrir mão de muitas coisas, mas que me ajudaram a ter uma visão nova sobre muitas coisas, e a principal era de que: "você sempre pode mais, você sempre pode ser melhor e se tornar melhor, o sucesso é treinável.". E cara, eu senti isso, e sei que posso fazer tudo isso, eu quero sempre ser melhor, e me preparar para ser e dar o melhor.
83 | Eu consegui me destacar na semana, sendo o membro TOP1 🥇 de toda a comunidade, com mais mensagens / respostas / auxílios / e outros tipos de ajudas e participações.
84 | A Rocketseat me proporcionou e está me proporcionando uma experiência incrível! É incrível estar aqui. E eu vou dar meu máximo! 💜 85 |

86 | 87 | --- 88 | 89 |

Arquivo no Notion 📋

90 | 91 | - [Flutter Trail](https://www.notion.so/NLW-Together-Conte-dos-complementares-ae22125e899549efb2d4e360b5ee5ca3) 🚀 92 | 93 | --- 94 | 95 |

Como Usar 🤔

96 | 97 | ``` 98 | Primeiro, configure corretamente o ambiente de desenvolvimento em Flutter na sua máruina, veja em: https://flutter.dev/docs/get-started/install 99 | 100 | - Clone esse repositório: 101 | $ git clone https://github.com/felipecastrosales/payflow payflow 102 | 103 | - Entre no diretório: 104 | $ cd payflow 105 | 106 | - Instale as dependências: 107 | $ flutter pub get 108 | 109 | - Inicie o app: 110 | $ flutter run 111 | ``` 112 | 113 | --- 114 | 115 |

Como Contribuir 💪

116 | 117 | ``` 118 | - Fork o projeto 119 | 120 | - Cria uma nova branch com suas mudanças: 121 | $ git checkout -b my-feature 122 | 123 | - Salve suas mudanças e crie uma mensagem de commit falando o que fez: 124 | $ git commit -m "feature: My new feature" 125 | 126 | - Envie suas mudanças: 127 | $ git push origin my-feature 128 | ``` 129 | 130 | --- 131 | 132 |

Licença 📝

133 | 134 |

135 | Este repositório está sob licença MIT. Você pode ver o arquivo LICENSE para mais detalhes. 😉 136 |

137 | 138 | --- 139 | 140 | >Esse projeto foi desenvolvido com ❤️ por **[@Felipe Sales](https://www.linkedin.com/in/felipecastrosales/)**, com o instrutor **[@GabulDev](https://www.linkedin.com/in/gabuldev/)**, na #NextLevelWeek da **[Rocketseat](https://rocketseat.com.br/)**.
141 | Se isso te ajudou, dê uma ⭐, isso vai me ajudar também! 😉 142 | 143 | --- 144 | 145 |
146 | 147 | [![Linkedin Badge](https://img.shields.io/badge/-Felipe%20Sales-292929?style=flat-square&logo=Linkedin&logoColor=white&link=https://www.linkedin.com/in/felipecastrosales/)](https://www.linkedin.com/in/felipecastrosales/) 148 | 149 |
-------------------------------------------------------------------------------- /ios/Runner.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 54; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; }; 11 | 331C808B294A63AB00263BE5 /* RunnerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 331C807B294A618700263BE5 /* RunnerTests.swift */; }; 12 | 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; }; 13 | 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; }; 14 | 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; }; 15 | 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; }; 16 | 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; }; 17 | C76341CFCF42AAA610BF8305 /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 0B1FE0E1FA9DC4FE5D1250DA /* GoogleService-Info.plist */; }; 18 | /* End PBXBuildFile section */ 19 | 20 | /* Begin PBXContainerItemProxy section */ 21 | 331C8085294A63A400263BE5 /* PBXContainerItemProxy */ = { 22 | isa = PBXContainerItemProxy; 23 | containerPortal = 97C146E61CF9000F007C117D /* Project object */; 24 | proxyType = 1; 25 | remoteGlobalIDString = 97C146ED1CF9000F007C117D; 26 | remoteInfo = Runner; 27 | }; 28 | /* End PBXContainerItemProxy section */ 29 | 30 | /* Begin PBXCopyFilesBuildPhase section */ 31 | 9705A1C41CF9048500538489 /* Embed Frameworks */ = { 32 | isa = PBXCopyFilesBuildPhase; 33 | buildActionMask = 2147483647; 34 | dstPath = ""; 35 | dstSubfolderSpec = 10; 36 | files = ( 37 | ); 38 | name = "Embed Frameworks"; 39 | runOnlyForDeploymentPostprocessing = 0; 40 | }; 41 | /* End PBXCopyFilesBuildPhase section */ 42 | 43 | /* Begin PBXFileReference section */ 44 | 0B1FE0E1FA9DC4FE5D1250DA /* GoogleService-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; name = "GoogleService-Info.plist"; path = "Runner/GoogleService-Info.plist"; sourceTree = ""; }; 45 | 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = ""; }; 46 | 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = ""; }; 47 | 331C807B294A618700263BE5 /* RunnerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RunnerTests.swift; sourceTree = ""; }; 48 | 331C8081294A63A400263BE5 /* RunnerTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = RunnerTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 49 | 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; }; 50 | 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = ""; }; 51 | 74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 52 | 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; }; 53 | 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = ""; }; 54 | 9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = ""; }; 55 | 97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; }; 56 | 97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 57 | 97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 58 | 97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 59 | 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 60 | /* End PBXFileReference section */ 61 | 62 | /* Begin PBXFrameworksBuildPhase section */ 63 | 97C146EB1CF9000F007C117D /* Frameworks */ = { 64 | isa = PBXFrameworksBuildPhase; 65 | buildActionMask = 2147483647; 66 | files = ( 67 | ); 68 | runOnlyForDeploymentPostprocessing = 0; 69 | }; 70 | /* End PBXFrameworksBuildPhase section */ 71 | 72 | /* Begin PBXGroup section */ 73 | 331C8082294A63A400263BE5 /* RunnerTests */ = { 74 | isa = PBXGroup; 75 | children = ( 76 | 331C807B294A618700263BE5 /* RunnerTests.swift */, 77 | ); 78 | path = RunnerTests; 79 | sourceTree = ""; 80 | }; 81 | 9740EEB11CF90186004384FC /* Flutter */ = { 82 | isa = PBXGroup; 83 | children = ( 84 | 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */, 85 | 9740EEB21CF90195004384FC /* Debug.xcconfig */, 86 | 7AFA3C8E1D35360C0083082E /* Release.xcconfig */, 87 | 9740EEB31CF90195004384FC /* Generated.xcconfig */, 88 | ); 89 | name = Flutter; 90 | sourceTree = ""; 91 | }; 92 | 97C146E51CF9000F007C117D = { 93 | isa = PBXGroup; 94 | children = ( 95 | 9740EEB11CF90186004384FC /* Flutter */, 96 | 97C146F01CF9000F007C117D /* Runner */, 97 | 97C146EF1CF9000F007C117D /* Products */, 98 | 331C8082294A63A400263BE5 /* RunnerTests */, 99 | 0B1FE0E1FA9DC4FE5D1250DA /* GoogleService-Info.plist */, 100 | ); 101 | sourceTree = ""; 102 | }; 103 | 97C146EF1CF9000F007C117D /* Products */ = { 104 | isa = PBXGroup; 105 | children = ( 106 | 97C146EE1CF9000F007C117D /* Runner.app */, 107 | 331C8081294A63A400263BE5 /* RunnerTests.xctest */, 108 | ); 109 | name = Products; 110 | sourceTree = ""; 111 | }; 112 | 97C146F01CF9000F007C117D /* Runner */ = { 113 | isa = PBXGroup; 114 | children = ( 115 | 97C146FA1CF9000F007C117D /* Main.storyboard */, 116 | 97C146FD1CF9000F007C117D /* Assets.xcassets */, 117 | 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */, 118 | 97C147021CF9000F007C117D /* Info.plist */, 119 | 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */, 120 | 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */, 121 | 74858FAE1ED2DC5600515810 /* AppDelegate.swift */, 122 | 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */, 123 | ); 124 | path = Runner; 125 | sourceTree = ""; 126 | }; 127 | /* End PBXGroup section */ 128 | 129 | /* Begin PBXNativeTarget section */ 130 | 331C8080294A63A400263BE5 /* RunnerTests */ = { 131 | isa = PBXNativeTarget; 132 | buildConfigurationList = 331C8087294A63A400263BE5 /* Build configuration list for PBXNativeTarget "RunnerTests" */; 133 | buildPhases = ( 134 | 331C807D294A63A400263BE5 /* Sources */, 135 | 331C807F294A63A400263BE5 /* Resources */, 136 | ); 137 | buildRules = ( 138 | ); 139 | dependencies = ( 140 | 331C8086294A63A400263BE5 /* PBXTargetDependency */, 141 | ); 142 | name = RunnerTests; 143 | productName = RunnerTests; 144 | productReference = 331C8081294A63A400263BE5 /* RunnerTests.xctest */; 145 | productType = "com.apple.product-type.bundle.unit-test"; 146 | }; 147 | 97C146ED1CF9000F007C117D /* Runner */ = { 148 | isa = PBXNativeTarget; 149 | buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */; 150 | buildPhases = ( 151 | 9740EEB61CF901F6004384FC /* Run Script */, 152 | 97C146EA1CF9000F007C117D /* Sources */, 153 | 97C146EB1CF9000F007C117D /* Frameworks */, 154 | 97C146EC1CF9000F007C117D /* Resources */, 155 | 9705A1C41CF9048500538489 /* Embed Frameworks */, 156 | 3B06AD1E1E4923F5004D2608 /* Thin Binary */, 157 | ); 158 | buildRules = ( 159 | ); 160 | dependencies = ( 161 | ); 162 | name = Runner; 163 | productName = Runner; 164 | productReference = 97C146EE1CF9000F007C117D /* Runner.app */; 165 | productType = "com.apple.product-type.application"; 166 | }; 167 | /* End PBXNativeTarget section */ 168 | 169 | /* Begin PBXProject section */ 170 | 97C146E61CF9000F007C117D /* Project object */ = { 171 | isa = PBXProject; 172 | attributes = { 173 | BuildIndependentTargetsInParallel = YES; 174 | LastUpgradeCheck = 1510; 175 | ORGANIZATIONNAME = ""; 176 | TargetAttributes = { 177 | 331C8080294A63A400263BE5 = { 178 | CreatedOnToolsVersion = 14.0; 179 | TestTargetID = 97C146ED1CF9000F007C117D; 180 | }; 181 | 97C146ED1CF9000F007C117D = { 182 | CreatedOnToolsVersion = 7.3.1; 183 | LastSwiftMigration = 1100; 184 | }; 185 | }; 186 | }; 187 | buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */; 188 | compatibilityVersion = "Xcode 9.3"; 189 | developmentRegion = en; 190 | hasScannedForEncodings = 0; 191 | knownRegions = ( 192 | en, 193 | Base, 194 | ); 195 | mainGroup = 97C146E51CF9000F007C117D; 196 | productRefGroup = 97C146EF1CF9000F007C117D /* Products */; 197 | projectDirPath = ""; 198 | projectRoot = ""; 199 | targets = ( 200 | 97C146ED1CF9000F007C117D /* Runner */, 201 | 331C8080294A63A400263BE5 /* RunnerTests */, 202 | ); 203 | }; 204 | /* End PBXProject section */ 205 | 206 | /* Begin PBXResourcesBuildPhase section */ 207 | 331C807F294A63A400263BE5 /* Resources */ = { 208 | isa = PBXResourcesBuildPhase; 209 | buildActionMask = 2147483647; 210 | files = ( 211 | ); 212 | runOnlyForDeploymentPostprocessing = 0; 213 | }; 214 | 97C146EC1CF9000F007C117D /* Resources */ = { 215 | isa = PBXResourcesBuildPhase; 216 | buildActionMask = 2147483647; 217 | files = ( 218 | 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */, 219 | 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */, 220 | 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */, 221 | 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */, 222 | C76341CFCF42AAA610BF8305 /* GoogleService-Info.plist in Resources */, 223 | ); 224 | runOnlyForDeploymentPostprocessing = 0; 225 | }; 226 | /* End PBXResourcesBuildPhase section */ 227 | 228 | /* Begin PBXShellScriptBuildPhase section */ 229 | 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = { 230 | isa = PBXShellScriptBuildPhase; 231 | alwaysOutOfDate = 1; 232 | buildActionMask = 2147483647; 233 | files = ( 234 | ); 235 | inputPaths = ( 236 | "${TARGET_BUILD_DIR}/${INFOPLIST_PATH}", 237 | ); 238 | name = "Thin Binary"; 239 | outputPaths = ( 240 | ); 241 | runOnlyForDeploymentPostprocessing = 0; 242 | shellPath = /bin/sh; 243 | shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin"; 244 | }; 245 | 9740EEB61CF901F6004384FC /* Run Script */ = { 246 | isa = PBXShellScriptBuildPhase; 247 | alwaysOutOfDate = 1; 248 | buildActionMask = 2147483647; 249 | files = ( 250 | ); 251 | inputPaths = ( 252 | ); 253 | name = "Run Script"; 254 | outputPaths = ( 255 | ); 256 | runOnlyForDeploymentPostprocessing = 0; 257 | shellPath = /bin/sh; 258 | shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build"; 259 | }; 260 | /* End PBXShellScriptBuildPhase section */ 261 | 262 | /* Begin PBXSourcesBuildPhase section */ 263 | 331C807D294A63A400263BE5 /* Sources */ = { 264 | isa = PBXSourcesBuildPhase; 265 | buildActionMask = 2147483647; 266 | files = ( 267 | 331C808B294A63AB00263BE5 /* RunnerTests.swift in Sources */, 268 | ); 269 | runOnlyForDeploymentPostprocessing = 0; 270 | }; 271 | 97C146EA1CF9000F007C117D /* Sources */ = { 272 | isa = PBXSourcesBuildPhase; 273 | buildActionMask = 2147483647; 274 | files = ( 275 | 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */, 276 | 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */, 277 | ); 278 | runOnlyForDeploymentPostprocessing = 0; 279 | }; 280 | /* End PBXSourcesBuildPhase section */ 281 | 282 | /* Begin PBXTargetDependency section */ 283 | 331C8086294A63A400263BE5 /* PBXTargetDependency */ = { 284 | isa = PBXTargetDependency; 285 | target = 97C146ED1CF9000F007C117D /* Runner */; 286 | targetProxy = 331C8085294A63A400263BE5 /* PBXContainerItemProxy */; 287 | }; 288 | /* End PBXTargetDependency section */ 289 | 290 | /* Begin PBXVariantGroup section */ 291 | 97C146FA1CF9000F007C117D /* Main.storyboard */ = { 292 | isa = PBXVariantGroup; 293 | children = ( 294 | 97C146FB1CF9000F007C117D /* Base */, 295 | ); 296 | name = Main.storyboard; 297 | sourceTree = ""; 298 | }; 299 | 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */ = { 300 | isa = PBXVariantGroup; 301 | children = ( 302 | 97C147001CF9000F007C117D /* Base */, 303 | ); 304 | name = LaunchScreen.storyboard; 305 | sourceTree = ""; 306 | }; 307 | /* End PBXVariantGroup section */ 308 | 309 | /* Begin XCBuildConfiguration section */ 310 | 249021D3217E4FDB00AE95B9 /* Profile */ = { 311 | isa = XCBuildConfiguration; 312 | buildSettings = { 313 | ALWAYS_SEARCH_USER_PATHS = NO; 314 | ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; 315 | CLANG_ANALYZER_NONNULL = YES; 316 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 317 | CLANG_CXX_LIBRARY = "libc++"; 318 | CLANG_ENABLE_MODULES = YES; 319 | CLANG_ENABLE_OBJC_ARC = YES; 320 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 321 | CLANG_WARN_BOOL_CONVERSION = YES; 322 | CLANG_WARN_COMMA = YES; 323 | CLANG_WARN_CONSTANT_CONVERSION = YES; 324 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 325 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 326 | CLANG_WARN_EMPTY_BODY = YES; 327 | CLANG_WARN_ENUM_CONVERSION = YES; 328 | CLANG_WARN_INFINITE_RECURSION = YES; 329 | CLANG_WARN_INT_CONVERSION = YES; 330 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 331 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 332 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 333 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 334 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 335 | CLANG_WARN_STRICT_PROTOTYPES = YES; 336 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 337 | CLANG_WARN_UNREACHABLE_CODE = YES; 338 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 339 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 340 | COPY_PHASE_STRIP = NO; 341 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 342 | ENABLE_NS_ASSERTIONS = NO; 343 | ENABLE_STRICT_OBJC_MSGSEND = YES; 344 | ENABLE_USER_SCRIPT_SANDBOXING = NO; 345 | GCC_C_LANGUAGE_STANDARD = gnu99; 346 | GCC_NO_COMMON_BLOCKS = YES; 347 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 348 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 349 | GCC_WARN_UNDECLARED_SELECTOR = YES; 350 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 351 | GCC_WARN_UNUSED_FUNCTION = YES; 352 | GCC_WARN_UNUSED_VARIABLE = YES; 353 | IPHONEOS_DEPLOYMENT_TARGET = 12.0; 354 | MTL_ENABLE_DEBUG_INFO = NO; 355 | SDKROOT = iphoneos; 356 | SUPPORTED_PLATFORMS = iphoneos; 357 | TARGETED_DEVICE_FAMILY = "1,2"; 358 | VALIDATE_PRODUCT = YES; 359 | }; 360 | name = Profile; 361 | }; 362 | 249021D4217E4FDB00AE95B9 /* Profile */ = { 363 | isa = XCBuildConfiguration; 364 | baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; 365 | buildSettings = { 366 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 367 | CLANG_ENABLE_MODULES = YES; 368 | CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; 369 | DEVELOPMENT_TEAM = C2ZWJXER5Z; 370 | ENABLE_BITCODE = NO; 371 | INFOPLIST_FILE = Runner/Info.plist; 372 | LD_RUNPATH_SEARCH_PATHS = ( 373 | "$(inherited)", 374 | "@executable_path/Frameworks", 375 | ); 376 | PRODUCT_BUNDLE_IDENTIFIER = com.example.payflow; 377 | PRODUCT_NAME = "$(TARGET_NAME)"; 378 | SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; 379 | SWIFT_VERSION = 5.0; 380 | VERSIONING_SYSTEM = "apple-generic"; 381 | }; 382 | name = Profile; 383 | }; 384 | 331C8088294A63A400263BE5 /* Debug */ = { 385 | isa = XCBuildConfiguration; 386 | buildSettings = { 387 | BUNDLE_LOADER = "$(TEST_HOST)"; 388 | CODE_SIGN_STYLE = Automatic; 389 | CURRENT_PROJECT_VERSION = 1; 390 | GENERATE_INFOPLIST_FILE = YES; 391 | MARKETING_VERSION = 1.0; 392 | PRODUCT_BUNDLE_IDENTIFIER = com.example.payflow.RunnerTests; 393 | PRODUCT_NAME = "$(TARGET_NAME)"; 394 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; 395 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 396 | SWIFT_VERSION = 5.0; 397 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Runner.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Runner"; 398 | }; 399 | name = Debug; 400 | }; 401 | 331C8089294A63A400263BE5 /* Release */ = { 402 | isa = XCBuildConfiguration; 403 | buildSettings = { 404 | BUNDLE_LOADER = "$(TEST_HOST)"; 405 | CODE_SIGN_STYLE = Automatic; 406 | CURRENT_PROJECT_VERSION = 1; 407 | GENERATE_INFOPLIST_FILE = YES; 408 | MARKETING_VERSION = 1.0; 409 | PRODUCT_BUNDLE_IDENTIFIER = com.example.payflow.RunnerTests; 410 | PRODUCT_NAME = "$(TARGET_NAME)"; 411 | SWIFT_VERSION = 5.0; 412 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Runner.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Runner"; 413 | }; 414 | name = Release; 415 | }; 416 | 331C808A294A63A400263BE5 /* Profile */ = { 417 | isa = XCBuildConfiguration; 418 | buildSettings = { 419 | BUNDLE_LOADER = "$(TEST_HOST)"; 420 | CODE_SIGN_STYLE = Automatic; 421 | CURRENT_PROJECT_VERSION = 1; 422 | GENERATE_INFOPLIST_FILE = YES; 423 | MARKETING_VERSION = 1.0; 424 | PRODUCT_BUNDLE_IDENTIFIER = com.example.payflow.RunnerTests; 425 | PRODUCT_NAME = "$(TARGET_NAME)"; 426 | SWIFT_VERSION = 5.0; 427 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Runner.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Runner"; 428 | }; 429 | name = Profile; 430 | }; 431 | 97C147031CF9000F007C117D /* Debug */ = { 432 | isa = XCBuildConfiguration; 433 | buildSettings = { 434 | ALWAYS_SEARCH_USER_PATHS = NO; 435 | ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; 436 | CLANG_ANALYZER_NONNULL = YES; 437 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 438 | CLANG_CXX_LIBRARY = "libc++"; 439 | CLANG_ENABLE_MODULES = YES; 440 | CLANG_ENABLE_OBJC_ARC = YES; 441 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 442 | CLANG_WARN_BOOL_CONVERSION = YES; 443 | CLANG_WARN_COMMA = YES; 444 | CLANG_WARN_CONSTANT_CONVERSION = YES; 445 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 446 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 447 | CLANG_WARN_EMPTY_BODY = YES; 448 | CLANG_WARN_ENUM_CONVERSION = YES; 449 | CLANG_WARN_INFINITE_RECURSION = YES; 450 | CLANG_WARN_INT_CONVERSION = YES; 451 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 452 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 453 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 454 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 455 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 456 | CLANG_WARN_STRICT_PROTOTYPES = YES; 457 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 458 | CLANG_WARN_UNREACHABLE_CODE = YES; 459 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 460 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 461 | COPY_PHASE_STRIP = NO; 462 | DEBUG_INFORMATION_FORMAT = dwarf; 463 | ENABLE_STRICT_OBJC_MSGSEND = YES; 464 | ENABLE_TESTABILITY = YES; 465 | ENABLE_USER_SCRIPT_SANDBOXING = NO; 466 | GCC_C_LANGUAGE_STANDARD = gnu99; 467 | GCC_DYNAMIC_NO_PIC = NO; 468 | GCC_NO_COMMON_BLOCKS = YES; 469 | GCC_OPTIMIZATION_LEVEL = 0; 470 | GCC_PREPROCESSOR_DEFINITIONS = ( 471 | "DEBUG=1", 472 | "$(inherited)", 473 | ); 474 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 475 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 476 | GCC_WARN_UNDECLARED_SELECTOR = YES; 477 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 478 | GCC_WARN_UNUSED_FUNCTION = YES; 479 | GCC_WARN_UNUSED_VARIABLE = YES; 480 | IPHONEOS_DEPLOYMENT_TARGET = 12.0; 481 | MTL_ENABLE_DEBUG_INFO = YES; 482 | ONLY_ACTIVE_ARCH = YES; 483 | SDKROOT = iphoneos; 484 | TARGETED_DEVICE_FAMILY = "1,2"; 485 | }; 486 | name = Debug; 487 | }; 488 | 97C147041CF9000F007C117D /* Release */ = { 489 | isa = XCBuildConfiguration; 490 | buildSettings = { 491 | ALWAYS_SEARCH_USER_PATHS = NO; 492 | ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; 493 | CLANG_ANALYZER_NONNULL = YES; 494 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 495 | CLANG_CXX_LIBRARY = "libc++"; 496 | CLANG_ENABLE_MODULES = YES; 497 | CLANG_ENABLE_OBJC_ARC = YES; 498 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 499 | CLANG_WARN_BOOL_CONVERSION = YES; 500 | CLANG_WARN_COMMA = YES; 501 | CLANG_WARN_CONSTANT_CONVERSION = YES; 502 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 503 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 504 | CLANG_WARN_EMPTY_BODY = YES; 505 | CLANG_WARN_ENUM_CONVERSION = YES; 506 | CLANG_WARN_INFINITE_RECURSION = YES; 507 | CLANG_WARN_INT_CONVERSION = YES; 508 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 509 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 510 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 511 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 512 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 513 | CLANG_WARN_STRICT_PROTOTYPES = YES; 514 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 515 | CLANG_WARN_UNREACHABLE_CODE = YES; 516 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 517 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 518 | COPY_PHASE_STRIP = NO; 519 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 520 | ENABLE_NS_ASSERTIONS = NO; 521 | ENABLE_STRICT_OBJC_MSGSEND = YES; 522 | ENABLE_USER_SCRIPT_SANDBOXING = NO; 523 | GCC_C_LANGUAGE_STANDARD = gnu99; 524 | GCC_NO_COMMON_BLOCKS = YES; 525 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 526 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 527 | GCC_WARN_UNDECLARED_SELECTOR = YES; 528 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 529 | GCC_WARN_UNUSED_FUNCTION = YES; 530 | GCC_WARN_UNUSED_VARIABLE = YES; 531 | IPHONEOS_DEPLOYMENT_TARGET = 12.0; 532 | MTL_ENABLE_DEBUG_INFO = NO; 533 | SDKROOT = iphoneos; 534 | SUPPORTED_PLATFORMS = iphoneos; 535 | SWIFT_COMPILATION_MODE = wholemodule; 536 | SWIFT_OPTIMIZATION_LEVEL = "-O"; 537 | TARGETED_DEVICE_FAMILY = "1,2"; 538 | VALIDATE_PRODUCT = YES; 539 | }; 540 | name = Release; 541 | }; 542 | 97C147061CF9000F007C117D /* Debug */ = { 543 | isa = XCBuildConfiguration; 544 | baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; 545 | buildSettings = { 546 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 547 | CLANG_ENABLE_MODULES = YES; 548 | CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; 549 | DEVELOPMENT_TEAM = C2ZWJXER5Z; 550 | ENABLE_BITCODE = NO; 551 | INFOPLIST_FILE = Runner/Info.plist; 552 | LD_RUNPATH_SEARCH_PATHS = ( 553 | "$(inherited)", 554 | "@executable_path/Frameworks", 555 | ); 556 | PRODUCT_BUNDLE_IDENTIFIER = com.example.payflow; 557 | PRODUCT_NAME = "$(TARGET_NAME)"; 558 | SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; 559 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 560 | SWIFT_VERSION = 5.0; 561 | VERSIONING_SYSTEM = "apple-generic"; 562 | }; 563 | name = Debug; 564 | }; 565 | 97C147071CF9000F007C117D /* Release */ = { 566 | isa = XCBuildConfiguration; 567 | baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; 568 | buildSettings = { 569 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 570 | CLANG_ENABLE_MODULES = YES; 571 | CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; 572 | DEVELOPMENT_TEAM = C2ZWJXER5Z; 573 | ENABLE_BITCODE = NO; 574 | INFOPLIST_FILE = Runner/Info.plist; 575 | LD_RUNPATH_SEARCH_PATHS = ( 576 | "$(inherited)", 577 | "@executable_path/Frameworks", 578 | ); 579 | PRODUCT_BUNDLE_IDENTIFIER = com.example.payflow; 580 | PRODUCT_NAME = "$(TARGET_NAME)"; 581 | SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; 582 | SWIFT_VERSION = 5.0; 583 | VERSIONING_SYSTEM = "apple-generic"; 584 | }; 585 | name = Release; 586 | }; 587 | /* End XCBuildConfiguration section */ 588 | 589 | /* Begin XCConfigurationList section */ 590 | 331C8087294A63A400263BE5 /* Build configuration list for PBXNativeTarget "RunnerTests" */ = { 591 | isa = XCConfigurationList; 592 | buildConfigurations = ( 593 | 331C8088294A63A400263BE5 /* Debug */, 594 | 331C8089294A63A400263BE5 /* Release */, 595 | 331C808A294A63A400263BE5 /* Profile */, 596 | ); 597 | defaultConfigurationIsVisible = 0; 598 | defaultConfigurationName = Release; 599 | }; 600 | 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */ = { 601 | isa = XCConfigurationList; 602 | buildConfigurations = ( 603 | 97C147031CF9000F007C117D /* Debug */, 604 | 97C147041CF9000F007C117D /* Release */, 605 | 249021D3217E4FDB00AE95B9 /* Profile */, 606 | ); 607 | defaultConfigurationIsVisible = 0; 608 | defaultConfigurationName = Release; 609 | }; 610 | 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */ = { 611 | isa = XCConfigurationList; 612 | buildConfigurations = ( 613 | 97C147061CF9000F007C117D /* Debug */, 614 | 97C147071CF9000F007C117D /* Release */, 615 | 249021D4217E4FDB00AE95B9 /* Profile */, 616 | ); 617 | defaultConfigurationIsVisible = 0; 618 | defaultConfigurationName = Release; 619 | }; 620 | /* End XCConfigurationList section */ 621 | }; 622 | rootObject = 97C146E61CF9000F007C117D /* Project object */; 623 | } 624 | --------------------------------------------------------------------------------