Merge branch 'dev' of https://git.empatnusabangsa.com/nugrohob825/cims_apps into bayu/dev
This commit is contained in:
@@ -65,6 +65,7 @@ class PasswordView extends StatelessWidget {
|
||||
name: 'Confirm',
|
||||
heightWrapContent: true,
|
||||
width: SizeConfig.width,
|
||||
textSize: 18,
|
||||
marginVertical: 0,
|
||||
contentPadding: EdgeInsets.symmetric(horizontal: 16, vertical: 12),
|
||||
onPressed: nextStep,
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
import 'package:cims_apps/application/theme/color_palette.dart';
|
||||
import 'package:cims_apps/features/dashboard/dashboard_account/view/homepage/homepage_view.dart';
|
||||
import 'package:cims_apps/features/dashboard/dashboard_account/view/plan/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/plan/view_model/plan_view_model.dart';
|
||||
import 'package:cims_apps/features/dashboard/dashboard_account/view/portfolio/portfolio_view.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
class BottomNavigationView extends StatefulWidget {
|
||||
const BottomNavigationView({Key? key}) : super(key: key);
|
||||
|
||||
@@ -228,7 +228,7 @@ class _HomeViewState extends State<HomeView> {
|
||||
children: listPortofolioType.asMap().entries.map((e) {
|
||||
return GestureDetector(
|
||||
onTap: () {
|
||||
routePush(context, page: InvestTypeView(e.value.name));
|
||||
routePush(context, page: InvestTypeView(title: e.value.name));
|
||||
},
|
||||
child: Container(
|
||||
color: Colors.white,
|
||||
|
||||
@@ -6,21 +6,14 @@ import 'package:cims_apps/application/theme/color_palette.dart';
|
||||
import 'package:cims_apps/core/route/route.dart';
|
||||
import 'package:cims_apps/core/utils/number_formatter.dart';
|
||||
import 'package:cims_apps/core/utils/size_config.dart';
|
||||
import 'package:cims_apps/features/dashboard/dashboard_account/view/product/product_view.dart';
|
||||
import 'package:cims_apps/features/dashboard/dashboard_account/view/product/view/product_view.dart';
|
||||
import 'package:cims_apps/features/dashboard/dashboard_account/view/product/view_model/product_view_model.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class Product {
|
||||
String name;
|
||||
double yield;
|
||||
double priceUnit;
|
||||
double funds;
|
||||
|
||||
Product(this.name, this.yield, this.priceUnit, this.funds);
|
||||
}
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
class InvestTypeView extends StatefulWidget {
|
||||
final String title;
|
||||
const InvestTypeView(this.title, {super.key});
|
||||
const InvestTypeView({super.key, required this.title});
|
||||
|
||||
@override
|
||||
State<InvestTypeView> createState() => _InvestTypeViewState();
|
||||
@@ -29,71 +22,89 @@ class InvestTypeView extends StatefulWidget {
|
||||
class _InvestTypeViewState extends State<InvestTypeView> {
|
||||
|
||||
List<Product> listProduct = [
|
||||
Product('Gemilang Dana Kas Maxima', 8.17, 2600.79, 6300000),
|
||||
Product('Gemilang Dana Likuid', 6.42, 1600.79, 2340000),
|
||||
Product('Gemilang Income Fund', 8.17, 2600.79, 6300000)
|
||||
Product(name: 'Gemilang Dana Kas Maxima', type: '', yield: 8.17, priceUnit: 2600.79, funds: 6300000),
|
||||
Product(name: 'Gemilang Dana Likuid', type: '', yield: 6.42, priceUnit: 1600.79, funds: 2340000),
|
||||
Product(name: 'Gemilang Income Fund', type: '', yield: 8.17, priceUnit: 2600.79, funds: 6300000)
|
||||
];
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
// TODO: implement initState
|
||||
super.initState();
|
||||
listProduct = listProduct.map((e) {
|
||||
e.type = widget.title;
|
||||
return e;
|
||||
}).toList();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
body: SizedBox(
|
||||
width: SizeConfig.width,
|
||||
height: SizeConfig.height,
|
||||
child: Stack(
|
||||
children: [
|
||||
const ImageView(image: PathAssets.imgDashboardAccount),
|
||||
Column(
|
||||
children: [
|
||||
const SizedBox(
|
||||
height: 50,
|
||||
),
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 24),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
return ChangeNotifierProvider<ProductViewModel>(
|
||||
create: (context) => ProductViewModel(),
|
||||
child: Consumer<ProductViewModel>(
|
||||
builder: (context, provider, child) {
|
||||
return Scaffold(
|
||||
body: SizedBox(
|
||||
width: SizeConfig.width,
|
||||
height: SizeConfig.height,
|
||||
child: Stack(
|
||||
children: [
|
||||
const ImageView(image: PathAssets.imgDashboardAccount),
|
||||
Column(
|
||||
children: [
|
||||
const BackButtonView(),
|
||||
TextTitle(title: widget.title, color: Colors.white),
|
||||
SizedBox(
|
||||
width: SizeConfig.width * 0.1,
|
||||
)
|
||||
const SizedBox(
|
||||
height: 50,
|
||||
),
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 24),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
const BackButtonView(),
|
||||
TextTitle(title: widget.title, color: Colors.white),
|
||||
SizedBox(
|
||||
width: SizeConfig.width * 0.1,
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
const SizedBox(
|
||||
height: 24,
|
||||
),
|
||||
Container(
|
||||
padding: const EdgeInsets.all(24),
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(16),
|
||||
color: Colors.white
|
||||
),
|
||||
child: Column(
|
||||
children: [
|
||||
filters(),
|
||||
ListView(
|
||||
shrinkWrap: true,
|
||||
children: listProduct.asMap().entries.map((e) {
|
||||
return GestureDetector(
|
||||
onTap: () {
|
||||
provider.setSelectedProduct(e.value);
|
||||
routePush(context, page: ProductView(widget.title));
|
||||
},
|
||||
child: Padding(
|
||||
padding: EdgeInsets.only(top: e.key != 0 ? 24 : 0),
|
||||
child: cardProduct(e.value),
|
||||
),
|
||||
);
|
||||
}).toList(),
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
const SizedBox(
|
||||
height: 24,
|
||||
),
|
||||
Container(
|
||||
padding: const EdgeInsets.all(24),
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(16),
|
||||
color: Colors.white
|
||||
),
|
||||
child: Column(
|
||||
children: [
|
||||
filters(),
|
||||
ListView(
|
||||
shrinkWrap: true,
|
||||
children: listProduct.asMap().entries.map((e) {
|
||||
return GestureDetector(
|
||||
onTap: () {
|
||||
routePush(context, page: ProductView(widget.title));
|
||||
},
|
||||
child: Padding(
|
||||
padding: EdgeInsets.only(top: e.key != 0 ? 24 : 0),
|
||||
child: cardProduct(e.value),
|
||||
),
|
||||
);
|
||||
}).toList(),
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
)
|
||||
],
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
),
|
||||
);
|
||||
}
|
||||
@@ -158,7 +169,7 @@ class _InvestTypeViewState extends State<InvestTypeView> {
|
||||
),
|
||||
Expanded(
|
||||
child: Text(
|
||||
product.name,
|
||||
product.name ?? '',
|
||||
style: const TextStyle(
|
||||
fontWeight: FontWeight.bold,
|
||||
fontSize: 18
|
||||
|
||||
@@ -1,22 +0,0 @@
|
||||
import 'package:cims_apps/application/component/custom_app_bar/custom_app_bar.dart';
|
||||
import 'package:cims_apps/application/component/goal_investing_view.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class PlanView extends StatelessWidget {
|
||||
const PlanView({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
appBar: CustomAppBar(height: 70, title: 'Investment Plan'),
|
||||
body: SingleChildScrollView(
|
||||
padding: EdgeInsets.all(24),
|
||||
child: Column(
|
||||
children: [
|
||||
GoalInvestingView()
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,126 @@
|
||||
import 'package:cims_apps/application/component/button/button_view.dart';
|
||||
import 'package:cims_apps/application/component/custom_app_bar/custom_app_bar.dart';
|
||||
import 'package:cims_apps/application/component/subscribe/goal_investing_view.dart';
|
||||
import 'package:cims_apps/application/component/subscribe/input_investment_view.dart';
|
||||
import 'package:cims_apps/application/component/numeric_pad/numeric_pad.dart';
|
||||
import 'package:cims_apps/application/component/risk_profile.dart';
|
||||
import 'package:cims_apps/application/component/text_form/text_form_view.dart';
|
||||
import 'package:cims_apps/application/theme/color_palette.dart';
|
||||
import 'package:cims_apps/core/utils/number_formatter.dart';
|
||||
import 'package:cims_apps/core/utils/size_config.dart';
|
||||
import 'package:cims_apps/features/dashboard/dashboard_account/view/plan/view/step_invest_plan/options_starting_invest.dart';
|
||||
import 'package:cims_apps/features/dashboard/dashboard_account/view/plan/view_model/plan_view_model.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
class PlanView extends StatefulWidget {
|
||||
const PlanView({super.key});
|
||||
|
||||
@override
|
||||
State<PlanView> createState() => _PlanViewState();
|
||||
}
|
||||
|
||||
class _PlanViewState extends State<PlanView> {
|
||||
TextEditingController inputController = TextEditingController();
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
// TODO: implement initState
|
||||
inputController.text = 'Rp 0';
|
||||
super.initState();
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
// TODO: implement dispose
|
||||
super.dispose();
|
||||
inputController.dispose();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
|
||||
return Scaffold(
|
||||
appBar: CustomAppBar(height: 70, title: 'Investment Plan'),
|
||||
body: SingleChildScrollView(
|
||||
padding: EdgeInsets.all(24),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
RiskProfile(
|
||||
totalScore: 26,
|
||||
rowSuitableProduct: true
|
||||
),
|
||||
SizedBox(
|
||||
height: 32,
|
||||
),
|
||||
Text('Your Goal in Investing',
|
||||
style: TextStyle(
|
||||
fontWeight: FontWeight.w700,
|
||||
color: ColorPalette.slate800,
|
||||
fontSize: 18
|
||||
),
|
||||
),
|
||||
SizedBox(
|
||||
height: 24,
|
||||
),
|
||||
GoalInvestingView(
|
||||
onListSelected: (p0) {
|
||||
showModalBottomSheet(
|
||||
context: context,
|
||||
isScrollControlled: true,
|
||||
builder: (context) {
|
||||
return modalInvest(context, p0);
|
||||
},
|
||||
);
|
||||
},
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget modalInvest(context, String text) {
|
||||
return Container(
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
borderRadius: BorderRadius.circular(16)
|
||||
),
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 24, vertical: 18),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Text("It's time to invest",
|
||||
style: TextStyle(
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.w600
|
||||
),
|
||||
),
|
||||
GestureDetector(
|
||||
onTap: () {
|
||||
Navigator.pop(context);
|
||||
},
|
||||
child: Icon(Icons.close_rounded)
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
Divider(color: ColorPalette.slate200, height: 1),
|
||||
InputInvestmentView(
|
||||
selectedPlan: text,
|
||||
nextMove: (value) {
|
||||
Navigator.pop(context);
|
||||
int formatIntParse = int.parse(value.replaceAll('Rp ', '').replaceAll(',', ''));
|
||||
showModalBottomSheet(context: context, builder: (context) => OptionsStartingInvest(totalInvest: formatIntParse));
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,123 @@
|
||||
import 'package:cims_apps/application/assets/path_assets.dart';
|
||||
import 'package:cims_apps/application/theme/color_palette.dart';
|
||||
import 'package:cims_apps/features/dashboard/dashboard_account/view/plan/view/step_invest_plan/result_options_product.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class OptionsStartingInvest extends StatelessWidget {
|
||||
final int totalInvest;
|
||||
const OptionsStartingInvest({super.key, required this.totalInvest});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
List<dynamic> listOptions = [
|
||||
{
|
||||
"title": "Results From Your Risk Profile",
|
||||
"subtitle": "Start Investing from recommended products that suit you",
|
||||
"iconImg": PathAssets.iconThumb,
|
||||
"value": "risk profile"
|
||||
},
|
||||
{
|
||||
"title": "Create Portfolio",
|
||||
"subtitle": "Choose a portfolio according to your investment goals",
|
||||
"iconImg": PathAssets.iconPortofolio,
|
||||
"value": "investment goals"
|
||||
}
|
||||
];
|
||||
|
||||
return Container(
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
borderRadius: BorderRadius.circular(16)
|
||||
),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 24, vertical: 16),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Text('Your options for starting to invest',
|
||||
style: TextStyle(
|
||||
fontSize: 18,
|
||||
fontWeight: FontWeight.w600
|
||||
),
|
||||
),
|
||||
GestureDetector(
|
||||
onTap: () {
|
||||
Navigator.pop(context);
|
||||
},
|
||||
child: Icon(Icons.close_rounded),
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
SizedBox(height: 8),
|
||||
...listOptions.asMap().entries.map((e) {
|
||||
return GestureDetector(
|
||||
onTap: () {
|
||||
Navigator.pop(context);
|
||||
showModalBottomSheet(
|
||||
context: context,
|
||||
isScrollControlled: true,
|
||||
builder: (context) => ResultOptionsProduct(totalInvest: totalInvest));
|
||||
},
|
||||
child: Container(
|
||||
margin: const EdgeInsets.only(left: 24, right: 24, bottom: 12),
|
||||
padding: EdgeInsets.all(16),
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(14),
|
||||
border: Border.all(color: ColorPalette.slate200),
|
||||
),
|
||||
child: Row(
|
||||
children: [
|
||||
Expanded(
|
||||
child: Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Container(
|
||||
padding: EdgeInsets.all(8),
|
||||
alignment: Alignment.center,
|
||||
decoration: BoxDecoration(
|
||||
color: ColorPalette.blue200.withOpacity(0.5),
|
||||
borderRadius: BorderRadius.circular(8)
|
||||
),
|
||||
child: Image.asset(e.value['iconImg'], width: 22),
|
||||
),
|
||||
SizedBox(width: 16),
|
||||
Expanded(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(e.value['title'],
|
||||
style: TextStyle(
|
||||
fontWeight: FontWeight.w600,
|
||||
color: ColorPalette.slate800,
|
||||
fontSize: 16
|
||||
),
|
||||
),
|
||||
SizedBox(height: 4),
|
||||
Text(e.value['subtitle'],
|
||||
style: TextStyle(
|
||||
color: ColorPalette.slate400
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
Icon(Icons.keyboard_arrow_right_rounded, color: ColorPalette.slate400,)
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}),
|
||||
SizedBox(height: 16,)
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,153 @@
|
||||
import 'package:cims_apps/application/assets/path_assets.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/subscribe/total_payment_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/dashboard/dashboard_account/view/product/view_model/product_view_model.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class ResultOptionsProduct extends StatelessWidget {
|
||||
final int totalInvest;
|
||||
const ResultOptionsProduct({super.key, required this.totalInvest});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
List<Product> listProduct = [
|
||||
Product(name: 'Gemilang Dana Kas Maxima', type: 'Money Market', totalPercent: 0.7),
|
||||
Product(name: 'Gemilang Dana Likuid', type: 'Bonds', totalPercent: 0.2),
|
||||
Product(name: 'Gemilang Kas 2 Kelas A', type: 'Shares', totalPercent: 0.1)
|
||||
];
|
||||
|
||||
return Container(
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
borderRadius: BorderRadius.circular(16)
|
||||
),
|
||||
padding: const EdgeInsets.all(24),
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
const Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Icon(Icons.arrow_back, color: ColorPalette.slate500),
|
||||
Text('Results from your risk profile',
|
||||
style: TextStyle(
|
||||
fontWeight: FontWeight.w600,
|
||||
fontSize: 18,
|
||||
color: ColorPalette.slate800
|
||||
),
|
||||
),
|
||||
Icon(Icons.close_rounded, color: ColorPalette.slate400)
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 32),
|
||||
SingleChildScrollView(
|
||||
child: Column(
|
||||
children: listProduct.asMap().entries.map((e) {
|
||||
return Container(
|
||||
margin: const EdgeInsets.only(bottom: 16),
|
||||
padding: const EdgeInsets.all(16),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
border: Border.all(color: ColorPalette.slate200),
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
boxShadow: const [
|
||||
BoxShadow(
|
||||
color: Color(0XFF1E293B0A)
|
||||
)
|
||||
]
|
||||
),
|
||||
child: Column(
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
const ImageView(image: PathAssets.iconGoogle, width: 30,),
|
||||
const SizedBox(
|
||||
width: 12,
|
||||
),
|
||||
Expanded(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(e.value.name ?? '',
|
||||
style: const TextStyle(
|
||||
fontWeight: FontWeight.w700,
|
||||
color: ColorPalette.slate800,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 4,),
|
||||
Container(
|
||||
padding: const EdgeInsets.symmetric(vertical: 6, horizontal: 12),
|
||||
decoration: BoxDecoration(
|
||||
border: Border.all(color: ColorPalette.investTypeColor[e.value.type]!),
|
||||
color: ColorPalette.investTypeBgColor[e.value.type],
|
||||
borderRadius: BorderRadius.circular(40)
|
||||
),
|
||||
child: Text(e.value.type ?? '',
|
||||
style: TextStyle(
|
||||
color: ColorPalette.investTypeColor[e.value.type],
|
||||
fontWeight: FontWeight.w600,
|
||||
fontSize: 12
|
||||
),
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
Text('${(e.value.totalPercent! * 100).toInt()} %',
|
||||
style: const TextStyle(
|
||||
fontWeight: FontWeight.w700,
|
||||
fontSize: 16,
|
||||
color: ColorPalette.slate800
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
const Padding(
|
||||
padding: EdgeInsets.symmetric(vertical: 16),
|
||||
child: Divider(height: 1, color: ColorPalette.slate200),
|
||||
),
|
||||
GestureDetector(
|
||||
onTap: () {
|
||||
},
|
||||
child: const Text('See More',
|
||||
style: TextStyle(
|
||||
color: ColorPalette.slate500,
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
);
|
||||
}).toList(),
|
||||
),
|
||||
),
|
||||
const SizedBox(
|
||||
height: 16,
|
||||
),
|
||||
ButtonView(
|
||||
name: 'Next',
|
||||
onPressed: () {
|
||||
showModalBottomSheet(
|
||||
context: context,
|
||||
isScrollControlled: true,
|
||||
builder: (context) =>
|
||||
TotalPaymentView(
|
||||
listProduct: listProduct,
|
||||
totalInvest: totalInvest,
|
||||
)
|
||||
);
|
||||
},
|
||||
width: SizeConfig.width,
|
||||
heightWrapContent: true,
|
||||
contentPadding: const EdgeInsets.symmetric(vertical: 16),
|
||||
marginVertical: 0,
|
||||
)
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
import 'package:cims_apps/features/dashboard/dashboard_account/view/product/view_model/product_view_model.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class PlanViewModel extends ChangeNotifier {
|
||||
List<Product> listProduct = [];
|
||||
}
|
||||
@@ -9,9 +9,12 @@ 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/number_formatter.dart';
|
||||
import 'package:cims_apps/core/utils/size_config.dart';
|
||||
import 'package:cims_apps/features/dashboard/dashboard_account/view/product/product_chart_view.dart';
|
||||
import 'package:cims_apps/features/dashboard/dashboard_account/view/product/view/product_chart_view.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:flutter/material.dart';
|
||||
import 'package:group_button/group_button.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
class Time {
|
||||
int value;
|
||||
@@ -97,58 +100,65 @@ class _ProductViewState extends State<ProductView> {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
body: SizedBox(
|
||||
child: Stack(
|
||||
children: [
|
||||
const ImageView(image: PathAssets.imgDashboardAccount),
|
||||
Column(
|
||||
children: [
|
||||
const SizedBox(
|
||||
height: 50,
|
||||
),
|
||||
const Padding(
|
||||
padding: EdgeInsets.symmetric(horizontal: 24),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
BackButtonView(),
|
||||
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)
|
||||
],
|
||||
)
|
||||
],
|
||||
return ChangeNotifierProvider(
|
||||
create: (context) => ProductViewModel(),
|
||||
child: Scaffold(
|
||||
body: SizedBox(
|
||||
child: Stack(
|
||||
children: [
|
||||
const ImageView(image: PathAssets.imgDashboardAccount),
|
||||
Column(
|
||||
children: [
|
||||
const SizedBox(
|
||||
height: 50,
|
||||
),
|
||||
),
|
||||
const SizedBox(
|
||||
height: 24,
|
||||
),
|
||||
headContainer(),
|
||||
const SizedBox(
|
||||
height: 24,
|
||||
),
|
||||
Expanded(
|
||||
child: contentContainer()
|
||||
)
|
||||
],
|
||||
)
|
||||
],
|
||||
const Padding(
|
||||
padding: EdgeInsets.symmetric(horizontal: 24),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
BackButtonView(),
|
||||
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)
|
||||
],
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
const SizedBox(
|
||||
height: 24,
|
||||
),
|
||||
headContainer(),
|
||||
const SizedBox(
|
||||
height: 24,
|
||||
),
|
||||
Expanded(
|
||||
child: contentContainer()
|
||||
)
|
||||
],
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
bottomNavigationBar: Container(
|
||||
height: SizeConfig.height * .1,
|
||||
padding: const EdgeInsets.symmetric(horizontal: 24),
|
||||
child: ButtonView(
|
||||
name: 'Buy',
|
||||
onPressed: () {
|
||||
|
||||
},
|
||||
height: SizeConfig.height * 0.06,
|
||||
marginVertical: 16,
|
||||
bottomNavigationBar: Container(
|
||||
height: SizeConfig.height * .1,
|
||||
padding: const EdgeInsets.symmetric(horizontal: 24),
|
||||
child: ButtonView(
|
||||
name: 'Subscribe',
|
||||
onPressed: () {
|
||||
showModalBottomSheet(
|
||||
context: context,
|
||||
isScrollControlled: true,
|
||||
builder: (context) => SelectGoalInvesting(),
|
||||
);
|
||||
},
|
||||
height: SizeConfig.height * 0.06,
|
||||
marginVertical: 16,
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
@@ -581,18 +591,10 @@ class _ProductViewState extends State<ProductView> {
|
||||
},
|
||||
selectedMachineType
|
||||
),
|
||||
const Padding(
|
||||
padding: EdgeInsets.only(top: 16, bottom: 8),
|
||||
child: Text(
|
||||
"Today's Investment Estimated Value",
|
||||
style: TextStyle(
|
||||
fontWeight: FontWeight.w600,
|
||||
color: ColorPalette.slate800
|
||||
),
|
||||
),
|
||||
),
|
||||
SizedBox(height: 16),
|
||||
TextFormView(
|
||||
name: '',
|
||||
name: "Today's Investment Estimated Value",
|
||||
nameSize: 14,
|
||||
ctrl: machineController,
|
||||
keyboardType: TextInputType.number,
|
||||
contentPadding: EdgeInsets.all(12),
|
||||
@@ -0,0 +1,282 @@
|
||||
import 'dart:ffi';
|
||||
|
||||
import 'package:cims_apps/application/assets/path_assets.dart';
|
||||
import 'package:cims_apps/application/component/button/button_view.dart';
|
||||
import 'package:cims_apps/application/component/custom_app_bar/custom_app_bar.dart';
|
||||
import 'package:cims_apps/application/component/modal_redirect_app.dart';
|
||||
import 'package:cims_apps/application/component/success_view.dart';
|
||||
import 'package:cims_apps/application/theme/color_palette.dart';
|
||||
import 'package:cims_apps/core/route/route.dart';
|
||||
import 'package:cims_apps/core/utils/number_formatter.dart';
|
||||
import 'package:cims_apps/core/utils/size_config.dart';
|
||||
import 'package:cims_apps/features/bottom_navigation_view.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
class Payment {
|
||||
String name;
|
||||
int fee;
|
||||
double? discount;
|
||||
|
||||
Payment({required this.name, required this.fee, this.discount = 1});
|
||||
}
|
||||
|
||||
class PaymentMethodView extends StatefulWidget {
|
||||
final int totalInvest;
|
||||
const PaymentMethodView({super.key, required this.totalInvest });
|
||||
|
||||
@override
|
||||
State<PaymentMethodView> createState() => _PaymentMethodViewState();
|
||||
}
|
||||
|
||||
class _PaymentMethodViewState extends State<PaymentMethodView> {
|
||||
int selectedPayment = 0;
|
||||
Payment currentPayment = Payment(name: 'Wallet Pay', fee: 2500);
|
||||
List<Payment> listInstantPayment = [
|
||||
Payment(name: 'Wallet Pay', fee: 2500),
|
||||
Payment(name: 'Link Start', fee: 2500),
|
||||
Payment(name: 'Shopping Pay', fee: 2500, discount: 0.5),
|
||||
Payment(name: 'Fund', fee: 2500, discount: 0.2)
|
||||
];
|
||||
|
||||
List<Payment> listTransferBank = [
|
||||
Payment(name: 'BCA', fee: 2500),
|
||||
Payment(name: 'Bank Republik Indonesia', fee: 2500)
|
||||
];
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
|
||||
return Scaffold(
|
||||
appBar: const CustomAppBar(
|
||||
height: 70,
|
||||
title: 'Payment Method'
|
||||
),
|
||||
body: SingleChildScrollView(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 24, vertical: 8),
|
||||
child: Column(
|
||||
children: [
|
||||
segmentTitle(Icons.bolt_rounded, 'Instant Payment'),
|
||||
Wrap(
|
||||
runSpacing: 16,
|
||||
children: listInstantPayment.asMap().entries.map((e) {
|
||||
return cardPayment(e.value, e.key);
|
||||
}).toList(),
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
segmentTitle(Icons.account_balance_outlined, 'Transfer Bank'),
|
||||
Wrap(
|
||||
runSpacing: 16,
|
||||
children: listTransferBank.asMap().entries.map((e) {
|
||||
return cardPayment(e.value, e.key + (listInstantPayment.length));
|
||||
}).toList(),
|
||||
),
|
||||
SizedBox(height: 16,)
|
||||
],
|
||||
),
|
||||
),
|
||||
bottomNavigationBar: Container(
|
||||
padding: const EdgeInsets.all(24),
|
||||
child: segmentBottom(currentPayment)
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget segmentTitle(IconData? icon, String title) {
|
||||
return Padding(
|
||||
padding: const EdgeInsets.symmetric(vertical: 16),
|
||||
child: Row(
|
||||
children: [
|
||||
Icon(icon, color: ColorPalette.primary),
|
||||
const SizedBox(width: 8),
|
||||
Text(title,
|
||||
style: const TextStyle(
|
||||
color: ColorPalette.slate800,
|
||||
fontWeight: FontWeight.w600,
|
||||
fontSize: 16
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget cardPayment(Payment value, int index) {
|
||||
return GestureDetector(
|
||||
onTap: () {
|
||||
setState(() {
|
||||
selectedPayment = index;
|
||||
currentPayment = value;
|
||||
});
|
||||
},
|
||||
child: AnimatedContainer(
|
||||
duration: const Duration(milliseconds: 200),
|
||||
padding: const EdgeInsets.all(16),
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(14),
|
||||
border: Border.all(color: selectedPayment == index ? ColorPalette.primary : ColorPalette.slate200)
|
||||
),
|
||||
child: Column(
|
||||
children: [
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(value.name,
|
||||
style: const TextStyle(
|
||||
fontSize: 16
|
||||
),
|
||||
),
|
||||
RichText(
|
||||
text: TextSpan(
|
||||
text: 'Payment fee ',
|
||||
style: const TextStyle(
|
||||
fontFamily: 'Manrope',
|
||||
color: ColorPalette.slate400,
|
||||
),
|
||||
children: [
|
||||
TextSpan(
|
||||
text: '${NumberFormatter.numberCurrency(value.fee, 'Rp ', 'id_ID', decimalDigits: 0)} ',
|
||||
style: TextStyle(
|
||||
decoration: value.discount != 1 ? TextDecoration.lineThrough : TextDecoration.none,
|
||||
fontFamily: 'Manrope',
|
||||
color: ColorPalette.slate400,
|
||||
),
|
||||
),
|
||||
if(value.discount != 1)...[
|
||||
TextSpan(
|
||||
text: value.discount == 0 ? 'Free' : NumberFormatter.numberCurrency(value.fee * value.discount!, 'Rp ', 'id_ID', decimalDigits: 0),
|
||||
style: const TextStyle(
|
||||
fontFamily: 'Manrope',
|
||||
color: ColorPalette.primary,
|
||||
),
|
||||
)
|
||||
]
|
||||
]
|
||||
)
|
||||
)
|
||||
],
|
||||
)
|
||||
],
|
||||
),
|
||||
AnimatedContainer(
|
||||
duration: const Duration(milliseconds: 200),
|
||||
width: 16,
|
||||
height: 16,
|
||||
alignment: Alignment.center,
|
||||
decoration: BoxDecoration(
|
||||
shape: BoxShape.circle,
|
||||
color: selectedPayment == index ? ColorPalette.primary : Colors.white,
|
||||
border: Border.all(color: selectedPayment == index ? ColorPalette.primary : ColorPalette.slate200, width: 1.5)
|
||||
),
|
||||
child: const Icon(Icons.done_rounded, color: Colors.white, size: 12),
|
||||
)
|
||||
],
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget segmentBottom(Payment currentPayment) {
|
||||
return Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
rowTotal('Total Invest', widget.totalInvest),
|
||||
rowTotal('Payment Fee', (currentPayment.fee * currentPayment.discount!).toInt()),
|
||||
Row(
|
||||
children: [
|
||||
Expanded(child: Divider(color: ColorPalette.slate200, height: 1,)),
|
||||
Icon(Icons.add, size: 10,)
|
||||
],
|
||||
),
|
||||
rowTotal('Total Payment', widget.totalInvest + (currentPayment.fee * currentPayment.discount!).toInt()),
|
||||
SizedBox(height: 24),
|
||||
ButtonView(
|
||||
name: 'Buy',
|
||||
textSize: 18,
|
||||
marginVertical: 0,
|
||||
width: SizeConfig.width,
|
||||
heightWrapContent: true,
|
||||
contentPadding: EdgeInsets.symmetric(vertical: 16),
|
||||
onPressed: () {
|
||||
List<String> redirect = ['Shopping Pay'];
|
||||
if(redirect.contains(currentPayment.name)){
|
||||
showModalBottomSheet(
|
||||
context: context,
|
||||
builder: (context) {
|
||||
return ModalRedirectApp(value: currentPayment.name);
|
||||
},
|
||||
);
|
||||
}
|
||||
routePush(context, page: SuccessView(
|
||||
img: PathAssets.imgPaymentSuccess,
|
||||
textTitle: 'Payment Success!',
|
||||
subtitle: RichText(
|
||||
text: TextSpan(
|
||||
text: 'Payment With ',
|
||||
style: TextStyle(
|
||||
fontFamily: 'Manrope',
|
||||
fontWeight: FontWeight.w600,
|
||||
fontSize: 16,
|
||||
color: ColorPalette.slate500
|
||||
),
|
||||
children: [
|
||||
TextSpan(
|
||||
text: currentPayment.name,
|
||||
style: TextStyle(
|
||||
fontFamily: 'Manrope',
|
||||
fontWeight: FontWeight.w700,
|
||||
fontSize: 16,
|
||||
color: ColorPalette.slate800
|
||||
)
|
||||
),
|
||||
TextSpan(
|
||||
text: ' successful',
|
||||
style: TextStyle(
|
||||
fontFamily: 'Manrope',
|
||||
fontWeight: FontWeight.w600,
|
||||
fontSize: 16,
|
||||
color: ColorPalette.slate500
|
||||
)
|
||||
)
|
||||
]
|
||||
)
|
||||
),
|
||||
nextRoute: () {
|
||||
routePush(context, page: BottomNavigationView(), routeType: RouteType.pushRemove);
|
||||
},
|
||||
));
|
||||
},
|
||||
)
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
Widget rowTotal(String title, int value) {
|
||||
return Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Text(title,
|
||||
style: const TextStyle(
|
||||
fontWeight: FontWeight.w600,
|
||||
color: ColorPalette.slate500,
|
||||
fontSize: 16
|
||||
),
|
||||
),
|
||||
Text(NumberFormatter.numberCurrency(value, 'Rp', 'id_ID', decimalDigits: 0),
|
||||
style: const TextStyle(
|
||||
fontWeight: FontWeight.w700,
|
||||
color: ColorPalette.slate800,
|
||||
fontSize: 16
|
||||
),
|
||||
)
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
import 'package:cims_apps/application/component/subscribe/goal_investing_view.dart';
|
||||
import 'package:cims_apps/application/component/subscribe/input_investment_view.dart';
|
||||
import 'package:cims_apps/application/component/subscribe/total_payment_view.dart';
|
||||
import 'package:cims_apps/application/theme/color_palette.dart';
|
||||
import 'package:cims_apps/features/dashboard/dashboard_account/view/product/view_model/product_view_model.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
class SelectGoalInvesting extends StatelessWidget {
|
||||
const SelectGoalInvesting({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return MultiProvider(
|
||||
providers: [
|
||||
ChangeNotifierProvider(create: (context) => ProductViewModel(),)
|
||||
],
|
||||
child: Consumer<ProductViewModel>(
|
||||
builder: (context, provider, child) {
|
||||
return Container(
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(16)
|
||||
),
|
||||
padding: EdgeInsets.all(24),
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Text('Your Goal in Investing',
|
||||
style: TextStyle(
|
||||
fontWeight: FontWeight.w700,
|
||||
color: ColorPalette.slate800,
|
||||
fontSize: 18
|
||||
),
|
||||
),
|
||||
GestureDetector(
|
||||
onTap: () {
|
||||
Navigator.pop(context);
|
||||
},
|
||||
child: Icon(Icons.close_rounded, color: ColorPalette.slate400)
|
||||
)
|
||||
],
|
||||
),
|
||||
SizedBox(height: 32),
|
||||
GoalInvestingView(
|
||||
onListSelected: (p0) {
|
||||
Navigator.pop(context);
|
||||
showModalBottomSheet(
|
||||
context: context,
|
||||
isScrollControlled: true,
|
||||
builder: (context) {
|
||||
return InputInvestmentView(
|
||||
selectedPlan: p0,
|
||||
nextMove: (value) {
|
||||
Navigator.pop(context);
|
||||
int formatIntParse = int.parse(value.replaceAll('Rp ', '').replaceAll(',', ''));
|
||||
showModalBottomSheet(
|
||||
context: context,
|
||||
isScrollControlled: true,
|
||||
builder: (context) =>
|
||||
TotalPaymentView(
|
||||
listProduct: [
|
||||
provider.getSelectedProduct
|
||||
],
|
||||
totalInvest: formatIntParse,
|
||||
)
|
||||
);
|
||||
},
|
||||
);
|
||||
},
|
||||
);
|
||||
},
|
||||
)
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class Product {
|
||||
String? name, type;
|
||||
double? yield;
|
||||
double? priceUnit, funds, totalPercent;
|
||||
|
||||
Product({this.name, this.type, this.yield, this.priceUnit, this.funds, this.totalPercent = 1});
|
||||
}
|
||||
|
||||
class ProductViewModel extends ChangeNotifier {
|
||||
static Product selectedProduct = Product();
|
||||
Product get getSelectedProduct => selectedProduct;
|
||||
|
||||
double totalInvestment = 0;
|
||||
|
||||
void setSelectedProduct(Product product) {
|
||||
selectedProduct = product;
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
void setTotalInvestment(double value) {
|
||||
totalInvestment = value;
|
||||
notifyListeners();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user