feat: wip redeem portfolio
This commit is contained in:
parent
6e03fa5fa7
commit
a3148d8210
BIN
assets/icons/icon-remove.png
Normal file
BIN
assets/icons/icon-remove.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.2 KiB |
|
@ -54,6 +54,7 @@ class PathAssets {
|
|||
static const String iconNavigationTransaction = 'assets/icons/icon-navigation-transaction.png';
|
||||
static const String iconNavigationPortfolio = 'assets/icons/icon-navigation-portfolio.png';
|
||||
static const String iconNavigationProfile = 'assets/icons/icon-navigation-profile.png';
|
||||
static const String iconRemove = 'assets/icons/icon-remove.png';
|
||||
|
||||
/// IMAGE
|
||||
static const String imgSplashLogo = 'assets/images/splash-logo.png';
|
||||
|
@ -91,4 +92,20 @@ class PathAssets {
|
|||
static const String imgPaymentSuccess = 'assets/images/img-payment-success.png';
|
||||
static const String frameSignature = 'assets/images/frame-signature.png';
|
||||
static const String imgFinish = 'assets/images/img-finish.png';
|
||||
|
||||
static const Map<String, String> goalInvestIcon = {
|
||||
'Education': iconToga,
|
||||
'Marriage': iconCake,
|
||||
'Old age days': iconHouse,
|
||||
'Home': iconHouse,
|
||||
'Other Plan': iconCreatePlan,
|
||||
'Create Plan': iconCreatePlan,
|
||||
'Entertainment': iconTicket,
|
||||
'Gadget': iconGadget,
|
||||
'Business': iconMarket,
|
||||
'Fashion': iconBag,
|
||||
'Shop': iconBag,
|
||||
'Vehicle': iconCar,
|
||||
'Holiday': iconPlane,
|
||||
};
|
||||
}
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
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:flutter/material.dart';
|
||||
|
@ -102,7 +104,8 @@ class NumericPad extends StatelessWidget {
|
|||
textAlign: TextAlign.center,
|
||||
style: TextStyle(
|
||||
fontSize: 28,
|
||||
fontWeight: FontWeight.bold
|
||||
fontWeight: FontWeight.bold,
|
||||
color: ColorPalette.slate800
|
||||
),
|
||||
),
|
||||
),
|
||||
|
@ -117,8 +120,9 @@ class NumericPad extends StatelessWidget {
|
|||
onNumberSelected('');
|
||||
},
|
||||
child: Icon(
|
||||
Icons.highlight_remove,
|
||||
Icons.backspace_outlined,
|
||||
size: 28,
|
||||
color: ColorPalette.slate800,
|
||||
),
|
||||
)
|
||||
);
|
||||
|
|
|
@ -92,6 +92,7 @@ class ColorPalette {
|
|||
static const Color green100 = Color(0xFFDCFCE7);
|
||||
static const Color green400 = Color(0xFF4ADE80);
|
||||
static const Color green500 = Color(0xFF16A34A);
|
||||
static const Color red600 = Color(0xffDC2626);
|
||||
|
||||
static const Map<String, Color> investTypeColor = {
|
||||
'Money Market': purple500,
|
||||
|
|
|
@ -0,0 +1,258 @@
|
|||
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/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/portfolio/redeem_product/view/redeem_product.dart';
|
||||
import 'package:cims_apps/features/dashboard/dashboard_account/view/portfolio/redeem_product/view_model/redeem_product_view_model.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
class PortfolioDetailView extends StatelessWidget {
|
||||
const PortfolioDetailView({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
List<PortfolioProduct> listProduct = [
|
||||
PortfolioProduct(
|
||||
name: 'Gemilang Dana Kas Maxima',
|
||||
type: '',
|
||||
yield: 8.17,
|
||||
priceUnit: 2600.79,
|
||||
funds: 6300000),
|
||||
PortfolioProduct(
|
||||
name: 'Gemilang Dana Likuid',
|
||||
type: '',
|
||||
yield: 6.42,
|
||||
priceUnit: 1600.79,
|
||||
funds: 2340000),
|
||||
PortfolioProduct(
|
||||
name: 'Gemilang Income Fund',
|
||||
type: '',
|
||||
yield: 8.17,
|
||||
priceUnit: 2600.79,
|
||||
funds: 6300000)
|
||||
];
|
||||
|
||||
|
||||
return MultiProvider(
|
||||
providers: [
|
||||
ChangeNotifierProvider(create: (context) => RedeemProductViewModel())
|
||||
],
|
||||
child: Scaffold(
|
||||
backgroundColor: Colors.white,
|
||||
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,
|
||||
children: [
|
||||
const BackButtonView(),
|
||||
const TextTitle(title: 'Education', color: Colors.white),
|
||||
SizedBox(width: SizeConfig.width * 0.1,)
|
||||
],
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 24,),
|
||||
const Padding(
|
||||
padding: EdgeInsets.symmetric(horizontal: 24),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text('Portfolio Value',
|
||||
style: TextStyle(
|
||||
color: ColorPalette.white,
|
||||
fontWeight: FontWeight.w400
|
||||
),
|
||||
),
|
||||
TextTitle(title: 'Rp 2.000.000', fontSize: 14, color: Colors.white)
|
||||
],
|
||||
),
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.end,
|
||||
children: [
|
||||
Text('Advantages',
|
||||
style: TextStyle(
|
||||
color: ColorPalette.white,
|
||||
fontWeight: FontWeight.w400
|
||||
),
|
||||
),
|
||||
TextTitle(title: 'Rp 2.000.000', fontSize: 14, color: Colors.white)
|
||||
],
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 24,),
|
||||
Expanded(
|
||||
child: ClipRRect(
|
||||
borderRadius: BorderRadius.circular(0),
|
||||
child: Container(
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
color: Colors.white,
|
||||
),
|
||||
child: ListView(
|
||||
padding: const EdgeInsets.all(24),
|
||||
children: [
|
||||
cardPortfolio(context)
|
||||
],
|
||||
),
|
||||
),
|
||||
)
|
||||
)
|
||||
],
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget cardPortfolio(context) {
|
||||
return Container(
|
||||
padding: const EdgeInsets.all(16),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
border: Border.all(color: ColorPalette.slate200),
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: const Color(0xff1E293B).withOpacity(0.04),
|
||||
blurRadius: 8,
|
||||
spreadRadius: 2
|
||||
)
|
||||
]
|
||||
),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
ImageView(
|
||||
image: PathAssets.imgProduct,
|
||||
width: SizeConfig.width * .13,
|
||||
),
|
||||
const SizedBox(width: 8),
|
||||
Expanded(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
const TextTitle(title: 'Gemilang Dana Kas Maxima', fontSize: 16,),
|
||||
const SizedBox(height: 4),
|
||||
Container(
|
||||
padding: const EdgeInsets.all(6),
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(40),
|
||||
color: ColorPalette.investTypeBgColor['Money Market']?.withOpacity(0.5) ?? Colors.white,
|
||||
border: Border.all(width: 2, color: ColorPalette.investTypeColor['Money Market']?.withOpacity(0.4) ?? Colors.white)
|
||||
),
|
||||
child: Text(
|
||||
'Money Market' ?? '',
|
||||
style: TextStyle(
|
||||
color: ColorPalette.investTypeColor['Money Market'],
|
||||
fontWeight: FontWeight.w600
|
||||
),
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
const Padding(
|
||||
padding: EdgeInsets.symmetric(vertical: 16),
|
||||
child: Divider(height: 1, color: ColorPalette.slate200,),
|
||||
),
|
||||
Wrap(
|
||||
runSpacing: 8,
|
||||
children: [
|
||||
rowDescription('Present Value', 'Rp2.660.706', fontWeight: FontWeight.w700),
|
||||
rowDescription('Investment Capital', 'Rp2.660.706'),
|
||||
rowDescription('Advantages', 'Rp2.660.706'),
|
||||
rowDescription('Purchase Price', 'Rp1.500,57'),
|
||||
rowDescription('Number of Units', '14.002'),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 16,),
|
||||
Row(
|
||||
children: [
|
||||
Expanded(
|
||||
child: ButtonView(
|
||||
name: 'Redeem',
|
||||
marginVertical: 0,
|
||||
width: SizeConfig.width,
|
||||
isOutlined: true,
|
||||
heightWrapContent: true,
|
||||
contentPadding: const EdgeInsets.all(12),
|
||||
backgroundColor: Colors.white,
|
||||
borderColor: ColorPalette.red600,
|
||||
textColor: ColorPalette.red600,
|
||||
onPressed: () {
|
||||
showModalBottomSheet(
|
||||
context: context,
|
||||
isScrollControlled: true,
|
||||
builder: (context) {
|
||||
return RedeemProduct();
|
||||
},
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 16),
|
||||
Expanded(
|
||||
child: ButtonView(
|
||||
name: 'Buy',
|
||||
marginVertical: 0,
|
||||
width: SizeConfig.width,
|
||||
heightWrapContent: true,
|
||||
contentPadding: const EdgeInsets.all(12),
|
||||
onPressed: () {
|
||||
|
||||
},
|
||||
),
|
||||
)
|
||||
],
|
||||
)
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget rowDescription(String title, String value, {Color? color, FontWeight? fontWeight}) {
|
||||
return Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Text(title,
|
||||
style: const TextStyle(
|
||||
color: ColorPalette.slate400,
|
||||
fontWeight: FontWeight.w600
|
||||
),
|
||||
),
|
||||
Text(value,
|
||||
style: TextStyle(
|
||||
color: color ?? ColorPalette.slate800,
|
||||
fontWeight: fontWeight ?? FontWeight.w600,
|
||||
),
|
||||
)
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
|
@ -1,7 +1,10 @@
|
|||
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/route/route.dart';
|
||||
import 'package:cims_apps/core/utils/size_config.dart';
|
||||
import 'package:cims_apps/features/dashboard/dashboard_account/view/portfolio/portfolio_detail_view.dart';
|
||||
import 'package:fl_chart/fl_chart.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
|
@ -147,9 +150,31 @@ class _PortofolioViewState extends State<PortofolioView> {
|
|||
),
|
||||
menuPortofolio(),
|
||||
const SizedBox(
|
||||
height: 24,
|
||||
height: 12,
|
||||
),
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 24, vertical: 12),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
TextTitle(title: 'My Portfolio', fontSize: 16),
|
||||
Row(
|
||||
children: [
|
||||
Icon(Icons.add, size: 18, color: ColorPalette.primary),
|
||||
SizedBox(width: 4),
|
||||
Text('Create',
|
||||
style: TextStyle(
|
||||
color: ColorPalette.primary,
|
||||
fontWeight: FontWeight.w600
|
||||
),
|
||||
)
|
||||
],
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
...listColumnPortofolio(),
|
||||
cardPortfolio()
|
||||
],
|
||||
),
|
||||
),
|
||||
|
@ -183,6 +208,7 @@ class _PortofolioViewState extends State<PortofolioView> {
|
|||
seePortofolioValue
|
||||
? Icons.visibility_off_outlined
|
||||
: Icons.visibility_outlined,
|
||||
size: 18,
|
||||
color: const Color(0xff93C5FD)))
|
||||
],
|
||||
),
|
||||
|
@ -358,4 +384,85 @@ class _PortofolioViewState extends State<PortofolioView> {
|
|||
);
|
||||
}).toList();
|
||||
}
|
||||
|
||||
Widget cardPortfolio() {
|
||||
return GestureDetector(
|
||||
onTap: () {
|
||||
routePush(context, page: PortfolioDetailView());
|
||||
},
|
||||
child: Container(
|
||||
margin: EdgeInsets.symmetric(horizontal: 24),
|
||||
padding: EdgeInsets.all(16),
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
border: Border.all(color: ColorPalette.slate200)
|
||||
),
|
||||
child: Column(
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
Container(
|
||||
padding: EdgeInsets.all(4),
|
||||
decoration: BoxDecoration(
|
||||
color: ColorPalette.blue200.withOpacity(0.5),
|
||||
borderRadius: BorderRadius.circular(8)
|
||||
),
|
||||
child: ImageView(
|
||||
image: PathAssets.goalInvestIcon['Education'],
|
||||
width: SizeConfig.width * 0.07
|
||||
)
|
||||
),
|
||||
SizedBox(width: 8),
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
TextTitle(title: 'Education', fontSize: 16,),
|
||||
Text('2 Subscriptions',
|
||||
style: TextStyle(
|
||||
color: ColorPalette.slate400,
|
||||
fontWeight: FontWeight.w600
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(vertical: 8),
|
||||
child: Divider(height: 1, color: ColorPalette.slate200),
|
||||
),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text('Portfolio Value',
|
||||
style: TextStyle(
|
||||
color: ColorPalette.slate400,
|
||||
fontWeight: FontWeight.w400
|
||||
),
|
||||
),
|
||||
TextTitle(title: 'Rp 2.000.000', fontSize: 14,)
|
||||
],
|
||||
),
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.end,
|
||||
children: [
|
||||
Text('Advantages',
|
||||
style: TextStyle(
|
||||
color: ColorPalette.slate400,
|
||||
fontWeight: FontWeight.w400
|
||||
),
|
||||
),
|
||||
TextTitle(title: 'Rp 2.000.000', fontSize: 14)
|
||||
],
|
||||
)
|
||||
],
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,235 @@
|
|||
import 'dart:math';
|
||||
|
||||
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/numeric_pad/numeric_pad.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/number_formatter.dart';
|
||||
import 'package:cims_apps/core/utils/size_config.dart';
|
||||
import 'package:cims_apps/features/dashboard/dashboard_account/view/portfolio/redeem_product/view/redeem_product.dart';
|
||||
import 'package:cims_apps/features/dashboard/dashboard_account/view/portfolio/redeem_product/view_model/redeem_product_view_model.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
class ChangeAmount extends StatefulWidget {
|
||||
final int totalAmount;
|
||||
const ChangeAmount({super.key, required this.totalAmount});
|
||||
|
||||
@override
|
||||
State<ChangeAmount> createState() => _ChangeAmountState();
|
||||
}
|
||||
|
||||
class _ChangeAmountState extends State<ChangeAmount> {
|
||||
TextEditingController amountController = TextEditingController();
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
// TODO: implement initState
|
||||
super.initState();
|
||||
amountController.text = NumberFormatter.numberCurrency(widget.totalAmount, 'Rp ', 'id_ID', decimalDigits: 0);
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
// TODO: implement dispose
|
||||
super.dispose();
|
||||
amountController.dispose();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return ChangeNotifierProvider(
|
||||
create: (context) => RedeemProductViewModel(),
|
||||
child: Consumer<RedeemProductViewModel>(
|
||||
builder: (context, provider, child) {
|
||||
return Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(vertical: 16, horizontal: 24),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
GestureDetector(
|
||||
onTap: () {
|
||||
Navigator.pop(context);
|
||||
showModalBottomSheet(
|
||||
context: context,
|
||||
isScrollControlled: true,
|
||||
builder: (context) {
|
||||
return const RedeemProduct();
|
||||
},
|
||||
);
|
||||
},
|
||||
child: const Icon(Icons.arrow_back_rounded)
|
||||
),
|
||||
const Text('Type amount',
|
||||
style: TextStyle(
|
||||
fontWeight: FontWeight.w600,
|
||||
fontSize: 16,
|
||||
color: ColorPalette.slate800
|
||||
),
|
||||
),
|
||||
GestureDetector(
|
||||
onTap: () {
|
||||
Navigator.pop(context);
|
||||
},
|
||||
child: const Icon(Icons.close_rounded)
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
const Divider(height: 1, color: ColorPalette.slate200,),
|
||||
Padding(
|
||||
padding: EdgeInsets.all(24),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
cardProduct(),
|
||||
SizedBox(height: 24),
|
||||
TextField(
|
||||
controller: amountController,
|
||||
textAlign: TextAlign.center,
|
||||
style: const TextStyle(
|
||||
fontSize: 28,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: ColorPalette.slate800
|
||||
),
|
||||
keyboardType: TextInputType.number,
|
||||
onChanged: (value) {
|
||||
value = value.replaceAll('Rp ', '').replaceAll('.', '');
|
||||
double parseValue = double.parse(value);
|
||||
if(value.isNotEmpty){
|
||||
amountController.text = NumberFormatter.numberCurrency(parseValue, 'Rp ', 'id_ID', decimalDigits: 0);
|
||||
}else{
|
||||
amountController.text = NumberFormatter.numberCurrency(0, 'Rp ', 'id_ID', decimalDigits: 0);
|
||||
}
|
||||
},
|
||||
decoration: const InputDecoration(
|
||||
enabledBorder: UnderlineInputBorder(
|
||||
borderSide: BorderSide(
|
||||
color: ColorPalette.primary,
|
||||
width: 2
|
||||
),
|
||||
)
|
||||
),
|
||||
),
|
||||
SizedBox(height: 12),
|
||||
Text(
|
||||
'Min Redeem: ${(NumberFormatter.numberCurrency(10000, 'Rp ', 'id_ID', decimalDigits: 0))}',
|
||||
style: TextStyle(
|
||||
color: ColorPalette.slate400,
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
),
|
||||
Text(
|
||||
'Max Redeem: ${(NumberFormatter.numberCurrency((provider.getCurrentProduct.priceUnit! * provider.getCurrentProduct.totalUnit!).toInt(), 'Rp ', 'id_ID', decimalDigits: 0))}',
|
||||
style: TextStyle(
|
||||
color: ColorPalette.slate400,
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 24),
|
||||
NumericPad(onNumberSelected: (p0) {
|
||||
String checkIsZeroInput = amountController.text.replaceAll('Rp ', '').replaceAll('.', '');
|
||||
String getNumeric = p0;
|
||||
|
||||
if(p0.isNotEmpty){
|
||||
if(checkIsZeroInput != '0'){
|
||||
getNumeric = checkIsZeroInput + getNumeric;
|
||||
}
|
||||
}else{
|
||||
getNumeric = checkIsZeroInput.substring(0, checkIsZeroInput.length - 1);
|
||||
}
|
||||
if(getNumeric.isEmpty){
|
||||
getNumeric = '0';
|
||||
}
|
||||
if(double.parse(getNumeric) >= provider.getCurrentProduct.priceUnit! * provider.getCurrentProduct.totalUnit!){
|
||||
getNumeric = (provider.getCurrentProduct.priceUnit! * provider.getCurrentProduct.totalUnit!).toString();
|
||||
}
|
||||
String formatNumeric = NumberFormatter.numberCurrency(
|
||||
double.parse(getNumeric).toInt(), 'Rp ', 'id_ID', decimalDigits: 0);
|
||||
amountController.text = formatNumeric;
|
||||
}),
|
||||
const SizedBox(height: 24),
|
||||
ButtonView(
|
||||
name: 'Confirm',
|
||||
textSize: 20,
|
||||
marginVertical: 0,
|
||||
onPressed: () {
|
||||
String formatValueInput = amountController.text.replaceAll('Rp ', '').replaceAll('.', '');
|
||||
provider.setAmount(double.parse(formatValueInput));
|
||||
Navigator.pop(context);
|
||||
showModalBottomSheet(
|
||||
context: context,
|
||||
isScrollControlled: true,
|
||||
builder: (context) {
|
||||
return const RedeemProduct();
|
||||
},
|
||||
);
|
||||
},
|
||||
)
|
||||
],
|
||||
),
|
||||
)
|
||||
],
|
||||
);
|
||||
}
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget cardProduct() {
|
||||
return Container(
|
||||
padding: const EdgeInsets.all(16),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
border: Border.all(color: ColorPalette.slate200),
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: const Color(0xff1E293B).withOpacity(0.04),
|
||||
blurRadius: 8,
|
||||
spreadRadius: 2
|
||||
)
|
||||
]
|
||||
),
|
||||
child: Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
ImageView(
|
||||
image: PathAssets.imgProduct,
|
||||
width: SizeConfig.width * .13,
|
||||
),
|
||||
const SizedBox(width: 8),
|
||||
Expanded(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
const TextTitle(title: 'Gemilang Dana Kas Maxima', fontSize: 16,),
|
||||
const SizedBox(height: 4),
|
||||
Container(
|
||||
padding: const EdgeInsets.all(6),
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(40),
|
||||
color: ColorPalette.investTypeBgColor['Money Market']?.withOpacity(0.5) ?? Colors.white,
|
||||
border: Border.all(width: 2, color: ColorPalette.investTypeColor['Money Market']?.withOpacity(0.4) ?? Colors.white)
|
||||
),
|
||||
child: Text(
|
||||
'Money Market' ?? '',
|
||||
style: TextStyle(
|
||||
color: ColorPalette.investTypeColor['Money Market'],
|
||||
fontWeight: FontWeight.w600
|
||||
),
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,191 @@
|
|||
import 'package:cims_apps/application/component/button/button_view.dart';
|
||||
import 'package:cims_apps/application/theme/color_palette.dart';
|
||||
import 'package:cims_apps/features/dashboard/dashboard_account/view/portfolio/redeem_product/view/redeem_product.dart';
|
||||
import 'package:cims_apps/features/dashboard/dashboard_account/view/portfolio/redeem_product/view_model/redeem_product_view_model.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
class ChangeDestinationAccount extends StatelessWidget {
|
||||
const ChangeDestinationAccount({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
List<Account> listAccount = [
|
||||
Account('Muhamad Rosyidin', 'BRI', '902139012324'),
|
||||
Account('Achmad Muhaimin', 'BCA', '21391283928')
|
||||
];
|
||||
|
||||
return ChangeNotifierProvider(
|
||||
create: (context) => RedeemProductViewModel(),
|
||||
child: Consumer<RedeemProductViewModel>(
|
||||
builder: (context, provider, child) {
|
||||
return Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(vertical: 16, horizontal: 24),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
GestureDetector(
|
||||
onTap: () {
|
||||
Navigator.pop(context);
|
||||
showModalBottomSheet(
|
||||
context: context,
|
||||
isScrollControlled: true,
|
||||
builder: (context) {
|
||||
return const RedeemProduct();
|
||||
},
|
||||
);
|
||||
},
|
||||
child: const Icon(Icons.arrow_back_rounded)
|
||||
),
|
||||
const Text('Change Destination Account',
|
||||
style: TextStyle(
|
||||
fontWeight: FontWeight.w600,
|
||||
fontSize: 16,
|
||||
color: ColorPalette.slate800
|
||||
),
|
||||
),
|
||||
GestureDetector(
|
||||
onTap: () {
|
||||
Navigator.pop(context);
|
||||
},
|
||||
child: const Icon(Icons.close_rounded)
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
const Divider(height: 1, color: ColorPalette.slate200,),
|
||||
Padding(
|
||||
padding: const EdgeInsets.all(24),
|
||||
child: Column(
|
||||
children: [
|
||||
...listAccount.asMap().entries.map((e) {
|
||||
return GestureDetector(
|
||||
onTap: () => provider.setSelectedAcc(e.value),
|
||||
child: Padding(
|
||||
padding: EdgeInsets.only(top: e.key != 0 ? 16 : 0),
|
||||
child: cardAccount(e.value, provider.selectedAccount?.number ?? provider.getCurrentAccount.number),
|
||||
),
|
||||
);
|
||||
}),
|
||||
const SizedBox(height: 24),
|
||||
GestureDetector(
|
||||
child: const Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Icon(Icons.add, size: 24, color: ColorPalette.primary),
|
||||
SizedBox(width: 12,),
|
||||
Text('New Bank',
|
||||
style: TextStyle(
|
||||
color: ColorPalette.primary,
|
||||
fontSize: 20,
|
||||
fontWeight: FontWeight.w600
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 32),
|
||||
ButtonView(
|
||||
name: 'Save',
|
||||
textSize: 20,
|
||||
marginVertical: 0,
|
||||
onPressed: () {
|
||||
Navigator.pop(context);
|
||||
showModalBottomSheet(
|
||||
context: context,
|
||||
isScrollControlled: true,
|
||||
builder: (context) {
|
||||
provider.setCurrentAcc(provider.selectedAccount!);
|
||||
return const RedeemProduct();
|
||||
},
|
||||
);
|
||||
},
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget cardAccount(Account account, String numberSelected) {
|
||||
List<String> listNumber = [];
|
||||
|
||||
List.generate(account.number.length, (index) {
|
||||
if(index > 3 && index < account.number.length - 4){
|
||||
listNumber.add('*');
|
||||
}else{
|
||||
listNumber.add(account.number[index]);
|
||||
}
|
||||
});
|
||||
|
||||
return Container(
|
||||
padding: const EdgeInsets.all(16),
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(14),
|
||||
border: Border.all(color: ColorPalette.slate200)
|
||||
),
|
||||
child: Row(
|
||||
children: [
|
||||
Expanded(
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(account.nameOwner,
|
||||
style: const TextStyle(
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: ColorPalette.slate800
|
||||
),
|
||||
),
|
||||
Text(
|
||||
'${account.nameBank} - ${listNumber.join("")}',
|
||||
style: const TextStyle(
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: ColorPalette.slate400
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
AnimatedContainer(
|
||||
margin: const EdgeInsets.only(top: 4),
|
||||
duration: const Duration(milliseconds: 200),
|
||||
height: 16,
|
||||
width: 16,
|
||||
padding: const EdgeInsets.all(1),
|
||||
alignment: Alignment.center,
|
||||
decoration: BoxDecoration(
|
||||
shape: BoxShape.circle,
|
||||
border: Border.all(
|
||||
color: numberSelected == account.number
|
||||
? ColorPalette.primary
|
||||
: ColorPalette.slate200)),
|
||||
child: AnimatedContainer(
|
||||
duration: const Duration(milliseconds: 200),
|
||||
child: Container(
|
||||
decoration: BoxDecoration(
|
||||
color:
|
||||
numberSelected == account.number ? ColorPalette.primary : ColorPalette.white,
|
||||
shape: BoxShape.circle),
|
||||
),
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,361 @@
|
|||
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/text_form/text_form_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/number_formatter.dart';
|
||||
import 'package:cims_apps/core/utils/size_config.dart';
|
||||
import 'package:cims_apps/features/dashboard/dashboard_account/view/portfolio/redeem_product/view/change_amount.dart';
|
||||
import 'package:cims_apps/features/dashboard/dashboard_account/view/portfolio/redeem_product/view/change_destination_account.dart';
|
||||
import 'package:cims_apps/features/dashboard/dashboard_account/view/portfolio/redeem_product/view/total_redeem.dart';
|
||||
import 'package:cims_apps/features/dashboard/dashboard_account/view/portfolio/redeem_product/view_model/redeem_product_view_model.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
class RedeemProduct extends StatefulWidget {
|
||||
const RedeemProduct({super.key});
|
||||
|
||||
@override
|
||||
State<RedeemProduct> createState() => _RedeemProductState();
|
||||
}
|
||||
|
||||
class _RedeemProductState extends State<RedeemProduct> {
|
||||
TextEditingController amountController = TextEditingController();
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
// TODO: implement initState
|
||||
super.initState();
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
// TODO: implement dispose
|
||||
super.dispose();
|
||||
amountController.dispose();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return ChangeNotifierProvider(
|
||||
create: (context) => RedeemProductViewModel(),
|
||||
child: Consumer<RedeemProductViewModel>(
|
||||
builder: (context, provider, child) {
|
||||
double amount = provider.getAmount ?? provider.getCurrentProduct.priceUnit! * provider.getCurrentProduct.totalUnit!;
|
||||
amountController.text = NumberFormatter.numberCurrency(amount.toInt(), 'Rp ', 'id_ID', decimalDigits: 0);
|
||||
return Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 24, vertical: 16),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
const Text('Products to be Redeemed',
|
||||
style: TextStyle(
|
||||
fontWeight: FontWeight.w600,
|
||||
color: ColorPalette.slate800,
|
||||
fontSize: 16
|
||||
),
|
||||
),
|
||||
GestureDetector(
|
||||
onTap: () => Navigator.pop(context),
|
||||
child: const Icon(Icons.close_rounded, color: ColorPalette.slate800,)
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
const Divider(height: 1, color: ColorPalette.slate200,),
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 24, vertical: 16),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
cardProduct(),
|
||||
const SizedBox(height: 16),
|
||||
segmentAmount(
|
||||
context,
|
||||
provider.getAmount ?? provider.getCurrentProduct.priceUnit! * (provider.getCurrentProduct.totalUnit! / 2.0),
|
||||
provider.getUnit ?? provider.getCurrentProduct.totalUnit! / 2.0,
|
||||
(value) {
|
||||
provider.setUnit(value);
|
||||
},
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
segmentDestinationAcc(provider.getCurrentAccount),
|
||||
const SizedBox(height: 36),
|
||||
ButtonView(
|
||||
name: 'Redeem',
|
||||
textSize: 20,
|
||||
marginVertical: 0,
|
||||
onPressed: () {
|
||||
Navigator.pop(context);
|
||||
showModalBottomSheet(
|
||||
context: context,
|
||||
isScrollControlled: true,
|
||||
builder: (context) {
|
||||
return TotalRedeem();
|
||||
},
|
||||
);
|
||||
},
|
||||
),
|
||||
const SizedBox(height: 16)
|
||||
],
|
||||
),
|
||||
)
|
||||
],
|
||||
);
|
||||
}
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget cardProduct() {
|
||||
return Container(
|
||||
padding: const EdgeInsets.all(16),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
border: Border.all(color: ColorPalette.slate200),
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: const Color(0xff1E293B).withOpacity(0.04),
|
||||
blurRadius: 8,
|
||||
spreadRadius: 2
|
||||
)
|
||||
]
|
||||
),
|
||||
child: Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
ImageView(
|
||||
image: PathAssets.imgProduct,
|
||||
width: SizeConfig.width * .13,
|
||||
),
|
||||
const SizedBox(width: 8),
|
||||
Expanded(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
const TextTitle(title: 'Gemilang Dana Kas Maxima', fontSize: 16,),
|
||||
const SizedBox(height: 4),
|
||||
Container(
|
||||
padding: const EdgeInsets.all(6),
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(40),
|
||||
color: ColorPalette.investTypeBgColor['Money Market']?.withOpacity(0.5) ?? Colors.white,
|
||||
border: Border.all(width: 2, color: ColorPalette.investTypeColor['Money Market']?.withOpacity(0.4) ?? Colors.white)
|
||||
),
|
||||
child: Text(
|
||||
'Money Market' ?? '',
|
||||
style: TextStyle(
|
||||
color: ColorPalette.investTypeColor['Money Market'],
|
||||
fontWeight: FontWeight.w600
|
||||
),
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget segmentAmount(context, double currentAmount, double currentUnit, void Function(double value) setUnit) {
|
||||
double sliderValue = currentUnit / Provider.of<RedeemProductViewModel>(context, listen: false).getCurrentProduct.totalUnit!;
|
||||
return Column(
|
||||
children: [
|
||||
const Align(
|
||||
alignment: Alignment.centerLeft,
|
||||
child: Text('Amount',
|
||||
style: TextStyle(
|
||||
fontWeight: FontWeight.w600,
|
||||
color: ColorPalette.slate800,
|
||||
fontSize: 16
|
||||
),
|
||||
),
|
||||
),
|
||||
TextField(
|
||||
controller: amountController,
|
||||
textAlign: TextAlign.center,
|
||||
style: const TextStyle(
|
||||
fontSize: 28,
|
||||
fontWeight: FontWeight.w700,
|
||||
color: ColorPalette.slate800
|
||||
),
|
||||
keyboardType: TextInputType.number,
|
||||
readOnly: true,
|
||||
decoration: InputDecoration(
|
||||
enabledBorder: const UnderlineInputBorder(
|
||||
borderSide: BorderSide(
|
||||
color: ColorPalette.slate200,
|
||||
width: 1
|
||||
),
|
||||
),
|
||||
suffixIcon: GestureDetector(
|
||||
onTap: () {
|
||||
Navigator.pop(context);
|
||||
showModalBottomSheet(
|
||||
context: context,
|
||||
isScrollControlled: true,
|
||||
builder: (context) {
|
||||
return ChangeAmount(
|
||||
totalAmount: currentAmount.toInt(),
|
||||
);
|
||||
},
|
||||
);
|
||||
},
|
||||
child: const Icon(Icons.edit, color: ColorPalette.primary),
|
||||
)
|
||||
),
|
||||
),
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(vertical: 20),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Text(currentUnit.toStringAsFixed(2).replaceAll('.', ','),
|
||||
style: const TextStyle(
|
||||
fontWeight: FontWeight.w700,
|
||||
fontSize: 18,
|
||||
color: ColorPalette.slate800
|
||||
),
|
||||
),
|
||||
const Text(' unit',
|
||||
style: TextStyle(
|
||||
fontWeight: FontWeight.w600,
|
||||
color: ColorPalette.slate400
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
Row(
|
||||
children: [
|
||||
Expanded(
|
||||
child: SliderTheme(
|
||||
data: SliderTheme.of(context).copyWith(
|
||||
trackHeight: 4.0,
|
||||
thumbColor: ColorPalette.primary,
|
||||
thumbShape: const RoundSliderThumbShape(enabledThumbRadius: 10.0),
|
||||
overlayColor:Colors.deepPurple,
|
||||
inactiveTickMarkColor: ColorPalette.primary,
|
||||
inactiveTrackColor: ColorPalette.slate200,
|
||||
overlayShape: SliderComponentShape.noOverlay
|
||||
),
|
||||
child: Slider(
|
||||
value: sliderValue,
|
||||
onChanged: setUnit,
|
||||
label: sliderValue.round().toString(),
|
||||
),
|
||||
),
|
||||
),
|
||||
SizedBox(width: 12),
|
||||
Text('${(sliderValue * 100).toStringAsFixed(2)} %',
|
||||
style: const TextStyle(
|
||||
color: ColorPalette.slate800,
|
||||
fontWeight: FontWeight.w600
|
||||
),
|
||||
)
|
||||
],
|
||||
)
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
Widget segmentDestinationAcc(Account account) {
|
||||
List<String> listNumber = [];
|
||||
|
||||
List.generate(account.number.length, (index) {
|
||||
if(index > 3 && index < account.number.length - 4){
|
||||
listNumber.add('*');
|
||||
}else{
|
||||
listNumber.add(account.number[index]);
|
||||
}
|
||||
});
|
||||
|
||||
return Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
const Text('Destination Account',
|
||||
style: TextStyle(
|
||||
fontWeight: FontWeight.w600,
|
||||
color: ColorPalette.slate800,
|
||||
fontSize: 16
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
Container(
|
||||
padding: const EdgeInsets.all(16),
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(14),
|
||||
border: Border.all(color: ColorPalette.slate200)
|
||||
),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Expanded(
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(account.nameOwner,
|
||||
style: const TextStyle(
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: ColorPalette.slate800
|
||||
),
|
||||
),
|
||||
Text('${account.nameBank} - ${listNumber.join("")}',
|
||||
style: const TextStyle(
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: ColorPalette.slate400
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
GestureDetector(
|
||||
onTap: () {
|
||||
Navigator.pop(context);
|
||||
showModalBottomSheet(
|
||||
context: context,
|
||||
isScrollControlled: true,
|
||||
builder: (context) => const ChangeDestinationAccount(),
|
||||
);
|
||||
},
|
||||
child: Container(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 6),
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(18),
|
||||
color: ColorPalette.blue200.withOpacity(0.5)
|
||||
),
|
||||
child: const Row(
|
||||
children: [
|
||||
Icon(Icons.change_circle_outlined, color: ColorPalette.primary, size: 20),
|
||||
SizedBox(width: 4),
|
||||
Text('Change',
|
||||
style: TextStyle(
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: ColorPalette.primary
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
)
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,151 @@
|
|||
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/portfolio/redeem_product/view_model/redeem_product_view_model.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
class TotalRedeem extends StatelessWidget {
|
||||
const TotalRedeem({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return ChangeNotifierProvider(
|
||||
create: (context) => RedeemProductViewModel(),
|
||||
child: Consumer<RedeemProductViewModel>(
|
||||
builder: (context, provider, child) {
|
||||
return Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 24, vertical: 16),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Text('Investment Funds that You Cash Out',
|
||||
style: TextStyle(
|
||||
fontWeight: FontWeight.w600,
|
||||
color: ColorPalette.slate800,
|
||||
fontSize: 16
|
||||
),
|
||||
),
|
||||
GestureDetector(
|
||||
onTap: () => Navigator.pop(context),
|
||||
child: Icon(Icons.close_rounded, color: ColorPalette.slate800,)
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
Divider(height: 1, color: ColorPalette.slate200,),
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 24, vertical: 16),
|
||||
child: cardProduct(provider.getCurrentProduct, provider.getUnit!),
|
||||
),
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 24),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Text('Sales Commission',
|
||||
style: TextStyle(
|
||||
color: ColorPalette.slate400,
|
||||
fontSize: 16
|
||||
),
|
||||
),
|
||||
Text('Free',
|
||||
style: TextStyle(
|
||||
fontWeight: FontWeight.w600,
|
||||
color: ColorPalette.primary,
|
||||
fontSize: 16
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
SizedBox(height: 16),
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 24),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Text('Cash Out Method',
|
||||
style: TextStyle(
|
||||
color: ColorPalette.slate400,
|
||||
fontSize: 16
|
||||
),
|
||||
),
|
||||
Text('Regular',
|
||||
style: TextStyle(
|
||||
fontWeight: FontWeight.w600,
|
||||
color: ColorPalette.primary,
|
||||
fontSize: 16
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
SizedBox(height: 16,),
|
||||
|
||||
],
|
||||
);
|
||||
}
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget cardProduct(PortfolioProduct product, double currentUnit) {
|
||||
return Container(
|
||||
padding: const EdgeInsets.all(16),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
border: Border.all(color: ColorPalette.slate200),
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: const Color(0xff1E293B).withOpacity(0.04),
|
||||
blurRadius: 8,
|
||||
spreadRadius: 2
|
||||
)
|
||||
]
|
||||
),
|
||||
child: Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
ImageView(
|
||||
image: PathAssets.imgProduct,
|
||||
width: SizeConfig.width * .13,
|
||||
),
|
||||
const SizedBox(width: 8),
|
||||
Expanded(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
TextTitle(title: product.name ?? '', fontSize: 16,),
|
||||
const SizedBox(height: 4),
|
||||
Row(
|
||||
children: [
|
||||
Text(currentUnit.toStringAsFixed(2).replaceAll('.', ','),
|
||||
style: const TextStyle(
|
||||
fontWeight: FontWeight.w700,
|
||||
fontSize: 18,
|
||||
color: ColorPalette.slate800
|
||||
),
|
||||
),
|
||||
const Text(' unit',
|
||||
style: TextStyle(
|
||||
fontWeight: FontWeight.w600,
|
||||
color: ColorPalette.slate400
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,64 @@
|
|||
import 'package:flutter/material.dart';
|
||||
|
||||
class Account {
|
||||
String nameOwner, nameBank, number;
|
||||
|
||||
Account(this.nameOwner, this.nameBank, this.number);
|
||||
}
|
||||
|
||||
class PortfolioProduct {
|
||||
String? name, type;
|
||||
double? yield;
|
||||
double? priceUnit, funds, totalPercent, totalUnit;
|
||||
|
||||
PortfolioProduct({this.name, this.type, this.yield, this.priceUnit, this.funds, this.totalPercent = 1, this.totalUnit});
|
||||
}
|
||||
|
||||
class RedeemProductViewModel extends ChangeNotifier {
|
||||
static Account currentAccount = Account('Muhamad Rosyidin', 'BRI', '902139012324');
|
||||
static PortfolioProduct currentProduct =
|
||||
PortfolioProduct(
|
||||
name: 'Gemilang Dana Kas Maxima',
|
||||
type: '',
|
||||
yield: 8.17,
|
||||
priceUnit: 2600.79,
|
||||
funds: 6300000,
|
||||
totalUnit: 25
|
||||
);
|
||||
|
||||
static double? amount;
|
||||
static double? unit;
|
||||
Account? selectedAccount;
|
||||
|
||||
Account get getCurrentAccount => currentAccount;
|
||||
PortfolioProduct get getCurrentProduct => currentProduct;
|
||||
double? get getAmount => amount;
|
||||
double? get getUnit => unit;
|
||||
|
||||
void setCurrentAcc(Account account) {
|
||||
currentAccount = account;
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
void setSelectedAcc(Account account){
|
||||
selectedAccount = account;
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
void setAmount(double amount) {
|
||||
amount = amount;
|
||||
unit = (amount / currentProduct.priceUnit!);
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
void setUnit(double value){
|
||||
unit = currentProduct.totalUnit! * value;
|
||||
amount = unit! * currentProduct.priceUnit!;
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
void setProduct(PortfolioProduct product) {
|
||||
currentProduct = product;
|
||||
notifyListeners();
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user