├── .gradle └── 5.6.2 │ ├── gc.properties │ ├── fileChanges │ └── last-build.bin │ └── fileHashes │ └── fileHashes.lock ├── ios ├── Flutter │ ├── Debug.xcconfig │ ├── Release.xcconfig │ └── AppFrameworkInfo.plist ├── Runner │ ├── Runner-Bridging-Header.h │ ├── Assets.xcassets │ │ └── AppIcon.appiconset │ │ │ ├── 100.png │ │ │ ├── 114.png │ │ │ ├── 120.png │ │ │ ├── 144.png │ │ │ ├── 152.png │ │ │ ├── 167.png │ │ │ ├── 180.png │ │ │ ├── 20.png │ │ │ ├── 29.png │ │ │ ├── 40.png │ │ │ ├── 50.png │ │ │ ├── 57.png │ │ │ ├── 58.png │ │ │ ├── 60.png │ │ │ ├── 72.png │ │ │ ├── 76.png │ │ │ ├── 80.png │ │ │ ├── 87.png │ │ │ ├── 1024.png │ │ │ └── Contents.json │ ├── AppDelegate.swift │ ├── Base.lproj │ │ ├── Main.storyboard │ │ └── LaunchScreen.storyboard │ └── Info.plist ├── Runner.xcworkspace │ ├── contents.xcworkspacedata │ └── xcshareddata │ │ ├── WorkspaceSettings.xcsettings │ │ └── IDEWorkspaceChecks.plist ├── Runner.xcodeproj │ ├── project.xcworkspace │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata │ │ │ ├── WorkspaceSettings.xcsettings │ │ │ └── IDEWorkspaceChecks.plist │ ├── xcshareddata │ │ └── xcschemes │ │ │ └── Runner.xcscheme │ └── project.pbxproj └── .gitignore ├── images ├── logo.png ├── login_bg.jpg ├── google_logo.png └── demo │ ├── Screenshot_20210122-101432.jpg │ ├── Screenshot_20210122-101443.jpg │ ├── Screenshot_20210122-101449.jpg │ ├── Screenshot_20210122-101513.jpg │ └── Screenshot_20210122-101536.jpg ├── fonts ├── Raleway-Light.ttf ├── Raleway-Italic.ttf ├── Raleway-Medium.ttf ├── Raleway-Regular.ttf ├── Raleway-ExtraBold.ttf └── Raleway-SemiBold.ttf ├── android ├── gradle.properties ├── app │ ├── src │ │ ├── main │ │ │ ├── res │ │ │ │ ├── mipmap-hdpi │ │ │ │ │ └── ic_launcher.png │ │ │ │ ├── mipmap-mdpi │ │ │ │ │ └── ic_launcher.png │ │ │ │ ├── mipmap-xhdpi │ │ │ │ │ └── ic_launcher.png │ │ │ │ ├── mipmap-xxhdpi │ │ │ │ │ └── ic_launcher.png │ │ │ │ ├── mipmap-xxxhdpi │ │ │ │ │ └── ic_launcher.png │ │ │ │ ├── drawable │ │ │ │ │ └── launch_background.xml │ │ │ │ └── values │ │ │ │ │ └── styles.xml │ │ │ ├── kotlin │ │ │ │ └── com │ │ │ │ │ └── example │ │ │ │ │ └── basic_banking │ │ │ │ │ └── MainActivity.kt │ │ │ └── AndroidManifest.xml │ │ ├── debug │ │ │ └── AndroidManifest.xml │ │ └── profile │ │ │ └── AndroidManifest.xml │ ├── google-services.json │ └── build.gradle ├── gradle │ └── wrapper │ │ └── gradle-wrapper.properties ├── .gitignore ├── settings.gradle └── build.gradle ├── .metadata ├── lib ├── main.dart ├── models │ ├── customer.dart │ └── history.dart ├── screens │ ├── history.dart │ ├── home.dart │ ├── login.dart │ ├── all_customer.dart │ └── transaction.dart ├── database │ └── databseService.dart ├── authentication │ └── sign_in_google.dart └── components │ ├── customerTile.dart │ └── historyTile.dart ├── .gitignore ├── test └── widget_test.dart ├── README.md ├── pubspec.yaml └── pubspec.lock /.gradle/5.6.2/gc.properties: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.gradle/5.6.2/fileChanges/last-build.bin: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /ios/Flutter/Debug.xcconfig: -------------------------------------------------------------------------------- 1 | #include "Generated.xcconfig" 2 | -------------------------------------------------------------------------------- /ios/Flutter/Release.xcconfig: -------------------------------------------------------------------------------- 1 | #include "Generated.xcconfig" 2 | -------------------------------------------------------------------------------- /ios/Runner/Runner-Bridging-Header.h: -------------------------------------------------------------------------------- 1 | #import "GeneratedPluginRegistrant.h" 2 | -------------------------------------------------------------------------------- /images/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vivek9patel/flutter-banking-app/HEAD/images/logo.png -------------------------------------------------------------------------------- /images/login_bg.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vivek9patel/flutter-banking-app/HEAD/images/login_bg.jpg -------------------------------------------------------------------------------- /fonts/Raleway-Light.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vivek9patel/flutter-banking-app/HEAD/fonts/Raleway-Light.ttf -------------------------------------------------------------------------------- /images/google_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vivek9patel/flutter-banking-app/HEAD/images/google_logo.png -------------------------------------------------------------------------------- /fonts/Raleway-Italic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vivek9patel/flutter-banking-app/HEAD/fonts/Raleway-Italic.ttf -------------------------------------------------------------------------------- /fonts/Raleway-Medium.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vivek9patel/flutter-banking-app/HEAD/fonts/Raleway-Medium.ttf -------------------------------------------------------------------------------- /fonts/Raleway-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vivek9patel/flutter-banking-app/HEAD/fonts/Raleway-Regular.ttf -------------------------------------------------------------------------------- /fonts/Raleway-ExtraBold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vivek9patel/flutter-banking-app/HEAD/fonts/Raleway-ExtraBold.ttf -------------------------------------------------------------------------------- /fonts/Raleway-SemiBold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vivek9patel/flutter-banking-app/HEAD/fonts/Raleway-SemiBold.ttf -------------------------------------------------------------------------------- /.gradle/5.6.2/fileHashes/fileHashes.lock: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vivek9patel/flutter-banking-app/HEAD/.gradle/5.6.2/fileHashes/fileHashes.lock -------------------------------------------------------------------------------- /android/gradle.properties: -------------------------------------------------------------------------------- 1 | org.gradle.jvmargs=-Xmx1536M 2 | android.useAndroidX=true 3 | android.enableJetifier=true 4 | android.enableR8=true 5 | -------------------------------------------------------------------------------- /images/demo/Screenshot_20210122-101432.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vivek9patel/flutter-banking-app/HEAD/images/demo/Screenshot_20210122-101432.jpg -------------------------------------------------------------------------------- /images/demo/Screenshot_20210122-101443.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vivek9patel/flutter-banking-app/HEAD/images/demo/Screenshot_20210122-101443.jpg -------------------------------------------------------------------------------- /images/demo/Screenshot_20210122-101449.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vivek9patel/flutter-banking-app/HEAD/images/demo/Screenshot_20210122-101449.jpg -------------------------------------------------------------------------------- /images/demo/Screenshot_20210122-101513.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vivek9patel/flutter-banking-app/HEAD/images/demo/Screenshot_20210122-101513.jpg -------------------------------------------------------------------------------- /images/demo/Screenshot_20210122-101536.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vivek9patel/flutter-banking-app/HEAD/images/demo/Screenshot_20210122-101536.jpg -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vivek9patel/flutter-banking-app/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/vivek9patel/flutter-banking-app/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/vivek9patel/flutter-banking-app/HEAD/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vivek9patel/flutter-banking-app/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/100.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/114.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vivek9patel/flutter-banking-app/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/114.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/120.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vivek9patel/flutter-banking-app/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/120.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/144.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vivek9patel/flutter-banking-app/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/144.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/152.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vivek9patel/flutter-banking-app/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/152.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/167.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vivek9patel/flutter-banking-app/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/167.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/180.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vivek9patel/flutter-banking-app/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/180.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/20.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vivek9patel/flutter-banking-app/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/20.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/29.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vivek9patel/flutter-banking-app/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/29.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/40.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vivek9patel/flutter-banking-app/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/40.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/50.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vivek9patel/flutter-banking-app/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/50.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/57.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vivek9patel/flutter-banking-app/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/57.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/58.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vivek9patel/flutter-banking-app/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/58.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/60.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vivek9patel/flutter-banking-app/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/60.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/72.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vivek9patel/flutter-banking-app/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/72.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/76.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vivek9patel/flutter-banking-app/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/76.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/80.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vivek9patel/flutter-banking-app/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/80.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/87.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vivek9patel/flutter-banking-app/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/87.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vivek9patel/flutter-banking-app/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/vivek9patel/flutter-banking-app/HEAD/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/1024.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vivek9patel/flutter-banking-app/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/1024.png -------------------------------------------------------------------------------- /android/app/src/main/kotlin/com/example/basic_banking/MainActivity.kt: -------------------------------------------------------------------------------- 1 | package com.example.basic_banking 2 | 3 | import io.flutter.embedding.android.FlutterActivity 4 | 5 | class MainActivity: FlutterActivity() { 6 | } 7 | -------------------------------------------------------------------------------- /ios/Runner.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /android/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Fri Jun 23 08:50:38 CEST 2017 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.2-all.zip 7 | -------------------------------------------------------------------------------- /ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | PreviewsEnabled 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /android/.gitignore: -------------------------------------------------------------------------------- 1 | gradle-wrapper.jar 2 | /.gradle 3 | /captures/ 4 | /gradlew 5 | /gradlew.bat 6 | /local.properties 7 | GeneratedPluginRegistrant.java 8 | 9 | # Remember to never publicly share your keystore. 10 | # See https://flutter.dev/docs/deployment/android#reference-the-keystore-from-the-app 11 | key.properties 12 | -------------------------------------------------------------------------------- /ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | PreviewsEnabled 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /.metadata: -------------------------------------------------------------------------------- 1 | # This file tracks properties of this Flutter project. 2 | # Used by Flutter tool to assess capabilities and perform upgrades etc. 3 | # 4 | # This file should be version controlled and should not be manually edited. 5 | 6 | version: 7 | revision: 78910062997c3a836feee883712c241a5fd22983 8 | channel: stable 9 | 10 | project_type: app 11 | -------------------------------------------------------------------------------- /android/app/src/debug/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /android/app/src/profile/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /ios/Runner/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | import UIKit 2 | import Flutter 3 | 4 | @UIApplicationMain 5 | @objc class AppDelegate: FlutterAppDelegate { 6 | override func application( 7 | _ application: UIApplication, 8 | didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? 9 | ) -> Bool { 10 | GeneratedPluginRegistrant.register(with: self) 11 | return super.application(application, didFinishLaunchingWithOptions: launchOptions) 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /lib/main.dart: -------------------------------------------------------------------------------- 1 | import 'package:basic_banking/screens/login.dart'; 2 | import 'package:flutter/material.dart'; 3 | 4 | void main() { 5 | runApp(MyApp()); 6 | } 7 | 8 | class MyApp extends StatelessWidget { 9 | const MyApp({Key key}) : super(key: key); 10 | 11 | @override 12 | Widget build(BuildContext context) { 13 | return MaterialApp( 14 | title: "Home Page", 15 | home: Home(), 16 | theme: ThemeData(fontFamily: "Raleway"), 17 | ); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /android/settings.gradle: -------------------------------------------------------------------------------- 1 | include ':app' 2 | 3 | def localPropertiesFile = new File(rootProject.projectDir, "local.properties") 4 | def properties = new Properties() 5 | 6 | assert localPropertiesFile.exists() 7 | localPropertiesFile.withReader("UTF-8") { reader -> properties.load(reader) } 8 | 9 | def flutterSdkPath = properties.getProperty("flutter.sdk") 10 | assert flutterSdkPath != null, "flutter.sdk not set in local.properties" 11 | apply from: "$flutterSdkPath/packages/flutter_tools/gradle/app_plugin_loader.gradle" 12 | -------------------------------------------------------------------------------- /android/app/src/main/res/drawable/launch_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 12 | 13 | -------------------------------------------------------------------------------- /lib/models/customer.dart: -------------------------------------------------------------------------------- 1 | import 'package:cloud_firestore/cloud_firestore.dart'; 2 | 3 | class Customer { 4 | String name; 5 | String email; 6 | int balance; 7 | int number; 8 | final CollectionReference _customerCollection = 9 | FirebaseFirestore.instance.collection('cutomers'); 10 | 11 | Customer({this.name, this.balance, this.number, this.email}); 12 | 13 | Future save() async { 14 | try { 15 | await _customerCollection.add( 16 | {"name": name, "number": number, "email": email, "balance": balance}); 17 | } catch (err) { 18 | print(err); 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /lib/screens/history.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:basic_banking/database/databseService.dart'; 3 | import 'package:basic_banking/components/historyTile.dart'; 4 | 5 | import 'package:cloud_firestore/cloud_firestore.dart'; 6 | import 'package:provider/provider.dart'; 7 | 8 | class History extends StatelessWidget { 9 | const History({Key key}) : super(key: key); 10 | 11 | @override 12 | Widget build(BuildContext context) { 13 | return StreamProvider.value( 14 | value: DatabaseService().history, 15 | child: Scaffold( 16 | body: HistoryTile(), 17 | )); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /ios/.gitignore: -------------------------------------------------------------------------------- 1 | *.mode1v3 2 | *.mode2v3 3 | *.moved-aside 4 | *.pbxuser 5 | *.perspectivev3 6 | **/*sync/ 7 | .sconsign.dblite 8 | .tags* 9 | **/.vagrant/ 10 | **/DerivedData/ 11 | Icon? 12 | **/Pods/ 13 | **/.symlinks/ 14 | profile 15 | xcuserdata 16 | **/.generated/ 17 | Flutter/App.framework 18 | Flutter/Flutter.framework 19 | Flutter/Flutter.podspec 20 | Flutter/Generated.xcconfig 21 | Flutter/app.flx 22 | Flutter/app.zip 23 | Flutter/flutter_assets/ 24 | Flutter/flutter_export_environment.sh 25 | ServiceDefinitions.json 26 | Runner/GeneratedPluginRegistrant.* 27 | 28 | # Exceptions to above rules. 29 | !default.mode1v3 30 | !default.mode2v3 31 | !default.pbxuser 32 | !default.perspectivev3 33 | -------------------------------------------------------------------------------- /android/build.gradle: -------------------------------------------------------------------------------- 1 | buildscript { 2 | ext.kotlin_version = '1.3.50' 3 | repositories { 4 | google() 5 | jcenter() 6 | } 7 | 8 | dependencies { 9 | classpath 'com.android.tools.build:gradle:3.5.0' 10 | classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" 11 | classpath 'com.google.gms:google-services:4.3.4' 12 | } 13 | } 14 | 15 | allprojects { 16 | repositories { 17 | google() 18 | jcenter() 19 | } 20 | } 21 | 22 | rootProject.buildDir = '../build' 23 | subprojects { 24 | project.buildDir = "${rootProject.buildDir}/${project.name}" 25 | } 26 | subprojects { 27 | project.evaluationDependsOn(':app') 28 | } 29 | 30 | task clean(type: Delete) { 31 | delete rootProject.buildDir 32 | } 33 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Miscellaneous 2 | *.class 3 | *.log 4 | *.pyc 5 | *.swp 6 | .DS_Store 7 | .atom/ 8 | .buildlog/ 9 | .history 10 | .svn/ 11 | 12 | # IntelliJ related 13 | *.iml 14 | *.ipr 15 | *.iws 16 | .idea/ 17 | 18 | # The .vscode folder contains launch configuration and tasks you configure in 19 | # VS Code which you may wish to be included in version control, so this line 20 | # is commented out by default. 21 | #.vscode/ 22 | 23 | # Flutter/Dart/Pub related 24 | **/doc/api/ 25 | **/ios/Flutter/.last_build_id 26 | .dart_tool/ 27 | .flutter-plugins 28 | .flutter-plugins-dependencies 29 | .packages 30 | .pub-cache/ 31 | .pub/ 32 | /build/ 33 | 34 | # Web related 35 | lib/generated_plugin_registrant.dart 36 | 37 | # Symbolication related 38 | app.*.symbols 39 | 40 | # Obfuscation related 41 | app.*.map.json 42 | -------------------------------------------------------------------------------- /lib/models/history.dart: -------------------------------------------------------------------------------- 1 | import 'package:cloud_firestore/cloud_firestore.dart'; 2 | 3 | class History { 4 | String sender; 5 | String receiver; 6 | int amount; 7 | DateTime dateTime; 8 | String currentUser; 9 | final CollectionReference _historyCollection = 10 | FirebaseFirestore.instance.collection('transaction_history'); 11 | 12 | History( 13 | {this.sender, 14 | this.receiver, 15 | this.amount, 16 | this.dateTime, 17 | this.currentUser}); 18 | 19 | Future save() async { 20 | try { 21 | await _historyCollection.add({ 22 | "sender": sender, 23 | "receiver": receiver, 24 | "amount": amount, 25 | "date_time": dateTime, 26 | "done_by": currentUser 27 | }); 28 | } catch (err) { 29 | throw err; 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /lib/database/databseService.dart: -------------------------------------------------------------------------------- 1 | import 'package:cloud_firestore/cloud_firestore.dart'; 2 | 3 | class DatabaseService { 4 | // history collection stream 5 | final Query historyCollection = FirebaseFirestore.instance 6 | .collection('transaction_history') 7 | .orderBy("date_time"); 8 | Stream get history { 9 | return historyCollection.snapshots(); 10 | } 11 | 12 | // customer collection stream 13 | final CollectionReference customerCollection = 14 | FirebaseFirestore.instance.collection('cutomers'); 15 | 16 | Stream get customers { 17 | return customerCollection.snapshots(); 18 | } 19 | 20 | // getting customer's list from firestore 21 | Future getCustomerList() async { 22 | try { 23 | return customerCollection.get(); 24 | } catch (err) { 25 | print(err); 26 | return null; 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /ios/Flutter/AppFrameworkInfo.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | App 9 | CFBundleIdentifier 10 | io.flutter.flutter.app 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | App 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1.0 23 | MinimumOSVersion 24 | 8.0 25 | 26 | 27 | -------------------------------------------------------------------------------- /android/app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 9 | 15 | 18 | 19 | -------------------------------------------------------------------------------- /test/widget_test.dart: -------------------------------------------------------------------------------- 1 | // This is a basic Flutter widget test. 2 | // 3 | // To perform an interaction with a widget in your test, use the WidgetTester 4 | // utility that Flutter provides. For example, you can send tap and scroll 5 | // gestures. You can also use WidgetTester to find child widgets in the widget 6 | // tree, read text, and verify that the values of widget properties are correct. 7 | 8 | import 'package:flutter/material.dart'; 9 | import 'package:flutter_test/flutter_test.dart'; 10 | 11 | import 'package:basic_banking/main.dart'; 12 | 13 | void main() { 14 | testWidgets('Counter increments smoke test', (WidgetTester tester) async { 15 | // Build our app and trigger a frame. 16 | await tester.pumpWidget(MyApp()); 17 | 18 | // Verify that our counter starts at 0. 19 | expect(find.text('0'), findsOneWidget); 20 | expect(find.text('1'), findsNothing); 21 | 22 | // Tap the '+' icon and trigger a frame. 23 | await tester.tap(find.byIcon(Icons.add)); 24 | await tester.pump(); 25 | 26 | // Verify that our counter has incremented. 27 | expect(find.text('0'), findsNothing); 28 | expect(find.text('1'), findsOneWidget); 29 | }); 30 | } 31 | -------------------------------------------------------------------------------- /android/app/google-services.json: -------------------------------------------------------------------------------- 1 | { 2 | "project_info": { 3 | "project_number": "1058311517356", 4 | "project_id": "spark-basic-banking-system", 5 | "storage_bucket": "spark-basic-banking-system.appspot.com" 6 | }, 7 | "client": [ 8 | { 9 | "client_info": { 10 | "mobilesdk_app_id": "1:1058311517356:android:5f6927dd7635ce036d1b09", 11 | "android_client_info": { 12 | "package_name": "com.vivek9patel.basic_banking" 13 | } 14 | }, 15 | "oauth_client": [ 16 | { 17 | "client_id": "1058311517356-7g66mcajhj2lm046tb2si812n5hbb1m5.apps.googleusercontent.com", 18 | "client_type": 3 19 | } 20 | ], 21 | "api_key": [ 22 | { 23 | "current_key": "AIzaSyBPFRPXfq_knLVBZsXzhT8zVGbrZTvJAYk" 24 | } 25 | ], 26 | "services": { 27 | "appinvite_service": { 28 | "other_platform_oauth_client": [ 29 | { 30 | "client_id": "1058311517356-7g66mcajhj2lm046tb2si812n5hbb1m5.apps.googleusercontent.com", 31 | "client_type": 3 32 | } 33 | ] 34 | } 35 | } 36 | } 37 | ], 38 | "configuration_version": "1" 39 | } -------------------------------------------------------------------------------- /lib/authentication/sign_in_google.dart: -------------------------------------------------------------------------------- 1 | import 'package:firebase_auth/firebase_auth.dart'; 2 | import 'package:firebase_core/firebase_core.dart'; 3 | import 'package:google_sign_in/google_sign_in.dart'; 4 | 5 | final FirebaseAuth _auth = FirebaseAuth.instance; 6 | final GoogleSignIn googleSignIn = GoogleSignIn(); 7 | 8 | Future> signInWithGoogle() async { 9 | await Firebase.initializeApp(); 10 | 11 | final GoogleSignInAccount googleSignInAccount = await googleSignIn.signIn(); 12 | final GoogleSignInAuthentication googleSignInAuthentication = 13 | await googleSignInAccount.authentication; 14 | 15 | final AuthCredential credential = GoogleAuthProvider.credential( 16 | accessToken: googleSignInAuthentication.accessToken, 17 | idToken: googleSignInAuthentication.idToken, 18 | ); 19 | 20 | final UserCredential authResult = 21 | await _auth.signInWithCredential(credential); 22 | final User user = authResult.user; 23 | 24 | if (user != null) { 25 | assert(!user.isAnonymous); 26 | assert(await user.getIdToken() != null); 27 | 28 | final User currentUser = _auth.currentUser; 29 | assert(user.uid == currentUser.uid); 30 | 31 | String userName = user.displayName; 32 | String userEmail = user.email; 33 | String userImgUrl = user.photoURL; 34 | 35 | print('signInWithGoogle succeeded'); 36 | return { 37 | "userName": userName, 38 | "userEmail": userEmail, 39 | "userImgUrl": userImgUrl 40 | }; 41 | } 42 | print('signInWithGoogle failed'); 43 | return null; 44 | } 45 | 46 | Future signOutGoogle() async { 47 | await googleSignIn.signOut(); 48 | 49 | print("User Signed Out"); 50 | } 51 | -------------------------------------------------------------------------------- /ios/Runner/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /ios/Runner/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | basic_banking 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | $(FLUTTER_BUILD_NAME) 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | $(FLUTTER_BUILD_NUMBER) 23 | LSRequiresIPhoneOS 24 | 25 | UILaunchStoryboardName 26 | LaunchScreen 27 | UIMainStoryboardFile 28 | Main 29 | UISupportedInterfaceOrientations 30 | 31 | UIInterfaceOrientationPortrait 32 | UIInterfaceOrientationLandscapeLeft 33 | UIInterfaceOrientationLandscapeRight 34 | 35 | UISupportedInterfaceOrientations~ipad 36 | 37 | UIInterfaceOrientationPortrait 38 | UIInterfaceOrientationPortraitUpsideDown 39 | UIInterfaceOrientationLandscapeLeft 40 | UIInterfaceOrientationLandscapeRight 41 | 42 | UIViewControllerBasedStatusBarAppearance 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /android/app/build.gradle: -------------------------------------------------------------------------------- 1 | def localProperties = new Properties() 2 | def localPropertiesFile = rootProject.file('local.properties') 3 | if (localPropertiesFile.exists()) { 4 | localPropertiesFile.withReader('UTF-8') { reader -> 5 | localProperties.load(reader) 6 | } 7 | } 8 | 9 | def flutterRoot = localProperties.getProperty('flutter.sdk') 10 | if (flutterRoot == null) { 11 | throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.") 12 | } 13 | 14 | def flutterVersionCode = localProperties.getProperty('flutter.versionCode') 15 | if (flutterVersionCode == null) { 16 | flutterVersionCode = '1' 17 | } 18 | 19 | def flutterVersionName = localProperties.getProperty('flutter.versionName') 20 | if (flutterVersionName == null) { 21 | flutterVersionName = '1.0' 22 | } 23 | 24 | apply plugin: 'com.android.application' 25 | apply plugin: 'kotlin-android' 26 | apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" 27 | 28 | android { 29 | compileSdkVersion 29 30 | 31 | sourceSets { 32 | main.java.srcDirs += 'src/main/kotlin' 33 | } 34 | 35 | lintOptions { 36 | disable 'InvalidPackage' 37 | } 38 | 39 | defaultConfig { 40 | // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). 41 | applicationId "com.vivek9patel.basic_banking" 42 | minSdkVersion 21 43 | targetSdkVersion 29 44 | versionCode flutterVersionCode.toInteger() 45 | versionName flutterVersionName 46 | } 47 | 48 | buildTypes { 49 | release { 50 | // TODO: Add your own signing config for the release build. 51 | // Signing with the debug keys for now, so `flutter run --release` works. 52 | signingConfig signingConfigs.debug 53 | } 54 | } 55 | } 56 | 57 | flutter { 58 | source '../..' 59 | } 60 | 61 | dependencies { 62 | implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" 63 | implementation platform('com.google.firebase:firebase-bom:26.2.0') 64 | } 65 | 66 | apply plugin: 'com.google.gms.google-services' -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /android/app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 8 | 12 | 19 | 23 | 27 | 32 | 36 | 37 | 38 | 39 | 40 | 41 | 43 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /lib/components/customerTile.dart: -------------------------------------------------------------------------------- 1 | import 'dart:math'; 2 | import 'package:cloud_firestore/cloud_firestore.dart'; 3 | import 'package:flutter/material.dart'; 4 | import 'package:provider/provider.dart'; 5 | 6 | class CustomerTile extends StatefulWidget { 7 | @override 8 | _CustomerTile createState() => _CustomerTile(); 9 | } 10 | 11 | class _CustomerTile extends State { 12 | @override 13 | Widget build(BuildContext context) { 14 | if (Provider.of(context) == null) { 15 | return Center(child: CircularProgressIndicator()); 16 | } 17 | final allCustomers = Provider.of(context).docs; 18 | // allCustomers.sort(); 19 | return ListView.builder( 20 | itemCount: allCustomers.length, 21 | itemBuilder: (context, index) { 22 | dynamic customer = allCustomers[index].data(); 23 | return CustomerCard( 24 | customerName: customer['name'], 25 | customerBalance: customer['balance']); 26 | }); 27 | } 28 | } 29 | 30 | class CustomerCard extends StatelessWidget { 31 | const CustomerCard({ 32 | Key key, 33 | @required this.customerName, 34 | @required this.customerBalance, 35 | }) : super(key: key); 36 | 37 | final String customerName; 38 | final int customerBalance; 39 | 40 | String _getBalance(int balance) { 41 | String balanceWithComma = balance.toString(); 42 | 43 | balanceWithComma = balanceWithComma.replaceAllMapped( 44 | new RegExp(r'(\d{1,3})(?=(\d{3})+(?!\d))'), (Match m) => '${m[1]},'); 45 | return balanceWithComma; 46 | } 47 | 48 | @override 49 | Widget build(BuildContext context) { 50 | Color randomColor = Color.fromARGB((Random().nextInt(100) + 155) % 255, 0, 51 | Random().nextInt(80), Random().nextInt(200)); 52 | return Padding( 53 | padding: const EdgeInsets.all(10), 54 | child: Card( 55 | margin: EdgeInsets.fromLTRB(20.0, 6.0, 20.0, 0.0), 56 | child: ListTile( 57 | leading: Container( 58 | height: 40, 59 | width: 40, 60 | decoration: BoxDecoration( 61 | color: Colors.grey[200], 62 | borderRadius: BorderRadius.all(Radius.circular(20))), 63 | child: Icon( 64 | Icons.person_rounded, 65 | size: 30.0, 66 | color: randomColor, 67 | ), 68 | ), 69 | title: Text( 70 | customerName, 71 | style: TextStyle( 72 | fontWeight: FontWeight.bold, 73 | color: Color.fromARGB( 74 | 255, 0, randomColor.green, randomColor.blue)), 75 | ), 76 | subtitle: Row(children: [ 77 | Text('Balance: '), 78 | Text( 79 | '\$' + _getBalance(customerBalance), 80 | style: 81 | TextStyle(color: Colors.green, fontWeight: FontWeight.bold), 82 | ) 83 | ])), 84 | ), 85 | ); 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

