CW-148 cake pay partial redemptions (#490)
* Ionia custom redemption screen * update ionia gift card remaining amount with custom value * [NO-TASK] Fix issues with custom redeem * replace redeem * update remaining amount * fixed from code review * Add localizationwow-support
parent
0aee6e1b8d
commit
bd25d047b2
@ -0,0 +1,167 @@
|
||||
import 'package:cake_wallet/src/screens/base_page.dart';
|
||||
import 'package:cake_wallet/src/screens/ionia/widgets/card_item.dart';
|
||||
import 'package:cake_wallet/src/widgets/base_text_form_field.dart';
|
||||
import 'package:cake_wallet/src/widgets/keyboard_done_button.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/themes/theme_base.dart';
|
||||
import 'package:cake_wallet/view_model/ionia/ionia_custom_redeem_view_model.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:flutter_mobx/flutter_mobx.dart';
|
||||
import 'package:keyboard_actions/keyboard_actions.dart';
|
||||
import 'package:cake_wallet/generated/i18n.dart';
|
||||
|
||||
class IoniaCustomRedeemPage extends BasePage {
|
||||
IoniaCustomRedeemPage(
|
||||
this.ioniaCustomRedeemViewModel,
|
||||
) : _amountFieldFocus = FocusNode(),
|
||||
_amountController = TextEditingController() {
|
||||
_amountController.addListener(() {
|
||||
ioniaCustomRedeemViewModel.updateAmount(_amountController.text);
|
||||
});
|
||||
}
|
||||
|
||||
final IoniaCustomRedeemViewModel ioniaCustomRedeemViewModel;
|
||||
|
||||
|
||||
@override
|
||||
String get title => S.current.custom_redeem_amount;
|
||||
|
||||
@override
|
||||
Color get titleColor => Colors.white;
|
||||
|
||||
@override
|
||||
bool get extendBodyBehindAppBar => true;
|
||||
|
||||
@override
|
||||
AppBarStyle get appBarStyle => AppBarStyle.transparent;
|
||||
|
||||
Color get textColor => currentTheme.type == ThemeType.dark ? Colors.white : Color(0xff393939);
|
||||
|
||||
final TextEditingController _amountController;
|
||||
final FocusNode _amountFieldFocus;
|
||||
|
||||
@override
|
||||
Widget body(BuildContext context) {
|
||||
final _width = MediaQuery.of(context).size.width;
|
||||
final giftCard = ioniaCustomRedeemViewModel.giftCard;
|
||||
return KeyboardActions(
|
||||
disableScroll: true,
|
||||
config: KeyboardActionsConfig(
|
||||
keyboardActionsPlatform: KeyboardActionsPlatform.IOS,
|
||||
keyboardBarColor: Theme.of(context).accentTextTheme.body2.backgroundColor,
|
||||
nextFocus: false,
|
||||
actions: [
|
||||
KeyboardActionsItem(
|
||||
focusNode: _amountFieldFocus,
|
||||
toolbarButtons: [(_) => KeyboardDoneButton()],
|
||||
),
|
||||
]),
|
||||
child: Container(
|
||||
color: Theme.of(context).backgroundColor,
|
||||
child: ScrollableWithBottomSection(
|
||||
contentPadding: EdgeInsets.zero,
|
||||
content: Column(
|
||||
children: [
|
||||
Container(
|
||||
padding: EdgeInsets.symmetric(horizontal: 25),
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.only(bottomLeft: Radius.circular(24), bottomRight: Radius.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(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||
children: [
|
||||
SizedBox(height: 150),
|
||||
BaseTextFormField(
|
||||
controller: _amountController,
|
||||
focusNode: _amountFieldFocus,
|
||||
keyboardType: TextInputType.numberWithOptions(signed: false, decimal: true),
|
||||
inputFormatters: [FilteringTextInputFormatter.deny(RegExp('[\-|\ ]'))],
|
||||
hintText: '1000',
|
||||
placeholderTextStyle: TextStyle(
|
||||
color: Theme.of(context).primaryTextTheme.headline.color,
|
||||
fontWeight: FontWeight.w500,
|
||||
fontSize: 36,
|
||||
),
|
||||
borderColor: Theme.of(context).primaryTextTheme.headline.color,
|
||||
textColor: Colors.white,
|
||||
textStyle: TextStyle(
|
||||
color: Colors.white,
|
||||
fontSize: 36,
|
||||
),
|
||||
suffixIcon: SizedBox(
|
||||
width: _width / 6,
|
||||
),
|
||||
prefixIcon: Padding(
|
||||
padding: EdgeInsets.only(
|
||||
top: 5.0,
|
||||
left: _width / 4,
|
||||
),
|
||||
child: Text(
|
||||
'USD: ',
|
||||
style: TextStyle(
|
||||
color: Colors.white,
|
||||
fontWeight: FontWeight.w900,
|
||||
fontSize: 36,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
SizedBox(height: 8),
|
||||
Observer(builder: (_)=>
|
||||
!ioniaCustomRedeemViewModel.disableRedeem ?
|
||||
Center(
|
||||
child: Text('\$${giftCard.remainingAmount} - \$${ioniaCustomRedeemViewModel.amount} = \$${ioniaCustomRedeemViewModel.remaining} ${S.of(context).remaining}',
|
||||
style: TextStyle(
|
||||
color: Theme.of(context).primaryTextTheme.headline.color,
|
||||
),),
|
||||
) : SizedBox.shrink(),
|
||||
),
|
||||
SizedBox(height: 24),
|
||||
],
|
||||
),
|
||||
),
|
||||
Padding(
|
||||
padding: const EdgeInsets.all(24.0),
|
||||
child: CardItem(
|
||||
title: giftCard.legalName,
|
||||
backgroundColor: Theme.of(context).accentTextTheme.display4.backgroundColor.withOpacity(0.1),
|
||||
discount: giftCard.remainingAmount,
|
||||
isAmount: true,
|
||||
discountBackground: AssetImage('assets/images/red_badge_discount.png'),
|
||||
titleColor: Theme.of(context).accentTextTheme.display4.backgroundColor,
|
||||
subtitleColor: Theme.of(context).hintColor,
|
||||
subTitle: S.of(context).online,
|
||||
logoUrl: giftCard.logoUrl,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
bottomSection: Column(
|
||||
children: [
|
||||
Padding(
|
||||
padding: EdgeInsets.only(bottom: 12),
|
||||
child: PrimaryButton(
|
||||
onPressed: () {
|
||||
Navigator.of(context).pop(_amountController.text);
|
||||
},
|
||||
isDisabled: ioniaCustomRedeemViewModel.disableRedeem,
|
||||
text: S.of(context).add_custom_redemption,
|
||||
color: Theme.of(context).accentTextTheme.body2.color,
|
||||
textColor: Colors.white,
|
||||
),
|
||||
),
|
||||
SizedBox(height: 30),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
@ -0,0 +1,90 @@
|
||||
import 'package:cake_wallet/ionia/ionia_gift_card.dart';
|
||||
import 'package:cake_wallet/routes.dart';
|
||||
import 'package:cake_wallet/src/screens/base_page.dart';
|
||||
import 'package:cake_wallet/generated/i18n.dart';
|
||||
import 'package:cake_wallet/typography.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
|
||||
class IoniaMoreOptionsPage extends BasePage {
|
||||
IoniaMoreOptionsPage(this.giftCard);
|
||||
|
||||
final IoniaGiftCard giftCard;
|
||||
|
||||
@override
|
||||
Widget middle(BuildContext context) {
|
||||
return Text(
|
||||
S.current.more_options,
|
||||
style: textMediumSemiBold(
|
||||
color: Theme.of(context).accentTextTheme.display4.backgroundColor,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
Widget body(BuildContext context) {
|
||||
return Padding(
|
||||
padding: const EdgeInsets.all(16.0),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||
children: [
|
||||
SizedBox(height: 10,),
|
||||
Center(child: Text(S.of(context).choose_from_available_options, style: textMedium(
|
||||
color: Theme.of(context).primaryTextTheme.title.color,
|
||||
),)),
|
||||
SizedBox(height: 40,),
|
||||
InkWell(
|
||||
onTap: () async {
|
||||
final amount = await Navigator.of(context).pushNamed(Routes.ioniaCustomRedeemPage, arguments: [giftCard]) as String;
|
||||
if(amount.isNotEmpty){
|
||||
Navigator.pop(context, amount);
|
||||
}
|
||||
},
|
||||
child: _GradiantContainer(
|
||||
content: Padding(
|
||||
padding: const EdgeInsets.only(top: 24, left: 20, right: 24, bottom: 50),
|
||||
child: Text(
|
||||
S.of(context).custom_redeem_amount,
|
||||
style: textXLargeSemiBold(),
|
||||
),
|
||||
),
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class _GradiantContainer extends StatelessWidget {
|
||||
const _GradiantContainer({
|
||||
Key key,
|
||||
@required this.content,
|
||||
this.padding,
|
||||
this.width,
|
||||
}) : super(key: key);
|
||||
|
||||
final Widget content;
|
||||
final EdgeInsets padding;
|
||||
final double width;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Container(
|
||||
child: content,
|
||||
width: width,
|
||||
padding: padding ?? EdgeInsets.all(24),
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(15),
|
||||
gradient: LinearGradient(
|
||||
colors: [
|
||||
Theme.of(context).scaffoldBackgroundColor,
|
||||
Theme.of(context).accentColor,
|
||||
],
|
||||
begin: Alignment.topRight,
|
||||
end: Alignment.bottomLeft,
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
@ -0,0 +1,27 @@
|
||||
import 'package:cake_wallet/ionia/ionia_gift_card.dart';
|
||||
import 'package:mobx/mobx.dart';
|
||||
part 'ionia_custom_redeem_view_model.g.dart';
|
||||
class IoniaCustomRedeemViewModel = IoniaCustomRedeemViewModelBase with _$IoniaCustomRedeemViewModel;
|
||||
|
||||
abstract class IoniaCustomRedeemViewModelBase with Store {
|
||||
IoniaCustomRedeemViewModelBase(this.giftCard){
|
||||
amount = 0;
|
||||
}
|
||||
|
||||
final IoniaGiftCard giftCard;
|
||||
|
||||
@observable
|
||||
double amount;
|
||||
|
||||
@computed
|
||||
double get remaining => amount <= giftCard.remainingAmount ? giftCard.remainingAmount - amount : 0;
|
||||
|
||||
@computed
|
||||
bool get disableRedeem => amount > giftCard.remainingAmount;
|
||||
|
||||
@action
|
||||
void updateAmount(String text){
|
||||
amount = text.isEmpty ? 0 : (double.parse(text.replaceAll(',', '.')) ?? 0);
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in new issue