From cb12c970aa3fabc8bfe8735a2699dc6f0d15be62 Mon Sep 17 00:00:00 2001 From: Godwin Asuquo Date: Fri, 13 May 2022 07:17:36 +0100 Subject: [PATCH] design ui for cakepay --- assets/images/badge_discount.png | Bin 0 -> 1411 bytes assets/images/card.png | Bin 0 -> 556 bytes assets/images/filter.png | Bin 0 -> 504 bytes assets/images/profile.png | Bin 0 -> 1060 bytes assets/images/search_icon.png | Bin 0 -> 536 bytes cw_haven/pubspec.lock | 7 - ios/Podfile.lock | 14 +- lib/di.dart | 18 ++ lib/router.dart | 24 ++ lib/routes.dart | 8 +- .../cake_pay/auth/create_account_page.dart | 94 ++++++++ .../cake_pay/auth/forgot_password_page.dart | 55 +++++ lib/src/screens/cake_pay/auth/login_page.dart | 80 +++++++ .../screens/cake_pay/auth/welcome_page.dart | 95 ++++++++ lib/src/screens/cake_pay/cake_pay.dart | 1 + .../screens/cake_pay/cards/buy_gift_card.dart | 96 ++++++++ .../cake_pay/cards/manage_cards_page.dart | 219 ++++++++++++++++++ .../screens/cake_pay/widgets/card_menu.dart | 11 + lib/src/screens/dashboard/dashboard_page.dart | 10 +- .../dashboard/widgets/market_place_page.dart | 51 ++++ lib/src/widgets/market_place_item.dart | 129 +++++++++++ res/values/strings_en.arb | 18 +- 22 files changed, 913 insertions(+), 17 deletions(-) create mode 100644 assets/images/badge_discount.png create mode 100644 assets/images/card.png create mode 100644 assets/images/filter.png create mode 100644 assets/images/profile.png create mode 100644 assets/images/search_icon.png create mode 100644 lib/src/screens/cake_pay/auth/create_account_page.dart create mode 100644 lib/src/screens/cake_pay/auth/forgot_password_page.dart create mode 100644 lib/src/screens/cake_pay/auth/login_page.dart create mode 100644 lib/src/screens/cake_pay/auth/welcome_page.dart create mode 100644 lib/src/screens/cake_pay/cake_pay.dart create mode 100644 lib/src/screens/cake_pay/cards/buy_gift_card.dart create mode 100644 lib/src/screens/cake_pay/cards/manage_cards_page.dart create mode 100644 lib/src/screens/cake_pay/widgets/card_menu.dart create mode 100644 lib/src/screens/dashboard/widgets/market_place_page.dart create mode 100644 lib/src/widgets/market_place_item.dart diff --git a/assets/images/badge_discount.png b/assets/images/badge_discount.png new file mode 100644 index 0000000000000000000000000000000000000000..64c8789c53a37ea9e1c5621a08b531c1441b1301 GIT binary patch literal 1411 zcmV-}1$_F6P)Q{Nhzs%n4Xya)KgVSnJKB> zQ&}&(`}4Kf^+ABYL{%kTSpPac={>{zeXI zn{!>RxBW1mGuOh{5W|UWck|hHy|rb;{DKr#1TL0gOq*UZJS=bCj`369(fLK5vP`kGLgLSOg7wqvkX#~wrs$mIjq^{FD7(v6_| zdu))%)bG7~NNd|z(Bjh&k^txrq-7Y+4N3ZSn{wwo^F>i>WYFQq%!e4ayha9GkfylWc*#;-~ zjSsl|x2kp`KvG$WX5}v)AHJ@E|K#OYq9M(QE22|9hvz4LCsE3u@OPdkjO&`!HAJpv zo)~@3{TT?z4DS5kzE&ybqgMs;)4q%V@p8~w27$Vv9Un5Si5WCn5qFX;;8H7kIE~2p z=XRMUnLbtXMoRcRYk8MyL`L9$Tp!o_lT;oHx|nrUng}C{NClcsTB5VrDJP;pM@r~j ze`5xuajBvm)t%>ay_R*@xtu)>x~hlgEVg@7B}yH*et23z<6{~(L=1kg00xo%(;+h( zjN>S7!uphs7}CM8aF6yn+i}b5wJq)nSTmi09w~D&o}uoY_a8%R#yyVfOR=EIx`mXF z4bEyS&5xG!nt9BUr!gn-SwK+XBMV7d>yAQ+!xd&fO4@sN6=x^Bo|6*7;#tTPd@f$cfEQ+`z% zvU7M|Youae>J>(2J9}73@of$N&GI)788QR8XKLi3pO)Bu$WRuSR)mad))g69Q_%bC z33LH+6xmc()g+Z_jiZ4DBxGfdtI7Z%ea{2p#iLY! z8Y>sWEL08P%*l`$UxnsvBiR*_$5t!Z$;{*BvK1>V3?($_ z1v#(eTYV7pNeiBQtIA#mk=5R zFOZGI#WEEbBC023s*H7K9he$sGUb?diIMTiD(wcy^6KSF=|eW`Dn3ICZndYes$VyI z^qUry%9NHnrrL|K%s{^*lOfYeVRII=z)G1}tECS$6Bt*K#J!}>>y%*?D~-!BnBT_@ z@_dv4ex)2!>W2U6kL3-&R{eB1N;i9PP3NSfiz2n=FrnkPqd z&6vXxcRuNyEQaFyfkkFUJ~W{}>W7$H#O)Wy6ONGRc6C%&tya=cN91`=<{=>-4)8Y0 zjzV+*HgcF0B5p>QN80>JwXBx8ub~(TuB-$H@2MA$=Ss#O*N^YB=la=LDA%|Z2}X4m z9NNT@v{J*0sagYI2NI@|&6a@LL#>KeR^d8}D7uz3h#f8mGr^Bw6Y#9|zW`BSjzW_V R`&R$}002ovPDHLkV1hR^mL32A literal 0 HcmV?d00001 diff --git a/assets/images/card.png b/assets/images/card.png new file mode 100644 index 0000000000000000000000000000000000000000..58935bdaca99aca87b6ee1888f90f0cf01df986f GIT binary patch literal 556 zcmV+{0@MA8P)8^9)%Nq|XcCx8uNCLl}@?!ZBp#C8&@#!lrYooYEh(w%)y zsvjVcNX(k7Pf%5rqMr@Lib7!;w23myvUiMyl3r0fP<&S5DXQOGlr7iHk~|AvG2Lnp zMN{l)N3@)56yQj{q&S-24@|?_JU5@*KrDuLrIIG~(mSHYp2`r+uoY%^0*8t9r0> zh(sFxZoDb+mo&WPV~AyAR^3}%-i#`Z=qB`Xi@>8 zNd<%^6%d+KKxmd@#Ox5D>lYRDzv-n%1K&O8Ft`Ad*puTLI3b_Lbq~(us#-|8UF)`x zR_mEp4W1VAXyCeM1PYd1T?O300w;(bhG_nYT-2g-mCd3V8C#nnq8yQ6{Lw$V-6uTA zU5LRSHNL3R+-=+IY;L`wdtlgV)R@*@=Uj4h?e)etg4uuI=)4DvU{CRgI6PAB0M2FG uPM#U^k&jQj!t@{cep=U-bRvvt&t0000NZ&QsDO$c2g?g z*KyhMXpH-C@<-6NTs8rlSJ=FeQZ^Qs27Wu)b~i$5^)^Py&J|aC8hU*pr4Z`_kK5k> zg2ITL@OV*AstKt9SO*&BhMmz*lt?N7%-%B|A1I-GfDZM&_r6B`ykO{E%qD1o+1g{a z?(wb?Dti6XlzPp3aZa)`F}^;;jv{5Dg?~kJBzC=C z`~AIL&-#_LL;|9nf-u8D)@tozAl^mL&>68=CAkRhhV>Y*siq*8Lb#K%4zxSKk|Gpy z7Pz}X9%y&H?r0@|RdfTm0i*+{`t?<4`4 z;hWh(Nc-N^y<~uQye=j%AP{j%e-fgU=#1!-ezYTcB-#^gCzHt@214%u$Z6&51yQC+ zf|BTgXidS?@ERb;Gok|fqagYQkqEAU&iF03vt2`z;U{QXMnSdKIdtu1!UZFjj;ZEdJ9I5!XlSE_#aJ$J+M_pd1aj9$ugyqh$#?<-LE9({8&z)`I`gLU zIgA8dQ8S46O6XE@%wc4ZjfGilhye*M4Mhu~oElzNM&&AfFB9sR$JpiylF+u%?PgZY zh84<2E3=(akb;;u7*ImAzbig$gh3P`ezZbn`4WN5+LGmrJx?t>cLKd;CuATHD!3y8 z{>(74@bE4|9m2y_Do!ycJ+r?Wfq!cFl=_(S5an8CCsN+=^NQ_20HZ5%DdUAeH}KSe z5TP>ItesjEE+(^7q8ado0&x2Ff${P3hwPg6%#fsoQk$#~+LxN$O4(isFjyN1Ice}f#nTGketI+(qn@|JK|1vN~r zc&lJDk*QtWPtK=hrLYF@5r)AP(FVFI&J}sy(VFN61^};sH9`sWOEv>pOO!-kBKE%4 z4siu=27yox5zV0q0Eh>0pz{3@CW@Ct&$X)_I-=1G$ zRaSaXLU-QtmFN!y0Gq{M2F=UNOWvLlZHZK?Z6OR9yDptAh#^bYPNv;L?of`Mmbnz# z;49eN$C$cGW#PTXFsEIp&_DTkm-rKlfXaNP|GlAd<)%XVqjpoab&o1-3C&VO4Fpg6 zetS~=S<59B*&3Qrsy6Jcp_{!``^>-xJl{)8by82(WUIs#7x5cb1y7&xkW?yy) zjF!!`R<^S^-fOhNn=n!_*1drZdI>0000tajG#exvv>VV3U<23yHc+i1H>!#;54-*EeBr>7KFjhW z0ROB6RtgbQ^OJF-=gzbtNsEC#eg}u0QV{;>;DWPh z-!$?GpSh@s19)hAZ^vyASMOAC1(V((uy9D&)}(oY&Sy)5If3R1#CGx1= 2.7.5) - SwiftProtobuf (1.12.0) - SwiftyGif (5.3.0) - uni_links (0.0.1): @@ -145,6 +151,7 @@ DEPENDENCIES: - permission_handler (from `.symlinks/plugins/permission_handler/ios`) - share (from `.symlinks/plugins/share/ios`) - shared_preferences (from `.symlinks/plugins/shared_preferences/ios`) + - sqflite (from `.symlinks/plugins/sqflite/ios`) - uni_links (from `.symlinks/plugins/uni_links/ios`) - UnstoppableDomainsResolution (~> 4.0.0) - url_launcher (from `.symlinks/plugins/url_launcher/ios`) @@ -156,6 +163,7 @@ SPEC REPOS: - CryptoSwift - DKImagePickerController - DKPhotoGallery + - FMDB - MTBBarcodeScanner - Reachability - SDWebImage @@ -196,6 +204,8 @@ EXTERNAL SOURCES: :path: ".symlinks/plugins/share/ios" shared_preferences: :path: ".symlinks/plugins/shared_preferences/ios" + sqflite: + :path: ".symlinks/plugins/sqflite/ios" uni_links: :path: ".symlinks/plugins/uni_links/ios" url_launcher: @@ -218,6 +228,7 @@ SPEC CHECKSUMS: file_picker: 3e6c3790de664ccf9b882732d9db5eaf6b8d4eb1 Flutter: 434fef37c0980e73bb6479ef766c45957d4b510c flutter_secure_storage: 7953c38a04c3fdbb00571bcd87d8e3b5ceb9daec + FMDB: 2ce00b547f966261cd18927a3ddb07cb6f3db82a local_auth: 25938960984c3a7f6e3253e3f8d962fdd16852bd MTBBarcodeScanner: f453b33c4b7dfe545d8c6484ed744d55671788cb package_info: 873975fc26034f0b863a300ad47e7f1ac6c7ec62 @@ -227,6 +238,7 @@ SPEC CHECKSUMS: SDWebImage: a990c053fff71e388a10f3357edb0be17929c9c5 share: 0b2c3e82132f5888bccca3351c504d0003b3b410 shared_preferences: af6bfa751691cdc24be3045c43ec037377ada40d + sqflite: 6d358c025f5b867b29ed92fc697fd34924e11904 SwiftProtobuf: 4ef85479c18ca85b5482b343df9c319c62bda699 SwiftyGif: e466e86c660d343357ab944a819a101c4127cb40 uni_links: d97da20c7701486ba192624d99bffaaffcfc298a @@ -236,4 +248,4 @@ SPEC CHECKSUMS: PODFILE CHECKSUM: ae71bdf0eb731a1ffc399c122f6aa4dea0cb5f6f -COCOAPODS: 1.11.2 +COCOAPODS: 1.11.3 diff --git a/lib/di.dart b/lib/di.dart index 3cc4dacae..27923cfa4 100644 --- a/lib/di.dart +++ b/lib/di.dart @@ -5,6 +5,12 @@ 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/cake_pay.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/dashboard/widgets/balance_page.dart'; import 'package:cw_core/unspent_coins_info.dart'; import 'package:cake_wallet/core/backup_service.dart'; @@ -639,5 +645,17 @@ Future setup( getIt.registerFactory(() => AddressResolver(yatService: getIt.get())); + getIt.registerFactory(() => WelcomePage()); + + getIt.registerFactory(() => LoginPage()); + + getIt.registerFactory(() => CreateAccountPage()); + + getIt.registerFactory(() => ForgotPassword()); + + getIt.registerFactory(() => ManageCardsPage()); + + getIt.registerFactory(() => BuyGiftCardPage()); + _isSetupFinished = true; } diff --git a/lib/router.dart b/lib/router.dart index acfb18684..b2ef23d6c 100644 --- a/lib/router.dart +++ b/lib/router.dart @@ -5,6 +5,12 @@ 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/cake_pay.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'; @@ -402,6 +408,24 @@ Route createRoute(RouteSettings settings) { getIt.get( param1: args)); + case Routes.cakePayWelcomePage: + return CupertinoPageRoute(builder: (_) => getIt.get()); + + case Routes.cakePayLoginPage: + return CupertinoPageRoute( builder: (_) => getIt.get()); + + case Routes.cakePayCreateAccountPage: + return CupertinoPageRoute( builder: (_) => getIt.get()); + + case Routes.cakePayForgotPasswordPage: + return CupertinoPageRoute(builder: (_) => getIt.get()); + + case Routes.manageCardsPage: + return CupertinoPageRoute(builder: (_) => getIt.get()); + + case Routes.buyGiftCardPage: + return CupertinoPageRoute(builder: (_) => getIt.get()); + default: return MaterialPageRoute( builder: (_) => Scaffold( diff --git a/lib/routes.dart b/lib/routes.dart index 23e236023..0ec0efd0d 100644 --- a/lib/routes.dart +++ b/lib/routes.dart @@ -60,4 +60,10 @@ class Routes { static const moneroRestoreWalletFromWelcome = '/monero_restore_wallet'; static const moneroNewWalletFromWelcome = '/monero_new_wallet'; static const addressPage = '/address_page'; -} \ No newline at end of file + 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'; +} diff --git a/lib/src/screens/cake_pay/auth/create_account_page.dart b/lib/src/screens/cake_pay/auth/create_account_page.dart new file mode 100644 index 000000000..32ec228e8 --- /dev/null +++ b/lib/src/screens/cake_pay/auth/create_account_page.dart @@ -0,0 +1,94 @@ +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 CreateAccountPage extends BasePage { + CreateAccountPage() : _formKey = GlobalKey(); + + final GlobalKey _formKey; + + @override + Widget middle(BuildContext context) { + return Text( + S.current.sign_up, + style: TextStyle( + fontSize: 22, + fontFamily: 'Lato', + fontWeight: FontWeight.w900, + ), + ); + } + + @override + Widget body(BuildContext context) { + return ScrollableWithBottomSection( + contentPadding: EdgeInsets.all(24), + content: Form( + key: _formKey, + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + BaseTextFormField( + hintText: 'Email Address *', + ), + SizedBox(height: 20), + BaseTextFormField( + hintText: 'Password *', + ), + ], + ), + ), + bottomSectionPadding: EdgeInsets.symmetric(vertical: 36, horizontal: 24), + bottomSection: Column( + children: [ + Column( + mainAxisAlignment: MainAxisAlignment.end, + children: [ + PrimaryButton( + text: S.of(context).create_account, + onPressed: () {}, + color: Theme.of(context).accentTextTheme.body2.color, + textColor: Colors.white, + ), + SizedBox( + height: 20, + ), + RichText( + textAlign: TextAlign.center, + text: TextSpan( + text: 'By creating account you agree to the ', + style: TextStyle( + color: Color(0xff7A93BA), + fontSize: 12, + fontFamily: 'Lato', + ), + children: [ + TextSpan( + text: S.of(context).settings_terms_and_conditions, + style: TextStyle( + color: Theme.of(context).accentTextTheme.body2.color, + fontWeight: FontWeight.w700, + ), + ), + TextSpan(text: ' and '), + TextSpan( + text: S.of(context).privacy_policy, + style: TextStyle( + color: Theme.of(context).accentTextTheme.body2.color, + fontWeight: FontWeight.w700, + ), + ), + TextSpan(text: ' by CakePay'), + ], + ), + ), + ], + ), + ], + ), + ); + } +} diff --git a/lib/src/screens/cake_pay/auth/forgot_password_page.dart b/lib/src/screens/cake_pay/auth/forgot_password_page.dart new file mode 100644 index 000000000..990380d03 --- /dev/null +++ b/lib/src/screens/cake_pay/auth/forgot_password_page.dart @@ -0,0 +1,55 @@ +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: [ + BaseTextFormField( + hintText: 'Email Address*', + ), + SizedBox(height: 20), + ], + ), + bottomSectionPadding: EdgeInsets.symmetric(vertical: 36, horizontal: 24), + bottomSection: Column( + children: [ + Column( + mainAxisAlignment: MainAxisAlignment.end, + children: [ + PrimaryButton( + text: S.of(context).reset_password, + onPressed: () {}, + color: Theme.of(context).accentTextTheme.body2.color, + textColor: Colors.white, + ), + ], + ), + ], + ), + ); + } +} diff --git a/lib/src/screens/cake_pay/auth/login_page.dart b/lib/src/screens/cake_pay/auth/login_page.dart new file mode 100644 index 000000000..e427799a3 --- /dev/null +++ b/lib/src/screens/cake_pay/auth/login_page.dart @@ -0,0 +1,80 @@ +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/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 LoginPage extends BasePage { + LoginPage() : _formKey = GlobalKey(); + + final GlobalKey _formKey; + @override + Color get titleColor => Colors.black; + + @override + Widget middle(BuildContext context) { + return Text( + S.current.login, + style: TextStyle( + fontSize: 22, + fontFamily: 'Lato', + fontWeight: FontWeight.w900, + ), + ); + } + + @override + Widget body(BuildContext context) { + return ScrollableWithBottomSection( + contentPadding: EdgeInsets.all(24), + content: Form( + key: _formKey, + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + BaseTextFormField( + hintText: 'Email Address', + ), + SizedBox(height: 20), + BaseTextFormField( + hintText: 'Password', + ), + ], + ), + ), + bottomSectionPadding: EdgeInsets.symmetric(vertical: 36, horizontal: 24), + bottomSection: Column( + children: [ + Column( + mainAxisAlignment: MainAxisAlignment.end, + children: [ + PrimaryButton( + text: S.of(context).login, + onPressed: () {}, + color: Theme.of(context).accentTextTheme.body2.color, + textColor: Colors.white, + ), + 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, + ), + ), + ) + ], + ), + ], + ), + ); + } +} diff --git a/lib/src/screens/cake_pay/auth/welcome_page.dart b/lib/src/screens/cake_pay/auth/welcome_page.dart new file mode 100644 index 000000000..234abb887 --- /dev/null +++ b/lib/src/screens/cake_pay/auth/welcome_page.dart @@ -0,0 +1,95 @@ +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/primary_button.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter/src/widgets/framework.dart'; +import 'package:cake_wallet/generated/i18n.dart'; + +class WelcomePage extends BasePage { + @override + Color get titleColor => Colors.black; + + @override + Widget middle(BuildContext context) { + return Text( + S.current.welcome_to_cakepay, + style: TextStyle( + fontSize: 22, + fontFamily: 'Lato', + fontWeight: FontWeight.w900, + ), + ); + } + + @override + Widget body(BuildContext context) { + return Padding( + padding: const EdgeInsets.all(24.0), + child: Column( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Column( + children: [ + SizedBox(height: 100), + Text( + S.of(context).about_cake_pay, + style: TextStyle( + fontSize: 18, + fontWeight: FontWeight.w400, + fontFamily: 'Lato', + color: Theme.of(context).primaryTextTheme.title.color, + ), + ), + SizedBox(height: 20), + Text( + S.of(context).cake_pay_account_note, + style: TextStyle( + fontSize: 18, + fontWeight: FontWeight.w400, + fontFamily: 'Lato', + color: Theme.of(context).primaryTextTheme.title.color, + ), + ), + ], + ), + Column( + mainAxisAlignment: MainAxisAlignment.end, + children: [ + PrimaryButton( + text: S.of(context).create_account, + onPressed: () => Navigator.of(context).pushNamed(Routes.cakePayCreateAccountPage), + color: Theme.of(context).accentTextTheme.body2.color, + textColor: Colors.white, + ), + SizedBox( + height: 16, + ), + Text( + S.of(context).already_have_account, + style: TextStyle( + fontSize: 15, + fontWeight: FontWeight.w500, + fontFamily: 'Lato', + color: Theme.of(context).primaryTextTheme.title.color, + ), + ), + SizedBox(height: 8), + InkWell( + onTap: () => Navigator.of(context).pushNamed(Routes.cakePayLoginPage), + child: Text( + S.of(context).login, + style: TextStyle( + color: Palette.blueCraiola, + fontSize: 16, + fontWeight: FontWeight.w900, + ), + ), + ) + ], + ) + ], + ), + ); + } +} diff --git a/lib/src/screens/cake_pay/cake_pay.dart b/lib/src/screens/cake_pay/cake_pay.dart new file mode 100644 index 000000000..b6e794905 --- /dev/null +++ b/lib/src/screens/cake_pay/cake_pay.dart @@ -0,0 +1 @@ +export 'auth/welcome_page.dart'; \ No newline at end of file diff --git a/lib/src/screens/cake_pay/cards/buy_gift_card.dart b/lib/src/screens/cake_pay/cards/buy_gift_card.dart new file mode 100644 index 000000000..a3f611067 --- /dev/null +++ b/lib/src/screens/cake_pay/cards/buy_gift_card.dart @@ -0,0 +1,96 @@ +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/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:flutter/material.dart'; +import 'package:keyboard_actions/keyboard_actions.dart'; +import 'package:cake_wallet/generated/i18n.dart'; + + +class BuyGiftCardPage extends BasePage { + BuyGiftCardPage(): _amountFieldFocus = FocusNode(), + _amountController = TextEditingController(); + @override + String get title => 'Enter 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) { + 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: + Container( + padding: EdgeInsets.symmetric(horizontal: 14), + 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: 200), + + BaseTextFormField(controller: _amountController, focusNode: _amountFieldFocus, ) + ], + ), + ), + bottomSection: + Column( + children: [ + + Padding( + padding: EdgeInsets.only(bottom: 12), + child: PrimaryButton( + onPressed: () {}, + text: S.of(context).continue_text, + color: Theme.of(context).accentTextTheme.body2.color, + textColor: Colors.white, + ), + ), + SizedBox(height: 20), + + SizedBox(height: 10) + ], + ) , + ) ,), + ); + } +} diff --git a/lib/src/screens/cake_pay/cards/manage_cards_page.dart b/lib/src/screens/cake_pay/cards/manage_cards_page.dart new file mode 100644 index 000000000..5e14cd703 --- /dev/null +++ b/lib/src/screens/cake_pay/cards/manage_cards_page.dart @@ -0,0 +1,219 @@ +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/widgets/market_place_item.dart'; +import 'package:cake_wallet/themes/theme_base.dart'; +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import 'package:cake_wallet/generated/i18n.dart'; + +class ManageCardsPage extends BasePage { + @override + Color get backgroundLightColor => currentTheme.type == ThemeType.bright ? Colors.transparent : Colors.white; + + @override + Color get backgroundDarkColor => Colors.transparent; + + @override + Color get titleColor => currentTheme.type == ThemeType.bright ? Colors.white : Colors.black; + + @override + Widget Function(BuildContext, Widget) get rootWrapper => (BuildContext context, Widget scaffold) => Container( + decoration: BoxDecoration( + gradient: LinearGradient( + colors: [ + Theme.of(context).accentColor, + Theme.of(context).scaffoldBackgroundColor, + Theme.of(context).primaryColor, + ], + begin: Alignment.topRight, + end: Alignment.bottomLeft, + ), + ), + child: scaffold, + ); + + @override + bool get resizeToAvoidBottomInset => false; + + @override + Widget get endDrawer => CardMenu(); + + @override + Widget middle(BuildContext context) { + return Text( + S.of(context).manage_cards, + style: TextStyle( + fontSize: 24, + fontWeight: FontWeight.w500, + color: Theme.of(context).accentTextTheme.display3.backgroundColor, + ), + ); + } + + final ScrollController _scrollController = ScrollController(); + + @override + Widget trailing(BuildContext context) { + return Row( + mainAxisSize: MainAxisSize.min, + children: [ + _TrailingIcon( + asset: 'assets/images/card.png', + onPressed: () {}, + ), + SizedBox(width: 16), + _TrailingIcon( + asset: 'assets/images/profile.png', + onPressed: () {}, + ), + ], + ); + } + + @override + Widget body(BuildContext context) { + final filterIcon = Image.asset( + 'assets/images/filter.png', + color: Theme.of(context).textTheme.caption.decorationColor, + ); + + return Padding( + padding: const EdgeInsets.all(14.0), + child: Column( + children: [ + MarketPlaceItem( + onTap: () {}, + title: S.of(context).setup_your_debit_card, + subTitle: S.of(context).no_id_required, + ), + SizedBox(height: 48), + Container( + padding: EdgeInsets.only(left: 2, right: 22), + height: 32, + child: Row( + children: [ + Expanded(child: _SearchWidget()), + SizedBox(width: 10), + Container( + width: 32, + padding: EdgeInsets.all(8), + decoration: BoxDecoration( + color: Colors.white.withOpacity(0.15), + border: Border.all( + color: Colors.white.withOpacity(0.2), + ), + borderRadius: BorderRadius.circular(10), + ), + child: filterIcon, + ) + ], + ), + ), + SizedBox(height: 8), + Expanded( + child: RawScrollbar( + thumbColor: Colors.white.withOpacity(0.15), + radius: Radius.circular(20), + isAlwaysShown: true, + thickness: 2, + controller: _scrollController, + child: ListView.separated( + padding: EdgeInsets.only(left: 2, right: 22), + controller: _scrollController, + itemCount: 20, + separatorBuilder: (_, __) => SizedBox(height: 4), + itemBuilder: (_, index) { + return MarketPlaceItem( + padding: EdgeInsets.symmetric(horizontal: 12, vertical: 12), + logoUrl: '', + onTap: ()=>Navigator.of(context).pushNamed(Routes.buyGiftCardPage), + title: 'Amazon', + subTitle: 'Online', + hasDiscount: true, + ); + }, + ), + ), + ), + ], + ), + ); + } +} + +class _SearchWidget extends StatelessWidget { + const _SearchWidget({ + Key key, + }) : super(key: key); + + @override + Widget build(BuildContext context) { + final searchIcon = Padding( + padding: EdgeInsets.all(8), + child: Image.asset( + 'assets/images/search_icon.png', + color: Theme.of(context).textTheme.caption.decorationColor, + ), + ); + + return TextField( + style: TextStyle(color: Colors.white), + decoration: InputDecoration( + filled: true, + contentPadding: EdgeInsets.only( + top: 10, + left: 10, + ), + fillColor: Colors.white.withOpacity(0.15), + hintText: 'Search', + hintStyle: TextStyle( + color: Colors.white.withOpacity(0.6), + ), + alignLabelWithHint: true, + floatingLabelBehavior: FloatingLabelBehavior.never, + suffixIcon: searchIcon, + border: OutlineInputBorder( + borderSide: BorderSide( + color: Colors.white.withOpacity(0.2), + ), + borderRadius: BorderRadius.circular(10), + ), + enabledBorder: OutlineInputBorder( + borderSide: BorderSide( + color: Colors.white.withOpacity(0.2), + ), + borderRadius: BorderRadius.circular(10), + ), + focusedBorder: OutlineInputBorder( + borderSide: BorderSide(color: Colors.white.withOpacity(0.2)), + borderRadius: BorderRadius.circular(10), + )), + ); + } +} + +class _TrailingIcon extends StatelessWidget { + final String asset; + final VoidCallback onPressed; + + const _TrailingIcon({this.asset, this.onPressed}); + + @override + Widget build(BuildContext context) { + return Container( + alignment: Alignment.centerRight, + width: 25, + child: FlatButton( + highlightColor: Colors.transparent, + splashColor: Colors.transparent, + padding: EdgeInsets.all(0), + onPressed: onPressed, + child: Image.asset( + asset, + color: Theme.of(context).accentTextTheme.display3.backgroundColor, + ), + ), + ); + } +} diff --git a/lib/src/screens/cake_pay/widgets/card_menu.dart b/lib/src/screens/cake_pay/widgets/card_menu.dart new file mode 100644 index 000000000..9212c0448 --- /dev/null +++ b/lib/src/screens/cake_pay/widgets/card_menu.dart @@ -0,0 +1,11 @@ +import 'package:flutter/material.dart'; + +class CardMenu extends StatelessWidget { + + @override + Widget build(BuildContext context) { + return Container( + + ); + } +} \ No newline at end of file diff --git a/lib/src/screens/dashboard/dashboard_page.dart b/lib/src/screens/dashboard/dashboard_page.dart index eb8c9ab17..f11398564 100644 --- a/lib/src/screens/dashboard/dashboard_page.dart +++ b/lib/src/screens/dashboard/dashboard_page.dart @@ -1,8 +1,8 @@ import 'dart:async'; +import 'package:cake_wallet/src/screens/dashboard/widgets/market_place_page.dart'; import 'package:cw_core/wallet_type.dart'; import 'package:cake_wallet/generated/i18n.dart'; import 'package:cake_wallet/routes.dart'; -import 'package:cake_wallet/src/screens/yat/yat_popup.dart'; import 'package:cake_wallet/src/screens/yat_emoji_id.dart'; import 'package:cake_wallet/src/widgets/alert_with_one_action.dart'; import 'package:cake_wallet/themes/theme_base.dart'; @@ -14,19 +14,15 @@ import 'package:cake_wallet/src/screens/base_page.dart'; import 'package:cake_wallet/src/screens/dashboard/widgets/menu_widget.dart'; import 'package:cake_wallet/src/screens/dashboard/widgets/action_button.dart'; import 'package:cake_wallet/src/screens/dashboard/widgets/balance_page.dart'; -import 'package:cake_wallet/src/screens/dashboard/widgets/address_page.dart'; import 'package:cake_wallet/src/screens/dashboard/widgets/transactions_page.dart'; import 'package:cake_wallet/src/screens/dashboard/widgets/sync_indicator.dart'; import 'package:cake_wallet/view_model/wallet_address_list/wallet_address_list_view_model.dart'; import 'package:flutter_mobx/flutter_mobx.dart'; import 'package:mobx/mobx.dart'; import 'package:smooth_page_indicator/smooth_page_indicator.dart'; -import 'package:flutter_spinkit/flutter_spinkit.dart'; import 'package:cake_wallet/main.dart'; -import 'package:cake_wallet/router.dart'; import 'package:cake_wallet/buy/moonpay/moonpay_buy_provider.dart'; import 'package:url_launcher/url_launcher.dart'; -import 'package:cake_wallet/wallet_type_utils.dart'; class DashboardPage extends BasePage { DashboardPage({ @@ -85,7 +81,7 @@ class DashboardPage extends BasePage { final DashboardViewModel walletViewModel; final WalletAddressListViewModel addressListViewModel; - final controller = PageController(initialPage: 0); + final controller = PageController(initialPage: 1); var pages = []; bool _isEffectsInstalled = false; @@ -221,7 +217,7 @@ class DashboardPage extends BasePage { if (_isEffectsInstalled) { return; } - + pages.add(MarketPlacePage()); pages.add(balancePage); pages.add(TransactionsPage(dashboardViewModel: walletViewModel)); _isEffectsInstalled = true; diff --git a/lib/src/screens/dashboard/widgets/market_place_page.dart b/lib/src/screens/dashboard/widgets/market_place_page.dart new file mode 100644 index 000000000..cd67eb20d --- /dev/null +++ b/lib/src/screens/dashboard/widgets/market_place_page.dart @@ -0,0 +1,51 @@ +import 'package:cake_wallet/routes.dart'; +import 'package:cake_wallet/src/widgets/market_place_item.dart'; +import 'package:flutter/material.dart'; +import 'package:cake_wallet/generated/i18n.dart'; + +class MarketPlacePage extends StatelessWidget { + final ScrollController _scrollController = ScrollController(); + @override + Widget build(BuildContext context) { + return Padding( + padding: const EdgeInsets.symmetric(horizontal: 10.0), + child: RawScrollbar( + thumbColor: Colors.white.withOpacity(0.15), + radius: Radius.circular(20), + isAlwaysShown: true, + thickness: 2, + controller: _scrollController, + child: Padding( + padding: const EdgeInsets.symmetric(horizontal: 10.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + SizedBox(height: 50), + Text( + S.of(context).market_place, + style: TextStyle( + fontSize: 24, + fontWeight: FontWeight.w500, + color: Theme.of(context).accentTextTheme.display3.backgroundColor, + ), + ), + Expanded( + child: ListView( + controller: _scrollController, + children: [ + SizedBox(height: 20), + MarketPlaceItem( + onTap: () => Navigator.of(context).pushNamed(Routes.manageCardsPage), + title: S.of(context).cake_pay_title, + subTitle: S.of(context).cake_pay_subtitle, + ), + ], + ), + ), + ], + ), + ), + ), + ); + } +} diff --git a/lib/src/widgets/market_place_item.dart b/lib/src/widgets/market_place_item.dart new file mode 100644 index 000000000..ed3b90a4e --- /dev/null +++ b/lib/src/widgets/market_place_item.dart @@ -0,0 +1,129 @@ +import 'package:flutter/material.dart'; +import 'package:cached_network_image/cached_network_image.dart'; + +class MarketPlaceItem extends StatelessWidget { + final VoidCallback onTap; + final String title; + final String subTitle; + final String logoUrl; + final EdgeInsets padding; + final bool hasDiscount; + + MarketPlaceItem({ + @required this.onTap, + @required this.title, + @required this.subTitle, + this.logoUrl, + this.padding, + this.hasDiscount = false, + }); + + @override + Widget build(BuildContext context) { + return InkWell( + onTap: onTap, + child: Stack( + children: [ + Container( + padding: padding ?? EdgeInsets.all(20), + width: double.infinity, + decoration: BoxDecoration( + color: Colors.white.withOpacity(0.20), + borderRadius: BorderRadius.circular(20), + border: Border.all( + color: Colors.white.withOpacity(0.20), + ), + ), + child: Row( + children: [ + if (logoUrl != null) ...[ + ClipOval( + child: CachedNetworkImage( + width: 42.0, + height: 42.0, + imageUrl: logoUrl, + placeholder: (context, url) => _PlaceholderContainer(text: 'Logo'), + errorWidget: (context, url, error) => _PlaceholderContainer(text: '!'), + ), + ), + SizedBox(width: 5), + ], + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + title, + style: TextStyle( + color: Colors.white, + fontSize: 24, + fontWeight: FontWeight.w900, + ), + ), + SizedBox(height: 5), + Text( + subTitle, + style: TextStyle( + color: Colors.white, + ), + ) + ], + ), + ], + ), + ), + if (hasDiscount) ...[ + Align( + alignment: Alignment.centerRight, + child: Padding( + padding: const EdgeInsets.only(top: 20.0), + child: Image.asset('assets/images/badge_discount.png'), + ), + ), + Align( + alignment: Alignment.centerRight, + child: Padding( + padding: const EdgeInsets.only(top: 22.0, right: 2), + child: Text( + 'Save 20%', + style: TextStyle( + color: Colors.white, + fontWeight: FontWeight.w500, + fontFamily: 'Lato', + ), + ), + ), + ) + ], + ], + ), + ); + } +} + +class _PlaceholderContainer extends StatelessWidget { + final String text; + + const _PlaceholderContainer({@required this.text}); + + @override + Widget build(BuildContext context) { + return Container( + height: 42, + width: 42, + child: Center( + child: Text( + text, + style: TextStyle( + color: Colors.black, + fontSize: 12, + fontWeight: FontWeight.w900, + ), + ), + ), + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(100), + ), + ); + } +} diff --git a/res/values/strings_en.arb b/res/values/strings_en.arb index 2de02e8b8..7366e0a62 100644 --- a/res/values/strings_en.arb +++ b/res/values/strings_en.arb @@ -527,5 +527,21 @@ "learn_more" : "Learn More", "search": "Search", "new_template" : "New Template", - "electrum_address_disclaimer": "We generate new addresses each time you use one, but previous addresses continue to work" + "electrum_address_disclaimer": "We generate new addresses each time you use one, but previous addresses continue to work", + "market_place": "Market place", + "cake_pay_title": "Gift cards and debit cards", + "cake_pay_subtitle": "Buy gift cards and top up no-KYC debit cards", + "about_cake_pay": "CakePay allows you to easily buy gift cards and load up prepaid debit cards with cryptocurrencies, spendable at millions of merchants in the United States.", + "cake_pay_account_note": "Make an account to see the available cards. Some are even available at a discount!", + "already_have_account": "Already have an account?", + "create_account": "Create Account", + "privacy_policy": "Privacy policy", + "welcome_to_cakepay": "Welcome to CakePay!", + "sign_up": "Sign Up", + "forgot_password": "Forgot Password", + "reset_password": "Reset Password", + "manage_cards": "Manage Cards", + "setup_your_debit_card": "Set up your debit card", + "no_id_required": "No ID required. Top up and spend anywhere", + "how_to_use_card": "How to use this card" } \ No newline at end of file