feat: Implement major features and fix theming bug

This commit introduces several new features and a critical bug fix.

- Implemented a full "Quick Pay" flow for both within and outside the bank, including IFSC validation, beneficiary verification, and a TPIN-based payment process.
- Added a date range filter to the Account Statement screen and streamlined the UI by removing the amount filters.
- Fixed a major bug that prevented dynamic theme changes from being applied. The app now correctly switches between color themes.
- Refactored and improved beneficiary management, transaction models, and the fund transfer flow to support NEFT/RTGS.
This commit is contained in:
asif
2025-08-11 04:06:05 +05:30
parent 3024ddef15
commit f91d0f739b
34 changed files with 1638 additions and 911 deletions

View File

@@ -95,7 +95,10 @@ class _DashboardScreenState extends State<DashboardScreen> {
return Shimmer.fromColors(
baseColor: Theme.of(context).dialogBackgroundColor,
highlightColor: Theme.of(context).dialogBackgroundColor,
child: Container(width: 100, height: 32, color: Theme.of(context).scaffoldBackgroundColor),
child: Container(
width: 100,
height: 32,
color: Theme.of(context).scaffoldBackgroundColor),
);
}
@@ -199,7 +202,7 @@ class _DashboardScreenState extends State<DashboardScreen> {
child: Scaffold(
backgroundColor: Theme.of(context).scaffoldBackgroundColor,
appBar: AppBar(
backgroundColor:Theme.of(context).scaffoldBackgroundColor,
backgroundColor: Theme.of(context).scaffoldBackgroundColor,
automaticallyImplyLeading: false,
title: Text(
AppLocalizations.of(context).kconnect,
@@ -291,7 +294,8 @@ class _DashboardScreenState extends State<DashboardScreen> {
Text(
"${AppLocalizations.of(context).accountNumber}: ",
style: TextStyle(
color: Theme.of(context).dialogBackgroundColor,
color:
Theme.of(context).dialogBackgroundColor,
fontSize: 12,
),
),
@@ -300,9 +304,11 @@ class _DashboardScreenState extends State<DashboardScreen> {
dropdownColor: Theme.of(context).primaryColor,
underline: const SizedBox(),
icon: const Icon(Icons.keyboard_arrow_down),
iconEnabledColor:Theme.of(context).dialogBackgroundColor,
iconEnabledColor:
Theme.of(context).dialogBackgroundColor,
style: TextStyle(
color: Theme.of(context).dialogBackgroundColor,
color:
Theme.of(context).dialogBackgroundColor,
fontSize: 14,
),
items: List.generate(users.length, (index) {
@@ -311,7 +317,8 @@ class _DashboardScreenState extends State<DashboardScreen> {
child: Text(
users[index].accountNo ?? 'N/A',
style: TextStyle(
color: Theme.of(context).dialogBackgroundColor,
color: Theme.of(context)
.dialogBackgroundColor,
fontSize: 14,
),
),
@@ -351,13 +358,15 @@ class _DashboardScreenState extends State<DashboardScreen> {
width: 20,
height: 20,
child: CircularProgressIndicator(
color: Theme.of(context).dialogBackgroundColor,
color: Theme.of(context)
.dialogBackgroundColor,
strokeWidth: 2,
),
)
: Icon(
: Icon(
Icons.refresh,
color: Theme.of(context).dialogBackgroundColor,
color: Theme.of(context)
.dialogBackgroundColor,
),
onPressed: isRefreshing
? null
@@ -380,7 +389,8 @@ class _DashboardScreenState extends State<DashboardScreen> {
Text(
"",
style: TextStyle(
color: Theme.of(context).dialogBackgroundColor,
color:
Theme.of(context).dialogBackgroundColor,
fontSize: 40,
fontWeight: FontWeight.w700,
),
@@ -393,7 +403,8 @@ class _DashboardScreenState extends State<DashboardScreen> {
'0.00'
: '********',
style: TextStyle(
color: Theme.of(context).dialogBackgroundColor,
color: Theme.of(context)
.dialogBackgroundColor,
fontSize: 40,
fontWeight: FontWeight.w700,
),
@@ -423,7 +434,8 @@ class _DashboardScreenState extends State<DashboardScreen> {
isVisible
? Symbols.visibility_lock
: Symbols.visibility,
color: Theme.of(context).scaffoldBackgroundColor,
color: Theme.of(context)
.scaffoldBackgroundColor,
),
),
],
@@ -473,21 +485,21 @@ class _DashboardScreenState extends State<DashboardScreen> {
);
},
),
_buildQuickLink(Symbols.send_money,
AppLocalizations.of(context).fundTransfer, () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) =>
FundTransferBeneficiaryScreen(creditAccountNo: users[selectedAccountIndex].accountNo!, remitterName: users[selectedAccountIndex].name!)));
}, disable: false),
_buildQuickLink(
Symbols.send_money,
AppLocalizations.of(context).fundTransfer,
Symbols.server_person,
AppLocalizations.of(context).accountInfo,
() {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) =>
const FundTransferBeneficiaryScreen()));
}, disable: true),
_buildQuickLink(Symbols.server_person,
AppLocalizations.of(context).accountInfo, () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => AccountInfoScreen(
users: users,
selectedIndex: selectedAccountIndex,
@@ -496,39 +508,42 @@ class _DashboardScreenState extends State<DashboardScreen> {
);
},
),
_buildQuickLink(
Symbols.receipt_long,
AppLocalizations.of(context).accountStatement,
() {
Navigator.push(
_buildQuickLink(Symbols.receipt_long,
AppLocalizations.of(context).accountStatement,
() {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => AccountStatementScreen(
accountNo: users[selectedAccountIndex]
.accountNo!,
)));
}),
_buildQuickLink(Symbols.checkbook,
AppLocalizations.of(context).handleCheque, () {},
disable: true),
_buildQuickLink(Icons.group,
AppLocalizations.of(context).manageBeneficiary, () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) =>
const ManageBeneficiariesScreen()));
}, disable: false),
_buildQuickLink(Symbols.support_agent,
AppLocalizations.of(context).contactUs, () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => const EnquiryScreen()));
}),
],
),
const SizedBox(height: 5),
builder: (context) =>
AccountStatementScreen(
accountNo: users[selectedAccountIndex]
.accountNo!,
)));
}),
_buildQuickLink(Symbols.checkbook,
AppLocalizations.of(context).handleCheque, () {},
disable: true),
_buildQuickLink(Icons.group,
AppLocalizations.of(context).manageBeneficiary,
() {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) =>
ManageBeneficiariesScreen(
customerName: currAccount.name!)));
}, disable: false),
_buildQuickLink(Symbols.support_agent,
AppLocalizations.of(context).contactUs, () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) =>
const EnquiryScreen()));
}),
],
),
const SizedBox(height: 5),
// Recent Transactions
Text(
@@ -599,17 +614,25 @@ class _DashboardScreenState extends State<DashboardScreen> {
leading: Shimmer.fromColors(
baseColor: Colors.grey[300]!,
highlightColor: Colors.grey[100]!,
child: CircleAvatar(radius: 12, backgroundColor: Theme.of(context).scaffoldBackgroundColor),
child: CircleAvatar(
radius: 12,
backgroundColor: Theme.of(context).scaffoldBackgroundColor),
),
title: Shimmer.fromColors(
baseColor: Colors.grey[300]!,
highlightColor: Colors.grey[100]!,
child: Container(height: 10, width: 100, color: Theme.of(context).scaffoldBackgroundColor),
child: Container(
height: 10,
width: 100,
color: Theme.of(context).scaffoldBackgroundColor),
),
subtitle: Shimmer.fromColors(
baseColor: Colors.grey[300]!,
highlightColor: Colors.grey[100]!,
child: Container(height: 8, width: 60, color: Theme.of(context).scaffoldBackgroundColor),
child: Container(
height: 8,
width: 60,
color: Theme.of(context).scaffoldBackgroundColor),
),
);
});

