Skip to content
This repository has been archived by the owner on Dec 12, 2024. It is now read-only.

Commit

Permalink
Add withdraw page (#31)
Browse files Browse the repository at this point in the history
* update readme

* extract fee details to shared component

* extract currency converter to shared component

* update deposit page with shared components

* add withdraw page

* add navigation to withdraw page

* Update account balance test

* Add withdraw page test

* Add fee details test

* Update currency converter component

* Add currency converter test

* update readme, tests, component usage per comments
  • Loading branch information
kirahsapong authored Jan 31, 2024
1 parent bec57f4 commit ea7dfd8
Show file tree
Hide file tree
Showing 14 changed files with 494 additions and 171 deletions.
6 changes: 4 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,10 @@ The aim is that this app can work with any tbdex liquidity node, discoverying th
## Running

* Install Hermit https://cashapp.github.io/hermit/ (on macos you can run `brew install hermit` and then `hermit shell-hooks`)
* Ensure you have a mobile app simulator handy (XCode on macOS and runing the Simulator app will do for example)
* Run `flutter run` from this project to build and start the app in the simulator. Use `flutter run --dart-define=DEV_PFI=your_did_string` to run against a local tbdex liquidity node at dev time.
* Ensure you have a mobile app simulator connected and running (XCode on macOS and running the Simulator app will do for example)
* Run `pub get`.
* With your simulator running, change into your `frontend` directory, then run `flutter run` to build and start the app in the simulator.




Expand Down
143 changes: 13 additions & 130 deletions frontend/lib/features/deposit/deposit_page.dart
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:flutter_starter/l10n/app_localizations.dart';
import 'package:flutter_starter/shared/currency_converter.dart';
import 'package:flutter_starter/shared/fee_details.dart';
import 'package:flutter_starter/shared/grid.dart';
import 'package:flutter_starter/shared/number_pad.dart';
import 'package:intl/intl.dart';

class DepositPage extends HookWidget {
const DepositPage({super.key});
Expand All @@ -26,11 +27,19 @@ class DepositPage extends HookWidget {
horizontal: Grid.side, vertical: Grid.sm),
child: Column(
children: [
buildCurrencyConverter(
context, depositAmount, 'MXN', '17'),
CurrencyConverter(
originAmount: depositAmount.value,
originCurrency: 'MXN',
originLabel: Loc.of(context).youDeposit,
destinationCurrency: Loc.of(context).usd,
exchangeRate: (1 / 17).toString()),
const SizedBox(height: Grid.xl),
// these will come from PFI offerings later
buildDepositDetails(context, 'MXN', '17', '0'),
FeeDetails(
originCurrency: Loc.of(context).usd,
destinationCurrency: 'MXN',
exchangeRate: '17',
serviceFee: '0')
],
),
),
Expand All @@ -51,132 +60,6 @@ class DepositPage extends HookWidget {
);
}

Widget buildCurrencyConverter(
BuildContext context,
ValueNotifier<String> depositAmount,
String depositCurrency,
String exchangeRate) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
crossAxisAlignment: CrossAxisAlignment.baseline,
textBaseline: TextBaseline.alphabetic,
children: [
Text(
NumberFormat.simpleCurrency()
.format(double.parse(depositAmount.value)),
style: Theme.of(context).textTheme.displayMedium,
),
const SizedBox(width: Grid.xs),
Text(
depositCurrency,
style: Theme.of(context).textTheme.headlineMedium,
),
],
),
const SizedBox(height: Grid.xxs),
Text(
Loc.of(context).youDeposit,
style: Theme.of(context).textTheme.bodyLarge,
),
const SizedBox(height: Grid.sm),
Row(
crossAxisAlignment: CrossAxisAlignment.baseline,
textBaseline: TextBaseline.alphabetic,
children: [
Text(
NumberFormat.simpleCurrency().format(
double.parse(depositAmount.value) /
double.parse(exchangeRate)),
style: Theme.of(context).textTheme.displayMedium,
),
const SizedBox(width: Grid.xs),
Baseline(
baseline: 0,
baselineType: TextBaseline.alphabetic,
child: Text(
Loc.of(context).usd,
style: Theme.of(context).textTheme.headlineMedium,
),
),
],
),
const SizedBox(height: Grid.xxs),
Text(
Loc.of(context).youGet,
style: Theme.of(context).textTheme.bodyLarge,
),
],
);
}

