mirror of
https://github.com/cake-tech/cake_wallet.git
synced 2025-03-12 09:32:33 +00:00
implement user create card
This commit is contained in:
parent
ac3b397908
commit
16616cf7d8
27 changed files with 790 additions and 182 deletions
BIN
assets/images/mastercard.png
Normal file
BIN
assets/images/mastercard.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 2.1 KiB |
BIN
assets/images/wifi.png
Normal file
BIN
assets/images/wifi.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.1 KiB |
35
lib/di.dart
35
lib/di.dart
|
@ -7,14 +7,7 @@ import 'package:cake_wallet/monero/monero.dart';
|
|||
import 'package:cake_wallet/haven/haven.dart';
|
||||
import 'package:cake_wallet/haven/haven.dart';
|
||||
import 'package:cake_wallet/bitcoin/bitcoin.dart';
|
||||
import 'package:cake_wallet/src/screens/cake_pay/auth/create_account_page.dart';
|
||||
import 'package:cake_wallet/src/screens/cake_pay/auth/forgot_password_page.dart';
|
||||
import 'package:cake_wallet/src/screens/cake_pay/auth/login_page.dart';
|
||||
import 'package:cake_wallet/src/screens/cake_pay/auth/verify_otp_page.dart';
|
||||
import 'package:cake_wallet/src/screens/cake_pay/cake_pay.dart';
|
||||
import 'package:cake_wallet/src/screens/cake_pay/cards/buy_card_detail_page.dart';
|
||||
import 'package:cake_wallet/src/screens/cake_pay/cards/buy_gift_card.dart';
|
||||
import 'package:cake_wallet/src/screens/cake_pay/cards/manage_cards_page.dart';
|
||||
import 'package:cake_wallet/src/screens/ionia/ionia.dart';
|
||||
import 'package:cake_wallet/src/screens/dashboard/widgets/balance_page.dart';
|
||||
import 'package:cake_wallet/view_model/ionia/ionia_view_model.dart';
|
||||
import 'package:cw_core/unspent_coins_info.dart';
|
||||
|
@ -652,8 +645,6 @@ Future setup(
|
|||
|
||||
getIt.registerFactory(() => AddressResolver(yatService: getIt.get<YatService>()));
|
||||
|
||||
getIt.registerFactory(() => ForgotPassword());
|
||||
|
||||
getIt.registerFactory(() => IoniaApi());
|
||||
|
||||
getIt.registerFactory<IoniaService>(
|
||||
|
@ -661,17 +652,29 @@ Future setup(
|
|||
|
||||
getIt.registerFactory(() => IoniaViewModel(ioniaService: getIt.get<IoniaService>()));
|
||||
|
||||
getIt.registerFactory(() => CreateAccountPage(getIt.get<IoniaViewModel>()));
|
||||
getIt.registerFactory(() => IoniaCreateAccountPage(getIt.get<IoniaViewModel>()));
|
||||
|
||||
getIt.registerFactory(() => LoginPage(getIt.get<IoniaViewModel>()));
|
||||
getIt.registerFactory(() => IoniaLoginPage(getIt.get<IoniaViewModel>()));
|
||||
|
||||
getIt.registerFactory(() => VerifyIoniaOtp(getIt.get<IoniaViewModel>()));
|
||||
getIt.registerFactoryParam<IoniaVerifyIoniaOtp, List, void>((List args, _) {
|
||||
final email = args.first as String;
|
||||
final ioniaViewModel = args[1] as IoniaViewModel;
|
||||
|
||||
getIt.registerFactory(() => WelcomePage(getIt.get<IoniaViewModel>()));
|
||||
return IoniaVerifyIoniaOtp(ioniaViewModel, email);
|
||||
});
|
||||
|
||||
getIt.registerFactory(() => BuyGiftCardPage());
|
||||
getIt.registerFactory(() => IoniaWelcomePage(getIt.get<IoniaViewModel>()));
|
||||
|
||||
getIt.registerFactory(() => IoniaBuyGiftCardPage());
|
||||
|
||||
getIt.registerFactory(() => IoniaBuyGiftCardDetailPage());
|
||||
|
||||
getIt.registerFactory(() => IoniaManageCardsPage(getIt.get<IoniaViewModel>()));
|
||||
|
||||
getIt.registerFactory(() => IoniaDebitCardPage(getIt.get<IoniaViewModel>()));
|
||||
|
||||
getIt.registerFactory(() => IoniaActivateDebitCardPage(getIt.get<IoniaViewModel>()));
|
||||
|
||||
getIt.registerFactory(() => BuyGiftCardDetailPage());
|
||||
|
||||
_isSetupFinished = true;
|
||||
}
|
||||
|
|
|
@ -88,7 +88,7 @@ class IoniaApi {
|
|||
final isSuccessful = bodyJson['Successful'] as bool;
|
||||
|
||||
if (!isSuccessful) {
|
||||
throw Exception(data['ErrorMessage'] as String);
|
||||
throw Exception(data['message'] as String);
|
||||
}
|
||||
|
||||
final virtualCard = data['VirtualCard'] as Map<String, Object>;
|
||||
|
@ -117,7 +117,7 @@ class IoniaApi {
|
|||
final isSuccessful = bodyJson['Successful'] as bool;
|
||||
|
||||
if (!isSuccessful) {
|
||||
throw Exception(data['ErrorMessage'] as String);
|
||||
throw Exception(data['message'] as String);
|
||||
}
|
||||
|
||||
return IoniaVirtualCard.fromMap(data);
|
||||
|
|
|
@ -1,12 +1,13 @@
|
|||
import 'package:cake_wallet/ionia/ionia_virtual_card.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
abstract class IoniaCreateState {}
|
||||
abstract class IoniaCreateAccountState {}
|
||||
|
||||
class IoniaCreateStateSuccess extends IoniaCreateState {}
|
||||
class IoniaCreateStateSuccess extends IoniaCreateAccountState {}
|
||||
|
||||
class IoniaCreateStateLoading extends IoniaCreateState {}
|
||||
class IoniaCreateStateLoading extends IoniaCreateAccountState {}
|
||||
|
||||
class IoniaCreateStateFailure extends IoniaCreateState {
|
||||
class IoniaCreateStateFailure extends IoniaCreateAccountState {
|
||||
IoniaCreateStateFailure({@required this.error});
|
||||
|
||||
final String error;
|
||||
|
@ -27,3 +28,29 @@ class IoniaOtpFailure extends IoniaOtpState {
|
|||
|
||||
final String error;
|
||||
}
|
||||
|
||||
class IoniaCreateCardState {}
|
||||
|
||||
class IoniaCreateCardSuccess extends IoniaCreateCardState {}
|
||||
|
||||
class IoniaCreateCardLoading extends IoniaCreateCardState {}
|
||||
|
||||
class IoniaCreateCardFailure extends IoniaCreateCardState {
|
||||
IoniaCreateCardFailure({@required this.error});
|
||||
|
||||
final String error;
|
||||
}
|
||||
|
||||
class IoniaFetchCardState {}
|
||||
|
||||
class IoniaNoCardState extends IoniaFetchCardState {}
|
||||
|
||||
class IoniaFetchingCard extends IoniaFetchCardState {}
|
||||
|
||||
class IoniaFetchCardFailure extends IoniaFetchCardState {}
|
||||
|
||||
class IoniaCardSuccess extends IoniaFetchCardState {
|
||||
IoniaCardSuccess({@required this.card});
|
||||
|
||||
final IoniaVirtualCard card;
|
||||
}
|
||||
|
|
|
@ -5,14 +5,6 @@ import 'package:cake_wallet/src/screens/backup/backup_page.dart';
|
|||
import 'package:cake_wallet/src/screens/backup/edit_backup_password_page.dart';
|
||||
import 'package:cake_wallet/src/screens/buy/buy_webview_page.dart';
|
||||
import 'package:cake_wallet/src/screens/buy/pre_order_page.dart';
|
||||
import 'package:cake_wallet/src/screens/cake_pay/auth/create_account_page.dart';
|
||||
import 'package:cake_wallet/src/screens/cake_pay/auth/forgot_password_page.dart';
|
||||
import 'package:cake_wallet/src/screens/cake_pay/auth/login_page.dart';
|
||||
import 'package:cake_wallet/src/screens/cake_pay/auth/verify_otp_page.dart';
|
||||
import 'package:cake_wallet/src/screens/cake_pay/cake_pay.dart';
|
||||
import 'package:cake_wallet/src/screens/cake_pay/cards/buy_card_detail_page.dart';
|
||||
import 'package:cake_wallet/src/screens/cake_pay/cards/buy_gift_card.dart';
|
||||
import 'package:cake_wallet/src/screens/cake_pay/cards/manage_cards_page.dart';
|
||||
import 'package:cake_wallet/src/screens/order_details/order_details_page.dart';
|
||||
import 'package:cake_wallet/src/screens/pin_code/pin_code_widget.dart';
|
||||
import 'package:cake_wallet/src/screens/restore/restore_from_backup_page.dart';
|
||||
|
@ -78,6 +70,7 @@ import 'package:hive/hive.dart';
|
|||
import 'package:cake_wallet/wallet_type_utils.dart';
|
||||
import 'package:cake_wallet/wallet_types.g.dart';
|
||||
import 'package:cake_wallet/src/screens/dashboard/widgets/address_page.dart';
|
||||
import 'package:cake_wallet/src/screens/ionia/ionia.dart';
|
||||
|
||||
RouteSettings currentRouteSettings;
|
||||
|
||||
|
@ -410,29 +403,33 @@ Route<dynamic> createRoute(RouteSettings settings) {
|
|||
getIt.get<UnspentCoinsDetailsPage>(
|
||||
param1: args));
|
||||
|
||||
case Routes.cakePayWelcomePage:
|
||||
return CupertinoPageRoute<void>(builder: (_) => getIt.get<WelcomePage>());
|
||||
case Routes.ioniaWelcomePage:
|
||||
return CupertinoPageRoute<void>(builder: (_) => getIt.get<IoniaWelcomePage>());
|
||||
|
||||
case Routes.cakePayLoginPage:
|
||||
return CupertinoPageRoute<void>( builder: (_) => getIt.get<LoginPage>());
|
||||
case Routes.ioniaLoginPage:
|
||||
return CupertinoPageRoute<void>( builder: (_) => getIt.get<IoniaLoginPage>());
|
||||
|
||||
case Routes.cakePayCreateAccountPage:
|
||||
return CupertinoPageRoute<void>( builder: (_) => getIt.get<CreateAccountPage>());
|
||||
case Routes.ioniaCreateAccountPage:
|
||||
return CupertinoPageRoute<void>( builder: (_) => getIt.get<IoniaCreateAccountPage>());
|
||||
|
||||
case Routes.cakePayForgotPasswordPage:
|
||||
return CupertinoPageRoute<void>(builder: (_) => getIt.get<ForgotPassword>());
|
||||
case Routes.ioniaManageCardsPage:
|
||||
return CupertinoPageRoute<void>(builder: (_) => getIt.get<IoniaManageCardsPage>());
|
||||
|
||||
case Routes.ioniaBuyGiftCardPage:
|
||||
return CupertinoPageRoute<void>(builder: (_) => getIt.get<IoniaBuyGiftCardPage>());
|
||||
|
||||
case Routes.manageCardsPage:
|
||||
return CupertinoPageRoute<void>(builder: (_) => getIt.get<ManageCardsPage>());
|
||||
case Routes.ioniaBuyGiftCardDetailPage:
|
||||
return CupertinoPageRoute<void>(builder: (_) => getIt.get<IoniaBuyGiftCardDetailPage>());
|
||||
|
||||
case Routes.buyGiftCardPage:
|
||||
return CupertinoPageRoute<void>(builder: (_) => getIt.get<BuyGiftCardPage>());
|
||||
|
||||
case Routes.buyGiftCardDetailPage:
|
||||
return CupertinoPageRoute<void>(builder: (_) => getIt.get<BuyGiftCardDetailPage>());
|
||||
case Routes.ioniaVerifyIoniaOtpPage:
|
||||
final args = settings.arguments as List;
|
||||
return CupertinoPageRoute<void>(builder: (_) =>getIt.get<IoniaVerifyIoniaOtp>(param1: args));
|
||||
|
||||
case Routes.verifyIoniaOtpPage:
|
||||
return CupertinoPageRoute<void>(builder: (_) => getIt.get<VerifyIoniaOtp>());
|
||||
case Routes.ioniaDebitCardPage:
|
||||
return CupertinoPageRoute<void>(builder: (_) => getIt.get<IoniaDebitCardPage>());
|
||||
|
||||
case Routes.ioniaActivateDebitCardPage:
|
||||
return CupertinoPageRoute<void>(builder: (_) => getIt.get<IoniaActivateDebitCardPage>());
|
||||
|
||||
default:
|
||||
return MaterialPageRoute<void>(
|
||||
|
|
|
@ -60,12 +60,14 @@ class Routes {
|
|||
static const moneroRestoreWalletFromWelcome = '/monero_restore_wallet';
|
||||
static const moneroNewWalletFromWelcome = '/monero_new_wallet';
|
||||
static const addressPage = '/address_page';
|
||||
static const cakePayWelcomePage = '/cake_pay_welcome_page';
|
||||
static const cakePayCreateAccountPage = '/cake_pay_create_account_page';
|
||||
static const cakePayLoginPage = '/cake_pay_login_page';
|
||||
static const cakePayForgotPasswordPage = '/cake_pay_forgot_password_page';
|
||||
static const manageCardsPage = '/manage_cards_page';
|
||||
static const buyGiftCardPage = '/buy_gift_card_page';
|
||||
static const buyGiftCardDetailPage = '/buy_gift_card_detail_page';
|
||||
static const verifyIoniaOtpPage = '/cake_pay_verify_otp_page';
|
||||
static const ioniaWelcomePage = '/cake_pay_welcome_page';
|
||||
static const ioniaCreateAccountPage = '/cake_pay_create_account_page';
|
||||
static const ioniaLoginPage = '/cake_pay_login_page';
|
||||
static const ioniaManageCardsPage = '/manage_cards_page';
|
||||
static const ioniaBuyGiftCardPage = '/buy_gift_card_page';
|
||||
static const ioniaBuyGiftCardDetailPage = '/buy_gift_card_detail_page';
|
||||
static const ioniaVerifyIoniaOtpPage = '/cake_pay_verify_otp_page';
|
||||
static const ioniaDebitCardPage = '/debit_card_page';
|
||||
static const ioniaActivateDebitCardPage = '/activate_debit_card_page';
|
||||
|
||||
}
|
||||
|
|
|
@ -1,55 +0,0 @@
|
|||
import 'package:cake_wallet/src/screens/base_page.dart';
|
||||
import 'package:cake_wallet/src/widgets/base_text_form_field.dart';
|
||||
import 'package:cake_wallet/src/widgets/primary_button.dart';
|
||||
import 'package:cake_wallet/src/widgets/scollable_with_bottom_section.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:cake_wallet/generated/i18n.dart';
|
||||
|
||||
class ForgotPassword extends BasePage {
|
||||
@override
|
||||
Color get titleColor => Colors.black;
|
||||
|
||||
@override
|
||||
Widget middle(BuildContext context) {
|
||||
return Text(
|
||||
S.current.forgot_password,
|
||||
style: TextStyle(
|
||||
fontSize: 22,
|
||||
fontFamily: 'Lato',
|
||||
fontWeight: FontWeight.w900,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
Widget body(BuildContext context) {
|
||||
return ScrollableWithBottomSection(
|
||||
contentPadding: EdgeInsets.all(24),
|
||||
content: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: <Widget>[
|
||||
BaseTextFormField(
|
||||
hintText: 'Email Address*',
|
||||
),
|
||||
SizedBox(height: 20),
|
||||
],
|
||||
),
|
||||
bottomSectionPadding: EdgeInsets.symmetric(vertical: 36, horizontal: 24),
|
||||
bottomSection: Column(
|
||||
children: [
|
||||
Column(
|
||||
mainAxisAlignment: MainAxisAlignment.end,
|
||||
children: <Widget>[
|
||||
PrimaryButton(
|
||||
text: S.of(context).reset_password,
|
||||
onPressed: () {},
|
||||
color: Theme.of(context).accentTextTheme.body2.color,
|
||||
textColor: Colors.white,
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
|
@ -1 +0,0 @@
|
|||
export 'auth/welcome_page.dart';
|
|
@ -35,7 +35,7 @@ class MarketPlacePage extends StatelessWidget {
|
|||
children: <Widget>[
|
||||
SizedBox(height: 20),
|
||||
MarketPlaceItem(
|
||||
onTap: () => Navigator.of(context).pushNamed(Routes.cakePayWelcomePage),
|
||||
onTap: () => Navigator.of(context).pushNamed(Routes.ioniaWelcomePage),
|
||||
title: S.of(context).cake_pay_title,
|
||||
subTitle: S.of(context).cake_pay_subtitle,
|
||||
),
|
||||
|
|
|
@ -13,10 +13,10 @@ import 'package:cake_wallet/generated/i18n.dart';
|
|||
import 'package:flutter_mobx/flutter_mobx.dart';
|
||||
import 'package:mobx/mobx.dart';
|
||||
|
||||
class CreateAccountPage extends BasePage {
|
||||
class IoniaCreateAccountPage extends BasePage {
|
||||
final IoniaViewModel _ioniaViewModel;
|
||||
|
||||
CreateAccountPage(this._ioniaViewModel)
|
||||
IoniaCreateAccountPage(this._ioniaViewModel)
|
||||
: _emailFocus = FocusNode(),
|
||||
_emailController = TextEditingController(),
|
||||
_formKey = GlobalKey<FormState>() {
|
||||
|
@ -43,12 +43,12 @@ class CreateAccountPage extends BasePage {
|
|||
|
||||
@override
|
||||
Widget body(BuildContext context) {
|
||||
reaction((_) => _ioniaViewModel.createUserState, (IoniaCreateState state) {
|
||||
reaction((_) => _ioniaViewModel.createUserState, (IoniaCreateAccountState state) {
|
||||
if (state is IoniaCreateStateFailure) {
|
||||
_onCreateUserFailure(context, state.error);
|
||||
}
|
||||
if (state is IoniaCreateStateSuccess) {
|
||||
_onCreateSuccessful(context);
|
||||
_onCreateSuccessful(context, _ioniaViewModel);
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -135,4 +135,8 @@ void _onCreateUserFailure(BuildContext context, String error) {
|
|||
});
|
||||
}
|
||||
|
||||
void _onCreateSuccessful(BuildContext context) => Navigator.pushNamed(context, Routes.verifyIoniaOtpPage);
|
||||
void _onCreateSuccessful(BuildContext context, IoniaViewModel ioniaViewModel) => Navigator.pushNamed(
|
||||
context,
|
||||
Routes.ioniaVerifyIoniaOtpPage,
|
||||
arguments: [ioniaViewModel.email, ioniaViewModel],
|
||||
);
|
|
@ -14,9 +14,9 @@ import 'package:cake_wallet/generated/i18n.dart';
|
|||
import 'package:flutter_mobx/flutter_mobx.dart';
|
||||
import 'package:mobx/mobx.dart';
|
||||
|
||||
class LoginPage extends BasePage {
|
||||
class IoniaLoginPage extends BasePage {
|
||||
final IoniaViewModel _ioniaViewModel;
|
||||
LoginPage(this._ioniaViewModel)
|
||||
IoniaLoginPage(this._ioniaViewModel)
|
||||
: _formKey = GlobalKey<FormState>(),
|
||||
_emailFocus = FocusNode(),
|
||||
_emailController = TextEditingController() {
|
||||
|
@ -45,12 +45,12 @@ class LoginPage extends BasePage {
|
|||
|
||||
@override
|
||||
Widget body(BuildContext context) {
|
||||
reaction((_) => _ioniaViewModel.createUserState, (IoniaCreateState state) {
|
||||
reaction((_) => _ioniaViewModel.createUserState, (IoniaCreateAccountState state) {
|
||||
if (state is IoniaCreateStateFailure) {
|
||||
_onLoginUserFailure(context, state.error);
|
||||
}
|
||||
if (state is IoniaCreateStateSuccess) {
|
||||
_onLoginSuccessful(context);
|
||||
_onLoginSuccessful(context, _ioniaViewModel);
|
||||
}
|
||||
});
|
||||
return ScrollableWithBottomSection(
|
||||
|
@ -86,17 +86,6 @@ class LoginPage extends BasePage {
|
|||
SizedBox(
|
||||
height: 20,
|
||||
),
|
||||
InkWell(
|
||||
onTap: () => Navigator.of(context).pushNamed(Routes.cakePayForgotPasswordPage),
|
||||
child: Text(
|
||||
S.of(context).forgot_password,
|
||||
style: TextStyle(
|
||||
color: Palette.blueCraiola,
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.w900,
|
||||
),
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
],
|
||||
|
@ -117,4 +106,8 @@ void _onLoginUserFailure(BuildContext context, String error) {
|
|||
});
|
||||
}
|
||||
|
||||
void _onLoginSuccessful(BuildContext context) => Navigator.pushNamed(context, Routes.verifyIoniaOtpPage);
|
||||
void _onLoginSuccessful(BuildContext context, IoniaViewModel ioniaViewModel) => Navigator.pushNamed(
|
||||
context,
|
||||
Routes.ioniaVerifyIoniaOtpPage,
|
||||
arguments: [ioniaViewModel.email, ioniaViewModel],
|
||||
);
|
|
@ -1,18 +1,24 @@
|
|||
import 'package:cake_wallet/ionia/ionia_create_state.dart';
|
||||
import 'package:cake_wallet/palette.dart';
|
||||
import 'package:cake_wallet/routes.dart';
|
||||
import 'package:cake_wallet/src/screens/base_page.dart';
|
||||
import 'package:cake_wallet/src/widgets/alert_with_one_action.dart';
|
||||
import 'package:cake_wallet/src/widgets/base_text_form_field.dart';
|
||||
import 'package:cake_wallet/src/widgets/primary_button.dart';
|
||||
import 'package:cake_wallet/src/widgets/scollable_with_bottom_section.dart';
|
||||
import 'package:cake_wallet/typography.dart';
|
||||
import 'package:cake_wallet/utils/show_pop_up.dart';
|
||||
import 'package:cake_wallet/view_model/ionia/ionia_view_model.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:cake_wallet/generated/i18n.dart';
|
||||
import 'package:flutter_mobx/flutter_mobx.dart';
|
||||
import 'package:mobx/mobx.dart';
|
||||
|
||||
class VerifyIoniaOtp extends BasePage {
|
||||
class IoniaVerifyIoniaOtp extends BasePage {
|
||||
final IoniaViewModel _ioniaViewModel;
|
||||
final String _email;
|
||||
|
||||
VerifyIoniaOtp(this._ioniaViewModel)
|
||||
IoniaVerifyIoniaOtp(this._ioniaViewModel, this._email)
|
||||
: _codeController = TextEditingController(),
|
||||
_codeFocus = FocusNode() {
|
||||
_codeController.addListener(() {
|
||||
|
@ -43,6 +49,14 @@ class VerifyIoniaOtp extends BasePage {
|
|||
|
||||
@override
|
||||
Widget body(BuildContext context) {
|
||||
reaction((_) => _ioniaViewModel.otpState, (IoniaOtpState state) {
|
||||
if (state is IoniaOtpFailure) {
|
||||
_onOtpFailure(context, state.error);
|
||||
}
|
||||
if (state is IoniaOtpSuccess) {
|
||||
_onOtpSuccessful(context);
|
||||
}
|
||||
});
|
||||
return ScrollableWithBottomSection(
|
||||
contentPadding: EdgeInsets.all(24),
|
||||
content: Column(
|
||||
|
@ -63,12 +77,11 @@ class VerifyIoniaOtp extends BasePage {
|
|||
children: [
|
||||
Text(S.of(context).dont_get_code),
|
||||
SizedBox(width: 20),
|
||||
Text(
|
||||
S.of(context).resend_code,
|
||||
style: TextStyle(
|
||||
color: Palette.blueCraiola,
|
||||
fontSize: 14,
|
||||
fontWeight: FontWeight.w400,
|
||||
InkWell(
|
||||
onTap: () => _ioniaViewModel.createUser(_email),
|
||||
child: Text(
|
||||
S.of(context).resend_code,
|
||||
style: textSmallSemiBold(color: Palette.blueCraiola),
|
||||
),
|
||||
),
|
||||
],
|
||||
|
@ -91,9 +104,7 @@ class VerifyIoniaOtp extends BasePage {
|
|||
textColor: Colors.white,
|
||||
),
|
||||
),
|
||||
SizedBox(
|
||||
height: 20,
|
||||
),
|
||||
SizedBox(height: 20),
|
||||
],
|
||||
),
|
||||
],
|
||||
|
@ -101,3 +112,18 @@ class VerifyIoniaOtp extends BasePage {
|
|||
);
|
||||
}
|
||||
}
|
||||
|
||||
void _onOtpFailure(BuildContext context, String error) {
|
||||
showPopUp<void>(
|
||||
context: context,
|
||||
builder: (BuildContext context) {
|
||||
return AlertWithOneAction(
|
||||
alertTitle: S.current.verification,
|
||||
alertContent: error,
|
||||
buttonText: S.of(context).ok,
|
||||
buttonAction: () => Navigator.of(context).pop());
|
||||
});
|
||||
}
|
||||
|
||||
void _onOtpSuccessful(BuildContext context) =>
|
||||
Navigator.pushNamedAndRemoveUntil(context, Routes.ioniaManageCardsPage, ModalRoute.withName(Routes.dashboard));
|
|
@ -8,10 +8,10 @@ import 'package:flutter/src/widgets/framework.dart';
|
|||
import 'package:cake_wallet/generated/i18n.dart';
|
||||
import 'package:mobx/mobx.dart';
|
||||
|
||||
class WelcomePage extends BasePage {
|
||||
class IoniaWelcomePage extends BasePage {
|
||||
final IoniaViewModel _ioniaViewModel;
|
||||
|
||||
WelcomePage(this._ioniaViewModel);
|
||||
IoniaWelcomePage(this._ioniaViewModel);
|
||||
|
||||
@override
|
||||
Color get titleColor => Colors.black;
|
||||
|
@ -32,7 +32,7 @@ class WelcomePage extends BasePage {
|
|||
Widget body(BuildContext context) {
|
||||
reaction((_) => _ioniaViewModel.isLoggedIn, (bool state) {
|
||||
if (state) {
|
||||
// TODO:: Navigate to main page
|
||||
Navigator.pushReplacementNamed(context, Routes.ioniaDebitCardPage);
|
||||
}
|
||||
});
|
||||
return Padding(
|
||||
|
@ -69,7 +69,7 @@ class WelcomePage extends BasePage {
|
|||
children: <Widget>[
|
||||
PrimaryButton(
|
||||
text: S.of(context).create_account,
|
||||
onPressed: () => Navigator.of(context).pushNamed(Routes.cakePayCreateAccountPage),
|
||||
onPressed: () => Navigator.of(context).pushNamed(Routes.ioniaCreateAccountPage),
|
||||
color: Theme.of(context).accentTextTheme.body2.color,
|
||||
textColor: Colors.white,
|
||||
),
|
||||
|
@ -87,7 +87,7 @@ class WelcomePage extends BasePage {
|
|||
),
|
||||
SizedBox(height: 8),
|
||||
InkWell(
|
||||
onTap: () => Navigator.of(context).pushNamed(Routes.cakePayLoginPage),
|
||||
onTap: () => Navigator.of(context).pushNamed(Routes.ioniaLoginPage),
|
||||
child: Text(
|
||||
S.of(context).login,
|
||||
style: TextStyle(
|
114
lib/src/screens/ionia/cards/ionia_activate_debit_card_page.dart
Normal file
114
lib/src/screens/ionia/cards/ionia_activate_debit_card_page.dart
Normal file
|
@ -0,0 +1,114 @@
|
|||
import 'package:cake_wallet/ionia/ionia_create_state.dart';
|
||||
import 'package:cake_wallet/routes.dart';
|
||||
import 'package:cake_wallet/src/screens/base_page.dart';
|
||||
import 'package:cake_wallet/src/screens/ionia/widgets/text_icon_button.dart';
|
||||
import 'package:cake_wallet/src/widgets/alert_with_one_action.dart';
|
||||
import 'package:cake_wallet/src/widgets/primary_button.dart';
|
||||
import 'package:cake_wallet/src/widgets/scollable_with_bottom_section.dart';
|
||||
import 'package:cake_wallet/utils/show_pop_up.dart';
|
||||
import 'package:cake_wallet/view_model/ionia/ionia_view_model.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:cake_wallet/generated/i18n.dart';
|
||||
import 'package:mobx/mobx.dart';
|
||||
|
||||
class IoniaActivateDebitCardPage extends BasePage {
|
||||
final IoniaViewModel _ioniaViewModel;
|
||||
|
||||
IoniaActivateDebitCardPage(this._ioniaViewModel);
|
||||
|
||||
@override
|
||||
Widget middle(BuildContext context) {
|
||||
return Text(
|
||||
S.current.debit_card,
|
||||
style: TextStyle(
|
||||
fontSize: 22,
|
||||
fontFamily: 'Lato',
|
||||
fontWeight: FontWeight.w900,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
Widget body(BuildContext context) {
|
||||
reaction((_) => _ioniaViewModel.createCardState, (IoniaCreateCardState state) {
|
||||
if (state is IoniaCreateCardFailure) {
|
||||
_onCreateCardFailure(context, state.error);
|
||||
}
|
||||
if (state is IoniaCreateCardSuccess) {
|
||||
_onCreateCardSuccess(context);
|
||||
}
|
||||
});
|
||||
return ScrollableWithBottomSection(
|
||||
contentPadding: EdgeInsets.zero,
|
||||
content: Padding(
|
||||
padding: const EdgeInsets.all(16.0),
|
||||
child: Column(
|
||||
children: [
|
||||
SizedBox(height: 16),
|
||||
Text(S.of(context).debit_card_terms),
|
||||
SizedBox(height: 24),
|
||||
Text(S.of(context).please_reference_document),
|
||||
SizedBox(height: 40),
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 8.0),
|
||||
child: Column(
|
||||
children: [
|
||||
TextIconButton(
|
||||
label: S.current.cardholder_agreement,
|
||||
onTap: () {},
|
||||
),
|
||||
SizedBox(
|
||||
height: 24,
|
||||
),
|
||||
TextIconButton(
|
||||
label: S.current.e_sign_consent,
|
||||
onTap: () {},
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
bottomSection: LoadingPrimaryButton(
|
||||
onPressed: () {
|
||||
_ioniaViewModel.createCard();
|
||||
},
|
||||
isLoading: _ioniaViewModel.createCardState is IoniaCreateCardLoading,
|
||||
text: S.of(context).agree_and_continue,
|
||||
color: Theme.of(context).accentTextTheme.body2.color,
|
||||
textColor: Colors.white,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
void _onCreateCardFailure(BuildContext context, String errorMessage) {
|
||||
showPopUp<void>(
|
||||
context: context,
|
||||
builder: (BuildContext context) {
|
||||
return AlertWithOneAction(
|
||||
alertTitle: S.current.error,
|
||||
alertContent: errorMessage,
|
||||
buttonText: S.of(context).ok,
|
||||
buttonAction: () => Navigator.of(context).pop());
|
||||
});
|
||||
}
|
||||
|
||||
void _onCreateCardSuccess(BuildContext context) {
|
||||
Navigator.pushNamed(
|
||||
context,
|
||||
Routes.ioniaDebitCardPage,
|
||||
);
|
||||
showPopUp<void>(
|
||||
context: context,
|
||||
builder: (BuildContext context) {
|
||||
return AlertWithOneAction(
|
||||
alertTitle: 'Congratulations!',
|
||||
alertContent: 'You now have a debit card',
|
||||
buttonText: S.of(context).ok,
|
||||
buttonAction: () => Navigator.of(context).pop(),
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
|
@ -1,6 +1,7 @@
|
|||
import 'package:cake_wallet/di.dart';
|
||||
import 'package:cake_wallet/palette.dart';
|
||||
import 'package:cake_wallet/routes.dart';
|
||||
import 'package:cake_wallet/src/screens/ionia/widgets/text_icon_button.dart';
|
||||
import 'package:cake_wallet/src/widgets/alert_with_two_actions.dart';
|
||||
import 'package:cake_wallet/src/widgets/discount_badge.dart';
|
||||
import 'package:cake_wallet/src/widgets/primary_button.dart';
|
||||
|
@ -13,7 +14,7 @@ import 'package:flutter/material.dart';
|
|||
import 'package:flutter/src/widgets/framework.dart';
|
||||
import 'package:cake_wallet/generated/i18n.dart';
|
||||
|
||||
class BuyGiftCardDetailPage extends StatelessWidget {
|
||||
class IoniaBuyGiftCardDetailPage extends StatelessWidget {
|
||||
ThemeBase get currentTheme => getIt.get<SettingsStore>().currentTheme;
|
||||
|
||||
Color get backgroundLightColor => Colors.white;
|
||||
|
@ -175,24 +176,11 @@ class BuyGiftCardDetailPage extends StatelessWidget {
|
|||
SizedBox(height: 20),
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 24.0),
|
||||
child: InkWell(
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Text(
|
||||
S.of(context).how_to_use_card,
|
||||
style: textMediumSemiBold(
|
||||
color: Theme.of(context).primaryTextTheme.title.color,
|
||||
),
|
||||
),
|
||||
Icon(
|
||||
Icons.chevron_right_rounded,
|
||||
color: Theme.of(context).primaryTextTheme.title.color,
|
||||
),
|
||||
],
|
||||
),
|
||||
child: TextIconButton(
|
||||
label: S.of(context).how_to_use_card,
|
||||
onTap: () {},
|
||||
),
|
||||
)
|
||||
),
|
||||
],
|
||||
),
|
||||
bottomSection: Column(
|
||||
|
@ -308,7 +296,7 @@ class TipButton extends StatelessWidget {
|
|||
SizedBox(height: 4),
|
||||
Text(
|
||||
subTitle,
|
||||
style: textXSmallSemiBold(color: Palette.gray),
|
||||
style: textXxSmallSemiBold(color: Palette.gray),
|
||||
),
|
||||
]
|
||||
],
|
|
@ -11,8 +11,8 @@ import 'package:flutter/services.dart';
|
|||
import 'package:keyboard_actions/keyboard_actions.dart';
|
||||
import 'package:cake_wallet/generated/i18n.dart';
|
||||
|
||||
class BuyGiftCardPage extends BasePage {
|
||||
BuyGiftCardPage()
|
||||
class IoniaBuyGiftCardPage extends BasePage {
|
||||
IoniaBuyGiftCardPage()
|
||||
: _amountFieldFocus = FocusNode(),
|
||||
_amountController = TextEditingController();
|
||||
@override
|
||||
|
@ -143,14 +143,13 @@ class BuyGiftCardPage extends BasePage {
|
|||
Padding(
|
||||
padding: EdgeInsets.only(bottom: 12),
|
||||
child: PrimaryButton(
|
||||
onPressed: () =>Navigator.of(context).pushNamed(Routes.buyGiftCardDetailPage),
|
||||
onPressed: () => Navigator.of(context).pushNamed(Routes.ioniaBuyGiftCardDetailPage),
|
||||
text: S.of(context).continue_text,
|
||||
color: Theme.of(context).accentTextTheme.body2.color,
|
||||
textColor: Colors.white,
|
||||
),
|
||||
),
|
||||
SizedBox(height: 20),
|
||||
SizedBox(height: 10)
|
||||
SizedBox(height: 30),
|
||||
],
|
||||
),
|
||||
),
|
382
lib/src/screens/ionia/cards/ionia_debit_card_page.dart
Normal file
382
lib/src/screens/ionia/cards/ionia_debit_card_page.dart
Normal file
|
@ -0,0 +1,382 @@
|
|||
import 'package:cake_wallet/ionia/ionia_create_state.dart';
|
||||
import 'package:cake_wallet/ionia/ionia_virtual_card.dart';
|
||||
import 'package:cake_wallet/routes.dart';
|
||||
import 'package:cake_wallet/src/screens/base_page.dart';
|
||||
import 'package:cake_wallet/src/screens/ionia/widgets/text_icon_button.dart';
|
||||
import 'package:cake_wallet/src/widgets/alert_background.dart';
|
||||
import 'package:cake_wallet/src/widgets/primary_button.dart';
|
||||
import 'package:cake_wallet/src/widgets/scollable_with_bottom_section.dart';
|
||||
import 'package:cake_wallet/typography.dart';
|
||||
import 'package:cake_wallet/utils/show_pop_up.dart';
|
||||
import 'package:cake_wallet/view_model/ionia/ionia_view_model.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:cake_wallet/generated/i18n.dart';
|
||||
import 'package:flutter_mobx/flutter_mobx.dart';
|
||||
|
||||
class IoniaDebitCardPage extends BasePage {
|
||||
final IoniaViewModel _ioniaViewModel;
|
||||
|
||||
IoniaDebitCardPage(this._ioniaViewModel);
|
||||
|
||||
@override
|
||||
Widget middle(BuildContext context) {
|
||||
return Text(
|
||||
S.current.debit_card,
|
||||
style: TextStyle(
|
||||
fontSize: 22,
|
||||
fontFamily: 'Lato',
|
||||
fontWeight: FontWeight.w900,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
Widget body(BuildContext context) {
|
||||
return Observer(
|
||||
builder: (_) {
|
||||
final cardState = _ioniaViewModel.cardState;
|
||||
if (cardState is IoniaFetchingCard) {
|
||||
return Center(child: CircularProgressIndicator());
|
||||
}
|
||||
if (cardState is IoniaCardSuccess) {
|
||||
return ScrollableWithBottomSection(
|
||||
contentPadding: EdgeInsets.zero,
|
||||
content: Padding(
|
||||
padding: const EdgeInsets.all(16.0),
|
||||
child: Column(
|
||||
children: [
|
||||
_IoniaDebitCard(
|
||||
cardInfo: cardState.card,
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
bottomSection: Column(
|
||||
children: [
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 20.0),
|
||||
child: Text(
|
||||
'If asked for a billing address, provide your shipping address',
|
||||
style: textSmall(color: Theme.of(context).textTheme.display1.color),
|
||||
textAlign: TextAlign.center,
|
||||
),
|
||||
),
|
||||
SizedBox(height: 24),
|
||||
PrimaryButton(
|
||||
text: 'Order Physical Card',
|
||||
onPressed: () {},
|
||||
color: Color(0xffE9F2FC),
|
||||
textColor: Theme.of(context).textTheme.display2.color,
|
||||
),
|
||||
SizedBox(height: 8),
|
||||
PrimaryButton(
|
||||
text: 'Add Value',
|
||||
onPressed: () {},
|
||||
color: Theme.of(context).accentTextTheme.body2.color,
|
||||
textColor: Colors.white,
|
||||
),
|
||||
SizedBox(height: 16)
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
return ScrollableWithBottomSection(
|
||||
contentPadding: EdgeInsets.zero,
|
||||
content: Padding(
|
||||
padding: const EdgeInsets.all(16.0),
|
||||
child: Column(
|
||||
children: [
|
||||
_IoniaDebitCard(isCardSample: true),
|
||||
SizedBox(height: 40),
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 8.0),
|
||||
child: Column(
|
||||
children: [
|
||||
TextIconButton(
|
||||
label: S.current.how_to_use_card,
|
||||
onTap: () => _showHowToUseCard(context),
|
||||
),
|
||||
SizedBox(
|
||||
height: 24,
|
||||
),
|
||||
TextIconButton(
|
||||
label: S.current.frequently_asked_questions,
|
||||
onTap: () {},
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
SizedBox(height: 50),
|
||||
Container(
|
||||
padding: EdgeInsets.all(20),
|
||||
margin: EdgeInsets.all(8),
|
||||
width: double.infinity,
|
||||
decoration: BoxDecoration(
|
||||
color: Color.fromRGBO(233, 242, 252, 1),
|
||||
borderRadius: BorderRadius.circular(20),
|
||||
),
|
||||
child: RichText(
|
||||
text: TextSpan(
|
||||
text: 'Get a',
|
||||
style: textMedium(color: Theme.of(context).textTheme.display2.color),
|
||||
children: [
|
||||
TextSpan(
|
||||
text: ' digital and physical prepaid debit card',
|
||||
style: textMediumBold(color: Theme.of(context).textTheme.display2.color),
|
||||
),
|
||||
TextSpan(
|
||||
text: ' that you can reload with digital currencies. No additional information needed!')
|
||||
])),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
bottomSectionPadding: EdgeInsets.symmetric(
|
||||
horizontal: 16,
|
||||
vertical: 32,
|
||||
),
|
||||
bottomSection: PrimaryButton(
|
||||
text: 'Activate',
|
||||
onPressed: () => _showHowToUseCard(context, activate: true),
|
||||
color: Theme.of(context).accentTextTheme.body2.color,
|
||||
textColor: Colors.white,
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
void _showHowToUseCard(BuildContext context, {bool activate = false}) {
|
||||
showPopUp<void>(
|
||||
context: context,
|
||||
builder: (BuildContext context) {
|
||||
return AlertBackground(
|
||||
child: Material(
|
||||
color: Colors.transparent,
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
SizedBox(height: 10),
|
||||
Container(
|
||||
padding: EdgeInsets.only(top: 24, left: 24, right: 24),
|
||||
margin: EdgeInsets.all(24),
|
||||
decoration: BoxDecoration(
|
||||
color: Theme.of(context).backgroundColor,
|
||||
borderRadius: BorderRadius.circular(30),
|
||||
),
|
||||
child: Column(
|
||||
children: [
|
||||
Text(
|
||||
'How to use this card',
|
||||
style: textLargeSemiBold(
|
||||
color: Theme.of(context).textTheme.body1.color,
|
||||
),
|
||||
),
|
||||
SizedBox(height: 24),
|
||||
Align(
|
||||
alignment: Alignment.bottomLeft,
|
||||
child: Text(
|
||||
'Sign up for the card and accept the terms.',
|
||||
style: textSmallSemiBold(
|
||||
color: Theme.of(context).textTheme.display2.color,
|
||||
),
|
||||
),
|
||||
),
|
||||
SizedBox(height: 24),
|
||||
_TitleSubtitleTile(
|
||||
title: 'Add prepaid funds to the cards (up to \$1000)',
|
||||
subtitle:
|
||||
'Funds are converted to USD when the held in the prepaid account, not in digital currencies.',
|
||||
),
|
||||
SizedBox(height: 21),
|
||||
_TitleSubtitleTile(
|
||||
title: 'Use the digital card online or with contactless payment methods.',
|
||||
subtitle: 'Optionally order a physical card.',
|
||||
),
|
||||
SizedBox(height: 35),
|
||||
PrimaryButton(
|
||||
onPressed: () => activate
|
||||
? Navigator.pushNamed(context, Routes.ioniaActivateDebitCardPage)
|
||||
: Navigator.pop(context),
|
||||
text: 'Got it!',
|
||||
color: Color.fromRGBO(233, 242, 252, 1),
|
||||
textColor: Theme.of(context).textTheme.display2.color,
|
||||
),
|
||||
SizedBox(height: 21),
|
||||
],
|
||||
),
|
||||
),
|
||||
InkWell(
|
||||
onTap: () => Navigator.pop(context),
|
||||
child: Container(
|
||||
margin: EdgeInsets.only(bottom: 40),
|
||||
child: CircleAvatar(
|
||||
child: Icon(
|
||||
Icons.close,
|
||||
color: Colors.black,
|
||||
),
|
||||
backgroundColor: Colors.white,
|
||||
),
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
class _IoniaDebitCard extends StatefulWidget {
|
||||
final bool isCardSample;
|
||||
final IoniaVirtualCard cardInfo;
|
||||
const _IoniaDebitCard({
|
||||
Key key,
|
||||
this.isCardSample = false,
|
||||
this.cardInfo,
|
||||
}) : super(key: key);
|
||||
|
||||
@override
|
||||
_IoniaDebitCardState createState() => _IoniaDebitCardState();
|
||||
}
|
||||
|
||||
class _IoniaDebitCardState extends State<_IoniaDebitCard> {
|
||||
bool _showDetails = false;
|
||||
void _toggleVisibility() {
|
||||
setState(() => _showDetails = !_showDetails);
|
||||
}
|
||||
|
||||
String _formatPan(String pan) {
|
||||
if (pan == null) return '';
|
||||
return pan.replaceAllMapped(RegExp(r'.{4}'), (match) => '${match.group(0)} ');
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final last4 = widget.isCardSample ? '0000' : widget.cardInfo.pan.substring(widget.cardInfo.pan.length - 5);
|
||||
final spendLimit = widget.isCardSample ? '10000' : widget.cardInfo.spendLimit.toStringAsFixed(2);
|
||||
return Container(
|
||||
padding: EdgeInsets.symmetric(horizontal: 24, vertical: 19),
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(24),
|
||||
gradient: LinearGradient(
|
||||
colors: [
|
||||
Theme.of(context).primaryTextTheme.subhead.color,
|
||||
Theme.of(context).primaryTextTheme.subhead.decorationColor,
|
||||
],
|
||||
begin: Alignment.topLeft,
|
||||
end: Alignment.bottomRight,
|
||||
),
|
||||
),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
SizedBox(height: 16),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Text(
|
||||
S.current.cakepay_prepaid_card,
|
||||
style: textSmall(),
|
||||
),
|
||||
Image.asset(
|
||||
'assets/images/mastercard.png',
|
||||
width: 54,
|
||||
),
|
||||
],
|
||||
),
|
||||
Text(
|
||||
widget.isCardSample ? 'up to \$$spendLimit' : '\$$spendLimit',
|
||||
style: textXLargeSemiBold(),
|
||||
),
|
||||
SizedBox(height: 16),
|
||||
Text(
|
||||
_showDetails ? _formatPan(widget.cardInfo.pan) : '**** **** **** $last4',
|
||||
style: textMediumSemiBold(),
|
||||
),
|
||||
SizedBox(height: 32),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
if (widget.isCardSample)
|
||||
Text(
|
||||
S.current.no_id_needed,
|
||||
style: textMediumBold(),
|
||||
)
|
||||
else ...[
|
||||
Column(
|
||||
children: [
|
||||
Text(
|
||||
'CVV',
|
||||
style: textXSmallSemiBold(),
|
||||
),
|
||||
SizedBox(height: 4),
|
||||
Text(
|
||||
_showDetails ? widget.cardInfo.cvv : '***',
|
||||
style: textMediumSemiBold(),
|
||||
)
|
||||
],
|
||||
),
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
'Expires',
|
||||
style: textXSmallSemiBold(),
|
||||
),
|
||||
SizedBox(height: 4),
|
||||
Text(
|
||||
'${widget.cardInfo.expirationMonth ?? 'MM'}/${widget.cardInfo.expirationYear ?? 'YY'}',
|
||||
style: textMediumSemiBold(),
|
||||
)
|
||||
],
|
||||
),
|
||||
]
|
||||
],
|
||||
),
|
||||
if (!widget.isCardSample) ...[
|
||||
SizedBox(height: 8),
|
||||
Center(
|
||||
child: InkWell(
|
||||
onTap: () => _toggleVisibility(),
|
||||
child: Text(
|
||||
_showDetails ? 'Hide Details' : 'Show Details',
|
||||
style: textSmall(),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class _TitleSubtitleTile extends StatelessWidget {
|
||||
final String title;
|
||||
final String subtitle;
|
||||
const _TitleSubtitleTile({
|
||||
Key key,
|
||||
@required this.title,
|
||||
@required this.subtitle,
|
||||
}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
title,
|
||||
style: textSmallSemiBold(color: Theme.of(context).textTheme.display2.color),
|
||||
),
|
||||
SizedBox(height: 4),
|
||||
Text(
|
||||
subtitle,
|
||||
style: textSmall(color: Theme.of(context).textTheme.display2.color),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
|
@ -1,13 +1,18 @@
|
|||
import 'package:cake_wallet/routes.dart';
|
||||
import 'package:cake_wallet/src/screens/base_page.dart';
|
||||
import 'package:cake_wallet/src/screens/cake_pay/widgets/card_menu.dart';
|
||||
import 'package:cake_wallet/src/screens/ionia/widgets/card_menu.dart';
|
||||
import 'package:cake_wallet/src/widgets/market_place_item.dart';
|
||||
import 'package:cake_wallet/themes/theme_base.dart';
|
||||
import 'package:cake_wallet/view_model/ionia/ionia_view_model.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:cake_wallet/generated/i18n.dart';
|
||||
|
||||
class ManageCardsPage extends BasePage {
|
||||
class IoniaManageCardsPage extends BasePage {
|
||||
final IoniaViewModel _ioniaViewModel;
|
||||
|
||||
IoniaManageCardsPage(this._ioniaViewModel);
|
||||
|
||||
@override
|
||||
Color get backgroundLightColor => currentTheme.type == ThemeType.bright ? Colors.transparent : Colors.white;
|
||||
|
||||
|
@ -39,6 +44,29 @@ class ManageCardsPage extends BasePage {
|
|||
@override
|
||||
Widget get endDrawer => CardMenu();
|
||||
|
||||
@override
|
||||
Widget leading(BuildContext context) {
|
||||
final _backButton = Icon(
|
||||
Icons.arrow_back_ios,
|
||||
color: titleColor ?? Theme.of(context).primaryTextTheme.title.color,
|
||||
size: 16,
|
||||
);
|
||||
|
||||
return SizedBox(
|
||||
height: 37,
|
||||
width: 37,
|
||||
child: ButtonTheme(
|
||||
minWidth: double.minPositive,
|
||||
child: FlatButton(
|
||||
highlightColor: Colors.transparent,
|
||||
splashColor: Colors.transparent,
|
||||
padding: EdgeInsets.all(0),
|
||||
onPressed: () => Navigator.pushReplacementNamed(context, Routes.dashboard),
|
||||
child: _backButton),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
Widget middle(BuildContext context) {
|
||||
return Text(
|
||||
|
@ -60,7 +88,7 @@ class ManageCardsPage extends BasePage {
|
|||
children: [
|
||||
_TrailingIcon(
|
||||
asset: 'assets/images/card.png',
|
||||
onPressed: () {},
|
||||
onPressed: () => Navigator.pushNamed(context, Routes.ioniaDebitCardPage),
|
||||
),
|
||||
SizedBox(width: 16),
|
||||
_TrailingIcon(
|
||||
|
@ -127,7 +155,7 @@ class ManageCardsPage extends BasePage {
|
|||
return MarketPlaceItem(
|
||||
padding: EdgeInsets.symmetric(horizontal: 12, vertical: 12),
|
||||
logoUrl: '',
|
||||
onTap: ()=>Navigator.of(context).pushNamed(Routes.buyGiftCardPage),
|
||||
onTap: () => Navigator.of(context).pushNamed(Routes.ioniaBuyGiftCardPage),
|
||||
title: 'Amazon',
|
||||
subTitle: 'Onlin',
|
||||
hasDiscount: true,
|
9
lib/src/screens/ionia/ionia.dart
Normal file
9
lib/src/screens/ionia/ionia.dart
Normal file
|
@ -0,0 +1,9 @@
|
|||
export 'auth/ionia_welcome_page.dart';
|
||||
export 'auth/ionia_create_account_page.dart';
|
||||
export 'auth/ionia_login_page.dart';
|
||||
export 'auth/ionia_verify_otp_page.dart';
|
||||
export 'cards/ionia_activate_debit_card_page.dart';
|
||||
export 'cards/ionia_buy_card_detail_page.dart';
|
||||
export 'cards/ionia_manage_cards_page.dart';
|
||||
export 'cards/ionia_debit_card_page.dart';
|
||||
export 'cards/ionia_buy_gift_card.dart';
|
35
lib/src/screens/ionia/widgets/text_icon_button.dart
Normal file
35
lib/src/screens/ionia/widgets/text_icon_button.dart
Normal file
|
@ -0,0 +1,35 @@
|
|||
import 'package:cake_wallet/typography.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class TextIconButton extends StatelessWidget {
|
||||
final String label;
|
||||
final VoidCallback onTap;
|
||||
const TextIconButton({
|
||||
Key key,
|
||||
this.label,
|
||||
this.onTap,
|
||||
}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return
|
||||
InkWell(
|
||||
onTap: onTap,
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Text(
|
||||
label,
|
||||
style: textMediumSemiBold(
|
||||
color: Theme.of(context).primaryTextTheme.title.color,
|
||||
),
|
||||
),
|
||||
Icon(
|
||||
Icons.chevron_right_rounded,
|
||||
color: Theme.of(context).primaryTextTheme.title.color,
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
|
@ -2,9 +2,13 @@ import 'package:flutter/material.dart';
|
|||
|
||||
const latoFont = "Lato";
|
||||
|
||||
TextStyle textXSmall({Color color}) => _cakeRegular(10, color);
|
||||
TextStyle textXxSmall({Color color}) => _cakeRegular(10, color);
|
||||
|
||||
TextStyle textXSmallSemiBold({Color color}) => _cakeSemiBold(10, color);
|
||||
TextStyle textXxSmallSemiBold({Color color}) => _cakeSemiBold(10, color);
|
||||
|
||||
TextStyle textXSmall({Color color}) => _cakeRegular(12, color);
|
||||
|
||||
TextStyle textXSmallSemiBold({Color color}) => _cakeSemiBold(12, color);
|
||||
|
||||
TextStyle textSmall({Color color}) => _cakeRegular(14, color);
|
||||
|
||||
|
@ -12,6 +16,8 @@ TextStyle textSmallSemiBold({Color color}) => _cakeSemiBold(14, color);
|
|||
|
||||
TextStyle textMedium({Color color}) => _cakeRegular(16, color);
|
||||
|
||||
TextStyle textMediumBold({Color color}) => _cakeBold(16, color);
|
||||
|
||||
TextStyle textMediumSemiBold({Color color}) => _cakeSemiBold(22, color);
|
||||
|
||||
TextStyle textLarge({Color color}) => _cakeRegular(18, color);
|
||||
|
@ -28,6 +34,12 @@ TextStyle _cakeRegular(double size, Color color) => _textStyle(
|
|||
color: color,
|
||||
);
|
||||
|
||||
TextStyle _cakeBold(double size, Color color) => _textStyle(
|
||||
size: size,
|
||||
fontWeight: FontWeight.w900,
|
||||
color: color,
|
||||
);
|
||||
|
||||
TextStyle _cakeSemiBold(double size, Color color) => _textStyle(
|
||||
size: size,
|
||||
fontWeight: FontWeight.w700,
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import 'package:cake_wallet/ionia/ionia.dart';
|
||||
import 'package:cake_wallet/ionia/ionia_create_state.dart';
|
||||
import 'package:cake_wallet/ionia/ionia_virtual_card.dart';
|
||||
import 'package:mobx/mobx.dart';
|
||||
part 'ionia_view_model.g.dart';
|
||||
|
||||
|
@ -8,18 +9,25 @@ class IoniaViewModel = IoniaViewModelBase with _$IoniaViewModel;
|
|||
abstract class IoniaViewModelBase with Store {
|
||||
IoniaViewModelBase({this.ioniaService})
|
||||
: createUserState = IoniaCreateStateSuccess(),
|
||||
otpState = IoniaOtpSendDisabled() {
|
||||
otpState = IoniaOtpSendDisabled(), cardState = IoniaNoCardState() {
|
||||
_getCard();
|
||||
_getAuthStatus().then((value) => isLoggedIn = value);
|
||||
}
|
||||
|
||||
final IoniaService ioniaService;
|
||||
|
||||
@observable
|
||||
IoniaCreateState createUserState;
|
||||
IoniaCreateAccountState createUserState;
|
||||
|
||||
@observable
|
||||
IoniaOtpState otpState;
|
||||
|
||||
@observable
|
||||
IoniaCreateCardState createCardState;
|
||||
|
||||
@observable
|
||||
IoniaFetchCardState cardState;
|
||||
|
||||
@observable
|
||||
String email;
|
||||
|
||||
|
@ -55,4 +63,31 @@ abstract class IoniaViewModelBase with Store {
|
|||
Future<bool> _getAuthStatus() async {
|
||||
return await ioniaService.isLogined();
|
||||
}
|
||||
|
||||
@action
|
||||
Future<IoniaVirtualCard> createCard() async {
|
||||
createCardState = IoniaCreateCardLoading();
|
||||
try {
|
||||
final card = await ioniaService.createCard();
|
||||
createCardState = IoniaCreateCardSuccess();
|
||||
return card;
|
||||
} catch (e) {
|
||||
final error = e as Exception;
|
||||
createCardState = IoniaCreateCardFailure(error: error.toString());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
Future<void> _getCard() async {
|
||||
|
||||
cardState = IoniaFetchingCard();
|
||||
try {
|
||||
final card = await ioniaService.getCard();
|
||||
|
||||
cardState = IoniaCardSuccess(card: card);
|
||||
|
||||
} catch (_) {
|
||||
cardState = IoniaFetchCardFailure();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -51,6 +51,7 @@ dependencies:
|
|||
flushbar: ^1.10.4
|
||||
archive: ^2.0.13
|
||||
cryptography: ^1.4.0
|
||||
cached_network_image: ^2.0.0
|
||||
file_picker: ^3.0.0-nullsafety.2
|
||||
unorm_dart: ^0.2.0
|
||||
permission_handler: ^5.0.1+1
|
||||
|
|
|
@ -551,5 +551,14 @@
|
|||
"verification": "Verification",
|
||||
"fill_code": "Please fill in the verification code provided to your email",
|
||||
"dont_get_code": "Don't get code",
|
||||
"resend_code": "Please resend it"
|
||||
"resend_code": "Please resend it",
|
||||
"debit_card": "Debit Card",
|
||||
"cakepay_prepaid_card": "CakePay Prepaid Debit Card",
|
||||
"no_id_needed": "No ID needed!",
|
||||
"frequently_asked_questions": "Frequently asked questions",
|
||||
"debit_card_terms": "The storage and usage of your payment card number (and credentials corresponding to your payment card number) in this digital wallet are subject to the Terms and Conditions of the applicable cardholder agreement with the payment card issuer, as in effect from time to time.",
|
||||
"please_reference_document": "Please reference the documents below for more information.",
|
||||
"cardholder_agreement": "Cardholder Agreement",
|
||||
"e_sign_consent": "E-Sign Consent",
|
||||
"agree_and_continue": "Agree & Continue"
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue