Untitled
unknown
plain_text
9 months ago
25 kB
9
Indexable
import 'package:ctexpeess/constants/dimensions.dart';
import 'package:ctexpeess/constants/styles.dart';
import 'package:ctexpeess/core/config/color.dart';
import 'package:ctexpeess/core/config/constant.dart';
import 'package:ctexpeess/core/utils/platform_physics.dart';
import 'package:ctexpeess/core/widget/cus_elevated_button.dart';
import 'package:ctexpeess/core/widget/cus_form_field.dart';
import 'package:ctexpeess/core/widget/svg_builder.dart';
import 'package:ctexpeess/feature/add_fund/presentation/cubit/transfer_quote.cubit.dart';
import 'package:ctexpeess/feature/add_fund/presentation/view/widget/confirm_detail_widger.dart';
import 'package:ctexpeess/feature/add_fund/presentation/view/widget/transfer_detail_invalid_widget.dart';
import 'package:ctexpeess/feature/home/data/model/beneficiary.model.dart';
import 'package:ctexpeess/feature/home/presentation/cubit/virtual_card.state.dart';
import 'package:ctexpeess/feature/home/presentation/cubit/virutal_card.cubit.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter/widgets.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'dart:async';
class TransferDetailWidget extends StatefulWidget {
final BeneficiaryModel? beneficiary;
final void Function()? onContinue;
const TransferDetailWidget({
super.key,
this.onContinue,
this.beneficiary,
});
@override
State<TransferDetailWidget> createState() => _TransferDetailWidgetState();
}
class _TransferDetailWidgetState extends State<TransferDetailWidget> {
final GlobalKey<FormState> _formkey = GlobalKey<FormState>();
TextEditingController promoTxcontroller = TextEditingController();
TextEditingController receiverTxcontroller = TextEditingController();
TextEditingController sendTxcontroller = TextEditingController();
bool disabled = true;
bool isInvalid = false;
final double serviceFeePercentage = 2.5;
double balance = 1.0;
bool balanceError = false;
double exchangeRate = 0.0;
double serviceFee = 0.0;
double amountToConvert = 0.0;
late final BeneficiaryModel? beneficiary;
// Add timer for debouncing
Timer? _debounceTimer;
@override
void initState() {
beneficiary = widget.beneficiary;
super.initState();
// sendTxcontroller.addListener(_calculateConversionDetails);
print("initState");
print(widget.beneficiary?.bankName);
print(widget.beneficiary?.address);
print(widget.beneficiary?.bankAccountNumber);
print(widget.beneficiary?.bankName);
print(widget.beneficiary?.country);
print(widget.beneficiary?.currency);
print(widget.beneficiary?.name);
print(widget.beneficiary?.photoUrl);
print(widget.beneficiary?.relationship);
print(widget.beneficiary?.type);
getTransferQuote();
}
void getTransferQuote() {
// Cancel any existing timer
_debounceTimer?.cancel();
// Set new timer
_debounceTimer = Timer(const Duration(milliseconds: 500), () {
context.read<TransferQuoteCubit>().getTransferQuote(
beneficiaryId: beneficiary?.id ?? " ",
sendAmount: sendTxcontroller.text,
sendCurrency: "AUD",
);
});
}
/* void _calculateConversionDetails() {
setState(() {
final double sendAmount = double.tryParse(sendTxcontroller.text) ?? 0.0;
serviceFee = (sendAmount * serviceFeePercentage) / 100;
amountToConvert = sendAmount - serviceFee;
final double receiverAmount = amountToConvert * exchangeRate;
receiverTxcontroller.text = receiverAmount.toStringAsFixed(2);
});
} */
void _updateFieldState() {
getTransferQuote();
setState(() {
disabled = sendTxcontroller.text.isEmpty ||
receiverTxcontroller.text.isEmpty ||
!(_formkey.currentState?.validate() ?? false);
});
}
@override
void dispose() {
_debounceTimer?.cancel(); // Cancel timer on dispose
sendTxcontroller.dispose();
receiverTxcontroller.dispose();
promoTxcontroller.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return isInvalid
? const TransferDetailInvalidWidget()
: BlocConsumer<TransferQuoteCubit, TransferQuoteState>(
listener: (context, state) {
if (state is TransferQuoteSuccess) {
print(state.transferQuoteModel.data?.toMap());
setState(() {
exchangeRate = double.tryParse(
state.transferQuoteModel.data?.exchangeRate ??
"0.0") ??
0.0;
serviceFee = double.tryParse(state
.transferQuoteModel.data?.serviceFee
.toString() ??
"0.0") ??
0.0;
receiverTxcontroller.text = state
.transferQuoteModel.data?.receiveAmount
?.toStringAsFixed(2) ??
"0.00";
});
print(exchangeRate);
print(serviceFee);
}
},
builder: (context, state) {
return SingleChildScrollView(
physics: platformPhysics,
child: Padding(
padding: const EdgeInsets.only(
left: Dimensions.HORIZONTAL_PADDING,
right: Dimensions.HORIZONTAL_PADDING),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
children: [
Text("Transfer Details", style: bodyBoldStyle),
const Spacer(),
Container(
decoration: BoxDecoration(
color: balanceError
? CusColor.kR900
: CusColor.kG900,
borderRadius: BorderRadius.circular(
RadiusDimensions.ROUND_6),
),
child: Padding(
padding: const EdgeInsets.symmetric(
horizontal: Dimensions.P8,
vertical: Dimensions.P6),
child: Center(
child: BlocBuilder<VirtualCardCubit,
VirtualCardState>(
builder: (context, state) {
if (state is VirtualCardSuccess) {
balance = double.tryParse(state
.virtualCard
.data
?.balance ??
"0.00") ??
0.00;
return Text(
"\$${balance.toStringAsFixed(2)}",
style: bodyBoldStyle.copyWith(
color: balanceError
? CusColor.kR400
: CusColor.kG100),
);
} else {
return Text(
"\$0.00",
style: bodyBoldStyle.copyWith(
color: CusColor.kG100),
);
}
},
),
),
),
),
],
),
const SizedBox(
height: Spacers.SPACER_12,
),
Container(
decoration: BoxDecoration(
color: CusColor.kP99,
borderRadius:
BorderRadius.circular(RadiusDimensions.ROUND_6),
),
child: Padding(
padding: const EdgeInsets.all(Dimensions.P16),
child: Column(children: [
Row(
children: [
Text(
beneficiary?.name ?? "John Doe",
style: bodyBoldStyle.copyWith(
color: CusColor.kBlack100),
),
Flexible(
child: Align(
alignment: Alignment.bottomRight,
child: Text(
beneficiary?.bankAccountNumber
?.isNotEmpty ==
true
? beneficiary!.bankAccountNumber!
.length >
5
? "Acc.No: **** ${beneficiary!.bankAccountNumber!.substring(beneficiary!.bankAccountNumber!.length - 5)}"
: "Acc.No: ${beneficiary!.bankAccountNumber}"
: "Acc.No: N/A",
style: bodyBoldStyle.copyWith(
color: CusColor.kBlack100),
overflow: TextOverflow.ellipsis,
maxLines: 2,
),
),
)
],
),
const SizedBox(
height: Spacers.SPACER_12,
),
Row(
children: [
SvgBuilder(
svgUrl: beneficiary?.photoUrl ??
ImageAsset.kImNepal,
height: 24,
),
const SizedBox(
width: Spacers.SPACER_12,
),
Text(
beneficiary?.country ?? "Nepal",
style: bodyMediumStyle.copyWith(
color: CusColor.kBlack300),
),
const SizedBox(
width: Spacers.SPACER_12,
),
Flexible(
child: Align(
alignment: Alignment.bottomRight,
child: Tooltip(
message: beneficiary?.bankName ?? "",
child: Text(
beneficiary?.bankName ?? "",
style: bodyBoldStyle.copyWith(
color: CusColor.kBlack100),
overflow: TextOverflow.ellipsis,
maxLines: 1,
),
),
),
),
],
),
]),
),
),
const SizedBox(
height: Spacers.SPACER_24,
),
Form(
key: _formkey,
child: Column(
children: [
CusFormField(
controller: sendTxcontroller,
label: 'Send Exactly',
hintText: "",
prefixSvg: SvgAsset.kAIcDollarSign,
prefixOnTapPadding: 17,
prefixIconColor: CusColor.kBlack100,
keyboardType: TextInputType.number,
inputFormatters: [
FilteringTextInputFormatter.digitsOnly
],
validator: (value) {
if (value == null || value.isEmpty) {
setState(() {
balanceError = true;
});
return "Please enter an amount";
} else if (balance < double.parse(value)) {
setState(() {
balanceError = true;
});
return "Insufficient Fund";
}
setState(() {
balanceError = false;
});
return null;
},
onChanged: (value) => _updateFieldState(),
suffixSvg: balanceError
? SvgAsset.kAIcExclamationIcon
: null,
suffixIconColor: CusColor.kR500,
suffixText: balanceError ? null : "AUD",
),
const SizedBox(
height: Spacers.SPACER_20,
),
Column(
children: [
Row(
children: [
Container(
height: 100,
width: 2,
color: CusColor.kBlack800,
),
const SizedBox(width: 10),
Expanded(
child: Column(
children: [
Row(
mainAxisAlignment:
MainAxisAlignment
.spaceBetween,
children: [
Tooltip(
message:
"\$${serviceFee.toStringAsFixed(2)} AUD",
child: Text(
serviceFee
.toStringAsFixed(
2)
.length >
10
? "\$${serviceFee.toStringAsFixed(2).substring(0, 10)}..."
: "\$${serviceFee.toStringAsFixed(2)} AUD",
style: bodyMediumStyle
.copyWith(
color: CusColor
.kBlack300),
),
),
Text(
"Service fees",
style:
bodyMediumStyle.copyWith(
color: CusColor
.kBlack300),
),
],
),
const SizedBox(
height: Spacers.SPACER_20),
Row(
mainAxisAlignment:
MainAxisAlignment
.spaceBetween,
children: [
Tooltip(
message:
"\$${amountToConvert.toStringAsFixed(2)} AUD",
child: Text(
amountToConvert
.toStringAsFixed(
2)
.length >
10
? "\$${amountToConvert.toStringAsFixed(2).substring(0, 10)}..."
: "\$${amountToConvert.toStringAsFixed(2)} AUD",
style: bodyMediumStyle
.copyWith(
color: CusColor
.kBlack300),
),
),
Text(
"Amount we'll convert",
style:
bodyMediumStyle.copyWith(
color: CusColor
.kBlack300),
),
],
),
const SizedBox(
height: Spacers.SPACER_20),
Row(
mainAxisAlignment:
MainAxisAlignment
.spaceBetween,
children: [
Tooltip(
message: exchangeRate
.toStringAsFixed(2),
child: Text(
exchangeRate
.toStringAsFixed(
2)
.length >
10
? "${exchangeRate.toStringAsFixed(2).substring(0, 10)}..."
: exchangeRate
.toStringAsFixed(2),
style: bodyMediumStyle
.copyWith(
color: CusColor
.kBlack300),
maxLines: 1,
),
),
Text(
"Exchange rate",
style:
bodyMediumStyle.copyWith(
color: CusColor
.kBlack300),
),
],
),
],
),
),
],
),
],
),
const SizedBox(
height: Spacers.SPACER_24,
),
CusFormField(
controller: receiverTxcontroller,
inputFormatters: [
FilteringTextInputFormatter.digitsOnly
],
label: 'Receiver gets',
hintText: "0.00",
keyboardType: TextInputType.number,
onChanged: (value) => _updateFieldState(),
suffixText: "NPR",
),
const SizedBox(
height: Spacers.SPACER_24,
),
CusFormField(
controller: promoTxcontroller,
label: 'Promo Code',
hintText: "Enter Code",
keyboardType: TextInputType.number,
onChanged: (value) => _updateFieldState(),
),
const SizedBox(
height: Spacers.SPACER_24,
),
GestureDetector(
child: Row(
children: [
Expanded(
child: CusElevatedButton(
onPressed: () {
ConfirmDetailWidger(
beneficiary: beneficiary,
onContinue: () {},
);
widget.onContinue?.call();
},
disabled: disabled,
text: 'Continue',
)),
],
),
)
],
),
),
]),
),
);
},
);
}
}
Editor is loading...
Leave a Comment