Widget buildDepositDetails(
BuildContext context,
String depositCurrency,
String exchangeRate,
String serviceFee,
) {
return Container(
decoration: BoxDecoration(
border: Border.all(color: Theme.of(context).colorScheme.outline),
borderRadius: BorderRadius.circular(15.0),
),
padding: const EdgeInsets.all(Grid.xs),
child: Column(
children: [
Row(
children: [
Expanded(
flex: 1,
child: Text(
Loc.of(context).estRate,
style: Theme.of(context).textTheme.bodyMedium?.copyWith(
color: Theme.of(context).colorScheme.secondary,
),
),
),
Expanded(
flex: 2,
child: Text(
'1 ${Loc.of(context).usd} = $exchangeRate $depositCurrency',
style: Theme.of(context).textTheme.bodyMedium?.copyWith(
color: Theme.of(context).colorScheme.secondary,
),
textAlign: TextAlign.right,
),
),
],
),
const SizedBox(height: Grid.sm),
Row(
children: [
Expanded(
flex: 1,
child: Text(
Loc.of(context).serviceFee,
style: Theme.of(context).textTheme.bodyMedium?.copyWith(
color: Theme.of(context).colorScheme.secondary,
),
),
),
Expanded(
flex: 2,
child: Text(
'$serviceFee $depositCurrency',
style: Theme.of(context).textTheme.bodyMedium?.copyWith(
color: Theme.of(context).colorScheme.secondary,
),
textAlign: TextAlign.right,
),
),
],
),
],
),
);
}

Widget buildNumberPad(ValueNotifier<String> depositAmount) {
return NumberPad(
onKeyPressed: (key) {
Expand Down
8 changes: 7 additions & 1 deletion frontend/lib/features/home/account_balance.dart
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:flutter_starter/features/deposit/deposit_page.dart';
import 'package:flutter_starter/features/withdraw/withdraw_page.dart';
import 'package:flutter_starter/l10n/app_localizations.dart';
import 'package:flutter_starter/shared/grid.dart';

Expand Down Expand Up @@ -50,7 +51,12 @@ class AccountBalance extends HookWidget {
const SizedBox(width: Grid.xs),
Expanded(
child: FilledButton(
onPressed: () {}, child: Text(Loc.of(context).withdraw)),
onPressed: () {
Navigator.of(context).push(MaterialPageRoute(
builder: (context) => const WithdrawPage(),
));
},
child: Text(Loc.of(context).withdraw)),
),
],
),
Expand Down
76 changes: 76 additions & 0 deletions frontend/lib/features/withdraw/withdraw_page.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:flutter_starter/l10n/app_localizations.dart';
import 'package:flutter_starter/shared/currency_converter.dart';
import 'package:flutter_starter/shared/fee_details.dart';
import 'package:flutter_starter/shared/grid.dart';
import 'package:flutter_starter/shared/number_pad.dart';

class WithdrawPage extends HookWidget {
const WithdrawPage({super.key});

@override
Widget build(BuildContext context) {
final withdrawAmount = useState<String>('0');

return Scaffold(
appBar: AppBar(),
body: SafeArea(
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Expanded(
child: SingleChildScrollView(
physics: const BouncingScrollPhysics(),
child: Padding(
padding: const EdgeInsets.symmetric(
horizontal: Grid.side, vertical: Grid.sm),
child: Column(
children: [
CurrencyConverter(
originAmount: withdrawAmount.value,
originCurrency: Loc.of(context).usd,
originLabel: Loc.of(context).youWithdraw,
destinationCurrency: 'MXN',
exchangeRate: '17'),
const SizedBox(height: Grid.xl),
// these will come from PFI offerings later
FeeDetails(
originCurrency: Loc.of(context).usd,
destinationCurrency: 'MXN',
exchangeRate: '17',
serviceFee: '0')
],
),
),
),
),
Center(child: buildNumberPad(withdrawAmount)),
const SizedBox(height: Grid.sm),
Padding(
padding: const EdgeInsets.symmetric(horizontal: Grid.side),
child: FilledButton(
onPressed: () {},
child: Text(Loc.of(context).next),
),
),
],
),
),
);
}

