feat: plan view, wip plan view model
This commit is contained in:
@@ -37,6 +37,8 @@ class PathAssets {
|
||||
static const String iconHouse = 'assets/icons/icon-house.png';
|
||||
static const String iconToga = 'assets/icons/icon-toga.png';
|
||||
static const String iconCreatePlan = 'assets/icons/icon-create-plan.png';
|
||||
static const String iconThumb = 'assets/icons/icon-thumb.png';
|
||||
static const String iconPortofolio = 'assets/icons/icon-portofolio.png';
|
||||
|
||||
/// IMAGE
|
||||
static const String imgSplashLogo = 'assets/images/splash-logo.png';
|
||||
|
||||
@@ -9,7 +9,7 @@ class ButtonView extends StatelessWidget {
|
||||
final double? height, width, widthSuffix, widthPrefix, marginVertical;
|
||||
final EdgeInsetsGeometry? contentPadding;
|
||||
final bool isSecondaryColor, isOutlined, heightWrapContent, disabled;
|
||||
final Color? backgroundColor, textColor, borderColor;
|
||||
final Color? backgroundColor, textColor, borderColor, disabledBgColor;
|
||||
final MainAxisAlignment? mainAxisAlignmentContent;
|
||||
// final _widthBtn = SizeConfig.screenWidth / 1.5;
|
||||
final _widthBtn = SizeConfig.width * .9;
|
||||
@@ -34,6 +34,7 @@ class ButtonView extends StatelessWidget {
|
||||
this.backgroundColor,
|
||||
this.borderColor,
|
||||
this.textColor,
|
||||
this.disabledBgColor,
|
||||
this.textWeight = FontWeight.bold,
|
||||
this.textSize,
|
||||
this.textAlign = TextAlign.center,
|
||||
@@ -65,7 +66,7 @@ class ButtonView extends StatelessWidget {
|
||||
height: heightWrapContent ? null : height ?? _heightBtn,
|
||||
child: ElevatedButton(
|
||||
style: ElevatedButton.styleFrom(
|
||||
disabledBackgroundColor: isOutlined ? Colors.white : color.surface,
|
||||
disabledBackgroundColor: disabledBgColor ?? (isOutlined ? Colors.white : color.surface),
|
||||
padding: contentPadding,
|
||||
backgroundColor: backgroundColor ??
|
||||
(isOutlined
|
||||
|
||||
@@ -11,7 +11,8 @@ class GoalInvest {
|
||||
}
|
||||
|
||||
class GoalInvestingView extends StatelessWidget {
|
||||
const GoalInvestingView({super.key});
|
||||
final void Function(String) onListSelected;
|
||||
const GoalInvestingView({super.key, required this.onListSelected});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
@@ -28,6 +29,9 @@ class GoalInvestingView extends StatelessWidget {
|
||||
return Padding(
|
||||
padding: EdgeInsets.only(top: e.key != 0 ? 16 : 0),
|
||||
child: ListTile(
|
||||
onTap: () {
|
||||
onListSelected(e.value.title);
|
||||
},
|
||||
shape: RoundedRectangleBorder(
|
||||
side: BorderSide(color: ColorPalette.slate200),
|
||||
borderRadius: BorderRadius.circular(14)
|
||||
|
||||
@@ -36,6 +36,18 @@ class NumericPad extends StatelessWidget {
|
||||
],
|
||||
),
|
||||
dividerGradient(true, Alignment.centerLeft, Alignment.centerRight),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
numberWidget('7'),
|
||||
dividerGradient(false, Alignment.center, Alignment.center, fullColor: true),
|
||||
numberWidget('8'),
|
||||
dividerGradient(false, Alignment.center, Alignment.center, fullColor: true),
|
||||
numberWidget('9')
|
||||
],
|
||||
),
|
||||
dividerGradient(true, Alignment.centerLeft, Alignment.centerRight),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
@@ -54,7 +66,7 @@ class NumericPad extends StatelessWidget {
|
||||
Widget dividerGradient(bool isHorizontal, AlignmentGeometry gradientFrom, AlignmentGeometry gradientTo, {bool fullColor = false}) {
|
||||
return Container(
|
||||
width: isHorizontal ? SizeConfig.width : 1,
|
||||
height: isHorizontal ? 1 : SizeConfig.height * 0.11,
|
||||
height: isHorizontal ? 1 : SizeConfig.height * 0.097,
|
||||
decoration: BoxDecoration(
|
||||
gradient: LinearGradient(
|
||||
colors: [
|
||||
@@ -100,9 +112,14 @@ class NumericPad extends StatelessWidget {
|
||||
|
||||
Widget removeWidget() {
|
||||
return Expanded(
|
||||
child: Icon(
|
||||
Icons.highlight_remove,
|
||||
size: 28,
|
||||
child: GestureDetector(
|
||||
onTap: () {
|
||||
onNumberSelected('');
|
||||
},
|
||||
child: Icon(
|
||||
Icons.highlight_remove,
|
||||
size: 28,
|
||||
),
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
212
lib/application/component/risk_profile.dart
Normal file
212
lib/application/component/risk_profile.dart
Normal file
@@ -0,0 +1,212 @@
|
||||
import 'package:cims_apps/application/assets/path_assets.dart';
|
||||
import 'package:cims_apps/application/theme/color_palette.dart';
|
||||
import 'package:cims_apps/core/utils/size_config.dart';
|
||||
import 'package:cims_apps/features/auth/registration/view/submission_data/risk_profile/risk_profile_view_model/risk_profile_view_model.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class RiskProfile extends StatelessWidget {
|
||||
final int totalScore;
|
||||
final bool rowSuitableProduct;
|
||||
const RiskProfile({super.key, required this.totalScore, required this.rowSuitableProduct});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
List<RiskProfileResult> listRiskProfileResult = [
|
||||
RiskProfileResult(
|
||||
'Conservative',
|
||||
PathAssets.imgCat,
|
||||
ColorPalette.green500,
|
||||
'Investors with a conservative risk profile are risk-averse or do not want to experience large losses. Therefore, mutual fund products that are suitable for conservative investors are products that have low risk and stable returns.',
|
||||
[
|
||||
{'desc': 'Money Market Mutual Fund', 'icon': PathAssets.iconStrongBox},
|
||||
{'desc': 'Fixed Income Mutual Fund', 'icon': PathAssets.iconMoneyReceive},
|
||||
{'desc': 'Balanced Mutual Fund', 'icon': PathAssets.iconBalance},
|
||||
]
|
||||
),
|
||||
RiskProfileResult(
|
||||
'Moderate',
|
||||
PathAssets.imgDeer,
|
||||
ColorPalette.orange500,
|
||||
'Investors with a moderate risk profile are investors who are ready to accept moderate risk to get higher returns than conservative mutual fund products. Therefore, mutual fund products that are suitable for moderate investors are products that have moderate risk and higher returns than conservative mutual fund products.',
|
||||
[
|
||||
{'desc': 'Fixed Income Mutual Fund', 'icon': PathAssets.iconMoneyReceive},
|
||||
{'desc': 'Balanced Mutual Fund', 'icon': PathAssets.iconBalance},
|
||||
]
|
||||
),
|
||||
RiskProfileResult(
|
||||
'Aggressive',
|
||||
PathAssets.imgLion,
|
||||
ColorPalette.purple500,
|
||||
'Investors with an aggressive risk profile are investors who are ready to accept high risks to get high returns. Therefore, mutual fund products that are suitable for aggressive investors are products that have high risk and high returns.',
|
||||
[
|
||||
{'desc': 'Equity Mutual Fund', 'icon': PathAssets.iconCoins},
|
||||
{'desc': 'Aggressive Balanced Fund', 'icon': PathAssets.iconBalance},
|
||||
]
|
||||
)
|
||||
];
|
||||
RiskProfileResult riskProfile;
|
||||
if(totalScore <= 25){
|
||||
riskProfile = listRiskProfileResult[0];
|
||||
}else if(totalScore <= 50){
|
||||
riskProfile = listRiskProfileResult[1];
|
||||
}else{
|
||||
riskProfile = listRiskProfileResult[2];
|
||||
}
|
||||
|
||||
return Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
ClipRRect(
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
child: Container(
|
||||
decoration: BoxDecoration(
|
||||
color: riskProfile.color,
|
||||
image: DecorationImage(image: AssetImage(riskProfile.img), alignment: Alignment.centerRight),
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: riskProfile.color.withOpacity(0.2),
|
||||
blurRadius: 30
|
||||
)
|
||||
]
|
||||
),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Container(
|
||||
padding: EdgeInsets.all(24),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
riskProfile.type,
|
||||
style: TextStyle(
|
||||
fontWeight: FontWeight.bold,
|
||||
fontSize: 24,
|
||||
color: ColorPalette.white
|
||||
),
|
||||
),
|
||||
SizedBox(height: 16,),
|
||||
Text('Total Score :',
|
||||
style: TextStyle(
|
||||
fontWeight: FontWeight.bold,
|
||||
fontSize: 16,
|
||||
color: ColorPalette.white
|
||||
),
|
||||
),
|
||||
Text('$totalScore',
|
||||
style: TextStyle(
|
||||
fontWeight: FontWeight.bold,
|
||||
fontSize: 28,
|
||||
color: ColorPalette.white
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
SizedBox(
|
||||
height: 24,
|
||||
),
|
||||
Text(
|
||||
riskProfile.desc,
|
||||
style: TextStyle(
|
||||
color: ColorPalette.slate500,
|
||||
fontSize: 16
|
||||
)
|
||||
),
|
||||
SizedBox(
|
||||
height: 24,
|
||||
),
|
||||
Text(
|
||||
'Suitable Product',
|
||||
style: TextStyle(
|
||||
color: ColorPalette.slate800,
|
||||
fontWeight: FontWeight.bold,
|
||||
fontSize: 18
|
||||
),
|
||||
),
|
||||
SizedBox(
|
||||
height: 16,
|
||||
),
|
||||
rowSuitableProduct ?
|
||||
Row(
|
||||
children: riskProfile.suitableProduct.asMap().entries.map((e) {
|
||||
return Expanded(
|
||||
child: Container(
|
||||
margin: EdgeInsets.only(left: e.key != 0 ? 12 : 0),
|
||||
padding: EdgeInsets.all(16),
|
||||
decoration: BoxDecoration(
|
||||
border: Border.all(color: ColorPalette.slate200),
|
||||
borderRadius: BorderRadius.circular(6)
|
||||
),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Container(
|
||||
padding: EdgeInsets.all(8),
|
||||
decoration: BoxDecoration(
|
||||
shape: BoxShape.circle,
|
||||
color: riskProfile.color.withOpacity(0.1)
|
||||
),
|
||||
child: Image.asset(e.value['icon'], width: SizeConfig.width * 0.07, color: riskProfile.color)
|
||||
),
|
||||
SizedBox(
|
||||
height: 12,
|
||||
),
|
||||
Text(e.value['desc'],
|
||||
style: TextStyle(
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.bold,
|
||||
color: ColorPalette.slate800
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
)
|
||||
);
|
||||
}).toList(),
|
||||
)
|
||||
: Wrap(
|
||||
runSpacing: 16,
|
||||
children: riskProfile.suitableProduct.map((e) {
|
||||
return Container(
|
||||
padding: EdgeInsets.all(16),
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(6),
|
||||
border: Border.all(color: ColorPalette.slate200),
|
||||
),
|
||||
child: Row(
|
||||
children: [
|
||||
Container(
|
||||
padding: EdgeInsets.all(8),
|
||||
alignment: Alignment.center,
|
||||
decoration: BoxDecoration(
|
||||
shape: BoxShape.circle,
|
||||
color: riskProfile.color.withOpacity(0.1)
|
||||
),
|
||||
child: Image.asset(e['icon'], width: SizeConfig.width * 0.07, color: riskProfile.color)
|
||||
),
|
||||
SizedBox(
|
||||
width: 12,
|
||||
),
|
||||
Expanded(
|
||||
child: Text(e['desc'],
|
||||
style: TextStyle(
|
||||
fontSize: 18,
|
||||
fontWeight: FontWeight.bold,
|
||||
color: ColorPalette.slate800
|
||||
),
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
);
|
||||
}).toList(),
|
||||
)
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user