diff --git a/assets/images/red_badge_discount.png b/assets/images/red_badge_discount.png new file mode 100644 index 000000000..4f5dc56a2 Binary files /dev/null and b/assets/images/red_badge_discount.png differ diff --git a/lib/src/screens/ionia/cards/ionia_account_cards_page.dart b/lib/src/screens/ionia/cards/ionia_account_cards_page.dart index a0d02e4f4..ba2ddae55 100644 --- a/lib/src/screens/ionia/cards/ionia_account_cards_page.dart +++ b/lib/src/screens/ionia/cards/ionia_account_cards_page.dart @@ -1,14 +1,17 @@ +import 'package:cake_wallet/ionia/ionia_merchant.dart'; import 'package:cake_wallet/src/screens/base_page.dart'; +import 'package:cake_wallet/src/screens/ionia/widgets/card_item.dart'; import 'package:cake_wallet/typography.dart'; import 'package:cake_wallet/view_model/ionia/ionia_account_view_model.dart'; import 'package:flutter/material.dart'; import 'package:cake_wallet/generated/i18n.dart'; +import 'package:flutter_mobx/flutter_mobx.dart'; class IoniaAccountCardsPage extends BasePage { IoniaAccountCardsPage(this.ioniaAccountViewModel); final IoniaAccountViewModel ioniaAccountViewModel; - + @override Widget middle(BuildContext context) { return Text( @@ -21,11 +24,15 @@ class IoniaAccountCardsPage extends BasePage { @override Widget body(BuildContext context) { - return _IoniaCardTabs(); + return _IoniaCardTabs(ioniaAccountViewModel); } } class _IoniaCardTabs extends StatefulWidget { + _IoniaCardTabs(this.ioniaAccountViewModel); + + final IoniaAccountViewModel ioniaAccountViewModel; + @override _IoniaCardTabsState createState() => _IoniaCardTabsState(); } @@ -48,71 +55,109 @@ class _IoniaCardTabsState extends State<_IoniaCardTabs> with SingleTickerProvide @override Widget build(BuildContext context) { return Padding( - padding: const EdgeInsets.all(24.0), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Container( - height: 45, - width: 230, - padding: EdgeInsets.all(5), - decoration: BoxDecoration( - color: Theme.of(context).accentTextTheme.display4.backgroundColor.withOpacity(0.1), - borderRadius: BorderRadius.circular( - 25.0, - ), - ), - child: Theme( - data: ThemeData( - primaryTextTheme: TextTheme( - body2: TextStyle(backgroundColor: Colors.transparent) - ) - ), - child: TabBar( - controller: _tabController, - indicator: BoxDecoration( - borderRadius: BorderRadius.circular( - 25.0, - ), - color: Theme.of(context).accentTextTheme.body2.color, - ), - labelColor: Theme.of(context).primaryTextTheme.display4.backgroundColor, - unselectedLabelColor: Theme.of(context).primaryTextTheme.title.color, - tabs: [ - Tab( - text: S.of(context).active, - ), - Tab( - text: S.of(context).redeemed, - ), - ], - ), + padding: const EdgeInsets.all(24.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Container( + height: 45, + width: 230, + padding: EdgeInsets.all(5), + decoration: BoxDecoration( + color: Theme.of(context).accentTextTheme.display4.backgroundColor.withOpacity(0.1), + borderRadius: BorderRadius.circular( + 25.0, ), ), - Expanded( - child: TabBarView( + child: Theme( + data: ThemeData(primaryTextTheme: TextTheme(body2: TextStyle(backgroundColor: Colors.transparent))), + child: TabBar( controller: _tabController, - children: [ - Center( - child: Text( - S.of(context).gift_card_balance_note, - textAlign: TextAlign.center, - style: textSmall(color: Theme.of(context).primaryTextTheme.overline.color,), - ), + indicator: BoxDecoration( + borderRadius: BorderRadius.circular( + 25.0, ), - - Center( - child: Text( - S.of(context).gift_card_redeemed_note, - textAlign: TextAlign.center, - style: textSmall(color: Theme.of(context).primaryTextTheme.overline.color,), - ), + color: Theme.of(context).accentTextTheme.body2.color, + ), + labelColor: Theme.of(context).primaryTextTheme.display4.backgroundColor, + unselectedLabelColor: Theme.of(context).primaryTextTheme.title.color, + tabs: [ + Tab( + text: S.of(context).active, + ), + Tab( + text: S.of(context).redeemed, ), ], ), ), - ], - ), - ); + ), + SizedBox(height: 16), + Expanded( + child: Observer(builder: (_) { + final viewModel = widget.ioniaAccountViewModel; + return TabBarView( + controller: _tabController, + children: [ + _IoniaCardListView( + emptyText: S.of(context).gift_card_balance_note, + merchList: viewModel.activeMechs, + ), + _IoniaCardListView( + emptyText: S.of(context).gift_card_redeemed_note, + merchList: viewModel.redeemedMerchs, + ), + ], + ); + }), + ), + ], + ), + ); + } +} + +class _IoniaCardListView extends StatelessWidget { + _IoniaCardListView({ + Key key, + @required this.emptyText, + @required this.merchList, + }) : super(key: key); + + final String emptyText; + final List merchList; + + @override + Widget build(BuildContext context) { + return merchList.isEmpty + ? Center( + child: Text( + emptyText, + textAlign: TextAlign.center, + style: textSmall( + color: Theme.of(context).primaryTextTheme.overline.color, + ), + ), + ) + : ListView.builder( + itemCount: merchList.length, + itemBuilder: (context, index) { + final merchant = merchList[index]; + return Padding( + padding: const EdgeInsets.only(bottom: 16), + child: CardItem( + title: merchant.legalName, + backgroundColor: Theme.of(context).accentTextTheme.display4.backgroundColor.withOpacity(0.1), + discount: merchant.minimumDiscount, + discountBackground: AssetImage('assets/images/red_badge_discount.png'), + titleColor: Theme.of(context).accentTextTheme.display4.backgroundColor, + subtitleColor: Theme.of(context).hintColor, + subTitle: + '${merchant.isOnline ? '${S.of(context).online}' ' && ${S.current.in_store}' : S.of(context).offline}', + logoUrl: merchant.logoUrl, + ), + ); + }, + ); } } diff --git a/lib/src/screens/ionia/cards/ionia_account_page.dart b/lib/src/screens/ionia/cards/ionia_account_page.dart index 2612b2c66..c16aef002 100644 --- a/lib/src/screens/ionia/cards/ionia_account_page.dart +++ b/lib/src/screens/ionia/cards/ionia_account_page.dart @@ -26,7 +26,6 @@ class IoniaAccountPage extends BasePage { @override Widget body(BuildContext context) { - final deviceWidth = MediaQuery.of(context).size.width; return ScrollableWithBottomSection( contentPadding: EdgeInsets.all(24), content: Column( @@ -35,18 +34,18 @@ class IoniaAccountPage extends BasePage { content: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - Observer(builder: (_) => - RichText( - text: TextSpan( - text: '${ioniaAccountViewModel.countOfMerch}', - style: textLargeSemiBold(), - children: [ - TextSpan( - text: ' ${S.of(context).active_cards}', - style: textSmall(color: Colors.white.withOpacity(0.7))), - ], - ), - )), + Observer( + builder: (_) => RichText( + text: TextSpan( + text: '${ioniaAccountViewModel.countOfMerch}', + style: textLargeSemiBold(), + children: [ + TextSpan( + text: ' ${S.of(context).active_cards}', + style: textSmall(color: Colors.white.withOpacity(0.7))), + ], + ), + )), InkWell( onTap: () => Navigator.pushNamed(context, Routes.ioniaAccountCardsPage), child: Padding( @@ -121,10 +120,9 @@ class IoniaAccountPage extends BasePage { // ], //), SizedBox(height: 40), - Observer(builder: (_) => - IoniaTile( - title: S.of(context).email_address, - subTitle: ioniaAccountViewModel.email)), + Observer( + builder: (_) => IoniaTile(title: S.of(context).email_address, subTitle: ioniaAccountViewModel.email), + ), Divider() ], ), diff --git a/lib/src/screens/ionia/widgets/card_item.dart b/lib/src/screens/ionia/widgets/card_item.dart index 9a46072fd..bcddccdb9 100644 --- a/lib/src/screens/ionia/widgets/card_item.dart +++ b/lib/src/screens/ionia/widgets/card_item.dart @@ -2,17 +2,16 @@ import 'package:cake_wallet/src/widgets/discount_badge.dart'; import 'package:flutter/material.dart'; class CardItem extends StatelessWidget { - CardItem({ @required this.title, @required this.subTitle, @required this.backgroundColor, @required this.titleColor, @required this.subtitleColor, + this.discountBackground, this.onTap, this.logoUrl, this.discount, - }); final VoidCallback onTap; @@ -23,6 +22,7 @@ class CardItem extends StatelessWidget { final Color backgroundColor; final Color titleColor; final Color subtitleColor; + final AssetImage discountBackground; @override Widget build(BuildContext context) { @@ -70,7 +70,7 @@ class CardItem extends StatelessWidget { title, overflow: TextOverflow.ellipsis, style: TextStyle( - color: titleColor, + color: titleColor, fontSize: 20, fontWeight: FontWeight.w900, ), @@ -80,9 +80,10 @@ class CardItem extends StatelessWidget { Text( subTitle, style: TextStyle( - color: subtitleColor, - fontWeight: FontWeight.w500, - fontFamily: 'Lato'), + color: subtitleColor, + fontWeight: FontWeight.w500, + fontFamily: 'Lato', + ), ) ], ), @@ -94,7 +95,10 @@ class CardItem extends StatelessWidget { alignment: Alignment.topRight, child: Padding( padding: const EdgeInsets.only(top: 20.0), - child: DiscountBadge(percentage: discount), + child: DiscountBadge( + percentage: discount, + discountBackground: discountBackground, + ), ), ), ], @@ -104,7 +108,6 @@ class CardItem extends StatelessWidget { } class _PlaceholderContainer extends StatelessWidget { - const _PlaceholderContainer({@required this.text}); final String text; diff --git a/lib/src/widgets/discount_badge.dart b/lib/src/widgets/discount_badge.dart index d4e9836b2..855822c60 100644 --- a/lib/src/widgets/discount_badge.dart +++ b/lib/src/widgets/discount_badge.dart @@ -1,33 +1,35 @@ import 'package:flutter/material.dart'; import 'package:cake_wallet/generated/i18n.dart'; - class DiscountBadge extends StatelessWidget { const DiscountBadge({ Key key, @required this.percentage, + this.discountBackground, }) : super(key: key); final double percentage; + final AssetImage discountBackground; @override Widget build(BuildContext context) { return Container( padding: EdgeInsets.symmetric(horizontal: 8, vertical: 4), - child: Text( S.of(context).discount(percentage.toString()), + child: Text( + S.of(context).discount(percentage.toString()), style: TextStyle( color: Colors.white, fontSize: 12, fontWeight: FontWeight.w500, fontFamily: 'Lato', - ), ), + ), decoration: BoxDecoration( image: DecorationImage( fit: BoxFit.fill, - image: AssetImage('assets/images/badge_discount.png'), - ), - ), - ); - } + image: discountBackground ?? AssetImage('assets/images/badge_discount.png'), + ), + ), + ); + } } diff --git a/lib/view_model/ionia/ionia_account_view_model.dart b/lib/view_model/ionia/ionia_account_view_model.dart index 2332d5731..1b049b974 100644 --- a/lib/view_model/ionia/ionia_account_view_model.dart +++ b/lib/view_model/ionia/ionia_account_view_model.dart @@ -7,14 +7,11 @@ part 'ionia_account_view_model.g.dart'; class IoniaAccountViewModel = IoniaAccountViewModelBase with _$IoniaAccountViewModel; abstract class IoniaAccountViewModelBase with Store { - IoniaAccountViewModelBase({this.ioniaService}) { email = ''; merchs = []; - ioniaService.getUserEmail() - .then((email) => this.email = email); - ioniaService.getCurrentUserGiftCardSummaries() - .then((merchs) => this.merchs = merchs); + ioniaService.getUserEmail().then((email) => this.email = email); + ioniaService.getCurrentUserGiftCardSummaries().then((merchs) => this.merchs = merchs); } final IoniaService ioniaService; @@ -28,9 +25,14 @@ abstract class IoniaAccountViewModelBase with Store { @computed int get countOfMerch => merchs.where((merch) => merch.isActive).length; + @computed + List get activeMechs => merchs.where((merch) => merch.isActive).toList(); + + @computed + List get redeemedMerchs => merchs.where((merch) => !merch.isActive).toList(); + @action - void logout(){ + void logout() { ioniaService.logout(); } - -} \ No newline at end of file +} diff --git a/res/values/strings_en.arb b/res/values/strings_en.arb index d89edde0c..b3e683946 100644 --- a/res/values/strings_en.arb +++ b/res/values/strings_en.arb @@ -619,5 +619,6 @@ "more_options": "More Options", "awaiting_payment_confirmation": "Awaiting payment confirmation", "transaction_sent_notice": "If the screen doesn’t proceed after 1 minute, check a block explorer and your email.", - "agree": "Agree" + "agree": "Agree", + "in_store": "In Store" }