Widget buildNumberPad(ValueNotifier<String> withdrawAmount) {
return NumberPad(
onKeyPressed: (key) {
withdrawAmount.value =
(withdrawAmount.value == '0') ? key : '${withdrawAmount.value}$key';
},
onDeletePressed: () {
withdrawAmount.value = (withdrawAmount.value.length > 1)
? withdrawAmount.value.substring(0, withdrawAmount.value.length - 1)
: '0';
},
);
}
}
1 change: 1 addition & 0 deletions frontend/lib/l10n/app_en.arb
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
"next": "Next",
"accountBalance": "Account balance",
"youDeposit": "You deposit",
"youWithdraw": "You withdraw",
"youGet": "You get",
"estRate": "Est. rate",
"serviceFee": "Service fee",
Expand Down
6 changes: 6 additions & 0 deletions frontend/lib/l10n/app_localizations.dart
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,12 @@ abstract class Loc {
/// **'You deposit'**
String get youDeposit;

/// No description provided for @youWithdraw.
///
/// In en, this message translates to:
/// **'You withdraw'**
String get youWithdraw;

/// No description provided for @youGet.
///
/// In en, this message translates to:
Expand Down
3 changes: 3 additions & 0 deletions frontend/lib/l10n/app_localizations_en.dart
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,9 @@ class LocEn extends Loc {
@override
String get youDeposit => 'You deposit';

@override
String get youWithdraw => 'You withdraw';

@override
String get youGet => 'You get';

Expand Down
77 changes: 77 additions & 0 deletions frontend/lib/shared/currency_converter.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:flutter_starter/l10n/app_localizations.dart';
import 'package:flutter_starter/shared/grid.dart';
import 'package:intl/intl.dart';

class CurrencyConverter extends HookWidget {
final String originAmount;
final String originCurrency;
final String originLabel;
final String destinationCurrency;
final String exchangeRate;

const CurrencyConverter({
required this.originAmount,
required this.originCurrency,
required this.originLabel,
required this.destinationCurrency,
required this.exchangeRate,
super.key,
});

@override
Widget build(BuildContext context) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
crossAxisAlignment: CrossAxisAlignment.baseline,
textBaseline: TextBaseline.alphabetic,
children: [
Text(
NumberFormat.simpleCurrency().format(double.parse(originAmount)),
style: Theme.of(context).textTheme.displayMedium,
),
const SizedBox(width: Grid.xs),
Baseline(
baseline: 0,
baselineType: TextBaseline.alphabetic,
child: Text(
originCurrency,
style: Theme.of(context).textTheme.headlineMedium,
),
),
],
),
const SizedBox(height: Grid.xxs),
Text(
originLabel,
style: Theme.of(context).textTheme.bodyLarge,
),
const SizedBox(height: Grid.sm),
Row(
crossAxisAlignment: CrossAxisAlignment.baseline,
textBaseline: TextBaseline.alphabetic,
children: [
Text(
NumberFormat.simpleCurrency().format(
double.parse(originAmount) * double.parse(exchangeRate)),
style: Theme.of(context).textTheme.displayMedium,
),
const SizedBox(width: Grid.xs),
Text(
destinationCurrency,
style: Theme.of(context).textTheme.headlineMedium,
),
],
),
const SizedBox(height: Grid.xxs),
Text(
Loc.of(context).youGet,
style: Theme.of(context).textTheme.bodyLarge,
),
],
);
}
}
Loading

0 comments on commit ea7dfd8

Please sign in to comment.