fix: validation input investment

This commit is contained in:
Prajna Prayoga 2024-02-23 14:56:06 +07:00
parent 38837bd4f8
commit d79959c47f
4 changed files with 161 additions and 176 deletions

View File

@ -1,3 +1,5 @@
import 'dart:math';
import 'package:cims_apps/application/component/button/button_view.dart'; 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/component/numeric_pad/numeric_pad.dart';
import 'package:cims_apps/application/theme/color_palette.dart'; import 'package:cims_apps/application/theme/color_palette.dart';
@ -6,9 +8,13 @@ import 'package:cims_apps/core/utils/size_config.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
class InputInvestmentView extends StatefulWidget { class InputInvestmentView extends StatefulWidget {
final String selectedPlan; final String? currentPlan;
final void Function()? changePlan;
final int? currentPrice;
final int? minimumPrice;
final int? maximumPrice;
final void Function(String value) nextMove; final void Function(String value) nextMove;
const InputInvestmentView({super.key, required this.selectedPlan, required this.nextMove}); const InputInvestmentView({super.key, required this.nextMove, this.currentPlan, this.minimumPrice, this.maximumPrice, this.currentPrice, this.changePlan});
@override @override
State<InputInvestmentView> createState() => _InputInvestmentViewState(); State<InputInvestmentView> createState() => _InputInvestmentViewState();
@ -17,10 +23,35 @@ class InputInvestmentView extends StatefulWidget {
class _InputInvestmentViewState extends State<InputInvestmentView> { class _InputInvestmentViewState extends State<InputInvestmentView> {
TextEditingController inputController = TextEditingController(); 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 @override
void initState() { void initState() {
// TODO: implement 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(); super.initState();
} }
@ -41,22 +72,25 @@ class _InputInvestmentViewState extends State<InputInvestmentView> {
child: Column( child: Column(
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
children: [ children: [
SizedBox(height: 16),
Padding( Padding(
padding: EdgeInsets.symmetric(horizontal: 24, vertical: 12), padding: const EdgeInsets.symmetric(horizontal: 24, vertical: 12),
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
if(widget.currentPlan != null)
Row( Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween, mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [ children: [
Text(widget.selectedPlan, Text(widget.currentPlan ?? '',
style: TextStyle( style: const TextStyle(
fontSize: 20, fontSize: 20,
fontWeight: FontWeight.w700, fontWeight: FontWeight.w700,
), ),
), ),
Row( InkWell(
borderRadius: BorderRadius.circular(16),
onTap: widget.changePlan,
child: const Row(
children: [ children: [
Icon(Icons.change_circle_outlined, color: ColorPalette.primary, size: 20), Icon(Icons.change_circle_outlined, color: ColorPalette.primary, size: 20),
SizedBox(width: 4), SizedBox(width: 4),
@ -68,28 +102,23 @@ class _InputInvestmentViewState extends State<InputInvestmentView> {
), ),
) )
], ],
),
) )
], ],
), ),
TextField( TextField(
controller: inputController, controller: inputController,
textAlign: TextAlign.center, textAlign: TextAlign.center,
style: TextStyle( style: const TextStyle(
fontSize: 28, fontSize: 28,
fontWeight: FontWeight.w600, fontWeight: FontWeight.w600,
color: ColorPalette.slate800 color: ColorPalette.slate800
), ),
keyboardType: TextInputType.number, keyboardType: TextInputType.number,
onChanged: (value) { onChanged: (value) {
value = value.replaceAll('Rp ', '').replaceAll('.', ''); validationInputValue(value);
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: InputDecoration( decoration: const InputDecoration(
enabledBorder: UnderlineInputBorder( enabledBorder: UnderlineInputBorder(
borderSide: BorderSide( borderSide: BorderSide(
color: ColorPalette.primary, color: ColorPalette.primary,
@ -98,30 +127,36 @@ class _InputInvestmentViewState extends State<InputInvestmentView> {
) )
), ),
), ),
SizedBox(height: 12), const SizedBox(height: 12),
Text('Minimum Budget Rp1,000,000', if(widget.minimumPrice != null)
style: TextStyle( Text('Minimum ${NumberFormatter.numberCurrency(widget.minimumPrice, 'Rp ', 'id_ID')}',
style: const TextStyle(
color: ColorPalette.slate400, color: ColorPalette.slate400,
fontSize: 16, fontSize: 16,
fontWeight: FontWeight.w600 fontWeight: FontWeight.w600
), ),
), ),
SizedBox(height: 16), 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),
NumericPad(onNumberSelected: (p0) { NumericPad(onNumberSelected: (p0) {
String checkIsZeroInput = inputController.text.replaceAll('Rp ', '').replaceAll(',', ''); String currentValue = inputController.text;
String getNumeric = p0;
if(p0.isNotEmpty){ if(p0.isNotEmpty){
if(checkIsZeroInput != '0'){ if(currentValue != '0'){
getNumeric = checkIsZeroInput + getNumeric; currentValue = currentValue + p0;
} }
}else{ }else{
getNumeric = checkIsZeroInput.substring(0, checkIsZeroInput.length - 1); currentValue = currentValue.substring(0, currentValue.length - 1);
} }
String formatNumeric = NumberFormatter.numberCurrency( validationInputValue(currentValue);
double.parse(getNumeric), 'Rp ', 'id_ID', decimalDigits: 0).replaceAll('.', ',');
inputController.text = formatNumeric;
}), }),
SizedBox(height: 8), const SizedBox(height: 24),
ButtonView( ButtonView(
name: 'Next', name: 'Next',
onPressed: () { onPressed: () {
@ -129,7 +164,7 @@ class _InputInvestmentViewState extends State<InputInvestmentView> {
}, },
width: SizeConfig.width, width: SizeConfig.width,
heightWrapContent: true, heightWrapContent: true,
contentPadding: EdgeInsets.symmetric(vertical: 16), contentPadding: const EdgeInsets.symmetric(vertical: 16),
marginVertical: 0, marginVertical: 0,
) )
], ],
@ -137,6 +172,6 @@ class _InputInvestmentViewState extends State<InputInvestmentView> {
), ),
], ],
), ),
);; );
} }
} }

