4 Commits
dev ... yoga

Author SHA1 Message Date
e441c56bab fix: product view 2024-03-06 16:43:02 +07:00
e513df325c fix: homepage view 2024-03-05 19:25:49 +07:00
23e1a6628f fix: merge origin dev 2024-03-05 15:43:52 +07:00
eb99ad9d7f feat: profile page 2024-02-29 17:14:05 +07:00
34 changed files with 498 additions and 938 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.3 KiB

After

Width:  |  Height:  |  Size: 1.0 KiB

BIN
assets/icons/icon-cat.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.0 KiB

BIN
assets/icons/icon-faqs.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.7 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.1 KiB

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.4 KiB

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

View File

Before

Width:  |  Height:  |  Size: 4.0 MiB

After

Width:  |  Height:  |  Size: 4.0 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 32 KiB

View File

@@ -60,15 +60,17 @@ class PathAssets {
static const String iconNavigationProfile = static const String iconNavigationProfile =
'assets/icons/icon-navigation-profile.png'; 'assets/icons/icon-navigation-profile.png';
static const String iconRemove = 'assets/icons/icon-remove.png'; static const String iconRemove = 'assets/icons/icon-remove.png';
static const String iconCat = 'assets/icons/icon-cat.png';
static const String iconProfile = 'assets/icons/icon-profile.png';
static const String iconPadlock = 'assets/icons/icon-padlock.png';
static const String iconCard = 'assets/icons/icon-card.png';
static const String iconSetting = 'assets/icons/icon-setting.png';
static const String iconFaqs = 'assets/icons/icon-faqs.png';
static const String iconLogout = 'assets/icons/icon-logout.png';
static const String iconEducation = 'assets/icons/icon-education.png'; static const String iconEducation = 'assets/icons/icon-education.png';
static const String iconFund = 'assets/icons/icon-fund.png'; static const String iconFund = 'assets/icons/icon-fund.png';
static const String iconHome = 'assets/icons/icon-home.png'; static const String iconHome = 'assets/icons/icon-home.png';
static const String iconShop = 'assets/icons/icon-shop.png'; static const String iconShop = 'assets/icons/icon-shop.png';
static const String iconCard = 'assets/icons/icon-card.png';
static const String iconChat = 'assets/icons/icon-chat.png';
static const String iconLogout = 'assets/icons/icon-logout.png';
static const String iconProfile = 'assets/icons/icon-profile.png';
static const String iconSetting = 'assets/icons/icon-setting.png';
static const String iconGadgetOutline = static const String iconGadgetOutline =
'assets/icons/icon-gadget-outline.png'; 'assets/icons/icon-gadget-outline.png';
@@ -99,7 +101,6 @@ class PathAssets {
static const String imgMoneyIncome = 'assets/images/img-money-income.png'; static const String imgMoneyIncome = 'assets/images/img-money-income.png';
static const String imgGrowing = 'assets/images/img-growing.png'; static const String imgGrowing = 'assets/images/img-growing.png';
static const String imgCat = 'assets/images/img-cat.png'; static const String imgCat = 'assets/images/img-cat.png';
static const String imgCatOutlined = 'assets/images/img-cat-outlined.png';
static const String imgDeer = 'assets/images/img-deer.png'; static const String imgDeer = 'assets/images/img-deer.png';
static const String imgLion = 'assets/images/img-lion.png'; static const String imgLion = 'assets/images/img-lion.png';
static const String imgGuideBank = 'assets/images/img-guide-bank.png'; static const String imgGuideBank = 'assets/images/img-guide-bank.png';
@@ -110,11 +111,10 @@ class PathAssets {
'assets/images/img-payment-success.png'; 'assets/images/img-payment-success.png';
static const String frameSignature = 'assets/images/frame-signature.png'; static const String frameSignature = 'assets/images/frame-signature.png';
static const String imgFinish = 'assets/images/img-finish.png'; static const String imgFinish = 'assets/images/img-finish.png';
static const String imgExpandPurchase = static const String imgDashboardProfile =
'assets/images/img-expand-purchase.png'; 'assets/images/img-dashboard-profile.png';
static const String imgEmptyTransaction = static const String imgEmptyTransaction =
'assets/images/img-empty-transaction.png'; 'assets/images/img-empty-transaction.png';
static const String bgProfile = 'assets/images/bg-profile.png';
static const Map<String, String> goalInvestIcon = { static const Map<String, String> goalInvestIcon = {
'Education': iconToga, 'Education': iconToga,

View File

@@ -8,26 +8,22 @@ class ListTileView extends StatelessWidget {
final String title; final String title;
final VoidCallback? onPressed; final VoidCallback? onPressed;
final Widget? prefixIcon, suffixIcon; final Widget? prefixIcon, suffixIcon;
final EdgeInsetsGeometry? padding, margin; final Color? colorTitle;
final TextStyle? textStyle;
const ListTileView( const ListTileView(
{Key? key, {Key? key,
required this.title, required this.title,
this.onPressed, this.onPressed,
this.prefixIcon, this.prefixIcon,
this.suffixIcon, this.suffixIcon,
this.padding, this.colorTitle})
this.textStyle,
this.margin})
: super(key: key); : super(key: key);
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Container( return Container(
width: SizeConfig.width, width: SizeConfig.width,
padding: padding ?? padding: const EdgeInsets.symmetric(vertical: 16.0, horizontal: 8.0),
const EdgeInsets.symmetric(vertical: 16.0, horizontal: 8.0), margin: const EdgeInsets.symmetric(vertical: 16.0),
margin: margin ?? const EdgeInsets.symmetric(vertical: 16.0),
decoration: BoxDecoration( decoration: BoxDecoration(
color: ColorPalette.blue50, color: ColorPalette.blue50,
borderRadius: BorderRadius.circular(10), borderRadius: BorderRadius.circular(10),
@@ -51,23 +47,22 @@ class ListTileView extends StatelessWidget {
Expanded( Expanded(
child: Text( child: Text(
title, title,
style: textStyle ?? style: TextStyle(
const TextStyle( fontWeight: FontWeight.w600,
fontWeight: FontWeight.w600, color: colorTitle ?? ColorPalette.slate500,
color: ColorPalette.slate500, ),
),
), ),
), ),
suffixIcon ?? suffixIcon != null
IconButton( ? IconButton(
onPressed: onPressed, onPressed: onPressed,
icon: const Icon( icon: const Icon(
Icons.arrow_forward_ios, Icons.arrow_forward_ios,
color: ColorPalette.primary, color: ColorPalette.primary,
size: 20, size: 20,
), ),
), )
// : const SizedBox(), : const SizedBox(),
], ],
), ),
); );

View File

@@ -1,5 +1,3 @@
import 'package:cims_apps/application/assets/path_assets.dart';
import 'package:cims_apps/application/component/image/image_view.dart';
import 'package:cims_apps/application/theme/color_palette.dart'; import 'package:cims_apps/application/theme/color_palette.dart';
import 'package:cims_apps/core/utils/size_config.dart'; import 'package:cims_apps/core/utils/size_config.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
@@ -86,7 +84,7 @@ class NumericPad extends StatelessWidget {
} }
Widget spaceWidget() { Widget spaceWidget() {
return Expanded( return const Expanded(
child: SizedBox() child: SizedBox()
); );
} }
@@ -98,11 +96,12 @@ class NumericPad extends StatelessWidget {
onNumberSelected(number); onNumberSelected(number);
}, },
child: Container( child: Container(
color: Colors.transparent,
padding: EdgeInsets.symmetric(vertical: SizeConfig.height * .028), padding: EdgeInsets.symmetric(vertical: SizeConfig.height * .028),
child: Text( child: Text(
number, number,
textAlign: TextAlign.center, textAlign: TextAlign.center,
style: TextStyle( style: const TextStyle(
fontSize: 28, fontSize: 28,
fontWeight: FontWeight.bold, fontWeight: FontWeight.bold,
color: ColorPalette.slate800 color: ColorPalette.slate800
@@ -119,10 +118,14 @@ class NumericPad extends StatelessWidget {
onTap: () { onTap: () {
onNumberSelected(''); onNumberSelected('');
}, },
child: Icon( child: Container(
Icons.backspace_outlined, color: Colors.transparent,
size: 28, padding: EdgeInsets.symmetric(vertical: SizeConfig.height * .028),
color: ColorPalette.slate800, child: const Icon(
Icons.backspace_outlined,
size: 28,
color: ColorPalette.slate800,
),
), ),
) )
); );

View File

@@ -190,6 +190,18 @@ class TextFormView extends StatelessWidget {
color: focusedBorderColor ?? ColorPalette.greyBorder, color: focusedBorderColor ?? ColorPalette.greyBorder,
), ),
), ),
errorBorder: OutlineInputBorder(
borderRadius: _borderRadius,
borderSide: BorderSide(
color: ColorPalette.red600
)
),
focusedErrorBorder: OutlineInputBorder(
borderRadius: _borderRadius,
borderSide: BorderSide(
color: ColorPalette.red600
)
),
border: OutlineInputBorder(borderRadius: _borderRadius), border: OutlineInputBorder(borderRadius: _borderRadius),
suffixIcon: suffixIcon, suffixIcon: suffixIcon,
prefixIcon: prefixIcon, prefixIcon: prefixIcon,

View File

@@ -5,17 +5,20 @@ class TextTitle extends StatelessWidget {
final String title; final String title;
final Color? color; final Color? color;
final double? fontSize; final double? fontSize;
final TextAlign? textAlign;
const TextTitle({ const TextTitle({
Key? key, Key? key,
required this.title, required this.title,
this.color, this.color,
this.fontSize, this.fontSize,
this.textAlign,
}) : super(key: key); }) : super(key: key);
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Text( return Text(
title, title,
textAlign: textAlign,
style: TextStyle( style: TextStyle(
fontSize: fontSize ?? 20, fontSize: fontSize ?? 20,
fontWeight: FontWeight.w700, fontWeight: FontWeight.w700,

View File

@@ -75,6 +75,7 @@ class ColorPalette {
static const Color backgroundBlueLight = Color(0xFFEBF3FD); static const Color backgroundBlueLight = Color(0xFFEBF3FD);
static const Color blue50 = Color(0xFFEFF6FF); static const Color blue50 = Color(0xFFEFF6FF);
static const Color blue200 = Color(0xFFBFDBFE); static const Color blue200 = Color(0xFFBFDBFE);
static const Color blue600 = Color(0xFF2563EB);
static const Color blue900 = Color(0xFF1E3A8A); static const Color blue900 = Color(0xFF1E3A8A);
static const Color slate50 = Color(0xFFF8FAFC); static const Color slate50 = Color(0xFFF8FAFC);
static const Color slate200 = Color(0xFFE2E8F0); static const Color slate200 = Color(0xFFE2E8F0);
@@ -90,9 +91,11 @@ class ColorPalette {
static const Color cyan100 = Color(0xFFCFFAFE); static const Color cyan100 = Color(0xFFCFFAFE);
static const Color cyan500 = Color(0xFF06B6D4); static const Color cyan500 = Color(0xFF06B6D4);
static const Color green100 = Color(0xFFDCFCE7); static const Color green100 = Color(0xFFDCFCE7);
static const Color green300 = Color(0xFF86EFAC);
static const Color green400 = Color(0xFF4ADE80); static const Color green400 = Color(0xFF4ADE80);
static const Color green500 = Color(0xFF16A34A); static const Color green500 = Color(0xFF16A34A);
static const Color red600 = Color(0xffDC2626); static const Color red600 = Color(0xFFDC2626);
static const Color red50 = Color(0xFFFEF2F2);
static const Map<String, Color> investTypeColor = { static const Map<String, Color> investTypeColor = {
'Money Market': purple500, 'Money Market': purple500,
@@ -107,4 +110,16 @@ class ColorPalette {
'Sharia': green100, 'Sharia': green100,
'Bonds': cyan100 'Bonds': cyan100
}; };
static const Map<String, Color> riskColor = {
'Moderate': orange500,
'Conservative': green500,
'Aggressive': cyan500
};
static const Map<String, Color> textRiskColor = {
'Moderate': orange500,
'Conservative': green300,
'Aggressive': cyan500
};
} }

View File

@@ -1,6 +1,3 @@
import 'package:cims_apps/application/theme/color_palette.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:intl/intl.dart'; import 'package:intl/intl.dart';
class StringUtils { class StringUtils {
@@ -26,16 +23,4 @@ class StringUtils {
} }
return '--:--:--'; return '--:--:--';
} }
static void iCopyToClipboard(BuildContext context,
{String? desc, required String text}) {
Clipboard.setData(ClipboardData(text: text));
ScaffoldMessenger.of(context)
.showSnackBar(SnackBar(
backgroundColor: ColorPalette.primary,
content: Text(desc ?? "Text copied to clipboard"),
))
.closed
.then((value) => ScaffoldMessenger.of(context).removeCurrentSnackBar());
}
} }

View File

@@ -52,7 +52,7 @@ class PhoneNumberView extends StatelessWidget {
width: SizeConfig.width * .23, width: SizeConfig.width * .23,
padding: padding:
const EdgeInsets.symmetric(horizontal: 16.0), const EdgeInsets.symmetric(horizontal: 16.0),
margin: const EdgeInsets.only(right: 16), margin: const EdgeInsets.only(right: 16, left: 1, top: 1, bottom: 1),
decoration: const BoxDecoration( decoration: const BoxDecoration(
color: ColorPalette.grey, color: ColorPalette.grey,
borderRadius: BorderRadius.only( borderRadius: BorderRadius.only(

View File

@@ -4,7 +4,7 @@ import 'package:cims_apps/core/utils/size_config.dart';
import 'package:cims_apps/features/dashboard/dashboard_account/view/homepage/homepage_view.dart'; import 'package:cims_apps/features/dashboard/dashboard_account/view/homepage/homepage_view.dart';
import 'package:cims_apps/features/dashboard/dashboard_account/view/plan/view/plan_view.dart'; import 'package:cims_apps/features/dashboard/dashboard_account/view/plan/view/plan_view.dart';
import 'package:cims_apps/features/dashboard/dashboard_account/view/portfolio/portfolio_view.dart'; import 'package:cims_apps/features/dashboard/dashboard_account/view/portfolio/portfolio_view.dart';
import 'package:cims_apps/features/profile/view/profile_view.dart'; import 'package:cims_apps/features/dashboard/dashboard_account/view/profile/view/profile_view.dart';
import 'package:cims_apps/features/transaction/view/transaction_view.dart'; import 'package:cims_apps/features/transaction/view/transaction_view.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';

View File

@@ -50,7 +50,7 @@ class _HomeViewState extends State<HomeView> {
]; ];
StepVerification listStepVerification = StepVerification listStepVerification =
StepVerification(0, ['Registration', 'Verification', 'Complete']); StepVerification(1, ['Registration', '', 'Verification', '', 'Complete']);
List<Article> listArticle = [ List<Article> listArticle = [
Article( Article(
@@ -69,77 +69,90 @@ class _HomeViewState extends State<HomeView> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Scaffold( return Scaffold(
backgroundColor: const Color(0xffF8FAFC), backgroundColor: ColorPalette.slate50,
body: SizedBox( body: CustomScrollView(
width: SizeConfig.width, slivers: [
height: SizeConfig.height, SliverAppBar(
child: Stack( onStretchTrigger: () async {
children: [ },
const ImageView(image: PathAssets.imgDashboardAccount), expandedHeight: 325,
Column( collapsedHeight: 325,
children: [ leading: const SizedBox(),
const SizedBox( surfaceTintColor: ColorPalette.slate50,
height: 50, backgroundColor: ColorPalette.slate50,
), flexibleSpace: FlexibleSpaceBar(
Padding( background: Stack(
padding: const EdgeInsets.only(left: 24, right: 16), children: [
child: Row( const ImageView(image: PathAssets.imgDashboardAccount),
mainAxisAlignment: MainAxisAlignment.spaceBetween, Column(
children: [ children: [
const Text( const SizedBox(
'Home', height: 50,
style: TextStyle( ),
color: Colors.white, Padding(
fontSize: 20, padding: const EdgeInsets.only(left: 24, right: 16),
fontWeight: FontWeight.w700), child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
const Text(
'Home',
style: TextStyle(
color: Colors.white,
fontSize: 20,
fontWeight: FontWeight.w700),
),
ElevatedButton(
onPressed: () {},
style: ElevatedButton.styleFrom(
padding: const EdgeInsets.all(0),
backgroundColor: Colors.white,
foregroundColor: const Color(0xff2563EB),
elevation: 0,
shape: const CircleBorder()),
child: const Icon(Icons.notifications_outlined))
],
),
),
const SizedBox(
height: 32,
),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 24),
child: portofolioValue(),
),
const SizedBox(
height: 24,
),
cardInvestType(),
const SizedBox(
height: 24,
), ),
ElevatedButton(
onPressed: () {},
style: ElevatedButton.styleFrom(
padding: const EdgeInsets.all(0),
backgroundColor: Colors.white,
foregroundColor: const Color(0xff2563EB),
elevation: 0,
shape: const CircleBorder()),
child: const Icon(Icons.notifications_outlined))
], ],
), )
), ],
const SizedBox( ),
height: 32, ),
), floating: true,
Padding( snap: true,
padding: const EdgeInsets.symmetric(horizontal: 24), ),
child: portofolioValue(), SliverToBoxAdapter(
), child: Column(
children: [
cardVerification(),
const SizedBox( const SizedBox(
height: 24, height: 24,
), ),
cardInvestType(), infoAndPromo(),
const SizedBox( const SizedBox(
height: 32, height: 24,
),
Expanded(
child: ListView(
padding: const EdgeInsets.all(0),
children: [
cardVerification(),
const SizedBox(
height: 24,
),
infoAndPromo(),
const SizedBox(
height: 24,
),
articles(),
],
),
), ),
articles(),
], ],
) ),
], )
), ],
), ),
); );
} }
@@ -279,9 +292,10 @@ class _HomeViewState extends State<HomeView> {
child: Column( child: Column(
children: [ children: [
stepVerification(), stepVerification(),
const SizedBox( if(listStepVerification.currentStep < 3)
height: 24, const SizedBox(
), height: 24,
),
if (listStepVerification.currentStep == 1) ...[ if (listStepVerification.currentStep == 1) ...[
Row( Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween, mainAxisAlignment: MainAxisAlignment.spaceBetween,
@@ -291,6 +305,7 @@ class _HomeViewState extends State<HomeView> {
Icon( Icon(
Icons.verified, Icons.verified,
size: 18, size: 18,
color: ColorPalette.slate300,
), ),
SizedBox( SizedBox(
width: 12, width: 12,
@@ -324,6 +339,7 @@ class _HomeViewState extends State<HomeView> {
Icon( Icon(
Icons.verified, Icons.verified,
size: 18, size: 18,
color: ColorPalette.slate300,
), ),
SizedBox( SizedBox(
width: 12, width: 12,
@@ -388,11 +404,11 @@ class _HomeViewState extends State<HomeView> {
borderRadius: BorderRadius.circular(12)), borderRadius: BorderRadius.circular(12)),
child: Column( child: Column(
children: [ children: [
Text( const Text(
"Let's start registering your data to start mutual fund investment at PT Gemilang Indonesia", "Let's start registering your data to start mutual fund investment at PT Gemilang Indonesia",
style: TextStyle(color: ColorPalette.slate500), style: TextStyle(color: ColorPalette.slate500),
), ),
SizedBox( const SizedBox(
height: 16, height: 16,
), ),
ButtonView( ButtonView(
@@ -400,9 +416,9 @@ class _HomeViewState extends State<HomeView> {
width: SizeConfig.width, width: SizeConfig.width,
marginVertical: 0, marginVertical: 0,
heightWrapContent: true, heightWrapContent: true,
contentPadding: EdgeInsets.all(12), contentPadding: const EdgeInsets.all(12),
onPressed: () { onPressed: () {
routePush(context, page: InitialRegistrationStep()); routePush(context, page: const InitialRegistrationStep());
}, },
) )
], ],
@@ -417,57 +433,61 @@ class _HomeViewState extends State<HomeView> {
Widget stepVerification() { Widget stepVerification() {
return Row( return Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween, mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: listStepVerification.nameStep.asMap().entries.map((e) { crossAxisAlignment: CrossAxisAlignment.start,
return Row( children: List.generate(
crossAxisAlignment: CrossAxisAlignment.start, listStepVerification.nameStep.length,
children: [ (index) {
if (e.key != 0) print(index % 2);
SizedBox( if (index % 2 == 0) {
width: 30, final currentStep = index ~/ 2;
height: 30, return Column(
child: Divider(
color: listStepVerification.currentStep >= e.key
? const Color(0xff2563EB)
: const Color(0xffCBD5E1),
),
),
Column(
children: [ children: [
Container( Container(
width: 30, width: 30,
height: 30, height: 30,
decoration: BoxDecoration( decoration: BoxDecoration(
shape: BoxShape.circle, shape: BoxShape.circle,
color: listStepVerification.currentStep <= e.key color: listStepVerification.currentStep <= currentStep
? Colors.white ? Colors.white
: const Color(0xff2563EB),
border: Border.all(
color: listStepVerification.currentStep < currentStep
? const Color(0xffCBD5E1)
: const Color(0xff2563EB), : const Color(0xff2563EB),
border: Border.all( width: 2,
color: listStepVerification.currentStep < e.key ),
? const Color(0xffCBD5E1) ),
: const Color(0xff2563EB), child: listStepVerification.currentStep <= currentStep
width: 2)),
child: listStepVerification.currentStep <= e.key
? const SizedBox() ? const SizedBox()
: const Icon( : const Icon(
Icons.done_rounded, Icons.done_rounded,
color: Colors.white, color: Colors.white,
), ),
),
const SizedBox(
height: 8,
), ),
const SizedBox(height: 8),
Text( Text(
e.value, listStepVerification.nameStep[index],
style: TextStyle( style: TextStyle(
color: listStepVerification.currentStep == e.key color: listStepVerification.currentStep == currentStep
? const Color(0xff2563EB) ? const Color(0xff2563EB)
: Colors.black), : Colors.black,
) ),
),
], ],
), );
], } else {
); return SizedBox(
}).toList(), width: 30,
height: 30,
child: Divider(
color: listStepVerification.currentStep > index ~/ 2
? const Color(0xff2563EB)
: const Color(0xffCBD5E1),
),
);
}
},
),
); );
} }
@@ -591,7 +611,7 @@ class _HomeViewState extends State<HomeView> {
color: ColorPalette.green100), color: ColorPalette.green100),
child: Text( child: Text(
article.type, article.type,
style: TextStyle( style: const TextStyle(
fontWeight: FontWeight.w600, fontWeight: FontWeight.w600,
color: ColorPalette.green500), color: ColorPalette.green500),
), ),

View File

@@ -388,7 +388,7 @@ class _PortofolioViewState extends State<PortofolioView> {
Widget cardPortfolio() { Widget cardPortfolio() {
return GestureDetector( return GestureDetector(
onTap: () { onTap: () {
routePush(context, page: const PortfolioDetailView()); // routePush(context, page: const PortfolioDetailView());
}, },
child: Container( child: Container(
margin: const EdgeInsets.symmetric(horizontal: 24), margin: const EdgeInsets.symmetric(horizontal: 24),

View File

@@ -13,6 +13,7 @@ import 'package:cims_apps/features/dashboard/dashboard_account/view/product/view
import 'package:cims_apps/features/dashboard/dashboard_account/view/product/view/step_subscribe/select_goal_investing.dart'; import 'package:cims_apps/features/dashboard/dashboard_account/view/product/view/step_subscribe/select_goal_investing.dart';
import 'package:cims_apps/features/dashboard/dashboard_account/view/product/view_model/product_view_model.dart'; import 'package:cims_apps/features/dashboard/dashboard_account/view/product/view_model/product_view_model.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:group_button/group_button.dart'; import 'package:group_button/group_button.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
@@ -79,6 +80,8 @@ class _ProductViewState extends State<ProductView> {
}); });
} }
double currentScroll = 0;
@override @override
void initState() { void initState() {
machineController.text = NumberFormatter.numberCurrency(100000, 'Rp ', 'id_ID', decimalDigits: 0); machineController.text = NumberFormatter.numberCurrency(100000, 'Rp ', 'id_ID', decimalDigits: 0);
@@ -104,64 +107,106 @@ class _ProductViewState extends State<ProductView> {
return ChangeNotifierProvider( return ChangeNotifierProvider(
create: (context) => ProductViewModel(), create: (context) => ProductViewModel(),
child: Scaffold( child: Scaffold(
body: SizedBox( body: NotificationListener<ScrollNotification>(
child: Stack( onNotification: (notification) {
children: [ setState(() {
const ImageView(image: PathAssets.imgDashboardAccount), currentScroll = notification.metrics.pixels;
Column( });
children: [ return false;
const SizedBox( },
height: 50, child: CustomScrollView(
), slivers: [
const Padding( SliverAppBar(
padding: EdgeInsets.symmetric(horizontal: 24), toolbarHeight: 70,
child: Row( expandedHeight: 170,
mainAxisAlignment: MainAxisAlignment.spaceBetween, leadingWidth: 0,
children: [ floating: false,
BackButtonView(), automaticallyImplyLeading: false,
Wrap( title: AnimatedCrossFade(
spacing: 12, firstChild: Text(
children: [ widget.selectedProduct.name ?? '',
Icon(Icons.search_rounded, color: ColorPalette.blue200, size: 32), maxLines: 2,
Icon(Icons.file_download_outlined, color: ColorPalette.blue200, size: 32), overflow: TextOverflow.ellipsis,
Icon(Icons.star_outline_rounded, color: ColorPalette.blue200, size: 32) style: TextStyle(
], color: Colors.white,
) fontWeight: FontWeight.w700,
], fontSize: 18
), ),
), ),
const SizedBox( secondChild: Padding(
height: 24, padding: const EdgeInsets.only(left: 8),
child: BackButtonView(),
), ),
headContainer(), crossFadeState: currentScroll >= 85 ? CrossFadeState.showFirst : CrossFadeState.showSecond,
const SizedBox( duration: Duration(milliseconds: 200)
height: 24, ),
centerTitle: false,
snap: false,
pinned: true,
backgroundColor: Color(0xFF1745C8).withOpacity(currentScroll >= 95 ? 1 : currentScroll / 95),
surfaceTintColor: ColorPalette.primary,
actions: [
Wrap(
spacing: 12,
children: [
Icon(Icons.search_rounded, color: ColorPalette.blue200, size: 32),
Icon(Icons.file_download_outlined, color: ColorPalette.blue200, size: 32),
Icon(Icons.star_outline_rounded, color: ColorPalette.blue200, size: 32)
],
), ),
Expanded( SizedBox(width: 24,)
child: contentContainer()
)
], ],
flexibleSpace: Opacity(
opacity: currentScroll > 0 ? ((95 - currentScroll) / 95) > 0.01 ? ((95 - currentScroll) / 95) : 0 : 1,
child: Stack(
children: [
ImageView(image: PathAssets.imgDashboardAccount, width: SizeConfig.width, height: 200),
Column(
mainAxisAlignment: MainAxisAlignment.end,
children: [
headContainer(),
const SizedBox(
height: 24,
),
Container(
height: 12,
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.only(
topLeft: Radius.circular(12),
topRight: Radius.circular(12)
)
),
)
],
)
],
),
),
),
SliverToBoxAdapter(
child: contentContainer(),
) )
], ],
), ),
), ),
bottomNavigationBar: !widget.seeMore ? bottomNavigationBar: !widget.seeMore ?
Container( Container(
height: SizeConfig.height * .1, height: SizeConfig.height * .1,
padding: const EdgeInsets.symmetric(horizontal: 24), padding: const EdgeInsets.symmetric(horizontal: 24),
child: ButtonView( child: ButtonView(
name: 'Subscribe', name: 'Subscribe',
onPressed: () { onPressed: () {
showModalBottomSheet( showModalBottomSheet(
context: context, context: context,
isScrollControlled: true, isScrollControlled: true,
builder: (context) => SelectGoalInvesting(), builder: (context) => SelectGoalInvesting(),
); );
}, },
height: SizeConfig.height * 0.06, height: SizeConfig.height * 0.06,
marginVertical: 16, marginVertical: 16,
), ),
) : SizedBox(), ) : SizedBox(),
), ),
); );
} }
@@ -220,8 +265,11 @@ class _ProductViewState extends State<ProductView> {
decoration: BoxDecoration( decoration: BoxDecoration(
color: Colors.white, color: Colors.white,
), ),
child: ListView( child: Column(
children: [ children: [
const SizedBox(
height: 12,
),
ProductChartView( ProductChartView(
tabType: listTab[selectedTab], tabType: listTab[selectedTab],
lastTime: selectedTime.completeName, lastTime: selectedTime.completeName,

View File

@@ -0,0 +1,165 @@
import 'package:cims_apps/application/assets/path_assets.dart';
import 'package:cims_apps/application/component/image/image_view.dart';
import 'package:cims_apps/application/component/text_title/text_title.dart';
import 'package:cims_apps/application/theme/color_palette.dart';
import 'package:cims_apps/core/utils/size_config.dart';
import 'package:cims_apps/features/dashboard/dashboard_account/view/profile/view_model/profile_view_model.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
class RouteNavigation {
String icon;
String title;
Widget destination;
RouteNavigation(this.icon, this.title, this.destination);
}
class ProfileView extends StatelessWidget {
const ProfileView({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
List<RouteNavigation> listGeneral = [
RouteNavigation(PathAssets.iconProfile, 'Personal Data', Container()),
RouteNavigation(PathAssets.iconPadlock, 'Change Password', Container()),
RouteNavigation(PathAssets.iconCard, 'Add Card', Container()),
RouteNavigation(PathAssets.iconSetting, 'Settings', Container())
];
List<RouteNavigation> listPreferences = [
RouteNavigation(PathAssets.iconFaqs, 'FAQs', Container()),
RouteNavigation(PathAssets.iconLogout, 'Log Out', Container())
];
return Provider(
create: (context) => ProfileViewModel(),
child: Scaffold(
body: SizedBox(
width: SizeConfig.width,
height: SizeConfig.height,
child: Stack(
children: [
const Positioned(
left: 0,
right: 0,
top: 0,
bottom: 0,
child: ImageView(image: PathAssets.imgDashboardProfile)
),
Consumer<ProfileViewModel>(
builder: (context, provider, child) {
return ListView(
padding: const EdgeInsets.all(0),
children: [
const SizedBox(
height: 50,
),
const Center(
child: TextTitle(title: 'Profile', color: Colors.white, fontSize: 20,)
),
SizedBox(
height: SizeConfig.height * 0.05,
),
Container(
alignment: Alignment.center,
decoration: BoxDecoration(
shape: BoxShape.circle,
color: Colors.white,
border: Border.all(color: ColorPalette.slate200, width: 1.5)
),
padding: const EdgeInsets.all(8),
child: ImageView(image: PathAssets.iconCat, width: SizeConfig.width * 0.14,),
),
const SizedBox(height: 16),
Center(
child: TextTitle(title: provider.getUser.name ?? '', color: Colors.white, fontSize: 24,)),
Text('Investor ${provider.getUser.risk}',
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 16,
color: ColorPalette.textRiskColor[provider.getUser.risk]
),
),
const SizedBox(height: 24),
boxNavigation('General', listGeneral),
const SizedBox(height: 24),
boxNavigation('Preferences', listPreferences)
],
);
}
)
],
),
),
),
);
}
Widget boxNavigation(String title, List<RouteNavigation> list) {
return Container(
padding: const EdgeInsets.all(16),
margin: const EdgeInsets.symmetric(horizontal: 24),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(12),
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(title,
style: const TextStyle(
fontWeight: FontWeight.w700,
color: ColorPalette.slate400
),
),
const SizedBox(height: 16),
Wrap(
runSpacing: 16,
children: list.map((e) {
return rowNavigation(
e.icon,
e.title,
e.destination
);
}).toList(),
)
],
),
);
}
Widget rowNavigation(String icon, String text, Widget destination) {
bool isLogout = text == 'Log Out';
Color textColor = isLogout ? ColorPalette.red600 : ColorPalette.slate800;
Color bgLeadingColor = isLogout ? ColorPalette.red50 : ColorPalette.blue50;
Color iconColor = isLogout ? ColorPalette.red600 : ColorPalette.blue600;
return Row(
children: [
Container(
alignment: Alignment.center,
padding: const EdgeInsets.all(4),
decoration: BoxDecoration(
shape: BoxShape.circle,
color: bgLeadingColor
),
child: Image.asset(icon, width: SizeConfig.width * 0.05, color: iconColor)
),
Expanded(
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 16),
child: Text(text,
style: TextStyle(
fontWeight: FontWeight.w600,
fontSize: 16,
color: textColor
),
),
),
),
const Icon(Icons.chevron_right_outlined, size: 28, color: ColorPalette.slate400)
],
);
}
}

View File

@@ -0,0 +1,11 @@
class User {
String? name, risk;
User({this.name, this.risk});
}
class ProfileViewModel {
static final User _user = User(name: 'Muhammad Rosyidin', risk: 'Conservative');
User get getUser => _user;
}

View File

@@ -44,7 +44,7 @@ class DashboardPublicView extends StatelessWidget {
return Scaffold( return Scaffold(
body: SingleChildScrollView( body: SingleChildScrollView(
padding: const EdgeInsets.only( padding: const EdgeInsets.only(
bottom: 8.0, bottom: 24.0,
left: 24.0, left: 24.0,
right: 24.0, right: 24.0,
), ),
@@ -59,6 +59,7 @@ class DashboardPublicView extends StatelessWidget {
image: PathAssets.icon1, image: PathAssets.icon1,
width: SizeConfig.width * .35, width: SizeConfig.width * .35,
), ),
SizedBox(height: SizeConfig.height * .02),
Align( Align(
alignment: Alignment.center, alignment: Alignment.center,
heightFactor: 1, heightFactor: 1,
@@ -105,7 +106,7 @@ class DashboardPublicView extends StatelessWidget {
provider.loginGoogle(context); provider.loginGoogle(context);
}, },
), ),
SizedBox(height: SizeConfig.height * .1), SizedBox(height: SizeConfig.height * .07),
Row( Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween, mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [ children: [

View File

@@ -1,8 +0,0 @@
import 'package:flutter/material.dart';
class ListMenuModel {
final String title, pathAsset;
final Widget page;
ListMenuModel(
{required this.title, required this.pathAsset, required this.page});
}

View File

@@ -1,119 +0,0 @@
import 'package:cims_apps/application/assets/path_assets.dart';
import 'package:cims_apps/application/component/image/image_view.dart';
import 'package:cims_apps/application/theme/color_palette.dart';
import 'package:cims_apps/core/utils/size_config.dart';
import 'package:cims_apps/features/profile/model/list_menu_model.dart';
import 'package:flutter/material.dart';
class ProfileView extends StatelessWidget {
const ProfileView({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
List<ListMenuModel> listMenuGeneral = [
ListMenuModel(
title: 'Personal Data',
pathAsset: PathAssets.iconProfile,
page: Container()),
ListMenuModel(
title: 'Change Password',
pathAsset: PathAssets.iconLock,
page: Container()),
ListMenuModel(
title: 'Add Card', pathAsset: PathAssets.iconCard, page: Container()),
ListMenuModel(
title: 'Settings',
pathAsset: PathAssets.iconSetting,
page: Container()),
];
List<ListMenuModel> listMenuPreferences = [
ListMenuModel(
title: 'FAQs', pathAsset: PathAssets.iconChat, page: Container()),
ListMenuModel(
title: 'Log Out',
pathAsset: PathAssets.iconLogout,
page: Container()),
];
TextStyle textStyle = const TextStyle(
fontSize: 20,
fontWeight: FontWeight.bold,
color: Colors.white,
);
Widget cardContent(
{required String title, required List<ListMenuModel> listMenu}) {
return Container(
width: SizeConfig.width,
padding: const EdgeInsets.all(16.0),
decoration: const BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.all(Radius.circular(12))),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(title),
...listMenu.map((e) {
return Padding(
padding: const EdgeInsets.only(top: 8.0),
child: ListTile(
title: Text(e.title),
contentPadding: EdgeInsets.zero,
leading: ImageView(
image: e.pathAsset, width: SizeConfig.width * .08),
trailing: const Icon(Icons.arrow_forward_ios,
color: ColorPalette.slate400),
onTap: () {
// routePush(context, page: e.page);
},
),
);
}),
],
),
);
}
return Scaffold(
appBar: null,
body: Stack(
children: [
ImageView(image: PathAssets.bgProfile, width: SizeConfig.width),
Container(
width: SizeConfig.width,
padding: const EdgeInsets.only(top: 40.0, left: 16.0, right: 16.0),
child: SingleChildScrollView(
padding: const EdgeInsets.only(bottom: 60.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Text('Profile', style: textStyle),
Padding(
padding: const EdgeInsets.only(top: 40.0, bottom: 8.0),
child: ImageView(
image: PathAssets.imgCatOutlined,
width: SizeConfig.width * .28,
),
),
Text('Muhamad Rosyidin',
style: textStyle.copyWith(fontSize: 24)),
Text('Investor Conservative',
style: textStyle.copyWith(
fontSize: 16,
fontWeight: FontWeight.normal,
color: ColorPalette.green400,
)),
SizedBox(height: SizeConfig.height * .02),
cardContent(title: 'General', listMenu: listMenuGeneral),
SizedBox(height: SizeConfig.height * .03),
cardContent(
title: 'Preference', listMenu: listMenuPreferences),
],
),
),
),
],
),
);
}
}

View File

@@ -1,10 +1,5 @@
import 'package:cims_apps/application/assets/path_assets.dart';
import 'package:cims_apps/application/component/card_transaction/card_transaction_view.dart'; import 'package:cims_apps/application/component/card_transaction/card_transaction_view.dart';
import 'package:cims_apps/application/component/card_transaction/empty_card_transaction.dart'; import 'package:cims_apps/application/component/card_transaction/empty_card_transaction.dart';
import 'package:cims_apps/core/route/route.dart';
import 'package:cims_apps/core/utils/number_formatter.dart';
import 'package:cims_apps/core/utils/string_utils.dart';
import 'package:cims_apps/features/transaction/view/subscribe_detail_view.dart';
import 'package:cims_apps/features/transaction/viewmodel/transaction_viewmodel.dart'; import 'package:cims_apps/features/transaction/viewmodel/transaction_viewmodel.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
@@ -18,29 +13,18 @@ class CancelView extends StatelessWidget {
child: Consumer<TransactionViewModel>( child: Consumer<TransactionViewModel>(
builder: (context, provider, child) => Column( builder: (context, provider, child) => Column(
children: [ children: [
if (provider.listCancelTransaction.isEmpty) if (provider.listOnProcessTransaction.isEmpty)
EmptyCardTransaction( EmptyCardTransaction(
onPressedButton: () {}, onPressedButton: () {},
), ),
...provider.listCancelTransaction.map((e) { ...provider.listOnProcessTransaction.map((e) {
return CardTransactionView( return CardTransactionView(
onTap: () {
routePush(context,
page: const SubscribeDetailView(
type: 'virtual',
));
},
iconPath: PathAssets.iconEducation,
type: 'Education',
amount: NumberFormatter.numberCurrency(
6000000,
'Rp ',
'id_ID',
decimalDigits: 0,
),
timeTransaction: StringUtils.formatTime(DateTime.now()),
subs: '3 Subscription',
step: 'cancel', step: 'cancel',
type: 'type',
amount: 'amount',
iconPath: 'iconPath',
subs: 'subs',
onTap: () {},
); );
}), }),
], ],

View File

@@ -1,10 +1,5 @@
import 'package:cims_apps/application/assets/path_assets.dart';
import 'package:cims_apps/application/component/card_transaction/card_transaction_view.dart'; import 'package:cims_apps/application/component/card_transaction/card_transaction_view.dart';
import 'package:cims_apps/application/component/card_transaction/empty_card_transaction.dart'; import 'package:cims_apps/application/component/card_transaction/empty_card_transaction.dart';
import 'package:cims_apps/core/route/route.dart';
import 'package:cims_apps/core/utils/number_formatter.dart';
import 'package:cims_apps/core/utils/string_utils.dart';
import 'package:cims_apps/features/transaction/view/subscribe_detail_view.dart';
import 'package:cims_apps/features/transaction/viewmodel/transaction_viewmodel.dart'; import 'package:cims_apps/features/transaction/viewmodel/transaction_viewmodel.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
@@ -19,29 +14,18 @@ class DoneView extends StatelessWidget {
builder: (context, provider, child) { builder: (context, provider, child) {
return Column( return Column(
children: [ children: [
if (provider.listDoneTransaction.isEmpty) if (provider.listOnProcessTransaction.isEmpty)
EmptyCardTransaction( EmptyCardTransaction(
onPressedButton: () {}, onPressedButton: () {},
), ),
...provider.listDoneTransaction.map((e) { ...provider.listOnProcessTransaction.map((e) {
return CardTransactionView( return CardTransactionView(
onTap: () {
routePush(context,
page: const SubscribeDetailView(
type: 'virtual',
));
},
iconPath: PathAssets.iconEducation,
type: 'Education',
amount: NumberFormatter.numberCurrency(
6000000,
'Rp ',
'id_ID',
decimalDigits: 0,
),
timeTransaction: StringUtils.formatTime(DateTime.now()),
subs: '3 Subscription',
step: 'done', step: 'done',
type: 'type',
amount: 'amount',
iconPath: 'iconPath',
subs: 'subs',
onTap: () {},
); );
}), }),
], ],

View File

@@ -1,10 +1,5 @@
import 'package:cims_apps/application/assets/path_assets.dart';
import 'package:cims_apps/application/component/card_transaction/card_transaction_view.dart'; import 'package:cims_apps/application/component/card_transaction/card_transaction_view.dart';
import 'package:cims_apps/application/component/card_transaction/empty_card_transaction.dart'; import 'package:cims_apps/application/component/card_transaction/empty_card_transaction.dart';
import 'package:cims_apps/core/route/route.dart';
import 'package:cims_apps/core/utils/number_formatter.dart';
import 'package:cims_apps/core/utils/string_utils.dart';
import 'package:cims_apps/features/transaction/view/subscribe_detail_view.dart';
import 'package:cims_apps/features/transaction/viewmodel/transaction_viewmodel.dart'; import 'package:cims_apps/features/transaction/viewmodel/transaction_viewmodel.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
@@ -24,23 +19,12 @@ class OnProcessView extends StatelessWidget {
), ),
...provider.listOnProcessTransaction.map((e) { ...provider.listOnProcessTransaction.map((e) {
return CardTransactionView( return CardTransactionView(
onTap: () {
routePush(context,
page: const SubscribeDetailView(
type: 'virtual',
));
},
iconPath: PathAssets.iconHome,
type: 'Home',
amount: NumberFormatter.numberCurrency(
6000000,
'Rp ',
'id_ID',
decimalDigits: 0,
),
timeTransaction: StringUtils.formatTime(DateTime.now()),
subs: '3 Subscription',
step: 'on process', step: 'on process',
type: 'type',
amount: 'amount',
iconPath: 'iconPath',
subs: 'subs',
onTap: () {},
); );
}), }),
]); ]);

View File

@@ -1,516 +0,0 @@
import 'package:cims_apps/application/assets/path_assets.dart';
import 'package:cims_apps/application/component/button/back_button_view.dart';
import 'package:cims_apps/application/component/button/button_view.dart';
import 'package:cims_apps/application/component/image/image_view.dart';
import 'package:cims_apps/application/component/list_tile/list_tile_view.dart';
import 'package:cims_apps/application/theme/color_palette.dart';
import 'package:cims_apps/core/utils/size_config.dart';
import 'package:cims_apps/core/utils/string_utils.dart';
import 'package:flutter/material.dart';
class SubscribeDetailView extends StatelessWidget {
final String type;
const SubscribeDetailView({Key? key, required this.type}) : super(key: key);
Widget _stepper(
TextTheme textTheme, {
required String description,
String? date,
time,
bool isActive = false,
bool isDone = false,
bool isLast = false,
}) {
return Container(
padding: const EdgeInsets.only(top: 8.0, left: 16.0),
child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Column(
children: [
Padding(
padding: const EdgeInsets.only(left: 2.0, top: 8.0),
child: Icon(
Icons.circle_rounded,
size: 10,
color: isDone
? ColorPalette.primary
: isActive
? ColorPalette.primary
: ColorPalette.slate400,
),
),
if (!isLast)
ConstrainedBox(
constraints: BoxConstraints.expand(
height: SizeConfig.width * .2, width: 0.0),
child: Padding(
padding: const EdgeInsets.symmetric(vertical: 4.0),
child: VerticalDivider(
color:
isDone ? ColorPalette.primary : ColorPalette.slate400,
thickness: 2.0,
),
),
),
],
),
Padding(
padding: const EdgeInsets.only(left: 16.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Padding(
padding: const EdgeInsets.only(bottom: 8.0),
child: Text(
description,
style: TextStyle(
fontSize: 16,
fontWeight: FontWeight.w600,
color: isDone
? Colors.black87
: isActive
? ColorPalette.primary
: ColorPalette.slate400,
),
),
),
isDone
? Row(
children: [
Text(date ?? ''),
const Padding(
padding: EdgeInsets.symmetric(horizontal: 4.0),
child: Icon(
Icons.circle,
size: 6,
color: ColorPalette.slate400,
),
),
Text(time ?? ''),
],
)
: const SizedBox(),
],
),
)
],
),
);
}
Widget _listProduct(BuildContext context) {
TextTheme textTheme = Theme.of(context).textTheme;
return Padding(
padding: const EdgeInsets.symmetric(horizontal: 16.0, vertical: 8.0),
child: Column(
children: [
Row(
children: [
ImageView(
image: PathAssets.imgProduct,
width: SizeConfig.width * .1,
),
Padding(
padding: const EdgeInsets.only(left: 8.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'Gemilang Dana Kas Maxima',
style: textTheme.headlineSmall,
),
Container(
padding: const EdgeInsets.symmetric(
horizontal: 8.0, vertical: 2.0),
decoration: BoxDecoration(
color: ColorPalette.purple100,
border: Border.all(
width: 1,
color: ColorPalette.purple,
),
borderRadius:
const BorderRadius.all(Radius.circular(24)),
),
child: const Text(
'Money Market',
style: TextStyle(
color: ColorPalette.purple500,
),
)),
],
),
),
],
),
Padding(
padding: const EdgeInsets.symmetric(vertical: 8.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
const Text('Investment Amount'),
Text(
'Rp 2.000.000',
style: textTheme.headlineSmall,
),
],
),
),
const Divider(
color: ColorPalette.slate200,
),
],
),
);
}
Widget _cardVA(BuildContext context) {
return Container(
margin: const EdgeInsets.only(top: 16.0, bottom: 8.0),
padding: const EdgeInsets.only(bottom: 16.0),
decoration: BoxDecoration(
color: Colors.white,
border: Border.all(width: 1, color: ColorPalette.slate200),
borderRadius: const BorderRadius.all(Radius.circular(12)),
),
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 16.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
SizedBox(height: SizeConfig.height * .02),
RichText(
text: const TextSpan(children: [
TextSpan(
text: 'Transfer to ',
style: TextStyle(
color: ColorPalette.slate400,
fontWeight: FontWeight.normal,
),
),
TextSpan(
text: 'ABC Virtual Account',
style: TextStyle(
color: ColorPalette.slate800,
fontWeight: FontWeight.bold,
),
),
])),
SizedBox(height: SizeConfig.height * .01),
const Text(
'Ferdy Maulana',
style: TextStyle(
color: Colors.black87,
fontSize: 16,
),
),
ListTileView(
title: '8785 0000 3165 5512',
prefixIcon: const SizedBox(),
padding: const EdgeInsets.only(right: 16.0),
margin: const EdgeInsets.only(top: 8.0, bottom: 8.0),
textStyle: const TextStyle(
fontWeight: FontWeight.bold, color: ColorPalette.primary),
suffixIcon: ButtonView(
name: 'Copy',
width: SizeConfig.width * .3,
height: SizeConfig.height * .052,
sizeBorderRadius: 8.0,
widthPrefix: 8.0,
marginVertical: 10.0,
prefixIcon: const Icon(
Icons.file_copy_outlined,
color: Colors.white,
size: 20,
),
onPressed: () {
StringUtils.iCopyToClipboard(
context,
text: '8785 0000 3165 5512',
);
},
),
),
const Divider(color: ColorPalette.slate200),
const Text(
'Amount to be transferred',
style: TextStyle(
color: Colors.black87,
fontSize: 16,
),
),
ListTileView(
title: 'Rp 10.000.000',
prefixIcon: const SizedBox(),
padding: const EdgeInsets.only(right: 16.0),
margin: const EdgeInsets.only(top: 8.0),
textStyle: const TextStyle(
fontWeight: FontWeight.bold, color: ColorPalette.primary),
suffixIcon: ButtonView(
name: 'Copy',
width: SizeConfig.width * .3,
height: SizeConfig.height * .052,
sizeBorderRadius: 8.0,
widthPrefix: 8.0,
marginVertical: 10.0,
prefixIcon: const Icon(
Icons.file_copy_outlined,
color: Colors.white,
size: 20,
),
onPressed: () {
StringUtils.iCopyToClipboard(
context,
text: '10.000.000',
);
},
),
),
],
),
),
);
}
Widget _cardContent(BuildContext context) {
TextTheme textTheme = Theme.of(context).textTheme;
List mySteps = const [
{
'desc': 'Payment Being Verified',
'date': '07 Feb 2024 ',
'time': '21:01',
'isActive': false,
'isDone': true,
'isLast': false,
},
{
'desc': 'Successful Payment',
'date': '07 Feb 2024 ',
'time': '21:01',
'isActive': true,
'isDone': false,
'isLast': false,
},
{
'desc': 'Investment Manager Verification',
'date': '07 Feb 2024 ',
'time': '21:01',
'isActive': false,
'isDone': false,
'isLast': false,
},
{
'desc': 'Successful Purchase',
'date': '07 Feb 2024 ',
'time': '21:01',
'isActive': false,
'isDone': false,
'isLast': true,
},
];
return SingleChildScrollView(
padding: const EdgeInsets.symmetric(horizontal: 16.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
const Icon(Icons.access_time, color: ColorPalette.slate400),
const Padding(
padding: EdgeInsets.symmetric(horizontal: 8.0),
child: Text('Waiting for Payment'),
),
Text('23:56:42', style: textTheme.headlineSmall),
],
),
type == 'virtual' ? _cardVA(context) : const SizedBox(),
Padding(
padding: const EdgeInsets.symmetric(vertical: 16.0),
child: Text('Purchase Details', style: textTheme.headlineSmall),
),
Container(
margin: const EdgeInsets.symmetric(vertical: 8.0),
padding: const EdgeInsets.only(bottom: 16.0),
decoration: BoxDecoration(
color: Colors.white,
border: Border.all(width: 1, color: ColorPalette.slate200),
borderRadius: const BorderRadius.all(Radius.circular(12)),
),
child: ExpansionTile(
shape: ShapeBorder.lerp(
const StadiumBorder(side: BorderSide.none),
InputBorder.none,
0),
title: Row(
children: [
ImageView(
image: PathAssets.iconEducation,
width: SizeConfig.width * .08,
),
const Padding(
padding: EdgeInsets.only(left: 8.0),
child: Text('Education'),
),
],
),
subtitle: Padding(
padding: const EdgeInsets.only(left: 40.0),
child: Text('3 Subscriptions', style: textTheme.bodyMedium),
),
children: [
_listProduct(context),
_listProduct(context),
],
),
),
...mySteps.map((e) {
return _stepper(
textTheme,
description: '${e['desc']}',
date: e['date'],
time: e['time'],
isActive: e['isActive'],
isDone: e['isDone'],
isLast: e['isLast'],
);
}),
Container(
margin: const EdgeInsets.symmetric(vertical: 8.0),
// padding: const EdgeInsets.only(bottom: 16.0),
decoration: BoxDecoration(
color: Colors.white,
border: Border.all(width: 1, color: ColorPalette.slate200),
borderRadius: const BorderRadius.all(Radius.circular(12)),
),
child: ExpansionTile(
shape: ShapeBorder.lerp(
const StadiumBorder(side: BorderSide.none),
InputBorder.none,
0),
title: Row(
children: [
const Expanded(
child: Text('When Is My Purchase Complete?')),
ImageView(
image: PathAssets.imgExpandPurchase,
width: SizeConfig.width * .15,
),
],
))),
],
),
);
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: SizedBox(
child: Stack(
children: [
const ImageView(image: PathAssets.imgDashboardAccount),
Column(
children: [
SizedBox(height: SizeConfig.height * .05),
Padding(
padding: const EdgeInsets.all(16.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.start,
children: [
BackButtonView(
onPress: () => Navigator.pop(context),
),
const Padding(
padding: EdgeInsets.symmetric(horizontal: 80.0),
child: Text(
'Subscribe Detail',
style: TextStyle(
fontSize: 18,
color: Colors.white,
fontWeight: FontWeight.bold,
),
),
),
],
),
),
type == 'virtual'
? const Padding(
padding: EdgeInsets.only(bottom: 8.0),
child: Text(
'Virtual Account',
style: TextStyle(
color: Colors.white,
fontSize: 16,
),
),
)
: const SizedBox(),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
ImageView(
image: PathAssets.imgProduct,
width: SizeConfig.width * .08,
),
Padding(
padding: const EdgeInsets.only(left: 8.0),
child: Text(
type == 'virtual' ? 'ABC' : 'Shopping Pay',
style: const TextStyle(
fontWeight: FontWeight.bold,
color: Colors.white,
),
),
),
],
),
const Padding(
padding: EdgeInsets.only(top: 8.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
'No.Subscribe : ',
style: TextStyle(
fontWeight: FontWeight.normal,
color: Colors.white,
),
),
Text(
'PI9393084SDMI1',
style: TextStyle(
fontWeight: FontWeight.bold,
color: Colors.white,
),
),
],
),
),
Expanded(
child: Container(
color: Colors.transparent,
width: SizeConfig.width,
padding: const EdgeInsets.only(top: 16.0),
child: Container(
margin: const EdgeInsets.only(top: 32.0),
padding: const EdgeInsets.only(top: 32.0),
decoration: const BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.only(
topLeft: Radius.circular(24),
topRight: Radius.circular(24)),
),
child: _cardContent(context)),
),
),
],
)
],
),
),
);
}
}

View File

@@ -1,10 +1,8 @@
import 'package:cims_apps/application/assets/path_assets.dart'; import 'package:cims_apps/application/assets/path_assets.dart';
import 'package:cims_apps/application/component/card_transaction/card_transaction_view.dart'; import 'package:cims_apps/application/component/card_transaction/card_transaction_view.dart';
import 'package:cims_apps/application/component/card_transaction/empty_card_transaction.dart'; import 'package:cims_apps/application/component/card_transaction/empty_card_transaction.dart';
import 'package:cims_apps/core/route/route.dart';
import 'package:cims_apps/core/utils/number_formatter.dart'; import 'package:cims_apps/core/utils/number_formatter.dart';
import 'package:cims_apps/core/utils/string_utils.dart'; import 'package:cims_apps/core/utils/string_utils.dart';
import 'package:cims_apps/features/transaction/view/subscribe_detail_view.dart';
import 'package:cims_apps/features/transaction/viewmodel/transaction_viewmodel.dart'; import 'package:cims_apps/features/transaction/viewmodel/transaction_viewmodel.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
@@ -21,12 +19,7 @@ class WaitingView extends StatelessWidget {
children: [ children: [
provider.listWaitingTransaction.isNotEmpty provider.listWaitingTransaction.isNotEmpty
? CardTransactionView( ? CardTransactionView(
onTap: () { onTap: () {},
routePush(context,
page: const SubscribeDetailView(
type: 'normal',
));
},
iconPath: PathAssets.iconEducation, iconPath: PathAssets.iconEducation,
type: 'Education', type: 'Education',
amount: NumberFormatter.numberCurrency( amount: NumberFormatter.numberCurrency(

View File

@@ -2,7 +2,7 @@ import 'package:flutter/material.dart';
class TransactionViewModel extends ChangeNotifier { class TransactionViewModel extends ChangeNotifier {
List listWaitingTransaction = [1]; List listWaitingTransaction = [1];
List listOnProcessTransaction = [1]; List listOnProcessTransaction = [];
List listDoneTransaction = []; List listDoneTransaction = [];
List listCancelTransaction = []; List listCancelTransaction = [];
} }