quick-pay-screens
This commit is contained in:
parent
0a69a9a09f
commit
89c1ab8992
@ -5,6 +5,7 @@ import 'package:kmobile/features/cheque/screens/cheque_management_screen.dart';
|
|||||||
import 'package:kmobile/features/customer_info/screens/customer_info_screen.dart';
|
import 'package:kmobile/features/customer_info/screens/customer_info_screen.dart';
|
||||||
import 'package:kmobile/features/beneficiaries/screens/manage_beneficiaries_screen.dart';
|
import 'package:kmobile/features/beneficiaries/screens/manage_beneficiaries_screen.dart';
|
||||||
import 'package:kmobile/features/enquiry/screens/enquiry_screen.dart';
|
import 'package:kmobile/features/enquiry/screens/enquiry_screen.dart';
|
||||||
|
import 'package:kmobile/features/quick_pay/screens/quick_pay_screen.dart';
|
||||||
import 'package:material_symbols_icons/material_symbols_icons.dart';
|
import 'package:material_symbols_icons/material_symbols_icons.dart';
|
||||||
|
|
||||||
class DashboardScreen extends StatefulWidget {
|
class DashboardScreen extends StatefulWidget {
|
||||||
@ -113,7 +114,10 @@ class _DashboardScreenState extends State<DashboardScreen> {
|
|||||||
builder: (context) => const CustomerInfoScreen()));
|
builder: (context) => const CustomerInfoScreen()));
|
||||||
}),
|
}),
|
||||||
_buildQuickLink(Symbols.currency_rupee, "Quick \n Pay",
|
_buildQuickLink(Symbols.currency_rupee, "Quick \n Pay",
|
||||||
() => print("")),
|
() {
|
||||||
|
Navigator.push(context, MaterialPageRoute(
|
||||||
|
builder: (context) => const QuickPayScreen()));
|
||||||
|
}),
|
||||||
_buildQuickLink(Symbols.send_money, "Fund \n Transfer",
|
_buildQuickLink(Symbols.send_money, "Fund \n Transfer",
|
||||||
() => print("")),
|
() => print("")),
|
||||||
_buildQuickLink(Symbols.server_person, "Account \n Info",
|
_buildQuickLink(Symbols.server_person, "Account \n Info",
|
||||||
|
@ -0,0 +1,368 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:material_symbols_icons/material_symbols_icons.dart';
|
||||||
|
|
||||||
|
class QuickPayOutsideBankScreen extends StatefulWidget {
|
||||||
|
const QuickPayOutsideBankScreen({super.key});
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<QuickPayOutsideBankScreen> createState() =>
|
||||||
|
_QuickPayOutsideBankScreen();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _QuickPayOutsideBankScreen extends State<QuickPayOutsideBankScreen> {
|
||||||
|
final _formKey = GlobalKey<FormState>();
|
||||||
|
|
||||||
|
// Controllers
|
||||||
|
final accountNumberController = TextEditingController();
|
||||||
|
final nameController = TextEditingController();
|
||||||
|
final bankNameController = TextEditingController();
|
||||||
|
final branchNameController = TextEditingController();
|
||||||
|
final ifscController = TextEditingController();
|
||||||
|
final phoneController = TextEditingController();
|
||||||
|
final amountController = TextEditingController();
|
||||||
|
|
||||||
|
String accountType = 'Savings';
|
||||||
|
final List<String> transactionModes = ['NEFT', 'RTGS', 'IMPS'];
|
||||||
|
int selectedTransactionIndex = 0;
|
||||||
|
|
||||||
|
@override
|
||||||
|
void dispose() {
|
||||||
|
// Dispose controllers
|
||||||
|
accountNumberController.dispose();
|
||||||
|
nameController.dispose();
|
||||||
|
bankNameController.dispose();
|
||||||
|
branchNameController.dispose();
|
||||||
|
ifscController.dispose();
|
||||||
|
phoneController.dispose();
|
||||||
|
amountController.dispose();
|
||||||
|
super.dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Scaffold(
|
||||||
|
appBar: AppBar(
|
||||||
|
leading: IconButton(
|
||||||
|
icon: const Icon(Symbols.arrow_back_ios_new),
|
||||||
|
onPressed: () {
|
||||||
|
Navigator.pop(context);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
title: const Text(
|
||||||
|
'Quick Pay - Other Bank',
|
||||||
|
style: TextStyle(color: Colors.black, fontWeight: FontWeight.w500),
|
||||||
|
),
|
||||||
|
centerTitle: false,
|
||||||
|
actions: const [
|
||||||
|
Padding(
|
||||||
|
padding: EdgeInsets.only(right: 10.0),
|
||||||
|
child: CircleAvatar(
|
||||||
|
backgroundImage: AssetImage('assets/images/avatar.jpg'),
|
||||||
|
// Replace with your image
|
||||||
|
radius: 20,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
body: Padding(
|
||||||
|
padding: const EdgeInsets.all(12),
|
||||||
|
child: Form(
|
||||||
|
key: _formKey,
|
||||||
|
child: ListView(
|
||||||
|
children: [
|
||||||
|
const SizedBox(height: 25),
|
||||||
|
TextFormField(
|
||||||
|
decoration: const InputDecoration(
|
||||||
|
labelText: 'Account Number',
|
||||||
|
border: OutlineInputBorder(),
|
||||||
|
isDense: true,
|
||||||
|
filled: true,
|
||||||
|
fillColor: Colors.white,
|
||||||
|
enabledBorder: OutlineInputBorder(
|
||||||
|
borderSide: BorderSide(color: Colors.black),
|
||||||
|
),
|
||||||
|
focusedBorder: OutlineInputBorder(
|
||||||
|
borderSide: BorderSide(color: Colors.black, width: 2),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
controller: accountNumberController,
|
||||||
|
keyboardType: TextInputType.number,
|
||||||
|
textInputAction: TextInputAction.next,
|
||||||
|
validator: (value) {
|
||||||
|
if (value == null || value.isEmpty) {
|
||||||
|
return 'Account number is required';
|
||||||
|
} else if (value.length != 16) {
|
||||||
|
return 'Enter a valid account number';
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
},
|
||||||
|
),
|
||||||
|
const SizedBox(height: 25),
|
||||||
|
TextFormField(
|
||||||
|
decoration: const InputDecoration(
|
||||||
|
labelText: 'Name',
|
||||||
|
border: OutlineInputBorder(),
|
||||||
|
isDense: true,
|
||||||
|
filled: true,
|
||||||
|
fillColor: Colors.white,
|
||||||
|
enabledBorder: OutlineInputBorder(
|
||||||
|
borderSide: BorderSide(color: Colors.black),
|
||||||
|
),
|
||||||
|
focusedBorder: OutlineInputBorder(
|
||||||
|
borderSide: BorderSide(color: Colors.black, width: 2),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
controller: nameController,
|
||||||
|
keyboardType: TextInputType.name,
|
||||||
|
textInputAction: TextInputAction.next,
|
||||||
|
validator: (value) {
|
||||||
|
if (value == null || value.isEmpty) {
|
||||||
|
return 'Name is required';
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
},
|
||||||
|
),
|
||||||
|
const SizedBox(height: 25),
|
||||||
|
TextFormField(
|
||||||
|
decoration: const InputDecoration(
|
||||||
|
labelText: "Beneficiary Bank Name",
|
||||||
|
border: OutlineInputBorder(),
|
||||||
|
isDense: true,
|
||||||
|
filled: true,
|
||||||
|
fillColor: Colors.white,
|
||||||
|
enabledBorder: OutlineInputBorder(
|
||||||
|
borderSide: BorderSide(color: Colors.black),
|
||||||
|
),
|
||||||
|
focusedBorder: OutlineInputBorder(
|
||||||
|
borderSide: BorderSide(color: Colors.black, width: 2),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
controller: bankNameController,
|
||||||
|
textInputAction: TextInputAction.next,
|
||||||
|
validator: (value) {
|
||||||
|
if (value == null || value.isEmpty) {
|
||||||
|
return 'Beneficiary Bank Name is required';
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
},
|
||||||
|
),
|
||||||
|
const SizedBox(height: 25),
|
||||||
|
TextFormField(
|
||||||
|
decoration: const InputDecoration(
|
||||||
|
labelText: "Branch Name",
|
||||||
|
border: OutlineInputBorder(),
|
||||||
|
isDense: true,
|
||||||
|
filled: true,
|
||||||
|
fillColor: Colors.white,
|
||||||
|
enabledBorder: OutlineInputBorder(
|
||||||
|
borderSide: BorderSide(color: Colors.black),
|
||||||
|
),
|
||||||
|
focusedBorder: OutlineInputBorder(
|
||||||
|
borderSide: BorderSide(color: Colors.black, width: 2),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
controller: branchNameController,
|
||||||
|
textInputAction: TextInputAction.next,
|
||||||
|
validator: (value) {
|
||||||
|
if (value == null || value.isEmpty) {
|
||||||
|
return 'Branch Name is required';
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
},
|
||||||
|
),
|
||||||
|
const SizedBox(height: 25),
|
||||||
|
Row(
|
||||||
|
children: [
|
||||||
|
Expanded(
|
||||||
|
child: TextFormField(
|
||||||
|
decoration: const InputDecoration(
|
||||||
|
labelText: "IFSC Code",
|
||||||
|
border: OutlineInputBorder(),
|
||||||
|
isDense: true,
|
||||||
|
filled: true,
|
||||||
|
fillColor: Colors.white,
|
||||||
|
enabledBorder: OutlineInputBorder(
|
||||||
|
borderSide: BorderSide(color: Colors.black),
|
||||||
|
),
|
||||||
|
focusedBorder: OutlineInputBorder(
|
||||||
|
borderSide: BorderSide(color: Colors.black, width: 2),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
controller: ifscController,
|
||||||
|
textInputAction: TextInputAction.next,
|
||||||
|
validator: (value) {
|
||||||
|
if (value == null || value.isEmpty) {
|
||||||
|
return 'IFSC Code is required';
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
},
|
||||||
|
)),
|
||||||
|
const SizedBox(width: 10),
|
||||||
|
Expanded(
|
||||||
|
child: DropdownButtonFormField<String>(
|
||||||
|
value: accountType,
|
||||||
|
decoration: const InputDecoration(
|
||||||
|
labelText: "Account Type",
|
||||||
|
border: OutlineInputBorder(),
|
||||||
|
isDense: true,
|
||||||
|
filled: true,
|
||||||
|
fillColor: Colors.white,
|
||||||
|
enabledBorder: OutlineInputBorder(
|
||||||
|
borderSide: BorderSide(color: Colors.black),
|
||||||
|
),
|
||||||
|
focusedBorder: OutlineInputBorder(
|
||||||
|
borderSide: BorderSide(color: Colors.black, width: 2),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
items: ['Savings', 'Current']
|
||||||
|
.map((e) => DropdownMenuItem(
|
||||||
|
value: e,
|
||||||
|
child: Text(e),
|
||||||
|
))
|
||||||
|
.toList(),
|
||||||
|
onChanged: (value) => setState(() {
|
||||||
|
accountType = value!;
|
||||||
|
}),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
const SizedBox(height: 25),
|
||||||
|
Row(
|
||||||
|
children: [
|
||||||
|
Expanded(
|
||||||
|
child: TextFormField(
|
||||||
|
controller: phoneController,
|
||||||
|
keyboardType: TextInputType.phone,
|
||||||
|
decoration: const InputDecoration(
|
||||||
|
labelText: "Phone",
|
||||||
|
prefixIcon: Icon(Icons.phone),
|
||||||
|
border: OutlineInputBorder(),
|
||||||
|
isDense: true,
|
||||||
|
filled: true,
|
||||||
|
fillColor: Colors.white,
|
||||||
|
enabledBorder: OutlineInputBorder(
|
||||||
|
borderSide: BorderSide(color: Colors.black),
|
||||||
|
),
|
||||||
|
focusedBorder: OutlineInputBorder(
|
||||||
|
borderSide: BorderSide(color: Colors.black, width: 2),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
textInputAction: TextInputAction.next,
|
||||||
|
validator: (value) => value == null || value.isEmpty
|
||||||
|
? "Phone number is Required"
|
||||||
|
: null,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(width: 10),
|
||||||
|
Expanded(
|
||||||
|
child: TextFormField(
|
||||||
|
decoration: const InputDecoration(
|
||||||
|
labelText: 'Amount',
|
||||||
|
border: OutlineInputBorder(),
|
||||||
|
isDense: true,
|
||||||
|
filled: true,
|
||||||
|
fillColor: Colors.white,
|
||||||
|
enabledBorder: OutlineInputBorder(
|
||||||
|
borderSide: BorderSide(color: Colors.black),
|
||||||
|
),
|
||||||
|
focusedBorder: OutlineInputBorder(
|
||||||
|
borderSide: BorderSide(color: Colors.black, width: 2),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
controller: amountController,
|
||||||
|
keyboardType: TextInputType.number,
|
||||||
|
textInputAction: TextInputAction.next,
|
||||||
|
validator: (value) {
|
||||||
|
if (value == null || value.isEmpty) {
|
||||||
|
return 'Amount is required';
|
||||||
|
}
|
||||||
|
final amount = double.tryParse(value);
|
||||||
|
if (amount == null || amount <= 0) {
|
||||||
|
return 'Enter a valid amount';
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
const SizedBox(height: 30),
|
||||||
|
Row(
|
||||||
|
children: [
|
||||||
|
const Text("Transaction Mode",
|
||||||
|
style: TextStyle(fontWeight: FontWeight.w500)),
|
||||||
|
const SizedBox(width: 12),
|
||||||
|
Expanded(child: buildTransactionModeSelector()),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
|
||||||
|
const SizedBox(height: 45),
|
||||||
|
Align(
|
||||||
|
alignment: Alignment.center,
|
||||||
|
child: SizedBox(
|
||||||
|
width: 250,
|
||||||
|
child: ElevatedButton(
|
||||||
|
style: ElevatedButton.styleFrom(
|
||||||
|
shape: const StadiumBorder(),
|
||||||
|
padding: const EdgeInsets.symmetric(vertical: 16),
|
||||||
|
backgroundColor: Colors.blue[900],
|
||||||
|
foregroundColor: Colors.white,
|
||||||
|
),
|
||||||
|
onPressed: () {
|
||||||
|
if (_formKey.currentState!.validate()) {
|
||||||
|
// Perform payment logic
|
||||||
|
final selectedMode = transactionModes[selectedTransactionIndex];
|
||||||
|
ScaffoldMessenger.of(context).showSnackBar(
|
||||||
|
SnackBar(content: Text('Paying via $selectedMode...')),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
child: const Text('Pay'),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget buildTransactionModeSelector() {
|
||||||
|
return Container(
|
||||||
|
padding: const EdgeInsets.all(4),
|
||||||
|
child: Row(
|
||||||
|
children: List.generate(transactionModes.length, (index) {
|
||||||
|
bool isSelected = selectedTransactionIndex == index;
|
||||||
|
return Expanded(
|
||||||
|
child: GestureDetector(
|
||||||
|
onTap: () {
|
||||||
|
setState(() => selectedTransactionIndex = index);
|
||||||
|
},
|
||||||
|
child: Container(
|
||||||
|
margin: const EdgeInsets.symmetric(horizontal: 4),
|
||||||
|
padding: const EdgeInsets.symmetric(vertical: 5),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: isSelected ? Colors.blue[200] : Colors.white,
|
||||||
|
borderRadius: BorderRadius.circular(5),
|
||||||
|
border: Border.all(
|
||||||
|
color: isSelected? Colors.blue : Colors.grey,
|
||||||
|
width: isSelected ? 0 : 1.2,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
alignment: Alignment.center,
|
||||||
|
child: Text(
|
||||||
|
transactionModes[index],
|
||||||
|
style: const TextStyle(
|
||||||
|
color: Colors.black,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
95
lib/features/quick_pay/screens/quick_pay_screen.dart
Normal file
95
lib/features/quick_pay/screens/quick_pay_screen.dart
Normal file
@ -0,0 +1,95 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:kmobile/features/quick_pay/screens/quick_pay_outside_bank_screen.dart';
|
||||||
|
import 'package:kmobile/features/quick_pay/screens/quick_pay_within_bank_screen.dart';
|
||||||
|
import 'package:material_symbols_icons/material_symbols_icons.dart';
|
||||||
|
|
||||||
|
class QuickPayScreen extends StatefulWidget {
|
||||||
|
const QuickPayScreen({super.key});
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<QuickPayScreen> createState() => _QuickPayScreen();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _QuickPayScreen extends State<QuickPayScreen> {
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Scaffold(
|
||||||
|
appBar: AppBar(
|
||||||
|
leading: IconButton(
|
||||||
|
icon: const Icon(Symbols.arrow_back_ios_new),
|
||||||
|
onPressed: () {
|
||||||
|
Navigator.pop(context);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
title: const Text(
|
||||||
|
'Quick Pay',
|
||||||
|
style: TextStyle(color: Colors.black, fontWeight: FontWeight.w500),
|
||||||
|
),
|
||||||
|
centerTitle: false,
|
||||||
|
actions: const [
|
||||||
|
Padding(
|
||||||
|
padding: EdgeInsets.only(right: 10.0),
|
||||||
|
child: CircleAvatar(
|
||||||
|
backgroundImage: AssetImage('assets/images/avatar.jpg'),
|
||||||
|
// Replace with your image
|
||||||
|
radius: 20,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
body: ListView(
|
||||||
|
children: [
|
||||||
|
QuickPayManagementTile(
|
||||||
|
icon: Symbols.input_circle,
|
||||||
|
label: 'Own Bank',
|
||||||
|
onTap: () {
|
||||||
|
Navigator.push(
|
||||||
|
context,
|
||||||
|
MaterialPageRoute(
|
||||||
|
builder: (context) => const QuickPayWithinBankScreen()));
|
||||||
|
},
|
||||||
|
),
|
||||||
|
const Divider(
|
||||||
|
height: 1,
|
||||||
|
),
|
||||||
|
QuickPayManagementTile(
|
||||||
|
icon: Symbols.output_circle,
|
||||||
|
label: 'Outside Bank',
|
||||||
|
onTap: () {
|
||||||
|
Navigator.push(
|
||||||
|
context,
|
||||||
|
MaterialPageRoute(
|
||||||
|
builder: (context) => const QuickPayOutsideBankScreen()));
|
||||||
|
},
|
||||||
|
),
|
||||||
|
const Divider(
|
||||||
|
height: 1,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class QuickPayManagementTile extends StatelessWidget {
|
||||||
|
final IconData icon;
|
||||||
|
final String label;
|
||||||
|
final VoidCallback onTap;
|
||||||
|
|
||||||
|
const QuickPayManagementTile({
|
||||||
|
super.key,
|
||||||
|
required this.icon,
|
||||||
|
required this.label,
|
||||||
|
required this.onTap,
|
||||||
|
});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return ListTile(
|
||||||
|
leading: Icon(icon),
|
||||||
|
title: Text(label),
|
||||||
|
trailing: const Icon(Symbols.arrow_right, size: 20),
|
||||||
|
onTap: onTap,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
207
lib/features/quick_pay/screens/quick_pay_within_bank_screen.dart
Normal file
207
lib/features/quick_pay/screens/quick_pay_within_bank_screen.dart
Normal file
@ -0,0 +1,207 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:material_symbols_icons/material_symbols_icons.dart';
|
||||||
|
|
||||||
|
class QuickPayWithinBankScreen extends StatefulWidget {
|
||||||
|
const QuickPayWithinBankScreen({super.key});
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<QuickPayWithinBankScreen> createState() => _QuickPayWithinBankScreen();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _QuickPayWithinBankScreen extends State<QuickPayWithinBankScreen> {
|
||||||
|
final _formKey = GlobalKey<FormState>();
|
||||||
|
|
||||||
|
final TextEditingController accountNumberController = TextEditingController();
|
||||||
|
final TextEditingController nameController = TextEditingController();
|
||||||
|
final TextEditingController amountController = TextEditingController();
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Scaffold(
|
||||||
|
appBar: AppBar(
|
||||||
|
leading: IconButton(
|
||||||
|
icon: const Icon(Symbols.arrow_back_ios_new),
|
||||||
|
onPressed: () {
|
||||||
|
Navigator.pop(context);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
title: const Text(
|
||||||
|
'Quick Pay - Own Bank',
|
||||||
|
style: TextStyle(color: Colors.black, fontWeight: FontWeight.w500),
|
||||||
|
),
|
||||||
|
centerTitle: false,
|
||||||
|
actions: const [
|
||||||
|
Padding(
|
||||||
|
padding: EdgeInsets.only(right: 10.0),
|
||||||
|
child: CircleAvatar(
|
||||||
|
backgroundImage: AssetImage('assets/images/avatar.jpg'),
|
||||||
|
// Replace with your image
|
||||||
|
radius: 20,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
body: Padding(
|
||||||
|
padding: const EdgeInsets.all(16.0),
|
||||||
|
child: Form(
|
||||||
|
key: _formKey,
|
||||||
|
child: Column(
|
||||||
|
children: [
|
||||||
|
const SizedBox(height: 25),
|
||||||
|
TextFormField(
|
||||||
|
decoration: const InputDecoration(
|
||||||
|
labelText: 'Account Number',
|
||||||
|
border: OutlineInputBorder(),
|
||||||
|
isDense: true,
|
||||||
|
filled: true,
|
||||||
|
fillColor: Colors.white,
|
||||||
|
enabledBorder: OutlineInputBorder(
|
||||||
|
borderSide: BorderSide(color: Colors.black),
|
||||||
|
),
|
||||||
|
focusedBorder: OutlineInputBorder(
|
||||||
|
borderSide: BorderSide(color: Colors.black, width: 2),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
controller: accountNumberController,
|
||||||
|
keyboardType: TextInputType.number,
|
||||||
|
textInputAction: TextInputAction.next,
|
||||||
|
validator: (value) {
|
||||||
|
if (value == null || value.isEmpty) {
|
||||||
|
return 'Account number is required';
|
||||||
|
} else if (value.length != 16) {
|
||||||
|
return 'Enter a valid account number';
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
},
|
||||||
|
),
|
||||||
|
const Align(
|
||||||
|
alignment: Alignment.topLeft,
|
||||||
|
child: Padding(
|
||||||
|
padding: EdgeInsets.only(left: 15.0, top: 5),
|
||||||
|
child: Text(
|
||||||
|
'Beneficiary Account Number',
|
||||||
|
style: TextStyle(color: Colors.black54),
|
||||||
|
),
|
||||||
|
)),
|
||||||
|
const SizedBox(height: 25),
|
||||||
|
TextFormField(
|
||||||
|
decoration: const InputDecoration(
|
||||||
|
labelText: 'Name',
|
||||||
|
border: OutlineInputBorder(),
|
||||||
|
isDense: true,
|
||||||
|
filled: true,
|
||||||
|
fillColor: Colors.white,
|
||||||
|
enabledBorder: OutlineInputBorder(
|
||||||
|
borderSide: BorderSide(color: Colors.black),
|
||||||
|
),
|
||||||
|
focusedBorder: OutlineInputBorder(
|
||||||
|
borderSide: BorderSide(color: Colors.black, width: 2),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
controller: nameController,
|
||||||
|
keyboardType: TextInputType.name,
|
||||||
|
textInputAction: TextInputAction.next,
|
||||||
|
validator: (value) {
|
||||||
|
if (value == null || value.isEmpty) {
|
||||||
|
return 'Name is required';
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
},
|
||||||
|
),
|
||||||
|
const Align(
|
||||||
|
alignment: Alignment.topLeft,
|
||||||
|
child: Padding(
|
||||||
|
padding: EdgeInsets.only(left: 15.0, top: 5),
|
||||||
|
child: Text(
|
||||||
|
'Beneficiary Name',
|
||||||
|
style: TextStyle(color: Colors.black54),
|
||||||
|
),
|
||||||
|
)),
|
||||||
|
const SizedBox(height: 25),
|
||||||
|
TextFormField(
|
||||||
|
decoration: const InputDecoration(
|
||||||
|
labelText: 'Amount',
|
||||||
|
border: OutlineInputBorder(),
|
||||||
|
isDense: true,
|
||||||
|
filled: true,
|
||||||
|
fillColor: Colors.white,
|
||||||
|
enabledBorder: OutlineInputBorder(
|
||||||
|
borderSide: BorderSide(color: Colors.black),
|
||||||
|
),
|
||||||
|
focusedBorder: OutlineInputBorder(
|
||||||
|
borderSide: BorderSide(color: Colors.black, width: 2),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
controller: amountController,
|
||||||
|
keyboardType: TextInputType.number,
|
||||||
|
textInputAction: TextInputAction.next,
|
||||||
|
validator: (value) {
|
||||||
|
if (value == null || value.isEmpty) {
|
||||||
|
return 'Amount is required';
|
||||||
|
}
|
||||||
|
final amount = double.tryParse(value);
|
||||||
|
if (amount == null || amount <= 0) {
|
||||||
|
return 'Enter a valid amount';
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
},
|
||||||
|
),
|
||||||
|
const SizedBox(height: 45),
|
||||||
|
Align(
|
||||||
|
alignment: Alignment.center,
|
||||||
|
child: SizedBox(
|
||||||
|
width: 250,
|
||||||
|
height: 50,
|
||||||
|
child: ElevatedButton(
|
||||||
|
style: ElevatedButton.styleFrom(
|
||||||
|
shape: const StadiumBorder(),
|
||||||
|
padding: const EdgeInsets.symmetric(vertical: 16),
|
||||||
|
backgroundColor: Colors.blue[900],
|
||||||
|
foregroundColor: Colors.white,
|
||||||
|
),
|
||||||
|
onPressed: () {
|
||||||
|
if (_formKey.currentState!.validate()) {
|
||||||
|
// Perform payment logic
|
||||||
|
ScaffoldMessenger.of(context).showSnackBar(
|
||||||
|
const SnackBar(
|
||||||
|
content: Text('Processing Payment...')),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
child: const Text('Pay'),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget buildTextFormField({
|
||||||
|
required String label,
|
||||||
|
required TextEditingController controller,
|
||||||
|
TextInputType keyboardType = TextInputType.text,
|
||||||
|
String? Function(String?)? validator,
|
||||||
|
}) {
|
||||||
|
return TextFormField(
|
||||||
|
controller: controller,
|
||||||
|
keyboardType: keyboardType,
|
||||||
|
validator: validator,
|
||||||
|
decoration: InputDecoration(
|
||||||
|
labelText: label,
|
||||||
|
border: const OutlineInputBorder(),
|
||||||
|
isDense: true,
|
||||||
|
filled: true,
|
||||||
|
fillColor: Colors.white,
|
||||||
|
enabledBorder: const OutlineInputBorder(
|
||||||
|
borderSide: BorderSide(color: Colors.black),
|
||||||
|
),
|
||||||
|
focusedBorder: const OutlineInputBorder(
|
||||||
|
borderSide: BorderSide(color: Colors.black, width: 2),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user