diff --git a/banking_app_flutter-main/.gitignore b/banking_app_flutter-main/.gitignore new file mode 100644 index 00000000..24476c5d --- /dev/null +++ b/banking_app_flutter-main/.gitignore @@ -0,0 +1,44 @@ +# Miscellaneous +*.class +*.log +*.pyc +*.swp +.DS_Store +.atom/ +.buildlog/ +.history +.svn/ +migrate_working_dir/ + +# IntelliJ related +*.iml +*.ipr +*.iws +.idea/ + +# The .vscode folder contains launch configuration and tasks you configure in +# VS Code which you may wish to be included in version control, so this line +# is commented out by default. +#.vscode/ + +# Flutter/Dart/Pub related +**/doc/api/ +**/ios/Flutter/.last_build_id +.dart_tool/ +.flutter-plugins +.flutter-plugins-dependencies +.packages +.pub-cache/ +.pub/ +/build/ + +# Symbolication related +app.*.symbols + +# Obfuscation related +app.*.map.json + +# Android Studio will place build artifacts here +/android/app/debug +/android/app/profile +/android/app/release diff --git a/banking_app_flutter-main/.metadata b/banking_app_flutter-main/.metadata new file mode 100644 index 00000000..e27f5ccf --- /dev/null +++ b/banking_app_flutter-main/.metadata @@ -0,0 +1,45 @@ +# This file tracks properties of this Flutter project. +# Used by Flutter tool to assess capabilities and perform upgrades etc. +# +# This file should be version controlled. + +version: + revision: e3c29ec00c9c825c891d75054c63fcc46454dca1 + channel: stable + +project_type: app + +# Tracks metadata for the flutter migrate command +migration: + platforms: + - platform: root + create_revision: e3c29ec00c9c825c891d75054c63fcc46454dca1 + base_revision: e3c29ec00c9c825c891d75054c63fcc46454dca1 + - platform: android + create_revision: e3c29ec00c9c825c891d75054c63fcc46454dca1 + base_revision: e3c29ec00c9c825c891d75054c63fcc46454dca1 + - platform: ios + create_revision: e3c29ec00c9c825c891d75054c63fcc46454dca1 + base_revision: e3c29ec00c9c825c891d75054c63fcc46454dca1 + - platform: linux + create_revision: e3c29ec00c9c825c891d75054c63fcc46454dca1 + base_revision: e3c29ec00c9c825c891d75054c63fcc46454dca1 + - platform: macos + create_revision: e3c29ec00c9c825c891d75054c63fcc46454dca1 + base_revision: e3c29ec00c9c825c891d75054c63fcc46454dca1 + - platform: web + create_revision: e3c29ec00c9c825c891d75054c63fcc46454dca1 + base_revision: e3c29ec00c9c825c891d75054c63fcc46454dca1 + - platform: windows + create_revision: e3c29ec00c9c825c891d75054c63fcc46454dca1 + base_revision: e3c29ec00c9c825c891d75054c63fcc46454dca1 + + # User provided section + + # List of Local paths (relative to this file) that should be + # ignored by the migrate tool. + # + # Files that are not part of the templates will be ignored by default. + unmanaged_files: + - 'lib/main.dart' + - 'ios/Runner.xcodeproj/project.pbxproj' diff --git a/banking_app_flutter-main/README.md b/banking_app_flutter-main/README.md new file mode 100644 index 00000000..54fbdb13 --- /dev/null +++ b/banking_app_flutter-main/README.md @@ -0,0 +1,16 @@ +# banking_app + +A new Flutter project. + +## Getting Started + +This project is a starting point for a Flutter application. + +A few resources to get you started if this is your first Flutter project: + +- [Lab: Write your first Flutter app](https://docs.flutter.dev/get-started/codelab) +- [Cookbook: Useful Flutter samples](https://docs.flutter.dev/cookbook) + +For help getting started with Flutter development, view the +[online documentation](https://docs.flutter.dev/), which offers tutorials, +samples, guidance on mobile development, and a full API reference. diff --git a/banking_app_flutter-main/analysis_options.yaml b/banking_app_flutter-main/analysis_options.yaml new file mode 100644 index 00000000..61b6c4de --- /dev/null +++ b/banking_app_flutter-main/analysis_options.yaml @@ -0,0 +1,29 @@ +# This file configures the analyzer, which statically analyzes Dart code to +# check for errors, warnings, and lints. +# +# The issues identified by the analyzer are surfaced in the UI of Dart-enabled +# IDEs (https://dart.dev/tools#ides-and-editors). The analyzer can also be +# invoked from the command line by running `flutter analyze`. + +# The following line activates a set of recommended lints for Flutter apps, +# packages, and plugins designed to encourage good coding practices. +include: package:flutter_lints/flutter.yaml + +linter: + # The lint rules applied to this project can be customized in the + # section below to disable rules from the `package:flutter_lints/flutter.yaml` + # included above or to enable additional rules. A list of all available lints + # and their documentation is published at + # https://dart-lang.github.io/linter/lints/index.html. + # + # Instead of disabling a lint rule for the entire project in the + # section below, it can also be suppressed for a single line of code + # or a specific dart file by using the `// ignore: name_of_lint` and + # `// ignore_for_file: name_of_lint` syntax on the line or in the file + # producing the lint. + rules: + # avoid_print: false # Uncomment to disable the `avoid_print` rule + # prefer_single_quotes: true # Uncomment to enable the `prefer_single_quotes` rule + +# Additional information about this file can be found at +# https://dart.dev/guides/language/analysis-options diff --git a/banking_app_flutter-main/android/.gitignore b/banking_app_flutter-main/android/.gitignore new file mode 100644 index 00000000..6f568019 --- /dev/null +++ b/banking_app_flutter-main/android/.gitignore @@ -0,0 +1,13 @@ +gradle-wrapper.jar +/.gradle +/captures/ +/gradlew +/gradlew.bat +/local.properties +GeneratedPluginRegistrant.java + +# Remember to never publicly share your keystore. +# See https://flutter.dev/docs/deployment/android#reference-the-keystore-from-the-app +key.properties +**/*.keystore +**/*.jks diff --git a/banking_app_flutter-main/android/app/build.gradle b/banking_app_flutter-main/android/app/build.gradle new file mode 100644 index 00000000..0a9ef003 --- /dev/null +++ b/banking_app_flutter-main/android/app/build.gradle @@ -0,0 +1,71 @@ +def localProperties = new Properties() +def localPropertiesFile = rootProject.file('local.properties') +if (localPropertiesFile.exists()) { + localPropertiesFile.withReader('UTF-8') { reader -> + localProperties.load(reader) + } +} + +def flutterRoot = localProperties.getProperty('flutter.sdk') +if (flutterRoot == null) { + throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.") +} + +def flutterVersionCode = localProperties.getProperty('flutter.versionCode') +if (flutterVersionCode == null) { + flutterVersionCode = '1' +} + +def flutterVersionName = localProperties.getProperty('flutter.versionName') +if (flutterVersionName == null) { + flutterVersionName = '1.0' +} + +apply plugin: 'com.android.application' +apply plugin: 'kotlin-android' +apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" + +android { + compileSdkVersion flutter.compileSdkVersion + ndkVersion flutter.ndkVersion + + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } + + kotlinOptions { + jvmTarget = '1.8' + } + + sourceSets { + main.java.srcDirs += 'src/main/kotlin' + } + + defaultConfig { + // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). + applicationId "com.example.banking_app" + // You can update the following values to match your application needs. + // For more information, see: https://docs.flutter.dev/deployment/android#reviewing-the-build-configuration. + minSdkVersion flutter.minSdkVersion + targetSdkVersion flutter.targetSdkVersion + versionCode flutterVersionCode.toInteger() + versionName flutterVersionName + } + + buildTypes { + release { + // TODO: Add your own signing config for the release build. + // Signing with the debug keys for now, so `flutter run --release` works. + signingConfig signingConfigs.debug + } + } +} + +flutter { + source '../..' +} + +dependencies { + implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" +} diff --git a/banking_app_flutter-main/android/app/src/debug/AndroidManifest.xml b/banking_app_flutter-main/android/app/src/debug/AndroidManifest.xml new file mode 100644 index 00000000..eb9dacc2 --- /dev/null +++ b/banking_app_flutter-main/android/app/src/debug/AndroidManifest.xml @@ -0,0 +1,8 @@ + + + + diff --git a/banking_app_flutter-main/android/app/src/main/AndroidManifest.xml b/banking_app_flutter-main/android/app/src/main/AndroidManifest.xml new file mode 100644 index 00000000..12e42dfe --- /dev/null +++ b/banking_app_flutter-main/android/app/src/main/AndroidManifest.xml @@ -0,0 +1,34 @@ + + + + + + + + + + + + + + diff --git a/banking_app_flutter-main/android/app/src/main/kotlin/com/example/banking_app/MainActivity.kt b/banking_app_flutter-main/android/app/src/main/kotlin/com/example/banking_app/MainActivity.kt new file mode 100644 index 00000000..0124830c --- /dev/null +++ b/banking_app_flutter-main/android/app/src/main/kotlin/com/example/banking_app/MainActivity.kt @@ -0,0 +1,6 @@ +package com.example.banking_app + +import io.flutter.embedding.android.FlutterActivity + +class MainActivity: FlutterActivity() { +} diff --git a/banking_app_flutter-main/android/app/src/main/res/drawable-v21/launch_background.xml b/banking_app_flutter-main/android/app/src/main/res/drawable-v21/launch_background.xml new file mode 100644 index 00000000..f74085f3 --- /dev/null +++ b/banking_app_flutter-main/android/app/src/main/res/drawable-v21/launch_background.xml @@ -0,0 +1,12 @@ + + + + + + + + diff --git a/banking_app_flutter-main/android/app/src/main/res/drawable/launch_background.xml b/banking_app_flutter-main/android/app/src/main/res/drawable/launch_background.xml new file mode 100644 index 00000000..304732f8 --- /dev/null +++ b/banking_app_flutter-main/android/app/src/main/res/drawable/launch_background.xml @@ -0,0 +1,12 @@ + + + + + + + + diff --git a/banking_app_flutter-main/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml b/banking_app_flutter-main/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml new file mode 100644 index 00000000..90f95809 --- /dev/null +++ b/banking_app_flutter-main/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/banking_app_flutter-main/android/app/src/main/res/mipmap-hdpi/ic_launcher.png b/banking_app_flutter-main/android/app/src/main/res/mipmap-hdpi/ic_launcher.png new file mode 100644 index 00000000..33ce2a35 Binary files /dev/null and b/banking_app_flutter-main/android/app/src/main/res/mipmap-hdpi/ic_launcher.png differ diff --git a/banking_app_flutter-main/android/app/src/main/res/mipmap-hdpi/ic_launcher_adaptive_back.png b/banking_app_flutter-main/android/app/src/main/res/mipmap-hdpi/ic_launcher_adaptive_back.png new file mode 100644 index 00000000..04751a00 Binary files /dev/null and b/banking_app_flutter-main/android/app/src/main/res/mipmap-hdpi/ic_launcher_adaptive_back.png differ diff --git a/banking_app_flutter-main/android/app/src/main/res/mipmap-hdpi/ic_launcher_adaptive_fore.png b/banking_app_flutter-main/android/app/src/main/res/mipmap-hdpi/ic_launcher_adaptive_fore.png new file mode 100644 index 00000000..d7bd7a44 Binary files /dev/null and b/banking_app_flutter-main/android/app/src/main/res/mipmap-hdpi/ic_launcher_adaptive_fore.png differ diff --git a/banking_app_flutter-main/android/app/src/main/res/mipmap-mdpi/ic_launcher.png b/banking_app_flutter-main/android/app/src/main/res/mipmap-mdpi/ic_launcher.png new file mode 100644 index 00000000..7a5d6dac Binary files /dev/null and b/banking_app_flutter-main/android/app/src/main/res/mipmap-mdpi/ic_launcher.png differ diff --git a/banking_app_flutter-main/android/app/src/main/res/mipmap-mdpi/ic_launcher_adaptive_back.png b/banking_app_flutter-main/android/app/src/main/res/mipmap-mdpi/ic_launcher_adaptive_back.png new file mode 100644 index 00000000..4608b75a Binary files /dev/null and b/banking_app_flutter-main/android/app/src/main/res/mipmap-mdpi/ic_launcher_adaptive_back.png differ diff --git a/banking_app_flutter-main/android/app/src/main/res/mipmap-mdpi/ic_launcher_adaptive_fore.png b/banking_app_flutter-main/android/app/src/main/res/mipmap-mdpi/ic_launcher_adaptive_fore.png new file mode 100644 index 00000000..a14ae1e3 Binary files /dev/null and b/banking_app_flutter-main/android/app/src/main/res/mipmap-mdpi/ic_launcher_adaptive_fore.png differ diff --git a/banking_app_flutter-main/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/banking_app_flutter-main/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png new file mode 100644 index 00000000..dc98218c Binary files /dev/null and b/banking_app_flutter-main/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png differ diff --git a/banking_app_flutter-main/android/app/src/main/res/mipmap-xhdpi/ic_launcher_adaptive_back.png b/banking_app_flutter-main/android/app/src/main/res/mipmap-xhdpi/ic_launcher_adaptive_back.png new file mode 100644 index 00000000..5ada224a Binary files /dev/null and b/banking_app_flutter-main/android/app/src/main/res/mipmap-xhdpi/ic_launcher_adaptive_back.png differ diff --git a/banking_app_flutter-main/android/app/src/main/res/mipmap-xhdpi/ic_launcher_adaptive_fore.png b/banking_app_flutter-main/android/app/src/main/res/mipmap-xhdpi/ic_launcher_adaptive_fore.png new file mode 100644 index 00000000..e485e7c2 Binary files /dev/null and b/banking_app_flutter-main/android/app/src/main/res/mipmap-xhdpi/ic_launcher_adaptive_fore.png differ diff --git a/banking_app_flutter-main/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/banking_app_flutter-main/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png new file mode 100644 index 00000000..66c9209c Binary files /dev/null and b/banking_app_flutter-main/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png differ diff --git a/banking_app_flutter-main/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_adaptive_back.png b/banking_app_flutter-main/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_adaptive_back.png new file mode 100644 index 00000000..d5d36ab1 Binary files /dev/null and b/banking_app_flutter-main/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_adaptive_back.png differ diff --git a/banking_app_flutter-main/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_adaptive_fore.png b/banking_app_flutter-main/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_adaptive_fore.png new file mode 100644 index 00000000..ecc75862 Binary files /dev/null and b/banking_app_flutter-main/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_adaptive_fore.png differ diff --git a/banking_app_flutter-main/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/banking_app_flutter-main/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png new file mode 100644 index 00000000..d8295e56 Binary files /dev/null and b/banking_app_flutter-main/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png differ diff --git a/banking_app_flutter-main/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_adaptive_back.png b/banking_app_flutter-main/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_adaptive_back.png new file mode 100644 index 00000000..94f505f2 Binary files /dev/null and b/banking_app_flutter-main/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_adaptive_back.png differ diff --git a/banking_app_flutter-main/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_adaptive_fore.png b/banking_app_flutter-main/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_adaptive_fore.png new file mode 100644 index 00000000..f03592bb Binary files /dev/null and b/banking_app_flutter-main/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_adaptive_fore.png differ diff --git a/banking_app_flutter-main/android/app/src/main/res/values-night/styles.xml b/banking_app_flutter-main/android/app/src/main/res/values-night/styles.xml new file mode 100644 index 00000000..06952be7 --- /dev/null +++ b/banking_app_flutter-main/android/app/src/main/res/values-night/styles.xml @@ -0,0 +1,18 @@ + + + + + + + diff --git a/banking_app_flutter-main/android/app/src/main/res/values/styles.xml b/banking_app_flutter-main/android/app/src/main/res/values/styles.xml new file mode 100644 index 00000000..cb1ef880 --- /dev/null +++ b/banking_app_flutter-main/android/app/src/main/res/values/styles.xml @@ -0,0 +1,18 @@ + + + + + + + diff --git a/banking_app_flutter-main/android/app/src/profile/AndroidManifest.xml b/banking_app_flutter-main/android/app/src/profile/AndroidManifest.xml new file mode 100644 index 00000000..eb9dacc2 --- /dev/null +++ b/banking_app_flutter-main/android/app/src/profile/AndroidManifest.xml @@ -0,0 +1,8 @@ + + + + diff --git a/banking_app_flutter-main/android/build.gradle b/banking_app_flutter-main/android/build.gradle new file mode 100644 index 00000000..83ae2200 --- /dev/null +++ b/banking_app_flutter-main/android/build.gradle @@ -0,0 +1,31 @@ +buildscript { + ext.kotlin_version = '1.6.10' + repositories { + google() + mavenCentral() + } + + dependencies { + classpath 'com.android.tools.build:gradle:7.1.2' + classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" + } +} + +allprojects { + repositories { + google() + mavenCentral() + } +} + +rootProject.buildDir = '../build' +subprojects { + project.buildDir = "${rootProject.buildDir}/${project.name}" +} +subprojects { + project.evaluationDependsOn(':app') +} + +task clean(type: Delete) { + delete rootProject.buildDir +} diff --git a/banking_app_flutter-main/android/gradle.properties b/banking_app_flutter-main/android/gradle.properties new file mode 100644 index 00000000..94adc3a3 --- /dev/null +++ b/banking_app_flutter-main/android/gradle.properties @@ -0,0 +1,3 @@ +org.gradle.jvmargs=-Xmx1536M +android.useAndroidX=true +android.enableJetifier=true diff --git a/banking_app_flutter-main/android/gradle/wrapper/gradle-wrapper.properties b/banking_app_flutter-main/android/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 00000000..cb24abda --- /dev/null +++ b/banking_app_flutter-main/android/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,5 @@ +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-7.4-all.zip diff --git a/banking_app_flutter-main/android/settings.gradle b/banking_app_flutter-main/android/settings.gradle new file mode 100644 index 00000000..44e62bcf --- /dev/null +++ b/banking_app_flutter-main/android/settings.gradle @@ -0,0 +1,11 @@ +include ':app' + +def localPropertiesFile = new File(rootProject.projectDir, "local.properties") +def properties = new Properties() + +assert localPropertiesFile.exists() +localPropertiesFile.withReader("UTF-8") { reader -> properties.load(reader) } + +def flutterSdkPath = properties.getProperty("flutter.sdk") +assert flutterSdkPath != null, "flutter.sdk not set in local.properties" +apply from: "$flutterSdkPath/packages/flutter_tools/gradle/app_plugin_loader.gradle" diff --git a/banking_app_flutter-main/lib/db/db_helper.dart b/banking_app_flutter-main/lib/db/db_helper.dart new file mode 100644 index 00000000..6b8e527d --- /dev/null +++ b/banking_app_flutter-main/lib/db/db_helper.dart @@ -0,0 +1,121 @@ +import 'dart:async'; + +import 'package:faker/faker.dart'; +import 'package:sqflite/sqflite.dart'; +import 'package:path/path.dart' as p; + +import '../model/customer.dart'; +import '../model/transfer_transaction.dart'; + +class DbHelper { + static DbHelper instance = DbHelper._(); + static const String tableName = 'CUSTOMERS'; + static const String tableName2 = 'TRANSFERS'; + DbHelper._(); + Database? _database; + + Future get database async { + return _database ??= await openDatabase( + p.join(await getDatabasesPath(), "Mydb.db"), + version: 1, + onCreate: _onCreate, + ); + } + + Future> getAllCustomers() async { + List customers = []; + final db = await instance.database; + final result = await db.query(tableName); + for (var customerData in result) { + customers.add(Customer.fromJson(customerData)); + } + return customers; + } + + Future updateCustomer(Customer customer) async { + final db = await instance.database; + await db.rawUpdate( + 'Update $tableName Set balance=? where name=?', + [ + customer.balance, + customer.name, + ], + ); + print('updated'); + } + + FutureOr _onCreate(Database db, int version) async { + await db.execute("""CREATE TABLE $tableName( + name TEXT Primary Key, + email TEXT, + balance REAL + )"""); + await db.execute("""CREATE TABLE $tableName2( + from_name TEXT, + to_name TEXT, + to_email TEXT, + from_email TEXT, + amount REAL + )"""); + print("$tableName created"); + print("$tableName2 created"); + _insertCustomerData(); + } + + Future addTransfer(TransferTransaction transfer) async { + final db = await instance.database; + await db.insert( + tableName2, + { + 'to_name': transfer.to, + 'from_name': transfer.from, + 'from_email': transfer.fromEmail, + 'to_email': transfer.toEmail, + 'amount': transfer.amount, + }, + ); + print("$transfer inserted into db"); + } + + Future> getAllTransfersOfCustomer( + Customer customer) async { + List transfers = []; + final db = await database; + final result = await db.query( + tableName2, + where: 'to_name=? OR from_name=?', + whereArgs: [ + customer.name, + customer.name, + ], + ); + for (var transferData in result) { + transfers.add(TransferTransaction.fromJson(transferData)); + } + return transfers; + } + + void _insertCustomerData() async { + final db = await instance.database; + Faker faker = Faker(); + String insertQuery = "INSERT INTO $tableName Values"; + for (var i = 0; i < 10; i++) { + String name = faker.person.name(); + name = name.replaceAll("'", ""); + String email = faker.internet.email(); + email = email.replaceAll("'", ""); + final balance = faker.randomGenerator.decimal(min: 315, scale: 20000); + insertQuery += "('$name','$email',${balance.toStringAsFixed(2)}),"; + } + insertQuery = insertQuery.substring(0, insertQuery.length - 1); + print('Query: $insertQuery'); + await db.rawInsert(insertQuery); + print("Rows inserted"); + } + + Future deleteDb() async { + await deleteDatabase(p.join(await getDatabasesPath(), 'Mydb.db')); + _database = null; + print("deleted"); + } +} diff --git a/banking_app_flutter-main/lib/main.dart b/banking_app_flutter-main/lib/main.dart new file mode 100644 index 00000000..5f76f3dc --- /dev/null +++ b/banking_app_flutter-main/lib/main.dart @@ -0,0 +1,21 @@ +import 'package:banking_app/db/db_helper.dart'; +import 'package:banking_app/pages/home.dart'; +import 'package:flutter/material.dart'; + +void main() async { + WidgetsFlutterBinding.ensureInitialized(); + await DbHelper.instance.database; + runApp(const BankingApp()); +} + +class BankingApp extends StatelessWidget { + const BankingApp({super.key}); + + @override + Widget build(BuildContext context) { + return const MaterialApp( + debugShowCheckedModeBanner: false, + home: HomePage(), + ); + } +} diff --git a/banking_app_flutter-main/lib/model/customer.dart b/banking_app_flutter-main/lib/model/customer.dart new file mode 100644 index 00000000..90c9e2c0 --- /dev/null +++ b/banking_app_flutter-main/lib/model/customer.dart @@ -0,0 +1,25 @@ +class Customer { + String name; + String email; + double balance; + + Customer({ + required this.balance, + required this.email, + required this.name, + }); + + static Customer fromJson(json) => Customer( + balance: json['balance'], + email: json['email'], + name: json['name'], + ); + + @override + String toString() { + return '''Customer{ + name: $name, + email: $email, + balance:$balance}\n'''; + } +} diff --git a/banking_app_flutter-main/lib/model/transfer_transaction.dart b/banking_app_flutter-main/lib/model/transfer_transaction.dart new file mode 100644 index 00000000..01cc0d7e --- /dev/null +++ b/banking_app_flutter-main/lib/model/transfer_transaction.dart @@ -0,0 +1,31 @@ +class TransferTransaction { + String from; + String to; + String toEmail; + String fromEmail; + double amount; + + TransferTransaction({ + required this.amount, + required this.to, + required this.from, + required this.fromEmail, + required this.toEmail, + }); + + static TransferTransaction fromJson(json) => TransferTransaction( + amount: json['amount'], + from: json['from_name'], + fromEmail: json['to_email'], + to: json['to_name'], + toEmail: json['to_email'], + ); + + @override + String toString() { + return '''Transfer{ + From: $from, + To: $to, + Amount:$amount}\n'''; + } +} diff --git a/banking_app_flutter-main/lib/pages/home.dart b/banking_app_flutter-main/lib/pages/home.dart new file mode 100644 index 00000000..4cd29fcc --- /dev/null +++ b/banking_app_flutter-main/lib/pages/home.dart @@ -0,0 +1,94 @@ +import 'package:banking_app/pages/select_operation_page.dart'; +import 'package:flutter/material.dart'; + +import '../db/db_helper.dart'; +import '../model/customer.dart'; +import '../widgets/customer_card.dart'; + +class HomePage extends StatefulWidget { + const HomePage({super.key}); + + @override + State createState() => _HomePageState(); +} + +class _HomePageState extends State { + bool isLoading = false; + final _dbHelper = DbHelper.instance; + List customerList = []; + @override + void initState() { + super.initState(); + loadData(); + loadData(); + } + + loadData() async { + setState(() { + isLoading = true; + }); + final data = await _dbHelper.getAllCustomers(); + print(data.length); + setState(() { + customerList = data; + }); + await Future.delayed(const Duration(milliseconds: 300)); + print("done"); + setState(() { + isLoading = false; + }); + } + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + title: const Text('All customers'), + centerTitle: true, + actions: [ + IconButton(onPressed: loadData, icon: const Icon(Icons.refresh)) + ], + ), + body: Container( + margin: const EdgeInsets.all(10.0), + child: isLoading + ? const Center( + child: CircularProgressIndicator( + color: Colors.pink, + strokeWidth: 5, + ), + ) + : customerList.isEmpty + ? const Center( + child: Text('No data available.'), + ) + : ListView.builder( + padding: const EdgeInsets.only(bottom: 10.0), + itemCount: customerList.length, + itemBuilder: (context, index) => CustomerCard( + customer: customerList[index], + onPressed: () async { + final answer = await Navigator.push( + context, + MaterialPageRoute(builder: (_) { + return SelectOperationPage( + customerList: customerList, + selectedCustomer: customerList[index], + ); + }), + ); + if (answer != null && answer == 1) { + loadData(); + } + }, + ), + ), + ), + // floatingActionButton: FloatingActionButton( + // onPressed: () async { + // await _dbHelper.deleteDb(); + // }, + // ), + ); + } +} diff --git a/banking_app_flutter-main/lib/pages/select_customer_page.dart b/banking_app_flutter-main/lib/pages/select_customer_page.dart new file mode 100644 index 00000000..c5dd79df --- /dev/null +++ b/banking_app_flutter-main/lib/pages/select_customer_page.dart @@ -0,0 +1,44 @@ +import 'package:banking_app/pages/transaction_page.dart'; +import 'package:flutter/material.dart'; + +import '../model/customer.dart'; +import '../widgets/customer_card.dart'; + +class SelectCustomerPage extends StatelessWidget { + final List customerList; + final Customer selected; + + const SelectCustomerPage({ + super.key, + required this.customerList, + required this.selected, + }); + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + title: const Text('Select a customer'), + ), + body: Container( + margin: const EdgeInsets.all(10.0), + child: ListView.builder( + itemCount: customerList.length, + itemBuilder: (_, index) => CustomerCard( + customer: customerList[index], + onPressed: () { + Navigator.push( + context, + MaterialPageRoute( + builder: (_) => TransactionPage( + fromCustomer: selected, + toCustomer: customerList[index], + ), + ), + ); + }, + ), + ), + ), + ); + } +} diff --git a/banking_app_flutter-main/lib/pages/select_operation_page.dart b/banking_app_flutter-main/lib/pages/select_operation_page.dart new file mode 100644 index 00000000..2ab79f6d --- /dev/null +++ b/banking_app_flutter-main/lib/pages/select_operation_page.dart @@ -0,0 +1,81 @@ +import 'package:banking_app/pages/select_customer_page.dart'; +import 'package:banking_app/pages/transaction_history.dart'; +import 'package:flutter/material.dart'; + +import '../model/customer.dart'; + +class SelectOperationPage extends StatelessWidget { + const SelectOperationPage( + {super.key, required this.selectedCustomer, required this.customerList}); + final Customer selectedCustomer; + final List customerList; + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + title: const Text('Choose an operation'), + centerTitle: true, + ), + body: Padding( + padding: const EdgeInsets.all(15.0), + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + buildRoundedButton( + 'Transfer Money', + () => onTransferMoneyBtnPressed(context), + ), + const SizedBox(width: 10, height: 10), + buildRoundedButton( + 'View Transactions', + () => onViewTransactionPressed(context), + ), + ], + ), + ), + ); + } + + ElevatedButton buildRoundedButton(String btnText, VoidCallback onPressed) { + return ElevatedButton( + style: ElevatedButton.styleFrom( + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(10), + ), + ), + onPressed: onPressed, + child: Padding( + padding: const EdgeInsets.all(15.0), + child: Text(btnText), + ), + ); + } + + void onTransferMoneyBtnPressed(context) async { + final thisCustomerList = customerList + .where((customer) => customer.name != selectedCustomer.name) + .toList(); + Navigator.push( + context, + MaterialPageRoute(builder: (_) { + return SelectCustomerPage( + customerList: thisCustomerList, + selected: selectedCustomer, + ); + }), + ); + } + + void onViewTransactionPressed(context) { + Navigator.push( + context, + MaterialPageRoute(builder: (_) { + return TransactionHistoryPage( + selectedCustomer: selectedCustomer, + ); + }), + ); + } +} diff --git a/banking_app_flutter-main/lib/pages/transaction_history.dart b/banking_app_flutter-main/lib/pages/transaction_history.dart new file mode 100644 index 00000000..ebf1f7eb --- /dev/null +++ b/banking_app_flutter-main/lib/pages/transaction_history.dart @@ -0,0 +1,65 @@ +import 'package:banking_app/model/customer.dart'; +import 'package:banking_app/model/transfer_transaction.dart'; +import 'package:flutter/material.dart'; + +import '../db/db_helper.dart'; +import '../widgets/transferhistorycard.dart'; + +class TransactionHistoryPage extends StatefulWidget { + const TransactionHistoryPage({super.key, required this.selectedCustomer}); + final Customer selectedCustomer; + @override + State createState() => _TransactionHistoryPageState(); +} + +class _TransactionHistoryPageState extends State { + bool isLoading = false; + final _dbHelper = DbHelper.instance; + List transactions = []; + + @override + void initState() { + super.initState(); + loadTransactionHistory(); + } + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + title: const Text('Transaction History'), + ), + body: isLoading + ? const Center( + child: CircularProgressIndicator( + color: Colors.pink, + ), + ) + : transactions.isEmpty + ? const Center(child: Text('No transaction history.')) + : ListView.builder( + itemCount: transactions.length, + itemBuilder: (_, index) => TransferTransactionCard( + transaction: transactions[index], + ), + ), + ); + } + + void loadTransactionHistory() async { + setState(() { + isLoading = true; + }); + final history = + await _dbHelper.getAllTransfersOfCustomer(widget.selectedCustomer); + if (history.isNotEmpty) { + setState(() { + transactions = history; + }); + } + await Future.delayed(const Duration(milliseconds: 200)); + setState(() { + isLoading = false; + }); + } +} diff --git a/banking_app_flutter-main/lib/pages/transaction_page.dart b/banking_app_flutter-main/lib/pages/transaction_page.dart new file mode 100644 index 00000000..21dc5f8f --- /dev/null +++ b/banking_app_flutter-main/lib/pages/transaction_page.dart @@ -0,0 +1,240 @@ +import 'dart:async'; + +import 'package:banking_app/db/db_helper.dart'; +import 'package:banking_app/model/transfer_transaction.dart'; +import 'package:flutter/material.dart'; + +import '../model/customer.dart'; + +class TransactionPage extends StatefulWidget { + const TransactionPage( + {super.key, required this.fromCustomer, required this.toCustomer}); + final Customer fromCustomer; + final Customer toCustomer; + + @override + State createState() => _TransactionPageState(); +} + +class _TransactionPageState extends State { + final formKey = GlobalKey(); + final amountController = TextEditingController(); + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + title: const Text('Enter amount'), + ), + body: Form( + key: formKey, + child: Padding( + padding: const EdgeInsets.all(8.0), + child: Stack( + fit: StackFit.expand, + children: [ + buildHeader(), + Column( + crossAxisAlignment: CrossAxisAlignment.stretch, + mainAxisAlignment: MainAxisAlignment.center, + children: [ + buildAvailableBalance(), + const SizedBox(width: 10, height: 30), + buildAmountTextField(), + const SizedBox(width: 10, height: 10), + buildTransferBtn(), + ], + ), + ], + ), + ), + ), + ); + } + + Align buildAvailableBalance() { + return Align( + alignment: Alignment.topRight, + child: Row( + mainAxisAlignment: MainAxisAlignment.end, + children: [ + Text( + 'Available balance: ', + style: buildDialogTextStyle(color: Colors.black, fontSize: 15), + ), + Text( + '\$${widget.fromCustomer.balance}', + style: const TextStyle( + fontSize: 15, + color: Colors.blue, + fontWeight: FontWeight.bold, + ), + ), + ], + ), + ); + } + + Column buildHeader() { + return Column( + children: [ + Text( + 'From', + style: buildDialogTextStyle(color: Colors.black), + ), + Text( + widget.fromCustomer.name, + style: buildDialogTextStyle(fontSize: 25), + ), + const SizedBox(width: 10, height: 10), + Text( + 'To', + style: buildDialogTextStyle(color: Colors.black), + ), + Text( + widget.toCustomer.name, + style: buildDialogTextStyle(fontSize: 25), + ), + ], + ); + } + + ElevatedButton buildTransferBtn() { + return ElevatedButton( + style: ElevatedButton.styleFrom( + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(10), + ), + ), + onPressed: onTransferBtnPressed, + child: const Padding( + padding: EdgeInsets.all(15.0), + child: Text('Transfer'), + ), + ); + } + + TextFormField buildAmountTextField() { + return TextFormField( + keyboardType: const TextInputType.numberWithOptions(decimal: true), + decoration: InputDecoration( + border: OutlineInputBorder( + borderRadius: BorderRadius.circular(20.0), + ), + hintText: '\$ amount', + ), + controller: amountController, + validator: (val) { + if (val == null || val.isEmpty) { + return 'enter an amount.'; + } + if (double.parse(val) > widget.fromCustomer.balance) { + return 'not enough balance.'; + } + return null; + }, + ); + } + + AlertDialog buildAlertDialog(double amount) { + return AlertDialog( + contentPadding: const EdgeInsets.all(20.0), + title: Center( + child: Text( + 'Transfer Successful', + style: buildDialogTextStyle( + fontSize: 22, + color: Colors.black, + ), + ), + ), + content: Column( + mainAxisSize: MainAxisSize.min, + children: [ + const Icon( + Icons.check, + color: Colors.green, + size: 80, + ), + const SizedBox(width: 10, height: 10), + Text( + 'From', + style: buildDialogTextStyle(color: Colors.black), + ), + Text( + widget.fromCustomer.name, + style: buildDialogTextStyle(), + ), + const SizedBox(width: 10, height: 10), + Text( + 'To', + style: buildDialogTextStyle(color: Colors.black), + ), + Text( + widget.toCustomer.name, + style: buildDialogTextStyle(), + ), + const SizedBox(width: 10, height: 10), + Text( + 'Amount', + style: buildDialogTextStyle(color: Colors.black), + ), + Text( + '\$$amount', + style: buildDialogTextStyle(), + ), + ], + ), + ); + } + + TextStyle buildDialogTextStyle( + {Color color = Colors.blue, double fontSize = 20}) { + return TextStyle( + color: color, + fontSize: fontSize, + ); + } + + void onTransferBtnPressed() async { + if (formKey.currentState!.validate()) { + final amount = double.parse(amountController.text); + TransferTransaction transaction = TransferTransaction( + amount: double.parse(amountController.text), + to: widget.toCustomer.name, + from: widget.fromCustomer.name, + fromEmail: widget.fromCustomer.email, + toEmail: widget.toCustomer.email, + ); + print(transaction); + await DbHelper.instance.addTransfer(transaction); + // print("From Customer before: ${widget.fromCustomer}"); + // print("To Customer before: ${widget.toCustomer}"); + widget.fromCustomer.balance -= amount; + widget.toCustomer.balance += amount; + await DbHelper.instance.updateCustomer(widget.fromCustomer); + await DbHelper.instance.updateCustomer(widget.toCustomer); + // print("From Customer after: ${widget.fromCustomer}"); + // print("To Customer after: ${widget.toCustomer}"); + amountController.clear(); + setState(() {}); + await showDialog( + context: context, + // ignore: prefer_const_constructors + builder: (context) { + Timer(const Duration(milliseconds: 1200), () { + Navigator.pop(context); + }); + return buildAlertDialog(amount); + }, + ); + // ignore: use_build_context_synchronously + Navigator.pop(context); + // ignore: use_build_context_synchronously + Navigator.pop(context); + // ignore: use_build_context_synchronously + Navigator.pop(context, 1); + } else { + print("Validation failed"); + } + } +} diff --git a/banking_app_flutter-main/lib/widgets/customer_card.dart b/banking_app_flutter-main/lib/widgets/customer_card.dart new file mode 100644 index 00000000..af5e8a26 --- /dev/null +++ b/banking_app_flutter-main/lib/widgets/customer_card.dart @@ -0,0 +1,44 @@ +import 'package:flutter/material.dart'; + +import '../model/customer.dart'; + +class CustomerCard extends StatelessWidget { + const CustomerCard({ + super.key, + required this.customer, + required this.onPressed, + }); + + final Customer customer; + final VoidCallback? onPressed; + @override + Widget build(BuildContext context) { + return Card( + elevation: 5.0, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(10), + ), + color: Colors.blue, + child: ListTile( + onTap: onPressed, + leading: CircleAvatar( + radius: 30, + backgroundColor: Colors.white.withOpacity(0.9), + child: Text( + customer.name.characters.first.toUpperCase(), + style: const TextStyle( + color: Colors.blue, + fontSize: 25, + fontWeight: FontWeight.bold, + ), + ), + ), + contentPadding: const EdgeInsets.all(15.0), + textColor: Colors.white, + title: Text(customer.name), + subtitle: Text(customer.email), + trailing: Text('\$${customer.balance}'), + ), + ); + } +} diff --git a/banking_app_flutter-main/lib/widgets/transferhistorycard.dart b/banking_app_flutter-main/lib/widgets/transferhistorycard.dart new file mode 100644 index 00000000..34988c2e --- /dev/null +++ b/banking_app_flutter-main/lib/widgets/transferhistorycard.dart @@ -0,0 +1,27 @@ +import 'package:flutter/material.dart'; + +import '../model/transfer_transaction.dart'; + +class TransferTransactionCard extends StatelessWidget { + const TransferTransactionCard({Key? key, required this.transaction}) + : super(key: key); + final TransferTransaction transaction; + @override + Widget build(BuildContext context) { + return Card( + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(15.0), + ), + margin: const EdgeInsets.all(10.0), + child: ListTile( + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(15.0), + ), + title: Text('To: ${transaction.to}(${transaction.toEmail})'), + subtitle: Text('Amount: \$${transaction.amount}'), + tileColor: Colors.blue, + textColor: Colors.white, + ), + ); + } +} diff --git a/banking_app_flutter-main/pubspec.lock b/banking_app_flutter-main/pubspec.lock new file mode 100644 index 00000000..3632533b --- /dev/null +++ b/banking_app_flutter-main/pubspec.lock @@ -0,0 +1,203 @@ +# Generated by pub +# See https://dart.dev/tools/pub/glossary#lockfile +packages: + async: + dependency: transitive + description: + name: async + url: "https://pub.dartlang.org" + source: hosted + version: "2.9.0" + boolean_selector: + dependency: transitive + description: + name: boolean_selector + url: "https://pub.dartlang.org" + source: hosted + version: "2.1.0" + characters: + dependency: transitive + description: + name: characters + url: "https://pub.dartlang.org" + source: hosted + version: "1.2.1" + clock: + dependency: transitive + description: + name: clock + url: "https://pub.dartlang.org" + source: hosted + version: "1.1.1" + collection: + dependency: transitive + description: + name: collection + url: "https://pub.dartlang.org" + source: hosted + version: "1.16.0" + crypto: + dependency: transitive + description: + name: crypto + url: "https://pub.dartlang.org" + source: hosted + version: "3.0.2" + cupertino_icons: + dependency: "direct main" + description: + name: cupertino_icons + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.5" + fake_async: + dependency: transitive + description: + name: fake_async + url: "https://pub.dartlang.org" + source: hosted + version: "1.3.1" + faker: + dependency: "direct main" + description: + name: faker + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.0" + flutter: + dependency: "direct main" + description: flutter + source: sdk + version: "0.0.0" + flutter_lints: + dependency: "direct dev" + description: + name: flutter_lints + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.1" + flutter_test: + dependency: "direct dev" + description: flutter + source: sdk + version: "0.0.0" + lints: + dependency: transitive + description: + name: lints + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.0" + matcher: + dependency: transitive + description: + name: matcher + url: "https://pub.dartlang.org" + source: hosted + version: "0.12.12" + material_color_utilities: + dependency: transitive + description: + name: material_color_utilities + url: "https://pub.dartlang.org" + source: hosted + version: "0.1.5" + meta: + dependency: transitive + description: + name: meta + url: "https://pub.dartlang.org" + source: hosted + version: "1.8.0" + path: + dependency: transitive + description: + name: path + url: "https://pub.dartlang.org" + source: hosted + version: "1.8.2" + sky_engine: + dependency: transitive + description: flutter + source: sdk + version: "0.0.99" + source_span: + dependency: transitive + description: + name: source_span + url: "https://pub.dartlang.org" + source: hosted + version: "1.9.0" + sqflite: + dependency: "direct main" + description: + name: sqflite + url: "https://pub.dartlang.org" + source: hosted + version: "2.1.0+1" + sqflite_common: + dependency: transitive + description: + name: sqflite_common + url: "https://pub.dartlang.org" + source: hosted + version: "2.3.0" + stack_trace: + dependency: transitive + description: + name: stack_trace + url: "https://pub.dartlang.org" + source: hosted + version: "1.10.0" + stream_channel: + dependency: transitive + description: + name: stream_channel + url: "https://pub.dartlang.org" + source: hosted + version: "2.1.0" + string_scanner: + dependency: transitive + description: + name: string_scanner + url: "https://pub.dartlang.org" + source: hosted + version: "1.1.1" + synchronized: + dependency: transitive + description: + name: synchronized + url: "https://pub.dartlang.org" + source: hosted + version: "3.0.0+3" + term_glyph: + dependency: transitive + description: + name: term_glyph + url: "https://pub.dartlang.org" + source: hosted + version: "1.2.1" + test_api: + dependency: transitive + description: + name: test_api + url: "https://pub.dartlang.org" + source: hosted + version: "0.4.12" + typed_data: + dependency: transitive + description: + name: typed_data + url: "https://pub.dartlang.org" + source: hosted + version: "1.3.1" + vector_math: + dependency: transitive + description: + name: vector_math + url: "https://pub.dartlang.org" + source: hosted + version: "2.1.2" +sdks: + dart: ">=2.18.1 <3.0.0" + flutter: ">=3.3.0-0" diff --git a/banking_app_flutter-main/pubspec.yaml b/banking_app_flutter-main/pubspec.yaml new file mode 100644 index 00000000..d9fc326b --- /dev/null +++ b/banking_app_flutter-main/pubspec.yaml @@ -0,0 +1,78 @@ +name: banking_app +description: A new Flutter project. + +# The following line prevents the package from being accidentally published to +# pub.dev using `flutter pub publish`. This is preferred for private packages. +publish_to: 'none' # Remove this line if you wish to publish to pub.dev + +# The following defines the version and build number for your application. +# A version number is three numbers separated by dots, like 1.2.43 +# followed by an optional build number separated by a +. +# Both the version and the builder number may be overridden in flutter +# build by specifying --build-name and --build-number, respectively. +# In Android, build-name is used as versionName while build-number used as versionCode. +# Read more about Android versioning at https://developer.android.com/studio/publish/versioning +# In iOS, build-name is used as CFBundleShortVersionString while build-number is used as CFBundleVersion. +# Read more about iOS versioning at +# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html +# In Windows, build-name is used as the major, minor, and patch parts +# of the product and file versions while build-number is used as the build suffix. +version: 1.0.0+1 + +environment: + sdk: '>=2.18.1 <3.0.0' + +# Dependencies specify other packages that your package needs in order to work. +# To automatically upgrade your package dependencies to the latest versions +# consider running `flutter pub upgrade --major-versions`. Alternatively, +# dependencies can be manually updated by changing the version numbers below to +# the latest version available on pub.dev. To see which dependencies have newer +# versions available, run `flutter pub outdated`. +dependencies: + cupertino_icons: ^1.0.2 + faker: ^2.0.0 + flutter: + sdk: flutter + sqflite: ^2.1.0+1 + +dev_dependencies: + flutter_lints: ^2.0.0 + flutter_test: + sdk: flutter + +# For information on the generic Dart part of this file, see the +# following page: https://dart.dev/tools/pub/pubspec +# The following section is specific to Flutter packages. +flutter: + + # The following line ensures that the Material Icons font is + # included with your application, so that you can use the icons in + # the material Icons class. + uses-material-design: true + # To add assets to your application, add an assets section, like this: + # assets: + # - images/a_dot_burr.jpeg + # - images/a_dot_ham.jpeg + # An image asset can refer to one or more resolution-specific "variants", see + # https://flutter.dev/assets-and-images/#resolution-aware + # For details regarding adding assets from package dependencies, see + # https://flutter.dev/assets-and-images/#from-packages + # To add custom fonts to your application, add a fonts section here, + # in this "flutter" section. Each entry in this list should have a + # "family" key with the font family name, and a "fonts" key with a + # list giving the asset and other descriptors for the font. For + # example: + # fonts: + # - family: Schyler + # fonts: + # - asset: fonts/Schyler-Regular.ttf + # - asset: fonts/Schyler-Italic.ttf + # style: italic + # - family: Trajan Pro + # fonts: + # - asset: fonts/TrajanPro.ttf + # - asset: fonts/TrajanPro_Bold.ttf + # weight: 700 + # + # For details regarding fonts from package dependencies, + # see https://flutter.dev/custom-fonts/#from-packages