2 | 3 | Logo 4 | 5 | 6 |

Basic Banking Flutter App

7 | 8 |

9 | A Beginner Flutter Project with the integration of Firebase. 10 |
11 |
12 | Report Bug 13 | · 14 | Install App 15 |

16 |

17 | 18 | 19 |
20 |

Table of Contents

21 |
    22 |
  1. 23 | About The Project 24 | 27 |
  2. 28 |
  3. Demo
  4. 29 |
  5. Contributing
  6. 30 |
  7. Contact
  8. 31 |
32 |
33 | 34 | 35 | 36 | ## About The Project 37 | 38 |

39 | This Project is created to learn Flutter and Firebase.Used for creating transactions between different Users and displaying the history of transactions done by different Google Users. 40 |

41 | 42 | ### Features 43 | 44 | - Sign in with Google Account 45 | - Add Users to Database (Admin Only) 46 | - Display all Customers with Account Balance 47 | - Transact Amount between Customers from all Customers 48 | - Display Transaction History and which User did the transaction 49 | - Displaying Data with Firebase Stream (No Screen Refreshing!) 50 | 51 | ### Built With 52 | 53 | - [Flutter](https://flutter.dev/) 54 | - [Firebase Authentication](https://firebase.google.com/docs/auth) 55 | - [Firestore Database](https://firebase.google.com/docs/firestore) 56 | 57 | ## Demo 58 | 59 | - Here are some Screen shots of different Screens of this Flutter APP 60 |
61 | Logo 62 | Logo 63 | Logo 64 | Logo 65 | Logo 66 | 67 | ## Contributing 68 | 69 | Contributions are what make the open source community such an amazing place to be learn, inspire, and create. Any contributiors who wants to get into Flutter or App development can make contribution,which will be **greatly appreciated**. 70 | 71 | 1. Fork the Project 72 | 2. Create your Feature Branch (`git checkout -b feature/AmazingFeature`) 73 | 3. Commit your Changes (`git commit -m 'Added some AmazingFeature'`) 74 | 4. Push to the Branch (`git push origin feature/AmazingFeature`) 75 | 5. Open a Pull Request 76 | 77 | ## Contact 78 | 79 | Vivek Patel - [@vivek9patel-linkedlin](https://www.linkedin.com/in/vivek9patel/) | vivek.p9737@gmail.com 80 | 81 | Project Link: [https://github.com/vivek9patel/flutter-banking-app](https://github.com/vivek9patel/flutter-banking-app) 82 | -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | {"images":[{"size":"60x60","expected-size":"180","filename":"180.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"iphone","scale":"3x"},{"size":"40x40","expected-size":"80","filename":"80.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"iphone","scale":"2x"},{"size":"40x40","expected-size":"120","filename":"120.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"iphone","scale":"3x"},{"size":"60x60","expected-size":"120","filename":"120.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"iphone","scale":"2x"},{"size":"57x57","expected-size":"57","filename":"57.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"iphone","scale":"1x"},{"size":"29x29","expected-size":"58","filename":"58.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"iphone","scale":"2x"},{"size":"29x29","expected-size":"29","filename":"29.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"iphone","scale":"1x"},{"size":"29x29","expected-size":"87","filename":"87.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"iphone","scale":"3x"},{"size":"57x57","expected-size":"114","filename":"114.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"iphone","scale":"2x"},{"size":"20x20","expected-size":"40","filename":"40.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"iphone","scale":"2x"},{"size":"20x20","expected-size":"60","filename":"60.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"iphone","scale":"3x"},{"size":"1024x1024","filename":"1024.png","expected-size":"1024","idiom":"ios-marketing","folder":"Assets.xcassets/AppIcon.appiconset/","scale":"1x"},{"size":"40x40","expected-size":"80","filename":"80.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"ipad","scale":"2x"},{"size":"72x72","expected-size":"72","filename":"72.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"ipad","scale":"1x"},{"size":"76x76","expected-size":"152","filename":"152.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"ipad","scale":"2x"},{"size":"50x50","expected-size":"100","filename":"100.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"ipad","scale":"2x"},{"size":"29x29","expected-size":"58","filename":"58.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"ipad","scale":"2x"},{"size":"76x76","expected-size":"76","filename":"76.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"ipad","scale":"1x"},{"size":"29x29","expected-size":"29","filename":"29.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"ipad","scale":"1x"},{"size":"50x50","expected-size":"50","filename":"50.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"ipad","scale":"1x"},{"size":"72x72","expected-size":"144","filename":"144.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"ipad","scale":"2x"},{"size":"40x40","expected-size":"40","filename":"40.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"ipad","scale":"1x"},{"size":"83.5x83.5","expected-size":"167","filename":"167.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"ipad","scale":"2x"},{"size":"20x20","expected-size":"20","filename":"20.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"ipad","scale":"1x"},{"size":"20x20","expected-size":"40","filename":"40.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"ipad","scale":"2x"}]} -------------------------------------------------------------------------------- /pubspec.yaml: -------------------------------------------------------------------------------- 1 | name: basic_banking 2 | description: A Flutter Project with integration of Firebase, for basic transaction between users. 3 | 4 | # The following line prevents the package from being accidentally published to 5 | # pub.dev using `pub publish`. This is preferred for private packages. 6 | publish_to: "none" # Remove this line if you wish to publish to pub.dev 7 | 8 | # The following defines the version and build number for your application. 9 | # A version number is three numbers separated by dots, like 1.2.43 10 | # followed by an optional build number separated by a +. 11 | # Both the version and the builder number may be overridden in flutter 12 | # build by specifying --build-name and --build-number, respectively. 13 | # In Android, build-name is used as versionName while build-number used as versionCode. 14 | # Read more about Android versioning at https://developer.android.com/studio/publish/versioning 15 | # In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion. 16 | # Read more about iOS versioning at 17 | # https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html 18 | version: 1.0.0+1 19 | 20 | environment: 21 | sdk: ">=2.7.0 <3.0.0" 22 | 23 | dependencies: 24 | flutter: 25 | sdk: flutter 26 | 27 | # The following adds the Cupertino Icons font to your application. 28 | # Use with the CupertinoIcons class for iOS style icons. 29 | cupertino_icons: ^1.0.0 30 | firebase_auth: ^0.18.4+1 31 | google_sign_in: ^4.5.6 32 | firebase_core: ^0.5.3 33 | cloud_firestore: ^0.14.4 34 | provider: ^4.3.2+4 35 | flushbar: ^1.10.4 36 | 37 | dev_dependencies: 38 | flutter_test: 39 | sdk: flutter 40 | 41 | # For information on the generic Dart part of this file, see the 42 | # following page: https://dart.dev/tools/pub/pubspec 43 | 44 | # The following section is specific to Flutter. 45 | flutter: 46 | # The following line ensures that the Material Icons font is 47 | # included with your application, so that you can use the icons in 48 | # the material Icons class. 49 | uses-material-design: true 50 | 51 | # To add assets to your application, add an assets section, like this: 52 | assets: 53 | - images/ 54 | 55 | # An image asset can refer to one or more resolution-specific "variants", see 56 | # https://flutter.dev/assets-and-images/#resolution-aware. 57 | 58 | # For details regarding adding assets from package dependencies, see 59 | # https://flutter.dev/assets-and-images/#from-packages 60 | 61 | # To add custom fonts to your application, add a fonts section here, 62 | # in this "flutter" section. Each entry in this list should have a 63 | # "family" key with the font family name, and a "fonts" key with a 64 | # list giving the asset and other descriptors for the font. For 65 | # example: 66 | fonts: 67 | - family: Raleway 68 | fonts: 69 | - asset: fonts/Raleway-Regular.ttf 70 | - asset: fonts/Raleway-Italic.ttf 71 | style: italic 72 | - asset: fonts/Raleway-ExtraBold.ttf 73 | weight: 800 74 | - asset: fonts/Raleway-Light.ttf 75 | weight: 300 76 | - asset: fonts/Raleway-Medium.ttf 77 | weight: 500 78 | - asset: fonts/Raleway-SemiBold.ttf 79 | weight: 600 80 | # 81 | # For details regarding fonts from package dependencies, 82 | # see https://flutter.dev/custom-fonts/#from-packages 83 | -------------------------------------------------------------------------------- /ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 39 | 40 | 41 | 42 | 43 | 44 | 54 | 56 | 62 | 63 | 64 | 65 | 66 | 67 | 73 | 75 | 81 | 82 | 83 | 84 | 86 | 87 | 90 | 91 | 92 | -------------------------------------------------------------------------------- /lib/screens/home.dart: -------------------------------------------------------------------------------- 1 | import 'package:basic_banking/authentication/sign_in_google.dart'; 2 | import 'package:basic_banking/screens/all_customer.dart'; 3 | import 'package:basic_banking/screens/login.dart'; 4 | import 'package:basic_banking/screens/transaction.dart'; 5 | import 'package:basic_banking/screens/history.dart'; 6 | import 'package:flutter/material.dart'; 7 | 8 | class CustomersList extends StatefulWidget { 9 | const CustomersList({ 10 | Key key, 11 | @required this.userDetails, 12 | }) : super(key: key); 13 | 14 | final Map userDetails; 15 | 16 | @override 17 | _CustomersListState createState() => _CustomersListState(); 18 | } 19 | 20 | class _CustomersListState extends State { 21 | int _selectedIndex = 0; 22 | 23 | @override 24 | Widget build(BuildContext context) { 25 | var screens = [ 26 | { 27 | "title": "All customers", 28 | "screen": AllCustomersList(userEmail: widget.userDetails["userEmail"]), 29 | "bgColor": Colors.transparent, 30 | "elevation": 0.0, 31 | "textColor": Colors.black, 32 | }, 33 | { 34 | "title": "Transaction", 35 | "screen": MakeTransaction(currentUser: widget.userDetails["userName"]), 36 | "bgColor": Colors.blue[400] 37 | }, 38 | {"title": "History", "screen": History(), "bgColor": Colors.blueGrey}, 39 | ]; 40 | final Map userDetails = widget.userDetails; 41 | 42 | return Scaffold( 43 | appBar: AppBar( 44 | elevation: screens[_selectedIndex]["elevation"] ?? 4.0, 45 | title: Row(children: [ 46 | Container( 47 | decoration: BoxDecoration( 48 | color: Colors.white, 49 | borderRadius: BorderRadius.circular(50), 50 | boxShadow: [ 51 | BoxShadow( 52 | color: Color.fromARGB(35, 0, 0, 0), 53 | spreadRadius: 3, 54 | blurRadius: 2, 55 | offset: Offset(0, 1), 56 | ), 57 | ], 58 | ), 59 | child: ClipRRect( 60 | borderRadius: BorderRadius.circular(50), 61 | child: Image( 62 | image: NetworkImage(userDetails["userImgUrl"].toString()), 63 | width: 35, 64 | ), 65 | ), 66 | ), 67 | SizedBox( 68 | width: 20, 69 | ), 70 | Text( 71 | screens[_selectedIndex]["title"], 72 | style: TextStyle( 73 | color: screens[_selectedIndex]["textColor"] ?? Colors.white, 74 | fontWeight: FontWeight.w800, 75 | fontSize: 24), 76 | ) 77 | ]), 78 | backgroundColor: screens[_selectedIndex]["bgColor"], 79 | actions: [ 80 | FlatButton.icon( 81 | icon: Icon( 82 | Icons.logout, 83 | size: 26, 84 | ), 85 | label: Text( 86 | 'Log Out', 87 | style: TextStyle(fontSize: 0), 88 | ), 89 | onPressed: () async { 90 | await signOutGoogle().then((result) { 91 | Navigator.pushAndRemoveUntil( 92 | context, 93 | MaterialPageRoute(builder: (context) => Home()), 94 | (Route route) => false, 95 | ); 96 | }); 97 | }, 98 | ), 99 | ], 100 | ), 101 | body: screens[_selectedIndex]["screen"], 102 | bottomNavigationBar: BottomNavigationBar( 103 | elevation: screens[_selectedIndex]["elevation"] ?? 4.0, 104 | type: BottomNavigationBarType.shifting, 105 | items: [ 106 | BottomNavigationBarItem( 107 | icon: Icon(Icons.home), 108 | label: 'Customers', 109 | backgroundColor: Colors.orange), 110 | BottomNavigationBarItem( 111 | icon: Icon(Icons.money), 112 | label: 'Transaction', 113 | backgroundColor: screens[1]["bgColor"]), 114 | BottomNavigationBarItem( 115 | icon: Icon(Icons.history), 116 | label: 'History', 117 | backgroundColor: screens[2]["bgColor"]), 118 | ], 119 | currentIndex: _selectedIndex, 120 | onTap: (index) { 121 | setState(() { 122 | _selectedIndex = index; 123 | }); 124 | }, 125 | ), 126 | ); 127 | } 128 | } 129 | -------------------------------------------------------------------------------- /lib/screens/login.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:basic_banking/screens/home.dart'; 3 | import 'package:basic_banking/authentication/sign_in_google.dart'; 4 | 5 | class Home extends StatelessWidget { 6 | const Home({Key key}) : super(key: key); 7 | 8 | @override 9 | Widget build(BuildContext context) { 10 | return Container( 11 | decoration: BoxDecoration( 12 | image: DecorationImage( 13 | image: AssetImage("images/login_bg.jpg"), 14 | fit: BoxFit.cover, 15 | )), 16 | child: Scaffold( 17 | backgroundColor: Colors.transparent, 18 | appBar: AppBar( 19 | backgroundColor: Colors.transparent, 20 | elevation: 0, 21 | ), 22 | body: SafeArea(child: Body()), 23 | ), 24 | ); 25 | } 26 | } 27 | 28 | class Body extends StatelessWidget { 29 | @override 30 | Widget build(BuildContext context) { 31 | return FractionallySizedBox( 32 | alignment: Alignment.center, 33 | widthFactor: 1, 34 | heightFactor: 1, 35 | child: Column( 36 | mainAxisAlignment: MainAxisAlignment.spaceBetween, 37 | crossAxisAlignment: CrossAxisAlignment.stretch, 38 | children: [ 39 | Column( 40 | crossAxisAlignment: CrossAxisAlignment.center, 41 | mainAxisAlignment: MainAxisAlignment.start, 42 | children: [ 43 | Image( 44 | image: AssetImage("images/logo.png"), 45 | height: 200, 46 | ), 47 | SizedBox( 48 | height: 30, 49 | ), 50 | Text( 51 | "Basic Banking", 52 | style: TextStyle(fontSize: 40, fontWeight: FontWeight.w600), 53 | ), 54 | SizedBox( 55 | height: 10, 56 | ), 57 | Row( 58 | mainAxisAlignment: MainAxisAlignment.center, 59 | crossAxisAlignment: CrossAxisAlignment.center, 60 | children: [ 61 | Text( 62 | "by", 63 | style: TextStyle( 64 | fontSize: 20, 65 | fontWeight: FontWeight.w500, 66 | color: Colors.grey[900]), 67 | ), 68 | SizedBox( 69 | width: 5, 70 | ), 71 | Text( 72 | "vivek9patel", 73 | style: TextStyle( 74 | fontSize: 20, 75 | fontWeight: FontWeight.w600, 76 | color: Colors.blueGrey[800]), 77 | ), 78 | ], 79 | ) 80 | ], 81 | ), 82 | Column( 83 | children: [ 84 | Container( 85 | width: 200, 86 | child: RaisedButton( 87 | color: Colors.white, 88 | shape: StadiumBorder(), 89 | padding: EdgeInsets.all(10), 90 | child: Row( 91 | mainAxisAlignment: MainAxisAlignment.spaceAround, 92 | crossAxisAlignment: CrossAxisAlignment.center, 93 | children: [ 94 | Image( 95 | image: AssetImage("images/google_logo.png"), 96 | height: 32, 97 | ), 98 | Text("Sign in with Google") 99 | ]), 100 | onPressed: () { 101 | signInWithGoogle().then((userDetails) { 102 | if (userDetails != null) { 103 | Navigator.pushAndRemoveUntil( 104 | context, 105 | MaterialPageRoute( 106 | builder: (context) => 107 | CustomersList(userDetails: userDetails)), 108 | (Route route) => false, 109 | ); 110 | } else { 111 | print("Error in Sign in With Google!"); 112 | } 113 | }); 114 | }), 115 | ), 116 | SizedBox( 117 | height: 100, 118 | ), 119 | ], 120 | ), 121 | ], 122 | ), 123 | ); 124 | } 125 | } 126 | -------------------------------------------------------------------------------- /lib/components/historyTile.dart: -------------------------------------------------------------------------------- 1 | import 'package:cloud_firestore/cloud_firestore.dart'; 2 | import 'package:flutter/material.dart'; 3 | import 'package:provider/provider.dart'; 4 | import 'dart:math'; 5 | 6 | class HistoryTile extends StatefulWidget { 7 | @override 8 | _HistoryTile createState() => _HistoryTile(); 9 | } 10 | 11 | class _HistoryTile extends State { 12 | @override 13 | Widget build(BuildContext context) { 14 | if (Provider.of(context) == null) { 15 | return Center(child: CircularProgressIndicator()); 16 | } 17 | List transactionHistory = 18 | Provider.of(context).docs.reversed.toList(); 19 | return ListView.builder( 20 | itemCount: transactionHistory.length, 21 | itemBuilder: (context, index) { 22 | dynamic history = transactionHistory[index].data(); 23 | return HistoryCard( 24 | sender: history['sender'], 25 | receiver: history['receiver'], 26 | dateTime: history["date_time"], 27 | amount: history["amount"], 28 | doneBy: history["done_by"] ?? "anonymous", 29 | ); 30 | }); 31 | } 32 | } 33 | 34 | class HistoryCard extends StatelessWidget { 35 | const HistoryCard({ 36 | Key key, 37 | @required this.sender, 38 | @required this.receiver, 39 | @required this.dateTime, 40 | @required this.amount, 41 | @required this.doneBy, 42 | }) : super(key: key); 43 | 44 | final String sender, receiver; 45 | final Timestamp dateTime; 46 | final int amount; 47 | final String doneBy; 48 | 49 | String _getBalance(int balance) { 50 | String balanceWithComma = balance.toString(); 51 | 52 | balanceWithComma = balanceWithComma.replaceAllMapped( 53 | new RegExp(r'(\d{1,3})(?=(\d{3})+(?!\d))'), (Match m) => '${m[1]},'); 54 | return balanceWithComma; 55 | } 56 | 57 | @override 58 | Widget build(BuildContext context) { 59 | DateTime dateTimeInstance = dateTime.toDate(); 60 | String date = dateTimeInstance.day.toString(); 61 | int month = dateTimeInstance.month; 62 | String hour = dateTimeInstance.hour.toString(); 63 | String minute = dateTimeInstance.minute.toString(); 64 | String second = dateTimeInstance.second.toString(); 65 | List months = [ 66 | "Jan", 67 | "Feb", 68 | "Mar", 69 | "Apr", 70 | "May", 71 | "Jun", 72 | "Jul", 73 | "Aug", 74 | "Sept", 75 | "Oct", 76 | "Nov", 77 | "Dec" 78 | ]; 79 | 80 | Color randomColor = Color.fromARGB((Random().nextInt(100) + 155) % 255, 81 | Random().nextInt(155), Random().nextInt(155), Random().nextInt(100)); 82 | 83 | return Padding( 84 | padding: const EdgeInsets.fromLTRB(0, 10, 0, 10), 85 | child: Card( 86 | margin: EdgeInsets.fromLTRB(20.0, 6.0, 20.0, 0.0), 87 | child: ListTile( 88 | leading: Container( 89 | height: 45, 90 | width: 45, 91 | decoration: BoxDecoration( 92 | color: Colors.grey[200], 93 | borderRadius: BorderRadius.all(Radius.circular(5))), 94 | child: Center( 95 | child: Column( 96 | mainAxisAlignment: MainAxisAlignment.center, 97 | crossAxisAlignment: CrossAxisAlignment.center, 98 | children: [ 99 | Text( 100 | date + "\u1d57\u02b0", 101 | style: TextStyle( 102 | fontWeight: FontWeight.bold, 103 | fontSize: 12, 104 | fontFamily: "Roboto"), 105 | ), 106 | Text( 107 | months[month - 1], 108 | style: TextStyle( 109 | fontWeight: FontWeight.w800, 110 | fontSize: 15, 111 | ), 112 | ), 113 | ], 114 | ), 115 | ), 116 | ), 117 | title: Row( 118 | children: [ 119 | Flexible( 120 | child: Container( 121 | width: 120, 122 | child: Text(sender, 123 | overflow: TextOverflow.ellipsis, 124 | style: TextStyle( 125 | fontWeight: FontWeight.bold, 126 | color: Colors.blueGrey[800])), 127 | ), 128 | ), 129 | Icon(Icons.arrow_right_alt_rounded), 130 | Flexible( 131 | child: Container( 132 | width: 120, 133 | child: Text(receiver, 134 | overflow: TextOverflow.ellipsis, 135 | style: TextStyle( 136 | fontWeight: FontWeight.bold, 137 | color: Colors.blueGrey[800])), 138 | ), 139 | ), 140 | ], 141 | ), 142 | subtitle: Column( 143 | children: [ 144 | Row( 145 | mainAxisAlignment: MainAxisAlignment.spaceBetween, 146 | children: [ 147 | Text( 148 | '-\$' + _getBalance(amount), 149 | style: TextStyle( 150 | color: Colors.red, 151 | fontWeight: FontWeight.w800, 152 | fontSize: 16), 153 | ), 154 | ]), 155 | SizedBox( 156 | height: 5, 157 | ), 158 | Row( 159 | mainAxisAlignment: MainAxisAlignment.spaceBetween, 160 | children: [ 161 | Text( 162 | hour + ":" + minute + ":" + second, 163 | style: TextStyle( 164 | letterSpacing: 1.0, 165 | color: Colors.grey, 166 | fontWeight: FontWeight.bold, 167 | fontSize: 12, 168 | fontFamily: "Roboto"), 169 | ), 170 | Row( 171 | children: [ 172 | Text( 173 | "by ", 174 | style: TextStyle( 175 | fontSize: 13, 176 | color: Colors.grey, 177 | fontWeight: FontWeight.bold), 178 | ), 179 | Text(doneBy, 180 | style: TextStyle( 181 | fontSize: 13, 182 | color: randomColor, 183 | fontWeight: FontWeight.bold, 184 | fontFamily: "Roboto", 185 | letterSpacing: 1)) 186 | ], 187 | ) 188 | ], 189 | ), 190 | ], 191 | )), 192 | ), 193 | ); 194 | } 195 | } 196 | -------------------------------------------------------------------------------- /pubspec.lock: -------------------------------------------------------------------------------- 1 | # Generated by pub 2 | # See https://dart.dev/tools/pub/glossary#lockfile 3 | packages: 4 | async: 5 | dependency: transitive 6 | description: 7 | name: async 8 | url: "https://pub.dartlang.org" 9 | source: hosted 10 | version: "2.5.0-nullsafety.1" 11 | boolean_selector: 12 | dependency: transitive 13 | description: 14 | name: boolean_selector 15 | url: "https://pub.dartlang.org" 16 | source: hosted 17 | version: "2.1.0-nullsafety.1" 18 | characters: 19 | dependency: transitive 20 | description: 21 | name: characters 22 | url: "https://pub.dartlang.org" 23 | source: hosted 24 | version: "1.1.0-nullsafety.3" 25 | charcode: 26 | dependency: transitive 27 | description: 28 | name: charcode 29 | url: "https://pub.dartlang.org" 30 | source: hosted 31 | version: "1.2.0-nullsafety.1" 32 | clock: 33 | dependency: transitive 34 | description: 35 | name: clock 36 | url: "https://pub.dartlang.org" 37 | source: hosted 38 | version: "1.1.0-nullsafety.1" 39 | cloud_firestore: 40 | dependency: "direct main" 41 | description: 42 | name: cloud_firestore 43 | url: "https://pub.dartlang.org" 44 | source: hosted 45 | version: "0.14.4" 46 | cloud_firestore_platform_interface: 47 | dependency: transitive 48 | description: 49 | name: cloud_firestore_platform_interface 50 | url: "https://pub.dartlang.org" 51 | source: hosted 52 | version: "2.2.1" 53 | cloud_firestore_web: 54 | dependency: transitive 55 | description: 56 | name: cloud_firestore_web 57 | url: "https://pub.dartlang.org" 58 | source: hosted 59 | version: "0.2.1+2" 60 | collection: 61 | dependency: transitive 62 | description: 63 | name: collection 64 | url: "https://pub.dartlang.org" 65 | source: hosted 66 | version: "1.15.0-nullsafety.3" 67 | cupertino_icons: 68 | dependency: "direct main" 69 | description: 70 | name: cupertino_icons 71 | url: "https://pub.dartlang.org" 72 | source: hosted 73 | version: "1.0.0" 74 | fake_async: 75 | dependency: transitive 76 | description: 77 | name: fake_async 78 | url: "https://pub.dartlang.org" 79 | source: hosted 80 | version: "1.2.0-nullsafety.1" 81 | firebase_auth: 82 | dependency: "direct main" 83 | description: 84 | name: firebase_auth 85 | url: "https://pub.dartlang.org" 86 | source: hosted 87 | version: "0.18.4+1" 88 | firebase_auth_platform_interface: 89 | dependency: transitive 90 | description: 91 | name: firebase_auth_platform_interface 92 | url: "https://pub.dartlang.org" 93 | source: hosted 94 | version: "2.1.4" 95 | firebase_auth_web: 96 | dependency: transitive 97 | description: 98 | name: firebase_auth_web 99 | url: "https://pub.dartlang.org" 100 | source: hosted 101 | version: "0.3.2+3" 102 | firebase_core: 103 | dependency: "direct main" 104 | description: 105 | name: firebase_core 106 | url: "https://pub.dartlang.org" 107 | source: hosted 108 | version: "0.5.3" 109 | firebase_core_platform_interface: 110 | dependency: transitive 111 | description: 112 | name: firebase_core_platform_interface 113 | url: "https://pub.dartlang.org" 114 | source: hosted 115 | version: "2.1.0" 116 | firebase_core_web: 117 | dependency: transitive 118 | description: 119 | name: firebase_core_web 120 | url: "https://pub.dartlang.org" 121 | source: hosted 122 | version: "0.2.1+1" 123 | flushbar: 124 | dependency: "direct main" 125 | description: 126 | name: flushbar 127 | url: "https://pub.dartlang.org" 128 | source: hosted 129 | version: "1.10.4" 130 | flutter: 131 | dependency: "direct main" 132 | description: flutter 133 | source: sdk 134 | version: "0.0.0" 135 | flutter_test: 136 | dependency: "direct dev" 137 | description: flutter 138 | source: sdk 139 | version: "0.0.0" 140 | flutter_web_plugins: 141 | dependency: transitive 142 | description: flutter 143 | source: sdk 144 | version: "0.0.0" 145 | google_sign_in: 146 | dependency: "direct main" 147 | description: 148 | name: google_sign_in 149 | url: "https://pub.dartlang.org" 150 | source: hosted 151 | version: "4.5.6" 152 | google_sign_in_platform_interface: 153 | dependency: transitive 154 | description: 155 | name: google_sign_in_platform_interface 156 | url: "https://pub.dartlang.org" 157 | source: hosted 158 | version: "1.1.2" 159 | google_sign_in_web: 160 | dependency: transitive 161 | description: 162 | name: google_sign_in_web 163 | url: "https://pub.dartlang.org" 164 | source: hosted 165 | version: "0.9.2" 166 | http_parser: 167 | dependency: transitive 168 | description: 169 | name: http_parser 170 | url: "https://pub.dartlang.org" 171 | source: hosted 172 | version: "3.1.4" 173 | intl: 174 | dependency: transitive 175 | description: 176 | name: intl 177 | url: "https://pub.dartlang.org" 178 | source: hosted 179 | version: "0.16.1" 180 | js: 181 | dependency: transitive 182 | description: 183 | name: js 184 | url: "https://pub.dartlang.org" 185 | source: hosted 186 | version: "0.6.2" 187 | matcher: 188 | dependency: transitive 189 | description: 190 | name: matcher 191 | url: "https://pub.dartlang.org" 192 | source: hosted 193 | version: "0.12.10-nullsafety.1" 194 | meta: 195 | dependency: transitive 196 | description: 197 | name: meta 198 | url: "https://pub.dartlang.org" 199 | source: hosted 200 | version: "1.3.0-nullsafety.3" 201 | nested: 202 | dependency: transitive 203 | description: 204 | name: nested 205 | url: "https://pub.dartlang.org" 206 | source: hosted 207 | version: "0.0.4" 208 | path: 209 | dependency: transitive 210 | description: 211 | name: path 212 | url: "https://pub.dartlang.org" 213 | source: hosted 214 | version: "1.8.0-nullsafety.1" 215 | plugin_platform_interface: 216 | dependency: transitive 217 | description: 218 | name: plugin_platform_interface 219 | url: "https://pub.dartlang.org" 220 | source: hosted 221 | version: "1.0.3" 222 | provider: 223 | dependency: "direct main" 224 | description: 225 | name: provider 226 | url: "https://pub.dartlang.org" 227 | source: hosted 228 | version: "4.3.2+4" 229 | quiver: 230 | dependency: transitive 231 | description: 232 | name: quiver 233 | url: "https://pub.dartlang.org" 234 | source: hosted 235 | version: "2.1.5" 236 | sky_engine: 237 | dependency: transitive 238 | description: flutter 239 | source: sdk 240 | version: "0.0.99" 241 | source_span: 242 | dependency: transitive 243 | description: 244 | name: source_span 245 | url: "https://pub.dartlang.org" 246 | source: hosted 247 | version: "1.8.0-nullsafety.2" 248 | stack_trace: 249 | dependency: transitive 250 | description: 251 | name: stack_trace 252 | url: "https://pub.dartlang.org" 253 | source: hosted 254 | version: "1.10.0-nullsafety.1" 255 | stream_channel: 256 | dependency: transitive 257 | description: 258 | name: stream_channel 259 | url: "https://pub.dartlang.org" 260 | source: hosted 261 | version: "2.1.0-nullsafety.1" 262 | string_scanner: 263 | dependency: transitive 264 | description: 265 | name: string_scanner 266 | url: "https://pub.dartlang.org" 267 | source: hosted 268 | version: "1.1.0-nullsafety.1" 269 | term_glyph: 270 | dependency: transitive 271 | description: 272 | name: term_glyph 273 | url: "https://pub.dartlang.org" 274 | source: hosted 275 | version: "1.2.0-nullsafety.1" 276 | test_api: 277 | dependency: transitive 278 | description: 279 | name: test_api 280 | url: "https://pub.dartlang.org" 281 | source: hosted 282 | version: "0.2.19-nullsafety.2" 283 | typed_data: 284 | dependency: transitive 285 | description: 286 | name: typed_data 287 | url: "https://pub.dartlang.org" 288 | source: hosted 289 | version: "1.3.0-nullsafety.3" 290 | vector_math: 291 | dependency: transitive 292 | description: 293 | name: vector_math 294 | url: "https://pub.dartlang.org" 295 | source: hosted 296 | version: "2.1.0-nullsafety.3" 297 | sdks: 298 | dart: ">=2.10.0-110 <2.11.0" 299 | flutter: ">=1.16.0 <2.0.0" 300 | -------------------------------------------------------------------------------- /lib/screens/all_customer.dart: -------------------------------------------------------------------------------- 1 | import 'package:basic_banking/database/databseService.dart'; 2 | import 'package:basic_banking/models/customer.dart'; 3 | import 'package:basic_banking/components/customerTile.dart'; 4 | 5 | import 'package:flushbar/flushbar.dart'; 6 | import 'package:flutter/material.dart'; 7 | import 'package:cloud_firestore/cloud_firestore.dart'; 8 | import 'package:provider/provider.dart'; 9 | 10 | class AllCustomersList extends StatelessWidget { 11 | const AllCustomersList({Key key, this.userEmail}) : super(key: key); 12 | 13 | final String userEmail; 14 | 15 | static List admin = [ 16 | "vicky.p8980@gmail.com", 17 | "vivek.p9737@gmail.com" 18 | ]; 19 | 20 | @override 21 | Widget build(BuildContext context) { 22 | void _showBottomSheet() { 23 | showModalBottomSheet( 24 | isScrollControlled: true, 25 | shape: RoundedRectangleBorder( 26 | borderRadius: BorderRadius.vertical(top: Radius.circular(25.0))), 27 | context: context, 28 | builder: (context) { 29 | return Container( 30 | padding: EdgeInsets.only( 31 | bottom: MediaQuery.of(context).viewInsets.bottom), 32 | child: SingleChildScrollView( 33 | child: Column(children: [ 34 | SizedBox( 35 | height: 10, 36 | ), 37 | SizedBox( 38 | width: 200, 39 | height: 20, 40 | child: Card( 41 | elevation: 0, 42 | shape: RoundedRectangleBorder( 43 | side: BorderSide(color: Colors.white, width: 1.0), 44 | borderRadius: BorderRadius.circular(50)), 45 | child: Divider( 46 | indent: 1, 47 | endIndent: 1, 48 | thickness: 8, 49 | color: Colors.grey[300], 50 | ), 51 | ), 52 | ), 53 | AddCustomerForm() 54 | ])), 55 | ); 56 | }, 57 | elevation: 5.0, 58 | ); 59 | } 60 | 61 | return StreamProvider.value( 62 | value: DatabaseService().customers, 63 | child: Scaffold( 64 | resizeToAvoidBottomInset: true, 65 | body: CustomerTile(), 66 | floatingActionButton: admin.contains(userEmail) 67 | ? FloatingActionButton( 68 | onPressed: () => _showBottomSheet(), 69 | child: Icon(Icons.add), 70 | backgroundColor: Colors.green, 71 | ) 72 | : null, 73 | ), 74 | ); 75 | } 76 | } 77 | 78 | class AddCustomerForm extends StatefulWidget { 79 | const AddCustomerForm({ 80 | Key key, 81 | }) : super(key: key); 82 | 83 | @override 84 | _AddCustomerFormState createState() => _AddCustomerFormState(); 85 | } 86 | 87 | class _AddCustomerFormState extends State { 88 | final _formKey = GlobalKey(); 89 | 90 | String customerName; 91 | String customerBalance; 92 | String customerNumber; 93 | String customerEmail; 94 | 95 | @override 96 | Widget build(BuildContext context) { 97 | return Form( 98 | key: _formKey, 99 | child: Column( 100 | children: [ 101 | SizedBox( 102 | height: 20.0, 103 | ), 104 | Padding( 105 | padding: const EdgeInsets.fromLTRB(15, 0, 20, 0), 106 | child: TextFormField( 107 | keyboardType: TextInputType.name, 108 | decoration: const InputDecoration( 109 | icon: Icon(Icons.person), 110 | hintText: 'Enter full name', 111 | labelText: 'Name *', 112 | ), 113 | validator: (value) { 114 | if (value.isEmpty) { 115 | return 'Please enter full name'; 116 | } 117 | return null; 118 | }, 119 | onChanged: (String value) { 120 | setState(() { 121 | customerName = value; 122 | }); 123 | }, 124 | ), 125 | ), 126 | SizedBox( 127 | height: 20.0, 128 | ), 129 | Padding( 130 | padding: const EdgeInsets.fromLTRB(15, 0, 20, 0), 131 | child: TextFormField( 132 | keyboardType: TextInputType.phone, 133 | decoration: const InputDecoration( 134 | icon: Icon(Icons.phone), 135 | hintText: 'Enter Phone Number', 136 | labelText: 'Number *', 137 | ), 138 | validator: (value) { 139 | if (value.isEmpty) { 140 | return 'Please enter phone number'; 141 | } 142 | return null; 143 | }, 144 | onChanged: (String value) { 145 | setState(() { 146 | customerNumber = value; 147 | }); 148 | }, 149 | ), 150 | ), 151 | SizedBox( 152 | height: 20.0, 153 | ), 154 | Padding( 155 | padding: const EdgeInsets.fromLTRB(15, 0, 20, 0), 156 | child: TextFormField( 157 | keyboardType: TextInputType.emailAddress, 158 | decoration: const InputDecoration( 159 | icon: Icon(Icons.email), 160 | hintText: 'Enter Email Address', 161 | labelText: 'Email *', 162 | ), 163 | validator: (value) { 164 | if (value.isEmpty) { 165 | return 'Please enter email'; 166 | } else if (RegExp( 167 | r'^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$') 168 | .hasMatch(value) == 169 | false) { 170 | return 'Enter Valid Email'; 171 | } 172 | return null; 173 | }, 174 | onChanged: (String value) { 175 | setState(() { 176 | customerEmail = value; 177 | }); 178 | }, 179 | ), 180 | ), 181 | SizedBox( 182 | height: 20.0, 183 | ), 184 | Padding( 185 | padding: const EdgeInsets.fromLTRB(15, 0, 20, 0), 186 | child: TextFormField( 187 | keyboardType: TextInputType.number, 188 | decoration: const InputDecoration( 189 | icon: Icon(Icons.phone_android), 190 | hintText: 'Enter Account Balance', 191 | labelText: 'Balance *', 192 | ), 193 | validator: (value) { 194 | if (value.isEmpty) { 195 | return 'Please enter balance'; 196 | } 197 | return null; 198 | }, 199 | onChanged: (String value) { 200 | setState(() { 201 | customerBalance = value; 202 | }); 203 | }, 204 | ), 205 | ), 206 | SizedBox( 207 | height: 50.0, 208 | ), 209 | RaisedButton( 210 | color: Colors.green[400], 211 | child: Text( 212 | "Add Customer", 213 | style: TextStyle(color: Colors.white), 214 | ), 215 | onPressed: () async { 216 | if (_formKey.currentState.validate()) { 217 | Customer newCustomer = new Customer( 218 | name: customerName, 219 | balance: int.parse(customerBalance), 220 | number: int.parse(customerNumber), 221 | email: customerEmail); 222 | await newCustomer.save(); 223 | Navigator.pop(context); 224 | Flushbar( 225 | margin: EdgeInsets.fromLTRB(10, 0, 10, 20), 226 | padding: EdgeInsets.all(20), 227 | borderRadius: 10, 228 | message: "Customer Added !", 229 | duration: Duration(seconds: 3), 230 | icon: Icon(Icons.person_add, 231 | size: 28, color: Colors.greenAccent), 232 | dismissDirection: FlushbarDismissDirection.HORIZONTAL, 233 | // leftBarIndicatorColor: Colors.blue[300], 234 | )..show(context); 235 | } 236 | }, 237 | ), 238 | SizedBox( 239 | height: 50.0, 240 | ) 241 | ], 242 | )); 243 | } 244 | } 245 | -------------------------------------------------------------------------------- /ios/Runner.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; }; 11 | 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; }; 12 | 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; }; 13 | 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; }; 14 | 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; }; 15 | 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; }; 16 | /* End PBXBuildFile section */ 17 | 18 | /* Begin PBXCopyFilesBuildPhase section */ 19 | 9705A1C41CF9048500538489 /* Embed Frameworks */ = { 20 | isa = PBXCopyFilesBuildPhase; 21 | buildActionMask = 2147483647; 22 | dstPath = ""; 23 | dstSubfolderSpec = 10; 24 | files = ( 25 | ); 26 | name = "Embed Frameworks"; 27 | runOnlyForDeploymentPostprocessing = 0; 28 | }; 29 | /* End PBXCopyFilesBuildPhase section */ 30 | 31 | /* Begin PBXFileReference section */ 32 | 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = ""; }; 33 | 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = ""; }; 34 | 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; }; 35 | 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = ""; }; 36 | 74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 37 | 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; }; 38 | 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = ""; }; 39 | 9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = ""; }; 40 | 97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; }; 41 | 97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 42 | 97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 43 | 97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 44 | 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 45 | /* End PBXFileReference section */ 46 | 47 | /* Begin PBXFrameworksBuildPhase section */ 48 | 97C146EB1CF9000F007C117D /* Frameworks */ = { 49 | isa = PBXFrameworksBuildPhase; 50 | buildActionMask = 2147483647; 51 | files = ( 52 | ); 53 | runOnlyForDeploymentPostprocessing = 0; 54 | }; 55 | /* End PBXFrameworksBuildPhase section */ 56 | 57 | /* Begin PBXGroup section */ 58 | 9740EEB11CF90186004384FC /* Flutter */ = { 59 | isa = PBXGroup; 60 | children = ( 61 | 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */, 62 | 9740EEB21CF90195004384FC /* Debug.xcconfig */, 63 | 7AFA3C8E1D35360C0083082E /* Release.xcconfig */, 64 | 9740EEB31CF90195004384FC /* Generated.xcconfig */, 65 | ); 66 | name = Flutter; 67 | sourceTree = ""; 68 | }; 69 | 97C146E51CF9000F007C117D = { 70 | isa = PBXGroup; 71 | children = ( 72 | 9740EEB11CF90186004384FC /* Flutter */, 73 | 97C146F01CF9000F007C117D /* Runner */, 74 | 97C146EF1CF9000F007C117D /* Products */, 75 | ); 76 | sourceTree = ""; 77 | }; 78 | 97C146EF1CF9000F007C117D /* Products */ = { 79 | isa = PBXGroup; 80 | children = ( 81 | 97C146EE1CF9000F007C117D /* Runner.app */, 82 | ); 83 | name = Products; 84 | sourceTree = ""; 85 | }; 86 | 97C146F01CF9000F007C117D /* Runner */ = { 87 | isa = PBXGroup; 88 | children = ( 89 | 97C146FA1CF9000F007C117D /* Main.storyboard */, 90 | 97C146FD1CF9000F007C117D /* Assets.xcassets */, 91 | 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */, 92 | 97C147021CF9000F007C117D /* Info.plist */, 93 | 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */, 94 | 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */, 95 | 74858FAE1ED2DC5600515810 /* AppDelegate.swift */, 96 | 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */, 97 | ); 98 | path = Runner; 99 | sourceTree = ""; 100 | }; 101 | /* End PBXGroup section */ 102 | 103 | /* Begin PBXNativeTarget section */ 104 | 97C146ED1CF9000F007C117D /* Runner */ = { 105 | isa = PBXNativeTarget; 106 | buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */; 107 | buildPhases = ( 108 | 9740EEB61CF901F6004384FC /* Run Script */, 109 | 97C146EA1CF9000F007C117D /* Sources */, 110 | 97C146EB1CF9000F007C117D /* Frameworks */, 111 | 97C146EC1CF9000F007C117D /* Resources */, 112 | 9705A1C41CF9048500538489 /* Embed Frameworks */, 113 | 3B06AD1E1E4923F5004D2608 /* Thin Binary */, 114 | ); 115 | buildRules = ( 116 | ); 117 | dependencies = ( 118 | ); 119 | name = Runner; 120 | productName = Runner; 121 | productReference = 97C146EE1CF9000F007C117D /* Runner.app */; 122 | productType = "com.apple.product-type.application"; 123 | }; 124 | /* End PBXNativeTarget section */ 125 | 126 | /* Begin PBXProject section */ 127 | 97C146E61CF9000F007C117D /* Project object */ = { 128 | isa = PBXProject; 129 | attributes = { 130 | LastUpgradeCheck = 1020; 131 | ORGANIZATIONNAME = ""; 132 | TargetAttributes = { 133 | 97C146ED1CF9000F007C117D = { 134 | CreatedOnToolsVersion = 7.3.1; 135 | LastSwiftMigration = 1100; 136 | }; 137 | }; 138 | }; 139 | buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */; 140 | compatibilityVersion = "Xcode 9.3"; 141 | developmentRegion = en; 142 | hasScannedForEncodings = 0; 143 | knownRegions = ( 144 | en, 145 | Base, 146 | ); 147 | mainGroup = 97C146E51CF9000F007C117D; 148 | productRefGroup = 97C146EF1CF9000F007C117D /* Products */; 149 | projectDirPath = ""; 150 | projectRoot = ""; 151 | targets = ( 152 | 97C146ED1CF9000F007C117D /* Runner */, 153 | ); 154 | }; 155 | /* End PBXProject section */ 156 | 157 | /* Begin PBXResourcesBuildPhase section */ 158 | 97C146EC1CF9000F007C117D /* Resources */ = { 159 | isa = PBXResourcesBuildPhase; 160 | buildActionMask = 2147483647; 161 | files = ( 162 | 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */, 163 | 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */, 164 | 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */, 165 | 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */, 166 | ); 167 | runOnlyForDeploymentPostprocessing = 0; 168 | }; 169 | /* End PBXResourcesBuildPhase section */ 170 | 171 | /* Begin PBXShellScriptBuildPhase section */ 172 | 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = { 173 | isa = PBXShellScriptBuildPhase; 174 | buildActionMask = 2147483647; 175 | files = ( 176 | ); 177 | inputPaths = ( 178 | ); 179 | name = "Thin Binary"; 180 | outputPaths = ( 181 | ); 182 | runOnlyForDeploymentPostprocessing = 0; 183 | shellPath = /bin/sh; 184 | shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin"; 185 | }; 186 | 9740EEB61CF901F6004384FC /* Run Script */ = { 187 | isa = PBXShellScriptBuildPhase; 188 | buildActionMask = 2147483647; 189 | files = ( 190 | ); 191 | inputPaths = ( 192 | ); 193 | name = "Run Script"; 194 | outputPaths = ( 195 | ); 196 | runOnlyForDeploymentPostprocessing = 0; 197 | shellPath = /bin/sh; 198 | shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build"; 199 | }; 200 | /* End PBXShellScriptBuildPhase section */ 201 | 202 | /* Begin PBXSourcesBuildPhase section */ 203 | 97C146EA1CF9000F007C117D /* Sources */ = { 204 | isa = PBXSourcesBuildPhase; 205 | buildActionMask = 2147483647; 206 | files = ( 207 | 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */, 208 | 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */, 209 | ); 210 | runOnlyForDeploymentPostprocessing = 0; 211 | }; 212 | /* End PBXSourcesBuildPhase section */ 213 | 214 | /* Begin PBXVariantGroup section */ 215 | 97C146FA1CF9000F007C117D /* Main.storyboard */ = { 216 | isa = PBXVariantGroup; 217 | children = ( 218 | 97C146FB1CF9000F007C117D /* Base */, 219 | ); 220 | name = Main.storyboard; 221 | sourceTree = ""; 222 | }; 223 | 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */ = { 224 | isa = PBXVariantGroup; 225 | children = ( 226 | 97C147001CF9000F007C117D /* Base */, 227 | ); 228 | name = LaunchScreen.storyboard; 229 | sourceTree = ""; 230 | }; 231 | /* End PBXVariantGroup section */ 232 | 233 | /* Begin XCBuildConfiguration section */ 234 | 249021D3217E4FDB00AE95B9 /* Profile */ = { 235 | isa = XCBuildConfiguration; 236 | buildSettings = { 237 | ALWAYS_SEARCH_USER_PATHS = NO; 238 | CLANG_ANALYZER_NONNULL = YES; 239 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 240 | CLANG_CXX_LIBRARY = "libc++"; 241 | CLANG_ENABLE_MODULES = YES; 242 | CLANG_ENABLE_OBJC_ARC = YES; 243 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 244 | CLANG_WARN_BOOL_CONVERSION = YES; 245 | CLANG_WARN_COMMA = YES; 246 | CLANG_WARN_CONSTANT_CONVERSION = YES; 247 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 248 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 249 | CLANG_WARN_EMPTY_BODY = YES; 250 | CLANG_WARN_ENUM_CONVERSION = YES; 251 | CLANG_WARN_INFINITE_RECURSION = YES; 252 | CLANG_WARN_INT_CONVERSION = YES; 253 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 254 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 255 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 256 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 257 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 258 | CLANG_WARN_STRICT_PROTOTYPES = YES; 259 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 260 | CLANG_WARN_UNREACHABLE_CODE = YES; 261 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 262 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 263 | COPY_PHASE_STRIP = NO; 264 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 265 | ENABLE_NS_ASSERTIONS = NO; 266 | ENABLE_STRICT_OBJC_MSGSEND = YES; 267 | GCC_C_LANGUAGE_STANDARD = gnu99; 268 | GCC_NO_COMMON_BLOCKS = YES; 269 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 270 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 271 | GCC_WARN_UNDECLARED_SELECTOR = YES; 272 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 273 | GCC_WARN_UNUSED_FUNCTION = YES; 274 | GCC_WARN_UNUSED_VARIABLE = YES; 275 | IPHONEOS_DEPLOYMENT_TARGET = 9.0; 276 | MTL_ENABLE_DEBUG_INFO = NO; 277 | SDKROOT = iphoneos; 278 | SUPPORTED_PLATFORMS = iphoneos; 279 | TARGETED_DEVICE_FAMILY = "1,2"; 280 | VALIDATE_PRODUCT = YES; 281 | }; 282 | name = Profile; 283 | }; 284 | 249021D4217E4FDB00AE95B9 /* Profile */ = { 285 | isa = XCBuildConfiguration; 286 | baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; 287 | buildSettings = { 288 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 289 | CLANG_ENABLE_MODULES = YES; 290 | CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; 291 | ENABLE_BITCODE = NO; 292 | FRAMEWORK_SEARCH_PATHS = ( 293 | "$(inherited)", 294 | "$(PROJECT_DIR)/Flutter", 295 | ); 296 | INFOPLIST_FILE = Runner/Info.plist; 297 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 298 | LIBRARY_SEARCH_PATHS = ( 299 | "$(inherited)", 300 | "$(PROJECT_DIR)/Flutter", 301 | ); 302 | PRODUCT_BUNDLE_IDENTIFIER = com.example.basicBanking; 303 | PRODUCT_NAME = "$(TARGET_NAME)"; 304 | SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; 305 | SWIFT_VERSION = 5.0; 306 | VERSIONING_SYSTEM = "apple-generic"; 307 | }; 308 | name = Profile; 309 | }; 310 | 97C147031CF9000F007C117D /* Debug */ = { 311 | isa = XCBuildConfiguration; 312 | buildSettings = { 313 | ALWAYS_SEARCH_USER_PATHS = NO; 314 | CLANG_ANALYZER_NONNULL = YES; 315 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 316 | CLANG_CXX_LIBRARY = "libc++"; 317 | CLANG_ENABLE_MODULES = YES; 318 | CLANG_ENABLE_OBJC_ARC = YES; 319 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 320 | CLANG_WARN_BOOL_CONVERSION = YES; 321 | CLANG_WARN_COMMA = YES; 322 | CLANG_WARN_CONSTANT_CONVERSION = YES; 323 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 324 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 325 | CLANG_WARN_EMPTY_BODY = YES; 326 | CLANG_WARN_ENUM_CONVERSION = YES; 327 | CLANG_WARN_INFINITE_RECURSION = YES; 328 | CLANG_WARN_INT_CONVERSION = YES; 329 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 330 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 331 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 332 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 333 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 334 | CLANG_WARN_STRICT_PROTOTYPES = YES; 335 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 336 | CLANG_WARN_UNREACHABLE_CODE = YES; 337 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 338 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 339 | COPY_PHASE_STRIP = NO; 340 | DEBUG_INFORMATION_FORMAT = dwarf; 341 | ENABLE_STRICT_OBJC_MSGSEND = YES; 342 | ENABLE_TESTABILITY = YES; 343 | GCC_C_LANGUAGE_STANDARD = gnu99; 344 | GCC_DYNAMIC_NO_PIC = NO; 345 | GCC_NO_COMMON_BLOCKS = YES; 346 | GCC_OPTIMIZATION_LEVEL = 0; 347 | GCC_PREPROCESSOR_DEFINITIONS = ( 348 | "DEBUG=1", 349 | "$(inherited)", 350 | ); 351 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 352 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 353 | GCC_WARN_UNDECLARED_SELECTOR = YES; 354 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 355 | GCC_WARN_UNUSED_FUNCTION = YES; 356 | GCC_WARN_UNUSED_VARIABLE = YES; 357 | IPHONEOS_DEPLOYMENT_TARGET = 9.0; 358 | MTL_ENABLE_DEBUG_INFO = YES; 359 | ONLY_ACTIVE_ARCH = YES; 360 | SDKROOT = iphoneos; 361 | TARGETED_DEVICE_FAMILY = "1,2"; 362 | }; 363 | name = Debug; 364 | }; 365 | 97C147041CF9000F007C117D /* Release */ = { 366 | isa = XCBuildConfiguration; 367 | buildSettings = { 368 | ALWAYS_SEARCH_USER_PATHS = NO; 369 | CLANG_ANALYZER_NONNULL = YES; 370 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 371 | CLANG_CXX_LIBRARY = "libc++"; 372 | CLANG_ENABLE_MODULES = YES; 373 | CLANG_ENABLE_OBJC_ARC = YES; 374 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 375 | CLANG_WARN_BOOL_CONVERSION = YES; 376 | CLANG_WARN_COMMA = YES; 377 | CLANG_WARN_CONSTANT_CONVERSION = YES; 378 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 379 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 380 | CLANG_WARN_EMPTY_BODY = YES; 381 | CLANG_WARN_ENUM_CONVERSION = YES; 382 | CLANG_WARN_INFINITE_RECURSION = YES; 383 | CLANG_WARN_INT_CONVERSION = YES; 384 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 385 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 386 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 387 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 388 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 389 | CLANG_WARN_STRICT_PROTOTYPES = YES; 390 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 391 | CLANG_WARN_UNREACHABLE_CODE = YES; 392 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 393 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 394 | COPY_PHASE_STRIP = NO; 395 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 396 | ENABLE_NS_ASSERTIONS = NO; 397 | ENABLE_STRICT_OBJC_MSGSEND = YES; 398 | GCC_C_LANGUAGE_STANDARD = gnu99; 399 | GCC_NO_COMMON_BLOCKS = YES; 400 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 401 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 402 | GCC_WARN_UNDECLARED_SELECTOR = YES; 403 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 404 | GCC_WARN_UNUSED_FUNCTION = YES; 405 | GCC_WARN_UNUSED_VARIABLE = YES; 406 | IPHONEOS_DEPLOYMENT_TARGET = 9.0; 407 | MTL_ENABLE_DEBUG_INFO = NO; 408 | SDKROOT = iphoneos; 409 | SUPPORTED_PLATFORMS = iphoneos; 410 | SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; 411 | TARGETED_DEVICE_FAMILY = "1,2"; 412 | VALIDATE_PRODUCT = YES; 413 | }; 414 | name = Release; 415 | }; 416 | 97C147061CF9000F007C117D /* Debug */ = { 417 | isa = XCBuildConfiguration; 418 | baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; 419 | buildSettings = { 420 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 421 | CLANG_ENABLE_MODULES = YES; 422 | CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; 423 | ENABLE_BITCODE = NO; 424 | FRAMEWORK_SEARCH_PATHS = ( 425 | "$(inherited)", 426 | "$(PROJECT_DIR)/Flutter", 427 | ); 428 | INFOPLIST_FILE = Runner/Info.plist; 429 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 430 | LIBRARY_SEARCH_PATHS = ( 431 | "$(inherited)", 432 | "$(PROJECT_DIR)/Flutter", 433 | ); 434 | PRODUCT_BUNDLE_IDENTIFIER = com.example.basicBanking; 435 | PRODUCT_NAME = "$(TARGET_NAME)"; 436 | SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; 437 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 438 | SWIFT_VERSION = 5.0; 439 | VERSIONING_SYSTEM = "apple-generic"; 440 | }; 441 | name = Debug; 442 | }; 443 | 97C147071CF9000F007C117D /* Release */ = { 444 | isa = XCBuildConfiguration; 445 | baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; 446 | buildSettings = { 447 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 448 | CLANG_ENABLE_MODULES = YES; 449 | CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; 450 | ENABLE_BITCODE = NO; 451 | FRAMEWORK_SEARCH_PATHS = ( 452 | "$(inherited)", 453 | "$(PROJECT_DIR)/Flutter", 454 | ); 455 | INFOPLIST_FILE = Runner/Info.plist; 456 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 457 | LIBRARY_SEARCH_PATHS = ( 458 | "$(inherited)", 459 | "$(PROJECT_DIR)/Flutter", 460 | ); 461 | PRODUCT_BUNDLE_IDENTIFIER = com.example.basicBanking; 462 | PRODUCT_NAME = "$(TARGET_NAME)"; 463 | SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; 464 | SWIFT_VERSION = 5.0; 465 | VERSIONING_SYSTEM = "apple-generic"; 466 | }; 467 | name = Release; 468 | }; 469 | /* End XCBuildConfiguration section */ 470 | 471 | /* Begin XCConfigurationList section */ 472 | 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */ = { 473 | isa = XCConfigurationList; 474 | buildConfigurations = ( 475 | 97C147031CF9000F007C117D /* Debug */, 476 | 97C147041CF9000F007C117D /* Release */, 477 | 249021D3217E4FDB00AE95B9 /* Profile */, 478 | ); 479 | defaultConfigurationIsVisible = 0; 480 | defaultConfigurationName = Release; 481 | }; 482 | 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */ = { 483 | isa = XCConfigurationList; 484 | buildConfigurations = ( 485 | 97C147061CF9000F007C117D /* Debug */, 486 | 97C147071CF9000F007C117D /* Release */, 487 | 249021D4217E4FDB00AE95B9 /* Profile */, 488 | ); 489 | defaultConfigurationIsVisible = 0; 490 | defaultConfigurationName = Release; 491 | }; 492 | /* End XCConfigurationList section */ 493 | }; 494 | rootObject = 97C146E61CF9000F007C117D /* Project object */; 495 | } 496 | -------------------------------------------------------------------------------- /lib/screens/transaction.dart: -------------------------------------------------------------------------------- 1 | import 'package:basic_banking/models/history.dart'; 2 | import 'package:flushbar/flushbar.dart'; 3 | import 'package:flutter/material.dart'; 4 | import 'package:cloud_firestore/cloud_firestore.dart'; 5 | import 'package:basic_banking/database/databseService.dart'; 6 | import 'package:flutter/services.dart'; 7 | 8 | class MakeTransaction extends StatefulWidget { 9 | const MakeTransaction({Key key, this.currentUser}) : super(key: key); 10 | final String currentUser; 11 | @override 12 | _MakeTransactionState createState() => _MakeTransactionState(); 13 | } 14 | 15 | class _MakeTransactionState extends State { 16 | List customerNamesList; 17 | String _senderName, _receiverName; 18 | String _transferAmount; 19 | bool isBalSet = false; 20 | 21 | @override 22 | void initState() { 23 | super.initState(); 24 | getCustomerNames(); 25 | } 26 | 27 | void getCustomerNames() { 28 | List customerNames = []; 29 | 30 | Future customerList = DatabaseService().getCustomerList(); 31 | customerList.then((querySnapshots) { 32 | if (querySnapshots.docs.isNotEmpty) { 33 | querySnapshots.docs.forEach((docs) { 34 | String name = docs.data()["name"]; 35 | customerNames.add(name); 36 | }); 37 | setState(() { 38 | customerNamesList = customerNames; 39 | }); 40 | } else { 41 | print("Customer List Empty!"); 42 | setState(() { 43 | customerNamesList = ["No Customers!"]; 44 | }); 45 | } 46 | }); 47 | } 48 | 49 | @override 50 | Widget build(BuildContext context) { 51 | void _transferMoney() { 52 | FocusScopeNode currentFocus = FocusScope.of(context); 53 | if (!currentFocus.hasPrimaryFocus) { 54 | currentFocus.unfocus(); 55 | } 56 | 57 | if (_senderName != null && 58 | _receiverName != null && 59 | _transferAmount != null) { 60 | showModalBottomSheet( 61 | isScrollControlled: false, 62 | backgroundColor: Colors.white, 63 | shape: RoundedRectangleBorder( 64 | side: BorderSide(color: Colors.white), 65 | borderRadius: BorderRadius.vertical(top: Radius.circular(25.0))), 66 | context: context, 67 | builder: (context) { 68 | return BottomSheetConfirmation( 69 | senderName: _senderName, 70 | transferAmount: _transferAmount, 71 | receiverName: _receiverName, 72 | currentUser: widget.currentUser, 73 | ); 74 | }, 75 | elevation: 5.0, 76 | ); 77 | } 78 | } 79 | 80 | return Container( 81 | height: MediaQuery.of(context).size.height, 82 | width: MediaQuery.of(context).size.width, 83 | child: Center( 84 | child: Padding( 85 | padding: const EdgeInsets.fromLTRB(20, 0, 20, 0), 86 | child: Container( 87 | height: 400, 88 | width: 500, 89 | child: Card( 90 | elevation: 5.0, 91 | shadowColor: Color.fromARGB(55, 0, 0, 0), 92 | shape: RoundedRectangleBorder( 93 | side: BorderSide(color: Colors.transparent, width: 1), 94 | borderRadius: BorderRadius.circular(20)), 95 | child: Column( 96 | mainAxisAlignment: MainAxisAlignment.spaceEvenly, 97 | crossAxisAlignment: CrossAxisAlignment.center, 98 | children: [ 99 | Row( 100 | mainAxisAlignment: MainAxisAlignment.center, 101 | crossAxisAlignment: CrossAxisAlignment.center, 102 | children: [ 103 | SenderDropDown( 104 | customerNamesList: customerNamesList, 105 | setSender: (val) => 106 | setState(() => _senderName = val)), 107 | SizedBox( 108 | width: 10, 109 | ), 110 | ReciverDropDown( 111 | customerNamesList: customerNamesList, 112 | setRecevier: (val) => 113 | setState(() => _receiverName = val), 114 | ) 115 | ], 116 | ), 117 | Column( 118 | mainAxisAlignment: MainAxisAlignment.center, 119 | crossAxisAlignment: CrossAxisAlignment.start, 120 | children: [ 121 | Padding( 122 | padding: const EdgeInsets.fromLTRB(4, 0, 0, 0), 123 | child: Text("Amount *", 124 | style: TextStyle( 125 | fontSize: 12, 126 | fontWeight: FontWeight.w500, 127 | color: Colors.grey[600])), 128 | ), 129 | Container( 130 | width: 200, 131 | height: 50, 132 | child: Card( 133 | shape: RoundedRectangleBorder( 134 | side: BorderSide( 135 | color: Color.fromARGB(130, 40, 33, 173), 136 | width: 1), 137 | borderRadius: BorderRadius.circular(10)), 138 | elevation: 0, 139 | child: Padding( 140 | padding: const EdgeInsets.fromLTRB(10, 0, 0, 4), 141 | child: TextField( 142 | style: TextStyle( 143 | fontWeight: FontWeight.w800, 144 | letterSpacing: 0.5, 145 | fontFamily: "Roboto"), 146 | autofocus: false, 147 | decoration: const InputDecoration( 148 | icon: Icon( 149 | Icons.monetization_on_rounded, 150 | size: 22, 151 | ), 152 | border: InputBorder.none, 153 | focusedBorder: InputBorder.none, 154 | enabledBorder: InputBorder.none, 155 | errorBorder: InputBorder.none, 156 | disabledBorder: InputBorder.none, 157 | hintText: 'Enter Amount', 158 | hintStyle: TextStyle( 159 | fontSize: 16, 160 | fontWeight: FontWeight.w500, 161 | fontFamily: "Raleway", 162 | letterSpacing: 0)), 163 | keyboardType: TextInputType.number, 164 | onChanged: (String value) { 165 | setState(() { 166 | _transferAmount = value; 167 | }); 168 | }), 169 | ), 170 | ), 171 | ) 172 | ], 173 | ), 174 | Row( 175 | mainAxisAlignment: MainAxisAlignment.center, 176 | crossAxisAlignment: CrossAxisAlignment.center, 177 | children: [ 178 | RaisedButton( 179 | shape: RoundedRectangleBorder( 180 | side: BorderSide( 181 | color: Color.fromARGB(130, 40, 33, 173), 182 | width: 1), 183 | borderRadius: BorderRadius.circular(10)), 184 | color: Color.fromARGB(200, 40, 33, 173), 185 | onPressed: () { 186 | _transferMoney(); 187 | }, 188 | child: Padding( 189 | padding: const EdgeInsets.fromLTRB(8, 15, 8, 15), 190 | child: Text("Transfer", 191 | style: TextStyle( 192 | color: Colors.white, 193 | fontSize: 14, 194 | fontWeight: FontWeight.w800)), 195 | ), 196 | ) 197 | ], 198 | ) 199 | ], 200 | ), 201 | ), 202 | ), 203 | ), 204 | ), 205 | ); 206 | } 207 | } 208 | 209 | class BottomSheetConfirmation extends StatefulWidget { 210 | const BottomSheetConfirmation({ 211 | Key key, 212 | @required String senderName, 213 | @required String transferAmount, 214 | @required String receiverName, 215 | @required String currentUser, 216 | }) : _senderName = senderName, 217 | _transferAmount = transferAmount, 218 | _receiverName = receiverName, 219 | _currentUser = currentUser, 220 | super(key: key); 221 | 222 | final String _senderName; 223 | final String _transferAmount; 224 | final String _receiverName; 225 | final String _currentUser; 226 | 227 | @override 228 | _BottomSheetConfirmationState createState() => 229 | _BottomSheetConfirmationState(); 230 | } 231 | 232 | class _BottomSheetConfirmationState extends State { 233 | int _senderBalance, _receiverBalance; 234 | String _senderDocId, _receiverDocId; 235 | String currentUser; 236 | void initState() { 237 | super.initState(); 238 | currentUser = widget._currentUser; 239 | getAccBalance(widget._senderName).then((value) { 240 | setState(() { 241 | _senderBalance = value["accBal"]; 242 | _senderDocId = value["docId"]; 243 | }); 244 | }); 245 | getAccBalance(widget._receiverName).then((value) { 246 | setState(() { 247 | _receiverBalance = value["accBal"]; 248 | _receiverDocId = value["docId"]; 249 | }); 250 | }); 251 | } 252 | 253 | Future> getAccBalance(String name) async { 254 | final CollectionReference collectionReference = 255 | DatabaseService().customerCollection; 256 | int accBal; 257 | String docId; 258 | var result = await collectionReference.where('name', isEqualTo: name).get(); 259 | docId = result.docs.first.id; 260 | accBal = result.docs.first["balance"]; 261 | return {"accBal": accBal, "docId": docId}; 262 | } 263 | 264 | int _transferTo(String senderName, String receiverName, int amount) { 265 | if (senderName != null || receiverName != null || amount != null) { 266 | int transfferResult; 267 | if (senderName == receiverName) { 268 | transfferResult = 0; 269 | } else if (_senderBalance >= amount) { 270 | // deduct amount from sender 271 | _senderBalance -= amount; 272 | // add amount to receiver 273 | _receiverBalance += amount; 274 | 275 | DatabaseService() 276 | .customerCollection 277 | .doc(_senderDocId) 278 | .update({"balance": _senderBalance}).then((value) { 279 | print("Amount Deducted Successfully"); 280 | }); 281 | 282 | DatabaseService() 283 | .customerCollection 284 | .doc(_receiverDocId) 285 | .update({"balance": _receiverBalance}).then((value) { 286 | print("Amount Added Successfully"); 287 | }); 288 | 289 | History( 290 | sender: senderName, 291 | receiver: receiverName, 292 | amount: amount, 293 | dateTime: DateTime.now(), 294 | currentUser: currentUser) 295 | .save() 296 | .then((value) => print("Transaction History Saved!")) 297 | .catchError((err) { 298 | print(err); 299 | }); 300 | 301 | transfferResult = 1; 302 | } else { 303 | transfferResult = 2; 304 | } 305 | return transfferResult ?? 0; 306 | } 307 | return -1; 308 | } 309 | 310 | @override 311 | Widget build(BuildContext context) { 312 | String senderBalance = _senderBalance.toString().replaceAllMapped( 313 | new RegExp(r'(\d{1,3})(?=(\d{3})+(?!\d))'), (Match m) => '${m[1]},'); 314 | String recevierBalance = _receiverBalance.toString().replaceAllMapped( 315 | new RegExp(r'(\d{1,3})(?=(\d{3})+(?!\d))'), (Match m) => '${m[1]},'); 316 | String transfferAmount = widget._transferAmount.toString().replaceAllMapped( 317 | new RegExp(r'(\d{1,3})(?=(\d{3})+(?!\d))'), (Match m) => '${m[1]},'); 318 | return _senderBalance == null || _receiverBalance == null 319 | ? Container( 320 | height: 200, 321 | width: 200, 322 | child: Center(child: CircularProgressIndicator())) 323 | : Container( 324 | color: Colors.transparent, 325 | padding: EdgeInsets.only( 326 | bottom: MediaQuery.of(context).viewInsets.bottom), 327 | child: Column(children: [ 328 | SizedBox( 329 | height: 10, 330 | ), 331 | SizedBox( 332 | width: 200, 333 | height: 20, 334 | child: Card( 335 | elevation: 0, 336 | shape: RoundedRectangleBorder( 337 | side: BorderSide(color: Colors.white, width: 1.0), 338 | borderRadius: BorderRadius.circular(50)), 339 | child: Divider( 340 | indent: 1, 341 | endIndent: 1, 342 | thickness: 8, 343 | color: Colors.grey[300], 344 | ), 345 | ), 346 | ), 347 | SingleChildScrollView( 348 | child: Column( 349 | mainAxisAlignment: MainAxisAlignment.center, 350 | crossAxisAlignment: CrossAxisAlignment.center, 351 | children: [ 352 | SizedBox(height: 30), 353 | Padding( 354 | padding: const EdgeInsets.all(8.0), 355 | child: Card( 356 | shadowColor: Color.fromARGB(80, 0, 0, 0), 357 | elevation: 5.0, 358 | shape: RoundedRectangleBorder( 359 | side: BorderSide( 360 | color: Color.fromARGB(130, 40, 33, 173), 361 | width: 1.5), 362 | borderRadius: BorderRadius.circular(10)), 363 | child: Padding( 364 | padding: const EdgeInsets.fromLTRB(15, 15, 5, 15), 365 | child: Row( 366 | children: [ 367 | Text("From Sender: "), 368 | Text( 369 | "${widget._senderName} ", 370 | style: TextStyle( 371 | fontWeight: FontWeight.w800, 372 | fontSize: 15, 373 | color: Colors.grey[700]), 374 | ), 375 | Text("[\$$senderBalance]", 376 | style: TextStyle( 377 | fontWeight: FontWeight.w400, 378 | fontFamily: "Roboto", 379 | color: Colors.grey)) 380 | ], 381 | ), 382 | )), 383 | ), 384 | SizedBox(height: 20), 385 | Padding( 386 | padding: const EdgeInsets.fromLTRB(15, 8, 8, 8), 387 | child: Row( 388 | children: [ 389 | Text("Transfer Amount: "), 390 | Card( 391 | color: Color.fromARGB(255, 239, 241, 245), 392 | elevation: 0.0, 393 | shape: RoundedRectangleBorder( 394 | side: BorderSide( 395 | color: Colors.transparent, width: 1.5), 396 | borderRadius: BorderRadius.circular(10)), 397 | child: Padding( 398 | padding: 399 | const EdgeInsets.fromLTRB(8, 10, 8, 10), 400 | child: Text( 401 | "\$" + transfferAmount, 402 | style: TextStyle( 403 | fontWeight: FontWeight.w600, 404 | fontSize: 17, 405 | color: Color.fromARGB(255, 40, 33, 173)), 406 | ), 407 | ), 408 | ), 409 | ], 410 | ), 411 | ), 412 | SizedBox(height: 20), 413 | Padding( 414 | padding: const EdgeInsets.all(8.0), 415 | child: Card( 416 | shadowColor: Color.fromARGB(80, 0, 0, 0), 417 | elevation: 5.0, 418 | shape: RoundedRectangleBorder( 419 | side: BorderSide( 420 | color: Color.fromARGB(130, 40, 33, 173), 421 | width: 1.5), 422 | borderRadius: BorderRadius.circular(10)), 423 | child: Padding( 424 | padding: const EdgeInsets.fromLTRB(15, 15, 5, 15), 425 | child: Row( 426 | children: [ 427 | Text("To Receiver: "), 428 | Text("${widget._receiverName} ", 429 | style: TextStyle( 430 | fontWeight: FontWeight.w800, 431 | fontSize: 15, 432 | color: Colors.grey[700])), 433 | Text("[\$$recevierBalance]", 434 | style: TextStyle( 435 | fontWeight: FontWeight.w400, 436 | fontFamily: "Roboto", 437 | color: Colors.grey)) 438 | ], 439 | ), 440 | )), 441 | ), 442 | SizedBox(height: 30), 443 | RaisedButton( 444 | shape: RoundedRectangleBorder( 445 | side: BorderSide( 446 | color: Colors.transparent, width: 1), 447 | borderRadius: BorderRadius.circular(10)), 448 | color: Colors.green[400], 449 | child: Padding( 450 | padding: const EdgeInsets.fromLTRB(8, 15, 8, 15), 451 | child: Text( 452 | "Confirm Transaction", 453 | style: 454 | TextStyle(color: Colors.white, fontSize: 14), 455 | ), 456 | ), 457 | onPressed: () { 458 | int isTranssferd = _transferTo( 459 | widget._senderName, 460 | widget._receiverName, 461 | int.parse(widget._transferAmount)); 462 | Navigator.pop(context); 463 | if (isTranssferd == 1) { 464 | // Transfer Successful 465 | Flushbar( 466 | margin: EdgeInsets.fromLTRB(10, 0, 10, 20), 467 | padding: EdgeInsets.all(20), 468 | borderRadius: 10, 469 | message: "Transfer Successful!", 470 | duration: Duration(seconds: 3), 471 | icon: Icon(Icons.check_circle, 472 | size: 28, color: Colors.greenAccent), 473 | dismissDirection: 474 | FlushbarDismissDirection.HORIZONTAL, 475 | // leftBarIndicatorColor: Colors.blue[300], 476 | )..show(context); 477 | } else if (isTranssferd == -1) { 478 | // Transfer Error 479 | Flushbar( 480 | margin: EdgeInsets.fromLTRB(10, 0, 10, 20), 481 | padding: EdgeInsets.all(20), 482 | borderRadius: 10, 483 | message: "Transfer Unsuccessful!", 484 | duration: Duration(seconds: 3), 485 | icon: Icon(Icons.cancel, 486 | size: 28, color: Colors.redAccent), 487 | dismissDirection: 488 | FlushbarDismissDirection.HORIZONTAL, 489 | // leftBarIndicatorColor: Colors.blue[300], 490 | )..show(context); 491 | } else if (isTranssferd == 2) { 492 | // Insufficient Balance 493 | Flushbar( 494 | margin: EdgeInsets.fromLTRB(10, 0, 10, 20), 495 | padding: EdgeInsets.all(20), 496 | borderRadius: 10, 497 | message: "Insufficient Balance!", 498 | duration: Duration(seconds: 3), 499 | icon: Icon(Icons.cancel, 500 | size: 28, color: Colors.redAccent), 501 | dismissDirection: 502 | FlushbarDismissDirection.HORIZONTAL, 503 | // leftBarIndicatorColor: Colors.blue[300], 504 | )..show(context); 505 | } else { 506 | // Names are Same 507 | Flushbar( 508 | margin: EdgeInsets.fromLTRB(10, 0, 10, 20), 509 | padding: EdgeInsets.all(20), 510 | borderRadius: 10, 511 | message: "Sender & Receiver are Same!", 512 | duration: Duration(seconds: 3), 513 | icon: Icon(Icons.cancel, 514 | size: 28, color: Colors.redAccent), 515 | dismissDirection: 516 | FlushbarDismissDirection.HORIZONTAL, 517 | // leftBarIndicatorColor: Colors.blue[300], 518 | )..show(context); 519 | } 520 | }), 521 | SizedBox(height: 30) 522 | ]), 523 | ) 524 | ])); 525 | } 526 | } 527 | 528 | typedef void StringCallback(String val); 529 | 530 | class SenderDropDown extends StatefulWidget { 531 | SenderDropDown({Key key, this.customerNamesList, this.setSender}) 532 | : super(key: key); 533 | final List customerNamesList; 534 | final StringCallback setSender; 535 | 536 | @override 537 | _SenderDropDownState createState() => _SenderDropDownState(); 538 | } 539 | 540 | class _SenderDropDownState extends State { 541 | String _currentSender = 'Vivek Patel'; 542 | 543 | @override 544 | Widget build(BuildContext context) { 545 | return widget.customerNamesList != null 546 | ? Column( 547 | crossAxisAlignment: CrossAxisAlignment.start, 548 | children: [ 549 | Padding( 550 | padding: const EdgeInsets.fromLTRB(4, 0, 0, 0), 551 | child: Text( 552 | "Select Sender *", 553 | style: TextStyle( 554 | fontSize: 12, 555 | fontWeight: FontWeight.w500, 556 | color: Colors.grey[600]), 557 | ), 558 | ), 559 | Card( 560 | child: Padding( 561 | padding: const EdgeInsets.fromLTRB(15, 0, 5, 0), 562 | child: DropdownButtonHideUnderline( 563 | child: DropdownButton( 564 | value: _currentSender, 565 | icon: Icon(Icons.arrow_drop_down_rounded), 566 | iconSize: 26, 567 | elevation: 1, 568 | iconEnabledColor: Colors.deepPurple, 569 | iconDisabledColor: Colors.grey, 570 | style: TextStyle( 571 | color: Colors.deepPurple[400], 572 | fontWeight: FontWeight.w600, 573 | letterSpacing: 0.2), 574 | onChanged: (String newValue) { 575 | setState(() { 576 | _currentSender = newValue; 577 | }); 578 | widget.setSender(newValue); 579 | }, 580 | items: widget.customerNamesList 581 | .map>((String value) { 582 | return DropdownMenuItem( 583 | value: value, 584 | child: Text(value), 585 | ); 586 | }).toList(), 587 | ), 588 | ), 589 | ), 590 | ), 591 | ], 592 | ) 593 | : CircularProgressIndicator(); 594 | } 595 | } 596 | 597 | class ReciverDropDown extends StatefulWidget { 598 | ReciverDropDown({Key key, this.customerNamesList, this.setRecevier}) 599 | : super(key: key); 600 | final List customerNamesList; 601 | final StringCallback setRecevier; 602 | 603 | @override 604 | _ReciverDropDownState createState() => _ReciverDropDownState(); 605 | } 606 | 607 | class _ReciverDropDownState extends State { 608 | String _currentReciever = "Om Patel"; 609 | 610 | @override 611 | Widget build(BuildContext context) { 612 | return widget.customerNamesList != null 613 | ? Column( 614 | crossAxisAlignment: CrossAxisAlignment.start, 615 | children: [ 616 | Padding( 617 | padding: const EdgeInsets.fromLTRB(4, 0, 0, 0), 618 | child: Text( 619 | "Select Receiver *", 620 | style: TextStyle( 621 | fontSize: 12, 622 | fontWeight: FontWeight.w500, 623 | color: Colors.grey[600]), 624 | )), 625 | Card( 626 | child: Padding( 627 | padding: const EdgeInsets.fromLTRB(15, 0, 5, 0), 628 | child: DropdownButtonHideUnderline( 629 | child: DropdownButton( 630 | value: _currentReciever, 631 | icon: Icon(Icons.arrow_drop_down_rounded), 632 | iconSize: 26, 633 | elevation: 1, 634 | iconEnabledColor: Colors.deepPurple, 635 | iconDisabledColor: Colors.grey, 636 | style: TextStyle( 637 | color: Colors.deepPurple[400], 638 | fontWeight: FontWeight.w600, 639 | letterSpacing: 0.2), 640 | onChanged: (String newValue) { 641 | setState(() { 642 | _currentReciever = newValue; 643 | }); 644 | widget.setRecevier(newValue); 645 | }, 646 | items: widget.customerNamesList 647 | .map>((String value) { 648 | return DropdownMenuItem( 649 | value: value, 650 | child: Text(value), 651 | ); 652 | }).toList(), 653 | ), 654 | ))) 655 | ]) 656 | : CircularProgressIndicator(); 657 | } 658 | } 659 | --------------------------------------------------------------------------------