Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Review Request Page #65

Merged
merged 7 commits into from
Feb 15, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 14 additions & 5 deletions lib/features/deposit/deposit_page.dart
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import 'package:didpay/features/home/transaction.dart';
import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:didpay/features/currency/currency_converter.dart';
Expand Down Expand Up @@ -25,6 +26,8 @@ class DepositPage extends HookWidget {
final isValidKeyPress = useState<bool>(true);
final selectedCurrencyItem =
useState<Map<String, Object>>(supportedCurrencyList[1]);
final outputAmount = double.parse('0${depositAmount.value}') /
double.parse(selectedCurrencyItem.value['exchangeRate'].toString());

return Scaffold(
appBar: AppBar(),
Expand All @@ -45,10 +48,7 @@ class DepositPage extends HookWidget {
inputSelectedCurrency:
selectedCurrencyItem.value['label'].toString(),
inputLabel: Loc.of(context).youDeposit,
outputAmount: (double.parse('0${depositAmount.value}') /
double.parse(selectedCurrencyItem
.value['exchangeRate']
.toString())),
outputAmount: outputAmount,
isValidKeyPress: isValidKeyPress.value,
onDropdownTap: () {
CurrencyModal.show(
Expand Down Expand Up @@ -83,7 +83,16 @@ class DepositPage extends HookWidget {
onPressed: () {
Navigator.of(context).push(
MaterialPageRoute(
builder: (context) => const PaymentDetailsPage(),
builder: (context) => PaymentDetailsPage(
inputAmount: depositAmount.value,
inputCurrency:
selectedCurrencyItem.value['label'].toString(),
exchangeRate: selectedCurrencyItem.value['exchangeRate']
.toString(),
outputAmount: outputAmount.toString(),
outputCurrency: Loc.of(context).usd,
transactionType: Type.deposit,
),
),
);
},
Expand Down
45 changes: 43 additions & 2 deletions lib/features/payments/payment_details_page.dart
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import 'package:collection/collection.dart';
import 'package:didpay/features/payments/review_request_page.dart';
import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:didpay/features/payments/payment_method.dart';
Expand All @@ -8,7 +10,21 @@ import 'package:didpay/shared/json_schema_form.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';

class PaymentDetailsPage extends HookConsumerWidget {
const PaymentDetailsPage({super.key});
final String inputCurrency;
final String inputAmount;
final String outputCurrency;
final String outputAmount;
final String exchangeRate;
final String transactionType;

const PaymentDetailsPage(
{required this.inputCurrency,
required this.inputAmount,
required this.outputCurrency,
required this.outputAmount,
required this.exchangeRate,
required this.transactionType,
super.key});

@override
Widget build(BuildContext context, WidgetRef ref) {
Expand Down Expand Up @@ -174,12 +190,37 @@ class PaymentDetailsPage extends HookConsumerWidget {
child: JsonSchemaForm(
schema: selectedPaymentMethod.value!.requiredPaymentDetails,
onSubmit: (formData) {
// TODO: save payment details here
if (isValidOnSubmit(formData, selectedPaymentMethod)) {
Navigator.of(context).push(
MaterialPageRoute(
builder: (context) => ReviewRequestPage(
formData: formData,
bankName: selectedPaymentMethod.value!.kind
.split('_')
.lastOrNull ??
'',
inputAmount: inputAmount,
outputAmount: outputAmount,
inputCurrency: inputCurrency,
outputCurrency: outputCurrency,
exchangeRate: exchangeRate,
serviceFee: selectedPaymentMethod.value!.fee ?? '0.00',
transactionType: transactionType,
),
),
);
}
},
),
);
}

bool isValidOnSubmit(Map<String, String> formData,
ValueNotifier<PaymentMethod?> selectedPaymentMethod) {
return formData['accountNumber'] != null &&
selectedPaymentMethod.value!.kind.split('_').lastOrNull != null;
}

Widget _buildDisabledButton(BuildContext context) {
return Expanded(
child: Column(
Expand Down
173 changes: 173 additions & 0 deletions lib/features/payments/review_request_page.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,173 @@
import 'package:didpay/features/home/transaction.dart';
import 'package:didpay/l10n/app_localizations.dart';
import 'package:didpay/shared/fee_details.dart';
import 'package:didpay/shared/success_page.dart';
import 'package:didpay/shared/theme/grid.dart';
import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:intl/intl.dart';

class ReviewRequestPage extends HookWidget {
final String inputAmount;
final String outputAmount;
final String inputCurrency;
final String outputCurrency;
final String exchangeRate;
final String serviceFee;
final String bankName;
final Map<String, String> formData;
final String transactionType;

const ReviewRequestPage({
required this.inputAmount,
required this.outputAmount,
required this.inputCurrency,
required this.outputCurrency,
required this.exchangeRate,
required this.serviceFee,
required this.bankName,
required this.formData,
required this.transactionType,
super.key,
});

@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(),
body: SafeArea(
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: Grid.side),
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Expanded(
child: SingleChildScrollView(
physics: const BouncingScrollPhysics(),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
_buildHeader(context),
const SizedBox(height: Grid.md),
_buildAmounts(context),
const SizedBox(height: Grid.md),
_buildFeeDetails(context),
const SizedBox(height: Grid.md),
_buildBankDetails(context),
])),
),
Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
FilledButton(
onPressed: () {
Navigator.of(context).push(
MaterialPageRoute(
builder: (context) => SuccessPage(
text: Loc.of(context).yourRequestWasSubmitted,
),
),
);
},
child: Text(Loc.of(context).submit),
),
],
),
],
))));
}

Widget _buildHeader(BuildContext context) => Column(children: [
Align(
alignment: Alignment.topLeft,
child: Text(
Loc.of(context).reviewYourRequest,
style: Theme.of(context).textTheme.headlineSmall?.copyWith(
fontWeight: FontWeight.bold,
),
),
),
const SizedBox(height: Grid.xs),
Align(
alignment: Alignment.topLeft,
child: Text(
Loc.of(context).makeSureInfoIsCorrect,
style: Theme.of(context).textTheme.bodyMedium,
),
),
]);

Widget _buildAmounts(BuildContext context) =>
Column(crossAxisAlignment: CrossAxisAlignment.start, children: [
Row(
crossAxisAlignment: CrossAxisAlignment.baseline,
textBaseline: TextBaseline.alphabetic,
children: [
Text(
NumberFormat.simpleCurrency().format(double.parse(inputAmount)),
style: Theme.of(context).textTheme.displaySmall,
),
const SizedBox(width: Grid.xs),
Text(
inputCurrency,
style: Theme.of(context).textTheme.headlineMedium,
),
],
),
const SizedBox(height: Grid.xxs),
Text(
transactionType == Type.deposit
? Loc.of(context).youPay
: Loc.of(context).withdrawAmount,
style: Theme.of(context).textTheme.bodyLarge,
),
const SizedBox(height: Grid.xs),
Row(
crossAxisAlignment: CrossAxisAlignment.baseline,
textBaseline: TextBaseline.alphabetic,
children: [
Text(
NumberFormat.simpleCurrency().format(double.parse(outputAmount)),
style: Theme.of(context).textTheme.displaySmall,
),
const SizedBox(width: Grid.xs),
Text(
outputCurrency,
style: Theme.of(context).textTheme.headlineMedium,
),
],
),
const SizedBox(height: Grid.xxs),
Text(
transactionType == Type.deposit
? Loc.of(context).depositAmount
: Loc.of(context).youGet,
style: Theme.of(context).textTheme.bodyLarge,
)
]);

Widget _buildFeeDetails(BuildContext context) => FeeDetails(
originCurrency: Loc.of(context).usd,
destinationCurrency:
inputCurrency != Loc.of(context).usd ? inputCurrency : outputCurrency,
exchangeRate: exchangeRate,
serviceFee: double.parse(serviceFee).toStringAsFixed(2),
total: inputCurrency != Loc.of(context).usd
? (double.parse(inputAmount) + double.parse(serviceFee))
.toStringAsFixed(2)
: (double.parse(outputAmount) + double.parse(serviceFee))
.toStringAsFixed(2));

Widget _buildBankDetails(BuildContext context) => Column(children: [
Text(bankName),
const SizedBox(height: Grid.xxs),
Text(obscureAccountNumber(formData['accountNumber']!)),
]);

String obscureAccountNumber(String input) {
if (input.length <= 4) {
return input;
}
return '${'•' * (input.length - 4)} ${input.substring(input.length - 4)}';
}
}
20 changes: 14 additions & 6 deletions lib/features/withdraw/withdraw_page.dart
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import 'package:didpay/features/home/transaction.dart';
import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:didpay/features/currency/currency_converter.dart';
Expand Down Expand Up @@ -25,6 +26,8 @@ class WithdrawPage extends HookWidget {
final isValidKeyPress = useState<bool>(true);
final selectedCurrencyItem =
useState<Map<String, Object>>(supportedCurrencyList[1]);
final outputAmount = double.parse('0${withdrawAmount.value}') *
double.parse(selectedCurrencyItem.value['exchangeRate'].toString());

return Scaffold(
appBar: AppBar(),
Expand All @@ -45,11 +48,7 @@ class WithdrawPage extends HookWidget {
inputLabel: Loc.of(context).youWithdraw,
outputSelectedCurrency:
selectedCurrencyItem.value['label'].toString(),
outputAmount:
(double.parse('0${withdrawAmount.value}') *
double.parse(selectedCurrencyItem
.value['exchangeRate']
.toString())),
outputAmount: outputAmount,
isValidKeyPress: isValidKeyPress.value,
onDropdownTap: () {
CurrencyModal.show(
Expand Down Expand Up @@ -84,7 +83,16 @@ class WithdrawPage extends HookWidget {
onPressed: () {
Navigator.of(context).push(
MaterialPageRoute(
builder: (context) => const PaymentDetailsPage(),
builder: (context) => PaymentDetailsPage(
inputAmount: withdrawAmount.value,
inputCurrency: Loc.of(context).usd,
exchangeRate: selectedCurrencyItem.value['exchangeRate']
.toString(),
outputAmount: outputAmount.toString(),
outputCurrency:
selectedCurrencyItem.value['label'].toString(),
transactionType: Type.withdrawal,
),
),
);
},
Expand Down
8 changes: 7 additions & 1 deletion lib/l10n/app_en.arb
Original file line number Diff line number Diff line change
Expand Up @@ -72,5 +72,11 @@
"copiedDid": "Copied DID!",
"simulatedQrCodeScan": "Simulated QR code scan!",
"sendingPayment": "Sending payment...",
"verifyingYourIdentity": "Verifying your identity..."
"verifyingYourIdentity": "Verifying your identity...",
"reviewYourRequest": "Review your request",
"depositAmount": "Deposit amount",
"withdrawAmount": "Withdraw amount",
"total": "Total",
"submit": "Submit",
"yourRequestWasSubmitted": "Your request was submitted!"
}
36 changes: 36 additions & 0 deletions lib/l10n/app_localizations.dart
Original file line number Diff line number Diff line change
Expand Up @@ -384,6 +384,42 @@ abstract class Loc {
/// In en, this message translates to:
/// **'Verifying your identity...'**
String get verifyingYourIdentity;

/// No description provided for @reviewYourRequest.
///
/// In en, this message translates to:
/// **'Review your request'**
String get reviewYourRequest;

/// No description provided for @depositAmount.
///
/// In en, this message translates to:
/// **'Deposit amount'**
String get depositAmount;

/// No description provided for @withdrawAmount.
///
/// In en, this message translates to:
/// **'Withdraw amount'**
String get withdrawAmount;

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

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

/// No description provided for @yourRequestWasSubmitted.
///
/// In en, this message translates to:
/// **'Your request was submitted!'**
String get yourRequestWasSubmitted;
}

class _LocDelegate extends LocalizationsDelegate<Loc> {
Expand Down
Loading
Loading