Compare commits
No commits in common. "a87afe16cb36497efb3e8d75ac4c59a40dd64dd7" and "a6ea9a23149e76fc88931e1e3350bf846e2c140e" have entirely different histories.
a87afe16cb
...
a6ea9a2314
|
@ -1,119 +0,0 @@
|
|||
import 'package:cims_apps/application/component/expandable_widget/see_more_less_widget.dart';
|
||||
import 'package:cims_apps/application/theme/color_palette.dart';
|
||||
import 'package:cims_apps/core/utils/size_config.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class ExpandableWidget extends StatelessWidget {
|
||||
final String? content;
|
||||
final double? fontSize;
|
||||
final int maxLinesToShow;
|
||||
final Alignment? alignmentMore;
|
||||
final bool? hideTextMore;
|
||||
final bool? hideIconMore;
|
||||
|
||||
ExpandableWidget({
|
||||
super.key,
|
||||
required this.content,
|
||||
this.fontSize,
|
||||
this.maxLinesToShow = 1,
|
||||
this.alignmentMore,
|
||||
this.hideTextMore = false,
|
||||
this.hideIconMore = true,
|
||||
});
|
||||
|
||||
ValueNotifier<bool> expanded = ValueNotifier(false);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final TextSpan textSpan = TextSpan(
|
||||
text: content ?? "",
|
||||
style: TextStyle(
|
||||
fontSize: fontSize ?? 16.0,
|
||||
color: ColorPalette.slate400,
|
||||
),
|
||||
);
|
||||
|
||||
final TextPainter textPainter = TextPainter(
|
||||
text: textSpan,
|
||||
maxLines: expanded.value ? null : maxLinesToShow,
|
||||
textDirection: TextDirection.ltr,
|
||||
strutStyle: StrutStyle(
|
||||
fontSize: fontSize ?? 16.0,
|
||||
)
|
||||
);
|
||||
|
||||
textPainter.layout(maxWidth: SizeConfig.width);
|
||||
|
||||
final int numberOfLines = textPainter.computeLineMetrics().length;
|
||||
return ValueListenableBuilder(
|
||||
valueListenable: expanded,
|
||||
builder: (context, values, _) {
|
||||
return Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
LayoutBuilder(
|
||||
builder: (BuildContext context, BoxConstraints constraints) {
|
||||
if (!expanded.value && numberOfLines >= maxLinesToShow) {
|
||||
return Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
content ?? "",
|
||||
maxLines: maxLinesToShow,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
style: TextStyle(
|
||||
fontSize: fontSize ?? 16.0,
|
||||
color: ColorPalette.slate400,
|
||||
),
|
||||
),
|
||||
/* See More :: type 1 - See More | 2 - See Less */
|
||||
SeeMoreLessWidget(
|
||||
textData: 'See More',
|
||||
type: 1,
|
||||
section: 1,
|
||||
onSeeMoreLessTap: () {
|
||||
expanded.value = true;
|
||||
},
|
||||
alignment: alignmentMore,
|
||||
hideIconMore: hideIconMore!,
|
||||
hideTextMore: hideTextMore!,
|
||||
),
|
||||
/* See More :: type 1 - See More | 2 - See Less */
|
||||
],
|
||||
);
|
||||
} else {
|
||||
return Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
content ?? "",
|
||||
style: TextStyle(
|
||||
fontSize: fontSize ?? 16.0,
|
||||
color: ColorPalette.slate400,
|
||||
),
|
||||
),
|
||||
if (expanded.value && numberOfLines >= maxLinesToShow)
|
||||
/* See Less :: type 1 - See More | 2 - See Less */
|
||||
SeeMoreLessWidget(
|
||||
textData: 'See Less',
|
||||
type: 2,
|
||||
section: 1,
|
||||
onSeeMoreLessTap: () {
|
||||
expanded.value = false;
|
||||
},
|
||||
alignment: alignmentMore,
|
||||
hideIconMore: hideIconMore!,
|
||||
hideTextMore: hideTextMore!,
|
||||
),
|
||||
/* See Less :: type 1 - See More | 2 - See Less */
|
||||
],
|
||||
);
|
||||
}
|
||||
},
|
||||
),
|
||||
],
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
|
@ -1,74 +0,0 @@
|
|||
import 'package:cims_apps/application/theme/color_palette.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class SeeMoreLessWidget extends StatelessWidget {
|
||||
final String? textData;
|
||||
final int? type; /* type 1 - See More | 2 - See Less */
|
||||
final Function? onSeeMoreLessTap;
|
||||
final int?
|
||||
section; /* 1: About the course | 2 - Who can take up this course? | 3 - Mentors | 4 - Course Video Reviews */
|
||||
final Alignment? alignment;
|
||||
final bool hideTextMore;
|
||||
final bool hideIconMore;
|
||||
|
||||
const SeeMoreLessWidget({
|
||||
super.key,
|
||||
required this.textData,
|
||||
required this.type,
|
||||
required this.onSeeMoreLessTap,
|
||||
required this.section,
|
||||
required this.alignment,
|
||||
required this.hideTextMore,
|
||||
required this.hideIconMore,
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Align(
|
||||
alignment: alignment ?? Alignment.centerLeft,
|
||||
child: InkWell(
|
||||
onTap: () {
|
||||
if (onSeeMoreLessTap != null) {
|
||||
onSeeMoreLessTap!();
|
||||
}
|
||||
},
|
||||
child: Text.rich(
|
||||
softWrap: true,
|
||||
style: const TextStyle(
|
||||
color: ColorPalette.primary,
|
||||
),
|
||||
textAlign: TextAlign.start,
|
||||
TextSpan(
|
||||
text: "",
|
||||
children: [
|
||||
if(!hideTextMore)
|
||||
TextSpan(
|
||||
text: textData,
|
||||
style: const TextStyle(
|
||||
color: ColorPalette.primary,
|
||||
decoration: TextDecoration.underline,
|
||||
),
|
||||
),
|
||||
if(!hideTextMore && !hideIconMore)
|
||||
const WidgetSpan(
|
||||
child: SizedBox(
|
||||
width: 3.0,
|
||||
),
|
||||
),
|
||||
if(!hideIconMore)
|
||||
WidgetSpan(
|
||||
child: Icon(
|
||||
(type == 1)
|
||||
? Icons.keyboard_arrow_down
|
||||
: Icons.keyboard_arrow_up,
|
||||
color: ColorPalette.slate300,
|
||||
size: 28,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
|
@ -1,4 +1,3 @@
|
|||
import 'package:cims_apps/application/component/expandable_widget/expandable_widget.dart';
|
||||
import 'package:cims_apps/application/theme/color_palette.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
|
@ -45,11 +44,28 @@ class RadioAgreement extends StatelessWidget {
|
|||
width: 12,
|
||||
),
|
||||
Expanded(
|
||||
child: ExpandableWidget(
|
||||
content: desc,
|
||||
maxLinesToShow: 3,
|
||||
)
|
||||
)
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
desc,
|
||||
style: TextStyle(
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: ColorPalette.slate400),
|
||||
),
|
||||
GestureDetector(
|
||||
onTap: () {},
|
||||
child: const Text(
|
||||
'Read More',
|
||||
style: TextStyle(
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.w600,
|
||||
decoration: TextDecoration.underline,
|
||||
color: ColorPalette.primary),
|
||||
))
|
||||
],
|
||||
))
|
||||
],
|
||||
),
|
||||
);
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
import 'package:cims_apps/application/assets/path_assets.dart';
|
||||
import 'package:cims_apps/application/component/expandable_widget/expandable_widget.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';
|
||||
|
@ -74,20 +73,20 @@ class RiskProfile extends StatelessWidget {
|
|||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Container(
|
||||
padding: const EdgeInsets.all(24),
|
||||
padding: EdgeInsets.all(24),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
riskProfile.type,
|
||||
style: const TextStyle(
|
||||
style: TextStyle(
|
||||
fontWeight: FontWeight.bold,
|
||||
fontSize: 24,
|
||||
color: ColorPalette.white
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 16,),
|
||||
const Text('Total Score :',
|
||||
SizedBox(height: 16,),
|
||||
Text('Total Score :',
|
||||
style: TextStyle(
|
||||
fontWeight: FontWeight.bold,
|
||||
fontSize: 16,
|
||||
|
@ -95,7 +94,7 @@ class RiskProfile extends StatelessWidget {
|
|||
),
|
||||
),
|
||||
Text('$totalScore',
|
||||
style: const TextStyle(
|
||||
style: TextStyle(
|
||||
fontWeight: FontWeight.bold,
|
||||
fontSize: 28,
|
||||
color: ColorPalette.white
|
||||
|
@ -108,20 +107,20 @@ class RiskProfile extends StatelessWidget {
|
|||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(
|
||||
SizedBox(
|
||||
height: 24,
|
||||
),
|
||||
ExpandableWidget(
|
||||
content: riskProfile.desc,
|
||||
hideTextMore: true,
|
||||
hideIconMore: false,
|
||||
maxLinesToShow: 4,
|
||||
alignmentMore: Alignment.center,
|
||||
Text(
|
||||
riskProfile.desc,
|
||||
style: TextStyle(
|
||||
color: ColorPalette.slate500,
|
||||
fontSize: 16
|
||||
)
|
||||
),
|
||||
const SizedBox(
|
||||
SizedBox(
|
||||
height: 24,
|
||||
),
|
||||
const Text(
|
||||
Text(
|
||||
'Suitable Product',
|
||||
style: TextStyle(
|
||||
color: ColorPalette.slate800,
|
||||
|
@ -129,7 +128,7 @@ class RiskProfile extends StatelessWidget {
|
|||
fontSize: 18
|
||||
),
|
||||
),
|
||||
const SizedBox(
|
||||
SizedBox(
|
||||
height: 16,
|
||||
),
|
||||
rowSuitableProduct ?
|
||||
|
@ -138,7 +137,7 @@ class RiskProfile extends StatelessWidget {
|
|||
return Expanded(
|
||||
child: Container(
|
||||
margin: EdgeInsets.only(left: e.key != 0 ? 12 : 0),
|
||||
padding: const EdgeInsets.all(16),
|
||||
padding: EdgeInsets.all(16),
|
||||
decoration: BoxDecoration(
|
||||
border: Border.all(color: ColorPalette.slate200),
|
||||
borderRadius: BorderRadius.circular(6)
|
||||
|
@ -147,18 +146,18 @@ class RiskProfile extends StatelessWidget {
|
|||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Container(
|
||||
padding: const EdgeInsets.all(8),
|
||||
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)
|
||||
),
|
||||
const SizedBox(
|
||||
SizedBox(
|
||||
height: 12,
|
||||
),
|
||||
Text(e.value['desc'],
|
||||
style: const TextStyle(
|
||||
style: TextStyle(
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.bold,
|
||||
color: ColorPalette.slate800
|
||||
|
@ -174,7 +173,7 @@ class RiskProfile extends StatelessWidget {
|
|||
runSpacing: 16,
|
||||
children: riskProfile.suitableProduct.map((e) {
|
||||
return Container(
|
||||
padding: const EdgeInsets.all(16),
|
||||
padding: EdgeInsets.all(16),
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(6),
|
||||
border: Border.all(color: ColorPalette.slate200),
|
||||
|
@ -182,7 +181,7 @@ class RiskProfile extends StatelessWidget {
|
|||
child: Row(
|
||||
children: [
|
||||
Container(
|
||||
padding: const EdgeInsets.all(8),
|
||||
padding: EdgeInsets.all(8),
|
||||
alignment: Alignment.center,
|
||||
decoration: BoxDecoration(
|
||||
shape: BoxShape.circle,
|
||||
|
@ -190,12 +189,12 @@ class RiskProfile extends StatelessWidget {
|
|||
),
|
||||
child: Image.asset(e['icon'], width: SizeConfig.width * 0.07, color: riskProfile.color)
|
||||
),
|
||||
const SizedBox(
|
||||
SizedBox(
|
||||
width: 12,
|
||||
),
|
||||
Expanded(
|
||||
child: Text(e['desc'],
|
||||
style: const TextStyle(
|
||||
style: TextStyle(
|
||||
fontSize: 18,
|
||||
fontWeight: FontWeight.bold,
|
||||
color: ColorPalette.slate800
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
import 'dart:math';
|
||||
|
||||
import 'package:cims_apps/application/component/button/button_view.dart';
|
||||
import 'package:cims_apps/application/component/numeric_pad/numeric_pad.dart';
|
||||
import 'package:cims_apps/application/theme/color_palette.dart';
|
||||
|
@ -8,13 +6,9 @@ import 'package:cims_apps/core/utils/size_config.dart';
|
|||
import 'package:flutter/material.dart';
|
||||
|
||||
class InputInvestmentView extends StatefulWidget {
|
||||
final String? currentPlan;
|
||||
final void Function()? changePlan;
|
||||
final int? currentPrice;
|
||||
final int? minimumPrice;
|
||||
final int? maximumPrice;
|
||||
final String selectedPlan;
|
||||
final void Function(String value) nextMove;
|
||||
const InputInvestmentView({super.key, required this.nextMove, this.currentPlan, this.minimumPrice, this.maximumPrice, this.currentPrice, this.changePlan});
|
||||
const InputInvestmentView({super.key, required this.selectedPlan, required this.nextMove});
|
||||
|
||||
@override
|
||||
State<InputInvestmentView> createState() => _InputInvestmentViewState();
|
||||
|
@ -23,35 +17,10 @@ class InputInvestmentView extends StatefulWidget {
|
|||
class _InputInvestmentViewState extends State<InputInvestmentView> {
|
||||
TextEditingController inputController = TextEditingController();
|
||||
|
||||
void validationInputValue(String currentValue) {
|
||||
currentValue = currentValue.replaceAll('Rp ', '').replaceAll('.', '');
|
||||
if(currentValue.isEmpty){
|
||||
currentValue = '0';
|
||||
}
|
||||
double parseValue = double.parse(currentValue);
|
||||
if(widget.minimumPrice != null){
|
||||
if(parseValue <= widget.minimumPrice!){
|
||||
parseValue = widget.minimumPrice!.toDouble();
|
||||
}
|
||||
}
|
||||
|
||||
if(widget.maximumPrice != null){
|
||||
if(parseValue >= widget.maximumPrice!){
|
||||
parseValue = widget.maximumPrice!.toDouble();
|
||||
}
|
||||
}
|
||||
|
||||
inputController.text = NumberFormatter.numberCurrency(parseValue, 'Rp ', 'id_ID', decimalDigits: 0);
|
||||
}
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
// TODO: implement initState
|
||||
if(widget.currentPrice != null){
|
||||
inputController.text = NumberFormatter.numberCurrency(widget.currentPrice, 'Rp ', 'id_ID', decimalDigits: 0);
|
||||
}else{
|
||||
inputController.text = 'Rp 0';
|
||||
}
|
||||
inputController.text = 'Rp 0';
|
||||
super.initState();
|
||||
}
|
||||
|
||||
|
@ -72,53 +41,55 @@ class _InputInvestmentViewState extends State<InputInvestmentView> {
|
|||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
SizedBox(height: 16),
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 24, vertical: 12),
|
||||
padding: EdgeInsets.symmetric(horizontal: 24, vertical: 12),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
if(widget.currentPlan != null)
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Text(widget.currentPlan ?? '',
|
||||
style: const TextStyle(
|
||||
fontSize: 20,
|
||||
fontWeight: FontWeight.w700,
|
||||
),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Text(widget.selectedPlan,
|
||||
style: TextStyle(
|
||||
fontSize: 20,
|
||||
fontWeight: FontWeight.w700,
|
||||
),
|
||||
InkWell(
|
||||
borderRadius: BorderRadius.circular(16),
|
||||
onTap: widget.changePlan,
|
||||
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
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
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
|
||||
),
|
||||
)
|
||||
],
|
||||
)
|
||||
],
|
||||
),
|
||||
TextField(
|
||||
controller: inputController,
|
||||
textAlign: TextAlign.center,
|
||||
style: const TextStyle(
|
||||
style: TextStyle(
|
||||
fontSize: 28,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: ColorPalette.slate800
|
||||
),
|
||||
keyboardType: TextInputType.number,
|
||||
onChanged: (value) {
|
||||
validationInputValue(value);
|
||||
value = value.replaceAll('Rp ', '').replaceAll('.', '');
|
||||
double parseValue = double.parse(value);
|
||||
if(value.isNotEmpty){
|
||||
inputController.text = NumberFormatter.numberCurrency(parseValue, 'Rp ', 'id_ID', decimalDigits: 0);
|
||||
}else{
|
||||
inputController.text = NumberFormatter.numberCurrency(0, 'Rp ', 'id_ID', decimalDigits: 0);
|
||||
}
|
||||
},
|
||||
decoration: const InputDecoration(
|
||||
decoration: InputDecoration(
|
||||
enabledBorder: UnderlineInputBorder(
|
||||
borderSide: BorderSide(
|
||||
color: ColorPalette.primary,
|
||||
|
@ -127,36 +98,30 @@ class _InputInvestmentViewState extends State<InputInvestmentView> {
|
|||
)
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 12),
|
||||
if(widget.minimumPrice != null)
|
||||
Text('Minimum ${NumberFormatter.numberCurrency(widget.minimumPrice, 'Rp ', 'id_ID')}',
|
||||
style: const TextStyle(
|
||||
color: ColorPalette.slate400,
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.w600
|
||||
),
|
||||
SizedBox(height: 12),
|
||||
Text('Minimum Budget Rp1,000,000',
|
||||
style: TextStyle(
|
||||
color: ColorPalette.slate400,
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.w600
|
||||
),
|
||||
if(widget.maximumPrice != null)
|
||||
Text('Maximum ${NumberFormatter.numberCurrency(widget.maximumPrice, 'Rp ', 'id_ID')}',
|
||||
style: const TextStyle(
|
||||
color: ColorPalette.slate400,
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.w600
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
),
|
||||
SizedBox(height: 16),
|
||||
NumericPad(onNumberSelected: (p0) {
|
||||
String currentValue = inputController.text;
|
||||
String checkIsZeroInput = inputController.text.replaceAll('Rp ', '').replaceAll(',', '');
|
||||
String getNumeric = p0;
|
||||
if(p0.isNotEmpty){
|
||||
if(currentValue != '0'){
|
||||
currentValue = currentValue + p0;
|
||||
if(checkIsZeroInput != '0'){
|
||||
getNumeric = checkIsZeroInput + getNumeric;
|
||||
}
|
||||
}else{
|
||||
currentValue = currentValue.substring(0, currentValue.length - 1);
|
||||
getNumeric = checkIsZeroInput.substring(0, checkIsZeroInput.length - 1);
|
||||
}
|
||||
validationInputValue(currentValue);
|
||||
String formatNumeric = NumberFormatter.numberCurrency(
|
||||
double.parse(getNumeric), 'Rp ', 'id_ID', decimalDigits: 0).replaceAll('.', ',');
|
||||
inputController.text = formatNumeric;
|
||||
}),
|
||||
const SizedBox(height: 24),
|
||||
SizedBox(height: 8),
|
||||
ButtonView(
|
||||
name: 'Next',
|
||||
onPressed: () {
|
||||
|
@ -164,7 +129,7 @@ class _InputInvestmentViewState extends State<InputInvestmentView> {
|
|||
},
|
||||
width: SizeConfig.width,
|
||||
heightWrapContent: true,
|
||||
contentPadding: const EdgeInsets.symmetric(vertical: 16),
|
||||
contentPadding: EdgeInsets.symmetric(vertical: 16),
|
||||
marginVertical: 0,
|
||||
)
|
||||
],
|
||||
|
@ -172,6 +137,6 @@ class _InputInvestmentViewState extends State<InputInvestmentView> {
|
|||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
);;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -139,8 +139,9 @@ class TotalPaymentView extends StatelessWidget {
|
|||
),
|
||||
RadioAgreement(
|
||||
isAgree: isAgree,
|
||||
desc: 'I agree to buy the mutual fund on this page and have read and agreed to all the contents of the Prospectus and summary information and understand the risks of my investment decision.',
|
||||
desc: 'I agree to buy the mutual fund on this page and have read and agreed to all the contents of the Prospectus and summary information and understand the risks of my investment decision. Read More',
|
||||
onTap: () {
|
||||
print('gagaga');
|
||||
onTapAgree();
|
||||
},
|
||||
),
|
||||
|
|
|
@ -1,8 +1,12 @@
|
|||
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';
|
||||
|
@ -42,32 +46,33 @@ class _PlanViewState extends State<PlanView> {
|
|||
appBar: CustomAppBar(
|
||||
height: SizeConfig.height * 0.08,
|
||||
title: 'Investment Plan',
|
||||
leading: const SizedBox(),
|
||||
leading: SizedBox(),
|
||||
),
|
||||
body: SingleChildScrollView(
|
||||
padding: const EdgeInsets.all(24),
|
||||
padding: EdgeInsets.all(24),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
const RiskProfile(
|
||||
RiskProfile(
|
||||
totalScore: 26,
|
||||
rowSuitableProduct: true
|
||||
),
|
||||
const SizedBox(
|
||||
SizedBox(
|
||||
height: 32,
|
||||
),
|
||||
const Text('Your Goal in Investing',
|
||||
Text('Your Goal in Investing',
|
||||
style: TextStyle(
|
||||
fontWeight: FontWeight.w700,
|
||||
color: ColorPalette.slate800,
|
||||
fontSize: 18
|
||||
),
|
||||
),
|
||||
const SizedBox(
|
||||
SizedBox(
|
||||
height: 24,
|
||||
),
|
||||
GoalInvestingView(
|
||||
onListSelected: (p0) {
|
||||
print(p0);
|
||||
showModalBottomSheet(
|
||||
context: context,
|
||||
isScrollControlled: true,
|
||||
|
@ -98,7 +103,7 @@ class _PlanViewState extends State<PlanView> {
|
|||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
const Text("It's time to invest",
|
||||
Text("It's time to invest",
|
||||
style: TextStyle(
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.w600
|
||||
|
@ -108,20 +113,17 @@ class _PlanViewState extends State<PlanView> {
|
|||
onTap: () {
|
||||
Navigator.pop(context);
|
||||
},
|
||||
child: const Icon(Icons.close_rounded)
|
||||
child: Icon(Icons.close_rounded)
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
const Divider(color: ColorPalette.slate200, height: 1),
|
||||
Divider(color: ColorPalette.slate200, height: 1),
|
||||
InputInvestmentView(
|
||||
currentPlan: text,
|
||||
changePlan: () {
|
||||
Navigator.pop(context);
|
||||
},
|
||||
selectedPlan: text,
|
||||
nextMove: (value) {
|
||||
Navigator.pop(context);
|
||||
int formatIntParse = int.parse(value.replaceAll('Rp ', '').replaceAll('.', ''));
|
||||
int formatIntParse = int.parse(value.replaceAll('Rp ', '').replaceAll(',', ''));
|
||||
showModalBottomSheet(context: context, builder: (context) => OptionsStartingInvest(totalInvest: formatIntParse));
|
||||
},
|
||||
),
|
||||
|
|
|
@ -4,7 +4,6 @@ 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/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';
|
||||
|
@ -19,33 +18,29 @@ class PortfolioDetailView extends StatelessWidget {
|
|||
List<PortfolioProduct> listProduct = [
|
||||
PortfolioProduct(
|
||||
name: 'Gemilang Dana Kas Maxima',
|
||||
type: 'Money Market',
|
||||
type: '',
|
||||
yield: 8.17,
|
||||
priceUnit: 2600.79,
|
||||
funds: 6300000,
|
||||
totalUnit: 14520
|
||||
),
|
||||
funds: 6300000),
|
||||
PortfolioProduct(
|
||||
name: 'Gemilang Dana Likuid',
|
||||
type: 'Sharia',
|
||||
type: '',
|
||||
yield: 6.42,
|
||||
priceUnit: 1600.79,
|
||||
funds: 2340000,
|
||||
totalUnit: 232,
|
||||
),
|
||||
funds: 2340000),
|
||||
PortfolioProduct(
|
||||
name: 'Gemilang Income Fund',
|
||||
type: 'Bonds',
|
||||
type: '',
|
||||
yield: 8.17,
|
||||
priceUnit: 2600.79,
|
||||
funds: 6300000,
|
||||
totalUnit: 2450,
|
||||
)
|
||||
funds: 6300000)
|
||||
];
|
||||
|
||||
|
||||
return ChangeNotifierProvider(
|
||||
create: (context) => RedeemProductViewModel(),
|
||||
return MultiProvider(
|
||||
providers: [
|
||||
ChangeNotifierProvider(create: (context) => RedeemProductViewModel())
|
||||
],
|
||||
child: Scaffold(
|
||||
backgroundColor: Colors.white,
|
||||
body: SizedBox(
|
||||
|
@ -105,20 +100,19 @@ class PortfolioDetailView extends StatelessWidget {
|
|||
),
|
||||
const SizedBox(height: 24,),
|
||||
Expanded(
|
||||
child: Container(
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
color: Colors.white,
|
||||
),
|
||||
child: Consumer<RedeemProductViewModel>(
|
||||
builder: (context, provider, child) {
|
||||
return ListView(
|
||||
padding: const EdgeInsets.all(24),
|
||||
children: listProduct.asMap().entries.map((e) {
|
||||
return cardPortfolio(context, e.value);
|
||||
}).toList(),
|
||||
);
|
||||
}
|
||||
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)
|
||||
],
|
||||
),
|
||||
),
|
||||
)
|
||||
)
|
||||
|
@ -131,7 +125,7 @@ class PortfolioDetailView extends StatelessWidget {
|
|||
);
|
||||
}
|
||||
|
||||
Widget cardPortfolio(context, PortfolioProduct product) {
|
||||
Widget cardPortfolio(context) {
|
||||
return Container(
|
||||
padding: const EdgeInsets.all(16),
|
||||
decoration: BoxDecoration(
|
||||
|
@ -161,19 +155,19 @@ class PortfolioDetailView extends StatelessWidget {
|
|||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
TextTitle(title: product.name ?? '', fontSize: 16,),
|
||||
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[product.type!]?.withOpacity(0.5) ?? Colors.white,
|
||||
border: Border.all(width: 2, color: ColorPalette.investTypeColor[product.type!]?.withOpacity(0.4) ?? Colors.white)
|
||||
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(
|
||||
product.type ?? '',
|
||||
'Money Market' ?? '',
|
||||
style: TextStyle(
|
||||
color: ColorPalette.investTypeColor[product.type!],
|
||||
color: ColorPalette.investTypeColor['Money Market'],
|
||||
fontWeight: FontWeight.w600
|
||||
),
|
||||
),
|
||||
|
@ -193,8 +187,8 @@ class PortfolioDetailView extends StatelessWidget {
|
|||
rowDescription('Present Value', 'Rp2.660.706', fontWeight: FontWeight.w700),
|
||||
rowDescription('Investment Capital', 'Rp2.660.706'),
|
||||
rowDescription('Advantages', 'Rp2.660.706'),
|
||||
rowDescription('Purchase Price', NumberFormatter.numberCurrency(product.priceUnit, 'Rp ', 'id_ID')),
|
||||
rowDescription('Number of Units', '${product.totalUnit ?? 0}'),
|
||||
rowDescription('Purchase Price', 'Rp1.500,57'),
|
||||
rowDescription('Number of Units', '14.002'),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 16,),
|
||||
|
@ -212,7 +206,6 @@ class PortfolioDetailView extends StatelessWidget {
|
|||
borderColor: ColorPalette.red600,
|
||||
textColor: ColorPalette.red600,
|
||||
onPressed: () {
|
||||
Provider.of<RedeemProductViewModel>(context, listen: false).setProduct(product);
|
||||
showModalBottomSheet(
|
||||
context: context,
|
||||
isScrollControlled: true,
|
||||
|
|
|
@ -4,7 +4,6 @@ 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/subscribe/input_investment_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';
|
||||
|
@ -83,33 +82,98 @@ class _ChangeAmountState extends State<ChangeAmount> {
|
|||
),
|
||||
),
|
||||
const Divider(height: 1, color: ColorPalette.slate200,),
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Padding(
|
||||
padding: EdgeInsets.all(24),
|
||||
child: cardProduct()
|
||||
),
|
||||
InputInvestmentView(
|
||||
minimumPrice: (provider.getCurrentProduct.priceUnit! * 1).toInt(),
|
||||
maximumPrice: (provider.getCurrentProduct.priceUnit! * provider.getCurrentProduct.totalUnit!).toInt(),
|
||||
currentPrice: provider.getAmount!.toInt(),
|
||||
nextMove: (value) {
|
||||
String formatValueInput = value.replaceAll('Rp ', '').replaceAll('.', '');
|
||||
provider.setAmount(double.parse(formatValueInput));
|
||||
Navigator.pop(context);
|
||||
showModalBottomSheet(
|
||||
context: context,
|
||||
isScrollControlled: true,
|
||||
builder: (context) {
|
||||
return const RedeemProduct();
|
||||
},
|
||||
);
|
||||
},
|
||||
)
|
||||
],
|
||||
),
|
||||
SizedBox(height: 16,)
|
||||
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();
|
||||
},
|
||||
);
|
||||
},
|
||||
)
|
||||
],
|
||||
),
|
||||
)
|
||||
],
|
||||
);
|
||||
}
|
||||
|
|
|
@ -42,7 +42,8 @@ class _RedeemProductState extends State<RedeemProduct> {
|
|||
create: (context) => RedeemProductViewModel(),
|
||||
child: Consumer<RedeemProductViewModel>(
|
||||
builder: (context, provider, child) {
|
||||
amountController.text = NumberFormatter.numberCurrency(provider.getAmount!.toInt(), 'Rp ', 'id_ID', decimalDigits: 0);
|
||||
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: [
|
||||
|
@ -75,8 +76,8 @@ class _RedeemProductState extends State<RedeemProduct> {
|
|||
const SizedBox(height: 16),
|
||||
segmentAmount(
|
||||
context,
|
||||
provider.getAmount!,
|
||||
provider.getUnit!,
|
||||
provider.getAmount ?? provider.getCurrentProduct.priceUnit! * (provider.getCurrentProduct.totalUnit! / 2.0),
|
||||
provider.getUnit ?? provider.getCurrentProduct.totalUnit! / 2.0,
|
||||
(value) {
|
||||
provider.setUnit(value);
|
||||
},
|
||||
|
|
|
@ -61,8 +61,6 @@ class RedeemProductViewModel extends ChangeNotifier {
|
|||
|
||||
void setProduct(PortfolioProduct product) {
|
||||
currentProduct = product;
|
||||
amount = product.priceUnit! * (product.totalUnit! / 2.0);
|
||||
unit = (product.totalUnit! / 2.0);
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
|
|
|
@ -55,43 +55,32 @@ class SelectGoalInvesting extends StatelessWidget {
|
|||
create: (context) => ProductViewModel(),
|
||||
child: Consumer<ProductViewModel>(
|
||||
builder: (context, provider, child) {
|
||||
return Padding(
|
||||
padding: EdgeInsets.symmetric(vertical: 16),
|
||||
child: InputInvestmentView(
|
||||
currentPlan: p0,
|
||||
changePlan: () {
|
||||
Navigator.pop(context);
|
||||
showModalBottomSheet(
|
||||
context: context,
|
||||
isScrollControlled: true,
|
||||
builder: (context) => SelectGoalInvesting(),
|
||||
);
|
||||
},
|
||||
nextMove: (value) {
|
||||
Navigator.pop(context);
|
||||
int formatIntParse = int.parse(value.replaceAll('Rp ', '').replaceAll('.', ''));
|
||||
showModalBottomSheet(
|
||||
context: context,
|
||||
isScrollControlled: true,
|
||||
builder: (context) =>
|
||||
ChangeNotifierProvider(
|
||||
create: (context) => ProductViewModel(),
|
||||
child: Consumer<ProductViewModel>(
|
||||
builder: (context, provider, child) {
|
||||
return TotalPaymentView(
|
||||
listProduct: [
|
||||
provider.getSelectedProduct
|
||||
],
|
||||
totalInvest: formatIntParse,
|
||||
isAgree: provider.isAgree,
|
||||
onTapAgree: provider.setAgree,
|
||||
);
|
||||
}
|
||||
),
|
||||
)
|
||||
);
|
||||
},
|
||||
),
|
||||
return InputInvestmentView(
|
||||
selectedPlan: p0,
|
||||
nextMove: (value) {
|
||||
Navigator.pop(context);
|
||||
int formatIntParse = int.parse(value.replaceAll('Rp ', '').replaceAll(',', ''));
|
||||
showModalBottomSheet(
|
||||
context: context,
|
||||
isScrollControlled: true,
|
||||
builder: (context) =>
|
||||
ChangeNotifierProvider(
|
||||
create: (context) => ProductViewModel(),
|
||||
child: Consumer<ProductViewModel>(
|
||||
builder: (context, provider, child) {
|
||||
return TotalPaymentView(
|
||||
listProduct: [
|
||||
provider.getSelectedProduct
|
||||
],
|
||||
totalInvest: formatIntParse,
|
||||
isAgree: provider.isAgree,
|
||||
onTapAgree: provider.setAgree,
|
||||
);
|
||||
}
|
||||
),
|
||||
)
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
),
|
||||
|
|
|
@ -44,7 +44,7 @@ class DashboardPublicView extends StatelessWidget {
|
|||
return Scaffold(
|
||||
body: SingleChildScrollView(
|
||||
padding: const EdgeInsets.only(
|
||||
top: 36.0,
|
||||
top: 32.0,
|
||||
bottom: 8.0,
|
||||
left: 24.0,
|
||||
right: 24.0,
|
||||
|
@ -59,7 +59,6 @@ class DashboardPublicView extends StatelessWidget {
|
|||
image: PathAssets.icon1,
|
||||
width: SizeConfig.width * .35,
|
||||
),
|
||||
SizedBox(height: SizeConfig.height * .03),
|
||||
Align(
|
||||
alignment: Alignment.center,
|
||||
heightFactor: 1,
|
||||
|
@ -106,7 +105,7 @@ class DashboardPublicView extends StatelessWidget {
|
|||
provider.loginGoogle(context);
|
||||
},
|
||||
),
|
||||
SizedBox(height: SizeConfig.height * .07),
|
||||
SizedBox(height: SizeConfig.height * .15),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
|
|
Loading…
Reference in New Issue
Block a user