fix: validation input investment
This commit is contained in:
parent
38837bd4f8
commit
d79959c47f
|
@ -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> {
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
);;
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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));
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
|
|
|
@ -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,)
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 {
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
),
|
),
|
||||||
|
|
Loading…
Reference in New Issue
Block a user