View File

@@ -13,14 +13,15 @@ class AccountCard extends StatelessWidget {
width: 300,
padding: const EdgeInsets.all(20),
decoration: BoxDecoration(
gradient: LinearGradient(
begin: Alignment.topLeft,
end: Alignment.bottomRight,
colors: [
Theme.of(context).primaryColor,
Theme.of(context).primaryColor.withBlue(200),
],
),
// gradient: LinearGradient(
// begin: Alignment.topLeft,
// end: Alignment.bottomRight,
// colors: [
// Theme.of(context).primaryColor,
// Theme.of(context).primaryColor.withBlue(200),
// ],
// ),
color: Theme.of(context).primaryColor,
borderRadius: BorderRadius.circular(12),
boxShadow: [
BoxShadow(
@@ -56,12 +57,13 @@ class AccountCard extends StatelessWidget {
const SizedBox(height: 20),
Text(
account.accountNumber,
style: TextStyle(color: Theme.of(context).dialogBackgroundColor, fontSize: 16),
style: TextStyle(
color: Theme.of(context).dialogBackgroundColor, fontSize: 16),
),
const SizedBox(height: 30),
Text(
'${account.currency} ${account.balance.toStringAsFixed(2)}',
style: TextStyle(
style: TextStyle(
color: Theme.of(context).scaffoldBackgroundColor,
fontSize: 22,
fontWeight: FontWeight.bold,
@@ -70,7 +72,8 @@ class AccountCard extends StatelessWidget {
const SizedBox(height: 5),
Text(
AppLocalizations.of(context).availableBalance,
style: TextStyle(color: Theme.of(context).dialogBackgroundColor, fontSize: 12),
style: TextStyle(
color: Theme.of(context).dialogBackgroundColor, fontSize: 12),
),
],
),