View File

@ -115,10 +115,13 @@ class _PlanViewState extends State<PlanView> {
), ),
const Divider(color: ColorPalette.slate200, height: 1), const Divider(color: ColorPalette.slate200, height: 1),
InputInvestmentView( InputInvestmentView(
selectedPlan: text, currentPlan: text,
changePlan: () {
Navigator.pop(context);
},
nextMove: (value) { nextMove: (value) {
Navigator.pop(context); 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)); showModalBottomSheet(context: context, builder: (context) => OptionsStartingInvest(totalInvest: formatIntParse));
}, },
), ),

View File

@ -4,6 +4,7 @@ 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/button/button_view.dart';
import 'package:cims_apps/application/component/image/image_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/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/component/text_title/text_title.dart';
import 'package:cims_apps/application/theme/color_palette.dart'; import 'package:cims_apps/application/theme/color_palette.dart';
import 'package:cims_apps/core/utils/number_formatter.dart'; import 'package:cims_apps/core/utils/number_formatter.dart';
@ -82,84 +83,19 @@ class _ChangeAmountState extends State<ChangeAmount> {
), ),
), ),
const Divider(height: 1, color: ColorPalette.slate200,), const Divider(height: 1, color: ColorPalette.slate200,),
Padding( Column(
padding: EdgeInsets.all(24),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
cardProduct(), Padding(
SizedBox(height: 24), padding: EdgeInsets.all(24),
TextField( child: cardProduct()
controller: amountController,
textAlign: TextAlign.center,
style: const TextStyle(
fontSize: 28,
fontWeight: FontWeight.w600,
color: ColorPalette.slate800
), ),
keyboardType: TextInputType.number, InputInvestmentView(
onChanged: (value) { minimumPrice: (provider.getCurrentProduct.priceUnit! * 1).toInt(),
value = value.replaceAll('Rp ', '').replaceAll('.', ''); maximumPrice: (provider.getCurrentProduct.priceUnit! * provider.getCurrentProduct.totalUnit!).toInt(),
double parseValue = double.parse(value); currentPrice: provider.getAmount!.toInt(),
if(value.isNotEmpty){ nextMove: (value) {
amountController.text = NumberFormatter.numberCurrency(parseValue, 'Rp ', 'id_ID', decimalDigits: 0); String formatValueInput = value.replaceAll('Rp ', '').replaceAll('.', '');
}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)); provider.setAmount(double.parse(formatValueInput));
Navigator.pop(context); Navigator.pop(context);
showModalBottomSheet( showModalBottomSheet(
@ -173,7 +109,7 @@ class _ChangeAmountState extends State<ChangeAmount> {
) )
], ],
), ),
) SizedBox(height: 16,)
], ],
); );
} }

View File

@ -55,11 +55,21 @@ class SelectGoalInvesting extends StatelessWidget {
create: (context) => ProductViewModel(), create: (context) => ProductViewModel(),
child: Consumer<ProductViewModel>( child: Consumer<ProductViewModel>(
builder: (context, provider, child) { builder: (context, provider, child) {
return InputInvestmentView( return Padding(
selectedPlan: p0, padding: EdgeInsets.symmetric(vertical: 16),
child: InputInvestmentView(
currentPlan: p0,
changePlan: () {
Navigator.pop(context);
showModalBottomSheet(
context: context,
isScrollControlled: true,
builder: (context) => SelectGoalInvesting(),
);
},
nextMove: (value) { nextMove: (value) {
Navigator.pop(context); Navigator.pop(context);
int formatIntParse = int.parse(value.replaceAll('Rp ', '').replaceAll(',', '')); int formatIntParse = int.parse(value.replaceAll('Rp ', '').replaceAll('.', ''));
showModalBottomSheet( showModalBottomSheet(
context: context, context: context,
isScrollControlled: true, isScrollControlled: true,
@ -81,6 +91,7 @@ class SelectGoalInvesting extends StatelessWidget {
) )
); );
}, },
),
); );
} }
), ),