Cw 115 implement gift cards list for ionia (#405)

* Implement show purchased cards

* fix padding
This commit is contained in:
Godwin Asuquo 2022-07-07 20:47:27 +03:00 committed by GitHub
parent f320e749b8
commit 28ff890afd
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 153 additions and 102 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

View file

@ -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<IoniaMerchant> 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,
),
);
},
);
}
}

View file

@ -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()
],
),

View file

@ -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;

View file

@ -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'),
),
),
);
}
}

View file

@ -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<IoniaMerchant> get activeMechs => merchs.where((merch) => merch.isActive).toList();
@computed
List<IoniaMerchant> get redeemedMerchs => merchs.where((merch) => !merch.isActive).toList();
@action
void logout(){
void logout() {
ioniaService.logout();
}
}
}

View file

@ -619,5 +619,6 @@
"more_options": "More Options",
"awaiting_payment_confirmation": "Awaiting payment confirmation",
"transaction_sent_notice": "If the screen doesnt proceed after 1 minute, check a block explorer and your email.",
"agree": "Agree"
"agree": "Agree",
"in_store": "In Store"
}